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 <ivstream.h>
37 #include <stdio.h>
38 #include <assert.h>
39 
40 #include <InterViews/canvas.h>
41 #include <InterViews/hit.h>
42 #include <InterViews/session.h>
43 #include <InterViews/style.h>
44 #include <InterViews/color.h>
45 #include <InterViews/brush.h>
46 #include <InterViews/background.h>
47 #include <OS/list.h>
48 
49 #include "mymath.h"
50 #include "epsprint.h"
51 #include "scenevie.h"
52 #include "scenepic.h"
53 #include "idraw.h"
54 #include "ivoc.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 declareList(SceneInfo_List, SceneInfo);
97 implementList(SceneInfo_List, SceneInfo);
98 declarePtrList(XYView_PtrList, XYView);
99 implementPtrList(XYView_PtrList, XYView);
100 declarePtrList(Scene_PtrList, Scene);
101 implementPtrList(Scene_PtrList, Scene);
102 
103 static const float epsilon = 0.001;
104 static Scene_PtrList* scene_list;
105 
107 Coord Scene::mbs() const {
108  return mbs_;
109 }
110 static const Brush* mb_brush_;
111 static const Color* mb_color_;
112 
114  // will not redraw unless allocation is changed
115  // use damage(index) to do a definite redraw on a constant allocation
116  SceneInfo& info = info_->item_ref(index);
117  Requisition s;
118  info.glyph_->request(s);
119  Allocation a_old = info.allocation_;
120  Allocation& a = info.allocation_;
121  Allotment ax = Allotment(info.x_,
124  Allotment ay = Allotment(info.y_,
127  a.allot(Dimension_X, ax);
128  a.allot(Dimension_Y, ay);
129  if (info.status_ & SceneInfoAllocated) {
130  if (!a_old.equals(a, epsilon)) {
131  damage(index, a_old);
132  damage(index);
133  }
134  } else {
135  damage(index);
136  }
137  info.status_ |= SceneInfoAllocated;
138 }
139 
141  // will not redraw unless allocation is changed
142  // use damage(index) to do a definite redraw on a constant allocation
143  SceneInfo& info = info_->item_ref(index);
144  Requisition s;
145  info.glyph_->request(s);
146  Allocation a_old = info.allocation_;
147  Allocation& a = info.allocation_;
148  Allotment ax = Allotment(info.x_,
151  Allotment ay = Allotment(info.y_,
154  a.allot(Dimension_X, ax);
155  a.allot(Dimension_Y, ay);
156  // printf("Scene::modified(%d) allocation %g %g %g %g\n", index, a.left(), a.bottom(),
157  // a.right(), a.top());
158  if ((info.status_ & SceneInfoAllocated) && !a_old.equals(a, epsilon)) {
159  // printf("damaged\n");
160  damage(index, a_old);
161  }
162  damage(index);
163  info.status_ |= SceneInfoAllocated;
164 }
165 
166 static const Color* scene_background_;
167 static const Color* scene_foreground_;
168 
170  if (!scene_background_) {
171  Style* s = Session::instance()->style();
172  String c;
173  if (!s->find_attribute("Scene_background", c) ||
174  (scene_background_ = Color::lookup(Session::instance()->default_display(), c)) ==
175  NULL) {
176  scene_background_ = Color::lookup(Session::instance()->default_display(), "#ffffff");
177  }
178  Resource::ref(scene_background_);
179  }
180  return scene_background_;
181 }
182 
184  if (!scene_foreground_) {
185  Style* s = Session::instance()->style();
186  String c;
187  if (!s->find_attribute("Scene_foreground", c) ||
188  (scene_foreground_ = Color::lookup(Session::instance()->default_display(), c)) ==
189  NULL) {
190  scene_foreground_ = Color::lookup(Session::instance()->default_display(), "#000000");
191  }
192  Resource::ref(scene_foreground_);
193  }
194  return scene_foreground_;
195 }
196 
197 Scene::Scene(Coord x1, Coord y1, Coord x2, Coord y2, Glyph* bg)
198  : Glyph() {
199  drawing_fixed_item_ = false;
200  tool_ = NOTOOL;
201  background_ = NULL;
202  background(bg);
203  info_ = new SceneInfo_List();
204  views_ = new XYView_PtrList();
205  x1_orig_ = x1;
206  x2_orig_ = x2;
207  y1_orig_ = y1;
208  y2_orig_ = y2;
209  x1_ = x1;
210  x2_ = x2;
211  y1_ = y1;
212  y2_ = y2;
213  if (!scene_list) {
214  scene_list = new Scene_PtrList;
215  }
216  if (mbs_ == 0.) {
217 #if MAC
218  mbs_ = 10.;
219 #endif
220  Session::instance()->style()->find_attribute("scene_menu_box_size", mbs_);
221  if (mbs_ > 0.) {
222  mb_color_ = new Color(ColorIntensity(.5), ColorIntensity(.5), ColorIntensity(.5));
223  mb_brush_ = new Brush(1);
224  Resource::ref(mb_color_);
225  Resource::ref(mb_brush_);
226  } else {
227  mbs_ = -1.;
228  }
229  // printf ("mbs_=%g\n", mbs_);
230  }
231  scene_list->append(this);
232  picker_ = NULL;
233  mark_ = false;
234  hoc_obj_ptr_ = NULL;
235 }
236 
237 void Scene::background(Glyph* bg) {
239  if (bg) {
240  background_ = bg;
241  } else {
243  }
245 }
246 
247 int Scene::tool() {
248  return tool_;
249 }
250 void Scene::tool(int t) {
251  tool_ = t;
252  notify();
253 }
254 
255 void Scene::help() {
256  switch (tool()) {
257  case MOVE:
258  Oc::help(Scene_Move_Text_);
259  break;
260  case DELETE:
261  Oc::help(Scene_Delete_);
262  break;
263  case CHANGECOLOR:
264  Oc::help(Scene_ChangeColor_);
265  break;
266  default:
267  printf("No help for this tool\n");
268  break;
269  }
270 }
271 
272 XYView* Scene::sceneview(int i) const {
273  if (views_->count()) {
274  return views_->item(i);
275  } else {
276  return NULL;
277  }
278 }
279 
280 void Scene::new_size(Coord x1, Coord y1, Coord x2, Coord y2) {
281 #if 1
282  if (x1 == x2) {
283  x1 -= 1.;
284  x2 += 1.;
285  }
286  if (y1 == y2) {
287  y1 -= 1.;
288  y2 += 1.;
289  }
290  x1_ = x1;
291  y1_ = y1;
292  x2_ = x2;
293  y2_ = y2;
294 #endif
295 #if 1
296  // resize first view
297  if (views_->count()) {
298  XYView* v = views_->item(0);
299  // v->origin(x1, y1);
300  // v->x_span(x2 - x1);
301  // v->y_span(y2 - y1);
302  v->box_size(x1, y1, x2, y2);
303  if (v->canvas()) {
304  v->damage_all();
305  }
306  }
307 #endif
308 
309 #if 0
310  //resize all views to correspond to the new size
311  damage_all();
312  for (long i = 0; i < views_->count(); ++i) {
313  XYView* v = views_->item(i);
314  v->x_span(x2 - x1);
315  v->y_span(y2 - y1);
316  v->origin(x1, y1);
317  }
318  GlyphIndex count = info_->count();
319  for (i=0; i < count; ++i) {
320  modified(i);
321  }
322 #endif
323  notify();
324 }
325 
326 Scene::~Scene() {
327  // printf("~Scene\n");
328  GlyphIndex count = info_->count();
329  for (GlyphIndex i = 0; i < count; ++i) {
330  SceneInfo& info = info_->item_ref(i);
331  Resource::unref(info.glyph_);
332  }
333  delete info_;
334  info_ = NULL;
336  if (picker_) {
337  delete picker_;
338  }
339  // only xyview can manipulate this list. when xyview is deleted it
340  // will remove itself from this list. There is no way to delete scene
341  // without first deleteing all the views.
342  assert(views_->count() == 0);
343 
344 #if 0
345  count = views_->count();
346  for (i = 0; i < count; ++i) {
347  XYView* view = views_->item(i);
348  Resource::unref(view);
349  }
350  views_->remove_all();
351 #endif
352  for (long j = 0; j < scene_list->count(); ++j) {
353  if (scene_list->item(j) == this) {
354  scene_list->remove(j);
355  break;
356  }
357  }
358  delete views_;
359 }
360 
361 void Scene::wholeplot(Coord& l, Coord& b, Coord& r, Coord& t) const {
362  l = x1();
363  b = y1();
364  r = x2();
365  t = y2();
366 }
367 
368 int Scene::view_count() const {
369  return int(views_->count());
370 }
371 
372 void Scene::append_view(XYView* v) {
373  views_->append(v);
374  // Resource::ref(v);
375 }
376 
377 void Scene::remove_view(XYView* v) {
378  long count = views_->count();
379  for (long i = 0; i < count; ++i) {
380  if (v == views_->item(i)) {
381  views_->remove(i);
382  break;
383  // Resource::unref(v);
384  }
385  }
386 }
387 
388 void Scene::dismiss() {
389  long count = views_->count();
390  for (long i = count - 1; i >= 0; --i) {
391  OcViewGlyph* g = views_->item(i)->parent();
392  if (g && g->has_window()) {
393  g->window()->dismiss();
394  g->window(NULL);
395  }
396  }
397 }
398 
400  SceneInfo& info = info_->item_ref(index);
401  Allocation& a = info.allocation_;
402  long count = views_->count();
403  for (long i = 0; i < count; ++i) {
404  // printf("damage view\n");
405  XYView* view = views_->item(i);
406  view->damage(info.glyph_,
407  a,
408  (info.status_ & SceneInfoFixed) != 0,
409  (info.status_ & SceneInfoViewFixed) != 0);
410  }
411 }
412 
413 void Scene::damage(GlyphIndex index, const Allocation& a) {
414  SceneInfo& info = info_->item_ref(index);
415  long count = views_->count();
416  for (long i = 0; i < count; ++i) {
417  XYView* view = views_->item(i);
418  view->damage(info.glyph_,
419  a,
420  (info.status_ & SceneInfoFixed) != 0,
421  (info.status_ & SceneInfoViewFixed) != 0);
422  }
423 }
424 
425 void Scene::damage_all() {
426  for (long i = 0; i < views_->count(); ++i) {
427  XYView* v = views_->item(i);
428  if (v->canvas()) {
429  v->damage_all();
430  }
431  }
432 }
433 
434 void Scene::damage(Coord x1, Coord y1, Coord x2, Coord y2) {
435  long count = views_->count();
436  for (long i = 0; i < count; ++i) {
437  XYView* view = views_->item(i);
438  view->damage(x1, y1, x2, y2);
439  }
440 }
441 
442 void Scene::show(GlyphIndex index, bool showing) {
443  SceneInfo& info = info_->item_ref(index);
444  if (((info.status_ & SceneInfoShowing) == SceneInfoShowing) != showing) {
445  // printf("show %d showing=%d want %d\n", index, (info.status_ & SceneInfoHidden) == 0,
446  // showing); info.pinfo();
447  if (showing) {
448  info.status_ |= SceneInfoShowing;
449  } else {
450  info.status_ &= ~SceneInfoShowing;
451  }
452  modified(index);
453  }
454 }
455 
456 bool Scene::showing(GlyphIndex index) const {
457  return (info_->item_ref(index).status_ & SceneInfoShowing) != 0;
458 }
459 
460 void Scene::move(GlyphIndex index, Coord x, Coord y) {
461  SceneInfo& info = info_->item_ref(index);
462  float x1 = info.x_, y1 = info.y_;
463  info.x_ = x;
464  info.y_ = y;
465 
466  if (!(info.status_ & SceneInfoAllocated) || x1 != x || y1 != y) {
467  modified(index);
468  }
469 }
470 
471 void Scene::location(GlyphIndex index, Coord& x, Coord& y) const {
472  SceneInfo& info = info_->item_ref(index);
473  x = info.x_;
474  y = info.y_;
475 }
476 
477 GlyphIndex Scene::count() const {
478  return info_->count();
479 }
480 
482  return info_->item_ref(index).glyph_;
483 }
484 
486  a = info_->item_ref(index).allocation_.allotment(res);
487 }
488 
490  modified(index);
491 }
492 
494  SceneInfo& info = info_->item_ref(index);
495  if (info.status_ & SceneInfoViewFixed) {
496  info.status_ &= ~SceneInfoViewFixed;
497  printf("changed to fixed\n");
498  v->view_ratio(info.x_, info.y_, info.x_, info.y_);
499  v->s2o().transform(info.x_, info.y_);
500  }
501  info.status_ |= SceneInfoFixed;
502  modified(index);
503 }
504 
506  SceneInfo& info = info_->item_ref(index);
507  if (!(info.status_ & SceneInfoViewFixed)) {
508  info.status_ |= SceneInfoViewFixed;
509  info.status_ |= SceneInfoFixed;
510  printf("changed to vfixed\n");
511  v->s2o().inverse_transform(info.x_, info.y_);
512  v->ratio_view(info.x_, info.y_, info.x_, info.y_);
513  }
514  modified(index);
515 }
516 
517 void Scene::append(Glyph* glyph) {
518  SceneInfo info(glyph);
519  info_->append(info);
520  Resource::ref(glyph);
521  // modified(info_->count() - 1);
522 }
523 
524 void Scene::append_fixed(Glyph* glyph) {
525  SceneInfo info(glyph);
526  info.status_ |= SceneInfoFixed;
527  info_->append(info);
528  Resource::ref(glyph);
529  // modified(info_->count() - 1);
530 }
531 
532 void Scene::append_viewfixed(Glyph* glyph) {
533  // printf("Scene::append_viewfixed\n");
534  SceneInfo info(glyph);
535  info.status_ |= SceneInfoFixed | SceneInfoViewFixed;
536  info_->append(info);
537  Resource::ref(glyph);
538  // modified(info_->count() - 1);
539 }
540 
541 void Scene::prepend(Glyph* glyph) {
542  SceneInfo info(glyph);
543  info_->prepend(info);
544  Resource::ref(glyph);
545  // modified(0);
546 }
547 
548 void Scene::insert(GlyphIndex index, Glyph* glyph) {
549  SceneInfo info(glyph);
550  info_->insert(index, info);
551  Resource::ref(glyph);
552  // modified(index);
553 }
554 
556  SceneInfo& info = info_->item_ref(index);
557  damage(index);
558  Resource::unref(info.glyph_);
559  info_->remove(index);
560 }
561 
562 void Scene::replace(GlyphIndex index, Glyph* glyph) {
563  SceneInfo& info = info_->item_ref(index);
564  damage(index);
565  Resource::ref(glyph);
566  Resource::unref(info.glyph_);
567  info.glyph_ = glyph;
568  modified(index);
569 }
570 
572  GlyphIndex i, cnt = info_->count();
573  ;
574  for (i = 0; i < cnt; ++i) {
575  if (info_->item_ref(i).glyph_ == g) {
576  return i;
577  }
578  }
579  return -1;
580 }
581 
582 void Scene::request(Requisition& req) const {
583 // printf("Scene::request\n");
584 #if 0
585  if (background_ != NULL) {
586  background_->request(requisition);
587  }
588 #endif
589  Requirement rx(x2() - x1(), 0, 0, -x1() / (x2() - x1()));
590  Requirement ry(y2() - y1(), 0, 0, -y1() / (y2() - y1()));
591  req.require_x(rx);
592  req.require_y(ry);
593 }
594 
595 void Scene::allocate(Canvas* c, const Allocation& a, Extension& ext) {
596  // printf("Scene::allocate\n");
597  GlyphIndex count = info_->count();
598  for (GlyphIndex index = 0; index < count; ++index) {
600  }
601  ext.set(c, a);
602 }
603 
604 #if 0
605 #include <IV-X11/xcanvas.h>
606 #include <InterViews/transformer.h>
607 void candam(Canvas* c) {
608  const CanvasDamage& cd = c->rep()->damage_;
609  printf("damage %g %g %g %g\n", cd.left, cd.bottom, cd.right, cd.top);
610  const Transformer& t = c->transformer();
611  Coord x1, y1, x2, y2;
612  t.inverse_transform(cd.left, cd.bottom, x1, y1);
613  t.inverse_transform(cd.right, cd.top, x2, y2);
614  printf(" model %g %g %g %g\n", x1, y1, x2, y2);
615 }
616 #endif
617 
618 void Scene::draw(Canvas* canvas, const Allocation& a) const {
619  // printf("Scene::draw");
620  // candam(canvas);
621  if (background_ != NULL) {
622  background_->draw(canvas, a);
623  }
624  // the menu selection area
625  if (mbs() > 0.) {
626  Coord l, t;
627  canvas->transformer().transform(a.left(), a.top(), l, t);
628  if (canvas->damaged(l, t - mbs_, l + mbs_, t)) {
629  // printf("draw box at corner (%g, %g)\n", l, t);
630  canvas->push_transform();
631  Transformer tr;
632  canvas->transformer(tr);
633  canvas->rect(l, t - mbs_, l + mbs_, t, mb_color_, mb_brush_);
634  canvas->pop_transform();
635  }
636  }
637  GlyphIndex count = info_->count();
638  bool are_fixed = false;
639  for (GlyphIndex index = 0; index < count; ++index) {
640  SceneInfo& info = info_->item_ref(index);
641  if (info.status_ & SceneInfoFixed) {
642  are_fixed = true;
643  } else if (info.glyph_ != NULL && (info.status_ & SceneInfoShowing)) {
644  Allocation& a = info.allocation_;
645  Extension b;
646  b.set(canvas, a);
647  // printf("%d alloc %g %g %g %g\n", index, a.left(), a.bottom(), a.right(), a.top());
648  // printf("%d exten %g %g %g %g\n", index, b.left(), b.bottom(), b.right(), b.top());
649  if (canvas->damaged(b)) {
650  info.glyph_->draw(canvas, a);
651  }
652  }
653  }
654 
655  if (are_fixed) {
656  ((Scene*) this)->drawing_fixed_item_ = true;
657  canvas->push_transform();
658  // Transformer tv;
659  // view_transform(canvas, 2, tv);
660  const Transformer& tv = XYView::current_draw_view()->s2o();
661  canvas->transform(tv);
662  IfIdraw(pict(tv));
663  for (GlyphIndex index = 0; index < count; ++index) {
664  SceneInfo& info = info_->item_ref(index);
665  if ((info.status_ & SceneInfoFixed) && info.glyph_ != NULL &&
666  (info.status_ & SceneInfoShowing)) {
667  Allocation a = info.allocation_;
668  Coord x, y;
669  if (!(info.status_ & SceneInfoViewFixed)) {
670  tv.inverse_transform(a.x(), a.y(), x, y);
671  } else {
672  XYView::current_draw_view()->view_ratio(a.x(), a.y(), x, y);
673  }
674  a.x_allotment().origin(x);
675  a.y_allotment().origin(y);
676  Extension b;
677  b.set(canvas, a);
678  if (canvas->damaged(b)) {
679  info.glyph_->draw(canvas, a);
680  }
681  // printf("%d alloc %g %g %g %g\n", index, a.left(), a.bottom(), a.right(),
682  // a.top()); printf("%d exten %g %g %g %g\n", index, b.left(), b.bottom(),
683  // b.right(), b.top());
684  }
685  }
686  ((Scene*) this)->drawing_fixed_item_ = false;
687  canvas->pop_transform();
688  IfIdraw(end());
689  }
690 }
691 
692 void Scene::print(Printer* canvas, const Allocation& a) const {
693  if (background_ != NULL) {
694  background_->print(canvas, a);
695  }
696  GlyphIndex count = info_->count();
697  bool are_fixed = false;
698  for (GlyphIndex index = 0; index < count; ++index) {
699  SceneInfo& info = info_->item_ref(index);
700  if (info.status_ & SceneInfoFixed) {
701  are_fixed = true;
702  } else if (info.glyph_ != NULL && (info.status_ & SceneInfoShowing)) {
703  Allocation& a = info.allocation_;
704  Extension b;
705  b.set(canvas, a);
706  if (canvas->damaged(b)) {
707  info.glyph_->print(canvas, a);
708  }
709  }
710  }
711 
712  if (are_fixed) {
713  ((Scene*) this)->drawing_fixed_item_ = true;
714  canvas->push_transform();
715  // Transformer tv;
716  // view_transform(canvas, 2, tv);
717  const Transformer& tv = XYView::current_draw_view()->s2o();
718  canvas->transform(tv);
719  for (GlyphIndex index = 0; index < count; ++index) {
720  SceneInfo& info = info_->item_ref(index);
721  if ((info.status_ & SceneInfoFixed) && info.glyph_ != NULL &&
722  (info.status_ & SceneInfoShowing)) {
723  Allocation a = info.allocation_;
724  Coord x, y;
725  if (!(info.status_ & SceneInfoViewFixed)) {
726  tv.inverse_transform(a.x(), a.y(), x, y);
727  } else {
728  XYView::current_draw_view()->view_ratio(a.x(), a.y(), x, y);
729  }
730  a.x_allotment().origin(x);
731  a.y_allotment().origin(y);
732  Extension b;
733  b.set(canvas, a);
734  if (canvas->damaged(b)) {
735  info.glyph_->print(canvas, a);
736  }
737  }
738  }
739  ((Scene*) this)->drawing_fixed_item_ = false;
740  canvas->pop_transform();
741  }
742 }
743 
744 void Scene::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
745  menu_picked_ = false;
746  if (mbs() > 0. && picker_ && h.event() && h.event()->type() == Event::down) {
747  Coord ax, ay, ex, ey;
748  c->transformer().transform(h.left(), h.top(), ex, ey);
749  c->transformer().transform(a.left(), a.top(), ax, ay);
750  // printf("a=(%g,%g) e=(%g,%g)\n", ax, ay, ex, ey);
751  if (MyMath::inside(ex, ey, ax, ay - mbs_, ax + mbs_, ay)) {
752  picker()->pick_menu(this, depth, h);
753  menu_picked_ = true;
754  return;
755  }
756  }
757  if (picker_ && picker()->pick(c, this, depth, h)) {
758  return;
759  }
760  if (background_ != NULL) {
761  background_->pick(c, a, depth, h);
762  }
763  GlyphIndex count = info_->count();
764 #if 0
765  for (GlyphIndex index = 0; index < count; ++index) {
766  SceneInfo& info = info_->item_ref(index);
767  if (info.glyph_ != NULL && (info.status_ & SceneInfoShowing)) {
768  Allocation& a = info.allocation_;
769  if (
770  h.right() >= a.left() && h.left() < a.right()
771  && h.top() >= a.bottom() && h.bottom() < a.top()
772  ) {
773  h.begin(depth, this, index);
774  info.glyph_->pick(c, a, depth + 1, h);
775  h.end();
776  }
777  }
778  }
779 #else
780  // pick with some extra epsilon in canvas coords
783 
784  bool are_fixed = false;
785  for (GlyphIndex index = 0; index < count; ++index) {
786  SceneInfo& info = info_->item_ref(index);
787  if (info.status_ & SceneInfoFixed) {
788  are_fixed = true;
789  } else if (info.glyph_ != NULL && (info.status_ & SceneInfoShowing)) {
790  Allocation& a = info.allocation_;
791  if (h.right() >= a.left() - epsx && h.left() < a.right() + epsx &&
792  h.top() >= a.bottom() - epsy && h.bottom() < a.top() + epsy) {
793  h.begin(depth, this, index);
794  info.glyph_->pick(c, a, depth + 1, h);
795  h.end();
796  }
797  }
798  }
799 
800  if (are_fixed) {
801  // Transformer tv;
802  // view_transform(c, 2, tv);
803  const Transformer& tv = XYView::current_pick_view()->s2o();
804  float scx, scy, tmp;
805  tv.matrix(scx, tmp, tmp, scy, tmp, tmp);
806  for (GlyphIndex index = 0; index < count; ++index) {
807  SceneInfo& info = info_->item_ref(index);
808  if ((info.status_ & SceneInfoFixed) && info.glyph_ != NULL &&
809  (info.status_ & SceneInfoShowing)) {
810  Allocation a = info.allocation_;
811  Coord l, r, t, b;
812  if (info.status_ & SceneInfoViewFixed) {
813  Coord x, y;
814  XYView::current_pick_view()->view_ratio(a.x(), a.y(), x, y);
815  a.x_allotment().origin(x);
816  a.y_allotment().origin(y);
817  tv.transform(a.left(), a.bottom(), l, b);
818  tv.transform(a.right(), a.top(), r, t);
819  } else {
820  l = (a.left() - a.x()) * scx + a.x();
821  r = (a.right() - a.x()) * scx + a.x();
822  t = (a.top() - a.y()) * scy + a.y();
823  b = (a.bottom() - a.y()) * scy + a.y();
824  }
825  // printf("%g %g %g %g %g %g %g %g %g %g\n", a.left(), a.bottom(), a.right(),
826  // a.top(), l,r,t,b, h.left(), h.bottom());
827  if (h.right() >= l && h.left() < r && h.top() >= b && h.bottom() < t) {
828  h.begin(depth, this, index);
829  info.glyph_->pick(c, a, depth + 1, h);
830  h.end();
831  }
832  }
833  }
834  }
835 #endif
836 }
837 
839  long i, cnt = scene_list->count();
840  for (i = 0; i < cnt; ++i) {
841  if (s == scene_list->item(i)) {
842  return i;
843  }
844  }
845  return -1;
846 }
847 
848 void Scene::save_all(ostream& o) {
849  char buf[200];
850  o << "objectvar save_window_, rvp_" << endl;
851  if (!scene_list) {
852  return;
853  }
854  long count = scene_list->count();
855  if (count) {
856  sprintf(buf, "objectvar scene_vector_[%ld]", count);
857  o << buf << endl;
858  }
859  for (long i = 0; i < count; ++i) {
860  Scene* s = scene_list->item(i);
861  s->mark(false);
862  }
863 }
864 
865 void Scene::save_class(ostream& o, const char* s) {
866  long count = views_->count();
867  // PrintableWindow* w = (PrintableWindow*)canvas()->window();
868  o << "save_window_ = new " << s << "(0)" << endl;
869  char buf[256];
870  Coord left, top, right, bottom;
871  if (view_count()) {
872  sceneview(0)->zin(left, bottom, right, top);
873  } else {
874  left = x1();
875  right = x2();
876  bottom = y1();
877  top = y2();
878  }
879 
880  sprintf(buf, "save_window_.size(%g,%g,%g,%g)", left, right, bottom, top);
881  o << buf << endl;
882 }
883 
884 void Scene::save_phase1(ostream&) {}
885 void Scene::save_phase2(ostream&) {}
886 
887 void Scene::printfile(const char* fname) {
888  if (view_count()) {
889  views_->item(0)->printfile(fname);
890  }
891 }
892 
893 void XYView::printfile(const char* fname) {
894  filebuf obuf;
895  if (!obuf.open(fname, IOS_OUT)) {
896  return;
897  }
898  ostream o(&obuf);
899  EPSPrinter* pr = new EPSPrinter(&o);
900  Allocation a;
901  Allotment ax(0, xsize_, 0);
902  Allotment ay(0, ysize_, 0);
903  a.allot_x(ax);
904  a.allot_y(ay);
905  pr->eps_prolog(o, xsize_, ysize_);
906  pr->resize(0, 0, xsize_, ysize_);
907  pr->clip_rect(0, 0, xsize_, ysize_);
908  pr->damage_all();
909  print(pr, a);
910  pr->epilog();
911  undraw();
912  obuf.close();
913  delete pr;
915 }
916 
917 #endif
#define Background
Definition: _defines.h:43
#define Color
Definition: _defines.h:74
#define ColorIntensity
Definition: _defines.h:17
#define Transformer
Definition: _defines.h:316
#define Canvas
Definition: _defines.h:65
#define Style
Definition: _defines.h:281
#define Allotment
Definition: _defines.h:38
#define Coord
Definition: _defines.h:19
#define Brush
Definition: _defines.h:59
#define Hit
Definition: _defines.h:147
#define Printer
Definition: _defines.h:211
#define GlyphIndex
Definition: _defines.h:23
#define CanvasDamage
Definition: _defines.h:66
#define Glyph
Definition: _defines.h:132
short index
Definition: cabvars.h:10
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
bool equals(const Allocation &, float epsilon) const
Coord bottom() const
Definition: geometry.h:294
void allot(DimensionName, const Allotment &)
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 origin(Coord)
Definition: geometry.h:266
void set(Canvas *, const Allocation &)
static bool inside(Coord x, Coord min, Coord max)
Definition: mymath.h:94
virtual void notify()
Definition: observe.cpp:75
static void help(const char *)
static PrintableWindowManager * current()
void psfilter(const char *filename)
void alignment(float)
Definition: geometry.h:241
void natural(Coord)
Definition: geometry.h:235
void require_x(const Requirement &)
Definition: geometry.h:247
void require_y(const Requirement &)
Definition: geometry.h:248
const Requirement & requirement(DimensionName) const
virtual void ref() const
Definition: resource.cpp:47
virtual void unref() const
Definition: resource.cpp:52
virtual GlyphIndex glyph_index(const Glyph *)
virtual void pick(Canvas *, const Allocation &, int depth, Hit &)
static long scene_list_index(Scene *)
SceneInfo_List * info_
Definition: scenevie.h:334
virtual XYView * sceneview(int) const
void show(GlyphIndex, bool)
virtual void printfile(const char *)
void move(GlyphIndex, Coord x, Coord y)
virtual Coord y2() const
Definition: scenevie.h:366
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:363
virtual void replace(GlyphIndex, Glyph *)
virtual void damage(GlyphIndex)
virtual void allocate(Canvas *, const Allocation &, Extension &)
bool showing(GlyphIndex) const
virtual void background(Glyph *bg=NULL)
virtual void append_viewfixed(Glyph *)
virtual void dismiss()
ScenePicker * picker()
Coord x2_
Definition: scenevie.h:333
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:336
virtual void append(Glyph *)
static Coord mbs_
Definition: scenevie.h:341
virtual void change_to_vfixed(GlyphIndex, XYView *)
virtual void new_size(Coord x1, Coord y1, Coord x2, Coord y2)
Coord y2_
Definition: scenevie.h:333
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:344
virtual void save_class(std::ostream &, const char *)
virtual int view_count() const
bool mark()
Definition: scenevie.h:292
virtual void request(Requisition &) const
virtual void wholeplot(Coord &x1, Coord &y1, Coord &x2, Coord &y2) const
ScenePicker * picker_
Definition: scenevie.h:337
Coord y1_
Definition: scenevie.h:333
virtual ~Scene()
Coord x1_
Definition: scenevie.h:333
virtual Coord x2() const
Definition: scenevie.h:360
virtual GlyphIndex count() const
virtual Glyph * component(GlyphIndex) const
virtual void remove(GlyphIndex)
@ MOVE
Definition: scenevie.h:258
@ CHANGECOLOR
Definition: scenevie.h:258
@ DELETE
Definition: scenevie.h:258
int tool_
Definition: scenevie.h:338
virtual Coord x1() const
Definition: scenevie.h:357
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
XYView_PtrList * views_
Definition: scenevie.h:335
virtual void pick_menu(Glyph *, int, Hit &)
void event(const Event &)
Definition: string.h:34
Coord x_pick_epsilon()
Definition: scenevie.h:153
virtual void view_ratio(float xratio, float yratio, Coord &x, Coord &y) const
virtual void printfile(const char *)
virtual void undraw()
virtual void damage(Glyph *, const Allocation &, bool fixed=false, bool viewfixed=false)
Coord xsize_
Definition: scenevie.h:193
Coord ysize_
Definition: scenevie.h:193
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:139
Coord y_pick_epsilon()
Definition: scenevie.h:156
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
@ Dimension_Y
Definition: geometry.h:43
@ Dimension_X
Definition: geometry.h:43
unsigned int DimensionName
Definition: geometry.h:40
char buf[512]
Definition: init.cpp:13
#define assert(ex)
Definition: hocassrt.h:32
#define IfIdraw(arg)
Definition: idraw.h:104
#define IOS_OUT
Definition: ivstream.h:8
#define implementPtrList(PtrList, T)
#define declareList(List, T)
Definition: list.h:49
#define declarePtrList(PtrList, T)
implementList(__AnyPtrList, __AnyPtr) static long ListImpl_best_new_sizes[]
#define v
Definition: md1redef.h:4
#define i
Definition: md1redef.h:12
#define printf
Definition: mwprefix.h:26
static List * info
size_t j
static N_Vector y_
static void pr(N_Vector x)
static N_Vector x_
#define g
Definition: passive0.cpp:21
#define left
Definition: rbtqueue.cpp:45
#define right
Definition: rbtqueue.cpp:46
#define lookup
Definition: redef.h:90
#define print
Definition: redef.h:109
o
Definition: seclist.cpp:175
#define cnt
Definition: spt2queue.cpp:19
#define NULL
Definition: sptree.h:16
static const char * fname(const char *name)
Definition: nrnbbs.cpp:113