diff options
| author | Hannes Schulze <haschu0103@outlook.de> | 2024-05-06 13:42:55 +0200 |
|---|---|---|
| committer | Hannes Schulze <haschu0103@outlook.de> | 2024-05-06 14:33:54 +0200 |
| commit | 37d5ef75306c45ca95550f4af40d9750c5b9cb88 (patch) | |
| tree | 7125c8e8445eeecb86097bc99bb2d1febfb7e2a5 /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.c | 195 |
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 |
