From f70759b6c1a61e34660a3bc2dddfb3f2cbf18fe7 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 15 Dec 2009 16:04:29 -0600 Subject: Building the basic generic menu item. --- libdbusmenu-gtk/genericmenuitem.c | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 libdbusmenu-gtk/genericmenuitem.c (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c new file mode 100644 index 0000000..3dd3969 --- /dev/null +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -0,0 +1,49 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "genericmenuitem.h" + +typedef struct _GenericmenuitemPrivate GenericmenuitemPrivate; + +struct _GenericmenuitemPrivate +{ +}; + +#define GENERICMENUITEM_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), GENERICMENUITEM_TYPE, GenericmenuitemPrivate)) + +static void genericmenuitem_class_init (GenericmenuitemClass *klass); +static void genericmenuitem_init (Genericmenuitem *self); +static void genericmenuitem_dispose (GObject *object); +static void genericmenuitem_finalize (GObject *object); + +G_DEFINE_TYPE (Genericmenuitem, genericmenuitem, GTK_TYPE_CHECK_MENU_ITEM); + +static void +genericmenuitem_class_init (GenericmenuitemClass *klass) +{ +GObjectClass *object_class = G_OBJECT_CLASS (klass); + +g_type_class_add_private (klass, sizeof (GenericmenuitemPrivate)); + +object_class->dispose = genericmenuitem_dispose; +object_class->finalize = genericmenuitem_finalize; +} + +static void +genericmenuitem_init (Genericmenuitem *self) +{ +} + +static void +genericmenuitem_dispose (GObject *object) +{ +G_OBJECT_CLASS (genericmenuitem_parent_class)->dispose (object); +} + +static void +genericmenuitem_finalize (GObject *object) +{ +G_OBJECT_CLASS (genericmenuitem_parent_class)->finalize (object); +} -- cgit v1.2.3 From eda482ed8bee77ed0904f1b1f3e835b49e174c5b Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 15 Dec 2009 16:26:08 -0600 Subject: Slight cleanups, getting this code going. --- libdbusmenu-gtk/genericmenuitem.c | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 3dd3969..1d59d34 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -4,10 +4,9 @@ #include "genericmenuitem.h" -typedef struct _GenericmenuitemPrivate GenericmenuitemPrivate; - -struct _GenericmenuitemPrivate -{ +struct _GenericmenuitemPrivate { + int checkbox_type; + int state; }; #define GENERICMENUITEM_GET_PRIVATE(o) \ @@ -20,30 +19,50 @@ static void genericmenuitem_finalize (GObject *object); G_DEFINE_TYPE (Genericmenuitem, genericmenuitem, GTK_TYPE_CHECK_MENU_ITEM); +/* Initializing all of the classes. Most notably we're + disabling the drawing of the check early. */ static void genericmenuitem_class_init (GenericmenuitemClass *klass) { -GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (GenericmenuitemPrivate)); + + object_class->dispose = genericmenuitem_dispose; + object_class->finalize = genericmenuitem_finalize; -g_type_class_add_private (klass, sizeof (GenericmenuitemPrivate)); + GtkCheckMenuItemClass * check_class = GTK_CHECK_MENU_ITEM_CLASS (klass); -object_class->dispose = genericmenuitem_dispose; -object_class->finalize = genericmenuitem_finalize; + /* We'll put this back if we get a type set */ + check_class->draw_indicator = NULL; + + return; } +/* Sets default values for all the class variables. Mostly, + this puts us in a default state. */ static void genericmenuitem_init (Genericmenuitem *self) { + self->priv = GENERICMENUITEM_GET_PRIVATE(self); + + return; } +/* Clean everything up. Whew, that can be work. */ static void genericmenuitem_dispose (GObject *object) { -G_OBJECT_CLASS (genericmenuitem_parent_class)->dispose (object); + + G_OBJECT_CLASS (genericmenuitem_parent_class)->dispose (object); + return; } +/* Now free memory, we no longer need it. */ static void genericmenuitem_finalize (GObject *object) { -G_OBJECT_CLASS (genericmenuitem_parent_class)->finalize (object); + + G_OBJECT_CLASS (genericmenuitem_parent_class)->finalize (object); + return; } -- cgit v1.2.3 From fcb8ac056eceee3ac25f28812cd9090177d91463 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 15 Dec 2009 16:37:12 -0600 Subject: Setting up enums for the type of check and the state of it. --- libdbusmenu-gtk/genericmenuitem.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 1d59d34..ee02a1c 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -5,8 +5,8 @@ #include "genericmenuitem.h" struct _GenericmenuitemPrivate { - int checkbox_type; - int state; + GenericmenuitemCheckType check_type; + GenericmenuitemState state; }; #define GENERICMENUITEM_GET_PRIVATE(o) \ @@ -46,6 +46,9 @@ genericmenuitem_init (Genericmenuitem *self) { self->priv = GENERICMENUITEM_GET_PRIVATE(self); + self->priv->check_type = GENERICMENUITEM_CHECK_TYPE_NONE; + self->priv->state = GENERICMENUITEM_STATE_UNCHECKED; + return; } -- cgit v1.2.3 From 5e7b2cec7f0ffd4147d81470ca162fd14ed92836 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 15 Dec 2009 16:49:07 -0600 Subject: Better handling of the draw_indicator function, as in, this one will actually work. --- libdbusmenu-gtk/genericmenuitem.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index ee02a1c..b40a3f5 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -4,21 +4,33 @@ #include "genericmenuitem.h" +/** + GenericmenuitemPrivate: + @check_type: What type of check we have, or none at all. + @state: What the state of our check is. +*/ struct _GenericmenuitemPrivate { GenericmenuitemCheckType check_type; GenericmenuitemState state; }; +/* Private macro */ #define GENERICMENUITEM_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GENERICMENUITEM_TYPE, GenericmenuitemPrivate)) +/* Prototypes */ static void genericmenuitem_class_init (GenericmenuitemClass *klass); static void genericmenuitem_init (Genericmenuitem *self); static void genericmenuitem_dispose (GObject *object); static void genericmenuitem_finalize (GObject *object); +static void draw_indicator (GtkCheckMenuItem *check_menu_item, GdkRectangle *area); +/* GObject stuff */ G_DEFINE_TYPE (Genericmenuitem, genericmenuitem, GTK_TYPE_CHECK_MENU_ITEM); +/* Globals */ +static void (*parent_draw_indicator) (GtkCheckMenuItem *check_menu_item, GdkRectangle *area) = NULL; + /* Initializing all of the classes. Most notably we're disabling the drawing of the check early. */ static void @@ -33,8 +45,8 @@ genericmenuitem_class_init (GenericmenuitemClass *klass) GtkCheckMenuItemClass * check_class = GTK_CHECK_MENU_ITEM_CLASS (klass); - /* We'll put this back if we get a type set */ - check_class->draw_indicator = NULL; + parent_draw_indicator = check_class->draw_indicator; + check_class->draw_indicator = draw_indicator; return; } @@ -69,3 +81,16 @@ genericmenuitem_finalize (GObject *object) G_OBJECT_CLASS (genericmenuitem_parent_class)->finalize (object); return; } + +/* Checks to see if we should be drawing a little box at + all. If we should be, let's do that, otherwise we're + going suppress the box drawing. */ +static void +draw_indicator (GtkCheckMenuItem *check_menu_item, GdkRectangle *area) +{ + Genericmenuitem * self = GENERICMENUITEM(check_menu_item); + if (self->priv->check_type != GENERICMENUITEM_CHECK_TYPE_NONE) { + parent_draw_indicator(check_menu_item, area); + } + return; +} -- cgit v1.2.3 From f54a417fde8f6937ecafd269db51a135af2e7a3e Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 15 Dec 2009 17:09:16 -0600 Subject: Functions for setting the check type and state of the check. --- libdbusmenu-gtk/genericmenuitem.c | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index b40a3f5..6eee2f7 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -94,3 +94,48 @@ draw_indicator (GtkCheckMenuItem *check_menu_item, GdkRectangle *area) } return; } + +/** + genericmenuitem_set_check_type: + @item: #Genericmenuitem to set the type on + @check_type: Which type of check should be displayed + + This function changes the type of the checkmark that + appears in the left hand gutter for the menuitem. +*/ +void +genericmenuitem_set_check_type (Genericmenuitem * item, GenericmenuitemCheckType check_type) +{ + if (item->priv->check_type == check_type) { + return; + } + + item->priv->check_type = check_type; + + gtk_widget_queue_draw(GTK_WIDGET(item)); + + return; +} + +/** + genericmenuitem_set_state: + @item: #Genericmenuitem to set the type on + @check_type: What is the state of the check + + Sets the state of the check in the menu item. It does + not require, but isn't really useful if the type of + check that the menuitem is set to #GENERICMENUITEM_CHECK_TYPE_NONE. +*/ +void +genericmenuitem_set_state (Genericmenuitem * item, GenericmenuitemState state) +{ + if (item->priv->state == state) { + return; + } + + item->priv->state = state; + + gtk_widget_queue_draw(GTK_WIDGET(item)); + + return; +} -- cgit v1.2.3 From 16812b7ca72e41dfaf76b14d5517739f44e815b7 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 15 Dec 2009 17:12:32 -0600 Subject: Building up the case statements. --- libdbusmenu-gtk/genericmenuitem.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 6eee2f7..3f36bbf 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -112,6 +112,18 @@ genericmenuitem_set_check_type (Genericmenuitem * item, GenericmenuitemCheckType item->priv->check_type = check_type; + switch (item->priv->check_type) { + case GENERICMENUITEM_CHECK_TYPE_NONE: + break; + case GENERICMENUITEM_CHECK_TYPE_CHECKBOX: + break; + case GENERICMENUITEM_CHECK_TYPE_RADIO: + break; + default: + g_warning("Generic Menuitem invalid check type: %d", check_type); + return; + } + gtk_widget_queue_draw(GTK_WIDGET(item)); return; @@ -135,6 +147,18 @@ genericmenuitem_set_state (Genericmenuitem * item, GenericmenuitemState state) item->priv->state = state; + switch (item->priv->state) { + case GENERICMENUITEM_STATE_UNCHECKED: + break; + case GENERICMENUITEM_STATE_CHECKED: + break; + case GENERICMENUITEM_STATE_INDETERMINATE: + break; + default: + g_warning("Generic Menuitem invalid check state: %d", state); + return; + } + gtk_widget_queue_draw(GTK_WIDGET(item)); return; -- cgit v1.2.3 From 0669b0c473075115337aede5eb1ae6b86a521668 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 16 Dec 2009 08:31:02 -0600 Subject: Setting the properties based on the enum value changes. --- libdbusmenu-gtk/genericmenuitem.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 3f36bbf..d8e9b39 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -111,13 +111,23 @@ genericmenuitem_set_check_type (Genericmenuitem * item, GenericmenuitemCheckType } item->priv->check_type = check_type; + GValue value = {0}; switch (item->priv->check_type) { case GENERICMENUITEM_CHECK_TYPE_NONE: + /* We don't need to do anything here as we're queuing the + draw and then when it draws it'll avoid drawing the + check on the item. */ break; case GENERICMENUITEM_CHECK_TYPE_CHECKBOX: + g_value_init(&value, G_TYPE_BOOLEAN); + g_value_set_boolean(&value, FALSE); + g_object_set_property(G_OBJECT(item), "draw-as-radio", &value); break; case GENERICMENUITEM_CHECK_TYPE_RADIO: + g_value_init(&value, G_TYPE_BOOLEAN); + g_value_set_boolean(&value, TRUE); + g_object_set_property(G_OBJECT(item), "draw-as-radio", &value); break; default: g_warning("Generic Menuitem invalid check type: %d", check_type); @@ -146,13 +156,27 @@ genericmenuitem_set_state (Genericmenuitem * item, GenericmenuitemState state) } item->priv->state = state; + GValue value = {0}; + g_value_init(&value, G_TYPE_BOOLEAN); switch (item->priv->state) { case GENERICMENUITEM_STATE_UNCHECKED: + g_value_set_boolean(&value, FALSE); + g_object_set_property(G_OBJECT(item), "active", &value); + g_value_set_boolean(&value, FALSE); + g_object_set_property(G_OBJECT(item), "inconsistent", &value); break; case GENERICMENUITEM_STATE_CHECKED: + g_value_set_boolean(&value, TRUE); + g_object_set_property(G_OBJECT(item), "active", &value); + g_value_set_boolean(&value, FALSE); + g_object_set_property(G_OBJECT(item), "inconsistent", &value); break; case GENERICMENUITEM_STATE_INDETERMINATE: + g_value_set_boolean(&value, TRUE); + g_object_set_property(G_OBJECT(item), "active", &value); + g_value_set_boolean(&value, TRUE); + g_object_set_property(G_OBJECT(item), "inconsistent", &value); break; default: g_warning("Generic Menuitem invalid check state: %d", state); -- cgit v1.2.3 From 58c6ed7efa57ff15c27cee2fc07b4b31a48b734b Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 16 Dec 2009 13:09:32 -0600 Subject: Stubs for setting and getting the image and label. --- libdbusmenu-gtk/genericmenuitem.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index d8e9b39..20fb8e2 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -24,6 +24,8 @@ static void genericmenuitem_init (Genericmenuitem *self); static void genericmenuitem_dispose (GObject *object); static void genericmenuitem_finalize (GObject *object); static void draw_indicator (GtkCheckMenuItem *check_menu_item, GdkRectangle *area); +static void set_label (GtkMenuItem * menu_item, const gchar * label); +static const gchar * get_label (GtkMenuItem * menu_item); /* GObject stuff */ G_DEFINE_TYPE (Genericmenuitem, genericmenuitem, GTK_TYPE_CHECK_MENU_ITEM); @@ -48,6 +50,10 @@ genericmenuitem_class_init (GenericmenuitemClass *klass) parent_draw_indicator = check_class->draw_indicator; check_class->draw_indicator = draw_indicator; + GtkMenuItemClass * menuitem_class = GTK_MENU_ITEM_CLASS (klass); + menuitem_class->set_label = set_label; + menuitem_class->get_label = get_label; + return; } @@ -95,6 +101,23 @@ draw_indicator (GtkCheckMenuItem *check_menu_item, GdkRectangle *area) return; } +/* Set the label on the item */ +static void +set_label (GtkMenuItem * menu_item, const gchar * label) +{ + + return; +} + +/* Get the text of the label for the item */ +static const gchar * +get_label (GtkMenuItem * menu_item) +{ + + + return NULL; +} + /** genericmenuitem_set_check_type: @item: #Genericmenuitem to set the type on @@ -187,3 +210,19 @@ genericmenuitem_set_state (Genericmenuitem * item, GenericmenuitemState state) return; } + +void +genericmenuitem_set_image (Genericmenuitem * item, GtkWidget * image) +{ + + + return; +} + +GtkWidget * +genericmenuitem_get_image (Genericmenuitem * item) +{ + + + return NULL; +} -- cgit v1.2.3 From 7ee8c7fd98fa88c2821b955064240364d1c0c903 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 16 Dec 2009 13:13:23 -0600 Subject: Comments --- libdbusmenu-gtk/genericmenuitem.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 20fb8e2..63cc936 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -211,6 +211,13 @@ genericmenuitem_set_state (Genericmenuitem * item, GenericmenuitemState state) return; } +/** + genericmenuitem_set_image: + @item: A #Genericmenuitem + @image: The image to set as the image of @item + + Sets the image of the menu item. +*/ void genericmenuitem_set_image (Genericmenuitem * item, GtkWidget * image) { @@ -219,6 +226,15 @@ genericmenuitem_set_image (Genericmenuitem * item, GtkWidget * image) return; } +/** + genericmenuitem_get_image: + @item: A #Genericmenuitem + + Returns the image if there is one. + + Return value: A pointer to the image of the item or #NULL + if there isn't one. +*/ GtkWidget * genericmenuitem_get_image (Genericmenuitem * item) { -- cgit v1.2.3 From 0f9080a861c521e41fe4fa4c8c8ab138671d6659 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 16 Dec 2009 13:41:29 -0600 Subject: Woot, a set label function. --- libdbusmenu-gtk/genericmenuitem.c | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 63cc936..d2a20ef 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -101,10 +101,50 @@ draw_indicator (GtkCheckMenuItem *check_menu_item, GdkRectangle *area) return; } +/* A small helper to look through the widgets in the + box and find the one that is the label. */ +static void +set_label_helper (GtkWidget * widget, gpointer data) +{ + GtkWidget ** labelval = (GtkWidget **)data; + if (GTK_IS_LABEL(widget)) { + *labelval = widget; + } + return; +} + /* Set the label on the item */ static void set_label (GtkMenuItem * menu_item, const gchar * label) { + GtkWidget * child = gtk_bin_get_child(GTK_BIN(menu_item)); + + if (child == NULL) { + GtkWidget * labelw = gtk_label_new(label); + gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE); + gtk_container_add(GTK_CONTAINER(menu_item), labelw); + } else if (GTK_IS_LABEL(child)) { + gtk_label_set_label(GTK_LABEL(child), label); + } else if (GTK_IS_BOX(child)) { + GtkWidget * labelw = NULL; + /* Look for the label */ + gtk_container_foreach(GTK_CONTAINER(child), set_label_helper, &labelw); + + if (labelw == NULL) { + /* We don't have a label, so we need to build */ + labelw = gtk_label_new(label); + gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE); + gtk_box_pack_end(GTK_BOX(child), labelw, TRUE, TRUE, 0); + } else { + /* We can reset the label that we have. */ + gtk_label_set_label(GTK_LABEL(labelw), label); + } + } else { + g_error("Generic item in an indeterminate state."); + return; + } + + g_object_notify(G_OBJECT(menu_item), "label"); return; } -- cgit v1.2.3 From 9ab79b5a7cf9a6d0224acd7902324a76ad2f8cf5 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 16 Dec 2009 16:29:24 -0600 Subject: Yeah, gotta show those labels. --- libdbusmenu-gtk/genericmenuitem.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index d2a20ef..5eba55a 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -123,6 +123,7 @@ set_label (GtkMenuItem * menu_item, const gchar * label) GtkWidget * labelw = gtk_label_new(label); gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE); gtk_container_add(GTK_CONTAINER(menu_item), labelw); + gtk_widget_show(labelw); } else if (GTK_IS_LABEL(child)) { gtk_label_set_label(GTK_LABEL(child), label); } else if (GTK_IS_BOX(child)) { @@ -135,6 +136,7 @@ set_label (GtkMenuItem * menu_item, const gchar * label) labelw = gtk_label_new(label); gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE); gtk_box_pack_end(GTK_BOX(child), labelw, TRUE, TRUE, 0); + gtk_widget_show(labelw); } else { /* We can reset the label that we have. */ gtk_label_set_label(GTK_LABEL(labelw), label); -- cgit v1.2.3 From 6731f63179ec24929a8209aee8eed363f3350c47 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 16 Dec 2009 16:32:50 -0600 Subject: Set alignment on the labels. --- libdbusmenu-gtk/genericmenuitem.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 5eba55a..3f7f22d 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -122,6 +122,7 @@ set_label (GtkMenuItem * menu_item, const gchar * label) if (child == NULL) { GtkWidget * labelw = gtk_label_new(label); gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE); + gtk_misc_set_alignment(GTK_MISC(labelw), 0.0, 0.5); gtk_container_add(GTK_CONTAINER(menu_item), labelw); gtk_widget_show(labelw); } else if (GTK_IS_LABEL(child)) { @@ -135,6 +136,7 @@ set_label (GtkMenuItem * menu_item, const gchar * label) /* We don't have a label, so we need to build */ labelw = gtk_label_new(label); gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE); + gtk_misc_set_alignment(GTK_MISC(labelw), 0.0, 0.5); gtk_box_pack_end(GTK_BOX(child), labelw, TRUE, TRUE, 0); gtk_widget_show(labelw); } else { -- cgit v1.2.3 From 186e1058f5142308a02ecf20ed4653a7862cd973 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 16 Dec 2009 23:17:59 -0600 Subject: Adding in an activate function so that we don't toggle our value on click. We're letting the application handle that. But, in turn, it turns out that is the only way to set the active property. So without an activate function, we can't set it. So, we're taking a lot more responsibility for setting it properly when we want to. --- libdbusmenu-gtk/genericmenuitem.c | 43 ++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 14 deletions(-) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 3f7f22d..09d5004 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -26,6 +26,7 @@ static void genericmenuitem_finalize (GObject *object); static void draw_indicator (GtkCheckMenuItem *check_menu_item, GdkRectangle *area); static void set_label (GtkMenuItem * menu_item, const gchar * label); static const gchar * get_label (GtkMenuItem * menu_item); +static void activate (GtkMenuItem * menu_item); /* GObject stuff */ G_DEFINE_TYPE (Genericmenuitem, genericmenuitem, GTK_TYPE_CHECK_MENU_ITEM); @@ -53,6 +54,7 @@ genericmenuitem_class_init (GenericmenuitemClass *klass) GtkMenuItemClass * menuitem_class = GTK_MENU_ITEM_CLASS (klass); menuitem_class->set_label = set_label; menuitem_class->get_label = get_label; + menuitem_class->activate = activate; return; } @@ -162,6 +164,14 @@ get_label (GtkMenuItem * menu_item) return NULL; } +/* Make sure we don't toggle when there is an + activate like a normal check menu item. */ +static void +activate (GtkMenuItem * menu_item) +{ + return; +} + /** genericmenuitem_set_check_type: @item: #Genericmenuitem to set the type on @@ -223,33 +233,38 @@ genericmenuitem_set_state (Genericmenuitem * item, GenericmenuitemState state) } item->priv->state = state; - GValue value = {0}; - g_value_init(&value, G_TYPE_BOOLEAN); + + GtkCheckMenuItem * check = GTK_CHECK_MENU_ITEM(item); + + gboolean old_active = check->active; + gboolean old_inconsist = check->inconsistent; switch (item->priv->state) { case GENERICMENUITEM_STATE_UNCHECKED: - g_value_set_boolean(&value, FALSE); - g_object_set_property(G_OBJECT(item), "active", &value); - g_value_set_boolean(&value, FALSE); - g_object_set_property(G_OBJECT(item), "inconsistent", &value); + check->active = FALSE; + check->inconsistent = FALSE; break; case GENERICMENUITEM_STATE_CHECKED: - g_value_set_boolean(&value, TRUE); - g_object_set_property(G_OBJECT(item), "active", &value); - g_value_set_boolean(&value, FALSE); - g_object_set_property(G_OBJECT(item), "inconsistent", &value); + check->active = TRUE; + check->inconsistent = FALSE; break; case GENERICMENUITEM_STATE_INDETERMINATE: - g_value_set_boolean(&value, TRUE); - g_object_set_property(G_OBJECT(item), "active", &value); - g_value_set_boolean(&value, TRUE); - g_object_set_property(G_OBJECT(item), "inconsistent", &value); + check->active = TRUE; + check->inconsistent = TRUE; break; default: g_warning("Generic Menuitem invalid check state: %d", state); return; } + if (old_active != check->active) { + g_object_notify(G_OBJECT(item), "active"); + } + + if (old_inconsist != check->inconsistent) { + g_object_notify(G_OBJECT(item), "inconsistent"); + } + gtk_widget_queue_draw(GTK_WIDGET(item)); return; -- cgit v1.2.3 From 339b68e8b1a816a9ee5d44fea3a98e0492c65885 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 17 Dec 2009 14:25:32 -0600 Subject: License headers. I hate these. --- libdbusmenu-gtk/genericmenuitem.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 09d5004..aff14ef 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -1,3 +1,31 @@ +/* +A menuitem subclass that has the ability to do lots of different +things depending on it's settings. + +Copyright 2009 Canonical Ltd. + +Authors: + Ted Gould + +This program is free software: you can redistribute it and/or modify it +under the terms of either or both of the following licenses: + +1) the GNU Lesser General Public License version 3, as published by the +Free Software Foundation; and/or +2) the GNU Lesser General Public License version 2.1, as published by +the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR +PURPOSE. See the applicable version of the GNU Lesser General Public +License for more details. + +You should have received a copy of both the GNU Lesser General Public +License version 3 and version 2.1 along with this program. If not, see + +*/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -- cgit v1.2.3 From 7f702b6234af4ec162997c16a3c4e8eb64afa8cb Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 17 Dec 2009 15:21:58 -0600 Subject: Trying to reduce the complexity of adding a label. Now we can detect the various cases and make sense of them. Which is kinda nice. More confident in this code. --- libdbusmenu-gtk/genericmenuitem.c | 91 +++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 23 deletions(-) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index aff14ef..0eb78dc 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -148,37 +148,66 @@ static void set_label (GtkMenuItem * menu_item, const gchar * label) { GtkWidget * child = gtk_bin_get_child(GTK_BIN(menu_item)); + GtkLabel * labelw = NULL; + gboolean suppress_update = FALSE; + + /* Try to find if we have a label already */ + if (child != NULL) { + if (GTK_IS_LABEL(child)) { + /* We've got a label, let's update it. */ + labelw = GTK_LABEL(child); + } else if (GTK_IS_BOX(child)) { + /* Look for the label in the box */ + gtk_container_foreach(GTK_CONTAINER(child), set_label_helper, &labelw); + } else { + /* We need to put the child into a new box and + make the box the child of the menu item. Basically + we're inserting a box in the middle. */ + GtkWidget * hbox = gtk_hbox_new(FALSE, 0); + g_object_ref(child); + gtk_container_remove(GTK_CONTAINER(menu_item), child); + gtk_box_pack_start(GTK_BOX(hbox), child, FALSE, FALSE, 0); + gtk_container_add(GTK_CONTAINER(menu_item), hbox); + gtk_widget_show(hbox); + g_object_unref(child); + child = hbox; + /* It's important to notice that labelw is not set + by this condition. There was no label to find. */ + } + } - if (child == NULL) { - GtkWidget * labelw = gtk_label_new(label); + /* No we can see if we need to ethier build a label or just + update the one that we already have. */ + if (labelw == NULL) { + /* Build it */ + labelw = GTK_LABEL(gtk_label_new(label)); gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE); gtk_misc_set_alignment(GTK_MISC(labelw), 0.0, 0.5); - gtk_container_add(GTK_CONTAINER(menu_item), labelw); - gtk_widget_show(labelw); - } else if (GTK_IS_LABEL(child)) { - gtk_label_set_label(GTK_LABEL(child), label); - } else if (GTK_IS_BOX(child)) { - GtkWidget * labelw = NULL; - /* Look for the label */ - gtk_container_foreach(GTK_CONTAINER(child), set_label_helper, &labelw); - - if (labelw == NULL) { - /* We don't have a label, so we need to build */ - labelw = gtk_label_new(label); - gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE); - gtk_misc_set_alignment(GTK_MISC(labelw), 0.0, 0.5); - gtk_box_pack_end(GTK_BOX(child), labelw, TRUE, TRUE, 0); - gtk_widget_show(labelw); + gtk_widget_show(GTK_WIDGET(labelw)); + + /* Check to see if it needs to be in the bin for this + menu item or whether it gets packed in a box. */ + if (child == NULL) { + gtk_container_add(GTK_CONTAINER(menu_item), GTK_WIDGET(labelw)); } else { - /* We can reset the label that we have. */ - gtk_label_set_label(GTK_LABEL(labelw), label); + gtk_box_pack_end(GTK_BOX(child), GTK_WIDGET(labelw), TRUE, TRUE, 0); } } else { - g_error("Generic item in an indeterminate state."); - return; + /* Oh, just an update. No biggie. */ + if (!g_strcmp0(label, gtk_label_get_label(labelw))) { + /* The only reason to suppress the update is if we had + a label and the value was the same as the one we're + getting in. */ + suppress_update = TRUE; + } else { + gtk_label_set_label(labelw, label); + } } - g_object_notify(G_OBJECT(menu_item), "label"); + /* If we changed the value, tell folks. */ + if (!suppress_update) { + g_object_notify(G_OBJECT(menu_item), "label"); + } return; } @@ -187,7 +216,23 @@ set_label (GtkMenuItem * menu_item, const gchar * label) static const gchar * get_label (GtkMenuItem * menu_item) { + GtkWidget * child = gtk_bin_get_child(GTK_BIN(menu_item)); + GtkLabel * labelw = NULL; + + /* Try to find if we have a label already */ + if (child != NULL) { + if (GTK_IS_LABEL(child)) { + /* We've got a label, let's update it. */ + labelw = GTK_LABEL(child); + } else if (GTK_IS_BOX(child)) { + /* Look for the label in the box */ + gtk_container_foreach(GTK_CONTAINER(child), set_label_helper, &labelw); + } + } + if (labelw != NULL) { + return gtk_label_get_label(labelw); + } return NULL; } -- cgit v1.2.3 From ef5865fb14bb25ffbb05c6c22c7a74cb22a89f5e Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 17 Dec 2009 15:35:23 -0600 Subject: Fleshing out the image functions for our generic item. --- libdbusmenu-gtk/genericmenuitem.c | 70 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 0eb78dc..dded1de 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -343,6 +343,18 @@ genericmenuitem_set_state (Genericmenuitem * item, GenericmenuitemState state) return; } +/* A small helper to look through the widgets in the + box and find the one that is the image. */ +static void +set_image_helper (GtkWidget * widget, gpointer data) +{ + GtkWidget ** labelval = (GtkWidget **)data; + if (GTK_IS_IMAGE(widget)) { + *labelval = widget; + } + return; +} + /** genericmenuitem_set_image: @item: A #Genericmenuitem @@ -351,9 +363,49 @@ genericmenuitem_set_state (Genericmenuitem * item, GenericmenuitemState state) Sets the image of the menu item. */ void -genericmenuitem_set_image (Genericmenuitem * item, GtkWidget * image) +genericmenuitem_set_image (Genericmenuitem * menu_item, GtkWidget * image) { + GtkWidget * child = gtk_bin_get_child(GTK_BIN(menu_item)); + GtkImage * imagew = NULL; + /* Try to find if we have a label already */ + if (child != NULL) { + if (GTK_IS_IMAGE(child)) { + /* We've got a label, let's update it. */ + imagew = GTK_IMAGE(child); + } else if (GTK_IS_BOX(child)) { + /* Look for the label in the box */ + gtk_container_foreach(GTK_CONTAINER(child), set_image_helper, &imagew); + } else { + /* We need to put the child into a new box and + make the box the child of the menu item. Basically + we're inserting a box in the middle. */ + GtkWidget * hbox = gtk_hbox_new(FALSE, 0); + g_object_ref(child); + gtk_container_remove(GTK_CONTAINER(menu_item), child); + gtk_box_pack_end(GTK_BOX(hbox), child, TRUE, TRUE, 0); + gtk_container_add(GTK_CONTAINER(menu_item), hbox); + gtk_widget_show(hbox); + g_object_unref(child); + child = hbox; + /* It's important to notice that imagew is not set + by this condition. There was no label to find. */ + } + } + + /* No we can see if we need to ethier replace and image or + just put ourselves into the structures */ + if (imagew != NULL) { + gtk_widget_destroy(GTK_WIDGET(imagew)); + } + + /* Check to see if it needs to be in the bin for this + menu item or whether it gets packed in a box. */ + if (child == NULL) { + gtk_container_add(GTK_CONTAINER(menu_item), GTK_WIDGET(image)); + } else { + gtk_box_pack_start(GTK_BOX(child), GTK_WIDGET(image), FALSE, FALSE, 0); + } return; } @@ -368,9 +420,21 @@ genericmenuitem_set_image (Genericmenuitem * item, GtkWidget * image) if there isn't one. */ GtkWidget * -genericmenuitem_get_image (Genericmenuitem * item) +genericmenuitem_get_image (Genericmenuitem * menu_item) { + GtkWidget * child = gtk_bin_get_child(GTK_BIN(menu_item)); + GtkWidget * imagew = NULL; + /* Try to find if we have a label already */ + if (child != NULL) { + if (GTK_IS_IMAGE(child)) { + /* We've got a label, let's update it. */ + imagew = child; + } else if (GTK_IS_BOX(child)) { + /* Look for the label in the box */ + gtk_container_foreach(GTK_CONTAINER(child), set_image_helper, &imagew); + } + } - return NULL; + return imagew; } -- cgit v1.2.3 From 21b5c268ced2ded5ffe46be7f718e186eb2c834c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 17 Dec 2009 15:49:27 -0600 Subject: Handling the case of getting an image with the purpose of clearing the label. Also showing the image. --- libdbusmenu-gtk/genericmenuitem.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'libdbusmenu-gtk/genericmenuitem.c') diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index dded1de..f927556 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -376,7 +376,7 @@ genericmenuitem_set_image (Genericmenuitem * menu_item, GtkWidget * image) } else if (GTK_IS_BOX(child)) { /* Look for the label in the box */ gtk_container_foreach(GTK_CONTAINER(child), set_image_helper, &imagew); - } else { + } else if (image != NULL) { /* We need to put the child into a new box and make the box the child of the menu item. Basically we're inserting a box in the middle. */ @@ -401,10 +401,14 @@ genericmenuitem_set_image (Genericmenuitem * menu_item, GtkWidget * image) /* Check to see if it needs to be in the bin for this menu item or whether it gets packed in a box. */ - if (child == NULL) { - gtk_container_add(GTK_CONTAINER(menu_item), GTK_WIDGET(image)); - } else { - gtk_box_pack_start(GTK_BOX(child), GTK_WIDGET(image), FALSE, FALSE, 0); + if (image != NULL) { + if (child == NULL) { + gtk_container_add(GTK_CONTAINER(menu_item), GTK_WIDGET(image)); + } else { + gtk_box_pack_start(GTK_BOX(child), GTK_WIDGET(image), FALSE, FALSE, 0); + } + + gtk_widget_show(image); } return; -- cgit v1.2.3