summaryrefslogtreecommitdiff
path: root/src/widgets/inset-container.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/inset-container.c')
-rw-r--r--src/widgets/inset-container.c363
1 files changed, 0 insertions, 363 deletions
diff --git a/src/widgets/inset-container.c b/src/widgets/inset-container.c
deleted file mode 100644
index 052f872..0000000
--- a/src/widgets/inset-container.c
+++ /dev/null
@@ -1,363 +0,0 @@
-#include "widgets/inset-container.h"
-
-//
-// FoobarInsetContainer:
-//
-// A custom widget which renders a child with an inset/padding.
-//
-// Notably, it also supports negative inset values which is useful in order to provide uniform spacing between widgets.
-//
-
-struct _FoobarInsetContainer
-{
- GtkWidget parent_instance;
- GtkWidget* child;
- gint inset_horizontal;
- gint inset_vertical;
-};
-
-enum
-{
- PROP_CHILD = 1,
- PROP_INSET_HORIZONTAL,
- PROP_INSET_VERTICAL,
- N_PROPS,
-};
-
-static GParamSpec* props[N_PROPS] = { 0 };
-
-static void foobar_inset_container_class_init ( FoobarInsetContainerClass* klass );
-static void foobar_inset_container_init ( FoobarInsetContainer* self );
-static void foobar_inset_container_get_property ( GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec );
-static void foobar_inset_container_set_property ( GObject* object,
- guint prop_id,
- GValue const* value,
- GParamSpec* pspec );
-static void foobar_inset_container_dispose ( GObject* object );
-static GtkSizeRequestMode foobar_inset_container_get_request_mode( GtkWidget* widget );
-static void foobar_inset_container_measure ( GtkWidget* widget,
- GtkOrientation orientation,
- int for_size,
- int* minimum,
- int* natural,
- int* minimum_baseline,
- int* natural_baseline );
-static void foobar_inset_container_size_allocate ( GtkWidget* widget,
- int width,
- int height,
- int baseline );
-
-G_DEFINE_FINAL_TYPE( FoobarInsetContainer, foobar_inset_container, GTK_TYPE_WIDGET )
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Widget Implementation
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Static initialization for inset containers.
-//
-void foobar_inset_container_class_init( FoobarInsetContainerClass* klass )
-{
- GtkWidgetClass* widget_klass = GTK_WIDGET_CLASS( klass );
- widget_klass->get_request_mode = foobar_inset_container_get_request_mode;
- widget_klass->measure = foobar_inset_container_measure;
- widget_klass->size_allocate = foobar_inset_container_size_allocate;
- gtk_widget_class_set_css_name( widget_klass, "inset-container" );
-
- GObjectClass* object_klass = G_OBJECT_CLASS( klass );
- object_klass->get_property = foobar_inset_container_get_property;
- object_klass->set_property = foobar_inset_container_set_property;
- object_klass->dispose = foobar_inset_container_dispose;
-
- props[PROP_CHILD] = g_param_spec_object(
- "child",
- "Child",
- "Child widget for the panel item.",
- GTK_TYPE_WIDGET,
- G_PARAM_READWRITE );
- props[PROP_INSET_HORIZONTAL] = g_param_spec_int(
- "inset-horizontal",
- "Inset Horizontal",
- "The horizontal offset (may be negative).",
- INT_MIN,
- INT_MAX,
- 0,
- G_PARAM_READWRITE );
- props[PROP_INSET_VERTICAL] = g_param_spec_int(
- "inset-vertical",
- "Inset Vertical",
- "The vertical offset (may be negative).",
- INT_MIN,
- INT_MAX,
- 0,
- G_PARAM_READWRITE );
- g_object_class_install_properties( object_klass, N_PROPS, props );
-}
-
-//
-// Instance initialization for inset containers.
-//
-void foobar_inset_container_init( FoobarInsetContainer* self )
-{
- (void)self;
-}
-
-//
-// Property getter implementation, mapping a property id to a method.
-//
-void foobar_inset_container_get_property(
- GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec )
-{
- FoobarInsetContainer* self = (FoobarInsetContainer*)object;
-
- switch ( prop_id )
- {
- case PROP_CHILD:
- g_value_set_object( value, foobar_inset_container_get_child( self ) );
- break;
- case PROP_INSET_HORIZONTAL:
- g_value_set_int( value, foobar_inset_container_get_inset_horizontal( self ) );
- break;
- case PROP_INSET_VERTICAL:
- g_value_set_int( value, foobar_inset_container_get_inset_vertical( 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_inset_container_set_property(
- GObject* object,
- guint prop_id,
- GValue const* value,
- GParamSpec* pspec )
-{
- FoobarInsetContainer* self = (FoobarInsetContainer*)object;
-
- switch ( prop_id )
- {
- case PROP_CHILD:
- foobar_inset_container_set_child( self, g_value_get_object( value ) );
- break;
- case PROP_INSET_HORIZONTAL:
- foobar_inset_container_set_inset_horizontal( self, g_value_get_int( value ) );
- break;
- case PROP_INSET_VERTICAL:
- foobar_inset_container_set_inset_vertical( self, g_value_get_int( value ) );
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec );
- break;
- }
-}
-
-//
-// Instance de-initialization for inset containers.
-//
-void foobar_inset_container_dispose( GObject* object )
-{
- FoobarInsetContainer* self = (FoobarInsetContainer*)object;
-
- g_clear_pointer( &self->child, gtk_widget_unparent );
-
- G_OBJECT_CLASS( foobar_inset_container_parent_class )->dispose( object );
-}
-
-//
-// Determine the size request mode used to measure the widget.
-//
-// This implementation just forwards the request mode from the child widget.
-//
-GtkSizeRequestMode foobar_inset_container_get_request_mode( GtkWidget* widget )
-{
- FoobarInsetContainer* self = (FoobarInsetContainer*)widget;
- if ( !self->child ) { return GTK_SIZE_REQUEST_CONSTANT_SIZE; }
-
- return gtk_widget_get_request_mode( self->child );
-}
-
-//
-// Compute the requested size of the widget.
-//
-// This implementation uses the size requested by the child widget and then adds the inset to it.
-//
-void foobar_inset_container_measure(
- GtkWidget* widget,
- GtkOrientation orientation,
- int for_size,
- int* minimum,
- int* natural,
- int* minimum_baseline,
- int* natural_baseline )
-{
- FoobarInsetContainer* self = (FoobarInsetContainer*)widget;
- if ( !self->child )
- {
- *minimum = 0;
- *natural = 0;
- *minimum_baseline = 0;
- *natural_baseline = 0;
- return;
- }
-
- // Get the inset for the given orientation and the other one.
-
- gint inset;
- gint other_inset;
- switch ( orientation )
- {
- case GTK_ORIENTATION_HORIZONTAL:
- inset = self->inset_horizontal;
- other_inset = self->inset_vertical;
- break;
- case GTK_ORIENTATION_VERTICAL:
- inset = self->inset_vertical;
- other_inset = self->inset_horizontal;
- break;
- default:
- g_warn_if_reached( );
- return;
- }
-
- // Compute the new size, taking into consideration that the inset might have already been added to measure the other
- // side and needs to be subtracted before passing it to the child widget's measure function.
-
- for_size = MAX( 0, for_size - ( 2 * other_inset ) );
- gtk_widget_measure( self->child, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline );
- *minimum = MAX( 0, *minimum + ( 2 * inset ) );
- *natural = MAX( 0, *natural + ( 2 * inset ) );
- if ( orientation == GTK_ORIENTATION_VERTICAL )
- {
- *minimum_baseline = MAX( 0, *minimum_baseline + inset );
- *natural_baseline = MAX( 0, *natural_baseline + inset );
- }
-}
-
-//
-// Arrange the child widget.
-//
-void foobar_inset_container_size_allocate(
- GtkWidget* widget,
- int width,
- int height,
- int baseline )
-{
- FoobarInsetContainer* self = (FoobarInsetContainer*)widget;
- if ( !self->child ) { return; }
-
- GtkAllocation allocation =
- {
- .width = MAX( 0, width - 2 * self->inset_horizontal ),
- .height = MAX( 0, height - 2 * self->inset_vertical ),
- .x = self->inset_horizontal,
- .y = self->inset_vertical,
- };
- gtk_widget_size_allocate( self->child, &allocation, MAX( 0, baseline + self->inset_vertical ) );
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-// Public API
-// ---------------------------------------------------------------------------------------------------------------------
-
-//
-// Create a new inset container instance.
-//
-GtkWidget* foobar_inset_container_new( void )
-{
- return g_object_new( FOOBAR_TYPE_INSET_CONTAINER, NULL );
-}
-
-//
-// Get the container's child widget.
-//
-GtkWidget* foobar_inset_container_get_child( FoobarInsetContainer* self )
-{
- g_return_val_if_fail( FOOBAR_IS_INSET_CONTAINER( self ), NULL );
- return self->child;
-}
-
-//
-// Get the inset applied to the left and right side of the widget.
-//
-gint foobar_inset_container_get_inset_horizontal( FoobarInsetContainer* self )
-{
- g_return_val_if_fail( FOOBAR_IS_INSET_CONTAINER( self ), 0 );
- return self->inset_horizontal;
-}
-
-//
-// Get the inset applied to the top and bottom side of the widget.
-//
-gint foobar_inset_container_get_inset_vertical( FoobarInsetContainer* self )
-{
- g_return_val_if_fail( FOOBAR_IS_INSET_CONTAINER( self ), 0 );
- return self->inset_vertical;
-}
-
-//
-// Update the container's child widget.
-//
-void foobar_inset_container_set_child(
- FoobarInsetContainer* self,
- GtkWidget* child )
-{
- g_return_if_fail( FOOBAR_IS_INSET_CONTAINER( self ) );
- g_return_if_fail( child == NULL || self->child == child || gtk_widget_get_parent( child ) == NULL );
-
- if ( self->child != child )
- {
- g_clear_pointer( &self->child, gtk_widget_unparent );
-
- if ( child )
- {
- self->child = child;
- gtk_widget_set_parent( child, GTK_WIDGET( self ) );
- }
-
- g_object_notify_by_pspec( G_OBJECT( self ), props[PROP_CHILD] );
- }
-}
-
-//
-// Update the inset applied to the left and right side of the widget.
-//
-void foobar_inset_container_set_inset_horizontal(
- FoobarInsetContainer* self,
- gint value )
-{
- g_return_if_fail( FOOBAR_IS_INSET_CONTAINER( self ) );
-
- if ( self->inset_horizontal != value )
- {
- self->inset_horizontal = value;
- gtk_widget_queue_resize( GTK_WIDGET( self ) );
- g_object_notify_by_pspec( G_OBJECT( self ), props[PROP_INSET_HORIZONTAL] );
- }
-}
-
-//
-// Update the inset applied to the top and bottom side of the widget.
-//
-void foobar_inset_container_set_inset_vertical(
- FoobarInsetContainer* self,
- gint value )
-{
- g_return_if_fail( FOOBAR_IS_INSET_CONTAINER( self ) );
-
- if ( self->inset_vertical != value )
- {
- self->inset_vertical = value;
- gtk_widget_queue_resize( GTK_WIDGET( self ) );
- g_object_notify_by_pspec( G_OBJECT( self ), props[PROP_INSET_VERTICAL] );
- }
-}