[gtk+] GtkPopover: Add gtk_popover_popdown/popup
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GtkPopover: Add gtk_popover_popdown/popup
- Date: Tue, 16 Aug 2016 15:55:42 +0000 (UTC)
commit 1f7b6c1d6f822ee660b8cca3b08a2bcc1c48b359
Author: Timm Bäder <mail baedert org>
Date: Wed Aug 10 18:28:14 2016 +0200
GtkPopover: Add gtk_popover_popdown/popup
Since not chaining up in gtk_widget_show/gtk_widget_hide is not allowed,
we can't just implicitly delay the hiding in GtkPopover's hide
implementation. Fix this by introducing gtk_popover_popup() and
gtk_popover_popdown() to show or hide a popover with transition and
revert GtkPopover's show/hide implementation to apply their effect
without the transition.
https://bugzilla.gnome.org/show_bug.cgi?id=769706
docs/reference/gtk/gtk3-sections.txt | 2 +
gtk/gtkpopover.c | 146 ++++++++++++++++++++++++++-------
gtk/gtkpopover.h | 7 ++
3 files changed, 124 insertions(+), 31 deletions(-)
---
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index a049638..b1a81c7 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -8159,6 +8159,8 @@ GtkPopover
gtk_popover_new
gtk_popover_new_from_model
gtk_popover_bind_model
+gtk_popover_popup
+gtk_popover_popdown
gtk_popover_set_relative_to
gtk_popover_get_relative_to
gtk_popover_set_pointing_to
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index 3e5e6e7..48be0ef 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -208,6 +208,8 @@ gtk_popover_init (GtkPopover *popover)
popover->priv = gtk_popover_get_instance_private (popover);
popover->priv->modal = TRUE;
popover->priv->tick_id = 0;
+ popover->priv->state = STATE_HIDDEN;
+ popover->priv->visible = FALSE;
popover->priv->transitions_enabled = TRUE;
popover->priv->preferred_position = GTK_POS_TOP;
popover->priv->constraint = GTK_POPOVER_CONSTRAINT_WINDOW;
@@ -296,6 +298,30 @@ transitions_enabled (GtkPopover *popover)
}
static void
+gtk_popover_hide_internal (GtkPopover *popover)
+{
+ GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
+ GtkWidget *widget = GTK_WIDGET (popover);
+
+ if (!priv->visible)
+ return;
+
+ priv->visible = FALSE;
+ g_signal_emit (widget, signals[CLOSED], 0);
+
+ if (priv->modal)
+ gtk_popover_apply_modality (popover, FALSE);
+
+ if (gtk_widget_get_realized (widget))
+ {
+ cairo_region_t *region = cairo_region_create ();
+ gdk_window_input_shape_combine_region (gtk_widget_get_parent_window (widget),
+ region, 0, 0);
+ cairo_region_destroy (region);
+ }
+}
+
+static void
gtk_popover_finalize (GObject *object)
{
GtkPopover *popover = GTK_POPOVER (object);
@@ -550,12 +576,27 @@ show_animate_cb (GtkWidget *widget,
gtk_popover_set_state (popover, STATE_HIDING);
}
else
- gtk_popover_set_state (popover, STATE_HIDDEN);
+ {
+ gtk_widget_hide (widget);
+ }
- return FALSE;
+ priv->tick_id = 0;
+ return G_SOURCE_REMOVE;
}
else
- return TRUE;
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+gtk_popover_stop_transition (GtkPopover *popover)
+{
+ GtkPopoverPrivate *priv = popover->priv;
+
+ if (priv->tick_id != 0)
+ {
+ gtk_widget_remove_tick_callback (GTK_WIDGET (popover), priv->tick_id);
+ priv->tick_id = 0;
+ }
}
static void
@@ -593,11 +634,7 @@ gtk_popover_set_state (GtkPopover *popover,
gtk_popover_start_transition (popover);
else
{
- if (priv->tick_id)
- {
- gtk_widget_remove_tick_callback (GTK_WIDGET (popover), priv->tick_id);
- priv->tick_id = 0;
- }
+ gtk_popover_stop_transition (popover);
gtk_widget_set_visible (GTK_WIDGET (popover), state == STATE_SHOWN);
}
@@ -1483,10 +1520,12 @@ gtk_popover_button_release (GtkWidget *widget,
event->x > child_alloc.x + child_alloc.width ||
event->y < child_alloc.y ||
event->y > child_alloc.y + child_alloc.height)
- gtk_widget_hide (widget);
+ gtk_popover_popdown (popover);
}
else if (!gtk_widget_is_ancestor (event_widget, widget))
- gtk_widget_hide (widget);
+ {
+ gtk_popover_popdown (popover);
+ }
return GDK_EVENT_PROPAGATE;
}
@@ -1583,7 +1622,7 @@ gtk_popover_show (GtkWidget *widget)
if (priv->modal)
gtk_popover_apply_modality (GTK_POPOVER (widget), TRUE);
- gtk_popover_set_state (GTK_POPOVER (widget), STATE_SHOWING);
+ priv->state = STATE_SHOWN;
if (gtk_widget_get_realized (widget))
gdk_window_input_shape_combine_region (gtk_widget_get_parent_window (widget),
@@ -1594,29 +1633,17 @@ static void
gtk_popover_hide (GtkWidget *widget)
{
GtkPopoverPrivate *priv = GTK_POPOVER (widget)->priv;
- cairo_region_t *region;
- if (priv->visible)
- {
- priv->visible = FALSE;
- g_signal_emit (widget, signals[CLOSED], 0);
+ gtk_popover_hide_internal (GTK_POPOVER (widget));
- if (priv->modal)
- gtk_popover_apply_modality (GTK_POPOVER (widget), FALSE);
- }
+ gtk_popover_stop_transition (GTK_POPOVER (widget));
+ priv->state = STATE_HIDDEN;
+ priv->transition_diff = 0;
+ gtk_progress_tracker_finish (&priv->tracker);
+ gtk_widget_set_opacity (widget, 1.0);
- if (gtk_widget_get_realized (widget))
- {
- region = cairo_region_create ();
- gdk_window_input_shape_combine_region (gtk_widget_get_parent_window (widget),
- region, 0, 0);
- cairo_region_destroy (region);
- }
- if (!priv->window || priv->state == STATE_HIDDEN)
- GTK_WIDGET_CLASS (gtk_popover_parent_class)->hide (widget);
- else if (priv->state != STATE_SHOWING)
- gtk_popover_set_state (GTK_POPOVER (widget), STATE_HIDING);
+ GTK_WIDGET_CLASS (gtk_popover_parent_class)->hide (widget);
}
static void
@@ -1827,7 +1854,7 @@ _gtk_popover_parent_grab_notify (GtkWidget *widget,
grab_widget = gtk_grab_get_current ();
if (!grab_widget || !GTK_IS_POPOVER (grab_widget))
- gtk_widget_hide (GTK_WIDGET (popover));
+ gtk_popover_popdown (popover);
}
}
@@ -2569,3 +2596,60 @@ gtk_popover_get_constrain_to (GtkPopover *popover)
return priv->constraint;
}
+
+/**
+ * gtk_popover_popup:
+ * @popover: a #GtkPopover
+ *
+ * Pops @popover up. This is different than a gtk_widget_show() call
+ * in that it shows the popover with a transition. If you want to show
+ * the popover without a transition, use gtk_widget_show().
+ *
+ * Since: 3.22
+ */
+void
+gtk_popover_popup (GtkPopover *popover)
+{
+ GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
+
+ g_return_if_fail (GTK_IS_POPOVER (popover));
+
+ if (priv->state == STATE_SHOWING ||
+ priv->state == STATE_SHOWN)
+ return;
+
+ gtk_widget_show (GTK_WIDGET (popover));
+
+ if (transitions_enabled (popover))
+ gtk_popover_set_state (popover, STATE_SHOWING);
+}
+
+/**
+ * gtk_popover_popdown:
+ * @popover: a #GtkPopover
+ *
+ * Pops @popover down.This is different than a gtk_widget_hide() call
+ * in that it shows the popover with a transition. If you want to hide
+ * the popover without a transition, use gtk_widget_hide().
+ *
+ * Since: 3.22
+ */
+void
+gtk_popover_popdown (GtkPopover *popover)
+{
+ GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
+
+ g_return_if_fail (GTK_IS_POPOVER (popover));
+
+ if (priv->state == STATE_HIDING ||
+ priv->state == STATE_HIDDEN)
+ return;
+
+
+ if (!transitions_enabled (popover))
+ gtk_widget_hide (GTK_WIDGET (popover));
+ else
+ gtk_popover_set_state (popover, STATE_HIDING);
+
+ gtk_popover_hide_internal (popover);
+}
diff --git a/gtk/gtkpopover.h b/gtk/gtkpopover.h
index 61bcd92..af8359c 100644
--- a/gtk/gtkpopover.h
+++ b/gtk/gtkpopover.h
@@ -116,6 +116,13 @@ void gtk_popover_set_constrain_to (GtkPopover *popover
GDK_AVAILABLE_IN_3_20
GtkPopoverConstraint gtk_popover_get_constrain_to (GtkPopover *popover);
+GDK_AVAILABLE_IN_3_22
+void gtk_popover_popup (GtkPopover *popover);
+
+GDK_AVAILABLE_IN_3_22
+void gtk_popover_popdown (GtkPopover *popover);
+
+
G_END_DECLS
#endif /* __GTK_POPOVER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]