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-2013 Alexandru Munteanu
7  * Contact: m@ioalex.net
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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 #if GTK_MAJOR_VERSION >= 3
79  GtkWidget *table = gtk_grid_new();
80  g_object_set_data(G_OBJECT(table), "rows", GINT_TO_POINTER(0));
81  gtk_grid_set_column_spacing(GTK_GRID(table), 5);
82  gtk_grid_set_row_spacing(GTK_GRID(table), 4);
83 #else
84  GtkWidget *table = gtk_table_new(1, 2, FALSE);
85  gtk_table_set_col_spacing(GTK_TABLE(table), 0, 0);
86  gtk_table_set_col_spacing(GTK_TABLE(table), 1, 5);
87 #endif
88  return table;
89 }
90 
91 void wh_add_in_table(GtkWidget *table, GtkWidget *widget)
92 {
93  guint last_row = _wh_add_row_to_table(table);
94 
95  _wh_attach_to_table(table, widget, 1, 3, last_row, TRUE);
96 }
97 
98 void wh_add_in_table_with_label_expand(GtkWidget *table, const gchar *label_text, GtkWidget *widget)
99 {
100  _wh_add_in_table_with_label(table, label_text, widget, TRUE);
101 }
102 
103 void wh_add_in_table_with_label(GtkWidget *table, const gchar *label_text, GtkWidget *widget)
104 {
105  _wh_add_in_table_with_label(table, label_text, widget, FALSE);
106 }
107 
108 GtkWidget *wh_put_in_new_hbox_with_margin_level(GtkWidget *widget, gint margin_level)
109 {
110  return _wh_put_in_new_hbox_with_margin(widget, 6 * margin_level);
111 }
112 
113 void wh_put_in_hbox_and_attach_to_vbox(GtkWidget *widget, GtkWidget *vbox, gint vertical_margin)
114 {
115  wh_put_in_hbox_and_attach_to_vbox_with_bottom_margin(widget, vbox, vertical_margin, -1);
116 }
117 
118 void wh_put_in_hbox_and_attach_to_vbox_with_bottom_margin(GtkWidget *widget, GtkWidget *vbox,
119  gint vertical_margin, gint bottom_margin)
120 {
121  GtkWidget *hbox = wh_hbox_new();
122  gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
123  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, vertical_margin);
124 
125  if (bottom_margin > 0)
126  {
127  GtkWidget *fake_hbox = wh_hbox_new();
128  gtk_box_pack_start(GTK_BOX(vbox), fake_hbox, FALSE, FALSE, bottom_margin);
129  }
130 }
131 
132 GtkWidget *wh_new_entry(gpointer callback, ui_state *ui)
133 {
134  GtkWidget *entry = gtk_entry_new();
135  gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE);
136 
137  if (callback)
138  {
139  g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(callback), ui);
140  }
141 
142  return entry;
143 }
144 
145 GtkWidget *wh_new_button(const gchar *button_label)
146 {
147  return gtk_button_new_with_mnemonic(button_label);
148 }
149 
150 void wh_get_widget_size(GtkWidget *widget, gint *width, gint *height)
151 {
152 #if GTK_MAJOR_VERSION <= 2
153  GtkAllocation allocation;
154  gtk_widget_get_allocation(widget, &allocation);
155 
156  if (width != NULL)
157  {
158  *width = allocation.width;
159  }
160 
161  if (height != NULL)
162  {
163  *height= allocation.height;
164  }
165 #else
166  if (width != NULL)
167  {
168  *width = gtk_widget_get_allocated_width(widget);
169  }
170 
171  if (height != NULL)
172  {
173  *height = gtk_widget_get_allocated_height(widget);
174  }
175 #endif
176 }
177 
178 GtkWidget *wh_create_int_spinner_in_box_with_top_width(gchar *before_label, gchar *after_label,
179  gdouble initial_value,
180  gdouble minimum_value, gdouble maximum_value,
181  gdouble step_increment, gdouble page_increment,
182  gchar *after_newline_label,
183  void (*spinner_callback)(GtkWidget *spinner, ui_state *ui),
184  ui_state *ui, GtkWidget *box, gint top_width)
185 {
186  GtkWidget *horiz_fake = wh_hbox_new();
187  GtkWidget *label = gtk_label_new(before_label);
188  gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0);
189 
190  GtkAdjustment *adj = (GtkAdjustment *)
191  gtk_adjustment_new(initial_value, minimum_value, maximum_value, step_increment, page_increment, 0.0);
192 
193  GtkWidget *spinner = gtk_spin_button_new(adj, 0, 0);
194 
195  gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spinner), TRUE);
196  g_signal_connect(G_OBJECT(spinner), "value_changed", G_CALLBACK(spinner_callback), ui);
197  gtk_box_pack_start(GTK_BOX(horiz_fake), spinner, FALSE, FALSE, 5);
198 
199  if (after_label != NULL)
200  {
201  gtk_box_pack_start(GTK_BOX(horiz_fake), gtk_label_new(after_label), FALSE, FALSE, 3);
202  }
203 
204  GtkWidget *fake = wh_hbox_new();
205  gtk_box_pack_start(GTK_BOX(box), fake, FALSE, FALSE, top_width);
206 
207  gtk_box_pack_start(GTK_BOX(box), horiz_fake, FALSE, FALSE, 1);
208 
209  if (after_newline_label != NULL)
210  {
211  horiz_fake = wh_hbox_new();
212  gtk_box_pack_start(GTK_BOX(horiz_fake), gtk_label_new(after_newline_label), FALSE, FALSE, 0);
213  gtk_box_pack_start(GTK_BOX(box), horiz_fake, FALSE, FALSE, 2);
214  }
215 
216  fake = wh_hbox_new();
217  gtk_box_pack_start(GTK_BOX(box), fake, FALSE, FALSE, 2);
218 
219  return spinner;
220 }
221 
222 GtkWidget *wh_create_int_spinner_in_box(gchar *before_label, gchar *after_label,
223  gdouble initial_value,
224  gdouble minimum_value, gdouble maximum_value,
225  gdouble step_increment, gdouble page_increment,
226  gchar *after_newline_label,
227  void (*spinner_callback)(GtkWidget *spinner, ui_state *ui),
228  ui_state *ui,
229  GtkWidget *box)
230 {
231  return wh_create_int_spinner_in_box_with_top_width(before_label, after_label,
232  initial_value, minimum_value, maximum_value, step_increment, page_increment,
233  after_newline_label, spinner_callback, ui, box, 2);
234 }
235 
236 GtkWidget *wh_hbox_new()
237 {
238 #if GTK_MAJOR_VERSION <= 2
239  return gtk_hbox_new(FALSE, 0);
240 #else
241  GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
242  gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
243  return hbox;
244 #endif
245 }
246 
247 GtkWidget *wh_vbox_new()
248 {
249 #if GTK_MAJOR_VERSION <= 2
250  return gtk_vbox_new(FALSE, 0);
251 #else
252  GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
253  gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
254  return vbox;
255 #endif
256 }
257 
258 GtkWidget *wh_hscale_new(GtkAdjustment *adjustment)
259 {
260 #if GTK_MAJOR_VERSION <= 2
261  return gtk_hscale_new(adjustment);
262 #else
263  return gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, adjustment);
264 #endif
265 }
266 
267 GtkWidget *wh_hscale_new_with_range(gdouble min, gdouble max, gdouble step)
268 {
269 #if GTK_MAJOR_VERSION <= 2
270  return gtk_hscale_new_with_range(min, max, step);
271 #else
272  return gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, min, max, step);
273 #endif
274 }
275 
276 void wh_get_pointer(GdkEventMotion *event, gint *x, gint *y, GdkModifierType *state)
277 {
278 #if GTK_MAJOR_VERSION <= 2
279  gdk_window_get_pointer(event->window, x, y, state);
280 #else
281  gdk_window_get_device_position(event->window, event->device, x, y, state);
282 #endif
283 }
284 
287 {
288  GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
289  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
290  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
291  GTK_POLICY_AUTOMATIC,
292  GTK_POLICY_AUTOMATIC);
293  return scrolled_window;
294 }
295 
302 gboolean wh_container_has_child(GtkContainer *container, GtkWidget *my_child)
303 {
304  GList *children = gtk_container_get_children(GTK_CONTAINER(container));
305  int i = 0;
306  GtkWidget *child = NULL;
307  while ((child = g_list_nth_data(children, i)) != NULL)
308  {
309  if (child == my_child)
310  {
311  return TRUE;
312  }
313  i++;
314  }
315 
316  return FALSE;
317 }
318 
319 void wh_set_image_on_button(GtkButton *button, GtkWidget *image)
320 {
321  gtk_button_set_image(button, image);
322 }
323 
324 static void _wh_folder_changed_event(GtkFileChooser *chooser, ui_state *ui)
325 {
326  ui_set_browser_directory(ui, gtk_file_chooser_get_current_folder(chooser));
327 }
328 
329 void wh_set_browser_directory_handler(ui_state *ui, GtkWidget* dialog)
330 {
331  const gchar *browser_dir = ui_get_browser_directory(ui);
332  if (browser_dir)
333  {
334  gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), browser_dir);
335  }
336 
337  g_signal_connect(GTK_FILE_CHOOSER(dialog), "current-folder-changed",
338  G_CALLBACK(_wh_folder_changed_event), ui);
339 }
340 
348 GtkWidget *wh_create_cool_button(gchar *stock_id, gchar *label_text,
349  gint toggle_or_not)
350 {
351  GtkWidget *box = wh_hbox_new();
352  gtk_container_set_border_width(GTK_CONTAINER(box), 0);
353 
354  GtkWidget *image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU);
355  gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0);
356 
357  if (label_text != NULL)
358  {
359  GtkWidget *label = gtk_label_new(label_text);
360  gtk_label_set_text_with_mnemonic(GTK_LABEL(label),label_text);
361  gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 3);
362  }
363 
364  GtkWidget *button;
365  if (toggle_or_not)
366  {
367  button = gtk_toggle_button_new();
368  }
369  else
370  {
371  button = gtk_button_new();
372  }
373 
374  gtk_container_add(GTK_CONTAINER(button), box);
375 
376  return button;
377 }
378 
379 GtkWidget *wh_create_cool_label(gchar *stock_id, gchar *label_text)
380 {
381  GtkWidget *box = wh_hbox_new();
382  gtk_container_set_border_width(GTK_CONTAINER(box), 0);
383 
384  GtkWidget *image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU);
385  gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0);
386 
387  if (label_text != NULL)
388  {
389  GtkWidget *label = gtk_label_new(label_text);
390  gtk_label_set_text_with_mnemonic(GTK_LABEL(label),label_text);
391  gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 3);
392  }
393 
394  gtk_widget_show_all(box);
395 
396  return box;
397 }
398 
399 GtkWidget *wh_create_window_with_close_button(gchar *title, gint width, gint height,
400  GtkWindowPosition position, GtkWindow *parent_window,
401  GtkWidget *main_area_widget, GtkWidget *bottom_widget, ...)
402 {
403  GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
404  g_signal_connect(G_OBJECT(window), "delete_event",
405  G_CALLBACK(gtk_widget_hide_on_delete), window);
406  gtk_window_set_title(GTK_WINDOW(window), title);
407  gtk_window_set_destroy_with_parent(GTK_WINDOW(window), TRUE);
408  gtk_window_set_default_size(GTK_WINDOW(window), width, height);
409  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
410 
411  GtkWidget *vbox = wh_vbox_new();
412  gtk_container_set_border_width(GTK_CONTAINER(vbox), 4);
413  gtk_container_add(GTK_CONTAINER(window), vbox);
414  gtk_box_pack_start(GTK_BOX(vbox), main_area_widget, TRUE, TRUE, 2);
415 
416  GtkWidget *bottom_hbox = wh_hbox_new();
417  gtk_box_pack_start(GTK_BOX(vbox), bottom_hbox, FALSE, FALSE, 3);
418 
419  va_list ap;
420  va_start(ap, bottom_widget);
421  while (bottom_widget)
422  {
423  gtk_box_pack_start(GTK_BOX(bottom_hbox), bottom_widget, FALSE, FALSE, 3);
424  bottom_widget = va_arg(ap, GtkWidget *);
425  }
426  va_end(ap);
427 
428  GtkWidget *close_button = wh_create_cool_button(GTK_STOCK_CLOSE, _("_Close"), FALSE);
429  gtk_box_pack_end(GTK_BOX(bottom_hbox), close_button, FALSE, FALSE, 3);
430  g_signal_connect(G_OBJECT(close_button), "clicked",
431  G_CALLBACK(hide_window_from_button), window);
432 
433  return window;
434 }
435 
436 void wh_show_window(GtkWidget *window)
437 {
438  if (!gtk_widget_get_visible(window))
439  {
440  gtk_widget_show_all(window);
441  return;
442  }
443 
444  gtk_window_present(GTK_WINDOW(window));
445 }
446 
447 static void hide_window_from_button(GtkWidget *widget, gpointer data)
448 {
449  GtkWidget *window = (GtkWidget *)data;
450  gtk_widget_hide(window);
451 }
452 
453 static guint _wh_add_row_to_table(GtkWidget *table)
454 {
455 #if GTK_MAJOR_VERSION >= 3
456  int number_of_rows = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(table), "rows"));
457  number_of_rows++;
458  g_object_set_data(G_OBJECT(table), "rows", GINT_TO_POINTER(number_of_rows));
459  gtk_grid_insert_row(GTK_GRID(table), number_of_rows);
460  return number_of_rows;
461 #else
462  guint rows;
463  guint columns;
464 
465  g_object_get(G_OBJECT(table),
466  "n-rows", &rows,
467  "n-columns", &columns,
468  NULL);
469 
470  guint new_rows = rows + 1;
471 
472  gtk_table_resize(GTK_TABLE(table), new_rows, columns);
473  gtk_table_set_row_spacing(GTK_TABLE(table), new_rows - 1, 4);
474 
475  return new_rows;
476 #endif
477 }
478 
479 static GtkWidget *_wh_put_in_new_hbox_with_margin(GtkWidget *widget, gint margin)
480 {
481  GtkWidget *hbox = wh_hbox_new();
482  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, margin);
483  return hbox;
484 }
485 
486 static void _wh_add_in_table_with_label(GtkWidget *table, const gchar *label_text,
487  GtkWidget *widget, int expand)
488 {
489  guint last_row = _wh_add_row_to_table(table);
490 
491  GtkWidget *label = gtk_label_new(label_text);
492  gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
493 
494  _wh_attach_to_table(table, label, 1, 2, last_row, FALSE);
495  _wh_attach_to_table(table, widget, 2, 3, last_row, expand);
496 }
497 
498 static void _wh_attach_to_table(GtkWidget *table, GtkWidget *widget,
499  guint start_column, guint end_column, guint row, int expand)
500 {
501  GtkWidget *my_widget = widget;
502  GtkWidget *hbox;
503 
504 #if GTK_MAJOR_VERSION >= 3
505  gtk_widget_set_halign(my_widget, GTK_ALIGN_FILL);
506 #else
507  GtkAttachOptions xoptions = GTK_FILL;
508 #endif
509  if (expand)
510  {
511 #if GTK_MAJOR_VERSION >= 3
512  gtk_widget_set_hexpand(my_widget, TRUE);
513 #else
514  xoptions |= GTK_EXPAND;
515 #endif
516  }
517  else
518  {
519  hbox = wh_hbox_new();
520  gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
521  my_widget = hbox;
522  }
523 
524 #if GTK_MAJOR_VERSION >= 3
525  gtk_grid_attach(GTK_GRID(table), my_widget, start_column, row - 1, end_column - start_column, 1);
526 #else
527  gtk_table_attach(GTK_TABLE(table), my_widget,
528  start_column, end_column, row-1, row,
529  xoptions, GTK_FILL | GTK_EXPAND,
530  0, 0);
531 #endif
532 }
533 
GtkWidget * wh_create_scrolled_window()
creates a scrolled window
gboolean wh_container_has_child(GtkContainer *container, GtkWidget *my_child)
Does this GtkContainer contain that object?
GtkWidget * wh_set_title_and_get_vbox(GtkWidget *widget, const gchar *title)
Generates a window portion containing a caption and a vbox.
GtkWidget * wh_create_cool_button(gchar *stock_id, gchar *label_text, gint toggle_or_not)
creates a cool button with image from stock