home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 February / CMCD0205.ISO / Linux / gimp-2.2.0.tar.gz / gimp-2.2.0.tar / gimp-2.2.0 / libgimpwidgets / gimpbutton.c next >
C/C++ Source or Header  |  2003-12-05  |  6KB  |  219 lines

  1. /* LIBGIMP - The GIMP Library
  2.  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  3.  *
  4.  * gimpbutton.c
  5.  * Copyright (C) 2000 Michael Natterer <mitch@gimp.org>
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the
  19.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20.  * Boston, MA 02111-1307, USA.
  21.  */
  22.  
  23. #include "config.h"
  24.  
  25. #include <gtk/gtk.h>
  26.  
  27. #include "gimpwidgetstypes.h"
  28.  
  29. #include "gimpbutton.h"
  30.  
  31.  
  32. enum
  33. {
  34.   EXTENDED_CLICKED,
  35.   LAST_SIGNAL
  36. };
  37.  
  38.  
  39. static void       gimp_button_class_init     (GimpButtonClass  *klass);
  40. static void       gimp_button_init           (GimpButton       *button);
  41.  
  42. static gboolean   gimp_button_button_press   (GtkWidget        *widget,
  43.                           GdkEventButton   *event);
  44. static gboolean   gimp_button_button_release (GtkWidget        *widget,
  45.                           GdkEventButton   *event);
  46.  
  47.  
  48. static guint button_signals[LAST_SIGNAL] = { 0 };
  49.  
  50. static GtkButtonClass *parent_class = NULL;
  51.  
  52.  
  53. GType
  54. gimp_button_get_type (void)
  55. {
  56.   static GType button_type = 0;
  57.  
  58.   if (! button_type)
  59.     {
  60.       static const GTypeInfo button_info =
  61.       {
  62.         sizeof (GimpButtonClass),
  63.         (GBaseInitFunc) NULL,
  64.         (GBaseFinalizeFunc) NULL,
  65.         (GClassInitFunc) gimp_button_class_init,
  66.         NULL,           /* class_finalize */
  67.         NULL,           /* class_data     */
  68.         sizeof (GimpButton),
  69.         0,              /* n_preallocs    */
  70.         (GInstanceInitFunc) gimp_button_init,
  71.       };
  72.  
  73.       button_type = g_type_register_static (GTK_TYPE_BUTTON,
  74.                         "GimpButton",
  75.                         &button_info, 0);
  76.     }
  77.  
  78.   return button_type;
  79. }
  80.  
  81. static void
  82. gimp_button_class_init (GimpButtonClass *klass)
  83. {
  84.   GObjectClass   *object_class;
  85.   GtkWidgetClass *widget_class;
  86.  
  87.   object_class = G_OBJECT_CLASS (klass);
  88.   widget_class = GTK_WIDGET_CLASS (klass);
  89.  
  90.   parent_class = g_type_class_peek_parent (klass);
  91.  
  92.   button_signals[EXTENDED_CLICKED] =
  93.     g_signal_new ("extended_clicked",
  94.           G_TYPE_FROM_CLASS (klass),
  95.           G_SIGNAL_RUN_FIRST,
  96.           G_STRUCT_OFFSET (GimpButtonClass, extended_clicked),
  97.           NULL, NULL,
  98.           g_cclosure_marshal_VOID__FLAGS,
  99.           G_TYPE_NONE, 1,
  100.           GDK_TYPE_MODIFIER_TYPE);
  101.  
  102.   widget_class->button_press_event   = gimp_button_button_press;
  103.   widget_class->button_release_event = gimp_button_button_release;
  104. }
  105.  
  106. static void
  107. gimp_button_init (GimpButton *button)
  108. {
  109.   button->press_state = 0;
  110. }
  111.  
  112. /**
  113.  * gimp_button_new:
  114.  *
  115.  * Creates a new #GimpButton widget.
  116.  *
  117.  * Returns: A pointer to the new #GimpButton widget.
  118.  **/
  119. GtkWidget *
  120. gimp_button_new (void)
  121. {
  122.   GimpButton *button;
  123.  
  124.   button = g_object_new (GIMP_TYPE_BUTTON, NULL);
  125.  
  126.   return GTK_WIDGET (button);
  127. }
  128.  
  129. /**
  130.  * gimp_button_extended_clicked:
  131.  * @button: a #GimpButton.
  132.  * @state:  a state as found in #GdkEventButton->state, e.g. #GDK_SHIFT_MASK.
  133.  *
  134.  * Emits the button's "extended_clicked" signal.
  135.  **/
  136. void
  137. gimp_button_extended_clicked (GimpButton      *button,
  138.                               GdkModifierType  state)
  139. {
  140.   g_return_if_fail (GIMP_IS_BUTTON (button));
  141.  
  142.   g_signal_emit (button, button_signals[EXTENDED_CLICKED], 0, state);
  143. }
  144.  
  145. static gboolean
  146. gimp_button_button_press (GtkWidget      *widget,
  147.               GdkEventButton *bevent)
  148. {
  149.   GimpButton *button;
  150.  
  151.   g_return_val_if_fail (GIMP_IS_BUTTON (widget), FALSE);
  152.   g_return_val_if_fail (bevent != NULL, FALSE);
  153.  
  154.   button = GIMP_BUTTON (widget);
  155.  
  156.   if (bevent->type == GDK_BUTTON_PRESS && bevent->button == 1)
  157.     {
  158.       button->press_state = bevent->state;
  159.     }
  160.   else
  161.     {
  162.       button->press_state = 0;
  163.     }
  164.  
  165.   if (GTK_WIDGET_CLASS (parent_class)->button_press_event)
  166.     return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, bevent);
  167.  
  168.   return FALSE;
  169. }
  170.  
  171. static gboolean
  172. gimp_button_button_release (GtkWidget      *widget,
  173.                 GdkEventButton *bevent)
  174. {
  175.   GtkButton *button;
  176.   gboolean   extended_clicked = FALSE;
  177.  
  178.   g_return_val_if_fail (GIMP_IS_BUTTON (widget), FALSE);
  179.   g_return_val_if_fail (bevent != NULL, FALSE);
  180.  
  181.   button = GTK_BUTTON (widget);
  182.  
  183.   if (bevent->button == 1)
  184.     {
  185.       if (button->in_button &&
  186.       (GIMP_BUTTON (button)->press_state &
  187.        (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)))
  188.     {
  189.       gimp_button_extended_clicked (GIMP_BUTTON (button),
  190.                                         GIMP_BUTTON (button)->press_state);
  191.  
  192.       extended_clicked  = TRUE;
  193.  
  194.       /* HACK: don't let GtkButton emit "clicked" by telling it that
  195.        * the mouse pointer is outside the widget
  196.        */
  197.       button->in_button = FALSE;
  198.     }
  199.     }
  200.  
  201.   if (GTK_WIDGET_CLASS (parent_class)->button_release_event)
  202.     GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, bevent);
  203.  
  204.   if (extended_clicked)
  205.     {
  206.       /* revert the above HACK and let the button draw itself in the
  207.        * correct state, because upchaining with "in_button" == FALSE
  208.        * messed it up
  209.        */
  210.       button->in_button = TRUE;
  211.  
  212.       gtk_widget_set_state (widget, GTK_STATE_PRELIGHT);
  213.       gtk_widget_queue_draw (widget);
  214.       gdk_window_process_updates (widget->window, TRUE);
  215.    }
  216.  
  217.   return TRUE;
  218. }
  219.