summaryrefslogtreecommitdiff
path: root/src/widgets/panel/panel-item.c
diff options
context:
space:
mode:
authorHannes Schulze <haschu0103@outlook.de>2024-05-06 13:42:55 +0200
committerHannes Schulze <haschu0103@outlook.de>2024-05-06 14:33:54 +0200
commit37d5ef75306c45ca95550f4af40d9750c5b9cb88 (patch)
tree7125c8e8445eeecb86097bc99bb2d1febfb7e2a5 /src/widgets/panel/panel-item.c
initial commit
yup, i definitely wrote all of this in a single commit
Diffstat (limited to 'src/widgets/panel/panel-item.c')
-rw-r--r--src/widgets/panel/panel-item.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/widgets/panel/panel-item.c b/src/widgets/panel/panel-item.c
new file mode 100644
index 0000000..f2d4383
--- /dev/null
+++ b/src/widgets/panel/panel-item.c
@@ -0,0 +1,195 @@
+#include "widgets/panel/panel-item.h"
+#include "application.h"
+
+//
+// FoobarPanelItem:
+//
+// Base class for all panel items. This is basically a bin layout where the subclass usually sets the child widget.
+//
+
+typedef struct _FoobarPanelItemPrivate
+{
+ GtkWidget* child;
+} FoobarPanelItemPrivate;
+
+enum
+{
+ PROP_CHILD = 1,
+ N_PROPS,
+};
+
+static GParamSpec* props[N_PROPS] = { 0 };
+
+static void foobar_panel_item_class_init ( FoobarPanelItemClass* klass );
+static void foobar_panel_item_init ( FoobarPanelItem* self );
+static void foobar_panel_item_get_property( GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec );
+static void foobar_panel_item_set_property( GObject* object,
+ guint prop_id,
+ GValue const* value,
+ GParamSpec* pspec );
+static void foobar_panel_item_dispose ( GObject* object );
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE( FoobarPanelItem, foobar_panel_item, GTK_TYPE_WIDGET )
+
+// ---------------------------------------------------------------------------------------------------------------------
+// Widget Implementation
+// ---------------------------------------------------------------------------------------------------------------------
+
+//
+// Static initialization for panel items.
+//
+void foobar_panel_item_class_init( FoobarPanelItemClass* klass )
+{
+ GtkWidgetClass* widget_klass = GTK_WIDGET_CLASS( klass );
+ gtk_widget_class_set_css_name( widget_klass, "panel-item" );
+ gtk_widget_class_set_layout_manager_type( widget_klass, GTK_TYPE_BIN_LAYOUT );
+
+ GObjectClass* object_klass = G_OBJECT_CLASS( klass );
+ object_klass->get_property = foobar_panel_item_get_property;
+ object_klass->set_property = foobar_panel_item_set_property;
+ object_klass->dispose = foobar_panel_item_dispose;
+
+ props[PROP_CHILD] = g_param_spec_object(
+ "child",
+ "Child",
+ "Child widget for the panel item.",
+ GTK_TYPE_WIDGET,
+ G_PARAM_READWRITE );
+ g_object_class_install_properties( object_klass, N_PROPS, props );
+}
+
+//
+// Instance initialization for panel items.
+//
+void foobar_panel_item_init( FoobarPanelItem* self )
+{
+ (void)self;
+}
+
+//
+// Property getter implementation, mapping a property id to a method.
+//
+void foobar_panel_item_get_property(
+ GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec )
+{
+ FoobarPanelItem* self = (FoobarPanelItem*)object;
+
+ switch ( prop_id )
+ {
+ case PROP_CHILD:
+ g_value_set_object( value, foobar_panel_item_get_child( self ) );
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec );
+ break;
+ }
+}
+
+//
+// Property setter implementation, mapping a property id to a method.
+//
+void foobar_panel_item_set_property(
+ GObject* object,
+ guint prop_id,
+ GValue const* value,
+ GParamSpec* pspec )
+{
+ FoobarPanelItem* self = (FoobarPanelItem*)object;
+
+ switch ( prop_id )
+ {
+ case PROP_CHILD:
+ foobar_panel_item_set_child( self, g_value_get_object( value ) );
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec );
+ break;
+ }
+}
+
+//
+// Instance de-initialization for panel items.
+//
+void foobar_panel_item_dispose( GObject* object )
+{
+ FoobarPanelItem* self = (FoobarPanelItem*)object;
+ FoobarPanelItemPrivate* priv = foobar_panel_item_get_instance_private( self );
+
+ g_clear_pointer( &priv->child, gtk_widget_unparent );
+
+ G_OBJECT_CLASS( foobar_panel_item_parent_class )->dispose( object );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+// Public API
+// ---------------------------------------------------------------------------------------------------------------------
+
+//
+// Get the child widget for the panel item.
+//
+GtkWidget* foobar_panel_item_get_child( FoobarPanelItem* self )
+{
+ g_return_val_if_fail( FOOBAR_IS_PANEL_ITEM( self ), NULL );
+ FoobarPanelItemPrivate* priv = foobar_panel_item_get_instance_private( self );
+
+ return priv->child;
+}
+
+//
+// Update the child widget for the panel item.
+//
+void foobar_panel_item_set_child(
+ FoobarPanelItem* self,
+ GtkWidget* child )
+{
+ g_return_if_fail( FOOBAR_IS_PANEL_ITEM( self ) );
+ FoobarPanelItemPrivate* priv = foobar_panel_item_get_instance_private( self );
+ g_return_if_fail( child == NULL || priv->child == child || gtk_widget_get_parent( child ) == NULL );
+
+ if ( priv->child != child )
+ {
+ g_clear_pointer( &priv->child, gtk_widget_unparent );
+
+ if ( child )
+ {
+ priv->child = child;
+ gtk_widget_set_parent( child, GTK_WIDGET( self ) );
+ }
+
+ g_object_notify_by_pspec( G_OBJECT( self ), props[PROP_CHILD] );
+ }
+}
+
+//
+// Invoke the action for the panel item.
+//
+// This needs to be triggered by a subclass, for example by adding a button to the item. Support for panel item actions
+// is opt-in and subclasses have to explicitly implement it. This is just a helper for implementing the action.
+//
+void foobar_panel_item_invoke_action(
+ FoobarPanelItem* self,
+ FoobarPanelItemAction action )
+{
+ g_return_if_fail( FOOBAR_IS_PANEL_ITEM( self ) );
+
+ switch ( action )
+ {
+ case FOOBAR_PANEL_ITEM_ACTION_NONE:
+ break;
+ case FOOBAR_PANEL_ITEM_ACTION_LAUNCHER:
+ foobar_application_toggle_launcher( FOOBAR_APPLICATION_DEFAULT );
+ break;
+ case FOOBAR_PANEL_ITEM_ACTION_CONTROL_CENTER:
+ foobar_application_toggle_control_center( FOOBAR_APPLICATION_DEFAULT );
+ break;
+ default:
+ g_warn_if_reached( );
+ break;
+ }
+} \ No newline at end of file