PageRenderTime 15ms CodeModel.GetById 10ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

/src/wrappers/gtk/examples/gtk-demo/drawingarea.e

http://github.com/tybor/Liberty
Specman e | 349 lines | 21 code | 66 blank | 262 comment | 2 complexity | 62b6a3354ab17b9e42e220e05847a08f MD5 | raw file
  1indexing
  2	description: "."
  3	copyright: "[
  4					Copyright (C) 2006 Paolo Redaelli, GTK+ team
  5					
  6					This library is free software; you can redistribute it and/or
  7					modify it under the terms of the GNU Lesser General Public License
  8					as published by the Free Software Foundation; either version 2.1 of
  9					the License, or (at your option) any later version.
 10					
 11					This library is distributed in the hope that it will be useful, but
 12					WITHOUT ANY WARRANTY; without even the implied warranty of
 13					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14					Lesser General Public License for more details.
 15
 16					You should have received a copy of the GNU Lesser General Public
 17					License along with this library; if not, write to the Free Software
 18					Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 19					02110-1301 USA
 20			]"
 21
 22class DRAWINGAREA
 23
 24creation make
 25
 26feature
 27-- /* Drawing Area
 28--  *
 29--  * GtkDrawingArea is a blank area where you can draw custom displays
 30--  * of various kinds.
 31--  *
 32--  * This demo has two drawing areas. The checkerboard area shows
 33--  * how you can just draw something; all you have to do is write
 34--  * a signal handler for expose_event, as shown here.
 35--  *
 36--  * The "scribble" area is a bit more advanced, and shows how to handle
 37--  * events such as button presses and mouse motion. Click the mouse
 38--  * and drag in the scribble area to draw squiggles. Resize the window
 39--  * to clear the area.
 40--  */
 41
 42-- #include <gtk/gtk.h>
 43
 44-- static GtkWidget *window = NULL;
 45-- /* Pixmap for scribble area, to store current scribbles */
 46-- static GdkPixmap *pixmap = NULL;
 47
 48-- /* Create a new pixmap of the appropriate size to store our scribbles */
 49-- static gboolean
 50-- scribble_configure_event (GtkWidget	    *widget,
 51-- 			  GdkEventConfigure *event,
 52-- 			  gpointer	     data)
 53-- {
 54--   if (pixmap)
 55--     g_object_unref (pixmap);
 56
 57--   pixmap = gdk_pixmap_new (widget->window,
 58-- 			   widget->allocation.width,
 59-- 			   widget->allocation.height,
 60-- 			   -1);
 61
 62--   /* Initialize the pixmap to white */
 63--   gdk_draw_rectangle (pixmap,
 64-- 		      widget->style->white_gc,
 65-- 		      TRUE,
 66-- 		      0, 0,
 67-- 		      widget->allocation.width,
 68-- 		      widget->allocation.height);
 69
 70--   /* We've handled the configure event, no need for further processing. */
 71--   return TRUE;
 72-- }
 73
 74-- /* Redraw the screen from the pixmap */
 75-- static gboolean
 76-- scribble_expose_event (GtkWidget      *widget,
 77-- 		       GdkEventExpose *event,
 78-- 		       gpointer	       data)
 79-- {
 80--   /* We use the "foreground GC" for the widget since it already exists,
 81--    * but honestly any GC would work. The only thing to worry about
 82--    * is whether the GC has an inappropriate clip region set.
 83--    */
 84  
 85--   gdk_draw_drawable (widget->window,
 86-- 		     widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
 87-- 		     pixmap,
 88-- 		     /* Only copy the area that was exposed. */
 89-- 		     event->area.x, event->area.y,
 90-- 		     event->area.x, event->area.y,
 91-- 		     event->area.width, event->area.height);
 92  
 93--   return FALSE;
 94-- }
 95
 96-- /* Draw a rectangle on the screen */
 97-- static void
 98-- draw_brush (GtkWidget *widget,
 99-- 	    gdouble    x,
100-- 	    gdouble    y)
101-- {
102--   GdkRectangle update_rect;
103
104--   update_rect.x = x - 3;
105--   update_rect.y = y - 3;
106--   update_rect.width = 6;
107--   update_rect.height = 6;
108
109--   /* Paint to the pixmap, where we store our state */
110--   gdk_draw_rectangle (pixmap,
111-- 		      widget->style->black_gc,
112-- 		      TRUE,
113-- 		      update_rect.x, update_rect.y,
114-- 		      update_rect.width, update_rect.height);
115
116--   /* Now invalidate the affected region of the drawing area. */
117--   gdk_window_invalidate_rect (widget->window,
118-- 			      &update_rect,
119-- 			      FALSE);
120-- }
121
122-- static gboolean
123-- scribble_button_press_event (GtkWidget	    *widget,
124-- 			     GdkEventButton *event,
125-- 			     gpointer	     data)
126-- {
127--   if (pixmap == NULL)
128--     return FALSE; /* paranoia check, in case we haven't gotten a configure event */
129  
130--   if (event->button == 1)
131--     draw_brush (widget, event->x, event->y);
132
133--   /* We've handled the event, stop processing */
134--   return TRUE;
135-- }
136
137-- static gboolean
138-- scribble_motion_notify_event (GtkWidget	     *widget,
139-- 			      GdkEventMotion *event,
140-- 			      gpointer	      data)
141-- {
142--   int x, y;
143--   GdkModifierType state;
144
145--   if (pixmap == NULL)
146--     return FALSE; /* paranoia check, in case we haven't gotten a configure event */
147
148--   /* This call is very important; it requests the next motion event.
149--    * If you don't call gdk_window_get_pointer() you'll only get
150--    * a single motion event. The reason is that we specified
151--    * GDK_POINTER_MOTION_HINT_MASK to gtk_widget_set_events().
152--    * If we hadn't specified that, we could just use event->x, event->y
153--    * as the pointer location. But we'd also get deluged in events.
154--    * By requesting the next event as we handle the current one,
155--    * we avoid getting a huge number of events faster than we
156--    * can cope.
157--    */
158  
159--   gdk_window_get_pointer (event->window, &x, &y, &state);
160	
161--   if (state & GDK_BUTTON1_MASK)
162--     draw_brush (widget, x, y);
163
164--   /* We've handled it, stop processing */
165--   return TRUE;
166-- }
167
168
169-- static gboolean
170-- checkerboard_expose (GtkWidget	    *da,
171-- 		     GdkEventExpose *event,
172-- 		     gpointer	     data)
173-- {
174--   gint i, j, xcount, ycount;
175--   GdkGC *gc1, *gc2;
176--   GdkColor color;
177  
178-- #define CHECK_SIZE 10
179-- #define SPACING 2
180  
181--   /* At the start of an expose handler, a clip region of event->area
182--    * is set on the window, and event->area has been cleared to the
183--    * widget's background color. The docs for
184--    * gdk_window_begin_paint_region() give more details on how this
185--    * works.
186--    */
187
188--   /* It would be a bit more efficient to keep these
189--    * GC's around instead of recreating on each expose, but
190--    * this is the lazy/slow way.
191--    */
192--   gc1 = gdk_gc_new (da->window);
193--   color.red = 30000;
194--   color.green = 0;
195--   color.blue = 30000;
196--   gdk_gc_set_rgb_fg_color (gc1, &color);
197
198--   gc2 = gdk_gc_new (da->window);
199--   color.red = 65535;
200--   color.green = 65535;
201--   color.blue = 65535;
202--   gdk_gc_set_rgb_fg_color (gc2, &color);
203  
204--   xcount = 0;
205--   i = SPACING;
206--   while (i < da->allocation.width)
207--     {
208--       j = SPACING;
209--       ycount = xcount % 2; /* start with even/odd depending on row */
210--       while (j < da->allocation.height)
211-- 	{
212-- 	  GdkGC *gc;
213	
214-- 	  if (ycount % 2)
215-- 	    gc = gc1;
216-- 	  else
217-- 	    gc = gc2;
218
219-- 	  /* If we're outside event->area, this will do nothing.
220-- 	   * It might be mildly more efficient if we handled
221-- 	   * the clipping ourselves, but again we're feeling lazy.
222-- 	   */
223-- 	  gdk_draw_rectangle (da->window,
224-- 			      gc,
225-- 			      TRUE,
226-- 			      i, j,
227-- 			      CHECK_SIZE,
228-- 			      CHECK_SIZE);
229
230-- 	  j += CHECK_SIZE + SPACING;
231-- 	  ++ycount;
232-- 	}
233
234--       i += CHECK_SIZE + SPACING;
235--       ++xcount;
236--     }
237  
238--   g_object_unref (gc1);
239--   g_object_unref (gc2);
240  
241--   /* return TRUE because we've handled this event, so no
242--    * further processing is required.
243--    */
244--   return TRUE;
245-- }
246
247-- GtkWidget *
248-- do_drawingarea (GtkWidget *do_widget)
249-- {
250--   GtkWidget *frame;
251--   GtkWidget *vbox;
252--   GtkWidget *da;
253--   GtkWidget *label;
254  
255--   if (!window)
256--     {
257--       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
258--       gtk_window_set_screen (GTK_WINDOW (window),
259-- 			     gtk_widget_get_screen (do_widget));
260--       gtk_window_set_title (GTK_WINDOW (window), "Drawing Area");
261
262--       g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
263
264--       gtk_container_set_border_width (GTK_CONTAINER (window), 8);
265
266--       vbox = gtk_vbox_new (FALSE, 8);
267--       gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
268--       gtk_container_add (GTK_CONTAINER (window), vbox);
269
270--       /*
271--        * Create the checkerboard area
272--        */
273		
274--       label = gtk_label_new (NULL);
275--       gtk_label_set_markup (GTK_LABEL (label),
276-- 			    "<u>Checkerboard pattern</u>");
277--       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
278		
279--       frame = gtk_frame_new (NULL);
280--       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
281--       gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
282		
283--       da = gtk_drawing_area_new ();
284--       /* set a minimum size */
285--       gtk_widget_set_size_request (da, 100, 100);
286
287--       gtk_container_add (GTK_CONTAINER (frame), da);
288
289--       g_signal_connect (da, "expose_event",
290-- 			G_CALLBACK (checkerboard_expose), NULL);
291
292--       /*
293--        * Create the scribble area
294--        */
295		
296--       label = gtk_label_new (NULL);
297--       gtk_label_set_markup (GTK_LABEL (label),
298-- 			    "<u>Scribble area</u>");
299--       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
300		
301--       frame = gtk_frame_new (NULL);
302--       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
303--       gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
304		
305--       da = gtk_drawing_area_new ();
306--       /* set a minimum size */
307--       gtk_widget_set_size_request (da, 100, 100);
308
309--       gtk_container_add (GTK_CONTAINER (frame), da);
310
311--       /* Signals used to handle backing pixmap */
312		
313--       g_signal_connect (da, "expose_event",
314-- 			G_CALLBACK (scribble_expose_event), NULL);
315--       g_signal_connect (da,"configure_event",
316-- 			G_CALLBACK (scribble_configure_event), NULL);
317		
318--       /* Event signals */
319		
320--       g_signal_connect (da, "motion_notify_event",
321-- 			G_CALLBACK (scribble_motion_notify_event), NULL);
322--       g_signal_connect (da, "button_press_event",
323-- 			G_CALLBACK (scribble_button_press_event), NULL);
324
325
326--       /* Ask to receive events the drawing area doesn't normally
327--        * subscribe to
328--        */
329--       gtk_widget_set_events (da, gtk_widget_get_events (da)
330-- 			     | GDK_LEAVE_NOTIFY_MASK
331-- 			     | GDK_BUTTON_PRESS_MASK
332-- 			     | GDK_POINTER_MOTION_MASK
333-- 			     | GDK_POINTER_MOTION_HINT_MASK);
334
335--     }
336
337--   if (!GTK_WIDGET_VISIBLE (window))
338--     {
339--       gtk_widget_show_all (window);
340--     }
341--   else
342--     {
343--       gtk_widget_destroy (window);
344--       window = NULL;
345--     }
346
347--   return window;
348-- }
349end