summaryrefslogtreecommitdiff
path: root/src/panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/panel.c')
-rw-r--r--src/panel.c348
1 files changed, 0 insertions, 348 deletions
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 <gtk4-layer-shell.h>
-
-//
-// 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 ) );
-}