1 /*
2 *
3 * Author: Giacomo Lozito <james@develia.org>, (C) 2005-2007
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
18 *
19 */
20 
21 #include <math.h>
22 
23 #include <gtk/gtk.h>
24 
25 #include <libaudcore/i18n.h>
26 #include <libaudcore/index.h>
27 #include <libaudcore/preferences.h>
28 
29 #include "aosd.h"
30 #include "aosd_style.h"
31 #include "aosd_trigger.h"
32 #include "aosd_cfg.h"
33 #include "aosd_osd.h"
34 
35 
chooser_get_aosd_color(GtkColorButton * chooser,aosd_color_t * color)36 static void chooser_get_aosd_color (GtkColorButton * chooser, aosd_color_t * color)
37 {
38   GdkColor gdk_color;
39   gtk_color_button_get_color (chooser, & gdk_color);
40 
41   color->red = gdk_color.red;
42   color->green = gdk_color.green;
43   color->blue = gdk_color.blue;
44   color->alpha = gtk_color_button_get_alpha (chooser);
45 }
46 
47 
chooser_set_aosd_color(GtkColorButton * chooser,const aosd_color_t * color)48 static void chooser_set_aosd_color (GtkColorButton * chooser, const aosd_color_t * color)
49 {
50   GdkColor gdk_color = {0, (uint16_t) color->red, (uint16_t) color->green, (uint16_t) color->blue};
51 
52   gtk_color_button_set_color (chooser, & gdk_color);
53   gtk_color_button_set_use_alpha (chooser, true);
54   gtk_color_button_set_alpha (chooser, color->alpha);
55 }
56 
57 
58 /*************************************************************/
59 /* small callback system used by the configuration interface */
60 typedef void (*aosd_ui_cb_func_t)( GtkWidget * , aosd_cfg_t * );
61 
62 typedef struct
63 {
64   GtkWidget * widget;
65   aosd_ui_cb_func_t func;
66 }
67 aosd_ui_cb_t;
68 
69 static Index<aosd_ui_cb_t> aosd_cb_list;
70 
71 static void
aosd_callback_list_run(aosd_cfg_t * cfg)72 aosd_callback_list_run ( aosd_cfg_t * cfg )
73 {
74   for (const aosd_ui_cb_t & cb : aosd_cb_list)
75     cb.func (cb.widget, cfg);
76 }
77 /*************************************************************/
78 
79 
80 
81 static gboolean
aosd_cb_configure_position_expose(GtkWidget * darea,GdkEventExpose * event,void * coord_gp)82 aosd_cb_configure_position_expose ( GtkWidget * darea ,
83                                     GdkEventExpose * event ,
84                                     void * coord_gp )
85 {
86   int coord = GPOINTER_TO_INT(coord_gp);
87 
88   cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (darea));
89   cairo_set_source_rgb ( cr , 0 , 0 , 0 );
90   cairo_rectangle ( cr , (coord % 3) * 10 , (coord / 3) * 16 , 20 , 8 );
91   cairo_fill ( cr );
92   cairo_destroy (cr);
93 
94   return false;
95 }
96 
97 
98 static void
aosd_cb_configure_position_placement_commit(GtkWidget * grid,aosd_cfg_t * cfg)99 aosd_cb_configure_position_placement_commit ( GtkWidget * grid , aosd_cfg_t * cfg )
100 {
101   GList *placbt_list = gtk_container_get_children( GTK_CONTAINER(grid) );
102 
103   for ( GList *iter = placbt_list; iter != nullptr; iter = iter->next )
104   {
105     GtkWidget *placbt = (GtkWidget *) iter->data;
106 
107     if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(placbt) ) == true )
108     {
109       cfg->position.placement = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(placbt),"value"));
110       break;
111     }
112   }
113 
114   g_list_free( placbt_list );
115 }
116 
117 
118 static void
aosd_cb_configure_position_offset_commit(GtkWidget * grid,aosd_cfg_t * cfg)119 aosd_cb_configure_position_offset_commit ( GtkWidget * grid , aosd_cfg_t * cfg )
120 {
121   cfg->position.offset_x = gtk_spin_button_get_value_as_int(
122     GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(grid),"offx")) );
123   cfg->position.offset_y = gtk_spin_button_get_value_as_int(
124     GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(grid),"offy")) );
125 }
126 
127 
128 static void
aosd_cb_configure_position_maxsize_commit(GtkWidget * grid,aosd_cfg_t * cfg)129 aosd_cb_configure_position_maxsize_commit ( GtkWidget * grid , aosd_cfg_t * cfg )
130 {
131   cfg->position.maxsize_width = gtk_spin_button_get_value_as_int(
132     GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(grid),"maxsize_width")) );
133 }
134 
135 
136 static void
aosd_cb_configure_position_multimon_commit(GtkWidget * combo,aosd_cfg_t * cfg)137 aosd_cb_configure_position_multimon_commit ( GtkWidget * combo , aosd_cfg_t * cfg )
138 {
139   int active = gtk_combo_box_get_active( GTK_COMBO_BOX(combo) );
140   cfg->position.multimon_id = ( active > -1 ) ? (active - 1) : -1;
141 }
142 
143 
144 static GtkWidget *
aosd_ui_configure_position(aosd_cfg_t * cfg)145 aosd_ui_configure_position ( aosd_cfg_t * cfg )
146 {
147   GtkWidget *pos_vbox;
148   GtkWidget *pos_placement_frame, *pos_placement_hbox, *pos_placement_grid;
149   GtkWidget *pos_placement_bt[9], *pos_placement_bt_darea[9];
150   GtkWidget *pos_offset_grid, *pos_offset_x_label, *pos_offset_x_spinbt;
151   GtkWidget *pos_offset_y_label, *pos_offset_y_spinbt;
152   GtkWidget *pos_maxsize_width_label, *pos_maxsize_width_spinbt;
153   GtkWidget *pos_multimon_frame, *pos_multimon_hbox;
154   GtkWidget *pos_multimon_label;
155   GtkWidget *pos_multimon_combobox;
156   int monitors_num = gdk_screen_get_n_monitors( gdk_screen_get_default() );
157   int i = 0;
158 
159   pos_vbox = gtk_vbox_new( false , 4 );
160   gtk_container_set_border_width( GTK_CONTAINER(pos_vbox) , 6 );
161 
162   pos_placement_frame = gtk_frame_new( _("Placement") );
163   pos_placement_hbox = gtk_hbox_new( false , 0 );
164   gtk_container_set_border_width( GTK_CONTAINER(pos_placement_hbox) , 6 );
165   gtk_container_add( GTK_CONTAINER(pos_placement_frame) , pos_placement_hbox );
166   gtk_box_pack_start( GTK_BOX(pos_vbox) , pos_placement_frame , false , false , 0 );
167 
168   pos_placement_grid = gtk_table_new (0, 0, false);
169   for ( i = 0 ; i < 9 ; i++ )
170   {
171     if ( i == 0 )
172       pos_placement_bt[i] = gtk_radio_button_new( nullptr );
173     else
174       pos_placement_bt[i] = gtk_radio_button_new_from_widget( GTK_RADIO_BUTTON(pos_placement_bt[0]) );
175     gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON(pos_placement_bt[i]) , false );
176     pos_placement_bt_darea[i] = gtk_drawing_area_new();
177     gtk_widget_set_size_request( pos_placement_bt_darea[i] , 40 , 40 );
178     gtk_container_add( GTK_CONTAINER(pos_placement_bt[i]) , pos_placement_bt_darea[i] );
179     g_signal_connect( G_OBJECT(pos_placement_bt_darea[i]) , "expose-event" ,
180                       G_CALLBACK(aosd_cb_configure_position_expose) , GINT_TO_POINTER(i) );
181     gtk_table_attach_defaults( GTK_TABLE(pos_placement_grid) , pos_placement_bt[i] ,
182                                (i % 3) , (i % 3) + 1 , (i / 3) , (i / 3) + 1 );
183     g_object_set_data( G_OBJECT(pos_placement_bt[i]) , "value" , GINT_TO_POINTER(i+1) );
184     if ( cfg->position.placement == (i+1) )
185       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pos_placement_bt[i]) , true );
186   }
187   gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , pos_placement_grid , false , false , 0 );
188   aosd_cb_list.append( pos_placement_grid , aosd_cb_configure_position_placement_commit );
189 
190   gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , gtk_vseparator_new() , false , false , 6 );
191 
192   pos_offset_grid = gtk_table_new (0, 0, false);
193   gtk_table_set_row_spacings( GTK_TABLE(pos_offset_grid) , 4 );
194   gtk_table_set_col_spacings( GTK_TABLE(pos_offset_grid) , 4 );
195   pos_offset_x_label = gtk_label_new( _( "Relative X offset:" ) );
196   gtk_misc_set_alignment( GTK_MISC(pos_offset_x_label) , 0 , 0.5 );
197   gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_x_label , 0 , 1 , 0 , 1 );
198   pos_offset_x_spinbt = gtk_spin_button_new_with_range( -9999 , 9999 , 1 );
199   gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_offset_x_spinbt) , cfg->position.offset_x );
200   gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_x_spinbt , 1 , 2 , 0 , 1 );
201   g_object_set_data( G_OBJECT(pos_offset_grid) , "offx" , pos_offset_x_spinbt );
202   pos_offset_y_label = gtk_label_new( _( "Relative Y offset:" ) );
203   gtk_misc_set_alignment( GTK_MISC(pos_offset_y_label) , 0 , 0.5 );
204   gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_y_label , 0 , 1 , 1 , 2 );
205   pos_offset_y_spinbt = gtk_spin_button_new_with_range( -9999 , 9999 , 1 );
206   gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_offset_y_spinbt) , cfg->position.offset_y );
207   gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_y_spinbt , 1 , 2 , 1 , 2 );
208   g_object_set_data( G_OBJECT(pos_offset_grid) , "offy" , pos_offset_y_spinbt );
209   pos_maxsize_width_label = gtk_label_new( _("Max OSD width:") );
210   gtk_misc_set_alignment( GTK_MISC(pos_maxsize_width_label) , 0 , 0.5 );
211   gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_maxsize_width_label , 0 , 1 , 2 , 3 );
212   pos_maxsize_width_spinbt = gtk_spin_button_new_with_range( 0 , 99999 , 1 );
213   g_object_set_data( G_OBJECT(pos_offset_grid) , "maxsize_width" , pos_maxsize_width_spinbt );
214   gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_maxsize_width_spinbt) , cfg->position.maxsize_width );
215   gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_maxsize_width_spinbt , 1 , 2 , 2 , 3 );
216   gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , pos_offset_grid , false , false , 0 );
217   aosd_cb_list.append( pos_offset_grid , aosd_cb_configure_position_offset_commit );
218   aosd_cb_list.append( pos_offset_grid , aosd_cb_configure_position_maxsize_commit );
219 
220   pos_multimon_frame = gtk_frame_new( _("Multi-Monitor options") );
221   pos_multimon_hbox = gtk_hbox_new( false , 4 );
222   gtk_container_set_border_width( GTK_CONTAINER(pos_multimon_hbox) , 6 );
223   gtk_container_add( GTK_CONTAINER(pos_multimon_frame), pos_multimon_hbox );
224   pos_multimon_label = gtk_label_new( _("Display OSD using:") );
225   pos_multimon_combobox = gtk_combo_box_text_new ();
226   gtk_combo_box_text_append_text ((GtkComboBoxText *) pos_multimon_combobox, _("all monitors"));
227   for ( i = 0 ; i < monitors_num ; i++ )
228   {
229     char *mon_str = g_strdup_printf( _("monitor %i") , i + 1 );
230     gtk_combo_box_text_append_text ((GtkComboBoxText *) pos_multimon_combobox, mon_str);
231     g_free( mon_str );
232   }
233   gtk_combo_box_set_active( GTK_COMBO_BOX(pos_multimon_combobox) , (cfg->position.multimon_id + 1) );
234   aosd_cb_list.append( pos_multimon_combobox , aosd_cb_configure_position_multimon_commit );
235   gtk_box_pack_start( GTK_BOX(pos_multimon_hbox) , pos_multimon_label , false , false , 0 );
236   gtk_box_pack_start( GTK_BOX(pos_multimon_hbox) , pos_multimon_combobox , false , false , 0 );
237   gtk_box_pack_start( GTK_BOX(pos_vbox) , pos_multimon_frame , false , false , 0 );
238 
239   return pos_vbox;
240 }
241 
242 
243 static GtkWidget *
aosd_ui_configure_animation_timing(char * label_string)244 aosd_ui_configure_animation_timing ( char * label_string )
245 {
246   GtkWidget *hbox, *desc_label, *spinbt;
247   hbox = gtk_hbox_new( false , 4 );
248   desc_label = gtk_label_new( label_string );
249   spinbt = gtk_spin_button_new_with_range( 0 , 99999 , 1 );
250   gtk_box_pack_start( GTK_BOX(hbox) , desc_label , false , false , 0 );
251   gtk_box_pack_start( GTK_BOX(hbox) , spinbt , false , false , 0 );
252   g_object_set_data( G_OBJECT(hbox) , "spinbt" , spinbt );
253   return hbox;
254 }
255 
256 
257 static void
aosd_cb_configure_animation_timing_commit(GtkWidget * timing_hbox,aosd_cfg_t * cfg)258 aosd_cb_configure_animation_timing_commit ( GtkWidget * timing_hbox , aosd_cfg_t * cfg )
259 {
260   cfg->animation.timing_display = gtk_spin_button_get_value_as_int(
261     GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(timing_hbox),"display")) );
262   cfg->animation.timing_fadein = gtk_spin_button_get_value_as_int(
263     GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(timing_hbox),"fadein")) );
264   cfg->animation.timing_fadeout = gtk_spin_button_get_value_as_int(
265     GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(timing_hbox),"fadeout")) );
266 }
267 
268 
269 static GtkWidget *
aosd_ui_configure_animation(aosd_cfg_t * cfg)270 aosd_ui_configure_animation ( aosd_cfg_t * cfg )
271 {
272   GtkWidget *ani_vbox;
273   GtkWidget *ani_timing_frame, *ani_timing_hbox;
274   GtkWidget *ani_timing_fadein_widget, *ani_timing_fadeout_widget, *ani_timing_stay_widget;
275   GtkSizeGroup *sizegroup;
276 
277   ani_vbox = gtk_vbox_new( false , 0 );
278   gtk_container_set_border_width( GTK_CONTAINER(ani_vbox) , 6 );
279 
280   ani_timing_hbox = gtk_hbox_new( false , 0 );
281   ani_timing_frame = gtk_frame_new( _("Timing (ms)") );
282   gtk_container_set_border_width( GTK_CONTAINER(ani_timing_hbox) , 6 );
283   gtk_container_add( GTK_CONTAINER(ani_timing_frame) , ani_timing_hbox );
284   gtk_box_pack_start( GTK_BOX(ani_vbox) , ani_timing_frame , false , false , 0 );
285 
286   ani_timing_stay_widget = aosd_ui_configure_animation_timing( _("Display:") );
287   gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
288     G_OBJECT(ani_timing_stay_widget),"spinbt")) , cfg->animation.timing_display );
289   gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , ani_timing_stay_widget , true , true , 0 );
290   gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , gtk_vseparator_new() , false , false , 4 );
291   ani_timing_fadein_widget = aosd_ui_configure_animation_timing( _("Fade in:") );
292   gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
293     G_OBJECT(ani_timing_fadein_widget),"spinbt")) , cfg->animation.timing_fadein );
294   gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , ani_timing_fadein_widget , true , true , 0 );
295   gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , gtk_vseparator_new() , false , false , 4 );
296   ani_timing_fadeout_widget = aosd_ui_configure_animation_timing( _("Fade out:") );
297   gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
298     G_OBJECT(ani_timing_fadeout_widget),"spinbt")) , cfg->animation.timing_fadeout );
299   gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , ani_timing_fadeout_widget , true , true , 0 );
300   g_object_set_data( G_OBJECT(ani_timing_hbox) , "display" ,
301     g_object_get_data(G_OBJECT(ani_timing_stay_widget),"spinbt") );
302   g_object_set_data( G_OBJECT(ani_timing_hbox) , "fadein" ,
303     g_object_get_data(G_OBJECT(ani_timing_fadein_widget),"spinbt") );
304   g_object_set_data( G_OBJECT(ani_timing_hbox) , "fadeout" ,
305     g_object_get_data(G_OBJECT(ani_timing_fadeout_widget),"spinbt") );
306   sizegroup = gtk_size_group_new( GTK_SIZE_GROUP_HORIZONTAL );
307   gtk_size_group_add_widget( sizegroup , ani_timing_stay_widget );
308   gtk_size_group_add_widget( sizegroup , ani_timing_fadein_widget );
309   gtk_size_group_add_widget( sizegroup , ani_timing_fadeout_widget );
310   aosd_cb_list.append( ani_timing_hbox , aosd_cb_configure_animation_timing_commit );
311 
312   return ani_vbox;
313 }
314 
315 
316 static void
aosd_cb_configure_text_font_shadow_toggle(GtkToggleButton * shadow_togglebt,void * shadow_colorbt)317 aosd_cb_configure_text_font_shadow_toggle ( GtkToggleButton * shadow_togglebt ,
318                                             void * shadow_colorbt )
319 {
320   if ( gtk_toggle_button_get_active( shadow_togglebt ) == true )
321     gtk_widget_set_sensitive( GTK_WIDGET(shadow_colorbt) , true );
322   else
323     gtk_widget_set_sensitive( GTK_WIDGET(shadow_colorbt) , false );
324 }
325 
326 
327 static void
aosd_cb_configure_text_font_commit(GtkWidget * fontbt,aosd_cfg_t * cfg)328 aosd_cb_configure_text_font_commit ( GtkWidget * fontbt , aosd_cfg_t * cfg )
329 {
330   int fontnum = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(fontbt) , "fontnum" ));
331   GtkColorButton * chooser;
332 
333   cfg->text.fonts_name[fontnum] =
334    String (gtk_font_button_get_font_name (GTK_FONT_BUTTON (fontbt)));
335 
336   cfg->text.fonts_draw_shadow[fontnum] = gtk_toggle_button_get_active(
337     GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(fontbt),"use_shadow")) );
338 
339   chooser = (GtkColorButton *) g_object_get_data ((GObject *) fontbt, "color");
340   chooser_get_aosd_color (chooser, & cfg->text.fonts_color[fontnum]);
341 
342   chooser = (GtkColorButton *) g_object_get_data ((GObject *) fontbt, "shadow_color");
343   chooser_get_aosd_color (chooser, & cfg->text.fonts_shadow_color[fontnum]);
344 }
345 
346 
347 static GtkWidget *
aosd_ui_configure_text(aosd_cfg_t * cfg)348 aosd_ui_configure_text ( aosd_cfg_t * cfg )
349 {
350   GtkWidget *tex_vbox;
351   GtkWidget *tex_font_grid, *tex_font_frame;
352   GtkWidget *tex_font_label[3], *tex_font_fontbt[3];
353   GtkWidget *tex_font_colorbt[3], *tex_font_shadow_togglebt[3];
354   GtkWidget *tex_font_shadow_colorbt[3];
355   int i = 0;
356 
357   tex_vbox = gtk_vbox_new( false , 4 );
358   gtk_container_set_border_width( GTK_CONTAINER(tex_vbox) , 6 );
359 
360   tex_font_frame = gtk_frame_new( _("Fonts") );
361   tex_font_grid = gtk_table_new (0, 0, false);
362   gtk_container_set_border_width( GTK_CONTAINER(tex_font_grid) , 6 );
363   gtk_table_set_row_spacings( GTK_TABLE(tex_font_grid) , 4 );
364   gtk_table_set_col_spacings( GTK_TABLE(tex_font_grid) , 4 );
365   for ( i = 0 ; i < AOSD_TEXT_FONTS_NUM ; i++ )
366   {
367     char *label_str = g_strdup_printf( _("Font %i:") , i+1 );
368     tex_font_label[i] = gtk_label_new( label_str );
369     g_free( label_str );
370     tex_font_fontbt[i] = gtk_font_button_new();
371     gtk_font_button_set_show_style( GTK_FONT_BUTTON(tex_font_fontbt[i]) , true );
372     gtk_font_button_set_show_size( GTK_FONT_BUTTON(tex_font_fontbt[i]) , true );
373     gtk_font_button_set_use_font( GTK_FONT_BUTTON(tex_font_fontbt[i]) , false );
374     gtk_font_button_set_use_size( GTK_FONT_BUTTON(tex_font_fontbt[i]) , false );
375     gtk_font_button_set_font_name( GTK_FONT_BUTTON(tex_font_fontbt[i]) , cfg->text.fonts_name[i] );
376 
377     tex_font_colorbt[i] = gtk_color_button_new ();
378     chooser_set_aosd_color ((GtkColorButton *) tex_font_colorbt[i],
379      & cfg->text.fonts_color[i]);
380 
381     tex_font_shadow_togglebt[i] = gtk_toggle_button_new_with_label( _("Shadow") );
382     gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON(tex_font_shadow_togglebt[i]) , false );
383 
384     tex_font_shadow_colorbt[i] = gtk_color_button_new ();
385     chooser_set_aosd_color ((GtkColorButton *) tex_font_shadow_colorbt[i],
386      & cfg->text.fonts_shadow_color[i]);
387 
388     gtk_widget_set_sensitive( tex_font_shadow_colorbt[i] , false );
389     g_signal_connect( G_OBJECT(tex_font_shadow_togglebt[i]) , "toggled" ,
390                       G_CALLBACK(aosd_cb_configure_text_font_shadow_toggle) ,
391                       tex_font_shadow_colorbt[i] );
392     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(tex_font_shadow_togglebt[i]) ,
393       cfg->text.fonts_draw_shadow[i] );
394     gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_label[i] , 0 , 1 , i , i + 1 );
395     gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_fontbt[i] , 1 , 2 , i , i + 1 );
396     gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_colorbt[i] , 2 , 3 , i , i + 1 );
397     gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_shadow_togglebt[i] , 3 , 4 , i , i + 1 );
398     gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_shadow_colorbt[i] , 4 , 5 , i , i + 1 );
399     g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "fontnum" , GINT_TO_POINTER(i) );
400     g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "color" , tex_font_colorbt[i] );
401     g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "use_shadow" , tex_font_shadow_togglebt[i] );
402     g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "shadow_color" , tex_font_shadow_colorbt[i] );
403     aosd_cb_list.append( tex_font_fontbt[i] , aosd_cb_configure_text_font_commit );
404   }
405   gtk_container_add( GTK_CONTAINER(tex_font_frame) , tex_font_grid );
406   gtk_box_pack_start( GTK_BOX(tex_vbox) , tex_font_frame , false , false , 0 );
407 
408   return tex_vbox;
409 }
410 
411 
412 static void
aosd_cb_configure_decoration_style_commit(GtkWidget * lv,aosd_cfg_t * cfg)413 aosd_cb_configure_decoration_style_commit ( GtkWidget * lv , aosd_cfg_t * cfg )
414 {
415   GtkTreeSelection *sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(lv) );
416   GtkTreeModel *model;
417   GtkTreeIter iter;
418 
419   if ( gtk_tree_selection_get_selected( sel , &model , &iter ) == true )
420   {
421     int deco_code = 0;
422     gtk_tree_model_get( model , &iter , 1 , &deco_code , -1 );
423     cfg->decoration.code = deco_code;
424   }
425 }
426 
427 
428 static void
aosd_cb_configure_decoration_color_commit(GtkWidget * colorbt,aosd_cfg_t * cfg)429 aosd_cb_configure_decoration_color_commit ( GtkWidget * colorbt , aosd_cfg_t * cfg )
430 {
431   aosd_color_t color;
432   chooser_get_aosd_color ((GtkColorButton *) colorbt, & color);
433 
434   int colnum = GPOINTER_TO_INT( g_object_get_data( G_OBJECT(colorbt) , "colnum" ) );
435   cfg->decoration.colors[colnum] = color;
436 }
437 
438 
439 static GtkWidget *
aosd_ui_configure_decoration(aosd_cfg_t * cfg)440 aosd_ui_configure_decoration ( aosd_cfg_t * cfg )
441 {
442   GtkWidget *dec_hbox;
443   GtkWidget *dec_rstyle_lv, *dec_rstyle_lv_frame, *dec_rstyle_lv_sw;
444   GtkListStore *dec_rstyle_store;
445   GtkCellRenderer *dec_rstyle_lv_rndr_text;
446   GtkTreeViewColumn *dec_rstyle_lv_col_desc;
447   GtkTreeSelection *dec_rstyle_lv_sel;
448   GtkTreeIter iter, iter_sel;
449   GtkWidget *dec_rstyle_hbox;
450   GtkWidget *dec_rstyleopts_frame, *dec_rstyleopts_grid;
451   int colors_max_num = 0, i = 0;
452 
453   dec_hbox = gtk_hbox_new( false , 4 );
454   gtk_container_set_border_width( GTK_CONTAINER(dec_hbox) , 6 );
455 
456   /* decoration style model
457      ---------------------------------------------
458      G_TYPE_STRING -> decoration description
459      G_TYPE_INT -> decoration code
460      G_TYPE_INT -> number of user-definable colors
461      ---------------------------------------------
462   */
463   dec_rstyle_store = gtk_list_store_new( 3 , G_TYPE_STRING , G_TYPE_INT , G_TYPE_INT );
464   for ( i = 0 ; i < AOSD_NUM_DECO_STYLES ; i++ )
465   {
466     int colors_num = aosd_deco_style_get_numcol( i );
467     if ( colors_num > colors_max_num )
468       colors_max_num = colors_num;
469     gtk_list_store_append( dec_rstyle_store , &iter );
470     gtk_list_store_set( dec_rstyle_store , &iter ,
471       0 , _(aosd_deco_style_get_desc( i )) ,
472       1 , i , 2 , colors_num , -1 );
473     if ( i == cfg->decoration.code )
474       iter_sel = iter;
475   }
476 
477   dec_rstyle_lv_frame = gtk_frame_new( nullptr );
478   dec_rstyle_lv = gtk_tree_view_new_with_model( GTK_TREE_MODEL(dec_rstyle_store) );
479   g_object_unref( dec_rstyle_store );
480   dec_rstyle_lv_sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(dec_rstyle_lv) );
481   gtk_tree_selection_set_mode( dec_rstyle_lv_sel , GTK_SELECTION_BROWSE );
482 
483   dec_rstyle_lv_rndr_text = gtk_cell_renderer_text_new();
484   dec_rstyle_lv_col_desc = gtk_tree_view_column_new_with_attributes(
485     _("Render Style") , dec_rstyle_lv_rndr_text , "text" , 0 , nullptr );
486   gtk_tree_view_append_column( GTK_TREE_VIEW(dec_rstyle_lv), dec_rstyle_lv_col_desc );
487   dec_rstyle_lv_sw = gtk_scrolled_window_new( nullptr , nullptr );
488   gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(dec_rstyle_lv_sw) ,
489                                   GTK_POLICY_NEVER , GTK_POLICY_ALWAYS );
490   gtk_container_add( GTK_CONTAINER(dec_rstyle_lv_sw) , dec_rstyle_lv );
491   gtk_container_add( GTK_CONTAINER(dec_rstyle_lv_frame) , dec_rstyle_lv_sw );
492 
493   gtk_tree_selection_select_iter( dec_rstyle_lv_sel , &iter_sel );
494   gtk_box_pack_start( GTK_BOX(dec_hbox) , dec_rstyle_lv_frame , false , false , 0 );
495   aosd_cb_list.append( dec_rstyle_lv , aosd_cb_configure_decoration_style_commit );
496 
497   dec_rstyle_hbox = gtk_vbox_new( false , 4 );
498   gtk_box_pack_start( GTK_BOX(dec_hbox) , dec_rstyle_hbox , true , true , 0 );
499 
500   /* in colors_max_num now there's the maximum number of colors used by decoration styles */
501   dec_rstyleopts_frame = gtk_frame_new( _("Colors") );
502   dec_rstyleopts_grid = gtk_table_new (0, 0, false);
503   gtk_container_set_border_width( GTK_CONTAINER(dec_rstyleopts_grid) , 6 );
504   gtk_table_set_row_spacings( GTK_TABLE(dec_rstyleopts_grid) , 4 );
505   gtk_table_set_col_spacings( GTK_TABLE(dec_rstyleopts_grid) , 8 );
506   gtk_container_add( GTK_CONTAINER(dec_rstyleopts_frame) , dec_rstyleopts_grid );
507   for ( i = 0 ; i < colors_max_num ; i++ )
508   {
509     GtkWidget *hbox, *label;
510     char *label_str = nullptr;
511     hbox = gtk_hbox_new( false , 4 );
512     label_str = g_strdup_printf( _("Color %i:") , i+1 );
513     label = gtk_label_new( label_str );
514     g_free( label_str );
515 
516     GtkWidget * colorbt = gtk_color_button_new ();
517     chooser_set_aosd_color ((GtkColorButton *) colorbt, & cfg->decoration.colors[i]);
518 
519     gtk_box_pack_start( GTK_BOX(hbox) , label , false , false , 0 );
520     gtk_box_pack_start( GTK_BOX(hbox) , colorbt , false , false , 0 );
521     gtk_table_attach_defaults( GTK_TABLE(dec_rstyleopts_grid) , hbox , (i % 3) , (i % 3) + 1, (i / 3) , (i / 3) + 1);
522     g_object_set_data( G_OBJECT(colorbt) , "colnum" , GINT_TO_POINTER(i) );
523     aosd_cb_list.append( colorbt , aosd_cb_configure_decoration_color_commit );
524   }
525   gtk_box_pack_start( GTK_BOX(dec_rstyle_hbox) , dec_rstyleopts_frame , false , false , 0 );
526 
527   return dec_hbox;
528 }
529 
530 
531 static void
aosd_cb_configure_trigger_lvchanged(GtkTreeSelection * sel,void * nb)532 aosd_cb_configure_trigger_lvchanged ( GtkTreeSelection *sel , void * nb )
533 {
534   GtkTreeModel *model;
535   GtkTreeIter iter;
536 
537   if ( gtk_tree_selection_get_selected( sel , &model , &iter ) == true )
538   {
539     int page_num = 0;
540     gtk_tree_model_get( model , &iter , 2 , &page_num , -1 );
541     gtk_notebook_set_current_page( GTK_NOTEBOOK(nb) , page_num );
542   }
543 }
544 
545 
546 static void
aosd_cb_configure_trigger_commit(GtkWidget * cbt,aosd_cfg_t * cfg)547 aosd_cb_configure_trigger_commit ( GtkWidget * cbt , aosd_cfg_t * cfg )
548 {
549   if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(cbt) ) == true )
550   {
551     int value = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cbt),"code"));
552     cfg->trigger.enabled[value] = true;
553   }
554 }
555 
556 
557 static GtkWidget *
aosd_ui_configure_trigger(aosd_cfg_t * cfg)558 aosd_ui_configure_trigger ( aosd_cfg_t * cfg )
559 {
560   GtkWidget *tri_hbox;
561   GtkWidget *tri_event_lv, *tri_event_lv_frame, *tri_event_lv_sw;
562   GtkListStore *tri_event_store;
563   GtkCellRenderer *tri_event_lv_rndr_text;
564   GtkTreeViewColumn *tri_event_lv_col_desc;
565   GtkTreeSelection *tri_event_lv_sel;
566   GtkTreeIter iter;
567   GtkWidget *tri_event_nb;
568   int i = 0;
569 
570   tri_event_nb = gtk_notebook_new();
571   gtk_notebook_set_tab_pos( GTK_NOTEBOOK(tri_event_nb) , GTK_POS_LEFT );
572   gtk_notebook_set_show_tabs( GTK_NOTEBOOK(tri_event_nb) , false );
573   gtk_notebook_set_show_border( GTK_NOTEBOOK(tri_event_nb) , false );
574 
575   tri_hbox = gtk_hbox_new( false , 4 );
576   gtk_container_set_border_width( GTK_CONTAINER(tri_hbox) , 6 );
577 
578   /* trigger model
579      ---------------------------------------------
580      G_TYPE_STRING -> trigger description
581      G_TYPE_INT -> trigger code
582      G_TYPE_INT -> gtk notebook page number
583      ---------------------------------------------
584   */
585   tri_event_store = gtk_list_store_new( 3 , G_TYPE_STRING , G_TYPE_INT , G_TYPE_INT );
586   for ( i = 0 ; i < AOSD_NUM_TRIGGERS ; i ++ )
587   {
588     GtkWidget *frame, *vbox, *label, *checkbt;
589     gtk_list_store_append( tri_event_store , &iter );
590     gtk_list_store_set( tri_event_store , &iter ,
591       0 , _(aosd_trigger_get_name( i )) ,
592       1 , i , 2 , i , -1 );
593     vbox = gtk_vbox_new( false , 0 );
594     gtk_container_set_border_width( GTK_CONTAINER(vbox) , 6 );
595     label = gtk_label_new( _(aosd_trigger_get_desc( i )) );
596     gtk_label_set_line_wrap( GTK_LABEL(label) , true );
597     gtk_label_set_max_width_chars( GTK_LABEL(label), 40 );
598     gtk_misc_set_alignment( GTK_MISC(label) , 0.0 , 0.0 );
599     checkbt = gtk_check_button_new_with_label( _("Enable trigger") );
600     if ( cfg->trigger.enabled[i] )
601       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(checkbt) , true );
602     else
603       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(checkbt) , false );
604     gtk_box_pack_start( GTK_BOX(vbox) , checkbt , false , false , 0 );
605     gtk_box_pack_start( GTK_BOX(vbox) , gtk_hseparator_new() , false , false , 4 );
606     gtk_box_pack_start( GTK_BOX(vbox) , label , false , false , 0 );
607     frame = gtk_frame_new( nullptr );
608     gtk_container_add( GTK_CONTAINER(frame) , vbox );
609     gtk_notebook_append_page( GTK_NOTEBOOK(tri_event_nb) , frame , nullptr );
610     g_object_set_data( G_OBJECT(checkbt) , "code" , GINT_TO_POINTER(i) );
611     aosd_cb_list.append( checkbt , aosd_cb_configure_trigger_commit );
612   }
613 
614   tri_event_lv_frame = gtk_frame_new( nullptr );
615   tri_event_lv = gtk_tree_view_new_with_model( GTK_TREE_MODEL(tri_event_store) );
616   g_object_unref( tri_event_store );
617   tri_event_lv_sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(tri_event_lv) );
618   gtk_tree_selection_set_mode( tri_event_lv_sel , GTK_SELECTION_BROWSE );
619   g_signal_connect( G_OBJECT(tri_event_lv_sel) , "changed" ,
620                     G_CALLBACK(aosd_cb_configure_trigger_lvchanged) , tri_event_nb );
621   if ( gtk_tree_model_get_iter_first( GTK_TREE_MODEL(tri_event_store) , &iter ) == true )
622     gtk_tree_selection_select_iter( tri_event_lv_sel , &iter );
623 
624   tri_event_lv_rndr_text = gtk_cell_renderer_text_new();
625   tri_event_lv_col_desc = gtk_tree_view_column_new_with_attributes(
626     _("Event") , tri_event_lv_rndr_text , "text" , 0 , nullptr );
627   gtk_tree_view_append_column( GTK_TREE_VIEW(tri_event_lv), tri_event_lv_col_desc );
628   tri_event_lv_sw = gtk_scrolled_window_new( nullptr , nullptr );
629   gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(tri_event_lv_sw) ,
630                                   GTK_POLICY_NEVER , GTK_POLICY_ALWAYS );
631   gtk_container_add( GTK_CONTAINER(tri_event_lv_sw) , tri_event_lv );
632   gtk_container_add( GTK_CONTAINER(tri_event_lv_frame) , tri_event_lv_sw );
633   gtk_tree_selection_select_iter( tri_event_lv_sel , &iter );
634 
635   gtk_box_pack_start( GTK_BOX(tri_hbox) , tri_event_lv_frame , false , false , 0 );
636 
637   gtk_box_pack_start( GTK_BOX(tri_hbox) , tri_event_nb , true , true , 0 );
638 
639   return tri_hbox;
640 }
641 
642 
643 static void
aosd_cb_configure_misc_transp_real_clicked(GtkToggleButton * real_rbt,void * status_hbox)644 aosd_cb_configure_misc_transp_real_clicked ( GtkToggleButton * real_rbt , void * status_hbox )
645 {
646   GtkWidget *img = (GtkWidget *) g_object_get_data( G_OBJECT(status_hbox) , "img" );
647   GtkWidget *label = (GtkWidget *) g_object_get_data( G_OBJECT(status_hbox) , "label" );
648   if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(real_rbt) ) )
649   {
650     if ( aosd_osd_check_composite_mgr() )
651     {
652       gtk_image_set_from_icon_name( GTK_IMAGE(img) , "face-smile" , GTK_ICON_SIZE_MENU );
653       gtk_label_set_text( GTK_LABEL(label) , _("Composite manager detected") );
654       gtk_widget_set_sensitive( GTK_WIDGET(status_hbox) , true );
655     }
656     else
657     {
658       gtk_image_set_from_icon_name( GTK_IMAGE(img) , "dialog-warning" , GTK_ICON_SIZE_MENU );
659       gtk_label_set_text( GTK_LABEL(label) ,
660         _("Composite manager not detected;\nunless you know that you have one running, "
661           "please activate a composite manager otherwise the OSD won't work properly") );
662       gtk_widget_set_sensitive( GTK_WIDGET(status_hbox) , true );
663     }
664   }
665   else
666   {
667     gtk_image_set_from_icon_name( GTK_IMAGE(img) , "dialog-information" , GTK_ICON_SIZE_MENU );
668     gtk_label_set_text( GTK_LABEL(label) , _("Composite manager not required for fake transparency") );
669     gtk_widget_set_sensitive( GTK_WIDGET(status_hbox) , false );
670   }
671 }
672 
673 
674 static void
aosd_cb_configure_misc_transp_commit(GtkWidget * mis_transp_vbox,aosd_cfg_t * cfg)675 aosd_cb_configure_misc_transp_commit ( GtkWidget * mis_transp_vbox , aosd_cfg_t * cfg )
676 {
677   GList *child_list = gtk_container_get_children( GTK_CONTAINER(mis_transp_vbox) );
678 
679   for ( GList *iter = child_list; iter != nullptr; iter = iter->next )
680   {
681     if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(iter->data) ) )
682     {
683       cfg->misc.transparency_mode = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(iter->data), "val"));
684       break;
685     }
686   }
687 
688   g_list_free( child_list );
689 }
690 
691 
692 static GtkWidget *
aosd_ui_configure_misc(aosd_cfg_t * cfg)693 aosd_ui_configure_misc ( aosd_cfg_t * cfg )
694 {
695   GtkWidget *mis_vbox;
696   GtkWidget *mis_transp_frame, *mis_transp_vbox;
697   GtkWidget *mis_transp_fake_rbt, *mis_transp_real_rbt;
698   GtkWidget *mis_transp_status_frame, *mis_transp_status_hbox;
699   GtkWidget *mis_transp_status_img, *mis_transp_status_label;
700 
701   mis_vbox = gtk_vbox_new( false , 0 );
702   gtk_container_set_border_width( GTK_CONTAINER(mis_vbox) , 6 );
703 
704   mis_transp_vbox = gtk_vbox_new( false , 0 );
705   mis_transp_frame = gtk_frame_new( _("Transparency") );
706   gtk_container_set_border_width( GTK_CONTAINER(mis_transp_vbox) , 6 );
707   gtk_container_add( GTK_CONTAINER(mis_transp_frame) , mis_transp_vbox );
708   gtk_box_pack_start( GTK_BOX(mis_vbox) , mis_transp_frame , false , false , 0 );
709 
710   mis_transp_fake_rbt = gtk_radio_button_new_with_label( nullptr ,
711                           _("Fake transparency") );
712   mis_transp_real_rbt = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(mis_transp_fake_rbt) ,
713                           _("Real transparency (requires X Composite Ext.)") );
714   g_object_set_data( G_OBJECT(mis_transp_fake_rbt) , "val" ,
715                      GINT_TO_POINTER(AOSD_MISC_TRANSPARENCY_FAKE) );
716   g_object_set_data( G_OBJECT(mis_transp_real_rbt) , "val" ,
717                      GINT_TO_POINTER(AOSD_MISC_TRANSPARENCY_REAL) );
718   gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_fake_rbt , true , true , 0 );
719   gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_real_rbt , true , true , 0 );
720 
721   mis_transp_status_hbox = gtk_hbox_new( false , 4 );
722   mis_transp_status_frame = gtk_frame_new( nullptr );
723   gtk_container_set_border_width( GTK_CONTAINER(mis_transp_status_hbox) , 3 );
724   gtk_container_add( GTK_CONTAINER(mis_transp_status_frame) , mis_transp_status_hbox );
725   gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_status_frame , true , true , 0 );
726 
727   mis_transp_status_img = gtk_image_new();
728   gtk_misc_set_alignment( GTK_MISC(mis_transp_status_img) , 0.5 , 0 );
729   mis_transp_status_label = gtk_label_new( "" );
730   gtk_misc_set_alignment( GTK_MISC(mis_transp_status_label) , 0 , 0.5 );
731   gtk_label_set_line_wrap( GTK_LABEL(mis_transp_status_label) , true );
732   gtk_box_pack_start( GTK_BOX(mis_transp_status_hbox) , mis_transp_status_img , false , false , 0 );
733   gtk_box_pack_start( GTK_BOX(mis_transp_status_hbox) , mis_transp_status_label , true , true , 0 );
734   g_object_set_data( G_OBJECT(mis_transp_status_hbox) , "img" , mis_transp_status_img );
735   g_object_set_data( G_OBJECT(mis_transp_status_hbox) , "label" , mis_transp_status_label );
736 
737   g_signal_connect( G_OBJECT(mis_transp_real_rbt) , "toggled" ,
738     G_CALLBACK(aosd_cb_configure_misc_transp_real_clicked) , mis_transp_status_hbox );
739 
740   /* check if the composite extension is loaded */
741   if ( aosd_osd_check_composite_ext() )
742   {
743     if ( cfg->misc.transparency_mode == AOSD_MISC_TRANSPARENCY_FAKE )
744       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_fake_rbt) , true );
745     else
746       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_real_rbt) , true );
747   }
748   else
749   {
750     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_fake_rbt) , true );
751     gtk_widget_set_sensitive( GTK_WIDGET(mis_transp_real_rbt) , false );
752     gtk_image_set_from_icon_name( GTK_IMAGE(mis_transp_status_img) ,
753       "dialog-error" , GTK_ICON_SIZE_MENU );
754     gtk_label_set_text( GTK_LABEL(mis_transp_status_label) , _("Composite extension not loaded") );
755     gtk_widget_set_sensitive( GTK_WIDGET(mis_transp_status_hbox) , false );
756   }
757 
758   aosd_cb_list.append( mis_transp_vbox , aosd_cb_configure_misc_transp_commit );
759 
760   return mis_vbox;
761 }
762 
763 
764 static void
aosd_cb_configure_test(void)765 aosd_cb_configure_test ( void )
766 {
767   aosd_cfg_t cfg = aosd_cfg_t ();
768   aosd_callback_list_run (& cfg);
769 
770   char * markup_message = g_markup_printf_escaped
771    (_("<span font_desc='%s'>Audacious OSD</span>"),
772    (const char *) cfg.text.fonts_name[0]);
773 
774   aosd_osd_shutdown (); /* stop any displayed osd */
775   aosd_osd_cleanup (); /* just in case it's active */
776   aosd_osd_init (cfg.misc.transparency_mode);
777   aosd_osd_display (markup_message, & cfg, true);
778 
779   g_free (markup_message);
780 }
781 
782 
783 static void
aosd_cb_configure_cancel(void)784 aosd_cb_configure_cancel ( void )
785 {
786   aosd_cb_list.clear ();
787 
788   aosd_osd_shutdown (); /* stop any displayed osd */
789   aosd_osd_cleanup (); /* just in case it's active */
790   aosd_osd_init (global_config.misc.transparency_mode);
791 }
792 
793 
794 static void
aosd_cb_configure_ok(void)795 aosd_cb_configure_ok ( void )
796 {
797   aosd_cfg_t cfg = aosd_cfg_t ();
798 
799   aosd_callback_list_run (& cfg);
800   aosd_cb_list.clear ();
801 
802   aosd_osd_shutdown (); /* stop any displayed osd */
803   aosd_osd_cleanup (); /* just in case it's active */
804 
805   aosd_trigger_stop (global_config.trigger); /* stop triggers */
806   global_config = cfg; /* put the new config */
807   aosd_cfg_save (cfg); /* save the new configuration on config file */
808   aosd_osd_init (cfg.misc.transparency_mode); /* restart osd */
809   aosd_trigger_start (cfg.trigger); /* restart triggers */
810 }
811 
812 
813 static void *
aosd_ui_configure(void)814 aosd_ui_configure ( void )
815 {
816   GtkWidget *cfg_nb;
817   GtkWidget *cfg_position_widget;
818   GtkWidget *cfg_animation_widget;
819   GtkWidget *cfg_text_widget;
820   GtkWidget *cfg_decoration_widget;
821   GtkWidget *cfg_trigger_widget;
822 
823   /* create a new configuration object */
824   aosd_cfg_t cfg = aosd_cfg_t();
825   /* fill it with information from config file */
826   aosd_cfg_load( cfg );
827 
828   cfg_nb = gtk_notebook_new();
829   gtk_notebook_set_tab_pos( GTK_NOTEBOOK(cfg_nb) , GTK_POS_TOP );
830 
831   /* add POSITION page */
832   cfg_position_widget = aosd_ui_configure_position( &cfg );
833   gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
834     cfg_position_widget , gtk_label_new( _("Position") ) );
835 
836   /* add ANIMATION page */
837   cfg_animation_widget = aosd_ui_configure_animation( &cfg );
838   gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
839     cfg_animation_widget , gtk_label_new( _("Animation") ) );
840 
841   /* add TEXT page */
842   cfg_text_widget = aosd_ui_configure_text( &cfg );
843   gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
844     cfg_text_widget , gtk_label_new( _("Text") ) );
845 
846   /* add DECORATION page */
847   cfg_decoration_widget = aosd_ui_configure_decoration( &cfg );
848   gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
849     cfg_decoration_widget , gtk_label_new( _("Decoration") ) );
850 
851   /* add TRIGGER page */
852   cfg_trigger_widget = aosd_ui_configure_trigger( &cfg );
853   gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
854     cfg_trigger_widget , gtk_label_new( _("Trigger") ) );
855 
856   /* add MISC page */
857   cfg_trigger_widget = aosd_ui_configure_misc( &cfg );
858   gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
859     cfg_trigger_widget , gtk_label_new( _("Misc") ) );
860 
861   return cfg_nb;
862 }
863 
864 
865 const PreferencesWidget AOSD::widgets[] = {
866     WidgetCustomGTK (aosd_ui_configure),
867     WidgetSeparator ({true}),
868     WidgetButton (N_("Test"), {aosd_cb_configure_test, "media-playback-start"})
869 };
870 
871 const PluginPreferences AOSD::prefs = {
872     {widgets},
873     nullptr,  // init
874     aosd_cb_configure_ok,
875     aosd_cb_configure_cancel
876 };
877