diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-05-07 12:27:43 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-05-11 18:34:23 +0200 |
commit | 492b0d5d076d38234fea4e4e7c5dbec578296fd2 (patch) | |
tree | 47b4a17120d7d3c71bf7674b45768f38b761e360 /vcl | |
parent | acd290431fd39ed0602e057e036326b46a99f7a8 (diff) |
weld conditional formatting
Change-Id: Ia9c99a17d5a95d67a412cfde959192c99caa70be
Reviewed-on: https://gerrit.libreoffice.org/71956
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/source/app/salvtables.cxx | 110 | ||||
-rw-r--r-- | vcl/source/window/stacking.cxx | 2 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 160 |
3 files changed, 219 insertions, 53 deletions
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 390305ad0b60..16cdc0d37a5f 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -245,11 +245,13 @@ protected: private: DECL_LINK(EventListener, VclWindowEvent&, void); DECL_LINK(KeyEventListener, VclWindowEvent&, bool); + DECL_LINK(MouseEventListener, VclSimpleEvent&, void); DECL_LINK(MnemonicActivateHdl, vcl::Window&, bool); const bool m_bTakeOwnership; bool m_bEventListener; bool m_bKeyEventListener; + bool m_bMouseEventListener; int m_nBlockNotify; protected: @@ -274,8 +276,20 @@ protected: } } + // we want the ability to know about mouse events that happen in our children + // so use this variant, we will need to filter them later + void ensure_mouse_listener() + { + if (!m_bMouseEventListener) + { + Application::AddEventListener(LINK(this, SalInstanceWidget, MouseEventListener)); + m_bMouseEventListener = true; + } + } + virtual void HandleEventListener(VclWindowEvent& rEvent); virtual bool HandleKeyEventListener(VclWindowEvent& rEvent); + virtual void HandleMouseEventListener(VclSimpleEvent& rEvent); public: SalInstanceWidget(vcl::Window* pWidget, SalInstanceBuilder* pBuilder, bool bTakeOwnership) @@ -283,7 +297,7 @@ public: , m_pBuilder(pBuilder) , m_bTakeOwnership(bTakeOwnership) , m_bEventListener(false) - , m_bKeyEventListener(false) + , m_bMouseEventListener(false) , m_nBlockNotify(0) { } @@ -529,19 +543,19 @@ public: virtual void connect_mouse_press(const Link<const MouseEvent&, bool>& rLink) override { - ensure_event_listener(); + ensure_mouse_listener(); weld::Widget::connect_mouse_press(rLink); } virtual void connect_mouse_move(const Link<const MouseEvent&, bool>& rLink) override { - ensure_event_listener(); + ensure_mouse_listener(); weld::Widget::connect_mouse_move(rLink); } virtual void connect_mouse_release(const Link<const MouseEvent&, bool>& rLink) override { - ensure_event_listener(); + ensure_mouse_listener(); weld::Widget::connect_mouse_release(rLink); } @@ -608,6 +622,8 @@ public: { if (m_aMnemonicActivateHdl.IsSet()) m_xWidget->SetMnemonicActivateHdl(Link<vcl::Window&,bool>()); + if (m_bMouseEventListener) + Application::RemoveEventListener(LINK(this, SalInstanceWidget, MouseEventListener)); if (m_bKeyEventListener) Application::RemoveKeyListener(LINK(this, SalInstanceWidget, KeyEventListener)); if (m_bEventListener) @@ -654,6 +670,15 @@ public: return m_xWidget->GetDropTarget(); } + virtual void set_stack_background() override + { + m_xWidget->SetControlBackground(m_xWidget->GetSettings().GetStyleSettings().GetWindowColor()); + m_xWidget->SetBackground(m_xWidget->GetControlBackground()); + // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under" + // transparent children of the widget + m_xWidget->SetStyle(m_xWidget->GetStyle() & ~WB_CLIPCHILDREN); + } + SystemWindow* getSystemWindow() { return m_xWidget->GetSystemWindow(); @@ -668,20 +693,36 @@ void SalInstanceWidget::HandleEventListener(VclWindowEvent& rEvent) m_aFocusOutHdl.Call(*this); else if (rEvent.GetId() == VclEventId::WindowResize) m_aSizeAllocateHdl.Call(m_xWidget->GetSizePixel()); - else if (rEvent.GetId() == VclEventId::WindowMouseButtonDown) +} + +void SalInstanceWidget::HandleMouseEventListener(VclSimpleEvent& rEvent) +{ + if (rEvent.GetId() == VclEventId::WindowMouseButtonDown) { - const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rEvent.GetData()); - m_aMousePressHdl.Call(*pMouseEvent); + auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent); + if (m_xWidget->IsWindowOrChild(rWinEvent.GetWindow())) + { + const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData()); + m_aMousePressHdl.Call(*pMouseEvent); + } } else if (rEvent.GetId() == VclEventId::WindowMouseButtonUp) { - const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rEvent.GetData()); - m_aMouseReleaseHdl.Call(*pMouseEvent); + auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent); + if (m_xWidget->IsWindowOrChild(rWinEvent.GetWindow())) + { + const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData()); + m_aMouseReleaseHdl.Call(*pMouseEvent); + } } else if (rEvent.GetId() == VclEventId::WindowMouseMove) { - const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rEvent.GetData()); - m_aMouseMotionHdl.Call(*pMouseEvent); + auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent); + if (m_xWidget->IsWindowOrChild(rWinEvent.GetWindow())) + { + const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData()); + m_aMouseMotionHdl.Call(*pMouseEvent); + } } } @@ -713,6 +754,11 @@ IMPL_LINK(SalInstanceWidget, KeyEventListener, VclWindowEvent&, rEvent, bool) return HandleKeyEventListener(rEvent); } +IMPL_LINK(SalInstanceWidget, MouseEventListener, VclSimpleEvent&, rEvent, void) +{ + HandleMouseEventListener(rEvent); +} + IMPL_LINK_NOARG(SalInstanceWidget, MnemonicActivateHdl, vcl::Window&, bool) { return m_aMnemonicActivateHdl.Call(*this); @@ -2331,15 +2377,24 @@ public: return !m_xEntry->IsReadOnly(); } - virtual void set_error(bool bError) override + virtual void set_message_type(weld::EntryMessageType eType) override { - if (bError) + if (eType == weld::EntryMessageType::Error) { - // #i75179# enable setting the background to a different color + // tdf#114603: enable setting the background to a different color; + // relevant for GTK; see also #i75179# m_xEntry->SetForceControlBackground(true); m_xEntry->SetControlForeground(COL_WHITE); m_xEntry->SetControlBackground(0xff6563); } + else if (eType == weld::EntryMessageType::Warning) + { + // tdf#114603: enable setting the background to a different color; + // relevant for GTK; see also #i75179# + m_xEntry->SetForceControlBackground(true); + m_xEntry->SetControlForeground(); + m_xEntry->SetControlBackground(COL_YELLOW); + } else { m_xEntry->SetForceControlBackground(false); @@ -3904,10 +3959,12 @@ public: pLabel->set_mnemonic_widget(pTargetWidget ? pTargetWidget->getWidget() : nullptr); } - virtual void set_error(bool bShowError) override + virtual void set_message_type(weld::EntryMessageType eType) override { - if (bShowError) + if (eType == weld::EntryMessageType::Error) m_xLabel->SetControlBackground(m_xLabel->GetSettings().GetStyleSettings().GetHighlightColor()); + else if (eType == weld::EntryMessageType::Warning) + m_xLabel->SetControlBackground(COL_YELLOW); else m_xLabel->SetControlBackground(); } @@ -4127,16 +4184,23 @@ private: // in VclDrawingArea virtual void HandleEventListener(VclWindowEvent& rEvent) override { - if (rEvent.GetId() == VclEventId::WindowResize || - rEvent.GetId() == VclEventId::WindowMouseButtonDown || + if (rEvent.GetId() == VclEventId::WindowResize) + return; + SalInstanceWidget::HandleEventListener(rEvent); + } + + virtual void HandleMouseEventListener(VclSimpleEvent& rEvent) override + { + if (rEvent.GetId() == VclEventId::WindowMouseButtonDown || rEvent.GetId() == VclEventId::WindowMouseButtonUp || rEvent.GetId() == VclEventId::WindowMouseMove) { return; } - SalInstanceWidget::HandleEventListener(rEvent); + SalInstanceWidget::HandleMouseEventListener(rEvent); } + virtual bool HandleKeyEventListener(VclWindowEvent& /*rEvent*/) override { return false; @@ -4520,7 +4584,7 @@ public: return false; } - virtual void set_entry_error(bool /*bError*/) override + virtual void set_entry_message_type(weld::EntryMessageType /*eType*/) override { assert(false); } @@ -4588,10 +4652,12 @@ public: return true; } - virtual void set_entry_error(bool bError) override + virtual void set_entry_message_type(weld::EntryMessageType eType) override { - if (bError) + if (eType == weld::EntryMessageType::Error) m_xComboBox->SetControlForeground(Color(0xf0, 0, 0)); + else if (eType == weld::EntryMessageType::Warning) + m_xComboBox->SetControlForeground(COL_YELLOW); else m_xComboBox->SetControlForeground(); } diff --git a/vcl/source/window/stacking.cxx b/vcl/source/window/stacking.cxx index d00ad9f9b5ef..4c01b7e94e9d 100644 --- a/vcl/source/window/stacking.cxx +++ b/vcl/source/window/stacking.cxx @@ -838,7 +838,7 @@ static SystemWindow *ImplGetLastSystemWindow( vcl::Window *pWin ) void Window::SetParent( vcl::Window* pNewParent ) { - SAL_WARN_IF( !pNewParent, "vcl", "Window::SetParent(): pParent == NULL" ); + SAL_INFO_IF( !pNewParent, "vcl", "Window::SetParent(): pParent == NULL" ); SAL_WARN_IF( pNewParent == this, "vcl", "someone tried to reparent a window to itself" ); if( !pNewParent || pNewParent == this ) diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index f12e6f4baa6b..1b4ab74b4c96 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -1254,6 +1254,7 @@ class GtkInstanceWidget : public virtual weld::Widget { protected: GtkWidget* m_pWidget; + GtkWidget* m_pMouseEventBox; GtkInstanceBuilder* m_pBuilder; DECL_LINK(async_signal_focus_in, void*, void); @@ -1298,10 +1299,69 @@ protected: m_aFocusOutHdl.Call(*this); } + void ensureEventWidget() + { + // not every widget has a GdkWindow and can get any event, so if we + // want an event it doesn't have, insert a GtkEventBox so we can get + // those + if (!m_pMouseEventBox) + { + if (gtk_widget_get_has_window(m_pWidget)) + m_pMouseEventBox = m_pWidget; + else + { + // remove the widget and replace it with an eventbox and put the old + // widget into it + GtkWidget* pParent = gtk_widget_get_parent(m_pWidget); + + g_object_ref(m_pWidget); + + gint nTopAttach(0), nLeftAttach(0), nHeight(1), nWidth(1); + if (GTK_IS_GRID(pParent)) + { + gtk_container_child_get(GTK_CONTAINER(pParent), m_pWidget, + "left-attach", &nTopAttach, + "top-attach", &nLeftAttach, + "width", &nWidth, + "height", &nHeight, + nullptr); + } + + gtk_container_remove(GTK_CONTAINER(pParent), m_pWidget); + + m_pMouseEventBox = gtk_event_box_new(); + gtk_event_box_set_above_child(GTK_EVENT_BOX(m_pMouseEventBox), false); + gtk_event_box_set_visible_window(GTK_EVENT_BOX(m_pMouseEventBox), false); + gtk_widget_show(m_pMouseEventBox); + + gtk_container_add(GTK_CONTAINER(pParent), m_pMouseEventBox); + + if (GTK_IS_GRID(pParent)) + { + gtk_container_child_set(GTK_CONTAINER(pParent), m_pMouseEventBox, + "left-attach", nTopAttach, + "top-attach", nLeftAttach, + "width", nWidth, + "height", nHeight, + nullptr); + } + + gtk_container_add(GTK_CONTAINER(m_pMouseEventBox), m_pWidget); + g_object_unref(m_pWidget); + + gtk_widget_set_hexpand(m_pMouseEventBox, gtk_widget_get_hexpand(m_pWidget)); + gtk_widget_set_vexpand(m_pMouseEventBox, gtk_widget_get_vexpand(m_pWidget)); + } + } + } + void ensureButtonPressSignal() { if (!m_nButtonPressSignalId) - m_nButtonPressSignalId = g_signal_connect(m_pWidget, "button-press-event", G_CALLBACK(signalButton), this); + { + ensureEventWidget(); + m_nButtonPressSignalId = g_signal_connect(m_pMouseEventBox, "button-press-event", G_CALLBACK(signalButton), this); + } } static gboolean signalPopupMenu(GtkWidget* pWidget, gpointer widget) @@ -1515,6 +1575,7 @@ private: public: GtkInstanceWidget(GtkWidget* pWidget, GtkInstanceBuilder* pBuilder, bool bTakeOwnership) : m_pWidget(pWidget) + , m_pMouseEventBox(nullptr) , m_pBuilder(pBuilder) , m_bTakeOwnership(bTakeOwnership) , m_bFrozen(false) @@ -1556,13 +1617,15 @@ public: virtual void connect_mouse_move(const Link<const MouseEvent&, bool>& rLink) override { - m_nMotionSignalId = g_signal_connect(m_pWidget, "motion-notify-event", G_CALLBACK(signalMotion), this); + ensureEventWidget(); + m_nMotionSignalId = g_signal_connect(m_pMouseEventBox, "motion-notify-event", G_CALLBACK(signalMotion), this); weld::Widget::connect_mouse_move(rLink); } virtual void connect_mouse_release(const Link<const MouseEvent&, bool>& rLink) override { - m_nButtonReleaseSignalId = g_signal_connect(m_pWidget, "button-release-event", G_CALLBACK(signalButton), this); + ensureEventWidget(); + m_nButtonReleaseSignalId = g_signal_connect(m_pMouseEventBox, "button-release-event", G_CALLBACK(signalButton), this); weld::Widget::connect_mouse_release(rLink); } @@ -1993,6 +2056,17 @@ public: return m_xDropTarget.get(); } + virtual void set_stack_background() override + { + GtkStyleContext *pWidgetContext = gtk_widget_get_style_context(GTK_WIDGET(m_pWidget)); + GtkCssProvider *pProvider = gtk_css_provider_new(); + OUString aBuffer = "* { background-color: #" + Application::GetSettings().GetStyleSettings().GetWindowColor().AsRGBHexString() + "; }"; + OString aResult = OUStringToOString(aBuffer, RTL_TEXTENCODING_UTF8); + gtk_css_provider_load_from_data(pProvider, aResult.getStr(), aResult.getLength(), nullptr); + gtk_style_context_add_provider(pWidgetContext, GTK_STYLE_PROVIDER(pProvider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + } + virtual ~GtkInstanceWidget() override { if (m_nDragMotionSignalId) @@ -2008,11 +2082,11 @@ public: if (m_nKeyReleaseSignalId) g_signal_handler_disconnect(m_pWidget, m_nKeyReleaseSignalId); if (m_nButtonPressSignalId) - g_signal_handler_disconnect(m_pWidget, m_nButtonPressSignalId); + g_signal_handler_disconnect(m_pMouseEventBox, m_nButtonPressSignalId); if (m_nMotionSignalId) - g_signal_handler_disconnect(m_pWidget, m_nMotionSignalId); + g_signal_handler_disconnect(m_pMouseEventBox, m_nMotionSignalId); if (m_nButtonReleaseSignalId) - g_signal_handler_disconnect(m_pWidget, m_nButtonReleaseSignalId); + g_signal_handler_disconnect(m_pMouseEventBox, m_nButtonReleaseSignalId); if (m_nFocusInSignalId) g_signal_handler_disconnect(m_pWidget, m_nFocusInSignalId); if (m_nMnemonicActivateSignalId) @@ -2021,6 +2095,21 @@ public: g_signal_handler_disconnect(m_pWidget, m_nFocusOutSignalId); if (m_nSizeAllocateSignalId) g_signal_handler_disconnect(m_pWidget, m_nSizeAllocateSignalId); + + if (m_pMouseEventBox && m_pMouseEventBox != m_pWidget) + { + // put things back they way we found them + GtkWidget* pParent = gtk_widget_get_parent(m_pMouseEventBox); + + g_object_ref(m_pWidget); + gtk_container_remove(GTK_CONTAINER(m_pMouseEventBox), m_pWidget); + + gtk_widget_destroy(m_pMouseEventBox); + + gtk_container_add(GTK_CONTAINER(pParent), m_pWidget); + g_object_unref(m_pWidget); + } + if (m_bTakeOwnership) gtk_widget_destroy(m_pWidget); } @@ -5564,6 +5653,19 @@ namespace } } +namespace +{ + void set_entry_message_type(GtkEntry* pEntry, weld::EntryMessageType eType) + { + if (eType == weld::EntryMessageType::Error) + gtk_entry_set_icon_from_icon_name(pEntry, GTK_ENTRY_ICON_SECONDARY, "dialog-error"); + else if (eType == weld::EntryMessageType::Warning) + gtk_entry_set_icon_from_icon_name(pEntry, GTK_ENTRY_ICON_SECONDARY, "dialog-warning"); + else + gtk_entry_set_icon_from_icon_name(pEntry, GTK_ENTRY_ICON_SECONDARY, nullptr); + } +} + class GtkInstanceEntry : public GtkInstanceWidget, public virtual weld::Entry { private: @@ -5716,12 +5818,9 @@ public: return gtk_editable_get_editable(GTK_EDITABLE(m_pEntry)); } - virtual void set_error(bool bError) override + virtual void set_message_type(weld::EntryMessageType eType) override { - if (bError) - gtk_entry_set_icon_from_icon_name(m_pEntry, GTK_ENTRY_ICON_SECONDARY, "dialog-error"); - else - gtk_entry_set_icon_from_icon_name(m_pEntry, GTK_ENTRY_ICON_SECONDARY, nullptr); + ::set_entry_message_type(m_pEntry, eType); } virtual void disable_notify_events() override @@ -7917,6 +8016,19 @@ class GtkInstanceLabel : public GtkInstanceWidget, public virtual weld::Label { private: GtkLabel* m_pLabel; + + void set_text_color(const Color& rColor) + { + guint16 nRed = rColor.GetRed() << 8; + guint16 nGreen = rColor.GetRed() << 8; + guint16 nBlue = rColor.GetBlue() << 8; + + PangoAttrList* pAttrs = pango_attr_list_new(); + pango_attr_list_insert(pAttrs, pango_attr_background_new(nRed, nGreen, nBlue)); + gtk_label_set_attributes(m_pLabel, pAttrs); + pango_attr_list_unref(pAttrs); + } + public: GtkInstanceLabel(GtkLabel* pLabel, GtkInstanceBuilder* pBuilder, bool bTakeOwnership) : GtkInstanceWidget(GTK_WIDGET(pLabel), pBuilder, bTakeOwnership) @@ -7941,21 +8053,12 @@ public: gtk_label_set_mnemonic_widget(m_pLabel, pTargetWidget ? pTargetWidget->getWidget() : nullptr); } - virtual void set_error(bool bShowError) override + virtual void set_message_type(weld::EntryMessageType eType) override { - if (bShowError) - { - Color aColor(Application::GetSettings().GetStyleSettings().GetHighlightColor()); - - guint16 nRed = aColor.GetRed() << 8; - guint16 nGreen = aColor.GetRed() << 8; - guint16 nBlue = aColor.GetBlue() << 8; - - PangoAttrList* pAttrs = pango_attr_list_new(); - pango_attr_list_insert(pAttrs, pango_attr_background_new(nRed, nGreen, nBlue)); - gtk_label_set_attributes(m_pLabel, pAttrs); - pango_attr_list_unref(pAttrs); - } + if (eType == weld::EntryMessageType::Error) + set_text_color(Application::GetSettings().GetStyleSettings().GetHighlightColor()); + else if (eType == weld::EntryMessageType::Warning) + set_text_color(COL_YELLOW); else gtk_label_set_attributes(m_pLabel, nullptr); } @@ -9032,15 +9135,12 @@ public: return gtk_combo_box_get_has_entry(m_pComboBox); } - virtual void set_entry_error(bool bError) override + virtual void set_entry_message_type(weld::EntryMessageType eType) override { GtkWidget* pChild = gtk_bin_get_child(GTK_BIN(m_pComboBox)); assert(GTK_IS_ENTRY(pChild)); GtkEntry* pEntry = GTK_ENTRY(pChild); - if (bError) - gtk_entry_set_icon_from_icon_name(pEntry, GTK_ENTRY_ICON_SECONDARY, "dialog-error"); - else - gtk_entry_set_icon_from_icon_name(pEntry, GTK_ENTRY_ICON_SECONDARY, nullptr); + ::set_entry_message_type(pEntry, eType); } virtual void set_entry_text(const OUString& rText) override |