source: vital-to8-sdk/music/mod/vital_tracker.c @ 1

Last change on this file since 1 was 1, checked in by svn, 6 years ago

Import initial

File size: 24.9 KB
Line 
1/*
2    This is gonna be my second "mod player" to date (previous one was in Turbo pascal + asm some 20years ago...)
3    This one is intended to be a preview for underpowered platforms with lots of degrade functions (lower frequency, low bit count...)
4*/
5
6#include <gtk/gtk.h>
7#include <gdk/gdkx.h>
8#include <gdk/gdkkeysyms.h>
9
10#include <string.h>
11
12#include "player_module.h"
13#include "alsa_playback.h"
14
15GtkWidget *window;
16
17GtkWidget *sample_drawing_area;
18   
19#define MY_MAX_PATH 4096
20
21int cur_sample=1;
22int cur_pattern=0;
23
24void update_sample(void);
25
26static gboolean delete_event( GtkWidget *widget,
27                              GdkEvent  *event,
28                              gpointer   data )
29{
30    g_print ("delete event occurred May autosave in release...\n");
31    gtk_main_quit ();
32}
33
34static void destroy( GtkWidget *widget,
35                     gpointer   data )
36{
37    gtk_main_quit ();
38}
39
40
41/* open_file:
42 *  Charge une nouvelle disquette (callback).
43 */
44static void open_mod_file ( GtkWidget *widget,
45                     gpointer   data )
46{
47    GtkFileFilter *filter;
48    static GtkWidget *dialog;
49    char *folderName;
50    static char folderNameLast[MY_MAX_PATH+1]="";
51    char *fileName;
52
53    g_print ("Open mod file...\n");
54
55        dialog = gtk_file_chooser_dialog_new (
56                 "Open a module file",
57                 (GtkWindow *) window, GTK_FILE_CHOOSER_ACTION_OPEN,
58                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
59                 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
60                 
61        filter = gtk_file_filter_new ();
62        gtk_file_filter_set_name (filter,"Plain old amiga files");
63        gtk_file_filter_add_pattern (filter, "*.MOD");
64        gtk_file_filter_add_pattern (filter, "*.mod");
65        gtk_file_filter_add_pattern (filter, "mod.*");
66        gtk_file_filter_add_pattern (filter, "MOD.*");
67        gtk_file_chooser_add_filter ((GtkFileChooser *)dialog, filter);
68
69        /* voids any pending message */
70        while (gtk_events_pending ())
71            gtk_main_iteration ();
72
73    if (folderNameLast[0]=='\0') {
74        strncpy(folderNameLast,g_get_current_dir(),MY_MAX_PATH);
75    }
76   
77    (void)gtk_file_chooser_set_current_folder((GtkFileChooser *)dialog,folderNameLast);
78
79    if (gtk_dialog_run ((GtkDialog *)dialog) == GTK_RESPONSE_ACCEPT)
80    {
81        fileName = gtk_file_chooser_get_filename((GtkFileChooser *)dialog);
82        folderName = gtk_file_chooser_get_current_folder ((GtkFileChooser *)dialog);
83       
84        strncpy(folderNameLast,folderName,MY_MAX_PATH);
85        load_module(fileName);
86        update_song();
87        update_pattern(0);
88        update_sample();
89    }
90   
91    gtk_widget_hide(dialog);
92}
93
94static void play_mod ( GtkWidget *widget,
95                     gpointer   data )
96{
97        stop_playback();
98        play_start();
99        start_playback();
100}
101
102static void stop_mod ( GtkWidget *widget,
103                     gpointer   data )
104{
105        stop_playback();
106}
107
108static void play_atstart ( GtkWidget *widget,
109                     gpointer   data )
110{
111        stop_playback();
112        play_start();
113        start_playback();
114}
115
116static void play_rewind ( GtkWidget *widget,
117                     gpointer   data )
118{
119        stop_playback();
120        play_prev_pattern();
121        start_playback();
122}
123
124static void play_forward ( GtkWidget *widget,
125                     gpointer   data )
126{
127        stop_playback();
128        play_next_pattern();
129        start_playback();
130}
131
132
133void get_main_menu( GtkWidget  *window,
134                    GtkWidget **menuBar
135                     )
136{
137    GtkWidget *menu;
138    GtkWidget *filemenu;
139    GtkWidget *file;
140    GtkWidget *new;
141    GtkWidget *open;
142    GtkWidget *export;
143    GtkWidget *quit;
144
145    GtkWidget *sep;
146
147    GtkAccelGroup *accel_group = NULL;
148
149    menu = gtk_menu_new ();
150   
151    *menuBar = gtk_menu_bar_new();
152    filemenu = gtk_menu_new();
153
154    accel_group = gtk_accel_group_new();
155    gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
156
157    file = gtk_menu_item_new_with_mnemonic("_File");
158//    new = gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW, NULL);
159    open = gtk_image_menu_item_new_from_stock("Open module", NULL);
160    export = gtk_image_menu_item_new_from_stock("Export", NULL);
161    sep = gtk_separator_menu_item_new();
162    quit = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, accel_group);
163
164    gtk_widget_add_accelerator(quit, "activate", accel_group,
165        GDK_KEY_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
166
167
168    gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), filemenu);
169//    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), new);
170    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), open);
171    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), export);
172    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), sep);
173    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), quit);
174    gtk_menu_shell_append(GTK_MENU_SHELL(*menuBar), file);
175
176    g_signal_connect_swapped(G_OBJECT(window), "destroy",
177        G_CALLBACK(gtk_main_quit), NULL);
178
179    g_signal_connect(G_OBJECT(quit), "activate",
180        G_CALLBACK(gtk_main_quit), NULL);
181    g_signal_connect(G_OBJECT(open), "activate",
182        G_CALLBACK(open_mod_file),"from_menu");
183       
184}
185
186
187void get_main_toolbar( GtkWidget  *window,
188                    GtkWidget **toolBar
189                     )
190{
191    GtkWidget *open;
192    GtkWidget *export;
193    GtkWidget *sep;
194    GtkWidget *mediaStart;
195    GtkWidget *mediaRewind;
196    GtkWidget *mediaPlay;
197    GtkWidget *mediaStop;
198    GtkWidget *mediaForward;
199    *toolBar = gtk_toolbar_new();
200    gtk_toolbar_set_style(GTK_TOOLBAR(*toolBar), GTK_TOOLBAR_ICONS);
201
202    gtk_container_set_border_width(GTK_CONTAINER(*toolBar), 2);
203
204    open = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN);
205    gtk_toolbar_insert(GTK_TOOLBAR(*toolBar), GTK_TOOL_ITEM(open), -1);
206
207    export = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE);
208    gtk_toolbar_insert(GTK_TOOLBAR(*toolBar), GTK_TOOL_ITEM(export), -1);
209   
210    sep = gtk_separator_tool_item_new();
211    gtk_toolbar_insert(GTK_TOOLBAR(*toolBar), GTK_TOOL_ITEM(sep), -1);
212   
213
214    mediaStart = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PREVIOUS);
215    gtk_toolbar_insert(GTK_TOOLBAR(*toolBar), GTK_TOOL_ITEM(mediaStart), -1);
216
217
218    mediaRewind = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_REWIND);
219    gtk_toolbar_insert(GTK_TOOLBAR(*toolBar), GTK_TOOL_ITEM(mediaRewind), -1);
220
221
222    mediaPlay = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PLAY);
223    gtk_toolbar_insert(GTK_TOOLBAR(*toolBar), GTK_TOOL_ITEM(mediaPlay), -1);
224
225
226    mediaStop = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_STOP);
227    gtk_toolbar_insert(GTK_TOOLBAR(*toolBar), GTK_TOOL_ITEM(mediaStop), -1);
228
229    mediaForward = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_FORWARD);
230    gtk_toolbar_insert(GTK_TOOLBAR(*toolBar), GTK_TOOL_ITEM(mediaForward), -1);
231
232    g_signal_connect(G_OBJECT(open), "clicked",
233        G_CALLBACK(open_mod_file),"from_toolbar");
234
235    g_signal_connect(G_OBJECT(mediaPlay), "clicked",
236        G_CALLBACK(play_mod),"from_toolbar");
237
238    g_signal_connect(G_OBJECT(mediaStop), "clicked",
239        G_CALLBACK(stop_mod),"from_toolbar");
240
241    g_signal_connect(G_OBJECT(mediaRewind), "clicked",
242        G_CALLBACK(play_rewind),"from_toolbar");
243
244    g_signal_connect(G_OBJECT(mediaForward), "clicked",
245        G_CALLBACK(play_forward),"from_toolbar");
246
247    g_signal_connect(G_OBJECT(mediaStart), "clicked",
248        G_CALLBACK(play_atstart),"from_toolbar");
249   
250}
251
252
253static  GtkWidget *song_view;
254static  GtkListStore *list_store_song;
255
256enum {
257        SONG_INDEX=0,
258        SONG_PATTERN,
259        NB_COL
260};
261
262volatile int song_updating=FALSE;
263gboolean
264select_pattern (GtkTreeSelection *selection,
265                     GtkTreeModel     *model,
266                     GtkTreePath      *path,
267                     gboolean          path_currently_selected,
268                     gpointer          userdata)
269{
270        GtkTreeIter iter;
271 
272    if (gtk_tree_model_get_iter(model, &iter, path))
273    {
274                int song_pattern;
275 
276                gtk_tree_model_get(model, &iter, SONG_PATTERN, &song_pattern, -1);
277 
278                if (!path_currently_selected)
279                {
280                        // g_print ("%d is going to be selected.\n", sample_index);
281                        cur_pattern=song_pattern;
282                        update_pattern(cur_pattern);
283                }
284                else
285                {
286                        // g_print ("%s is going to be unselected.\n", name);
287                }
288 
289        }
290 
291    return TRUE; /* allow selection state to change */
292}
293
294void
295update_song_pos(int i) {
296        GtkTreeSelection *selection;
297        GtkTreePath *path;
298       
299        if (song_updating) return;
300       
301        selection=gtk_tree_view_get_selection(song_view);
302        path=gtk_tree_path_new_from_indices(i,-1);
303        gtk_tree_view_scroll_to_cell(song_view,path,NULL,FALSE,1.0,1.0);
304       
305        gtk_tree_selection_select_path(selection,path);
306       
307        gtk_tree_path_free(path);
308       
309}
310
311void
312update_song(void) {
313        int loop;
314        GtkTreeIter   iter;
315        static  GtkListStore *list_store_song_new;
316
317        song_updating=TRUE;
318       
319        list_store_song_new = gtk_list_store_new (2, G_TYPE_UINT, G_TYPE_UINT);
320
321        for (loop=0;loop<128;loop++) {
322                gtk_list_store_append(list_store_song_new, &iter);
323
324                gtk_list_store_set (list_store_song_new, &iter,
325                                                        SONG_INDEX, (guint)loop,
326                                                        SONG_PATTERN, (guint)get_song_pattern(loop),
327                                                        -1);   
328        }
329
330        gtk_tree_view_set_model(GTK_TREE_VIEW(song_view), GTK_TREE_MODEL(list_store_song_new));
331
332        g_object_unref(list_store_song);
333       
334        list_store_song=list_store_song_new;
335        song_updating=FALSE;
336}
337
338void get_song ( GtkWidget  *box
339                     ) {
340        GtkWidget *widget;
341        GtkTreeViewColumn   *col;
342        GtkCellRenderer     *renderer;
343        GtkTreeIter   iter;
344    GtkTreeSelection  *selection;
345 
346        int loop;
347
348        list_store_song = gtk_list_store_new (2, G_TYPE_UINT, G_TYPE_UINT);     
349
350        for (loop=0;loop<128;loop++) {
351                gtk_list_store_append(list_store_song, &iter);
352
353                gtk_list_store_set (list_store_song, &iter,
354                                                        SONG_INDEX, (guint)loop,
355                                                        SONG_PATTERN, (guint)0,
356                                                        -1);   
357        }
358
359
360        song_view = gtk_tree_view_new();       
361       
362        /* --- Column #1 --- */
363
364        col = gtk_tree_view_column_new();       
365        gtk_tree_view_column_set_title(col, "Num");
366
367        gtk_tree_view_append_column(GTK_TREE_VIEW(song_view), col);
368
369        renderer = gtk_cell_renderer_text_new();
370
371        /* pack cell renderer into tree view column */
372        gtk_tree_view_column_pack_start(col, renderer, TRUE);
373        gtk_tree_view_column_add_attribute(col, renderer, "text", SONG_INDEX);
374
375        /* --- Column #2 --- */
376
377        col = gtk_tree_view_column_new();
378
379        gtk_tree_view_column_set_title(col, "Pattern");
380
381        gtk_tree_view_append_column(GTK_TREE_VIEW(song_view), col);
382
383        renderer = gtk_cell_renderer_text_new();
384
385        /* pack cell renderer into tree view column */
386        gtk_tree_view_column_pack_start(col, renderer, TRUE);
387        gtk_tree_view_column_add_attribute(col, renderer, "text", SONG_PATTERN);
388               
389       
390        gtk_tree_view_set_model(GTK_TREE_VIEW(song_view), GTK_TREE_MODEL(list_store_song));
391
392        gtk_widget_show(song_view);
393
394    widget=gtk_scrolled_window_new (NULL, NULL);
395    gtk_scrolled_window_set_min_content_height((GtkScrolledWindow*)widget,150);
396
397    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget),
398                                   GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
399
400    gtk_container_add(GTK_CONTAINER(widget), song_view);
401                                         
402    gtk_box_pack_start( GTK_BOX(box), widget, TRUE, TRUE, 0);
403
404        selection=gtk_tree_view_get_selection(song_view);
405        gtk_tree_selection_set_select_function(selection, select_pattern, NULL, NULL);
406
407}
408
409static  GtkWidget *sample_view;
410static  GtkListStore *list_store_sample;
411
412enum {
413        SAMPLE_INDEX=0,
414        SAMPLE_NAME,
415        SAMPLE_LEN,
416        SAMPLE_HIT,
417        SAMPLE_NOTES,
418        NB_COL_SAMPLE
419};
420
421volatile int sample_updating=FALSE;
422
423gboolean
424select_sample (GtkTreeSelection *selection,
425                     GtkTreeModel     *model,
426                     GtkTreePath      *path,
427                     gboolean          path_currently_selected,
428                     gpointer          userdata)
429{
430        GtkTreeIter iter;
431 
432    if (gtk_tree_model_get_iter(model, &iter, path))
433    {
434                int sample_index;
435 
436                gtk_tree_model_get(model, &iter, SAMPLE_INDEX, &sample_index, -1);
437 
438                if (!path_currently_selected)
439                {
440                        // g_print ("%d is going to be selected.\n", sample_index);
441                        cur_sample=sample_index;
442                        gtk_widget_queue_draw(sample_drawing_area);
443                }
444                else
445                {
446                        // g_print ("%s is going to be unselected.\n", name);
447                }
448 
449        }
450 
451    return TRUE; /* allow selection state to change */
452}
453
454void
455update_sample(void) {
456        int loop;
457        GtkTreeIter   iter;
458        static  GtkListStore *list_store_sample_new;
459
460        sample_updating=TRUE;
461       
462        list_store_sample_new = gtk_list_store_new (5, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);     
463
464        for (loop=1;loop<get_nb_sample()+1;loop++) {
465                gtk_list_store_append(list_store_sample_new, &iter);
466
467                gtk_list_store_set (list_store_sample_new, &iter,
468                                                        SAMPLE_INDEX, (guint)loop,
469                                                        SAMPLE_NAME, (guint)get_sample_name(loop),
470                                                        SAMPLE_LEN, (guint)get_sample_size(loop),
471                                                        SAMPLE_HIT, (guint)get_sample_hit(loop),
472                                                        SAMPLE_NOTES, (guint)get_sample_pitch_hit(loop),
473                                                        -1);   
474        }
475
476        gtk_tree_view_set_model(GTK_TREE_VIEW(sample_view), GTK_TREE_MODEL(list_store_sample_new));
477
478        g_object_unref(list_store_sample);
479       
480        list_store_sample=list_store_sample_new;
481        sample_updating=FALSE;
482}
483
484void get_sample ( GtkWidget  *box
485                     ) {
486        GtkWidget *widget;
487        GtkTreeViewColumn   *col;
488        GtkCellRenderer     *renderer;
489        GtkTreeIter   iter;
490    GtkTreeSelection  *selection;
491     
492        int loop;
493
494        list_store_sample = gtk_list_store_new (5, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); 
495
496        for (loop=1;loop<32;loop++) {
497                gtk_list_store_append(list_store_sample, &iter);
498
499                gtk_list_store_set (list_store_sample, &iter,
500                                                        SAMPLE_INDEX, (guint)loop,
501                                                        SAMPLE_NAME, "",
502                                                        SAMPLE_LEN, 0,
503                                                        SAMPLE_HIT, 0,
504                                                        SAMPLE_NOTES, 0,
505                                                        -1);   
506        }
507
508
509        sample_view = gtk_tree_view_new();     
510       
511        /* --- Column #1 --- */
512
513        col = gtk_tree_view_column_new();       
514        gtk_tree_view_column_set_title(col, "Num");
515
516        gtk_tree_view_append_column(GTK_TREE_VIEW(sample_view), col);
517
518        renderer = gtk_cell_renderer_text_new();
519
520        /* pack cell renderer into tree view column */
521        gtk_tree_view_column_pack_start(col, renderer, TRUE);
522        gtk_tree_view_column_add_attribute(col, renderer, "text", SAMPLE_INDEX);
523
524        /* --- Column #2 --- */
525
526        col = gtk_tree_view_column_new();
527
528        gtk_tree_view_column_set_title(col, "Sample");
529
530        gtk_tree_view_append_column(GTK_TREE_VIEW(sample_view), col);
531
532        renderer = gtk_cell_renderer_text_new();
533
534        /* pack cell renderer into tree view column */
535        gtk_tree_view_column_pack_start(col, renderer, TRUE);
536        gtk_tree_view_column_add_attribute(col, renderer, "text", SAMPLE_NAME);
537
538        /* --- Column #3 --- */
539
540        col = gtk_tree_view_column_new();
541
542        gtk_tree_view_column_set_title(col, "Length");
543
544        gtk_tree_view_append_column(GTK_TREE_VIEW(sample_view), col);
545
546        renderer = gtk_cell_renderer_text_new();
547
548        /* pack cell renderer into tree view column */
549        gtk_tree_view_column_pack_start(col, renderer, TRUE);
550        gtk_tree_view_column_add_attribute(col, renderer, "text", SAMPLE_LEN);
551
552        /* --- Column #4 --- */
553
554        col = gtk_tree_view_column_new();
555
556        gtk_tree_view_column_set_title(col, "Used");
557
558        gtk_tree_view_append_column(GTK_TREE_VIEW(sample_view), col);
559
560        renderer = gtk_cell_renderer_text_new();
561
562        /* pack cell renderer into tree view column */
563        gtk_tree_view_column_pack_start(col, renderer, TRUE);
564        gtk_tree_view_column_add_attribute(col, renderer, "text", SAMPLE_HIT);
565
566        /* --- Column #5 --- */
567
568        col = gtk_tree_view_column_new();
569
570        gtk_tree_view_column_set_title(col, "Notes");
571
572        gtk_tree_view_append_column(GTK_TREE_VIEW(sample_view), col);
573
574        renderer = gtk_cell_renderer_text_new();
575
576        /* pack cell renderer into tree view column */
577        gtk_tree_view_column_pack_start(col, renderer, TRUE);
578        gtk_tree_view_column_add_attribute(col, renderer, "text", SAMPLE_NOTES);
579               
580       
581        gtk_tree_view_set_model(GTK_TREE_VIEW(sample_view), GTK_TREE_MODEL(list_store_sample));
582
583        gtk_widget_show(sample_view);
584
585    widget=gtk_scrolled_window_new (NULL, NULL);
586    gtk_scrolled_window_set_min_content_height((GtkScrolledWindow*)widget,150);
587
588    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget),
589                                   GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
590
591    gtk_container_add(GTK_CONTAINER(widget), sample_view);
592                                         
593    gtk_box_pack_start( GTK_BOX(box), widget, TRUE, TRUE, 0);
594
595        selection=gtk_tree_view_get_selection(sample_view);
596        gtk_tree_selection_set_select_function(selection, select_sample, NULL, NULL);
597
598}
599
600
601void get_main_upper_panel ( GtkWidget  *window,
602                    GtkWidget **upperPanel
603                     ) {
604    GtkWidget *songBox;
605    GtkWidget *dialogBox;
606    GtkWidget *voicesBox;
607    GtkWidget *mixBox;
608        GtkWidget *sampleBox;
609       
610    GtkWidget *separator;
611       
612    *upperPanel=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
613   
614    songBox=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
615    gtk_box_pack_start( GTK_BOX(*upperPanel), songBox, FALSE, FALSE, 0);
616
617        get_song(songBox);
618
619    separator = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
620    gtk_box_pack_start( GTK_BOX(*upperPanel), separator, FALSE, FALSE, 0);
621       
622    dialogBox=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
623    gtk_box_pack_start( GTK_BOX(*upperPanel), dialogBox, FALSE, FALSE, 0);
624
625    separator = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
626    gtk_box_pack_start( GTK_BOX(*upperPanel), separator, FALSE, FALSE, 0);
627
628    voicesBox=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
629    gtk_box_pack_start( GTK_BOX(*upperPanel), voicesBox, FALSE, FALSE, 0);
630
631    separator = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
632    gtk_box_pack_start( GTK_BOX(*upperPanel), separator, FALSE, FALSE, 0);
633
634    mixBox=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
635    gtk_box_pack_start( GTK_BOX(*upperPanel), mixBox, FALSE, FALSE, 0);
636
637    separator = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
638    gtk_box_pack_start( GTK_BOX(*upperPanel), separator, FALSE, FALSE, 0);
639
640    sampleBox=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
641    gtk_box_pack_start( GTK_BOX(*upperPanel), sampleBox, FALSE, FALSE, 0);
642
643        get_sample(sampleBox);
644       
645}
646
647static GtkWidget *pattern_text_view;
648static GtkTextBuffer *pattern_text_buffer;
649
650static  GtkWidget *pattern_view;
651static  GtkListStore *list_store_pattern;
652
653enum {
654        PATTERN_INDEX=0,
655        PATTERN_CONTENT,
656        NB_COL_PATTERN
657};
658
659volatile int pattern_updating=FALSE;
660
661void
662update_pattern_pos(int i) {
663        GtkTreeSelection *selection;
664        GtkTreePath *path;
665       
666        if (pattern_updating) return;
667        selection=gtk_tree_view_get_selection(pattern_view);
668        path=gtk_tree_path_new_from_indices(i,-1);
669       
670        gtk_tree_selection_select_path(selection,path);
671        gtk_tree_view_scroll_to_cell(pattern_view,path,NULL,FALSE,1.0,1.0);
672        gtk_tree_path_free(path);
673}
674
675
676void
677update_pattern(int patnum) {
678        int loop;
679        GtkTreeIter   iter;
680        static  GtkListStore *list_store_pattern_new;
681       
682        pattern_updating=TRUE;
683       
684        list_store_pattern_new = gtk_list_store_new (2, G_TYPE_UINT, G_TYPE_STRING);   
685
686        for (loop=0;loop<64;loop++) {
687                gtk_list_store_append(list_store_pattern_new, &iter);
688
689                gtk_list_store_set (list_store_pattern_new, &iter,
690                                                        PATTERN_INDEX, (guint)loop,
691                                                        PATTERN_CONTENT, get_pattern_line(patnum,loop),
692                                                        -1);   
693        }
694
695        gtk_tree_view_set_model(GTK_TREE_VIEW(pattern_view), GTK_TREE_MODEL(list_store_pattern_new));
696
697        g_object_unref(list_store_pattern);
698       
699        list_store_pattern=list_store_pattern_new;
700        pattern_updating=FALSE;
701}
702
703void get_pattern ( GtkWidget  *box
704                     ) {
705        GtkWidget *widget;
706        GtkTreeViewColumn   *col;
707        GtkCellRenderer     *renderer;
708        GtkTreeIter   iter;
709 
710        int loop;
711
712        list_store_pattern = gtk_list_store_new (2, G_TYPE_UINT, G_TYPE_STRING);       
713
714        for (loop=0;loop<64;loop++) {
715                gtk_list_store_append(list_store_pattern, &iter);
716
717                gtk_list_store_set (list_store_pattern, &iter,
718                                                        PATTERN_INDEX, (guint)loop,
719                                                        PATTERN_CONTENT, get_pattern_line(0,loop),
720                                                        -1);   
721        }
722
723        pattern_view = gtk_tree_view_new();     
724       
725        /* --- Column #1 --- */
726
727        col = gtk_tree_view_column_new();       
728        gtk_tree_view_column_set_title(col, "Num");
729
730        gtk_tree_view_append_column(GTK_TREE_VIEW(pattern_view), col);
731
732        renderer = gtk_cell_renderer_text_new();
733
734        /* pack cell renderer into tree view column */
735        gtk_tree_view_column_pack_start(col, renderer, TRUE);
736        gtk_tree_view_column_add_attribute(col, renderer, "text", PATTERN_INDEX);
737
738        /* --- Column #2 --- */
739
740        col = gtk_tree_view_column_new();
741
742        gtk_tree_view_column_set_title(col, "Pattern");
743
744        gtk_tree_view_append_column(GTK_TREE_VIEW(pattern_view), col);
745
746        renderer = gtk_cell_renderer_text_new();
747
748        /* pack cell renderer into tree view column */
749        gtk_tree_view_column_pack_start(col, renderer, TRUE);
750        gtk_tree_view_column_add_attribute(col, renderer, "text", PATTERN_CONTENT);
751    g_object_set(renderer,
752               "family", "Monospace",
753               "cell-family-set", TRUE,
754               NULL);                   
755       
756        gtk_tree_view_set_model(GTK_TREE_VIEW(pattern_view), GTK_TREE_MODEL(list_store_pattern));
757
758        gtk_widget_show(pattern_view);
759
760    widget=gtk_scrolled_window_new (NULL, NULL);
761
762    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget),
763                                   GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
764
765    gtk_container_add(GTK_CONTAINER(widget), pattern_view);
766    gtk_box_pack_start( GTK_BOX(box), widget, TRUE, TRUE, 0);
767   
768}
769
770gboolean
771sample_draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data) {
772        guint width, height;
773        GdkRGBA color;
774        float *tab;
775        int loop;
776
777        width = gtk_widget_get_allocated_width (widget);
778        height = gtk_widget_get_allocated_height (widget);
779 
780        tab=get_sample_preview(cur_sample,width,4);
781        if (tab==NULL) return FALSE;
782       
783        cairo_set_line_width (cr, .5);
784        cairo_set_source_rgb(cr, 1, 0, 0);
785       
786        cairo_move_to(cr,0*1.0,(height*(tab[0]+1.0))/2.0);
787        for (loop=1;loop<width;loop++) {
788                cairo_line_to(cr,loop*1.0,(height*(tab[loop]+1.0))/2.0);
789        }
790        cairo_stroke(cr);
791       
792
793        return FALSE;
794}
795
796void get_main_lower_panel ( GtkWidget  *window,
797                    GtkWidget **lowerPanel
798                     ) {
799        GtkWidget *notebook;
800    GtkWidget *frame;
801    GtkWidget *widget;
802    GtkWidget *pattern;
803    GtkWidget *content;
804
805   
806    *lowerPanel = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
807    notebook=gtk_notebook_new();
808    gtk_box_pack_start( GTK_BOX(*lowerPanel), notebook, TRUE, TRUE, 0);
809
810        /* the pattern panel */
811    frame=gtk_frame_new("");
812    gtk_frame_set_shadow_type( GTK_FRAME(frame), GTK_SHADOW_NONE);
813    gtk_frame_set_label_align( GTK_FRAME(frame), 0.985, 0.0);
814    widget=gtk_label_new("Pattern");
815    gtk_notebook_append_page( GTK_NOTEBOOK(notebook), frame, widget);
816
817    content=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
818    gtk_container_add( GTK_CONTAINER(frame), content);
819
820        get_pattern(content);
821
822        /* the sample panel */
823    frame=gtk_frame_new("");
824    gtk_frame_set_shadow_type( GTK_FRAME(frame), GTK_SHADOW_NONE);
825    gtk_frame_set_label_align( GTK_FRAME(frame), 0.985, 0.0);
826    widget=gtk_label_new("Sample");
827    gtk_notebook_append_page( GTK_NOTEBOOK(notebook), frame, widget);
828
829    content=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
830    gtk_container_add( GTK_CONTAINER(frame), content);
831
832        /* for now just the cairo drawing area */
833        sample_drawing_area = gtk_drawing_area_new ();
834        gtk_widget_set_size_request (sample_drawing_area, 50, 50);
835        g_signal_connect (G_OBJECT (sample_drawing_area), "draw",
836                    G_CALLBACK (sample_draw_callback), NULL);
837
838    gtk_box_pack_start( GTK_BOX(content), sample_drawing_area, TRUE, TRUE, 0);
839       
840}
841
842static gint timer = 0;
843volatile int timer_updating=FALSE;
844
845/*
846 * do update in a non blocking timer to avoid conflicts with gtk_main()
847 */
848gint TimerCallback (gpointer data)
849{
850        static int old_song_pos=-1,song_pos;
851        static int old_patnum=-1,patnum;
852        static int old_note=-1,note;
853
854        if (timer_updating) return;
855       
856        timer_updating=TRUE;
857
858        where_am_i(&song_pos,&patnum,&note);
859        if (old_patnum!=patnum) {
860                    update_pattern(patnum);
861                        old_patnum=patnum;
862        }
863        if (old_note!=note) {
864                    update_pattern_pos(note);
865                        old_note=note;
866        }
867        if (old_song_pos!=song_pos) {
868                    update_song_pos(song_pos);
869                        old_song_pos=song_pos;
870        }
871        timer_updating=FALSE;
872       
873    return 1; // NOTE: Needs to be non-zero otherwise timer will stop
874}
875
876int main( int   argc,
877          char *argv[] )
878{
879    GtkWidget *button;
880    GtkWidget *mainVbox;
881    GtkWidget *menuBar;
882    GtkWidget *toolBar;
883    GtkWidget *upperPanel;
884    GtkWidget *lowerPanel;
885 
886    gtk_init (&argc, &argv);
887   
888
889    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
890    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
891    gtk_window_set_default_size(GTK_WINDOW(window), 600, 400);
892    gtk_window_set_title(GTK_WINDOW(window), "VitalMotion min tracker");
893   
894    g_signal_connect (window, "delete-event",
895                      G_CALLBACK (delete_event), NULL);
896   
897    g_signal_connect (window, "destroy",
898                      G_CALLBACK (destroy), NULL);
899       
900    mainVbox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
901    gtk_container_add (GTK_CONTAINER (window), mainVbox);
902    gtk_widget_show (mainVbox);
903 
904    get_main_menu (window, &menuBar);
905    gtk_box_pack_start (GTK_BOX (mainVbox), menuBar, FALSE, TRUE, 0);
906 
907    get_main_toolbar (window, &toolBar);
908    gtk_box_pack_start (GTK_BOX (mainVbox), toolBar, FALSE, TRUE, 0);
909
910    get_main_upper_panel (window, &upperPanel);
911    gtk_box_pack_start (GTK_BOX (mainVbox), upperPanel, FALSE, TRUE, 0);
912
913    get_main_lower_panel (window, &lowerPanel);
914    gtk_box_pack_start (GTK_BOX (mainVbox), lowerPanel, TRUE, TRUE, 0);
915 
916    gtk_widget_show_all (window);
917   
918    update_song();
919   
920    timer = g_timeout_add (10, TimerCallback, NULL);
921               
922    gtk_main ();
923   
924    return 0;
925}
926
Note: See TracBrowser for help on using the repository browser.