summaryrefslogtreecommitdiff
path: root/src/widgets/panel
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/panel')
-rw-r--r--src/widgets/panel/meson.build7
-rw-r--r--src/widgets/panel/panel-item-clock.c152
-rw-r--r--src/widgets/panel/panel-item-clock.h15
-rw-r--r--src/widgets/panel/panel-item-icon.c92
-rw-r--r--src/widgets/panel/panel-item-icon.h13
-rw-r--r--src/widgets/panel/panel-item-status.c955
-rw-r--r--src/widgets/panel/panel-item-status.h25
-rw-r--r--src/widgets/panel/panel-item-workspaces.c327
-rw-r--r--src/widgets/panel/panel-item-workspaces.h16
-rw-r--r--src/widgets/panel/panel-item.c195
-rw-r--r--src/widgets/panel/panel-item.h23
11 files changed, 0 insertions, 1820 deletions
diff --git a/src/widgets/panel/meson.build b/src/widgets/panel/meson.build
deleted file mode 100644
index 10afc94..0000000
--- a/src/widgets/panel/meson.build
+++ /dev/null
@@ -1,7 +0,0 @@
-foobar_sources += files(
- 'panel-item.c',
- 'panel-item-icon.c',
- 'panel-item-clock.c',
- 'panel-item-workspaces.c',
- 'panel-item-status.c',
-)
diff --git a/src/widgets/panel/panel-item-clock.c b/src/widgets/panel/panel-item-clock.c
deleted file mode 100644
index 00b2cc5..0000000
--- a/src/widgets/panel/panel-item-clock.c
+++ /dev/null
@@ -1,152 +0,0 @@
-#include "widgets/panel/panel-item-clock.h"
-
-//
-// FoobarPanelItemClock:
-//
-// A panel item displaying the current time in the format configured by the user.
-//
-
-struct _FoobarPanelItemClock
-{
- FoobarPanelItem parent_instance;
- gchar* format;
- FoobarPanelItemAction action;
- GtkWidget* label;
- GtkWidget* button;
- FoobarClockService* clock_service;
-};
-
-static void foobar_panel_item_clock_class_init ( FoobarPanelItemClockClass* klass );
-static void foobar_panel_item_clock_init ( FoobarPanelItemClock* self );
-static void foobar_panel_item_clock_finalize ( GObject* object );
-static void foobar_panel_item_clock_handle_clicked( GtkButton* button,
- gpointer userdata );
-static gchar* foobar_panel_item_clock_compute_label ( GtkExpression* expression,
- GDateTime* time,
- gpointer userdata );
-
-G_DEFINE_FINAL_TYPE( FoobarPanelItemClock, foobar_panel_item_clock, FOOBAR_TYPE_PANEL_ITEM )
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Panel Item Implementation
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Static initialization for clock panel items.
-//
-void foobar_panel_item_clock_class_init( FoobarPanelItemClockClass* klass )
-{
- GObjectClass* object_klass = G_OBJECT_CLASS( klass );
- object_klass->finalize = foobar_panel_item_clock_finalize;
-}
-
-//
-// Instance initialization for clock panel items.
-//
-void foobar_panel_item_clock_init( FoobarPanelItemClock* self )
-{
- self->label = gtk_label_new( NULL );
- gtk_label_set_justify( GTK_LABEL( self->label ), GTK_JUSTIFY_CENTER );
-
- self->button = gtk_button_new( );
- gtk_button_set_has_frame( GTK_BUTTON( self->button ), FALSE );
- gtk_button_set_child( GTK_BUTTON( self->button ), self->label );
- gtk_widget_set_halign( self->button, GTK_ALIGN_CENTER );
- gtk_widget_set_valign( self->button, GTK_ALIGN_CENTER );
- g_signal_connect(
- self->button,
- "clicked",
- G_CALLBACK( foobar_panel_item_clock_handle_clicked ),
- self );
-
- gtk_widget_add_css_class( GTK_WIDGET( self ), "clock" );
- foobar_panel_item_set_child( FOOBAR_PANEL_ITEM( self ), self->button );
-}
-
-//
-// Instance cleanup for clock panel items.
-//
-void foobar_panel_item_clock_finalize( GObject* object )
-{
- FoobarPanelItemClock* self = (FoobarPanelItemClock*)object;
-
- g_clear_pointer( &self->format, g_free );
- g_clear_object( &self->clock_service );
-
- G_OBJECT_CLASS( foobar_panel_item_clock_parent_class )->finalize( object );
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Public API
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Create a new clock panel item with the given configuration.
-//
-FoobarPanelItem* foobar_panel_item_clock_new(
- FoobarPanelItemConfiguration const* config,
- FoobarClockService* clock_service )
-{
- g_return_val_if_fail( config != NULL, NULL );
- g_return_val_if_fail( foobar_panel_item_configuration_get_kind( config ) == FOOBAR_PANEL_ITEM_KIND_CLOCK, NULL );
- g_return_val_if_fail( FOOBAR_IS_CLOCK_SERVICE( clock_service ), NULL );
-
- FoobarPanelItemClock* self = g_object_new( FOOBAR_TYPE_PANEL_ITEM_CLOCK, NULL );
- self->format = g_strdup( foobar_panel_item_clock_configuration_get_format( config ) );
- self->action = foobar_panel_item_configuration_get_action( config );
- self->clock_service = g_object_ref( clock_service );
-
- gtk_widget_set_sensitive( self->button, self->action != FOOBAR_PANEL_ITEM_ACTION_NONE );
-
- {
- GtkExpression* service_expr = gtk_constant_expression_new( FOOBAR_TYPE_CLOCK_SERVICE, self->clock_service );
- GtkExpression* time_expr = gtk_property_expression_new( FOOBAR_TYPE_CLOCK_SERVICE, service_expr, "time" );
- GtkExpression* label_params[] = { time_expr };
- GtkExpression* label_expr = gtk_cclosure_expression_new(
- G_TYPE_STRING,
- NULL,
- G_N_ELEMENTS( label_params ),
- label_params,
- G_CALLBACK( foobar_panel_item_clock_compute_label ),
- self,
- NULL );
- gtk_expression_bind( label_expr, self->label, "label", NULL );
- }
-
- return FOOBAR_PANEL_ITEM( self );
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Signal Handlers
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Called when the button was clicked.
-//
-void foobar_panel_item_clock_handle_clicked(
- GtkButton* button,
- gpointer userdata )
-{
- (void)button;
- FoobarPanelItemClock* self = (FoobarPanelItemClock*)userdata;
-
- foobar_panel_item_invoke_action( FOOBAR_PANEL_ITEM( self ), self->action );
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Value Converters
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Derive the label from a timestamp, depending on the configured time format.
-//
-gchar* foobar_panel_item_clock_compute_label(
- GtkExpression* expression,
- GDateTime* time,
- gpointer userdata )
-{
- (void)expression;
- FoobarPanelItemClock* self = (FoobarPanelItemClock*)userdata;
-
- return g_date_time_format( time, self->format );
-}
diff --git a/src/widgets/panel/panel-item-clock.h b/src/widgets/panel/panel-item-clock.h
deleted file mode 100644
index 5ff7e5b..0000000
--- a/src/widgets/panel/panel-item-clock.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "widgets/panel/panel-item.h"
-#include "services/clock-service.h"
-
-G_BEGIN_DECLS
-
-#define FOOBAR_TYPE_PANEL_ITEM_CLOCK foobar_panel_item_clock_get_type( )
-
-G_DECLARE_FINAL_TYPE( FoobarPanelItemClock, foobar_panel_item_clock, FOOBAR, PANEL_ITEM_CLOCK, FoobarPanelItem )
-
-FoobarPanelItem* foobar_panel_item_clock_new( FoobarPanelItemConfiguration const* config,
- FoobarClockService* clock_service );
-
-G_END_DECLS
diff --git a/src/widgets/panel/panel-item-icon.c b/src/widgets/panel/panel-item-icon.c
deleted file mode 100644
index 0a3b4e9..0000000
--- a/src/widgets/panel/panel-item-icon.c
+++ /dev/null
@@ -1,92 +0,0 @@
-#include "widgets/panel/panel-item-icon.h"
-
-//
-// FoobarPanelItemIcon:
-//
-// Simple item implementation displaying an icon.
-//
-
-struct _FoobarPanelItemIcon
-{
- FoobarPanelItem parent_instance;
- GtkWidget* button;
- FoobarPanelItemAction action;
-};
-
-static void foobar_panel_item_icon_class_init ( FoobarPanelItemIconClass* klass );
-static void foobar_panel_item_icon_init ( FoobarPanelItemIcon* self );
-static void foobar_panel_item_icon_handle_clicked( GtkButton* button,
- gpointer userdata );
-
-G_DEFINE_FINAL_TYPE( FoobarPanelItemIcon, foobar_panel_item_icon, FOOBAR_TYPE_PANEL_ITEM )
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Panel Item Implementation
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Static initialization for icon panel items.
-//
-void foobar_panel_item_icon_class_init( FoobarPanelItemIconClass* klass )
-{
- (void)klass;
-}
-
-//
-// Instance initialization for icon panel items.
-//
-void foobar_panel_item_icon_init( FoobarPanelItemIcon* self )
-{
- self->button = gtk_button_new( );
- gtk_button_set_has_frame( GTK_BUTTON( self->button ), FALSE );
- gtk_widget_set_halign( self->button, GTK_ALIGN_CENTER );
- gtk_widget_set_valign( self->button, GTK_ALIGN_CENTER );
- g_signal_connect(
- self->button,
- "clicked",
- G_CALLBACK( foobar_panel_item_icon_handle_clicked ),
- self );
-
- gtk_widget_add_css_class( GTK_WIDGET( self ), "icon" );
- foobar_panel_item_set_child( FOOBAR_PANEL_ITEM( self ), self->button );
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Public API
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Create a new icon panel item with the given configuration.
-//
-FoobarPanelItem* foobar_panel_item_icon_new( FoobarPanelItemConfiguration const* config )
-{
- g_return_val_if_fail( config != NULL, NULL );
- g_return_val_if_fail( foobar_panel_item_configuration_get_kind( config ) == FOOBAR_PANEL_ITEM_KIND_ICON, NULL );
-
- FoobarPanelItemIcon* self = g_object_new( FOOBAR_TYPE_PANEL_ITEM_ICON, NULL );
- self->action = foobar_panel_item_configuration_get_action( config );
-
- gtk_widget_set_sensitive( self->button, self->action != FOOBAR_PANEL_ITEM_ACTION_NONE );
- gtk_button_set_icon_name(
- GTK_BUTTON( self->button ),
- foobar_panel_item_icon_configuration_get_icon_name( config ) );
-
- return FOOBAR_PANEL_ITEM( self );
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Signal Handlers
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Called when the button was clicked.
-//
-void foobar_panel_item_icon_handle_clicked(
- GtkButton* button,
- gpointer userdata )
-{
- (void)button;
- FoobarPanelItemIcon* self = (FoobarPanelItemIcon*)userdata;
-
- foobar_panel_item_invoke_action( FOOBAR_PANEL_ITEM( self ), self->action );
-}
diff --git a/src/widgets/panel/panel-item-icon.h b/src/widgets/panel/panel-item-icon.h
deleted file mode 100644
index 2b4ac1f..0000000
--- a/src/widgets/panel/panel-item-icon.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include "widgets/panel/panel-item.h"
-
-G_BEGIN_DECLS
-
-#define FOOBAR_TYPE_PANEL_ITEM_ICON foobar_panel_item_icon_get_type( )
-
-G_DECLARE_FINAL_TYPE( FoobarPanelItemIcon, foobar_panel_item_icon, FOOBAR, PANEL_ITEM_ICON, FoobarPanelItem )
-
-FoobarPanelItem* foobar_panel_item_icon_new( FoobarPanelItemConfiguration const* config );
-
-G_END_DECLS
diff --git a/src/widgets/panel/panel-item-status.c b/src/widgets/panel/panel-item-status.c
deleted file mode 100644
index f06bb68..0000000
--- a/src/widgets/panel/panel-item-status.c
+++ /dev/null
@@ -1,955 +0,0 @@
-#include "widgets/panel/panel-item-status.h"
-
-//
-// FoobarPanelItemStatus:
-//
-// A panel item showing status indicators for various things such as network state, audio volume, screen brightness,
-// battery level, etc.
-//
-
-struct _FoobarPanelItemStatus
-{
- FoobarPanelItem parent_instance;
- FoobarPanelItemAction action;
- GtkWidget* button;
- GtkWidget* layout;
- FoobarBatteryService* battery_service;
- FoobarBrightnessService* brightness_service;
- FoobarAudioService* audio_service;
- FoobarNetworkService* network_service;
- FoobarBluetoothService* bluetooth_service;
- FoobarNotificationService* notification_service;
- GtkWidget* network_icon;
- GtkWidget* network_label;
- GtkExpression* network_icon_expr;
- FoobarNetwork* network;
- gulong network_handler_id;
- gulong network_strength_handler_id;
-};
-
-enum
-{
- PROP_ORIENTATION = 1,
- N_PROPS,
-};
-
-static GParamSpec* props[N_PROPS] = { 0 };
-
-static void foobar_panel_item_status_class_init ( FoobarPanelItemStatusClass* klass );
-static void foobar_panel_item_status_init ( FoobarPanelItemStatus* self );
-static void foobar_panel_item_status_get_property ( GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec );
-static void foobar_panel_item_status_set_property ( GObject* object,
- guint prop_id,
- GValue const* value,
- GParamSpec* pspec );
-static void foobar_panel_item_status_finalize ( GObject* object );
-static void foobar_panel_item_status_handle_network_change ( FoobarNetworkAdapterWifi* adapter,
- GParamSpec* pspec,
- gpointer userdata );
-static void foobar_panel_item_status_handle_network_strength_change( GObject* object,
- GParamSpec* pspec,
- gpointer userdata );
-static void foobar_panel_item_status_handle_clicked ( GtkButton* button,
- gpointer userdata );
-static gboolean foobar_panel_item_status_handle_brightness_scroll ( GtkEventControllerScroll* controller,
- gdouble dx,
- gdouble dy,
- gpointer userdata );
-static gboolean foobar_panel_item_status_handle_audio_scroll ( GtkEventControllerScroll* controller,
- gdouble dx,
- gdouble dy,
- gpointer userdata );
-static gchar* foobar_panel_item_status_compute_network_icon ( GtkExpression* expression,
- FoobarNetworkAdapter* adapter,
- FoobarNetworkAdapterState state,
- gpointer userdata );
-static gchar* foobar_panel_item_status_compute_bluetooth_icon ( GtkExpression* expression,
- gboolean is_enabled,
- guint connected_device_count,
- gpointer userdata );
-static gchar* foobar_panel_item_status_compute_battery_icon ( GtkExpression* expression,
- FoobarBatteryState const* state,
- gpointer userdata );
-static gchar* foobar_panel_item_status_compute_battery_label ( GtkExpression* expression,
- FoobarBatteryState const* state,
- gpointer userdata );
-static gchar* foobar_panel_item_status_compute_brightness_icon ( GtkExpression* expression,
- gint percentage,
- gpointer userdata );
-static gchar* foobar_panel_item_status_compute_brightness_label ( GtkExpression* expression,
- gint percentage,
- gpointer userdata );
-static gchar* foobar_panel_item_status_compute_audio_icon ( GtkExpression* expression,
- gboolean is_available,
- gint volume,
- gpointer userdata );
-static gchar* foobar_panel_item_status_compute_audio_label ( GtkExpression* expression,
- gboolean is_available,
- gint volume,
- gpointer userdata );
-static gchar* foobar_panel_item_status_compute_notifications_icon ( GtkExpression* expression,
- guint count,
- gpointer userdata );
-static GtkWidget* foobar_panel_item_status_create_item ( FoobarPanelItemStatus* self,
- FoobarStatusItem item,
- gboolean show_labels,
- gboolean enable_scrolling );
-static void foobar_panel_item_status_reevaluate_network ( FoobarPanelItemStatus* self );
-
-G_DEFINE_FINAL_TYPE_WITH_CODE(
- FoobarPanelItemStatus,
- foobar_panel_item_status,
- FOOBAR_TYPE_PANEL_ITEM,
- G_IMPLEMENT_INTERFACE( GTK_TYPE_ORIENTABLE, NULL ) )
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Panel Item Implementation
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Static initialization for status panel items.
-//
-void foobar_panel_item_status_class_init( FoobarPanelItemStatusClass* klass )
-{
- GObjectClass* object_klass = G_OBJECT_CLASS( klass );
- object_klass->get_property = foobar_panel_item_status_get_property;
- object_klass->set_property = foobar_panel_item_status_set_property;
- object_klass->finalize = foobar_panel_item_status_finalize;
-
- gpointer orientable_iface = g_type_default_interface_peek( GTK_TYPE_ORIENTABLE );
- props[PROP_ORIENTATION] = g_param_spec_override(
- "orientation",
- g_object_interface_find_property( orientable_iface, "orientation" ) );
- g_object_class_install_properties( object_klass, N_PROPS, props );
-}
-
-//
-// Instance initialization for status panel items.
-//
-void foobar_panel_item_status_init( FoobarPanelItemStatus* self )
-{
- self->layout = gtk_box_new( GTK_ORIENTATION_VERTICAL, 0 );
-
- self->button = gtk_button_new( );
- gtk_button_set_has_frame( GTK_BUTTON( self->button ), FALSE );
- gtk_button_set_child( GTK_BUTTON( self->button ), self->layout );
- gtk_widget_set_halign( self->button, GTK_ALIGN_CENTER );
- gtk_widget_set_valign( self->button, GTK_ALIGN_CENTER );
- g_signal_connect(
- self->button,
- "clicked",
- G_CALLBACK( foobar_panel_item_status_handle_clicked ),
- self );
-
- gtk_widget_add_css_class( GTK_WIDGET( self ), "status" );
- foobar_panel_item_set_child( FOOBAR_PANEL_ITEM( self ), self->button );
-}
-
-//
-// Property getter implementation, mapping a property id to a method.
-//
-void foobar_panel_item_status_get_property(
- GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec )
-{
- FoobarPanelItemStatus* self = (FoobarPanelItemStatus*)object;
-
- switch ( prop_id )
- {
- case PROP_ORIENTATION:
- g_value_set_enum( value, gtk_orientable_get_orientation( GTK_ORIENTABLE( self->layout ) ) );
- 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_status_set_property(
- GObject* object,
- guint prop_id,
- GValue const* value,
- GParamSpec* pspec )
-{
- FoobarPanelItemStatus* self = (FoobarPanelItemStatus*)object;
-
- switch ( prop_id )
- {
- case PROP_ORIENTATION:
- gtk_orientable_set_orientation( GTK_ORIENTABLE( self->layout ), g_value_get_enum( value ) );
- g_object_notify_by_pspec( G_OBJECT( self ), props[PROP_ORIENTATION] );
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec );
- break;
- }
-}
-
-//
-// Instance cleanup for status panel items.
-//
-void foobar_panel_item_status_finalize( GObject* object )
-{
- FoobarPanelItemStatus* self = (FoobarPanelItemStatus*)object;
-
- FoobarNetworkAdapterWifi* adapter = foobar_network_service_get_wifi( self->network_service );
- g_clear_signal_handler( &self->network_handler_id, adapter );
- g_clear_signal_handler( &self->network_strength_handler_id, self->network );
- g_clear_object( &self->network );
- g_clear_object( &self->battery_service );
- g_clear_object( &self->brightness_service );
- g_clear_object( &self->audio_service );
- g_clear_object( &self->network_service );
- g_clear_object( &self->bluetooth_service );
- g_clear_object( &self->notification_service );
- g_clear_pointer( &self->network_icon_expr, gtk_expression_unref );
-
- G_OBJECT_CLASS( foobar_panel_item_status_parent_class )->finalize( object );
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Public API
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Create a new status panel item with the given configuration.
-//
-FoobarPanelItem* foobar_panel_item_status_new(
- FoobarPanelItemConfiguration const* config,
- FoobarBatteryService* battery_service,
- FoobarBrightnessService* brightness_service,
- FoobarAudioService* audio_service,
- FoobarNetworkService* network_service,
- FoobarBluetoothService* bluetooth_service,
- FoobarNotificationService* notification_service )
-{
- g_return_val_if_fail( config != NULL, NULL );
- g_return_val_if_fail( foobar_panel_item_configuration_get_kind( config ) == FOOBAR_PANEL_ITEM_KIND_STATUS, NULL );
- g_return_val_if_fail( FOOBAR_IS_BATTERY_SERVICE( battery_service ), NULL );
- g_return_val_if_fail( FOOBAR_IS_BRIGHTNESS_SERVICE( brightness_service ), NULL );
- g_return_val_if_fail( FOOBAR_IS_AUDIO_SERVICE( audio_service ), NULL );
- g_return_val_if_fail( FOOBAR_IS_NETWORK_SERVICE( network_service ), NULL );
- g_return_val_if_fail( FOOBAR_IS_BLUETOOTH_SERVICE( bluetooth_service ), NULL );
- g_return_val_if_fail( FOOBAR_IS_NOTIFICATION_SERVICE( notification_service ), NULL );
-
- FoobarPanelItemStatus* self = g_object_new( FOOBAR_TYPE_PANEL_ITEM_STATUS, NULL );
- self->action = foobar_panel_item_configuration_get_action( config );
- self->battery_service = g_object_ref( battery_service );
- self->brightness_service = g_object_ref( brightness_service );
- self->audio_service = g_object_ref( audio_service );
- self->network_service = g_object_ref( network_service );
- self->bluetooth_service = g_object_ref( bluetooth_service );
- self->notification_service = g_object_ref( notification_service );
-
- gtk_widget_set_sensitive( self->button, self->action != FOOBAR_PANEL_ITEM_ACTION_NONE );
-
- gtk_box_set_spacing( GTK_BOX( self->layout ), foobar_panel_item_status_configuration_get_spacing( config ) );
- gboolean show_labels = foobar_panel_item_status_configuration_get_show_labels( config );
- gboolean enable_scrolling = foobar_panel_item_status_configuration_get_enable_scrolling( config );
- gsize items_count;
- FoobarStatusItem const* items = foobar_panel_item_status_configuration_get_items( config, &items_count );
- for ( gsize i = 0; i < items_count; ++i )
- {
- GtkWidget* widget = foobar_panel_item_status_create_item( self, items[i], show_labels, enable_scrolling );
- if ( widget )
- {
- gtk_widget_set_halign( widget, GTK_ALIGN_CENTER );
- gtk_box_append( GTK_BOX( self->layout ), widget );
- }
- }
-
- return FOOBAR_PANEL_ITEM( self );
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Signal Handlers
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Called when the wi-fi adapter's active network changes.
-//
-// This is used to then subscribe to changes to the active network's strength. Unfortunately, we can't just use
-// GtkExpressions here because the active network may be NULL in which case the strength expression would fail. If one
-// expression fails to evaluate, then the closure expression used to derive the network icon/label also does not get
-// updated.
-//
-// In addition, this method also updates the network label to show the active network's name or become invisible.
-//
-void foobar_panel_item_status_handle_network_change(
- FoobarNetworkAdapterWifi* adapter,
- GParamSpec* pspec,
- gpointer userdata )
-{
- (void)pspec;
- FoobarPanelItemStatus* self = (FoobarPanelItemStatus*)userdata;
-
- FoobarNetwork* network = foobar_network_adapter_wifi_get_active( adapter );
- if ( self->network != network )
- {
- g_clear_signal_handler( &self->network_strength_handler_id, self->network );
- g_clear_object( &self->network );
-
- if ( network )
- {
- self->network = g_object_ref( network );
- self->network_strength_handler_id = g_signal_connect(
- self->network,
- "notify::strength",
- G_CALLBACK( foobar_panel_item_status_handle_network_strength_change ),
- self );
- }
-
- if ( self->network_label )
- {
- gtk_label_set_label(
- GTK_LABEL( self->network_label ), self->network ? foobar_network_get_name( self->network ) : NULL );
- gtk_widget_set_visible( GTK_WIDGET( self->network_label ), self->network != NULL );
- }
-
- foobar_panel_item_status_reevaluate_network( self );
- }
-}
-
-//
-// Called when the wi-fi adapter's active network strength changes.
-//
-// This just forces re-evaluation of the network icon expression for reasons mentioned in
-// foobar_panel_item_status_handle_network_change.
-//
-void foobar_panel_item_status_handle_network_strength_change(
- GObject* object,
- GParamSpec* pspec,
- gpointer userdata )
-{
- (void)object;
- (void)pspec;
- FoobarPanelItemStatus* self = (FoobarPanelItemStatus*)userdata;
- foobar_panel_item_status_reevaluate_network( self );
-}
-
-//
-// Called when the button was clicked.
-//
-void foobar_panel_item_status_handle_clicked(
- GtkButton* button,
- gpointer userdata )
-{
- (void)button;
- FoobarPanelItemStatus* self = (FoobarPanelItemStatus*)userdata;
-
- foobar_panel_item_invoke_action( FOOBAR_PANEL_ITEM( self ), self->action );
-}
-
-//
-// Called when the user has scrolled over the brightness item, used to adjust the brightness level.
-//
-gboolean foobar_panel_item_status_handle_brightness_scroll(
- GtkEventControllerScroll* controller,
- gdouble dx,
- gdouble dy,
- gpointer userdata )
-{
- (void)controller;
- (void)dx;
- FoobarPanelItemStatus* self = (FoobarPanelItemStatus*)userdata;
-
- gint new_brightness = foobar_brightness_service_get_percentage( self->brightness_service ) + (gint)dy;
- foobar_brightness_service_set_percentage( self->brightness_service, new_brightness );
-
- return TRUE;
-}
-
-//
-// Called when the user has scrolled over the audio item, used to adjust the volume.
-//
-gboolean foobar_panel_item_status_handle_audio_scroll(
- GtkEventControllerScroll* controller,
- gdouble dx,
- gdouble dy,
- gpointer userdata )
-{
- (void)controller;
- (void)dx;
- FoobarPanelItemStatus* self = (FoobarPanelItemStatus*)userdata;
-
- FoobarAudioDevice* device = foobar_audio_service_get_default_output( self->audio_service );
- gint new_volume = foobar_audio_device_get_volume( device ) + (gint)dy;
- foobar_audio_device_set_volume( device, new_volume );
-
- return TRUE;
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Value Converters
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Derive the network icon from the active network adapter and its state.
-//
-// In addition, this also uses the wi-fi adapter's active network strength which is monitored separately (see
-// foobar_panel_item_status_handle_network_change).
-//
-gchar* foobar_panel_item_status_compute_network_icon(
- GtkExpression* expression,
- FoobarNetworkAdapter* adapter,
- FoobarNetworkAdapterState state,
- gpointer userdata )
-{
- (void)expression;
- (void)userdata;
-
- if ( FOOBAR_IS_NETWORK_ADAPTER_WIFI( adapter ) )
- {
- if ( state == FOOBAR_NETWORK_ADAPTER_STATE_DISCONNECTED ) { return g_strdup( "fluent-wifi-off-symbolic" ); }
- if ( state != FOOBAR_NETWORK_ADAPTER_STATE_CONNECTED ) { return g_strdup( "fluent-wifi-warning-symbolic" ); }
-
- FoobarNetwork* network = foobar_network_adapter_wifi_get_active( FOOBAR_NETWORK_ADAPTER_WIFI( adapter ) );
- gint strength = network ? foobar_network_get_strength( network ) : 0;
- if ( strength <= 25 ) { return g_strdup( "fluent-wifi-4-symbolic" ); }
- if ( strength <= 50 ) { return g_strdup( "fluent-wifi-3-symbolic" ); }
- if ( strength <= 75 ) { return g_strdup( "fluent-wifi-2-symbolic" ); }
- return g_strdup( "fluent-wifi-1-symbolic" );
- }
- else
- {
- return g_strdup( "fluent-virtual-network-symbolic" );
- }
-}
-
-//
-// Derive the bluetooth icon from the bluetooth adapter's state and the number of currently connected devices.
-//
-gchar* foobar_panel_item_status_compute_bluetooth_icon(
- GtkExpression* expression,
- gboolean is_enabled,
- guint connected_device_count,
- gpointer userdata )
-{
- (void)expression;
- (void)userdata;
-
- if (is_enabled)
- {
- return ( connected_device_count > 0 )
- ? g_strdup( "fluent-bluetooth-connected-symbolic" )
- : g_strdup( "fluent-bluetooth-symbolic" );
- }
- else
- {
- return g_strdup( "fluent-bluetooth-off-symbolic" );
- }
-}
-
-//
-// Derive the battery icon from the current state structure.
-//
-gchar* foobar_panel_item_status_compute_battery_icon(
- GtkExpression* expression,
- FoobarBatteryState const* state,
- gpointer userdata )
-{
- (void)expression;
- (void)userdata;
-
- if ( state )
- {
- gint percentage = foobar_battery_state_get_percentage( state );
- if ( foobar_battery_state_is_charging( state ) ) { return g_strdup( "fluent-battery-charge-symbolic" ); }
- if ( percentage <= 5 ) { return g_strdup( "fluent-battery-0-symbolic" ); }
- if ( percentage <= 15 ) { return g_strdup( "fluent-battery-1-symbolic" ); }
- if ( percentage <= 25 ) { return g_strdup( "fluent-battery-2-symbolic" ); }
- if ( percentage <= 35 ) { return g_strdup( "fluent-battery-3-symbolic" ); }
- if ( percentage <= 45 ) { return g_strdup( "fluent-battery-4-symbolic" ); }
- if ( percentage <= 55 ) { return g_strdup( "fluent-battery-5-symbolic" ); }
- if ( percentage <= 65 ) { return g_strdup( "fluent-battery-6-symbolic" ); }
- if ( percentage <= 75 ) { return g_strdup( "fluent-battery-7-symbolic" ); }
- if ( percentage <= 85 ) { return g_strdup( "fluent-battery-8-symbolic" ); }
- if ( percentage <= 95 ) { return g_strdup( "fluent-battery-9-symbolic" ); }
- return g_strdup( "fluent-battery-10-symbolic" );
- }
- else
- {
- return g_strdup( "fluent-plug-connected-symbolic" );
- }
-}
-
-//
-// Derive the battery label from the current state structure, showing the percentage if available.
-//
-gchar* foobar_panel_item_status_compute_battery_label(
- GtkExpression* expression,
- FoobarBatteryState const* state,
- gpointer userdata )
-{
- (void)expression;
- (void)userdata;
-
- if ( state )
- {
- return g_strdup_printf( "%d%%", foobar_battery_state_get_percentage( state ) );
- }
- else
- {
- return g_strdup( "n/a" );
- }
-}
-
-//
-// Derive the brightness icon from the current percentage value.
-//
-gchar* foobar_panel_item_status_compute_brightness_icon(
- GtkExpression* expression,
- gint percentage,
- gpointer userdata )
-{
- (void)expression;
- (void)userdata;
-
- if ( percentage <= 50 )
- {
- return g_strdup( "fluent-brightness-low-symbolic" );
- }
- else
- {
- return g_strdup( "fluent-brightness-high-symbolic" );
- }
-}
-
-//
-// Derive the brightness label from the current percentage value.
-//
-gchar* foobar_panel_item_status_compute_brightness_label(
- GtkExpression* expression,
- gint percentage,
- gpointer userdata )
-{
- (void)expression;
- (void)userdata;
-
- return g_strdup_printf( "%d%%", percentage );
-}
-
-//
-// Derive the audio icon from the current state and volume of the default output device.
-//
-gchar* foobar_panel_item_status_compute_audio_icon(
- GtkExpression* expression,
- gboolean is_available,
- gint volume,
- gpointer userdata )
-{
- (void)expression;
- (void)userdata;
-
- if ( is_available )
- {
- if ( volume == 0 ) { return g_strdup( "fluent-speaker-mute-symbolic" ); }
- if ( volume <= 33 ) { return g_strdup( "fluent-speaker-0-symbolic" ); }
- if ( volume <= 67 ) { return g_strdup( "fluent-speaker-1-symbolic" ); }
- return g_strdup( "fluent-speaker-2-symbolic" );
- }
- else
- {
- return g_strdup( "fluent-speaker-off-symbolic" );
- }
-}
-
-//
-// Derive the audio label from the current state and volume of the default output device.
-//
-gchar* foobar_panel_item_status_compute_audio_label(
- GtkExpression* expression,
- gboolean is_available,
- gint volume,
- gpointer userdata )
-{
- (void)expression;
- (void)userdata;
-
- if ( is_available )
- {
- return g_strdup_printf( "%d%%", volume );
- }
- else
- {
- return g_strdup( "n/a" );
- }
-}
-
-//
-// Derive the notification icon from the current number of notifications.
-//
-gchar* foobar_panel_item_status_compute_notifications_icon(
- GtkExpression* expression,
- guint count,
- gpointer userdata )
-{
- (void)expression;
- (void)userdata;
-
- switch ( count )
- {
- case 0:
- return g_strdup( "fluent-checkmark-circle-symbolic" );
- case 1:
- return g_strdup( "fluent-number-circle-1-symbolic" );
- case 2:
- return g_strdup( "fluent-number-circle-2-symbolic" );
- case 3:
- return g_strdup( "fluent-number-circle-3-symbolic" );
- case 4:
- return g_strdup( "fluent-number-circle-4-symbolic" );
- case 5:
- return g_strdup( "fluent-number-circle-5-symbolic" );
- case 6:
- return g_strdup( "fluent-number-circle-6-symbolic" );
- case 7:
- return g_strdup( "fluent-number-circle-7-symbolic" );
- case 8:
- return g_strdup( "fluent-number-circle-8-symbolic" );
- case 9:
- return g_strdup( "fluent-number-circle-9-symbolic" );
- default:
- return g_strdup( "fluent-more-circle-symbolic" );
- }
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Helper Methods
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Create a new icon displaying the specified status item, optionally adding a label to it (if supported).
-//
-GtkWidget* foobar_panel_item_status_create_item(
- FoobarPanelItemStatus* self,
- FoobarStatusItem item,
- gboolean show_labels,
- gboolean enable_scrolling )
-{
- switch ( item )
- {
- case FOOBAR_STATUS_ITEM_NETWORK:
- {
- GtkWidget* box = gtk_box_new( GTK_ORIENTATION_HORIZONTAL, 0 );
- gtk_widget_set_valign( box, GTK_ALIGN_FILL );
-
- GtkExpression* service_expr = gtk_constant_expression_new(
- FOOBAR_TYPE_NETWORK_SERVICE,
- self->network_service );
- GtkExpression* active_expr = gtk_property_expression_new(
- FOOBAR_TYPE_NETWORK_SERVICE,
- service_expr,
- "active" );
- GtkExpression* state_expr = gtk_property_expression_new(
- FOOBAR_TYPE_NETWORK_ADAPTER,
- gtk_expression_ref( active_expr ),
- "state" );
- GtkExpression* icon_params[] = { active_expr, state_expr };
- self->network_icon_expr = gtk_cclosure_expression_new(
- G_TYPE_STRING,
- NULL,
- G_N_ELEMENTS( icon_params ),
- icon_params,
- G_CALLBACK( foobar_panel_item_status_compute_network_icon ),
- self,
- NULL );
- self->network_icon = gtk_image_new( );
- gtk_widget_set_valign( self->network_icon, GTK_ALIGN_CENTER );
- gtk_expression_bind( gtk_expression_ref( self->network_icon_expr ), self->network_icon, "icon-name", NULL );
- gtk_box_append( GTK_BOX( box ), self->network_icon );
-
- if ( show_labels )
- {
- self->network_label = gtk_label_new( NULL );
- gtk_widget_set_valign( self->network_label, GTK_ALIGN_CENTER );
- gtk_label_set_max_width_chars( GTK_LABEL( self->network_label ), 16 );
- gtk_label_set_ellipsize( GTK_LABEL( self->network_label ), PANGO_ELLIPSIZE_END );
- gtk_box_append( GTK_BOX( box ), self->network_label );
- }
-
- // Manually subscribe to network (/strength) because evaluation might fail.
-
- FoobarNetworkAdapterWifi* adapter = foobar_network_service_get_wifi( self->network_service );
- if ( adapter )
- {
- self->network_handler_id = g_signal_connect(
- adapter,
- "notify::active",
- G_CALLBACK( foobar_panel_item_status_handle_network_change ),
- self );
- if ( foobar_network_adapter_wifi_get_active( adapter ) )
- {
- self->network = g_object_ref( foobar_network_adapter_wifi_get_active( adapter ) );
- self->network_strength_handler_id = g_signal_connect(
- self->network,
- "notify::strength",
- G_CALLBACK( foobar_panel_item_status_handle_network_strength_change ),
- self );
- }
- if ( self->network_label )
- {
- gtk_label_set_label(
- GTK_LABEL( self->network_label ),
- self->network ? foobar_network_get_name( self->network ) : NULL );
- gtk_widget_set_visible( GTK_WIDGET( self->network_label ), self->network != NULL );
- }
- }
-
- return box;
- }
- case FOOBAR_STATUS_ITEM_BLUETOOTH:
- {
- GtkWidget* icon = gtk_image_new( );
- gtk_widget_set_valign( icon, GTK_ALIGN_CENTER );
-
- GtkExpression* service_expr = gtk_constant_expression_new(
- FOOBAR_TYPE_BLUETOOTH_SERVICE,
- self->bluetooth_service );
- GtkExpression* enabled_expr = gtk_property_expression_new(
- FOOBAR_TYPE_BLUETOOTH_SERVICE,
- gtk_expression_ref( service_expr ),
- "is-enabled" );
- GtkExpression* connected_devices_expr = gtk_property_expression_new(
- FOOBAR_TYPE_BLUETOOTH_SERVICE,
- service_expr,
- "connected-devices" );
- GtkExpression* connected_device_count_expr = gtk_property_expression_new(
- GTK_TYPE_FILTER_LIST_MODEL,
- connected_devices_expr,
- "n-items" );
- GtkExpression* icon_params[] = { enabled_expr, connected_device_count_expr };
- GtkExpression* icon_expr = gtk_cclosure_expression_new(
- G_TYPE_STRING,
- NULL,
- G_N_ELEMENTS( icon_params ),
- icon_params,
- G_CALLBACK( foobar_panel_item_status_compute_bluetooth_icon ),
- NULL,
- NULL );
- gtk_expression_bind( icon_expr, icon, "icon-name", NULL );
-
- return icon;
- }
- case FOOBAR_STATUS_ITEM_BATTERY:
- {
- GtkWidget* box = gtk_box_new( GTK_ORIENTATION_HORIZONTAL, 0 );
- gtk_widget_set_valign( box, GTK_ALIGN_FILL );
-
- GtkExpression* service_expr = gtk_constant_expression_new(
- FOOBAR_TYPE_BATTERY_SERVICE,
- self->battery_service );
- GtkExpression* state_expr = gtk_property_expression_new(
- FOOBAR_TYPE_BATTERY_SERVICE,
- service_expr,
- "state" );
-
- GtkExpression* icon_params[] = { state_expr };
- GtkExpression* icon_expr = gtk_cclosure_expression_new(
- G_TYPE_STRING,
- NULL,
- G_N_ELEMENTS( icon_params ),
- icon_params,
- G_CALLBACK( foobar_panel_item_status_compute_battery_icon ),
- NULL,
- NULL );
- GtkWidget* icon = gtk_image_new( );
- gtk_widget_set_valign( icon, GTK_ALIGN_CENTER );
- gtk_expression_bind( icon_expr, icon, "icon-name", NULL );
- gtk_box_append( GTK_BOX( box ), icon );
-
- if ( show_labels )
- {
- GtkExpression* label_params[] = { gtk_expression_ref( state_expr ) };
- GtkExpression* label_expr = gtk_cclosure_expression_new(
- G_TYPE_STRING,
- NULL,
- G_N_ELEMENTS( label_params ),
- label_params,
- G_CALLBACK( foobar_panel_item_status_compute_battery_label ),
- NULL,
- NULL );
- GtkWidget* label = gtk_label_new( NULL );
- gtk_widget_set_valign( label, GTK_ALIGN_CENTER );
- gtk_expression_bind( label_expr, label, "label", NULL );
- gtk_box_append( GTK_BOX( box ), label );
- }
-
- return box;
- }
- case FOOBAR_STATUS_ITEM_BRIGHTNESS:
- {
- GtkWidget* box = gtk_box_new( GTK_ORIENTATION_HORIZONTAL, 0 );
- gtk_widget_set_valign( box, GTK_ALIGN_FILL );
-
- if ( enable_scrolling )
- {
- GtkEventController* scroll_controller = gtk_event_controller_scroll_new(
- GTK_EVENT_CONTROLLER_SCROLL_VERTICAL | GTK_EVENT_CONTROLLER_SCROLL_DISCRETE );
- g_signal_connect(
- scroll_controller,
- "scroll",
- G_CALLBACK( foobar_panel_item_status_handle_brightness_scroll ),
- self );
- gtk_widget_add_controller( box, scroll_controller );
- }
-
- GtkExpression* service_expr = gtk_constant_expression_new(
- FOOBAR_TYPE_BRIGHTNESS_SERVICE,
- self->brightness_service );
- GtkExpression* percentage_expr = gtk_property_expression_new(
- FOOBAR_TYPE_BRIGHTNESS_SERVICE,
- service_expr,
- "percentage" );
-
- GtkExpression* icon_params[] = { percentage_expr };
- GtkExpression* icon_expr = gtk_cclosure_expression_new(
- G_TYPE_STRING,
- NULL,
- G_N_ELEMENTS( icon_params ),
- icon_params,
- G_CALLBACK( foobar_panel_item_status_compute_brightness_icon ),
- NULL,
- NULL );
- GtkWidget* icon = gtk_image_new( );
- gtk_widget_set_valign( icon, GTK_ALIGN_CENTER );
- gtk_expression_bind( icon_expr, icon, "icon-name", NULL );
- gtk_box_append( GTK_BOX( box ), icon );
-
- if ( show_labels )
- {
- GtkExpression* label_params[] = { gtk_expression_ref( percentage_expr ) };
- GtkExpression* label_expr = gtk_cclosure_expression_new(
- G_TYPE_STRING,
- NULL,
- G_N_ELEMENTS( label_params ),
- label_params,
- G_CALLBACK( foobar_panel_item_status_compute_brightness_label ),
- NULL,
- NULL );
- GtkWidget* label = gtk_label_new( NULL );
- gtk_widget_set_valign( label, GTK_ALIGN_CENTER );
- gtk_expression_bind( label_expr, label, "label", NULL );
- gtk_box_append( GTK_BOX( box ), label );
- }
-
- return box;
- }
- case FOOBAR_STATUS_ITEM_AUDIO:
- {
- GtkWidget* box = gtk_box_new( GTK_ORIENTATION_HORIZONTAL, 0 );
- gtk_widget_set_valign( box, GTK_ALIGN_FILL );
-
- if ( enable_scrolling )
- {
- GtkEventController* scroll_controller = gtk_event_controller_scroll_new(
- GTK_EVENT_CONTROLLER_SCROLL_VERTICAL | GTK_EVENT_CONTROLLER_SCROLL_DISCRETE );
- g_signal_connect(
- scroll_controller,
- "scroll",
- G_CALLBACK( foobar_panel_item_status_handle_audio_scroll ),
- self );
- gtk_widget_add_controller( box, scroll_controller );
- }
-
- GtkExpression* device_expr = gtk_constant_expression_new(
- FOOBAR_TYPE_AUDIO_DEVICE,
- foobar_audio_service_get_default_output( self->audio_service ) );
- GtkExpression* available_expr = gtk_property_expression_new(
- FOOBAR_TYPE_AUDIO_DEVICE,
- gtk_expression_ref( device_expr ),
- "is-available" );
- GtkExpression* volume_expr = gtk_property_expression_new(
- FOOBAR_TYPE_AUDIO_DEVICE,
- gtk_expression_ref( device_expr ),
- "volume" );
-
- GtkExpression* icon_params[] = { available_expr, volume_expr };
- GtkExpression* icon_expr = gtk_cclosure_expression_new(
- G_TYPE_STRING,
- NULL,
- G_N_ELEMENTS( icon_params ),
- icon_params,
- G_CALLBACK( foobar_panel_item_status_compute_audio_icon ),
- NULL,
- NULL );
- GtkWidget* icon = gtk_image_new( );
- gtk_widget_set_valign( icon, GTK_ALIGN_CENTER );
- gtk_expression_bind( icon_expr, icon, "icon-name", NULL );
- gtk_box_append( GTK_BOX( box ), icon );
-
- if ( show_labels )
- {
- GtkExpression* label_params[] = { gtk_expression_ref( available_expr ), gtk_expression_ref( volume_expr ) };
- GtkExpression* label_expr = gtk_cclosure_expression_new(
- G_TYPE_STRING,
- NULL,
- G_N_ELEMENTS( label_params ),
- label_params,
- G_CALLBACK( foobar_panel_item_status_compute_audio_label ),
- NULL,
- NULL );
- GtkWidget* label = gtk_label_new( NULL );
- gtk_widget_set_valign( label, GTK_ALIGN_CENTER );
- gtk_expression_bind( label_expr, label, "label", NULL );
- gtk_box_append( GTK_BOX( box ), label );
- }
-
- return box;
- }
- case FOOBAR_STATUS_ITEM_NOTIFICATIONS:
- {
- GtkWidget* icon = gtk_image_new( );
- gtk_widget_set_valign( icon, GTK_ALIGN_CENTER );
-
- GtkExpression* list_expr = gtk_constant_expression_new(
- G_TYPE_LIST_MODEL,
- foobar_notification_service_get_notifications( self->notification_service ) );
- GtkExpression* count_expr = gtk_property_expression_new(
- GTK_TYPE_SORT_LIST_MODEL,
- list_expr,
- "n-items" );
- GtkExpression* icon_params[] = { count_expr };
- GtkExpression* icon_expr = gtk_cclosure_expression_new(
- G_TYPE_STRING,
- NULL,
- G_N_ELEMENTS( icon_params ),
- icon_params,
- G_CALLBACK( foobar_panel_item_status_compute_notifications_icon ),
- NULL,
- NULL );
- gtk_expression_bind( icon_expr, icon, "icon-name", NULL );
-
- return icon;
- }
- default:
- g_warn_if_reached( );
- return NULL;
- }
-}
-
-//
-// Force re-evaluation of the network icon expression.
-//
-// This is used whenever the active network or its strength changes.
-//
-void foobar_panel_item_status_reevaluate_network( FoobarPanelItemStatus* self )
-{
- if ( self->network_icon && self->network_icon_expr )
- {
- GValue value = G_VALUE_INIT;
- if ( gtk_expression_evaluate( self->network_icon_expr, NULL, &value ) )
- {
- gtk_image_set_from_icon_name( GTK_IMAGE( self->network_icon ), g_value_get_string( &value ) );
- }
- g_value_unset( &value );
- }
-}
diff --git a/src/widgets/panel/panel-item-status.h b/src/widgets/panel/panel-item-status.h
deleted file mode 100644
index 0f1cfdb..0000000
--- a/src/widgets/panel/panel-item-status.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include "widgets/panel/panel-item.h"
-#include "services/battery-service.h"
-#include "services/brightness-service.h"
-#include "services/audio-service.h"
-#include "services/network-service.h"
-#include "services/bluetooth-service.h"
-#include "services/notification-service.h"
-
-G_BEGIN_DECLS
-
-#define FOOBAR_TYPE_PANEL_ITEM_STATUS foobar_panel_item_status_get_type( )
-
-G_DECLARE_FINAL_TYPE( FoobarPanelItemStatus, foobar_panel_item_status, FOOBAR, PANEL_ITEM_STATUS, FoobarPanelItem )
-
-FoobarPanelItem* foobar_panel_item_status_new( FoobarPanelItemConfiguration const* config,
- FoobarBatteryService* battery_service,
- FoobarBrightnessService* brightness_service,
- FoobarAudioService* audio_service,
- FoobarNetworkService* network_service,
- FoobarBluetoothService* bluetooth_service,
- FoobarNotificationService* notification_service );
-
-G_END_DECLS
diff --git a/src/widgets/panel/panel-item-workspaces.c b/src/widgets/panel/panel-item-workspaces.c
deleted file mode 100644
index dff629b..0000000
--- a/src/widgets/panel/panel-item-workspaces.c
+++ /dev/null
@@ -1,327 +0,0 @@
-#include "widgets/panel/panel-item-workspaces.h"
-#include "widgets/inset-container.h"
-
-//
-// FoobarPanelItemWorkspaces:
-//
-// A panel item showing all workspaces for the current monitor (if multi-monitor mode is enabled) as buttons, indicating
-// the current state of the workspace (i.e., whether it's active, visible, special, etc.).
-//
-
-struct _FoobarPanelItemWorkspaces
-{
- FoobarPanelItem parent_instance;
- GtkWidget* list_view;
- GtkWidget* inset_container;
- FoobarWorkspaceService* workspace_service;
- gint button_size;
- gint spacing;
- GtkFilter* monitor_filter;
- gulong monitor_configuration_handler_id;
-};
-
-enum
-{
- PROP_ORIENTATION = 1,
- N_PROPS,
-};
-
-static GParamSpec* props[N_PROPS] = { 0 };
-
-static void foobar_panel_item_workspaces_class_init ( FoobarPanelItemWorkspacesClass* klass );
-static void foobar_panel_item_workspaces_init ( FoobarPanelItemWorkspaces* self );
-static void foobar_panel_item_workspaces_get_property ( GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec );
-static void foobar_panel_item_workspaces_set_property ( GObject* object,
- guint prop_id,
- GValue const* value,
- GParamSpec* pspec );
-static void foobar_panel_item_workspaces_finalize ( GObject* object );
-static void foobar_panel_item_workspaces_handle_item_setup ( GtkListItemFactory* factory,
- GtkListItem* list_item,
- gpointer userdata );
-static void foobar_panel_item_workspaces_handle_item_clicked ( GtkButton* button,
- gpointer userdata );
-static void foobar_panel_item_workspaces_handle_monitor_configuration_changed( FoobarWorkspaceService* service,
- gpointer userdata );
-static gchar** foobar_panel_item_workspaces_compute_css_classes ( GtkExpression* expression,
- FoobarWorkspaceFlags flags,
- gpointer userdata );
-static gboolean foobar_panel_item_workspaces_monitor_filter_func ( gpointer item,
- gpointer userdata );
-
-G_DEFINE_FINAL_TYPE_WITH_CODE(
- FoobarPanelItemWorkspaces,
- foobar_panel_item_workspaces,
- FOOBAR_TYPE_PANEL_ITEM,
- G_IMPLEMENT_INTERFACE( GTK_TYPE_ORIENTABLE, NULL ) )
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Panel Item Implementation
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Static initialization for workspace panel items.
-//
-void foobar_panel_item_workspaces_class_init( FoobarPanelItemWorkspacesClass* klass )
-{
- GObjectClass* object_klass = G_OBJECT_CLASS( klass );
- object_klass->get_property = foobar_panel_item_workspaces_get_property;
- object_klass->set_property = foobar_panel_item_workspaces_set_property;
- object_klass->finalize = foobar_panel_item_workspaces_finalize;
-
- gpointer orientable_iface = g_type_default_interface_peek( GTK_TYPE_ORIENTABLE );
- props[PROP_ORIENTATION] = g_param_spec_override(
- "orientation",
- g_object_interface_find_property( orientable_iface, "orientation" ) );
- g_object_class_install_properties( object_klass, N_PROPS, props );
-}
-
-//
-// Instance initialization for workspace panel items.
-//
-void foobar_panel_item_workspaces_init( FoobarPanelItemWorkspaces* self )
-{
- GtkListItemFactory* item_factory = gtk_signal_list_item_factory_new( );
- g_signal_connect( item_factory, "setup", G_CALLBACK( foobar_panel_item_workspaces_handle_item_setup ), self );
-
- self->list_view = gtk_list_view_new( NULL, item_factory );
- gtk_widget_set_halign( self->list_view, GTK_ALIGN_CENTER );
- gtk_widget_set_valign( self->list_view, GTK_ALIGN_CENTER );
- gtk_list_view_set_single_click_activate( GTK_LIST_VIEW( self->list_view ), TRUE );
-
- self->inset_container = foobar_inset_container_new( );
- foobar_inset_container_set_child( FOOBAR_INSET_CONTAINER( self->inset_container ), GTK_WIDGET( self->list_view ) );
-
- gtk_widget_add_css_class( GTK_WIDGET( self ), "workspaces" );
- foobar_panel_item_set_child( FOOBAR_PANEL_ITEM( self ), GTK_WIDGET( self->inset_container ) );
-}
-
-//
-// Property getter implementation, mapping a property id to a method.
-//
-void foobar_panel_item_workspaces_get_property(
- GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec )
-{
- FoobarPanelItemWorkspaces* self = (FoobarPanelItemWorkspaces*)object;
-
- switch ( prop_id )
- {
- case PROP_ORIENTATION:
- g_value_set_enum( value, gtk_orientable_get_orientation( GTK_ORIENTABLE( self->list_view ) ) );
- 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_workspaces_set_property(
- GObject* object,
- guint prop_id,
- GValue const* value,
- GParamSpec* pspec )
-{
- FoobarPanelItemWorkspaces* self = (FoobarPanelItemWorkspaces*)object;
-
- switch ( prop_id )
- {
- case PROP_ORIENTATION:
- gtk_orientable_set_orientation( GTK_ORIENTABLE( self->list_view ), g_value_get_enum( value ) );
- g_object_notify_by_pspec( G_OBJECT( self ), props[PROP_ORIENTATION] );
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec );
- break;
- }
-}
-
-//
-// Instance cleanup for workspace panel items.
-//
-void foobar_panel_item_workspaces_finalize( GObject* object )
-{
- FoobarPanelItemWorkspaces* self = (FoobarPanelItemWorkspaces*)object;
-
- g_clear_signal_handler( &self->monitor_configuration_handler_id, self->workspace_service );
- g_clear_object( &self->workspace_service );
- g_clear_object( &self->monitor_filter );
-
- G_OBJECT_CLASS( foobar_panel_item_workspaces_parent_class )->finalize( object );
-}
-
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Public API
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Create a new workspaces panel item with the given configuration.
-//
-// If monitor is not NULL, only workspaces on this monitor will be shown.
-//
-FoobarPanelItem* foobar_panel_item_workspaces_new(
- FoobarPanelItemConfiguration const* config,
- GdkMonitor* monitor,
- FoobarWorkspaceService* workspace_service )
-{
- g_return_val_if_fail( config != NULL, NULL );
- g_return_val_if_fail( foobar_panel_item_configuration_get_kind( config ) == FOOBAR_PANEL_ITEM_KIND_WORKSPACES, NULL );
- g_return_val_if_fail( monitor == NULL || GDK_IS_MONITOR( monitor ), NULL );
- g_return_val_if_fail( FOOBAR_IS_WORKSPACE_SERVICE( workspace_service ), NULL );
-
- FoobarPanelItemWorkspaces* self = g_object_new( FOOBAR_TYPE_PANEL_ITEM_WORKSPACES, NULL );
- self->button_size = foobar_panel_item_workspaces_configuration_get_button_size( config );
- self->spacing = foobar_panel_item_workspaces_configuration_get_spacing( config );
- self->workspace_service = g_object_ref( workspace_service );
-
- // Set up the source model, optionally enabling filtering.
-
- GListModel* source_model = g_object_ref( foobar_workspace_service_get_workspaces( self->workspace_service ) );
- if ( monitor )
- {
- GtkCustomFilter* filter = gtk_custom_filter_new(
- foobar_panel_item_workspaces_monitor_filter_func,
- g_object_ref( monitor ),
- g_object_unref );
- self->monitor_filter = GTK_FILTER( filter );
- source_model = G_LIST_MODEL( gtk_filter_list_model_new( source_model, g_object_ref( self->monitor_filter ) ) );
-
- self->monitor_configuration_handler_id = g_signal_connect(
- self->workspace_service,
- "monitor-configuration-changed",
- G_CALLBACK( foobar_panel_item_workspaces_handle_monitor_configuration_changed ),
- self );
- }
- GtkNoSelection* selection_model = gtk_no_selection_new( source_model );
- gtk_list_view_set_model( GTK_LIST_VIEW( self->list_view ), GTK_SELECTION_MODEL( selection_model ) );
-
- // Wrap the list in an inset container to remove the outer margin from the items.
-
- foobar_inset_container_set_inset_horizontal( FOOBAR_INSET_CONTAINER( self->inset_container ), -self->spacing / 2 );
- foobar_inset_container_set_inset_vertical( FOOBAR_INSET_CONTAINER( self->inset_container ), -self->spacing / 2 );
-
- return FOOBAR_PANEL_ITEM( self );
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Signal Handlers
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Called by the list view to create a widget for displaying a workspace.
-//
-void foobar_panel_item_workspaces_handle_item_setup(
- GtkListItemFactory* factory,
- GtkListItem* list_item,
- gpointer userdata )
-{
- (void)factory;
- FoobarPanelItemWorkspaces* self = (FoobarPanelItemWorkspaces*)userdata;
-
- GtkWidget* button = gtk_button_new( );
- gtk_widget_set_size_request( button, self->button_size, self->button_size );
- gtk_widget_set_margin_top( button, self->spacing / 2 );
- gtk_widget_set_margin_bottom( button, self->spacing / 2 );
- gtk_widget_set_margin_start( button, self->spacing / 2 );
- gtk_widget_set_margin_end( button, self->spacing / 2 );
- g_signal_connect(
- button,
- "clicked",
- G_CALLBACK( foobar_panel_item_workspaces_handle_item_clicked ),
- list_item );
-
- gtk_list_item_set_child( list_item, button );
-
- {
- GtkExpression* item_expr = gtk_property_expression_new( GTK_TYPE_LIST_ITEM, NULL, "item" );
- GtkExpression* active_expr = gtk_property_expression_new( FOOBAR_TYPE_WORKSPACE, item_expr, "flags" );
- GtkExpression* params[] = { active_expr };
- GtkExpression* css_expr = gtk_cclosure_expression_new(
- G_TYPE_STRV,
- NULL,
- G_N_ELEMENTS( params ),
- params,
- G_CALLBACK( foobar_panel_item_workspaces_compute_css_classes ),
- NULL,
- NULL );
- gtk_expression_bind( css_expr, button, "css-classes", list_item );
- }
-}
-
-//
-// Called by the workspace service when the monitor for any workspace has changed.
-//
-// This is needed because the GtkFilterListModel does not track changes to the item properties and needs to be
-// re-evaluated manually.
-//
-void foobar_panel_item_workspaces_handle_monitor_configuration_changed(
- FoobarWorkspaceService* service,
- gpointer userdata )
-{
- (void)service;
- FoobarPanelItemWorkspaces* self = (FoobarPanelItemWorkspaces*)userdata;
-
- gtk_filter_changed( self->monitor_filter, GTK_FILTER_CHANGE_DIFFERENT );
-}
-
-//
-// Called when a workspace button was clicked, activating that workspace.
-//
-void foobar_panel_item_workspaces_handle_item_clicked( GtkButton* button, gpointer userdata )
-{
- (void)button;
- GtkListItem* item = (GtkListItem*)userdata;
-
- FoobarWorkspace* workspace = gtk_list_item_get_item( item );
- if ( workspace ) { foobar_workspace_activate( workspace ); }
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Value Converters
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Derive the list of CSS classes for a workspace button from the workspace's current flags.
-//
-gchar** foobar_panel_item_workspaces_compute_css_classes(
- GtkExpression* expression,
- FoobarWorkspaceFlags flags,
- gpointer userdata )
-{
- (void)expression;
- (void)userdata;
-
- GStrvBuilder* builder = g_strv_builder_new( );
- if ( flags & FOOBAR_WORKSPACE_FLAGS_ACTIVE ) { g_strv_builder_add( builder, "active" ); }
- if ( flags & FOOBAR_WORKSPACE_FLAGS_VISIBLE ) { g_strv_builder_add( builder, "visible" ); }
- if ( flags & FOOBAR_WORKSPACE_FLAGS_SPECIAL ) { g_strv_builder_add( builder, "special" ); }
- if ( flags & FOOBAR_WORKSPACE_FLAGS_URGENT ) { g_strv_builder_add( builder, "urgent" ); }
- if ( flags & FOOBAR_WORKSPACE_FLAGS_PERSISTENT ) { g_strv_builder_add( builder, "persistent" ); }
- return g_strv_builder_end( builder );
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Helper Methods
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Check if a workspace is on the panel's monitor.
-//
-gboolean foobar_panel_item_workspaces_monitor_filter_func( gpointer item, gpointer userdata )
-{
- FoobarWorkspace* workspace = (FoobarWorkspace*)item;
- GdkMonitor* monitor = (GdkMonitor*)userdata;
-
- gchar const* expected = gdk_monitor_get_connector( monitor );
- gchar const* actual = foobar_workspace_get_monitor( workspace );
- return !expected || !g_strcmp0( expected, actual );
-}
diff --git a/src/widgets/panel/panel-item-workspaces.h b/src/widgets/panel/panel-item-workspaces.h
deleted file mode 100644
index d179217..0000000
--- a/src/widgets/panel/panel-item-workspaces.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include "widgets/panel/panel-item.h"
-#include "services/workspace-service.h"
-
-G_BEGIN_DECLS
-
-#define FOOBAR_TYPE_PANEL_ITEM_WORKSPACES foobar_panel_item_workspaces_get_type( )
-
-G_DECLARE_FINAL_TYPE( FoobarPanelItemWorkspaces, foobar_panel_item_workspaces, FOOBAR, PANEL_ITEM_WORKSPACES, FoobarPanelItem )
-
-FoobarPanelItem* foobar_panel_item_workspaces_new( FoobarPanelItemConfiguration const* config,
- GdkMonitor* monitor,
- FoobarWorkspaceService* workspace_service );
-
-G_END_DECLS
diff --git a/src/widgets/panel/panel-item.c b/src/widgets/panel/panel-item.c
deleted file mode 100644
index 918d9f5..0000000
--- a/src/widgets/panel/panel-item.c
+++ /dev/null
@@ -1,195 +0,0 @@
-#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;
- }
-}
diff --git a/src/widgets/panel/panel-item.h b/src/widgets/panel/panel-item.h
deleted file mode 100644
index 12a7e35..0000000
--- a/src/widgets/panel/panel-item.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-#include <gtk/gtk.h>
-#include "services/configuration-service.h"
-
-G_BEGIN_DECLS
-
-#define FOOBAR_TYPE_PANEL_ITEM foobar_panel_item_get_type( )
-
-G_DECLARE_DERIVABLE_TYPE( FoobarPanelItem, foobar_panel_item, FOOBAR, PANEL_ITEM, GtkWidget )
-
-struct _FoobarPanelItemClass
-{
- GtkWidgetClass parent_class;
-};
-
-GtkWidget* foobar_panel_item_get_child ( FoobarPanelItem* self );
-void foobar_panel_item_set_child ( FoobarPanelItem* self,
- GtkWidget* child );
-void foobar_panel_item_invoke_action( FoobarPanelItem* self,
- FoobarPanelItemAction action );
-
-G_END_DECLS