1 /**
2 \brief This module implements the gnocl::drawingArea widget.
3 **/
4
5 /**
6 \page page_drawingArea gnocl::drawingArea
7 \htmlinclude drawingArea.html
8 **/
9
10 /**
11 \par Modification History
12 \verbatim
13 2013-07: added commands, options, commands
14 \endverbatim
15 **/
16
17 /* user documentation */
18
19 #include "gnocl.h"
20 #include <gdk/gdkkeysyms.h>
21
22 /*
23 The Widget implementation has a number of empty entries within its
24 options array. This will allow the coder to configure the widget
25 under scripted control, thereby providing a Gnocl framework for
26 customised widget creation.
27 */
28
29 static gint _n = 7; /* counter,number of implemented widget options */
30
31 static GnoclOption drawingAreaOptions[] =
32 {
33 /* common widget options */
34 { "-tooltip", GNOCL_OBJ, "", gnoclOptTooltip },
35 { "-data", GNOCL_OBJ, "", gnoclOptData },
36 { "-name", GNOCL_STRING, "name" },
37 { "-onShowHelp", GNOCL_OBJ, "", gnoclOptOnShowHelp },
38 { "-cursor", GNOCL_OBJ, "", gnoclOptCursor },
39 { "-sensitive", GNOCL_BOOL, "sensitive" },
40 { "-visible", GNOCL_BOOL, "visible" },
41
42 /* widget specific options, 30 blank spaces */
43 { "", GNOCL_OBJ, "", NULL },
44 { "", GNOCL_OBJ, "", NULL },
45 { "", GNOCL_OBJ, "", NULL },
46 { "", GNOCL_OBJ, "", NULL },
47 { "", GNOCL_OBJ, "", NULL },
48 { "", GNOCL_OBJ, "", NULL },
49 { "", GNOCL_OBJ, "", NULL },
50 { "", GNOCL_OBJ, "", NULL },
51 { "", GNOCL_OBJ, "", NULL },
52 { "", GNOCL_OBJ, "", NULL },
53 { "", GNOCL_OBJ, "", NULL },
54 { "", GNOCL_OBJ, "", NULL },
55 { "", GNOCL_OBJ, "", NULL },
56 { "", GNOCL_OBJ, "", NULL },
57 { "", GNOCL_OBJ, "", NULL },
58 { "", GNOCL_OBJ, "", NULL },
59 { "", GNOCL_OBJ, "", NULL },
60 { "", GNOCL_OBJ, "", NULL },
61 { "", GNOCL_OBJ, "", NULL },
62 { "", GNOCL_OBJ, "", NULL },
63 { "", GNOCL_OBJ, "", NULL },
64 { "", GNOCL_OBJ, "", NULL },
65 { "", GNOCL_OBJ, "", NULL },
66 { "", GNOCL_OBJ, "", NULL },
67 { "", GNOCL_OBJ, "", NULL },
68 { "", GNOCL_OBJ, "", NULL },
69 { "", GNOCL_OBJ, "", NULL },
70 { "", GNOCL_OBJ, "", NULL },
71 { "", GNOCL_OBJ, "", NULL },
72 { "", GNOCL_OBJ, "", NULL },
73 { "", GNOCL_OBJ, "", NULL },
74 { "", GNOCL_OBJ, "", NULL },
75 { NULL },
76 };
77
78 /*
79 GDK_EXPOSURE_MASK GDK_POINTER_MOTION_MASK GDK_POINTER_MOTION_HINT_MASK
80 GDK_BUTTON_MOTION_MASK GDK_BUTTON1_MOTION_MASK GDK_BUTTON2_MOTION_MASK
81 GDK_BUTTON3_MOTION_MASK GDK_BUTTON_PRESS_MASK GDK_BUTTON_RELEASE_MASK
82 GDK_KEY_PRESS_MASK GDK_KEY_RELEASE_MASK GDK_ENTER_NOTIFY_MASK
83 GDK_LEAVE_NOTIFY_MASK GDK_FOCUS_CHANGE_MASK GDK_STRUCTURE_MASK
84 GDK_PROPERTY_CHANGE_MASK GDK_VISIBILITY_NOTIFY_MASK GDK_PROXIMITY_IN_MASK
85 GDK_PROXIMITY_OUT_MASK GDK_SUBSTRUCTURE_MASK GDK_SCROLL_MASK
86 GDK_ALL_EVENTS_MASK
87 */
88
89 static const char *options[] =
90 {
91 "-onExpose", "-onPointerMotion", "motionHint",
92 "-onButtonMotion", "-onButton1Motion", "-onButton2Motion",
93 "-onButton3Motion", "-onButtonPress", "-onButtonRelease",
94 "-onKeyPress", "-onKeyRelease", "-onEnter",
95 "-onLeave", "-onFocus", "structure",
96 "propertyChange", "visibility", "proximityIn",
97 "proximityOut", "substructure", "-onScroll",
98 "all",
99 NULL
100 };
101
102 enum OptsIdx
103 {
104 OnExposeIdx, OnPointerMotionIdx, PointerMotionHintIdx,
105 OnButtonMotionIdx, OnButton1MotionIdx, OnButton2MotionIdx,
106 OnButton3MotionIdx, OnButtonPressIdx, OnButtonReleaseIdx,
107 OnKeyPressIdx, OnKeyReleaseIdx, OnEnterIdx,
108 OnLeaveIdx, OnFocusIdx, StructureIdx,
109 PropertyChangeIdx, VisibilityIdx, ProximityInIdx,
110 ProximityOutIdx, SubstructureIdx, OnScrollIdx,
111 AllIdx
112 };
113
114 /**
115 \brief
116 **/
configure(Tcl_Interp * interp,GtkDrawingArea * area,GnoclOption options[])117 static int configure ( Tcl_Interp *interp, GtkDrawingArea *area, GnoclOption options[] )
118 {
119
120 gint ret = gnoclSetOptions ( interp, options, area, -1 );
121
122 return TCL_OK;
123 }
124
125 static const char *cmds[] =
126 {
127 "draw", "cget", "configure",
128 "delete", "class", "erase",
129 "option",
130 NULL
131 };
132
133 /**
134 /brief
135 **/
drawingAreaFunc(ClientData data,Tcl_Interp * interp,int objc,Tcl_Obj * const objv[])136 int drawingAreaFunc ( ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[] )
137 {
138 #ifdef DEBUG_DRAWING_AREA
139 listParameters ( objc, objv, "drawingAreaFunc" );
140 #endif
141
142
143 enum cmdIdx
144 {
145 DrawIdx, CgetIdx, ConfigureIdx,
146 DeleteIdx, ClassIdx, EraseIdx,
147 OptionIdx
148 };
149
150 /*
151 static const char *events[] =
152 {
153 "expose", "motion", "motionHint",
154 "buttonMotion", "button1Motion", "button2Motion",
155 "button3Motion", "buttonPress", "buttonRelease",
156 "keyPress", "keyRelease", "enter",
157 "leave", "focus", "structure",
158 "propertyChange", "visibility", "proximityIn",
159 "proximityOut", "substructure", "scroll",
160 "all", NULL
161 };
162 */
163
164 GtkWidget *area = GTK_WIDGET ( data );
165
166 int idx;
167 int idx2;
168
169 if ( objc < 2 )
170 {
171 Tcl_WrongNumArgs ( interp, 1, objv, "command" );
172 return TCL_ERROR;
173 }
174
175 if ( Tcl_GetIndexFromObj ( interp, objv[1], cmds, "command", TCL_EXACT, &idx ) != TCL_OK )
176 {
177 return TCL_ERROR;
178 }
179
180 switch ( idx )
181 {
182
183 case OptionIdx:
184 {
185 #ifdef DEBUG_DRAWING_AREA
186 g_print ( "drawingArea OptionIdx\n" );
187 #endif
188
189 /*
190 other options here could include:
191 remove -remove the option from the options array (incl. script)
192 available -return a list of currently configured options
193 suspend -remove option from the event mask only
194 resume -add the option to the event mask
195 */
196
197 if ( strcmp ( Tcl_GetString ( objv[2] ), "add" ) )
198 {
199 return TCL_ERROR;
200 }
201
202
203 /* determine how many items in the add list */
204 gint noOptions;
205 gint n;
206
207 Tcl_ListObjLength ( interp, objv[3], &noOptions );
208
209 for ( n = 0; n < noOptions; ++n )
210 {
211 GtkWidget *childWidget;
212 Tcl_Obj *tp;
213
214 if ( Tcl_ListObjIndex ( interp, objv[3], n, &tp ) != TCL_OK )
215 {
216 return TCL_ERROR;
217 }
218
219 int OptIdx;
220
221 if ( Tcl_GetIndexFromObj ( interp, tp, options, "option", TCL_EXACT, &OptIdx ) != TCL_OK )
222 {
223 return TCL_ERROR;
224 }
225
226 _n = doOptionAdd ( interp, area, OptIdx );
227
228 }
229
230 break;
231 case ConfigureIdx:
232 {
233 #ifdef DEBUG_DRAWING_AREA
234 g_print ( "drawingArea ConfigureIdx\n" );
235 #endif
236 int ret = TCL_ERROR;
237
238 if ( gnoclParseAndSetOptions ( interp, objc - 1, objv + 1, drawingAreaOptions, area ) == TCL_OK )
239 {
240 ret = configure ( interp, area, drawingAreaOptions );
241 }
242
243 gnoclClearOptions ( drawingAreaOptions );
244
245 return ret;
246 }
247
248 break;
249 case DeleteIdx:
250 {
251 #ifdef DEBUG_DRAWING_AREA
252 g_print ( "delete\n" );
253 #endif
254 return gnoclDelete ( interp, area, objc, objv );
255 }
256
257 break;
258 case ClassIdx:
259 {
260 #ifdef DEBUG_DRAWING_AREA
261 g_print ( "Class = drawingArea\n" );
262 #endif
263 Tcl_SetObjResult ( interp, Tcl_NewStringObj ( "drawingArea", -1 ) );
264 }
265
266 break;
267 case DrawIdx:
268 {
269 #ifdef DEBUG_DRAWING_AREA
270 g_print ( "draw\n" );
271 #endif
272 /* relocate these to relevant parts of the souce file */
273 static const char *drawOpts[] =
274 {
275 "point", "points", "line",
276 "lines", "pixbuf", "segments",
277 "rectangle", "arc", "polygon",
278 "trapezoids", "glyph", "glyphTransformed",
279 "layoutLine", "layoutWithColors", "string",
280 "text", "image", "queue",
281 NULL
282 };
283
284 enum drawOptsIdx
285 {
286 PointIdx, PointsIdx, LineIdx,
287 LinesIdx, PixbufIdx, SegmentsIdx,
288 RectangleIdx, ArcIdx, PolygonIdx,
289 TrapezoidsIdx, GlyphIdx, GlyphTransformedIdx,
290 LayoutLineIdx, LayoutWithColorsIdx, StringIdx,
291 TextIdx, ImageIdx, QueueIdx
292 };
293
294 gint idx2;
295
296 if ( Tcl_GetIndexFromObj ( interp, objv[2], drawOpts, "option", TCL_EXACT, &idx2 ) != TCL_OK )
297 {
298 return TCL_ERROR;
299 }
300
301 switch ( idx2 )
302 {
303 case QueueIdx:
304 {
305 gtk_widget_queue_draw ( area );
306 }
307 break;
308 case PointIdx:
309 {
310 g_print ( "drawing point %s\n", Tcl_GetString ( objv[3] ) );
311 gint x, y;
312 sscanf ( Tcl_GetString ( objv[3] ), "%d %d", &x, &y );
313 gdk_draw_point ( area->window, area->style->fg_gc[GTK_WIDGET_STATE ( area ) ], x, y );
314 }
315 break;
316 case PointsIdx:
317 {
318
319 int k, n, npoints, x, y;
320 Tcl_ListObjLength ( interp, objv[3], &npoints );
321 g_print ( "drawing points %s (%d)\n", Tcl_GetString ( objv[3] ), npoints );
322
323
324 GdkPoint points[npoints]; // = { {x, y} , {x + 1, y} , {x - 1, y} , {x, y + 1} , {x, y - 1} };
325 k = 0;
326
327 for ( n = 0; n < npoints; n += 2 )
328 {
329 GtkWidget *childWidget;
330 Tcl_Obj *tpx, *tpy;
331
332 if ( Tcl_ListObjIndex ( interp, objv[3], n, &tpx ) != TCL_OK )
333 {
334 return TCL_ERROR;
335 }
336
337 if ( Tcl_ListObjIndex ( interp, objv[3], n + 1, &tpy ) != TCL_OK )
338 {
339 return TCL_ERROR;
340 }
341
342 Tcl_GetIntFromObj ( interp, tpx, &x );
343 Tcl_GetIntFromObj ( interp, tpy, &y );
344
345 g_print ( "points = %d: item %d x = %d : y = %d\n", npoints, k, x, y );
346
347 points[k].x = x;
348 points[k].y = y;
349 k++;
350
351 }
352
353 gdk_draw_points ( area->window, area->style->fg_gc[GTK_WIDGET_STATE ( area ) ], points, npoints / 2 );
354
355 }
356 break;
357 case LineIdx:
358 {
359 g_print ( "drawing line %s\n", Tcl_GetString ( objv[3] ) );
360 gint x1, y1, x2, y2;
361 sscanf ( Tcl_GetString ( objv[3] ), "%d %d %d %d", &x1, &y1, &x2, &y2 );
362 gdk_draw_line ( area->window, area->style->fg_gc[GTK_WIDGET_STATE ( area ) ], x1, y1, x2, y2 );
363 }
364 break;
365 case LinesIdx:
366 {
367
368 int k, n, npoints, x, y;
369 Tcl_ListObjLength ( interp, objv[3], &npoints );
370 g_print ( "drawing lines %s (%d)\n", Tcl_GetString ( objv[3] ), npoints );
371
372
373 GdkPoint points[npoints]; // = { {x, y} , {x + 1, y} , {x - 1, y} , {x, y + 1} , {x, y - 1} };
374 k = 0;
375
376 for ( n = 0; n < npoints; n += 2 )
377 {
378 GtkWidget *childWidget;
379 Tcl_Obj *tpx, *tpy;
380
381 if ( Tcl_ListObjIndex ( interp, objv[3], n, &tpx ) != TCL_OK )
382 {
383 return TCL_ERROR;
384 }
385
386 if ( Tcl_ListObjIndex ( interp, objv[3], n + 1, &tpy ) != TCL_OK )
387 {
388 return TCL_ERROR;
389 }
390
391 Tcl_GetIntFromObj ( interp, tpx, &x );
392 Tcl_GetIntFromObj ( interp, tpy, &y );
393
394 g_print ( "points = %d: item %d x = %d : y = %d\n", npoints, k, x, y );
395
396 points[k].x = x;
397 points[k].y = y;
398 k++;
399
400 }
401
402 gdk_draw_lines ( area->window, area->style->fg_gc[GTK_WIDGET_STATE ( area ) ], points, npoints / 2 );
403
404
405 //gdk_draw_lines (GdkDrawable *drawable, GdkGC *gc, const GdkPoint *points, gint n_points);
406
407 }
408 break;
409 case PixbufIdx:
410 {
411 g_print ( "drawing pixbuf %s\n", Tcl_GetString ( objv[3] ) );
412 GdkPixbuf *pixbuf;
413 GdkRgbDither dither;
414 gint src_x, src_y, dest_x, dest_y, width, height;
415 gint x_dither, y_dither;
416 gint ret;
417
418 /* set some defaults */
419 dither = GDK_RGB_DITHER_NONE;
420 src_x = 0; src_y = 0;
421 dest_x = 0; dest_y = 0;
422 width = -1; height = -1;
423 x_dither = 0; y_dither = 0;
424
425 pixbuf = gnoclGetPixBufFromName ( Tcl_GetString ( objv[3] ), interp );
426
427 width = gdk_pixbuf_get_width ( pixbuf );
428 height = gdk_pixbuf_get_height ( pixbuf );
429
430 int Idx2;
431 static const char *pbOpts[] =
432 {
433 "-from", "-to",
434 "-dither", "-offset",
435 NULL
436 };
437
438 enum pbIdx
439 {
440 FromIdx, ToIdx,
441 DitherIdx, OffsetIdx,
442 };
443
444 /* parse all the options */
445 int i = 4;
446
447 while ( i < objc )
448 {
449 //g_print ( "i = %d %s\n", i, Tcl_GetString ( objv[i] ) );
450
451 getIdx ( pbOpts, Tcl_GetString ( objv[i] ), &Idx2 );
452
453 switch ( Idx2 )
454 {
455 case FromIdx:
456 {
457
458 ret = sscanf ( Tcl_GetString ( objv[i+1] ), "%d %d %d %d", &src_x, &src_y, &width, &height );
459
460 if ( ret < 2 )
461 {
462 return TCL_ERROR;
463 }
464
465 g_print ( "-from %d %d %d %d\n", src_x, src_y, width, height );
466 }
467 break;
468 case ToIdx:
469 {
470
471 ret = sscanf ( Tcl_GetString ( objv[i+1] ), "%d %d", &dest_x, &dest_y );
472
473 if ( ret != 2 )
474 {
475 return TCL_ERROR;
476 }
477
478 g_print ( "-to %d %d\n", dest_x, dest_y );
479
480 }
481 break;
482 case DitherIdx:
483 {
484 /* one of none, normal or max : defaul = none */
485 if ( strcmp ( Tcl_GetString ( objv[i+1] ), "none" ) == 0 )
486 {
487 dither = GDK_RGB_DITHER_NONE;
488 }
489
490 if ( strcmp ( Tcl_GetString ( objv[i+1] ), "normal" ) == 0 )
491
492 {
493 dither = GDK_RGB_DITHER_NORMAL;
494 }
495
496 if ( strcmp ( Tcl_GetString ( objv[i+1] ), "max" ) == 0 )
497 {
498 dither = GDK_RGB_DITHER_MAX;
499 }
500
501 g_print ( "-dither %d\n", dither );
502 }
503
504 break;
505 case OffsetIdx:
506 {
507 ret = sscanf ( Tcl_GetString ( objv[i+1] ), "%d %d", &x_dither, &y_dither );
508
509 if ( ret != 2 )
510 {
511 return TCL_ERROR;
512 }
513
514 g_print ( "-offset %d %d\n", x_dither, y_dither );
515 }
516 break;
517 default:
518 {
519
520 return TCL_ERROR;
521 }
522 }
523
524 i += 2;
525 }
526
527 gdk_draw_pixbuf ( area->window, NULL, GDK_PIXBUF ( pixbuf ), src_x, src_y, dest_x, dest_y, width, height, dither, x_dither, y_dither );
528
529
530 }
531 break;
532
533 case SegmentsIdx:
534 {
535
536 int k, n, nsegments, x1, y1, x2, y2;
537 Tcl_ListObjLength ( interp, objv[3], &nsegments );
538 g_print ( "drawing segments %s (%d)\n", Tcl_GetString ( objv[3] ), nsegments );
539 GtkWidget *childWidget;
540 Tcl_Obj *tpx1, *tpy1, *tpx2, *tpy2;
541
542
543 GdkSegment segments[nsegments];
544 k = 0;
545
546 for ( n = 0; n < nsegments; n += 4 )
547 {
548
549 g_print ( "n = %d\n", n );
550
551
552 if ( Tcl_ListObjIndex ( interp, objv[3], n, &tpx1 ) != TCL_OK )
553 {
554 return TCL_ERROR;
555 }
556
557 if ( Tcl_ListObjIndex ( interp, objv[3], n + 1, &tpy1 ) != TCL_OK )
558 {
559 return TCL_ERROR;
560 }
561
562 if ( Tcl_ListObjIndex ( interp, objv[3], n + 2, &tpx2 ) != TCL_OK )
563 {
564 return TCL_ERROR;
565 }
566
567 if ( Tcl_ListObjIndex ( interp, objv[3], n + 3, &tpy2 ) != TCL_OK )
568 {
569 return TCL_ERROR;
570 }
571
572
573 Tcl_GetIntFromObj ( interp, tpx1, &x1 );
574 Tcl_GetIntFromObj ( interp, tpy1, &y1 );
575 Tcl_GetIntFromObj ( interp, tpx2, &x2 );
576 Tcl_GetIntFromObj ( interp, tpy2, &y2 );
577
578 segments[k].x1 = x1;
579 segments[k].y1 = y1;
580 segments[k].x2 = x2;
581 segments[k].y2 = y2;
582
583 g_print ( "points = %d: item %d x1 = %d : y1 = %d : x2 = %d : y2 = %d\n", nsegments, k, x1, y1, x2, y2 );
584 k++;
585
586 }
587
588 gdk_draw_segments ( area->window, area->style->fg_gc[GTK_WIDGET_STATE ( area ) ], segments, nsegments / 4 );
589
590 }
591 break;
592 case RectangleIdx:
593 {
594 g_print ( "drawing rectangle %s\n", Tcl_GetString ( objv[3] ) );
595 gint x, y, width, height;
596 gint filled;
597
598 filled = 0;
599
600 sscanf ( Tcl_GetString ( objv[3] ), "%d %d %d %d", &x, &y, &width, &height );
601
602 int Idx3;
603 static const char *rectOpts[] =
604 {
605 "-filled",
606 NULL
607 };
608
609 enum rectIdx
610 {
611 FilledIdx
612 };
613
614 int i = 4;
615
616 while ( i < objc )
617 {
618 g_print ( "%d %d\n", i, objc );
619 getIdx ( rectOpts, Tcl_GetString ( objv[i] ), &Idx3 );
620
621 switch ( Idx3 )
622 {
623 case FilledIdx:
624 {
625 g_print ( "yo\n" );
626 Tcl_GetIntFromObj ( NULL, objv[i+1], &filled );
627 }
628 break;
629 default: {};
630 }
631
632 i += 2;
633 }
634
635 gdk_draw_rectangle ( area->window, area->style->fg_gc[GTK_WIDGET_STATE ( area ) ], filled, x, y, width, height );
636
637 } break;
638 case ArcIdx:
639 {
640 g_print ( "drawing arc %s\n", Tcl_GetString ( objv[3] ) );
641
642
643 gboolean filled;
644 gint x, y;
645 gint width, height;
646 gint angle1, angle2;
647
648
649 sscanf ( Tcl_GetString ( objv[3] ), "%d %d %d %d %d %D", &x, &y, &width, &height, &angle1, &angle2 );
650
651 int Idx4;
652 static const char *arcOpts[] =
653 {
654 "-filled",
655 NULL
656 };
657
658 enum arcIdx
659 {
660 FilledIdx
661 };
662
663 int i = 4;
664
665 while ( i < objc )
666 {
667 g_print ( "%d %d\n", i, objc );
668 getIdx ( arcOpts, Tcl_GetString ( objv[i] ), &Idx4 );
669
670 switch ( Idx4 )
671 {
672 case FilledIdx:
673 {
674 Tcl_GetIntFromObj ( NULL, objv[i+1], &filled );
675 }
676 break;
677 default: {};
678 }
679
680 i += 2;
681 }
682
683
684 gdk_draw_arc ( area->window, area->style->fg_gc[GTK_WIDGET_STATE ( area ) ], filled, x, y, width, height, angle1, angle2 );
685
686
687 }
688 break;
689 case PolygonIdx:
690 {
691
692 int k, n, npoints, x, y;
693 gboolean filled;
694 Tcl_ListObjLength ( interp, objv[3], &npoints );
695 g_print ( "drawing polygon %s (%d)\n", Tcl_GetString ( objv[3] ), npoints );
696
697
698 GdkPoint points[npoints];
699 k = 0;
700
701 for ( n = 0; n < npoints; n += 2 )
702 {
703 GtkWidget *childWidget;
704 Tcl_Obj *tpx, *tpy;
705
706 if ( Tcl_ListObjIndex ( interp, objv[3], n, &tpx ) != TCL_OK )
707 {
708 return TCL_ERROR;
709 }
710
711 if ( Tcl_ListObjIndex ( interp, objv[3], n + 1, &tpy ) != TCL_OK )
712 {
713 return TCL_ERROR;
714 }
715
716 Tcl_GetIntFromObj ( interp, tpx, &x );
717 Tcl_GetIntFromObj ( interp, tpy, &y );
718
719 g_print ( "points = %d: item %d x = %d : y = %d\n", npoints, k, x, y );
720
721 points[k].x = x;
722 points[k].y = y;
723 k++;
724
725 }
726
727
728 int Idx5;
729 static const char *polyOpts[] =
730 {
731 "-filled",
732 NULL
733 };
734
735 enum polyIdx
736 {
737 FilledIdx
738 };
739
740 int i = 4;
741
742 while ( i < objc )
743 {
744 g_print ( "%d %d\n", i, objc );
745 getIdx ( polyOpts, Tcl_GetString ( objv[i] ), &Idx5 );
746
747 switch ( Idx5 )
748 {
749 case FilledIdx:
750 {
751 Tcl_GetIntFromObj ( NULL, objv[i+1], &filled );
752 }
753 break;
754 default: {};
755 }
756
757 i += 2;
758 }
759
760 //gdk_draw_points ( area->window, area->style->fg_gc[GTK_WIDGET_STATE ( area ) ], points, npoints / 2 );
761
762 gdk_draw_polygon ( area->window, area->style->fg_gc[GTK_WIDGET_STATE ( area ) ], filled, points, npoints / 2 );
763
764 } break;
765 case TrapezoidsIdx:
766 {
767 /*
768 double y1; the y coordinate of the start point.
769 double x11; the x coordinate of the top left corner
770 double x21; the x coordinate of the top right corner
771 double y2; the y coordinate of the end point.
772 double x12; the x coordinate of the bottom left corner
773 double x22; the x coordinate of the bottom right corner
774 */
775
776 int k, n, ntrapezoids;
777 double y1, x11, x21, y2, x12, x22;
778
779 Tcl_ListObjLength ( interp, objv[3], &ntrapezoids );
780 g_print ( "drawing polygon %s (%d)\n", Tcl_GetString ( objv[3] ), ntrapezoids );
781
782 GdkTrapezoid trapezoids[ntrapezoids];
783 k = 0;
784
785 for ( n = 0; n < ntrapezoids; n += 6 )
786 {
787 GtkWidget *childWidget;
788 Tcl_Obj *tpy1, *tpx11, *tpx21, *tpy2, *tpx12, *tpx22;
789
790 Tcl_ListObjIndex ( interp, objv[3], n, &tpy1 );
791 Tcl_ListObjIndex ( interp, objv[3], n + 1, &tpx11 );
792 Tcl_ListObjIndex ( interp, objv[3], n + 2, &tpx21 );
793 Tcl_ListObjIndex ( interp, objv[3], n + 3, &tpy2 );
794 Tcl_ListObjIndex ( interp, objv[3], n + 4 , &tpx12 );
795 Tcl_ListObjIndex ( interp, objv[3], n + 5, &tpx22 );
796
797
798 Tcl_GetIntFromObj ( interp, tpy1, &y1 );
799 Tcl_GetIntFromObj ( interp, tpx11, &x11 );
800 Tcl_GetIntFromObj ( interp, tpx21, &x21 );
801 Tcl_GetIntFromObj ( interp, tpy2, &y2 );
802 Tcl_GetIntFromObj ( interp, tpx12, &x12 );
803 Tcl_GetIntFromObj ( interp, tpx22, &x22 );
804
805 trapezoids[k].y1 = y1;
806 trapezoids[k].x11 = x11;
807 trapezoids[k].x21 = x21;
808 trapezoids[k].y2 = y2;
809 trapezoids[k].x12 = x12;
810 trapezoids[k].x22 = x11;
811
812 k++;
813
814 }
815
816 gdk_draw_trapezoids ( area->window, area->style->fg_gc[GTK_WIDGET_STATE ( area ) ], trapezoids, ntrapezoids / 2 );
817
818 } break;
819 case GlyphIdx:
820 {
821 gint x, y;
822 PangoGlyphString *glyphs;
823 g_print ( "NOT YET IMPLEMENTED drawing glyph %s\n", Tcl_GetString ( objv[3] ) );
824 //gdk_draw_glyphs (GdkDrawable *drawable, GdkGC *gc, PangoFont *font, gint x, gint y, PangoGlyphString *glyphs);
825
826
827
828
829
830
831 } break;
832 case GlyphTransformedIdx:
833 {
834 g_print ( "NOT YET IMPLEMENTED drawing glyphTransformed %s\n", Tcl_GetString ( objv[3] ) );
835 } break;
836 case LayoutLineIdx:
837 {
838 g_print ( "NOT YET IMPLEMENTED drawing layoutLine %s\n", Tcl_GetString ( objv[3] ) );
839 } break;
840 case LayoutWithColorsIdx:
841 {
842 g_print ( "NOT YET IMPLEMENTED drawing layoutWithColors %s\n", Tcl_GetString ( objv[3] ) );
843 } break;
844 case StringIdx:
845 {
846 g_print ( "drawing string %s\n", Tcl_GetString ( objv[3] ) );
847
848 GdkFont *font;
849 GdkGC *gc;
850 gint x;
851 gint y;
852 const gchar *string;
853 /*
854 typedef struct {
855 GdkFontType type;
856 gint ascent;
857 gint descent;
858 } GdkFont;
859 */
860
861 font = gdk_font_load ( "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" );
862 x = 100;
863 y = 100;
864 string = "Hello World!";
865
866
867 int Idx3;
868 static const char *rectOpts[] =
869 {
870 "-string", "-font",
871 "-x", "-y",
872 NULL
873 };
874
875 enum rectIdx
876 {
877 StringIdx, FontIdx, XIdx, YIdx
878 };
879
880 int i = 4;
881
882 while ( i < objc )
883 {
884 g_print ( "%d %d\n", i, objc );
885 getIdx ( rectOpts, Tcl_GetString ( objv[i] ), &Idx3 );
886
887 switch ( Idx3 )
888 {
889 case StringIdx:
890 {
891 g_print ( "yo\n" );
892 string = Tcl_GetString ( objv[i+1] );
893 }
894 break;
895 case FontIdx:
896 {
897 g_print ( "yo\n" );
898 string = Tcl_GetString ( objv[i+1] );
899 }
900 break;
901 case XIdx:
902 {
903 g_print ( "yo\n" );
904 Tcl_GetIntFromObj ( NULL, objv[i+1], &x );
905 }
906 break;
907 case YIdx:
908 {
909 g_print ( "yo\n" );
910 Tcl_GetIntFromObj ( NULL, objv[i+1], &y );
911 }
912 break;
913 default: {};
914 }
915
916 i += 2;
917 }
918
919 gdk_draw_string ( area->window, font, area->style->fg_gc[GTK_WIDGET_STATE ( area ) ], x, y, Tcl_GetString ( objv[3] ) );
920
921 } break;
922 case TextIdx:
923 {
924 g_print ( "drawing text %s\n", Tcl_GetString ( objv[3] ) );
925 /*
926 char *fnt = Tcl_GetStringFromObj ( opt->val.obj, NULL );
927 PangoFontDescription *font_desc = pango_font_description_from_string ( fnt );
928
929 gtk_widget_modify_font ( GTK_WIDGET ( obj ), font_desc );
930 pango_font_description_free ( font_desc );
931 */
932
933 } break;
934 case ImageIdx:
935 {
936 g_print ( "NOT YET IMPLEMENTED drawing image %s\n", Tcl_GetString ( objv[3] ) );
937 } break;
938 default:
939 {
940 g_print ( "drawing defaul %s\n", Tcl_GetString ( objv[3] ) );
941 }
942 }
943 }
944 break;
945 default: {}
946 }
947 }
948
949
950
951 return TCL_OK;
952 }
953
954
955 /**
956 /brief
957 **/
gnoclDrawingAreaCmd(ClientData data,Tcl_Interp * interp,int objc,Tcl_Obj * const objv[])958 int gnoclDrawingAreaCmd ( ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[] )
959 {
960 if ( gnoclGetCmdsAndOpts ( interp, cmds, drawingAreaOptions, objv, objc ) == TCL_OK )
961 {
962 return TCL_OK;
963 }
964
965 int ret;
966 GtkWidget *widget;
967
968 if ( gnoclParseOptions ( interp, objc, objv, drawingAreaOptions ) != TCL_OK )
969 {
970 gnoclClearOptions ( drawingAreaOptions );
971 return TCL_ERROR;
972 }
973
974 widget = gtk_drawing_area_new ();
975 gtk_widget_set_can_focus ( widget, 1 ); // allow widget to receive keyboard events
976
977 gtk_widget_show ( GTK_WIDGET ( widget ) );
978
979 gnoclSetOptions ( interp, drawingAreaOptions, G_OBJECT ( widget ), -1 );
980
981 gnoclClearOptions ( drawingAreaOptions );
982
983
984 /* register the new widget for use with the Tcl interpretor */
985 return gnoclRegisterWidget ( interp, GTK_WIDGET ( widget ), drawingAreaFunc );
986
987 }
988
989 /**
990 \brief Add new settings to the widget option array.
991 \author William J Giddings
992 \date 19/Feb/2010
993 \since 0.9.94
994 \see http://library.gnome.org/devel/gdk/stable/gdk-Events.html
995 \note Event Mask Options:
996
997 GDK_EXPOSURE_MASK GDK_POINTER_MOTION_MASK GDK_POINTER_MOTION_HINT_MASK
998 GDK_BUTTON_MOTION_MASK GDK_BUTTON1_MOTION_MASK GDK_BUTTON2_MOTION_MASK
999 GDK_BUTTON3_MOTION_MASK GDK_BUTTON_PRESS_MASK GDK_BUTTON_RELEASE_MASK
1000 GDK_KEY_PRESS_MASK GDK_KEY_RELEASE_MASK GDK_ENTER_NOTIFY_MASK
1001 GDK_LEAVE_NOTIFY_MASK GDK_FOCUS_CHANGE_MASK GDK_STRUCTURE_MASK
1002 GDK_PROPERTY_CHANGE_MASK GDK_VISIBILITY_NOTIFY_MASK GDK_PROXIMITY_IN_MASK
1003 GDK_PROXIMITY_OUT_MASK GDK_SUBSTRUCTURE_MASK GDK_SCROLL_MASK
1004 GDK_ALL_EVENTS_MASK
1005
1006 **/
doOptionAdd(Tcl_Interp * interp,GtkWidget * area,gint OptIdx)1007 int doOptionAdd ( Tcl_Interp *interp, GtkWidget *area, gint OptIdx )
1008 {
1009 #ifdef DEBUG_DRAWING_AREA
1010 g_print ( "drawingArea OptionIdx = %s\n", options[OptIdx] );
1011 #endif
1012
1013
1014 /* return error the maximum number of options has been reached */
1015 gint j = sizeof ( drawingAreaOptions ) / sizeof ( GnoclOption );
1016
1017 if ( j == _n )
1018 {
1019 return TCL_ERROR;
1020 }
1021
1022 /* set the option name directly from list of possible options */
1023 drawingAreaOptions[_n].optName = options[OptIdx];
1024
1025 /* set the remaining values, assign callback function */
1026 switch ( OptIdx )
1027 {
1028 case OnExposeIdx:
1029 {
1030 //g_print ( "adding GDK_EXPOSURE_MASK OptIdx = %d\n", OptIdx );
1031 gtk_widget_add_events ( area, GDK_EXPOSURE_MASK );
1032 drawingAreaOptions[_n].func = gnoclOptOnExpose;
1033 } break;
1034
1035 case OnButton1MotionIdx:
1036 {
1037 //g_print ( "adding GDK_BUTTON1_MOTION_MASK OptIdx = %d\n", OptIdx );
1038 gtk_widget_add_events ( area, GDK_BUTTON1_MOTION_MASK );
1039 drawingAreaOptions[_n].func = gnoclOptOnKeyPress;
1040 } break;
1041
1042 case OnButton2MotionIdx:
1043 {
1044 //g_print ( "adding GDK_BUTTON2_MOTION_MASK OptIdx = %d\n", OptIdx );
1045 gtk_widget_add_events ( area, GDK_BUTTON2_MOTION_MASK );
1046 drawingAreaOptions[_n].func = gnoclOptOnKeyPress;
1047 } break;
1048
1049 case OnButton3MotionIdx:
1050 {
1051 //g_print ( "adding GDK_BUTTON1_MOTION_MASK OptIdx = %d\n", OptIdx );
1052 gtk_widget_add_events ( area, GDK_BUTTON2_MOTION_MASK );
1053 drawingAreaOptions[_n].func = gnoclOptOnKeyPress;
1054 } break;
1055
1056 case OnKeyPressIdx:
1057 {
1058 //g_print ( "adding GDK_KEY_PRESS_MASK OptIdx = %d\n", OptIdx );
1059 gtk_widget_add_events ( area, GDK_KEY_PRESS_MASK );
1060 drawingAreaOptions[_n].func = gnoclOptOnKeyPress;
1061 } break;
1062
1063 case OnKeyReleaseIdx:
1064 {
1065 //g_print ( "adding GDK_KEY_RELEASE_MASK OptIdx = %d\n", OptIdx );
1066 gtk_widget_add_events ( area, GDK_KEY_RELEASE_MASK );
1067 drawingAreaOptions[_n].func = gnoclOptOnKeyRelease;
1068 }
1069 break;
1070
1071 case OnButtonMotionIdx:
1072 {
1073 //g_print ( "adding GDK_BUTTON_MOTION_MASK OptIdx = %d\n", OptIdx );
1074 gtk_widget_add_events ( area, GDK_BUTTON_MOTION_MASK );
1075 drawingAreaOptions[_n].func = gnoclOptOnButtonMotion;
1076 }
1077 break;
1078
1079 case OnPointerMotionIdx: // working ok!
1080 {
1081 //g_print ( "adding GDK_POINTER_MOTION_MASK OptIdx = %d\n", OptIdx );
1082 gtk_widget_add_events ( area, GDK_POINTER_MOTION_MASK );
1083 drawingAreaOptions[_n].func = gnoclOptOnMotion;
1084 }
1085 break;
1086
1087 case OnEnterIdx: // working ok!
1088 {
1089 //g_print ( "adding GDK_ENTER_NOTIFY_MASK OptIdx = %d\n", OptIdx );
1090 gtk_widget_add_events ( area, GDK_ENTER_NOTIFY_MASK );
1091 drawingAreaOptions[_n].propName = "E";
1092 drawingAreaOptions[_n].func = gnoclOptOnEnterLeave;
1093 }
1094 break;
1095
1096 case OnLeaveIdx: // working ok!
1097 {
1098 //g_print ( "adding GDK_ENTER_NOTIFY_MASK OptIdx = %d\n", OptIdx );
1099 gtk_widget_add_events ( area, GDK_LEAVE_NOTIFY_MASK );
1100 drawingAreaOptions[_n].propName = "L";
1101 drawingAreaOptions[_n].func = gnoclOptOnEnterLeave;
1102 }
1103 break;
1104 case OnButtonPressIdx: // working ok!
1105 {
1106 //g_print ( "adding GDK_BUTTON_PRESS_MASK OptIdx = %d\n", OptIdx );
1107 gtk_widget_add_events ( area, GDK_BUTTON_PRESS_MASK ) ;
1108 drawingAreaOptions[_n].propName = "P";
1109 drawingAreaOptions[_n].func = gnoclOptOnButton;
1110 }
1111 break;
1112
1113 case OnButtonReleaseIdx: // working ok!
1114 {
1115 //g_print ( "adding GDK_BUTTON_RELEASE_MASK OptIdx = %d\n", OptIdx );
1116 gtk_widget_add_events ( area, GDK_BUTTON_RELEASE_MASK ) ;
1117 drawingAreaOptions[_n].propName = "R";
1118 drawingAreaOptions[_n].func = gnoclOptOnButton;
1119 }
1120 break;
1121 }
1122
1123 /* implement changes */
1124 gnoclSetOptions ( interp, drawingAreaOptions, area, -1 );
1125
1126 return ++_n;
1127 }
1128
1129