save playlist and library grids widgets
[melted_gui] / src / ui.c
1 /*
2 * ui.c -- GTK+ 2 omnplay
3 * Copyright (C) 2011 Maksym Veremeyenko <verem@m1stereo.tv>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <stdio.h>
29
30 #include <gdk/gdkkeysyms.h>
31 #include <gtk/gtk.h>
32
33 #include "ui.h"
34 #include "ui_utils.h"
35 #include "ui_buttons.h"
36 #include "support.h"
37
38 static GtkWidget* create_label(GtkWidget* top, char* text, char* reg, GtkJustification jtype)
39 {
40 GtkWidget* label;
41
42 label = gtk_label_new ("");
43 gtk_widget_show (label);
44
45 gtk_label_set_justify (GTK_LABEL (label), jtype);
46
47 if(reg)
48 GLADE_HOOKUP_OBJECT (top, label, reg);
49
50 if(text)
51 gtk_label_set_text(GTK_LABEL (label), text);
52
53 return label;
54 };
55
56 static GtkWidget* create_treeview(GtkWidget* top, char* name, const char* columns[])
57 {
58 int i;
59
60 GtkWidget *treeview;
61 GtkCellRenderer *renderer;
62 GtkTreeViewColumn *column;
63 GtkListStore *list_store;
64
65 treeview = gtk_tree_view_new ();
66 gtk_widget_show (treeview);
67
68 list_store = gtk_list_store_new(7,
69 G_TYPE_STRING,
70 G_TYPE_STRING,
71 G_TYPE_STRING,
72 G_TYPE_STRING,
73 G_TYPE_STRING,
74 G_TYPE_STRING,
75 G_TYPE_STRING);
76 gtk_tree_view_set_model( GTK_TREE_VIEW( treeview ), GTK_TREE_MODEL( list_store ) );
77
78 for(i = 0; columns[i]; i++)
79 {
80 renderer = gtk_cell_renderer_toggle_new();
81 column = gtk_tree_view_column_new_with_attributes(
82 columns[i], renderer, "text", i, NULL);
83 gtk_tree_view_append_column(GTK_TREE_VIEW( treeview ), column);
84 };
85
86 GLADE_HOOKUP_OBJECT (top, treeview, name);
87
88 return treeview;
89 };
90
91 static GtkWidget* pane_library_grid(GtkWidget* top, omnplay_instance_t* app)
92 {
93 static const char* columns[] = {"ID", "DUR", "TITLE", NULL};
94 GtkWidget *scrolledwindow;
95
96 scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
97 gtk_widget_show (scrolledwindow);
98 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
99 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
100
101 gtk_container_add (GTK_CONTAINER (scrolledwindow),
102 app->library = create_treeview(top, "treeview_library", columns));
103
104 return scrolledwindow;
105 }
106
107 static GtkWidget* pane_library_buttons(GtkWidget* top, omnplay_instance_t* app)
108 {
109 GtkWidget* hbox;
110
111 hbox = gtk_hbox_new (FALSE, 0);
112 gtk_widget_show (hbox);
113
114 /* playlist modify buttons */
115 gtk_box_pack_start (GTK_BOX (hbox),
116 ui_create_button(top, app, BUTTON_LIBRARY_ADD),
117 FALSE, FALSE, 0);
118 gtk_box_pack_start (GTK_BOX (hbox),
119 ui_create_button(top, app, BUTTON_LIBRARY_REFRESH),
120 FALSE, FALSE, 0);
121
122 /* spacer */
123 gtk_box_pack_start (GTK_BOX (hbox),
124 create_label(top, NULL, NULL, GTK_JUSTIFY_CENTER),
125 TRUE, TRUE, 0);
126
127 return hbox;
128 }
129
130 static GtkWidget* pane_library(GtkWidget* top, omnplay_instance_t* app)
131 {
132 GtkWidget* vbox;
133
134 vbox = gtk_vbox_new (FALSE, 0);
135 gtk_widget_show (vbox);
136 gtk_widget_set_size_request(vbox, 300, -1);
137
138 /* add buttons box */
139 gtk_box_pack_start (GTK_BOX (vbox),
140 pane_library_buttons(top, app),
141 FALSE, FALSE, 0);
142
143 /* add buttons box */
144 gtk_box_pack_start (GTK_BOX (vbox),
145 pane_library_grid(top, app),
146 TRUE, TRUE, 0);
147
148 return vbox;
149 }
150
151 static GtkWidget* create_channel_status(GtkWidget* top, omnplay_instance_t* app, int idx)
152 {
153 GtkWidget* vbox;
154 GtkWidget* hbox;
155 GtkWidget* frame;
156 omnplay_player_t* player;
157
158 player = &app->players.item[idx];
159
160 frame = gtk_frame_new(player->name);
161 gtk_widget_show(frame);
162
163 vbox = gtk_vbox_new(FALSE, 0);
164 gtk_container_add(GTK_CONTAINER(frame), vbox);
165 gtk_widget_show(vbox);
166
167 /* status label */
168 gtk_box_pack_start(GTK_BOX (vbox),
169 player->label_status = create_label(top, "OFFLINE", NULL, GTK_JUSTIFY_LEFT),
170 FALSE, FALSE, 0);
171
172 /* spacel label */
173 gtk_box_pack_start(GTK_BOX (vbox),
174 create_label(top, " ", NULL, GTK_JUSTIFY_CENTER),
175 FALSE, FALSE, 0);
176
177 /* clip label */
178 gtk_box_pack_start (GTK_BOX (vbox),
179 player->label_clip = create_label(top, "U0002323", NULL, GTK_JUSTIFY_LEFT),
180 FALSE, FALSE, 0);
181
182 /* block state/current timecode */
183 gtk_box_pack_start(GTK_BOX (vbox),
184 hbox = gtk_hbox_new(TRUE, 0),
185 FALSE, FALSE, 0);
186 gtk_widget_show(hbox);
187
188 {
189 /* clip state */
190 gtk_box_pack_start(GTK_BOX (hbox),
191 player->label_state = create_label(top, "PLAYING", NULL, GTK_JUSTIFY_LEFT),
192 TRUE, TRUE, 0);
193
194 /* current timecode */
195 gtk_box_pack_start(GTK_BOX (hbox),
196 player->label_tc_cur = create_label(top, "00:00:00:00", NULL, GTK_JUSTIFY_LEFT),
197 TRUE, TRUE, 0);
198 };
199
200 /* block remain label/remain timecode */
201 gtk_box_pack_start(GTK_BOX (vbox),
202 hbox = gtk_hbox_new(TRUE, 0),
203 FALSE, FALSE, 0);
204 gtk_widget_show (hbox);
205
206 {
207 /* label */
208 gtk_box_pack_start(GTK_BOX (hbox),
209 create_label(top, "remain:", NULL, GTK_JUSTIFY_LEFT),
210 TRUE, TRUE, 0);
211
212 /* remaining timecode */
213 gtk_box_pack_start(GTK_BOX (hbox),
214 player->label_tc_rem = create_label(top, "00:00:00:00", NULL, GTK_JUSTIFY_LEFT),
215 TRUE, TRUE, 0);
216 };
217
218 return frame;
219 }
220
221 static GtkWidget* pane_operate_status(GtkWidget* top, omnplay_instance_t* app)
222 {
223 int i;
224 GtkWidget* vbox;
225
226 vbox = gtk_vbox_new (FALSE, 0);
227 gtk_widget_show (vbox);
228 gtk_widget_set_size_request(vbox, 250, -1);
229
230 for(i = 0; i < app->players.count; i++)
231 {
232 gtk_box_pack_start (GTK_BOX (vbox),
233 create_channel_status(top, app, i),
234 FALSE, FALSE, 0);
235
236 /* spacer */
237 gtk_box_pack_start (GTK_BOX (vbox),
238 create_label(top, NULL, NULL, GTK_JUSTIFY_CENTER),
239 FALSE, FALSE, 0);
240 }
241
242 /* spacer */
243 gtk_box_pack_start (GTK_BOX (vbox),
244 create_label(top, NULL, NULL, GTK_JUSTIFY_CENTER),
245 TRUE, TRUE, 0);
246
247 return vbox;
248 }
249
250 static GtkWidget* pane_operate_buttons_playlist(GtkWidget* top, omnplay_instance_t* app)
251 {
252 GtkWidget* hbox;
253
254 hbox = gtk_hbox_new (FALSE, 0);
255 gtk_widget_show (hbox);
256
257 /* playlist load/save buttons */
258 gtk_box_pack_start (GTK_BOX (hbox),
259 ui_create_button(top, app, BUTTON_PLAYLIST_LOAD),
260 FALSE, FALSE, 0);
261 gtk_box_pack_start (GTK_BOX (hbox),
262 ui_create_button(top, app, BUTTON_PLAYLIST_SAVE),
263 FALSE, FALSE, 0);
264
265 /* spacer */
266 gtk_box_pack_start (GTK_BOX (hbox),
267 create_label(top, " ", NULL, GTK_JUSTIFY_CENTER),
268 FALSE, FALSE, 0);
269
270 /* playlist modify buttons */
271 gtk_box_pack_start (GTK_BOX (hbox),
272 ui_create_button(top, app, BUTTON_PLAYLIST_ITEM_ADD),
273 FALSE, FALSE, 0);
274 gtk_box_pack_start (GTK_BOX (hbox),
275 ui_create_button(top, app, BUTTON_PLAYLIST_ITEM_EDIT),
276 FALSE, FALSE, 0);
277 gtk_box_pack_start (GTK_BOX (hbox),
278 ui_create_button(top, app, BUTTON_PLAYLIST_ITEM_DEL),
279 FALSE, FALSE, 0);
280
281 /* spacer */
282 gtk_box_pack_start (GTK_BOX (hbox),
283 create_label(top, " ", NULL, GTK_JUSTIFY_CENTER),
284 FALSE, FALSE, 0);
285
286 /* playlist block buttons */
287 gtk_box_pack_start (GTK_BOX (hbox),
288 ui_create_button(top, app, BUTTON_PLAYLIST_BLOCK_SINGLE),
289 FALSE, FALSE, 0);
290 gtk_box_pack_start (GTK_BOX (hbox),
291 ui_create_button(top, app, BUTTON_PLAYLIST_BLOCK_LOOP),
292 FALSE, FALSE, 0);
293
294 /* spacer */
295 gtk_box_pack_start (GTK_BOX (hbox),
296 create_label(top, " ", NULL, GTK_JUSTIFY_CENTER),
297 FALSE, FALSE, 0);
298
299 /* playlist move items buttons */
300 gtk_box_pack_start (GTK_BOX (hbox),
301 ui_create_button(top, app, BUTTON_PLAYLIST_ITEM_UP),
302 FALSE, FALSE, 0);
303 gtk_box_pack_start (GTK_BOX (hbox),
304 ui_create_button(top, app, BUTTON_PLAYLIST_ITEM_DOWN),
305 FALSE, FALSE, 0);
306
307 return hbox;
308 }
309
310 static GtkWidget* pane_operate_grid(GtkWidget* top, omnplay_instance_t* app)
311 {
312 static const char* columns[] = {"REM", "B", "CH", "ID", "IN", "DUR", "TITLE", NULL};
313 GtkWidget *scrolledwindow;
314
315 scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
316 gtk_widget_show (scrolledwindow);
317 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
318 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
319
320 gtk_container_add (GTK_CONTAINER (scrolledwindow),
321 app->playlist = create_treeview(top, "treeview_playlist", columns));
322
323 return scrolledwindow;
324 }
325
326 static GtkWidget* pane_operate_buttons_operate(GtkWidget* top, omnplay_instance_t* app)
327 {
328 GtkWidget* hbox;
329
330 hbox = gtk_hbox_new (FALSE, 0);
331 gtk_widget_show (hbox);
332
333 /* spacer */
334 gtk_box_pack_start (GTK_BOX (hbox),
335 create_label(top, NULL, NULL, GTK_JUSTIFY_CENTER),
336 TRUE, TRUE, 0);
337
338 /* playlist modify buttons */
339 gtk_box_pack_start (GTK_BOX (hbox),
340 ui_create_button(top, app, BUTTON_PLAYER_CUE),
341 FALSE, FALSE, 0);
342 gtk_box_pack_start (GTK_BOX (hbox),
343 ui_create_button(top, app, BUTTON_PLAYER_PLAY),
344 FALSE, FALSE, 0);
345 gtk_box_pack_start (GTK_BOX (hbox),
346 ui_create_button(top, app, BUTTON_PLAYER_PAUSE),
347 FALSE, FALSE, 0);
348 gtk_box_pack_start (GTK_BOX (hbox),
349 ui_create_button(top, app, BUTTON_PLAYER_STOP),
350 FALSE, FALSE, 0);
351
352 /* spacer */
353 gtk_box_pack_start (GTK_BOX (hbox),
354 create_label(top, NULL, NULL, GTK_JUSTIFY_CENTER),
355 TRUE, TRUE, 0);
356
357 return hbox;
358 }
359
360 static GtkWidget* pane_operate_operate(GtkWidget* top, omnplay_instance_t* app)
361 {
362 GtkWidget* vbox;
363
364 vbox = gtk_vbox_new (FALSE, 0);
365 gtk_widget_show (vbox);
366
367 /* add buttons box #1 */
368 gtk_box_pack_start (GTK_BOX (vbox),
369 pane_operate_buttons_playlist(top, app),
370 FALSE, FALSE, 0);
371
372 /* add buttons box */
373 gtk_box_pack_start (GTK_BOX (vbox),
374 pane_operate_grid(top, app),
375 TRUE, TRUE, 0);
376
377 /* add buttons box #1 */
378 gtk_box_pack_start (GTK_BOX (vbox),
379 pane_operate_buttons_operate(top, app),
380 FALSE, FALSE, 0);
381
382 return vbox;
383
384 }
385
386 static GtkWidget* pane_operate(GtkWidget* top, omnplay_instance_t* app)
387 {
388 GtkWidget* hbox;
389
390 hbox = gtk_hbox_new (FALSE, 0);
391 gtk_widget_show (hbox);
392
393 /* add buttons box */
394 gtk_box_pack_start (GTK_BOX (hbox),
395 pane_operate_status(top, app),
396 FALSE, FALSE, 0);
397
398 /* add buttons box */
399 gtk_box_pack_start (GTK_BOX (hbox),
400 pane_operate_operate(top, app),
401 TRUE, TRUE, 0);
402
403 return hbox;
404
405 };
406
407 static GtkWidget* pane_top(GtkWidget* top, omnplay_instance_t* app)
408 {
409 GtkWidget* pane;
410
411 pane = gtk_hpaned_new ();
412 gtk_widget_show (pane);
413
414 gtk_paned_set_position (GTK_PANED (pane), 800);
415
416 gtk_paned_pack1 (GTK_PANED (pane),
417 pane_operate(top, app),
418 TRUE, FALSE);
419
420 gtk_paned_pack2 (GTK_PANED (pane),
421 pane_library(top, app),
422 FALSE, FALSE);
423
424 return pane;
425 }
426
427 GtkWidget* ui_omnplay (omnplay_instance_t* app)
428 {
429 GtkWidget *wnd;
430
431 wnd = gtk_window_new (GTK_WINDOW_TOPLEVEL);
432 GLADE_HOOKUP_OBJECT_NO_REF (wnd, wnd, "omnplay_window");
433
434 gtk_window_set_title (GTK_WINDOW (wnd), _("Omneon Player"));
435 gtk_window_set_default_size (GTK_WINDOW (wnd), 1024, 768);
436
437 gtk_container_add (GTK_CONTAINER (wnd),
438 pane_top(wnd, app));
439
440 return wnd;
441 }