aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-gtk/genericmenuitem.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdbusmenu-gtk/genericmenuitem.c')
-rw-r--r--libdbusmenu-gtk/genericmenuitem.c173
1 files changed, 133 insertions, 40 deletions
diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c
index 2af70f3..5488f93 100644
--- a/libdbusmenu-gtk/genericmenuitem.c
+++ b/libdbusmenu-gtk/genericmenuitem.c
@@ -30,9 +30,11 @@ License version 3 and version 2.1 along with this program. If not, see
#include "config.h"
#endif
+#include <gdk/gdk.h>
+
#include "genericmenuitem.h"
-/**
+/*
GenericmenuitemPrivate:
@check_type: What type of check we have, or none at all.
@state: What the state of our check is.
@@ -40,6 +42,7 @@ License version 3 and version 2.1 along with this program. If not, see
struct _GenericmenuitemPrivate {
GenericmenuitemCheckType check_type;
GenericmenuitemState state;
+ GenericmenuitemDisposition disposition;
};
/* Private macro */
@@ -102,6 +105,7 @@ genericmenuitem_init (Genericmenuitem *self)
self->priv->check_type = GENERICMENUITEM_CHECK_TYPE_NONE;
self->priv->state = GENERICMENUITEM_STATE_UNCHECKED;
+ self->priv->disposition = GENERICMENUITEM_DISPOSITION_NORMAL;
return;
}
@@ -165,18 +169,61 @@ set_label_helper (GtkWidget * widget, gpointer data)
style. It should be considered for caching when
optimizing. */
static gint
-get_hpadding (GtkWidget * widget)
+get_toggle_space (GtkWidget * widget)
{
gint padding = 0;
- gtk_widget_style_get(widget, "horizontal-padding", &padding, NULL);
+ gtk_widget_style_get(widget, "toggle-spacing", &padding, NULL);
return padding;
}
+/* Get the value to put in the span for the disposition */
+static gchar *
+get_text_color (GenericmenuitemDisposition disposition, GtkWidget * widget)
+{
+ struct {const gchar * color_name; const gchar * default_color;} values[] = {
+ /* NORMAL */ { NULL, NULL},
+ /* INFO */ { "informational-color", "blue"},
+ /* WARN */ { "warning-color", "orange"},
+ /* ALERT */ { "error-color", "red"}
+ };
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ GtkStyleContext * context = gtk_widget_get_style_context(widget);
+ GdkRGBA color;
+
+ if (gtk_style_context_lookup_color(context, values[disposition].color_name, &color)) {
+ return g_strdup_printf("rgb(%d, %d, %d)", (gint)(color.red * 255), (gint)(color.green * 255), (gint)(color.blue * 255));
+ }
+#endif
+
+ return g_strdup(values[disposition].default_color);
+}
+
/* Set the label on the item */
static void
-set_label (GtkMenuItem * menu_item, const gchar * label)
+set_label (GtkMenuItem * menu_item, const gchar * in_label)
{
- if (label == NULL) return;
+ if (in_label == NULL) return;
+
+ /* Build a label that might include the colors of the disposition
+ so that it gets rendered in the menuitem. */
+ gchar * local_label = NULL;
+ switch (GENERICMENUITEM(menu_item)->priv->disposition) {
+ case GENERICMENUITEM_DISPOSITION_NORMAL:
+ local_label = g_strdup(in_label);
+ break;
+ case GENERICMENUITEM_DISPOSITION_INFORMATIONAL:
+ case GENERICMENUITEM_DISPOSITION_WARNING:
+ case GENERICMENUITEM_DISPOSITION_ALERT: {
+ gchar * color = get_text_color(GENERICMENUITEM(menu_item)->priv->disposition, GTK_WIDGET(menu_item));
+ local_label = g_markup_printf_escaped("<span fgcolor=\"%s\">%s</span>", color, in_label);
+ g_free(color);
+ break;
+ }
+ default:
+ g_warn_if_reached();
+ break;
+ }
GtkWidget * child = gtk_bin_get_child(GTK_BIN(menu_item));
GtkLabel * labelw = NULL;
@@ -194,10 +241,10 @@ set_label (GtkMenuItem * menu_item, const gchar * label)
/* 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);
+ GtkWidget * hbox = gtk_hbox_new(FALSE, get_toggle_space(GTK_WIDGET(menu_item)));
g_object_ref(child);
gtk_container_remove(GTK_CONTAINER(menu_item), child);
- gtk_box_pack_start(GTK_BOX(hbox), child, FALSE, FALSE, get_hpadding(GTK_WIDGET(menu_item)));
+ 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);
@@ -211,10 +258,12 @@ set_label (GtkMenuItem * menu_item, const gchar * label)
update the one that we already have. */
if (labelw == NULL) {
/* Build it */
- labelw = GTK_LABEL(gtk_accel_label_new(label));
+ labelw = GTK_LABEL(gtk_accel_label_new(local_label));
gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE);
+ gtk_label_set_use_markup(GTK_LABEL(labelw), TRUE);
gtk_misc_set_alignment(GTK_MISC(labelw), 0.0, 0.5);
gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(labelw), GTK_WIDGET(menu_item));
+ gtk_label_set_markup_with_mnemonic(labelw, local_label);
gtk_widget_show(GTK_WIDGET(labelw));
/* Check to see if it needs to be in the bin for this
@@ -222,17 +271,17 @@ set_label (GtkMenuItem * menu_item, const gchar * label)
if (child == NULL) {
gtk_container_add(GTK_CONTAINER(menu_item), GTK_WIDGET(labelw));
} else {
- gtk_box_pack_end(GTK_BOX(child), GTK_WIDGET(labelw), TRUE, TRUE, get_hpadding(GTK_WIDGET(menu_item)));
+ gtk_box_pack_end(GTK_BOX(child), GTK_WIDGET(labelw), TRUE, TRUE, 0);
}
} else {
/* Oh, just an update. No biggie. */
- if (!g_strcmp0(label, gtk_label_get_label(labelw))) {
+ if (!g_strcmp0(local_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);
+ gtk_label_set_markup_with_mnemonic(labelw, local_label);
}
}
@@ -241,6 +290,12 @@ set_label (GtkMenuItem * menu_item, const gchar * label)
g_object_notify(G_OBJECT(menu_item), "label");
}
+ /* Clean up this */
+ if (local_label != NULL) {
+ g_free(local_label);
+ local_label = NULL;
+ }
+
return;
}
@@ -278,12 +333,12 @@ activate (GtkMenuItem * menu_item)
}
/**
- 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.
+ * 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)
@@ -317,14 +372,14 @@ genericmenuitem_set_check_type (Genericmenuitem * item, GenericmenuitemCheckType
}
/**
- 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.
-*/
+ * 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)
{
@@ -377,11 +432,11 @@ set_image_helper (GtkWidget * widget, gpointer data)
}
/**
- genericmenuitem_set_image:
- @item: A #Genericmenuitem
- @image: The image to set as the image of @item
-
- Sets the image of the menu item.
+ * 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 * menu_item, GtkWidget * image)
@@ -401,10 +456,10 @@ genericmenuitem_set_image (Genericmenuitem * menu_item, GtkWidget * image)
/* 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);
+ GtkWidget * hbox = gtk_hbox_new(FALSE, get_toggle_space(GTK_WIDGET(menu_item)));
g_object_ref(child);
gtk_container_remove(GTK_CONTAINER(menu_item), child);
- gtk_box_pack_end(GTK_BOX(hbox), child, TRUE, TRUE, get_hpadding(GTK_WIDGET(menu_item)));
+ 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);
@@ -429,7 +484,7 @@ genericmenuitem_set_image (Genericmenuitem * menu_item, GtkWidget * image)
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, get_hpadding(GTK_WIDGET(menu_item)));
+ gtk_box_pack_start(GTK_BOX(child), GTK_WIDGET(image), FALSE, FALSE, 0);
}
gtk_widget_show(image);
@@ -439,13 +494,13 @@ genericmenuitem_set_image (Genericmenuitem * menu_item, GtkWidget * image)
}
/**
- 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.
+ * genericmenuitem_get_image:
+ * @item: A #Genericmenuitem
+ *
+ * Returns the image if there is one.
+ *
+ * Return value: (transfer none): A pointer to the image of the item or #NULL
+ * if there isn't one.
*/
GtkWidget *
genericmenuitem_get_image (Genericmenuitem * menu_item)
@@ -466,3 +521,41 @@ genericmenuitem_get_image (Genericmenuitem * menu_item)
return imagew;
}
+
+/**
+ * genericmenuitem_set_disposition:
+ * @item: A #Genericmenuitem
+ * @disposition: The disposition of the item
+ *
+ * Sets the disposition of the menuitem.
+ */
+void
+genericmenuitem_set_disposition (Genericmenuitem * item, GenericmenuitemDisposition disposition)
+{
+ g_return_if_fail(IS_GENERICMENUITEM(item));
+
+ if (item->priv->disposition == disposition)
+ return;
+
+ item->priv->disposition = disposition;
+
+ set_label(GTK_MENU_ITEM(item), get_label(GTK_MENU_ITEM(item)));
+
+ return;
+}
+
+/**
+ * genericmenuitem_get_disposition:
+ * @item: A #Genericmenuitem
+ *
+ * Gets the disposition of the menuitem.
+ *
+ * Return value: The disposition of the menuitem.
+ */
+GenericmenuitemDisposition
+genericmenuitem_get_disposition (Genericmenuitem * item)
+{
+ g_return_val_if_fail(IS_GENERICMENUITEM(item), GENERICMENUITEM_DISPOSITION_NORMAL);
+
+ return item->priv->disposition;
+}