diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 25 | ||||
-rw-r--r-- | src/idoalarmmenuitem.c | 4 | ||||
-rw-r--r-- | src/idoappointmentmenuitem.c | 3 | ||||
-rw-r--r-- | src/idobasicmenuitem.c | 65 | ||||
-rw-r--r-- | src/idolevelmenuitem.c | 294 | ||||
-rw-r--r-- | src/idolevelmenuitem.h | 52 | ||||
-rw-r--r-- | src/idolocationmenuitem.c | 3 | ||||
-rw-r--r-- | src/idomediaplayermenuitem.c | 2 | ||||
-rw-r--r-- | src/idomenuitemfactory.c | 6 | ||||
-rw-r--r-- | src/idoplaybackmenuitem.c | 10 | ||||
-rw-r--r-- | src/idoprogressmenuitem.c | 129 | ||||
-rw-r--r-- | src/idoremovablemenuitem.c | 21 | ||||
-rw-r--r-- | src/idoscalemenuitem.c | 38 | ||||
-rw-r--r-- | src/idousermenuitem.c | 4 |
14 files changed, 516 insertions, 140 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d0f023e..5b3638d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,6 +39,7 @@ set(HEADERS idoscalemenuitem.h idodetaillabel.h idoentrymenuitem.h + idolevelmenuitem.h ) set(SOURCES @@ -65,6 +66,7 @@ set(SOURCES idousermenuitem.c idosourcemenuitem.c idotimeline.c + idolevelmenuitem.c ${CMAKE_CURRENT_BINARY_DIR}/idotypebuiltins.c ) @@ -95,19 +97,16 @@ add_custom_command( # ayatana-ido3-0.4.so -set_source_files_properties(${SOURCES} PROPERTIES COMPILE_FLAGS ${COMPILE_FLAGS}) add_library("ayatana-ido3-0.4" SHARED ${SOURCES}) set_target_properties("ayatana-ido3-0.4" PROPERTIES VERSION 0.0.0 SOVERSION 0) -target_link_libraries("ayatana-ido3-0.4" ${PROJECT_DEPS_LIBRARIES}) +target_link_libraries("ayatana-ido3-0.4" ${PROJECT_DEPS_LIBRARIES} m) target_include_directories("ayatana-ido3-0.4" PUBLIC ${PROJECT_DEPS_INCLUDE_DIRS}) target_include_directories("ayatana-ido3-0.4" PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories("ayatana-ido3-0.4" PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_compile_definitions("ayatana-ido3-0.4" PUBLIC G_LOG_DOMAIN="IDO") -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libayatana-ido3-0.4.so" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}") -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libayatana-ido3-0.4.so.0" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}") -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libayatana-ido3-0.4.so.0.0.0" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}") +install(TARGETS "ayatana-ido3-0.4" LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}") -# ayatana-ido3-0.4.gir +# AyatanaIdo3-0.4.gir find_package(GObjectIntrospection REQUIRED QUIET) @@ -137,6 +136,7 @@ if (INTROSPECTION_FOUND) --pkg=gtk+-3.0 --warn-all --include=Gtk-3.0 + --c-include="libayatana-ido/libayatana-ido.h" --library="ayatana-ido3-0.4" --library-path=${CMAKE_CURRENT_BINARY_DIR} --output "${CMAKE_CURRENT_BINARY_DIR}/AyatanaIdo3-0.4.gir" @@ -144,7 +144,7 @@ if (INTROSPECTION_FOUND) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AyatanaIdo3-0.4.gir" DESTINATION "${CMAKE_INSTALL_FULL_DATADIR}/gir-1.0") - # ayatana-ido3-0.4.typelib + # AyatanaIdo3-0.4.typelib add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AyatanaIdo3-0.4.typelib" @@ -159,27 +159,26 @@ if (INTROSPECTION_FOUND) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AyatanaIdo3-0.4.typelib" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/girepository-1.0") - - # ayatana-ido3-0.4.vapi + # libayatana-ido3-0.4.vapi find_package(Vala REQUIRED QUIET) if (VALA_FOUND) add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AyatanaIdo3-0.4.vapi" + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libayatana-ido3-0.4.vapi" DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/AyatanaIdo3-0.4.typelib" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${VAPI_GEN} - --library=AyatanaIdo3-0.4 + --library=libayatana-ido3-0.4 --pkg gtk+-3.0 AyatanaIdo3-0.4.gir ) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AyatanaIdo3-0.4.vapi" DESTINATION "${CMAKE_INSTALL_FULL_DATADIR}/vala/vapi") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libayatana-ido3-0.4.vapi" DESTINATION "${CMAKE_INSTALL_FULL_DATADIR}/vala/vapi") - add_custom_target("src" ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/AyatanaIdo3-0.4.vapi") + add_custom_target("src" ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libayatana-ido3-0.4.vapi") endif () diff --git a/src/idoalarmmenuitem.c b/src/idoalarmmenuitem.c index 7b70e6d..1547809 100644 --- a/src/idoalarmmenuitem.c +++ b/src/idoalarmmenuitem.c @@ -1,9 +1,11 @@ /* * Copyright 2013 Canonical Ltd. + * Copyright 2021-2023 Robert Tari * * Authors: * Charles Kerr <charles.kerr@canonical.com> * Ted Gould <ted@canonical.com> + * Robert Tari <robert@tari.in> * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published @@ -91,8 +93,6 @@ ido_alarm_menu_item_new_from_model (GMenuItem * menu_item, for (i=0; i<n; i++) g_value_unset (&values[i]); - g_free(names); - /* add an ActionHelper */ if (g_menu_item_get_attribute (menu_item, "action", "s", &str)) diff --git a/src/idoappointmentmenuitem.c b/src/idoappointmentmenuitem.c index 0219c2c..dcdc3a8 100644 --- a/src/idoappointmentmenuitem.c +++ b/src/idoappointmentmenuitem.c @@ -1,6 +1,6 @@ /* * Copyright 2013 Canonical Ltd. - * Copyright 2021 Robert Tari + * Copyright 2021-2023 Robert Tari * * Authors: * Charles Kerr <charles.kerr@canonical.com> @@ -136,6 +136,7 @@ ido_appointment_menu_item_new_from_model (GMenuItem * menu_item, for (i=0; i<n; i++) g_value_unset (&values[i]); + g_free (values); /* add an ActionHelper */ diff --git a/src/idobasicmenuitem.c b/src/idobasicmenuitem.c index 29444ab..5106144 100644 --- a/src/idobasicmenuitem.c +++ b/src/idobasicmenuitem.c @@ -1,6 +1,6 @@ /* * Copyright 2013 Canonical Ltd. - * Copyright 2021 Robert Tari + * Copyright 2021-2023 Robert Tari * * Authors: * Charles Kerr <charles.kerr@canonical.com> @@ -20,7 +20,7 @@ */ #include <gtk/gtk.h> - +#include "idodetaillabel.h" #include "idoactionhelper.h" #include "idobasicmenuitem.h" @@ -126,6 +126,7 @@ my_dispose (GObject * object) g_clear_object (&p->icon); g_clear_object (&p->pPixbuf); + g_clear_object (&p->secondary_label); G_OBJECT_CLASS (ido_basic_menu_item_parent_class)->dispose (object); } @@ -162,25 +163,8 @@ ido_basic_menu_item_update_image (IdoBasicMenuItem *self) } else if (p->icon) { - GtkIconInfo *info; - const gchar *filename; - - info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default (), p->icon, 16, 0); - filename = gtk_icon_info_get_filename (info); - - if (filename) - { - GdkPixbuf *pixbuf; - - pixbuf = gdk_pixbuf_new_from_file_at_scale (filename, -1, 16, TRUE, NULL); - gtk_image_set_from_pixbuf (GTK_IMAGE (p->image), pixbuf); - - g_object_unref (pixbuf); - } - - gtk_widget_set_visible (p->image, filename != NULL); - - g_object_unref (info); + gtk_image_set_from_gicon (GTK_IMAGE (p->image), p->icon, GTK_ICON_SIZE_MENU); + gtk_widget_set_visible (p->image, TRUE); } } } @@ -258,9 +242,10 @@ ido_basic_menu_item_init (IdoBasicMenuItem *self) p->label = gtk_label_new (""); gtk_widget_set_halign(p->label, GTK_ALIGN_START); gtk_widget_set_valign(p->label, GTK_ALIGN_CENTER); - p->secondary_label = gtk_label_new (""); + p->secondary_label = g_object_ref (ido_detail_label_new ("")); gtk_widget_set_halign(p->secondary_label, GTK_ALIGN_END); gtk_widget_set_valign(p->secondary_label, GTK_ALIGN_CENTER); + gtk_style_context_add_class (gtk_widget_get_style_context (p->secondary_label), "accelerator"); w = gtk_grid_new (); grid = GTK_GRID (w); @@ -370,12 +355,25 @@ ido_basic_menu_item_set_secondary_text (IdoBasicMenuItem * self, const char * se { g_free (p->secondary_text); p->secondary_text = g_strdup (secondary_text); + ido_detail_label_set_text (IDO_DETAIL_LABEL (p->secondary_label), p->secondary_text); + gtk_widget_set_visible (p->secondary_label, (gboolean)(p->secondary_text && *p->secondary_text)); + } +} - g_object_set (G_OBJECT(p->secondary_label), - "label", p->secondary_text, - "visible", (gboolean)(p->secondary_text && *p->secondary_text), - NULL); +void ido_basic_menu_item_set_secondary_count (IdoBasicMenuItem *self, gint nCount) +{ + IdoBasicMenuItemPrivate *pPrivate = ido_basic_menu_item_get_instance_private (self); + gchar *sSecondaryText = g_strdup_printf("%i", nCount); + + if (g_strcmp0 (pPrivate->secondary_text, sSecondaryText)) + { + g_free (pPrivate->secondary_text); + pPrivate->secondary_text = g_strdup (sSecondaryText); + ido_detail_label_set_count (IDO_DETAIL_LABEL (pPrivate->secondary_label), nCount); + gtk_widget_set_visible (pPrivate->secondary_label, (gboolean)(pPrivate->secondary_text && *pPrivate->secondary_text)); } + + g_free (sSecondaryText); } static void @@ -410,6 +408,21 @@ ido_basic_menu_item_new_from_model (GMenuItem * menu_item, g_free (label); } + gchar *sSecondaryText; + + if (g_menu_item_get_attribute (menu_item, "x-ayatana-secondary-text", "s", &sSecondaryText)) + { + ido_basic_menu_item_set_secondary_text (IDO_BASIC_MENU_ITEM (item), sSecondaryText); + g_free (sSecondaryText); + } + + guint nSecondaryCount; + + if (g_menu_item_get_attribute (menu_item, "x-ayatana-secondary-count", "i", &nSecondaryCount)) + { + ido_basic_menu_item_set_secondary_count (IDO_BASIC_MENU_ITEM (item), nSecondaryCount); + } + serialized_icon = g_menu_item_get_attribute_value (menu_item, "icon", NULL); if (serialized_icon) { diff --git a/src/idolevelmenuitem.c b/src/idolevelmenuitem.c new file mode 100644 index 0000000..5f4f5bb --- /dev/null +++ b/src/idolevelmenuitem.c @@ -0,0 +1,294 @@ +/* + * Copyright 2023 Robert Tari + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, 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 GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Robert Tari <robert@tari.in> + */ + +#include "idolevelmenuitem.h" +#include "idoactionhelper.h" + +enum +{ + PROP_0, + PROP_ICON, + PROP_TEXT, + PROP_LEVEL, + PROP_LAST +}; + +static GParamSpec *lProperties[PROP_LAST]; + +typedef struct +{ + GIcon *pIcon; + gchar *sText; + GtkWidget *pLabel; + GtkWidget *pImage; + GtkWidget *pLevelBar; + IdoActionHelper *pHelper; + +} IdoLevelMenuItemPrivate; + +static GParamSpec *lProperties[PROP_LAST]; + +G_DEFINE_TYPE_WITH_PRIVATE (IdoLevelMenuItem, ido_level_menu_item, GTK_TYPE_MENU_ITEM) + +static void onGetProperty (GObject *pObject, guint nProperty, GValue *pValue, GParamSpec *pParamSpec) +{ + IdoLevelMenuItem *self = IDO_LEVEL_MENU_ITEM (pObject); + IdoLevelMenuItemPrivate *pPrivate = ido_level_menu_item_get_instance_private (self); + + switch (nProperty) + { + case PROP_ICON: + { + g_value_set_object (pValue, pPrivate->pIcon); + + break; + } + case PROP_TEXT: + { + g_value_set_string (pValue, pPrivate->sText); + + break; + } + case PROP_LEVEL: + { + guint16 nLevel = (guint16) gtk_level_bar_get_value (GTK_LEVEL_BAR (pPrivate->pLevelBar)); + g_value_set_uint (pValue, (guint16) nLevel); + + break; + } + default: + { + G_OBJECT_WARN_INVALID_PROPERTY_ID (pObject, nProperty, pParamSpec); + + break; + } + } +} + +static void onSetProperty (GObject *pObject, guint nProperty, const GValue *pValue, GParamSpec *pParamSpec) +{ + IdoLevelMenuItem *self = IDO_LEVEL_MENU_ITEM(pObject); + + switch (nProperty) + { + case PROP_ICON: + { + idoLevelMenuItemSetIcon (self, g_value_get_object (pValue)); + + break; + } + case PROP_TEXT: + { + idoLevelMenuItemSetText (self, g_value_get_string (pValue)); + + break; + } + case PROP_LEVEL: + { + idoLevelMenuItemSetLevel (self, g_value_get_uint (pValue)); + + break; + } + default: + { + G_OBJECT_WARN_INVALID_PROPERTY_ID (pObject, nProperty, pParamSpec); + + break; + } + } +} + +static void onDispose (GObject *pObject) +{ + IdoLevelMenuItem *self = IDO_LEVEL_MENU_ITEM (pObject); + IdoLevelMenuItemPrivate *pPrivate = ido_level_menu_item_get_instance_private (self); + + g_clear_object (&pPrivate->pIcon); + G_OBJECT_CLASS (ido_level_menu_item_parent_class)->dispose(pObject); +} + +static void onFinalize(GObject *pObject) +{ + IdoLevelMenuItem *self = IDO_LEVEL_MENU_ITEM (pObject); + IdoLevelMenuItemPrivate *pPrivate = ido_level_menu_item_get_instance_private (self); + + g_free (pPrivate->sText); + G_OBJECT_CLASS (ido_level_menu_item_parent_class)->finalize (pObject); +} + +static void idoLevelMenuItemStyleUpdateImage (IdoLevelMenuItem *self) +{ + IdoLevelMenuItemPrivate *pPrivate = ido_level_menu_item_get_instance_private (self); + + gtk_image_clear (GTK_IMAGE (pPrivate->pImage)); + + if (pPrivate->pIcon == NULL) + { + gtk_widget_set_visible (pPrivate->pImage, FALSE); + } + else + { + gtk_image_set_from_gicon (GTK_IMAGE (pPrivate->pImage), pPrivate->pIcon, GTK_ICON_SIZE_MENU); + gtk_widget_set_visible (pPrivate->pImage, TRUE); + } +} + +static void onStyleUpdated (GtkWidget *pWidget) +{ + GTK_WIDGET_CLASS (ido_level_menu_item_parent_class)->style_updated (pWidget); + idoLevelMenuItemStyleUpdateImage (IDO_LEVEL_MENU_ITEM (pWidget)); + gtk_widget_queue_draw (pWidget); +} + +static void onActivate (GtkMenuItem *item, gpointer pData) +{ + IdoActionHelper *pHelper = pData; + ido_action_helper_activate (pHelper); +} + +static void ido_level_menu_item_class_init (IdoLevelMenuItemClass *klass) +{ + GObjectClass *pObject = G_OBJECT_CLASS (klass); + GtkWidgetClass *pWidget = GTK_WIDGET_CLASS (klass); + pObject->get_property = onGetProperty; + pObject->set_property = onSetProperty; + pObject->dispose = onDispose; + pObject->finalize = onFinalize; + pWidget->style_updated = onStyleUpdated; + + GParamFlags nParamFlags = G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS; + lProperties[PROP_ICON] = g_param_spec_object ("icon", "Icon", "The menuitem's GIcon", G_TYPE_OBJECT, nParamFlags); + lProperties[PROP_TEXT] = g_param_spec_string ("text", "Text", "The menuitem's text", "", nParamFlags); + lProperties[PROP_LEVEL] = g_param_spec_uint ("level", "Level", "The menuitem's level bar value", 0, 100, 0, nParamFlags); + + g_object_class_install_properties(pObject, PROP_LAST, lProperties); +} + +static void ido_level_menu_item_init (IdoLevelMenuItem *self) +{ + IdoLevelMenuItemPrivate *pPrivate = ido_level_menu_item_get_instance_private (self); + pPrivate->pHelper = NULL; + pPrivate->pImage = gtk_image_new(); + pPrivate->pLabel = gtk_label_new(""); + pPrivate->pLevelBar = gtk_level_bar_new_for_interval (0.0, 100.0); + gtk_level_bar_add_offset_value (GTK_LEVEL_BAR (pPrivate->pLevelBar), GTK_LEVEL_BAR_OFFSET_LOW, 20.0); + gtk_level_bar_add_offset_value (GTK_LEVEL_BAR (pPrivate->pLevelBar), GTK_LEVEL_BAR_OFFSET_HIGH, 90.0); + gtk_level_bar_add_offset_value (GTK_LEVEL_BAR (pPrivate->pLevelBar), GTK_LEVEL_BAR_OFFSET_FULL, 100.0); + + GtkWidget *pGrid = gtk_grid_new (); + gtk_grid_attach (GTK_GRID (pGrid), pPrivate->pImage, 0, 0, 1, 2); + gtk_grid_attach (GTK_GRID (pGrid), pPrivate->pLabel, 1, 0, 1, 1); + gtk_grid_attach (GTK_GRID (pGrid), pPrivate->pLevelBar, 1, 1, 1, 1); + + g_object_set (pPrivate->pImage, "halign", GTK_ALIGN_START, "hexpand", FALSE, "valign", GTK_ALIGN_START, "margin-right", 6, NULL); + g_object_set (pPrivate->pLabel, "halign", GTK_ALIGN_START, "hexpand", TRUE, "valign", GTK_ALIGN_CENTER, NULL); + + gtk_widget_show_all (pGrid); + gtk_container_add (GTK_CONTAINER(self), pGrid); +} + +GtkWidget* ido_level_menu_item_new () +{ + return GTK_WIDGET (g_object_new (IDO_TYPE_LEVEL_MENU_ITEM, NULL)); +} + +void idoLevelMenuItemSetIcon (IdoLevelMenuItem *self, GIcon *pIcon) +{ + IdoLevelMenuItemPrivate *pPrivate = ido_level_menu_item_get_instance_private (self); + + if (pPrivate->pIcon != pIcon) + { + if (pPrivate->pIcon) + { + g_object_unref (pPrivate->pIcon); + } + + pPrivate->pIcon = pIcon ? g_object_ref (pIcon) : NULL; + idoLevelMenuItemStyleUpdateImage (self); + } +} + +void idoLevelMenuItemSetText (IdoLevelMenuItem *self, const char *sText) +{ + IdoLevelMenuItemPrivate *pPrivate = ido_level_menu_item_get_instance_private (self); + + if (g_strcmp0(pPrivate->sText, sText)) + { + g_free (pPrivate->sText); + pPrivate->sText = g_strdup (sText); + + g_object_set (G_OBJECT (pPrivate->pLabel), "label", pPrivate->sText, "visible", (gboolean)(pPrivate->sText && *pPrivate->sText), NULL); + } +} + +void idoLevelMenuItemSetLevel (IdoLevelMenuItem *self, guint16 nLevel) +{ + IdoLevelMenuItemPrivate *pPrivate = ido_level_menu_item_get_instance_private (self); + + gtk_level_bar_set_value (GTK_LEVEL_BAR (pPrivate->pLevelBar), (gdouble)nLevel); +} + +GtkMenuItem* ido_level_menu_item_new_from_model (GMenuItem *pMenuItem, GActionGroup *pActionGroup) +{ + GtkWidget *pItem = ido_level_menu_item_new (); + IdoLevelMenuItemPrivate *pPrivate = ido_level_menu_item_get_instance_private (IDO_LEVEL_MENU_ITEM (pItem)); + + gchar *sLabel; + + if (g_menu_item_get_attribute (pMenuItem, "label", "s", &sLabel)) + { + idoLevelMenuItemSetText (IDO_LEVEL_MENU_ITEM (pItem), sLabel); + g_free (sLabel); + } + + GVariant *sIcon = g_menu_item_get_attribute_value (pMenuItem, "icon", NULL); + + if (sIcon) + { + GIcon *pIcon = g_icon_deserialize (sIcon); + idoLevelMenuItemSetIcon (IDO_LEVEL_MENU_ITEM (pItem), pIcon); + g_object_unref (pIcon); + g_variant_unref (sIcon); + } + + guint16 nProgress = 0; + + if (g_menu_item_get_attribute (pMenuItem, "x-ayatana-level", "q", &nProgress)) + { + idoLevelMenuItemSetLevel (IDO_LEVEL_MENU_ITEM (pItem), nProgress); + } + + gchar *sAction; + + if (g_menu_item_get_attribute (pMenuItem, "action", "s", &sAction)) + { + GVariant *sTarget = g_menu_item_get_attribute_value (pMenuItem, "target", NULL); + pPrivate->pHelper = ido_action_helper_new (pItem, pActionGroup, sAction, sTarget); + g_signal_connect_object (pItem, "activate", G_CALLBACK (onActivate), pPrivate->pHelper, 0); + g_signal_connect_swapped (pItem, "destroy", G_CALLBACK (g_object_unref), pPrivate->pHelper); + + if (sTarget) + { + g_variant_unref (sTarget); + } + + g_free (sAction); + } + + return GTK_MENU_ITEM (pItem); +} diff --git a/src/idolevelmenuitem.h b/src/idolevelmenuitem.h new file mode 100644 index 0000000..bba5bc9 --- /dev/null +++ b/src/idolevelmenuitem.h @@ -0,0 +1,52 @@ +/* + * Copyright 2023 Robert Tari + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, 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 GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Robert Tari <robert@tari.in> + */ + +#ifndef __IDO_LEVEL_MENU_ITEM_H__ +#define __IDO_LEVEL_MENU_ITEM_H__ + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define IDO_TYPE_LEVEL_MENU_ITEM (ido_level_menu_item_get_type ()) +#define IDO_LEVEL_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_TYPE_LEVEL_MENU_ITEM, IdoLevelMenuItem)) +#define IDO_IS_LEVEL_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_TYPE_LEVEL_MENU_ITEM)) + +typedef struct _IdoLevelMenuItem IdoLevelMenuItem; +typedef struct _IdoLevelMenuItemClass IdoLevelMenuItemClass; + +struct _IdoLevelMenuItemClass +{ + GtkMenuItemClass parent_class; +}; + +struct _IdoLevelMenuItem +{ + GtkMenuItem parent; +}; + +GType ido_level_menu_item_get_type (void) G_GNUC_CONST; +GtkWidget* ido_level_menu_item_new (); +GtkMenuItem* ido_level_menu_item_new_from_model (GMenuItem *pMenuItem, GActionGroup *pActionGroup); +void idoLevelMenuItemSetIcon (IdoLevelMenuItem *self, GIcon *pIcon); +void idoLevelMenuItemSetText (IdoLevelMenuItem *self, const char *sText); +void idoLevelMenuItemSetLevel (IdoLevelMenuItem *self, guint16 nLevel); + +G_END_DECLS + +#endif diff --git a/src/idolocationmenuitem.c b/src/idolocationmenuitem.c index 6999cc1..2748e54 100644 --- a/src/idolocationmenuitem.c +++ b/src/idolocationmenuitem.c @@ -1,8 +1,10 @@ /* * Copyright 2013 Canonical Ltd. + * Copyright 2023 Robert Tari * * Authors: * Charles Kerr <charles.kerr@canonical.com> + * Robert Tari <robert@tari.in> * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published @@ -337,6 +339,7 @@ ido_location_menu_item_new_from_model (GMenuItem * menu_item, for (i=0; i<n; i++) g_value_unset (&values[i]); + g_free (values); /* give it an ActionHelper */ diff --git a/src/idomediaplayermenuitem.c b/src/idomediaplayermenuitem.c index 801d57b..071c4af 100644 --- a/src/idomediaplayermenuitem.c +++ b/src/idomediaplayermenuitem.c @@ -1,5 +1,6 @@ /* * Copyright 2013 Canonical Ltd. + * Copyright 2023 Robert Tari * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published @@ -17,6 +18,7 @@ * Conor Curran <conor.curran@canonical.com> * Mirco Müller <mirco.mueller@canonical.com> * Lars Uebernickel <lars.uebernickel@canonical.com> + * Robert Tari <robert@tari.in> */ #include "idomediaplayermenuitem.h" diff --git a/src/idomenuitemfactory.c b/src/idomenuitemfactory.c index 7f9978c..85318d5 100644 --- a/src/idomenuitemfactory.c +++ b/src/idomenuitemfactory.c @@ -1,5 +1,6 @@ /* * Copyright 2013 Canonical Ltd. + * Copyright 2023 Robert Tari * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published @@ -15,6 +16,7 @@ * * Authors: * Lars Uebernickel <lars.uebernickel@canonical.com> + * Robert Tari <robert@tari.in> */ #include <gtk/gtk.h> @@ -33,6 +35,7 @@ #include "idoswitchmenuitem.h" #include "idoprogressmenuitem.h" #include "idoremovablemenuitem.h" +#include "idolevelmenuitem.h" #define IDO_TYPE_MENU_ITEM_FACTORY (ido_menu_item_factory_get_type ()) #define IDO_MENU_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_MENU_ITEM_FACTORY, IdoMenuItemFactory)) @@ -102,6 +105,9 @@ ido_menu_item_factory_create_menu_item (AyatanaMenuItemFactory *factory, else if (g_str_equal (type, "org.ayatana.indicator.removable")) item = ido_removable_menu_item_new_from_model (menuitem, actions); + else if (g_str_equal (type, "org.ayatana.indicator.level")) + item = ido_level_menu_item_new_from_model (menuitem, actions); + return item; } diff --git a/src/idoplaybackmenuitem.c b/src/idoplaybackmenuitem.c index 7f19718..fc42b6d 100644 --- a/src/idoplaybackmenuitem.c +++ b/src/idoplaybackmenuitem.c @@ -1,5 +1,6 @@ /* * Copyright 2013 Canonical Ltd. + * Copyright 2023 Robert Tari * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published @@ -18,6 +19,7 @@ * Mirco Müller <mirco.mueller@canonical.com> * Andrea Cimitan <andrea.cimitan@canonical.com> * Lars Uebernickel <lars.uebernickel@canonical.com> + * Robert Tari <robert@tari.in> */ #include "idoplaybackmenuitem.h" @@ -290,14 +292,8 @@ ido_playback_menu_item_button_release_event (GtkWidget *menuitem, GdkEventButton *event) { IdoPlaybackMenuItem *item = IDO_PLAYBACK_MENU_ITEM (menuitem); - Button button; - const gchar *action = action; - button = ido_playback_menu_item_get_button_at_pos (menuitem, event->x, event->y); - if (button != item->cur_pushed_button) - button = BUTTON_NONE; - - action = item->button_actions[item->cur_pushed_button]; + const gchar *action = item->button_actions[item->cur_pushed_button]; if (item->action_group && action) g_action_group_activate_action (item->action_group, action, NULL); diff --git a/src/idoprogressmenuitem.c b/src/idoprogressmenuitem.c index 004682e..821d0a6 100644 --- a/src/idoprogressmenuitem.c +++ b/src/idoprogressmenuitem.c @@ -1,19 +1,19 @@ /* - * Copyright 2013 Canonical Ltd. + * Copyright 2023 Robert Tari * * Authors: - * Charles Kerr <charles.kerr@canonical.com> + * Robert Tari <robert@tari.in> * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 3, as published + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, 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 + * 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 GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along + * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -21,85 +21,70 @@ #include "idobasicmenuitem.h" #include "idoactionhelper.h" -static void -on_progress_action_state_changed (IdoActionHelper * helper, - GVariant * state, - gpointer unused G_GNUC_UNUSED) +static void onActivate (GtkMenuItem *item, gpointer pData) { - IdoBasicMenuItem * ido_menu_item; - char * str; - - ido_menu_item = IDO_BASIC_MENU_ITEM (ido_action_helper_get_widget (helper)); - - g_return_if_fail (ido_menu_item != NULL); - g_return_if_fail (g_variant_is_of_type (state, G_VARIANT_TYPE_UINT32)); - - str = g_strdup_printf ("%"G_GUINT32_FORMAT"%%", g_variant_get_uint32 (state)); - ido_basic_menu_item_set_secondary_text (ido_menu_item, str); - g_free (str); + IdoActionHelper *pHelper = pData; + ido_action_helper_activate (pHelper); } /** * ido_progress_menu_item_new_from_model: - * @menu_item: the corresponding menuitem - * @actions: action group to tell when this GtkMenuItem is activated + * @pMenuItem: the corresponding menuitem + * @pActionGroup: action group to tell when this GtkMenuItem is activated * * Creates a new progress menuitem with properties initialized from * the menuitem's attributes. * * If the menuitem's 'action' attribute is set, trigger that action - * in @actions when this IdoBasicMenuItem is activated. + * in @pActionGroup when this IdoProgressMenuItem is activated. */ -GtkMenuItem * -ido_progress_menu_item_new_from_model (GMenuItem * menu_item, - GActionGroup * actions) +GtkMenuItem *ido_progress_menu_item_new_from_model (GMenuItem *pMenuItem, GActionGroup *pActionGroup) { - guint i; - guint n; - gchar * str; - IdoBasicMenuItem * ido_menu_item; - const gchar * names[1] = {0}; - GValue * values; - const guint n_max = 1; - - /* create the ido menuitem */; + IdoBasicMenuItem *pBasicMenuItem = NULL; + gchar *sLabel = NULL; - n = 0; - values = g_new0(GValue, n_max); - - if (g_menu_item_get_attribute (menu_item, "label", "s", &str)) + if (g_menu_item_get_attribute (pMenuItem, "label", "s", &sLabel)) { - names[n] = "text"; - g_value_init (&values[n], G_TYPE_STRING); - g_value_take_string (&values[n], str); - n++; - } - - g_assert (n <= G_N_ELEMENTS (names)); - g_assert (n <= n_max); - ido_menu_item = IDO_BASIC_MENU_ITEM(g_object_new_with_properties (IDO_TYPE_BASIC_MENU_ITEM, n, names, values)); - - for (i=0; i<n; i++) - g_value_unset (&values[i]); - - /* give it an ActionHelper */ - - if (g_menu_item_get_attribute (menu_item, "action", "s", &str)) - { - IdoActionHelper * helper; - - helper = ido_action_helper_new (GTK_WIDGET(ido_menu_item), - actions, - str, - NULL); - g_signal_connect (helper, "action-state-changed", - G_CALLBACK (on_progress_action_state_changed), NULL); - g_signal_connect_swapped (ido_menu_item, "destroy", - G_CALLBACK (g_object_unref), helper); - - g_free (str); + pBasicMenuItem = IDO_BASIC_MENU_ITEM (g_object_new (IDO_TYPE_BASIC_MENU_ITEM, "text", sLabel, NULL)); + g_free (sLabel); + + GVariant *pIconVariant = g_menu_item_get_attribute_value (pMenuItem, "icon", NULL); + + if (pIconVariant) + { + GIcon *pIcon = g_icon_deserialize (pIconVariant); + ido_basic_menu_item_set_icon (pBasicMenuItem, pIcon); + g_object_unref (pIcon); + g_variant_unref (pIconVariant); + } + + guint16 nProgress = 0; + + if (g_menu_item_get_attribute (pMenuItem, "x-ayatana-progress", "q", &nProgress)) + { + gchar *sProgress = g_strdup_printf ("%"G_GUINT16_FORMAT"%%", nProgress); + ido_basic_menu_item_set_secondary_text (pBasicMenuItem, sProgress); + g_free (sProgress); + } + + gchar *sAction = NULL; + + if (g_menu_item_get_attribute (pMenuItem, "action", "s", &sAction)) + { + GVariant *pTarget = g_menu_item_get_attribute_value (pMenuItem, "target", NULL); + IdoActionHelper *pHelper = ido_action_helper_new (GTK_WIDGET (pBasicMenuItem), pActionGroup, sAction, pTarget); + g_signal_connect_object (pBasicMenuItem, "activate", G_CALLBACK (onActivate), pHelper, 0); + g_signal_connect_swapped (pBasicMenuItem, "destroy", G_CALLBACK (g_object_unref), pHelper); + + if (pTarget) + { + g_variant_unref (pTarget); + } + + g_free (sAction); + } } - return GTK_MENU_ITEM (ido_menu_item); + return GTK_MENU_ITEM (pBasicMenuItem); } diff --git a/src/idoremovablemenuitem.c b/src/idoremovablemenuitem.c index 946ffb3..d857fd4 100644 --- a/src/idoremovablemenuitem.c +++ b/src/idoremovablemenuitem.c @@ -1,8 +1,10 @@ /* * Copyright 2013 Canonical Ltd. + * Copyright 2023 Robert Tari * * Authors: * Charles Kerr <charles.kerr@canonical.com> + * Robert Tari <robert@tari.in> * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published @@ -131,23 +133,8 @@ static void idoRemovableMenuItemStyleUpdateImage(IdoRemovableMenuItem *self) } else { - GtkIconInfo *pInfo; - const gchar *sFilename; - - pInfo = gtk_icon_theme_lookup_by_gicon(gtk_icon_theme_get_default(), pPrivate->pIcon, 16, 0); - sFilename = gtk_icon_info_get_filename(pInfo); - - if (sFilename) - { - GdkPixbuf *pPixbuf; - - pPixbuf = gdk_pixbuf_new_from_file_at_scale(sFilename, -1, 16, TRUE, NULL); - gtk_image_set_from_pixbuf(GTK_IMAGE(pPrivate->pImage), pPixbuf); - g_object_unref (pPixbuf); - } - - gtk_widget_set_visible(pPrivate->pImage, sFilename != NULL); - g_object_unref(pInfo); + gtk_image_set_from_gicon (GTK_IMAGE (pPrivate->pImage), pPrivate->pIcon, GTK_ICON_SIZE_MENU); + gtk_widget_set_visible (pPrivate->pImage, TRUE); } } diff --git a/src/idoscalemenuitem.c b/src/idoscalemenuitem.c index 7baac17..c6cf877 100644 --- a/src/idoscalemenuitem.c +++ b/src/idoscalemenuitem.c @@ -1,5 +1,6 @@ /* * Copyright 2010 Canonical, Ltd. + * Copyright 2021-2024 Robert Tari * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: @@ -21,9 +22,11 @@ * * Authors: * Cody Russell <crussell@canonical.com> + * Robert Tari <robert@tari.in> */ #include <gtk/gtk.h> +#include <math.h> #include "idorange.h" #include "idoscalemenuitem.h" #include "idotypebuiltins.h" @@ -166,7 +169,6 @@ ido_scale_menu_item_constructed (GObject *object) gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_widget_set_margin_end(hbox, 16); priv->primary_image = gtk_image_new (); g_signal_connect (priv->primary_image, "notify", @@ -700,7 +702,7 @@ ido_scale_menu_item_new_with_range (const gchar *label, gdouble max, gdouble step) { - GObject *adjustment = G_OBJECT (gtk_adjustment_new (value, min, max, step, 10 * step, 0)); + GObject *adjustment = G_OBJECT (gtk_adjustment_new (value, min, max, step, step, 0)); return GTK_WIDGET (g_object_new (IDO_TYPE_SCALE_MENU_ITEM, "label", label, @@ -1047,6 +1049,13 @@ menu_item_get_icon (GMenuItem *menuitem, return value ? g_icon_deserialize (value) : NULL; } +static gchar* onFormatValue (GtkScale *pScale, gdouble fValue) +{ + gint nValue = fValue * 100; + gchar *sValue = g_strdup_printf ("%i%%", nValue); + + return sValue; +} /** * ido_scale_menu_item_new_from_model: * @@ -1088,6 +1097,31 @@ ido_scale_menu_item_new_from_model (GMenuItem *menuitem, g_free (action); } + IdoScaleMenuItemPrivate *pPrivate = ido_scale_menu_item_get_instance_private (IDO_SCALE_MENU_ITEM (item)); + guchar nDigits = 0; + gboolean bFound = g_menu_item_get_attribute (menuitem, "digits", "y", &nDigits); + + if (bFound) + { + gtk_scale_set_digits (GTK_SCALE (pPrivate->scale), nDigits); + gtk_range_set_round_digits (GTK_RANGE (pPrivate->scale), nDigits); + } + + gboolean bMarks = FALSE; + bFound = g_menu_item_get_attribute (menuitem, "marks", "b", &bMarks); + + if (bFound) + { + gtk_scale_set_draw_value (GTK_SCALE (pPrivate->scale), TRUE); + + for (gdouble fValue = min; fValue < (max + step); fValue += step) + { + gtk_scale_add_mark (GTK_SCALE (pPrivate->scale), round (fValue * 10) / 10, GTK_POS_BOTTOM, NULL); + } + + g_signal_connect (pPrivate->scale, "format-value", G_CALLBACK (onFormatValue), NULL); + } + min_icon = menu_item_get_icon (menuitem, "min-icon"); max_icon = menu_item_get_icon (menuitem, "max-icon"); ido_scale_menu_item_set_icons (IDO_SCALE_MENU_ITEM (item), min_icon, max_icon); diff --git a/src/idousermenuitem.c b/src/idousermenuitem.c index 1f157ae..4279723 100644 --- a/src/idousermenuitem.c +++ b/src/idousermenuitem.c @@ -1,10 +1,12 @@ /* Copyright 2011 Canonical Ltd. +Copyright 2023 Robert Tari Authors: Conor Curran <conor.curran@canonical.com> Mirco Müller <mirco.mueller@canonical.com> Charles Kerr <charles.kerr@canonical.com> + Robert Tari <robert@tari.in> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published @@ -445,6 +447,8 @@ user_menu_item_new_from_model (GMenuItem * menuitem, for (i=0; i<n; i++) g_value_unset (&values[i]); + g_free (values); + /* gie it an ActionHelper */ if (g_menu_item_get_attribute (menuitem, G_MENU_ATTRIBUTE_ACTION, "s", &action)) |