NEURON
axis.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #if HAVE_IV // to end of file
3 
4 #include <cstdio>
5 #include <InterViews/background.h>
6 #include <InterViews/canvas.h>
7 #include <InterViews/printer.h>
8 #include <InterViews/label.h>
9 #include <IV-look/kit.h>
10 #include <cmath>
11 #include "scenevie.h"
12 #include "mymath.h"
13 #include "axis.h"
14 #include "hocdec.h"
15 #include "rect.h"
16 #include "graph.h"
17 #include "idraw.h"
18 
19 /*static*/ class GAxisItem: public GraphItem {
20  public:
21  GAxisItem(Glyph* g)
22  : GraphItem(g) {}
23  virtual ~GAxisItem(){};
24  virtual void save(std::ostream&, Coord, Coord) {}
25  virtual void erase(Scene* s, GlyphIndex i, int type) {
27  s->remove(i);
28  }
29  }
30 };
31 
33  s_ = s;
34  d_ = d;
35  set_range();
36  location();
37  init(min_, max_, pos_, ntic_);
38 }
39 
41  s_ = s;
42  d_ = d;
43  min_ = x1;
44  max_ = x2;
45  location();
47  init(float(amin_), float(amax_), pos_, ntic_);
48 }
49 
51  DimensionName d,
52  Coord x1,
53  Coord x2,
54  Coord pos,
55  int ntic,
56  int nminor,
57  int invert,
58  bool number) {
59  s_ = s;
60  d_ = d;
61  init(x1, x2, pos, ntic, nminor, invert, number);
62 }
63 
64 void Axis::init(Coord x1, Coord x2, Coord pos, int ntic, int nminor, int invert, bool number) {
65  min_ = x1;
66  max_ = x2;
67  pos_ = pos;
68  ntic_ = ntic;
69  nminor_ = nminor;
70  invert_ = invert;
71  number_ = number;
72  amin_ = x1;
73  amax_ = x2;
74  s_->attach(this);
75  install();
76 }
77 
78 Axis::~Axis() {
79  s_->detach(this);
80  // printf("~Axis\n");
81 }
82 
83 void Axis::size(float& min, float& max) {
84  min = float(amin_);
85  max = float(amax_);
86 }
87 
88 void Axis::save(std::ostream& o) {
89  char buf[256];
90  int c;
91  if (d_ == Dimension_X) {
92  c = 'x';
93  } else {
94  c = 'y';
95  }
96  Sprintf(buf,
97  "save_window_.%caxis(%g,%g,%g,%d,%d,%d,%d)",
98  c,
99  amin_,
100  amax_,
101  pos_,
102  ntic_,
103  nminor_,
104  invert_,
105  number_);
106  o << buf << std::endl;
107 }
108 
109 void Axis::update(Observable*) {}
110 
111 bool Axis::set_range() {
112  Coord x1, x2;
113  if (d_ == Dimension_X) {
114  x1 = s_->x1();
115  x2 = s_->x2();
116  } else {
117  x1 = s_->y1();
118  x2 = s_->y2();
119  }
120 
121  min_ = x1;
122  max_ = x2;
124  return true;
125 }
126 
127 void Axis::location() {
128  Coord x1, y1, x2, y2;
130  if (v && v->scene() == s_) {
131  v->zin(x1, y1, x2, y2);
132  } else {
133  x1 = s_->x1();
134  x2 = s_->x2();
135  y1 = s_->y1();
136  y2 = s_->y2();
137  }
138  if (d_ == Dimension_X) {
139  if (y1 > 0) {
140  pos_ = y1;
141  } else if (y2 < 0) {
142  pos_ = y2;
143  } else {
144  pos_ = 0;
145  }
146  } else {
147  if (x1 > 0) {
148  pos_ = x1;
149  } else if (x2 < 0) {
150  pos_ = x2;
151  } else {
152  pos_ = 0;
153  }
154  }
155 }
156 #if 1
157 // Zach Mainen improvements
158 
159 void Axis::install() {
160  int i, j;
161  GlyphIndex gi;
162  Line* tic = NULL;
163  Coord x, y;
164  char str[20];
165  float tic_space;
166 
167  float y_align, x_align;
168  Line* minor_tic = NULL;
169 
170  Coord l_minor = 5.;
171  Coord length = 10.;
172 
173  if (invert_ == 1) {
174  l_minor *= -1.;
175  length *= -1.;
176  }
177 
178  char pform[10];
179 
180  int addprec;
181  double s = (amax_ - amin_) / float(ntic_);
182  while (s < 1)
183  s *= 10.;
184  if (s == 1 || s == 2)
185  addprec = 0;
186  else
187  addprec = 1;
188 
189  double logstep = -log10((amax_ - amin_) / float(ntic_));
190 
191  if (d_ == Dimension_X) {
192  if (logstep >= 0 && logstep <= 5) {
193  Sprintf(pform, "%%0.%.0ff", logstep + addprec);
194  } else {
195  Sprintf(pform, "%%g");
196  }
197  y = pos_;
198  s_->append(new GAxisItem(new Line(amax_ - amin_, 0)));
199  gi = s_->count() - 1;
200  s_->move(gi, amin_, y);
201 
202  tic = new Line(0, length);
203  tic->ref();
204  minor_tic = new Line(0, l_minor);
205  minor_tic->ref();
206  tic_space = (amax_ - amin_) / float(ntic_);
207 
208  for (i = 0; i <= ntic_; ++i) {
209  x = amin_ + i * tic_space;
210  if (std::abs(x) < 1e-10) {
211  x = 0.;
212  }
213  if (invert_ >= 0) {
214  s_->append_fixed(new GAxisItem(tic));
215  gi = s_->count() - 1;
216  s_->move(gi, x, y);
217  }
218 
219  if (number_) {
220  /* if (i==0) x_align = 0.;
221  else if (i==ntic_) x_align = .9;
222  else x_align = 0.5;
223  */
224  x_align = 0.5;
225  if (invert_ == 1)
226  y_align = -0.3;
227  else
228  y_align = 1.5;
229  Sprintf(str, pform, x);
230  s_->append_fixed(new GAxisItem(
231  new GLabel(str, Appear::default_color(), true, 1, x_align, y_align)));
232  gi = s_->count() - 1;
233  s_->move(gi, x, y);
234  }
235 
236  if (i < ntic_ && invert_ >= 0) {
237  for (j = 0; j < nminor_; j++) {
238  x = amin_ + i * tic_space + j * tic_space / nminor_;
239  s_->append_fixed(new GAxisItem(minor_tic));
240  gi = s_->count() - 1;
241  s_->move(gi, x, y);
242  }
243  }
244  }
245  } else {
246  if (logstep >= 0 && logstep <= 5) {
247  Sprintf(pform, " %%0.%.0ff ", logstep + 1);
248  } else {
249  Sprintf(pform, " %%g ");
250  }
251  x = pos_;
252  s_->append(new GAxisItem(new Line(0, amax_ - amin_)));
253  gi = s_->count() - 1;
254  s_->move(gi, x, amin_);
255 
256  tic = new Line(length, 0);
257  tic->ref();
258  minor_tic = new Line(l_minor, 0);
259  minor_tic->ref();
260  tic_space = (amax_ - amin_) / float(ntic_);
261 
262  for (i = 0; i <= ntic_; ++i) {
263  y = amin_ + i * tic_space;
264  if (invert_ >= 0) {
265  s_->append_fixed(new GAxisItem(tic));
266  gi = s_->count() - 1;
267  s_->move(gi, x, y);
268  }
269 
270  if (number_) {
271  Sprintf(str, pform, y);
272  y_align = 0.5;
273  // if (i==0) y_align = 0.;
274  // else if (i==ntic_) y_align = .66;
275  // else y_align = 0.33;
276  if (invert_ == 1)
277  x_align = 0;
278  else
279  x_align = 1.3;
280  s_->append_fixed(new GAxisItem(
281  new GLabel(str, Appear::default_color(), true, 1, x_align, y_align)));
282  gi = s_->count() - 1;
283  s_->move(gi, x, y);
284  }
285 
286  if (i < ntic_ && invert_ >= 0) {
287  for (j = 0; j < nminor_; j++) {
288  y = amin_ + i * tic_space + j * tic_space / nminor_;
289  s_->append_fixed(new GAxisItem(minor_tic));
290  gi = s_->count() - 1;
291  s_->move(gi, x, y);
292  }
293  }
294  }
295  }
296  Resource::unref(tic);
297  Resource::unref(minor_tic);
298 }
299 #else
300 void Axis::install() {
301  int i;
302  GlyphIndex gi;
303  Coord length = 10;
304  Line* tic = NULL;
305  Coord x, y;
306  char str[20];
307  if (d_ == Dimension_X) {
308  y = pos_;
309  s_->append(new GAxisItem(new Line(amax_ - amin_, 0)));
310  gi = s_->count() - 1;
311  s_->move(gi, amin_, y);
312 
313  tic = new Line(0, length);
314  tic->ref();
315  for (i = 0; i <= ntic_; ++i) {
316  x = amin_ + i * (amax_ - amin_) / float(ntic_);
317  if (std::abs(x) < 1e-10) {
318  x = 0.;
319  }
320  s_->append_fixed(new GAxisItem(tic));
321  gi = s_->count() - 1;
322  s_->move(gi, x, y);
323  Sprintf(str, "%g", x);
324  s_->append_fixed(
325  new GAxisItem(new GLabel(str, Appear::default_color(), true, 1, .5, 1.1)));
326  gi = s_->count() - 1;
327  s_->move(gi, x, y);
328  }
329  } else {
330  x = pos_;
331  s_->append(new GAxisItem(new Line(0, amax_ - amin_)));
332  gi = s_->count() - 1;
333  s_->move(gi, x, amin_);
334 
335  tic = new Line(length, 0);
336  tic->ref();
337  for (i = 0; i <= ntic_; ++i) {
338  y = amin_ + i * (amax_ - amin_) / float(ntic_);
339  s_->append_fixed(new GAxisItem(tic));
340  gi = s_->count() - 1;
341  s_->move(gi, x, y);
342  Sprintf(str, "%g", y);
343  s_->append_fixed(
344  new GAxisItem(new GLabel(str, Appear::default_color(), true, 1, 1, .5)));
345  gi = s_->count() - 1;
346  s_->move(gi, x, y);
347  }
348  }
349  Resource::unref(tic);
350 }
351 #endif
352 
354  : Background(NULL, Scene::default_background()) {}
355 
357 
358 void BoxBackground::draw(Canvas* c, const Allocation& a) const {
359  Background::draw(c, a);
360  draw_help(c, a);
361 }
362 void BoxBackground::print(Printer* c, const Allocation& a) const {
363  Background::print(c, a);
364  draw_help(c, a);
365 }
366 
367 #define IDLINE(x1, y1, x2, y2, color, br) \
368  c->line(x1, y1, x2, y2, color, br); \
369  IfIdraw(line(c, x1, y1, x2, y2, color, br));
370 
371 void BoxBackground::draw_help(Canvas* c, const Allocation&) const {
372  // printf("BoxBackground::draw\n");
373  const Color* color = Scene::default_foreground();
374  Coord x1, y1, x2, y2;
375  double d1, d2;
376  int xtic, ytic;
378  v.zin(x1, y1, x2, y2);
379  MyMath::round_range_down(x1, x2, d1, d2, xtic);
380  x1 = d1;
381  x2 = d2;
382  MyMath::round_range_down(y1, y2, d1, d2, ytic);
383  y1 = d1;
384  y2 = d2;
385  const Transformer& tr = v.s2o();
386  c->push_transform();
387  c->transform(tr);
388  IfIdraw(pict(tr));
389  Coord l, r, b, t;
390  tr.inverse_transform(x1, y1, l, b);
391  tr.inverse_transform(x2, y2, r, t);
392  const Brush* br = Appear::default_brush();
393  c->rect(l, b, r, t, color, br);
394  IfIdraw(rect(c, l, b, r, t, color, br, false));
395  const Coord tic = 10;
396  Coord x, y;
397 
398  Coord dtic = (r - l) / xtic;
399  Coord dx = (x2 - x1) / xtic;
400  int i;
401  for (i = 0; i <= xtic; ++i) {
402  x = l + i * dtic;
403  if (i > 0 && i < xtic) {
404  IDLINE(x, b, x, b + tic, color, br);
405  IDLINE(x, t, x, t - tic, color, br);
406  }
407  tic_label(x, b - 5, x1 + i * dx, .5, 1, c);
408  }
409  dtic = (t - b) / ytic;
410  dx = (y2 - y1) / ytic;
411  for (i = 0; i <= ytic; ++i) {
412  y = b + i * dtic;
413  if (i > 0 && i < ytic) {
414  IDLINE(l, y, l + tic, y, color, br);
415  IDLINE(r, y, r - tic, y, color, br);
416  }
417  tic_label(l - 5, y, y1 + i * dx, 1, .5, c);
418  }
419 
420  c->clip_rect(l, b, r, t);
421  c->pop_transform();
422  IfIdraw(end());
423 }
424 
425 void BoxBackground::tic_label(Coord x1, Coord y1, Coord val, float xa, float ya, Canvas* c) const {
426  char buf[20];
427  Sprintf(buf, "%g", val);
428  Glyph* g = new Label(buf, WidgetKit::instance()->font(), Appear::default_color());
429  g->ref();
430  Requisition req;
431  g->request(req);
432  Allocation a;
433  a.x_allotment().origin(x1 - xa * req.x_requirement().natural());
434  a.y_allotment().origin(y1 - ya * req.y_requirement().natural());
435  g->draw(c, a);
436  g->unref();
437  if (OcIdraw::idraw_stream) {
438  Transformer t;
439  t.translate(a.x(), a.y());
441  }
442 }
443 
445  : Background(NULL, Scene::default_background()) {}
446 
448 
449 void AxisBackground::draw(Canvas* c, const Allocation& a) const {
450  Background::draw(c, a);
451  draw_help(c, a);
452 }
453 void AxisBackground::print(Printer* c, const Allocation& a) const {
454  Background::print(c, a);
455  draw_help(c, a);
456 }
457 
458 void AxisBackground::draw_help(Canvas* c, const Allocation&) const {
459  // printf("AxisBackground::draw\n");
460  const Color* color = Scene::default_foreground();
461  Coord x1, y1, x2, y2;
462  double d1, d2;
463  int xtic, ytic;
465  v.zin(x1, y1, x2, y2);
466  MyMath::round_range_down(x1, x2, d1, d2, xtic);
467  x1 = d1;
468  x2 = d2;
469  MyMath::round_range_down(y1, y2, d1, d2, ytic);
470  y1 = d1;
471  y2 = d2;
472  const Transformer& tr = v.s2o();
473  c->push_transform();
474  c->transform(tr);
475  IfIdraw(pict(tr));
476  Coord l, r, b, t;
477  tr.inverse_transform(x1, y1, l, b);
478  tr.inverse_transform(x2, y2, r, t);
479  Coord xorg, yorg, xo, yo;
480  if (MyMath::inside(0, x1, x2)) {
481  xorg = 0;
482  } else {
483  xorg = x1;
484  }
485  if (MyMath::inside(0, y1, y2)) {
486  yorg = 0;
487  } else {
488  yorg = y1;
489  }
490  tr.inverse_transform(xorg, yorg, xo, yo);
491  const Brush* br = Appear::default_brush();
492  IDLINE(l, yo, r, yo, color, br);
493  IDLINE(xo, b, xo, t, color, br);
494  const Coord tic = 10;
495  Coord x, y;
496 
497  Coord dtic = (r - l) / xtic;
498  Coord dx = (x2 - x1) / xtic;
499  int i;
500  for (i = 0; i <= xtic; ++i) {
501  x = l + i * dtic;
502  IDLINE(x, yo, x, yo + tic, color, br);
503  tic_label(x, yo - 5, x1 + i * dx, .5, 1, c);
504  }
505  dtic = (t - b) / ytic;
506  dx = (y2 - y1) / ytic;
507  for (i = 0; i <= ytic; ++i) {
508  y = b + i * dtic;
509  IDLINE(xo, y, xo + tic, y, color, br);
510  tic_label(xo - 5, y, y1 + i * dx, 1, .5, c);
511  }
512 
513  c->pop_transform();
514  IfIdraw(end());
515 }
516 
517 void AxisBackground::tic_label(Coord x1, Coord y1, Coord val, float xa, float ya, Canvas* c) const {
518  char buf[20];
519  Sprintf(buf, "%g", val);
520  Glyph* g = new Label(buf, WidgetKit::instance()->font(), Appear::default_color());
521  g->ref();
522  Requisition req;
523  g->request(req);
524  Allocation a;
525  a.x_allotment().origin(x1 - xa * req.x_requirement().natural());
526  a.y_allotment().origin(y1 - ya * req.y_requirement().natural());
527  g->draw(c, a);
528  g->unref();
529  if (OcIdraw::idraw_stream) {
530  Transformer t;
531  t.translate(a.x(), a.y());
533  }
534 }
535 
536 #endif
#define Background
Definition: _defines.h:41
#define Color
Definition: _defines.h:72
#define Transformer
Definition: _defines.h:313
#define Canvas
Definition: _defines.h:63
#define Label
Definition: _defines.h:157
#define Coord
Definition: _defines.h:17
#define Brush
Definition: _defines.h:57
#define Line
Definition: _defines.h:9
#define Printer
Definition: _defines.h:209
#define GlyphIndex
Definition: _defines.h:21
#define Glyph
Definition: _defines.h:130
Coord x() const
Definition: geometry.h:286
Coord y() const
Definition: geometry.h:287
Allotment & x_allotment()
Definition: geometry.h:281
Allotment & y_allotment()
Definition: geometry.h:282
void origin(Coord)
Definition: geometry.h:262
static const Color * default_color()
static const Brush * default_brush()
void draw_help(Canvas *, const Allocation &) const
void tic_label(Coord x, Coord y, Coord val, float x_align, float y_align, Canvas *) const
virtual void print(Printer *, const Allocation &) const
virtual void draw(Canvas *, const Allocation &) const
virtual ~AxisBackground()
virtual void save(std::ostream &)
int ntic_
Definition: axis.h:43
double amin_
Definition: axis.h:42
double amax_
Definition: axis.h:42
int invert_
Definition: axis.h:44
void location()
virtual void update(Observable *)
virtual ~Axis()
void install()
DimensionName d_
Definition: axis.h:41
Coord min_
Definition: axis.h:40
Coord pos_
Definition: axis.h:46
bool number_
Definition: axis.h:45
Axis(Scene *, DimensionName)
virtual void size(float &, float &)
Coord max_
Definition: axis.h:40
Scene * s_
Definition: axis.h:39
int nminor_
Definition: axis.h:43
bool set_range()
void init(Coord x1, Coord x2, Coord pos=0., int ntic=1, int nminor=0, int invert=0, bool number=true)
virtual void draw(Canvas *, const Allocation &) const
virtual ~BoxBackground()
void tic_label(Coord x, Coord y, Coord val, float x_align, float y_align, Canvas *) const
virtual void print(Printer *, const Allocation &) const
void draw_help(Canvas *, const Allocation &) const
Definition: graph.h:418
virtual void erase(Scene *, GlyphIndex, int erase_type)
@ ERASE_AXIS
Definition: graph.h:28
bool save()
Definition: graph.h:34
Definition: rect.h:60
static void round_range_down(Coord x1, Coord x2, double &y1, double &y2, int &ntic)
Definition: mymath.cpp:224
static void round_range(Coord x1, Coord x2, double &y1, double &y2, int &ntic)
Definition: mymath.cpp:200
static bool inside(Coord x, Coord min, Coord max)
Definition: mymath.h:91
virtual void attach(Observer *)
Definition: observe.cpp:45
virtual void detach(Observer *)
Definition: observe.cpp:49
static void text(Canvas *, const char *, const Transformer &, const Font *f=NULL, const Color *c=NULL)
static std::ostream * idraw_stream
Definition: idraw.h:83
void natural(Coord)
Definition: geometry.h:231
const Requirement & x_requirement() const
Definition: geometry.h:245
const Requirement & y_requirement() const
Definition: geometry.h:246
virtual void unref() const
Definition: resource.cpp:47
void move(GlyphIndex, Coord x, Coord y)
virtual Coord y2() const
Definition: scenevie.h:364
virtual Coord y1() const
Definition: scenevie.h:361
virtual void append(Glyph *)
static const Color * default_foreground()
virtual Coord x2() const
Definition: scenevie.h:358
virtual GlyphIndex count() const
virtual Coord x1() const
Definition: scenevie.h:355
virtual void append_fixed(Glyph *)
static XYView * current_draw_view()
static XYView * current_pick_view()
#define v
Definition: md1redef.h:11
#define i
Definition: md1redef.h:19
@ Dimension_X
Definition: geometry.h:39
unsigned int DimensionName
Definition: geometry.h:36
char buf[512]
Definition: init.cpp:13
static int c
Definition: hoc.cpp:169
#define IfIdraw(arg)
Definition: idraw.h:102
invert
Definition: extdef.h:9
log10
Definition: extdef.h:4
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
Definition: wrap_sprintf.h:14
size_t j
s
Definition: multisend.cpp:521
short type
Definition: cabvars.h:10
#define xorg
Definition: axis.cpp:153
#define yorg
Definition: axis.cpp:154
#define NULL
Definition: spdefs.h:105