diff options
Diffstat (limited to 'libmdock/mdock-item-menu.c')
-rw-r--r-- | libmdock/mdock-item-menu.c | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/libmdock/mdock-item-menu.c b/libmdock/mdock-item-menu.c new file mode 100644 index 0000000..e5e60fc --- /dev/null +++ b/libmdock/mdock-item-menu.c @@ -0,0 +1,209 @@ +/* + * Copyright 2015 Javier S. Pedro <dev.git@javispedro.com> + * + * This file is part of MDock. + * + * MDock is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MDock is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MDock. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <glib/gi18n.h> + +#include "mdock-item-menu.h" + +#define MDOCK_ITEM_MENU_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), MDOCK_TYPE_ITEM_MENU, MDockItemMenuPrivate)) + +struct _MDockItemMenuPrivate +{ + GtkSeparatorMenuItem *menu_sep1; + GtkImageMenuItem *menu_close_all; + GtkImageMenuItem *menu_pin; + GtkImageMenuItem *menu_launch; +}; + +G_DEFINE_TYPE (MDockItemMenu, mdock_item_menu, GTK_TYPE_MENU) + +enum { + PROP_0, + PROP_ITEM, + N_PROPERTIES +}; + +static GParamSpec *obj_properties[N_PROPERTIES] = { NULL }; + +static void handle_item_pinned(MDockItemMenu *self, GParamSpec *spec, MDockItem *item) +{ + const gboolean pinned = mdock_item_get_pinned(item); + gtk_menu_item_set_label(GTK_MENU_ITEM(self->priv->menu_pin), + pinned ? _("Un_pin") : _("_Pin")); +} + +static void handle_item_desktop_app_info(MDockItemMenu *self, GParamSpec *spec, MDockItem *item) +{ + GDesktopAppInfo *appinfo = mdock_item_get_desktop_app_info(item); + + gtk_widget_set_visible(GTK_WIDGET(self->priv->menu_pin), appinfo != NULL); + gtk_widget_set_visible(GTK_WIDGET(self->priv->menu_launch), appinfo != NULL); + + if (!gtk_image_menu_item_get_image(self->priv->menu_launch) && appinfo) { + gint width, height; + if (gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height)) { + GtkIconTheme *theme = gtk_icon_theme_get_default(); + gint icon_size = MAX(width, height); + GIcon *icon = g_app_info_get_icon(G_APP_INFO(appinfo)); + GtkIconInfo *info = gtk_icon_theme_lookup_by_gicon(theme, icon, icon_size, + GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_FORCE_SIZE); + if (info) { + GdkPixbuf *pixbuf = gtk_icon_info_load_icon(info, NULL); + if (pixbuf) { + GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf); + gtk_image_menu_item_set_image(self->priv->menu_launch, image); + g_object_unref(pixbuf); + } + gtk_icon_info_free(info); + } + } + } +} + +static void handle_item_n_windows(MDockItemMenu *self, GParamSpec *spec, MDockItem *item) +{ + gtk_widget_set_visible(GTK_WIDGET(self->priv->menu_close_all), + mdock_item_has_windows(item)); +} + +static void mdock_item_menu_set_property(GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + MDockItemMenu *self = MDOCK_ITEM_MENU(object); + switch (property_id) { + case PROP_ITEM: + g_clear_object(&self->item); + self->item = g_value_dup_object(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void mdock_item_menu_get_property(GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + MDockItemMenu *self = MDOCK_ITEM_MENU(object); + switch (property_id) { + case PROP_ITEM: + g_value_set_object(value, self->item); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void +mdock_item_menu_constructed(GObject *object) +{ + MDockItemMenu *self = MDOCK_ITEM_MENU(object); + + g_signal_connect_object(self->priv->menu_close_all, "activate", + G_CALLBACK(mdock_item_close_all_windows), self->item, + G_CONNECT_SWAPPED); + + g_signal_connect_object(self->priv->menu_pin, "activate", + G_CALLBACK(mdock_item_toggle_pinned), self->item, + G_CONNECT_SWAPPED); + + g_signal_connect_object(self->priv->menu_launch, "activate", + G_CALLBACK(mdock_item_launch), self->item, + G_CONNECT_SWAPPED); + + g_signal_connect_object(self->item, "notify::pinned", + G_CALLBACK(handle_item_pinned), self, + G_CONNECT_SWAPPED); + + g_signal_connect_object(self->item, "notify::desktop-app-info", + G_CALLBACK(handle_item_desktop_app_info), self, + G_CONNECT_SWAPPED); + + g_signal_connect_object(self->item, "notify::n-windows", + G_CALLBACK(handle_item_n_windows), self, + G_CONNECT_SWAPPED); + + handle_item_desktop_app_info(self, NULL, self->item); + handle_item_pinned(self, NULL, self->item); +} + + +static void +mdock_item_menu_dispose(GObject *object) +{ + MDockItemMenu *self = MDOCK_ITEM_MENU(object); + g_clear_object(&self->item); + G_OBJECT_CLASS (mdock_item_menu_parent_class)->dispose(object); +} + +static void +mdock_item_menu_finalize (GObject *object) +{ + G_OBJECT_CLASS (mdock_item_menu_parent_class)->finalize (object); +} + +static void +mdock_item_menu_init (MDockItemMenu *self) +{ + self->priv = MDOCK_ITEM_MENU_GET_PRIVATE (self); + + self->priv->menu_sep1 = GTK_SEPARATOR_MENU_ITEM(gtk_separator_menu_item_new()); + gtk_menu_shell_append(GTK_MENU_SHELL(self), GTK_WIDGET(self->priv->menu_sep1)); + + self->priv->menu_close_all = GTK_IMAGE_MENU_ITEM(gtk_image_menu_item_new_from_stock(GTK_STOCK_CLOSE, NULL)); + gtk_menu_shell_append(GTK_MENU_SHELL(self), GTK_WIDGET(self->priv->menu_close_all)); + + self->priv->menu_pin = GTK_IMAGE_MENU_ITEM(gtk_image_menu_item_new_with_mnemonic(_("_Pin"))); + gtk_menu_shell_append(GTK_MENU_SHELL(self), GTK_WIDGET(self->priv->menu_pin)); + + self->priv->menu_launch = GTK_IMAGE_MENU_ITEM(gtk_image_menu_item_new_with_mnemonic(_("_New instance"))); + gtk_menu_shell_append(GTK_MENU_SHELL(self), GTK_WIDGET(self->priv->menu_launch)); +} + +static void +mdock_item_menu_class_init (MDockItemMenuClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS (klass); + obj_class->set_property = mdock_item_menu_set_property; + obj_class->get_property = mdock_item_menu_get_property; + obj_class->constructed = mdock_item_menu_constructed; + obj_class->dispose = mdock_item_menu_dispose; + obj_class->finalize = mdock_item_menu_finalize; + + g_type_class_add_private(obj_class, sizeof(MDockItemMenuPrivate)); + + obj_properties[PROP_ITEM] = g_param_spec_object("item", + "The MDockItem the options in this menu apply to", + "Set the MDockItem the options in this menu apply to", + MDOCK_TYPE_ITEM, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(obj_class, N_PROPERTIES, obj_properties); +} + +MDockItemMenu * +mdock_item_menu_new(MDockItem *item) +{ + return g_object_new(MDOCK_TYPE_ITEM_MENU, "item", item, NULL); +} |