diff options
author | Alexey Yakovenko <wakeroid@gmail.com> | 2010-03-10 19:36:10 +0100 |
---|---|---|
committer | Alexey Yakovenko <wakeroid@gmail.com> | 2010-03-10 19:36:10 +0100 |
commit | aa30e6b53816629d2fd4cb4dbd1f9a35b1473563 (patch) | |
tree | b8486438045e3022a8178e9d8c535481bd7a7441 | |
parent | 18b350cc0ee0c53d5ae93384576146a064bb5372 (diff) |
custom widget colors WIP
-rw-r--r-- | plugins/gtkui/Makefile.am | 3 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.c | 373 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.h | 28 | ||||
-rw-r--r-- | plugins/gtkui/ddbvolumebar.c | 13 | ||||
-rw-r--r-- | plugins/gtkui/deadbeef.glade | 289 | ||||
-rw-r--r-- | plugins/gtkui/drawing.h | 21 | ||||
-rw-r--r-- | plugins/gtkui/gdkdrawing.c | 81 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.c | 4 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.h | 1 | ||||
-rw-r--r-- | plugins/gtkui/interface.c | 134 | ||||
-rw-r--r-- | plugins/gtkui/mainplaylist.c | 12 | ||||
-rw-r--r-- | plugins/gtkui/plcommon.c | 10 | ||||
-rw-r--r-- | plugins/gtkui/prefwin.c | 498 |
13 files changed, 1086 insertions, 381 deletions
diff --git a/plugins/gtkui/Makefile.am b/plugins/gtkui/Makefile.am index b4d6dfe9..7ae2e8a8 100644 --- a/plugins/gtkui/Makefile.am +++ b/plugins/gtkui/Makefile.am @@ -15,7 +15,8 @@ gtkui_la_SOURCES = gtkui.c gtkui.h\ ddbvolumebar.c ddbvolumebar.h\ trkproperties.c trkproperties.h\ coverart.c coverart.h\ - plcommon.c plcommon.h + plcommon.c plcommon.h\ + prefwin.c gtkui_la_LDFLAGS = -module diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c index acf069ca..902476a5 100644 --- a/plugins/gtkui/callbacks.c +++ b/plugins/gtkui/callbacks.c @@ -40,6 +40,7 @@ #include "../../session.h" #include "gtkui.h" #include "parser.h" +#include "drawing.h" #define trace(...) { fprintf (stderr, __VA_ARGS__); } //#define trace(fmt,...) @@ -489,13 +490,15 @@ seekbar_draw (GtkWidget *widget) { if (!cr) { return; } + GdkColor *clr_selection = gtkui_get_selection_color (); + GdkColor *clr_back = gtkui_get_back_color (); + DB_playItem_t *trk = deadbeef->streamer_get_playing_track (); DB_fileinfo_t *dec = deadbeef->streamer_get_current_fileinfo (); if (!dec || !trk || deadbeef->pl_get_item_duration (trk) < 0) { clearlooks_rounded_rectangle (cr, 2, widget->allocation.height/2-4, widget->allocation.width-4, 8, 4, 0xff); // empty seekbar, just a frame - GdkColor *clr = &widget->style->base[GTK_STATE_SELECTED]; - cairo_set_source_rgb (cr, clr->red/65535.f, clr->green/65535.f, clr->blue/65535.f ); + cairo_set_source_rgb (cr, clr_selection->red/65535.f, clr_selection->green/65535.f, clr_selection->blue/65535.f ); cairo_stroke (cr); cairo_destroy (cr); return; @@ -519,8 +522,7 @@ seekbar_draw (GtkWidget *widget) { } // left if (pos > 0) { - GdkColor *clr = &widget->style->base[GTK_STATE_SELECTED]; - cairo_set_source_rgb (cr, clr->red/65535.f, clr->green/65535.f, clr->blue/65535.f ); + cairo_set_source_rgb (cr, clr_selection->red/65535.f, clr_selection->green/65535.f, clr_selection->blue/65535.f ); cairo_rectangle (cr, 0, widget->allocation.height/2-4, pos, 8); cairo_clip (cr); clearlooks_rounded_rectangle (cr, 0, widget->allocation.height/2-4, widget->allocation.width, 8, 4, 0xff); @@ -529,8 +531,7 @@ seekbar_draw (GtkWidget *widget) { } // right - GdkColor *clr = &widget->style->fg[GTK_STATE_NORMAL]; - cairo_set_source_rgb (cr, clr->red/65535.f, clr->green/65535.f, clr->blue/65535.f ); + cairo_set_source_rgb (cr, clr_back->red/65535.f, clr_back->green/65535.f, clr_back->blue/65535.f ); cairo_rectangle (cr, pos, widget->allocation.height/2-4, widget->allocation.width-pos, 8); cairo_clip (cr); clearlooks_rounded_rectangle (cr, 0, widget->allocation.height/2-4, widget->allocation.width, 8, 4, 0xff); @@ -791,326 +792,6 @@ on_helpwindow_key_press_event (GtkWidget *widget, return FALSE; } -static GtkWidget *prefwin; - -static char alsa_device_names[100][64]; -static int num_alsa_devices; - -static void -gtk_enum_sound_callback (const char *name, const char *desc, void *userdata) { - if (num_alsa_devices >= 100) { - fprintf (stderr, "wtf!! more than 100 alsa devices??\n"); - return; - } - GtkComboBox *combobox = GTK_COMBO_BOX (userdata); - gtk_combo_box_append_text (combobox, desc); - - if (!strcmp (deadbeef->conf_get_str ("alsa_soundcard", "default"), name)) { - gtk_combo_box_set_active (combobox, num_alsa_devices); - } - - strncpy (alsa_device_names[num_alsa_devices], name, 63); - alsa_device_names[num_alsa_devices][63] = 0; - num_alsa_devices++; -} - -void -on_plugin_active_toggled (GtkCellRendererToggle *cell_renderer, gchar *path, GtkTreeModel *model) { - GtkTreePath *p = gtk_tree_path_new_from_string (path); - if (p) { - int *indices = gtk_tree_path_get_indices (p); - //gtk_tree_path_free (p); // wtf?? gtk crashes on this - if (indices) { - DB_plugin_t **plugins = deadbeef->plug_get_list (); - DB_plugin_t *plug = plugins[*indices]; - gboolean state; - GtkTreeIter iter; - gtk_tree_model_get_iter (model, &iter, p); - gtk_tree_model_get (model, &iter, 0, &state, -1); - if (!deadbeef->plug_activate (plug, !state)) { - gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, !state, -1); - } - } - g_free (indices); - } -} - -void -preferences_fill_soundcards (void) { - if (!prefwin) { - return; - } - const char *s = deadbeef->conf_get_str ("alsa_soundcard", "default"); - GtkComboBox *combobox = GTK_COMBO_BOX (lookup_widget (prefwin, "pref_soundcard")); - GtkTreeModel *mdl = gtk_combo_box_get_model (combobox); - gtk_list_store_clear (GTK_LIST_STORE (mdl)); - - gtk_combo_box_append_text (combobox, "Default Audio Device"); - if (!strcmp (s, "default")) { - gtk_combo_box_set_active (combobox, 0); - } - num_alsa_devices = 1; - strcpy (alsa_device_names[0], "default"); - if (deadbeef->get_output ()->enum_soundcards) { - deadbeef->get_output ()->enum_soundcards (gtk_enum_sound_callback, combobox); - gtk_widget_set_sensitive (GTK_WIDGET (combobox), TRUE); - } - else { - gtk_widget_set_sensitive (GTK_WIDGET (combobox), FALSE); - } -} - -void -on_preferences_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - if (prefwin) { - return; - } - GtkWidget *w = prefwin = create_prefwin (); - gtk_window_set_transient_for (GTK_WINDOW (w), GTK_WINDOW (mainwin)); - - GtkComboBox *combobox = NULL; - - // output plugin selection - const char *outplugname = deadbeef->conf_get_str ("output_plugin", "ALSA output plugin"); - combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_output_plugin")); - - DB_output_t **out_plugs = deadbeef->plug_get_output_list (); - for (int i = 0; out_plugs[i]; i++) { - gtk_combo_box_append_text (combobox, out_plugs[i]->plugin.name); - if (!strcmp (outplugname, out_plugs[i]->plugin.name)) { - gtk_combo_box_set_active (combobox, i); - } - } - - // soundcard (output device) selection - preferences_fill_soundcards (); - - g_signal_connect ((gpointer) combobox, "changed", - G_CALLBACK (on_pref_output_plugin_changed), - NULL); - GtkWidget *pref_soundcard = lookup_widget (prefwin, "pref_soundcard"); - g_signal_connect ((gpointer) pref_soundcard, "changed", - G_CALLBACK (on_pref_soundcard_changed), - NULL); - - // alsa resampling - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_dynsamplerate")), deadbeef->conf_get_int ("playback.dynsamplerate", 0)); - - // src_quality - combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_src_quality")); - gtk_combo_box_set_active (combobox, deadbeef->conf_get_int ("src_quality", 2)); - - // replaygain_mode - combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_replaygain_mode")); - gtk_combo_box_set_active (combobox, deadbeef->conf_get_int ("replaygain_mode", 0)); - - // replaygain_scale - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_replaygain_scale")), deadbeef->conf_get_int ("replaygain_scale", 1)); - - // close_send_to_tray - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_close_send_to_tray")), deadbeef->conf_get_int ("close_send_to_tray", 0)); - - // network - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_network_enableproxy")), deadbeef->conf_get_int ("network.proxy", 0)); - gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "pref_network_proxyaddress")), deadbeef->conf_get_str ("network.proxy.address", "")); - gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "pref_network_proxyport")), deadbeef->conf_get_str ("network.proxy.port", "8080")); - combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_network_proxytype")); - const char *type = deadbeef->conf_get_str ("network.proxy.type", "HTTP"); - if (!strcasecmp (type, "HTTP")) { - gtk_combo_box_set_active (combobox, 0); - } - else if (!strcasecmp (type, "HTTP_1_0")) { - gtk_combo_box_set_active (combobox, 1); - } - else if (!strcasecmp (type, "SOCKS4")) { - gtk_combo_box_set_active (combobox, 2); - } - else if (!strcasecmp (type, "SOCKS5")) { - gtk_combo_box_set_active (combobox, 3); - } - else if (!strcasecmp (type, "SOCKS4A")) { - gtk_combo_box_set_active (combobox, 4); - } - else if (!strcasecmp (type, "SOCKS5_HOSTNAME")) { - gtk_combo_box_set_active (combobox, 5); - } - - // list of plugins - GtkTreeView *tree = GTK_TREE_VIEW (lookup_widget (w, "pref_pluginlist")); - GtkCellRenderer *rend_text = gtk_cell_renderer_text_new (); -#if 0 - GtkCellRenderer *rend_toggle = gtk_cell_renderer_toggle_new (); - GtkListStore *store = gtk_list_store_new (3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_BOOLEAN); - g_signal_connect ((gpointer)rend_toggle, "toggled", - G_CALLBACK (on_plugin_active_toggled), - store); - GtkTreeViewColumn *col1 = gtk_tree_view_column_new_with_attributes ("Active", rend_toggle, "active", 0, "activatable", 2, NULL); - GtkTreeViewColumn *col2 = gtk_tree_view_column_new_with_attributes ("Title", rend_text, "text", 1, NULL); - gtk_tree_view_append_column (tree, col1); - gtk_tree_view_append_column (tree, col2); - DB_plugin_t **plugins = deadbeef->plug_get_list (); - int i; - for (i = 0; plugins[i]; i++) { - GtkTreeIter it; - gtk_list_store_append (store, &it); - gtk_list_store_set (store, &it, 0, plugins[i]->inactive ? FALSE : TRUE, 1, plugins[i]->name, 2, plugins[i]->nostop ? FALSE : TRUE, -1); - } -#else - GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); - GtkTreeViewColumn *col2 = gtk_tree_view_column_new_with_attributes ("Title", rend_text, "text", 0, NULL); - gtk_tree_view_append_column (tree, col2); - DB_plugin_t **plugins = deadbeef->plug_get_list (); - int i; - for (i = 0; plugins[i]; i++) { - GtkTreeIter it; - gtk_list_store_append (store, &it); - gtk_list_store_set (store, &it, 0, plugins[i]->name, -1); - } -#endif - gtk_tree_view_set_model (tree, GTK_TREE_MODEL (store)); - - gtk_widget_set_sensitive (lookup_widget (prefwin, "configure_plugin"), FALSE); -// gtk_widget_show (w); - gtk_dialog_run (GTK_DIALOG (prefwin)); - gtk_widget_destroy (prefwin); - prefwin = NULL; -} - - -void -on_pref_soundcard_changed (GtkComboBox *combobox, - gpointer user_data) -{ - int active = gtk_combo_box_get_active (combobox); - if (active >= 0 && active < num_alsa_devices) { - const char *soundcard = deadbeef->conf_get_str ("alsa_soundcard", "default"); - if (strcmp (soundcard, alsa_device_names[active])) { - deadbeef->conf_set_str ("alsa_soundcard", alsa_device_names[active]); - deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); - } - } -} - -void -on_pref_output_plugin_changed (GtkComboBox *combobox, - gpointer user_data) -{ - const char *outplugname = deadbeef->conf_get_str ("output_plugin", "ALSA output plugin"); - int active = gtk_combo_box_get_active (combobox); - - DB_output_t **out_plugs = deadbeef->plug_get_output_list (); - DB_output_t *prev = NULL; - DB_output_t *new = NULL; - - for (int i = 0; out_plugs[i]; i++) { - if (!strcmp (out_plugs[i]->plugin.name, outplugname)) { - prev = out_plugs[i]; - } - if (i == active) { - new = out_plugs[i]; - } - } - - if (!new) { - fprintf (stderr, "failed to find output plugin selected in preferences window\n"); - } - else { - if (prev != new) { - deadbeef->conf_set_str ("output_plugin", new->plugin.name); - deadbeef->sendmessage (M_REINIT_SOUND, 0, 0, 0); - } - } -} - -void -on_pref_dynsamplerate_clicked (GtkButton *button, - gpointer user_data) -{ - int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); - deadbeef->conf_set_int ("playback.dynsamplerate", active); - deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); -} - - -void -on_pref_src_quality_changed (GtkComboBox *combobox, - gpointer user_data) -{ - int active = gtk_combo_box_get_active (combobox); - deadbeef->conf_set_int ("src_quality", active == -1 ? 2 : active); - deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); -} - - -void -on_pref_replaygain_mode_changed (GtkComboBox *combobox, - gpointer user_data) -{ - int active = gtk_combo_box_get_active (combobox); - deadbeef->conf_set_int ("replaygain_mode", active == -1 ? 0 : active); - deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); -} - -void -on_pref_replaygain_scale_clicked (GtkButton *button, - gpointer user_data) -{ - int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); - deadbeef->conf_set_int ("replaygain_scale", active); - deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); -} - - -void -on_pref_close_send_to_tray_clicked (GtkButton *button, - gpointer user_data) -{ - int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); - deadbeef->conf_set_int ("close_send_to_tray", active); - deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); -} - -void -on_pref_pluginlist_cursor_changed (GtkTreeView *treeview, - gpointer user_data) -{ - GtkTreePath *path; - GtkTreeViewColumn *col; - gtk_tree_view_get_cursor (treeview, &path, &col); - if (!path || !col) { - // reset - return; - } - int *indices = gtk_tree_path_get_indices (path); - DB_plugin_t **plugins = deadbeef->plug_get_list (); - DB_plugin_t *p = plugins[*indices]; - g_free (indices); - assert (p); - GtkWidget *w = prefwin;//GTK_WIDGET (gtk_widget_get_parent_window (GTK_WIDGET (treeview))); - assert (w); - GtkEntry *e = GTK_ENTRY (lookup_widget (w, "pref_plugin_descr")); - gtk_entry_set_text (e, p->descr ? p->descr : ""); - e = GTK_ENTRY (lookup_widget (w, "pref_plugin_author")); - gtk_entry_set_text (e, p->author ? p->author : ""); - e = GTK_ENTRY (lookup_widget (w, "pref_plugin_email")); - gtk_entry_set_text (e, p->email ? p->email : ""); - e = GTK_ENTRY (lookup_widget (w, "pref_plugin_website")); - gtk_entry_set_text (e, p->website ? p->website : ""); - - gtk_widget_set_sensitive (lookup_widget (prefwin, "configure_plugin"), p->configdialog ? TRUE : FALSE); -} - -gboolean -on_prefwin_delete_event (GtkWidget *widget, - GdkEvent *event, - gpointer user_data) -{ - prefwin = NULL; - return FALSE; -} - void on_column_id_changed (GtkComboBox *combobox, gpointer user_data) @@ -1198,37 +879,6 @@ on_prefwin_key_press_event (GtkWidget *widget, return FALSE; } -void -on_pref_close_clicked (GtkButton *button, - gpointer user_data) -{ - gtk_widget_hide (prefwin); - gtk_widget_destroy (prefwin); -} - - -void -on_configure_plugin_clicked (GtkButton *button, - gpointer user_data) -{ - GtkWidget *w = prefwin; - GtkTreeView *treeview = GTK_TREE_VIEW (lookup_widget (w, "pref_pluginlist")); - GtkTreePath *path; - GtkTreeViewColumn *col; - gtk_tree_view_get_cursor (treeview, &path, &col); - if (!path || !col) { - // reset - return; - } - int *indices = gtk_tree_path_get_indices (path); - DB_plugin_t **plugins = deadbeef->plug_get_list (); - DB_plugin_t *p = plugins[*indices]; - if (p->configdialog) { - plugin_configure (prefwin, p); - } -} - - gboolean on_mainwin_window_state_event (GtkWidget *widget, GdkEventWindowState *event, @@ -1329,3 +979,12 @@ create_volumebar_widget (gchar *widget_name, gchar *string1, gchar *string2, return ddb_volumebar_new (); } + + +void +on_mainwin_realize (GtkWidget *widget, + gpointer user_data) +{ + gtkui_init_theme_colors (); +} + diff --git a/plugins/gtkui/callbacks.h b/plugins/gtkui/callbacks.h index 7a02aa43..4a2ff4d8 100644 --- a/plugins/gtkui/callbacks.h +++ b/plugins/gtkui/callbacks.h @@ -717,3 +717,31 @@ create_tabstrip_widget (gchar *widget_name, gchar *string1, gchar *string2, GtkWidget* create_volumebar_widget (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2); + +void +on_color_light_color_set (GtkColorButton *colorbutton, + gpointer user_data); + +void +on_color_mid_color_set (GtkColorButton *colorbutton, + gpointer user_data); + +void +on_color_dark_color_set (GtkColorButton *colorbutton, + gpointer user_data); + +void +on_color_selection_color_set (GtkColorButton *colorbutton, + gpointer user_data); + +void +on_color_back_color_set (GtkColorButton *colorbutton, + gpointer user_data); + +void +on_override_gtk_colors_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_mainwin_realize (GtkWidget *widget, + gpointer user_data); diff --git a/plugins/gtkui/ddbvolumebar.c b/plugins/gtkui/ddbvolumebar.c index 1f7e4a97..4d2654a0 100644 --- a/plugins/gtkui/ddbvolumebar.c +++ b/plugins/gtkui/ddbvolumebar.c @@ -180,6 +180,13 @@ volumebar_draw (GtkWidget *widget) { int n = widget->allocation.width / 4; float vol = (range + deadbeef->volume_get_db ()) / range * n; float h = 17; + + GdkGC *back_gc = gdk_gc_new (widget->window); + gdk_gc_set_rgb_fg_color (back_gc, gtkui_get_back_color ()); + + GdkGC *front_gc = gdk_gc_new (widget->window); + gdk_gc_set_rgb_fg_color (front_gc, gtkui_get_selection_color ()); + for (int i = 0; i < n; i++) { float iy = (float)i + 3; int _x = i * 4; @@ -188,12 +195,14 @@ volumebar_draw (GtkWidget *widget) { _y += (h - _h); int _w = 3; if (i <= vol) { - gdk_draw_rectangle (volumebar_backbuf, widget->style->base_gc[GTK_STATE_SELECTED], TRUE, _x, _y, _w, _h); + gdk_draw_rectangle (volumebar_backbuf, front_gc, TRUE, _x, _y, _w, _h); } else { - gdk_draw_rectangle (volumebar_backbuf, widget->style->fg_gc[GTK_STATE_NORMAL], TRUE, _x, _y, _w, _h); + gdk_draw_rectangle (volumebar_backbuf, back_gc, TRUE, _x, _y, _w, _h); } } + g_object_unref (back_gc); + g_object_unref (front_gc); #endif } diff --git a/plugins/gtkui/deadbeef.glade b/plugins/gtkui/deadbeef.glade index 6849df03..9ea9eba1 100644 --- a/plugins/gtkui/deadbeef.glade +++ b/plugins/gtkui/deadbeef.glade @@ -26,6 +26,7 @@ <signal name="delete_event" handler="on_mainwin_delete_event" last_modification_time="Thu, 13 Aug 2009 20:35:55 GMT"/> <signal name="configure_event" handler="on_mainwin_configure_event" last_modification_time="Sun, 23 Aug 2009 15:26:53 GMT"/> <signal name="window_state_event" handler="on_mainwin_window_state_event" last_modification_time="Wed, 09 Dec 2009 19:39:55 GMT"/> + <signal name="realize" handler="on_mainwin_realize" last_modification_time="Wed, 10 Mar 2010 18:20:51 GMT"/> <child> <widget class="GtkVBox" id="vbox1"> @@ -2503,6 +2504,294 @@ Album</property> <property name="fill">False</property> </packing> </child> + + <child> + <widget class="GtkFrame" id="frame3"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="label_yalign">0.5</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + + <child> + <widget class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">1</property> + <property name="yscale">1</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">12</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkTable" id="colors_table"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="n_rows">2</property> + <property name="n_columns">5</property> + <property name="homogeneous">False</property> + <property name="row_spacing">8</property> + <property name="column_spacing">0</property> + + <child> + <widget class="GtkColorButton" id="color_light"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="use_alpha">False</property> + <property name="focus_on_click">True</property> + <signal name="color_set" handler="on_color_light_color_set" last_modification_time="Tue, 09 Mar 2010 19:11:31 GMT"/> + </widget> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">expand</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkColorButton" id="color_mid"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="use_alpha">False</property> + <property name="focus_on_click">True</property> + <signal name="color_set" handler="on_color_mid_color_set" last_modification_time="Tue, 09 Mar 2010 19:11:27 GMT"/> + </widget> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">expand</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkColorButton" id="color_dark"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="use_alpha">False</property> + <property name="focus_on_click">True</property> + <signal name="color_set" handler="on_color_dark_color_set" last_modification_time="Tue, 09 Mar 2010 19:11:22 GMT"/> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">expand</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkColorButton" id="color_selection"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="use_alpha">False</property> + <property name="focus_on_click">True</property> + <signal name="color_set" handler="on_color_selection_color_set" last_modification_time="Tue, 09 Mar 2010 19:11:16 GMT"/> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">expand</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label43"> + <property name="visible">True</property> + <property name="label" translatable="yes">Selection</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">expand</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label44"> + <property name="visible">True</property> + <property name="label" translatable="yes">Dark</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">expand</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label45"> + <property name="visible">True</property> + <property name="label" translatable="yes">Middle</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">expand</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label46"> + <property name="visible">True</property> + <property name="label" translatable="yes">Light</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">expand</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkColorButton" id="color_back"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="use_alpha">False</property> + <property name="focus_on_click">True</property> + <signal name="color_set" handler="on_color_back_color_set" last_modification_time="Tue, 09 Mar 2010 19:11:36 GMT"/> + </widget> + <packing> + <property name="left_attach">4</property> + <property name="right_attach">5</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">expand</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label47"> + <property name="visible">True</property> + <property name="label" translatable="yes">Background</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="left_attach">4</property> + <property name="right_attach">5</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">expand</property> + <property name="y_options"></property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkCheckButton" id="override_theme_colors"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Override GTK+ theme colors in custom widgets</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="on_override_gtk_colors_toggled" last_modification_time="Tue, 09 Mar 2010 19:44:00 GMT"/> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> </widget> <packing> <property name="tab_expand">False</property> diff --git a/plugins/gtkui/drawing.h b/plugins/gtkui/drawing.h index e6a7ee0a..54352ae1 100644 --- a/plugins/gtkui/drawing.h +++ b/plugins/gtkui/drawing.h @@ -35,9 +35,6 @@ draw_begin (uintptr_t canvas); void draw_end (void); -uintptr_t -draw_load_pixbuf (const char *fname); - void draw_get_canvas_size (uintptr_t canvas, int *w, int *h); @@ -71,4 +68,22 @@ draw_text_with_colors (float x, float y, int width, int align, const char *text) void draw_get_text_extents (const char *text, int len, int *w, int *h); +GdkColor * +gtkui_get_back_color (void); + +GdkColor * +gtkui_get_selection_color (void); + +GdkColor * +gtkui_get_dark_color (void); + +GdkColor * +gtkui_get_mid_color (void); + +GdkColor * +gtkui_get_light_color (void); + +void +gtkui_init_theme_colors (void); + #endif // __DRAWING_H diff --git a/plugins/gtkui/gdkdrawing.c b/plugins/gtkui/gdkdrawing.c index c78f5d54..3a992627 100644 --- a/plugins/gtkui/gdkdrawing.c +++ b/plugins/gtkui/gdkdrawing.c @@ -21,9 +21,11 @@ #endif #include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> +//#include <gdk/gdkkeysyms.h> +#include <string.h> #include "drawing.h" #include "support.h" +#include "gtkui.h" static GdkDrawable *drawable; static GdkGC *gc; @@ -58,11 +60,6 @@ draw_copy (uintptr_t dest_canvas, uintptr_t src_canvas, int dx, int dy, int sx, gdk_draw_drawable (GDK_DRAWABLE (dest_canvas), gc, GDK_DRAWABLE (src_canvas), dx, dy, sx, sy, w, h); } -uintptr_t -draw_load_pixbuf (const char *fname) { - return (uintptr_t)create_pixbuf (fname); -} - void draw_pixbuf (uintptr_t dest_canvas, uintptr_t pixbuf, int dx, int dy, int sx, int sy, int w, int h) { gdk_pixbuf_render_to_drawable (GDK_PIXBUF (pixbuf), GDK_DRAWABLE (dest_canvas), gc, sx, sy, dx, dy, w, h, GDK_RGB_DITHER_NONE, 0, 0); @@ -118,7 +115,7 @@ draw_get_font_size (void) { float dpi = gdk_screen_get_resolution (screen); GtkStyle *style = gtk_widget_get_default_style (); PangoFontDescription *desc = style->font_desc; - return (float)pango_font_description_get_size (desc) / PANGO_SCALE * dpi / 72; + return (float)(pango_font_description_get_size (desc) / PANGO_SCALE * dpi / 72); } void @@ -151,3 +148,73 @@ draw_get_text_extents (const char *text, int len, int *w, int *h) { *w = ink.width; *h = ink.height; } + +static GdkColor gtkui_back_color; +static GdkColor gtkui_selection_color; +static GdkColor gtkui_dark_color; +static GdkColor gtkui_mid_color; +static GdkColor gtkui_light_color; + +void +gtkui_init_theme_colors (void) { + int override = deadbeef->conf_get_int ("gtkui.override_theme_colors", 0); + + extern GtkWidget *mainwin; + GtkStyle *style = mainwin->style; + char color_text[100]; + const char *clr; + + if (!override) { + memcpy (>kui_selection_color, &style->base[GTK_STATE_SELECTED], sizeof (GdkColor)); + memcpy (>kui_back_color, &style->fg[GTK_STATE_NORMAL], sizeof (GdkColor)); + memcpy (>kui_dark_color, &style->dark[GTK_STATE_NORMAL], sizeof (GdkColor)); + memcpy (>kui_mid_color, &style->mid[GTK_STATE_NORMAL], sizeof (GdkColor)); + memcpy (>kui_light_color, &style->light[GTK_STATE_NORMAL], sizeof (GdkColor)); + } + else { + snprintf (color_text, sizeof (color_text), "%d %d %d", style->base[GTK_STATE_SELECTED].red, style->base[GTK_STATE_SELECTED].green, style->base[GTK_STATE_SELECTED].blue); + clr = deadbeef->conf_get_str ("gtkui.color.selection", color_text); + sscanf (clr, "%d %d %d", >kui_selection_color.red, >kui_selection_color.green, >kui_selection_color.blue); + + snprintf (color_text, sizeof (color_text), "%d %d %d", style->fg[GTK_STATE_NORMAL].red, style->fg[GTK_STATE_NORMAL].green, style->fg[GTK_STATE_NORMAL].blue); + clr = deadbeef->conf_get_str ("gtkui.color.back", color_text); + sscanf (clr, "%d %d %d", >kui_back_color.red, >kui_back_color.green, >kui_back_color.blue); + + snprintf (color_text, sizeof (color_text), "%d %d %d", style->dark[GTK_STATE_NORMAL].red, style->dark[GTK_STATE_NORMAL].green, style->dark[GTK_STATE_NORMAL].blue); + clr = deadbeef->conf_get_str ("gtkui.color.dark", color_text); + sscanf (clr, "%d %d %d", >kui_dark_color.red, >kui_dark_color.green, >kui_dark_color.blue); + + snprintf (color_text, sizeof (color_text), "%d %d %d", style->mid[GTK_STATE_NORMAL].red, style->mid[GTK_STATE_NORMAL].green, style->mid[GTK_STATE_NORMAL].blue); + clr = deadbeef->conf_get_str ("gtkui.color.mid", color_text); + sscanf (clr, "%d %d %d", >kui_mid_color.red, >kui_mid_color.green, >kui_mid_color.blue); + + snprintf (color_text, sizeof (color_text), "%d %d %d", style->light[GTK_STATE_NORMAL].red, style->light[GTK_STATE_NORMAL].green, style->light[GTK_STATE_NORMAL].blue); + clr = deadbeef->conf_get_str ("gtkui.color.light", color_text); + sscanf (clr, "%d %d %d", >kui_light_color.red, >kui_light_color.green, >kui_light_color.blue); + } +} + +GdkColor * +gtkui_get_back_color (void) { + return >kui_back_color; +} + +GdkColor * +gtkui_get_selection_color (void) { + return >kui_selection_color; +} + +GdkColor * +gtkui_get_dark_color (void) { + return >kui_dark_color; +} + +GdkColor * +gtkui_get_mid_color (void) { + return >kui_mid_color; +} + +GdkColor * +gtkui_get_light_color (void) { + return >kui_light_color; +} diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c index 775c9f1d..7b003ee0 100644 --- a/plugins/gtkui/gtkui.c +++ b/plugins/gtkui/gtkui.c @@ -41,6 +41,7 @@ #include "trkproperties.h" #include "../artwork/artwork.h" #include "coverart.h" +#include "plcommon.h" //#define trace(...) { fprintf(stderr, __VA_ARGS__); } #define trace(fmt,...) @@ -536,6 +537,9 @@ gtkui_on_configchanged (DB_event_t *ev, uintptr_t data) { // stop after current int stop_after_current = deadbeef->conf_get_int ("playlist.stop_after_current", 0); gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "stop_after_current")), stop_after_current ? TRUE : FALSE); + + // theme colors + gtkui_init_theme_colors (); return 0; } diff --git a/plugins/gtkui/gtkui.h b/plugins/gtkui/gtkui.h index 28714ab1..8dd5907a 100644 --- a/plugins/gtkui/gtkui.h +++ b/plugins/gtkui/gtkui.h @@ -86,4 +86,5 @@ playlist_refresh (void); void search_refresh (void); + #endif diff --git a/plugins/gtkui/interface.c b/plugins/gtkui/interface.c index 31af601c..e76bf963 100644 --- a/plugins/gtkui/interface.c +++ b/plugins/gtkui/interface.c @@ -531,6 +531,9 @@ create_mainwin (void) g_signal_connect ((gpointer) mainwin, "window_state_event", G_CALLBACK (on_mainwin_window_state_event), NULL); + g_signal_connect ((gpointer) mainwin, "realize", + G_CALLBACK (on_mainwin_realize), + NULL); g_signal_connect ((gpointer) open, "activate", G_CALLBACK (on_open_activate), NULL); @@ -1446,6 +1449,20 @@ create_prefwin (void) GtkWidget *label39; GtkWidget *vbox9; GtkWidget *pref_close_send_to_tray; + GtkWidget *frame3; + GtkWidget *alignment1; + GtkWidget *colors_table; + GtkWidget *color_light; + GtkWidget *color_mid; + GtkWidget *color_dark; + GtkWidget *color_selection; + GtkWidget *label43; + GtkWidget *label44; + GtkWidget *label45; + GtkWidget *label46; + GtkWidget *color_back; + GtkWidget *label47; + GtkWidget *override_theme_colors; GtkWidget *label2; GtkWidget *vbox11; GtkWidget *pref_network_enableproxy; @@ -1592,6 +1609,91 @@ create_prefwin (void) gtk_widget_show (pref_close_send_to_tray); gtk_box_pack_start (GTK_BOX (vbox9), pref_close_send_to_tray, FALSE, FALSE, 0); + frame3 = gtk_frame_new (NULL); + gtk_widget_show (frame3); + gtk_box_pack_start (GTK_BOX (vbox9), frame3, FALSE, TRUE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN); + + alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment1); + gtk_container_add (GTK_CONTAINER (frame3), alignment1); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 0, 0, 12, 0); + + colors_table = gtk_table_new (2, 5, FALSE); + gtk_widget_show (colors_table); + gtk_container_add (GTK_CONTAINER (alignment1), colors_table); + gtk_container_set_border_width (GTK_CONTAINER (colors_table), 12); + gtk_table_set_row_spacings (GTK_TABLE (colors_table), 8); + + color_light = gtk_color_button_new (); + gtk_widget_show (color_light); + gtk_table_attach (GTK_TABLE (colors_table), color_light, 3, 4, 1, 2, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + + color_mid = gtk_color_button_new (); + gtk_widget_show (color_mid); + gtk_table_attach (GTK_TABLE (colors_table), color_mid, 2, 3, 1, 2, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + + color_dark = gtk_color_button_new (); + gtk_widget_show (color_dark); + gtk_table_attach (GTK_TABLE (colors_table), color_dark, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + + color_selection = gtk_color_button_new (); + gtk_widget_show (color_selection); + gtk_table_attach (GTK_TABLE (colors_table), color_selection, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + + label43 = gtk_label_new ("Selection"); + gtk_widget_show (label43); + gtk_table_attach (GTK_TABLE (colors_table), label43, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label43), 0, 0.5); + + label44 = gtk_label_new ("Dark"); + gtk_widget_show (label44); + gtk_table_attach (GTK_TABLE (colors_table), label44, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label44), 0, 0.5); + + label45 = gtk_label_new ("Middle"); + gtk_widget_show (label45); + gtk_table_attach (GTK_TABLE (colors_table), label45, 2, 3, 0, 1, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label45), 0, 0.5); + + label46 = gtk_label_new ("Light"); + gtk_widget_show (label46); + gtk_table_attach (GTK_TABLE (colors_table), label46, 3, 4, 0, 1, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label46), 0, 0.5); + + color_back = gtk_color_button_new (); + gtk_widget_show (color_back); + gtk_table_attach (GTK_TABLE (colors_table), color_back, 4, 5, 1, 2, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + + label47 = gtk_label_new ("Background"); + gtk_widget_show (label47); + gtk_table_attach (GTK_TABLE (colors_table), label47, 4, 5, 0, 1, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label47), 0, 0.5); + + override_theme_colors = gtk_check_button_new_with_mnemonic ("Override GTK+ theme colors in custom widgets"); + gtk_widget_show (override_theme_colors); + gtk_frame_set_label_widget (GTK_FRAME (frame3), override_theme_colors); + label2 = gtk_label_new ("GUI"); gtk_widget_show (label2); gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 2), label2); @@ -1775,6 +1877,24 @@ create_prefwin (void) g_signal_connect ((gpointer) pref_close_send_to_tray, "clicked", G_CALLBACK (on_pref_close_send_to_tray_clicked), NULL); + g_signal_connect ((gpointer) color_light, "color_set", + G_CALLBACK (on_color_light_color_set), + NULL); + g_signal_connect ((gpointer) color_mid, "color_set", + G_CALLBACK (on_color_mid_color_set), + NULL); + g_signal_connect ((gpointer) color_dark, "color_set", + G_CALLBACK (on_color_dark_color_set), + NULL); + g_signal_connect ((gpointer) color_selection, "color_set", + G_CALLBACK (on_color_selection_color_set), + NULL); + g_signal_connect ((gpointer) color_back, "color_set", + G_CALLBACK (on_color_back_color_set), + NULL); + g_signal_connect ((gpointer) override_theme_colors, "toggled", + G_CALLBACK (on_override_gtk_colors_toggled), + NULL); g_signal_connect ((gpointer) pref_network_enableproxy, "clicked", G_CALLBACK (on_pref_network_enableproxy_clicked), NULL); @@ -1818,6 +1938,20 @@ create_prefwin (void) GLADE_HOOKUP_OBJECT (prefwin, label39, "label39"); GLADE_HOOKUP_OBJECT (prefwin, vbox9, "vbox9"); GLADE_HOOKUP_OBJECT (prefwin, pref_close_send_to_tray, "pref_close_send_to_tray"); + GLADE_HOOKUP_OBJECT (prefwin, frame3, "frame3"); + GLADE_HOOKUP_OBJECT (prefwin, alignment1, "alignment1"); + GLADE_HOOKUP_OBJECT (prefwin, colors_table, "colors_table"); + GLADE_HOOKUP_OBJECT (prefwin, color_light, "color_light"); + GLADE_HOOKUP_OBJECT (prefwin, color_mid, "color_mid"); + GLADE_HOOKUP_OBJECT (prefwin, color_dark, "color_dark"); + GLADE_HOOKUP_OBJECT (prefwin, color_selection, "color_selection"); + GLADE_HOOKUP_OBJECT (prefwin, label43, "label43"); + GLADE_HOOKUP_OBJECT (prefwin, label44, "label44"); + GLADE_HOOKUP_OBJECT (prefwin, label45, "label45"); + GLADE_HOOKUP_OBJECT (prefwin, label46, "label46"); + GLADE_HOOKUP_OBJECT (prefwin, color_back, "color_back"); + GLADE_HOOKUP_OBJECT (prefwin, label47, "label47"); + GLADE_HOOKUP_OBJECT (prefwin, override_theme_colors, "override_theme_colors"); GLADE_HOOKUP_OBJECT (prefwin, label2, "label2"); GLADE_HOOKUP_OBJECT (prefwin, vbox11, "vbox11"); GLADE_HOOKUP_OBJECT (prefwin, pref_network_enableproxy, "pref_network_enableproxy"); diff --git a/plugins/gtkui/mainplaylist.c b/plugins/gtkui/mainplaylist.c index 97b4de18..d5d7ee99 100644 --- a/plugins/gtkui/mainplaylist.c +++ b/plugins/gtkui/mainplaylist.c @@ -35,9 +35,9 @@ #define min(x,y) ((x)<(y)?(x):(y)) -uintptr_t play16_pixbuf; -uintptr_t pause16_pixbuf; -uintptr_t buffering16_pixbuf; +GdkPixbuf *play16_pixbuf; +GdkPixbuf *pause16_pixbuf; +GdkPixbuf *buffering16_pixbuf; // HACK!! extern GtkWidget *theme_treeview; @@ -254,9 +254,9 @@ DdbListviewBinding main_binding = { void main_playlist_init (GtkWidget *widget) { - play16_pixbuf = draw_load_pixbuf ("play_16.png"); - pause16_pixbuf = draw_load_pixbuf ("pause_16.png"); - buffering16_pixbuf = draw_load_pixbuf ("buffering_16.png"); + play16_pixbuf = create_pixbuf ("play_16.png"); + pause16_pixbuf = create_pixbuf ("pause_16.png"); + buffering16_pixbuf = create_pixbuf ("buffering_16.png"); // make listview widget and bind it to data DdbListview *listview = DDB_LISTVIEW(widget); diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c index ac5986f8..e55bad28 100644 --- a/plugins/gtkui/plcommon.c +++ b/plugins/gtkui/plcommon.c @@ -33,9 +33,9 @@ #define trace(fmt,...) extern GtkWidget *theme_treeview; -extern uintptr_t play16_pixbuf; -extern uintptr_t pause16_pixbuf; -extern uintptr_t buffering16_pixbuf; +extern GdkPixbuf *play16_pixbuf; +extern GdkPixbuf *pause16_pixbuf; +extern GdkPixbuf *buffering16_pixbuf; void write_column_config (const char *name, int idx, const char *title, int width, int align_right, int id, const char *format) { @@ -116,7 +116,7 @@ void draw_column_data (DdbListview *listview, GdkDrawable *drawable, DdbListview else if (it && it == deadbeef->streamer_get_playing_track () && cinf->id == DB_COLUMN_PLAYING) { int paused = deadbeef->get_output ()->state () == OUTPUT_STATE_PAUSED; int buffering = !deadbeef->streamer_ok_to_read (-1); - uintptr_t pixbuf; + GdkPixbuf *pixbuf; if (paused) { pixbuf = pause16_pixbuf; } @@ -126,7 +126,7 @@ void draw_column_data (DdbListview *listview, GdkDrawable *drawable, DdbListview else { pixbuf = buffering16_pixbuf; } - draw_pixbuf ((uintptr_t)drawable, pixbuf, x + cwidth/2 - 8, y + height/2 - 8, 0, 0, 16, 16); + gdk_pixbuf_render_to_drawable (pixbuf, drawable, GTK_WIDGET (listview)->style->black_gc, 0, 0, x + cwidth/2 - 8, y + height/2 - 8, 16, 16, GDK_RGB_DITHER_NONE, 0, 0); } else if (it) { char text[1024]; diff --git a/plugins/gtkui/prefwin.c b/plugins/gtkui/prefwin.c new file mode 100644 index 00000000..c1515fa8 --- /dev/null +++ b/plugins/gtkui/prefwin.c @@ -0,0 +1,498 @@ +/* + DeaDBeeF - ultimate music player for GNU/Linux systems with X11 + Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#include <gtk/gtk.h> +#include <string.h> +#include <assert.h> +#include "gtkui.h" +#include "support.h" +#include "interface.h" +#include "callbacks.h" + +static GtkWidget *prefwin; + +static char alsa_device_names[100][64]; +static int num_alsa_devices; + +static void +gtk_enum_sound_callback (const char *name, const char *desc, void *userdata) { + if (num_alsa_devices >= 100) { + fprintf (stderr, "wtf!! more than 100 alsa devices??\n"); + return; + } + GtkComboBox *combobox = GTK_COMBO_BOX (userdata); + gtk_combo_box_append_text (combobox, desc); + + if (!strcmp (deadbeef->conf_get_str ("alsa_soundcard", "default"), name)) { + gtk_combo_box_set_active (combobox, num_alsa_devices); + } + + strncpy (alsa_device_names[num_alsa_devices], name, 63); + alsa_device_names[num_alsa_devices][63] = 0; + num_alsa_devices++; +} + +void +on_plugin_active_toggled (GtkCellRendererToggle *cell_renderer, gchar *path, GtkTreeModel *model) { + GtkTreePath *p = gtk_tree_path_new_from_string (path); + if (p) { + int *indices = gtk_tree_path_get_indices (p); + //gtk_tree_path_free (p); // wtf?? gtk crashes on this + if (indices) { + DB_plugin_t **plugins = deadbeef->plug_get_list (); + DB_plugin_t *plug = plugins[*indices]; + gboolean state; + GtkTreeIter iter; + gtk_tree_model_get_iter (model, &iter, p); + gtk_tree_model_get (model, &iter, 0, &state, -1); + if (!deadbeef->plug_activate (plug, !state)) { + gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, !state, -1); + } + } + g_free (indices); + } +} + +void +preferences_fill_soundcards (void) { + if (!prefwin) { + return; + } + const char *s = deadbeef->conf_get_str ("alsa_soundcard", "default"); + GtkComboBox *combobox = GTK_COMBO_BOX (lookup_widget (prefwin, "pref_soundcard")); + GtkTreeModel *mdl = gtk_combo_box_get_model (combobox); + gtk_list_store_clear (GTK_LIST_STORE (mdl)); + + gtk_combo_box_append_text (combobox, "Default Audio Device"); + if (!strcmp (s, "default")) { + gtk_combo_box_set_active (combobox, 0); + } + num_alsa_devices = 1; + strcpy (alsa_device_names[0], "default"); + if (deadbeef->get_output ()->enum_soundcards) { + deadbeef->get_output ()->enum_soundcards (gtk_enum_sound_callback, combobox); + gtk_widget_set_sensitive (GTK_WIDGET (combobox), TRUE); + } + else { + gtk_widget_set_sensitive (GTK_WIDGET (combobox), FALSE); + } +} + +void +on_preferences_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + if (prefwin) { + return; + } + GtkWidget *w = prefwin = create_prefwin (); + gtk_window_set_transient_for (GTK_WINDOW (w), GTK_WINDOW (mainwin)); + + GtkComboBox *combobox = NULL; + + // output plugin selection + const char *outplugname = deadbeef->conf_get_str ("output_plugin", "ALSA output plugin"); + combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_output_plugin")); + + DB_output_t **out_plugs = deadbeef->plug_get_output_list (); + for (int i = 0; out_plugs[i]; i++) { + gtk_combo_box_append_text (combobox, out_plugs[i]->plugin.name); + if (!strcmp (outplugname, out_plugs[i]->plugin.name)) { + gtk_combo_box_set_active (combobox, i); + } + } + + // soundcard (output device) selection + preferences_fill_soundcards (); + + g_signal_connect ((gpointer) combobox, "changed", + G_CALLBACK (on_pref_output_plugin_changed), + NULL); + GtkWidget *pref_soundcard = lookup_widget (prefwin, "pref_soundcard"); + g_signal_connect ((gpointer) pref_soundcard, "changed", + G_CALLBACK (on_pref_soundcard_changed), + NULL); + + // alsa resampling + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_dynsamplerate")), deadbeef->conf_get_int ("playback.dynsamplerate", 0)); + + // src_quality + combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_src_quality")); + gtk_combo_box_set_active (combobox, deadbeef->conf_get_int ("src_quality", 2)); + + // replaygain_mode + combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_replaygain_mode")); + gtk_combo_box_set_active (combobox, deadbeef->conf_get_int ("replaygain_mode", 0)); + + // replaygain_scale + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_replaygain_scale")), deadbeef->conf_get_int ("replaygain_scale", 1)); + + // close_send_to_tray + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_close_send_to_tray")), deadbeef->conf_get_int ("close_send_to_tray", 0)); + + // override colors + int override = deadbeef->conf_get_int ("gtkui.override_theme_colors", 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "override_theme_colors")), override); + gtk_widget_set_sensitive (lookup_widget (prefwin, "colors_table"), override); + char color_selection[100]; + char color_dark[100]; + char color_mid[100]; + char color_light[100]; + char color_back[100]; + + extern GtkWidget *mainwin; + GtkStyle *style = mainwin->style; + + const char *clr; + GtkWidget *clr_widget; + GdkColor gdk_clr; + memset (&gdk_clr, 0, sizeof (gdk_clr)); + + snprintf (color_selection, sizeof (color_selection), "%d %d %d", style->base[GTK_STATE_SELECTED].red, style->base[GTK_STATE_SELECTED].green, style->base[GTK_STATE_SELECTED].blue); + clr = deadbeef->conf_get_str ("gtkui.color.selection", color_selection); + sscanf (clr, "%d %d %d", &gdk_clr.red, &gdk_clr.green, &gdk_clr.blue); + clr_widget = lookup_widget (prefwin, "color_selection"); + gtk_color_button_set_color (GTK_COLOR_BUTTON (clr_widget), &gdk_clr); + + snprintf (color_dark, sizeof (color_dark), "%d %d %d", style->dark[GTK_STATE_NORMAL].red, style->dark[GTK_STATE_NORMAL].green, style->dark[GTK_STATE_NORMAL].blue); + clr = deadbeef->conf_get_str ("gtkui.color.dark", color_dark); + sscanf (clr, "%d %d %d", &gdk_clr.red, &gdk_clr.green, &gdk_clr.blue); + clr_widget = lookup_widget (prefwin, "color_dark"); + gtk_color_button_set_color (GTK_COLOR_BUTTON (clr_widget), &gdk_clr); + + snprintf (color_mid, sizeof (color_mid), "%d %d %d", style->mid[GTK_STATE_NORMAL].red, style->mid[GTK_STATE_NORMAL].green, style->mid[GTK_STATE_NORMAL].blue); + clr = deadbeef->conf_get_str ("gtkui.color.mid", color_mid); + sscanf (clr, "%d %d %d", &gdk_clr.red, &gdk_clr.green, &gdk_clr.blue); + clr_widget = lookup_widget (prefwin, "color_mid"); + gtk_color_button_set_color (GTK_COLOR_BUTTON (clr_widget), &gdk_clr); + + snprintf (color_light, sizeof (color_light), "%d %d %d", style->light[GTK_STATE_NORMAL].red, style->light[GTK_STATE_NORMAL].green, style->light[GTK_STATE_NORMAL].blue); + clr = deadbeef->conf_get_str ("gtkui.color.light", color_light); + sscanf (clr, "%d %d %d", &gdk_clr.red, &gdk_clr.green, &gdk_clr.blue); + clr_widget = lookup_widget (prefwin, "color_light"); + gtk_color_button_set_color (GTK_COLOR_BUTTON (clr_widget), &gdk_clr); + + snprintf (color_back, sizeof (color_back), "%d %d %d", style->fg[GTK_STATE_NORMAL].red, style->fg[GTK_STATE_NORMAL].green, style->fg[GTK_STATE_NORMAL].blue); + clr = deadbeef->conf_get_str ("gtkui.color.back", color_back); + sscanf (clr, "%d %d %d", &gdk_clr.red, &gdk_clr.green, &gdk_clr.blue); + clr_widget = lookup_widget (prefwin, "color_back"); + gtk_color_button_set_color (GTK_COLOR_BUTTON (clr_widget), &gdk_clr); + + // network + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_network_enableproxy")), deadbeef->conf_get_int ("network.proxy", 0)); + gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "pref_network_proxyaddress")), deadbeef->conf_get_str ("network.proxy.address", "")); + gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "pref_network_proxyport")), deadbeef->conf_get_str ("network.proxy.port", "8080")); + combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_network_proxytype")); + const char *type = deadbeef->conf_get_str ("network.proxy.type", "HTTP"); + if (!strcasecmp (type, "HTTP")) { + gtk_combo_box_set_active (combobox, 0); + } + else if (!strcasecmp (type, "HTTP_1_0")) { + gtk_combo_box_set_active (combobox, 1); + } + else if (!strcasecmp (type, "SOCKS4")) { + gtk_combo_box_set_active (combobox, 2); + } + else if (!strcasecmp (type, "SOCKS5")) { + gtk_combo_box_set_active (combobox, 3); + } + else if (!strcasecmp (type, "SOCKS4A")) { + gtk_combo_box_set_active (combobox, 4); + } + else if (!strcasecmp (type, "SOCKS5_HOSTNAME")) { + gtk_combo_box_set_active (combobox, 5); + } + + // list of plugins + GtkTreeView *tree = GTK_TREE_VIEW (lookup_widget (w, "pref_pluginlist")); + GtkCellRenderer *rend_text = gtk_cell_renderer_text_new (); +#if 0 + GtkCellRenderer *rend_toggle = gtk_cell_renderer_toggle_new (); + GtkListStore *store = gtk_list_store_new (3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_BOOLEAN); + g_signal_connect ((gpointer)rend_toggle, "toggled", + G_CALLBACK (on_plugin_active_toggled), + store); + GtkTreeViewColumn *col1 = gtk_tree_view_column_new_with_attributes ("Active", rend_toggle, "active", 0, "activatable", 2, NULL); + GtkTreeViewColumn *col2 = gtk_tree_view_column_new_with_attributes ("Title", rend_text, "text", 1, NULL); + gtk_tree_view_append_column (tree, col1); + gtk_tree_view_append_column (tree, col2); + DB_plugin_t **plugins = deadbeef->plug_get_list (); + int i; + for (i = 0; plugins[i]; i++) { + GtkTreeIter it; + gtk_list_store_append (store, &it); + gtk_list_store_set (store, &it, 0, plugins[i]->inactive ? FALSE : TRUE, 1, plugins[i]->name, 2, plugins[i]->nostop ? FALSE : TRUE, -1); + } +#else + GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); + GtkTreeViewColumn *col2 = gtk_tree_view_column_new_with_attributes ("Title", rend_text, "text", 0, NULL); + gtk_tree_view_append_column (tree, col2); + DB_plugin_t **plugins = deadbeef->plug_get_list (); + int i; + for (i = 0; plugins[i]; i++) { + GtkTreeIter it; + gtk_list_store_append (store, &it); + gtk_list_store_set (store, &it, 0, plugins[i]->name, -1); + } +#endif + gtk_tree_view_set_model (tree, GTK_TREE_MODEL (store)); + + gtk_widget_set_sensitive (lookup_widget (prefwin, "configure_plugin"), FALSE); +// gtk_widget_show (w); + gtk_dialog_run (GTK_DIALOG (prefwin)); + gtk_widget_destroy (prefwin); + prefwin = NULL; +} + + +void +on_pref_soundcard_changed (GtkComboBox *combobox, + gpointer user_data) +{ + int active = gtk_combo_box_get_active (combobox); + if (active >= 0 && active < num_alsa_devices) { + const char *soundcard = deadbeef->conf_get_str ("alsa_soundcard", "default"); + if (strcmp (soundcard, alsa_device_names[active])) { + deadbeef->conf_set_str ("alsa_soundcard", alsa_device_names[active]); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); + } + } +} + +void +on_pref_output_plugin_changed (GtkComboBox *combobox, + gpointer user_data) +{ + const char *outplugname = deadbeef->conf_get_str ("output_plugin", "ALSA output plugin"); + int active = gtk_combo_box_get_active (combobox); + + DB_output_t **out_plugs = deadbeef->plug_get_output_list (); + DB_output_t *prev = NULL; + DB_output_t *new = NULL; + + for (int i = 0; out_plugs[i]; i++) { + if (!strcmp (out_plugs[i]->plugin.name, outplugname)) { + prev = out_plugs[i]; + } + if (i == active) { + new = out_plugs[i]; + } + } + + if (!new) { + fprintf (stderr, "failed to find output plugin selected in preferences window\n"); + } + else { + if (prev != new) { + deadbeef->conf_set_str ("output_plugin", new->plugin.name); + deadbeef->sendmessage (M_REINIT_SOUND, 0, 0, 0); + } + } +} + +void +on_pref_dynsamplerate_clicked (GtkButton *button, + gpointer user_data) +{ + int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + deadbeef->conf_set_int ("playback.dynsamplerate", active); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); +} + + +void +on_pref_src_quality_changed (GtkComboBox *combobox, + gpointer user_data) +{ + int active = gtk_combo_box_get_active (combobox); + deadbeef->conf_set_int ("src_quality", active == -1 ? 2 : active); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); +} + + +void +on_pref_replaygain_mode_changed (GtkComboBox *combobox, + gpointer user_data) +{ + int active = gtk_combo_box_get_active (combobox); + deadbeef->conf_set_int ("replaygain_mode", active == -1 ? 0 : active); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); +} + +void +on_pref_replaygain_scale_clicked (GtkButton *button, + gpointer user_data) +{ + int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + deadbeef->conf_set_int ("replaygain_scale", active); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); +} + + +void +on_pref_close_send_to_tray_clicked (GtkButton *button, + gpointer user_data) +{ + int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + deadbeef->conf_set_int ("close_send_to_tray", active); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); +} + +void +on_pref_pluginlist_cursor_changed (GtkTreeView *treeview, + gpointer user_data) +{ + GtkTreePath *path; + GtkTreeViewColumn *col; + gtk_tree_view_get_cursor (treeview, &path, &col); + if (!path || !col) { + // reset + return; + } + int *indices = gtk_tree_path_get_indices (path); + DB_plugin_t **plugins = deadbeef->plug_get_list (); + DB_plugin_t *p = plugins[*indices]; + g_free (indices); + assert (p); + GtkWidget *w = prefwin;//GTK_WIDGET (gtk_widget_get_parent_window (GTK_WIDGET (treeview))); + assert (w); + GtkEntry *e = GTK_ENTRY (lookup_widget (w, "pref_plugin_descr")); + gtk_entry_set_text (e, p->descr ? p->descr : ""); + e = GTK_ENTRY (lookup_widget (w, "pref_plugin_author")); + gtk_entry_set_text (e, p->author ? p->author : ""); + e = GTK_ENTRY (lookup_widget (w, "pref_plugin_email")); + gtk_entry_set_text (e, p->email ? p->email : ""); + e = GTK_ENTRY (lookup_widget (w, "pref_plugin_website")); + gtk_entry_set_text (e, p->website ? p->website : ""); + + gtk_widget_set_sensitive (lookup_widget (prefwin, "configure_plugin"), p->configdialog ? TRUE : FALSE); +} + +gboolean +on_prefwin_delete_event (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + prefwin = NULL; + return FALSE; +} + +void +on_pref_close_clicked (GtkButton *button, + gpointer user_data) +{ + gtk_widget_hide (prefwin); + gtk_widget_destroy (prefwin); +} + +void +on_configure_plugin_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *w = prefwin; + GtkTreeView *treeview = GTK_TREE_VIEW (lookup_widget (w, "pref_pluginlist")); + GtkTreePath *path; + GtkTreeViewColumn *col; + gtk_tree_view_get_cursor (treeview, &path, &col); + if (!path || !col) { + // reset + return; + } + int *indices = gtk_tree_path_get_indices (path); + DB_plugin_t **plugins = deadbeef->plug_get_list (); + DB_plugin_t *p = plugins[*indices]; + if (p->configdialog) { + plugin_configure (prefwin, p); + } +} + +void +on_color_light_color_set (GtkColorButton *colorbutton, + gpointer user_data) +{ + GdkColor clr; + gtk_color_button_get_color (colorbutton, &clr); + char str[100]; + snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue); + deadbeef->conf_set_str ("gtkui.color.light", str); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); +} + + +void +on_color_mid_color_set (GtkColorButton *colorbutton, + gpointer user_data) +{ + GdkColor clr; + gtk_color_button_get_color (colorbutton, &clr); + char str[100]; + snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue); + deadbeef->conf_set_str ("gtkui.color.mid", str); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); +} + + +void +on_color_dark_color_set (GtkColorButton *colorbutton, + gpointer user_data) +{ + GdkColor clr; + gtk_color_button_get_color (colorbutton, &clr); + char str[100]; + snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue); + deadbeef->conf_set_str ("gtkui.color.dark", str); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); +} + + +void +on_color_selection_color_set (GtkColorButton *colorbutton, + gpointer user_data) +{ + GdkColor clr; + gtk_color_button_get_color (colorbutton, &clr); + char str[100]; + snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue); + deadbeef->conf_set_str ("gtkui.color.selection", str); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); + +} + + +void +on_color_back_color_set (GtkColorButton *colorbutton, + gpointer user_data) +{ + GdkColor clr; + gtk_color_button_get_color (colorbutton, &clr); + char str[100]; + snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue); + deadbeef->conf_set_str ("gtkui.color.back", str); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); +} + +void +on_override_gtk_colors_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + int active = gtk_toggle_button_get_active (togglebutton); + deadbeef->conf_set_int ("gtkui.override_theme_colors", active); + gtk_widget_set_sensitive (lookup_widget (prefwin, "colors_table"), active); + deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); +} + |