[gtk+/wip/dboles/combobox-cleanup: 36/37] combobox: Move area and menu to .ui file
- From: Daniel Boles <dboles src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/dboles/combobox-cleanup: 36/37] combobox: Move area and menu to .ui file
- Date: Sat, 21 Jan 2017 21:01:09 +0000 (UTC)
commit e1c92b0ac9d583f0d4465f62df6f303c50d670d3
Author: Daniel Boles <dboles src gnome org>
Date: Sat Jan 21 20:23:27 2017 +0000
combobox: Move area and menu to .ui file
Now that priv->area is guaranteed to be constructed by us, and not
passed in by a user, we can move it to the .ui file and stop manually
managing its lifetime altogether. And once the area is there, we can
move the menu there too (and stop pointlessly destroying/rebuilding it).
gtk/gtkcombobox.c | 187 ++++++++++--------------------------------------
gtk/ui/gtkcombobox.ui | 9 +++
2 files changed, 48 insertions(+), 148 deletions(-)
---
diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c
index 229f448..b4cfc07 100644
--- a/gtk/gtkcombobox.c
+++ b/gtk/gtkcombobox.c
@@ -286,11 +286,6 @@ static void gtk_combo_box_model_row_changed (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data);
-/* menu */
-static void gtk_combo_box_menu_setup (GtkComboBox *combo_box);
-static void gtk_combo_box_menu_destroy (GtkComboBox *combo_box);
-
-
static gboolean gtk_combo_box_menu_button_press (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data);
@@ -973,7 +968,14 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
gtk_widget_class_bind_template_child_internal_private (widget_class, GtkComboBox, box);
gtk_widget_class_bind_template_child_internal_private (widget_class, GtkComboBox, button);
gtk_widget_class_bind_template_child_internal_private (widget_class, GtkComboBox, arrow);
+ gtk_widget_class_bind_template_child_internal_private (widget_class, GtkComboBox, area);
+ gtk_widget_class_bind_template_child_internal_private (widget_class, GtkComboBox, popup_widget);
gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_button_toggled);
+ gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_menu_button_press);
+ gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_menu_activate);
+ gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_menu_key_press);
+ gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_menu_show);
+ gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_menu_hide);
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_COMBO_BOX_ACCESSIBLE);
gtk_widget_class_set_css_name (widget_class, "combobox");
@@ -1001,17 +1003,30 @@ gtk_combo_box_cell_editable_init (GtkCellEditableIface *iface)
iface->start_editing = gtk_combo_box_start_editing;
}
+static gboolean
+gtk_combo_box_row_separator_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GtkComboBox *combo)
+{
+ GtkComboBoxPrivate *priv = combo->priv;
+
+ if (priv->row_separator_func)
+ return priv->row_separator_func (model, iter, priv->row_separator_data);
+
+ return FALSE;
+}
+
static void
gtk_combo_box_init (GtkComboBox *combo_box)
{
GtkComboBoxPrivate *priv;
GtkCssNode *widget_node;
GtkStyleContext *context;
+ GtkTreeMenu *menu;
combo_box->priv = gtk_combo_box_get_instance_private (combo_box);
priv = combo_box->priv;
- priv->popup_widget = NULL;
priv->wrap_width = 0;
priv->active = -1;
@@ -1033,6 +1048,7 @@ gtk_combo_box_init (GtkComboBox *combo_box)
priv->id_column = -1;
g_type_ensure (GTK_TYPE_ICON);
+ g_type_ensure (GTK_TYPE_TREE_MENU);
gtk_widget_init_template (GTK_WIDGET (combo_box));
gtk_widget_add_events (priv->button, GDK_SCROLL_MASK);
@@ -1048,6 +1064,17 @@ gtk_combo_box_init (GtkComboBox *combo_box)
gtk_combo_box_allocate,
gtk_combo_box_render,
NULL, NULL);
+
+ menu = GTK_TREE_MENU (priv->popup_widget);
+ _gtk_tree_menu_set_wrap_width (menu, priv->wrap_width);
+ _gtk_tree_menu_set_row_span_column (menu, priv->row_column);
+ _gtk_tree_menu_set_column_span_column (menu, priv->col_column);
+ _gtk_tree_menu_set_row_separator_func (menu,
+ (GtkTreeViewRowSeparatorFunc)gtk_combo_box_row_separator_func,
+ combo_box, NULL);
+ gtk_menu_attach_to_widget (GTK_MENU (menu),
+ GTK_WIDGET (combo_box),
+ NULL);
}
static void
@@ -1335,17 +1362,8 @@ gtk_combo_box_remove (GtkContainer *container,
gtk_widget_queue_resize (GTK_WIDGET (container));
- if (priv->popup_widget)
- {
- gtk_combo_box_menu_destroy (combo_box);
- gtk_menu_detach (GTK_MENU (priv->popup_widget));
- priv->popup_widget = NULL;
- }
-
gtk_combo_box_create_child (combo_box);
- gtk_combo_box_menu_setup (combo_box);
-
if (gtk_tree_row_reference_valid (priv->active_row))
{
path = gtk_tree_row_reference_get_path (priv->active_row);
@@ -1385,25 +1403,6 @@ gtk_combo_box_menu_hide (GtkWidget *menu,
FALSE);
}
-static void
-gtk_combo_box_detacher (GtkWidget *widget,
- GtkMenu *menu)
-{
- GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
- GtkComboBoxPrivate *priv = combo_box->priv;
-
- g_return_if_fail (priv->popup_widget == (GtkWidget *) menu);
-
- g_signal_handlers_disconnect_by_func (menu->priv->toplevel,
- gtk_combo_box_menu_show,
- combo_box);
- g_signal_handlers_disconnect_by_func (menu->priv->toplevel,
- gtk_combo_box_menu_hide,
- combo_box);
-
- priv->popup_widget = NULL;
-}
-
static gboolean
cell_layout_is_sensitive (GtkCellLayout *layout)
{
@@ -1982,91 +1981,6 @@ gtk_combo_box_scroll_event (GtkWidget *widget,
return TRUE;
}
-/*
- * menu style
- */
-static gboolean
-gtk_combo_box_row_separator_func (GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkComboBox *combo)
-{
- GtkComboBoxPrivate *priv = combo->priv;
-
- if (priv->row_separator_func)
- return priv->row_separator_func (model, iter, priv->row_separator_data);
-
- return FALSE;
-}
-
-static void
-gtk_combo_box_menu_setup (GtkComboBox *combo_box)
-{
- GtkComboBoxPrivate *priv = combo_box->priv;
- GtkWidget *menu;
-
- g_signal_connect (priv->button, "button-press-event",
- G_CALLBACK (gtk_combo_box_menu_button_press),
- combo_box);
-
- /* create our funky menu */
- menu = _gtk_tree_menu_new_with_area (priv->area);
- gtk_widget_set_name (menu, "gtk-combobox-popup-menu");
-
- _gtk_tree_menu_set_model (GTK_TREE_MENU (menu), priv->model);
-
- _gtk_tree_menu_set_wrap_width (GTK_TREE_MENU (menu), priv->wrap_width);
- _gtk_tree_menu_set_row_span_column (GTK_TREE_MENU (menu), priv->row_column);
- _gtk_tree_menu_set_column_span_column (GTK_TREE_MENU (menu), priv->col_column);
-
- g_signal_connect (menu, "menu-activate",
- G_CALLBACK (gtk_combo_box_menu_activate), combo_box);
-
- /* Chain our row_separator_func through */
- _gtk_tree_menu_set_row_separator_func (GTK_TREE_MENU (menu),
- (GtkTreeViewRowSeparatorFunc)gtk_combo_box_row_separator_func,
- combo_box, NULL);
-
- g_signal_connect (menu, "key-press-event",
- G_CALLBACK (gtk_combo_box_menu_key_press), combo_box);
-
- /* Set up the popup menu */
- if (priv->popup_widget)
- gtk_menu_detach (GTK_MENU (priv->popup_widget));
-
- priv->popup_widget = menu;
-
- /*
- * Note that we connect to show/hide on the toplevel, not the
- * menu itself, since the menu is not shown/hidden when it is
- * popped up while torn-off.
- */
- g_signal_connect (GTK_MENU (menu)->priv->toplevel, "show",
- G_CALLBACK (gtk_combo_box_menu_show), combo_box);
- g_signal_connect (GTK_MENU (menu)->priv->toplevel, "hide",
- G_CALLBACK (gtk_combo_box_menu_hide), combo_box);
-
- gtk_menu_attach_to_widget (GTK_MENU (menu),
- GTK_WIDGET (combo_box),
- gtk_combo_box_detacher);
-}
-
-static void
-gtk_combo_box_menu_destroy (GtkComboBox *combo_box)
-{
- GtkComboBoxPrivate *priv = combo_box->priv;
-
- g_signal_handlers_disconnect_matched (priv->button,
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL,
- gtk_combo_box_menu_button_press, NULL);
- g_signal_handlers_disconnect_matched (priv->popup_widget,
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL,
- gtk_combo_box_menu_activate, combo_box);
-
- /* changing the popup window will unref the menu and the children */
-}
-
/* callbacks */
static gboolean
gtk_combo_box_menu_button_press (GtkWidget *widget,
@@ -2221,16 +2135,8 @@ gtk_combo_box_menu_key_press (GtkWidget *widget,
static GtkCellArea *
gtk_combo_box_cell_layout_get_area (GtkCellLayout *cell_layout)
{
- GtkComboBox *combo = GTK_COMBO_BOX (cell_layout);
- GtkComboBoxPrivate *priv = combo->priv;
-
- if (G_UNLIKELY (!priv->area))
- {
- priv->area = gtk_cell_area_box_new ();
- g_object_ref_sink (priv->area);
- }
-
- return priv->area;
+ GtkComboBox *combo_box = GTK_COMBO_BOX (cell_layout);
+ return combo_box->priv->area;
}
/*
@@ -2915,7 +2821,6 @@ gtk_combo_box_destroy (GtkWidget *widget)
priv->box = NULL;
priv->button = NULL;
priv->arrow = NULL;
- priv->cell_view = NULL;
_gtk_bin_set_child (GTK_BIN (combo_box), NULL);
}
@@ -3019,18 +2924,8 @@ gtk_combo_box_constructed (GObject *object)
G_OBJECT_CLASS (gtk_combo_box_parent_class)->constructed (object);
- if (!priv->area)
- {
- priv->area = gtk_cell_area_box_new ();
- g_object_ref_sink (priv->area);
- }
-
gtk_combo_box_create_child (combo_box);
- /* Create the popup menu, if it doesn’t already exist. */
- if (!priv->popup_widget)
- gtk_combo_box_menu_setup (combo_box);
-
if (priv->has_entry)
{
priv->text_renderer = gtk_cell_renderer_text_new ();
@@ -3041,7 +2936,6 @@ gtk_combo_box_constructed (GObject *object)
}
}
-
static void
gtk_combo_box_dispose (GObject* object)
{
@@ -3050,17 +2944,14 @@ gtk_combo_box_dispose (GObject* object)
if (priv->popup_widget)
{
- gtk_combo_box_menu_destroy (combo_box);
+ /* Stop menu destruction triggering toggle on a now-invalid button */
+ g_signal_handlers_disconnect_by_func (priv->popup_widget,
+ gtk_combo_box_menu_hide,
+ combo_box);
gtk_menu_detach (GTK_MENU (priv->popup_widget));
priv->popup_widget = NULL;
}
- if (priv->area)
- {
- g_object_unref (priv->area);
- priv->area = NULL;
- }
-
gtk_combo_box_unset_model (combo_box);
G_OBJECT_CLASS (gtk_combo_box_parent_class)->dispose (object);
diff --git a/gtk/ui/gtkcombobox.ui b/gtk/ui/gtkcombobox.ui
index 2e6ac30..56a8628 100644
--- a/gtk/ui/gtkcombobox.ui
+++ b/gtk/ui/gtkcombobox.ui
@@ -26,6 +26,7 @@
</child>
</object>
</child>
+ <signal name="button-press-event" handler="gtk_combo_box_menu_button_press" swapped="no" />
</object>
<packing>
<property name="pack-type">end</property>
@@ -34,4 +35,12 @@
</object>
</child>
</template>
+ <object class="GtkCellAreaBox" id="area" />
+ <object class="GtkTreeMenu" id="popup_widget">
+ <property name="cell-area">area</property>
+ <signal name="menu-activate" handler="gtk_combo_box_menu_activate" swapped="no" />
+ <signal name="key-press-event" handler="gtk_combo_box_menu_key_press" swapped="no" />
+ <signal name="show" handler="gtk_combo_box_menu_show" swapped="no" />
+ <signal name="hide" handler="gtk_combo_box_menu_hide" swapped="no" />
+ </object>
</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]