home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xfig / part08 / e_glue.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-27  |  10.0 KB  |  490 lines

  1. /*
  2.  * FIG : Facility for Interactive Generation of figures
  3.  * Copyright (c) 1985 by Supoj Sutanthavibul
  4.  *
  5.  * "Permission to use, copy, modify, distribute, and sell this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both the copyright
  8.  * notice and this permission notice appear in supporting documentation. 
  9.  * No representations are made about the suitability of this software for 
  10.  * any purpose.  It is provided "as is" without express or implied warranty."
  11.  */
  12.  
  13. #include "fig.h"
  14. #include "resources.h"
  15. #include "mode.h"
  16. #include "object.h"
  17. #include "paintop.h"
  18. #include "u_create.h"
  19. #include "u_draw.h"
  20. #include "u_elastic.h"
  21. #include "u_list.h"
  22. #include "u_search.h"
  23. #include "u_undo.h"
  24. #include "w_canvas.h"
  25. #include "w_mousefun.h"
  26.  
  27. static        create_compoundobject(), cancel_tag_region(),
  28.         init_tag_region(), tag_region(), tag_object();
  29. static        get_arc(), sel_arc();
  30. static        get_compound(), sel_compound();
  31. static        get_ellipse(), sel_ellipse();
  32. static        get_line(), sel_line();
  33. static        get_spline(), sel_spline();
  34. static        get_text(), sel_text();
  35.  
  36. compound_selected()
  37. {
  38.     set_mousefun("tag object", "tag region", "compound tagged");
  39.     canvas_kbd_proc = null_proc;
  40.     canvas_locmove_proc = null_proc;
  41.     init_searchproc_left(tag_object);
  42.     canvas_leftbut_proc = object_search_left;
  43.     canvas_middlebut_proc = init_tag_region;
  44.     canvas_rightbut_proc = create_compoundobject;
  45.     set_cursor(pick9_cursor);
  46.     reset_action_on();
  47. }
  48.  
  49. static
  50. tag_object(p, type, x, y, px, py)
  51.     char           *p;
  52.     int             type;
  53.     int             x, y;
  54.     int             px, py;
  55. {
  56.     switch (type) {
  57.     case O_COMPOUND:
  58.         cur_c = (F_compound *) p;
  59.         toggle_compoundhighlight(cur_c);
  60.     cur_c->tagged = 1 - cur_c->tagged;
  61.         break;
  62.     case O_POLYLINE:
  63.         cur_l = (F_line *) p;
  64.         toggle_linehighlight(cur_l);
  65.     cur_l->tagged = 1 - cur_l->tagged;
  66.         break;
  67.     case O_TEXT:
  68.         cur_t = (F_text *) p;
  69.         toggle_texthighlight(cur_t);
  70.     cur_t->tagged = 1 - cur_t->tagged;
  71.         break;
  72.     case O_ELLIPSE:
  73.         cur_e = (F_ellipse *) p;
  74.         toggle_ellipsehighlight(cur_e);
  75.     cur_e->tagged = 1 - cur_e->tagged;
  76.         break;
  77.     case O_ARC:
  78.         cur_a = (F_arc *) p;
  79.         toggle_archighlight(cur_a);
  80.     cur_a->tagged = 1 - cur_a->tagged;
  81.         break;
  82.     case O_SPLINE:
  83.         cur_s = (F_spline *) p;
  84.         toggle_splinehighlight(cur_s);
  85.     cur_s->tagged = 1 - cur_s->tagged;
  86.         break;
  87.     default:
  88.         return;
  89.     }
  90. }
  91.  
  92. static
  93. init_tag_region(x, y)
  94.     int            x, y;
  95. {
  96.     init_box_drawing(x, y);
  97.     set_mousefun("", "final corner", "cancel");
  98.     draw_mousefun_canvas();
  99.     canvas_leftbut_proc = null_proc;
  100.     canvas_middlebut_proc = tag_region;
  101.     canvas_rightbut_proc = cancel_tag_region;
  102. }
  103.  
  104. static
  105. cancel_tag_region()
  106. {
  107.     elastic_box(fix_x, fix_y, cur_x, cur_y);
  108.     compound_selected();
  109.     draw_mousefun_canvas();
  110. }
  111.  
  112. static
  113. tag_region(x, y)
  114.     int            x, y;
  115. {
  116.     int            xmin, ymin, xmax, ymax;
  117.  
  118.     elastic_box(fix_x, fix_y, cur_x, cur_y);
  119.     xmin = min2(fix_x, x);
  120.     ymin = min2(fix_y, y);
  121.     xmax = max2(fix_x, x);
  122.     ymax = max2(fix_y, y);
  123.     tag_obj_in_region(xmin, ymin, xmax, ymax);
  124.     compound_selected();
  125.     draw_mousefun_canvas();
  126. }
  127.  
  128. static
  129. create_compoundobject(x, y)
  130.     int            x, y;
  131. {
  132.     F_compound       *c;
  133.  
  134.     if ((c = create_compound()) == NULL)
  135.     return;
  136.  
  137.     if (compose_compound(c) == 0) {
  138.     free((char *) c);
  139.     compound_selected();
  140.     draw_mousefun_canvas();
  141.     put_msg("Empty compound, ignored");
  142.     return;
  143.     }
  144.     /*
  145.      * Make the bounding box exactly match the dimensions of the compound.
  146.      */
  147.     compound_bound(c, &c->nwcorner.x, &c->nwcorner.y,
  148.            &c->secorner.x, &c->secorner.y);
  149.  
  150.     c->next = NULL;
  151.     clean_up();
  152.     set_action(F_GLUE);
  153.     toggle_markers_in_compound(c);
  154.     list_add_compound(&objects.compounds, c);
  155.     mask_toggle_compoundmarker(c);
  156.     set_latestcompound(c);
  157.     set_modifiedflag();
  158.     compound_selected();
  159.     draw_mousefun_canvas();
  160. }
  161.  
  162. tag_obj_in_region(xmin, ymin, xmax, ymax)
  163.     int            xmin, ymin, xmax, ymax;
  164. {
  165.     sel_ellipse(xmin, ymin, xmax, ymax);
  166.     sel_line(xmin, ymin, xmax, ymax);
  167.     sel_spline(xmin, ymin, xmax, ymax);
  168.     sel_text(xmin, ymin, xmax, ymax);
  169.     sel_arc(xmin, ymin, xmax, ymax);
  170.     sel_compound(xmin, ymin, xmax, ymax);
  171. }
  172.  
  173.  
  174. compose_compound(c)
  175.     F_compound       *c;
  176. {
  177.     c->ellipses = NULL;
  178.     c->lines = NULL;
  179.     c->texts = NULL;
  180.     c->splines = NULL;
  181.     c->arcs = NULL;
  182.     c->compounds = NULL;
  183.     get_ellipse(&c->ellipses);
  184.     get_line(&c->lines);
  185.     get_spline(&c->splines);
  186.     get_text(&c->texts);
  187.     get_arc(&c->arcs);
  188.     get_compound(&c->compounds);
  189.     if (c->ellipses != NULL)
  190.     return (1);
  191.     if (c->splines != NULL)
  192.     return (1);
  193.     if (c->lines != NULL)
  194.     return (1);
  195.     if (c->texts != NULL)
  196.     return (1);
  197.     if (c->arcs != NULL)
  198.     return (1);
  199.     if (c->compounds != NULL)
  200.     return (1);
  201.     return (0);
  202. }
  203.  
  204. static
  205. sel_ellipse(xmin, ymin, xmax, ymax)
  206.     int            xmin, ymin, xmax, ymax;
  207. {
  208.     F_ellipse       *e;
  209.  
  210.     for (e = objects.ellipses; e != NULL; e = e->next) {
  211.     if (xmin > e->center.x - e->radiuses.x)
  212.         continue;
  213.     if (xmax < e->center.x + e->radiuses.x)
  214.         continue;
  215.     if (ymin > e->center.y - e->radiuses.y)
  216.         continue;
  217.     if (ymax < e->center.y + e->radiuses.y)
  218.         continue;
  219.     e->tagged = 1 - e->tagged;
  220.     toggle_ellipsehighlight(e);
  221.     }
  222. }
  223.  
  224. static
  225. get_ellipse(list)
  226.     F_ellipse      **list;
  227. {
  228.     F_ellipse       *e, *ee, *ellipse;
  229.  
  230.     for (e = objects.ellipses; e != NULL;) {
  231.     if (!e->tagged) {
  232.         ee = e;
  233.         e = e->next;
  234.         continue;
  235.     }
  236.     if (*list == NULL)
  237.         *list = e;
  238.     else
  239.         ellipse->next = e;
  240.     ellipse = e;
  241.     if (e == objects.ellipses)
  242.         e = objects.ellipses = objects.ellipses->next;
  243.     else {
  244.         e = ee->next = e->next;
  245.     }
  246.     ellipse->next = NULL;
  247.     }
  248. }
  249.  
  250. static
  251. sel_arc(xmin, ymin, xmax, ymax)
  252.     int            xmin, ymin, xmax, ymax;
  253. {
  254.     F_arc       *a;
  255.     int            urx, ury, llx, lly;
  256.  
  257.     for (a = objects.arcs; a != NULL; a = a->next) {
  258.     arc_bound(a, &llx, &lly, &urx, &ury);
  259.     if (xmin > llx)
  260.         continue;
  261.     if (xmax < urx)
  262.         continue;
  263.     if (ymin > lly)
  264.         continue;
  265.     if (ymax < ury)
  266.         continue;
  267.     a->tagged = 1 - a->tagged;
  268.     toggle_archighlight(a);
  269.     }
  270. }
  271.  
  272. static
  273. get_arc(list)
  274.     F_arc      **list;
  275. {
  276.     F_arc       *a, *arc, *aa;
  277.  
  278.     for (a = objects.arcs; a != NULL;) {
  279.     if (!a->tagged) {
  280.         aa = a;
  281.         a = a->next;
  282.         continue;
  283.     }
  284.     if (*list == NULL)
  285.         *list = a;
  286.     else
  287.         arc->next = a;
  288.     arc = a;
  289.     if (a == objects.arcs)
  290.         a = objects.arcs = objects.arcs->next;
  291.     else
  292.         a = aa->next = a->next;
  293.     arc->next = NULL;
  294.     }
  295. }
  296.  
  297. static
  298. sel_line(xmin, ymin, xmax, ymax)
  299.     int            xmin, ymin, xmax, ymax;
  300. {
  301.     F_line       *l;
  302.     F_point       *p;
  303.     int            inbound;
  304.  
  305.     for (l = objects.lines; l != NULL; l = l->next) {
  306.     for (inbound = 1, p = l->points; p != NULL && inbound;
  307.          p = p->next) {
  308.         inbound = 0;
  309.         if (xmin > p->x)
  310.         continue;
  311.         if (xmax < p->x)
  312.         continue;
  313.         if (ymin > p->y)
  314.         continue;
  315.         if (ymax < p->y)
  316.         continue;
  317.         inbound = 1;
  318.     }
  319.     if (!inbound)
  320.         continue;
  321.     l->tagged = 1 - l->tagged;
  322.     toggle_linehighlight(l);
  323.     }
  324. }
  325.  
  326. static
  327. get_line(list)
  328.     F_line      **list;
  329. {
  330.     F_line       *line, *l, *ll;
  331.  
  332.     for (l = objects.lines; l != NULL;) {
  333.     if (!l->tagged) {
  334.         ll = l;
  335.         l = l->next;
  336.         continue;
  337.     }
  338.     if (*list == NULL)
  339.         *list = l;
  340.     else
  341.         line->next = l;
  342.     line = l;
  343.     if (l == objects.lines)
  344.         l = objects.lines = objects.lines->next;
  345.     else
  346.         l = ll->next = l->next;
  347.     line->next = NULL;
  348.     }
  349. }
  350.  
  351. static
  352. sel_spline(xmin, ymin, xmax, ymax)
  353.     int            xmin, ymin, xmax, ymax;
  354. {
  355.     F_spline       *s;
  356.     int            urx, ury, llx, lly;
  357.  
  358.     for (s = objects.splines; s != NULL; s = s->next) {
  359.     spline_bound(s, &llx, &lly, &urx, &ury);
  360.     if (xmin > llx)
  361.         continue;
  362.     if (xmax < urx)
  363.         continue;
  364.     if (ymin > lly)
  365.         continue;
  366.     if (ymax < ury)
  367.         continue;
  368.     s->tagged = 1 - s->tagged;
  369.     toggle_splinehighlight(s);
  370.     }
  371. }
  372.  
  373. static
  374. get_spline(list)
  375.     F_spline      **list;
  376. {
  377.     F_spline       *spline, *s, *ss;
  378.  
  379.     for (s = objects.splines; s != NULL;) {
  380.     if (!s->tagged) {
  381.         ss = s;
  382.         s = s->next;
  383.         continue;
  384.     }
  385.     if (*list == NULL)
  386.         *list = s;
  387.     else
  388.         spline->next = s;
  389.     spline = s;
  390.     if (s == objects.splines)
  391.         s = objects.splines = objects.splines->next;
  392.     else
  393.         s = ss->next = s->next;
  394.     spline->next = NULL;
  395.     }
  396. }
  397.  
  398. static
  399. sel_text(xmin, ymin, xmax, ymax)
  400.     int            xmin, ymin, xmax, ymax;
  401. {
  402.     F_text       *t;
  403.     int            txmin, txmax, tymin, tymax;
  404.     int            dum;
  405.  
  406.     for (t = objects.texts; t != NULL; t = t->next) {
  407.     if (appres.textoutline) {
  408.         text_bound_actual(t, t->angle, &txmin, &tymin, &txmax, &tymax,
  409.                 &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum);
  410.     } else {
  411.         text_bound(t, &txmin, &tymin, &txmax, &tymax);
  412.     }
  413.     if (xmin > txmin || xmax < txmax ||
  414.         ymin > tymin || ymax < tymax)
  415.         continue;
  416.     t->tagged = 1 - t->tagged;
  417.     toggle_texthighlight(t);
  418.     }
  419. }
  420.  
  421. static
  422. get_text(list)
  423.     F_text      **list;
  424. {
  425.     F_text       *text, *t, *tt;
  426.  
  427.     for (t = objects.texts; t != NULL;) {
  428.     if (!t->tagged) {
  429.         tt = t;
  430.         t = t->next;
  431.         continue;
  432.     }
  433.     if (*list == NULL)
  434.         *list = t;
  435.     else
  436.         text->next = t;
  437.     text = t;
  438.     if (t == objects.texts)
  439.         t = objects.texts = objects.texts->next;
  440.     else
  441.         t = tt->next = t->next;
  442.     text->next = NULL;
  443.     }
  444. }
  445.  
  446. static
  447. sel_compound(xmin, ymin, xmax, ymax)
  448.     int            xmin, ymin, xmax, ymax;
  449. {
  450.     F_compound       *c;
  451.  
  452.     for (c = objects.compounds; c != NULL; c = c->next) {
  453.     if (xmin > c->nwcorner.x)
  454.         continue;
  455.     if (xmax < c->secorner.x)
  456.         continue;
  457.     if (ymin > c->nwcorner.y)
  458.         continue;
  459.     if (ymax < c->secorner.y)
  460.         continue;
  461.     c->tagged = 1 - c->tagged;
  462.     toggle_compoundhighlight(c);
  463.     }
  464. }
  465.  
  466. static
  467. get_compound(list)
  468.     F_compound      **list;
  469. {
  470.     F_compound       *compd, *c, *cc;
  471.  
  472.     for (c = objects.compounds; c != NULL;) {
  473.     if (!c->tagged) {
  474.         cc = c;
  475.         c = c->next;
  476.         continue;
  477.     }
  478.     if (*list == NULL)
  479.         *list = c;
  480.     else
  481.         compd->next = c;
  482.     compd = c;
  483.     if (c == objects.compounds)
  484.         c = objects.compounds = objects.compounds->next;
  485.     else
  486.         c = cc->next = c->next;
  487.     compd->next = NULL;
  488.     }
  489. }
  490.