diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-12-03 17:15:06 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-12-03 21:29:46 +0100 |
commit | 9b12f2fe15403ab0a82abd11ba14dae4a70774a6 (patch) | |
tree | 31464a5eef3a9a354cd7faffc46f616d5ba9c235 /vcl | |
parent | 95ae027d5e331847d6ac695d11c299f2ca0e4ca1 (diff) |
support completely styling a welded button
Change-Id: I6e45c711b406a3836dd230ceaa738c5a250ff846
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107173
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/salvtables.hxx | 2 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 9 | ||||
-rw-r--r-- | vcl/source/control/button.cxx | 24 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 44 |
4 files changed, 78 insertions, 1 deletions
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 9fe7a6a5dac5..2fd7198a7b65 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -1007,6 +1007,8 @@ public: virtual void set_font(const vcl::Font& rFont) override; + virtual void set_custom_button(VirtualDevice* pDevice) override; + virtual ~SalInstanceButton() override; }; diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 0daf586ebb89..ccc3757e6718 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -2488,6 +2488,15 @@ void SalInstanceButton::set_font(const vcl::Font& rFont) m_xButton->Invalidate(); } +void SalInstanceButton::set_custom_button(VirtualDevice* pDevice) +{ + if (pDevice) + m_xButton->SetCustomButtonImage(createImage(*pDevice)); + else + m_xButton->SetCustomButtonImage(Image()); + m_xButton->Invalidate(); +} + OUString SalInstanceButton::get_label() const { return m_xButton->GetText(); } SalInstanceButton::~SalInstanceButton() { m_xButton->SetClickHdl(Link<::Button*, void>()); } diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx index 66a399c15bbc..38b32d4f54af 100644 --- a/vcl/source/control/button.cxx +++ b/vcl/source/control/button.cxx @@ -83,12 +83,14 @@ public: ImageAlign meImageAlign; SymbolAlign meSymbolAlign; + Image maCustomContentImage; + /** StatusListener. Updates the button as the slot state changes */ rtl::Reference<VclStatusListener<Button>> mpStatusListener; }; ImplCommonButtonData::ImplCommonButtonData() : maFocusRect(), mnSeparatorX(0), mnButtonState(DrawButtonFlags::NONE), -mbSmallSymbol(false), maImage(), meImageAlign(ImageAlign::Top), meSymbolAlign(SymbolAlign::LEFT) +mbSmallSymbol(false), maImage(), meImageAlign(ImageAlign::Top), meSymbolAlign(SymbolAlign::LEFT), maCustomContentImage() { } @@ -158,6 +160,20 @@ ImageAlign Button::GetImageAlign() const return mpButtonData->meImageAlign; } +void Button::SetCustomButtonImage(const Image& rImage) +{ + if (rImage != mpButtonData->maCustomContentImage) + { + mpButtonData->maCustomContentImage = rImage; + StateChanged( StateChangedType::Data ); + } +} + +Image const & Button::GetCustomButtonImage() const +{ + return mpButtonData->maCustomContentImage; +} + tools::Long Button::ImplGetSeparatorX() const { return mpButtonData->mnSeparatorX; @@ -1294,6 +1310,12 @@ void PushButton::FillLayoutData() const void PushButton::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) { + const Image& rCustomButtonImage = GetCustomButtonImage(); + if (!!rCustomButtonImage) + { + rRenderContext.DrawImage(Point(0, 0), rCustomButtonImage); + return; + } ImplDrawPushButton(rRenderContext); } diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index 1863076ddfcf..c4df0cca2855 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -6815,8 +6815,10 @@ class GtkInstanceButton : public GtkInstanceContainer, public virtual weld::Butt { private: GtkButton* m_pButton; + GtkCssProvider* m_pCustomCssProvider; gulong m_nSignalId; std::unique_ptr<vcl::Font> m_xFont; + std::unique_ptr<utl::TempFile> m_xCustomImage; static void signalClicked(GtkButton*, gpointer widget) { @@ -6856,6 +6858,39 @@ private: return pChild; } + // See: https://developer.gnome.org/Buttons/ + void use_custom_content(VirtualDevice* pDevice) + { + GtkStyleContext *pWidgetContext = gtk_widget_get_style_context(GTK_WIDGET(m_pButton)); + + if (m_pCustomCssProvider) + { + gtk_style_context_remove_provider(pWidgetContext, GTK_STYLE_PROVIDER(m_pCustomCssProvider)); + m_pCustomCssProvider = nullptr; + } + + m_xCustomImage.reset(); + + if (!pDevice) + return; + + m_xCustomImage.reset(new utl::TempFile); + m_xCustomImage->EnableKillingFile(true); + + cairo_surface_t* surface = get_underlying_cairo_surface(*pDevice); + Size aSize = pDevice->GetOutputSizePixel(); + cairo_surface_write_to_png(surface, OUStringToOString(m_xCustomImage->GetFileName(), osl_getThreadTextEncoding()).getStr()); + + m_pCustomCssProvider = gtk_css_provider_new(); + OUString aBuffer = "* { background-image: url(\"" + m_xCustomImage->GetURL() + "\"); " + "background-size: " + OUString::number(aSize.Width()) + "px " + OUString::number(aSize.Height()) + "px; " + "border-radius: 0; border-width: 0; }"; + OString aResult = OUStringToOString(aBuffer, RTL_TEXTENCODING_UTF8); + gtk_css_provider_load_from_data(m_pCustomCssProvider, aResult.getStr(), aResult.getLength(), nullptr); + gtk_style_context_add_provider(pWidgetContext, GTK_STYLE_PROVIDER(m_pCustomCssProvider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + } + protected: GtkWidget* get_label_widget() { @@ -6875,6 +6910,7 @@ public: GtkInstanceButton(GtkButton* pButton, GtkInstanceBuilder* pBuilder, bool bTakeOwnership) : GtkInstanceContainer(GTK_CONTAINER(pButton), pBuilder, bTakeOwnership) , m_pButton(pButton) + , m_pCustomCssProvider(nullptr) , m_nSignalId(g_signal_connect(pButton, "clicked", G_CALLBACK(signalClicked), this)) { g_object_set_data(G_OBJECT(m_pButton), "g-lo-GtkInstanceButton", this); @@ -6919,6 +6955,11 @@ public: } } + virtual void set_custom_button(VirtualDevice* pDevice) override + { + use_custom_content(pDevice); + } + virtual OUString get_label() const override { return ::get_label(m_pButton); @@ -6971,6 +7012,9 @@ public: { g_object_steal_data(G_OBJECT(m_pButton), "g-lo-GtkInstanceButton"); g_signal_handler_disconnect(m_pButton, m_nSignalId); + if (m_pCustomCssProvider) + use_custom_content(nullptr); + assert(!m_pCustomCssProvider); } }; |