home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / scroll.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  6.1 KB  |  244 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <stdlib.h>
  22.  
  23. #include <glib.h>
  24.  
  25. #include "apptypes.h"
  26.  
  27. #include "appenv.h"
  28. #include "apptypes.h"
  29. #include "scale.h"
  30. #include "scroll.h"
  31. #include "cursorutil.h"
  32. #include "tools.h"
  33. #include "nav_window.h"
  34.  
  35.  
  36. /*  This is the delay before dithering begins
  37.  *  for example, after an operation such as scrolling
  38.  */
  39. #define DITHER_DELAY 250  /*  milliseconds  */
  40.  
  41. /*  STATIC variables  */
  42. /*  These are the values of the initial pointer grab   */
  43. static int startx, starty;
  44.  
  45. gint
  46. scrollbar_vert_update (GtkAdjustment *adjustment,
  47.                gpointer       data)
  48. {
  49.   GDisplay *gdisp;
  50.  
  51.   gdisp = (GDisplay *) data;
  52.  
  53.   scroll_display (gdisp, 0, (adjustment->value - gdisp->offset_y));
  54.  
  55.   return FALSE;
  56. }
  57.  
  58.  
  59. gint
  60. scrollbar_horz_update (GtkAdjustment *adjustment,
  61.                gpointer       data)
  62. {
  63.   GDisplay *gdisp;
  64.  
  65.   gdisp = (GDisplay *) data;
  66.  
  67.   scroll_display (gdisp, (adjustment->value - gdisp->offset_x), 0);
  68.  
  69.   return FALSE;
  70. }
  71.  
  72. void
  73. start_grab_and_scroll (GDisplay       *gdisp,
  74.                GdkEventButton *bevent)
  75. {
  76.   startx = bevent->x + gdisp->offset_x;
  77.   starty = bevent->y + gdisp->offset_y;
  78.  
  79.   change_win_cursor (gdisp->canvas->window, GDK_FLEUR,
  80.              TOOL_TYPE_NONE, CURSOR_MODIFIER_NONE, FALSE);
  81. }
  82.  
  83.  
  84. void
  85. end_grab_and_scroll (GDisplay       *gdisp,
  86.              GdkEventButton *bevent)
  87. {
  88.   gdisplay_real_install_tool_cursor (gdisp,
  89.                      gdisp->current_cursor,
  90.                      gdisp->cursor_tool,
  91.                      CURSOR_MODIFIER_NONE,
  92.                      FALSE,
  93.                      TRUE);
  94. }
  95.  
  96.  
  97. void
  98. grab_and_scroll (GDisplay       *gdisp,
  99.          GdkEventMotion *mevent)
  100. {
  101.   if (mevent && mevent->window != gdisp->canvas->window)
  102.     {
  103.       return;
  104.     }
  105.  
  106.   scroll_display (gdisp,
  107.           startx - mevent->x - gdisp->offset_x,
  108.           starty - mevent->y - gdisp->offset_y);
  109. }
  110.  
  111.  
  112. void
  113. scroll_to_pointer_position (GDisplay       *gdisp,
  114.                 GdkEventMotion *mevent)
  115. {
  116.   double child_x, child_y;
  117.   int off_x, off_y;
  118.  
  119.   off_x = off_y = 0;
  120.  
  121.   /*  The cases for scrolling  */
  122.   if (mevent->x < 0)
  123.     off_x = mevent->x;
  124.   else if (mevent->x > gdisp->disp_width)
  125.     off_x = mevent->x - gdisp->disp_width;
  126.   if (mevent->y < 0)
  127.     off_y = mevent->y;
  128.   else if (mevent->y > gdisp->disp_height)
  129.     off_y = mevent->y - gdisp->disp_height;
  130.  
  131.   if (scroll_display (gdisp, off_x, off_y))
  132.     {
  133.       gdk_input_window_get_pointer (gdisp->canvas->window, mevent->deviceid,
  134.                     &child_x, &child_y, 
  135. #ifdef GTK_HAVE_SIX_VALUATORS
  136.                                     NULL, NULL, NULL, NULL, NULL);
  137. #else /* !GTK_HAVE_SIX_VALUATORS */
  138.                     NULL, NULL, NULL, NULL);
  139. #endif /* GTK_HAVE_SIX_VALUATORS */
  140.  
  141.       if (child_x == mevent->x && child_y == mevent->y)
  142.     /*  Put this event back on the queue -- so it keeps scrolling */
  143.     gdk_event_put ((GdkEvent *) mevent);
  144.     }
  145. }
  146.  
  147.  
  148. int
  149. scroll_display (GDisplay *gdisp,
  150.         gint      x_offset,
  151.         gint      y_offset)
  152. {
  153.   int old_x, old_y;
  154.   int src_x, src_y;
  155.   int dest_x, dest_y;
  156.   GdkEvent *event;
  157.  
  158.   old_x = gdisp->offset_x;
  159.   old_y = gdisp->offset_y;
  160.  
  161.   gdisp->offset_x += x_offset;
  162.   gdisp->offset_y += y_offset;
  163.  
  164.   bounds_checking (gdisp);
  165.  
  166.   /*  the actual changes in offset  */
  167.   x_offset = (gdisp->offset_x - old_x);
  168.   y_offset = (gdisp->offset_y - old_y);
  169.  
  170.   if (x_offset || y_offset)
  171.     {
  172.       setup_scale (gdisp);
  173.  
  174.       src_x = (x_offset < 0) ? 0 : x_offset;
  175.       src_y = (y_offset < 0) ? 0 : y_offset;
  176.       dest_x = (x_offset < 0) ? -x_offset : 0;
  177.       dest_y = (y_offset < 0) ? -y_offset : 0;
  178.  
  179.       /*  reset the old values so that the tool can accurately redraw  */
  180.       gdisp->offset_x = old_x;
  181.       gdisp->offset_y = old_y;
  182.  
  183.       /*  stop the currently active tool  */
  184.       active_tool_control (PAUSE, (void *) gdisp);
  185.  
  186.       /*  set the offsets back to the new values  */
  187.       gdisp->offset_x += x_offset;
  188.       gdisp->offset_y += y_offset;
  189.  
  190.       gdk_draw_pixmap (gdisp->canvas->window,
  191.                gdisp->scroll_gc,
  192.                gdisp->canvas->window,
  193.                src_x, src_y,
  194.                dest_x, dest_y,
  195.                (gdisp->disp_width - abs (x_offset)),
  196.                (gdisp->disp_height - abs (y_offset)));
  197.  
  198.       /*  resume the currently active tool  */
  199.       active_tool_control (RESUME, (void *) gdisp);
  200.  
  201.       /*  scale the image into the exposed regions  */
  202.       if (x_offset)
  203.     {
  204.       src_x = (x_offset < 0) ? 0 : gdisp->disp_width - x_offset;
  205.       src_y = 0;
  206.       gdisplay_expose_area (gdisp,
  207.                 src_x, src_y,
  208.                 abs (x_offset), gdisp->disp_height);
  209.     }
  210.       if (y_offset)
  211.     {
  212.       src_x = 0;
  213.       src_y = (y_offset < 0) ? 0 : gdisp->disp_height - y_offset;
  214.       gdisplay_expose_area (gdisp,
  215.                 src_x, src_y,
  216.                 gdisp->disp_width, abs (y_offset));
  217.     }
  218.  
  219.       if (x_offset || y_offset)
  220.     gdisplays_flush ();
  221.  
  222.       nav_window_update_window_marker(gdisp->window_nav_dialog); 
  223.  
  224.       /* Make sure graphics expose events are processed before scrolling
  225.        * again */
  226.       
  227.       while ((event = gdk_event_get_graphics_expose (gdisp->canvas->window)) 
  228.            != NULL)
  229.       {
  230.         gtk_widget_event (gdisp->canvas, event);
  231.         if (event->expose.count == 0)
  232.           {
  233.             gdk_event_free (event);
  234.             break;
  235.           }
  236.         gdk_event_free (event);
  237.       }
  238.  
  239.       return 1;
  240.     }
  241.  
  242.   return 0;
  243. }
  244.