1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3
4 /*************************************************************************
5 * Copyright (c) 2011 AT&T Intellectual Property
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 * Contributors: See CVS logs. Details at http://www.graphviz.org/
12 *************************************************************************/
13
14 #include "selectionfuncs.h"
15 #include "topviewfuncs.h"
16 #include "smyrna_utils.h"
17
select_node(Agraph_t * g,Agnode_t * obj,int reverse)18 static void select_node(Agraph_t* g,Agnode_t* obj,int reverse)
19 {
20 Agsym_t* sel_attr = GN_selected(g);
21
22 if(!sel_attr)
23 sel_attr = GN_selected(g) = agattr(g, AGNODE,"selected","0");
24 if(!reverse)
25 {
26 agxset(obj,sel_attr,"1");
27 ND_selected(obj) = 1;
28 }
29 else
30 {
31 if(ND_selected(obj)==1)
32 {
33 agxset(obj,sel_attr,"0");
34 ND_selected(obj) = 0;
35 ND_printLabel(obj) = 0;
36 }
37 else
38 {
39 agxset(obj,sel_attr,"1");
40 ND_selected(obj) = 1;
41 }
42
43 }
44
45
46 }
select_edge(Agraph_t * g,Agedge_t * obj,int reverse)47 static void select_edge(Agraph_t* g,Agedge_t* obj,int reverse)
48 {
49 Agsym_t* sel_attr = GE_selected(g);
50
51 if (!sel_attr)
52 sel_attr = GE_selected(g) = agattr(g, AGEDGE,"selected","0");
53 if (!reverse)
54 {
55 agxset(obj,sel_attr,"1");
56 ED_selected(obj) = 1;
57 }
58 else
59 {
60 if (ED_selected(obj) == 1)
61 {
62 agxset(obj,sel_attr,"0");
63 ED_selected(obj) = 0;
64 ED_printLabel(obj) = 0;
65 }
66 else
67 {
68 agxset(obj,sel_attr,"1");
69 ED_selected(obj) = 1;
70 }
71 }
72
73
74 }
75
76
pick_objects_in_rect(Agraph_t * g,GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)77 static void pick_objects_in_rect(Agraph_t* g,GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)
78 {
79 Agnode_t *v;
80 Agedge_t *e;
81 glCompPoint posT;
82 glCompPoint posH;
83 glCompPoint posN;
84
85 for (v = agfstnode(g); v; v = agnxtnode(g, v))
86 {
87 if(view->Topview->sel.selectNodes==1)
88 {
89 posN = ND_A(v);
90 if(!ND_visible(v))
91 continue;
92 if(is_point_in_rectangle(posN.x,posN.y,x1,y1,x2-x1,y2-y1) )
93 select_node(g,v,0);
94 }
95 if(view->Topview->sel.selectEdges==1) {
96 for (e = agfstout(g, v); e; e = agnxtout(g, e))
97 {
98 posT = ED_posTail(e);
99 posH = ED_posHead(e);
100 if(is_point_in_rectangle(posT.x,posT.y,x1,y1,x2-x1,y2-y1))
101 if(is_point_in_rectangle(posH.x,posH.y,x1,y1,x2-x1,y2-y1))
102 select_edge(g,e,0);
103 }
104 }
105 }
106 }
107
108
109
pick_object(Agraph_t * g,glCompPoint p)110 static void* pick_object(Agraph_t* g,glCompPoint p)
111 {
112 Agnode_t *v;
113 Agedge_t *e;
114 glCompPoint posT;
115 glCompPoint posH;
116 glCompPoint posN;
117 int defaultNodeShape;
118 float dist=999999999;
119 GLfloat nd; /*node distance to point*/
120 GLfloat ed; /*edge distance to point*/
121 GLfloat nodeSize=0;
122 void* rv=(void*)0;
123
124 defaultNodeShape=getAttrBool(g,g,"defaultnodeshape",0);
125
126 if(defaultNodeShape==0)
127 nodeSize=GetOGLDistance(view->nodeScale*view->Topview->fitin_zoom/view->zoom);
128
129 for (v = agfstnode(g); v; v = agnxtnode(g, v))
130 {
131 if(!ND_visible(v))
132 continue;
133 posN = ND_A(v);
134 if(defaultNodeShape==1)
135 {
136 nodeSize = ND_size(v);
137 }
138
139 nd=distBetweenPts(posN,p,nodeSize);
140 if( nd < dist )
141 {
142 rv=v;dist=nd;
143 }
144
145 for (e = agfstout(g, v); e; e = agnxtout(g, e))
146 {
147 posT = ED_posTail(e);
148 posH = ED_posHead(e);
149 ed=point_to_lineseg_dist(p, posT,posH);
150 if( ed < dist ) {rv=e;dist=ed;}
151 }
152 }
153 return rv;
154 }
155
pick_object_xyz(Agraph_t * g,topview * t,GLfloat x,GLfloat y,GLfloat z)156 void pick_object_xyz(Agraph_t* g,topview* t,GLfloat x,GLfloat y,GLfloat z)
157 {
158 glCompPoint p;
159 void* a;
160 p.x=x;p.y=y;p.z=z;
161 a=pick_object(g,p);
162 if (!a)
163 return;
164 if(agobjkind(a)==AGNODE)
165 {
166 select_node(g,a,1);
167 ND_printLabel((Agnode_t*)a) = 1;
168
169 cacheSelectedNodes(g,t);
170
171 }
172 if(agobjkind(a)==AGEDGE)
173 {
174 select_edge(g,a,1);
175 cacheSelectedEdges(g,t);
176 ED_printLabel((Agedge_t*)a) = 1;
177 }
178 }
pick_objects_rect(Agraph_t * g)179 void pick_objects_rect(Agraph_t* g)
180 {
181
182 GLfloat x1;
183 GLfloat y1;
184 GLfloat x2;
185 GLfloat y2;
186 if(view->mouse.GLfinalPos.x > view->mouse.GLinitPos.x)
187 {
188 x1=view->mouse.GLinitPos.x;
189 x2=view->mouse.GLfinalPos.x;
190 }
191 else
192 {
193 x2=view->mouse.GLinitPos.x;
194 x1=view->mouse.GLfinalPos.x;
195
196 }
197 if(view->mouse.GLfinalPos.y > view->mouse.GLinitPos.y)
198 {
199 y1=view->mouse.GLinitPos.y;
200 y2=view->mouse.GLfinalPos.y;
201 }
202 else
203 {
204 y2=view->mouse.GLinitPos.y;
205 y1=view->mouse.GLfinalPos.y;
206 }
207 pick_objects_in_rect(g,x1,y1,x2,y2);
208 cacheSelectedNodes(g,view->Topview);
209 cacheSelectedEdges(g,view->Topview);
210 }
211
212
213
deselect_all(Agraph_t * g)214 void deselect_all(Agraph_t* g)
215 {
216 Agnode_t *v;
217 Agedge_t *e;
218 Agsym_t* nsel_attr = GN_selected(g);
219 Agsym_t* esel_attr = GE_selected(g);
220 if(!nsel_attr)
221 nsel_attr = GN_selected(g) = agattr(g, AGNODE,"selected","0");
222 if(!esel_attr)
223 esel_attr = GE_selected(g) = agattr(g, AGEDGE,"selected","0");
224 for (v = agfstnode(g); v; v = agnxtnode(g, v))
225 {
226 agxset(v,nsel_attr,"0");
227 ND_selected(v) = 0;
228 ND_printLabel(v) = 0;
229
230 for (e = agfstout(g, v); e; e = agnxtout(g, e))
231 {
232 agxset(e,esel_attr,"0");
233 ED_selected(e) = 0;
234 ED_printLabel(e) = 0;
235 }
236 }
237 cacheSelectedNodes(g,view->Topview);
238 cacheSelectedEdges(g,view->Topview);
239 }
240
clear_selpoly(glCompPoly * sp)241 void clear_selpoly(glCompPoly* sp)
242 {
243 sp->pts=realloc(sp->pts,0);
244 sp->cnt=0;
245 }
close_poly(glCompPoly * selPoly,glCompPoint pt)246 static int close_poly(glCompPoly* selPoly,glCompPoint pt)
247 {
248 /* int i=0; */
249 float EPS=GetOGLDistance(3);
250 if (selPoly->cnt < 2)
251 return 0;
252 if(
253 ( (selPoly->pts[0].x-pt.x) < EPS) &&
254 ( (selPoly->pts[0].y-pt.y) < EPS))
255 return 1;
256 return 0;
257 }
258
259
select_polygon(Agraph_t * g,glCompPoly * selPoly)260 static void select_polygon (Agraph_t* g,glCompPoly* selPoly)
261 {
262 Agnode_t *v;
263 glCompPoint posN;
264
265 for (v = agfstnode(g); v; v = agnxtnode(g, v))
266 {
267 posN = ND_A(v);
268 if(point_in_polygon(selPoly,posN))
269 select_node(g,v,0);
270 }
271 cacheSelectedNodes(g,view->Topview);
272 }
273
274
add_selpoly(Agraph_t * g,glCompPoly * selPoly,glCompPoint pt)275 void add_selpoly(Agraph_t* g,glCompPoly* selPoly,glCompPoint pt)
276 {
277 if(!close_poly(selPoly,pt))
278 {
279 selPoly->cnt ++;
280 selPoly->pts=realloc(selPoly->pts,sizeof(glCompPoint)*selPoly->cnt);
281 selPoly->pts[selPoly->cnt-1].x=pt.x;
282 selPoly->pts[selPoly->cnt-1].y=pt.y;
283 selPoly->pts[selPoly->cnt-1].z=0;
284 }
285 else
286 {
287 select_polygon (g,selPoly);
288 clear_selpoly(selPoly);
289 }
290 }
291
292