2 #include <gdk/gdkkeysyms.h>
6 #include "../src/mark.h"
8 #include "../src/opticalflow.h"
17 #include "brightcontrast.h"
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;
32 GtkToggleButton *show_highlighted_button, *show_preview_button, *show_colorized_button;
34 GtkToggleButton *show_flow_button;
36 int button_down = 0, button_down_x = -1000, button_down_y = -1000, shift_pressed = 0, button_num = 1;
38 int 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)
44 void printerror(const char *fmt, ...)
50 vsprintf(buffer,fmt,args);
51 buffer[sizeof(buffer)-1]=0;
54 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(main_window),
55 GTK_DIALOG_DESTROY_WITH_PARENT,
59 gtk_dialog_run (GTK_DIALOG (dialog));
60 gtk_widget_destroy (dialog);
63 static int already_destroyed = 0;
65 /* exit program and save current mask / palette */
66 void main_destroy(void)
68 if (anything_modified) {
70 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(main_window),
71 GTK_DIALOG_DESTROY_WITH_PARENT,
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)
80 already_destroyed = 1;
85 static void destroy(GtkWidget *widget, gpointer data)
87 if (!already_destroyed)
95 /* event handler for main window keys */
96 static gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
100 // if (mouse_over_palette_area)
101 if (!mouse_over_drawing_area && !mouse_over_timeline_area)
104 switch (event->keyval) {
107 if (event->state & GDK_CONTROL_MASK) {
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)
118 if (frame < timeline_frames)
119 timeline_select_and_save(timeline_selected, frame);
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)
128 timeline_select_and_save(timeline_selected, frame);
132 timeline_select_and_save(timeline_selected, frame);
135 frame = timeline_frames - 1;
136 timeline_select_and_save(timeline_selected, frame);
146 if (event->state & GDK_CONTROL_MASK) {
152 if (event->state & GDK_CONTROL_MASK) {
165 // printf("press %x\n", event->keyval);
171 /* event handler for main window keys */
172 static gboolean on_key_release(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
174 switch (event->keyval) {
180 // printf("release %x\n", event->keyval);
190 /* events if mouse is over palette area */
191 static gboolean enter_palette_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
193 mouse_over_palette_area = 1;
196 static gboolean leave_palette_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
198 mouse_over_palette_area = 0;
202 /* events if mouse is over image area */
203 static gboolean enter_drawing_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
205 mouse_over_drawing_area = 1;
208 static gboolean leave_drawing_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
210 mouse_over_drawing_area = 0;
214 /* events if mouse is over timeline area */
215 static gboolean enter_timeline_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
217 mouse_over_timeline_area = 1;
220 static gboolean leave_timeline_area(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
222 mouse_over_timeline_area = 0;
223 timeline_point(-1, -1);
227 /* ugly non-bresenham.... */
228 static void draw_line(int x, int y, int paint)
230 double step_x = 0, step_y = 0;
232 if (abs(x,button_down_x) > abs(y,button_down_y)) {
234 if (button_down_x < x) {
236 step_y += (double)(button_down_y - y) / (double)(button_down_x - x);
239 step_y -= (double)(button_down_y - y) / (double)(button_down_x - x);
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)
248 if (y == button_down_y) /* no move at all */
250 if (button_down_y < y) {
252 step_x += (double)(button_down_x - x) / (double)(button_down_y - y);
255 step_x -= (double)(button_down_x - x) / (double)(button_down_y - y);
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)
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);
269 /* notify movement of mouse inside image area */
270 static gint motion_notify_event( GtkWidget *widget,
271 GdkEventMotion *event )
274 GdkModifierType state;
277 gdk_window_get_pointer (event->window, &x, &y, &state);
282 state = event->state;
285 if ((state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK))) {
286 if (button_down && pick_mode) {
289 if (button_down && !pick_mode) {
291 move_mark((x-button_down_x)*16/img_scale_x, (y-button_down_y)*16/img_scale_y);
292 draw_image(0, 0, -1, -1);
295 draw_line(x, y, button_num == 1);
299 if (button_down && pick_mode)
307 /* button press event inside image area */
308 static gint button_press_event (GtkWidget *widget, GdkEventButton *event)
314 button_num = event->button;
316 if (!button_down && !pick_mode)
324 fill(x, y, event->button != 1);
325 draw_image(0, 0, -1, -1);
334 /* if not shift, draw a dot and not a line */
335 if (!shift_pressed || button_down_x == -1000) {
339 draw_line(x, y, button_num == 1);
345 /* redraw event of image area */
346 static gint img_expose_event (GtkWidget *widget, GdkEventExpose *event)
348 draw_image(event->area.x, event->area.y, event->area.width, event->area.height);
357 /* mouse move event inside timeline */
358 static gint timeline_motion_notify_event( GtkWidget *widget,
359 GdkEventMotion *event )
362 GdkModifierType state;
365 gdk_window_get_pointer (event->window, &x, &y, &state);
370 state = event->state;
373 timeline_point(x, y);
375 if ((state & GDK_BUTTON1_MASK)) {
376 timeline_clicked(x, y);
383 /* button press event inside timeline area */
384 static gint timeline_press_event (GtkWidget *widget, GdkEventButton *event)
390 timeline_clicked(x, y);
395 /* redraw event of timeline area */
396 static gint timeline_expose_event (GtkWidget *widget, GdkEventExpose *event)
398 draw_timeline(event->area.x, event->area.y, event->area.width, event->area.height);
407 GtkWidget *colorseldlg = NULL;
408 GtkColorSelection *colorsel;
409 /* color selection's buttons have been pressed */
410 void color_response(GtkDialog *dialog, gint response_id, gpointer user_data)
414 switch (response_id) {
415 case GTK_RESPONSE_CANCEL:
416 gtk_color_selection_get_previous_color(colorsel, &ncolor);
418 anything_modified = 1;
420 mark_palette[mark_selected].r = ncolor.red / 256;
421 mark_palette[mark_selected].g = ncolor.green / 256;
422 mark_palette[mark_selected].b = ncolor.blue / 256;
423 update_color(mark_selected);
424 draw_image(0, 0, -1, -1);
426 case GTK_RESPONSE_OK:
427 gtk_color_selection_get_current_color(colorsel, &ncolor);
436 /* palette entry has been clicked */
437 void palette_change(GtkTreeSelection *selection, gpointer data)
442 if (gtk_tree_selection_get_selected(selection, &model, &iter))
446 gtk_tree_model_get (model, &iter, 0/*column*/, &name, -1);
447 mark_selected = atoi(name) - 1;
453 color.red = mark_palette[mark_selected].r * 256 + 128;
454 color.green = mark_palette[mark_selected].g * 256 + 128;
455 color.blue = mark_palette[mark_selected].b * 256 + 128;
458 gtk_color_selection_set_previous_color (colorsel, &color);
459 gtk_color_selection_set_current_color (colorsel, &color);
463 /* set current color for bightness+contrast window */
466 /* set current levels in window */
469 if (highlight || preview)
470 draw_image(0, 0, -1, -1);
474 /* name of palette entry has been entered */
475 void palette_edited(GtkCellRendererText *renderer, gchar *path, gchar *new_text, GtkTreeView *treeview)
477 anything_modified = 1;
480 strncpy(mark_palette[mark_selected].name, new_text, sizeof(mark_palette[mark_selected].name));
481 mark_palette[mark_selected].name[sizeof(mark_palette[mark_selected].name)-1] = '\0';
487 model = gtk_tree_view_get_model (treeview);
488 if (gtk_tree_model_get_iter_from_string (model, &iter, path))
489 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 2/*column*/, mark_palette[mark_selected].name, -1);
492 draw_image(0, 0, -1, -1);
496 * creation of main window
499 int main(int argc, char *argv[])
501 GtkWidget *vbox, *tool_bar;
503 GtkWidget *pal_scroll;
505 GtkTreeSelection *selection;
506 GtkTreeViewColumn *palette_column;
507 GtkCellRenderer *palette_renderer;
509 gtk_init(&argc, &argv);
511 main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
512 gtk_widget_set_size_request(GTK_WIDGET(main_window), 400, 200);
513 gtk_window_set_default_size(GTK_WINDOW(main_window), 800, 500);
514 gtk_window_set_title(GTK_WINDOW(main_window), CC_APP_TITLE " Version "
515 #include "../version.h"
517 g_signal_connect(main_window, "delete-event", G_CALLBACK(destroy), NULL);
518 g_signal_connect(main_window, "destroy", G_CALLBACK(destroy), NULL);
519 g_signal_connect(main_window, "key-press-event", G_CALLBACK(on_key_press), NULL);
520 g_signal_connect(main_window, "key-release-event", G_CALLBACK(on_key_release), NULL);
523 gtk_container_set_border_width (GTK_CONTAINER (main_window), 2);
525 /* create vbox (complete window) */
526 vbox = gtk_vbox_new(FALSE, 0);
527 gtk_container_add(GTK_CONTAINER(main_window), vbox);
528 gtk_widget_show(vbox);
530 /* add menu to vbox (top of vbox) */
531 menu_bar = gtk_menu_bar_new();
532 gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 2);
533 gtk_widget_show(menu_bar);
534 create_menus(menu_bar);
536 /* add tool_bar to vbox (bottom part of palette box) */
537 tool_bar = gtk_hbox_new(FALSE, 0);
538 gtk_box_pack_start(GTK_BOX(vbox), tool_bar, FALSE, FALSE, 2);
539 gtk_widget_show(tool_bar);
540 create_toolbar(tool_bar);
542 /* add paned view to vbox (middle part of vbox) */
543 paned = gtk_hpaned_new ();
544 gtk_widget_show(paned);
545 gtk_box_pack_start(GTK_BOX(vbox), paned, TRUE, TRUE, 2);
546 gtk_paned_set_position(GTK_PANED (paned), 250);
548 /* add palette treeview to hbox (top part of palette box) */
549 palette_treeview = gtk_tree_view_new();
550 gtk_widget_set_size_request(palette_treeview, 250, 400);
551 g_signal_connect(palette_treeview, "enter_notify_event", G_CALLBACK(enter_palette_area), NULL);
552 g_signal_connect(palette_treeview, "leave_notify_event", G_CALLBACK(leave_palette_area), NULL);
553 gtk_widget_set_events(palette_treeview, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
554 gtk_widget_show(palette_treeview);
556 pal_scroll = gtk_scrolled_window_new(NULL, NULL);
557 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(pal_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
558 gtk_widget_show(pal_scroll);
559 gtk_container_add(GTK_CONTAINER(pal_scroll), palette_treeview);
561 palette_renderer = gtk_cell_renderer_text_new();
562 g_object_set(G_OBJECT(palette_renderer), "editable", FALSE, NULL);
563 palette_column = gtk_tree_view_column_new_with_attributes("", palette_renderer, "text", 0/*column*/, NULL);
564 gtk_tree_view_insert_column(GTK_TREE_VIEW(palette_treeview), GTK_TREE_VIEW_COLUMN(palette_column), 0/*column*/);
566 palette_renderer = gtk_cell_renderer_pixbuf_new();
567 palette_column = gtk_tree_view_column_new_with_attributes("", palette_renderer, "pixbuf", 1/*column*/, NULL);
568 gtk_tree_view_insert_column(GTK_TREE_VIEW(palette_treeview), GTK_TREE_VIEW_COLUMN(palette_column), 1/*column*/);
570 palette_renderer = gtk_cell_renderer_text_new();
571 g_object_set(G_OBJECT(palette_renderer), "editable", TRUE, NULL);
572 g_signal_connect(palette_renderer, "edited", (GCallback) palette_edited, palette_treeview);
573 palette_column = gtk_tree_view_column_new_with_attributes("", palette_renderer, "text", 2/*column*/, NULL);
574 gtk_tree_view_insert_column(GTK_TREE_VIEW(palette_treeview), GTK_TREE_VIEW_COLUMN(palette_column), 2/*column*/);
578 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(palette_treeview));
579 g_signal_connect(selection, "changed", G_CALLBACK(palette_change), NULL);
580 gtk_paned_pack1 (GTK_PANED (paned), pal_scroll, FALSE, TRUE);
582 /* add drawing area (right of hbox) */
583 img_drawing_area = gtk_drawing_area_new ();
584 gtk_signal_connect(GTK_OBJECT(img_drawing_area), "motion_notify_event", (GtkSignalFunc)motion_notify_event, NULL);
585 gtk_signal_connect(GTK_OBJECT (img_drawing_area), "button_press_event", (GtkSignalFunc)button_press_event, NULL);
586 gtk_signal_connect(GTK_OBJECT (img_drawing_area), "expose_event", (GtkSignalFunc)img_expose_event, NULL);
587 g_signal_connect(img_drawing_area, "enter_notify_event", G_CALLBACK(enter_drawing_area), NULL);
588 g_signal_connect(img_drawing_area, "leave_notify_event", G_CALLBACK(leave_drawing_area), NULL);
589 gtk_widget_set_events(img_drawing_area, GDK_EXPOSURE_MASK
590 | GDK_ENTER_NOTIFY_MASK
591 | GDK_LEAVE_NOTIFY_MASK
592 | GDK_BUTTON_PRESS_MASK
593 | GDK_POINTER_MOTION_MASK
594 | GDK_POINTER_MOTION_HINT_MASK);
595 gtk_widget_show(img_drawing_area);
597 img_scroll = gtk_scrolled_window_new(NULL, NULL);
598 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(img_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
599 gtk_widget_show(img_scroll);
600 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(img_scroll), img_drawing_area);
601 gtk_paned_pack2 (GTK_PANED (paned), img_scroll, TRUE, TRUE);
604 /* add horizontal seperation to vbox */
605 separator = gtk_hseparator_new();
606 gtk_widget_show(separator);
607 gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 3);
610 /* add timeline (bottom of vbox) */
611 timeline_drawing_area = gtk_drawing_area_new ();
612 gtk_widget_set_size_request(timeline_drawing_area, 10, 10);
613 gtk_signal_connect(GTK_OBJECT(timeline_drawing_area), "motion_notify_event", (GtkSignalFunc)timeline_motion_notify_event, NULL);
614 gtk_signal_connect(GTK_OBJECT(timeline_drawing_area), "button_press_event", (GtkSignalFunc)timeline_press_event, NULL);
615 gtk_signal_connect(GTK_OBJECT(timeline_drawing_area), "expose_event", (GtkSignalFunc)timeline_expose_event, NULL);
616 g_signal_connect(timeline_drawing_area, "enter_notify_event", G_CALLBACK(enter_timeline_area), NULL);
617 g_signal_connect(timeline_drawing_area, "leave_notify_event", G_CALLBACK(leave_timeline_area), NULL);
618 gtk_widget_set_events(timeline_drawing_area, GDK_EXPOSURE_MASK
619 | GDK_ENTER_NOTIFY_MASK
620 | GDK_LEAVE_NOTIFY_MASK
621 | GDK_BUTTON_PRESS_MASK
622 | GDK_POINTER_MOTION_MASK
623 | GDK_POINTER_MOTION_HINT_MASK);
624 gtk_widget_show(timeline_drawing_area);
625 timeline_scroll = gtk_scrolled_window_new(NULL, NULL);
626 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(timeline_scroll), GTK_POLICY_ALWAYS, GTK_POLICY_NEVER);
627 // gtk_widget_show(timeline_scroll);
628 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(timeline_scroll), timeline_drawing_area);
629 gtk_box_pack_start(GTK_BOX(vbox), timeline_scroll, FALSE, FALSE, 0);
631 create_timeline(NULL);
634 img_label = GTK_LABEL(gtk_label_new(NULL));
635 gtk_widget_show(GTK_WIDGET(img_label));
636 gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(img_label), FALSE, FALSE, 0);
639 gtk_widget_show(main_window);
642 create_timeline(argv[1]);
644 create_image(frame_list[timeline_selected].filename, 1);