Mercurial > audlegacy
annotate src/audacious/ui_playlist_widget.c @ 4793:7f318fa97ea3
Only gtk.h should be included, as per -DGTK_DISABLE_SINGLE_INCLUDES (GTK+ 3 compatibility project).
author | Tony Vroon <chainsaw@gentoo.org> |
---|---|
date | Sat, 04 Oct 2008 23:41:34 +0100 |
parents | 4d15507f568c |
children |
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 | |
4736 | 43 static void |
44 ui_playlist_widget_set_title_active(GtkTreeModel *model, gint pos, | |
45 gboolean active) | |
46 { | |
47 GtkTreeIter iter; | |
48 GtkTreePath *path; | |
49 gchar *path_str; | |
4739 | 50 |
4736 | 51 path_str = g_strdup_printf("%d", pos); |
52 path = gtk_tree_path_new_from_string(path_str); | |
53 gtk_tree_model_get_iter(model, &iter, path); | |
54 | |
55 gtk_list_store_set(GTK_LIST_STORE(model), &iter, | |
56 3, active ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -1); | |
57 | |
58 g_free(path_str); | |
59 gtk_tree_path_free(path); | |
60 } | |
61 | |
4728 | 62 void |
63 ui_playlist_widget_set_current(GtkWidget *treeview, gint pos) | |
64 { | |
65 GtkTreeModel *model; | |
4736 | 66 gint old_pos; |
4739 | 67 |
4728 | 68 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)); |
4736 | 69 old_pos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(treeview), "current")); |
4728 | 70 |
4736 | 71 if (old_pos != -1) |
72 ui_playlist_widget_set_title_active(model, old_pos, FALSE); | |
73 if (pos != -1) | |
74 ui_playlist_widget_set_title_active(model, pos, TRUE); | |
4728 | 75 |
76 g_object_set_data(G_OBJECT(treeview), "current", GINT_TO_POINTER(pos)); | |
77 } | |
78 | |
79 static void | |
80 ui_playlist_widget_jump(GtkTreeView * treeview, gpointer data) | |
81 { | |
82 GtkTreeModel *model; | |
83 GtkTreeSelection *selection; | |
84 GtkTreeIter iter; | |
85 guint pos; | |
86 | |
87 model = gtk_tree_view_get_model(treeview); | |
88 selection = gtk_tree_view_get_selection(treeview); | |
89 | |
90 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) | |
91 return; | |
92 | |
93 gtk_tree_model_get(model, &iter, 0, &pos, -1); | |
94 | |
95 ui_playlist_widget_change_song(pos - 1); | |
96 } | |
97 | |
98 static gboolean | |
99 ui_playlist_widget_keypress_cb(GtkWidget * widget, | |
100 GdkEventKey * event, | |
101 gpointer data) | |
102 { | |
103 switch (event->keyval) { | |
104 case GDK_KP_Enter: | |
105 ui_playlist_widget_jump(GTK_TREE_VIEW(widget), NULL); | |
106 return TRUE; | |
107 default: | |
108 return FALSE; | |
109 }; | |
110 } | |
111 | |
112 void | |
113 ui_playlist_widget_update(GtkWidget *widget) | |
114 { | |
115 guint row; | |
116 gboolean valid; | |
117 | |
118 GList *playlist_glist; | |
119 gchar *desc_buf = NULL; | |
120 gchar *length = NULL; | |
121 GtkTreeIter iter; | |
122 Playlist *playlist; | |
123 GtkTreeModel *store; | |
124 GtkTreeView *tree = GTK_TREE_VIEW(widget); | |
125 | |
126 store = gtk_tree_view_get_model(tree); | |
127 valid = gtk_tree_model_get_iter_first(store, &iter); | |
128 | |
129 row = 1; | |
130 playlist = playlist_get_active(); | |
131 | |
132 for (playlist_glist = playlist->entries; playlist_glist; | |
133 playlist_glist = g_list_next(playlist_glist)) { | |
134 PlaylistEntry *entry = PLAYLIST_ENTRY(playlist_glist->data); | |
135 | |
136 if (entry->title) | |
137 desc_buf = g_strdup(entry->title); | |
138 else { | |
139 gchar *realfn = NULL; | |
140 realfn = g_filename_from_uri(entry->filename, NULL, NULL); | |
141 if (strchr(realfn ? realfn : entry->filename, '/')) | |
142 desc_buf = str_assert_utf8(strrchr(realfn ? realfn : entry->filename, '/') + 1); | |
143 else | |
144 desc_buf = str_assert_utf8(realfn ? realfn : entry->filename); | |
145 g_free(realfn); realfn = NULL; | |
146 } | |
147 | |
148 if (entry->length != -1) { | |
149 length = g_strdup_printf("%d:%-2.2d", entry->length / 60000, (entry->length / 1000) % 60); | |
150 } | |
151 | |
152 if (!valid) | |
153 gtk_list_store_append(GTK_LIST_STORE(store), &iter); | |
154 gtk_list_store_set(GTK_LIST_STORE(store), &iter, | |
155 COLUMN_NUM, row, COLUMN_TEXT, desc_buf, | |
156 COLUMN_TIME, length, | |
157 COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL, -1); | |
158 row++; | |
159 | |
160 g_free(desc_buf); | |
161 desc_buf = NULL; | |
162 | |
163 if (length) g_free(length); | |
164 length = NULL; | |
165 | |
166 valid = gtk_tree_model_iter_next(store, &iter); | |
167 } | |
168 | |
169 /* remove additional rows */ | |
170 while (valid) { | |
171 valid = gtk_list_store_remove(GTK_LIST_STORE(store), &iter); | |
172 } | |
173 | |
174 ui_playlist_widget_set_current(widget, playlist_get_position(playlist)); | |
175 } | |
176 | |
177 static gboolean | |
178 ui_playlist_widget_fill(gpointer treeview) | |
179 { | |
180 GList *playlist_glist; | |
181 Playlist *playlist; | |
182 gchar *desc_buf = NULL; | |
183 gchar *length = NULL; | |
184 guint row; | |
185 GtkTreeIter iter; | |
186 GtkListStore *store = (GtkListStore*)gtk_tree_view_get_model( GTK_TREE_VIEW(treeview) ); | |
187 | |
188 /* detach model from treeview before fill */ | |
189 g_object_ref(store); | |
190 gtk_tree_view_set_model( GTK_TREE_VIEW(treeview), NULL ); | |
191 | |
192 gtk_list_store_clear(store); | |
193 | |
194 row = 1; | |
195 playlist = playlist_get_active(); | |
196 | |
197 PLAYLIST_LOCK(playlist); | |
198 for (playlist_glist = playlist->entries; playlist_glist; | |
199 playlist_glist = g_list_next(playlist_glist)) { | |
200 | |
201 PlaylistEntry *entry = PLAYLIST_ENTRY(playlist_glist->data); | |
202 | |
203 if (entry->title) | |
204 desc_buf = g_strdup(entry->title); | |
205 else { | |
206 gchar *realfn = NULL; | |
207 realfn = g_filename_from_uri(entry->filename, NULL, NULL); | |
208 if (strchr(realfn ? realfn : entry->filename, '/')) | |
209 desc_buf = str_assert_utf8(strrchr(realfn ? realfn : entry->filename, '/') + 1); | |
210 else | |
211 desc_buf = str_assert_utf8(realfn ? realfn : entry->filename); | |
212 g_free(realfn); realfn = NULL; | |
213 } | |
214 | |
215 if (entry->length != -1) { | |
216 length = g_strdup_printf("%d:%-2.2d", entry->length / 60000, (entry->length / 1000) % 60); | |
217 } | |
218 | |
219 gtk_list_store_append(GTK_LIST_STORE(store), &iter); | |
220 gtk_list_store_set(GTK_LIST_STORE(store), &iter, | |
221 COLUMN_NUM, row, COLUMN_TEXT, desc_buf, | |
222 COLUMN_TIME, length, | |
223 COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL, -1); | |
224 row++; | |
225 | |
226 g_free(desc_buf); | |
227 desc_buf = NULL; | |
228 | |
229 if (length) g_free(length); | |
230 length = NULL; | |
231 } | |
232 PLAYLIST_UNLOCK(playlist); | |
233 | |
234 /* attach liststore to treeview */ | |
235 gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(store)); | |
236 g_object_unref(store); | |
237 | |
238 return FALSE; | |
239 } | |
240 | |
241 GtkWidget * | |
242 ui_playlist_widget_new(void) | |
243 { | |
244 GtkWidget *treeview; | |
245 GtkListStore *store; | |
246 GtkCellRenderer *renderer; | |
247 GtkTreeViewColumn *column; | |
248 | |
249 store = gtk_list_store_new(N_COLUMNS, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, PANGO_TYPE_WEIGHT); | |
250 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); | |
251 g_object_unref(store); | |
252 | |
253 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); | |
254 | |
255 column = gtk_tree_view_column_new(); | |
256 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE); | |
257 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); | |
258 gtk_tree_view_column_set_spacing(column, 4); | |
259 | |
260 renderer = gtk_cell_renderer_text_new(); | |
261 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
262 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
|
263 g_object_set(G_OBJECT(renderer), "ypad", 0, NULL); |
4728 | 264 |
265 renderer = gtk_cell_renderer_text_new(); | |
266 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
267 gtk_tree_view_column_set_attributes(column, renderer, "text", COLUMN_TEXT, "weight", COLUMN_WEIGHT, NULL); | |
4735
cc107c7ec07f
set ellipsize to PANGO_ELLIPSIZE_END in title column
Tomasz Mon <desowin@gmail.com>
parents:
4729
diff
changeset
|
268 g_object_set(G_OBJECT(renderer), "ypad", 0, "ellipsize-set", TRUE, |
cc107c7ec07f
set ellipsize to PANGO_ELLIPSIZE_END in title column
Tomasz Mon <desowin@gmail.com>
parents:
4729
diff
changeset
|
269 "ellipsize", PANGO_ELLIPSIZE_END, NULL); |
4728 | 270 |
271 renderer = gtk_cell_renderer_text_new(); | |
272 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
273 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
|
274 g_object_set(G_OBJECT(renderer), "ypad", 0, NULL); |
4728 | 275 |
276 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
277 | |
278 g_signal_connect(treeview, "row-activated", | |
279 G_CALLBACK(ui_playlist_widget_jump), NULL); | |
280 | |
281 g_signal_connect(treeview, "key-press-event", | |
282 G_CALLBACK(ui_playlist_widget_keypress_cb), NULL); | |
283 | |
284 ui_playlist_widget_fill(treeview); | |
285 | |
286 g_object_set_data(G_OBJECT(treeview), "current", GINT_TO_POINTER(-1)); | |
287 | |
288 return treeview; | |
289 } |