NEURON
xyview.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 <cassert>
6 #include <cmath>
7 
8 #include <InterViews/event.h>
9 #include <InterViews/hit.h>
10 #include <InterViews/canvas.h>
11 #include <InterViews/printer.h>
12 #include <InterViews/session.h>
13 
14 #include <InterViews/monoglyph.h>
15 #include <InterViews/tformsetter.h>
16 #include <InterViews/layout.h>
17 #include <InterViews/style.h>
18 #include <IV-look/kit.h>
19 #include <InterViews/background.h>
20 
21 #include "mymath.h"
22 #include "apwindow.h"
23 #include "hocdec.h"
24 #include "ocglyph.h"
25 #include "scenevie.h"
26 #include "scenepic.h"
27 #include "rubband.h"
28 #include "idraw.h"
29 
30 // XYView
31 /*static*/ class XYView_helper: public MonoGlyph {
32  public:
33  XYView_helper(Scene*, XYView*);
34  virtual ~XYView_helper();
35  virtual void request(Requisition&) const;
36  virtual void allocate(Canvas*, const Allocation&, Extension&);
37  virtual void draw(Canvas*, const Allocation&) const;
38  virtual void print(Printer*, const Allocation&) const;
39  virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
40 
41  public:
42  Transformer t_;
43 
44  private:
45  XYView* v_;
48  friend void XYView::current_pick_view(XYView*);
49  static XYView* current_pick_view_;
50  static XYView* current_draw_view_;
51 };
52 
54  XYView_helper::current_pick_view_ = v;
55 }
56 
57 void print_t(const char* s, const Transformer& t) {
58  float a00, a01, a10, a11, a20, a21;
59  t.matrix(a00, a01, a10, a11, a20, a21);
60  printf("%s transform %g %g %g %g %g %g\n", s, a00, a01, a10, a11, a20, a21);
61 }
62 XYView_helper::XYView_helper(Scene* s, XYView* v)
63  : MonoGlyph(s) {
64  v_ = v;
65 }
66 void XYView_helper::request(Requisition& req) const {
67  Requirement rx(v_->width(), 0, 0, -v_->left() / v_->width());
68  Requirement ry(v_->height(), 0, 0, -v_->bottom() / v_->height());
69  req.require_x(rx);
70  req.require_y(ry);
71 }
72 
73 void XYView_helper::allocate(Canvas* c, const Allocation& a, Extension& ext) {
74  t_ = c->transformer();
75  // print_t("XYView_helper::allocate", t_);
76  body()->allocate(c, a, ext);
77 }
78 
79 void XYView_helper::draw(Canvas* c, const Allocation& a) const {
80  current_draw_view_ = v_;
81  ((XYView_helper*) this)->t_ = c->transformer();
82  // print_t("XYView_helper::draw", c->transformer());
83  v_->set_damage_area(c);
84 #if 0
85  IfIdraw(pict(t_));
86 #else
88  Transformer tr(t_);
89  tr.translate(3 * 72, 4 * 72);
90  OcIdraw::pict(tr);
91  }
92 #endif
93  c->push_clipping();
94  c->clip_rect(v_->left(), v_->bottom(), v_->right(), v_->top());
95  body()->draw(c, a);
96  c->pop_clipping();
97  IfIdraw(end());
98 }
99 
100 void XYView_helper::print(Printer* c, const Allocation&) const {
101  current_draw_view_ = v_;
102  c->push_clipping();
103  c->clip_rect(v_->left(), v_->bottom(), v_->right(), v_->top());
104 
105  char buf[100];
106  float x, b;
107  v_->s2o().matrix(x, b, b, b, b, b);
108  Sprintf(buf, "\n%g setlinewidth", x);
109  c->comment(buf);
110 
111  // when printfile started printing at the level of the xyview
112  // the allocation was incorrect and was used by the background
113  // that was ok when the background was white...
114  // set the allocation the same as the clipping
115  Allocation a1;
116  Allotment ax(v_->left(), v_->width(), 0);
117  Allotment ay(v_->bottom(), v_->height(), 0);
118  a1.allot_x(ax);
119  a1.allot_y(ay);
120 
121  body()->print(c, a1);
122  c->pop_clipping();
123 }
124 
125 void XYView_helper::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
126  if (MyMath::inside(h.left(), h.bottom(), v_->left(), v_->bottom(), v_->right(), v_->top())) {
127  if (h.event()->grabber()) { // fixes a bug but I dont know why
128 #if 1
129  // The above fix broke the handling of keystrokes for crosshairs and Rotate3D
130  // It was needed so that buttons would appear normal when moving quickly from
131  // a button through a box to a scene. Now we put in the right handler in
132  // case event was a keystroke.
133  if (h.event()->type() == Event::key) {
134  h.target(depth, this, 0, h.event()->grabber());
135  }
136 #endif
137  return;
138  }
139  current_pick_view_ = v_;
140  MonoGlyph::pick(c, a, depth, h);
141  if (h.event()->type() == Event::down) {
142 #if 0
143 printf("XYView_helper hit (%g, %g) event (%g, %g)\n", h.left(), h.bottom(),
144 h.event()->pointer_x(), h.event()->pointer_y());
145 printf(" allocation lb=(%g, %g), rt=(%g,%g)\n", a.left(), a.bottom(), a.right(), a.top());
146 #endif
147  }
148  }
149 }
150 
151 static Coord pick_epsilon;
152 static void set_pick_epsilon() {
153  pick_epsilon = 2;
154 }
155 
156 
157 XYView::XYView(Scene* s, Coord xsize, Coord ysize)
158  : TransformSetter(new XYView_helper(s, this)) {
159  init(s->x1(), s->y1(), s->x2() - s->x1(), s->y2() - s->y1(), s, xsize, ysize);
160 }
161 
162 XYView::XYView(Coord x1, Coord y1, Coord xs, Coord ys, Scene* s, Coord xsize, Coord ysize)
163  : TransformSetter(new XYView_helper(s, this)) {
164  init(x1, y1, xs, ys, s, xsize, ysize);
165 }
166 
167 void XYView::init(Coord x1, Coord y1, Coord xs, Coord ys, Scene* s, Coord xsize, Coord ysize) {
168  set_pick_epsilon();
169  xsize_orig_ = xsize;
170  ysize_orig_ = ysize;
171  csize(0., xsize, 0., ysize);
172  origin(x1, y1);
173  x_span(xs);
174  y_span(ys);
175  canvas(NULL);
176  parent_ = NULL; // not reffed
177  append_view(s);
178 #if 0
179  if (view_margin_ == fil) {
180  Style* style = Session::instance()->style();
181  if (!style->find_attribute("view_margin", view_margin_)) {
182  view_margin_ = 0;
183  }
184  view_margin_ *= 72;
185  }
186 #endif
187 }
188 
190 
191 XYView_helper::~XYView_helper() {
192  if (v_ == current_pick_view_) {
193  current_pick_view_ = NULL;
194  }
195  if (v_ == current_draw_view_) {
196  current_draw_view_ = NULL;
197  }
198 }
199 
200 XYView::~XYView() {
201  // printf("~XYView\n");
202  scene()->remove_view(this);
203 }
204 
205 // should only be accessed by a method that traces its call from the pick
207  // printf("current pick view %p\n", XYView_helper::current_pick_view_);
208  return XYView_helper::current_pick_view_;
209 }
210 
211 XYView* XYView_helper::current_pick_view_;
212 
213 // should only be accessed by a method that traces its call from the draw
214 // or print
216  // printf("current draw view %p\n", XYView_helper::current_draw_view_);
217  return XYView_helper::current_draw_view_;
218 }
219 
220 XYView* XYView_helper::current_draw_view_;
221 
222 void XYView::append_view(Scene* s) {
223  s->append_view(this);
224 }
225 
226 void XYView::canvas(Canvas* c) {
227  canvas_ = c;
228 }
229 
230 void XYView::stroke(Canvas* c, const Color* color, const Brush* brush) {
231  if (scene()->drawing_fixed_item()) {
232  c->stroke(color, brush);
233  } else {
234  c->push_transform();
235  c->transform(s2o());
236  c->stroke(color, brush);
237  c->pop_transform();
238  }
239 }
240 
242  return canvas_;
243 }
244 
245 void XYView::undraw() {
246  canvas_ = NULL;
247  TransformSetter::undraw();
248 }
249 
250 void XYView::damage(Glyph* g, const Allocation& a, bool fixed, bool vf) {
251  if (canvas_) {
252  Extension e;
253  canvas_->push_transform();
254  canvas_->transformer(((XYView_helper*) body())->t_);
255  if (fixed) {
256  Coord x, y;
257  canvas_->transform(s2o());
258  if (vf) {
259  view_ratio(a.x(), a.y(), x, y);
260  } else {
261  s2o().inverse_transform(a.x(), a.y(), x, y);
262  }
263  Allocation a_fix = a;
264  a_fix.x_allotment().origin(x);
265  a_fix.y_allotment().origin(y);
266  g->allocate(canvas_, a_fix, e);
267  } else {
268  g->allocate(canvas_, a, e);
269  }
270  // printf("damage extension %g %g %g %g\n", e.left(), e.bottom(), e.right(), e.top());
271  // print_t("XYView::damage", canvas_->transformer());
272  canvas_->pop_transform();
273  canvas_->damage(e);
274  }
275 }
276 
277 void XYView::damage_all() {
278  if (canvas_) {
279  canvas_->damage(xc0_, yc0_, xc0_ + xsize_, yc0_ + ysize_);
280  }
281 }
282 
283 void XYView::damage(Coord x1, Coord y1, Coord x2, Coord y2) {
284  if (canvas_) {
285  Transformer& t = ((XYView_helper*) body())->t_;
286  Coord tx1, ty1, tx2, ty2;
287  t.transform(x1, y1, tx1, ty1);
288  t.transform(x2, y2, tx2, ty2);
289  const float off = canvas_->to_coord(1);
290  tx1 = std::max(tx1 - off, Coord(0));
291  ty1 = std::max(ty1 - off, Coord(0));
292  tx2 = std::min(tx2 + off, canvas_->width());
293  ty2 = std::min(ty2 + off, canvas_->height());
294  canvas_->damage(tx1, ty1, tx2, ty2);
295  }
296 }
297 
299  Extension e;
300  c->restrict_damage(0., 0., c->width(), c->height());
301  c->damage_area(e);
302  const float off = c->to_coord(1);
303  c->transformer().inverse_transform(e.left() - off, e.bottom() - off, xd1_, yd1_);
304  c->transformer().inverse_transform(e.right() + off, e.top() + off, xd2_, yd2_);
305 }
306 
307 void XYView::damage_area(Coord& x1, Coord& y1, Coord& x2, Coord& y2) const {
308  x1 = xd1_;
309  y1 = yd1_;
310  x2 = xd2_;
311  y2 = yd2_;
312 }
313 
314 void XYView::request(Requisition& req) const {
315  TransformSetter::request(req);
318  req.require_x(rx);
319  req.require_y(ry);
320 }
321 
322 void XYView::allocate(Canvas* c, const Allocation& a, Extension& ext) {
323 #ifdef MINGW
324  if (a.y_allotment().span() <= 0. || a.x_allotment().span() <= 0.) {
325  // a bug in mswindows iconify
326  return;
327  }
328 #endif
329  if (canvas_ == NULL) {
330  canvas_ = c;
331  }
332  c->push_transform();
333  TransformSetter::allocate(c, a, ext);
334  c->pop_transform();
335 }
336 
337 void XYView::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
338  canvas_ = c;
339  c->push_transform();
340  if (h.event()->type() == Event::down) {
341 #if 0
342 printf("XYView hit (%g, %g) event (%g, %g)\n", h.left(), h.bottom(),
343 h.event()->pointer_x(), h.event()->pointer_y());
344 #endif
345  }
346  TransformSetter::pick(c, a, depth, h);
347  c->pop_transform();
348 }
349 
350 Scene* XYView::scene() const {
351  return (Scene*) (((XYView_helper*) body())->body());
352 }
353 
354 Coord XYView::left() const {
355  return x1_;
356 }
357 Coord XYView::right() const {
358  return x1_ + x_span_;
359 }
360 Coord XYView::bottom() const {
361  return y1_;
362 }
363 Coord XYView::top() const {
364  return y1_ + y_span_;
365 }
366 Coord XYView::width() const {
367  return x_span_;
368 }
369 Coord XYView::height() const {
370  return y_span_;
371 }
372 
373 void XYView::view_ratio(float xrat, float yrat, Coord& x, Coord& y) const {
374  x = xrat * xsize_ + xc0_;
375  y = yrat * ysize_ + yc0_;
376 }
377 
378 void XYView::ratio_view(Coord x, Coord y, float& xrat, float& yrat) const {
379  xrat = (x - xc0_) / xsize_;
380  yrat = (y - yc0_) / ysize_;
381 }
382 
383 void XYView::size(Coord x1, Coord y1, Coord x2, Coord y2) {
384  x1_ = std::min(x1, x2);
385  y1_ = std::min(y1, y2);
386  x_span_ = std::abs(x2 - x1);
387  y_span_ = std::abs(y2 - y1);
388  notify();
389 }
390 
391 void XYView::origin(Coord x1, Coord y1) {
392  x1_ = x1;
393  y1_ = y1;
394  notify();
395 }
396 
397 void XYView::csize(Coord x0, Coord x, Coord y0, Coord y) const {
398  XYView* v = (XYView*) this;
399  v->xsize_ = x;
400  v->ysize_ = y;
401  v->xc0_ = x0;
402  v->yc0_ = y0;
403 }
404 
405 void XYView::box_size(Coord x1, Coord y1, Coord x2, Coord y2) {
406  size(x1, y1, x2, y2);
407 }
408 
409 void XYView::x_span(Coord x) {
410  x_span_ = (x > 0) ? x : 1.;
411  notify();
412 }
413 void XYView::y_span(Coord x) {
414  y_span_ = (x > 0) ? x : 1.;
415  notify();
416 }
417 
418 
419 void XYView::zout(Coord& x1, Coord& y1, Coord& x2, Coord& y2) const {
420  Coord dx, dy;
421  x1 = left();
422  x2 = right();
423  y1 = bottom();
424  y2 = top();
425  dx = .1 * (x2 - x1);
426  dy = .1 * (y2 - y1);
427  x1 -= dx;
428  x2 += dx;
429  y1 -= dy;
430  y2 += dy;
431 }
432 void XYView::zin(Coord& x1, Coord& y1, Coord& x2, Coord& y2) const {
433  Coord dx, dy;
434  x1 = left();
435  x2 = right();
436  y1 = bottom();
437  y2 = top();
438  dx = .1 / 1.2 * (x2 - x1);
439  dy = .1 / 1.2 * (y2 - y1);
440  x1 += dx;
441  x2 -= dx;
442  y1 += dy;
443  y2 -= dy;
444 }
445 
446 void XYView::save(std::ostream& o) {
447  PrintableWindow* w;
448  if (!canvas_) {
449  if (!parent() || !parent()->has_window()) {
450  return;
451  }
452  w = parent()->window();
453  } else {
454  w = (PrintableWindow*) canvas()->window();
455  }
456  char buf[256];
457  Coord x1, y1, x2, y2;
458  zin(x1, y1, x2, y2);
459  Sprintf(buf,
460  "{save_window_.view(%g, %g, %g, %g, %g, %g, %g, %g)}",
461  x1,
462  y1,
463  x2 - x1,
464  y2 - y1,
465  w->save_left(),
466  w->save_bottom(),
467  xsize_,
468  ysize_);
469  o << buf << std::endl;
470 }
471 
472 void XYView::scene2view(const Allocation& a) const {
473  float m00 = width() / a.x_allotment().span();
474  float m11 = height() / a.y_allotment().span();
475 
476  // takes a canvas transformation from scene to parent glyph coordinates
477  // transforms vectors from original to xyview
478  XYView* xyv = (XYView*) this;
479  xyv->scene2viewparent_ =
480  Transformer(m00, 0, 0, m11, left() - a.left() * m00, bottom() - a.bottom() * m11);
481  // print_t("scene2view", scene2viewparent_);
482 }
483 
484 void XYView::transform(Transformer& t, const Allocation& a, const Allocation& n) const {
485 #if 0
486  Allotment ax, ay;
487  if (view_margin()) {
488  const Allotment& alx = a.x_allotment();
489  ax.span(alx.span() - 2*view_margin());
490  ax.origin(alx.begin() + view_margin());
491  ax.alignment(0);
492  const Allotment& aly = a.y_allotment();
493  ay.span(aly.span() - 2*view_margin());
494  ay.origin(aly.begin() + view_margin());
495  ay.alignment(0);
496  }else{
497  ax = a.x_allotment();
498  ay = a.y_allotment();
499  }
500  Allocation al;
501  al.allot_x(ax);
502  al.allot_y(ay);
503  scene2view(al);
504 #else
505  scene2view(a);
506  const Allotment& ax = a.x_allotment();
507  const Allotment& ay = a.y_allotment();
508 #endif
509  const Allotment& nx = n.x_allotment();
510  const Allotment& ny = n.y_allotment();
511  XYView* v = (XYView*) this;
512  csize(ax.begin(), ax.span(), ay.begin(), ay.span());
513  float sx = xsize_ / width();
514  float sy = ysize_ / height();
515  XYView* xv = (XYView*) this;
516  xv->x_pick_epsilon_ = pick_epsilon / sx;
517  xv->y_pick_epsilon_ = pick_epsilon / sy;
518  t.translate(-left(), -bottom());
519  t.scale(sx, sy);
520  t.translate(ax.begin(), ay.begin());
521 #if 0
522 printf("XYView::transform ax origin=%g span=%g alignment=%g begin=%g\n",
523 ax.origin(), ax.span(), ax.alignment(), ax.begin());
524 printf("XYView::transform ay origin=%g span=%g alignment=%g begin=%g %g\n",
525 ay.origin(), ay.span(), ay.alignment(), ay.begin(), ay.end());
526 printf("XYView::transform natx origin=%g span=%g alignment=%g begin=%g\n",
527 nx.origin(), nx.span(), nx.alignment(), nx.begin());
528 printf("XYView::transform naty origin=%g span=%g alignment=%g begin=%g %g\n",
529 ny.origin(), ny.span(), ny.alignment(), ny.begin(), ny.end());
530 #endif
531 }
532 
533 // View
535  : XYView(s, s->x2() - s->x1(), s->y2() - s->y1()) {
536  x_span_ = XYView::width();
537  y_span_ = XYView::height();
538 }
539 View::View(Coord x, Coord y, Coord span, Scene* s, Coord xsize, Coord ysize)
540  : XYView(x - span / 2., y - (ysize / xsize) * span / 2., span, span, s, xsize, ysize) {
541  x_span_ = XYView::width();
542  y_span_ = XYView::height();
543 }
544 View::View(Coord x1, Coord y1, Coord xs, Coord ys, Scene* s, Coord xsize, Coord ysize)
545  : XYView(x1, y1, xs, ys, s, xsize, ysize) {
546  x_span_ = XYView::width();
547  y_span_ = XYView::height();
548 }
549 View::~View() {}
550 
551 void View::origin(Coord x, Coord y) {
552  XYView::origin(x - XYView::width() / 2., y - XYView::height() / 2.);
553 }
554 
555 void View::box_size(Coord x1, Coord y1, Coord x2, Coord y2) {
556  Coord w = x2 - x1;
557  Coord h = y2 - y1;
558  Coord magx = w / x_span_;
559  Coord magy = h / y_span_;
560  if (magx > magy) {
561  x_span_ *= magx;
562  y_span_ *= magx;
563  } else {
564  x_span_ *= magy;
565  y_span_ *= magy;
566  }
567  x_span(x_span_);
568  y_span(y_span_);
569  origin((x1 + x2) / 2, (y1 + y2) / 2);
570 }
571 
572 Coord View::x() const {
573  return left() + XYView::width() / 2.;
574 }
575 Coord View::y() const {
576  return bottom() + XYView::height() / 2.;
577 }
578 Coord View::view_width() const {
579  return x_span_;
580 }
581 Coord View::view_height() const {
582  return y_span_;
583 }
584 
585 void View::transform(Transformer& t, const Allocation& a, const Allocation&) const {
586  scene2view(a);
587  const Allotment& ax = a.x_allotment();
588  const Allotment& ay = a.y_allotment();
589  csize(ax.begin(), ax.span(), ay.begin(), ay.span());
590  float sx = ax.span() / XYView::width();
591  float sy = ay.span() / XYView::height();
592  // if (sx > sy) sx = sy;
593  t.translate(-x(), -y());
594  t.scale(sx, sx);
595  View* v = (View*) this;
596  v->x_pick_epsilon_ = pick_epsilon / sx;
597  v->y_pick_epsilon_ = pick_epsilon / sx;
598  t.translate((ax.begin() + ax.end()) / 2, (ay.begin() + ay.end()) / 2);
599  // printf("\nx origin=%g span=%g alignment=%g begin=%g end=%g\n", ax.origin(), ax.span(),
600  // ax.alignment(), ax.begin(), ax.end()); printf("\ny origin=%g span=%g alignment=%g begin=%g
601  // end=%g\n", ay.origin(), ay.span(), ay.alignment(), ay.begin(), ay.end());
602  Coord x1, y1;
603  t.transform(x() - x_span_ / 2, y() - y_span_ / 2, x1, y1);
604  if (!MyMath::eq(ax.begin(), x1, 1.f) || !MyMath::eq(ay.begin(), y1, 1.f)) {
605  t.inverse_transform(ax.begin(), ay.begin(), x1, y1);
606  v->x_span_ = 2 * (x() - x1);
607  v->y_span_ = 2 * (y() - y1);
608  v->size(x1, y1, x1 + v->x_span_, y1 + v->y_span_);
609  }
610 }
611 
612 void XYView::move_view(Coord dx1, Coord dy1) {
613  // printf("move by %g %g \n", dx1, dy1);
614  Coord x0, x1, y0, y1;
615  Coord dx = std::abs(dx1);
616  Coord dy = std::abs(dy1);
617  if (dx < .9 * dy) {
618  dx = 0.;
619  dy = dy1;
620  } else if (dy < .9 * dx) {
621  dx = dx1;
622  dy = 0.;
623  } else {
624  dx = dx1;
625  dy = dy1;
626  }
627  s2o().transform(0, 0, x0, y0);
628  s2o().transform(dx, dy, x1, y1);
629  x0 = x0 - x1 + left();
630  y0 = y0 - y1 + bottom();
631  x1 = x0 + width();
632  y1 = y0 + height();
633 
634 #if 1
635  if (dx > 0) {
636  MyMath::round(x0, x1, MyMath::Higher, 4);
637  } else {
638  MyMath::round(x0, x1, MyMath::Lower, 4);
639  }
640  if (dy > 0) {
641  MyMath::round(y0, y1, MyMath::Higher, 4);
642  } else {
643  MyMath::round(y0, y1, MyMath::Lower, 4);
644  }
645 #endif
646 
647  XYView::origin(x0, y0);
648  damage_all();
649 }
650 
651 void View::move_view(Coord dx, Coord dy) {
652  XYView::move_view(dx, dy);
653 }
654 
655 
656 void XYView::scale_view(Coord xorg, Coord yorg, float dxscl, float dyscl) {
657  Coord x0, y0, l, b, r, t;
658  Coord dx = std::abs(dxscl);
659  Coord dy = std::abs(dyscl);
660  if (dx < .9 * dy) {
661  dx = 0.;
662  dy = dyscl;
663  } else if (dy < .9 * dx) {
664  dx = dxscl;
665  dy = 0.;
666  } else {
667  dx = dxscl;
668  dy = dyscl;
669  }
670  s2o().transform(xorg, yorg, x0, y0);
671  // printf("org %g %g %g %g\n", xorg, yorg, x0, y0);
672  l = -(left() - x0) * dx + left();
673  b = -(bottom() - y0) * dy + bottom();
674  r = -(right() - x0) * dx + right();
675  t = -(top() - y0) * dy + top();
676 #if 1
677  if (dxscl > 1) {
678  MyMath::round(l, r, MyMath::Expand, 4);
679  } else {
681  }
682  if (dyscl > 1) {
684  } else {
686  }
687 #endif
688  size(l, b, r, t);
689  damage_all();
690 }
691 
692 void View::scale_view(Coord xorg, Coord yorg, float dxscl, float) {
693  XYView::scale_view(xorg, yorg, dxscl, dxscl);
694 }
695 
696 XYView* XYView::new_view(Coord x1, Coord y1, Coord x2, Coord y2) {
697  Coord l, b, r, t;
698  s2o().inverse_transform(x1, y1, l, b);
699  s2o().inverse_transform(x2, y2, r, t);
700  return new XYView(x1, y1, x2 - x1, y2 - y1, scene(), r - l, t - b);
701 }
702 
703 XYView* View::new_view(Coord x1, Coord y1, Coord x2, Coord y2) {
704  Coord l, b, r, t;
705  s2o().inverse_transform(x1, y1, l, b);
706  s2o().inverse_transform(x2, y2, r, t);
707  return new View((x1 + x2) / 2, (y1 + y2) / 2, x2 - x1, scene(), r - l, t - b);
708 }
709 
710 /*static*/ class NPInsetFrame: public MonoGlyph {
711  public:
712  NPInsetFrame(Glyph*);
713  virtual ~NPInsetFrame();
714  virtual void print(Printer*, const Allocation&) const;
715 };
716 
717 NPInsetFrame::NPInsetFrame(Glyph* g)
718  : MonoGlyph(WidgetKit::instance()->inset_frame(g)) {}
719 NPInsetFrame::~NPInsetFrame() {}
720 void NPInsetFrame::print(Printer* p, const Allocation& a) const {
721  Style* s = WidgetKit::instance()->style();
722  long i = 1;
723  s->find_attribute("scene_print_border", i);
724  // printf("NPInsetFrame %ld\n", i);
725  if (i) {
726  body()->print(p, a);
727  } else {
728  ((MonoGlyph*) body())->body()->print(p, a);
729  }
730 }
731 
733  : OcGlyph(new Background(
734  // WidgetKit::instance()->inset_frame(
735  new NPInsetFrame(LayoutKit::instance()->variable_span(v)),
736  WidgetKit::instance()->background())) {
737  v_ = v;
738  g_ = NULL;
739  v_->ref();
740  assert(v_->parent() == NULL);
741  v_->parent_ = this;
742 };
743 
745  v_->parent_ = NULL;
746  v_->unref();
748 }
749 
750 void OcViewGlyph::save(std::ostream& o) {
751  Scene* s = v_->scene();
752  char buf[256];
753  long i = Scene::scene_list_index(s);
754  if (!s->mark()) {
755  s->save_phase1(o);
756  Sprintf(buf, "scene_vector_[%ld] = save_window_", i);
757  } else {
758  Sprintf(buf, "save_window_ = scene_vector_[%ld]", i);
759  }
760  o << buf << std::endl;
761  v_->save(o);
762  if (!s->mark()) {
763  s->save_phase2(o);
764  s->mark(true);
765  }
766 }
767 
768 ViewWindow::ViewWindow(XYView* v, const char* name)
769  : PrintableWindow(new OcViewGlyph(v)) {
770  if (name) {
771  type(name);
772  }
773  v->attach(this);
774  update(v);
775 }
776 
778  OcViewGlyph* g = (OcViewGlyph*) glyph();
779  g->view()->detach(this);
780 }
781 
783  char s[200];
784  XYView* v = (XYView*) o;
785  Sprintf(s,
786  "%s %s x %g : %g y %g : %g",
787  type(),
788  v->scene()->picker()->select_name(),
789  v->left(),
790  v->right(),
791  v->bottom(),
792  v->top());
793  name(s);
794 }
795 #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 Style
Definition: _defines.h:278
#define Coord
Definition: _defines.h:17
#define Brush
Definition: _defines.h:57
#define Hit
Definition: _defines.h:145
#define WidgetKit
Definition: _defines.h:328
#define Printer
Definition: _defines.h:209
#define MonoGlyph
Definition: _defines.h:179
#define TransformSetter
Definition: _defines.h:312
#define LayoutKit
Definition: _defines.h:159
#define Glyph
Definition: _defines.h:130
Coord right() const
Definition: geometry.h:289
Coord top() const
Definition: geometry.h:291
Coord x() const
Definition: geometry.h:286
void allot_y(const Allotment &)
Definition: geometry.h:279
Coord left() const
Definition: geometry.h:288
Coord bottom() const
Definition: geometry.h:290
Coord y() const
Definition: geometry.h:287
Allotment & x_allotment()
Definition: geometry.h:281
Allotment & y_allotment()
Definition: geometry.h:282
void allot_x(const Allotment &)
Definition: geometry.h:278
void alignment(float)
Definition: geometry.h:267
Coord begin() const
Definition: geometry.h:270
void origin(Coord)
Definition: geometry.h:262
Coord end() const
Definition: geometry.h:274
void span(Coord)
Definition: geometry.h:265
virtual Glyph * glyph() const
Definition: apwindow.h:47
virtual const char * name() const
Coord left() const
Definition: geometry.h:293
Coord top() const
Definition: geometry.h:296
Coord bottom() const
Definition: geometry.h:294
Coord right() const
Definition: geometry.h:295
static bool eq(T x, T y, T e)
Definition: mymath.h:63
static bool inside(Coord x, Coord min, Coord max)
Definition: mymath.h:91
static double round(float &x1, float &x2, int direction, int digits)
Definition: mymath.cpp:253
@ Expand
Definition: mymath.h:48
@ Lower
Definition: mymath.h:48
@ Contract
Definition: mymath.h:48
@ Higher
Definition: mymath.h:48
virtual void notify()
Definition: observe.cpp:53
virtual void detach(Observer *)
Definition: observe.cpp:49
virtual PrintableWindow * window()
static void pict()
static std::ostream * idraw_stream
Definition: idraw.h:83
XYView * v_
Definition: scenevie.h:100
XYView * view()
Definition: scenevie.h:93
Glyph * g_
Definition: scenevie.h:101
OcViewGlyph(XYView *)
virtual ~OcViewGlyph()
virtual void save(std::ostream &)
virtual Coord save_left() const
virtual Coord save_bottom() const
const char * type() const
void require_x(const Requirement &)
Definition: geometry.h:243
void require_y(const Requirement &)
Definition: geometry.h:244
virtual void unref() const
Definition: resource.cpp:47
static long scene_list_index(Scene *)
void remove_view(XYView *)
Definition: scenevie.h:201
virtual void move_view(Coord dx, Coord dy)
virtual XYView * new_view(Coord x1, Coord y1, Coord x2, Coord y2)
virtual void transform(Transformer &, const Allocation &, const Allocation &natural) const
virtual void scale_view(Coord xorg, Coord yorg, float dxscale, float dyscale)
Coord x_span_
Definition: scenevie.h:230
View(Scene *)
void origin(Coord x, Coord y)
virtual Coord y() const
virtual Coord view_height() const
virtual ~View()
virtual Coord x() const
virtual Coord view_width() const
Coord y_span_
Definition: scenevie.h:230
virtual void box_size(Coord x1, Coord y1, Coord x2, Coord y2)
virtual ~ViewWindow()
ViewWindow(XYView *, const char *name)
virtual void update(Observable *)
virtual void damage_area(Coord &x1, Coord &y1, Coord &x2, Coord &y2) const
Coord x_span_
Definition: scenevie.h:188
Canvas * canvas()
Coord yd2_
Definition: scenevie.h:194
virtual Coord bottom() const
virtual Coord height() const
XYView(Scene *, Coord xsize=200, Coord ysize=200)
virtual void move_view(Coord dx, Coord dy)
virtual Coord top() const
virtual void view_ratio(float xratio, float yratio, Coord &x, Coord &y) const
void init(Coord x1, Coord y1, Coord x_span, Coord y_span, Scene *, Coord xsize, Coord ysize)
virtual void zout(Coord &x1, Coord &y1, Coord &x2, Coord &y2) const
Coord yd1_
Definition: scenevie.h:194
virtual void allocate(Canvas *, const Allocation &, Extension &)
void size(Coord x1, Coord y1, Coord x2, Coord y2)
virtual Scene * scene() const
virtual void set_damage_area(Canvas *)
virtual void undraw()
virtual Coord width() const
void origin(Coord x1, Coord y1)
Coord ysize_orig_
Definition: scenevie.h:191
virtual void damage(Glyph *, const Allocation &, bool fixed=false, bool viewfixed=false)
static Coord view_margin_
Definition: scenevie.h:195
Coord xc0_
Definition: scenevie.h:191
virtual ~XYView()
virtual Coord left() const
OcViewGlyph * parent()
Definition: scenevie.h:163
void csize(Coord x0, Coord xsize, Coord y0, Coord ysize) const
virtual XYView * new_view(Coord x1, Coord y1, Coord x2, Coord y2)
void x_span(Coord)
Coord yc0_
Definition: scenevie.h:191
Transformer scene2viewparent_
Definition: scenevie.h:190
virtual void pick(Canvas *, const Allocation &, int depth, Hit &)
Coord x1_
Definition: scenevie.h:188
virtual void save(std::ostream &)
virtual void request(Requisition &) const
virtual void transform(Transformer &, const Allocation &, const Allocation &natural) const
virtual void ratio_view(Coord x, Coord y, float &xratio, float &yratio) const
virtual void damage_all()
virtual Coord right() const
Canvas * canvas_
Definition: scenevie.h:189
Coord xsize_orig_
Definition: scenevie.h:191
void y_span(Coord)
Coord xsize_
Definition: scenevie.h:191
virtual void scale_view(Coord xorg, Coord yorg, float dxscale, float dyscale)
virtual void box_size(Coord x1, Coord y1, Coord x2, Coord y2)
Coord xd2_
Definition: scenevie.h:194
Coord ysize_
Definition: scenevie.h:191
void scene2view(const Allocation &parent) const
virtual void zin(Coord &x1, Coord &y1, Coord &x2, Coord &y2) const
static XYView * current_draw_view()
static XYView * current_pick_view()
Coord x_pick_epsilon_
Definition: scenevie.h:185
virtual void stroke(Canvas *, const Color *, const Brush *)
const Transformer & s2o() const
Definition: scenevie.h:137
Coord y1_
Definition: scenevie.h:188
Coord view_margin() const
Definition: scenevie.h:169
OcViewGlyph * parent_
Definition: scenevie.h:193
Coord y_pick_epsilon_
Definition: scenevie.h:185
Coord xd1_
Definition: scenevie.h:194
Coord y_span_
Definition: scenevie.h:188
void append_view(Scene *)
#define fil
Definition: coord.h:41
#define key
Definition: tqueue.hpp:45
#define v
Definition: md1redef.h:11
#define i
Definition: md1redef.h:19
char buf[512]
Definition: init.cpp:13
static int c
Definition: hoc.cpp:169
#define assert(ex)
Definition: hocassrt.h:24
#define IfIdraw(arg)
Definition: idraw.h:102
printf
Definition: extdef.h:5
void init()
Definition: init.cpp:141
const char * name
Definition: init.cpp:16
void update(NrnThread *_nt)
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
int const size_t const size_t n
Definition: nrngsl.h:10
size_t p
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