/* Copyright (C) 1999 Southern Gold Development * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define USE_DND #include "gview.h" #include "icons/gview.xpm" void openBrowser(GtkWidget *widget, gpointer data) { sgview *view; view = (sgview *) data; if (view->main) return; if (view->vMenu) { view->vMenu = NULL; } createWin(view); gloaddir(view); } gint resizePic(GtkWidget *widget, GdkEvent *event, gpointer data) { sgview *view; gchar *title; gint rx, ry; view = (sgview *) data; rx = widget->allocation.width; ry = widget->allocation.height; title = g_strdup_printf("gView - %s - %dx%d", view->currPic->filename, rx, ry); gtk_window_set_title(GTK_WINDOW (view->disp), title); g_free(title); gdk_imlib_apply_image(view->currPic, widget->window); return TRUE; } void killDiag(GtkWidget *widget, gpointer data) { sgview *view; view = (sgview *) data; if (view->setrsp) view->setrsp = NULL; } void killViewer(GtkWidget *widget, gpointer data) { sgview *view; view = (sgview *) data; gtk_widget_destroy(view->disp); } void menuVComment(GtkWidget *widget, gpointer data) { sgview *view; view = (sgview *) data; setGVComment(view, rindex(view->currPic->filename, '/')); } void popupPic(sgview *view, GdkEventButton *event) { GtkWidget *menu, *submenu; if (!view->vMenu) { menu = gtk_menu_new(); view->vMenu = menu; submenu = gtk_menu_new(); gAddMenu(view, GTK_MENU (submenu), _("Image Levels"), (GtkSignalFunc) setDialog); gAddMenu(view, GTK_MENU (submenu), _("Red Levels"), (GtkSignalFunc) redDialog); gAddMenu(view, GTK_MENU (submenu), _("Blue Levels"), (GtkSignalFunc) blueDialog); gAddMenu(view, GTK_MENU (submenu), _("Green Levels"), (GtkSignalFunc) greenDialog); gAddSubMenu(view, GTK_MENU (menu), submenu, _("Manipulate Image")); if (view->main) { submenu = gtk_menu_new(); gAddMenu(view, GTK_MENU (submenu), _("Start"), (GtkSignalFunc) startSlide); gAddMenu(view, GTK_MENU (submenu), _("Stop"), (GtkSignalFunc) stopSlide); gAddMenu(view, GTK_MENU (submenu), _("Pause"), (GtkSignalFunc) pauseSlide); gAddMenu(view, GTK_MENU (submenu), _("Resume"), (GtkSignalFunc) resumeSlide); gAddSubMenu(view, GTK_MENU (menu), submenu, _("SlideShow")); } else { gAddMenu(view, GTK_MENU (menu), _("Open Browser"), (GtkSignalFunc) openBrowser); } gAddMenu(view, GTK_MENU (menu), _("Set As Background"), (GtkSignalFunc) setBack); gAddMenu(view, GTK_MENU (menu), _("Edit Comment"), (GtkSignalFunc) menuVComment); gAddMenu(view, GTK_MENU (menu), _("Save Image As..."), (GtkSignalFunc) saveImageDialog); gAddMenu(view, GTK_MENU (menu), _("Close Image"), (GtkSignalFunc) killViewer); } gtk_menu_popup(GTK_MENU (view->vMenu), NULL, NULL, NULL, NULL, event->button, event->time); } void navImage(sgview *view, gboolean forward) { gint row, mod; gchar *file; if (!(view->main)) return; row = GTK_CLIST (view->clist)->focus_row; if (forward) { mod = 1; if ((row == -1) || (row == (GTK_CLIST (view->clist)->rows) - 1)) return; } else { mod = -1; if ((row == -1) || (row == 0)) return; } GTK_CLIST (view->clist)->focus_row += mod; gtk_clist_unselect_row(GTK_CLIST (view->clist), row, 0); row += mod; gtk_clist_select_row(GTK_CLIST (view->clist), row, 0); gtk_clist_moveto(GTK_CLIST (view->clist), row, 0, 0.5, 0.5); gtk_clist_get_text(GTK_CLIST (view->clist), row, 0, &file); if ((file[strlen(file) - 1] != '/') && (file[strlen(file) - 1] != ')')) handleFile(view, file); } void zoomImage(sgview *view, gboolean in) { gint xim, yim, xr, yr, hr, wr, dr, dx, dy, xfr, yfr; GtkPolicyType xovers, yovers; GdkCursor *curs; xim = GTK_WIDGET (view->draw)->allocation.width; yim = GTK_WIDGET (view->draw)->allocation.height; gdk_window_get_geometry(GDK_ROOT_PARENT(), &xr, &yr, &wr, &hr, &dr); gtk_signal_handler_block(GTK_OBJECT (view->draw), view->sigConf); if (in == -11) { xim = view->currPic->rgb_width; yim = view->currPic->rgb_height; view->factor = 1.0; } else { if (in) { view->factor *= ZOOMFACTOR; xim = (gint) (ZOOMFACTOR * xim); yim = (gint) (ZOOMFACTOR * yim); } else { view->factor /= ZOOMFACTOR; xim = (gint) (xim / ZOOMFACTOR); yim = (gint) (yim / ZOOMFACTOR); } } dx = xim; dy = yim; xovers = GTK_POLICY_NEVER; xfr = 4; yovers = GTK_POLICY_NEVER; yfr = 4; if (xim + 85 > wr) { xim = wr - 85; xovers = GTK_POLICY_ALWAYS; yfr = 23; } if (yim + 85 > hr) { yim = hr - 85; yovers = GTK_POLICY_ALWAYS; yfr = 23; } gtk_widget_set_usize(GTK_WIDGET (view->draw), dx, dy); gtk_widget_set_usize(GTK_WIDGET (view->disp), xim + yfr, yim + xfr); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (view->scr), xovers, yovers); if ((xfr == 23) || (yfr == 23)) curs = gdk_cursor_new(GDK_HAND2); else curs = gdk_cursor_new(GDK_LEFT_PTR); gdk_window_set_cursor(view->draw->window, curs); gdk_cursor_destroy(curs); gtk_widget_set_usize(GTK_WIDGET (view->scr), dx, dy); gdk_imlib_apply_image(view->currPic, view->draw->window); gtk_signal_handler_unblock(GTK_OBJECT (view->draw), view->sigConf); } void doMove(sgview *view, GViewMoveType move, gboolean vert) { GtkAdjustment *adj; gfloat val, step, edge; gboolean flag; if (vert) adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW (view->scr)); else adj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW (view->scr)); switch (move) { case GVIEW_UP_STEP: step = adj->step_increment; edge = adj->upper - adj->page_size; flag = TRUE; break; case GVIEW_DOWN_STEP: step = -(adj->step_increment); edge = adj->lower; flag = FALSE; break; case GVIEW_UP_PAGE: step = adj->page_increment; edge = adj->upper - adj->page_size; flag = TRUE; break; case GVIEW_DOWN_PAGE: step = -(adj->page_increment); edge = adj->lower; flag = FALSE; break; default: return; break; } val = adj->value + step; if (flag) { if (val > edge) val = edge; } else if (val < edge) val = edge; gtk_adjustment_set_value(adj, val); } gint viewKeys(GtkWidget *widget, GdkEventKey *event, gpointer data) { sgview *view; view = (sgview *) data; switch (event->keyval) { case GDK_V: case GDK_v: gdk_imlib_flip_image_vertical(view->currPic); gdk_imlib_apply_image(view->currPic, view->draw->window); break; case GDK_H: case GDK_h: gdk_imlib_flip_image_horizontal(view->currPic); gdk_imlib_apply_image(view->currPic, view->draw->window); break; case GDK_Q: case GDK_q: gtk_widget_destroy(view->disp); break; case GDK_Left: doMove(view, GVIEW_DOWN_STEP, FALSE); break; case GDK_Right: doMove(view, GVIEW_UP_STEP, FALSE); break; case GDK_Up: doMove(view, GVIEW_DOWN_STEP, TRUE); break; case GDK_Down: doMove(view, GVIEW_UP_STEP, TRUE); break; case GDK_Page_Up: if (event->state & GDK_SHIFT_MASK) doMove(view, GVIEW_DOWN_PAGE, FALSE); else doMove(view, GVIEW_DOWN_PAGE, TRUE); break; case GDK_Page_Down: if (event->state & GDK_SHIFT_MASK) doMove(view, GVIEW_UP_PAGE, FALSE); else doMove(view, GVIEW_UP_PAGE, TRUE); break; case GDK_n: case GDK_N: navImage(view, TRUE); break; case GDK_p: case GDK_P: navImage(view, FALSE); break; case GDK_plus: case GDK_equal: case GDK_KP_Add: zoomImage(view, TRUE); break; case GDK_minus: case GDK_KP_Subtract: zoomImage(view, FALSE); break; case GDK_1: zoomImage(view, -11); default: break; } gtk_signal_emit_stop_by_name(GTK_OBJECT (widget), "key_press_event"); return TRUE; } void killView(GtkWidget *widget, gpointer data) { sgview *view; view = (sgview *) data; view->disp = NULL; if (view->setrsp) gtk_widget_destroy(view->setrsp); view->setrsp = NULL; if (view->backPic != view->currPic) gdk_imlib_kill_image(view->backPic); gdk_imlib_kill_image(view->currPic); view->currPic = NULL; if (!(view->main)) { #ifdef HAVE_WORKING_MSG if (view->dqueue != -1) msgctl(view->dqueue, IPC_RMID, NULL); #endif /* HAVE_WORKING_MSG */ g_free(view); gtk_main_quit(); } } void loadPic(sgview *view, gchar *file) { GtkWidget *win, *scr, *draw; GdkImlibImage *im; GtkAdjustment *sadj; GdkCursor *curs; GdkPixmap *pixm; GdkBitmap *mask; GtkStyle *style; gchar *title, *dim, *fend; GdkImlibColorModifier mod; gint dx, dy, xim, yim, xr, yr, wr, hr, dr, place, depth, xfr, yfr; GtkPolicyType xovers, yovers; if (isExtern(view, file)) { runExtern(view, file); return; } gdk_window_get_geometry(GDK_ROOT_PARENT(), &xr, &yr, &wr, &hr, &dr); depth = gdk_visual_get_best_depth(); im = gdk_imlib_load_image(file); if (!(im)) return; xim = im->rgb_width; yim = im->rgb_height; if (view->statCh & 0x80) { if (fabs(view->factor-1.0)>0.0001) { xim = (gint) (view->factor * xim); yim = (gint) (view->factor * yim); } } dx = xim; dy = yim; xovers = GTK_POLICY_NEVER; xfr = 4; yovers = GTK_POLICY_NEVER; yfr = 4; if (xim + 85 > wr) { xim = wr - 85; xovers = GTK_POLICY_ALWAYS; xfr = 23; } if (yim + 85 > hr) { yim = hr - 85; yovers = GTK_POLICY_ALWAYS; yfr = 23; } if (view->currPic) { if (view->backPic != view->currPic) gdk_imlib_kill_image(view->backPic); gdk_imlib_kill_image(view->currPic); } view->currPic = im; view->backPic = view->currPic; dim = g_strdup_printf("%dx%d", dx, dy); if ((view->main) && (view->statCh & 0x02)) gtk_clist_set_text(GTK_CLIST (view->clist), GTK_CLIST(view->clist)->focus_row, 2, dim); fend = rindex (file, '/'); fend++; title = g_strconcat("gView - ", fend, " - ", dim, NULL); g_free (dim); if (view->disp) { if (view->setrsp) gtk_widget_destroy(view->setrsp); view->setrsp = NULL; gtk_signal_handler_block(GTK_OBJECT (view->disp), view->sigKey); gtk_signal_handler_block(GTK_OBJECT (view->draw), view->sigConf); if (view->main) { gtk_signal_handler_block(GTK_OBJECT (view->clist), view->sigBKey); gtk_signal_handler_block(GTK_OBJECT (view->clist), view->sigBMouse); } gtk_window_set_title(GTK_WINDOW (view->disp), title); gtk_widget_set_usize(GTK_WIDGET (view->disp), xim + yfr, yim + xfr); gtk_widget_set_usize(GTK_WIDGET (view->scr), xim, yim); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (view->scr), xovers, yovers); sadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW (view->scr)); gtk_adjustment_set_value(sadj, 0); sadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW (view->scr)); gtk_adjustment_set_value(sadj, 0); gtk_drawing_area_size(GTK_DRAWING_AREA (view->draw), dx, dy); gtk_widget_set_usize(GTK_WIDGET (view->draw), dx, dy); gtk_widget_reset_shapes(GTK_WIDGET (view->draw)); while (gtk_events_pending()) gtk_main_iteration(); place = view->defGamma * 256; gdk_imlib_get_image_modifier(im, &mod); mod.gamma = place; gdk_imlib_set_image_modifier(im, &mod); gdk_imlib_apply_image(im, view->draw->window); while (gtk_events_pending()) gtk_main_iteration(); gtk_signal_handler_unblock(GTK_OBJECT (view->disp), view->sigKey); gtk_signal_handler_unblock(GTK_OBJECT (view->draw), view->sigConf); if (view->main) { gtk_signal_handler_unblock(GTK_OBJECT (view->clist), view->sigBMouse); gtk_signal_handler_unblock(GTK_OBJECT (view->clist), view->sigBKey); } } else { view->setrsp = NULL; if (view->main) { gtk_signal_handler_block(GTK_OBJECT (view->clist), view->sigBKey); gtk_signal_handler_block(GTK_OBJECT (view->clist), view->sigBMouse); } win = gtk_window_new(GTK_WINDOW_TOPLEVEL); view->disp = win; gtk_window_set_title(GTK_WINDOW (win), title); gtk_window_set_policy(GTK_WINDOW (win), TRUE, TRUE, TRUE); gtk_window_set_position(GTK_WINDOW (win), GTK_WIN_POS_MOUSE); gtk_signal_connect(GTK_OBJECT (win), "destroy", (GtkSignalFunc) killView, (gpointer) view); view->sigKey = gtk_signal_connect(GTK_OBJECT (win), "key_press_event", (GtkSignalFunc) viewKeys, (gpointer) view); gtk_container_border_width(GTK_CONTAINER (win), 0); gtk_widget_set_usize(GTK_WIDGET (win), xim + yfr, yim + xfr); scr = gtk_scrolled_window_new(NULL, NULL); view->scr = scr; gtk_container_border_width(GTK_CONTAINER (scr), 0); gtk_widget_set_usize(GTK_WIDGET (scr), xim, yim); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scr), xovers, yovers); gtk_container_add(GTK_CONTAINER (win), scr); draw = gtk_drawing_area_new(); gtk_drawing_area_size(GTK_DRAWING_AREA (draw), dx, dy); view->draw = draw; gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW (scr), draw); gtk_signal_connect(GTK_OBJECT (draw), "button_press_event", (GtkSignalFunc) startDragPic, (gpointer) view); gtk_signal_connect(GTK_OBJECT (draw), "motion_notify_event", (GtkSignalFunc) doDragPic, (gpointer) view); gtk_signal_connect(GTK_OBJECT (draw), "button_release_event", (GtkSignalFunc) stopDragPic, (gpointer) view); gtk_drag_dest_set(draw, GTK_DEST_DEFAULT_ALL, target_table, 3, GDK_ACTION_COPY | GDK_ACTION_MOVE); gtk_signal_connect(GTK_OBJECT (draw), "drag_data_received", (GtkSignalFunc) dropDragFile, (gpointer) view); gtk_widget_set_events(draw, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); gtk_widget_show(draw); gtk_widget_show(scr); gtk_widget_show(win); style = gtk_widget_get_default_style(); pixm = gdk_pixmap_create_from_xpm_d(GDK_ROOT_PARENT(), &mask, &style->bg[GTK_STATE_NORMAL], gview_xpm); gdk_window_set_icon(win->window, NULL, pixm, mask); g_free(pixm); g_free(mask); place = view->defGamma * 256; gdk_imlib_get_image_modifier(im, &mod); mod.gamma = place; gdk_imlib_set_image_modifier(im, &mod); gdk_imlib_apply_image(im, view->draw->window); while (gtk_events_pending()) gtk_main_iteration(); view->sigConf = gtk_signal_connect(GTK_OBJECT (draw), "configure-event", (GtkSignalFunc) resizePic, (gpointer) view); if (view->main) { gtk_signal_handler_unblock(GTK_OBJECT (view->clist), view->sigBMouse); gtk_signal_handler_unblock(GTK_OBJECT (view->clist), view->sigBKey); } } g_free(title); getGVComment(view, rindex(file, '/')); while (gtk_events_pending()) gtk_main_iteration(); if ((xfr == 23) || (yfr == 23)) curs = gdk_cursor_new(GDK_HAND2); else curs = gdk_cursor_new(GDK_LEFT_PTR); gdk_window_set_cursor(view->draw->window, curs); gdk_cursor_destroy(curs); gtk_drawing_area_size(GTK_DRAWING_AREA (view->draw), dx, dy); gdk_imlib_apply_image(im, view->draw->window); if (view->main) gtk_widget_grab_focus(GTK_WIDGET (view->clist)); }