home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / flip_tool.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  7.5 KB  |  303 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 <gtk/gtk.h>
  24. #include <gdk/gdkkeysyms.h>
  25.  
  26. #include "apptypes.h"
  27.  
  28. #include "appenv.h"
  29. #include "cursorutil.h"
  30. #include "drawable.h"
  31. #include "flip_tool.h"
  32. #include "gdisplay.h"
  33. #include "gimage_mask.h"
  34. #include "gimpui.h"
  35. #include "path_transform.h"
  36.  
  37. #include "tile_manager_pvt.h"            /* ick. */
  38.  
  39. #include "libgimp/gimpintl.h"
  40.  
  41. #define FLIP_INFO 0
  42.  
  43. /*  the flip structures  */
  44.  
  45. typedef struct _FlipOptions FlipOptions;
  46.  
  47. struct _FlipOptions
  48. {
  49.   ToolOptions              tool_options;
  50.  
  51.   InternalOrientationType  type;
  52.   InternalOrientationType  type_d;
  53.   GtkWidget               *type_w[2];
  54. };
  55.  
  56. static FlipOptions *flip_options = NULL;
  57.  
  58. /*  functions  */
  59.  
  60. /*  FIXME: Lame - 1 hacks abound since the code assumes certain values for
  61.  *  the ORIENTATION_FOO constants.
  62.  */
  63.  
  64. static void
  65. flip_options_reset (void)
  66. {
  67.   FlipOptions *options = flip_options;
  68.  
  69.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->type_w[options->type_d - 1]), TRUE); 
  70. }
  71.  
  72. static FlipOptions *
  73. flip_options_new (void)
  74. {
  75.   FlipOptions *options;
  76.  
  77.   GtkWidget *vbox;
  78.   GtkWidget *frame;
  79.  
  80.   /*  the new flip tool options structure  */
  81.   options = g_new (FlipOptions, 1);
  82.   tool_options_init ((ToolOptions *) options,
  83.              _("Flip Tool"),
  84.              flip_options_reset);
  85.   options->type = options->type_d = ORIENTATION_HORIZONTAL;
  86.  
  87.   /*  the main vbox  */
  88.   vbox = options->tool_options.main_vbox;
  89.  
  90.   /*  tool toggle  */
  91.   frame =
  92.     gimp_radio_group_new2 (TRUE, _("Tool Toggle"),
  93.                gimp_radio_button_update,
  94.                &options->type, (gpointer) options->type,
  95.  
  96.                _("Horizontal"), (gpointer) ORIENTATION_HORIZONTAL,
  97.                &options->type_w[0],
  98.                _("Vertical"), (gpointer) ORIENTATION_VERTICAL,
  99.                &options->type_w[1],
  100.  
  101.                NULL);
  102.  
  103.   gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
  104.   gtk_widget_show (frame);
  105.  
  106.   return options;
  107. }
  108.  
  109. static void
  110. flip_modifier_key_func (Tool        *tool,
  111.             GdkEventKey *kevent,
  112.             gpointer     gdisp_ptr)
  113. {
  114.   switch (kevent->keyval)
  115.     {
  116.     case GDK_Alt_L: case GDK_Alt_R:
  117.       break;
  118.     case GDK_Shift_L: case GDK_Shift_R:
  119.       break;
  120.     case GDK_Control_L: case GDK_Control_R:
  121.       if (flip_options->type == ORIENTATION_HORIZONTAL)
  122.     {
  123.       gtk_toggle_button_set_active
  124.         (GTK_TOGGLE_BUTTON (flip_options->type_w[ORIENTATION_VERTICAL - 1]), TRUE);
  125.     }
  126.       else
  127.     {
  128.       gtk_toggle_button_set_active
  129.         (GTK_TOGGLE_BUTTON (flip_options->type_w[ORIENTATION_HORIZONTAL - 1]), TRUE);
  130.     }
  131.       break;
  132.     }
  133. }
  134.   
  135. TileManager *
  136. flip_tool_transform (Tool           *tool,
  137.                      gpointer        gdisp_ptr,
  138.                      TransformState  state)
  139. {
  140.   TransformCore *transform_core;
  141.   GDisplay      *gdisp;
  142.  
  143.   transform_core = (TransformCore *) tool->private;
  144.   gdisp = (GDisplay *) gdisp_ptr;
  145.  
  146.   switch (state)
  147.     {
  148.     case INIT:
  149.       transform_info = NULL;
  150.       break;
  151.  
  152.     case MOTION:
  153.       break;
  154.  
  155.     case RECALC:
  156.       break;
  157.  
  158.     case FINISH:
  159.       /*      transform_core->trans_info[FLIP] *= -1.0;*/
  160.       return flip_tool_flip (gdisp->gimage,
  161.                    gimage_active_drawable (gdisp->gimage),
  162.                  transform_core->original, 
  163.                  (int) transform_core->trans_info[FLIP_INFO],
  164.                  flip_options->type);
  165.       break;
  166.     }
  167.  
  168.   return NULL;
  169. }
  170.  
  171. static void
  172. flip_cursor_update (Tool           *tool,
  173.             GdkEventMotion *mevent,
  174.             gpointer        gdisp_ptr)
  175. {
  176.   GDisplay      *gdisp;
  177.   GimpDrawable  *drawable;
  178.   GdkCursorType  ctype = GIMP_BAD_CURSOR;
  179.  
  180.   gdisp = (GDisplay *) gdisp_ptr;
  181.   
  182.   if ((drawable = gimage_active_drawable (gdisp->gimage)))
  183.     {
  184.       gint x, y;
  185.       gint off_x, off_y;
  186.  
  187.       drawable_offsets (drawable, &off_x, &off_y);
  188.       gdisplay_untransform_coords (gdisp, 
  189.                    (double) mevent->x, (double) mevent->y,
  190.                    &x, &y, TRUE, FALSE);
  191.  
  192.       if (x >= off_x && y >= off_y &&
  193.       x < (off_x + drawable_width (drawable)) &&
  194.       y < (off_y + drawable_height (drawable)))
  195.     {
  196.       /*  Is there a selected region? If so, is cursor inside? */
  197.       if (gimage_mask_is_empty (gdisp->gimage) ||
  198.           gimage_mask_value (gdisp->gimage, x, y))
  199.         {
  200.           if (flip_options->type == ORIENTATION_HORIZONTAL)
  201.         ctype = GDK_SB_H_DOUBLE_ARROW;
  202.           else
  203.         ctype = GDK_SB_V_DOUBLE_ARROW;
  204.         }
  205.     }
  206.     }
  207.   gdisplay_install_tool_cursor (gdisp, ctype,
  208.                 FLIP,
  209.                 CURSOR_MODIFIER_NONE,
  210.                 ctype == GDK_SB_V_DOUBLE_ARROW);
  211. }
  212.  
  213. Tool *
  214. tools_new_flip (void)
  215. {
  216.   Tool          *tool;
  217.   TransformCore *private;
  218.  
  219.   /*  The tool options  */
  220.   if (! flip_options)
  221.     {
  222.       flip_options = flip_options_new ();
  223.       tools_register (FLIP, (ToolOptions *) flip_options);
  224.     }
  225.  
  226.   tool = transform_core_new (FLIP, FALSE);
  227.   private = tool->private;
  228.  
  229.   private->trans_func = flip_tool_transform;
  230.   private->trans_info[FLIP_INFO] = -1.0;
  231.  
  232.   tool->modifier_key_func  = flip_modifier_key_func;
  233.   tool->cursor_update_func = flip_cursor_update;
  234.  
  235.   return tool;
  236. }
  237.  
  238. void
  239. tools_free_flip_tool (Tool *tool)
  240. {
  241.   transform_core_free (tool);
  242. }
  243.  
  244. TileManager *
  245. flip_tool_flip (GimpImage               *gimage,
  246.         GimpDrawable            *drawable,
  247.         TileManager             *orig,
  248.         gint                     flip,
  249.         InternalOrientationType  type)
  250. {
  251.   TileManager *new;
  252.   PixelRegion  srcPR, destPR;
  253.   gint i;
  254.  
  255.   if (!orig)
  256.     return NULL;
  257.  
  258.   if (flip > 0)
  259.     {
  260.       new = tile_manager_new (orig->width, orig->height, orig->bpp);
  261.       pixel_region_init (&srcPR, orig, 0, 0, orig->width, orig->height, FALSE);
  262.       pixel_region_init (&destPR, new, 0, 0, orig->width, orig->height, TRUE);
  263.  
  264.       copy_region (&srcPR, &destPR);
  265.       new->x = orig->x;
  266.       new->y = orig->y;
  267.     }
  268.   else
  269.     {
  270.       new = tile_manager_new (orig->width, orig->height, orig->bpp);
  271.       new->x = orig->x;
  272.       new->y = orig->y;
  273.  
  274.       if (type == ORIENTATION_HORIZONTAL)
  275.     for (i = 0; i < orig->width; i++)
  276.       {
  277.         pixel_region_init (&srcPR, orig, i, 0, 1, orig->height, FALSE);
  278.         pixel_region_init (&destPR, new,
  279.                    (orig->width - i - 1), 0, 1, orig->height, TRUE);
  280.         copy_region (&srcPR, &destPR); 
  281.       }
  282.       else
  283.     for (i = 0; i < orig->height; i++)
  284.       {
  285.         pixel_region_init (&srcPR, orig, 0, i, orig->width, 1, FALSE);
  286.         pixel_region_init (&destPR, new,
  287.                    0, (orig->height - i - 1), orig->width, 1, TRUE);
  288.         copy_region (&srcPR, &destPR);
  289.       }
  290.  
  291.       /* flip locked paths */
  292.       /* Note that the undo structures etc are setup before we enter this
  293.        * function.
  294.        */
  295.       if (type == ORIENTATION_HORIZONTAL)
  296.     path_transform_flip_horz (gimage);
  297.       else
  298.     path_transform_flip_vert (gimage);
  299.     }
  300.  
  301.   return new;
  302. }
  303.