mp3splt-gtk
widgets_helper.c
Go to the documentation of this file.
1 /**********************************************************
2  * mp3splt-gtk -- utility based on mp3splt,
3  *
4  * for mp3/ogg splitting without decoding
5  *
6  * Copyright: (C) 2005-2012 Alexandru Munteanu
7  * Contact: io_fx@yahoo.fr
8  *
9  * http://mp3splt.sourceforge.net/
10  *
11  *********************************************************/
12 
13 /**********************************************************
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28  * USA.
29  *
30  *********************************************************/
31 
32 /*!********************************************************
33  * \file
34  *
35  * this file contains the code for the widgets helpers.
36  ********************************************************/
37 
38 #include "widgets_helper.h"
39 
40 static guint _wh_add_row_to_table();
41 static GtkWidget *_wh_put_in_new_hbox_with_margin(GtkWidget *widget, gint margin);
42 static void _wh_attach_to_table(GtkWidget *table, GtkWidget *widget,
43  guint start_column, guint end_column, guint row, int expand);
44 static void _wh_add_in_table_with_label(GtkWidget *table, const gchar *label_text,
45  GtkWidget *widget, int expand);
46 static void hide_window_from_button(GtkWidget *window, gpointer data);
47 
57 GtkWidget *wh_set_title_and_get_vbox(GtkWidget *widget, const gchar *title)
58 {
59  GtkWidget *vbox = wh_vbox_new();
60 
61  GtkWidget *label = gtk_label_new(NULL);
62  gtk_label_set_markup(GTK_LABEL(label), title);
63 
64  GtkWidget *label_hbox = wh_hbox_new();
65  gtk_box_pack_start(GTK_BOX(label_hbox), label, FALSE, FALSE, 0);
66  gtk_box_pack_start(GTK_BOX(vbox), label_hbox, FALSE, FALSE, 5);
67 
68  GtkWidget *hbox = wh_hbox_new();
69  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 16);
70 
71  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
72 
73  return vbox;
74 }
75 
76 GtkWidget *wh_new_table()
77 {
78  GtkWidget *table = gtk_table_new(1, 2, FALSE);
79  gtk_table_set_col_spacing(GTK_TABLE(table), 0, 0);
80  gtk_table_set_col_spacing(GTK_TABLE(table), 1, 5);
81  return table;
82 }
83 
84 void wh_add_in_table(GtkWidget *table, GtkWidget *widget)
85 {
86  guint last_row = _wh_add_row_to_table(table);
87 
88  _wh_attach_to_table(table, widget, 1, 3, last_row, TRUE);
89 }
90 
91 void wh_add_in_table_with_label_expand(GtkWidget *table, const gchar *label_text, GtkWidget *widget)
92 {
93  _wh_add_in_table_with_label(table, label_text, widget, TRUE);
94 }
95 
96 void wh_add_in_table_with_label(GtkWidget *table, const gchar *label_text, GtkWidget *widget)
97 {
98  _wh_add_in_table_with_label(table, label_text, widget, FALSE);
99 }
100 
101 GtkWidget *wh_put_in_new_hbox_with_margin_level(GtkWidget *widget, gint margin_level)
102 {
103  return _wh_put_in_new_hbox_with_margin(widget, 6 * margin_level);
104 }
105 
106 void wh_put_in_hbox_and_attach_to_vbox(GtkWidget *widget, GtkWidget *vbox, gint vertical_margin)
107 {
108  wh_put_in_hbox_and_attach_to_vbox_with_bottom_margin(widget, vbox, vertical_margin, -1);
109 }
110 
111 void wh_put_in_hbox_and_attach_to_vbox_with_bottom_margin(GtkWidget *widget, GtkWidget *vbox,
112  gint vertical_margin, gint bottom_margin)
113 {
114  GtkWidget *hbox = wh_hbox_new();
115  gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
116  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, vertical_margin);
117 
118  if (bottom_margin > 0)
119  {
120  GtkWidget *fake_hbox = wh_hbox_new();
121  gtk_box_pack_start(GTK_BOX(vbox), fake_hbox, FALSE, FALSE, bottom_margin);
122  }
123 }
124 
125 GtkWidget *wh_new_entry(gpointer callback, ui_state *ui)
126 {
127  GtkWidget *entry = gtk_entry_new();
128  gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE);
129 
130  if (callback)
131  {
132  g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(callback), ui);
133  }
134 
135  return entry;
136 }
137 
138 GtkWidget *wh_new_button(const gchar *button_label)
139 {
140  return gtk_button_new_with_mnemonic(button_label);
141 }
142 
143 void wh_get_widget_size(GtkWidget *widget, gint *width, gint *height)
144 {
145 #if GTK_MAJOR_VERSION <= 2
146  GtkAllocation allocation;
147  gtk_widget_get_allocation(widget, &allocation);
148 
149  if (width != NULL)
150  {
151  *width = allocation.width;
152  }
153 
154  if (height != NULL)
155  {
156  *height= allocation.height;
157  }
158 #else
159  if (width != NULL)
160  {
161  *width = gtk_widget_get_allocated_width(widget);
162  }
163 
164  if (height != NULL)
165  {
166  *height = gtk_widget_get_allocated_height(widget);
167  }
168 #endif
169 }
170 
171 GtkWidget *wh_create_int_spinner_in_box_with_top_width(gchar *before_label, gchar *after_label,
172  gdouble initial_value,
173  gdouble minimum_value, gdouble maximum_value,
174  gdouble step_increment, gdouble page_increment,
175  gchar *after_newline_label,
176  void (*spinner_callback)(GtkWidget *spinner, ui_state *ui),
177  ui_state *ui, GtkWidget *box, gint top_width)
178 {
179  GtkWidget *horiz_fake = wh_hbox_new();
180  GtkWidget *label = gtk_label_new(before_label);
181  gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0);
182 
183  GtkAdjustment *adj = (GtkAdjustment *)
184  gtk_adjustment_new(initial_value, minimum_value, maximum_value, step_increment, page_increment, 0.0);
185 
186  GtkWidget *spinner = gtk_spin_button_new(adj, 0, 0);
187 
188  gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spinner), TRUE);
189  g_signal_connect(G_OBJECT(spinner), "value_changed", G_CALLBACK(spinner_callback), ui);
190  gtk_box_pack_start(GTK_BOX(horiz_fake), spinner, FALSE, FALSE, 5);
191 
192  if (after_label != NULL)
193  {
194  gtk_box_pack_start(GTK_BOX(horiz_fake), gtk_label_new(after_label), FALSE, FALSE, 3);
195  }
196 
197  GtkWidget *fake = wh_hbox_new();
198  gtk_box_pack_start(GTK_BOX(box), fake, FALSE, FALSE, top_width);
199 
200  gtk_box_pack_start(GTK_BOX(box), horiz_fake, FALSE, FALSE, 1);
201 
202  if (after_newline_label != NULL)
203  {
204  horiz_fake = wh_hbox_new();
205  gtk_box_pack_start(GTK_BOX(horiz_fake), gtk_label_new(after_newline_label), FALSE, FALSE, 0);
206  gtk_box_pack_start(GTK_BOX(box), horiz_fake, FALSE, FALSE, 2);
207  }
208 
209  fake = wh_hbox_new();
210  gtk_box_pack_start(GTK_BOX(box), fake, FALSE, FALSE, 2);
211 
212  return spinner;
213 }
214 
215 GtkWidget *wh_create_int_spinner_in_box(gchar *before_label, gchar *after_label,
216  gdouble initial_value,
217  gdouble minimum_value, gdouble maximum_value,
218  gdouble step_increment, gdouble page_increment,
219  gchar *after_newline_label,
220  void (*spinner_callback)(GtkWidget *spinner, ui_state *ui),
221  ui_state *ui,
222  GtkWidget *box)
223 {
224  return wh_create_int_spinner_in_box_with_top_width(before_label, after_label,
225  initial_value, minimum_value, maximum_value, step_increment, page_increment,
226  after_newline_label, spinner_callback, ui, box, 2);
227 }
228 
229 GtkWidget *wh_hbox_new()
230 {
231 #if GTK_MAJOR_VERSION <= 2
232  return gtk_hbox_new(FALSE, 0);
233 #else
234  GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
235  gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
236  return hbox;
237 #endif
238 }
239 
240 GtkWidget *wh_vbox_new()
241 {
242 #if GTK_MAJOR_VERSION <= 2
243  return gtk_vbox_new(FALSE, 0);
244 #else
245  GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
246  gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
247  return vbox;
248 #endif
249 }
250 
251 GtkWidget *wh_hscale_new(GtkAdjustment *adjustment)
252 {
253 #if GTK_MAJOR_VERSION <= 2
254  return gtk_hscale_new(adjustment);
255 #else
256  return gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, adjustment);
257 #endif
258 }
259 
260 GtkWidget *wh_hscale_new_with_range(gdouble min, gdouble max, gdouble step)
261 {
262 #if GTK_MAJOR_VERSION <= 2
263  return gtk_hscale_new_with_range(min, max, step);
264 #else
265  return gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, min, max, step);
266 #endif
267 }
268 
269 void wh_get_pointer(GdkEventMotion *event, gint *x, gint *y, GdkModifierType *state)
270 {
271 #if GTK_MAJOR_VERSION <= 2
272  gdk_window_get_pointer(event->window, x, y, state);
273 #else
274  gdk_window_get_device_position(event->window, event->device, x, y, state);
275 #endif
276 }
277 
280 {
281  GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
282  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
283  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
284  GTK_POLICY_AUTOMATIC,
285  GTK_POLICY_AUTOMATIC);
286  return scrolled_window;
287 }
288 
295 gboolean wh_container_has_child(GtkContainer *container, GtkWidget *my_child)
296 {
297  GList *children = gtk_container_get_children(GTK_CONTAINER(container));
298  int i = 0;
299  GtkWidget *child = NULL;
300  while ((child = g_list_nth_data(children, i)) != NULL)
301  {
302  if (child == my_child)
303  {
304  return TRUE;
305  }
306  i++;
307  }
308 
309  return FALSE;
310 }
311 
312 void wh_set_image_on_button(GtkButton *button, GtkWidget *image)
313 {
314  gtk_button_set_image(button, image);
315 }
316 
317 static void _wh_folder_changed_event(GtkFileChooser *chooser, ui_state *ui)
318 {
319  ui_set_browser_directory(ui, gtk_file_chooser_get_current_folder(chooser));
320 }
321 
322 void wh_set_browser_directory_handler(ui_state *ui, GtkWidget* dialog)
323 {
324  const gchar *browser_dir = ui_get_browser_directory(ui);
325  if (browser_dir)
326  {
327  gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), browser_dir);
328  }
329 
330  g_signal_connect(GTK_FILE_CHOOSER(dialog), "current-folder-changed",
331  G_CALLBACK(_wh_folder_changed_event), ui);
332 }
333 
341 GtkWidget *wh_create_cool_button(gchar *stock_id, gchar *label_text,
342  gint toggle_or_not)
343 {
344  GtkWidget *box = wh_hbox_new();
345  gtk_container_set_border_width(GTK_CONTAINER(box), 0);
346 
347  GtkWidget *image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU);
348  gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0);
349 
350  if (label_text != NULL)
351  {
352  GtkWidget *label = gtk_label_new(label_text);
353  gtk_label_set_text_with_mnemonic(GTK_LABEL(label),label_text);
354  gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 3);
355  }
356 
357  GtkWidget *button;
358  if (toggle_or_not)
359  {
360  button = gtk_toggle_button_new();
361  }
362  else
363  {
364  button = gtk_button_new();
365  }
366 
367  gtk_container_add(GTK_CONTAINER(button), box);
368 
369  return button;
370 }
371 
372 GtkWidget *wh_create_cool_label(gchar *stock_id, gchar *label_text)
373 {
374  GtkWidget *box = wh_hbox_new();
375  gtk_container_set_border_width(GTK_CONTAINER(box), 0);
376 
377  GtkWidget *image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU);
378  gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0);
379 
380  if (label_text != NULL)
381  {
382  GtkWidget *label = gtk_label_new(label_text);
383  gtk_label_set_text_with_mnemonic(GTK_LABEL(label),label_text);
384  gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 3);
385  }
386 
387  gtk_widget_show_all(box);
388 
389  return box;
390 }
391 
392 GtkWidget *wh_create_window_with_close_button(gchar *title, gint width, gint height,
393  GtkWindowPosition position, GtkWindow *parent_window,
394  GtkWidget *main_area_widget, GtkWidget *bottom_widget, ...)
395 {
396  GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
397  g_signal_connect(G_OBJECT(window), "delete_event",
398  G_CALLBACK(gtk_widget_hide_on_delete), window);
399  gtk_window_set_title(GTK_WINDOW(window), title);
400  gtk_window_set_destroy_with_parent(GTK_WINDOW(window), TRUE);
401  gtk_window_set_default_size(GTK_WINDOW(window), width, height);
402  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
403 
404  GtkWidget *vbox = wh_vbox_new();
405  gtk_container_set_border_width(GTK_CONTAINER(vbox), 4);
406  gtk_container_add(GTK_CONTAINER(window), vbox);
407  gtk_box_pack_start(GTK_BOX(vbox), main_area_widget, TRUE, TRUE, 2);
408 
409  GtkWidget *bottom_hbox = wh_hbox_new();
410  gtk_box_pack_start(GTK_BOX(vbox), bottom_hbox, FALSE, FALSE, 3);
411 
412  va_list ap;
413  va_start(ap, bottom_widget);
414  while (bottom_widget)
415  {
416  gtk_box_pack_start(GTK_BOX(bottom_hbox), bottom_widget, FALSE, FALSE, 3);
417  bottom_widget = va_arg(ap, GtkWidget *);
418  }
419  va_end(ap);
420 
421  GtkWidget *close_button = wh_create_cool_button(GTK_STOCK_CLOSE, _("_Close"), FALSE);
422  gtk_box_pack_end(GTK_BOX(bottom_hbox), close_button, FALSE, FALSE, 3);
423  g_signal_connect(G_OBJECT(close_button), "clicked",
424  G_CALLBACK(hide_window_from_button), window);
425 
426  return window;
427 }
428 
429 void wh_show_window(GtkWidget *window)
430 {
431  if (!gtk_widget_get_visible(window))
432  {
433  gtk_widget_show_all(window);
434  return;
435  }
436 
437  gtk_window_present(GTK_WINDOW(window));
438 }
439 
440 static void hide_window_from_button(GtkWidget *widget, gpointer data)
441 {
442  GtkWidget *window = (GtkWidget *)data;
443  gtk_widget_hide(window);
444 }
445 
446 static guint _wh_add_row_to_table(GtkWidget *table)
447 {
448  guint rows;
449  guint columns;
450 
451  g_object_get(G_OBJECT(table),
452  "n-rows", &rows,
453  "n-columns", &columns,
454  NULL);
455 
456  guint new_rows = rows + 1;
457 
458  gtk_table_resize(GTK_TABLE(table), new_rows, columns);
459  gtk_table_set_row_spacing(GTK_TABLE(table), new_rows - 1, 4);
460 
461  return new_rows;
462 }
463 
464 static GtkWidget *_wh_put_in_new_hbox_with_margin(GtkWidget *widget, gint margin)
465 {
466  GtkWidget *hbox = wh_hbox_new();
467  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, margin);
468  return hbox;
469 }
470 
471 static void _wh_add_in_table_with_label(GtkWidget *table, const gchar *label_text,
472  GtkWidget *widget, int expand)
473 {
474  guint last_row = _wh_add_row_to_table(table);
475 
476  GtkWidget *label = gtk_label_new(label_text);
477  gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
478 
479  _wh_attach_to_table(table, label, 1, 2, last_row, FALSE);
480  _wh_attach_to_table(table, widget, 2, 3, last_row, expand);
481 }
482 
483 static void _wh_attach_to_table(GtkWidget *table, GtkWidget *widget,
484  guint start_column, guint end_column, guint row, int expand)
485 {
486  GtkWidget *my_widget = widget;
487  GtkWidget *hbox;
488 
489  GtkAttachOptions xoptions = GTK_FILL;
490  if (expand)
491  {
492  xoptions |= GTK_EXPAND;
493  }
494  else
495  {
496  hbox = wh_hbox_new();
497  gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
498  my_widget = hbox;
499  }
500 
501  gtk_table_attach(GTK_TABLE(table), my_widget,
502  start_column, end_column, row-1, row,
503  xoptions, GTK_FILL | GTK_EXPAND,
504  0, 0);
505 }
506