summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2019-05-07 12:27:43 +0100
committerCaolán McNamara <caolanm@redhat.com>2019-05-11 18:34:23 +0200
commit492b0d5d076d38234fea4e4e7c5dbec578296fd2 (patch)
tree47b4a17120d7d3c71bf7674b45768f38b761e360 /vcl
parentacd290431fd39ed0602e057e036326b46a99f7a8 (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.cxx110
-rw-r--r--vcl/source/window/stacking.cxx2
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx160
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