[gtk+/combo-refactor: 21/47] Make GtkTreeMenu update menu item sensitivity when "apply-attributes" signal is fired for a row in t
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/combo-refactor: 21/47] Make GtkTreeMenu update menu item sensitivity when "apply-attributes" signal is fired for a row in t
- Date: Mon, 6 Dec 2010 12:27:45 +0000 (UTC)
commit 48c03a645f51ae56b55694c1959f3f2951f39c0c
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Wed Nov 24 13:49:12 2010 +0900
Make GtkTreeMenu update menu item sensitivity when "apply-attributes" signal is fired for a row in the menu.
gtk/gtktreemenu.c | 201 ++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 153 insertions(+), 48 deletions(-)
---
diff --git a/gtk/gtktreemenu.c b/gtk/gtktreemenu.c
index 9598032..7212087 100644
--- a/gtk/gtktreemenu.c
+++ b/gtk/gtktreemenu.c
@@ -82,6 +82,9 @@ static void gtk_tree_menu_set_area (GtkTreeMenu
GtkCellArea *area);
static GtkWidget *gtk_tree_menu_get_path_item (GtkTreeMenu *menu,
GtkTreePath *path);
+static gboolean gtk_tree_menu_path_in_menu (GtkTreeMenu *menu,
+ GtkTreePath *path,
+ gboolean *header_item);
static void row_inserted_cb (GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
@@ -98,10 +101,15 @@ static void row_changed_cb (GtkTreeModel
GtkTreePath *path,
GtkTreeIter *iter,
GtkTreeMenu *menu);
-
static void context_size_changed_cb (GtkCellAreaContext *context,
GParamSpec *pspec,
GtkWidget *menu);
+static void area_apply_attributes_cb (GtkCellArea *area,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gboolean is_expander,
+ gboolean is_expanded,
+ GtkTreeMenu *menu);
static void item_activated_cb (GtkMenuItem *item,
GtkTreeMenu *menu);
static void submenu_activated_cb (GtkTreeMenu *submenu,
@@ -122,6 +130,7 @@ struct _GtkTreeMenuPrivate
/* Signals */
gulong size_changed_id;
+ gulong apply_attributes_id;
gulong row_inserted_id;
gulong row_deleted_id;
gulong row_reordered_id;
@@ -223,8 +232,8 @@ gtk_tree_menu_class_init (GtkTreeMenuClass *class)
object_class->set_property = gtk_tree_menu_set_property;
object_class->get_property = gtk_tree_menu_get_property;
- widget_class->get_preferred_width = gtk_tree_menu_get_preferred_width;
- widget_class->get_preferred_height = gtk_tree_menu_get_preferred_height;
+ widget_class->get_preferred_width = gtk_tree_menu_get_preferred_width;
+ widget_class->get_preferred_height = gtk_tree_menu_get_preferred_height;
tree_menu_signals[SIGNAL_MENU_ACTIVATE] =
g_signal_new (I_("menu-activate"),
@@ -359,11 +368,11 @@ gtk_tree_menu_constructor (GType type,
}
priv->context = gtk_cell_area_create_context (priv->area);
+
priv->size_changed_id =
g_signal_connect (priv->context, "notify",
G_CALLBACK (context_size_changed_cb), menu);
-
return object;
}
@@ -633,41 +642,60 @@ gtk_tree_menu_get_path_item (GtkTreeMenu *menu,
return item;
}
-static void
-row_inserted_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- GtkTreeMenu *menu)
+static gboolean
+gtk_tree_menu_path_in_menu (GtkTreeMenu *menu,
+ GtkTreePath *path,
+ gboolean *header_item)
{
GtkTreeMenuPrivate *priv = menu->priv;
- GtkTreePath *parent_path;
- gboolean this_menu = FALSE;
- gint *indices, index, depth;
-
- parent_path = gtk_tree_path_copy (path);
+ GtkTreePath *parent_path = gtk_tree_path_copy (path);
+ gboolean in_menu = FALSE;
+ gboolean is_header = FALSE;
- /* Check if the menu and the added iter are in root of the model */
- if (gtk_tree_path_get_depth (parent_path) <= 1)
+ /* Check if the is in root of the model */
+ if (gtk_tree_path_get_depth (parent_path) == 1)
{
if (!priv->root)
- this_menu = TRUE;
+ in_menu = TRUE;
}
- /* If we are a submenu, compare the path */
- else if (priv->root)
+ /* If we are a submenu, compare the parent path */
+ else if (priv->root && gtk_tree_path_up (parent_path))
{
GtkTreePath *root_path =
gtk_tree_row_reference_get_path (priv->root);
if (gtk_tree_path_compare (root_path, parent_path) == 0)
- this_menu = TRUE;
+ in_menu = TRUE;
+
+ if (!in_menu && priv->menu_with_header &&
+ gtk_tree_path_compare (root_path, path) == 0)
+ {
+ in_menu = TRUE;
+ is_header = TRUE;
+ }
gtk_tree_path_free (root_path);
}
gtk_tree_path_free (parent_path);
+ if (header_item)
+ *header_item = is_header;
+
+ return in_menu;
+}
+
+static void
+row_inserted_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GtkTreeMenu *menu)
+{
+ GtkTreeMenuPrivate *priv = menu->priv;
+ gint *indices, index, depth;
+
/* If the iter should be in this menu then go ahead and insert it */
- if (this_menu)
+ if (gtk_tree_menu_path_in_menu (menu, path, NULL))
{
GtkWidget *item;
@@ -706,34 +734,30 @@ row_deleted_cb (GtkTreeModel *model,
GtkTreeMenu *menu)
{
GtkTreeMenuPrivate *priv = menu->priv;
- GtkTreePath *root_path;
GtkWidget *item;
+ gboolean header_item;
+ gboolean in_menu;
- /* If it's the root node we leave it to the parent menu to remove us
- * from its menu */
- if (priv->root)
- {
- root_path = gtk_tree_row_reference_get_path (priv->root);
+ in_menu = gtk_tree_menu_path_in_menu (menu, path, &header_item);
- if (gtk_tree_path_compare (root_path, path) == 0)
- {
- gtk_tree_path_free (root_path);
- return;
- }
- }
-
- item = gtk_tree_menu_get_path_item (menu, path);
- if (item)
+ /* If it's the header item we leave it to the parent menu
+ * to remove us from its menu
+ */
+ if (!header_item && in_menu)
{
- if (priv->wrap_width > 0)
- rebuild_menu (menu);
- else
+ item = gtk_tree_menu_get_path_item (menu, path);
+ if (item)
{
- /* Get rid of the deleted item */
- gtk_widget_destroy (item);
-
- /* Resize everything */
- gtk_cell_area_context_flush (menu->priv->context);
+ if (priv->wrap_width > 0)
+ rebuild_menu (menu);
+ else
+ {
+ /* Get rid of the deleted item */
+ gtk_widget_destroy (item);
+
+ /* Resize everything */
+ gtk_cell_area_context_flush (menu->priv->context);
+ }
}
}
}
@@ -748,7 +772,7 @@ row_reordered_cb (GtkTreeModel *model,
GtkTreeMenuPrivate *priv = menu->priv;
gboolean this_menu = FALSE;
- if (iter == NULL && priv->root == NULL)
+ if (path == NULL && priv->root == NULL)
this_menu = TRUE;
else if (priv->root)
{
@@ -823,7 +847,7 @@ row_changed_cb (GtkTreeModel *model,
}
else if (!has_header && item)
{
- /* Destroy the header item and the following separator */
+ /* Destroy the header item and then the following separator */
gtk_widget_destroy (item);
gtk_widget_destroy (GTK_MENU_SHELL (menu)->children->data);
@@ -873,6 +897,75 @@ context_size_changed_cb (GtkCellAreaContext *context,
gtk_widget_queue_resize (menu);
}
+static gboolean
+area_is_sensitive (GtkCellArea *area)
+{
+ GList *cells, *list;
+ gboolean sensitive = FALSE;
+
+ cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (area));
+
+ for (list = cells; list; list = list->next)
+ {
+ g_object_get (list->data, "sensitive", &sensitive, NULL);
+
+ if (sensitive)
+ break;
+ }
+ g_list_free (cells);
+
+ return sensitive;
+}
+
+static void
+area_apply_attributes_cb (GtkCellArea *area,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gboolean is_expander,
+ gboolean is_expanded,
+ GtkTreeMenu *menu)
+{
+ /* If the menu for this iter has a submenu */
+ GtkTreeMenuPrivate *priv = menu->priv;
+ GtkTreePath *path;
+ GtkWidget *item;
+ gboolean is_header;
+ gboolean sensitive;
+
+ path = gtk_tree_model_get_path (tree_model, iter);
+
+ if (gtk_tree_menu_path_in_menu (menu, path, &is_header))
+ {
+ item = gtk_tree_menu_get_path_item (menu, path);
+
+ /* If there is no submenu, go ahead and update item sensitivity,
+ * items with submenus are always sensitive */
+ if (!gtk_menu_item_get_submenu (GTK_MENU_ITEM (item)))
+ {
+ sensitive = area_is_sensitive (priv->area);
+
+ gtk_widget_set_sensitive (item, sensitive);
+
+ if (is_header)
+ {
+ /* For header items we need to set the sensitivity
+ * of the following separator item
+ */
+ if (GTK_MENU_SHELL (menu)->children &&
+ GTK_MENU_SHELL (menu)->children->next)
+ {
+ GtkWidget *separator =
+ GTK_MENU_SHELL (menu)->children->next->data;
+
+ gtk_widget_set_sensitive (separator, sensitive);
+ }
+ }
+ }
+ }
+
+ gtk_tree_path_free (path);
+}
+
static void
gtk_tree_menu_set_area (GtkTreeMenu *menu,
GtkCellArea *area)
@@ -880,12 +973,24 @@ gtk_tree_menu_set_area (GtkTreeMenu *menu,
GtkTreeMenuPrivate *priv = menu->priv;
if (priv->area)
- g_object_unref (priv->area);
+ {
+ g_signal_handler_disconnect (priv->area,
+ priv->apply_attributes_id);
+ priv->apply_attributes_id = 0;
+
+ g_object_unref (priv->area);
+ }
priv->area = area;
if (priv->area)
- g_object_ref_sink (priv->area);
+ {
+ g_object_ref_sink (priv->area);
+
+ priv->apply_attributes_id =
+ g_signal_connect (priv->area, "apply-attributes",
+ G_CALLBACK (area_apply_attributes_cb), menu);
+ }
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]