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