Graphviz 13.1.0~dev.20250626.0830
Loading...
Searching...
No Matches
selectionfuncs.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <limits.h>
12#include <stddef.h>
13#include <util/alloc.h>
14#include "selectionfuncs.h"
15#include "topviewfuncs.h"
16#include "smyrna_utils.h"
17
18static 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_text(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}
47static 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_text(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 }
65 else
66 {
67 agxset(obj,sel_attr,"1");
68 ED_selected(obj) = 1;
69 }
70 }
71
72
73}
74
75static void pick_objects_in_rect(Agraph_t *g, float x1, float y1, float x2,
76 float y2) {
77 Agnode_t *v;
78 Agedge_t *e;
79 glCompPoint posT;
80 glCompPoint posH;
81 glCompPoint posN;
82
83 for (v = agfstnode(g); v; v = agnxtnode(g, v))
84 {
86 posN = ND_A(v);
87 if(!ND_visible(v))
88 continue;
89 if(is_point_in_rectangle(posN.x,posN.y,x1,y1,x2-x1,y2-y1) )
90 select_node(g,v,0);
91 }
93 for (e = agfstout(g, v); e; e = agnxtout(g, e))
94 {
95 posT = ED_posTail(e);
96 posH = ED_posHead(e);
97 if(is_point_in_rectangle(posT.x,posT.y,x1,y1,x2-x1,y2-y1))
98 if(is_point_in_rectangle(posH.x,posH.y,x1,y1,x2-x1,y2-y1))
99 select_edge(g,e,0);
100 }
101 }
102 }
103}
104
105
106
108{
109 double dist = DBL_MAX;
110 float nodeSize=0;
111 void *rv = NULL;
112
113 const int defaultNodeShape = getAttrBool(g, g, "defaultnodeshape", 0);
114
115 if(defaultNodeShape==0)
117
118 for (Agnode_t *v = agfstnode(g); v; v = agnxtnode(g, v)) {
119 if(!ND_visible(v))
120 continue;
121 const glCompPoint posN = ND_A(v);
122 if(defaultNodeShape==1)
123 {
124 nodeSize = ND_size(v);
125 }
126
127 // node distance to point
128 const float nd = distBetweenPts(posN , p, nodeSize);
129 if( nd < dist )
130 {
131 rv=v;dist=nd;
132 }
133
134 for (Agedge_t *e = agfstout(g, v); e; e = agnxtout(g, e)) {
135 const glCompPoint posT = ED_posTail(e);
136 const glCompPoint posH = ED_posHead(e);
137 const double ed = point_to_lineseg_dist(p, posT, posH);
138 if( ed < dist ) {rv=e;dist=ed;}
139 }
140 }
141 return rv;
142}
143
144void pick_object_xyz(Agraph_t *g, topview *t, float x, float y, float z) {
145 const glCompPoint p = {.x = x, .y = y, .z = z};
146 void *const a = pick_object(g, p);
147 if (!a)
148 return;
149 if(agobjkind(a)==AGNODE)
150 {
151 select_node(g,a,1);
152 ND_printLabel(a) = 1;
153
155
156 }
157 if(agobjkind(a)==AGEDGE)
158 {
159 select_edge(g,a,1);
161 }
162}
164{
165 float x1;
166 float y1;
167 float x2;
168 float y2;
170 {
171 x1=view->mouse.GLinitPos.x;
173 }
174 else
175 {
176 x2=view->mouse.GLinitPos.x;
178
179 }
181 {
182 y1=view->mouse.GLinitPos.y;
184 }
185 else
186 {
187 y2=view->mouse.GLinitPos.y;
189 }
190 pick_objects_in_rect(g,x1,y1,x2,y2);
193}
194
195
196
198{
199 Agnode_t *v;
200 Agedge_t *e;
201 Agsym_t* nsel_attr = GN_selected(g);
202 Agsym_t* esel_attr = GE_selected(g);
203 if(!nsel_attr)
204 nsel_attr = GN_selected(g) = agattr_text(g, AGNODE,"selected","0");
205 if(!esel_attr)
206 esel_attr = GE_selected(g) = agattr_text(g, AGEDGE,"selected","0");
207 for (v = agfstnode(g); v; v = agnxtnode(g, v))
208 {
209 agxset(v,nsel_attr,"0");
210 ND_selected(v) = 0;
211 ND_printLabel(v) = 0;
212
213 for (e = agfstout(g, v); e; e = agnxtout(g, e))
214 {
215 agxset(e,esel_attr,"0");
216 ED_selected(e) = 0;
217 }
218 }
221}
222
223static int close_poly(glCompPoly_t *selPoly, glCompPoint pt) {
224 /* int i=0; */
225 const float EPS = GetOGLDistance(3.0f);
226 if (glCompPoly_size(selPoly) < 2)
227 return 0;
228 if (glCompPoly_front(selPoly)->x - pt.x < EPS &&
229 glCompPoly_front(selPoly)->y - pt.y < EPS)
230 return 1;
231 return 0;
232}
233
234static void select_polygon(Agraph_t *g, glCompPoly_t *selPoly) {
235 Agnode_t *v;
236 glCompPoint posN;
237
238 for (v = agfstnode(g); v; v = agnxtnode(g, v))
239 {
240 posN = ND_A(v);
241 if(point_in_polygon(selPoly,posN))
242 select_node(g,v,0);
243 }
245}
246
247void add_selpoly(Agraph_t *g, glCompPoly_t *selPoly, glCompPoint pt) {
248 if(!close_poly(selPoly,pt))
249 {
250 glCompPoly_append(selPoly, (glCompPoint){.x = pt.x, .y = pt.y});
251 }
252 else
253 {
254 select_polygon (g,selPoly);
255 glCompPoly_free(selPoly);
256 }
257}
258
Memory allocation wrappers that exit on failure.
#define EPS
Definition emit.c:442
static double dist(int dim, double *x, double *y)
float GetOGLDistance(float l)
Definition glutils.c:47
float distBetweenPts(glCompPoint A, glCompPoint B, float R)
Definition glutils.c:346
int is_point_in_rectangle(float X, float Y, float RX, float RY, float RW, float RH)
Definition glutils.c:354
double point_to_lineseg_dist(glCompPoint p, glCompPoint a, glCompPoint b)
Definition glutils.c:162
node NULL
Definition grammar.y:181
Agsym_t * agattr_text(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up text attributes of a graph
Definition attr.c:348
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:536
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:26
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:41
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:48
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:41
int agobjkind(void *obj)
Definition obj.c:252
@ AGEDGE
Definition cgraph.h:207
@ AGNODE
Definition cgraph.h:207
static int z
void deselect_all(Agraph_t *g)
static void * pick_object(Agraph_t *g, glCompPoint p)
void add_selpoly(Agraph_t *g, glCompPoly_t *selPoly, glCompPoint pt)
static void pick_objects_in_rect(Agraph_t *g, float x1, float y1, float x2, float y2)
void pick_objects_rect(Agraph_t *g)
static void select_node(Agraph_t *g, Agnode_t *obj, int reverse)
static void select_edge(Agraph_t *g, Agedge_t *obj, int reverse)
static int close_poly(glCompPoly_t *selPoly, glCompPoint pt)
static void select_polygon(Agraph_t *g, glCompPoly_t *selPoly)
void pick_object_xyz(Agraph_t *g, topview *t, float x, float y, float z)
int getAttrBool(Agraph_t *g, void *obj, char *attr_name, int def)
int point_in_polygon(glCompPoly_t *selPoly, glCompPoint p)
ViewInfo * view
Definition viewport.c:37
#define ED_posHead(e)
Definition smyrnadefs.h:173
#define GN_selected(g)
Definition smyrnadefs.h:195
#define ED_posTail(e)
Definition smyrnadefs.h:172
#define ND_size(n)
Definition smyrnadefs.h:161
#define ND_printLabel(n)
Definition smyrnadefs.h:159
#define GE_selected(g)
Definition smyrnadefs.h:201
#define ED_selected(e)
Definition smyrnadefs.h:171
#define ND_selected(n)
Definition smyrnadefs.h:158
#define ND_A(n)
Definition smyrnadefs.h:160
#define ND_visible(n)
Definition smyrnadefs.h:157
graph or subgraph
Definition cgraph.h:424
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:651
topview * Topview
Definition smyrnadefs.h:309
float nodeScale
Definition smyrnadefs.h:339
float zoom
Definition smyrnadefs.h:254
glCompMouse mouse
Definition smyrnadefs.h:299
bool selectEdges
Definition smyrnadefs.h:212
bool selectNodes
Definition smyrnadefs.h:211
glCompPoint GLfinalPos
Definition glcompdefs.h:227
glCompPoint GLinitPos
Definition glcompdefs.h:226
float fitin_zoom
Definition smyrnadefs.h:233
selection sel
Definition smyrnadefs.h:239
void cacheSelectedEdges(Agraph_t *g, topview *t)
void cacheSelectedNodes(Agraph_t *g, topview *t)