Graphviz 14.1.2~dev.20260118.1035
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 "config.h"
12
13#include <limits.h>
14#include <stddef.h>
15#include <util/alloc.h>
16#include <util/list.h>
17#include "selectionfuncs.h"
18#include "topviewfuncs.h"
19#include "smyrna_utils.h"
20
21static void select_node(Agraph_t* g,Agnode_t* obj,int reverse)
22{
23 Agsym_t* sel_attr = GN_selected(g);
24
25 if(!sel_attr)
26 sel_attr = GN_selected(g) = agattr_text(g, AGNODE,"selected","0");
27 if(!reverse)
28 {
29 agxset(obj,sel_attr,"1");
30 ND_selected(obj) = 1;
31 }
32 else
33 {
34 if(ND_selected(obj)==1)
35 {
36 agxset(obj,sel_attr,"0");
37 ND_selected(obj) = 0;
38 ND_printLabel(obj) = 0;
39 }
40 else
41 {
42 agxset(obj,sel_attr,"1");
43 ND_selected(obj) = 1;
44 }
45
46 }
47
48
49}
50static void select_edge(Agraph_t* g,Agedge_t* obj,int reverse)
51{
52 Agsym_t* sel_attr = GE_selected(g);
53
54 if (!sel_attr)
55 sel_attr = GE_selected(g) = agattr_text(g, AGEDGE,"selected","0");
56 if (!reverse)
57 {
58 agxset(obj,sel_attr,"1");
59 ED_selected(obj) = 1;
60 }
61 else
62 {
63 if (ED_selected(obj) == 1)
64 {
65 agxset(obj,sel_attr,"0");
66 ED_selected(obj) = 0;
67 }
68 else
69 {
70 agxset(obj,sel_attr,"1");
71 ED_selected(obj) = 1;
72 }
73 }
74
75
76}
77
78static void pick_objects_in_rect(Agraph_t *g, float x1, float y1, float x2,
79 float y2) {
80 Agnode_t *v;
81 Agedge_t *e;
82 glCompPoint posT;
83 glCompPoint posH;
84 glCompPoint posN;
85
86 for (v = agfstnode(g); v; v = agnxtnode(g, v))
87 {
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 }
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
111{
112 double dist = DBL_MAX;
113 double nodeSize = 0;
114 void *rv = NULL;
115
116 const int defaultNodeShape = getAttrBool(g, g, "defaultnodeshape", 0);
117
118 if(defaultNodeShape==0)
120
121 for (Agnode_t *v = agfstnode(g); v; v = agnxtnode(g, v)) {
122 if(!ND_visible(v))
123 continue;
124 const glCompPoint posN = ND_A(v);
125 if(defaultNodeShape==1)
126 {
127 nodeSize = ND_size(v);
128 }
129
130 // node distance to point
131 const double nd = distBetweenPts(posN , p, nodeSize);
132 if( nd < dist )
133 {
134 rv=v;dist=nd;
135 }
136
137 for (Agedge_t *e = agfstout(g, v); e; e = agnxtout(g, e)) {
138 const glCompPoint posT = ED_posTail(e);
139 const glCompPoint posH = ED_posHead(e);
140 const double ed = point_to_lineseg_dist(p, posT, posH);
141 if( ed < dist ) {rv=e;dist=ed;}
142 }
143 }
144 return rv;
145}
146
147void pick_object_xyz(Agraph_t *g, topview *t, float x, float y, float z) {
148 const glCompPoint p = {.x = x, .y = y, .z = z};
149 void *const a = pick_object(g, p);
150 if (!a)
151 return;
152 if(agobjkind(a)==AGNODE)
153 {
154 select_node(g,a,1);
155 ND_printLabel(a) = 1;
156
158
159 }
160 if(agobjkind(a)==AGEDGE)
161 {
162 select_edge(g,a,1);
164 }
165}
167{
168 float x1;
169 float y1;
170 float x2;
171 float y2;
173 {
174 x1=view->mouse.GLinitPos.x;
176 }
177 else
178 {
179 x2=view->mouse.GLinitPos.x;
181
182 }
184 {
185 y1=view->mouse.GLinitPos.y;
187 }
188 else
189 {
190 y2=view->mouse.GLinitPos.y;
192 }
193 pick_objects_in_rect(g,x1,y1,x2,y2);
196}
197
198
199
201{
202 Agnode_t *v;
203 Agedge_t *e;
204 Agsym_t* nsel_attr = GN_selected(g);
205 Agsym_t* esel_attr = GE_selected(g);
206 if(!nsel_attr)
207 nsel_attr = GN_selected(g) = agattr_text(g, AGNODE,"selected","0");
208 if(!esel_attr)
209 esel_attr = GE_selected(g) = agattr_text(g, AGEDGE,"selected","0");
210 for (v = agfstnode(g); v; v = agnxtnode(g, v))
211 {
212 agxset(v,nsel_attr,"0");
213 ND_selected(v) = 0;
214 ND_printLabel(v) = 0;
215
216 for (e = agfstout(g, v); e; e = agnxtout(g, e))
217 {
218 agxset(e,esel_attr,"0");
219 ED_selected(e) = 0;
220 }
221 }
224}
225
226static int close_poly(glCompPoly_t *selPoly, glCompPoint pt) {
227 /* int i=0; */
228 const double EPS = GetOGLDistance(3.0);
229 if (LIST_SIZE(selPoly) < 2)
230 return 0;
231 if (LIST_FRONT(selPoly)->x - pt.x < EPS &&
232 LIST_FRONT(selPoly)->y - pt.y < EPS)
233 return 1;
234 return 0;
235}
236
237static void select_polygon(Agraph_t *g, glCompPoly_t *selPoly) {
238 Agnode_t *v;
239 glCompPoint posN;
240
241 for (v = agfstnode(g); v; v = agnxtnode(g, v))
242 {
243 posN = ND_A(v);
244 if(point_in_polygon(selPoly,posN))
245 select_node(g,v,0);
246 }
248}
249
250void add_selpoly(Agraph_t *g, glCompPoly_t *selPoly, glCompPoint pt) {
251 if(!close_poly(selPoly,pt))
252 {
253 LIST_APPEND(selPoly, ((glCompPoint){.x = pt.x, .y = pt.y}));
254 }
255 else
256 {
257 select_polygon (g,selPoly);
258 LIST_FREE(selPoly);
259 }
260}
261
Memory allocation wrappers that exit on failure.
#define EPS
Definition emit.c:451
static double dist(int dim, double *x, double *y)
double GetOGLDistance(double l)
Definition glutils.c:49
double distBetweenPts(glCompPoint A, glCompPoint B, double R)
Definition glutils.c:328
int is_point_in_rectangle(float X, float Y, float RX, float RY, float RW, float RH)
Definition glutils.c:336
double point_to_lineseg_dist(glCompPoint p, glCompPoint a, glCompPoint b)
Definition glutils.c:164
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:336
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:524
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:28
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:43
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:50
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:43
int agobjkind(void *obj)
Definition obj.c:254
@ AGEDGE
Definition cgraph.h:207
@ AGNODE
Definition cgraph.h:207
static int z
type-generic dynamically expanding list
#define LIST_SIZE(list)
Definition list.h:80
#define LIST_APPEND(list, item)
Definition list.h:120
#define LIST_FREE(list)
Definition list.h:370
#define LIST_FRONT(list)
Definition list.h:180
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:40
#define ED_posHead(e)
Definition smyrnadefs.h:169
#define GN_selected(g)
Definition smyrnadefs.h:191
#define ED_posTail(e)
Definition smyrnadefs.h:168
#define ND_size(n)
Definition smyrnadefs.h:157
#define ND_printLabel(n)
Definition smyrnadefs.h:155
#define GE_selected(g)
Definition smyrnadefs.h:197
#define ED_selected(e)
Definition smyrnadefs.h:167
#define ND_selected(n)
Definition smyrnadefs.h:154
#define ND_A(n)
Definition smyrnadefs.h:156
#define ND_visible(n)
Definition smyrnadefs.h:153
graph or subgraph
Definition cgraph.h:424
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:640
topview * Topview
Definition smyrnadefs.h:305
double zoom
Definition smyrnadefs.h:250
double nodeScale
Definition smyrnadefs.h:335
glCompMouse mouse
Definition smyrnadefs.h:295
bool selectEdges
Definition smyrnadefs.h:208
bool selectNodes
Definition smyrnadefs.h:207
glCompPoint GLfinalPos
Definition glcompdefs.h:227
glCompPoint GLinitPos
Definition glcompdefs.h:226
double fitin_zoom
Definition smyrnadefs.h:229
selection sel
Definition smyrnadefs.h:235
void cacheSelectedEdges(Agraph_t *g, topview *t)
void cacheSelectedNodes(Agraph_t *g, topview *t)