framework/source/uielement/generictoolbarcontroller.cxx | 14 ++++++ include/framework/generictoolbarcontroller.hxx | 1 include/vcl/weld.hxx | 1 sfx2/source/toolbox/weldutils.cxx | 7 +-- vcl/inc/salvtables.hxx | 2 vcl/source/app/salvtables.cxx | 6 ++ vcl/source/window/toolbox2.cxx | 13 ------ vcl/unx/gtk3/gtkinst.cxx | 33 ++++++++++++---- 8 files changed, 53 insertions(+), 24 deletions(-)
New commits: commit 4fb8c0d14cb2468f7336438004f699b9eb7e7e4a Author: Maxim Monastirsky <momonas...@gmail.com> AuthorDate: Fri Jul 29 00:36:18 2022 +0300 Commit: Maxim Monastirsky <momonas...@gmail.com> CommitDate: Tue Aug 30 13:08:03 2022 +0200 tdf#149741 tdf#149956 Make flipping work also in the sidebar - Reset the icon each time, as there seems to be no easy way to retrieve the existing icon from a gtk widget in order to mirror it, like we used to do for vcl. Similar approach is currently taken in ToolboxButtonColorUpdaterBase::Update. - Store the flipping state also in GtkInstanceToolbar, similar to vcl's ToolBox. This seems to be the easiest way to make flipping not break on icon theme change, covering all 4 cases (ToolBarManager, SidebarToolBox, ToolbarUnoDispatcher, GenericToolbarController), w/o too involved changes in each. This might benefit from some refactoring later on, but should be good enough for now. - One unsolved problem is the appearance of flipped icons with svg themes, as the regular variant is handed to gtk directly, whereas the flipped one is loaded by us, resulting with a different (blurry) look. Change-Id: I48c16827b46fb75fd798a041851af6e2648ae8fe Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139021 Tested-by: Jenkins Reviewed-by: Maxim Monastirsky <momonas...@gmail.com> diff --git a/framework/source/uielement/generictoolbarcontroller.cxx b/framework/source/uielement/generictoolbarcontroller.cxx index e8e49cb30933..312b5ed9e77f 100644 --- a/framework/source/uielement/generictoolbarcontroller.cxx +++ b/framework/source/uielement/generictoolbarcontroller.cxx @@ -91,6 +91,7 @@ GenericToolbarController::GenericToolbarController( const Reference< XComponentC , m_xToolbar( pToolbar ) , m_nID( nID ) , m_bEnumCommand( isEnumCommand( aCommand )) + , m_bMirrored( false ) , m_bMadeInvisible( false ) , m_aEnumCommand( getEnumCommand( aCommand )) { @@ -189,6 +190,7 @@ void GenericToolbarController::statusChanged( const FeatureStateEvent& Event ) bool bValue; OUString aStrValue; + SfxImageItem aImageItem; if ( Event.State >>= bValue ) { @@ -199,6 +201,13 @@ void GenericToolbarController::statusChanged( const FeatureStateEvent& Event ) { m_pToolbar->set_item_label(sId, aStrValue); } + else if ( aImageItem.PutValue( Event.State, 0 ) && aImageItem.IsMirrored() != m_bMirrored ) + { + m_pToolbar->set_item_image_mirrored(sId, aImageItem.IsMirrored()); + auto xGraphic(vcl::CommandInfoProvider::GetXGraphicForCommand(m_aCommandURL, m_xFrame, m_pToolbar->get_icon_size())); + m_pToolbar->set_item_image(sId, xGraphic); + m_bMirrored = !m_bMirrored; + } else m_pToolbar->set_item_active(sId, false); @@ -295,9 +304,12 @@ void GenericToolbarController::statusChanged( const FeatureStateEvent& Event ) if ( m_bMadeInvisible ) m_xToolbar->ShowItem( m_nID ); } - else if ( aImageItem.PutValue( Event.State, 0 ) ) + else if ( aImageItem.PutValue( Event.State, 0 ) && aImageItem.IsMirrored() != m_bMirrored ) { m_xToolbar->SetItemImageMirrorMode( m_nID, aImageItem.IsMirrored() ); + Image aImage( vcl::CommandInfoProvider::GetImageForCommand( m_aCommandURL, m_xFrame, m_xToolbar->GetImageSize() )); + m_xToolbar->SetItemImage( m_nID, aImage ); + m_bMirrored = !m_bMirrored; if ( m_bMadeInvisible ) m_xToolbar->ShowItem( m_nID ); } diff --git a/include/framework/generictoolbarcontroller.hxx b/include/framework/generictoolbarcontroller.hxx index e177ea5f00a9..473941a7682a 100644 --- a/include/framework/generictoolbarcontroller.hxx +++ b/include/framework/generictoolbarcontroller.hxx @@ -64,6 +64,7 @@ class FWK_DLLPUBLIC GenericToolbarController final : public svt::ToolboxControll VclPtr<ToolBox> m_xToolbar; ToolBoxItemId m_nID; bool m_bEnumCommand : 1, + m_bMirrored : 1, m_bMadeInvisible : 1; OUString m_aEnumCommand; }; diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index b3bbe60a7390..adbd35d85df6 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -2461,6 +2461,7 @@ public: virtual void set_item_tooltip_text(const OString& rIdent, const OUString& rTip) = 0; virtual OUString get_item_tooltip_text(const OString& rIdent) const = 0; virtual void set_item_icon_name(const OString& rIdent, const OUString& rIconName) = 0; + virtual void set_item_image_mirrored(const OString& rIdent, bool bMirrored) = 0; virtual void set_item_image(const OString& rIdent, const css::uno::Reference<css::graphic::XGraphic>& rIcon) = 0; diff --git a/sfx2/source/toolbox/weldutils.cxx b/sfx2/source/toolbox/weldutils.cxx index 5c1f1c58fa4f..25b173de633f 100644 --- a/sfx2/source/toolbox/weldutils.cxx +++ b/sfx2/source/toolbox/weldutils.cxx @@ -158,9 +158,10 @@ IMPL_LINK_NOARG(ToolbarUnoDispatcher, ChangedIconSizeHandler, LinkParamNone*, vo for (int i = 0, nItems = m_pToolbar->get_n_items(); i < nItems; ++i) { - OUString sCommand = OUString::fromUtf8(m_pToolbar->get_item_ident(i)); - auto xImage(vcl::CommandInfoProvider::GetXGraphicForCommand(sCommand, m_xFrame, eSize)); - m_pToolbar->set_item_image(i, xImage); + OString sIdent(m_pToolbar->get_item_ident(i)); + auto xImage(vcl::CommandInfoProvider::GetXGraphicForCommand(OUString::fromUtf8(sIdent), + m_xFrame, eSize)); + m_pToolbar->set_item_image(sIdent, xImage); } for (auto const& it : maControllers) diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 642eabd49990..ed6e35d6e48f 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -1259,6 +1259,8 @@ public: virtual void set_item_icon_name(const OString& rIdent, const OUString& rIconName) override; + virtual void set_item_image_mirrored(const OString& rIdent, bool bMirrored) override; + virtual void set_item_image(const OString& rIdent, const css::uno::Reference<css::graphic::XGraphic>& rIcon) override; diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 3874e76ab79d..74327b0bf72e 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -1153,6 +1153,12 @@ void SalInstanceToolbar::set_item_icon_name(const OString& rIdent, const OUStrin Image(StockImage::Yes, rIconName)); } +void SalInstanceToolbar::set_item_image_mirrored(const OString& rIdent, bool bMirrored) +{ + m_xToolBox->SetItemImageMirrorMode(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), + bMirrored); +} + void SalInstanceToolbar::set_item_image(const OString& rIdent, const css::uno::Reference<css::graphic::XGraphic>& rIcon) { diff --git a/vcl/source/window/toolbox2.cxx b/vcl/source/window/toolbox2.cxx index fe50d399a5a8..701d77624d90 100644 --- a/vcl/source/window/toolbox2.cxx +++ b/vcl/source/window/toolbox2.cxx @@ -1025,18 +1025,7 @@ void ToolBox::SetItemImageMirrorMode( ToolBoxItemId nItemId, bool bMirror ) return; ImplToolItem* pItem = &mpData->m_aItems[nPos]; - - if (pItem->mbMirrorMode != bMirror) - { - pItem->mbMirrorMode = bMirror; - if (!!pItem->maImage) - { - pItem->maImage = ImplMirrorImage(pItem->maImage); - } - - if (!mbCalc) - ImplUpdateItem(nPos); - } + pItem->mbMirrorMode = bMirror; } Image ToolBox::GetItemImage(ToolBoxItemId nItemId) const diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 1eb056936a41..19372ab78446 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -4801,9 +4801,18 @@ GdkPixbuf* load_icon_by_name(const OUString& rIconName) namespace { - GdkPixbuf* getPixbuf(const css::uno::Reference<css::graphic::XGraphic>& rImage) + Image mirrorImage(const Image& rImage) + { + BitmapEx aMirrBitmapEx(rImage.GetBitmapEx()); + aMirrBitmapEx.Mirror(BmpMirrorFlags::Horizontal); + return Image(aMirrBitmapEx); + } + + GdkPixbuf* getPixbuf(const css::uno::Reference<css::graphic::XGraphic>& rImage, bool bMirror = false) { Image aImage(rImage); + if (bMirror) + aImage = mirrorImage(aImage); OUString sStock(aImage.GetStock()); if (!sStock.isEmpty()) @@ -11649,6 +11658,7 @@ private: std::map<OString, GtkWidget*> m_aMap; std::map<OString, std::unique_ptr<GtkInstanceMenuButton>> m_aMenuButtonMap; + std::map<OString, bool> m_aMirroredMap; #if !GTK_CHECK_VERSION(4, 0, 0) // at the time of writing there is no gtk_menu_tool_button_set_popover available @@ -11813,14 +11823,14 @@ private: #endif #if !GTK_CHECK_VERSION(4, 0, 0) - static void set_item_image(GtkToolButton* pItem, const css::uno::Reference<css::graphic::XGraphic>& rIcon) + static void set_item_image(GtkToolButton* pItem, const css::uno::Reference<css::graphic::XGraphic>& rIcon, bool bMirror) #else - static void set_item_image(GtkWidget* pItem, const css::uno::Reference<css::graphic::XGraphic>& rIcon) + static void set_item_image(GtkWidget* pItem, const css::uno::Reference<css::graphic::XGraphic>& rIcon, bool bMirror) #endif { GtkWidget* pImage = nullptr; - if (GdkPixbuf* pixbuf = getPixbuf(rIcon)) + if (GdkPixbuf* pixbuf = getPixbuf(rIcon, bMirror)) { pImage = gtk_image_new_from_pixbuf(pixbuf); g_object_unref(pixbuf); @@ -12194,17 +12204,24 @@ public: #endif } + virtual void set_item_image_mirrored(const OString& rIdent, bool bMirrored) override + { + m_aMirroredMap[rIdent] = bMirrored; + } + virtual void set_item_image(const OString& rIdent, const css::uno::Reference<css::graphic::XGraphic>& rIcon) override { GtkWidget* pItem = m_aMap[rIdent]; + auto it = m_aMirroredMap.find(rIdent); + bool bMirrored = it != m_aMirroredMap.end() && it->second; #if !GTK_CHECK_VERSION(4, 0, 0) if (!pItem || !GTK_IS_TOOL_BUTTON(pItem)) return; - set_item_image(GTK_TOOL_BUTTON(pItem), rIcon); + set_item_image(GTK_TOOL_BUTTON(pItem), rIcon, bMirrored); #else if (!pItem) return; - set_item_image(pItem, rIcon); + set_item_image(pItem, rIcon, bMirrored); #endif } @@ -12228,9 +12245,9 @@ public: #if !GTK_CHECK_VERSION(4, 0, 0) if (!GTK_IS_TOOL_BUTTON(pItem)) return; - set_item_image(GTK_TOOL_BUTTON(pItem), rIcon); + set_item_image(GTK_TOOL_BUTTON(pItem), rIcon, false); #else - set_item_image(pItem, rIcon); + set_item_image(pItem, rIcon, false); #endif }