NEURON
rect.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #if HAVE_IV // to end of file
3 
4 #include <InterViews/glyph.h>
5 #include <InterViews/session.h>
6 #include <InterViews/style.h>
7 #include <InterViews/canvas.h>
8 #include <InterViews/color.h>
9 #include <InterViews/hit.h>
10 #include <InterViews/brush.h>
11 #include <InterViews/transformer.h>
12 #include <IV-look/kit.h>
13 #include <OS/string.h>
14 #include "scenevie.h"
15 #include "rect.h"
16 #include "mymath.h"
17 #include "idraw.h"
18 #include <stdio.h>
19 
20 Appear::Appear(const Color* c, const Brush* b) {
21  color_ = NULL;
22  brush_ = NULL;
23  color(c);
24  brush(b);
25 }
29 }
30 
31 void Appear::color(const Color* c) {
32  const Color* c1;
33  if (c) {
34  c1 = c;
35  } else {
36  c1 = default_color();
37  }
38  Resource::ref(c1);
40  color_ = c1;
41 }
42 void Appear::brush(const Brush* b) {
43  const Brush* b1;
44  if (b) {
45  b1 = b;
46  } else {
47  b1 = default_brush();
48  }
49  Resource::ref(b1);
51  brush_ = b1;
52 }
53 
54 const Color* Appear::dc_;
55 const Brush* Appear::db_;
56 
59 }
60 
62  if (!db_) {
63  Style* s = Session::instance()->style();
64  Coord b = 0;
65  s->find_attribute("default_brush", b);
66  db_ = new Brush(b);
68  }
69  return db_;
70 }
71 
72 // Rect
73 Rect::Rect(Coord l, Coord b, Coord w, Coord h, const Color* c, const Brush* br)
74  : Appear(c, br) {
75  left(l);
76  bottom(b);
77  width(w);
78  height(h);
79 }
80 
81 void Rect::request(Requisition& req) const {
82  Requirement rx(width(), 0, 0, left() / width());
83  Requirement ry(height(), 0, 0, bottom() / height());
84  req.require_x(rx);
85  req.require_y(ry);
86 }
87 
88 void Rect::allocate(Canvas* c, const Allocation& a, Extension& ext) {
89  ext.set(c, a);
90  MyMath::extend(ext, 1);
91 }
92 
93 void Rect::draw(Canvas* c, const Allocation& a) const {
94  Coord x = a.x();
95  Coord y = a.y();
96  c->rect(x + left(), y + bottom(), x + right(), y + top(), color(), brush());
97 }
98 
99 void Rect::pick(Canvas*, const Allocation&, int depth, Hit& h) {
100  Coord x = h.left();
101  Coord y = h.bottom();
102  if (MyMath::inside(x, y, left(), right(), bottom(), top())) {
103  h.target(depth, this, 0);
104  }
105 }
106 
107 // Line
108 Line::Line(Coord dx, Coord dy, const Color* c, const Brush* b)
109  : Appear(c, b) {
110  dx_ = dx;
111  dy_ = dy;
112  x_ = 0;
113  y_ = 0;
114 }
115 Line::Line(Coord dx, Coord dy, float xa, float ya, const Color* c, const Brush* b)
116  : Appear(c, b) {
117  dx_ = dx;
118  dy_ = dy;
119  x_ = -dx_ * xa;
120  y_ = -dy_ * ya;
121 }
122 Line::~Line() {}
123 
124 void Line::request(Requisition& req) const {
125  Coord dx, dy;
126  dx = (dx_) ? dx_ : 1e-5;
127  dy = (dy_) ? dy_ : 1e-5;
128  Requirement rx(dx, 0, 0, x_ / dx);
129  Requirement ry(dy, 0, 0, y_ / dy);
130  req.require_x(rx);
131  req.require_y(ry);
132 }
133 
134 void Line::allocate(Canvas* c, const Allocation& a, Extension& ext) {
135  ext.set(c, a);
136  MyMath::extend(ext, brush()->width() / 2 + 1);
137 }
138 
139 #if 0
140 void Line::draw(Canvas* c, const Allocation& a) const {
141  Coord x = a.x() + x_;
142  Coord y = a.y() + y_;
143 //printf("line %g %g %g %g\n", x, y, dx_, dy_);
144  c->line(x, y, x + dx_, y + dy_, color(), brush());
145  IfIdraw(line(c, x, y, x + dx_, y + dy_, color(), brush()));
146 }
147 #else
148 void Line::draw(Canvas* c, const Allocation& a) const {
149  Coord x = a.x() + x_;
150  Coord y = a.y() + y_;
151  // printf("line %g %g %g %g\n", x, y, dx_, dy_);
152 
153  c->new_path();
154  c->move_to(x, y);
155  c->line_to(x + dx_, y + dy_);
156 
157  // transform the line to get thickness right on printer
159  IfIdraw(line(c, x, y, x + dx_, y + dy_, color(), brush()));
160 }
161 #endif
162 
163 void Line::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
164  Coord l = a.x() + x_, b = a.y() + y_, r = a.x() + x_ + dx_, t = a.y() + y_ + dy_;
165  Coord x = h.left();
166  Coord y = h.bottom();
167  if (MyMath::inside(x, y, l, b, r, t)) {
168  float epsilon = 5;
169  const Transformer& tr = c->transformer();
170  tr.transform(x, y);
171  tr.transform(l, b);
172  tr.transform(r, t);
173  if (MyMath::near_line(x, y, l, b, r, t, epsilon)) {
174  h.target(depth, this, 0);
175  }
176  }
177 }
178 
179 // Circle
180 Circle::Circle(float radius, bool filled, const Color* c, const Brush* b)
181  : Appear(c, b) {
182  radius_ = radius;
183  filled_ = filled;
184 }
185 
186 Circle::~Circle() {}
187 
188 void Circle::request(Requisition& req) const {
189  Coord w = brush()->width();
190  Coord diameter = radius_ + radius_ + w + w;
191  Requirement rx(diameter, 0, 0, 0.5);
192  Requirement ry(diameter, 0, 0, 0.5);
193  req.require(Dimension_X, rx);
194  req.require(Dimension_Y, ry);
195 }
196 
197 void Circle::allocate(Canvas* c, const Allocation& a, Extension& ext) {
198  ext.merge(c, a);
199  MyMath::extend(ext, brush()->width() / 2 + 1);
200 }
201 
202 void Circle::draw(Canvas* c, const Allocation& a) const {
203  const Coord r = radius_, x = a.x(), y = a.y();
204  const Coord p0 = 1.00000000 * r;
205  const Coord p1 = 0.89657547 * r; // cos 30 * sqrt(1 + tan 15 * tan 15)
206  const Coord p2 = 0.70710678 * r; // cos 45
207  const Coord p3 = 0.51763809 * r; // cos 60 * sqrt(1 + tan 15 * tan 15)
208  const Coord p4 = 0.26794919 * r; // tan 15
209  c->new_path();
210  c->move_to(x + p0, y);
211  c->curve_to(x + p2, y + p2, x + p0, y + p4, x + p1, y + p3);
212  c->curve_to(x, y + p0, x + p3, y + p1, x + p4, y + p0);
213  c->curve_to(x - p2, y + p2, x - p4, y + p0, x - p3, y + p1);
214  c->curve_to(x - p0, y, x - p1, y + p3, x - p0, y + p4);
215  c->curve_to(x - p2, y - p2, x - p0, y - p4, x - p1, y - p3);
216  c->curve_to(x, y - p0, x - p3, y - p1, x - p4, y - p0);
217  c->curve_to(x + p2, y - p2, x + p4, y - p0, x + p3, y - p1);
218  c->curve_to(x + p0, y, x + p1, y - p3, x + p0, y - p4);
219  c->close_path();
220  if (filled_) {
221  c->fill(color());
222  } else {
223  c->stroke(color(), brush());
224  }
225  IfIdraw(ellipse(c, x, y, r, r, color(), brush(), filled_));
226 }
227 
228 
229 // Rectangle
230 Rectangle::Rectangle(float height, float width, bool filled, const Color* c, const Brush* b)
231  : Appear(c, b) {
232  height_ = height;
233  width_ = width;
234  filled_ = filled;
235 }
236 
238 
239 void Rectangle::request(Requisition& req) const {
240  Coord w = brush()->width();
241  Requirement rx(width_ + w + w, 0, 0, 0.5);
242  Requirement ry(height_ + w + w, 0, 0, 0.5);
243  req.require(Dimension_X, rx);
244  req.require(Dimension_Y, ry);
245 }
246 
247 void Rectangle::allocate(Canvas* c, const Allocation& a, Extension& ext) {
248  ext.merge(c, a);
249  MyMath::extend(ext, brush()->width() / 2 + 1);
250 }
251 
252 void Rectangle::draw(Canvas* c, const Allocation& a) const {
253  const Coord dx = width_ / 2, dy = height_ / 2, x = a.x(), y = a.y();
254 
255  if (filled_) {
256  c->fill_rect(x - dx, y - dy, x + dx, y + dy, color());
257  } else {
258  c->rect(x - dx, y - dy, x + dx, y + dy, color(), brush());
259  }
260  IfIdraw(rect(c, x - dx, y - dy, x + dx, y + dy, color(), brush(), filled_));
261 }
262 
263 
264 // Triangle
265 Triangle::Triangle(float side, bool filled, const Color* c, const Brush* b)
266  : Appear(c, b) {
267  side_ = side / 2;
268  filled_ = filled;
269 }
270 
272 
273 void Triangle::request(Requisition& req) const {
274  Coord w = brush()->width();
275  Requirement rx(side_ + side_ + w + w, 0, 0, 0.5);
276  Requirement ry((side_ + side_) * 1.1547 + w + w, 0, 0, 0.5);
277  req.require(Dimension_X, rx);
278  req.require(Dimension_Y, ry);
279 }
280 
281 void Triangle::allocate(Canvas* c, const Allocation& a, Extension& ext) {
282  ext.merge(c, a);
283  MyMath::extend(ext, brush()->width() / 2 + 1);
284 }
285 
286 void Triangle::draw(Canvas* c, const Allocation& a) const {
287  const Coord x = a.x(), y = a.y();
288  const Coord radius = 1.1547 * side_;
289 
290  c->new_path();
291  c->move_to(x, y + radius);
292  c->line_to(x + side_, y - radius);
293  c->line_to(x - side_, y - radius);
294  c->close_path();
295  if (filled_) {
296  c->fill(color());
297  } else {
298  c->stroke(color(), brush());
299  }
300 
301  Coord* xList = new Coord[4];
302  Coord* yList = new Coord[4];
303 
304  xList[0] = x;
305  xList[1] = x + side_;
306  xList[2] = x - side_;
307  xList[3] = x;
308 
309  yList[0] = y + radius;
310  yList[1] = y - radius;
311  yList[2] = y - radius;
312  yList[3] = y + radius;
313 
314  IfIdraw(polygon(c, 3, xList, yList, color(), brush(), filled_));
315 
316  delete[] xList;
317  delete[] yList;
318 }
319 
320 
321 #endif
#define Color
Definition: _defines.h:72
#define Transformer
Definition: _defines.h:313
#define Canvas
Definition: _defines.h:63
#define Style
Definition: _defines.h:278
#define Coord
Definition: _defines.h:17
#define Brush
Definition: _defines.h:57
#define Hit
Definition: _defines.h:145
Coord x() const
Definition: geometry.h:286
Coord y() const
Definition: geometry.h:287
Definition: rect.h:14
const Color * color_
Definition: rect.h:32
virtual ~Appear()
const Color * color() const
Definition: rect.h:20
static const Color * default_color()
const Brush * brush_
Definition: rect.h:33
Appear(const Color *color=NULL, const Brush *brush=NULL)
static const Brush * db_
Definition: rect.h:35
static const Color * dc_
Definition: rect.h:34
static const Brush * default_brush()
const Brush * brush() const
Definition: rect.h:24
Circle(float radius, bool filled=false, const Color *color=NULL, const Brush *brush=NULL)
virtual void draw(Canvas *, const Allocation &) const
virtual void request(Requisition &) const
virtual void allocate(Canvas *, const Allocation &, Extension &)
float radius_
Definition: rect.h:91
bool filled_
Definition: rect.h:92
virtual ~Circle()
void merge(const Extension &)
void set(Canvas *, const Allocation &)
virtual void request(Requisition &) const
Coord dx_
Definition: rect.h:77
float x_
Definition: rect.h:78
virtual ~Line()
virtual void allocate(Canvas *, const Allocation &, Extension &)
Line(Coord dx, Coord dy, const Color *color=NULL, const Brush *brush=NULL)
virtual void draw(Canvas *, const Allocation &) const
Coord dy_
Definition: rect.h:77
float y_
Definition: rect.h:78
virtual void pick(Canvas *, const Allocation &, int depth, Hit &)
static bool near_line(Coord x, Coord y, Coord x1, Coord y1, Coord x2, Coord y2, float epsilon)
Definition: mymath.cpp:110
static void extend(Extension &, Coord)
Definition: mymath.h:79
static bool inside(Coord x, Coord min, Coord max)
Definition: mymath.h:91
Coord bottom() const
Definition: rect.h:134
Rect(Coord left, Coord bottom, Coord width, Coord height, const Color *c=NULL, const Brush *b=NULL)
Coord right() const
Definition: rect.h:131
virtual void allocate(Canvas *, const Allocation &, Extension &)
virtual void pick(Canvas *, const Allocation &, int depth, Hit &)
virtual void request(Requisition &) const
Coord height() const
Definition: rect.h:143
Coord width() const
Definition: rect.h:140
Coord top() const
Definition: rect.h:137
Coord left() const
Definition: rect.h:128
virtual void draw(Canvas *, const Allocation &) const
virtual void request(Requisition &) const
bool filled_
Definition: rect.h:125
float height_
Definition: rect.h:123
virtual void draw(Canvas *, const Allocation &) const
Rectangle(float height, float width, bool filled=false, const Color *color=NULL, const Brush *brush=NULL)
virtual void allocate(Canvas *, const Allocation &, Extension &)
virtual ~Rectangle()
float width_
Definition: rect.h:124
void require_x(const Requirement &)
Definition: geometry.h:243
void require(DimensionName, const Requirement &)
void require_y(const Requirement &)
Definition: geometry.h:244
virtual void ref() const
Definition: resource.cpp:42
virtual void unref() const
Definition: resource.cpp:47
static const Color * default_foreground()
virtual ~Triangle()
virtual void allocate(Canvas *, const Allocation &, Extension &)
virtual void request(Requisition &) const
virtual void draw(Canvas *, const Allocation &) const
float side_
Definition: rect.h:105
bool filled_
Definition: rect.h:106
Triangle(float side, bool filled=false, const Color *color=NULL, const Brush *brush=NULL)
static XYView * current_draw_view()
virtual void stroke(Canvas *, const Color *, const Brush *)
#define y_(arg)
Crout matrix decomposition : Forward/Backward substitution.
Definition: crout.hpp:136
@ Dimension_Y
Definition: geometry.h:39
@ Dimension_X
Definition: geometry.h:39
static int c
Definition: hoc.cpp:169
#define IfIdraw(arg)
Definition: idraw.h:102
s
Definition: multisend.cpp:521
static N_Vector x_
#define NULL
Definition: spdefs.h:105