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