commit 37e584fc99e2a697e8d85845a067caab003540b6 Author: phantomjinx <p.g.richard...@phantomjinx.co.uk> Date: Sat Aug 27 13:00:59 2011 +0100
Implement clarity preferences * Preferences for changing background colour and artwork sorting * album_model.* * Narrowing of API and tidy up * Implementation of sort functions * clarity_canvas.* * loading_complete field introduced for stopping other signal handlers firing before the animation has completed. plugins/clarity/Makefile.am | 1 + plugins/clarity/album_model.c | 248 ++++++++++++++++++++------------- plugins/clarity/album_model.h | 11 +- plugins/clarity/clarity.xml | 38 +++--- plugins/clarity/clarity_canvas.c | 34 ++++- plugins/clarity/clarity_canvas.h | 4 +- plugins/clarity/clarity_preferences.c | 49 ++++--- plugins/clarity/clarity_preferences.h | 4 +- plugins/clarity/clarity_widget.c | 76 ++++++++--- plugins/clarity/clarity_widget.h | 6 +- plugins/clarity/plugin.c | 82 ++++++----- plugins/clarity/plugin.h | 2 + 12 files changed, 353 insertions(+), 202 deletions(-) --- diff --git a/plugins/clarity/Makefile.am b/plugins/clarity/Makefile.am index 4b0fd01..c623eda 100644 --- a/plugins/clarity/Makefile.am +++ b/plugins/clarity/Makefile.am @@ -35,6 +35,7 @@ libclarity_la_SOURCES = plugin.c plugin.h \ clarity_widget.c clarity_widget.h \ clarity_preview.c clarity_preview.h \ clarity_utils.c clarity_utils.h \ + clarity_preferences.c clarity_preferences.h \ clarity_context_menu.c clarity_context_menu.h \ fetchcover.c fetchcover.h libclarity_la_CFLAGS = $(CLUTTER_GTK_CFLAGS) diff --git a/plugins/clarity/album_model.c b/plugins/clarity/album_model.c index e09ec96..6db251c 100644 --- a/plugins/clarity/album_model.c +++ b/plugins/clarity/album_model.c @@ -32,6 +32,7 @@ #include "album_model.h" #include "libgtkpod/prefs.h" #include "libgtkpod/misc.h" +#include "libgtkpod/gp_private.h" G_DEFINE_TYPE( AlbumModel, album_model, G_TYPE_OBJECT); @@ -42,10 +43,103 @@ struct _AlbumModelPrivate { GHashTable *album_hash; GList *album_key_list; - - gint loaded; }; +static gchar *_create_key(Track *track) { + g_return_val_if_fail(track, ""); + + return g_strconcat(track->artist, "_", track->album, NULL); +} + +static void _add_track_to_album_item(AlbumItem *item, Track *track) { + item->tracks = g_list_prepend(item->tracks, track); +} + +static AlbumItem *_create_album_item(Track *track) { + AlbumItem *item = NULL; + + /* Album item not found so create a new one and populate */ + item = g_new0 (AlbumItem, 1); + item->albumart = NULL; + item->albumname = g_strdup(track->album); + item->artist = g_strdup(track->artist); + item->tracks = NULL; + _add_track_to_album_item(item, track); + + return item; +} + +/** + * compare_album_keys: + * + * Comparison function for comparing keys in + * the key list to sort them into alphabetical order. + * Could use g_ascii_strcasecmp directly but the NULL + * strings cause assertion errors. + * + * @a: first album key to compare + * @b: second album key to compare + * + */ +static gint _compare_album_item_keys(gchar *a, gchar *b) { + if (a == NULL) + return -1; + if (b == NULL) + return -1; + + return compare_string(a, b, prefs_get_int("clarity_case_sensitive")); +} + +void _index_album_item(AlbumModelPrivate *priv, gchar *album_key, AlbumItem *item) { + enum GtkPodSortTypes value = prefs_get_int("clarity_sort"); + + g_hash_table_insert(priv->album_hash, album_key, item); + + switch(value) { + case SORT_ASCENDING: + priv->album_key_list = g_list_insert_sorted(priv->album_key_list, album_key, (GCompareFunc) _compare_album_item_keys); + break; + case SORT_DESCENDING: + /* Already in descending order so reverse into ascending order */ + priv->album_key_list = g_list_reverse(priv->album_key_list); + /* Insert the track */ + priv->album_key_list = g_list_insert_sorted(priv->album_key_list, album_key, (GCompareFunc) _compare_album_item_keys); + /* Reverse again */ + priv->album_key_list = g_list_reverse(priv->album_key_list); + break; + default: + /* NO SORT */ + + // Quicker to reverse, prepend then reverse back + priv->album_key_list = g_list_reverse(priv->album_key_list); + priv->album_key_list = g_list_prepend(priv->album_key_list, album_key); + priv->album_key_list = g_list_reverse(priv->album_key_list); + break; + } +} + +static void _insert_track(AlbumModelPrivate *priv, Track *track) { + AlbumItem *item; + gchar *album_key; + + album_key = _create_key(track); + /* Check whether an album item has already been created in connection + * with the track's artist and album + */ + item = g_hash_table_lookup(priv->album_hash, album_key); + if (!item) { + // Create new album item + item = _create_album_item(track); + _index_album_item(priv, album_key, item); + } + else { + /* Album Item found in the album hash so prepend the + * track to the start of the track list */ + g_free(album_key); + _add_track_to_album_item(item, track); + } +} + /** * * clarity_widget_free_album: @@ -53,24 +147,26 @@ struct _AlbumModelPrivate { * Destroy an album struct once no longer needed. * */ -static void album_model_free_album(AlbumItem *album) { - if (album != NULL) { - if (album->tracks) { - g_list_free(album->tracks); +static void album_model_free_album_item(AlbumItem *item) { + if (item) { + if (item->tracks) { + g_list_free(item->tracks); } + item->tracks = NULL; + + g_free(item->albumname); + g_free(item->artist); - g_free(album->albumname); - g_free(album->artist); + if (item->albumart) + g_object_unref(item->albumart); - if (album->albumart) - g_object_unref(album->albumart); + item->data = NULL; } } static void album_model_finalize(GObject *gobject) { AlbumModelPrivate *priv = ALBUM_MODEL_GET_PRIVATE(gobject); - priv->album_key_list = g_list_remove_all(priv->album_key_list, NULL); g_hash_table_foreach_remove(priv->album_hash, (GHRFunc) gtk_true, NULL); g_hash_table_destroy(priv->album_hash); g_list_free(priv->album_key_list); @@ -92,9 +188,8 @@ static void album_model_init (AlbumModel *self) { AlbumModelPrivate *priv; priv = ALBUM_MODEL_GET_PRIVATE (self); - priv->album_hash = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) album_model_free_album); + priv->album_hash = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) album_model_free_album_item); priv->album_key_list = NULL; - priv->loaded = 0; } @@ -112,64 +207,49 @@ void album_model_clear(AlbumModel *model) { priv = ALBUM_MODEL_GET_PRIVATE (model); g_hash_table_remove_all (priv->album_hash); - g_list_free(priv->album_key_list); - priv->album_key_list = NULL; -} - -static gchar *_create_key(Track *track) { - g_return_val_if_fail(track, ""); - - return g_strconcat(track->artist, "_", track->album, NULL); + if (priv->album_key_list) { + g_list_free(priv->album_key_list); + priv->album_key_list = NULL; + } } -void album_model_add_track(AlbumModel *model, Track *track) { - AlbumItem *album; - gchar *album_key; - AlbumModelPrivate *priv; - - priv = ALBUM_MODEL_GET_PRIVATE (model); - album_key = _create_key(track); - /* Check whether an album item has already been created in connection - * with the track's artist and album - */ - album = g_hash_table_lookup(priv->album_hash, album_key); - if (album == NULL) { - /* Album item not found so create a new one and populate */ - album = g_new0 (AlbumItem, 1); - album->albumart = NULL; - album->albumname = g_strdup(track->album); - album->artist = g_strdup(track->artist); - album->tracks = NULL; - album->tracks = g_list_prepend(album->tracks, track); - - /* Insert the new Album Item into the hash */ - g_hash_table_insert(priv->album_hash, album_key, album); - /* Add the key to the list for sorting and other functions */ - priv->album_key_list = g_list_prepend(priv->album_key_list, album_key); - } - else { - /* Album Item found in the album hash so - * append the track to the end of the - * track list */ - g_free(album_key); - album->tracks = g_list_prepend(album->tracks, track); +void album_model_resort(AlbumModel *model, GList *tracks) { + AlbumModelPrivate *priv = ALBUM_MODEL_GET_PRIVATE (model); + enum GtkPodSortTypes value = prefs_get_int("clarity_sort"); + + switch (value) { + case SORT_ASCENDING: + priv->album_key_list = g_list_sort(priv->album_key_list, (GCompareFunc) _compare_album_item_keys); + break; + case SORT_DESCENDING: + priv->album_key_list = g_list_sort(priv->album_key_list, (GCompareFunc) _compare_album_item_keys); + priv->album_key_list = g_list_reverse(priv->album_key_list); + break; + default: + // No sorting needs to re-initialise the model from scratch + album_model_clear(model); + album_model_add_tracks(model, tracks); + break; } } -void album_model_reset_loaded_index(AlbumModel *model) { +void album_model_add_tracks(AlbumModel *model, GList *tracks) { g_return_if_fail(model); - AlbumModelPrivate *priv; - priv = ALBUM_MODEL_GET_PRIVATE (model); - priv->loaded = 0; + AlbumModelPrivate *priv = ALBUM_MODEL_GET_PRIVATE(model); + GList *trks = tracks; + while(trks) { + Track *track = trks->data; + _insert_track(priv, track); + trks = trks->next; + } } void album_model_foreach (AlbumModel *model, GFunc func, gpointer user_data) { g_return_if_fail(model); g_return_if_fail(func); - AlbumModelPrivate *priv; - priv = ALBUM_MODEL_GET_PRIVATE (model); + AlbumModelPrivate *priv = ALBUM_MODEL_GET_PRIVATE (model); GList *iter = priv->album_key_list; while(iter) { @@ -182,61 +262,39 @@ void album_model_foreach (AlbumModel *model, GFunc func, gpointer user_data) { } } - -gint album_model_get_size(AlbumModel *model) { - g_return_val_if_fail(model, 0); - - AlbumModelPrivate *priv; - priv = ALBUM_MODEL_GET_PRIVATE (model); - - return g_list_length(priv->album_key_list); -} - AlbumItem *album_model_get_item(AlbumModel *model, gint index) { g_return_val_if_fail(model, NULL); - AlbumModelPrivate *priv; - priv = ALBUM_MODEL_GET_PRIVATE (model); + AlbumModelPrivate *priv = ALBUM_MODEL_GET_PRIVATE (model); gchar *key = g_list_nth_data(priv->album_key_list, index); return g_hash_table_lookup(priv->album_hash, key); } -/** - * compare_album_keys: - * - * Comparison function for comparing keys in - * the key list to sort them into alphabetical order. - * Could use g_ascii_strcasecmp directly but the NULL - * strings cause assertion errors. - * - * @a: first album key to compare - * @b: second album key to compare - * - */ -static gint _compare_album_keys(gchar *a, gchar *b) { - if (a == NULL) - return -1; - if (b == NULL) - return -1; - - return compare_string(a, b, prefs_get_int("cad_case_sensitive")); -} - gint album_model_get_index(AlbumModel *model, Track *track) { g_return_val_if_fail(model, -1); - AlbumModelPrivate *priv; - priv = ALBUM_MODEL_GET_PRIVATE (model); + AlbumModelPrivate *priv = ALBUM_MODEL_GET_PRIVATE (model); gchar *trk_key = _create_key(track); - GList *key = g_list_find_custom(priv->album_key_list, trk_key, (GCompareFunc) _compare_album_keys); + GList *key_list = priv->album_key_list; + + GList *key = g_list_find_custom(key_list, trk_key, (GCompareFunc) _compare_album_item_keys); g_return_val_if_fail (key, -1); - gint index = g_list_position(priv->album_key_list, key); + gint index = g_list_position(key_list, key); g_free(trk_key); return index; } +gint album_model_get_size(AlbumModel *model) { + g_return_val_if_fail(model, 0); + + AlbumModelPrivate *priv; + priv = ALBUM_MODEL_GET_PRIVATE (model); + + return g_list_length(priv->album_key_list); +} + #endif /* ALBUM_MODEL_C_ */ diff --git a/plugins/clarity/album_model.h b/plugins/clarity/album_model.h index c8fd53e..2314f8f 100644 --- a/plugins/clarity/album_model.h +++ b/plugins/clarity/album_model.h @@ -83,16 +83,17 @@ void album_model_destroy(AlbumModel *model); void album_model_clear(AlbumModel *model); -void album_model_add_track(AlbumModel *model, Track *track); - -void album_model_reset_loaded_index(AlbumModel *model); - void album_model_foreach(AlbumModel *model, GFunc func, gpointer user_data); -gint album_model_get_size(AlbumModel *model); +void album_model_resort(AlbumModel *model, GList *tracks); + +void album_model_add_tracks(AlbumModel *model, GList *tracks); AlbumItem *album_model_get_item(AlbumModel *model, gint index); gint album_model_get_index(AlbumModel *model, Track *track); +gint album_model_get_size(AlbumModel *model); + + #endif /* ALBUM_MODEL_H_ */ diff --git a/plugins/clarity/clarity.xml b/plugins/clarity/clarity.xml index 063c0fe..349fa82 100644 --- a/plugins/clarity/clarity.xml +++ b/plugins/clarity/clarity.xml @@ -31,14 +31,15 @@ <property name="can_focus">False</property> <property name="spacing">12</property> <child> - <object class="GtkColorButton" id="coverart_display_bg_button"> + <object class="GtkColorButton" id="clarity_bg_button"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="use_action_appearance">False</property> - <property name="title" translatable="yes">Choose a Different Colour for the CoverArt Display Background</property> + <property name="use_alpha">True</property> + <property name="title" translatable="yes">Choose a Different Colour for the Clarity Background</property> <property name="color">#000000000000</property> - <signal name="color-set" handler="on_coverart_dialog_bg_color_set" swapped="no"/> + <signal name="color-set" handler="on_clarity_dialog_bg_color_set" swapped="no"/> </object> <packing> <property name="expand">False</property> @@ -59,14 +60,15 @@ </packing> </child> <child> - <object class="GtkColorButton" id="coverart_display_fg_button"> + <object class="GtkColorButton" id="clarity_fg_button"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="use_action_appearance">False</property> - <property name="title" translatable="yes">Choose a Different Colour for the CoverArt Display Background</property> + <property name="use_alpha">True</property> + <property name="title" translatable="yes">Choose a Different Colour for the Clarity Foreground</property> <property name="color">#ffffffffffff</property> - <signal name="color-set" handler="on_coverart_dialog_fg_color_set" swapped="no"/> + <signal name="color-set" handler="on_clarity_dialog_fg_color_set" swapped="no"/> </object> <packing> <property name="expand">False</property> @@ -94,7 +96,7 @@ <object class="GtkLabel" id="label18"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes"><b>Cover Art Display</b></property> + <property name="label" translatable="yes"><b>Clarity</b></property> <property name="use_markup">True</property> </object> </child> @@ -161,14 +163,14 @@ </packing> </child> <child> - <object class="GtkRadioButton" id="cad_ascend"> + <object class="GtkRadioButton" id="clarity_ascend"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="use_action_appearance">False</property> <property name="draw_indicator">True</property> - <property name="group">cad_none</property> - <signal name="toggled" handler="on_cad_ascend_toggled" swapped="no"/> + <property name="group">clarity_none</property> + <signal name="toggled" handler="on_clarity_ascend_toggled" swapped="no"/> <child> <object class="GtkImage" id="image1928"> <property name="visible">True</property> @@ -186,14 +188,14 @@ </packing> </child> <child> - <object class="GtkRadioButton" id="cad_descend"> + <object class="GtkRadioButton" id="clarity_descend"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="use_action_appearance">False</property> <property name="draw_indicator">True</property> - <property name="group">cad_none</property> - <signal name="toggled" handler="on_cad_descend_toggled" swapped="no"/> + <property name="group">clarity_none</property> + <signal name="toggled" handler="on_clarity_descend_toggled" swapped="no"/> <child> <object class="GtkImage" id="image1929"> <property name="visible">True</property> @@ -222,14 +224,14 @@ </packing> </child> <child> - <object class="GtkRadioButton" id="cad_none"> + <object class="GtkRadioButton" id="clarity_none"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="use_action_appearance">False</property> <property name="active">True</property> <property name="draw_indicator">True</property> - <signal name="toggled" handler="on_cad_none_toggled" swapped="no"/> + <signal name="toggled" handler="on_clarity_none_toggled" swapped="no"/> <child> <object class="GtkImage" id="image1930"> <property name="visible">True</property> @@ -259,7 +261,7 @@ </packing> </child> <child> - <object class="GtkCheckButton" id="cad_cfg_case_sensitive"> + <object class="GtkCheckButton" id="clarity_cfg_case_sensitive"> <property name="label" translatable="yes">Case sensitive sorting</property> <property name="visible">True</property> <property name="can_focus">True</property> @@ -267,7 +269,7 @@ <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> - <signal name="toggled" handler="on_cad_sort_case_sensitive_toggled" swapped="no"/> + <signal name="toggled" handler="on_clarity_sort_case_sensitive_toggled" swapped="no"/> </object> <packing> <property name="expand">False</property> @@ -300,7 +302,7 @@ <object class="GtkLabel" id="display_page_label"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes">Cover Art Display</property> + <property name="label" translatable="yes">Clarity</property> </object> <packing> <property name="tab_fill">False</property> diff --git a/plugins/clarity/clarity_canvas.c b/plugins/clarity/clarity_canvas.c index f95d2cc..970b876 100644 --- a/plugins/clarity/clarity_canvas.c +++ b/plugins/clarity/clarity_canvas.c @@ -60,6 +60,8 @@ struct _ClarityCanvasPrivate { gint curr_index; gulong preview_signal; + + gboolean loading_complete; }; enum DIRECTION { @@ -171,6 +173,7 @@ static void clarity_canvas_init(ClarityCanvas *self) { priv->timeline = clutter_timeline_new(1600); priv->alpha = clutter_alpha_new_full(priv->timeline, CLUTTER_EASE_OUT_EXPO); priv->curr_index = 0; + priv->loading_complete = FALSE; } @@ -186,7 +189,7 @@ GtkWidget *clarity_canvas_new() { * The return value is a hexstring in the form "rrggbbaa" * */ -gchar *clarity_canvas_get_background_color(ClarityCanvas *self) { +GdkRGBA *clarity_canvas_get_background_color(ClarityCanvas *self) { g_return_val_if_fail(CLARITY_IS_CANVAS(self), NULL); ClarityCanvasPrivate *priv = CLARITY_CANVAS_GET_PRIVATE(self); @@ -199,7 +202,14 @@ gchar *clarity_canvas_get_background_color(ClarityCanvas *self) { clutter_stage_get_color(CLUTTER_STAGE(stage), ccolor); g_return_val_if_fail(ccolor, NULL); - return clutter_color_to_string(ccolor); + GdkRGBA *rgba; + rgba = g_malloc(sizeof(GdkRGBA)); + rgba->red = ((gdouble) ccolor->red) / 255; + rgba->green = ((gdouble) ccolor->green) / 255; + rgba->blue = ((gdouble) ccolor->blue) / 255; + rgba->alpha = ((gdouble) ccolor->alpha) / 255; + + return rgba; } void clarity_canvas_set_background(ClarityCanvas *self, const gchar *color_string) { @@ -285,6 +295,12 @@ static void _display_clarity_cover(ClarityCover *ccover, gint index) { clutter_timeline_start (timeline); } +static gboolean _set_loading_complete(gpointer data) { + ClarityCanvasPrivate *priv = (ClarityCanvasPrivate *) data; + priv->loading_complete = TRUE; + return TRUE; +} + static gboolean _create_cover_idle(gpointer data) { AlbumItem *album_item = (AlbumItem *) data; @@ -372,6 +388,8 @@ static gpointer _init_album_model_threaded(gpointer data) { album_model_foreach(model, _init_album_item, cc); + g_idle_add_full(G_PRIORITY_LOW, _set_loading_complete, priv, NULL); + return NULL; } @@ -384,7 +402,7 @@ void clarity_canvas_init_album_model(ClarityCanvas *self, AlbumModel *model) { ClarityCanvasPrivate *priv = CLARITY_CANVAS_GET_PRIVATE(self); priv->model = model; - album_model_reset_loaded_index(model); + priv->loading_complete = FALSE; g_thread_create_full(_init_album_model_threaded, self, /* user data */ 0, /* stack size */ @@ -490,6 +508,8 @@ void clarity_canvas_move_left(ClarityCanvas *self, gint increment) { if(priv->curr_index == g_list_length(priv->covers) - 1) return; + priv->loading_complete = FALSE; + _move(priv, MOVE_LEFT, increment); } @@ -500,6 +520,8 @@ void clarity_canvas_move_right(ClarityCanvas *self, gint increment) { if(priv->curr_index == 0) return; + priv->loading_complete = FALSE; + _move(priv, MOVE_RIGHT, increment); } @@ -510,5 +532,9 @@ gint clarity_canvas_get_current_index(ClarityCanvas *self) { return priv->curr_index; } - +gboolean clarity_canvas_is_loading(ClarityCanvas *self) { + g_return_val_if_fail(self, FALSE); + ClarityCanvasPrivate *priv = CLARITY_CANVAS_GET_PRIVATE(self); + return !priv->loading_complete; +} diff --git a/plugins/clarity/clarity_canvas.h b/plugins/clarity/clarity_canvas.h index cf22471..2a6df7d 100644 --- a/plugins/clarity/clarity_canvas.h +++ b/plugins/clarity/clarity_canvas.h @@ -68,7 +68,7 @@ struct _ClarityCanvasClass { GtkWidget * clarity_canvas_new(); -gchar *clarity_canvas_get_background_color(ClarityCanvas *self); +GdkRGBA *clarity_canvas_get_background_color(ClarityCanvas *self); void clarity_canvas_set_background(ClarityCanvas *self, const gchar *color_string); @@ -82,6 +82,8 @@ void clarity_canvas_move_right(ClarityCanvas *self, gint increment); gint clarity_canvas_get_current_index(ClarityCanvas *self); +gboolean clarity_canvas_is_loading(ClarityCanvas *self); + G_END_DECLS #endif /* CLARITY_CANVAS_H_ */ diff --git a/plugins/clarity/clarity_preferences.c b/plugins/clarity/clarity_preferences.c index 33167e5..7414568 100644 --- a/plugins/clarity/clarity_preferences.c +++ b/plugins/clarity/clarity_preferences.c @@ -43,8 +43,8 @@ G_MODULE_EXPORT void on_clarity_dialog_bg_color_set (GtkColorButton *widget, gpo gchar *color_string = gdk_rgba_to_string(&color); prefs_set_string ("clarity_bg_color", color_string); + gtkpod_broadcast_preference_change("clarity_bg_color", color_string); g_free (color_string); - coverart_display_update (FALSE); } /* @@ -57,32 +57,37 @@ G_MODULE_EXPORT void on_clarity_dialog_fg_color_set (GtkColorButton *widget, gpo gchar *color_string = gdk_rgba_to_string(&color); prefs_set_string ("clarity_fg_color", color_string); + gtkpod_broadcast_preference_change("clarity_fg_color", color_string); g_free (color_string); - coverart_display_update (FALSE); } -G_MODULE_EXPORT void on_cad_ascend_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +static void _set_sort_preference(gint order) { + prefs_set_int("clarity_sort", order); + gtkpod_broadcast_preference_change("clarity_sort", &order); +} + +G_MODULE_EXPORT void on_clarity_ascend_toggled(GtkToggleButton *togglebutton, gpointer user_data) { if (gtk_toggle_button_get_active(togglebutton)) - coverart_display_sort(SORT_ASCENDING); + _set_sort_preference(SORT_ASCENDING); } -G_MODULE_EXPORT void on_cad_descend_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +G_MODULE_EXPORT void on_clarity_descend_toggled(GtkToggleButton *togglebutton, gpointer user_data) { if (gtk_toggle_button_get_active(togglebutton)) - coverart_display_sort(SORT_DESCENDING); + _set_sort_preference(SORT_DESCENDING); } -G_MODULE_EXPORT void on_cad_none_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +G_MODULE_EXPORT void on_clarity_none_toggled(GtkToggleButton *togglebutton, gpointer user_data) { if (gtk_toggle_button_get_active(togglebutton)) - coverart_display_sort(SORT_NONE); + _set_sort_preference(SORT_NONE); } -G_MODULE_EXPORT void on_cad_sort_case_sensitive_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +G_MODULE_EXPORT void on_clarity_sort_case_sensitive_toggled(GtkToggleButton *togglebutton, gpointer user_data) { gboolean val = gtk_toggle_button_get_active(togglebutton); - prefs_set_int("cad_case_sensitive", val); - gtkpod_broadcast_preference_change("cad_case_sensitive", val); + prefs_set_int("clarity_case_sensitive", val); + gtkpod_broadcast_preference_change("clarity_case_sensitive", &val); } -GtkWidget *init_cover_preferences(gchar *gladepath) { +GtkWidget *init_clarity_preferences(const gchar *gladepath, ClarityWidget *cw) { GtkWidget *notebook; GtkBuilder *pref_xml; GtkWidget *coverart_bgcolorselect_button; @@ -93,36 +98,36 @@ GtkWidget *init_cover_preferences(gchar *gladepath) { pref_xml = gtkpod_builder_xml_new(gladepath); win = gtkpod_builder_xml_get_widget(pref_xml, "preference_window"); notebook = gtkpod_builder_xml_get_widget(pref_xml, "cover_settings_notebook"); - coverart_bgcolorselect_button = gtkpod_builder_xml_get_widget (pref_xml, "coverart_display_bg_button"); - coverart_fgcolorselect_button = gtkpod_builder_xml_get_widget (pref_xml, "coverart_display_fg_button"); + coverart_bgcolorselect_button = gtkpod_builder_xml_get_widget (pref_xml, "clarity_bg_button"); + coverart_fgcolorselect_button = gtkpod_builder_xml_get_widget (pref_xml, "clarity_fg_button"); g_object_ref(notebook); gtk_container_remove(GTK_CONTAINER (win), notebook); - color = coverart_get_background_display_color(); + color = clarity_widget_get_background_display_color(cw); gtk_color_button_set_rgba (GTK_COLOR_BUTTON(coverart_bgcolorselect_button), color); gdk_rgba_free(color); - color = coverart_get_foreground_display_color(); + color = clarity_widget_get_foreground_display_color(cw); gtk_color_button_set_rgba (GTK_COLOR_BUTTON(coverart_fgcolorselect_button), color); gdk_rgba_free(color); - switch (prefs_get_int("cad_sort")) { + switch (prefs_get_int("clarity_sort")) { case SORT_ASCENDING: - w = gtkpod_builder_xml_get_widget(pref_xml, "cad_ascend"); + w = gtkpod_builder_xml_get_widget(pref_xml, "clarity_ascend"); break; case SORT_DESCENDING: - w = gtkpod_builder_xml_get_widget(pref_xml, "cad_descend"); + w = gtkpod_builder_xml_get_widget(pref_xml, "clarity_descend"); break; default: - w = gtkpod_builder_xml_get_widget(pref_xml, "cad_none"); + w = gtkpod_builder_xml_get_widget(pref_xml, "clarity_none"); break; } if (w) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), TRUE); - if ((w = gtkpod_builder_xml_get_widget(pref_xml, "cad_cfg_case_sensitive"))) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), prefs_get_int("cad_case_sensitive")); + if ((w = gtkpod_builder_xml_get_widget(pref_xml, "clarity_cfg_case_sensitive"))) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), prefs_get_int("clarity_case_sensitive")); } gtk_builder_connect_signals(pref_xml, NULL); diff --git a/plugins/clarity/clarity_preferences.h b/plugins/clarity/clarity_preferences.h index 2b102fa..5316083 100644 --- a/plugins/clarity/clarity_preferences.h +++ b/plugins/clarity/clarity_preferences.h @@ -29,6 +29,8 @@ #ifndef CLARITY_PREFERENCES_H_ #define CLARITY_PREFERENCES_H_ -GtkWidget *init_clarity_preferences(); +#include "clarity_widget.h" + +GtkWidget *init_clarity_preferences(const gchar *gladepath, ClarityWidget *cw); #endif /* CLARITY_PREFERENCES_H_ */ diff --git a/plugins/clarity/clarity_widget.c b/plugins/clarity/clarity_widget.c index eed716e..8636761 100644 --- a/plugins/clarity/clarity_widget.c +++ b/plugins/clarity/clarity_widget.c @@ -72,7 +72,6 @@ enum { * track updated * change background * text - * select cover * set cover from file * sort * preferences @@ -221,6 +220,21 @@ static void _init_slider_range(ClarityWidgetPrivate *priv) { g_signal_handler_unblock(G_OBJECT(priv->cdslider), priv->slider_signal_id); } +static void _set_background(ClarityWidget *self) { + gchar *hex_string; + + hex_string = "#FFFFFF"; + + if (!prefs_get_string_value("clarity_bg_color", NULL)) + hex_string = "#000000"; + else + prefs_get_string_value("clarity_bg_color", &hex_string); + + ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(self); + + clarity_canvas_set_background(CLARITY_CANVAS(priv->draw_area), hex_string); +} + static void clarity_widget_class_init (ClarityWidgetClass *klass) { GObjectClass *gobject_class; @@ -243,7 +257,7 @@ static void clarity_widget_init (ClarityWidget *self) { G_CALLBACK(_on_scrolling_covers_cb), priv); - clarity_widget_set_background(self); + _set_background(self); priv->leftbutton = gtk_button_new_with_label("<"); gtk_widget_set_name(priv->leftbutton, LEFT_BUTTON); @@ -294,7 +308,7 @@ static void clarity_widget_clear(ClarityWidget *self) { album_model_clear(priv->album_model); } -static void clarity_widget_init_tracks(ClarityWidget *cw, GList *tracks) { +static void _init_tracks(ClarityWidget *cw, GList *tracks) { g_return_if_fail(CLARITY_IS_WIDGET(cw)); if (!tracks) @@ -302,40 +316,59 @@ static void clarity_widget_init_tracks(ClarityWidget *cw, GList *tracks) { ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(cw); - while (tracks) { - Track *track = tracks->data; - album_model_add_track(priv->album_model, track); - tracks = tracks->next; - } + album_model_add_tracks(priv->album_model, tracks); clarity_canvas_init_album_model(CLARITY_CANVAS(priv->draw_area), priv->album_model); _init_slider_range(priv); } -void clarity_widget_set_background(ClarityWidget *self) { - gchar *hex_string; +GdkRGBA *clarity_widget_get_background_display_color(ClarityWidget *self) { + g_return_val_if_fail(CLARITY_IS_WIDGET(self), NULL); - hex_string = "#FFFFFF"; + ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(self); - if (!prefs_get_string_value("clarity_bg_color", NULL)) - hex_string = "#000000"; - else - prefs_get_string_value("clarity_bg_color", &hex_string); + return clarity_canvas_get_background_color(CLARITY_CANVAS(priv->draw_area)); +} + +GdkRGBA *clarity_widget_get_foreground_display_color(ClarityWidget *self) { + g_return_val_if_fail(CLARITY_IS_WIDGET(self), NULL); ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(self); - clarity_canvas_set_background(CLARITY_CANVAS(priv->draw_area), hex_string); + return clarity_canvas_get_background_color(CLARITY_CANVAS(priv->draw_area)); } -void clarity_widget_preference_changed_cb(GtkPodApp *app, gpointer pfname, gint32 value, gpointer data) { +static void _resort_albums(ClarityWidget *self) { + g_return_if_fail(CLARITY_IS_WIDGET(self)); + ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(self); + + // Need to clear away the graphics and start again + clarity_canvas_clear(CLARITY_CANVAS(priv->draw_area)); + + // Resort the albums + Playlist *playlist = gtkpod_get_current_playlist(); + if (playlist) { + album_model_resort(priv->album_model, playlist->members); + + // Re-init the graphics + clarity_canvas_init_album_model(CLARITY_CANVAS(priv->draw_area), priv->album_model); + + // Reset the slider and buttons + _init_slider_range(priv); + } +} + +void clarity_widget_preference_changed_cb(GtkPodApp *app, gpointer pfname, gpointer value, gpointer data) { g_return_if_fail(CLARITY_IS_WIDGET(data)); ClarityWidget *cw = CLARITY_WIDGET(data); gchar *pref_name = pfname; if (g_str_equal(pref_name, "clarity_bg_color")) - clarity_widget_set_background(cw); + _set_background(cw); + else if (g_str_equal(pref_name, "clarity_sort")) + _resort_albums(cw); } void clarity_widget_playlist_selected_cb(GtkPodApp *app, gpointer pl, gpointer data) { @@ -353,7 +386,7 @@ void clarity_widget_playlist_selected_cb(GtkPodApp *app, gpointer pl, gpointer d if (!tracks) return; - clarity_widget_init_tracks(cw, tracks); + _init_tracks(cw, tracks); } void clarity_widget_tracks_selected_cb(GtkPodApp *app, gpointer tks, gpointer data) { @@ -366,6 +399,11 @@ void clarity_widget_tracks_selected_cb(GtkPodApp *app, gpointer tks, gpointer da if (!tracks) return; + ClarityCanvas *ccanvas = CLARITY_CANVAS(priv->draw_area); + + if (clarity_canvas_is_loading(ccanvas)) + return; + gint album_index = album_model_get_index(priv->album_model, tracks->data); gtk_range_set_value(GTK_RANGE (priv->cdslider), album_index); } diff --git a/plugins/clarity/clarity_widget.h b/plugins/clarity/clarity_widget.h index 5debcb8..a6c216f 100644 --- a/plugins/clarity/clarity_widget.h +++ b/plugins/clarity/clarity_widget.h @@ -65,13 +65,15 @@ struct _ClarityWidgetClass { }; -void clarity_widget_set_background(ClarityWidget *self); +GdkRGBA *clarity_widget_get_background_display_color(ClarityWidget *self); + +GdkRGBA *clarity_widget_get_foreground_display_color(ClarityWidget *self); GtkWidget * clarity_widget_new(); // Signal callbacks -void clarity_widget_preference_changed_cb(GtkPodApp *app, gpointer pfname, gint32 value, gpointer data); +void clarity_widget_preference_changed_cb(GtkPodApp *app, gpointer pfname, gpointer value, gpointer data); void clarity_widget_playlist_selected_cb(GtkPodApp *app, gpointer pl, gpointer data); void clarity_widget_track_removed_cb(GtkPodApp *app, gpointer tk, gpointer data); void clarity_widget_tracks_selected_cb(GtkPodApp *app, gpointer tks, gpointer data); diff --git a/plugins/clarity/plugin.c b/plugins/clarity/plugin.c index 11c2981..8e5f9ea 100644 --- a/plugins/clarity/plugin.c +++ b/plugins/clarity/plugin.c @@ -39,7 +39,7 @@ #include "libgtkpod/directories.h" #include "plugin.h" #include "clarity_widget.h" -//#include "clarity_preferences.h" +#include "clarity_preferences.h" #define TAB_NAME "Clarity" @@ -50,11 +50,11 @@ static GtkActionEntry cover_actions[] = { }; static void set_default_preferences() { - if (!prefs_get_string_value("clarity_display_bg_color", NULL)) - prefs_set_string("clarity_display_bg_color", "#000000"); + if (!prefs_get_string_value("clarity_bg_color", NULL)) + prefs_set_string("clarity_bg_color", "#000000"); - if (!prefs_get_string_value("clarity_display_fg_color", NULL)) - prefs_set_string("clarity_display_fg_color", "#FFFFFF"); + if (!prefs_get_string_value("clarity_fg_color", NULL)) + prefs_set_string("clarity_fg_color", "#FFFFFF"); } static gboolean activate_plugin(AnjutaPlugin *plugin) { @@ -88,18 +88,18 @@ static gboolean activate_plugin(AnjutaPlugin *plugin) { gtk_scrolled_window_set_policy(clarity_plugin->cover_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(clarity_plugin->cover_window, GTK_SHADOW_IN); - GtkWidget* cw = clarity_widget_new (); - gtk_scrolled_window_add_with_viewport(clarity_plugin->cover_window, cw); + clarity_plugin->clarity_widget = CLARITY_WIDGET(clarity_widget_new ()); + gtk_scrolled_window_add_with_viewport(clarity_plugin->cover_window, GTK_WIDGET(clarity_plugin->clarity_widget)); gtk_widget_show_all(GTK_WIDGET(clarity_plugin->cover_window)); anjuta_shell_add_widget(plugin->shell, GTK_WIDGET(clarity_plugin->cover_window), "ClarityPlugin", "Cover Artwork", NULL, ANJUTA_SHELL_PLACEMENT_CENTER, NULL); - g_signal_connect (gtkpod_app, SIGNAL_PREFERENCE_CHANGE, G_CALLBACK (clarity_widget_preference_changed_cb), cw); - g_signal_connect (gtkpod_app, SIGNAL_PLAYLIST_SELECTED, G_CALLBACK (clarity_widget_playlist_selected_cb), cw); - g_signal_connect (gtkpod_app, SIGNAL_TRACK_REMOVED, G_CALLBACK (clarity_widget_track_removed_cb), cw); - g_signal_connect (gtkpod_app, SIGNAL_TRACKS_DISPLAYED, G_CALLBACK (clarity_widget_tracks_selected_cb), cw); - g_signal_connect (gtkpod_app, SIGNAL_TRACKS_SELECTED, G_CALLBACK (clarity_widget_tracks_selected_cb), cw); - g_signal_connect (gtkpod_app, SIGNAL_TRACK_UPDATED, G_CALLBACK (clarity_widget_track_updated_cb), cw); - g_signal_connect (gtkpod_app, SIGNAL_TRACK_ADDED, G_CALLBACK (clarity_widget_track_added_cb), cw); + g_signal_connect (gtkpod_app, SIGNAL_PREFERENCE_CHANGE, G_CALLBACK (clarity_widget_preference_changed_cb), clarity_plugin->clarity_widget); + g_signal_connect (gtkpod_app, SIGNAL_PLAYLIST_SELECTED, G_CALLBACK (clarity_widget_playlist_selected_cb), clarity_plugin->clarity_widget); + g_signal_connect (gtkpod_app, SIGNAL_TRACK_REMOVED, G_CALLBACK (clarity_widget_track_removed_cb), clarity_plugin->clarity_widget); + g_signal_connect (gtkpod_app, SIGNAL_TRACKS_DISPLAYED, G_CALLBACK (clarity_widget_tracks_selected_cb), clarity_plugin->clarity_widget); + g_signal_connect (gtkpod_app, SIGNAL_TRACKS_SELECTED, G_CALLBACK (clarity_widget_tracks_selected_cb), clarity_plugin->clarity_widget); + g_signal_connect (gtkpod_app, SIGNAL_TRACK_UPDATED, G_CALLBACK (clarity_widget_track_updated_cb), clarity_plugin->clarity_widget); + g_signal_connect (gtkpod_app, SIGNAL_TRACK_ADDED, G_CALLBACK (clarity_widget_track_added_cb), clarity_plugin->clarity_widget); return TRUE; /* FALSE if activation failed */ } @@ -109,6 +109,14 @@ static gboolean deactivate_plugin(AnjutaPlugin *plugin) { ClarityPlugin *clarity_plugin; clarity_plugin = (ClarityPlugin*) plugin; + + g_signal_handlers_disconnect_by_func(plugin->shell, G_CALLBACK (clarity_widget_preference_changed_cb), clarity_plugin->clarity_widget); + g_signal_handlers_disconnect_by_func(plugin->shell, G_CALLBACK (clarity_widget_playlist_selected_cb), clarity_plugin->clarity_widget); + g_signal_handlers_disconnect_by_func(plugin->shell, G_CALLBACK (clarity_widget_track_removed_cb), clarity_plugin->clarity_widget); + g_signal_handlers_disconnect_by_func(plugin->shell, G_CALLBACK (clarity_widget_tracks_selected_cb), clarity_plugin->clarity_widget); + g_signal_handlers_disconnect_by_func(plugin->shell, G_CALLBACK (clarity_widget_track_updated_cb), clarity_plugin->clarity_widget); + g_signal_handlers_disconnect_by_func(plugin->shell, G_CALLBACK (clarity_widget_track_added_cb), clarity_plugin->clarity_widget); + ui = anjuta_shell_get_ui(plugin->shell, NULL); /* Remove widgets from Shell */ @@ -117,6 +125,10 @@ static gboolean deactivate_plugin(AnjutaPlugin *plugin) { /* Unmerge UI */ anjuta_ui_unmerge(ui, clarity_plugin->uiid); + /* Destroy the widget */ + gtk_widget_destroy(GTK_WIDGET(clarity_plugin->clarity_widget)); + clarity_plugin->clarity_widget = NULL; + /* Remove Action groups */ anjuta_ui_remove_action_group(ui, clarity_plugin->action_group); @@ -144,33 +156,33 @@ static void clarity_plugin_class_init(GObjectClass *klass) { } static void ipreferences_merge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e) { -// GdkPixbuf *pixbuf; -// GError *error = NULL; -// -// ClarityPlugin* plugin = CLARITY_PLUGIN(ipref); -// plugin->prefs = init_cover_preferences(plugin->gladepath); -// if (plugin->prefs == NULL) -// return; -// -// pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), DEFAULT_COVER_ICON, 48, 0, &error); -// -// if (!pixbuf) { -// g_warning ("Couldn't load icon: %s", error->message); -// g_error_free(error); -// } -// anjuta_preferences_dialog_add_page(ANJUTA_PREFERENCES_DIALOG (anjuta_preferences_get_dialog (prefs)), "gtkpod-clarity-settings", _(TAB_NAME), pixbuf, plugin->prefs); -// g_object_unref(pixbuf); + GdkPixbuf *pixbuf; + GError *error = NULL; + + ClarityPlugin* plugin = CLARITY_PLUGIN(ipref); + plugin->prefs = init_clarity_preferences(plugin->gladepath, plugin->clarity_widget); + if (plugin->prefs == NULL) + return; + + pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), DEFAULT_COVER_ICON, 48, 0, &error); + + if (!pixbuf) { + g_warning ("Couldn't load icon: %s", error->message); + g_error_free(error); + } + anjuta_preferences_dialog_add_page(ANJUTA_PREFERENCES_DIALOG (anjuta_preferences_get_dialog (prefs)), "gtkpod-clarity-settings", _(TAB_NAME), pixbuf, plugin->prefs); + g_object_unref(pixbuf); } static void ipreferences_unmerge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e) { -// anjuta_preferences_remove_page(prefs, _(TAB_NAME)); -// ClarityPlugin* plugin = CLARITY_PLUGIN(ipref); -// gtk_widget_destroy(plugin->prefs); + anjuta_preferences_remove_page(prefs, _(TAB_NAME)); + ClarityPlugin* plugin = CLARITY_PLUGIN(ipref); + gtk_widget_destroy(plugin->prefs); } static void ipreferences_iface_init(IAnjutaPreferencesIface* iface) { -// iface->merge = ipreferences_merge; -// iface->unmerge = ipreferences_unmerge; + iface->merge = ipreferences_merge; + iface->unmerge = ipreferences_unmerge; } ANJUTA_PLUGIN_BEGIN (ClarityPlugin, clarity_plugin); diff --git a/plugins/clarity/plugin.h b/plugins/clarity/plugin.h index 1b9b746..f91f2fc 100644 --- a/plugins/clarity/plugin.h +++ b/plugins/clarity/plugin.h @@ -36,6 +36,7 @@ #include <libanjuta/anjuta-plugin.h> #include "clarity_utils.h" +#include "clarity_widget.h" extern GType clarity_plugin_get_type (GTypeModule *module); #define CLARITY_TYPE_PLUGIN (clarity_plugin_get_type (NULL)) @@ -51,6 +52,7 @@ typedef struct _ClarityPluginClass ClarityPluginClass; struct _ClarityPlugin { AnjutaPlugin parent; GtkScrolledWindow *cover_window; + ClarityWidget *clarity_widget; gint uiid; GtkActionGroup *action_group; GtkWidget *prefs; ------------------------------------------------------------------------------ Special Offer -- Download ArcSight Logger for FREE! Finally, a world-class log management solution at an even better price-free! And you'll get a free "Love Thy Logs" t-shirt when you download Logger. Secure your free ArcSight Logger TODAY! http://p.sf.net/sfu/arcsisghtdev2dev _______________________________________________ gtkpod-cvs2 mailing list gtkpod-cvs2@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2