1 /*
2 * Dr Geo an interactive geometry software
3 * (C) Copyright Hilaire Fernandes 1997-2003
4 * hilaire@ofset.org
5 *
6 * This code is copyright Laurent Gauthier 1999
7 * lolo@seul.org
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public Licences as by published
12 * by the Free Software Foundation; either version 2; or (at your option)
13 * any later version
14 *
15 * This program is distributed in the hope that it will entertaining,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
18 * Publis License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.
22 * 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include <string.h>
26
27 #include "drgeo_tool.h"
28 #include "drgeo_point.h"
29
30 drgeoState
getDrgeoState()31 drgeoTool::getDrgeoState ()
32 {
33 return state;
34 }
35
36 // -------------------------------------------------
37 // Implementation for the Null tool, this tool does nothing.
38
39 void
initialize(drgeoDrawableUI * drawable)40 drgeoNullTool::initialize (drgeoDrawableUI * drawable)
41 {
42 // Do nothing.
43 g_printerr ("initialize()\n");
44 }
45
46 void
handlePress(drgeoDrawableUI * drawable,drgeoPoint & where)47 drgeoNullTool::handlePress (drgeoDrawableUI * drawable, drgeoPoint & where)
48 {
49 // Do nothing.
50 g_printerr ("handlePress (%lf,%lf)\n", where.getX (), where.getY ());
51 }
52
53 void
handleRelease(drgeoDrawableUI * drawable,drgeoPoint & where)54 drgeoNullTool::handleRelease (drgeoDrawableUI * drawable, drgeoPoint & where)
55 {
56 // Do nothing.
57 // printf ("handleRelease (%lf,%lf)\n", where.getX (), where.getY ());
58 }
59
60 void
handleMouseAt(drgeoDrawableUI * drawable,drgeoPoint & where)61 drgeoNullTool::handleMouseAt (drgeoDrawableUI * drawable, drgeoPoint & where)
62 {
63 // Do nothing.
64 g_printerr ("handleMouseAt (%lf,%lf)\n", where.getX (), where.getY ());
65 }
66
67 void
68 drgeoNullTool::
handleChoice(drgeoDrawableUI * drawable,geometricObject * item)69 handleChoice (drgeoDrawableUI * drawable, geometricObject * item)
70 {
71 // Do nothing.
72 g_printerr ("HandleChoice()\n");
73 }
74
75 void
finish(drgeoDrawableUI * drawable)76 drgeoNullTool::finish (drgeoDrawableUI * drawable)
77 {
78 // Do nothing.
79 g_printerr ("finish()\n");
80 }
81
82 // -------------------------------------------------
83 // Implementation for the Printing Area tool.
84 void
initialize(class drgeoDrawableUI * drawable)85 drgeoPrintingAreaTool::initialize (class drgeoDrawableUI * drawable)
86 {
87 // no corner of the printing area is selected
88 state = drgeoStateNeutral;
89 }
90
91 void
handlePress(class drgeoDrawableUI * drawable,drgeoPoint & where)92 drgeoPrintingAreaTool::handlePress (class drgeoDrawableUI * drawable,
93 drgeoPoint & where)
94 {
95 switch (state)
96 {
97 case drgeoStateNeutral:
98 corner1 = where;
99 state = drgeoState1stCornerSelected;
100 break;
101 case drgeoState1stCornerSelected:
102 corner2 = where;
103 state = drgeoState2ndCornerSelected;
104 // instruct the drawable about the selected printing area
105 drawable->showPrintingArea (corner1, corner2);
106 break;
107 case drgeoState2ndCornerSelected:
108 // does the user wants to reselect the area? in this case
109 // fallback to initial state
110 corner1 = where;
111 state = drgeoState1stCornerSelected;
112 drawable->unsetPrintingArea ();
113 break;
114 default:
115 // We should never reach that point !
116 break;
117 }
118 }
119
120 void
handleMouseAt(class drgeoDrawableUI * drawable,drgeoPoint & where)121 drgeoPrintingAreaTool::handleMouseAt (class drgeoDrawableUI * drawable,
122 drgeoPoint & where)
123 {
124 switch (state)
125 {
126 case drgeoStateNeutral:
127 // nothing to be done
128 break;
129 case drgeoState1stCornerSelected:
130 // we can print the moving printing area
131 drawable->showPrintingArea (corner1, where);
132 break;
133 case drgeoState2ndCornerSelected:
134 // Nothing to be done, the selected drawing area is already
135 // printed
136 break;
137 default:
138 // We should never reach that point !
139 break;
140 }
141 }
142
143 void
finish(class drgeoDrawableUI * drawable)144 drgeoPrintingAreaTool::finish (class drgeoDrawableUI * drawable)
145 {
146 switch (state)
147 {
148 case drgeoState2ndCornerSelected:
149 // the drawable already now the drawing area
150 break;
151 case drgeoState1stCornerSelected:
152 // unselect the printing area, the 2 corner was not selected
153 drawable->unsetPrintingArea ();
154 }
155 }
156
157 // -------------------------------------------------
158 // Implementation for the Select tool.
159
160 void
initialize(drgeoDrawableUI * drawable)161 drgeoSelectTool::initialize (drgeoDrawableUI * drawable)
162 {
163 // This code is invoked when the tool selected.
164 state = drgeoStateNeutral;
165 tipOn = FALSE;
166 last_nb_elem = 0;
167 }
168
169 void
handlePress(drgeoDrawableUI * drawable,drgeoPoint & where)170 drgeoSelectTool::handlePress (drgeoDrawableUI * drawable, drgeoPoint & where)
171 {
172 liste_elem *list;
173 int i;
174
175 // Do nothing if no figure is currently associated with this drawable.
176 if (drawable->figure != NULL)
177 {
178 drawable->removeTip ();
179 switch (state)
180 {
181 case drgeoStateItemChoice:
182 // The user has not chosen any item, so revert to neutral
183 // state.
184 state = drgeoStateNeutral;
185 // Fall through! This is really what is wanted here.
186 case drgeoStateNeutral:
187 // The mouse button is being pressed, check if there are items
188 // near the mouse.
189 list = drawable->figure->mouseSelection (where);
190 list->init_lire ();
191 if (list->nb_elem == 1)
192 {
193 // Only one item is selected.
194 state = drgeoStateItemGrabbed;
195 handleChoice (drawable, (geometricObject *) list->lire (0));
196 last = where;
197 }
198 else if (list->nb_elem > 1)
199 {
200 // Several items are selected at once, we must prompt the
201 // user for a choice. When the user is done with his
202 // choice the handleChoice method will be invoked.
203 state = drgeoStateItemChoice;
204 last = where;
205 drawable->chooseItem (list);
206 }
207 else
208 {
209 // The user click on the background:
210 // clear the selection
211 state = drgeoStateNeutral;
212 drawable->getFigure ()->clearSelection ();
213 itemUnderMouse = NULL;
214 }
215 break;
216 case drgeoStateItemSelected:
217 // The mouse button is being pressed, check if the last
218 // selected item is near the mouse.
219 list = drawable->figure->mouseSelection (where);
220 list->init_lire ();
221 if (list->nb_elem >= 1)
222 {
223 // Check each item under the mouse to see if the last item
224 // selected is there. If so select it, if not go back to
225 // neutral state.
226 for (i = 0; i < list->nb_elem; i++)
227 {
228 if (this->item == (geometricObject *) list->lire (0))
229 {
230 state = drgeoStateItemGrabbed;
231 // The following is not necessary because it has
232 // already been performed, when the item has been
233 // selected among multiple items.
234 // handleChoice (drawable, this->item);
235 last = where;
236 break; // Get out of the loop! We found it.
237
238 }
239 }
240 if (state == drgeoStateItemSelected)
241 {
242 // The item last selected is not under the mouse at
243 // this point, so we are back to neutral state.
244 state = drgeoStateNeutral;
245 }
246 }
247 else
248 {
249 // No item under the mouse go back to the Neutral state.
250 state = drgeoStateNeutral;
251 }
252 break;
253 default:
254 // If we get there, then there's a problem with the event
255 // handling code... XXX
256 break;
257 }
258 }
259 }
260
261 void
262 drgeoSelectTool::
handleRelease(drgeoDrawableUI * drawable,drgeoPoint & where)263 handleRelease (drgeoDrawableUI * drawable, drgeoPoint & where)
264 {
265 // Do nothing if no figure is currently associated with this drawable.
266 if (drawable->figure != NULL)
267 {
268 liste_elem *list;
269 geometricObject *item;
270
271 drawable->removeTip ();
272 switch (state)
273 {
274 case drgeoStateItemChoice:
275 case drgeoStateItemSelected:
276 // The user has not chosen any item, so revert to neutral
277 // state.
278 state = drgeoStateNeutral;
279 // Fall through! This is really what is wanted here.
280 case drgeoStateNeutral:
281 // The mouse button is just being released with nothing being
282 // dragged, so we only show a tip displaying the full name of
283 // the nearest item.
284 list = drawable->figure->mouseSelection (where);
285 list->init_lire ();
286 if (list->nb_elem == 1)
287 {
288 item = (geometricObject *) list->lire (0);
289 drawable->showTip (where, item->getTypeName ());
290 tipOn = TRUE;
291 }
292 else if (list->nb_elem > 1)
293 {
294 // There are several items under the mouse.
295 drawable->showTip (where, "???");
296 tipOn = TRUE;
297 }
298 break;
299 case drgeoStateItemGrabbed:
300 // The user is just releasing the mouse. Reset the state to
301 // neutral and that's all.
302 state = drgeoStateNeutral;
303 break;
304 case drgeoStateItemDragged:
305 // The drag is finished, so we just drop the selected ietms
306 // where the mouse currently is.
307 state = drgeoStateNeutral;
308 drawable->figure->moveItem (NULL, where - start);
309 drawable->figure->dropSelection (last, where);
310 /* record the drag path */
311 drawable->removeTip ();
312
313 // Forget the item when dragged
314 drawable->getFigure ()->clearSelection ();
315 itemUnderMouse = NULL;
316
317 break;
318 default:
319 // If we get there, then there's a problem with the event
320 // handling code... XXX
321 break;
322 }
323 }
324 }
325 void
326 drgeoSelectTool::
handleMouseAt(drgeoDrawableUI * drawable,drgeoPoint & where)327 handleMouseAt (drgeoDrawableUI * drawable, drgeoPoint & where)
328 {
329 int i;
330
331 // Do nothing if no figure is currently associated with this drawable.
332 if (drawable->figure != NULL)
333 {
334 liste_elem *list;
335
336 switch (state)
337 {
338 case drgeoStateItemChoice:
339 // The user has not chosen any item, so revert to neutral
340 // state.
341 state = drgeoStateNeutral;
342 // Fall through! This is really what is wanted here.
343 case drgeoStateNeutral:
344 // The mouse is just moving over the figure, so we just query
345 // the figure to know which items are found near the current
346 // mouse position. And a tooltip is shown displaying the full
347 // name of the nearest item.
348
349 list = drawable->figure->mouseSelection (where);
350 if (list->nb_elem == 1 &&
351 ((geometricObject *) list->lire (1) != itemUnderMouse))
352 {
353 // The mouse move over another item
354 itemUnderMouse = (geometricObject *) list->lire (1);
355 drawable->showTip (where, itemUnderMouse->getTypeName ());
356 tipOn = TRUE;
357 drawable->setCursor (hand);
358 }
359 else if (list->nb_elem > 1 && last_nb_elem <= 1)
360 {
361 // There are NOW several items under the mouse.
362 drawable->showTip (where, "???");
363 tipOn = TRUE;
364 drawable->setCursor (hand);
365 itemUnderMouse = NULL;
366 }
367 else if (list->nb_elem == 0 && drawable->tipOn ())
368 {
369 /* mouse not over object anymore, remove the tip */
370 drawable->removeTip ();
371 drawable->setCursor (arrow);
372 tipOn = FALSE;
373 itemUnderMouse = NULL;
374 }
375 last_nb_elem = list->nb_elem;
376 break;
377 case drgeoStateItemSelected:
378 // The mouse is moving over the figure, check if we are moving
379 // away from the spot where the last item was selected. If so
380 // go back to neutral state.
381 if (away
382 && (spot - where).norm () > (last - spot).norm ()
383 + 4.0 * drawable->getRange ())
384 {
385 state = drgeoStateNeutral;
386 drawable->figure->clearSelection ();
387 drawable->setCursor (arrow);
388 }
389 else
390 {
391 // If the last selected item is under the mouse, then show
392 // a tip about it.
393 list = drawable->figure->mouseSelection (where);
394 list->init_lire ();
395 if (list->nb_elem >= 1)
396 {
397 // Check each item under the mouse to see if the last item
398 // selected is there. If so show its tip.
399 for (i = 0; i < list->nb_elem; i++)
400 {
401 if (this->item == (geometricObject *) list->lire (0)
402 && !tipOn)
403 {
404 drawable->showTip (where,
405 this->item->getTypeName ());
406 tipOn = TRUE;
407 drawable->setCursor (hand);
408 break; // Get out of the loop! We found it.
409 }
410 }
411 }
412 away = TRUE;
413 last = where;
414 }
415 break;
416 case drgeoStateItemGrabbed:
417 // The user is just starting a mouse move with an item
418 // grabbed, this means a drag is starting. Notify the
419 // figure.
420 state = drgeoStateItemDragged;
421 drawable->figure->dragSelection (last, where);
422 drawable->refresh ();
423 last = where;
424 start = where;
425 break;
426 case drgeoStateItemDragged:
427 // The drag is going on.
428 drawable->figure->dragSelection (last, where);
429 drawable->refresh ();
430 last = where;
431 break;
432 default:
433 // If we get there, then there's a problem with the event
434 // handling code... XXX
435 break;
436 }
437 }
438 }
439
440 void
441 drgeoSelectTool::
handleChoice(drgeoDrawableUI * drawable,geometricObject * item)442 handleChoice (drgeoDrawableUI * drawable, geometricObject * item)
443 {
444 drgeoPoint xxx;
445
446 if (drawable->figure)
447 {
448 if (state == drgeoStateItemChoice)
449 {
450 state = drgeoStateItemSelected;
451 this->item = item; // Keep track of the last item
452 // selected for later reference.
453
454 away = FALSE;
455 spot = last;
456 }
457 drawable->figure->clearSelection ();
458 drawable->figure->addToSelection (xxx, item);
459 }
460 }
461
462 void
finish(drgeoDrawableUI * drawable)463 drgeoSelectTool::finish (drgeoDrawableUI * drawable)
464 {
465 // This code is invoked when the tool is deselected.
466 }
467
468 // -------------------------------------------------
469 // Implementation for the Build tool.
470
471 void
initialize(drgeoDrawableUI * drawable)472 drgeoBuildTool::initialize (drgeoDrawableUI * drawable)
473 {
474 // This code is invoked when the tool selected.
475 state = drgeoStateNeutral;
476 tipOn = FALSE;
477 last_nb_elem = 0;
478 }
479
480 void
handlePress(drgeoDrawableUI * drawable,drgeoPoint & where)481 drgeoBuildTool::handlePress (drgeoDrawableUI * drawable, drgeoPoint & where)
482 {
483 liste_elem *list;
484 int i;
485
486 // Do nothing if no figure is currently associated with this drawable.
487 if (drawable->figure != NULL)
488 {
489 drawable->removeTip ();
490 switch (state)
491 {
492 case drgeoStateItemChoice:
493 // The user has not chosen any item, so revert to neutral
494 // state.
495 state = drgeoStateNeutral;
496 // Fall through! This is really what is wanted here.
497 case drgeoStateNeutral:
498 // The mouse button is being pressed, check if there are items
499 // near the mouse.
500 list = drawable->figure->mouseSelection (where);
501 list->init_lire ();
502 if (list->nb_elem == 0)
503 {
504 // no item was selected. Just invoke handleChoice with a
505 // NULL parameter that will be transmitted to
506 // figure->addToSelection() for appropriate processing.
507 last = where;
508 handleChoice (drawable, NULL);
509 }
510 else if (list->nb_elem == 1)
511 {
512 // Only one item is selected, add it to the selection.
513 last = where;
514 handleChoice (drawable, (geometricObject *) list->lire (0));
515 }
516 else if (list->nb_elem > 1)
517 {
518 // Several items are selected at once, we must prompt the
519 // user for a choice. When the user is done with his
520 // choice the handleChoice method will be invoked.
521 state = drgeoStateItemChoice;
522 last = where;
523 drawable->chooseItem (list);
524 }
525 break;
526 default:
527 // If we get there, then there's a problem with the event
528 // handling code... XXX
529 break;
530 }
531 }
532 }
533
534 void
handleRelease(drgeoDrawableUI * drawable,drgeoPoint & where)535 drgeoBuildTool::handleRelease (drgeoDrawableUI * drawable, drgeoPoint & where)
536 {
537 // Do nothing if no figure is currently associated with this drawable.
538 if (drawable->figure != NULL)
539 {
540 liste_elem *list;
541 geometricObject *item;
542
543 drawable->removeTip ();
544 switch (state)
545 {
546 case drgeoStateItemChoice:
547 // The user has not chosen any item, so revert to neutral
548 // state.
549 state = drgeoStateNeutral;
550 // Fall through! This is really what is wanted here.
551 case drgeoStateNeutral:
552 // The mouse button is just being released with nothing being
553 // dragged, so we only show a tip displaying the full name of
554 // the nearest item.
555 list = drawable->figure->mouseSelection (where);
556 list->init_lire ();
557 if (list->nb_elem == 1)
558 {
559 item = (geometricObject *) list->lire (0);
560 drawable->showTip (where, item->getTypeName ());
561 tipOn = TRUE;
562 }
563 else if (list->nb_elem > 1)
564 {
565 // There are several items under the mouse.
566 drawable->showTip (where, "???");
567 tipOn = TRUE;
568 }
569 break;
570 default:
571 // If we get there, then there's a problem with the event
572 // handling code... XXX
573 break;
574 }
575 }
576 }
577
578 void
handleMouseAt(drgeoDrawableUI * drawable,drgeoPoint & where)579 drgeoBuildTool::handleMouseAt (drgeoDrawableUI * drawable, drgeoPoint & where)
580 {
581 int i;
582
583 // Do nothing if no figure is currently associated with this drawable.
584 if (drawable->figure != NULL)
585 {
586 liste_elem *list;
587 geometricObject *item;
588
589 switch (state)
590 {
591 case drgeoStateItemChoice:
592 // The user has not chosen any item, so revert to neutral
593 // state.
594 state = drgeoStateNeutral;
595 // Fall through! This is really what is wanted here.
596 case drgeoStateNeutral:
597 // The mouse is just moving over the figure, so we just query
598 // the figure to know which items are found near the current
599 // mouse position. And a tooltip is shown displaying the full
600 // name of the nearest item.
601 list = drawable->figure->mouseSelection (where);
602
603 if (list->nb_elem == 1 &&
604 ((geometricObject *) list->lire (1) != itemUnderMouse))
605 {
606 itemUnderMouse = (geometricObject *) list->lire (1);
607 drawable->showTip (where, itemUnderMouse->getTypeName ());
608 drawable->setCursor (pen);
609 }
610 else if (list->nb_elem > 1 && last_nb_elem <= 1)
611 {
612 // There are several items under the mouse.
613 drawable->showTip (where, "???");
614 drawable->setCursor (pen);
615 itemUnderMouse = NULL;
616 }
617 else if (list->nb_elem == 0 && drawable->tipOn ())
618 {
619 /* mouse not over object anymore, remove the tip */
620 drawable->removeTip ();
621 drawable->setCursor (arrow);
622 itemUnderMouse = NULL;
623 }
624 last_nb_elem = list->nb_elem;
625 break;
626 default:
627 // If we get there, then there's a problem with the event
628 // handling code... XXX
629 break;
630 }
631 }
632 }
633
634 void
635 drgeoBuildTool::
handleChoice(drgeoDrawableUI * drawable,geometricObject * item)636 handleChoice (drgeoDrawableUI * drawable, geometricObject * item)
637 {
638 if (drawable->figure)
639 {
640 // Add the selected item to the current figure's selection.
641 drawable->figure->addToSelection (last, item);
642 }
643 }
644
645 void
finish(drgeoDrawableUI * drawable)646 drgeoBuildTool::finish (drgeoDrawableUI * drawable)
647 {
648 // This code is invoked when the tool is deselected.
649 }
650
651
652
653 // -----------------------------------------------------
654 // Macro Build Tool, used for macro creation.
655 // -----------------------------------------------------
656
657 void
initialize(drgeoDrawableUI * drawable)658 drgeoMacroBuildTool::initialize (drgeoDrawableUI * drawable)
659 {
660 // First invoke the initialize() method of drgeoBuildTool
661 // super-class.
662 drgeoBuildTool::initialize (drawable);
663
664 // Now let's do our stuff.
665 builder = new drgeoMacroBuilder (drawable->getFigure ());
666
667 // Create the macro dialog that will control the builder.
668 dialog = drawable->createMacroBuildDialog (builder);
669 }
670
671 // All the other methods are inherited from drgeoBuildTool. We only
672 // redefine the handleChoice() method, and of course the initialize()
673 // and finish().
674
675 void
676 drgeoMacroBuildTool::
handleChoice(drgeoDrawableUI * drawable,geometricObject * item)677 handleChoice (drgeoDrawableUI * drawable, geometricObject * item)
678 {
679 // Forward this item to the macro builder.
680 if (dialog && item)
681 {
682 dialog->add (item);
683 }
684 }
685
686 void
finish(drgeoDrawableUI * drawable)687 drgeoMacroBuildTool::finish (drgeoDrawableUI * drawable)
688 {
689 // First invoke the initialize() method of drgeoBuildTool
690 // super-class.
691 drgeoBuildTool::finish (drawable);
692
693 // Remove the macro dialog that is controlling the builder.
694 delete dialog;
695
696 // Free the drgeoMacroBuilder.
697 delete builder;
698 }
699
700 // -----------------------------------------------------
701 // Macro Play Tool, used for macro execution.
702 // -----------------------------------------------------
703
704 void
initialize(drgeoDrawableUI * drawable)705 drgeoMacroPlayTool::initialize (drgeoDrawableUI * drawable)
706 {
707 // First invoke the initialize() method of drgeoBuildTool
708 // super-class.
709 drgeoBuildTool::initialize (drawable);
710
711 // Now let's do our stuff.
712 player = new drgeoMacroPlayer (drawable->getFigure ());
713
714 // Create the macro dialog that will control the Player.
715 dialog = drawable->createMacroPlayDialog (player);
716 }
717
718 // All the other methods are inherited from drgeoBuildTool. We only
719 // redefine the handleChoice() method, and of course the initialize()
720 // and finish().
721
722 void
723 drgeoMacroPlayTool::
handleChoice(drgeoDrawableUI * drawable,geometricObject * item)724 handleChoice (drgeoDrawableUI * drawable, geometricObject * item)
725 {
726 drgeoPoint xxx;
727
728 // Forward this item to the macro Player.
729 if (dialog && item)
730 {
731 dialog->add (item);
732 }
733 }
734
735 void
finish(drgeoDrawableUI * drawable)736 drgeoMacroPlayTool::finish (drgeoDrawableUI * drawable)
737 {
738 // First invoke the initialize() method of drgeoPlayTool
739 // super-class.
740 drgeoBuildTool::finish (drawable);
741
742 // Remove the macro dialog that is controlling the Player.
743 delete dialog;
744
745 // Free the drgeoMacroPlayer.
746 delete player;
747 }
748
749
750 // -----------------------------------------------------
751 // Dialog Less Macro Play Tool, used for macro execution.
752 // From the menu barre
753 // -----------------------------------------------------
754
755 void
initialize(drgeoDrawableUI * drawable)756 drgeoMacroPlayToolDialogLess::initialize (drgeoDrawableUI * drawable)
757 {
758 // First invoke the initialize() method of drgeoBuildTool
759 // super-class.
760 drgeoBuildTool::initialize (drawable);
761
762 // Now let's do our stuff.
763 player = new drgeoMacroPlayer (drawable->getFigure ());
764
765 // Instruct the drawable about the Player.
766 drawable->setMacroPlayer (player);
767 }
768
769 // All the other methods are inherited from drgeoBuildTool. We only
770 // redefine the handleChoice() method, and of course the initialize()
771 // and finish().
772
773 void
774 drgeoMacroPlayToolDialogLess::
handleChoice(drgeoDrawableUI * drawable,geometricObject * item)775 handleChoice (drgeoDrawableUI * drawable, geometricObject * item)
776 {
777 // Forward this item to the macro Player.
778 if (player && item)
779 {
780 player->add (item);
781 }
782 }
783
784 void
785 drgeoMacroPlayToolDialogLess::
finish(drgeoDrawableUI * drawable)786 finish (drgeoDrawableUI * drawable)
787 {
788 // First invoke the initialize() method of drgeoPlayTool
789 // super-class.
790 drgeoBuildTool::finish (drawable);
791
792 // Free the drgeoMacroPlayer.
793 delete player;
794 }
795
796 gboolean drgeoMacroPlayToolDialogLess::
selectMacro(const gchar * name)797 selectMacro (const gchar *name)
798 {
799 return player->setMacro (name);
800 }
801
802 // -----------------------------------------------------
803 // Dialog Less Animation Tool, used for animation.
804 // From the menu barre
805 // -----------------------------------------------------
806 static int
timer_cb(drgeoAnimationDialogLess * tool)807 timer_cb (drgeoAnimationDialogLess * tool)
808 {
809 if (tool->getDrgeoState () == drgeoStateAnimated)
810 tool->animate ();
811 return (TRUE); // Make sure the CallBack will be
812 // called again and again...
813 }
814
815 void
initialize(drgeoDrawableUI * drawable)816 drgeoAnimationDialogLess::initialize (drgeoDrawableUI * drawable)
817 {
818 drgeoBuildTool::initialize (drawable);
819 step = 0.05;
820 timeoutTag = 0;
821 itemUnderMouse = NULL;
822 this->drawable = drawable;
823 }
824
825 void
handlePress(drgeoDrawableUI * drawable,drgeoPoint & where)826 drgeoAnimationDialogLess::handlePress (drgeoDrawableUI * drawable, drgeoPoint & where)
827 {
828 liste_elem *list;
829 int i;
830
831 // Do nothing if no figure is currently associated with this drawable.
832 if (drawable->figure != NULL)
833 {
834 drawable->removeTip ();
835 switch (state)
836 {
837 case drgeoStateAnimated:
838 // user click while a point is animated,
839 // stop and reset the animation
840 reset ();
841 state = drgeoStateNeutral;
842 break;
843 case drgeoStateItemChoice:
844 // The user has not chosen any item, so revert to neutral
845 // state.
846 state = drgeoStateNeutral;
847 // Fall through! This is really what is wanted here.
848 case drgeoStateNeutral:
849 // The mouse button is being pressed, check if there are items
850 // near the mouse.
851 list = drawable->figure->mouseSelection (where);
852 list->init_lire ();
853 if (list->nb_elem == 1)
854 {
855 // Only one item is selected, add it to the selection.
856 state = drgeoStateAnimated;
857 last = where;
858 handleChoice (drawable, (geometricObject *) list->lire (0));
859 }
860 else if (list->nb_elem > 1)
861 {
862 // Several items are selected at once, we must prompt the
863 // user for a choice. When the user is done with his
864 // choice the handleChoice method will be invoked.
865 state = drgeoStateItemChoice;
866 last = where;
867 drawable->chooseItem (list);
868 }
869 break;
870 default:
871 // If we get there, then there's a problem with the event
872 // handling code... XXX
873 break;
874 }
875 }
876 }
877 void
handleChoice(drgeoDrawableUI * drawable,geometricObject * item)878 drgeoAnimationDialogLess::handleChoice (drgeoDrawableUI * drawable,
879 geometricObject * item)
880 {
881 this->item = item;
882 state = drgeoStateAnimated;
883 animatedAbscissa = initialAbscissa = ((point * )item)->getAbscissa ();
884 timeoutTag =
885 gtk_timeout_add (100, (GtkFunction) timer_cb, (gpointer) this);
886 }
887
888 void
finish(drgeoDrawableUI * drawable)889 drgeoAnimationDialogLess::finish (drgeoDrawableUI * drawable)
890 {
891 reset ();
892 }
893
894 void
animate()895 drgeoAnimationDialogLess::animate ()
896 {
897 animatedAbscissa += step;
898 if (step > 0 && animatedAbscissa > 1.)
899 animatedAbscissa -= 1.;
900 if (step < 0 && animatedAbscissa < 0)
901 animatedAbscissa += 1.;
902 if (item)
903 {
904 ((point *) item)->setAbscissa (animatedAbscissa);
905 drawable->getFigure()->updateItems ();
906 drawable->refresh ();
907 }
908 }
909
910 void
reset()911 drgeoAnimationDialogLess::reset ()
912 {
913 if (timeoutTag)
914 gtk_timeout_remove (timeoutTag);
915 timeoutTag = 0;
916 if (item)
917 ((point *) item)->setAbscissa (initialAbscissa);
918 drawable->getFigure()->updateItems ();
919 drawable->refresh ();
920 itemUnderMouse = NULL;
921 }
922
923 void
setStep(gdouble aStep)924 drgeoAnimationDialogLess::setStep (gdouble aStep)
925 {
926 step = aStep;
927 }
928
929 // -----------------------------------------------------
930 // Delete Tool, used for object deletion.
931 // -----------------------------------------------------
932
933 void
934 drgeoDeleteTool::
handleChoice(drgeoDrawableUI * drawable,geometricObject * myItem)935 handleChoice (drgeoDrawableUI * drawable, geometricObject * myItem)
936 {
937 char *message;
938
939 // Forward this item to the macro builder.
940 if (drawable->figure && myItem != NULL)
941 {
942 // Hide the removed items just to show the consequence of the
943 // removal.
944 drawable->figure->hideRemovedItems (myItem);
945
946 // Ask the user if he wants to proceed with the item deletion.
947 if (myItem->getName ())
948 {
949 if (strlen (myItem->getName ()))
950 message = g_strdup_printf (_("Remove %s?"), myItem->getName ());
951 }
952 else
953 message = g_strdup (_("Remove selected item?"));
954 if (drawable->askOkCancel (message))
955 {
956 // Remove the item if the user wants it.
957 drawable->figure->removeItem (myItem);
958 }
959 g_free (message);
960 // Show again the list of items to be removed.
961 drawable->figure->showRemovedItems ();
962 drawable->figure->redraw (FALSE);
963 }
964 }
965
966
967
968
969
970
971 // -----------------------------------------------------
972 // Style Editor Tool, used to adjust colors, ...
973 // -----------------------------------------------------
974
975 void
initialize(drgeoDrawableUI * drawable)976 drgeoStyleTool::initialize (drgeoDrawableUI * drawable)
977 {
978 // First invoke the initialize() method of drgeoBuildTool
979 // super-class.
980 drgeoBuildTool::initialize (drawable);
981
982 dialog = drawable->createStyleDialog ();
983 }
984
985 // All the other methods are inherited from drgeoBuildTool. We only
986 // redefine the handleChoice() method, and of course the initialize()
987 // and finish().
988
989 void
990 drgeoStyleTool::
handleChoice(drgeoDrawableUI * drawable,geometricObject * item)991 handleChoice (drgeoDrawableUI * drawable, geometricObject * item)
992 {
993 drgeoPoint xxx;
994 // Forward this item to the style dialog.
995 if (dialog && item)
996 {
997 // Update the dialog that match the item newly selected.
998 drawable->figure->clearSelection ();
999 drawable->figure->addToSelection (xxx, item);
1000 dialog->edit (item);
1001 }
1002 }
1003
1004 void
finish(drgeoDrawableUI * drawable)1005 drgeoStyleTool::finish (drgeoDrawableUI * drawable)
1006 {
1007 // First invoke the initialize() method of drgeoBuildTool
1008 // super-class.
1009 drgeoBuildTool::finish (drawable);
1010
1011 // Remove the macro dialog that is used to adjust style.
1012 if (dialog)
1013 {
1014 delete dialog;
1015 }
1016 }
1017
1018 // -----------------------------------------------------
1019 // Property Editor Tool, used to adjust properties when
1020 // availables.
1021 // -----------------------------------------------------
1022
1023 void
initialize(drgeoDrawableUI * drawable)1024 drgeoPropertyTool::initialize (drgeoDrawableUI * drawable)
1025 {
1026 // First invoke the initialize() method of drgeoBuildTool
1027 // super-class.
1028 drgeoBuildTool::initialize (drawable);
1029
1030 dialog = drawable->createPropertyDialog ();
1031 }
1032
1033 void
1034 drgeoPropertyTool::
handleChoice(drgeoDrawableUI * drawable,geometricObject * item)1035 handleChoice (drgeoDrawableUI * drawable, geometricObject * item)
1036 {
1037 gint nb;
1038 drgeoPoint xxx;
1039 if (drawable->figure)
1040 {
1041 // Add the selected item to the current figure's selection.
1042 drawable->figure->clearSelection ();
1043 nb = drawable->figure->addToSelection (xxx, item);
1044 }
1045 // Forward this item to the style dialog.
1046 if (dialog && item && nb > 0)
1047 {
1048 // Update the dialog that match the item newly selected.
1049 dialog->edit (item);
1050 }
1051 }
1052
1053 void
finish(drgeoDrawableUI * drawable)1054 drgeoPropertyTool::finish (drgeoDrawableUI * drawable)
1055 {
1056 // First invoke the initialize() method of drgeoBuildTool
1057 // super-class.
1058 drgeoBuildTool::finish (drawable);
1059
1060 drawable->figure->clearSelection ();
1061 // Remove the macro dialog that is used to adjust style.
1062 if (dialog)
1063 {
1064 delete dialog;
1065 }
1066 }
1067