123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- /*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: Details at https://graphviz.org
- *************************************************************************/
- #include <limits.h>
- #include <stddef.h>
- #include <util/alloc.h>
- #include "selectionfuncs.h"
- #include "topviewfuncs.h"
- #include "smyrna_utils.h"
- static void select_node(Agraph_t* g,Agnode_t* obj,int reverse)
- {
- Agsym_t* sel_attr = GN_selected(g);
- if(!sel_attr)
- sel_attr = GN_selected(g) = agattr(g, AGNODE,"selected","0");
- if(!reverse)
- {
- agxset(obj,sel_attr,"1");
- ND_selected(obj) = 1;
- }
- else
- {
- if(ND_selected(obj)==1)
- {
- agxset(obj,sel_attr,"0");
- ND_selected(obj) = 0;
- ND_printLabel(obj) = 0;
- }
- else
- {
- agxset(obj,sel_attr,"1");
- ND_selected(obj) = 1;
- }
- }
- }
- static void select_edge(Agraph_t* g,Agedge_t* obj,int reverse)
- {
- Agsym_t* sel_attr = GE_selected(g);
- if (!sel_attr)
- sel_attr = GE_selected(g) = agattr(g, AGEDGE,"selected","0");
- if (!reverse)
- {
- agxset(obj,sel_attr,"1");
- ED_selected(obj) = 1;
- }
- else
- {
- if (ED_selected(obj) == 1)
- {
- agxset(obj,sel_attr,"0");
- ED_selected(obj) = 0;
- }
- else
- {
- agxset(obj,sel_attr,"1");
- ED_selected(obj) = 1;
- }
- }
- }
- static void pick_objects_in_rect(Agraph_t *g, float x1, float y1, float x2,
- float y2) {
- Agnode_t *v;
- Agedge_t *e;
- glCompPoint posT;
- glCompPoint posH;
- glCompPoint posN;
-
- for (v = agfstnode(g); v; v = agnxtnode(g, v))
- {
- if (view->Topview->sel.selectNodes) {
- posN = ND_A(v);
- if(!ND_visible(v))
- continue;
- if(is_point_in_rectangle(posN.x,posN.y,x1,y1,x2-x1,y2-y1) )
- select_node(g,v,0);
- }
- if (view->Topview->sel.selectEdges) {
- for (e = agfstout(g, v); e; e = agnxtout(g, e))
- {
- posT = ED_posTail(e);
- posH = ED_posHead(e);
- if(is_point_in_rectangle(posT.x,posT.y,x1,y1,x2-x1,y2-y1))
- if(is_point_in_rectangle(posH.x,posH.y,x1,y1,x2-x1,y2-y1))
- select_edge(g,e,0);
- }
- }
- }
- }
- static void* pick_object(Agraph_t* g,glCompPoint p)
- {
- Agnode_t *v;
- Agedge_t *e;
- glCompPoint posT;
- glCompPoint posH;
- glCompPoint posN;
- int defaultNodeShape;
- float dist = FLT_MAX;
- float nd; // node distance to point
- float ed; // edge distance to point
- float nodeSize=0;
- void *rv = NULL;
- defaultNodeShape=getAttrBool(g,g,"defaultnodeshape",0);
- if(defaultNodeShape==0)
- nodeSize=GetOGLDistance(view->nodeScale*view->Topview->fitin_zoom/view->zoom);
- for (v = agfstnode(g); v; v = agnxtnode(g, v))
- {
- if(!ND_visible(v))
- continue;
- posN = ND_A(v);
- if(defaultNodeShape==1)
- {
- nodeSize = ND_size(v);
- }
- nd=distBetweenPts(posN,p,nodeSize);
- if( nd < dist )
- {
- rv=v;dist=nd;
- }
- for (e = agfstout(g, v); e; e = agnxtout(g, e))
- {
- posT = ED_posTail(e);
- posH = ED_posHead(e);
- ed=point_to_lineseg_dist(p, posT,posH);
- if( ed < dist ) {rv=e;dist=ed;}
- }
- }
- return rv;
- }
- void pick_object_xyz(Agraph_t *g, topview *t, float x, float y, float z) {
- glCompPoint p;
- void* a;
- p.x=x;p.y=y;p.z=z;
- a=pick_object(g,p);
- if (!a)
- return;
- if(agobjkind(a)==AGNODE)
- {
- select_node(g,a,1);
- ND_printLabel((Agnode_t*)a) = 1;
- cacheSelectedNodes(g,t);
- }
- if(agobjkind(a)==AGEDGE)
- {
- select_edge(g,a,1);
- cacheSelectedEdges(g,t);
- }
- }
- void pick_objects_rect(Agraph_t* g)
- {
- float x1;
- float y1;
- float x2;
- float y2;
- if(view->mouse.GLfinalPos.x > view->mouse.GLinitPos.x)
- {
- x1=view->mouse.GLinitPos.x;
- x2=view->mouse.GLfinalPos.x;
- }
- else
- {
- x2=view->mouse.GLinitPos.x;
- x1=view->mouse.GLfinalPos.x;
- }
- if(view->mouse.GLfinalPos.y > view->mouse.GLinitPos.y)
- {
- y1=view->mouse.GLinitPos.y;
- y2=view->mouse.GLfinalPos.y;
- }
- else
- {
- y2=view->mouse.GLinitPos.y;
- y1=view->mouse.GLfinalPos.y;
- }
- pick_objects_in_rect(g,x1,y1,x2,y2);
- cacheSelectedNodes(g,view->Topview);
- cacheSelectedEdges(g,view->Topview);
- }
- void deselect_all(Agraph_t* g)
- {
- Agnode_t *v;
- Agedge_t *e;
- Agsym_t* nsel_attr = GN_selected(g);
- Agsym_t* esel_attr = GE_selected(g);
- if(!nsel_attr)
- nsel_attr = GN_selected(g) = agattr(g, AGNODE,"selected","0");
- if(!esel_attr)
- esel_attr = GE_selected(g) = agattr(g, AGEDGE,"selected","0");
- for (v = agfstnode(g); v; v = agnxtnode(g, v))
- {
- agxset(v,nsel_attr,"0");
- ND_selected(v) = 0;
- ND_printLabel(v) = 0;
- for (e = agfstout(g, v); e; e = agnxtout(g, e))
- {
- agxset(e,esel_attr,"0");
- ED_selected(e) = 0;
- }
- }
- cacheSelectedNodes(g,view->Topview);
- cacheSelectedEdges(g,view->Topview);
- }
- static int close_poly(glCompPoly_t *selPoly, glCompPoint pt) {
- /* int i=0; */
- const float EPS = GetOGLDistance(3.0f);
- if (glCompPoly_size(selPoly) < 2)
- return 0;
- if (glCompPoly_front(selPoly)->x - pt.x < EPS &&
- glCompPoly_front(selPoly)->y - pt.y < EPS)
- return 1;
- return 0;
- }
- static void select_polygon(Agraph_t *g, glCompPoly_t *selPoly) {
- Agnode_t *v;
- glCompPoint posN;
-
- for (v = agfstnode(g); v; v = agnxtnode(g, v))
- {
- posN = ND_A(v);
- if(point_in_polygon(selPoly,posN))
- select_node(g,v,0);
- }
- cacheSelectedNodes(g,view->Topview);
- }
- void add_selpoly(Agraph_t *g, glCompPoly_t *selPoly, glCompPoint pt) {
- if(!close_poly(selPoly,pt))
- {
- glCompPoly_append(selPoly, (glCompPoint){.x = pt.x, .y = pt.y});
- }
- else
- {
- select_polygon (g,selPoly);
- glCompPoly_free(selPoly);
- }
- }
|