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