summaryrefslogtreecommitdiff
path: root/libmdock/mdock-item-menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmdock/mdock-item-menu.c')
-rw-r--r--libmdock/mdock-item-menu.c209
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);
+}