home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / gdisplay_ops.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  8.3 KB  |  319 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 <gtk/gtk.h>
  22.  
  23. #include "apptypes.h"
  24.  
  25. #include "appenv.h"
  26. #include "colormaps.h"
  27. #include "cursorutil.h"
  28. #include "fileops.h"
  29. #include "gdisplay_ops.h"
  30. #include "gimage.h"
  31. #include "gimpui.h"
  32. #include "gximage.h"
  33. #include "menus.h"
  34. #include "scale.h"
  35. #include "gimprc.h"
  36.  
  37. #include "libgimp/gimpintl.h"
  38.  
  39. static void gdisplay_close_warning_callback  (GtkWidget *widget,
  40.                           gboolean   close,
  41.                           gpointer   data);
  42. static void gdisplay_close_warning_dialog    (gchar     *image_name,
  43.                           GDisplay  *gdisp);
  44.  
  45. /*
  46.  *  This file is for operations on the gdisplay object
  47.  */
  48.  
  49. gulong
  50. gdisplay_white_pixel (GDisplay *gdisp)
  51. {
  52.   return g_white_pixel;
  53. }
  54.  
  55. gulong
  56. gdisplay_gray_pixel (GDisplay *gdisp)
  57. {
  58.   return g_gray_pixel;
  59. }
  60.  
  61. gulong
  62. gdisplay_black_pixel (GDisplay *gdisp)
  63. {
  64.   return g_black_pixel;
  65. }
  66.  
  67. gulong
  68. gdisplay_color_pixel (GDisplay *gdisp)
  69. {
  70.   return g_color_pixel;
  71. }
  72.  
  73.  
  74. void
  75. gdisplay_xserver_resolution (gdouble *xres,
  76.                  gdouble *yres)
  77. {
  78.   gint width, height;
  79.   gint widthMM, heightMM;
  80.  
  81.   width  = gdk_screen_width ();
  82.   height = gdk_screen_height ();
  83.  
  84.   widthMM  = gdk_screen_width_mm ();
  85.   heightMM = gdk_screen_height_mm ();
  86.  
  87.   /*
  88.    * From xdpyinfo.c:
  89.    *
  90.    * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
  91.    *
  92.    *     dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
  93.    *         = N pixels / (M inch / 25.4)
  94.    *         = N * 25.4 pixels / M inch
  95.    */
  96.  
  97.   *xres = (width  * 25.4) / ((gdouble) widthMM);
  98.   *yres = (height * 25.4) / ((gdouble) heightMM);
  99. }
  100.  
  101.  
  102. void
  103. gdisplay_new_view (GDisplay *gdisp)
  104. {
  105.   GDisplay *new_gdisp;
  106.  
  107.   /* make sure the image has been fully loaded... */
  108.   if (gdisp->gimage)
  109.     {
  110.       new_gdisp = gdisplay_new (gdisp->gimage, gdisp->scale);
  111.     }
  112. }
  113.  
  114.  
  115. void
  116. gdisplay_close_window (GDisplay *gdisp,
  117.                gboolean  kill_it)
  118. {
  119.   /*  FIXME: gimp_busy HACK not really appropriate here because we only
  120.    *  want to prevent the busy image and display to be closed.  --Mitch
  121.    */
  122.   if (gimp_busy)
  123.     return;
  124.  
  125.   /*  If the image has been modified, give the user a chance to save
  126.    *  it before nuking it--this only applies if its the last view
  127.    *  to an image canvas.  (a gimage with disp_count = 1)
  128.    */
  129.   if (! kill_it &&
  130.       (gdisp->gimage->disp_count == 1) &&
  131.       gdisp->gimage->dirty &&
  132.       confirm_on_close)
  133.     {
  134.       gdisplay_close_warning_dialog
  135.     (g_basename (gimage_filename (gdisp->gimage)), gdisp);
  136.     }
  137.   else
  138.     {
  139.       gtk_widget_destroy (gdisp->shell);
  140.     }
  141. }
  142.  
  143.  
  144. void
  145. gdisplay_shrink_wrap (GDisplay *gdisp)
  146. {
  147.   /* 
  148.    * I'm pretty sure this assumes that the current size is < display size
  149.    * Is this a valid assumption? 
  150.    */
  151.   GtkAllocation allocation;
  152.   gint disp_width, disp_height;
  153.   gint width, height;
  154.   gint shell_x, shell_y;
  155.   gint shell_width, shell_height;
  156.   gint max_auto_width, max_auto_height;
  157.   gint border_x, border_y;
  158.   gint s_width, s_height;
  159.  
  160.   gboolean resize = FALSE;
  161.  
  162.   s_width  = gdk_screen_width ();
  163.   s_height = gdk_screen_height ();
  164.  
  165.   width  = SCALEX (gdisp, gdisp->gimage->width);
  166.   height = SCALEY (gdisp, gdisp->gimage->height);
  167.  
  168.   disp_width  = gdisp->disp_width;
  169.   disp_height = gdisp->disp_height;
  170.  
  171.   shell_width  = gdisp->shell->allocation.width;
  172.   shell_height = gdisp->shell->allocation.height;
  173.  
  174.   border_x = shell_width  - disp_width;
  175.   border_y = shell_height - disp_height;
  176.  
  177.   max_auto_width  = (s_width  - border_x) * 0.75;
  178.   max_auto_height = (s_height - border_y) * 0.75;
  179.  
  180.   allocation.x = 0;
  181.   allocation.y = 0;
  182.  
  183.   /* If one of the display dimensions has changed and one of the
  184.    * dimensions fits inside the screen
  185.    */
  186.   if (((width + border_x) < s_width || (height + border_y) < s_height) &&
  187.       (width != disp_width || height != disp_height))
  188.     {
  189.       width  = ((width  + border_x) < s_width)  ? width  : max_auto_width;
  190.       height = ((height + border_y) < s_height) ? height : max_auto_height;
  191.  
  192.       resize = TRUE;
  193.     }
  194.   /*  If the projected dimension is greater than current, but less than
  195.    *  3/4 of the screen size, expand automagically
  196.    */
  197.   else if ((width > disp_width || height > disp_height) &&
  198.        (disp_width < max_auto_width || disp_height < max_auto_height))
  199.     {
  200.       width  = MIN (max_auto_width, width);
  201.       height = MIN (max_auto_height, height);
  202.  
  203.       resize = TRUE;
  204.     }
  205.  
  206.   if (resize)
  207.     {
  208.       if (width < gdisp->statusarea->requisition.width) 
  209.         { 
  210.           width = gdisp->statusarea->requisition.width; 
  211.         }
  212.  
  213. #undef RESIZE_DEBUG
  214. #ifdef RESIZE_DEBUG
  215.       g_print ("1w:%d/%d d:%d/%d s:%d/%d b:%d/%d\n",
  216.            width, height,
  217.            disp_width, disp_height,
  218.            shell_width, shell_height,
  219.            border_x, border_y);
  220. #endif /* RESIZE_DEBUG */
  221.  
  222.       gdisp->disp_width  = width;
  223.       gdisp->disp_height = height;
  224.  
  225.       allocation.width  = width  + border_x;
  226.       allocation.height = height + border_y;
  227.  
  228.       /*  don't call gdisplay_canvas_events() on any of the following
  229.        *  changes because our caller has to do a full display update anyway
  230.        */
  231.       gtk_signal_handler_block_by_data (GTK_OBJECT (gdisp->canvas), gdisp);
  232.  
  233.       gtk_widget_size_allocate (gdisp->shell, &allocation);
  234.  
  235.       gdk_window_resize (gdisp->shell->window,
  236.              allocation.width,
  237.              allocation.height);
  238.  
  239.       /*  let Gtk/X/WM position the window  */
  240.       while (gtk_events_pending ())
  241.     gtk_main_iteration ();
  242.  
  243.       gdk_window_get_origin (gdisp->shell->window, &shell_x, &shell_y);
  244.  
  245.       /*  if the window is offscreen, center it...  */
  246.       if (shell_x > s_width || shell_y > s_height ||
  247.       (shell_x + width +  border_x) < 0 || (shell_y + height + border_y) < 0)
  248.     {
  249.       shell_x = (s_width  - width  - border_x) >> 1;
  250.       shell_y = (s_height - height - border_y) >> 1;
  251.  
  252.       gdk_window_move (gdisp->shell->window, shell_x, shell_y);
  253.     }
  254.  
  255.       gtk_signal_handler_unblock_by_data (GTK_OBJECT (gdisp->canvas), gdisp);
  256.     }
  257.  
  258.   /*  If the width or height of the display has changed, recalculate
  259.    *  the display offsets...
  260.    */
  261.   if (disp_width  != gdisp->disp_width ||
  262.       disp_height != gdisp->disp_height)
  263.     {
  264.       gdisp->offset_x += (disp_width  - gdisp->disp_width) / 2;
  265.       gdisp->offset_y += (disp_height - gdisp->disp_height) / 2;
  266.     }
  267. }
  268.  
  269. /********************************************************
  270.  *   Routines to query before closing a dirty image     *
  271.  ********************************************************/
  272.  
  273. static void
  274. gdisplay_close_warning_callback (GtkWidget *widget,
  275.                  gboolean   close,
  276.                  gpointer   data)
  277. {
  278.   GDisplay *gdisp;
  279.  
  280.   gdisp = (GDisplay *) data;
  281.  
  282.   gdisp->warning_dialog = NULL;
  283.  
  284.   if (close)
  285.     gtk_widget_destroy (gdisp->shell);
  286. }
  287.  
  288. static void
  289. gdisplay_close_warning_dialog (gchar    *image_name,
  290.                    GDisplay *gdisp)
  291. {
  292.   GtkWidget *mbox;
  293.   gchar     *warning_buf;
  294.  
  295.   if (gdisp->warning_dialog != NULL)
  296.     {
  297.       gdk_window_raise (gdisp->warning_dialog->window);
  298.       return;
  299.     }
  300.  
  301.   warning_buf =
  302.     g_strdup_printf (_("Changes were made to %s.\nClose anyway?"), image_name);
  303.  
  304.   gdisp->warning_dialog = mbox =
  305.     gimp_query_boolean_box (image_name,
  306.                 gimp_standard_help_func,
  307.                 "dialogs/really_close.html",
  308.                 FALSE,
  309.                 warning_buf,
  310.                 _("Close"), _("Cancel"),
  311.                 NULL, NULL,
  312.                 gdisplay_close_warning_callback,
  313.                 gdisp);
  314.  
  315.   g_free (warning_buf);
  316.  
  317.   gtk_widget_show (mbox);
  318. }
  319.