cui/source/dialogs/colorpicker.cxx | 14 - cui/source/inc/transfrm.hxx | 27 +-- cui/source/tabpages/transfrm.cxx | 134 ++++++++--------- cui/uiconfig/ui/rotationtabpage.ui | 86 ++++++++--- include/svx/dialcontrol.hxx | 93 ++++++++++++ include/vcl/customweld.hxx | 6 include/vcl/weld.hxx | 4 svx/source/dialog/charmap.cxx | 4 svx/source/dialog/dialcontrol.cxx | 277 ++++++++++++++++++++++++++++++++++++- vcl/source/app/salvtables.cxx | 15 ++ vcl/unx/gtk3/gtk3gtkinst.cxx | 15 ++ 11 files changed, 543 insertions(+), 132 deletions(-)
New commits: commit 66cd438e3545edecaa05aa27beb289c6a6df53fc Author: Caolán McNamara <caol...@redhat.com> Date: Fri May 25 16:54:30 2018 +0100 weld SvxAngleTabPage Change-Id: I03bd0a6a0805d549570ce44030a0f58ca2b98d05 Reviewed-on: https://gerrit.libreoffice.org/54818 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> diff --git a/cui/source/dialogs/colorpicker.cxx b/cui/source/dialogs/colorpicker.cxx index 4fba23b2f7ca..3b182cde641a 100644 --- a/cui/source/dialogs/colorpicker.cxx +++ b/cui/source/dialogs/colorpicker.cxx @@ -426,7 +426,7 @@ void ColorFieldControl::ShowPosition( const Point& rPos, bool bUpdate ) void ColorFieldControl::MouseButtonDown(const MouseEvent& rMEvt) { - grab_add(); + CaptureMouse(); mbMouseCaptured = true; ShowPosition(rMEvt.GetPosPixel(), true); Modify(); @@ -443,7 +443,7 @@ void ColorFieldControl::MouseMove(const MouseEvent& rMEvt) void ColorFieldControl::MouseButtonUp(const MouseEvent&) { - grab_remove(); + ReleaseMouse(); mbMouseCaptured = false; } @@ -537,14 +537,12 @@ private: VclPtr<VirtualDevice> mxBitmap; sal_Int16 mnLevel; double mdValue; - bool mbMouseCaptured; }; ColorSliderControl::ColorSliderControl() : meMode( DefaultMode ) , mnLevel( 0 ) , mdValue( -1.0 ) - , mbMouseCaptured(false) { } @@ -651,15 +649,14 @@ void ColorSliderControl::ChangePosition(long nY) void ColorSliderControl::MouseButtonDown(const MouseEvent& rMEvt) { - grab_add(); - mbMouseCaptured = true; + CaptureMouse(); ChangePosition(rMEvt.GetPosPixel().Y()); Modify(); } void ColorSliderControl::MouseMove(const MouseEvent& rMEvt) { - if (mbMouseCaptured) + if (IsMouseCaptured()) { ChangePosition(rMEvt.GetPosPixel().Y()); Modify(); @@ -668,8 +665,7 @@ void ColorSliderControl::MouseMove(const MouseEvent& rMEvt) void ColorSliderControl::MouseButtonUp(const MouseEvent&) { - grab_remove(); - mbMouseCaptured = false; + ReleaseMouse(); } void ColorSliderControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) diff --git a/cui/source/inc/transfrm.hxx b/cui/source/inc/transfrm.hxx index 7e7aa264f91b..9dccd2663241 100644 --- a/cui/source/inc/transfrm.hxx +++ b/cui/source/inc/transfrm.hxx @@ -175,15 +175,6 @@ class SvxAngleTabPage : public SvxTabPage static const sal_uInt16 pAngleRanges[]; private: - VclPtr<VclFrame> m_pFlPosition; - VclPtr<MetricField> m_pMtrPosX; - VclPtr<MetricField> m_pMtrPosY; - VclPtr<SvxRectCtl> m_pCtlRect; - - VclPtr<VclFrame> m_pFlAngle; - VclPtr<NumericField> m_pNfAngle; - VclPtr<svx::DialControl> m_pCtlAngle; - const SfxItemSet& rOutAttrs; const SdrView* pView; @@ -194,10 +185,20 @@ private: MapUnit ePoolUnit; FieldUnit eDlgUnit; + svx::SvxDialControl m_aCtlAngle; + RectCtl m_aCtlRect; + + std::unique_ptr<weld::Widget> m_xFlPosition; + std::unique_ptr<weld::MetricSpinButton> m_xMtrPosX; + std::unique_ptr<weld::MetricSpinButton> m_xMtrPosY; + std::unique_ptr<weld::CustomWeld> m_xCtlRect; + std::unique_ptr<weld::Widget> m_xFlAngle; + std::unique_ptr<weld::SpinButton> m_xNfAngle; + std::unique_ptr<weld::CustomWeld> m_xCtlAngle; + public: - SvxAngleTabPage( vcl::Window* pParent, const SfxItemSet& rInAttrs ); + SvxAngleTabPage(TabPageParent pParent, const SfxItemSet& rInAttrs); virtual ~SvxAngleTabPage() override; - virtual void dispose() override; static VclPtr<SfxTabPage> Create( TabPageParent, const SfxItemSet* ); static const sal_uInt16* GetRanges() { return pAngleRanges; } @@ -208,8 +209,8 @@ public: virtual void ActivatePage( const SfxItemSet& rSet ) override; virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override; - virtual void PointChanged( vcl::Window* pWindow, RectPoint eRP ) override; - virtual void PointChanged( weld::DrawingArea* pWindow, RectPoint eRP ) override; + virtual void PointChanged(weld::DrawingArea* pWindow, RectPoint eRP) override; + virtual void PointChanged(vcl::Window* pWindow, RectPoint eRP) override; void Construct(); void SetView( const SdrView* pSdrView ) { pView = pSdrView; } diff --git a/cui/source/tabpages/transfrm.cxx b/cui/source/tabpages/transfrm.cxx index b37d366f2f0b..cf3bc446a78e 100644 --- a/cui/source/tabpages/transfrm.cxx +++ b/cui/source/tabpages/transfrm.cxx @@ -173,57 +173,43 @@ void SvxTransformTabDialog::SetValidateFramePosLink(const Link<SvxSwFrameValidat |* angle and the rotation angle of the graphic objects |* \************************************************************************/ -SvxAngleTabPage::SvxAngleTabPage(vcl::Window* pParent, const SfxItemSet& rInAttrs) - : SvxTabPage( pParent,"Rotation","cui/ui/rotationtabpage.ui", rInAttrs) +SvxAngleTabPage::SvxAngleTabPage(TabPageParent pParent, const SfxItemSet& rInAttrs) + : SvxTabPage(pParent, "cui/ui/rotationtabpage.ui", "Rotation", rInAttrs) , rOutAttrs(rInAttrs) , pView(nullptr) , eDlgUnit(FUNIT_NONE) + , m_aCtlRect(this) + , m_xFlPosition(m_xBuilder->weld_widget("FL_POSITION")) + , m_xMtrPosX(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_X", FUNIT_CM)) + , m_xMtrPosY(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_Y", FUNIT_CM)) + , m_xCtlRect(new weld::CustomWeld(*m_xBuilder, "CTL_RECT", m_aCtlRect)) + , m_xFlAngle(m_xBuilder->weld_widget("FL_ANGLE")) + , m_xNfAngle(m_xBuilder->weld_spin_button("NF_ANGLE")) + , m_xCtlAngle(new weld::CustomWeld(*m_xBuilder, "CTL_ANGLE", m_aCtlAngle)) { - get(m_pFlPosition, "FL_POSITION"); - get(m_pMtrPosX, "MTR_FLD_POS_X"); - get(m_pMtrPosY, "MTR_FLD_POS_Y"); - get(m_pCtlRect, "CTL_RECT"); - - get(m_pFlAngle, "FL_ANGLE"); - get(m_pNfAngle, "NF_ANGLE"); - get(m_pCtlAngle, "CTL_ANGLE"); - // calculate PoolUnit SfxItemPool* pPool = rOutAttrs.GetPool(); DBG_ASSERT( pPool, "no pool (!)" ); ePoolUnit = pPool->GetMetric(SID_ATTR_TRANSFORM_POS_X); - m_pCtlAngle->SetLinkedField( m_pNfAngle, 2 ); + m_aCtlAngle.SetLinkedField(m_xNfAngle.get(), 2); } SvxAngleTabPage::~SvxAngleTabPage() { - disposeOnce(); -} - -void SvxAngleTabPage::dispose() -{ - m_pFlPosition.clear(); - m_pMtrPosX.clear(); - m_pMtrPosY.clear(); - m_pCtlRect.clear(); - m_pFlAngle.clear(); - m_pNfAngle.clear(); - m_pCtlAngle.clear(); - SvxTabPage::dispose(); } void SvxAngleTabPage::Construct() { DBG_ASSERT(pView, "No valid view (!)"); eDlgUnit = GetModuleFieldUnit(GetItemSet()); - SetFieldUnit(*m_pMtrPosX, eDlgUnit, true); - SetFieldUnit(*m_pMtrPosY, eDlgUnit, true); + SetFieldUnit(*m_xMtrPosX, eDlgUnit, true); + SetFieldUnit(*m_xMtrPosY, eDlgUnit, true); - if(FUNIT_MILE == eDlgUnit || FUNIT_KM == eDlgUnit) + if (FUNIT_MILE == eDlgUnit || FUNIT_KM == eDlgUnit) { - m_pMtrPosX->SetDecimalDigits( 3 ); - m_pMtrPosY->SetDecimalDigits( 3 ); + m_xMtrPosX->set_digits(3); + m_xMtrPosY->set_digits(3); } { // #i75273# @@ -251,13 +237,13 @@ void SvxAngleTabPage::Construct() TransfrmHelper::ScaleRect(maRange, aUIScale); // take UI units into account - sal_uInt16 nDigits(m_pMtrPosX->GetDecimalDigits()); + sal_uInt16 nDigits(m_xMtrPosX->get_digits()); TransfrmHelper::ConvertRect(maRange, nDigits, ePoolUnit, eDlgUnit); if(!pView->IsRotateAllowed()) { - m_pFlPosition->Disable(); - m_pFlAngle->Disable(); + m_xFlPosition->set_sensitive(false); + m_xFlAngle->set_sensitive(false); } } @@ -265,13 +251,13 @@ bool SvxAngleTabPage::FillItemSet(SfxItemSet* rSet) { bool bModified = false; - if(m_pCtlAngle->IsValueModified() || m_pMtrPosX->IsValueModified() || m_pMtrPosY->IsValueModified()) + if (m_aCtlAngle.IsValueModified() || m_xMtrPosX->get_value_changed_from_saved() || m_xMtrPosY->get_value_changed_from_saved()) { const double fUIScale(double(pView->GetModel()->GetUIScale())); - const double fTmpX((GetCoreValue(*m_pMtrPosX, ePoolUnit) + maAnchor.getX()) * fUIScale); - const double fTmpY((GetCoreValue(*m_pMtrPosY, ePoolUnit) + maAnchor.getY()) * fUIScale); + const double fTmpX((GetCoreValue(*m_xMtrPosX, ePoolUnit) + maAnchor.getX()) * fUIScale); + const double fTmpY((GetCoreValue(*m_xMtrPosY, ePoolUnit) + maAnchor.getY()) * fUIScale); - rSet->Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_ANGLE), m_pCtlAngle->GetRotation())); + rSet->Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_ANGLE), m_aCtlAngle.GetRotation())); rSet->Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_ROT_X), basegfx::fround(fTmpX))); rSet->Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_ROT_Y), basegfx::fround(fTmpY))); @@ -290,39 +276,41 @@ void SvxAngleTabPage::Reset(const SfxItemSet* rAttrs) if(pItem) { const double fTmp((static_cast<double>(static_cast<const SfxInt32Item*>(pItem)->GetValue()) - maAnchor.getX()) / fUIScale); - SetMetricValue(*m_pMtrPosX, basegfx::fround(fTmp), ePoolUnit); + SetMetricValue(*m_xMtrPosX, basegfx::fround(fTmp), ePoolUnit); } else { - m_pMtrPosX->SetText( OUString() ); + m_xMtrPosX->set_text(OUString()); } pItem = GetItem(*rAttrs, SID_ATTR_TRANSFORM_ROT_Y); if(pItem) { const double fTmp((static_cast<double>(static_cast<const SfxInt32Item*>(pItem)->GetValue()) - maAnchor.getY()) / fUIScale); - SetMetricValue(*m_pMtrPosY, basegfx::fround(fTmp), ePoolUnit); + SetMetricValue(*m_xMtrPosY, basegfx::fround(fTmp), ePoolUnit); } else { - m_pMtrPosY->SetText( OUString() ); + m_xMtrPosY->set_text(OUString()); } pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_ANGLE ); if(pItem) { - m_pCtlAngle->SetRotation(static_cast<const SfxInt32Item*>(pItem)->GetValue()); + m_aCtlAngle.SetRotation(static_cast<const SfxInt32Item*>(pItem)->GetValue()); } else { - m_pCtlAngle->SetRotation(0); + m_aCtlAngle.SetRotation(0); } - m_pCtlAngle->SaveValue(); + m_aCtlAngle.SaveValue(); + m_xMtrPosX->save_value(); + m_xMtrPosY->save_value(); } -VclPtr<SfxTabPage> SvxAngleTabPage::Create( TabPageParent pWindow, const SfxItemSet* rSet) +VclPtr<SfxTabPage> SvxAngleTabPage::Create(TabPageParent pParent, const SfxItemSet* rSet) { - return VclPtr<SvxAngleTabPage>::Create(pWindow.pParent, *rSet); + return VclPtr<SvxAngleTabPage>::Create(pParent, *rSet); } void SvxAngleTabPage::ActivatePage(const SfxItemSet& rSet) @@ -330,8 +318,8 @@ void SvxAngleTabPage::ActivatePage(const SfxItemSet& rSet) SfxBoolItem const * bPosProtect = nullptr; if(SfxItemState::SET == rSet.GetItemState( GetWhich(SID_ATTR_TRANSFORM_PROTECT_POS ) , false, reinterpret_cast<SfxPoolItem const **>(&bPosProtect) )) { - m_pFlPosition->Enable(!bPosProtect->GetValue()); - m_pFlAngle->Enable(!bPosProtect->GetValue()); + m_xFlPosition->set_sensitive(!bPosProtect->GetValue()); + m_xFlAngle->set_sensitive(!bPosProtect->GetValue()); } } @@ -345,75 +333,75 @@ DeactivateRC SvxAngleTabPage::DeactivatePage( SfxItemSet* _pSet ) return DeactivateRC::LeavePage; } -void SvxAngleTabPage::PointChanged(vcl::Window* pWindow, RectPoint eRP) +void SvxAngleTabPage::PointChanged(vcl::Window*, RectPoint) +{ + assert(false); +} + +void SvxAngleTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint eRP) { - if(pWindow == m_pCtlRect) + if (pDrawingArea == m_aCtlRect.GetDrawingArea()) { switch(eRP) { case RectPoint::LT: { - m_pMtrPosX->SetUserValue( basegfx::fround64(maRange.getMinX()), FUNIT_NONE ); - m_pMtrPosY->SetUserValue( basegfx::fround64(maRange.getMinY()), FUNIT_NONE ); + m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FUNIT_NONE ); + m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FUNIT_NONE ); break; } case RectPoint::MT: { - m_pMtrPosX->SetUserValue( basegfx::fround64(maRange.getCenter().getX()), FUNIT_NONE ); - m_pMtrPosY->SetUserValue( basegfx::fround64(maRange.getMinY()), FUNIT_NONE ); + m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FUNIT_NONE ); + m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FUNIT_NONE ); break; } case RectPoint::RT: { - m_pMtrPosX->SetUserValue( basegfx::fround64(maRange.getMaxX()), FUNIT_NONE ); - m_pMtrPosY->SetUserValue( basegfx::fround64(maRange.getMinY()), FUNIT_NONE ); + m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FUNIT_NONE ); + m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FUNIT_NONE ); break; } case RectPoint::LM: { - m_pMtrPosX->SetUserValue( basegfx::fround64(maRange.getMinX()), FUNIT_NONE ); - m_pMtrPosY->SetUserValue( basegfx::fround64(maRange.getCenter().getY()), FUNIT_NONE ); + m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FUNIT_NONE ); + m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FUNIT_NONE ); break; } case RectPoint::MM: { - m_pMtrPosX->SetUserValue( basegfx::fround64(maRange.getCenter().getX()), FUNIT_NONE ); - m_pMtrPosY->SetUserValue( basegfx::fround64(maRange.getCenter().getY()), FUNIT_NONE ); + m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FUNIT_NONE ); + m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FUNIT_NONE ); break; } case RectPoint::RM: { - m_pMtrPosX->SetUserValue( basegfx::fround64(maRange.getMaxX()), FUNIT_NONE ); - m_pMtrPosY->SetUserValue( basegfx::fround64(maRange.getCenter().getY()), FUNIT_NONE ); + m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FUNIT_NONE ); + m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FUNIT_NONE ); break; } case RectPoint::LB: { - m_pMtrPosX->SetUserValue( basegfx::fround64(maRange.getMinX()), FUNIT_NONE ); - m_pMtrPosY->SetUserValue( basegfx::fround64(maRange.getMaxY()), FUNIT_NONE ); + m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FUNIT_NONE ); + m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FUNIT_NONE ); break; } case RectPoint::MB: { - m_pMtrPosX->SetUserValue( basegfx::fround64(maRange.getCenter().getX()), FUNIT_NONE ); - m_pMtrPosY->SetUserValue( basegfx::fround64(maRange.getMaxY()), FUNIT_NONE ); + m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FUNIT_NONE ); + m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FUNIT_NONE ); break; } case RectPoint::RB: { - m_pMtrPosX->SetUserValue( basegfx::fround64(maRange.getMaxX()), FUNIT_NONE ); - m_pMtrPosY->SetUserValue( basegfx::fround64(maRange.getMaxY()), FUNIT_NONE ); + m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FUNIT_NONE ); + m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FUNIT_NONE ); break; } } } } -void SvxAngleTabPage::PointChanged(weld::DrawingArea* /*pWindow*/, RectPoint /*eRP*/) -{ - assert(false); -} - /************************************************************************* |* |* dialog for changing slant and corner radius diff --git a/cui/uiconfig/ui/rotationtabpage.ui b/cui/uiconfig/ui/rotationtabpage.ui index e1f27a26c222..af5f9ec6260c 100644 --- a/cui/uiconfig/ui/rotationtabpage.ui +++ b/cui/uiconfig/ui/rotationtabpage.ui @@ -1,14 +1,19 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.18.3 --> +<!-- Generated with glade 3.22.1 --> <interface domain="cui"> <requires lib="gtk+" version="3.18"/> - <requires lib="LibreOffice" version="1.0"/> <object class="GtkAdjustment" id="adjustmentANGLE"> <property name="upper">359.99000000000001</property> <property name="step_increment">1</property> <property name="page_increment">10</property> </object> - <object class="GtkAdjustment" id="adjustmentPOS"> + <object class="GtkAdjustment" id="adjustmentPOS1"> + <property name="lower">-500</property> + <property name="upper">50000</property> + <property name="step_increment">10</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="adjustmentPOS2"> <property name="lower">-500</property> <property name="upper">50000</property> <property name="step_increment">10</property> @@ -48,10 +53,10 @@ <object class="GtkLabel" id="FT_POS_X"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="xalign">0</property> <property name="label" translatable="yes" context="rotationtabpage|FT_POS_X">Position _X:</property> <property name="use_underline">True</property> - <property name="mnemonic_widget">MTR_FLD_POS_X:0.00cm</property> + <property name="mnemonic_widget">MTR_FLD_POS_X</property> + <property name="xalign">0</property> </object> <packing> <property name="left_attach">0</property> @@ -62,10 +67,10 @@ <object class="GtkLabel" id="FT_POS_Y"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="xalign">0</property> <property name="label" translatable="yes" context="rotationtabpage|FT_POS_Y">Position _Y:</property> <property name="use_underline">True</property> - <property name="mnemonic_widget">MTR_FLD_POS_Y:0.00cm</property> + <property name="mnemonic_widget">MTR_FLD_POS_Y</property> + <property name="xalign">0</property> </object> <packing> <property name="left_attach">0</property> @@ -73,10 +78,11 @@ </packing> </child> <child> - <object class="GtkSpinButton" id="MTR_FLD_POS_X:0.00cm"> + <object class="GtkSpinButton" id="MTR_FLD_POS_X"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="adjustment">adjustmentPOS</property> + <property name="activates_default">True</property> + <property name="adjustment">adjustmentPOS1</property> <property name="digits">2</property> </object> <packing> @@ -85,10 +91,11 @@ </packing> </child> <child> - <object class="GtkSpinButton" id="MTR_FLD_POS_Y:0.00cm"> + <object class="GtkSpinButton" id="MTR_FLD_POS_Y"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="adjustment">adjustmentPOS</property> + <property name="activates_default">True</property> + <property name="adjustment">adjustmentPOS2</property> <property name="digits">2</property> </object> <packing> @@ -124,14 +131,31 @@ </packing> </child> <child> - <object class="svxlo-SvxRectCtl" id="CTL_RECT"> + <object class="GtkScrolledWindow"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="tooltip_text" translatable="yes" context="rotationtabpage|CTL_RECT|tooltip_text">Rotation point</property> + <property name="can_focus">True</property> <property name="halign">center</property> + <property name="valign">center</property> + <property name="hscrollbar_policy">never</property> + <property name="vscrollbar_policy">never</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkViewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkDrawingArea" id="CTL_RECT"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property> + <property name="tooltip_text" translatable="yes" context="rotationtabpage|CTL_RECT|tooltip_text">Rotation point</property> + </object> + </child> + </object> + </child> </object> <packing> - <property name="expand">False</property> + <property name="expand">True</property> <property name="fill">True</property> <property name="position">1</property> </packing> @@ -151,8 +175,8 @@ <object class="GtkLabel" id="label1"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="xalign">0</property> <property name="label" translatable="yes" context="rotationtabpage|label1">Pivot Point</property> + <property name="xalign">0</property> <attributes> <attribute name="weight" value="bold"/> </attributes> @@ -193,10 +217,10 @@ <object class="GtkLabel" id="FT_ANGLE"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="xalign">0</property> <property name="label" translatable="yes" context="rotationtabpage|FT_ANGLE">_Angle:</property> <property name="use_underline">True</property> <property name="mnemonic_widget">NF_ANGLE</property> + <property name="xalign">0</property> </object> <packing> <property name="expand">False</property> @@ -208,6 +232,7 @@ <object class="GtkSpinButton" id="NF_ANGLE"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="activates_default">True</property> <property name="adjustment">adjustmentANGLE</property> <property name="digits">2</property> <property name="wrap">True</property> @@ -237,7 +262,6 @@ <property name="can_focus">False</property> <property name="label" translatable="yes" context="rotationtabpage|FT_ANGLEPRESETS">Default _settings:</property> <property name="use_underline">True</property> - <property name="mnemonic_widget">CTL_ANGLE</property> </object> <packing> <property name="expand">False</property> @@ -246,11 +270,25 @@ </packing> </child> <child> - <object class="svxlo-DialControl" id="CTL_ANGLE"> + <object class="GtkScrolledWindow"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="tooltip_text" translatable="yes" context="rotationtabpage|CTL_ANGLE|tooltip_text">Rotation Angle</property> + <property name="can_focus">True</property> <property name="halign">center</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkViewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkDrawingArea" id="CTL_ANGLE"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property> + <property name="tooltip_text" translatable="yes" context="rotationtabpage|CTL_ANGLE|tooltip_text">Rotation Angle</property> + </object> + </child> + </object> + </child> </object> <packing> <property name="expand">False</property> @@ -273,8 +311,8 @@ <object class="GtkLabel" id="label2"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="xalign">0</property> <property name="label" translatable="yes" context="rotationtabpage|label2">Rotation Angle</property> + <property name="xalign">0</property> <attributes> <attribute name="weight" value="bold"/> </attributes> @@ -297,8 +335,8 @@ </object> <object class="GtkSizeGroup" id="sizegroup2"> <widgets> - <widget name="MTR_FLD_POS_X:0.00cm"/> - <widget name="MTR_FLD_POS_Y:0.00cm"/> + <widget name="MTR_FLD_POS_X"/> + <widget name="MTR_FLD_POS_Y"/> <widget name="NF_ANGLE"/> </widgets> </object> diff --git a/include/svx/dialcontrol.hxx b/include/svx/dialcontrol.hxx index a62377f8251a..6388a0d2c2aa 100644 --- a/include/svx/dialcontrol.hxx +++ b/include/svx/dialcontrol.hxx @@ -22,6 +22,7 @@ #include <memory> #include <vcl/ctrl.hxx> +#include <vcl/weld.hxx> #include <sfx2/itemconnect.hxx> #include <svx/svxdllapi.h> @@ -33,7 +34,7 @@ namespace svx { class SAL_WARN_UNUSED DialControlBmp final : public VirtualDevice { public: - explicit DialControlBmp( vcl::Window& rParent ); + explicit DialControlBmp(OutputDevice& rReference); void InitBitmap(const vcl::Font& rFont); void SetSize(const Size& rSize); @@ -53,7 +54,7 @@ private: tools::Rectangle maRect; bool mbEnabled; - vcl::Window& mrParent; + OutputDevice& mrParent; long mnCenterX; long mnCenterY; }; @@ -157,6 +158,94 @@ private: void LinkedFieldModifyHdl(); }; +class SAL_WARN_UNUSED SVX_DLLPUBLIC SvxDialControl : public weld::CustomWidgetController +{ +private: + OUString m_aText; +public: + virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override; + + virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override; + + virtual void StyleUpdated() override; + + virtual void MouseButtonDown( const MouseEvent& rMEvt ) override; + virtual void MouseMove( const MouseEvent& rMEvt ) override; + virtual void MouseButtonUp( const MouseEvent& rMEvt ) override; + virtual bool KeyInput(const KeyEvent& rKEvt) override; + virtual void LoseFocus() override; + + virtual void Resize() override; + + const OUString& GetText() const { return m_aText; } + void SetText(const OUString& rText) { m_aText = rText; } + + /** Returns true, if the control is not in "don't care" state. */ + bool HasRotation() const; + /** Sets the control to "don't care" state. */ + void SetNoRotation(); + + /** Returns the current rotation angle in 1/100 degrees. */ + sal_Int32 GetRotation() const; + /** Sets the rotation to the passed value (in 1/100 degrees). */ + void SetRotation( sal_Int32 nAngle ); + + /** Links the passed numeric edit field to the control (bi-directional). + * nDecimalPlaces: + * field value is unsign given decimal places + * default is 0 which means field values are in degrees, + * 2 means 100th of degree + */ + void SetLinkedField(weld::SpinButton* pField, sal_Int32 nDecimalPlaces = 0); + + /** The passed handler is called whenever the rotation value changes. */ + void SetModifyHdl( const Link<SvxDialControl*,void>& rLink ); + + /** Save value for later comparison */ + void SaveValue(); + + /** Compare value with the saved value */ + bool IsValueModified(); + +protected: + struct DialControl_Impl + { + ScopedVclPtr<DialControlBmp> mxBmpEnabled; + ScopedVclPtr<DialControlBmp> mxBmpDisabled; + ScopedVclPtr<DialControlBmp> mxBmpBuffered; + Link<SvxDialControl*,void> maModifyHdl; + weld::SpinButton* mpLinkField; + sal_Int32 mnLinkedFieldValueMultiplyer; + Size maWinSize; + vcl::Font maWinFont; + sal_Int32 mnAngle; + sal_Int32 mnInitialAngle; + sal_Int32 mnOldAngle; + long mnCenterX; + long mnCenterY; + bool mbNoRot; + + explicit DialControl_Impl(OutputDevice& rReference); + void Init( const Size& rWinSize, const vcl::Font& rWinFont ); + void SetSize( const Size& rWinSize ); + }; + std::unique_ptr< DialControl_Impl > mpImpl; + + virtual void HandleMouseEvent( const Point& rPos, bool bInitial ); + void HandleEscapeEvent(); + + void SetRotation( sal_Int32 nAngle, bool bBroadcast ); + + void Init( const Size& rWinSize, const vcl::Font& rWinFont ); + void Init( const Size& rWinSize ); + +private: + void InvalidateControl(); + + DECL_LINK( LinkedFieldModifyHdl, weld::SpinButton&, void ); + void LinkedFieldModifyHdl(); +}; + /** Wrapper for usage of a DialControl in item connections. */ class SAL_WARN_UNUSED SVX_DLLPUBLIC DialControlWrapper : public sfx::SingleControlWrapper< DialControl, sal_Int32 > { diff --git a/include/vcl/customweld.hxx b/include/vcl/customweld.hxx index 203c6e024eb1..2d6089871ef3 100644 --- a/include/vcl/customweld.hxx +++ b/include/vcl/customweld.hxx @@ -57,8 +57,10 @@ public: bool IsEnabled() const { return m_pDrawingArea->get_sensitive(); } int GetTextHeight() const { return m_pDrawingArea->get_text_height(); } OUString GetAccessibleName() const { return m_pDrawingArea->get_accessible_name(); } - void grab_add() { m_pDrawingArea->grab_add(); } - void grab_remove() { m_pDrawingArea->grab_remove(); } + void CaptureMouse() { m_pDrawingArea->grab_add(); } + bool IsMouseCaptured() const { return m_pDrawingArea->has_grab(); } + void EnableRTL(bool bEnable) { m_pDrawingArea->set_direction(bEnable); } + void ReleaseMouse() { m_pDrawingArea->grab_remove(); } void set_size_request(int nWidth, int nHeight) { m_pDrawingArea->set_size_request(nWidth, nHeight); diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index 963a7e509ebf..b890bf197498 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -94,10 +94,12 @@ public: } virtual void grab_add() = 0; + virtual bool has_grab() const = 0; virtual void grab_remove() = 0; //true for rtl, false otherwise virtual bool get_direction() const = 0; + virtual void set_direction(bool bRTL) = 0; virtual Container* weld_parent() const = 0; @@ -833,6 +835,8 @@ public: virtual void queue_resize() = 0; virtual a11yref get_accessible_parent() = 0; virtual a11yrelationset get_accessible_relation_set() = 0; + // use return here just to generate matching VirtualDevices + virtual OutputDevice& get_ref_device() = 0; }; class VCL_DLLPUBLIC Menu diff --git a/svx/source/dialog/charmap.cxx b/svx/source/dialog/charmap.cxx index 0288524a6466..8b568d80269a 100644 --- a/svx/source/dialog/charmap.cxx +++ b/svx/source/dialog/charmap.cxx @@ -124,7 +124,7 @@ void SvxShowCharSet::MouseButtonDown(const MouseEvent& rMEvt) { GrabFocus(); bDrag = true; - grab_add(); + CaptureMouse(); int nIndex = PixelToMapIndex( rMEvt.GetPosPixel() ); // Fire the focus event @@ -153,7 +153,7 @@ void SvxShowCharSet::MouseButtonUp(const MouseEvent& rMEvt) // released mouse over character map if ( tools::Rectangle(Point(), GetOutputSizePixel()).IsInside(rMEvt.GetPosPixel())) aSelectHdl.Call( this ); - grab_remove(); + ReleaseMouse(); bDrag = false; } } diff --git a/svx/source/dialog/dialcontrol.cxx b/svx/source/dialog/dialcontrol.cxx index 874d280abefb..e62fe137dcbf 100644 --- a/svx/source/dialog/dialcontrol.cxx +++ b/svx/source/dialog/dialcontrol.cxx @@ -31,12 +31,12 @@ namespace svx { const long DIAL_OUTER_WIDTH = 8; -DialControlBmp::DialControlBmp(vcl::Window& rParent) : - VirtualDevice(rParent, DeviceFormat::DEFAULT, DeviceFormat::DEFAULT), - mbEnabled(true), - mrParent(rParent), - mnCenterX(0), - mnCenterY(0) +DialControlBmp::DialControlBmp(OutputDevice& rReference) + : VirtualDevice(rReference, DeviceFormat::DEFAULT, DeviceFormat::DEFAULT) + , mbEnabled(true) + , mrParent(rReference) + , mnCenterX(0) + , mnCenterY(0) { EnableRTL(false); } @@ -507,6 +507,270 @@ void DialControl::HandleEscapeEvent() } } +SvxDialControl::DialControl_Impl::DialControl_Impl(OutputDevice& rReference) : + mxBmpEnabled(VclPtr<DialControlBmp>::Create(rReference)), + mxBmpDisabled(VclPtr<DialControlBmp>::Create(rReference)), + mxBmpBuffered(VclPtr<DialControlBmp>::Create(rReference)), + mpLinkField( nullptr ), + mnLinkedFieldValueMultiplyer( 0 ), + mnAngle( 0 ), + mnInitialAngle( 0 ), + mnOldAngle( 0 ), + mnCenterX( 0 ), + mnCenterY( 0 ), + mbNoRot( false ) +{ +} + +void SvxDialControl::DialControl_Impl::Init( const Size& rWinSize, const vcl::Font& rWinFont ) +{ + maWinFont = rWinFont; + maWinFont.SetTransparent(true); + mxBmpBuffered->InitBitmap(maWinFont); + SetSize(rWinSize); +} + +void SvxDialControl::DialControl_Impl::SetSize( const Size& rWinSize ) +{ + // make the control squared, and adjusted so that we have a well-defined + // center ["(x - 1) | 1" creates odd value <= x] + long nMin = (std::min(rWinSize.Width(), rWinSize.Height()) - 1) | 1; + + maWinSize = Size( nMin, nMin ); + + mnCenterX = maWinSize.Width() / 2; + mnCenterY = maWinSize.Height() / 2; + + mxBmpEnabled->DrawBackground( maWinSize, true ); + mxBmpDisabled->DrawBackground( maWinSize, false ); + mxBmpBuffered->SetSize( maWinSize ); +} + +void SvxDialControl::SetDrawingArea(weld::DrawingArea* pDrawingArea) +{ + //use same logic as DialControl_Impl::SetSize + int nDim = (std::min<int>(pDrawingArea->get_approximate_digit_width() * 12, + pDrawingArea->get_text_height() * 6) - 1) | 1; + pDrawingArea->set_size_request(nDim, nDim); + CustomWidgetController::SetDrawingArea(pDrawingArea); + mpImpl.reset(new DialControl_Impl(pDrawingArea->get_ref_device())); + //set size and use that + Init(GetOutputSizePixel()); +} + +void SvxDialControl::Resize() +{ + mpImpl->SetSize(GetOutputSizePixel()); + InvalidateControl(); +} + +void SvxDialControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) +{ + Point aPos; + rRenderContext.SetBackground(); + rRenderContext.Erase(); + rRenderContext.DrawBitmapEx(aPos, mpImpl->mxBmpBuffered->GetBitmapEx(aPos, mpImpl->maWinSize)); +} + +void SvxDialControl::StyleUpdated() +{ + CustomWidgetController::StyleUpdated(); + Init( mpImpl->maWinSize, mpImpl->maWinFont ); + InvalidateControl(); +} + +void SvxDialControl::MouseButtonDown(const MouseEvent& rMEvt) +{ + if( rMEvt.IsLeft() ) + { + GrabFocus(); + CaptureMouse(); + mpImpl->mnOldAngle = mpImpl->mnAngle; + HandleMouseEvent( rMEvt.GetPosPixel(), true ); + } +} + +void SvxDialControl::MouseMove( const MouseEvent& rMEvt ) +{ + if( IsMouseCaptured() && rMEvt.IsLeft() ) + HandleMouseEvent( rMEvt.GetPosPixel(), false ); +} + +void SvxDialControl::MouseButtonUp(const MouseEvent&) +{ + if( IsMouseCaptured() ) + { + ReleaseMouse(); + if( mpImpl->mpLinkField ) + mpImpl->mpLinkField->grab_focus(); + } +} + +bool SvxDialControl::KeyInput( const KeyEvent& rKEvt ) +{ + const vcl::KeyCode& rKCode = rKEvt.GetKeyCode(); + if( !rKCode.GetModifier() && (rKCode.GetCode() == KEY_ESCAPE) ) + { + HandleEscapeEvent(); + return true; + } + return CustomWidgetController::KeyInput(rKEvt); +} + +void SvxDialControl::LoseFocus() +{ + // release captured mouse + HandleEscapeEvent(); +} + +bool SvxDialControl::HasRotation() const +{ + return !mpImpl->mbNoRot; +} + +void SvxDialControl::SetNoRotation() +{ + if( !mpImpl->mbNoRot ) + { + mpImpl->mbNoRot = true; + InvalidateControl(); + if( mpImpl->mpLinkField ) + mpImpl->mpLinkField->set_text(""); + } +} + +sal_Int32 SvxDialControl::GetRotation() const +{ + return mpImpl->mnAngle; +} + +void SvxDialControl::SetRotation( sal_Int32 nAngle ) +{ + SetRotation( nAngle, false ); +} + +void SvxDialControl::SetLinkedField(weld::SpinButton* pField, sal_Int32 nDecimalPlaces) +{ + mpImpl->mnLinkedFieldValueMultiplyer = 100 / std::pow(10.0, double(nDecimalPlaces)); + + // remove modify handler from old linked field + if( mpImpl->mpLinkField ) + { + weld::SpinButton& rField = *mpImpl->mpLinkField; + rField.connect_value_changed(Link<weld::SpinButton&,void>()); + } + // remember the new linked field + mpImpl->mpLinkField = pField; + // set modify handler at new linked field + if( mpImpl->mpLinkField ) + { + weld::SpinButton& rField = *mpImpl->mpLinkField; + rField.connect_value_changed(LINK(this, SvxDialControl, LinkedFieldModifyHdl)); + } +} + +IMPL_LINK_NOARG(SvxDialControl, LinkedFieldModifyHdl, weld::SpinButton&, void) +{ + LinkedFieldModifyHdl(); +} + +void SvxDialControl::LinkedFieldModifyHdl() +{ + if( mpImpl->mpLinkField ) + SetRotation(mpImpl->mpLinkField->get_value() * mpImpl->mnLinkedFieldValueMultiplyer, false); +} + + +void SvxDialControl::SaveValue() +{ + mpImpl->mnInitialAngle = mpImpl->mnAngle; +} + +bool SvxDialControl::IsValueModified() +{ + return mpImpl->mnInitialAngle != mpImpl->mnAngle; +} + +void SvxDialControl::SetModifyHdl( const Link<SvxDialControl*,void>& rLink ) +{ + mpImpl->maModifyHdl = rLink; +} + +void SvxDialControl::Init( const Size& rWinSize, const vcl::Font& rWinFont ) +{ + mpImpl->Init( rWinSize, rWinFont ); + EnableRTL( false ); // don't mirror mouse handling + SetOutputSizePixel( mpImpl->maWinSize ); +} + +void SvxDialControl::Init( const Size& rWinSize ) +{ + //hidpi TODO: GetDefaultFont() picks a font size too small, so fix it here. + vcl::Font aDefaultSize = Application::GetSettings().GetStyleSettings().GetLabelFont(); + + vcl::Font aFont( OutputDevice::GetDefaultFont( + DefaultFontType::UI_SANS, Application::GetSettings().GetUILanguageTag().getLanguageType(), GetDefaultFontFlags::OnlyOne ) ); + + aFont.SetFontHeight(aDefaultSize.GetFontHeight()); + Init( rWinSize, aFont ); +} + +void SvxDialControl::InvalidateControl() +{ + mpImpl->mxBmpBuffered->CopyBackground( IsEnabled() ? *mpImpl->mxBmpEnabled : *mpImpl->mxBmpDisabled ); + if( !mpImpl->mbNoRot ) + mpImpl->mxBmpBuffered->DrawElements( GetText(), mpImpl->mnAngle ); + Invalidate(); +} + +void SvxDialControl::SetRotation( sal_Int32 nAngle, bool bBroadcast ) +{ + bool bOldSel = mpImpl->mbNoRot; + mpImpl->mbNoRot = false; + + while( nAngle < 0 ) + nAngle += 36000; + + if( !bOldSel || (mpImpl->mnAngle != nAngle) ) + { + mpImpl->mnAngle = nAngle; + InvalidateControl(); + if( mpImpl->mpLinkField ) + mpImpl->mpLinkField->set_value(GetRotation() / mpImpl->mnLinkedFieldValueMultiplyer); + if( bBroadcast ) + mpImpl->maModifyHdl.Call( this ); + } +} + +void SvxDialControl::HandleMouseEvent( const Point& rPos, bool bInitial ) +{ + long nX = rPos.X() - mpImpl->mnCenterX; + long nY = mpImpl->mnCenterY - rPos.Y(); + double fH = sqrt( static_cast< double >( nX ) * nX + static_cast< double >( nY ) * nY ); + if( fH != 0.0 ) + { + double fAngle = acos( nX / fH ); + sal_Int32 nAngle = static_cast< sal_Int32 >( fAngle / F_PI180 * 100.0 ); + if( nY < 0 ) + nAngle = 36000 - nAngle; + if( bInitial ) // round to entire 15 degrees + nAngle = ((nAngle + 750) / 1500) * 1500; + // Round up to 1 degree + nAngle = (((nAngle + 50) / 100) * 100) % 36000; + SetRotation( nAngle, true ); + } +} + +void SvxDialControl::HandleEscapeEvent() +{ + if( IsMouseCaptured() ) + { + ReleaseMouse(); + SetRotation( mpImpl->mnOldAngle, true ); + if( mpImpl->mpLinkField ) + mpImpl->mpLinkField->grab_focus(); + } +} DialControlWrapper::DialControlWrapper( DialControl& rDial ) : SingleControlWrapperType( rDial ) @@ -534,7 +798,6 @@ void DialControlWrapper::SetControlValue( sal_Int32 nValue ) GetControl().SetRotation( nValue ); } - } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 1579aae20222..f587569adca5 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -368,6 +368,11 @@ public: m_xWidget->CaptureMouse(); } + virtual bool has_grab() const override + { + return m_xWidget->IsMouseCaptured(); + } + virtual void grab_remove() override { m_xWidget->ReleaseMouse(); @@ -378,6 +383,11 @@ public: return m_xWidget->IsRTLEnabled(); } + virtual void set_direction(bool bRTL) override + { + m_xWidget->EnableRTL(bRTL); + } + virtual weld::Container* weld_parent() const override; virtual ~SalInstanceWidget() override @@ -1831,6 +1841,11 @@ public: m_xDrawingArea->SetResizeHdl(Link<const Size&, void>()); m_xDrawingArea->SetPaintHdl(Link<std::pair<vcl::RenderContext&, const tools::Rectangle&>, void>()); } + + virtual OutputDevice& get_ref_device() override + { + return *m_xDrawingArea; + } }; IMPL_LINK(SalInstanceDrawingArea, PaintHdl, target_and_area, aPayload, void) diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index 9fecb7981593..9a1d58098e74 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -1430,6 +1430,11 @@ public: gtk_grab_add(m_pWidget); } + virtual bool has_grab() const override + { + return gtk_widget_has_grab(m_pWidget); + } + virtual void grab_remove() override { gtk_grab_remove(m_pWidget); @@ -1440,6 +1445,11 @@ public: return gtk_widget_get_direction(m_pWidget) == GTK_TEXT_DIR_RTL; } + virtual void set_direction(bool bRTL) override + { + gtk_widget_set_direction(m_pWidget, bRTL ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); + } + virtual ~GtkInstanceWidget() override { if (m_nFocusInSignalId) @@ -3919,6 +3929,11 @@ public: g_signal_handler_disconnect(m_pDrawingArea, m_nSizeAllocateSignalId); g_signal_handler_disconnect(m_pDrawingArea, m_nDrawSignalId); } + + virtual OutputDevice& get_ref_device() override + { + return *m_xDevice; + } }; namespace _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits