home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / layer_select.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  12.8 KB  |  479 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. #include <gdk/gdkkeysyms.h>
  23.  
  24. #include "apptypes.h"
  25.  
  26. #include "appenv.h"
  27. #include "gdisplay.h"
  28. #include "gimprc.h"
  29. #include "layer_select.h"
  30. #include "layers_dialogP.h"
  31.  
  32. #include "libgimp/gimpintl.h"
  33.  
  34.  
  35. #define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK
  36.  
  37. typedef struct _LayerSelect LayerSelect;
  38.  
  39. struct _LayerSelect
  40. {
  41.   GtkWidget *shell;
  42.   GtkWidget *layer_preview;
  43.   GtkWidget *label;
  44.   GdkPixmap *layer_pixmap;
  45.   GtkWidget *preview;
  46.  
  47.   GImage    *gimage;
  48.   Layer     *current_layer;
  49.   gboolean   dirty;
  50.   gint       image_width;
  51.   gint       image_height;
  52.   gdouble    ratio;
  53. };
  54.  
  55. /*  layer widget function prototypes  */
  56. static void layer_select_advance    (LayerSelect *, gint);
  57. static void layer_select_forward    (LayerSelect *);
  58. static void layer_select_backward   (LayerSelect *);
  59. static void layer_select_end        (LayerSelect *, guint32);
  60. static void layer_select_set_gimage (LayerSelect *, GImage *);
  61. static void layer_select_set_layer  (LayerSelect *);
  62. static gint layer_select_events     (GtkWidget *, GdkEvent *);
  63. static gint preview_events          (GtkWidget *, GdkEvent *);
  64. static void preview_redraw          (LayerSelect *);
  65.  
  66. /*
  67.  *  Local variables
  68.  */
  69. LayerSelect *layer_select = NULL;
  70.  
  71.  
  72. /**********************/
  73. /*  Public functions  */
  74. /**********************/
  75.  
  76.  
  77. void
  78. layer_select_init (GImage  *gimage,
  79.            gint     dir,
  80.            guint32  time)
  81. {
  82.   GtkWidget *frame1;
  83.   GtkWidget *frame2;
  84.   GtkWidget *hbox;
  85.   GtkWidget *alignment;
  86.  
  87.   if (!layer_select)
  88.     {
  89.       layer_select = g_malloc (sizeof (LayerSelect));
  90.       layer_select->layer_pixmap = NULL;
  91.       layer_select->layer_preview = NULL;
  92.       layer_select->preview = NULL;
  93.       layer_select->image_width = layer_select->image_height = 0;
  94.       layer_select_set_gimage (layer_select, gimage);
  95.       layer_select_advance (layer_select, dir);
  96.  
  97.       if (preview_size)
  98.     {
  99.       layer_select->preview = gtk_preview_new (GTK_PREVIEW_COLOR);
  100.       gtk_preview_size (GTK_PREVIEW (layer_select->preview), 
  101.                 preview_size, preview_size);
  102.     }
  103.  
  104.       /*  The shell and main vbox  */
  105.       layer_select->shell = gtk_window_new (GTK_WINDOW_POPUP);
  106.       gtk_window_set_wmclass (GTK_WINDOW (layer_select->shell), 
  107.                   "layer_select", "Gimp");
  108.       gtk_window_set_title (GTK_WINDOW (layer_select->shell), 
  109.                 _("Layer Select"));
  110.       gtk_window_set_position (GTK_WINDOW (layer_select->shell), 
  111.                    GTK_WIN_POS_MOUSE);
  112.       gtk_signal_connect (GTK_OBJECT (layer_select->shell), "event",
  113.               (GtkSignalFunc) layer_select_events,
  114.               layer_select);
  115.       gtk_widget_set_events (layer_select->shell, (GDK_KEY_PRESS_MASK |
  116.                            GDK_KEY_RELEASE_MASK |
  117.                            GDK_BUTTON_PRESS_MASK));
  118.  
  119.       frame1 = gtk_frame_new (NULL);
  120.       gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_OUT);
  121.       gtk_container_add (GTK_CONTAINER (layer_select->shell), frame1);
  122.       frame2 = gtk_frame_new (NULL);
  123.       gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
  124.       gtk_container_add (GTK_CONTAINER (frame1), frame2);
  125.  
  126.       hbox = gtk_hbox_new (FALSE, 1);
  127.       gtk_container_add (GTK_CONTAINER (frame2), hbox);
  128.  
  129.       /*  The preview  */
  130.       alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
  131.       gtk_box_pack_start (GTK_BOX (hbox), alignment, FALSE, FALSE, 0);
  132.       gtk_widget_show (alignment);
  133.  
  134.       layer_select->layer_preview = gtk_drawing_area_new ();
  135.       gtk_drawing_area_size (GTK_DRAWING_AREA (layer_select->layer_preview),
  136.                  layer_select->image_width, 
  137.                  layer_select->image_height);
  138.       gtk_widget_set_events (layer_select->layer_preview, PREVIEW_EVENT_MASK);
  139.       gtk_signal_connect (GTK_OBJECT (layer_select->layer_preview), "event",
  140.               (GtkSignalFunc) preview_events, layer_select);
  141.       gtk_object_set_user_data (GTK_OBJECT (layer_select->layer_preview), 
  142.                 layer_select);
  143.       gtk_container_add (GTK_CONTAINER (alignment), 
  144.              layer_select->layer_preview);
  145.       gtk_widget_show (layer_select->layer_preview);
  146.       gtk_widget_show (alignment);
  147.  
  148.       /*  the layer name label */
  149.       layer_select->label = gtk_label_new (_("Layer"));
  150.       gtk_box_pack_start (GTK_BOX (hbox), 
  151.               layer_select->label, FALSE, FALSE, 2);
  152.       gtk_widget_show (layer_select->label);
  153.  
  154.       gtk_widget_show (hbox);
  155.       gtk_widget_show (frame1);
  156.       gtk_widget_show (frame2);
  157.       gtk_widget_show (layer_select->shell);
  158.     }
  159.   else
  160.     {
  161.       layer_select_set_gimage (layer_select, gimage);
  162.       layer_select_advance (layer_select, dir);
  163.  
  164.       if (! GTK_WIDGET_VISIBLE (layer_select->shell))
  165.     gtk_widget_show (layer_select->shell);
  166.       else
  167.     gtk_widget_draw (layer_select->layer_preview, NULL);
  168.     }
  169.  
  170.   gdk_key_repeat_disable ();
  171.   gdk_keyboard_grab (layer_select->shell->window, FALSE, time);
  172. }
  173.  
  174. void
  175. layer_select_update_preview_size (void)
  176. {
  177.   if (layer_select != NULL)
  178.     {
  179.       gtk_preview_size (GTK_PREVIEW (layer_select->preview), 
  180.             preview_size, preview_size);
  181.       if (GTK_WIDGET_VISIBLE (layer_select->shell))
  182.         gtk_widget_draw (layer_select->layer_preview, NULL);
  183.     }  
  184. }
  185.  
  186.  
  187. /***********************/
  188. /*  Private functions  */
  189. /***********************/
  190.  
  191. static void
  192. layer_select_advance (LayerSelect *layer_select,
  193.               gint         dir)
  194. {
  195.   gint    index;
  196.   gint    length;
  197.   gint    count;
  198.   GSList *list;
  199.   GSList *nth;
  200.   Layer  *layer;
  201.  
  202.   index = 0;
  203.  
  204.   /*  If there is a floating selection, allow no advancement  */
  205.   if (gimage_floating_sel (layer_select->gimage))
  206.     return;
  207.  
  208.   count = 0;
  209.   list = layer_select->gimage->layer_stack;
  210.   while (list)
  211.     {
  212.       layer = (Layer *) list->data;
  213.       if (layer == layer_select->current_layer)
  214.     index = count;
  215.       count++;
  216.       list = g_slist_next (list);
  217.     }
  218.  
  219.   length = g_slist_length (layer_select->gimage->layer_stack);
  220.  
  221.   if (dir == 1)
  222.     index = (index == length - 1) ? 0 : (index + 1);
  223.   else
  224.     index = (index == 0) ? (length - 1) : (index - 1);
  225.  
  226.   nth = g_slist_nth (layer_select->gimage->layer_stack, index);
  227.  
  228.   if (nth)
  229.     {
  230.       layer = (Layer *) nth->data;
  231.       layer_select->current_layer = layer;
  232.     }
  233. }
  234.  
  235.  
  236. static void
  237. layer_select_forward (LayerSelect *layer_select)
  238. {
  239.   layer_select_advance (layer_select, 1);
  240.   layer_select->dirty = TRUE;
  241.   gtk_widget_draw (layer_select->layer_preview, NULL);
  242. }
  243.  
  244.  
  245. static void
  246. layer_select_backward (LayerSelect *layer_select)
  247. {
  248.   layer_select_advance (layer_select, -1);
  249.   layer_select->dirty = TRUE;
  250.   gtk_widget_draw (layer_select->layer_preview, NULL);
  251. }
  252.  
  253.  
  254. static void
  255. layer_select_end (LayerSelect *layer_select,
  256.           guint32      time)
  257. {
  258.   gdk_key_repeat_restore ();
  259.   gdk_keyboard_ungrab (time);
  260.  
  261.   gtk_widget_hide (layer_select->shell);
  262.  
  263.   /*  only reset the active layer if a new layer was specified  */
  264.   if (layer_select->current_layer != layer_select->gimage->active_layer)
  265.     {
  266.       gimage_set_active_layer (layer_select->gimage, layer_select->current_layer);
  267.       gdisplays_flush ();
  268.     }
  269. }
  270.  
  271.  
  272. static void
  273. layer_select_set_gimage (LayerSelect *layer_select,
  274.              GImage      *gimage)
  275. {
  276.   gint image_width;
  277.   gint image_height;
  278.  
  279.   layer_select->gimage = gimage;
  280.   layer_select->current_layer = gimage->active_layer;
  281.   layer_select->dirty = TRUE;
  282.  
  283.   /*  Get the image width and height variables, based on the gimage  */
  284.   if (gimage->width > gimage->height)
  285.     layer_select->ratio = 
  286.       MIN (1.0, (gdouble) preview_size / (gdouble) gimage->width);
  287.   else
  288.     layer_select->ratio = 
  289.       MIN (1.0, (gdouble) preview_size / (gdouble) gimage->height);
  290.  
  291.   image_width = (gint) (layer_select->ratio * gimage->width);
  292.   image_height = (gint) (layer_select->ratio * gimage->height);
  293.  
  294.   if (layer_select->image_width != image_width ||
  295.       layer_select->image_height != image_height)
  296.     {
  297.       layer_select->image_width = image_width;
  298.       layer_select->image_height = image_height;
  299.  
  300.       if (layer_select->layer_preview)
  301.     gtk_widget_set_usize (layer_select->layer_preview,
  302.                   layer_select->image_width,
  303.                   layer_select->image_height);
  304.  
  305.       if (layer_select->layer_pixmap)
  306.     {
  307.       gdk_pixmap_unref (layer_select->layer_pixmap);
  308.       layer_select->layer_pixmap = NULL;
  309.     }
  310.     }
  311. }
  312.  
  313.  
  314. static void
  315. layer_select_set_layer (LayerSelect *layer_select)
  316. {
  317.   Layer *layer;
  318.  
  319.   if (! (layer =  (layer_select->current_layer)))
  320.     return;
  321.  
  322.   /*  Set the layer label  */
  323.   gtk_label_set_text (GTK_LABEL (layer_select->label),
  324.               drawable_get_name (GIMP_DRAWABLE (layer)));
  325. }
  326.  
  327.  
  328. static gint
  329. layer_select_events (GtkWidget *widget,
  330.              GdkEvent  *event)
  331. {
  332.   GdkEventKey    *kevent;
  333.   GdkEventButton *bevent;
  334.  
  335.   switch (event->type)
  336.     {
  337.     case GDK_BUTTON_PRESS:
  338.       bevent = (GdkEventButton *) event;
  339.       layer_select_end (layer_select, bevent->time);
  340.       break;
  341.  
  342.     case GDK_KEY_PRESS:
  343.       kevent = (GdkEventKey *) event;
  344.  
  345.       switch (kevent->keyval)
  346.     {
  347.     case GDK_Tab:
  348.       if (kevent->state & GDK_MOD1_MASK)
  349.         layer_select_forward (layer_select);
  350.       else if (kevent->state & GDK_CONTROL_MASK)
  351.         layer_select_backward (layer_select);
  352.       break;
  353.     }
  354.       return TRUE;
  355.       break;
  356.  
  357.     case GDK_KEY_RELEASE:
  358.       kevent = (GdkEventKey *) event;
  359.  
  360.       switch (kevent->keyval)
  361.     {
  362.     case GDK_Alt_L: case GDK_Alt_R:
  363.       kevent->state &= ~GDK_MOD1_MASK;
  364.       break;
  365.     case GDK_Control_L: case GDK_Control_R:
  366.       kevent->state &= ~GDK_CONTROL_MASK;
  367.       break;
  368.     }
  369.  
  370.       if (! (kevent->state & (GDK_MOD1_MASK | GDK_CONTROL_MASK)))
  371.     layer_select_end (layer_select, kevent->time);
  372.  
  373.       return TRUE;
  374.       break;
  375.  
  376.     default:
  377.       break;
  378.     }
  379.  
  380.   return FALSE;
  381. }
  382.  
  383.  
  384. static gint
  385. preview_events (GtkWidget *widget,
  386.         GdkEvent  *event)
  387. {
  388.   switch (event->type)
  389.     {
  390.     case GDK_EXPOSE:
  391.       if (layer_select->dirty)
  392.     {
  393.       /*  If a preview exists, draw it  */
  394.       if (preview_size)
  395.         preview_redraw (layer_select);
  396.  
  397.       /*  Change the layer name label  */
  398.       layer_select_set_layer (layer_select);
  399.  
  400.       layer_select->dirty = FALSE;
  401.     }
  402.  
  403.       if (preview_size)
  404.     gdk_draw_pixmap (layer_select->layer_preview->window,
  405.              layer_select->layer_preview->style->black_gc,
  406.              layer_select->layer_pixmap,
  407.              0, 0, 0, 0,
  408.              layer_select->image_width,
  409.              layer_select->image_height);
  410.       break;
  411.  
  412.     default:
  413.       break;
  414.     }
  415.  
  416.   return FALSE;
  417. }
  418.  
  419.  
  420. static void
  421. preview_redraw (LayerSelect *layer_select)
  422. {
  423.   Layer   *layer;
  424.   TempBuf *preview_buf;
  425.   gint     w, h;
  426.   gint     offx, offy;
  427.  
  428.   if (! (layer =  (layer_select->current_layer)))
  429.     return;
  430.  
  431.   if (! layer_select->layer_pixmap)
  432.     layer_select->layer_pixmap = 
  433.       gdk_pixmap_new (layer_select->layer_preview->window,
  434.               layer_select->image_width,
  435.               layer_select->image_height,
  436.               -1);
  437.  
  438.   if (layer_is_floating_sel (layer))
  439.     render_fs_preview (layer_select->layer_preview, 
  440.                layer_select->layer_pixmap);
  441.   else
  442.     {
  443.       gint off_x;
  444.       gint off_y;
  445.  
  446.       drawable_offsets (GIMP_DRAWABLE(layer), &off_x, &off_y);
  447.  
  448.       /*  determine width and height  */
  449.       w = (gint) (layer_select->ratio * 
  450.           drawable_width (GIMP_DRAWABLE(layer)));
  451.       h = (gint) (layer_select->ratio * 
  452.           drawable_height (GIMP_DRAWABLE(layer)));
  453.       offx = (gint) (layer_select->ratio * off_x);
  454.       offy = (gint) (layer_select->ratio * off_y);
  455.  
  456.       preview_buf = layer_preview (layer, w, h);
  457.       preview_buf->x = offx;
  458.       preview_buf->y = offy;
  459.  
  460.       render_preview (preview_buf,
  461.               layer_select->preview,
  462.               layer_select->image_width,
  463.               layer_select->image_height,
  464.               -1);
  465.  
  466.       /*  Set the layer pixmap  */
  467.       gtk_preview_put (GTK_PREVIEW (layer_select->preview),
  468.                layer_select->layer_pixmap,
  469.                layer_select->layer_preview->style->black_gc,
  470.                0, 0, 0, 0,
  471.                layer_select->image_width, layer_select->image_height);
  472.  
  473.       /*  make sure the image has been transfered completely 
  474.        *  to the pixmap before we use it again...
  475.        */
  476.       gdk_flush ();
  477.     }
  478. }
  479.