gimp r24983 - in trunk: . libgimpwidgets



Author: neo
Date: Tue Feb 26 19:25:11 2008
New Revision: 24983
URL: http://svn.gnome.org/viewvc/gimp?rev=24983&view=rev

Log:
2008-02-26  Sven Neumann  <sven gimp org>

	* libgimpwidgets/gimpchainbutton.c: use a private inner class
	directly derived from GtkWidget for drawing the lines. This 
saves
	us two input windows.



Modified:
   trunk/ChangeLog
   trunk/libgimpwidgets/gimpchainbutton.c

Modified: trunk/libgimpwidgets/gimpchainbutton.c
==============================================================================
--- trunk/libgimpwidgets/gimpchainbutton.c	(original)
+++ trunk/libgimpwidgets/gimpchainbutton.c	Tue Feb 26 19:25:11 2008
@@ -56,11 +56,11 @@
 
 static void      gimp_chain_button_clicked_callback (GtkWidget       *widget,
                                                      GimpChainButton *button);
-static gboolean  gimp_chain_button_draw_lines       (GtkWidget       *widget,
-                                                     GdkEventExpose  *eevent,
-                                                     GimpChainButton *button);
 static void      gimp_chain_button_update_image     (GimpChainButton *button);
 
+static GtkWidget * gimp_chain_line_new            (GimpChainPosition  position,
+                                                   gint               which);
+
 
 G_DEFINE_TYPE (GimpChainButton, gimp_chain_button, GTK_TYPE_TABLE)
 
@@ -117,30 +117,16 @@
 {
   button->position = GIMP_CHAIN_TOP;
   button->active   = FALSE;
-
-
-  button->line1    = g_object_new (GTK_TYPE_EVENT_BOX,
-                                   "visible-window", FALSE,
-                                   NULL);
-  button->line2    = g_object_new (GTK_TYPE_EVENT_BOX,
-                                   "visible-window", FALSE,
-                                   NULL);
   button->image    = gtk_image_new ();
-
   button->button   = gtk_button_new ();
 
   gtk_button_set_relief (GTK_BUTTON (button->button), GTK_RELIEF_NONE);
   gtk_container_add (GTK_CONTAINER (button->button), button->image);
+  gtk_widget_show (button->image);
 
   g_signal_connect (button->button, "clicked",
                     G_CALLBACK (gimp_chain_button_clicked_callback),
                     button);
-  g_signal_connect (button->line1, "expose-event",
-                    G_CALLBACK (gimp_chain_button_draw_lines),
-                    button);
-  g_signal_connect (button->line2, "expose-event",
-                    G_CALLBACK (gimp_chain_button_draw_lines),
-                    button);
 }
 
 static GObject *
@@ -155,8 +141,10 @@
 
   button = GIMP_CHAIN_BUTTON (object);
 
+  button->line1 = gimp_chain_line_new (button->position, 1);
+  button->line2 = gimp_chain_line_new (button->position, -1);
+
   gimp_chain_button_update_image (button);
-  gtk_widget_show (button->image);
 
   if (button->position & GIMP_CHAIN_LEFT) /* are we a vertical chainbutton? */
     {
@@ -301,29 +289,83 @@
   g_signal_emit (button, gimp_chain_button_signals[TOGGLED], 0);
 }
 
+static void
+gimp_chain_button_update_image (GimpChainButton *button)
+{
+  guint i;
+
+  i = ((button->position & GIMP_CHAIN_LEFT) << 1) + (button->active ? 0 : 1);
+
+  gtk_image_set_from_stock (GTK_IMAGE (button->image),
+                            gimp_chain_stock_items[i],
+                            GTK_ICON_SIZE_BUTTON);
+}
+
+
+/* GimpChainLine is a simple no-window widget for drawing the lines.
+ *
+ * Originally this used to be a GtkDrawingArea but this turned out to
+ * be a bad idea. We don't need an extra window to draw on and we also
+ * don't need any input events.
+ */
+
+static GType     gimp_chain_line_get_type     (void) G_GNUC_CONST;
+static gboolean  gimp_chain_line_expose_event (GtkWidget       *widget,
+                                               GdkEventExpose  *event);
+
+struct _GimpChainLine
+{
+  GtkWidget          parent_instance;
+  GimpChainPosition  position;
+  gint               which;
+};
+
+typedef struct _GimpChainLine  GimpChainLine;
+typedef GtkWidgetClass         GimpChainLineClass;
+
+G_DEFINE_TYPE (GimpChainLine, gimp_chain_line, GTK_TYPE_WIDGET)
+
+static void
+gimp_chain_line_class_init (GimpChainLineClass *klass)
+{
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  widget_class->expose_event = gimp_chain_line_expose_event;
+}
+
+static void
+gimp_chain_line_init (GimpChainLine *line)
+{
+  GTK_WIDGET_SET_FLAGS (line, GTK_NO_WINDOW);
+}
+
+static GtkWidget *
+gimp_chain_line_new (GimpChainPosition  position,
+                     gint               which)
+{
+  GimpChainLine *line = g_object_new (gimp_chain_line_get_type (), NULL);
+
+  line->position = position;
+  line->which    = which;
+
+  return GTK_WIDGET (line);
+}
+
 static gboolean
-gimp_chain_button_draw_lines (GtkWidget       *widget,
-                              GdkEventExpose  *eevent,
-                              GimpChainButton *button)
+gimp_chain_line_expose_event (GtkWidget       *widget,
+                              GdkEventExpose  *event)
 {
+  GimpChainLine     *line = ((GimpChainLine *) widget);
   GdkPoint           points[3];
   GdkPoint           buf;
   GtkShadowType      shadow;
   GimpChainPosition  position;
-  gint               which_line;
 
 #define SHORT_LINE 4
-  /* don't set this too high, there's no check against drawing outside
-     the widgets bounds yet (and probably never will be) */
-
-  g_return_val_if_fail (GIMP_IS_CHAIN_BUTTON (button), FALSE);
-
   points[0].x = widget->allocation.x + widget->allocation.width  / 2;
   points[0].y = widget->allocation.y + widget->allocation.height / 2;
 
-  which_line = (widget == button->line1) ? 1 : -1;
-
-  position = button->position;
+  position = line->position;
 
   if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
     {
@@ -350,7 +392,7 @@
       points[1].x = points[0].x - SHORT_LINE;
       points[1].y = points[0].y;
       points[2].x = points[1].x;
-      points[2].y = (which_line == 1 ?
+      points[2].y = (line->which == 1 ?
                      widget->allocation.y + widget->allocation.height - 1 :
                      widget->allocation.y);
       shadow = GTK_SHADOW_ETCHED_IN;
@@ -361,7 +403,7 @@
       points[1].x = points[0].x + SHORT_LINE;
       points[1].y = points[0].y;
       points[2].x = points[1].x;
-      points[2].y = (which_line == 1 ?
+      points[2].y = (line->which == 1 ?
                      widget->allocation.y + widget->allocation.height - 1 :
                      widget->allocation.y);
       shadow = GTK_SHADOW_ETCHED_OUT;
@@ -371,7 +413,7 @@
       points[0].y += SHORT_LINE;
       points[1].x = points[0].x;
       points[1].y = points[0].y - SHORT_LINE;
-      points[2].x = (which_line == 1 ?
+      points[2].x = (line->which == 1 ?
                      widget->allocation.x + widget->allocation.width - 1 :
                      widget->allocation.x);
       points[2].y = points[1].y;
@@ -382,7 +424,7 @@
       points[0].y -= SHORT_LINE;
       points[1].x = points[0].x;
       points[1].y = points[0].y + SHORT_LINE;
-      points[2].x = (which_line == 1 ?
+      points[2].x = (line->which == 1 ?
                      widget->allocation.x + widget->allocation.width - 1 :
                      widget->allocation.x);
       points[2].y = points[1].y;
@@ -393,36 +435,21 @@
       return FALSE;
     }
 
-  if ( ((shadow == GTK_SHADOW_ETCHED_OUT) && (which_line == -1)) ||
-       ((shadow == GTK_SHADOW_ETCHED_IN) && (which_line == 1)) )
+  if ( ((shadow == GTK_SHADOW_ETCHED_OUT) && (line->which == -1)) ||
+       ((shadow == GTK_SHADOW_ETCHED_IN)  && (line->which == 1)) )
     {
       buf = points[0];
       points[0] = points[2];
       points[2] = buf;
     }
 
-  gtk_paint_polygon (widget->style,
-                     widget->window,
-                     GTK_STATE_NORMAL,
+  gtk_paint_polygon (widget->style, widget->window, GTK_STATE_NORMAL,
                      shadow,
-                     &eevent->area,
+                     &event->area,
                      widget,
                      "chainbutton",
-                     points,
-                     3,
+                     points, 3,
                      FALSE);
 
   return TRUE;
 }
-
-static void
-gimp_chain_button_update_image (GimpChainButton *button)
-{
-  guint i;
-
-  i = ((button->position & GIMP_CHAIN_LEFT) << 1) + (button->active ? 0 : 1);
-
-  gtk_image_set_from_stock (GTK_IMAGE (button->image),
-                            gimp_chain_stock_items[i],
-                            GTK_ICON_SIZE_BUTTON);
-}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]