summaryrefslogtreecommitdiff
path: root/csrc/widgets/panel/panel-item-clock.c
blob: 00b2cc5d68af1748b06bf43508d8a230c3a3b945 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#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 );
}