2 #include <gdk/gdkkeysyms.h>
6 #include "../src/mark.h"
8 #include "../src/opticalflow.h"
15 #include "brightcontrast.h"
22 #define CC_APP_TITLE "Colorize GTK"
23 GtkWidget *main_window;
24 GtkWidget *img_scroll;
25 GtkWidget *img_drawing_area = NULL;
26 GtkWidget *timeline_drawing_area;
27 GtkWidget *timeline_scroll;
28 GtkWidget *palette_treeview = NULL;
30 GtkToggleButton *show_highlighted_button, *show_preview_button, *show_colorized_button;
32 GtkToggleButton *show_flow_button;
34 int button_down = 0, button_down_x = -1000, button_down_y = -1000, shift_pressed = 0, button_num = 1;
36 int highlight = 0, preview = 0, rendered = 0, move_mode = 0, fill_mode = 0, flowview = 0;
37 int mouse_over_palette_area = 0, mouse_over_drawing_area = 0, mouse_over_timeline_area = 0;
38 #define min(x,y) ((x < y) ? x : y)
39 #define abs(x,y) ((x < y) ? y - x : x - y)
41 /* the labels are used to identify menu and button items */
43 TOGGLE_LABEL_NONE = 0,
44 TOGGLE_LABEL_HIGHLIGHT,
46 TOGGLE_LABEL_RENDERED,
47 TOGGLE_LABEL_FLOWVIEW,
48 TOGGLE_LABEL_ZOOMFIELDS,
51 static void set_button_toggel_by_label(enum toggle_label label, gboolean active);
54 void printerror(const char *fmt, ...)
60 vsprintf(buffer,fmt,args);
61 buffer[sizeof(buffer)-1]=0;
64 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(main_window),
65 GTK_DIALOG_DESTROY_WITH_PARENT,
69 gtk_dialog_run (GTK_DIALOG (dialog));
70 gtk_widget_destroy (dialog);
73 static int already_destroyed = 0;
75 /* exit program and save current mask / palette */
76 void main_destroy(void)
78 if (anything_modified) {
80 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(main_window),
81 GTK_DIALOG_DESTROY_WITH_PARENT,
83 GTK_BUTTONS_OK_CANCEL,
84 "Image has been changed, really quit?");
85 ret = gtk_dialog_run(GTK_DIALOG (dialog));
86 gtk_widget_destroy(dialog);
87 if (ret != GTK_RESPONSE_OK)
90 already_destroyed = 1;
95 static void destroy(GtkWidget *widget, gpointer data)
97 if (!already_destroyed)
105 static void undo_event(gpointer priv);
106 static void redo_event(gpointer priv);
107 static void copy_event(gpointer priv);
108 static void paste_event(gpointer priv);
110 /* event handler for main window keys */
111 static gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
115 // if (mouse_over_palette_area)
116 if (!mouse_over_drawing_area && !mouse_over_timeline_area)
119 switch (event->keyval) {
122 if (event->state & GDK_CONTROL_MASK) {
128 frame = timeline_selected + 1;
129 if (event->state & GDK_SHIFT_MASK) {
130 while(frame < timeline_frames && frame_list[frame].marked == 0 && frame_list[frame].keyframe == 0)
133 if (frame < timeline_frames)
134 timeline_select_and_save(timeline_selected, frame);
137 frame = timeline_selected - 1;
138 if (event->state & GDK_SHIFT_MASK) {
139 while(frame >= 0 && frame_list[frame].marked == 0 && frame_list[frame].keyframe == 0)
143 timeline_select_and_save(timeline_selected, frame);
147 timeline_select_and_save(timeline_selected, frame);
150 frame = timeline_frames - 1;
151 timeline_select_and_save(timeline_selected, frame);
161 if (event->state & GDK_CONTROL_MASK) {
167 if (event->state & GDK_CONTROL_MASK) {
180 // printf("press %x\n", event->keyval);
186 /* event handler for main window keys */
187 static gboolean on_key_release(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
189 switch (event->keyval) {
195 // printf("release %x\n", event->keyval);
205 /* events if mouse is over palette area */
206 static gboolean enter_palette_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
208 mouse_over_palette_area = 1;
211 static gboolean leave_palette_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
213 mouse_over_palette_area = 0;
217 /* events if mouse is over image area */
218 static gboolean enter_drawing_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
220 mouse_over_drawing_area = 1;
223 static gboolean leave_drawing_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
225 mouse_over_drawing_area = 0;
229 /* events if mouse is over timeline area */
230 static gboolean enter_timeline_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
232 mouse_over_timeline_area = 1;
235 static gboolean leave_timeline_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
237 mouse_over_timeline_area = 0;
238 timeline_point(-1, -1);
242 /* ugly non-bresenham.... */
243 static void draw_line(int x, int y, int paint)
245 double step_x = 0, step_y = 0;
247 if (abs(x,button_down_x) > abs(y,button_down_y)) {
249 if (button_down_x < x) {
251 step_y += (double)(button_down_y - y) / (double)(button_down_x - x);
254 step_y -= (double)(button_down_y - y) / (double)(button_down_x - x);
256 paint_brush(button_down_x+step_x, button_down_y+step_y, brush_size, paint);
257 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);
258 if (x == button_down_x+step_x)
263 if (y == button_down_y) /* no move at all */
265 if (button_down_y < y) {
267 step_x += (double)(button_down_x - x) / (double)(button_down_y - y);
270 step_x -= (double)(button_down_x - x) / (double)(button_down_y - y);
272 paint_brush(button_down_x+step_x, button_down_y+step_y, brush_size, paint);
273 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);
274 if (y == button_down_y+step_y)
278 paint_brush(x, y, brush_size, paint);
279 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);
284 /* notify movement of mouse inside image area */
285 static gint motion_notify_event( GtkWidget *widget,
286 GdkEventMotion *event )
289 GdkModifierType state;
292 gdk_window_get_pointer (event->window, &x, &y, &state);
297 state = event->state;
300 if ((state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK))) {
303 move_mark((x-button_down_x)*16/img_scale_x, (y-button_down_y)*16/img_scale_y);
304 draw_image(0, 0, -1, -1);
306 draw_line(x, y, button_num == 1);
316 /* button press event inside image area */
317 static gint button_press_event (GtkWidget *widget, GdkEventButton *event)
323 button_num = event->button;
328 fill(x, y, event->button != 1);
329 draw_image(0, 0, -1, -1);
337 /* if not shift, draw a dot and not a line */
338 if (!shift_pressed || button_down_x == -1000) {
342 draw_line(x, y, button_num == 1);
348 /* redraw event of image area */
349 static gint img_expose_event (GtkWidget *widget, GdkEventExpose *event)
351 draw_image(event->area.x, event->area.y, event->area.width, event->area.height);
360 /* mouse move event inside timeline */
361 static gint timeline_motion_notify_event( GtkWidget *widget,
362 GdkEventMotion *event )
365 GdkModifierType state;
368 gdk_window_get_pointer (event->window, &x, &y, &state);
373 state = event->state;
376 timeline_point(x, y);
378 if ((state & GDK_BUTTON1_MASK)) {
379 timeline_clicked(x, y);
386 /* button press event inside timeline area */
387 static gint timeline_press_event (GtkWidget *widget, GdkEventButton *event)
393 timeline_clicked(x, y);
398 /* redraw event of timeline area */
399 static gint timeline_expose_event (GtkWidget *widget, GdkEventExpose *event)
401 draw_timeline(event->area.x, event->area.y, event->area.width, event->area.height);
410 /* color selection's buttons have been pressed */
411 GtkWidget *colorseldlg = NULL;
412 GtkColorSelection *colorsel;
413 static void color_response(GtkDialog *dialog, gint response_id, gpointer user_data)
417 switch (response_id) {
418 case GTK_RESPONSE_CANCEL:
419 gtk_color_selection_get_previous_color(colorsel, &ncolor);
421 anything_modified = 1;
423 mark_palette[mark_selected].r = ncolor.red / 256;
424 mark_palette[mark_selected].g = ncolor.green / 256;
425 mark_palette[mark_selected].b = ncolor.blue / 256;
426 update_color(mark_selected);
427 draw_image(0, 0, -1, -1);
429 case GTK_RESPONSE_OK:
430 gtk_color_selection_get_current_color(colorsel, &ncolor);
439 static void open_event(gpointer priv)
442 char *filename = NULL;
444 if (anything_modified) {
446 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(main_window),
447 GTK_DIALOG_DESTROY_WITH_PARENT,
449 GTK_BUTTONS_OK_CANCEL,
450 "Image has been changed, really open new image?");
451 ret = gtk_dialog_run(GTK_DIALOG (dialog));
452 gtk_widget_destroy(dialog);
453 if (ret != GTK_RESPONSE_OK)
457 dialog = gtk_file_chooser_dialog_new("Select first grey image",
458 GTK_WINDOW(main_window),
459 GTK_FILE_CHOOSER_ACTION_OPEN,
460 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
461 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
465 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), frame_list[timeline_selected].filename);
466 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
467 filename = strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
470 gtk_widget_destroy(dialog);
473 // do not save timeline_select_and_save(timeline_selected, timeline_selected);
475 create_timeline(filename);
477 create_image(frame_list[timeline_selected].filename, 1);
483 static void save_event(gpointer priv)
485 timeline_select_and_save(timeline_selected, timeline_selected);
488 static void exit_event(gpointer priv)
493 static void color_changed(GtkWidget *widget, GtkColorSelection *colorsel)
497 static void undo_event(gpointer priv)
499 copy_undo_to_mark(0);
500 draw_image(0, 0, -1, -1);
503 static void redo_event(gpointer priv)
505 copy_undo_to_mark(1);
506 draw_image(0, 0, -1, -1);
509 static void copy_event(gpointer priv)
511 copy_color(mark_selected + 1);
514 static void copy_all_event(gpointer priv)
519 static void paste_event(gpointer priv)
523 draw_image(0, 0, -1, -1);
526 static void color_destroy(GtkWidget *widget, gpointer data)
531 static void palette_event(gpointer priv)
536 gtk_widget_destroy(colorseldlg);
541 color.red = mark_palette[mark_selected].r * 256 + 128;
542 color.green = mark_palette[mark_selected].g * 256 + 128;
543 color.blue = mark_palette[mark_selected].b * 256 + 128;
545 colorseldlg = gtk_color_selection_dialog_new("Select Color");
546 colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (colorseldlg)->colorsel);
547 gtk_color_selection_set_previous_color (colorsel, &color);
548 gtk_color_selection_set_current_color (colorsel, &color);
549 g_signal_connect(G_OBJECT(colorsel), "color_changed", G_CALLBACK(color_changed), (gpointer)colorsel);
550 g_signal_connect(G_OBJECT(colorseldlg), "response", G_CALLBACK(color_response), NULL);
551 g_signal_connect(G_OBJECT(colorseldlg), "destroy", G_CALLBACK(color_destroy), NULL);
554 gtk_widget_show(colorseldlg);
557 static void keyframe_event(gpointer priv)
562 static void erase_event(gpointer priv)
566 draw_image(0, 0, -1, -1);
569 static void erase_color_event(gpointer priv)
572 erase_mark(mark_selected + 1);
573 draw_image(0, 0, -1, -1);
576 static void zoom_in_event(gpointer priv)
578 if (img_scale_x < 64) {
579 int aspect = img_scale_y / img_scale_x;
581 img_scale_y = img_scale_x * aspect;
582 create_or_reset_pixbuf(0);
586 static void zoom_out_event(gpointer priv)
588 if (img_scale_x > 4) {
589 int aspect = img_scale_y / img_scale_x;
591 img_scale_y = img_scale_x * aspect;
592 create_or_reset_pixbuf(0);
596 static void zoom_100_event(gpointer priv)
600 create_or_reset_pixbuf(0);
603 static void zoom_field_event(gpointer priv)
605 if (gtk_check_menu_item_get_active((GtkCheckMenuItem *)priv))
606 img_scale_y = img_scale_x*2;
608 img_scale_y = img_scale_x;
609 create_or_reset_pixbuf(1);
612 static void show_highlighted_event(gpointer priv)
614 highlight = gtk_check_menu_item_get_active((GtkCheckMenuItem *)priv);
615 set_button_toggel_by_label(TOGGLE_LABEL_HIGHLIGHT, highlight);
618 static void show_preview_event(gpointer priv)
620 preview = gtk_check_menu_item_get_active((GtkCheckMenuItem *)priv);
621 set_button_toggel_by_label(TOGGLE_LABEL_PREVIEW, preview);
624 static void colorize_event(gpointer priv)
627 printerror("Disable colorized view first.");
632 printerror("Disable flow view first.");
640 static void show_colorized_event(gpointer priv)
642 if (timeline_frames > 1)
643 rendered = gtk_check_menu_item_get_active((GtkCheckMenuItem *)priv);
646 gtk_check_menu_item_set_active((GtkCheckMenuItem *)priv, rendered);
647 set_button_toggel_by_label(TOGGLE_LABEL_RENDERED, rendered);
651 static void show_flow_event(gpointer priv)
653 if (flow_enable && timeline_frames > 1)
654 flowview = gtk_check_menu_item_get_active((GtkCheckMenuItem *)priv);
657 gtk_check_menu_item_set_active((GtkCheckMenuItem *)priv, flowview);
658 set_button_toggel_by_label(TOGGLE_LABEL_FLOWVIEW, flowview);
662 static void dummy_event(gpointer priv)
666 struct my_menu_item {
667 enum toggle_label label;
670 void (*handler)(gpointer priv);
676 struct my_menu_item *items;
679 struct my_menu_item file_menu_items[] = {
680 { TOGGLE_LABEL_NONE, NULL, "Open", open_event, GTK_STOCK_OPEN },
681 { TOGGLE_LABEL_NONE, NULL, "Save", save_event, GTK_STOCK_SAVE },
682 { TOGGLE_LABEL_NONE, NULL, "", dummy_event, NULL },
683 { TOGGLE_LABEL_NONE, NULL, "Exit", exit_event, GTK_STOCK_QUIT },
684 { TOGGLE_LABEL_NONE, NULL, NULL, NULL }
687 struct my_menu_item edit_menu_items[] = {
688 { TOGGLE_LABEL_NONE, NULL, "Undo", undo_event, GTK_STOCK_UNDO },
689 { TOGGLE_LABEL_NONE, NULL, "Redo", redo_event, GTK_STOCK_REDO },
690 { TOGGLE_LABEL_NONE, NULL, "", dummy_event, NULL },
691 { TOGGLE_LABEL_NONE, NULL, "Copy", copy_event, GTK_STOCK_COPY },
692 { TOGGLE_LABEL_NONE, NULL, "Copy All", copy_all_event, NULL },
693 { TOGGLE_LABEL_NONE, NULL, "Paste", paste_event, GTK_STOCK_PASTE },
694 { TOGGLE_LABEL_NONE, NULL, "", dummy_event, NULL },
695 { TOGGLE_LABEL_NONE, NULL, "Palette", palette_event, NULL },
696 { TOGGLE_LABEL_NONE, NULL, "Bright/Contrast", bc_event, NULL },
697 { TOGGLE_LABEL_NONE, NULL, "Adjust Levels", level_event, NULL },
699 { TOGGLE_LABEL_NONE, NULL, "Optical Flow", flow_event, NULL },
701 { TOGGLE_LABEL_NONE, NULL, "", dummy_event, NULL },
702 { TOGGLE_LABEL_NONE, NULL, "Keyframe", keyframe_event, NULL },
703 { TOGGLE_LABEL_NONE, NULL, "", dummy_event, NULL },
704 { TOGGLE_LABEL_NONE, NULL, "Clear", erase_event, GTK_STOCK_CLEAR },
705 { TOGGLE_LABEL_NONE, NULL, "Clear Color", erase_color_event, NULL },
706 { TOGGLE_LABEL_NONE, NULL, NULL, NULL }
709 struct my_menu_item view_menu_items[] = {
710 { TOGGLE_LABEL_NONE, NULL, "Zoom In", zoom_in_event, GTK_STOCK_ZOOM_IN },
711 { TOGGLE_LABEL_NONE, NULL, "Zoom Out", zoom_out_event, GTK_STOCK_ZOOM_OUT },
712 { TOGGLE_LABEL_NONE, NULL, "Zoom 100", zoom_100_event, GTK_STOCK_ZOOM_100 },
713 { TOGGLE_LABEL_ZOOMFIELDS, NULL, "Zoom Field", zoom_field_event, NULL },
714 { TOGGLE_LABEL_NONE, NULL, "", dummy_event, NULL },
715 { TOGGLE_LABEL_HIGHLIGHT, NULL, "Highlight color", show_highlighted_event, NULL },
716 { TOGGLE_LABEL_PREVIEW, NULL, "Preview color", show_preview_event, NULL },
717 { TOGGLE_LABEL_RENDERED, NULL, "Show colorized", show_colorized_event, NULL },
719 { TOGGLE_LABEL_FLOWVIEW, NULL, "Show flow", show_flow_event, NULL },
721 { TOGGLE_LABEL_NONE, NULL, NULL, NULL }
724 struct my_menu_item render_menu_items[] = {
725 { TOGGLE_LABEL_NONE, NULL, "Colorize Image", colorize_event, NULL },
726 { TOGGLE_LABEL_NONE, NULL, NULL, NULL }
729 struct my_menu menus[] = {
730 { "_File", file_menu_items },
731 { "_Edit", edit_menu_items },
732 { "_View", view_menu_items },
733 { "_Render", render_menu_items },
737 /* create menu bar */
738 static void create_menus(GtkWidget *menu_bar)
740 GtkWidget *root_menu;
742 GtkWidget *menu_item;
743 struct my_menu_item *items;
746 /* create vbox and add menu_bar */
747 for (i = 0; menus[i].text; i++) {
748 /* create menu with items */
749 items = menus[i].items;
750 menu = gtk_menu_new();
751 for (j = 0; items[j].text; j++) {
752 if (!items[j].text[0])
753 menu_item = gtk_separator_menu_item_new();
754 else if (items[j].stock)
755 menu_item = gtk_image_menu_item_new_from_stock(items[j].stock, NULL);
756 else if (items[j].label != TOGGLE_LABEL_NONE)
757 menu_item = gtk_check_menu_item_new_with_label(items[j].text);
759 menu_item = gtk_menu_item_new_with_label(items[j].text);
760 items[j].widget = menu_item;
761 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
762 g_signal_connect_swapped(menu_item, "activate", G_CALLBACK(items[j].handler), menu_item);
763 gtk_widget_show(menu_item);
765 /* create root menu and add to menu_bar */
766 root_menu = gtk_menu_item_new_with_mnemonic(menus[i].text);
767 gtk_widget_show(root_menu);
768 gtk_menu_item_set_submenu(GTK_MENU_ITEM(root_menu), menu);
769 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), root_menu);
774 static void set_menu_toggel_by_label(enum toggle_label label, gboolean active)
776 struct my_menu_item *items;
779 for (i = 0; menus[i].text; i++) {
780 items = menus[i].items;
781 for (j = 0; items[j].text; j++) {
782 if (items[j].label == label)
783 gtk_check_menu_item_set_active((GtkCheckMenuItem *)items[j].widget, active);
792 /* palette entry has been clicked */
793 void palette_change(GtkTreeSelection *selection, gpointer data)
798 if (gtk_tree_selection_get_selected(selection, &model, &iter))
802 gtk_tree_model_get (model, &iter, 0/*column*/, &name, -1);
803 mark_selected = atoi(name) - 1;
809 color.red = mark_palette[mark_selected].r * 256 + 128;
810 color.green = mark_palette[mark_selected].g * 256 + 128;
811 color.blue = mark_palette[mark_selected].b * 256 + 128;
814 gtk_color_selection_set_previous_color (colorsel, &color);
815 gtk_color_selection_set_current_color (colorsel, &color);
819 /* set current color for bightness+contrast window */
822 /* set current levels in window */
825 if (highlight || preview)
826 draw_image(0, 0, -1, -1);
830 /* name of palette entry has been entered */
831 void palette_edited(GtkCellRendererText *renderer, gchar *path, gchar *new_text, GtkTreeView *treeview)
833 anything_modified = 1;
836 strncpy(mark_palette[mark_selected].name, new_text, sizeof(mark_palette[mark_selected].name));
837 mark_palette[mark_selected].name[sizeof(mark_palette[mark_selected].name)-1] = '\0';
843 model = gtk_tree_view_get_model (treeview);
844 if (gtk_tree_model_get_iter_from_string (model, &iter, path))
845 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 2/*column*/, mark_palette[mark_selected].name, -1);
848 draw_image(0, 0, -1, -1);
855 extern const guint8 img_size_1[];
856 extern const guint8 img_size_3[];
857 extern const guint8 img_size_5[];
858 extern const guint8 img_size_9[];
859 extern const guint8 img_size_11[];
860 extern const guint8 img_size_19[];
861 extern const guint8 img_fill[];
862 extern const guint8 img_move[];
864 struct paint_buttons {
866 GtkToggleButton *button;
872 } paint_buttons[] = {
873 { img_size_1, NULL, FALSE, 1, 0, 0, "Set pen size to 1" },
874 { img_size_3, NULL, TRUE, 2, 0, 0, "Set pen size to 3" },
875 { img_size_5, NULL, FALSE, 3, 0, 0, "Set pen size to 5" },
876 { img_size_9, NULL, FALSE, 5, 0, 0, "Set pen size to 9" },
877 { img_size_11, NULL, FALSE, 6, 0, 0, "Set pen size to 11" },
878 { img_size_19, NULL, FALSE, 10, 0, 0, "Set pen size to 19" },
879 { img_fill, NULL, FALSE, 0, 0, 1, "FILL marked area" },
880 { img_move, NULL, FALSE, 0, 1, 0, "Move marked pixles" },
881 { NULL, NULL, 0, 0, 0, 0, NULL },
884 void paint_button_toggled(GtkToggleButton *togglebutton, gpointer index)
888 if (paint_buttons[(long)index].toggle_state == gtk_toggle_button_get_active(togglebutton)) {
892 for (i = 0; paint_buttons[i].button; i++) {
893 if ((long)index == i) {
894 paint_buttons[i].toggle_state = TRUE;
895 gtk_toggle_button_set_active(paint_buttons[i].button, TRUE);
896 brush_size = paint_buttons[i].size;
897 move_mode = paint_buttons[i].move;
898 fill_mode = paint_buttons[i].fill;
900 paint_buttons[i].toggle_state = FALSE;
901 gtk_toggle_button_set_active(paint_buttons[i].button, FALSE);
907 void zoomin_button_clicked(GtkButton *button, gpointer index)
912 void zoomout_button_clicked(GtkButton *button, gpointer index)
914 zoom_out_event(NULL);
917 void highlight_button_toggled(GtkButton *button, gpointer index)
919 highlight = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
920 set_menu_toggel_by_label(TOGGLE_LABEL_HIGHLIGHT, highlight);
921 draw_image(0, 0, -1, -1);
924 void preview_button_toggled(GtkButton *button, gpointer index)
926 preview = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
927 set_menu_toggel_by_label(TOGGLE_LABEL_PREVIEW, preview);
928 draw_image(0, 0, -1, -1);
931 void palette_button_clicked(GtkButton *button, gpointer index)
936 void bc_button_clicked(GtkButton *button, gpointer index)
941 void colorize_button_clicked(GtkButton *button, gpointer index)
943 colorize_event(NULL);
946 void view_colorized_button_toggled(GtkButton *button, gpointer index)
948 if (timeline_frames > 1)
949 rendered = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
952 gtk_toggle_button_set_active(show_colorized_button, rendered);
953 set_menu_toggel_by_label(TOGGLE_LABEL_RENDERED, rendered);
954 timeline_select_and_save(timeline_selected, timeline_selected);
958 void view_flow_button_toggled(GtkButton *button, gpointer index)
960 if (flow_enable && timeline_frames > 1)
961 flowview = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
964 gtk_toggle_button_set_active(show_flow_button, flowview);
965 set_menu_toggel_by_label(TOGGLE_LABEL_FLOWVIEW, flowview);
966 timeline_select_and_save(timeline_selected, timeline_selected);
970 extern const guint8 img_zoomin[];
971 extern const guint8 img_zoomout[];
972 extern const guint8 img_pal[];
973 extern const guint8 img_bc[];
974 extern const guint8 img_highlight[];
975 extern const guint8 img_preview[];
976 extern const guint8 img_eye[];
977 extern const guint8 img_col[];
978 extern const guint8 img_flow[];
980 struct tool_buttons {
981 enum toggle_label label;
985 void (*handler)(GtkButton *togglebutton, gpointer priv);
986 GtkToggleButton **button;
989 { TOGGLE_LABEL_NONE, NULL, img_zoomin, 0, zoomin_button_clicked, NULL, "Zoom in" },
990 { TOGGLE_LABEL_NONE, NULL, img_zoomout, 0, zoomout_button_clicked, NULL, "Zoom out" },
991 { TOGGLE_LABEL_NONE, NULL, img_pal, 0, palette_button_clicked, NULL, "Palette dialog" },
992 { TOGGLE_LABEL_NONE, NULL, img_bc, 0, bc_button_clicked, NULL, "Brightness+Contrast dialog" },
993 { TOGGLE_LABEL_HIGHLIGHT, NULL, img_highlight, 1, highlight_button_toggled, &show_highlighted_button, "Highlight selected mark color" },
994 { TOGGLE_LABEL_PREVIEW, NULL, img_preview, 1, preview_button_toggled, &show_preview_button, "Show preview of selected mark color" },
995 { TOGGLE_LABEL_RENDERED, NULL, img_eye, 1, view_colorized_button_toggled, &show_colorized_button, "Show result of a rendered sequence" },
997 { TOGGLE_LABEL_FLOWVIEW, NULL, img_flow, 1, view_flow_button_toggled, &show_flow_button, "Show optical flow" },
999 { TOGGLE_LABEL_NONE, NULL, img_col, 0, colorize_button_clicked, NULL, "Colorize current image" },
1000 { TOGGLE_LABEL_NONE, NULL, NULL, 0, NULL, NULL, NULL },
1003 static void set_button_toggel_by_label(enum toggle_label label, gboolean active)
1007 for (i = 0; tool_buttons[i].data; i++) {
1008 if (tool_buttons[i].label == label)
1009 gtk_toggle_button_set_active((GtkToggleButton *)tool_buttons[i].widget, active);
1014 * creation of main window
1017 int main(int argc, char *argv[])
1019 GtkWidget *vbox, *tool_box;
1021 GtkWidget *pal_scroll;
1022 GtkWidget *menu_bar;
1023 GtkWidget *separator;
1024 GtkTreeSelection *selection;
1025 GtkTreeViewColumn *palette_column;
1026 GtkCellRenderer *palette_renderer;
1027 GtkToggleButton *button;
1030 GtkTooltips *tooltips;
1034 gtk_init(&argc, &argv);
1036 main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1037 gtk_widget_set_size_request(GTK_WIDGET(main_window), 400, 200);
1038 gtk_window_set_default_size(GTK_WINDOW(main_window), 800, 500);
1039 gtk_window_set_title(GTK_WINDOW(main_window), CC_APP_TITLE " Version "
1040 #include "../version.h"
1042 g_signal_connect(main_window, "delete-event", G_CALLBACK(destroy), NULL);
1043 g_signal_connect(main_window, "destroy", G_CALLBACK(destroy), NULL);
1044 g_signal_connect(main_window, "key-press-event", G_CALLBACK(on_key_press), NULL);
1045 g_signal_connect(main_window, "key-release-event", G_CALLBACK(on_key_release), NULL);
1048 gtk_container_set_border_width (GTK_CONTAINER (main_window), 2);
1050 /* create vbox (complete window) */
1051 vbox = gtk_vbox_new(FALSE, 0);
1052 gtk_container_add(GTK_CONTAINER(main_window), vbox);
1053 gtk_widget_show(vbox);
1055 /* add menu to vbox (top of vbox) */
1056 menu_bar = gtk_menu_bar_new();
1057 gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 2);
1058 gtk_widget_show(menu_bar);
1059 create_menus(menu_bar);
1061 /* add tool_box to vbox (bottom part of palette box) */
1062 tool_box = gtk_hbox_new(FALSE, 0);
1063 gtk_box_pack_start(GTK_BOX(vbox), tool_box, FALSE, FALSE, 2);
1064 gtk_widget_show(tool_box);
1066 for (i = 0; paint_buttons[i].data; i++) {
1067 pixbuf = gdk_pixbuf_new_from_inline(-1, paint_buttons[i].data, FALSE, NULL);
1068 image = gtk_image_new_from_pixbuf(pixbuf);
1069 gtk_widget_show(GTK_WIDGET(image));
1070 paint_buttons[i].button = button = (GtkToggleButton *) gtk_toggle_button_new();
1071 if (paint_buttons[i].toggle_state) {
1072 gtk_toggle_button_set_active(button, TRUE);
1073 brush_size = paint_buttons[i].size;
1075 g_signal_connect(button, "toggled", G_CALLBACK(paint_button_toggled), (void *)((long)i));
1076 tooltips = gtk_tooltips_new();
1077 gtk_tooltips_set_tip(tooltips, GTK_WIDGET(button), paint_buttons[i].tooltip, NULL);
1078 gtk_container_add (GTK_CONTAINER (button), image);
1079 gtk_widget_show(GTK_WIDGET(button));
1080 gtk_box_pack_start(GTK_BOX(tool_box), GTK_WIDGET(button), FALSE, FALSE, 2);
1083 for (i = 0; tool_buttons[i].data; i++) {
1084 if (i == 0 || i == 2) {
1085 /* add vertical seperation to hbox */
1086 separator = gtk_vseparator_new();
1087 gtk_widget_show(separator);
1088 gtk_box_pack_start(GTK_BOX(tool_box), separator, FALSE, FALSE, 3);
1090 pixbuf = gdk_pixbuf_new_from_inline(-1, tool_buttons[i].data, FALSE, NULL);
1091 image = gtk_image_new_from_pixbuf(pixbuf);
1092 gtk_widget_show(GTK_WIDGET(image));
1093 if (tool_buttons[i].toggle) {
1094 button = (GtkToggleButton *) gtk_toggle_button_new();
1095 g_signal_connect(button, "toggled", G_CALLBACK(tool_buttons[i].handler), NULL);
1097 button = (GtkToggleButton *) gtk_button_new();
1098 g_signal_connect(button, "clicked", G_CALLBACK(tool_buttons[i].handler), NULL);
1100 tool_buttons[i].widget = (GtkWidget *)button;
1101 tooltips = gtk_tooltips_new();
1102 gtk_tooltips_set_tip(tooltips, GTK_WIDGET(button), tool_buttons[i].tooltip, NULL);
1103 if (tool_buttons[i].button)
1104 *(tool_buttons[i].button) = button;
1105 gtk_container_add (GTK_CONTAINER (button), image);
1106 gtk_widget_show(GTK_WIDGET(button));
1107 gtk_box_pack_start(GTK_BOX(tool_box), GTK_WIDGET(button), FALSE, FALSE, 2);
1110 /* add paned view to vbox (middle part of vbox) */
1111 paned = gtk_hpaned_new ();
1112 gtk_widget_show(paned);
1113 gtk_box_pack_start(GTK_BOX(vbox), paned, TRUE, TRUE, 2);
1114 gtk_paned_set_position(GTK_PANED (paned), 250);
1116 /* add palette treeview to hbox (top part of palette box) */
1117 palette_treeview = gtk_tree_view_new();
1118 gtk_widget_set_size_request(palette_treeview, 250, 400);
1119 g_signal_connect(palette_treeview, "enter_notify_event", G_CALLBACK(enter_palette_area), NULL);
1120 g_signal_connect(palette_treeview, "leave_notify_event", G_CALLBACK(leave_palette_area), NULL);
1121 gtk_widget_set_events(palette_treeview, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
1122 gtk_widget_show(palette_treeview);
1124 pal_scroll = gtk_scrolled_window_new(NULL, NULL);
1125 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(pal_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
1126 gtk_widget_show(pal_scroll);
1127 gtk_container_add(GTK_CONTAINER(pal_scroll), palette_treeview);
1129 palette_renderer = gtk_cell_renderer_text_new();
1130 g_object_set(G_OBJECT(palette_renderer), "editable", FALSE, NULL);
1131 palette_column = gtk_tree_view_column_new_with_attributes("", palette_renderer, "text", 0/*column*/, NULL);
1132 gtk_tree_view_insert_column(GTK_TREE_VIEW(palette_treeview), GTK_TREE_VIEW_COLUMN(palette_column), 0/*column*/);
1134 palette_renderer = gtk_cell_renderer_pixbuf_new();
1135 palette_column = gtk_tree_view_column_new_with_attributes("", palette_renderer, "pixbuf", 1/*column*/, NULL);
1136 gtk_tree_view_insert_column(GTK_TREE_VIEW(palette_treeview), GTK_TREE_VIEW_COLUMN(palette_column), 1/*column*/);
1138 palette_renderer = gtk_cell_renderer_text_new();
1139 g_object_set(G_OBJECT(palette_renderer), "editable", TRUE, NULL);
1140 g_signal_connect(palette_renderer, "edited", (GCallback) palette_edited, palette_treeview);
1141 palette_column = gtk_tree_view_column_new_with_attributes("", palette_renderer, "text", 2/*column*/, NULL);
1142 gtk_tree_view_insert_column(GTK_TREE_VIEW(palette_treeview), GTK_TREE_VIEW_COLUMN(palette_column), 2/*column*/);
1146 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(palette_treeview));
1147 g_signal_connect(selection, "changed", G_CALLBACK(palette_change), NULL);
1148 gtk_paned_pack1 (GTK_PANED (paned), pal_scroll, FALSE, TRUE);
1150 /* add drawing area (right of hbox) */
1151 img_drawing_area = gtk_drawing_area_new ();
1152 gtk_signal_connect(GTK_OBJECT(img_drawing_area), "motion_notify_event", (GtkSignalFunc)motion_notify_event, NULL);
1153 gtk_signal_connect(GTK_OBJECT (img_drawing_area), "button_press_event", (GtkSignalFunc)button_press_event, NULL);
1154 gtk_signal_connect(GTK_OBJECT (img_drawing_area), "expose_event", (GtkSignalFunc)img_expose_event, NULL);
1155 g_signal_connect(img_drawing_area, "enter_notify_event", G_CALLBACK(enter_drawing_area), NULL);
1156 g_signal_connect(img_drawing_area, "leave_notify_event", G_CALLBACK(leave_drawing_area), NULL);
1157 gtk_widget_set_events(img_drawing_area, GDK_EXPOSURE_MASK
1158 | GDK_ENTER_NOTIFY_MASK
1159 | GDK_LEAVE_NOTIFY_MASK
1160 | GDK_BUTTON_PRESS_MASK
1161 | GDK_POINTER_MOTION_MASK
1162 | GDK_POINTER_MOTION_HINT_MASK);
1163 gtk_widget_show(img_drawing_area);
1165 img_scroll = gtk_scrolled_window_new(NULL, NULL);
1166 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(img_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1167 gtk_widget_show(img_scroll);
1168 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(img_scroll), img_drawing_area);
1169 gtk_paned_pack2 (GTK_PANED (paned), img_scroll, TRUE, TRUE);
1172 /* add horizontal seperation to vbox */
1173 separator = gtk_hseparator_new();
1174 gtk_widget_show(separator);
1175 gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 3);
1178 /* add timeline (bottom of vbox) */
1179 timeline_drawing_area = gtk_drawing_area_new ();
1180 gtk_widget_set_size_request(timeline_drawing_area, 10, 10);
1181 gtk_signal_connect(GTK_OBJECT(timeline_drawing_area), "motion_notify_event", (GtkSignalFunc)timeline_motion_notify_event, NULL);
1182 gtk_signal_connect(GTK_OBJECT(timeline_drawing_area), "button_press_event", (GtkSignalFunc)timeline_press_event, NULL);
1183 gtk_signal_connect(GTK_OBJECT(timeline_drawing_area), "expose_event", (GtkSignalFunc)timeline_expose_event, NULL);
1184 g_signal_connect(timeline_drawing_area, "enter_notify_event", G_CALLBACK(enter_timeline_area), NULL);
1185 g_signal_connect(timeline_drawing_area, "leave_notify_event", G_CALLBACK(leave_timeline_area), NULL);
1186 gtk_widget_set_events(timeline_drawing_area, GDK_EXPOSURE_MASK
1187 | GDK_ENTER_NOTIFY_MASK
1188 | GDK_LEAVE_NOTIFY_MASK
1189 | GDK_BUTTON_PRESS_MASK
1190 | GDK_POINTER_MOTION_MASK
1191 | GDK_POINTER_MOTION_HINT_MASK);
1192 gtk_widget_show(timeline_drawing_area);
1193 timeline_scroll = gtk_scrolled_window_new(NULL, NULL);
1194 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(timeline_scroll), GTK_POLICY_ALWAYS, GTK_POLICY_NEVER);
1195 // gtk_widget_show(timeline_scroll);
1196 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(timeline_scroll), timeline_drawing_area);
1197 gtk_box_pack_start(GTK_BOX(vbox), timeline_scroll, FALSE, FALSE, 0);
1199 create_timeline(NULL);
1202 img_label = GTK_LABEL(gtk_label_new(NULL));
1203 gtk_widget_show(GTK_WIDGET(img_label));
1204 gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(img_label), FALSE, FALSE, 0);
1207 gtk_widget_show(main_window);
1210 create_timeline(argv[1]);
1212 create_image(frame_list[timeline_selected].filename, 1);