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