Mercurial > audlegacy
annotate src/audacious/ui_playlist_widget.c @ 4729:5e70c200eb8d
Use GtkCellRenderer::ypad to provide a more compact playlist, similar to the list widgets in Conspire.
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Wed, 16 Jul 2008 17:32:37 -0500 |
parents | ab79ddbdcf42 |
children | cc107c7ec07f |
rev | line source |
---|---|
4728 | 1 /* Audacious - Cross-platform multimedia player |
2 * Copyright (C) 2008 Tomasz Moń <desowin@gmail.com> | |
3 * | |
4 * This program is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; under version 3 of the License. | |
7 * | |
8 * This program is distributed in the hope that it will be useful, | |
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 * GNU General Public License for more details. | |
12 * | |
13 * You should have received a copy of the GNU General Public License | |
14 * along with this program. If not, see <http://www.gnu.org/licenses>. | |
15 * | |
16 * The Audacious team does not consider modular code linking to | |
17 * Audacious or using our public API to be a derived work. | |
18 */ | |
19 | |
20 #include <gtk/gtk.h> | |
21 #include <gdk/gdkkeysyms.h> | |
22 #include "playlist.h" | |
23 #include "playback.h" | |
24 #include "strings.h" | |
25 | |
26 enum { | |
27 COLUMN_NUM = 0, | |
28 COLUMN_TEXT, | |
29 COLUMN_TIME, | |
30 COLUMN_WEIGHT, | |
31 N_COLUMNS | |
32 }; | |
33 | |
34 static void | |
35 ui_playlist_widget_change_song(guint pos) | |
36 { | |
37 playlist_set_position(playlist_get_active(), pos); | |
38 | |
39 if (!playback_get_playing()) | |
40 playback_initiate(); | |
41 } | |
42 | |
43 void | |
44 ui_playlist_widget_set_current(GtkWidget *treeview, gint pos) | |
45 { | |
46 GtkTreeModel *model; | |
47 GtkTreeIter iter; | |
48 GtkTreePath *path; | |
49 gchar *p; | |
50 | |
51 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)); | |
52 | |
53 gint old_pos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(treeview), "current")); | |
54 | |
55 if (old_pos != -1) { | |
56 p = g_strdup_printf("%d", old_pos); | |
57 path = gtk_tree_path_new_from_string(p); | |
58 gtk_tree_model_get_iter(model, &iter, path); | |
59 gtk_list_store_set(GTK_LIST_STORE(model), &iter, 3, PANGO_WEIGHT_NORMAL, -1); | |
60 g_free(p); | |
61 gtk_tree_path_free(path); | |
62 } | |
63 | |
64 if (pos != -1) { | |
65 p = g_strdup_printf("%d", pos); | |
66 path = gtk_tree_path_new_from_string(p); | |
67 gtk_tree_model_get_iter(model, &iter, path); | |
68 gtk_list_store_set(GTK_LIST_STORE(model), &iter, 3, PANGO_WEIGHT_BOLD, -1); | |
69 g_free(p); | |
70 gtk_tree_path_free(path); | |
71 } | |
72 | |
73 g_object_set_data(G_OBJECT(treeview), "current", GINT_TO_POINTER(pos)); | |
74 } | |
75 | |
76 static void | |
77 ui_playlist_widget_jump(GtkTreeView * treeview, gpointer data) | |
78 { | |
79 GtkTreeModel *model; | |
80 GtkTreeSelection *selection; | |
81 GtkTreeIter iter; | |
82 guint pos; | |
83 | |
84 model = gtk_tree_view_get_model(treeview); | |
85 selection = gtk_tree_view_get_selection(treeview); | |
86 | |
87 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) | |
88 return; | |
89 | |
90 gtk_tree_model_get(model, &iter, 0, &pos, -1); | |
91 | |
92 ui_playlist_widget_change_song(pos - 1); | |
93 | |
94 ui_playlist_widget_set_current(GTK_WIDGET(treeview), pos); | |
95 } | |
96 | |
97 static gboolean | |
98 ui_playlist_widget_keypress_cb(GtkWidget * widget, | |
99 GdkEventKey * event, | |
100 gpointer data) | |
101 { | |
102 switch (event->keyval) { | |
103 case GDK_KP_Enter: | |
104 ui_playlist_widget_jump(GTK_TREE_VIEW(widget), NULL); | |
105 return TRUE; | |
106 default: | |
107 return FALSE; | |
108 }; | |
109 } | |
110 | |
111 void | |
112 ui_playlist_widget_update(GtkWidget *widget) | |
113 { | |
114 guint row; | |
115 gboolean valid; | |
116 | |
117 GList *playlist_glist; | |
118 gchar *desc_buf = NULL; | |
119 gchar *length = NULL; | |
120 GtkTreeIter iter; | |
121 Playlist *playlist; | |
122 GtkTreeModel *store; | |
123 GtkTreeView *tree = GTK_TREE_VIEW(widget); | |
124 | |
125 store = gtk_tree_view_get_model(tree); | |
126 valid = gtk_tree_model_get_iter_first(store, &iter); | |
127 | |
128 row = 1; | |
129 playlist = playlist_get_active(); | |
130 | |
131 for (playlist_glist = playlist->entries; playlist_glist; | |
132 playlist_glist = g_list_next(playlist_glist)) { | |
133 PlaylistEntry *entry = PLAYLIST_ENTRY(playlist_glist->data); | |
134 | |
135 if (entry->title) | |
136 desc_buf = g_strdup(entry->title); | |
137 else { | |
138 gchar *realfn = NULL; | |
139 realfn = g_filename_from_uri(entry->filename, NULL, NULL); | |
140 if (strchr(realfn ? realfn : entry->filename, '/')) | |
141 desc_buf = str_assert_utf8(strrchr(realfn ? realfn : entry->filename, '/') + 1); | |
142 else | |
143 desc_buf = str_assert_utf8(realfn ? realfn : entry->filename); | |
144 g_free(realfn); realfn = NULL; | |
145 } | |
146 | |
147 if (entry->length != -1) { | |
148 length = g_strdup_printf("%d:%-2.2d", entry->length / 60000, (entry->length / 1000) % 60); | |
149 } | |
150 | |
151 if (!valid) | |
152 gtk_list_store_append(GTK_LIST_STORE(store), &iter); | |
153 gtk_list_store_set(GTK_LIST_STORE(store), &iter, | |
154 COLUMN_NUM, row, COLUMN_TEXT, desc_buf, | |
155 COLUMN_TIME, length, | |
156 COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL, -1); | |
157 row++; | |
158 | |
159 g_free(desc_buf); | |
160 desc_buf = NULL; | |
161 | |
162 if (length) g_free(length); | |
163 length = NULL; | |
164 | |
165 valid = gtk_tree_model_iter_next(store, &iter); | |
166 } | |
167 | |
168 /* remove additional rows */ | |
169 while (valid) { | |
170 valid = gtk_list_store_remove(GTK_LIST_STORE(store), &iter); | |
171 } | |
172 | |
173 ui_playlist_widget_set_current(widget, playlist_get_position(playlist)); | |
174 } | |
175 | |
176 static gboolean | |
177 ui_playlist_widget_fill(gpointer treeview) | |
178 { | |
179 GList *playlist_glist; | |
180 Playlist *playlist; | |
181 gchar *desc_buf = NULL; | |
182 gchar *length = NULL; | |
183 guint row; | |
184 GtkTreeIter iter; | |
185 GtkListStore *store = (GtkListStore*)gtk_tree_view_get_model( GTK_TREE_VIEW(treeview) ); | |
186 | |
187 /* detach model from treeview before fill */ | |
188 g_object_ref(store); | |
189 gtk_tree_view_set_model( GTK_TREE_VIEW(treeview), NULL ); | |
190 | |
191 gtk_list_store_clear(store); | |
192 | |
193 row = 1; | |
194 playlist = playlist_get_active(); | |
195 | |
196 PLAYLIST_LOCK(playlist); | |
197 for (playlist_glist = playlist->entries; playlist_glist; | |
198 playlist_glist = g_list_next(playlist_glist)) { | |
199 | |
200 PlaylistEntry *entry = PLAYLIST_ENTRY(playlist_glist->data); | |
201 | |
202 if (entry->title) | |
203 desc_buf = g_strdup(entry->title); | |
204 else { | |
205 gchar *realfn = NULL; | |
206 realfn = g_filename_from_uri(entry->filename, NULL, NULL); | |
207 if (strchr(realfn ? realfn : entry->filename, '/')) | |
208 desc_buf = str_assert_utf8(strrchr(realfn ? realfn : entry->filename, '/') + 1); | |
209 else | |
210 desc_buf = str_assert_utf8(realfn ? realfn : entry->filename); | |
211 g_free(realfn); realfn = NULL; | |
212 } | |
213 | |
214 if (entry->length != -1) { | |
215 length = g_strdup_printf("%d:%-2.2d", entry->length / 60000, (entry->length / 1000) % 60); | |
216 } | |
217 | |
218 gtk_list_store_append(GTK_LIST_STORE(store), &iter); | |
219 gtk_list_store_set(GTK_LIST_STORE(store), &iter, | |
220 COLUMN_NUM, row, COLUMN_TEXT, desc_buf, | |
221 COLUMN_TIME, length, | |
222 COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL, -1); | |
223 row++; | |
224 | |
225 g_free(desc_buf); | |
226 desc_buf = NULL; | |
227 | |
228 if (length) g_free(length); | |
229 length = NULL; | |
230 } | |
231 PLAYLIST_UNLOCK(playlist); | |
232 | |
233 /* attach liststore to treeview */ | |
234 gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(store)); | |
235 g_object_unref(store); | |
236 | |
237 return FALSE; | |
238 } | |
239 | |
240 GtkWidget * | |
241 ui_playlist_widget_new(void) | |
242 { | |
243 GtkWidget *treeview; | |
244 GtkListStore *store; | |
245 GtkCellRenderer *renderer; | |
246 GtkTreeViewColumn *column; | |
247 | |
248 store = gtk_list_store_new(N_COLUMNS, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, PANGO_TYPE_WEIGHT); | |
249 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); | |
250 g_object_unref(store); | |
251 | |
252 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); | |
253 | |
254 column = gtk_tree_view_column_new(); | |
255 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE); | |
256 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); | |
257 gtk_tree_view_column_set_spacing(column, 4); | |
258 | |
259 renderer = gtk_cell_renderer_text_new(); | |
260 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
261 gtk_tree_view_column_set_attributes(column, renderer, "text", COLUMN_NUM, NULL); | |
4729
5e70c200eb8d
Use GtkCellRenderer::ypad to provide a more compact playlist, similar to the list widgets in Conspire.
William Pitcock <nenolod@atheme.org>
parents:
4728
diff
changeset
|
262 g_object_set(G_OBJECT(renderer), "ypad", 0, NULL); |
4728 | 263 |
264 renderer = gtk_cell_renderer_text_new(); | |
265 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
266 gtk_tree_view_column_set_attributes(column, renderer, "text", COLUMN_TEXT, "weight", COLUMN_WEIGHT, NULL); | |
4729
5e70c200eb8d
Use GtkCellRenderer::ypad to provide a more compact playlist, similar to the list widgets in Conspire.
William Pitcock <nenolod@atheme.org>
parents:
4728
diff
changeset
|
267 g_object_set(G_OBJECT(renderer), "ypad", 0, NULL); |
4728 | 268 |
269 renderer = gtk_cell_renderer_text_new(); | |
270 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
271 gtk_tree_view_column_set_attributes(column, renderer, "text", COLUMN_TIME, NULL); | |
4729
5e70c200eb8d
Use GtkCellRenderer::ypad to provide a more compact playlist, similar to the list widgets in Conspire.
William Pitcock <nenolod@atheme.org>
parents:
4728
diff
changeset
|
272 g_object_set(G_OBJECT(renderer), "ypad", 0, NULL); |
4728 | 273 |
274 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
275 | |
276 g_signal_connect(treeview, "row-activated", | |
277 G_CALLBACK(ui_playlist_widget_jump), NULL); | |
278 | |
279 g_signal_connect(treeview, "key-press-event", | |
280 G_CALLBACK(ui_playlist_widget_keypress_cb), NULL); | |
281 | |
282 ui_playlist_widget_fill(treeview); | |
283 | |
284 g_object_set_data(G_OBJECT(treeview), "current", GINT_TO_POINTER(-1)); | |
285 | |
286 return treeview; | |
287 } |