/***************** Electirc Eyes ***********************/ /* This software is Copyright (C) 1998 but The Rasterman (Carsten Haitzler). */ /* This software falls under the GNU Public License. Please read the COPYING */ /* file for more information */ /*****************************************************************************/ #include #include #include #include #include #include #include "stdimg.xpm" #include #include #include #include #include #include static void ee_image_cb_destroy(GtkWidget *widget, gpointer *data); static void ee_image_cb_resize(GtkWidget *widget, GdkEventConfigure *event); static void ee_image_cb_button_down(GtkWidget * widget, GdkEventButton *event); static void ee_image_cb_button_up(GtkWidget * widget, GdkEventButton *event); static void ee_image_cb_mouse_move(GtkWidget * widget, GdkEventMotion *event); static void ee_image_clear_crop(GtkWidget * widget); static void ee_image_draw_crop(GtkWidget * widget); static int ee_image_key_pressed (GtkWidget *widget, GdkEventKey *event, gpointer data); static GdkImlibImage *default_img = NULL; static GdkWindow *gdk_root = NULL; GdkImlibImage * ee_image_get_image(GtkWidget *widget) { return (GdkImlibImage *)gtk_object_get_data(GTK_OBJECT(widget), "image"); } void ee_image_add_toolbar(GtkWidget *widget, GtkWidget *toolbar, gint place) { GtkWidget *top, *bottom, *left, *right; return; top = gtk_object_get_data(GTK_OBJECT(widget), "top"); if (!top) return; bottom = gtk_object_get_data(GTK_OBJECT(widget), "bottom"); left = gtk_object_get_data(GTK_OBJECT(widget), "left"); right = gtk_object_get_data(GTK_OBJECT(widget), "right"); padder_button = gtk_button_new(); gtk_widget_set_sensitive(padder_button, 0); gtk_widget_show(padder_button); switch (place) { case 0: gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL); gtk_box_pack_start(GTK_BOX(top), toolbar, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(top), padder_button, TRUE, TRUE, 0); gtk_widget_show(toolbar); gtk_object_set_data(GTK_OBJECT(widget), "toolbar_pos", GINT_TO_POINTER (1)); break; case 1: gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL); gtk_box_pack_start(GTK_BOX(bottom), toolbar, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(bottom), padder_button, TRUE, TRUE, 0); gtk_widget_show(toolbar); gtk_object_set_data(GTK_OBJECT(widget), "toolbar_pos", GINT_TO_POINTER (2)); break; case 2: gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_VERTICAL); gtk_box_pack_start(GTK_BOX(left), toolbar, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(left), padder_button, TRUE, TRUE, 0); gtk_widget_show(toolbar); gtk_object_set_data(GTK_OBJECT(widget), "toolbar_pos", GINT_TO_POINTER (3)); break; case 3: default: gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar), GTK_ORIENTATION_VERTICAL); gtk_box_pack_start(GTK_BOX(right), toolbar, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(right), padder_button, TRUE, TRUE, 0); gtk_widget_show(toolbar); gtk_object_set_data(GTK_OBJECT(widget), "toolbar_pos", GINT_TO_POINTER (4)); break; } } void ee_image_get_size(GtkWidget *widget, gint *width, gint *height) { GtkWidget *a; a = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "view"); if (!a) return; *width = a->allocation.width; *height = a->allocation.height; } void ee_image_set_size(GtkWidget *widget, gint width, gint height) { GtkWidget *a, *s; gchar txt[1024]; a = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "view"); s = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "scrolled"); gtk_object_set_data(GTK_OBJECT(widget), "width", GINT_TO_POINTER (width)); gtk_object_set_data(GTK_OBJECT(widget), "height", GINT_TO_POINTER (height)); if (a) { gtk_widget_set_usize(a, width, height); gtk_widget_queue_resize(s); g_snprintf(txt, sizeof(txt), _("Image Size: (%i x %i)"), width, height); ee_edit_set_size_label(edit_window, txt); } } void ee_image_force_scrollable(GtkWidget *widget, gint tru) { GtkWidget *a; gint forcescroll, w, h; a = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "view"); if (!a) return; forcescroll = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "forcescroll")); w = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "width")); h = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "height")); if (tru) { if (!forcescroll) { gtk_object_set_data(GTK_OBJECT(widget), "forcescroll", GINT_TO_POINTER (1)); ee_image_set_image_size(widget, w, h); } } else { if (forcescroll) { gtk_object_set_data(GTK_OBJECT(widget), "forcescroll", GINT_TO_POINTER (0)); ee_image_set_image_size(widget, w, h); } } } void ee_image_set_image_size(GtkWidget *widget, gint width, gint height) { GtkWidget *a, *s, *m, *al; GdkImlibImage *im; GdkPixmap *pmap, *mask; gint rw, rh; gint scrollable; gint forcescroll; im = (GdkImlibImage *)gtk_object_get_data(GTK_OBJECT(widget), "image"); a = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "view"); if (!a) return; s = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "scrolled"); m = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "middle"); al = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "alignment"); scrollable = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "scrollable")); forcescroll = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "forcescroll")); gtk_object_set_data(GTK_OBJECT(widget), "width", GINT_TO_POINTER (width)); gtk_object_set_data(GTK_OBJECT(widget), "height", GINT_TO_POINTER (height)); if (!im) { if (!default_img) default_img = gdk_imlib_create_image_from_xpm_data(stdimg_xpm); im = default_img; } gdk_window_get_size(gdk_root, &rw, &rh); if (!scrollable) { if ((width > rw) && (height > rh)) gtk_widget_set_usize(widget, rw - 64, rh - 64); else if (width > rw) gtk_widget_set_usize(widget, rw - 64, height - 32); else if (height > rh) gtk_widget_set_usize(widget, width - 32, rh - 64); } if ((width > rw) || (height > rh) || (forcescroll)) { if (!scrollable) { gtk_window_set_policy(GTK_WINDOW(widget), 1, 1, 0); gtk_widget_show(s); gtk_widget_reparent(a, al); gtk_widget_set_usize(s, -1, -1); gtk_widget_set_usize(a, width, height); gtk_object_set_data(GTK_OBJECT(widget), "scrollable", GINT_TO_POINTER (1)); } } else { if (scrollable) { gtk_window_set_policy(GTK_WINDOW(widget), 1, 1, 1); gtk_widget_set_usize(widget, -1, -1); gtk_widget_reparent(a, m); gtk_box_set_child_packing(GTK_BOX(m), a, TRUE, TRUE, 0, GTK_PACK_START); gtk_widget_set_usize(s, 1, 1); gtk_widget_hide(s); gtk_widget_show(a); gtk_object_set_data(GTK_OBJECT(widget), "scrollable", GINT_TO_POINTER (0)); } } gdk_imlib_render(im, width, height); pmap = gdk_imlib_move_image(im); mask = gdk_imlib_move_mask(im); gdk_window_set_back_pixmap(a->window, pmap, FALSE); gdk_window_clear(a->window); gdk_window_shape_combine_mask(a->window, mask, 0, 0); gdk_imlib_free_pixmap(pmap); } void ee_image_reset_size(GtkWidget *widget) { GdkImlibImage *im; gint scrollable; im = (GdkImlibImage *)gtk_object_get_data(GTK_OBJECT(widget), "image"); scrollable = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "scrollable")); if (!im) { if (!default_img) default_img = gdk_imlib_create_image_from_xpm_data(stdimg_xpm); im = default_img; } ee_image_set_size(widget, im->rgb_width, im->rgb_height); if (scrollable) ee_image_set_image_size(widget, im->rgb_width, im->rgb_height); } void ee_image_set_image(GtkWidget *widget, GdkImlibImage *im) { GdkImlibImage *old_im; gint scrollable; gint w, h; GdkImlibColorModifier mod, rmod, gmod, bmod; old_im = (GdkImlibImage *)gtk_object_get_data(GTK_OBJECT(widget), "image"); if (old_im) { gdk_imlib_get_image_modifier(old_im, &mod); gdk_imlib_get_image_red_modifier(old_im, &rmod); gdk_imlib_get_image_green_modifier(old_im, &gmod); gdk_imlib_get_image_blue_modifier(old_im, &bmod); gdk_imlib_destroy_image(old_im); } scrollable = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "scrollable")); gtk_object_set_data(GTK_OBJECT(widget), "image", im); if (!im) { if (!default_img) default_img = gdk_imlib_create_image_from_xpm_data(stdimg_xpm); im = default_img; } else { if (old_im) { gdk_imlib_set_image_modifier(im, &mod); gdk_imlib_set_image_red_modifier(im, &rmod); gdk_imlib_set_image_green_modifier(im, &gmod); gdk_imlib_set_image_blue_modifier(im, &bmod); } } ee_image_get_size(widget, &w, &h); ee_image_set_size(widget, im->rgb_width, im->rgb_height); if ((scrollable) || ((w == im->rgb_width) && (h == im->rgb_height))) ee_image_set_image_size(widget, im->rgb_width, im->rgb_height); ee_edit_update_graphs(edit_window); ee_edit_update_preview(edit_window); } void ee_image_set_popup_menu(GtkWidget *widget, GtkWidget *menu) { gtk_object_set_data(GTK_OBJECT(widget), "menu", menu); } void ee_image_set_filename(GtkWidget *widget, gchar *file) { char *old_name; old_name = gtk_object_get_data(GTK_OBJECT(widget), "filename"); if (old_name) g_free (old_name); gtk_object_set_data(GTK_OBJECT(widget), "filename", g_strdup (file)); } gchar * ee_image_get_filename(GtkWidget *widget) { return gtk_object_get_data(GTK_OBJECT(widget), "filename"); } void ee_image_do_crop(GtkWidget *widget) { GtkWidget *a; gint x, y, w, h, aw, ah; GdkImlibImage *im; gint scrolled; a = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "view"); if (!a) return; x = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_x")); y = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_y")); w = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_w")); h = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_h")); ee_image_get_size(widget, &aw, &ah); im = ee_image_get_image(widget); scrolled = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "scrollable")); if ((im) && (im != default_img)) { if ((w>0) && (h>0)) { x = (x * im->rgb_width) / aw; y = (y * im->rgb_height) / ah; w = (w * im->rgb_width) / aw; h = (h * im->rgb_height) / ah; gdk_imlib_crop_image(im, x, y, w, h); w = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_w")); h = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_h")); ee_image_set_size(widget, w, h); if (scrolled) ee_image_set_image_size(widget, w, h); ee_image_remove_crop(widget); } } } void ee_image_remove_crop(GtkWidget *widget) { gint cx, cy, cw, ch; gchar s[1024]; ee_image_clear_crop(widget); gtk_object_set_data(GTK_OBJECT(widget), "crop_x", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(widget), "crop_y", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(widget), "crop_w", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(widget), "crop_h", GINT_TO_POINTER (0)); cx = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_x")); cy = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_y")); cw = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_w")); ch = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_h")); g_snprintf(s, sizeof(s), _("Crop: (%i, %i) (%i x %i)"), cx, cy, cw, ch); ee_edit_set_crop_label(edit_window, s); } static void ee_image_cb_redraw(GtkWidget *widget, gpointer *data) { GtkWidget *ww; gint cw, ch; ww = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "widget"); if (!ww) return; cw = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_w")); ch = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_h")); if ((cw > 0) && (ch > 0)) { ee_image_clear_crop(ww); ee_image_draw_crop(ww); } data = NULL; } static void ee_image_cb_destroy(GtkWidget *widget, gpointer *data) { ee_conf_save(); exit(0); widget = NULL; data = NULL; } static void ee_image_cb_resize(GtkWidget *widget, GdkEventConfigure *event) { gint w, h; gint scrollable; static gint pw = -1, ph = -1; GtkWidget *ww = NULL; gchar s[1024]; w = event->width; h = event->height; if ((pw == w) && (ph == h)) return; pw = w; ph = h; if (widget) { ww = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "widget"); if (!ww) return; } if (ww) { scrollable = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "scrollable")); if (scrollable) return; } if (ww) { g_snprintf(s, sizeof(s), _("Image Size: (%i x %i)"), w, h); ee_edit_set_size_label(edit_window, s); ee_image_set_image_size(ww, w, h); } } static void ee_image_cb_button_down(GtkWidget * widget, GdkEventButton *event) { gint button; gint x, y, w, h; gint cx, cy, cw, ch; GdkImlibImage *im; GtkWidget *ww, *menu; gchar s[1024]; ww = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "widget")); im = (GdkImlibImage *)gtk_object_get_data(GTK_OBJECT(ww), "image"); button = event->button; x = event->x; y = event->y; w = widget->allocation.width; h = widget->allocation.height; if (button == 3) { menu = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(ww), "menu"); if (menu) gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, event->time); return; } else if (button == 2) { if (!edit_window) edit_window = ee_edit_new(); if (!GTK_WIDGET_VISIBLE(edit_window)) gtk_widget_show(edit_window); cx = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_x")); cy = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_y")); cw = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_w")); ch = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_h")); if ((x >= cx) && (x < (cx + cw)) && (y >= cy) && (y < (cy + ch))) { gtk_object_set_data(GTK_OBJECT(ww), "crop_do",GINT_TO_POINTER (3)); gtk_object_set_data(GTK_OBJECT(ww), "prev_x", GINT_TO_POINTER (x)); gtk_object_set_data(GTK_OBJECT(ww), "prev_y", GINT_TO_POINTER (y)); } else if ((x <= (cx + (cw / 2))) && (y <= (cy + (ch / 2))) && (x >= (cx - 8)) && (y >= (cy - 8))) { gtk_object_set_data(GTK_OBJECT(ww), "crop_do", GINT_TO_POINTER (2)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_x", GINT_TO_POINTER (1)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_y", GINT_TO_POINTER (1)); } else if ((x <= (cx + (cw / 2))) && (y >= (cy + (ch / 2))) && (x >= (cx - 8)) && (y <= (cy + ch + 8))) { gtk_object_set_data(GTK_OBJECT(ww), "crop_do", GINT_TO_POINTER (2)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_x", GINT_TO_POINTER (1)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_y", GINT_TO_POINTER (2)); } else if ((x >= (cx + (cw / 2))) && (y <= (cy + (ch / 2))) && (x <= (cx + cw + 8)) && (y >= (cy - 8))) { gtk_object_set_data(GTK_OBJECT(ww), "crop_do", GINT_TO_POINTER (2)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_x", GINT_TO_POINTER (2)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_y", GINT_TO_POINTER (1)); } else if ((x >= (cx + (cw / 2))) && (y >= (cy + (ch / 2))) && (x <= (cx + cw + 8)) && (y <= (cy + ch + 8))) { gtk_object_set_data(GTK_OBJECT(ww), "crop_do", GINT_TO_POINTER (2)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_x", GINT_TO_POINTER (2)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_y", GINT_TO_POINTER (2)); } else { ee_image_clear_crop(ww); gtk_object_set_data(GTK_OBJECT(ww), "crop_do", GINT_TO_POINTER (1)); gtk_object_set_data(GTK_OBJECT(ww), "crop_x", GINT_TO_POINTER (x)); gtk_object_set_data(GTK_OBJECT(ww), "crop_y", GINT_TO_POINTER (y)); gtk_object_set_data(GTK_OBJECT(ww), "crop_w", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(ww), "crop_h", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_x", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_y", GINT_TO_POINTER (0)); } } cx = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_x")); cy = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_y")); cw = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_w")); ch = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_h")); g_snprintf(s, sizeof(s), _("Crop: (%i, %i) (%i x %i)"), cx, cy, cw, ch); ee_edit_set_crop_label(edit_window, s); } static void ee_image_cb_button_up(GtkWidget * widget, GdkEventButton *event) { gint button; gint x, y, w, h, cdirx, cdiry; GdkImlibImage *im; GtkWidget *ww; ww = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "widget")); im = (GdkImlibImage *)gtk_object_get_data(GTK_OBJECT(ww), "image"); button = event->button; x = event->x; y = event->y; w = widget->allocation.width; h = widget->allocation.height; if (button == 2) { gtk_object_set_data(GTK_OBJECT(ww), "crop_do", GINT_TO_POINTER (0)); cdirx = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_dir_x")); cdiry = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_dir_y")); if ((!cdirx) || (!cdiry)) { ee_image_clear_crop(ww); gtk_object_set_data(GTK_OBJECT(ww), "crop_x", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(ww), "crop_y", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(ww), "crop_w", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(ww), "crop_h", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_x", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_y", GINT_TO_POINTER (0)); } } } static void ee_image_clear_crop(GtkWidget * widget) { GdkWindow *win; GtkWidget *a; gint x, y, w, h; a = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "view"); win = a->window; x = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_x")); y = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_y")); w = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_w")); h = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_h")); if ((w >= 10) && (h >= 10)) gdk_window_clear_area(win, x - 1 + (w >> 1) - 4, y - 1 + (h >> 1) - 4, 8, 8); gdk_window_clear_area(win, x - 8, y - 8, 8, h + 16); gdk_window_clear_area(win, x - 8, y - 8, w + 16, 8); gdk_window_clear_area(win, x + w, y - 8, 8, h + 16); gdk_window_clear_area(win, x - 8, y + h, w + 16, 8); } static void ee_image_draw_crop(GtkWidget * widget) { GdkWindow *win; GdkGC *gc; GdkColor c1, c2; GtkWidget *a; gint r, g, b; gint x, y, w, h; a = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(widget), "view"); win = a->window; x = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_x")); y = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_y")); w = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_w")); h = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(widget), "crop_h")); if ((w > 0) && (h > 0)) gdk_window_clear_area(win, x, y, w, h); gc = gdk_gc_new(win); r = 160, g = 200, b = 220; c1.pixel = gdk_imlib_best_color_match(&r, &g, &b); r = 0, g = 0, b = 0; c2.pixel = gdk_imlib_best_color_match(&r, &g, &b); gdk_gc_set_foreground(gc, &c1); if ((w >= 10) && (h >= 10)) { gdk_gc_set_foreground(gc, &c2); gdk_draw_rectangle(win, gc, FALSE, x - 1 + (w >> 1) - 4, y - 1 + (h >> 1) - 4, 7, 7); gdk_gc_set_foreground(gc, &c1); gdk_draw_rectangle(win, gc, TRUE, x - 1 + (w >> 1) - 3, y - 1 + (h >> 1) - 3, 6, 6); } gdk_gc_set_foreground(gc, &c2); gdk_draw_rectangle(win, gc, FALSE, x - 7 - 1, y - 7 - 1, 7, 7); gdk_gc_set_foreground(gc, &c1); gdk_draw_rectangle(win, gc, TRUE, x - 6 - 1, y - 6 - 1, 6, 6); gdk_gc_set_foreground(gc, &c2); gdk_draw_rectangle(win, gc, FALSE, x + w - 1 + 0 + 1, y - 7 - 1, 7, 7); gdk_gc_set_foreground(gc, &c1); gdk_draw_rectangle(win, gc, TRUE, x + w - 1 + 1 + 1, y - 6 - 1, 6, 6); gdk_gc_set_foreground(gc, &c2); gdk_draw_rectangle(win, gc, FALSE, x + w - 1 + 0 + 1, y + h + 1 - 1 + 0, 7, 7); gdk_gc_set_foreground(gc, &c1); gdk_draw_rectangle(win, gc, TRUE, x + w - 1 + 1 + 1, y + h + 1 - 1 + 1, 6, 6); gdk_gc_set_foreground(gc, &c2); gdk_draw_rectangle(win, gc, FALSE, x - 7 - 1, y + h + 1 - 1 + 0, 7, 7); gdk_gc_set_foreground(gc, &c1); gdk_draw_rectangle(win, gc, TRUE, x - 6 - 1, y + h + 1 + 1 - 1 + 1 - 1, 6, 6); gdk_gc_set_foreground(gc, &c2); gdk_draw_rectangle(win, gc, FALSE, x - 2 - 1, y - 2 - 1, w + 2 - 1 + 4, h + 2 - 1 + 4); gdk_draw_rectangle(win, gc, FALSE, x - 1, y - 1, w + 2 - 1, h + 2 - 1); gdk_gc_set_foreground(gc, &c1); gdk_draw_rectangle(win, gc, FALSE, x - 1 - 1, y - 1 - 1, w + 2 - 1 + 2, h + 2 - 1 + 2); gdk_flush(); gdk_gc_destroy(gc); } static void ee_image_cb_mouse_move(GtkWidget * widget, GdkEventMotion *event) { gint x, y, w, h; gint px, py, pw, ph, cx, cy, cw, ch, cdirx, cdiry; GdkImlibImage *im; GtkWidget *ww; gint cropping; gchar s[1024]; ww = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget), "widget")); im = (GdkImlibImage *)gtk_object_get_data(GTK_OBJECT(ww), "image"); x = event->x; y = event->y; w = widget->allocation.width; h = widget->allocation.height; cropping = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_do")); if (cropping == 1) { ee_image_clear_crop(ww); cx = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_x")); cy = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_y")); pw = cw = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_w")); ph = ch = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_h")); cdirx = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_dir_x")); cdiry = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_dir_y")); if (!cdirx) { if (x < cx) cdirx = 1; else if (x > cx) cdirx = 2; if (cdirx) gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_x", GINT_TO_POINTER (cdirx)); } if (!cdiry) { if (y < cy) cdiry = 1; else if (y > cy) cdiry = 2; if (cdiry) gtk_object_set_data(GTK_OBJECT(ww), "crop_dir_y", GINT_TO_POINTER (cdiry)); } if (x < 0) x = 0; if (x > w) x = w; if (cdirx == 1) { cw = cw + cx - x; } else if (cdirx == 2) { cw = x - cx; x = cx; } if (cw < 1) { cw = 1; if (x > (cx + pw - 1)) x = cx + pw - 1; if (pw == cw) x = cx; } else if (pw == cw) x = cx; if ((x + cw) > w) cw = w - x; gtk_object_set_data(GTK_OBJECT(ww), "crop_x", GINT_TO_POINTER (x)); gtk_object_set_data(GTK_OBJECT(ww), "crop_w", GINT_TO_POINTER (cw)); if (y < 0) y = 0; if (y > h) y = h; if (cdiry == 1) { ch = ch + cy - y; } else if (cdiry == 2) { ch = y - cy; y = cy; } if (ch < 1) { ch = 1; if (y > (cy + ph - 1)) y = cy + ph - 1; if (ph == ch) y = cy; } else if (ph == ch) y = cy; if ((y + ch) > h) ch = h - y; gtk_object_set_data(GTK_OBJECT(ww), "crop_y", GINT_TO_POINTER (y)); gtk_object_set_data(GTK_OBJECT(ww), "crop_h", GINT_TO_POINTER (ch)); ee_image_draw_crop(ww); } else if (cropping == 2) { ee_image_clear_crop(ww); cx = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_x")); cy = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_y")); pw = cw = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_w")); ph = ch = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_h")); cdirx = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_dir_x")); cdiry = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_dir_y")); if (x < 0) x = 0; if (x > w) x = w; if (cdirx == 1) { cw = cw + cx - x; } else if (cdirx == 2) { cw = x - cx; x = cx; } if (cw < 1) { cw = 1; if (x > (cx + pw - 1)) x = cx + pw - 1; if (pw == cw) x = cx; } else if (pw == cw) x = cx; if ((x + cw) > w) cw = w - x; gtk_object_set_data(GTK_OBJECT(ww), "crop_x", GINT_TO_POINTER (x)); gtk_object_set_data(GTK_OBJECT(ww), "crop_w", GINT_TO_POINTER (cw)); if (y < 0) y = 0; if (y > h) y = h; if (cdiry == 1) { ch = ch + cy - y; } else if (cdiry == 2) { ch = y - cy; y = cy; } if (ch < 1) { ch = 1; if (y > (cy + ph - 1)) y = cy + ph - 1; if (ph == ch) y = cy; } else if (ph == ch) y = cy; if ((y + ch) > h) ch = h - y; gtk_object_set_data(GTK_OBJECT(ww), "crop_y", GINT_TO_POINTER (y)); gtk_object_set_data(GTK_OBJECT(ww), "crop_h", GINT_TO_POINTER (ch)); ee_image_draw_crop(ww); } else if (cropping == 3) { ee_image_clear_crop(ww); cx = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_x")); cy = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_y")); px = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "prev_x")); py = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "prev_y")); cw = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_w")); ch = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_h")); cx += x - px; cy += y - py; if (cx < 0) cx = 0; if (cy < 0) cy = 0; if ((cx + cw) > w) cx = w - cw; if ((cy + ch) > h) cy = h - ch; gtk_object_set_data(GTK_OBJECT(ww), "prev_x", GINT_TO_POINTER (x)); gtk_object_set_data(GTK_OBJECT(ww), "prev_y", GINT_TO_POINTER (y)); gtk_object_set_data(GTK_OBJECT(ww), "crop_x", GINT_TO_POINTER (cx)); gtk_object_set_data(GTK_OBJECT(ww), "crop_y", GINT_TO_POINTER (cy)); ee_image_draw_crop(ww); } cx = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_x")); cy = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_y")); cw = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_w")); ch = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(ww), "crop_h")); g_snprintf(s, sizeof(s), _("Crop: (%i, %i) (%i x %i)"), cx, cy, cw, ch); ee_edit_set_crop_label(edit_window, s); } static int ee_image_key_pressed (GtkWidget *widget, GdkEventKey *event, gpointer data) { switch (event->keyval) { case GDK_BackSpace: func_prev(NULL, NULL); return TRUE; case GDK_space: func_next(NULL, NULL); return TRUE; case GDK_q: func_exit(NULL, NULL); return TRUE; default: break; } return FALSE; widget = NULL; data = NULL; } GtkWidget * ee_image_new(void) { GtkWidget *w, *a, *t, *al, *top, *bottom, *left, *right, *middle; GdkWindow *ic_win; GdkWindowAttr att; XIconSize *is; int i, count, j; GdkPixmap *pmap, *mask; w = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_wmclass(GTK_WINDOW(w), "ee", "Image Viewer"); gtk_window_set_title(GTK_WINDOW(w), _("Electric Eyes")); gtk_container_border_width(GTK_CONTAINER(w), 0); gtk_window_set_policy(GTK_WINDOW(w), 1, 1, 1); gtk_widget_realize(w); gtk_signal_connect (GTK_OBJECT (w), "key_press_event", GTK_SIGNAL_FUNC(ee_image_key_pressed), NULL); /* Guess what - UNLIKE every app out there, we are going to read the icon */ /* size hints and follow them AND follow ICCM by providing an icon window */ /* not a color pixmap sicne technically wer re only allowed to provide */ /* mono pixmaps - not color ones */ if ((XGetIconSizes(GDK_DISPLAY(), GDK_ROOT_WINDOW(), &is, &count)) && (count > 0)) { i = 0; /* use first icon size - not much point using the others */ att.width = is[i].max_width; att.height = 3 * att.width / 4; if (att.height < is[i].min_height) att.height = is[i].min_height; if (att.height > is[i].max_height) att.height = is[i].max_height; if (is[i].width_inc > 0) { j = ((att.width - is[i].min_width) / is[i].width_inc); att.width = is[i].min_width +(j * is[i].width_inc); } if (is[i].height_inc > 0) { j = ((att.height - is[i].min_height) / is[i].height_inc); att.height = is[i].min_height +(j * is[i].height_inc); } XFree(is); } else /* no icon size hints at all? ok - invent our own size */ { att.width = 32; att.height = 24; } att.wclass = GDK_INPUT_OUTPUT; att.window_type = GDK_WINDOW_TOPLEVEL; att.x = 0; att.y = 0; att.visual = gdk_imlib_get_visual(); att.colormap = gdk_imlib_get_colormap(); ic_win = gdk_window_new(NULL, &att, GDK_WA_VISUAL | GDK_WA_COLORMAP); if (!default_img) default_img = gdk_imlib_create_image_from_xpm_data(stdimg_xpm); gdk_window_set_icon(w->window, ic_win, NULL, NULL); gdk_imlib_render(default_img, att.width, att.height); pmap = gdk_imlib_move_image(default_img); mask = gdk_imlib_move_mask(default_img); gdk_window_set_back_pixmap(ic_win, pmap, FALSE); gdk_window_clear(ic_win); gdk_window_shape_combine_mask(ic_win, mask, 0, 0); gdk_imlib_free_pixmap(pmap); gdk_root = (GdkWindow *) &gdk_root_parent; gtk_signal_connect(GTK_OBJECT(w), "delete_event", GTK_SIGNAL_FUNC(ee_image_cb_destroy), w); t = gtk_table_new(3, 3, FALSE); gtk_widget_show(t); gtk_container_add(GTK_CONTAINER(w), t); top = gtk_hbox_new(FALSE, 0); gtk_widget_show(top); gtk_table_attach(GTK_TABLE(t), top, 1, 2, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL, 0, 0); gtk_object_set_data(GTK_OBJECT(w), "top", top); left = gtk_vbox_new(FALSE, 0); gtk_widget_show(left); gtk_table_attach(GTK_TABLE(t), left, 0, 1, 1, 2, GTK_FILL, GTK_FILL | GTK_SHRINK, 0, 0); gtk_object_set_data(GTK_OBJECT(w), "left", left); middle = gtk_vbox_new(FALSE, 0); gtk_widget_show(middle); gtk_table_attach(GTK_TABLE(t), middle, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0); gtk_object_set_data(GTK_OBJECT(w), "middle", middle); a = gtk_drawing_area_new(); gtk_signal_connect(GTK_OBJECT(a), "button_press_event", GTK_SIGNAL_FUNC(ee_image_cb_button_down), NULL); gtk_signal_connect(GTK_OBJECT(a), "button_release_event", GTK_SIGNAL_FUNC(ee_image_cb_button_up), NULL); gtk_signal_connect(GTK_OBJECT(a), "motion_notify_event", GTK_SIGNAL_FUNC(ee_image_cb_mouse_move), NULL); gtk_signal_connect(GTK_OBJECT(a), "configure_event", GTK_SIGNAL_FUNC(ee_image_cb_resize), NULL); gtk_signal_connect(GTK_OBJECT(a), "expose_event", GTK_SIGNAL_FUNC(ee_image_cb_redraw), NULL); gtk_widget_set_events(a, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK | GDK_EXPOSURE_MASK); gtk_box_pack_start(GTK_BOX(middle), a, TRUE, TRUE, 0); gtk_object_set_data(GTK_OBJECT(w), "view", a); gtk_object_set_data(GTK_OBJECT(a), "widget", w); gtk_widget_show(a); a = gtk_scrolled_window_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(middle), a, TRUE, TRUE, 0); gtk_object_set_data(GTK_OBJECT(w), "scrolled", a); gtk_widget_realize(a); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(a), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); al = gtk_alignment_new(0.5, 0.5, 0.0, 0.0); gtk_widget_show(al); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(a), al); gtk_object_set_data(GTK_OBJECT(w), "alignment", al); right = gtk_vbox_new(FALSE, 0); gtk_widget_show(right); gtk_table_attach(GTK_TABLE(t), right, 2, 3, 1, 2, GTK_FILL, GTK_FILL | GTK_SHRINK, 0, 0); gtk_object_set_data(GTK_OBJECT(w), "right", right); bottom = gtk_hbox_new(FALSE, 0); gtk_widget_show(bottom); gtk_table_attach(GTK_TABLE(t), bottom, 1, 2, 2, 3, GTK_FILL | GTK_SHRINK, GTK_FILL, 0, 0); gtk_object_set_data(GTK_OBJECT(w), "bottom", bottom); gtk_object_set_data(GTK_OBJECT(w), "image", NULL); gtk_object_set_data(GTK_OBJECT(w), "scrollable", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "forcescroll", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "width", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "height", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "crop_x", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "crop_y", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "crop_w", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "crop_h", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "crop_do", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "crop_dir_x", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "crop_dir_y", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "prev_x", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "prev_y", GINT_TO_POINTER (0)); gtk_object_set_data(GTK_OBJECT(w), "toolbar_pos", GINT_TO_POINTER (0)); return w; }