NEURON
grmanip.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #if HAVE_IV // to end of file
3 
4 #include <InterViews/canvas.h>
5 #include <InterViews/transformer.h>
6 #include <InterViews/label.h>
7 #include <InterViews/hit.h>
8 #include <InterViews/cursor.h>
9 #include <IV-look/kit.h>
10 
11 #include <stdio.h>
12 #include <string.h>
13 
14 #include "ivoc.h"
15 #include "mymath.h"
16 #include "rubband.h"
17 #include "graph.h"
18 #include "hocmark.h"
19 #include "utility.h"
20 
21 #define LineRubberMarker_event_ "Crosshair Graph"
22 #define DeleteLabelHandler_event_ "Delete Graph"
23 #define ChangeLabelHandler_event_ "ChangeText"
24 #define DeleteLineHandler_event_ "Delete Graph"
25 #define LinePicker_event_ "Pick Graph"
26 #define MoveLabelBand_press_ "MoveText Graph"
27 
28 extern double hoc_cross_x_, hoc_cross_y_;
29 
30 class LineRubberMarker: public Rubberband {
31  public:
32  LineRubberMarker(GPolyLine*, RubberAction*, Canvas* c = NULL);
33  LineRubberMarker(Coord, Coord, RubberAction*, Canvas* c = NULL);
34  virtual ~LineRubberMarker();
35  virtual bool event(Event&);
36  virtual void undraw(Coord, Coord);
37  virtual void draw(Coord, Coord);
38  int index() {
39  return index_;
40  }
41 
42  private:
43  GPolyLine* gl_;
44  Label* label_;
45  Coord x_, y_;
46  int index_;
47 #if defined(WIN32) || MAC
48  CopyString def_str_;
49 #endif
50 };
51 
52 class MoveLabelBand: public Rubberband {
53  public:
54  MoveLabelBand(GLabel*, RubberAction*, Canvas* = NULL);
55  virtual ~MoveLabelBand();
56  virtual void draw(Coord, Coord);
57  virtual void press(Event&);
58  virtual void release(Event&);
59 
60  private:
61  GLabel* gl_;
62  GLabel* label_;
63  GlyphIndex index_;
64  Allocation a_;
65  Cursor* cursor_;
66  Coord x0_, y0_;
67 };
68 
69 /*static*/ class DeleteLabelHandler: public Handler {
70  public:
71  DeleteLabelHandler(GLabel*);
72  ~DeleteLabelHandler();
73  virtual bool event(Event&);
74 
75  private:
76  GLabel* gl_;
77 };
78 
79 /*static*/ class ChangeLabelHandler: public Handler {
80  public:
81  ChangeLabelHandler(GLabel*);
82  ~ChangeLabelHandler();
83  virtual bool event(Event&);
84 
85  private:
86  GLabel* gl_;
87 };
88 
89 /*static*/ class DeleteLineHandler: public Handler {
90  public:
91  DeleteLineHandler(GPolyLine*);
92  ~DeleteLineHandler();
93  virtual bool event(Event&);
94 
95  private:
96  GPolyLine* gpl_;
97 };
98 
99 /*static*/ class LinePicker: public Rubberband {
100  public:
101  LinePicker(GPolyLine*);
102  ~LinePicker();
103  virtual void press(Event&);
104  virtual void release(Event&);
105 
106  private:
107  void common();
108 
109  private:
110  GPolyLine* gpl_;
111  const Color* c_;
112 };
113 
114 void GraphLine::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
115  GPolyLine::pick(c, a, depth, h);
116 }
117 
118 void GPolyLine::pick(Canvas* c, const Allocation&, int depth, Hit& h) {
119  if (h.count() && h.target(depth, 0)) {
120  return;
121  }
122  if (h.event() && h.event()->type() == Event::down &&
123  h.event()->pointer_button() == Event::left) {
124  Coord x = h.left(), y = h.bottom();
125  switch (XYView::current_pick_view()->scene()->tool()) {
126  case Graph::CROSSHAIR:
127  if (near(x, y, 10, c->transformer())) {
128  h.target(depth, this, 0, new LineRubberMarker(this, NULL, c));
129  }
130  break;
131  case Scene::DELETE:
132  if (near(x, y, 10, c->transformer())) {
133  h.target(depth, this, 0, new DeleteLineHandler(this));
134  }
135  break;
136  case Graph::CHANGECOLOR:
137  if (near(x, y, 10, c->transformer())) {
139  }
140  break;
141  case Graph::PICK:
142  if (near(x, y, 5, c->transformer())) {
143  h.target(depth, this, 0, new LinePicker(this));
144  }
145  break;
146  }
147  }
148 }
149 void HocMark::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
150  if (h.count() && h.target(depth, 0)) {
151  return;
152  }
153  if (h.event() && h.event()->type() == Event::down &&
154  h.event()->pointer_button() == Event::left) {
155  Coord x = h.left(), y = h.bottom();
156  switch (XYView::current_pick_view()->scene()->tool()) {
157  case Graph::CROSSHAIR:
158  h.target(depth, this, 0, new LineRubberMarker(a.x(), a.y(), NULL, c));
159  break;
160  }
161  }
162 }
163 
164 bool GPolyLine::near(Coord xcm, Coord ycm, float epsilon, const Transformer& t) const {
165  if (x_->count() <= 0) {
166  return false;
167  }
168  int index = nearest(xcm, ycm, t);
169  Coord xc, yc, x1, x2, y1, y2;
170  x1 = x(index);
171  y1 = y(index);
172  if (index < x_->count() - 1) {
173  x2 = x(index + 1);
174  y2 = y(index + 1);
175  } else {
176  x2 = x1;
177  y2 = y1;
178  }
179  // printf("nearest model %g %g to mouse %g %g\n", x1, y1, xcm, ycm);
180  t.transform(xcm, ycm, xc, yc);
181  t.transform(x1, y1);
182  t.transform(x2, y2);
183  // printf("nearest mouse %g %g box %g %g %g %g\n", xc, yc, x1, y1, x2, y2);
184  return MyMath::near_line(xc, yc, x1, y1, x2, y2, epsilon);
185 }
186 
187 int GPolyLine::nearest(Coord x1, Coord y1, const Transformer& t, int index_begin) const {
188  int index, i;
189  int count = x_->count();
190  Coord x, y, xt, yt;
191  t.transform(x1, y1, x, y);
192 
193 #define Norm2(lval, arg) \
194  t.transform(x_->get_val(arg), y_->get_val(arg), xt, yt); \
195  lval = MyMath::norm2(x - xt, y - yt);
196 
197  float dxmin, dx;
198  if (index_begin < 0) {
199  index = 0;
200  Norm2(dxmin, 0);
201  for (i = 1; i < count; ++i) {
202  Norm2(dx, i);
203  if (dx < dxmin) {
204  dxmin = dx;
205  index = i;
206  }
207  }
208  } else {
209  float dxleft, dxright;
210  i = index = index_begin;
211  Norm2(dxmin, i);
212  dxleft = dxright = dxmin;
213  if (i - 1 >= 0) {
214  Norm2(dxleft, i - 1);
215  }
216  if (i + 1 > count) {
217  Norm2(dxright, i + 1);
218  }
219  if (dxright < dxleft) {
220  while (++i < count) {
221  Norm2(dx, i);
222  if (dx < dxmin) {
223  dxmin = dx;
224  index = i;
225  } else {
226  break;
227  }
228  }
229  } else {
230  while (--i >= 0) {
231  Norm2(dx, i);
232  if (dx < dxmin) {
233  dxmin = dx;
234  index = i;
235  } else {
236  break;
237  }
238  }
239  }
240  }
241  return index;
242 }
243 
244 LineRubberMarker::LineRubberMarker(GPolyLine* gl, RubberAction* ra, Canvas* c)
245  : Rubberband(ra, c) {
246  // printf("LineRubberMarker\n");
247  gl_ = gl;
248  Resource::ref(gl);
249  label_ = NULL;
250  index_ = -1;
251 }
252 LineRubberMarker::LineRubberMarker(Coord x, Coord y, RubberAction* ra, Canvas* c)
253  : Rubberband(ra, c) {
254  // printf("LineRubberMarker\n");
255  gl_ = NULL;
256  label_ = NULL;
257  index_ = -1;
258  x_ = x;
259  y_ = y;
260 }
261 LineRubberMarker::~LineRubberMarker() {
262  // printf("~LineRubberMarker\n");
263  Resource::unref(gl_);
264  Resource::unref(label_);
265 }
266 bool LineRubberMarker::event(Event& e) {
267  if (Oc::helpmode()) {
268  if (e.type() == Event::down) {
269  Oc::help(LineRubberMarker_event_);
270  }
271  return true;
272  }
273  if (e.type() == Event::key) {
274  char buf[2];
275  if (e.mapkey(buf, 1) > 0) {
276  if (gl_) {
277  ((Graph*) XYView::current_pick_view()->scene())->cross_action(buf[0], gl_, index_);
278  } else {
279  ((Graph*) XYView::current_pick_view()->scene())->cross_action(buf[0], x_, y_);
280  }
281  }
282  return true;
283  } else {
284 #if defined(WIN32) || MAC
285  if (e.type() == Event::down) {
286  def_str_ = ((DismissableWindow*) canvas()->window())->name();
287  } else if (e.type() == Event::up) {
288  ((DismissableWindow*) canvas()->window())->name(def_str_.string());
289  }
290 #endif
291  return Rubberband::event(e);
292  }
293 }
294 void LineRubberMarker::undraw(Coord, Coord) {
295  Coord x, y;
296  transformer().transform(x_, y_, x, y);
297  Canvas* c = canvas();
298  Transformer identity;
299  c->push_transform();
300  c->transformer(identity);
301 #if !defined(WIN32) && !MAC
302  Allocation a;
303  a.allot_x(Allotment(x + 20, 0, 0));
304  a.allot_y(Allotment(y, 0, 0));
305  label_->draw(c, a);
306 #endif
307  c->line(x - 10, y, x + 10, y, Rubberband::color(), Rubberband::brush());
308  c->line(x, y - 10, x, y + 10, Rubberband::color(), Rubberband::brush());
309  c->pop_transform();
310 }
311 void LineRubberMarker::draw(Coord x, Coord y) {
312  // printf("draw %g %g", x, y);
313  Coord x1, y1;
314  transformer().inverse_transform(x, y, x1, y1);
315  // printf(" model %g %g", x1, y1);
316  if (gl_) {
317  index_ = gl_->nearest(x1, y1, transformer(), index_);
318  x_ = gl_->x(index_);
319  y_ = gl_->y(index_);
320  // printf(" on line %g %g\n", x_, y_);
321  }
322  char s[50];
323 
324 #if defined(WIN32) || MAC
325  sprintf(s, "crosshair x=%g y=%g", x_, y_);
326  ((DismissableWindow*) canvas()->window())->name(s);
327 #else
328  sprintf(s, "(%g,%g)", x_, y_);
329  Resource::unref(label_);
330  label_ = new Label(s, WidgetKit::instance()->font(), Rubberband::color());
331 #endif
332  hoc_cross_x_ = x_;
333  hoc_cross_y_ = y_;
334  undraw(0, 0);
335 }
336 
337 void GLabel::pick(Canvas* c, const Allocation&, int depth, Hit& h) {
338  if (h.count() && h.target(depth, 0)) {
339  return;
340  }
341  if (h.event() && h.event()->type() == Event::down &&
342  h.event()->pointer_button() == Event::left) {
343  // printf("GLabel picked %s\n", text_.string());
344  switch (XYView::current_pick_view()->scene()->tool()) {
345  case Scene::MOVE:
346  h.target(depth, this, 0, new MoveLabelBand(this, NULL, c));
347  break;
348  case Scene::DELETE:
349  h.target(depth, this, 0, new DeleteLabelHandler(this));
350  break;
351  case Scene::CHANGECOLOR:
353  break;
354  case Graph::CHANGELABEL:
355  h.target(depth, this, 0, new ChangeLabelHandler(this));
356  }
357  }
358 }
359 
360 DeleteLabelHandler::DeleteLabelHandler(GLabel* gl) {
361  // printf("DeleteLabelHandler\n");
362  gl_ = gl;
363 }
364 
365 DeleteLabelHandler::~DeleteLabelHandler() {
366  // printf("~DeleteLabelHandler\n");
367 }
368 bool DeleteLabelHandler::event(Event& e) {
369  if (Oc::helpmode()) {
370  if (e.type() == Event::down) {
371  Oc::help(DeleteLabelHandler_event_);
372  }
373  return true;
374  }
376  return true;
377 }
378 
379 ChangeLabelHandler::ChangeLabelHandler(GLabel* gl) {
380  // printf("ChangeLabelHandler\n");
381  gl_ = gl;
382 }
383 
384 ChangeLabelHandler::~ChangeLabelHandler() {
385  // printf("~ChangeLabelHandler\n");
386 }
387 bool ChangeLabelHandler::event(Event& e) {
388  if (Oc::helpmode()) {
389  if (e.type() == Event::down) {
390  Oc::help(ChangeLabelHandler_event_);
391  }
392  return true;
393  }
394  char buf[200];
395  strcpy(buf, gl_->text());
396  GLabel* gl = (GLabel*) gl_->clone();
397  gl->ref();
398  if (Graph::label_chooser("Modify Label", buf, gl, e.pointer_root_x(), e.pointer_root_y())) {
399  ((Graph*) (XYView::current_pick_view()->scene()))->change_label(gl_, buf, gl);
400  }
401  gl->unref();
402  return true;
403 }
404 
406  printf("No method for changeing label color %s\n", gl->text());
407 }
408 
410  printf("No method for changeing line color \n");
411 }
412 
413 void Scene::delete_label(GLabel* gl) {
414  printf("No method for deleting label %s\n", gl->text());
415 }
416 
417 DeleteLineHandler::DeleteLineHandler(GPolyLine* gpl) {
418  // printf("DeleteLineHandler\n");
419  gpl_ = gpl;
420 }
421 
422 DeleteLineHandler::~DeleteLineHandler() {
423  // printf("~DeleteLineHandler\n");
424 }
425 bool DeleteLineHandler::event(Event& e) {
426  if (Oc::helpmode()) {
427  if (e.type() == Event::down) {
428  Oc::help(DeleteLineHandler_event_);
429  }
430  return true;
431  }
433  GlyphIndex i = s->glyph_index(gpl_);
434  s->modified(i);
435  s->damage(i);
436  gpl_->erase_line(s, i);
437  return true;
438 }
439 
440 LinePicker::LinePicker(GPolyLine* gpl)
441  : Rubberband() {
442  // printf("LinePicker\n");
443  gpl_ = gpl;
444 }
445 
446 LinePicker::~LinePicker() {
447  // printf("~LinePicker\n");
448 }
449 void LinePicker::press(Event&) {
450  const Color* c;
451  if (Oc::helpmode()) {
452  Oc::help(LinePicker_event_);
453  return;
454  }
455  c_ = gpl_->color();
456  c = colors->color(2);
457  if (c == c_) {
458  c = colors->color(3);
459  }
460  gpl_->color(c);
461  gpl_->pick_vector();
462  common();
463 }
464 void LinePicker::release(Event&) {
465  gpl_->color(c_);
466  common();
467 }
468 
469 void LinePicker::common() {
471  GlyphIndex i = s->glyph_index(gpl_);
472  s->modified(i);
473  s->damage(i);
474  if (gpl_->label() && (i = s->glyph_index(gpl_->label())) >= 0) {
475  s->modified(i);
476  s->damage(i);
477  }
478 }
479 
480 MoveLabelBand::MoveLabelBand(GLabel* gl, RubberAction* ra, Canvas* c)
481  : Rubberband(ra, c) {
482  // printf("MoveLabelBand\n");
483  gl_ = gl;
484  gl_->ref();
485  label_ = (GLabel*) gl_->clone();
486  label_->ref();
487  label_->color(Rubberband::color());
489  index_ = gr->glyph_index(gl);
490  gr->location(index_, x0_, y0_);
491  if (gl_->fixed()) {
492  transformer().transform(x0_, y0_);
493  } else {
494  XYView::current_pick_view()->view_ratio(x0_, y0_, x0_, y0_);
495  }
496  // printf("MoveLabelBand label index %d (%g, %g)\n", index_, x0_, y0_);
497  Allotment ax, ay;
498  gr->allotment(index_, Dimension_X, ax);
499  gr->allotment(index_, Dimension_Y, ay);
500  a_.allot_x(ax);
501  a_.allot_y(ay);
502 }
503 
504 MoveLabelBand::~MoveLabelBand() {
505  // printf("~MoveLabelBand\n");
506  Resource::unref(label_);
507  Resource::unref(gl_);
508 }
509 
511  if (Oc::helpmode()) {
512  Oc::help(MoveLabelBand_press_);
513  return;
514  }
515  x0_ -= x_begin();
516  y0_ -= y_begin();
517 #if 0 && !defined(WIN32)
518  cursor_ = canvas()->window()->cursor();
519  canvas()->window()->cursor(noCursor);
520 #endif
521 #if !defined(WIN32) && !MAC
522  undraw(x(), y()); // so initial draw does not make it disappear
523 #endif
524 }
525 
527  if (Oc::helpmode()) {
528  return;
529  }
531  Coord x1, y1, x2, y2;
532  if (gl_->fixed()) {
533  transformer().inverse_transform(x(), y(), x2, y2);
534  transformer().inverse_transform(x_begin(), y_begin(), x1, y1);
535  } else {
536  x2 = x();
537  y2 = y();
538  x1 = x_begin();
539  y1 = y_begin();
540  }
541  gr->location(index_, x0_, y0_);
542  if (gl_->fixed()) {
543  x1 = x0_ + x2 - x1;
544  y1 = y0_ + y2 - y1;
545  } else {
546  XYView::current_pick_view()->view_ratio(x0_, y0_, x0_, y0_);
547  XYView::current_pick_view()->ratio_view(x0_ + x2 - x1, y0_ + y2 - y1, x1, y1);
548  }
549  // printf("move to %g %g\n", x1, y1);
550  gr->move(index_, x1, y1);
551 #if 0 && !defined(WIN32)
552  canvas()->window()->cursor(cursor_);
553 #endif
554 }
555 
556 void MoveLabelBand::draw(Coord x, Coord y) {
557  if (Oc::helpmode()) {
558  return;
559  }
560  Canvas* c = canvas();
561  // printf("MoveLabelBand::draw(%g, %g)\n", x, y);
562  a_.x_allotment().origin(x + x0_);
563  a_.y_allotment().origin(y + y0_);
564 #if defined(WIN32) || MAC
565  c->rect(a_.x_allotment().begin(),
566  a_.y_allotment().begin(),
567  a_.x_allotment().end(),
568  a_.y_allotment().end(),
571 #else
572  label_->draw(c, a_);
573 #endif
574 }
575 #endif
#define Handler
Definition: _defines.h:146
#define Color
Definition: _defines.h:74
#define Transformer
Definition: _defines.h:316
#define Canvas
Definition: _defines.h:65
#define Label
Definition: _defines.h:159
#define Allotment
Definition: _defines.h:38
#define Coord
Definition: _defines.h:19
#define Hit
Definition: _defines.h:147
#define GlyphIndex
Definition: _defines.h:23
#define Event
Definition: _defines.h:107
#define Cursor
Definition: _defines.h:85
short index
Definition: cabvars.h:10
Coord x() const
Definition: geometry.h:290
void allot_y(const Allotment &)
Definition: geometry.h:283
Coord y() const
Definition: geometry.h:291
void allot_x(const Allotment &)
Definition: geometry.h:282
const Color * color(int) const
int count() const
Definition: graph.h:210
Definition: graph.h:424
void text(const char *)
virtual void pick(Canvas *, const Allocation &, int depth, Hit &)
virtual Glyph * clone() const
Coord x(int index) const
Definition: graph.h:289
virtual void pick(Canvas *, const Allocation &, int depth, Hit &)
Coord y(int index) const
Definition: graph.h:292
bool near(Coord, Coord, float, const Transformer &) const
int nearest(Coord, Coord, const Transformer &, int index=-1) const
DataVec * x_
Definition: graph.h:321
Definition: graph.h:57
virtual GlyphIndex glyph_index(const Glyph *)
static bool label_chooser(const char *, char *, GLabel *, Coord x=400., Coord y=400.)
@ CROSSHAIR
Definition: graph.h:59
@ PICK
Definition: graph.h:59
@ CHANGELABEL
Definition: graph.h:59
virtual void pick(Canvas *, const Allocation &, int depth, Hit &)
virtual void pick(Canvas *, const Allocation &, int depth, Hit &)
static bool near_line(Coord x, Coord y, Coord x1, Coord y1, Coord x2, Coord y2, float epsilon)
Definition: mymath.cpp:116
static void help(const char *)
static bool helpmode()
Definition: ivoc.h:70
virtual void ref() const
Definition: resource.cpp:47
virtual void unref() const
Definition: resource.cpp:52
const Event & event() const
Definition: rubband.h:52
virtual void undraw(Coord x, Coord y)
virtual void release(Event &)
static const Color * color()
Coord x_
Definition: rubband.h:78
static const Brush * brush()
virtual void press(Event &)
Coord y_
Definition: rubband.h:78
virtual void draw(Coord x, Coord y)
virtual GlyphIndex glyph_index(const Glyph *)
virtual void change_label_color(GLabel *)
void move(GlyphIndex, Coord x, Coord y)
virtual void damage(GlyphIndex)
virtual void delete_label(GLabel *)
void location(GlyphIndex, Coord &x, Coord &y) const
virtual void change_line_color(GPolyLine *)
@ MOVE
Definition: scenevie.h:258
@ CHANGECOLOR
Definition: scenevie.h:258
@ DELETE
Definition: scenevie.h:258
virtual void allotment(GlyphIndex, DimensionName, Allotment &) const
virtual void modified(GlyphIndex)
virtual void view_ratio(float xratio, float yratio, Coord &x, Coord &y) const
virtual Scene * scene() const
virtual void ratio_view(Coord x, Coord y, float &xratio, float &yratio) const
static XYView * current_pick_view()
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
#define xc
Definition: extcelln.cpp:87
@ Dimension_Y
Definition: geometry.h:43
@ Dimension_X
Definition: geometry.h:43
ColorPalette * colors
char buf[512]
Definition: init.cpp:13
double hoc_cross_x_
Definition: hoc_init.cpp:401
double hoc_cross_y_
Definition: hoc_init.cpp:401
#define i
Definition: md1redef.h:12
char * name
Definition: init.cpp:16
#define printf
Definition: mwprefix.h:26
static N_Vector y_
static realtype c_
static realtype a_
static N_Vector x_
virtual void press(const Event &e)
Definition: ocinput.h:29
virtual void release(const Event &e)
Definition: ocinput.h:35
#define e
Definition: passive0.cpp:22
#define left
Definition: rbtqueue.cpp:45
#define key
Definition: spt2queue.cpp:20
#define NULL
Definition: sptree.h:16