NEURON
scene.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #if HAVE_IV // to end of file
3 
4 /* I have shamelessly hacked away at the page implementation to
5  create the Scene class. There really isn't much in common anymore but
6  I happily acknowlege the debt.
7 */
8 /*
9  * Copyright (c) 1987, 1988, 1989, 1990, 1991 Stanford University
10  * Copyright (c) 1991 Silicon Graphics, Inc.
11  *
12  * Permission to use, copy, modify, distribute, and sell this software and
13  * its documentation for any purpose is hereby granted without fee, provided
14  * that (i) the above copyright notices and this permission notice appear in
15  * all copies of the software and related documentation, and (ii) the names of
16  * Stanford and Silicon Graphics may not be used in any advertising or
17  * publicity relating to the software without the specific, prior written
18  * permission of Stanford and Silicon Graphics.
19  *
20  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
22  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
23  *
24  * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR
25  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
26  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
27  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
28  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
29  * OF THIS SOFTWARE.
30  */
31 
32 /*
33  * Scene - arbitrary placements seen from several views
34  */
35 
36 #include <stdio.h>
37 #include <assert.h>
38 
39 #include <InterViews/canvas.h>
40 #include <InterViews/hit.h>
41 #include <InterViews/session.h>
42 #include <InterViews/style.h>
43 #include <InterViews/color.h>
44 #include <InterViews/brush.h>
45 #include <InterViews/background.h>
46 #include <OS/list.h>
47 
48 #include "mymath.h"
49 #include "epsprint.h"
50 #include "scenevie.h"
51 #include "scenepic.h"
52 #include "idraw.h"
53 #include "ivoc.h"
54 #include "utils/enumerate.h"
55 
56 #define Scene_Move_Text_ "MoveText Graph"
57 #define Scene_ChangeColor_ "ChangeColor Graph"
58 #define Scene_Delete_ "Delete Graph"
59 
60 static const int SceneInfoShowing = 0x01;
61 static const int SceneInfoFixed = 0x02;
62 static const int SceneInfoViewFixed = 0x04;
63 static const int SceneInfoAllocated = 0x08;
64 
65 class SceneInfo {
66  public:
67  SceneInfo();
68  SceneInfo(Glyph*, Coord x = 0, Coord y = 0);
69  void pinfo();
70  Glyph* glyph_;
71  Allocation allocation_;
72  Coord x_;
73  Coord y_;
74  short status_;
75 };
76 
77 void SceneInfo::pinfo() {
78  Allocation& a = allocation_;
79  printf("allocation %g %g %g %g\n", a.left(), a.bottom(), a.right(), a.top());
80 }
81 
82 SceneInfo::SceneInfo() {
83  glyph_ = NULL;
84  x_ = 0;
85  y_ = 0;
86  status_ = 0;
87 }
88 
89 SceneInfo::SceneInfo(Glyph* g, Coord x, Coord y) {
90  glyph_ = g;
91  x_ = x;
92  y_ = y;
93  status_ = SceneInfoShowing;
94 }
95 
96 static const float epsilon = 0.001;
97 static std::vector<Scene*>* scene_list;
98 
100 Coord Scene::mbs() const {
101  return mbs_;
102 }
103 static const Brush* mb_brush_;
104 static const Color* mb_color_;
105 
107  // will not redraw unless allocation is changed
108  // use damage(index) to do a definite redraw on a constant allocation
109  SceneInfo& info = (*info_)[index];
110  Requisition s;
111  info.glyph_->request(s);
112  Allocation a_old = info.allocation_;
113  Allocation& a = info.allocation_;
114  Allotment ax = Allotment(info.x_,
115  s.requirement(Dimension_X).natural(),
116  s.requirement(Dimension_X).alignment());
117  Allotment ay = Allotment(info.y_,
118  s.requirement(Dimension_Y).natural(),
119  s.requirement(Dimension_Y).alignment());
120  a.allot(Dimension_X, ax);
121  a.allot(Dimension_Y, ay);
122  if (info.status_ & SceneInfoAllocated) {
123  if (!a_old.equals(a, epsilon)) {
124  damage(index, a_old);
125  damage(index);
126  }
127  } else {
128  damage(index);
129  }
130  info.status_ |= SceneInfoAllocated;
131 }
132 
134  // will not redraw unless allocation is changed
135  // use damage(index) to do a definite redraw on a constant allocation
136  SceneInfo& info = (*info_)[index];
137  Requisition s;
138  info.glyph_->request(s);
139  Allocation a_old = info.allocation_;
140  Allocation& a = info.allocation_;
141  Allotment ax = Allotment(info.x_,
142  s.requirement(Dimension_X).natural(),
143  s.requirement(Dimension_X).alignment());
144  Allotment ay = Allotment(info.y_,
145  s.requirement(Dimension_Y).natural(),
146  s.requirement(Dimension_Y).alignment());
147  a.allot(Dimension_X, ax);
148  a.allot(Dimension_Y, ay);
149  // printf("Scene::modified(%d) allocation %g %g %g %g\n", index, a.left(), a.bottom(),
150  // a.right(), a.top());
151  if ((info.status_ & SceneInfoAllocated) && !a_old.equals(a, epsilon)) {
152  // printf("damaged\n");
153  damage(index, a_old);
154  }
155  damage(index);
156  info.status_ |= SceneInfoAllocated;
157 }
158 
159 static const Color* scene_background_;
160 static const Color* scene_foreground_;
161 
163  if (!scene_background_) {
164  Style* s = Session::instance()->style();
165  String c;
166  if (!s->find_attribute("Scene_background", c) ||
167  (scene_background_ = Color::lookup(Session::instance()->default_display(), c)) ==
168  NULL) {
169  scene_background_ = Color::lookup(Session::instance()->default_display(), "#ffffff");
170  }
171  Resource::ref(scene_background_);
172  }
173  return scene_background_;
174 }
175 
177  if (!scene_foreground_) {
178  Style* s = Session::instance()->style();
179  String c;
180  if (!s->find_attribute("Scene_foreground", c) ||
181  (scene_foreground_ = Color::lookup(Session::instance()->default_display(), c)) ==
182  NULL) {
183  scene_foreground_ = Color::lookup(Session::instance()->default_display(), "#000000");
184  }
185  Resource::ref(scene_foreground_);
186  }
187  return scene_foreground_;
188 }
189 
190 Scene::Scene(Coord x1, Coord y1, Coord x2, Coord y2, Glyph* bg)
191  : Glyph() {
192  drawing_fixed_item_ = false;
193  tool_ = NOTOOL;
194  background_ = NULL;
195  background(bg);
196  info_ = new std::vector<SceneInfo>();
197  views_ = new std::vector<XYView*>();
198  x1_orig_ = x1;
199  x2_orig_ = x2;
200  y1_orig_ = y1;
201  y2_orig_ = y2;
202  x1_ = x1;
203  x2_ = x2;
204  y1_ = y1;
205  y2_ = y2;
206  if (!scene_list) {
207  scene_list = new std::vector<Scene*>();
208  }
209  if (mbs_ == 0.) {
210  Session::instance()->style()->find_attribute("scene_menu_box_size", mbs_);
211  if (mbs_ > 0.) {
212  mb_color_ = new Color(ColorIntensity(.5), ColorIntensity(.5), ColorIntensity(.5));
213  mb_brush_ = new Brush(1);
214  Resource::ref(mb_color_);
215  Resource::ref(mb_brush_);
216  } else {
217  mbs_ = -1.;
218  }
219  // printf ("mbs_=%g\n", mbs_);
220  }
221  scene_list->push_back(this);
222  picker_ = NULL;
223  mark_ = false;
224  hoc_obj_ptr_ = NULL;
225 }
226 
227 void Scene::background(Glyph* bg) {
229  if (bg) {
230  background_ = bg;
231  } else {
233  }
235 }
236 
237 int Scene::tool() {
238  return tool_;
239 }
240 void Scene::tool(int t) {
241  tool_ = t;
242  notify();
243 }
244 
245 void Scene::help() {
246  switch (tool()) {
247  case MOVE:
248  Oc::help(Scene_Move_Text_);
249  break;
250  case DELETE:
251  Oc::help(Scene_Delete_);
252  break;
253  case CHANGECOLOR:
254  Oc::help(Scene_ChangeColor_);
255  break;
256  default:
257  printf("No help for this tool\n");
258  break;
259  }
260 }
261 
262 XYView* Scene::sceneview(int i) const {
263  if (views_->size() > i) {
264  return views_->at(i);
265  } else {
266  return NULL;
267  }
268 }
269 
270 void Scene::new_size(Coord x1, Coord y1, Coord x2, Coord y2) {
271  if (x1 == x2) {
272  x1 -= 1.;
273  x2 += 1.;
274  }
275  if (y1 == y2) {
276  y1 -= 1.;
277  y2 += 1.;
278  }
279  x1_ = x1;
280  y1_ = y1;
281  x2_ = x2;
282  y2_ = y2;
283 
284  // resize first view
285  if (!views_->empty()) {
286  XYView* v = views_->front();
287  // v->origin(x1, y1);
288  // v->x_span(x2 - x1);
289  // v->y_span(y2 - y1);
290  v->box_size(x1, y1, x2, y2);
291  if (v->canvas()) {
292  v->damage_all();
293  }
294  }
295 
296  notify();
297 }
298 
299 Scene::~Scene() {
300  // printf("~Scene\n");
301  for (auto& item: *info_) {
302  Resource::unref(item.glyph_);
303  }
304  delete info_;
305  info_ = nullptr;
307  if (picker_) {
308  delete picker_;
309  }
310  // only xyview can manipulate this list. when xyview is deleted it
311  // will remove itself from this list. There is no way to delete scene
312  // without first deleteing all the views.
313  assert(views_->empty());
314 
315  erase_first(*scene_list, this);
316  delete views_;
317 }
318 
319 void Scene::wholeplot(Coord& l, Coord& b, Coord& r, Coord& t) const {
320  l = x1();
321  b = y1();
322  r = x2();
323  t = y2();
324 }
325 
326 int Scene::view_count() const {
327  return int(views_->size());
328 }
329 
330 void Scene::append_view(XYView* v) {
331  views_->push_back(v);
332  // Resource::ref(v);
333 }
334 
335 void Scene::remove_view(XYView* v) {
336  erase_first(*views_, v);
337 }
338 
339 void Scene::dismiss() {
340  for (auto&& item: reverse(*views_)) {
341  OcViewGlyph* g = item->parent();
342  if (g && g->has_window()) {
343  g->window()->dismiss();
344  g->window(NULL);
345  }
346  }
347 }
348 
350  SceneInfo& info = info_->at(index);
351  Allocation& a = info.allocation_;
352  for (auto& item: *views_) {
353  // printf("damage view\n");
354  item->damage(info.glyph_,
355  a,
356  (info.status_ & SceneInfoFixed) != 0,
357  (info.status_ & SceneInfoViewFixed) != 0);
358  }
359 }
360 
361 void Scene::damage(GlyphIndex index, const Allocation& a) {
362  SceneInfo& info = info_->at(index);
363  for (auto& item: *views_) {
364  item->damage(info.glyph_,
365  a,
366  (info.status_ & SceneInfoFixed) != 0,
367  (info.status_ & SceneInfoViewFixed) != 0);
368  }
369 }
370 
371 void Scene::damage_all() {
372  for (auto& item: *views_) {
373  if (item->canvas()) {
374  item->damage_all();
375  }
376  }
377 }
378 
379 void Scene::damage(Coord x1, Coord y1, Coord x2, Coord y2) {
380  for (auto& item: *views_) {
381  item->damage(x1, y1, x2, y2);
382  }
383 }
384 
385 void Scene::show(GlyphIndex index, bool showing) {
386  SceneInfo& info = info_->at(index);
387  if (((info.status_ & SceneInfoShowing) == SceneInfoShowing) != showing) {
388  // printf("show %d showing=%d want %d\n", index, (info.status_ & SceneInfoHidden) == 0,
389  // showing); info.pinfo();
390  if (showing) {
391  info.status_ |= SceneInfoShowing;
392  } else {
393  info.status_ &= ~SceneInfoShowing;
394  }
395  modified(index);
396  }
397 }
398 
399 bool Scene::showing(GlyphIndex index) const {
400  return (info_->at(index).status_ & SceneInfoShowing) != 0;
401 }
402 
403 void Scene::move(GlyphIndex index, Coord x, Coord y) {
404  SceneInfo& info = info_->at(index);
405  float x1 = info.x_, y1 = info.y_;
406  info.x_ = x;
407  info.y_ = y;
408 
409  if (!(info.status_ & SceneInfoAllocated) || x1 != x || y1 != y) {
410  modified(index);
411  }
412 }
413 
414 void Scene::location(GlyphIndex index, Coord& x, Coord& y) const {
415  SceneInfo& info = info_->at(index);
416  x = info.x_;
417  y = info.y_;
418 }
419 
420 GlyphIndex Scene::count() const {
421  return info_->size();
422 }
423 
425  return info_->at(index).glyph_;
426 }
427 
429  a = info_->at(index).allocation_.allotment(res);
430 }
431 
433  modified(index);
434 }
435 
437  SceneInfo& info = info_->at(index);
438  if (info.status_ & SceneInfoViewFixed) {
439  info.status_ &= ~SceneInfoViewFixed;
440  printf("changed to fixed\n");
441  v->view_ratio(info.x_, info.y_, info.x_, info.y_);
442  v->s2o().transform(info.x_, info.y_);
443  }
444  info.status_ |= SceneInfoFixed;
445  modified(index);
446 }
447 
449  SceneInfo& info = info_->at(index);
450  if (!(info.status_ & SceneInfoViewFixed)) {
451  info.status_ |= SceneInfoViewFixed;
452  info.status_ |= SceneInfoFixed;
453  printf("changed to vfixed\n");
454  v->s2o().inverse_transform(info.x_, info.y_);
455  v->ratio_view(info.x_, info.y_, info.x_, info.y_);
456  }
457  modified(index);
458 }
459 
460 void Scene::append(Glyph* glyph) {
461  SceneInfo info(glyph);
462  info_->push_back(info);
463  Resource::ref(glyph);
464 }
465 
466 void Scene::append_fixed(Glyph* glyph) {
467  SceneInfo info(glyph);
468  info.status_ |= SceneInfoFixed;
469  info_->push_back(info);
470  Resource::ref(glyph);
471 }
472 
473 void Scene::append_viewfixed(Glyph* glyph) {
474  // printf("Scene::append_viewfixed\n");
475  SceneInfo info(glyph);
476  info.status_ |= SceneInfoFixed | SceneInfoViewFixed;
477  info_->push_back(info);
478  Resource::ref(glyph);
479 }
480 
481 void Scene::prepend(Glyph* glyph) {
482  SceneInfo info(glyph);
483  info_->insert(info_->begin(), info);
484  Resource::ref(glyph);
485  // modified(0);
486 }
487 
488 void Scene::insert(GlyphIndex index, Glyph* glyph) {
489  SceneInfo info(glyph);
490  info_->insert(info_->begin() + index, info);
491  Resource::ref(glyph);
492  // modified(index);
493 }
494 
496  SceneInfo& info = info_->at(index);
497  damage(index);
498  Resource::unref(info.glyph_);
499  info_->erase(info_->begin() + index);
500 }
501 
502 void Scene::replace(GlyphIndex index, Glyph* glyph) {
503  SceneInfo& info = info_->at(index);
504  damage(index);
505  Resource::ref(glyph);
506  Resource::unref(info.glyph_);
507  info.glyph_ = glyph;
508  modified(index);
509 }
510 
512  for (const auto&& [i, info]: enumerate(*info_)) {
513  if (info.glyph_ == g) {
514  return i;
515  }
516  }
517  return -1;
518 }
519 
520 void Scene::request(Requisition& req) const {
521 // printf("Scene::request\n");
522 #if 0
523  if (background_ != NULL) {
524  background_->request(requisition);
525  }
526 #endif
527  Requirement rx(x2() - x1(), 0, 0, -x1() / (x2() - x1()));
528  Requirement ry(y2() - y1(), 0, 0, -y1() / (y2() - y1()));
529  req.require_x(rx);
530  req.require_y(ry);
531 }
532 
533 void Scene::allocate(Canvas* c, const Allocation& a, Extension& ext) {
534  // printf("Scene::allocate\n");
535  for (std::size_t index: range(*info_)) {
537  }
538  ext.set(c, a);
539 }
540 
541 #if 0
542 #include <IV-X11/xcanvas.h>
543 #include <InterViews/transformer.h>
544 void candam(Canvas* c) {
545  const CanvasDamage& cd = c->rep()->damage_;
546  printf("damage %g %g %g %g\n", cd.left, cd.bottom, cd.right, cd.top);
547  const Transformer& t = c->transformer();
548  Coord x1, y1, x2, y2;
549  t.inverse_transform(cd.left, cd.bottom, x1, y1);
550  t.inverse_transform(cd.right, cd.top, x2, y2);
551  printf(" model %g %g %g %g\n", x1, y1, x2, y2);
552 }
553 #endif
554 
555 void Scene::draw(Canvas* canvas, const Allocation& a) const {
556  // printf("Scene::draw");
557  // candam(canvas);
558  if (background_ != NULL) {
559  background_->draw(canvas, a);
560  }
561  // the menu selection area
562  if (mbs() > 0.) {
563  Coord l, t;
564  canvas->transformer().transform(a.left(), a.top(), l, t);
565  if (canvas->damaged(l, t - mbs_, l + mbs_, t)) {
566  // printf("draw box at corner (%g, %g)\n", l, t);
567  canvas->push_transform();
568  Transformer tr;
569  canvas->transformer(tr);
570  canvas->rect(l, t - mbs_, l + mbs_, t, mb_color_, mb_brush_);
571  canvas->pop_transform();
572  }
573  }
574  bool are_fixed = false;
575  for (auto& info: *info_) {
576  if (info.status_ & SceneInfoFixed) {
577  are_fixed = true;
578  } else if (info.glyph_ != NULL && (info.status_ & SceneInfoShowing)) {
579  Allocation& a = info.allocation_;
580  Extension b;
581  b.set(canvas, a);
582  if (canvas->damaged(b)) {
583  info.glyph_->draw(canvas, a);
584  }
585  }
586  }
587 
588  if (are_fixed) {
589  ((Scene*) this)->drawing_fixed_item_ = true;
590  canvas->push_transform();
591  // Transformer tv;
592  // view_transform(canvas, 2, tv);
593  const Transformer& tv = XYView::current_draw_view()->s2o();
594  canvas->transform(tv);
595  IfIdraw(pict(tv));
596  for (auto& info: *info_) {
597  if ((info.status_ & SceneInfoFixed) && info.glyph_ != NULL &&
598  (info.status_ & SceneInfoShowing)) {
599  Allocation a = info.allocation_;
600  Coord x, y;
601  if (!(info.status_ & SceneInfoViewFixed)) {
602  tv.inverse_transform(a.x(), a.y(), x, y);
603  } else {
604  XYView::current_draw_view()->view_ratio(a.x(), a.y(), x, y);
605  }
606  a.x_allotment().origin(x);
607  a.y_allotment().origin(y);
608  Extension b;
609  b.set(canvas, a);
610  if (canvas->damaged(b)) {
611  info.glyph_->draw(canvas, a);
612  }
613  // printf("%d alloc %g %g %g %g\n", index, a.left(), a.bottom(), a.right(),
614  // a.top()); printf("%d exten %g %g %g %g\n", index, b.left(), b.bottom(),
615  // b.right(), b.top());
616  }
617  }
618  ((Scene*) this)->drawing_fixed_item_ = false;
619  canvas->pop_transform();
620  IfIdraw(end());
621  }
622 }
623 
624 void Scene::print(Printer* canvas, const Allocation& a) const {
625  if (background_ != NULL) {
626  background_->print(canvas, a);
627  }
628  bool are_fixed = false;
629  for (auto& info: *info_) {
630  if (info.status_ & SceneInfoFixed) {
631  are_fixed = true;
632  } else if (info.glyph_ != NULL && (info.status_ & SceneInfoShowing)) {
633  Allocation& a = info.allocation_;
634  Extension b;
635  b.set(canvas, a);
636  if (canvas->damaged(b)) {
637  info.glyph_->print(canvas, a);
638  }
639  }
640  }
641 
642  if (are_fixed) {
643  ((Scene*) this)->drawing_fixed_item_ = true;
644  canvas->push_transform();
645  // Transformer tv;
646  // view_transform(canvas, 2, tv);
647  const Transformer& tv = XYView::current_draw_view()->s2o();
648  canvas->transform(tv);
649  for (auto& info: *info_) {
650  if ((info.status_ & SceneInfoFixed) && info.glyph_ != NULL &&
651  (info.status_ & SceneInfoShowing)) {
652  Allocation a = info.allocation_;
653  Coord x, y;
654  if (!(info.status_ & SceneInfoViewFixed)) {
655  tv.inverse_transform(a.x(), a.y(), x, y);
656  } else {
657  XYView::current_draw_view()->view_ratio(a.x(), a.y(), x, y);
658  }
659  a.x_allotment().origin(x);
660  a.y_allotment().origin(y);
661  Extension b;
662  b.set(canvas, a);
663  if (canvas->damaged(b)) {
664  info.glyph_->print(canvas, a);
665  }
666  }
667  }
668  ((Scene*) this)->drawing_fixed_item_ = false;
669  canvas->pop_transform();
670  }
671 }
672 
673 void Scene::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
674  menu_picked_ = false;
675  if (mbs() > 0. && picker_ && h.event() && h.event()->type() == Event::down) {
676  Coord ax, ay, ex, ey;
677  c->transformer().transform(h.left(), h.top(), ex, ey);
678  c->transformer().transform(a.left(), a.top(), ax, ay);
679  // printf("a=(%g,%g) e=(%g,%g)\n", ax, ay, ex, ey);
680  if (MyMath::inside(ex, ey, ax, ay - mbs_, ax + mbs_, ay)) {
681  picker()->pick_menu(this, depth, h);
682  menu_picked_ = true;
683  return;
684  }
685  }
686  if (picker_ && picker()->pick(c, this, depth, h)) {
687  return;
688  }
689  if (background_ != NULL) {
690  background_->pick(c, a, depth, h);
691  }
692  // pick with some extra epsilon in canvas coords
695 
696  bool are_fixed = false;
697  for (auto&& [index, info]: enumerate(*info_)) {
698  if (info.status_ & SceneInfoFixed) {
699  are_fixed = true;
700  } else if (info.glyph_ != NULL && (info.status_ & SceneInfoShowing)) {
701  Allocation& a = info.allocation_;
702  if (h.right() >= a.left() - epsx && h.left() < a.right() + epsx &&
703  h.top() >= a.bottom() - epsy && h.bottom() < a.top() + epsy) {
704  h.begin(depth, this, index);
705  info.glyph_->pick(c, a, depth + 1, h);
706  h.end();
707  }
708  }
709  }
710 
711  if (are_fixed) {
712  // Transformer tv;
713  // view_transform(c, 2, tv);
714  const Transformer& tv = XYView::current_pick_view()->s2o();
715  float scx, scy, tmp;
716  tv.matrix(scx, tmp, tmp, scy, tmp, tmp);
717  for (auto&& [index, info]: enumerate(*info_)) {
718  if ((info.status_ & SceneInfoFixed) && info.glyph_ != NULL &&
719  (info.status_ & SceneInfoShowing)) {
720  Allocation a = info.allocation_;
721  Coord l, r, t, b;
722  if (info.status_ & SceneInfoViewFixed) {
723  Coord x, y;
724  XYView::current_pick_view()->view_ratio(a.x(), a.y(), x, y);
725  a.x_allotment().origin(x);
726  a.y_allotment().origin(y);
727  tv.transform(a.left(), a.bottom(), l, b);
728  tv.transform(a.right(), a.top(), r, t);
729  } else {
730  l = (a.left() - a.x()) * scx + a.x();
731  r = (a.right() - a.x()) * scx + a.x();
732  t = (a.top() - a.y()) * scy + a.y();
733  b = (a.bottom() - a.y()) * scy + a.y();
734  }
735  // printf("%g %g %g %g %g %g %g %g %g %g\n", a.left(), a.bottom(), a.right(),
736  // a.top(), l,r,t,b, h.left(), h.bottom());
737  if (h.right() >= l && h.left() < r && h.top() >= b && h.bottom() < t) {
738  h.begin(depth, this, index);
739  info.glyph_->pick(c, a, depth + 1, h);
740  h.end();
741  }
742  }
743  }
744  }
745 }
746 
748  auto it = std::find(scene_list->begin(), scene_list->end(), s);
749  if (it == scene_list->end()) {
750  return -1;
751  }
752  return std::distance(scene_list->begin(), it);
753 }
754 
755 void Scene::save_all(std::ostream& o) {
756  o << "objectvar save_window_, rvp_" << std::endl;
757  if (!scene_list) {
758  return;
759  }
760  if (!scene_list->empty()) {
761  o << "objectvar scene_vector_[" << scene_list->size() << "]" << std::endl;
762  }
763  for (auto& scene: *scene_list) {
764  scene->mark(false);
765  }
766 }
767 
768 void Scene::save_class(std::ostream& o, const char* s) {
769  // PrintableWindow* w = (PrintableWindow*)canvas()->window();
770  o << "save_window_ = new " << s << "(0)" << std::endl;
771  char buf[256];
772  Coord left, top, right, bottom;
773  if (view_count()) {
774  sceneview(0)->zin(left, bottom, right, top);
775  } else {
776  left = x1();
777  right = x2();
778  bottom = y1();
779  top = y2();
780  }
781 
782  Sprintf(buf, "save_window_.size(%g,%g,%g,%g)", left, right, bottom, top);
783  o << buf << std::endl;
784 }
785 
786 void Scene::save_phase1(std::ostream&) {}
787 void Scene::save_phase2(std::ostream&) {}
788 
789 void Scene::printfile(const char* fname) {
790  if (!views_->empty()) {
791  views_->front()->printfile(fname);
792  }
793 }
794 
795 void XYView::printfile(const char* fname) {
796  std::filebuf obuf;
797  if (!obuf.open(fname, std::ios::out)) {
798  return;
799  }
800  std::ostream o(&obuf);
801  EPSPrinter* pr = new EPSPrinter(&o);
802  Allocation a;
803  Allotment ax(0, xsize_, 0);
804  Allotment ay(0, ysize_, 0);
805  a.allot_x(ax);
806  a.allot_y(ay);
807  pr->eps_prolog(o, xsize_, ysize_);
808  pr->resize(0, 0, xsize_, ysize_);
809  pr->clip_rect(0, 0, xsize_, ysize_);
810  pr->damage_all();
811  print(pr, a);
812  pr->epilog();
813  undraw();
814  obuf.close();
815  delete pr;
817 }
818 
819 #endif
#define Background
Definition: _defines.h:41
#define Color
Definition: _defines.h:72
#define ColorIntensity
Definition: _defines.h:15
#define Transformer
Definition: _defines.h:313
#define Canvas
Definition: _defines.h:63
#define Style
Definition: _defines.h:278
#define Allotment
Definition: _defines.h:36
#define Coord
Definition: _defines.h:17
#define Brush
Definition: _defines.h:57
#define Hit
Definition: _defines.h:145
#define Printer
Definition: _defines.h:209
#define GlyphIndex
Definition: _defines.h:21
#define CanvasDamage
Definition: _defines.h:64
#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
bool equals(const Allocation &, float epsilon) const
Coord bottom() const
Definition: geometry.h:290
void allot(DimensionName, const Allotment &)
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 origin(Coord)
Definition: geometry.h:262
virtual void dismiss()
void set(Canvas *, const Allocation &)
static bool inside(Coord x, Coord min, Coord max)
Definition: mymath.h:91
virtual void notify()
Definition: observe.cpp:53
virtual PrintableWindow * window()
virtual bool has_window()
static void help(const char *)
static PrintableWindowManager * current()
void psfilter(const char *filename)
void require_x(const Requirement &)
Definition: geometry.h:243
void require_y(const Requirement &)
Definition: geometry.h:244
virtual void ref() const
Definition: resource.cpp:42
virtual void unref() const
Definition: resource.cpp:47
virtual GlyphIndex glyph_index(const Glyph *)
virtual void pick(Canvas *, const Allocation &, int depth, Hit &)
static long scene_list_index(Scene *)
virtual XYView * sceneview(int) const
void show(GlyphIndex, bool)
std::vector< XYView * > * views_
Definition: scenevie.h:333
virtual void printfile(const char *)
void move(GlyphIndex, Coord x, Coord y)
virtual Coord y2() const
Definition: scenevie.h:364
virtual void save_phase1(std::ostream &)
virtual void change_to_fixed(GlyphIndex, XYView *)
virtual void save_phase2(std::ostream &)
virtual Coord y1() const
Definition: scenevie.h:361
virtual void replace(GlyphIndex, Glyph *)
virtual void damage(GlyphIndex)
std::vector< SceneInfo > * info_
Definition: scenevie.h:332
virtual void allocate(Canvas *, const Allocation &, Extension &)
bool showing(GlyphIndex) const
virtual void background(Glyph *bg=NULL)
@ MOVE
Definition: scenevie.h:256
@ CHANGECOLOR
Definition: scenevie.h:256
@ DELETE
Definition: scenevie.h:256
virtual void append_viewfixed(Glyph *)
virtual void dismiss()
ScenePicker * picker()
Coord x2_
Definition: scenevie.h:331
static const Color * default_background()
void location(GlyphIndex, Coord &x, Coord &y) const
Scene(Coord x1, Coord y1, Coord x2, Coord y2, Glyph *background=NULL)
void check_allocation(GlyphIndex)
virtual void damage_all()
Glyph * background_
Definition: scenevie.h:334
virtual void append(Glyph *)
static Coord mbs_
Definition: scenevie.h:339
virtual void change_to_vfixed(GlyphIndex, XYView *)
virtual void new_size(Coord x1, Coord y1, Coord x2, Coord y2)
Coord y2_
Definition: scenevie.h:331
virtual void prepend(Glyph *)
void remove_view(XYView *)
virtual int tool()
static const Color * default_foreground()
virtual void change(GlyphIndex)
bool menu_picked_
Definition: scenevie.h:342
virtual void save_class(std::ostream &, const char *)
virtual int view_count() const
virtual void request(Requisition &) const
virtual void wholeplot(Coord &x1, Coord &y1, Coord &x2, Coord &y2) const
ScenePicker * picker_
Definition: scenevie.h:335
Coord y1_
Definition: scenevie.h:331
virtual ~Scene()
Coord x1_
Definition: scenevie.h:331
virtual Coord x2() const
Definition: scenevie.h:358
virtual GlyphIndex count() const
virtual Glyph * component(GlyphIndex) const
virtual void remove(GlyphIndex)
int tool_
Definition: scenevie.h:336
virtual Coord x1() const
Definition: scenevie.h:355
virtual void insert(GlyphIndex, Glyph *)
static void save_all(std::ostream &)
virtual void allotment(GlyphIndex, DimensionName, Allotment &) const
void append_view(XYView *)
virtual void print(Printer *, const Allocation &) const
virtual void append_fixed(Glyph *)
virtual void help()
virtual void modified(GlyphIndex)
virtual void draw(Canvas *, const Allocation &) const
virtual Coord mbs() const
virtual void pick_menu(Glyph *, int, Hit &)
void event(const Event &)
Coord x_pick_epsilon()
Definition: scenevie.h:151
virtual void view_ratio(float xratio, float yratio, Coord &x, Coord &y) const
virtual void printfile(const char *)
virtual void undraw()
Coord xsize_
Definition: scenevie.h:191
Coord ysize_
Definition: scenevie.h:191
virtual void zin(Coord &x1, Coord &y1, Coord &x2, Coord &y2) const
static XYView * current_draw_view()
static XYView * current_pick_view()
const Transformer & s2o() const
Definition: scenevie.h:137
Coord y_pick_epsilon()
Definition: scenevie.h:154
#define v
Definition: md1redef.h:11
#define i
Definition: md1redef.h:19
#define y_(arg)
Crout matrix decomposition : Forward/Backward substitution.
Definition: crout.hpp:136
void erase_first(T &&iterable, value_type &&value)
Definition: enumerate.h:22
constexpr auto reverse(T &&iterable)
Definition: enumerate.h:62
constexpr auto range(T &&iterable)
Definition: enumerate.h:32
constexpr auto enumerate(T &&iterable)
Definition: enumerate.h:90
@ Dimension_Y
Definition: geometry.h:39
@ 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 assert(ex)
Definition: hocassrt.h:24
#define IfIdraw(arg)
Definition: idraw.h:102
Symbol * lookup(const char *)
printf
Definition: extdef.h:5
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
static List * info
void distance()
Definition: solve.cpp:226
s
Definition: multisend.cpp:521
short index
Definition: cabvars.h:11
static void pr(N_Vector x)
static N_Vector x_
int find(const int, const int, const int, const int, const int)
#define NULL
Definition: spdefs.h:105