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