From 1af3d14f3f995645a0de08a54b244c19840709e9 Mon Sep 17 00:00:00 2001 From: Hannes Schulze Date: Thu, 19 Jun 2025 23:17:58 +0200 Subject: init hs project --- src/panel.c | 348 ------------------------------------------------------------ 1 file changed, 348 deletions(-) delete mode 100644 src/panel.c (limited to 'src/panel.c') diff --git a/src/panel.c b/src/panel.c deleted file mode 100644 index 5bc7662..0000000 --- a/src/panel.c +++ /dev/null @@ -1,348 +0,0 @@ -#include "panel.h" -#include "widgets/panel/panel-item-icon.h" -#include "widgets/panel/panel-item-clock.h" -#include "widgets/panel/panel-item-workspaces.h" -#include "widgets/panel/panel-item-status.h" -#include - -// -// FoobarPanel: -// -// A panel that is divided into start, center and end sections. Each section can be configured to present a range of -// items. -// - -struct _FoobarPanel -{ - GtkWindow parent_instance; - GtkWidget* main_layout; - GtkWidget* start_items; - GtkWidget* center_items; - GtkWidget* end_items; - GPtrArray* item_widgets; - GdkMonitor* monitor; - FoobarBatteryService* battery_service; - FoobarClockService* clock_service; - FoobarBrightnessService* brightness_service; - FoobarWorkspaceService* workspace_service; - FoobarAudioService* audio_service; - FoobarNetworkService* network_service; - FoobarBluetoothService* bluetooth_service; - FoobarNotificationService* notification_service; - FoobarConfigurationService* configuration_service; - gulong config_handler_id; -}; - -static void foobar_panel_class_init ( FoobarPanelClass* klass ); -static void foobar_panel_init ( FoobarPanel* self ); -static void foobar_panel_finalize ( GObject* object ); -static void foobar_panel_handle_config_change( GObject* object, - GParamSpec* pspec, - gpointer userdata ); - -G_DEFINE_FINAL_TYPE( FoobarPanel, foobar_panel, GTK_TYPE_APPLICATION_WINDOW ) - -// --------------------------------------------------------------------------------------------------------------------- -// Window Implementation -// --------------------------------------------------------------------------------------------------------------------- - -// -// Static initialization for the panel. -// -void foobar_panel_class_init( FoobarPanelClass* klass ) -{ - GObjectClass* object_klass = G_OBJECT_CLASS( klass ); - object_klass->finalize = foobar_panel_finalize; -} - -// -// Instance initialization for the panel. -// -void foobar_panel_init( FoobarPanel* self ) -{ - self->start_items = gtk_box_new( GTK_ORIENTATION_VERTICAL, 0 ); - self->center_items = gtk_box_new( GTK_ORIENTATION_VERTICAL, 0 ); - self->end_items = gtk_box_new( GTK_ORIENTATION_VERTICAL, 0 ); - - self->main_layout = gtk_center_box_new( ); - gtk_center_box_set_start_widget( GTK_CENTER_BOX( self->main_layout ), self->start_items ); - gtk_center_box_set_center_widget( GTK_CENTER_BOX( self->main_layout ), self->center_items ); - gtk_center_box_set_end_widget( GTK_CENTER_BOX( self->main_layout ), self->end_items ); - - gtk_window_set_child( GTK_WINDOW( self ), self->main_layout ); - gtk_window_set_title( GTK_WINDOW( self ), "Foobar Panel" ); - gtk_widget_add_css_class( GTK_WIDGET( self ), "panel" ); - gtk_layer_init_for_window( GTK_WINDOW( self ) ); - gtk_layer_set_namespace( GTK_WINDOW( self ), "foobar-panel" ); - gtk_layer_auto_exclusive_zone_enable( GTK_WINDOW( self ) ); -} - -// -// Instance cleanup for the panel. -// -void foobar_panel_finalize( GObject* object ) -{ - FoobarPanel* self = (FoobarPanel*)object; - - g_clear_signal_handler( &self->config_handler_id, self->configuration_service ); - g_clear_object( &self->monitor ); - g_clear_object( &self->battery_service ); - g_clear_object( &self->clock_service ); - g_clear_object( &self->brightness_service ); - g_clear_object( &self->workspace_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_object( &self->configuration_service ); - g_clear_pointer( &self->item_widgets, g_ptr_array_unref ); - - G_OBJECT_CLASS( foobar_panel_parent_class )->finalize( object ); -} - -// --------------------------------------------------------------------------------------------------------------------- -// Public API -// --------------------------------------------------------------------------------------------------------------------- - -// -// Create a new panel instance. -// -// An optional GdkMonitor instance can be provided for multi-monitor setups. Otherwise, the default monitor is used. -// -FoobarPanel* foobar_panel_new( - GtkApplication* app, - GdkMonitor* monitor, - FoobarBatteryService* battery_service, - FoobarClockService* clock_service, - FoobarBrightnessService* brightness_service, - FoobarWorkspaceService* workspace_service, - FoobarAudioService* audio_service, - FoobarNetworkService* network_service, - FoobarBluetoothService* bluetooth_service, - FoobarNotificationService* notification_service, - FoobarConfigurationService* configuration_service ) -{ - g_return_val_if_fail( GTK_IS_APPLICATION( app ), NULL ); - g_return_val_if_fail( monitor == NULL || GDK_IS_MONITOR( monitor ), NULL ); - g_return_val_if_fail( FOOBAR_IS_BATTERY_SERVICE( battery_service ), NULL ); - g_return_val_if_fail( FOOBAR_IS_CLOCK_SERVICE( clock_service ), NULL ); - g_return_val_if_fail( FOOBAR_IS_BRIGHTNESS_SERVICE( brightness_service ), NULL ); - g_return_val_if_fail( FOOBAR_IS_WORKSPACE_SERVICE( workspace_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 ); - g_return_val_if_fail( FOOBAR_IS_CONFIGURATION_SERVICE( configuration_service ), NULL ); - - FoobarPanel* self = g_object_new( FOOBAR_TYPE_PANEL, "application", app, NULL ); - self->battery_service = g_object_ref( battery_service ); - self->clock_service = g_object_ref( clock_service ); - self->brightness_service = g_object_ref( brightness_service ); - self->workspace_service = g_object_ref( workspace_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 ); - self->configuration_service = g_object_ref( configuration_service ); - - // Set the monitor. - - if ( monitor ) - { - self->monitor = g_object_ref( monitor ); - gtk_layer_set_monitor( GTK_WINDOW( self ), self->monitor ); - } - - // Apply the configuration and subscribe to changes. - - FoobarConfiguration const* config = foobar_configuration_service_get_current( self->configuration_service ); - foobar_panel_apply_configuration( self, foobar_configuration_get_panel( config ) ); - self->config_handler_id = g_signal_connect( - self->configuration_service, - "notify::current", - G_CALLBACK( foobar_panel_handle_config_change ), - self ); - - return self; -} - -// -// Apply the panel configuration provided by the configuration service. -// -void foobar_panel_apply_configuration( - FoobarPanel* self, - FoobarPanelConfiguration const* config ) -{ - g_return_if_fail( FOOBAR_IS_PANEL( self ) ); - g_return_if_fail( config != NULL ); - - // Derive the orientation from the panel's position. - - FoobarScreenEdge position = foobar_panel_configuration_get_position( config ); - GtkOrientation orientation; - gchar const* orientation_css_class; - switch ( position ) - { - case FOOBAR_SCREEN_EDGE_LEFT: - case FOOBAR_SCREEN_EDGE_RIGHT: - orientation = GTK_ORIENTATION_VERTICAL; - orientation_css_class = "vertical"; - break; - case FOOBAR_SCREEN_EDGE_TOP: - case FOOBAR_SCREEN_EDGE_BOTTOM: - orientation = GTK_ORIENTATION_HORIZONTAL; - orientation_css_class = "horizontal"; - break; - default: - g_warn_if_reached( ); - return; - } - - // Configure the window. - - gtk_widget_remove_css_class( GTK_WIDGET( self ), "horizontal" ); - gtk_widget_remove_css_class( GTK_WIDGET( self ), "vertical" ); - gtk_widget_add_css_class( GTK_WIDGET( self ), orientation_css_class ); - - gint size = foobar_panel_configuration_get_size( config ); - gtk_window_set_default_size( - GTK_WINDOW( self ), - orientation == GTK_ORIENTATION_VERTICAL ? size : -1, - orientation == GTK_ORIENTATION_HORIZONTAL ? size : -1 ); - - gtk_layer_set_anchor( GTK_WINDOW( self ), GTK_LAYER_SHELL_EDGE_LEFT, position != FOOBAR_SCREEN_EDGE_RIGHT ); - gtk_layer_set_anchor( GTK_WINDOW( self ), GTK_LAYER_SHELL_EDGE_RIGHT, position != FOOBAR_SCREEN_EDGE_LEFT ); - gtk_layer_set_anchor( GTK_WINDOW( self ), GTK_LAYER_SHELL_EDGE_TOP, position != FOOBAR_SCREEN_EDGE_BOTTOM ); - gtk_layer_set_anchor( GTK_WINDOW( self ), GTK_LAYER_SHELL_EDGE_BOTTOM, position != FOOBAR_SCREEN_EDGE_TOP ); - - // Configure layout spacing. - - gint margin = foobar_panel_configuration_get_margin( config ); - gtk_layer_set_margin( GTK_WINDOW( self ), GTK_LAYER_SHELL_EDGE_LEFT, position != FOOBAR_SCREEN_EDGE_RIGHT ? margin : 0 ); - gtk_layer_set_margin( GTK_WINDOW( self ), GTK_LAYER_SHELL_EDGE_RIGHT, position != FOOBAR_SCREEN_EDGE_LEFT ? margin : 0 ); - gtk_layer_set_margin( GTK_WINDOW( self ), GTK_LAYER_SHELL_EDGE_TOP, position != FOOBAR_SCREEN_EDGE_BOTTOM ? margin : 0 ); - gtk_layer_set_margin( GTK_WINDOW( self ), GTK_LAYER_SHELL_EDGE_BOTTOM, position != FOOBAR_SCREEN_EDGE_TOP ? margin : 0 ); - - gint padding = foobar_panel_configuration_get_padding( config ); - gtk_widget_set_margin_start( GTK_WIDGET( self->main_layout ), orientation == GTK_ORIENTATION_HORIZONTAL ? padding : 0 ); - gtk_widget_set_margin_end( GTK_WIDGET( self->main_layout ), orientation == GTK_ORIENTATION_HORIZONTAL ? padding : 0 ); - gtk_widget_set_margin_top( GTK_WIDGET( self->main_layout ), orientation == GTK_ORIENTATION_VERTICAL ? padding : 0 ); - gtk_widget_set_margin_bottom( GTK_WIDGET( self->main_layout ), orientation == GTK_ORIENTATION_VERTICAL ? padding : 0 ); - - gint spacing = foobar_panel_configuration_get_spacing( config ); - gtk_box_set_spacing( GTK_BOX(self->start_items), spacing ); - gtk_box_set_spacing( GTK_BOX(self->center_items), spacing ); - gtk_box_set_spacing( GTK_BOX(self->end_items), spacing ); - gtk_widget_set_margin_top( GTK_WIDGET( self->center_items ), orientation == GTK_ORIENTATION_VERTICAL ? spacing : 0 ); - gtk_widget_set_margin_bottom( GTK_WIDGET( self->center_items ), orientation == GTK_ORIENTATION_VERTICAL ? spacing : 0 ); - gtk_widget_set_margin_start( GTK_WIDGET( self->center_items ), orientation == GTK_ORIENTATION_HORIZONTAL ? spacing : 0 ); - gtk_widget_set_margin_end( GTK_WIDGET( self->center_items ), orientation == GTK_ORIENTATION_HORIZONTAL ? spacing : 0 ); - - // Configure the container orientations. - - gtk_orientable_set_orientation( GTK_ORIENTABLE( self->main_layout ), orientation ); - gtk_orientable_set_orientation( GTK_ORIENTABLE( self->start_items ), orientation ); - gtk_orientable_set_orientation( GTK_ORIENTABLE( self->center_items ), orientation ); - gtk_orientable_set_orientation( GTK_ORIENTABLE( self->end_items ), orientation ); - - // Re-create panel items. - - if ( self->item_widgets ) - { - for ( guint i = 0; i < self->item_widgets->len; ++i ) - { - gtk_widget_unparent( g_ptr_array_index( self->item_widgets, i ) ); - } - g_clear_pointer( &self->item_widgets, g_ptr_array_unref ); - } - - gsize items_count; - FoobarPanelItemConfiguration const* const* items = foobar_panel_configuration_get_items( config, &items_count ); - self->item_widgets = g_ptr_array_sized_new( items_count ); - for ( gsize i = 0; i < items_count; ++i ) - { - // Create an item for the specified type and configuration. - - FoobarPanelItemConfiguration const* item = items[i]; - FoobarPanelItem* item_widget; - switch ( foobar_panel_item_configuration_get_kind( item ) ) - { - case FOOBAR_PANEL_ITEM_KIND_ICON: - item_widget = foobar_panel_item_icon_new( item ); - break; - case FOOBAR_PANEL_ITEM_KIND_CLOCK: - item_widget = foobar_panel_item_clock_new( - item, - self->clock_service ); - break; - case FOOBAR_PANEL_ITEM_KIND_WORKSPACES: - item_widget = foobar_panel_item_workspaces_new( - item, - self->monitor, - self->workspace_service ); - break; - case FOOBAR_PANEL_ITEM_KIND_STATUS: - item_widget = foobar_panel_item_status_new( - item, - self->battery_service, - self->brightness_service, - self->audio_service, - self->network_service, - self->bluetooth_service, - self->notification_service ); - break; - default: - g_warn_if_reached( ); - continue; - } - - // Propagate the panel's orientation if the item supports it. - - if ( GTK_IS_ORIENTABLE( item_widget ) ) - { - gtk_orientable_set_orientation( GTK_ORIENTABLE( item_widget ), orientation ); - } - - // Add the item to the correct container, depending on its configured position. - - switch ( foobar_panel_item_configuration_get_position( item ) ) - { - case FOOBAR_PANEL_ITEM_POSITION_START: - gtk_box_append( GTK_BOX( self->start_items ), GTK_WIDGET( item_widget ) ); - break; - case FOOBAR_PANEL_ITEM_POSITION_CENTER: - gtk_box_append( GTK_BOX( self->center_items ), GTK_WIDGET( item_widget ) ); - break; - case FOOBAR_PANEL_ITEM_POSITION_END: - gtk_box_append( GTK_BOX( self->end_items ), GTK_WIDGET( item_widget ) ); - break; - default: - g_warn_if_reached( ); - break; - } - - // Add the item to the pointer array for easier cleanup. - - g_ptr_array_add( self->item_widgets, GTK_WIDGET( item_widget ) ); - } -} - -// --------------------------------------------------------------------------------------------------------------------- -// Signal Handlers -// --------------------------------------------------------------------------------------------------------------------- - -// -// Signal handler called when the global configuration file has changed. -// -void foobar_panel_handle_config_change( - GObject* object, - GParamSpec* pspec, - gpointer userdata ) -{ - (void)object; - (void)pspec; - FoobarPanel* self = (FoobarPanel*)userdata; - - FoobarConfiguration const* config = foobar_configuration_service_get_current( self->configuration_service ); - foobar_panel_apply_configuration( self, foobar_configuration_get_panel( config ) ); -} -- cgit v1.3.1