fixup
[colorize.git] / gui / main.c
1 #include <gtk/gtk.h>
2 #include <gdk/gdkkeysyms.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <stdarg.h>
6 #include "../src/mark.h"
7 #ifdef WITH_OPENCV
8 #include "../src/opticalflow.h"
9 #endif
10 #include "main.h"
11 #include "menu.h"
12 #include "toolbar.h"
13 #include "image.h"
14 #include "palette.h"
15 #include "timeline.h"
16 #include "colorize.h"
17 #include "brightcontrast.h"
18 #include "level.h"
19 #include "fill.h"
20 #ifdef WITH_OPENCV
21 #include "flow.h"
22 #endif
23
24 #define CC_APP_TITLE "Colorize GTK"
25 GtkWidget *main_window;
26 GtkWidget *img_scroll;
27 GtkWidget *img_drawing_area = NULL;
28 GtkWidget *timeline_drawing_area;
29 GtkWidget *timeline_scroll;
30 GtkWidget *palette_treeview = NULL;
31 GtkLabel *img_label;
32 GtkToggleButton *show_marked_button, *show_highlighted_button, *show_preview_button, *show_colorized_button;
33 #ifdef WITH_OPENCV
34 GtkToggleButton *show_flow_button;
35 #endif
36 int button_down = 0, button_down_x = -1000, button_down_y = -1000, shift_pressed = 0, button_num = 1;
37 int brush_size;
38 int mark = 1, highlight = 0, preview = 0, rendered = 0, draw_mode = 1, move_mode = 0, fill_mode = 0, pick_mode = 0, flowview = 0;
39 int mouse_over_palette_area = 0, mouse_over_drawing_area = 0, mouse_over_timeline_area = 0;
40 #define min(x,y) ((x < y) ? x : y)
41 #define abs(x,y) ((x < y) ? y - x : x - y)
42
43 /* error requester */
44 void printerror(const char *fmt, ...)
45 {
46         char buffer[4096];
47         va_list args;
48
49         va_start(args,fmt);
50         vsprintf(buffer,fmt,args);
51         buffer[sizeof(buffer)-1]=0;
52         va_end(args);
53
54         GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(main_window),
55                 GTK_DIALOG_DESTROY_WITH_PARENT,
56                 GTK_MESSAGE_ERROR,
57                 GTK_BUTTONS_CLOSE,
58                 "%s", buffer);
59         gtk_dialog_run (GTK_DIALOG (dialog));
60         gtk_widget_destroy (dialog);
61 }
62
63 static int already_destroyed = 0;
64
65 /* exit program and save current mask / palette */
66 void main_destroy(void)
67 {
68         if (anything_modified) {
69                 int ret;
70                 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(main_window),
71                         GTK_DIALOG_DESTROY_WITH_PARENT,
72                         GTK_MESSAGE_ERROR,
73                         GTK_BUTTONS_OK_CANCEL,
74                         "Image has been changed, really quit?");
75                 ret = gtk_dialog_run(GTK_DIALOG (dialog));
76                 gtk_widget_destroy(dialog);
77                 if (ret != GTK_RESPONSE_OK)
78                         return;
79         }
80         already_destroyed = 1;
81         gtk_main_quit();
82 }
83
84
85 static void destroy(GtkWidget *widget, gpointer data)
86 {
87         if (!already_destroyed)
88                 main_destroy();
89 }
90
91 /*
92  * keypress
93  */
94
95 /* event handler for main window keys */
96 static gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
97 {
98         int frame;
99
100 //      if (mouse_over_palette_area)
101         if (!mouse_over_drawing_area && !mouse_over_timeline_area)
102                 return FALSE;
103
104         switch (event->keyval) {
105         case GDK_q:
106         case GDK_w:
107                 if (event->state & GDK_CONTROL_MASK) {
108                         main_destroy();
109                         return TRUE;
110                 }
111                 break;
112         case GDK_Right:
113                 frame = timeline_selected + 1;
114                 if (event->state & GDK_SHIFT_MASK) {
115                         while(frame < timeline_frames && frame_list[frame].marked == 0 && frame_list[frame].keyframe == 0)
116                                 frame++;
117                 }
118                 if (frame < timeline_frames)
119                         timeline_select_and_save(timeline_selected, frame);
120                 return TRUE;
121         case GDK_Left:
122                 frame = timeline_selected - 1;
123                 if (event->state & GDK_SHIFT_MASK) {
124                         while(frame >= 0 && frame_list[frame].marked == 0 && frame_list[frame].keyframe == 0)
125                                 frame--;
126                 }
127                 if (frame >= 0)
128                         timeline_select_and_save(timeline_selected, frame);
129                 return TRUE;
130         case GDK_Home:
131                 frame = 0;
132                 timeline_select_and_save(timeline_selected, frame);
133                 return TRUE;
134         case GDK_End:
135                 frame = timeline_frames - 1;
136                 timeline_select_and_save(timeline_selected, frame);
137                 return TRUE;
138         case GDK_u:
139         case GDK_z:
140                 undo_event(NULL);
141                 return TRUE;
142         case GDK_r:
143                 redo_event(NULL);
144                 return TRUE;
145         case GDK_c:
146                 if (event->state & GDK_CONTROL_MASK) {
147                         copy_event(NULL);
148                         return TRUE;
149                 }
150                 break;
151         case GDK_v:
152                 if (event->state & GDK_CONTROL_MASK) {
153                         paste_event(NULL);
154                         return TRUE;
155                 }
156                 break;
157         case GDK_k:
158                 toggle_keyframe();
159                 return TRUE;
160         case GDK_Shift_L:
161         case GDK_Shift_R:
162                 shift_pressed = 1;
163                 break;
164 //      default:
165 //              printf("press %x\n", event->keyval);
166         }
167
168         return FALSE;
169 }
170
171 /* event handler for main window keys */
172 static gboolean on_key_release(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
173 {
174         switch (event->keyval) {
175         case GDK_Shift_L:
176         case GDK_Shift_R:
177                 shift_pressed = 0;
178                 break;
179 //      default:
180 //              printf("release %x\n", event->keyval);
181         }
182
183         return FALSE;
184 }
185
186 /*
187  * image area
188  */
189
190 /* events if mouse is over palette area */
191 static gboolean enter_palette_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
192 {
193         mouse_over_palette_area = 1;
194         return FALSE;
195 }
196 static gboolean leave_palette_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
197 {
198         mouse_over_palette_area = 0;
199         return FALSE;
200 }
201
202 /* events if mouse is over image area */
203 static gboolean enter_drawing_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
204 {
205         mouse_over_drawing_area = 1;
206         return FALSE;
207 }
208 static gboolean leave_drawing_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
209 {
210         mouse_over_drawing_area = 0;
211         return FALSE;
212 }
213
214 /* events if mouse is over timeline area */
215 static gboolean enter_timeline_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
216 {
217         mouse_over_timeline_area = 1;
218         return FALSE;
219 }
220 static gboolean leave_timeline_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
221 {
222         mouse_over_timeline_area = 0;
223         timeline_point(-1, -1);
224         return FALSE;
225 }
226
227 /* ugly non-bresenham.... */
228 static void draw_line(int x, int y, int paint)
229 {
230         double step_x = 0, step_y = 0;
231
232         if (abs(x,button_down_x) > abs(y,button_down_y)) {
233                 while(42) {
234                         if (button_down_x < x) {
235                                 step_x++;
236                                 step_y += (double)(button_down_y - y) / (double)(button_down_x - x);
237                         } else {
238                                 step_x--;
239                                 step_y -= (double)(button_down_y - y) / (double)(button_down_x - x);
240                         }
241                         paint_brush(button_down_x+step_x, button_down_y+step_y, brush_size, paint);
242                         draw_image(button_down_x+step_x-(brush_size*img_scale_x/16)+1, button_down_y+step_y-(brush_size*img_scale_y/16)+1, brush_size*2*img_scale_x/16, brush_size*2*img_scale_y/16);
243                         if (x == button_down_x+step_x)
244                                 break;
245                 }
246         } else {
247                 while(42) {
248                         if (y == button_down_y) /* no move at all */
249                                 break;
250                         if (button_down_y < y) {
251                                 step_y++;
252                                 step_x += (double)(button_down_x - x) / (double)(button_down_y - y);
253                         } else {
254                                 step_y--;
255                                 step_x -= (double)(button_down_x - x) / (double)(button_down_y - y);
256                         }
257                         paint_brush(button_down_x+step_x, button_down_y+step_y, brush_size, paint);
258                         draw_image(button_down_x+step_x-(brush_size*img_scale_x/16)+1, button_down_y+(step_y-brush_size*img_scale_y/16)+1, brush_size*2*img_scale_x/16, brush_size*2*img_scale_y/16);
259                         if (y == button_down_y+step_y)
260                                 break;
261                 }
262         }
263         paint_brush(x, y, brush_size, paint);
264         draw_image(x-(brush_size*img_scale_x/16)+1, y-(brush_size*img_scale_y/16)+1, brush_size*2*img_scale_x/16, brush_size*2*img_scale_y/16);
265         button_down_x = x;
266         button_down_y = y;
267 }
268
269 /* notify movement of mouse inside image area */
270 static gint motion_notify_event( GtkWidget *widget,
271                                  GdkEventMotion *event )
272 {
273         int x, y;
274         GdkModifierType state;
275
276         if (event->is_hint)
277                 gdk_window_get_pointer (event->window, &x, &y, &state);
278         else
279         {
280                 x = event->x;
281                 y = event->y;
282                 state = event->state;
283         }
284
285         if ((state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK))) {
286                 if (mark || highlight) {
287                         if (button_down && pick_mode) {
288                                 pick_color(x, y);
289                         }
290                         if (button_down && !pick_mode) {
291                                 if (move_mode) {
292                                         move_mark((x-button_down_x)*16/img_scale_x, (y-button_down_y)*16/img_scale_y);
293                                         draw_image(0, 0, -1, -1);
294                                 } else
295                                 if (draw_mode) {
296                                         draw_line(x, y, button_num == 1);
297                                 }
298                         }
299                 }
300         } else {
301                 if (button_down && pick_mode)
302                         release_pick_mode();
303                 button_down = 0;
304         }
305                                                                                    
306         return TRUE;
307 }
308
309 /* button press event inside image area */
310 static gint button_press_event (GtkWidget *widget, GdkEventButton *event)
311 {
312         int x,y;
313
314         x = event->x;
315         y = event->y;
316         button_num = event->button;
317
318         if (mark || highlight) {
319                 if (pick_mode) {
320                         pick_color(x, y);
321                 } else
322                 if (fill_mode) {
323                         if (button_down)
324                                 return TRUE;
325                         copy_mark_to_undo();
326                         fill(x, y, event->button != 1);
327                         draw_image(0, 0, -1, -1);
328                 } else
329                 if (move_mode) {
330                         if (button_down)
331                                 return TRUE;
332                         copy_mark_to_undo();
333                         button_down_x = x;
334                         button_down_y = y;
335                 } else
336                 if (draw_mode) {
337                         if (!button_down)
338                                 copy_mark_to_undo();
339                         /* if not shift, draw a dot and not a line */
340                         if (!shift_pressed || button_down_x == -1000) {
341                                 button_down_x = x;
342                                 button_down_y = y;
343                         }
344                         draw_line(x, y, button_num == 1);
345                 }
346                 button_down = 1;
347         }
348         return TRUE;
349 }
350
351 /* redraw event of image area */
352 static gint img_expose_event (GtkWidget *widget, GdkEventExpose *event)
353 {
354         draw_image(event->area.x, event->area.y, event->area.width, event->area.height);
355
356         return FALSE;
357 }
358
359 /*
360  * timeline
361  */
362
363 /* mouse move event inside timeline */
364 static gint timeline_motion_notify_event( GtkWidget *widget,
365                                  GdkEventMotion *event )
366 {
367         int x, y;
368         GdkModifierType state;
369
370         if (event->is_hint)
371                 gdk_window_get_pointer (event->window, &x, &y, &state);
372         else
373         {
374                 x = event->x;
375                 y = event->y;
376                 state = event->state;
377         }
378
379         timeline_point(x, y);
380
381         if ((state & GDK_BUTTON1_MASK)) {
382                 timeline_clicked(x, y);
383
384         }
385                                                                                    
386         return TRUE;
387 }
388
389 /* button press event inside timeline area */
390 static gint timeline_press_event (GtkWidget *widget, GdkEventButton *event)
391 {
392         int x,y;
393
394         x = event->x;
395         y = event->y;
396         timeline_clicked(x, y);
397
398         return TRUE;
399 }
400
401 /* redraw event of timeline area */
402 static gint timeline_expose_event (GtkWidget *widget, GdkEventExpose *event)
403 {
404         draw_timeline(event->area.x, event->area.y, event->area.width, event->area.height);
405
406         return FALSE;
407 }
408
409 /*
410  * colorselection
411  */
412
413 GtkWidget *colorseldlg = NULL;
414 GtkColorSelection *colorsel;
415 /* color selection's buttons have been pressed */
416 void color_response(GtkDialog *dialog, gint response_id, gpointer user_data)
417 {
418         GdkColor ncolor;
419
420         switch (response_id) {
421         case GTK_RESPONSE_CANCEL:
422                 gtk_color_selection_get_previous_color(colorsel, &ncolor);
423 new_color:
424                 anything_modified = 1;
425
426                 mark_palette[mark_selected].r = ncolor.red / 256;
427                 mark_palette[mark_selected].g = ncolor.green / 256;
428                 mark_palette[mark_selected].b = ncolor.blue / 256;
429                 update_color(mark_selected);
430                 draw_image(0, 0, -1, -1);
431                 break;
432         case GTK_RESPONSE_OK:
433                 gtk_color_selection_get_current_color(colorsel, &ncolor);
434                 goto new_color;
435         }
436 }
437
438 /*
439  * palette
440  */
441
442 /* palette entry has been clicked */
443 void palette_change(GtkTreeSelection *selection, gpointer data)
444 {
445         GtkTreeModel     *model;
446         GtkTreeIter       iter;
447
448         if (gtk_tree_selection_get_selected(selection, &model, &iter))
449         {
450                 gchar *name;
451
452                 gtk_tree_model_get (model, &iter, 0/*column*/, &name, -1);
453                 mark_selected = atoi(name) - 1;
454                 g_free(name);
455
456                 if (colorseldlg) {
457                         GdkColor color;
458
459                         color.red = mark_palette[mark_selected].r * 256 + 128;
460                         color.green = mark_palette[mark_selected].g * 256 + 128;
461                         color.blue = mark_palette[mark_selected].b * 256 + 128;
462
463                         if (colorseldlg) {
464                                 gtk_color_selection_set_previous_color (colorsel, &color);
465                                 gtk_color_selection_set_current_color (colorsel, &color);
466                         }
467                 }
468
469                 /* set current color for bightness+contrast window */
470                 bc_set_current();
471
472                 /* set current levels in window */
473                 level_set_current();
474
475                 if (highlight || preview)
476                         draw_image(0, 0, -1, -1);
477         }
478 }
479
480 /* name of palette entry has been entered */
481 void palette_edited(GtkCellRendererText *renderer, gchar *path, gchar *new_text, GtkTreeView *treeview)
482 {
483         anything_modified = 1;
484
485         /* copy string */
486         strncpy(mark_palette[mark_selected].name, new_text, sizeof(mark_palette[mark_selected].name));
487         mark_palette[mark_selected].name[sizeof(mark_palette[mark_selected].name)-1] = '\0';
488
489         /* store string */
490         GtkTreeIter iter;
491         GtkTreeModel *model;
492
493         model = gtk_tree_view_get_model (treeview);
494         if (gtk_tree_model_get_iter_from_string (model, &iter, path))
495                 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 2/*column*/, mark_palette[mark_selected].name, -1);
496
497         if (preview)
498                 draw_image(0, 0, -1, -1);
499 }
500
501 /*
502  * creation of main window
503  */
504
505 int main(int argc, char *argv[])
506 {
507         GtkWidget *vbox, *tool_bar;
508         GtkWidget *paned;
509         GtkWidget *pal_scroll;
510         GtkWidget *menu_bar;
511         GtkTreeSelection *selection;
512         GtkTreeViewColumn *palette_column;
513         GtkCellRenderer *palette_renderer;
514
515         gtk_init(&argc, &argv);
516
517         main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
518         gtk_widget_set_size_request(GTK_WIDGET(main_window), 400, 200);
519         gtk_window_set_default_size(GTK_WINDOW(main_window), 800, 500);
520         gtk_window_set_title(GTK_WINDOW(main_window), CC_APP_TITLE " Version "
521 #include "../version.h"
522         );
523         g_signal_connect(main_window, "delete-event", G_CALLBACK(destroy), NULL);
524         g_signal_connect(main_window, "destroy", G_CALLBACK(destroy), NULL);
525         g_signal_connect(main_window, "key-press-event", G_CALLBACK(on_key_press), NULL);
526         g_signal_connect(main_window, "key-release-event", G_CALLBACK(on_key_release), NULL);
527
528
529         gtk_container_set_border_width (GTK_CONTAINER (main_window), 2);
530
531         /* create vbox (complete window) */
532         vbox = gtk_vbox_new(FALSE, 0);
533         gtk_container_add(GTK_CONTAINER(main_window), vbox);
534         gtk_widget_show(vbox);
535
536         /* add menu to vbox (top of vbox) */
537         menu_bar = gtk_menu_bar_new();
538         gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 2);
539         gtk_widget_show(menu_bar);
540         create_menus(menu_bar);
541
542         /* add tool_bar to vbox (bottom part of palette box) */
543         tool_bar = gtk_hbox_new(FALSE, 0);
544         gtk_box_pack_start(GTK_BOX(vbox), tool_bar, FALSE, FALSE, 2);
545         gtk_widget_show(tool_bar);
546         create_toolbar(tool_bar);
547
548         /* add paned view to vbox (middle part of vbox) */
549         paned = gtk_hpaned_new ();
550         gtk_widget_show(paned);
551         gtk_box_pack_start(GTK_BOX(vbox), paned, TRUE, TRUE, 2);
552         gtk_paned_set_position(GTK_PANED (paned), 250);
553
554         /* add palette treeview to hbox (top part of palette box) */
555         palette_treeview = gtk_tree_view_new();
556         gtk_widget_set_size_request(palette_treeview, 250, 400);
557         g_signal_connect(palette_treeview, "enter_notify_event", G_CALLBACK(enter_palette_area), NULL);
558         g_signal_connect(palette_treeview, "leave_notify_event", G_CALLBACK(leave_palette_area), NULL);
559         gtk_widget_set_events(palette_treeview, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
560         gtk_widget_show(palette_treeview);
561
562         pal_scroll = gtk_scrolled_window_new(NULL, NULL);
563         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(pal_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
564         gtk_widget_show(pal_scroll);
565         gtk_container_add(GTK_CONTAINER(pal_scroll), palette_treeview);
566
567         palette_renderer = gtk_cell_renderer_text_new();
568         g_object_set(G_OBJECT(palette_renderer), "editable", FALSE, NULL);
569         palette_column = gtk_tree_view_column_new_with_attributes("", palette_renderer, "text", 0/*column*/, NULL);
570         gtk_tree_view_insert_column(GTK_TREE_VIEW(palette_treeview), GTK_TREE_VIEW_COLUMN(palette_column), 0/*column*/);
571
572         palette_renderer = gtk_cell_renderer_pixbuf_new();
573         palette_column = gtk_tree_view_column_new_with_attributes("", palette_renderer, "pixbuf", 1/*column*/, NULL);
574         gtk_tree_view_insert_column(GTK_TREE_VIEW(palette_treeview), GTK_TREE_VIEW_COLUMN(palette_column), 1/*column*/);
575
576         palette_renderer = gtk_cell_renderer_text_new();
577         g_object_set(G_OBJECT(palette_renderer), "editable", TRUE, NULL);
578         g_signal_connect(palette_renderer, "edited", (GCallback) palette_edited, palette_treeview);
579         palette_column = gtk_tree_view_column_new_with_attributes("", palette_renderer, "text", 2/*column*/, NULL);
580         gtk_tree_view_insert_column(GTK_TREE_VIEW(palette_treeview), GTK_TREE_VIEW_COLUMN(palette_column), 2/*column*/);
581
582         create_palette();
583
584         selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(palette_treeview));
585         g_signal_connect(selection, "changed", G_CALLBACK(palette_change), NULL);
586         gtk_paned_pack1 (GTK_PANED (paned), pal_scroll, FALSE, TRUE);
587
588         /* add drawing area (right of hbox) */
589         img_drawing_area = gtk_drawing_area_new ();
590         gtk_signal_connect(GTK_OBJECT(img_drawing_area), "motion_notify_event", (GtkSignalFunc)motion_notify_event, NULL);
591         gtk_signal_connect(GTK_OBJECT (img_drawing_area), "button_press_event", (GtkSignalFunc)button_press_event, NULL);
592         gtk_signal_connect(GTK_OBJECT (img_drawing_area), "expose_event", (GtkSignalFunc)img_expose_event, NULL); 
593         g_signal_connect(img_drawing_area, "enter_notify_event", G_CALLBACK(enter_drawing_area), NULL);
594         g_signal_connect(img_drawing_area, "leave_notify_event", G_CALLBACK(leave_drawing_area), NULL);
595         gtk_widget_set_events(img_drawing_area, GDK_EXPOSURE_MASK
596                 | GDK_ENTER_NOTIFY_MASK
597                 | GDK_LEAVE_NOTIFY_MASK
598                 | GDK_BUTTON_PRESS_MASK
599                 | GDK_POINTER_MOTION_MASK
600                 | GDK_POINTER_MOTION_HINT_MASK);
601         gtk_widget_show(img_drawing_area);
602
603         img_scroll = gtk_scrolled_window_new(NULL, NULL);
604         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(img_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
605         gtk_widget_show(img_scroll);
606         gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(img_scroll), img_drawing_area);
607         gtk_paned_pack2 (GTK_PANED (paned), img_scroll, TRUE, TRUE);
608
609 #if 0
610         /* add horizontal seperation to vbox */
611         separator = gtk_hseparator_new();
612         gtk_widget_show(separator);
613         gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 3);
614 #endif
615
616         /* add timeline (bottom of vbox) */
617         timeline_drawing_area = gtk_drawing_area_new ();
618         gtk_widget_set_size_request(timeline_drawing_area, 10, 10);
619         gtk_signal_connect(GTK_OBJECT(timeline_drawing_area), "motion_notify_event", (GtkSignalFunc)timeline_motion_notify_event, NULL);
620         gtk_signal_connect(GTK_OBJECT(timeline_drawing_area), "button_press_event", (GtkSignalFunc)timeline_press_event, NULL);
621         gtk_signal_connect(GTK_OBJECT(timeline_drawing_area), "expose_event", (GtkSignalFunc)timeline_expose_event, NULL); 
622         g_signal_connect(timeline_drawing_area, "enter_notify_event", G_CALLBACK(enter_timeline_area), NULL);
623         g_signal_connect(timeline_drawing_area, "leave_notify_event", G_CALLBACK(leave_timeline_area), NULL);
624         gtk_widget_set_events(timeline_drawing_area, GDK_EXPOSURE_MASK
625                 | GDK_ENTER_NOTIFY_MASK
626                 | GDK_LEAVE_NOTIFY_MASK
627                 | GDK_BUTTON_PRESS_MASK
628                 | GDK_POINTER_MOTION_MASK
629                 | GDK_POINTER_MOTION_HINT_MASK);
630         gtk_widget_show(timeline_drawing_area);
631         timeline_scroll = gtk_scrolled_window_new(NULL, NULL);
632         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(timeline_scroll), GTK_POLICY_ALWAYS, GTK_POLICY_NEVER);
633 //      gtk_widget_show(timeline_scroll);
634         gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(timeline_scroll), timeline_drawing_area);
635         gtk_box_pack_start(GTK_BOX(vbox), timeline_scroll, FALSE, FALSE, 0);
636
637         create_timeline(NULL);
638
639         /* label */
640         img_label = GTK_LABEL(gtk_label_new(NULL));
641         gtk_widget_show(GTK_WIDGET(img_label));
642         gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(img_label), FALSE, FALSE, 0);
643
644         /* show window */
645         gtk_widget_show(main_window);
646
647         /* enable some button/menu */
648         set_menu_toggel_by_label(TOGGLE_LABEL_MARK, mark);
649         set_button_toggel_by_label(TOGGLE_LABEL_MARK, mark);
650
651         if (argc > 1) {
652                 create_timeline(argv[1]);
653                 if (frame_list)
654                         create_image(frame_list[timeline_selected].filename, 1);
655         }
656
657         gtk_main();
658
659         // FIXME: destroy
660
661         return 0;
662 }
663