NEURON
xmenu.cpp
Go to the documentation of this file.
1 
2 #include <../../nrnconf.h>
3 
4 #include <InterViews/resource.h>
5 #include "oc2iv.h"
6 #include "classreg.h"
7 double (*nrnpy_guigetval)(Object*);
8 void (*nrnpy_guisetval)(Object*, double);
9 int (*nrnpy_guigetstr)(Object*, char**);
10 
11 #include "gui-redirect.h"
12 
13 Object** (*nrnpy_gui_helper_)(const char* name, Object* obj) = NULL;
15 Object** (*nrnpy_gui_helper3_)(const char* name, Object* obj, int handle_strptr) = NULL;
16 char** (*nrnpy_gui_helper3_str_)(const char* name, Object* obj, int handle_strptr) = NULL;
17 
18 #if HAVE_IV // to end of file except for a few small fragments.
19 
20 #include <stdio.h>
21 #include <string.h>
22 #include <math.h>
23 #include <ivstream.h>
24 #include <ctype.h>
25 #include <errno.h>
26 
27 #include <InterViews/box.h>
28 #include <IV-look/kit.h>
29 #include <InterViews/event.h>
30 #include <InterViews/layout.h>
31 #include <InterViews/style.h>
32 #include <InterViews/background.h>
33 #include <InterViews/border.h>
34 #include <InterViews/dialog.h>
35 #include <InterViews/printer.h>
36 #include <InterViews/geometry.h>
37 #include <InterViews/transformer.h>
38 #include <InterViews/patch.h>
39 #include <InterViews/color.h>
40 #include <InterViews/telltale.h>
41 #include <InterViews/hit.h>
42 
43 #include <InterViews/display.h>
44 #include "mymath.h"
45 #include "xmenu.h"
46 #include "datapath.h"
47 #include "ivoc.h"
48 #include "bndedval.h"
49 #include "objcmd.h"
50 #include "parse.hpp"
51 #include "utility.h"
52 #include "scenepic.h"
53 
54 
55 // The problem this overcomes is that the pick of an input handler normally
56 // succeeds for a keystroke only if the mouse is over one of the child
57 // handlers. We want it to succeed whenever it is inside the panel.
58 class PanelInputHandler: public InputHandler {
59  public:
60  PanelInputHandler(Glyph*, Style*);
61  virtual ~PanelInputHandler();
62  virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
63  virtual void focus(InputHandler*);
64  static bool has_old_focus() {
65  bool old = sema_;
66  sema_ = false;
67  return old;
68  }
69  static void handle_old_focus();
70 
71  private:
72  static InputHandler* focus_;
73  static bool sema_;
74 };
75 
76 void handle_old_focus() {
78 }
79 
80 InputHandler* PanelInputHandler::focus_ = NULL;
81 bool PanelInputHandler::sema_ = false;
82 
83 PanelInputHandler::PanelInputHandler(Glyph* g, Style* s)
84  : InputHandler(g, s) {}
85 PanelInputHandler::~PanelInputHandler() {}
86 void PanelInputHandler::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
87  const Event* e = h.event();
88  if (focus_ && e && e->type() == Event::key && focus_->handler()) {
89  h.target(depth, this, 0, focus_->handler());
90  } else {
91  InputHandler::pick(c, a, depth, h);
92  }
93 }
94 void PanelInputHandler::focus(InputHandler* h) {
95  if (focus_ && focus_ != h) {
96  if (h) {
97  sema_ = true;
98  }
99  InputHandler* f = focus_;
100  focus_ = NULL;
101  f->focus_out();
102  }
103  focus_ = h;
104  InputHandler::focus(h);
105 }
106 
108  if (focus_) {
109  // printf("handle_old_focus %p\n", focus_);
110  sema_ = true;
111  InputHandler* f = focus_;
112  focus_ = NULL;
113  f->focus_out();
114  }
115 }
116 
117 class ValEdLabel: public MonoGlyph {
118  public:
119  ValEdLabel(Glyph*);
120  virtual ~ValEdLabel();
121  virtual void draw(Canvas*, const Allocation&) const;
122  void state(bool);
123  void tts(TelltaleState*);
124 
125  private:
126  static const Color* color_;
127  bool state_;
128  TelltaleState* tts_;
129 };
130 
131 const Color* ValEdLabel::color_;
132 
133 ValEdLabel::ValEdLabel(Glyph* g)
134  : MonoGlyph(g) {
135  state_ = false;
136  if (!color_) {
137  color_ = Color::lookup(Session::instance()->default_display(), "yellow");
138  Resource::ref(color_);
139  }
140  tts_ = NULL;
141 }
142 
143 ValEdLabel::~ValEdLabel() {}
144 void ValEdLabel::draw(Canvas* c, const Allocation& a) const {
145  if (state_) {
146  c->fill_rect(a.left(), a.bottom(), a.right(), a.top(), color_);
147  }
148  MonoGlyph::draw(c, a);
149 }
150 void ValEdLabel::state(bool s) {
151  if (state_ != s) {
152  state_ = s;
153  tts_->notify();
154  }
155 }
156 
157 void ValEdLabel::tts(TelltaleState* t) {
158  tts_ = t; // not reffed
159 }
160 
161 static void hoc_ivpanelPlace(Coord, Coord, int scroll = -1);
162 
163 static String* xvalue_format;
164 
165 #define Editor_Default "DefaultValueEditor"
166 #define Editor_Stepper "DefaultValueEditor"
167 
168 
169 extern int units_on_flag_;
171 extern "C" double* nrn_recalc_ptr(double*);
172 void hoc_notify_value() {
173  Oc oc;
174  oc.notify();
175 }
176 
177 void hoc_xpanel() {
178  TRY_GUI_REDIRECT_DOUBLE("xpanel", NULL);
179  IFGUI
180  if (ifarg(1) && hoc_is_str_arg(1)) { // begin spec
181  bool h = false;
182  if (ifarg(2)) {
183  h = (int) chkarg(2, 0, 1) ? true : false;
184  }
185  hoc_ivpanel(gargstr(1), h);
186  } else { // map
187  int scroll = -1; // leave up to panel_scroll attribute
188  if (ifarg(2)) {
189  if (ifarg(3)) {
190  scroll = (int) chkarg(3, -1, 1);
191  }
192  hoc_ivpanelPlace((Coord) *getarg(1), (Coord) *getarg(2), scroll);
193  } else {
194  if (ifarg(1)) {
195  scroll = (int) chkarg(1, -1, 1);
196  }
197  hoc_ivpanelmap(scroll);
198  }
199  }
200  ENDGUI
201 
202  hoc_ret();
203  hoc_pushx(0.);
204 }
205 
206 void hoc_xmenu() {
207  TRY_GUI_REDIRECT_DOUBLE("xmenu", NULL);
208  IFGUI
209  bool add2menubar = false;
210  char* mk = NULL;
211  Object* pyact = NULL;
212  int i = 2;
213  if (ifarg(i)) {
214  if (hoc_is_str_arg(i)) {
215  mk = gargstr(i);
216  ++i;
217  } else if (hoc_is_object_arg(i)) {
218  pyact = *hoc_objgetarg(i);
219  ++i;
220  }
221  if (ifarg(i)) {
222  add2menubar = int(chkarg(i, 0, 1));
223  }
224  }
225  if (ifarg(1)) {
226  if (mk || pyact) {
227  hoc_ivvarmenu(gargstr(1), mk, add2menubar, pyact);
228  } else {
229  hoc_ivmenu(gargstr(1), add2menubar);
230  }
231  } else {
232  hoc_ivmenu((char*) 0);
233  }
234  ENDGUI
235  hoc_ret();
236  hoc_pushx(0.);
237 }
238 
239 void hoc_xbutton() {
240  TRY_GUI_REDIRECT_DOUBLE("xbutton", NULL);
241 
242  IFGUI
243  char* s1;
244  s1 = gargstr(1);
245  if (ifarg(2)) {
246  if (hoc_is_object_arg(2)) {
247  hoc_ivbutton(s1, NULL, *hoc_objgetarg(2));
248  } else {
249  hoc_ivbutton(s1, gargstr(2));
250  }
251  } else {
252  hoc_ivbutton(s1, s1);
253  }
254  ENDGUI
255  hoc_ret();
256  hoc_pushx(0.);
257 }
258 
259 /*
260 xstatebutton("prompt",&var [,"action"])
261  like xbutton, but var is set to 0 or 1 depending to match the
262  telltale state of the button
263 */
264 
265 void hoc_xstatebutton() {
266  TRY_GUI_REDIRECT_DOUBLE("xstatebutton", NULL);
267  IFGUI
268  char *s1, *s2 = (char*) 0;
269 
270  s1 = gargstr(1);
271 
272  if (hoc_is_object_arg(2)) {
274  s1,
275  NULL,
277  *hoc_objgetarg(2),
278  ifarg(3) ? *hoc_objgetarg(3) : NULL);
279  } else {
280  if (ifarg(3)) {
281  s2 = gargstr(3);
282  }
284  }
285  ENDGUI
286  hoc_ret();
287  hoc_pushx(0.);
288 }
289 
290 
291 /*
292 xcheckbox("prompt",&var [,"action"])
293  like xbutton, but var is set to 0 or 1 depending to match the
294  telltale state of the button
295 */
296 
297 void hoc_xcheckbox() {
298  TRY_GUI_REDIRECT_DOUBLE("xcheckbox", NULL);
299  IFGUI
300 
301  char *s1, *s2 = (char*) 0;
302 
303  s1 = gargstr(1);
304 
305  if (hoc_is_object_arg(2)) {
307  s1,
308  NULL,
310  *hoc_objgetarg(2),
311  ifarg(3) ? *hoc_objgetarg(3) : 0);
312  } else {
313  if (ifarg(3)) {
314  s2 = gargstr(3);
315  }
317  }
318  ENDGUI
319  hoc_ret();
320  hoc_pushx(0.);
321 }
322 
323 void hoc_xradiobutton() {
324  TRY_GUI_REDIRECT_DOUBLE("xradiobutton", NULL);
325 
326  IFGUI
327  char *s1, *s2 = (char*) 0;
328  Object* po = NULL;
329  bool activate = false;
330  s1 = gargstr(1);
331  if (ifarg(2)) {
332  if (hoc_is_object_arg(2)) {
333  po = *hoc_objgetarg(2);
334  } else {
335  s2 = gargstr(2);
336  }
337  if (ifarg(3)) {
338  activate = (chkarg(3, 0, 1) != 0.);
339  }
340  } else {
341  s2 = s1;
342  }
343  if (po) {
344  hoc_ivradiobutton(s1, NULL, activate, po);
345  } else {
346  hoc_ivradiobutton(s1, s2, activate);
347  }
348  ENDGUI
349  hoc_ret();
350  hoc_pushx(0.);
351 }
352 
353 static void hoc_xvalue_helper() {
354  IFGUI // prompt, variable, deflt,action,canrun,usepointer
355  char *s1,
356  *s2, *s3;
357  double* ptr2 = NULL; /*allow variable arg2 to be double* */
358  Object* pyvar = NULL;
359  Object* pyact = NULL;
360  s2 = s3 = NULL;
361  s1 = gargstr(1);
362  if (ifarg(2)) {
363  if (hoc_is_object_arg(2)) {
364  pyvar = *hoc_objgetarg(2);
365  } else if (hoc_is_pdouble_arg(2)) {
366  ptr2 = hoc_pgetarg(2);
367  } else {
368  s2 = gargstr(2);
369  }
370  } else {
371  s2 = s1;
372  }
373  bool deflt = false;
374  if (ifarg(3) && *getarg(3)) {
375  if (*getarg(3) == 2.) {
376  if (pyvar) {
377  hoc_ivvalue_keep_updated(s1, NULL, pyvar);
378  } else {
379  hoc_ivvalue_keep_updated(s1, s2);
380  }
381  return;
382  }
383  deflt = true;
384  }
385  bool canRun = false, usepointer = false;
386  if (ifarg(4)) {
387  if (hoc_is_object_arg(4)) {
388  pyact = *hoc_objgetarg(4);
389  } else {
390  s3 = gargstr(4);
391  }
392  if (ifarg(5) && *getarg(5)) {
393  canRun = true;
394  }
395  if (ifarg(6) && *getarg(6)) {
396  usepointer = true;
397  }
398  }
399  hoc_ivvaluerun_ex(s1, s2, ptr2, pyvar, s3, pyact, deflt, canRun, usepointer);
400 
401  ENDGUI
402 }
403 
404 void hoc_xfixedvalue() {
405  TRY_GUI_REDIRECT_DOUBLE("xfixedvalue", NULL);
406 
407  IFGUI // prompt, variable, deflt,action,canrun,usepointer
408  char *s1,
409  *s2;
410  s1 = gargstr(1);
411  if (ifarg(2)) {
412  s2 = gargstr(2);
413  } else {
414  s2 = s1;
415  }
416  bool deflt = false;
417  if (ifarg(3) && *getarg(3)) {
418  deflt = true;
419  }
420  bool usepointer = false;
421  if (ifarg(4) && *getarg(4)) {
422  usepointer = true;
423  }
424  hoc_ivfixedvalue(s1, s2, deflt, usepointer);
425 
426  ENDGUI
427  hoc_ret();
428  hoc_pushx(0.);
429 }
430 
431 static void hoc_xpvalue_helper() {
432  IFGUI // prompt,variable,deflt,action,canrun
433  char *s1,
434  *s3;
435  double* pd;
436  HocSymExtension* extra = NULL;
437  Symbol* sym;
438  s1 = gargstr(1);
439  if (ifarg(2)) {
440  pd = hoc_pgetarg(2);
442  } else {
443  pd = hoc_val_pointer(s1);
444  sym = hoc_get_symbol(s1);
445  }
446  if (sym) {
447  extra = sym->extra;
448  }
449  bool deflt = false;
450  if (ifarg(3) && *getarg(3)) {
451  deflt = true;
452  }
453  if (ifarg(4)) {
454  s3 = gargstr(4);
455  bool canRun = false;
456  if (ifarg(5) && *getarg(5)) {
457  canRun = true;
458  }
459  hoc_ivpvaluerun(s1, pd, s3, deflt, canRun, extra);
460  } else {
461  hoc_ivpvalue(s1, pd, deflt, extra);
462  }
463  ENDGUI
464 }
465 
466 void hoc_xvalue() {
467  TRY_GUI_REDIRECT_DOUBLE("xvalue", NULL);
468 
469  hoc_xvalue_helper();
470  hoc_ret();
471  hoc_pushx(0.);
472 }
473 
474 void hoc_xpvalue() {
475  TRY_GUI_REDIRECT_DOUBLE("xpvalue", NULL);
476  hoc_xpvalue_helper();
477  hoc_ret();
478  hoc_pushx(0.);
479 }
480 
481 void hoc_xlabel() {
482  TRY_GUI_REDIRECT_DOUBLE("xlabel", NULL);
483  IFGUI
484  char* s1;
485  s1 = gargstr(1);
486  hoc_ivlabel(s1);
487  ENDGUI
488  hoc_ret();
489  hoc_pushx(0.);
490 }
491 
492 void hoc_xvarlabel() {
494  IFGUI
495  if (hoc_is_object_arg(1)) {
497  } else {
499  }
500  ENDGUI
501  hoc_ret();
502  hoc_pushx(0.);
503 }
504 
505 // ZFM modified to add vertical vs. horizontal
506 void hoc_xslider() {
507  TRY_GUI_REDIRECT_DOUBLE("xslider", NULL);
508  IFGUI
509  float low = 0, high = 100;
510  float resolution = 1;
511  int nsteps = 10;
512  char* send = NULL;
513  Object* pysend = NULL;
514  double* pval = NULL;
515  Object* pyvar = NULL;
516  bool vert = 0;
517  if (ifarg(3)) {
518  low = *getarg(2);
519  high = *getarg(3);
520  resolution = (high - low) / 100.;
521  }
522  int iarg = 4;
523  if (ifarg(iarg)) {
524  if (hoc_is_str_arg(iarg)) {
525  send = gargstr(4);
526  ++iarg;
527  } else if (hoc_is_object_arg(iarg)) {
528  pysend = *hoc_objgetarg(iarg);
529  ++iarg;
530  }
531  }
532  if (ifarg(iarg)) {
533  vert = int(chkarg(iarg, 0, 1));
534  }
535  bool slow = false;
536  if (ifarg(++iarg)) {
537  slow = int(chkarg(iarg, 0, 1));
538  }
539  if (hoc_is_object_arg(1)) {
540  pyvar = *hoc_objgetarg(1);
541  } else {
542  pval = hoc_pgetarg(1);
543  }
544  hoc_ivslider(pval, low, high, resolution, nsteps, send, vert, slow, pyvar, pysend);
545  ENDGUI
546  hoc_ret();
547  hoc_pushx(0.);
548 }
549 
550 
551 class HocButton: public Button {
552  public:
553  HocButton(const char*, Glyph*, Style*, TelltaleState*, Action*);
554  virtual ~HocButton();
555  static HocButton* instance(const char*, Action*);
556  virtual void print(Printer*, const Allocation&) const;
557 
558  private:
559  Glyph* l_;
560 };
561 HocButton::HocButton(const char* text, Glyph* g, Style* s, TelltaleState* t, Action* a)
562  : Button(g, s, t, a) {
563  l_ = WidgetKit::instance()->label(text);
564  l_->ref();
565 }
566 HocButton::~HocButton() {
567  Resource::unref(l_);
568 }
569 HocButton* HocButton::instance(const char* s, Action* a) {
570  Button* b = WidgetKit::instance()->push_button(s, a);
571  b->ref();
572  HocButton* hb = new HocButton(s, b->body(), b->style(), b->state(), b->action());
573  b->unref();
574  return hb;
575 }
576 void HocButton::print(Printer* pr, const Allocation& a) const {
577  l_->print(pr, a);
578 }
579 
580 implementPtrList(HocPanelList, HocPanel);
581 static HocPanelList* hoc_panel_list;
582 static HocPanel* curHocPanel;
583 static HocValEditor* last_fe_constructed_;
584 static void checkOpenPanel() {
585  if (!curHocPanel) {
586  hoc_execerror("No panel is open", NULL);
587  }
588 }
589 
590 declarePtrList(HocMenuList, HocMenu)
591 implementPtrList(HocMenuList, HocMenu)
592 /*static*/ class MenuStack {
593  public:
594  bool isEmpty() {
595  return l_.count() == 0;
596  }
597  void push(HocMenu* m);
598  void pop() {
599  if (l_.count()) {
600  l_.item(0)->unref();
601  l_.remove(0);
602  }
603  }
604  Menu* top() {
605  return (l_.count()) ? l_.item(0)->menu() : NULL;
606  }
607  HocItem* hoc_item() {
608  return (l_.count()) ? l_.item(0) : NULL;
609  }
610  void clean();
611 
612  private:
613  HocMenuList l_;
614 };
615 void MenuStack::push(HocMenu* m) {
616  m->ref();
617  l_.prepend(m);
618 }
619 void MenuStack::clean() {
620  for (long i = 0; i < l_.count(); i++) {
621  l_.item(i)->unref();
622  }
623  l_.remove_all();
624 }
625 static MenuStack* menuStack;
626 static Menu* hocmenubar;
627 
628 class OcTelltaleGroup: public TelltaleGroup {
629  public:
630  OcTelltaleGroup();
631  virtual ~OcTelltaleGroup();
632  virtual void update(TelltaleState*);
633  virtual void remove(TelltaleState*);
634  virtual void restore();
635 
636  private:
637  TelltaleState* previous_;
638  TelltaleState* current_;
639 };
640 
641 OcTelltaleGroup::OcTelltaleGroup() {
642  previous_ = NULL;
643  current_ = NULL;
644 }
645 OcTelltaleGroup::~OcTelltaleGroup() {}
647  if (t != current_ && t->test(TelltaleState::is_chosen)) {
648  previous_ = current_;
649  current_ = t;
650  }
652 }
654  if (previous_ == t) {
655  previous_ = NULL;
656  }
657  if (current_ == t) {
658  current_ = NULL;
659  }
661 }
663  if (previous_) {
664  previous_->set(TelltaleState::is_chosen, true);
665  } else if (current_) {
666  TelltaleGroup::update(current_);
667  current_->set(TelltaleState::is_chosen, false);
668  current_ = NULL;
669  }
670 }
671 
672 class HocRadioAction: public HocAction {
673  public:
674  HocRadioAction(const char* action, OcTelltaleGroup*, Object* pyact = NULL);
675  virtual ~HocRadioAction();
676  virtual void help();
677 
678  private:
679  OcTelltaleGroup* tg_;
680 };
681 
682 HocRadioAction::HocRadioAction(const char* action, OcTelltaleGroup* tg, Object* pyact)
683  : HocAction(action, pyact) {
684  tg_ = tg;
685  Resource::ref(tg_);
686 }
687 
688 HocRadioAction::~HocRadioAction() {
689  Resource::unref(tg_);
690 }
691 void HocRadioAction::help() {
692  tg_->restore();
693  HocAction::help();
694 }
695 
696 /*static*/ class HocRadio {
697  public:
698  HocRadio();
699  virtual ~HocRadio();
700 
701  OcTelltaleGroup* group() {
702  return g_;
703  }
704  void start();
705  void stop();
706 
707  private:
708  OcTelltaleGroup* g_;
709 };
710 
711 HocRadio::HocRadio() {
712  g_ = NULL;
713 }
714 HocRadio::~HocRadio() {
715  Resource::unref(g_);
716 }
717 void HocRadio::start() {
718  Resource::unref(g_);
719  g_ = new OcTelltaleGroup();
720  g_->ref();
721 }
722 
723 void HocRadio::stop() {
724  Resource::unref(g_);
725  g_ = NULL;
726 }
727 
728 static HocRadio* hoc_radio;
729 
730 void hoc_ivpanel(const char* name, bool h) {
731  if (!hoc_radio) {
732  hoc_radio = new HocRadio();
733  }
734  if (curHocPanel) {
735  fprintf(stderr, "%s not closed\n", curHocPanel->getName());
736  if (menuStack) {
737  menuStack->clean();
738  }
739  curHocPanel->unref();
740  curHocPanel = NULL;
741  hoc_execerror("Didn't close the previous panel", NULL);
742  } else {
743  curHocPanel = new HocPanel(name, h);
744  curHocPanel->ref();
745  }
746  hoc_radio->stop();
747 }
748 
749 void hoc_ivpanelmap(int scroll) {
750  checkOpenPanel();
751  curHocPanel->map_window(scroll);
752  curHocPanel->unref();
753  curHocPanel = NULL;
754  if (menuStack && !menuStack->isEmpty()) {
755  fprintf(stderr, "%s menu not closed\n", menuStack->hoc_item()->getStr());
756  menuStack->clean();
757  hoc_execerror("A menu is still open", 0);
758  }
759  hoc_radio->stop();
760 }
761 
762 void hoc_ivpanelPlace(Coord left, Coord bottom, int scroll) {
763  checkOpenPanel();
764  curHocPanel->left_ = left;
765  curHocPanel->bottom_ = bottom;
766  hoc_ivpanelmap(scroll);
767 }
768 
769 void hoc_ivbutton(const char* name, const char* action, Object* pyact) {
770  checkOpenPanel();
771  hoc_radio->stop();
772  if (menuStack && !menuStack->isEmpty()) {
773  menuStack->top()->append_item(curHocPanel->menuItem(name, action, false, pyact));
774  } else {
775  curHocPanel->pushButton(name, action, false, pyact);
776  }
777 }
778 
779 void hoc_ivstatebutton(double* pd,
780  const char* name,
781  const char* action,
782  int style,
783  Object* pyvar,
784  Object* pyact) {
785  checkOpenPanel();
786  hoc_radio->stop();
787  if (menuStack && !menuStack->isEmpty()) {
788  menuStack->top()->append_item(curHocPanel->menuStateItem(pd, name, action, pyvar, pyact));
789  } else {
790  curHocPanel->stateButton(pd, name, action, style, pyvar, pyact);
791  }
792 }
793 
794 void hoc_ivradiobutton(const char* name, const char* action, bool activate, Object* pyact) {
795  checkOpenPanel();
796  if (!hoc_radio->group()) {
797  hoc_radio->start();
798  }
799  if (menuStack && !menuStack->isEmpty()) {
800  menuStack->top()->append_item(curHocPanel->menuItem(name, action, activate, pyact));
801  } else {
802  curHocPanel->pushButton(name, action, activate, pyact);
803  }
804 }
805 
806 void hoc_ivmenu(const char* name, bool add2menubar) {
807  if (!menuStack) {
808  menuStack = new MenuStack();
809  }
810  checkOpenPanel();
811  hoc_radio->stop();
812  if (name) {
813  HocMenu* m = curHocPanel->menu(name, add2menubar);
814  menuStack->push(m);
815  } else {
816  curHocPanel->itemAppend("xmenu()");
817  menuStack->pop();
818  }
819 }
820 
821 void hoc_ivvarmenu(const char* name, const char* action, bool add2menubar, Object* pyvar) {
822  if (!menuStack) {
823  menuStack = new MenuStack();
824  }
825  checkOpenPanel();
826  hoc_radio->stop();
827  HocMenu* m = curHocPanel->menu(name, add2menubar);
828  HocMenuAction* hma = new HocMenuAction(action, pyvar, m);
829  m->item()->action(hma);
830 }
831 
832 void hoc_ivvalue_keep_updated(const char* name, const char* variable, Object* pyvar) {
833  checkOpenPanel();
834  hoc_radio->stop();
835  Symbol* s = hoc_get_symbol(variable);
836  curHocPanel->valueEd(name,
837  variable,
838  NULL,
839  false,
840  hoc_val_pointer(variable),
841  false,
842  true,
843  (s ? s->extra : NULL),
844  pyvar);
845 }
846 
847 void hoc_ivvalue(const char* name, const char* variable, bool deflt, Object* pyvar) {
848  hoc_ivvaluerun(name, variable, NULL, deflt, false, false);
849 }
850 
851 void hoc_ivfixedvalue(const char* name, const char* variable, bool deflt, bool usepointer) {
852  hoc_ivvaluerun(name, variable, NULL, deflt, false, usepointer);
853 }
854 
855 void hoc_ivpvalue(const char* name, double* pd, bool deflt, HocSymExtension* extra) {
856  hoc_ivpvaluerun(name, pd, 0, deflt, false, extra);
857 }
858 
859 void hoc_ivvaluerun(const char* name,
860  const char* variable,
861  const char* action,
862  bool deflt,
863  bool canRun,
864  bool usepointer,
865  Object* pyvar,
866  Object* pyact) {
867  hoc_ivvaluerun_ex(name, variable, NULL, pyvar, action, pyact, deflt, canRun, usepointer);
868 }
869 
871  CChar* variable,
872  double* pvar,
873  Object* pyvar,
874  CChar* action,
875  Object* pyact,
876  bool deflt,
877  bool canrun,
878  bool usepointer,
879  HocSymExtension* extra) {
880  checkOpenPanel();
881  hoc_radio->stop();
882  Symbol* s = NULL;
883  if (!pvar && !pyvar) {
884  s = hoc_get_symbol(variable);
885  if (usepointer) {
886  pvar = hoc_val_pointer(variable);
887  }
888  }
889  HocSymExtension* xtra = extra;
890  if (!xtra) {
891  xtra = s ? s->extra : NULL;
892  }
893  curHocPanel->valueEd(name, variable, action, canrun, pvar, deflt, false, xtra, pyvar, pyact);
894 }
895 
896 void hoc_ivpvaluerun(const char* name,
897  double* pd,
898  const char* action,
899  bool deflt,
900  bool canRun,
901  HocSymExtension* extra) {
902  checkOpenPanel();
903  hoc_radio->stop();
904  curHocPanel->valueEd(name, 0, action, canRun, pd, deflt, false, extra);
905 }
906 
907 void hoc_ivlabel(const char* s) {
908  checkOpenPanel();
909  hoc_radio->stop();
910  curHocPanel->label(s);
911 }
912 
913 void hoc_ivvarlabel(char** s, Object* pyvar) {
914  checkOpenPanel();
915  hoc_radio->stop();
916  curHocPanel->var_label(s, pyvar);
917 }
918 
919 // ZFM added vert
920 void hoc_ivslider(double* pd,
921  float low,
922  float high,
923  float resolution,
924  int nsteps,
925  const char* s,
926  bool vert,
927  bool slow,
928  Object* pyvar,
929  Object* pyact) {
930  checkOpenPanel();
931  curHocPanel->slider(pd, low, high, resolution, nsteps, s, vert, slow, pyvar, pyact);
932 }
933 
934 static char* hideQuote(const char* s) {
935  static char buf[200];
936  const char* cp1;
937  char* cp2;
938 
939  cp2 = buf;
940  if (s)
941  for (cp1 = s; *cp1; cp1++, cp2++) {
942  if (*cp1 == '"') {
943  *cp2++ = '\\';
944  }
945  *cp2 = *cp1;
946  }
947  *cp2 = '\0';
948  return buf;
949 }
950 
951 static void saveMenuFile() {}
952 
953 void HocPanel::save_all(ostream&) {
954  if (!hoc_panel_list)
955  return;
956 
957  long i, cnt;
958 
959  HocDataPaths* data_paths = new HocDataPaths();
960  cnt = hoc_panel_list->count();
961  if (hoc_panel_list)
962  for (i = 0; i < cnt; ++i) {
963  hoc_panel_list->item(i)->data_path(data_paths, true);
964  }
965  data_paths->search();
966  if (hoc_panel_list)
967  for (i = 0; i < cnt; ++i) {
968  hoc_panel_list->item(i)->data_path(data_paths, false);
969  }
970  delete data_paths;
971 }
972 
973 void HocPanel::update_ptrs() {
974  if (!hoc_panel_list)
975  return;
976  int i, j;
977  for (i = 0; i < hoc_panel_list->count(); ++i) {
978  HocUpdateItemList& ul = hoc_panel_list->item(i)->elist_;
979  for (j = 0; j < ul.count(); ++j) {
980  ul.item(j)->update_ptrs();
981  }
982  }
983 }
984 
985 #if MAC
986 void HocPanel::mac_menubar() {
987  int i = 1;
988  int mindex = 0;
989  printf("menubar 0 %s\n", getName());
990  mac_menubar(mindex, i, 0);
991 }
992 
993 void HocPanel::mac_menubar(int& mindex, int& i, int m) {
994  int mr;
995  int mi = 0;
996  while (i < ilist_.count()) {
997  mr = ilist_.item(i)->mac_menubar(mindex, m, mi);
998  ++i;
999  ++mi;
1000  if (mr > m) {
1001  mac_menubar(mindex, i, mr);
1002  } else if (mr < m) {
1003  return;
1004  }
1005  }
1006  return;
1007 }
1008 #endif
1009 
1010 void HocPanel::map_window(int scroll) {
1011  // switch to scrollbox if too many items
1012  static GlyphIndex maxcnt = -1;
1013  if (1 || maxcnt == -1) {
1014  maxcnt = 12;
1015  Style* s = WidgetKit::instance()->style();
1016  s->find_attribute("panel_scroll", maxcnt);
1017  }
1018  if ((scroll == -1 && box_->count() > maxcnt) || scroll == 1) {
1019  LayoutKit& lk = *LayoutKit::instance();
1020  WidgetKit& wk = *WidgetKit::instance();
1021  ScrollBox* vsb = lk.vscrollbox(box_->count());
1022  while (box_->count()) {
1023  vsb->append(box_->component(0));
1024  box_->remove(0);
1025  }
1026  box_->append(lk.hbox(vsb, lk.hspace(4), wk.vscroll_bar(vsb)));
1027  }
1028 
1029  PrintableWindow* w = OcGlyph::make_window(left_, bottom_);
1030  w->style(new Style(WidgetKit::instance()->style()));
1031  w->style()->attribute("name", getName());
1032  w->map();
1033 }
1034 
1035 // HocPanel
1036 
1037 implementPtrList(HocUpdateItemList, HocUpdateItem);
1038 implementPtrList(HocItemList, HocItem);
1039 
1040 static void var_freed(void* pd, int size) {
1041  if (hoc_panel_list)
1042  for (long i = hoc_panel_list->count() - 1; i >= 0; --i) {
1043  hoc_panel_list->item(i)->check_valid_pointers(pd, size);
1044  }
1045 }
1046 
1047 HocPanel::HocPanel(const char* name, bool h)
1048  : OcGlyph(NULL) {
1049  LayoutKit& lk = *LayoutKit::instance();
1050  WidgetKit& wk = *WidgetKit::instance();
1051  horizontal_ = h;
1052  hocmenubar = NULL;
1053  if (h) {
1054  box_ = lk.hbox();
1055  } else {
1056  box_ = lk.vbox();
1057  }
1058  box_->ref();
1059  body(ih_ = new PanelInputHandler(
1060  new Background(new Border(lk.margin(lk.hflexible(box_, fil, 0), 3), wk.foreground()),
1061  wk.background()),
1062  wk.style()));
1063  if (!hoc_panel_list) {
1064  hoc_panel_list = new HocPanelList;
1065  Oc oc;
1066  oc.notify_freed(var_freed);
1067  }
1068  hoc_panel_list->append(this);
1069  item_append(new HocItem(name));
1070  left_ = -1000.;
1071  bottom_ = -1000.;
1072  errno = 0;
1073 }
1074 
1075 HocPanel::~HocPanel() {
1076  long i;
1077  box_->unref();
1078  for (i = 0; i < ilist_.count(); i++) {
1079  ilist_.item(i)->HocItem::unref();
1080  }
1081  for (i = 0; i < elist_.count(); i++) {
1082  elist_.item(i)->HocItem::unref();
1083  }
1084  for (i = 0; i < hoc_panel_list->count(); ++i) {
1085  if (hoc_panel_list->item(i) == this) {
1086  hoc_panel_list->remove(i);
1087  break;
1088  }
1089  }
1090  ilist_.remove_all();
1091  elist_.remove_all();
1092  // printf("~HocPanel\n");
1093 }
1094 
1095 // HocUpdateItem
1096 HocUpdateItem::HocUpdateItem(const char* name, HocItem* hi)
1097  : HocItem(name, hi) {}
1099  HocPanel::keep_updated(this, false);
1100 }
1102 void HocUpdateItem::check_pointer(void*, int) {}
1103 void HocUpdateItem::data_path(HocDataPaths*, bool) {}
1104 
1105 // ones that get updated on every doEvents()
1106 HocUpdateItemList* HocPanel::update_list_;
1107 
1108 void HocPanel::keep_updated() {
1109  static int cnt = 0;
1110  if (update_list_ && (++cnt % 10 == 0)) {
1111  long i, cnt = update_list_->count();
1112  if (cnt)
1113  for (i = 0; i < cnt; ++i) {
1114  update_list_->item(i)->update_hoc_item();
1115  }
1116  }
1117 }
1118 void HocPanel::keep_updated(HocUpdateItem* hui, bool add) {
1119  if (!update_list_) {
1120  update_list_ = new HocUpdateItemList();
1121  }
1122  if (add) {
1123  update_list_->append(hui);
1124  } else {
1125  for (long i = 0; i < update_list_->count(); ++i) {
1126  if (update_list_->item(i) == hui) {
1127  update_list_->remove(i);
1128  break;
1129  }
1130  }
1131  }
1132 }
1133 
1134 void HocPanel::paneltool(const char* name,
1135  const char* proc,
1136  const char* selact,
1137  ScenePicker* sp,
1138  Object* pycallback,
1139  Object* pyselact) {
1140  HocCommand* hc = pycallback ? new HocCommand(pycallback) : new HocCommand(proc);
1141  HocCommandTool* hct = new HocCommandTool(hc);
1142  HocAction* ha = NULL;
1143  if (selact || pyselact) {
1144  ha = new HocAction(selact, pyselact);
1145  }
1146  if (curHocPanel && (!menuStack || menuStack->isEmpty())) {
1147  Button* b = sp->radio_button(name, hct, ha);
1148  curHocPanel->box()->append(b);
1149  } else {
1150  sp->add_radio_menu(gargstr(1), hct, ha);
1151  }
1152 }
1153 
1154 void HocPanel::itemAppend(const char* str) {
1155  item_append(new HocItem(str));
1156 }
1157 
1158 PolyGlyph* HocPanel::box() {
1159  // return (PolyGlyph*)(((MonoGlyph*)body())->body());
1160  return box_;
1161 }
1162 
1163 const char* HocPanel::getName() {
1164  return ilist_.item(0)->getStr();
1165 }
1166 
1167 HocItem* HocPanel::hoc_item() {
1168  return ilist_.item(0);
1169 }
1170 
1171 void HocPanel::pushButton(const char* name, const char* action, bool activate, Object* pyact) {
1172  if (hoc_radio->group()) {
1173  HocRadioAction* a = new HocRadioAction(action, hoc_radio->group(), pyact);
1174  Button* b = WidgetKit::instance()->radio_button(hoc_radio->group(), name, a);
1175  box()->append(b);
1176  item_append(new HocRadioButton(name, a, hoc_item()));
1177  if (activate) {
1178  TelltaleState* tts = b->state();
1179  tts->set(TelltaleState::is_chosen, true);
1180  hoc_radio->group()->update(tts);
1181  }
1182  } else {
1183  HocAction* a = new HocAction(action, pyact);
1184  box()->append(WidgetKit::instance()->push_button(name, a));
1185  item_append(new HocPushButton(name, a, hoc_item()));
1186  }
1187 }
1188 
1189 HocPushButton::HocPushButton(const char* name, HocAction* a, HocItem* hi)
1190  : HocItem(name, hi) {
1191  a_ = a;
1192  Resource::ref(a);
1193  a->hoc_item(this);
1194 }
1197 }
1198 void HocPushButton::write(ostream& o) {
1199  char buf[200];
1200  nrn_assert(snprintf(buf, 200, "xbutton(\"%s\",\"%s\")", getStr(), hideQuote(a_->name())) < 200);
1201  o << buf << endl;
1202 }
1203 
1204 #if MAC
1205 int HocPushButton::mac_menubar(int&, int m, int mi) {
1206  printf("button item %d in menu %d \"%s\", \"%s\"\n", mi, m, getStr(), hideQuote(a_->name()));
1207  return m;
1208 }
1209 #endif
1210 
1211 HocRadioButton::HocRadioButton(const char* name, HocRadioAction* a, HocItem* hi)
1212  : HocItem(name, hi) {
1213  a_ = a;
1214  Resource::ref(a);
1215  a->hoc_item(this);
1216 }
1219 }
1220 void HocRadioButton::write(ostream& o) {
1221  char buf[200];
1222  nrn_assert(snprintf(buf, 200, "xradiobutton(\"%s\",\"%s\")", getStr(), hideQuote(a_->name())) <
1223  200);
1224  o << buf << endl;
1225 }
1226 
1227 #if MAC
1228 int HocRadioButton::mac_menubar(int&, int m, int mi) {
1229  printf("radio item %d in menu %d \"%s\", \"%s\"\n", mi, m, getStr(), hideQuote(a_->name()));
1230  return m;
1231 }
1232 #endif
1233 
1234 void HocPanel::label(const char* name) {
1235  box()->append(LayoutKit::instance()->margin(WidgetKit::instance()->label(name), 3));
1236  item_append(new HocLabel(name));
1237 }
1238 
1239 void HocPanel::var_label(char** name, Object* pyvar) {
1240  HocVarLabel* l = new HocVarLabel(name, box(), pyvar);
1241  item_append(l);
1242  elist_.append(l);
1243  l->ref();
1244 }
1245 
1246 // ZFM added vert
1247 void HocPanel::slider(double* pd,
1248  float low,
1249  float high,
1250  float resolution,
1251  int nsteps,
1252  const char* send,
1253  bool vert,
1254  bool slow,
1255  Object* pyvar,
1256  Object* pysend) {
1257  OcSlider* s = new OcSlider(pd, low, high, resolution, nsteps, send, vert, slow, pyvar, pysend);
1258  LayoutKit* lk = LayoutKit::instance();
1259  WidgetKit* wk = WidgetKit::instance();
1260  if (slow) {
1261  wk->begin_style("SlowSlider");
1262  }
1263  if (vert) {
1264  box()->append(lk->hflexible(WidgetKit::instance()->vscroll_bar(s->adjustable())));
1265  } else {
1266  box()->append(lk->hflexible(WidgetKit::instance()->hscroll_bar(s->adjustable())));
1267  }
1268  if (slow) {
1269  wk->end_style();
1270  }
1271  item_append(s);
1272  elist_.append(s);
1273  s->ref();
1274 }
1275 
1276 HocMenu* HocPanel::menu(const char* name, bool add2menubar) {
1277  WidgetKit* wk = WidgetKit::instance();
1278  Menu* m = wk->pulldown();
1279  MenuItem* mi;
1280  HocMenu* hm;
1281  if (menuStack->isEmpty()) {
1282  Menu* m0;
1283  if (!add2menubar) {
1284  hocmenubar = NULL;
1285  }
1286  if (hocmenubar) {
1287  m0 = hocmenubar;
1288  } else {
1289  m0 = wk->menubar();
1290  hocmenubar = m0;
1291  LayoutKit* lk = LayoutKit::instance();
1292  box()->append(lk->hbox(m0, lk->hglue()));
1293  }
1294  mi = wk->menubar_item(name);
1295  m0->append_item(mi);
1296  hm = new HocMenu(name, m, mi, hoc_item(), add2menubar);
1297  } else {
1298  mi = K::menu_item(name);
1299  menuStack->top()->append_item(mi);
1300  hm = new HocMenu(name, m, mi, menuStack->hoc_item());
1301  }
1302  item_append(hm);
1303  mi->menu(m);
1304  return hm;
1305 }
1306 
1307 MenuItem* HocPanel::menuItem(const char* name, const char* act, bool activate, Object* pyact) {
1308  MenuItem* mi;
1309  if (hoc_radio->group()) {
1310  HocRadioAction* a = new HocRadioAction(act, hoc_radio->group(), pyact);
1311  mi = K::radio_menu_item(hoc_radio->group(), name);
1312  mi->action(a);
1313  item_append(new HocRadioButton(name, a, menuStack->hoc_item()));
1314  if (activate) {
1315  TelltaleState* tts = mi->state();
1316  tts->set(TelltaleState::is_chosen, true);
1317  hoc_radio->group()->update(tts);
1318  }
1319  } else {
1320  HocAction* a = new HocAction(act, pyact);
1321  mi = K::menu_item(name);
1322  mi->action(a);
1323  item_append(new HocPushButton(name, a, menuStack->hoc_item()));
1324  }
1325  return mi;
1326 }
1327 
1328 HocMenu::HocMenu(const char* name, Menu* m, MenuItem* mi, HocItem* hi, bool add2menubar)
1329  : HocItem(name, hi) {
1330  menu_ = m;
1331  mi_ = mi;
1332  add2menubar_ = add2menubar;
1333  m->ref();
1334 }
1336  menu_->unref();
1337 }
1338 void HocMenu::write(ostream& o) {
1339  char buf[200];
1340  sprintf(buf, "xmenu(\"%s\", %d)", getStr(), add2menubar_);
1341  o << buf << endl;
1342 }
1343 
1344 #if MAC
1345 int HocMenu::mac_menubar(int& mindex, int m, int mi) {
1346  ++mindex;
1347  printf("menu %d is item %d in %d %s\n", mindex, mi, m, getStr());
1348  return mindex;
1349 }
1350 #endif
1351 
1352 static Coord xvalue_field_size;
1353 
1354 void HocPanel::valueEd(const char* prompt,
1355  Object* pyvar,
1356  Object* pyact,
1357  bool canrun,
1358  bool deflt,
1359  bool keep_updated) {
1360  valueEd(prompt, NULL, NULL, canrun, NULL, deflt, keep_updated, NULL, pyvar, pyact);
1361 }
1362 
1363 void HocPanel::valueEd(const char* name,
1364  const char* variable,
1365  const char* action,
1366  bool canrun,
1367  double* pd,
1368  bool deflt,
1369  bool keep_updated,
1370  HocSymExtension* extra,
1371  Object* pyvar,
1372  Object* pyact) {
1373  HocValAction* act;
1374  if (pyact || action) {
1375  act = new HocValAction(action, pyact);
1376  } else {
1377  act = new HocValAction("");
1378  }
1379  ValEdLabel* vel;
1380  float* limits = 0;
1381  if (extra && extra->parmlimits) {
1382  limits = extra->parmlimits;
1383  }
1384  if (extra && extra->units && units_on_flag_) {
1385  char nu[256];
1386  sprintf(nu, "%s (%s)", name, extra->units);
1387  vel = new ValEdLabel(WidgetKit::instance()->label(nu));
1388  } else {
1389  vel = new ValEdLabel(WidgetKit::instance()->label(name));
1390  }
1391  Button* prompt;
1392  if (canrun) {
1393  prompt = WidgetKit::instance()->default_button(vel, act);
1394  } else {
1395  prompt = WidgetKit::instance()->push_button(vel, act);
1396  }
1397  vel->tts(prompt->state());
1398  HocValEditor* fe;
1399  Button* def;
1400  if (deflt) {
1401  HocDefaultValEditor* dve =
1402  new HocDefaultValEditor(name, variable, vel, act, pd, canrun, hoc_item(), pyvar);
1403  def = dve->checkbox();
1404  fe = dve;
1405  } else if (keep_updated) {
1406  fe = new HocValEditorKeepUpdated(name, variable, vel, act, pd, hoc_item(), pyvar);
1407  } else {
1408  fe = new HocValEditor(name, variable, vel, act, pd, canrun, hoc_item(), pyvar);
1409  }
1410  ih_->append_input_handler(fe->field_editor());
1411  elist_.append(fe);
1412  fe->ref();
1413  act->setFieldSEditor(fe); // so button can change the editor
1414  LayoutKit* lk = LayoutKit::instance();
1415  // from mike_neubig_ivoc_xmenu
1416  float fct;
1417  Style* s = WidgetKit::instance()->style();
1418  if (!s->find_attribute("stepper_size", fct)) {
1419  fct = 20;
1420  }
1421  if (deflt) {
1422  box()->append(lk->hbox(lk->vcenter(prompt),
1423  lk->vcenter(def),
1424  lk->vcenter(lk->h_fixed_span(fe->field_editor(), xvalue_field_size)),
1425  lk->vcenter(lk->fixed(fe->stepper(), (int) fct, (int) fct))));
1426  } else {
1427  box()->append(
1428  lk->hbox(prompt,
1429  lk->h_fixed_span(fe->field_editor(), xvalue_field_size),
1430  (fe->stepper() ? lk->fixed(fe->stepper(), int(fct), int(fct)) : NULL)));
1431  }
1432  item_append(fe);
1433  if (limits) {
1434  fe->setlimits(limits);
1435  }
1436  last_fe_constructed_ = fe;
1437 }
1438 
1439 void HocPanel::save(ostream& o) {
1440  o << "{" << endl;
1441  write(o);
1442  o << "}" << endl;
1443 }
1444 
1445 void HocPanel::write(ostream& o) {
1446  Oc oc;
1447  char buf[200];
1448  long i;
1449  // o << "xpanel(\"" << getName() << "\")" << endl;
1450  sprintf(buf, "xpanel(\"%s\", %d)", getName(), horizontal_);
1451  o << buf << endl;
1452  for (i = 1; i < ilist_.count(); i++) {
1453  ilist_.item(i)->write(o);
1454  }
1455  if (has_window()) {
1456  sprintf(buf, "xpanel(%g,%g)", window()->save_left(), window()->save_bottom());
1457  o << buf << endl;
1458  } else {
1459  o << "xpanel()" << endl;
1460  }
1461 }
1462 
1463 void HocPanel::item_append(HocItem* hi) {
1464  hi->ref();
1465  ilist_.append(hi);
1466 }
1467 
1468 // HocItem
1469 HocItem::HocItem(const char* str, HocItem* hi)
1470  : str_(str) {
1471  help_parent_ = hi;
1472 }
1474  // printf("~HocItem %s\n", str_.string());
1475 }
1476 void HocItem::write(ostream& o) {
1477  o << str_.string() << endl;
1478 }
1479 
1480 #if MAC
1481 int HocItem::mac_menubar(int&, int m, int mi) {
1482  if (strcmp(getStr(), "xmenu()") == 0) {
1483  printf("end menu %d\n", m);
1484  return -1;
1485  } else {
1486  printf("invalid menuitem %s\n", getStr());
1487  }
1488  return m;
1489 }
1490 #endif
1491 
1492 const char* HocItem::getStr() {
1493  return str_.string();
1494 }
1495 
1496 void HocItem::help_parent(HocItem* hi) {
1497  help_parent_ = hi; // not reffed
1498 }
1499 
1500 void HocItem::help(const char* child) {
1501  const char* c1;
1502  char buf[200], *c2 = buf;
1503  char path[512];
1504  for (c1 = getStr(); *c1; ++c1) {
1505  if (isalnum(*c1)) {
1506  *c2++ = *c1;
1507  }
1508  }
1509  *c2 = '\0';
1510  if (child) {
1511  sprintf(path, "%s %s", child, buf);
1512  } else {
1513  strcpy(path, buf);
1514  }
1515  if (help_parent_) {
1516  help_parent_->help(path);
1517  } else {
1518  Oc::help(path);
1519  }
1520 }
1521 
1522 // HocLabel
1523 HocLabel::HocLabel(const char* s)
1524  : HocItem(s) {}
1526 void HocLabel::write(ostream& o) {
1527  char buf[210];
1528  sprintf(buf, "xlabel(\"%s\")", hideQuote(getStr()));
1529  o << buf << endl;
1530 }
1531 
1532 #if 0
1533 extern void purify_watch_rw_4(char**);
1534 #endif
1535 
1536 // HocVarLabel
1537 HocVarLabel::HocVarLabel(char** cpp, PolyGlyph* pg, Object* pyvar)
1538  : HocUpdateItem("") {
1539  // purify_watch_rw_4(cpp);
1540  pyvar_ = pyvar;
1541  cpp_ = cpp;
1542  cp_ = NULL;
1543  if (pyvar_) {
1544  hoc_obj_ref(pyvar_);
1545  (*nrnpy_guigetstr)(pyvar_, &cp_);
1546  } else {
1547  cp_ = *cpp_;
1548  }
1549  variable_ = NULL;
1550  p_ = new Patch(LayoutKit::instance()->margin(WidgetKit::instance()->label(cp_), 3));
1551  p_->ref();
1552  pg->append(p_);
1553 }
1554 
1556  p_->unref();
1557  if (variable_) {
1558  delete variable_;
1559  }
1560  if (pyvar_) {
1562  if (cp_) {
1563  delete[] cp_;
1564  }
1565  }
1566 }
1567 
1568 void HocVarLabel::write(ostream& o) {
1569  if (variable_ && cpp_) {
1570  char buf[256];
1571  sprintf(buf, "xvarlabel(%s)", variable_->string());
1572  o << buf << endl;
1573  } else {
1574  o << "xlabel(\"<can't retrieve>\")" << endl;
1575  }
1576 }
1577 
1579  if (pyvar_) {
1580  if ((*nrnpy_guigetstr)(pyvar_, &cp_)) {
1581  p_->body(LayoutKit::instance()->margin(WidgetKit::instance()->label(cp_), 3));
1582  p_->redraw();
1583  p_->reallocate();
1584  p_->redraw();
1585  }
1586  } else if (cpp_) {
1587  // printf("update %s\n", cp_);
1588  if (*cpp_ != cp_) {
1589  cp_ = *cpp_;
1590  // printf("replacing with %s\n", cp_);
1591  p_->body(LayoutKit::instance()->margin(WidgetKit::instance()->label(cp_), 3));
1592  p_->redraw();
1593  p_->reallocate();
1594  p_->redraw();
1595  }
1596  } else if (cp_) {
1597  cp_ = 0;
1598  // printf("HocVarLabel::update() freed\n");
1599  p_->body(LayoutKit::instance()->margin(WidgetKit::instance()->label("Free'd"), 3));
1600  p_->redraw();
1601  p_->reallocate();
1602  p_->redraw();
1603  }
1604 }
1605 
1606 HocMenuAction::HocMenuAction(const char* action, Object* pyact, HocMenu* hm)
1607  : HocAction(action, pyact) {
1608  hm_ = hm;
1609  hp_ = NULL;
1610 }
1613 }
1614 void HocMenuAction::execute() {
1615  while (hm_->menu()->item_count()) {
1616  hm_->menu()->remove_item(0);
1617  }
1619  hp_ = NULL;
1620  hoc_ivpanel("");
1621  menuStack->push(hm_);
1623  menuStack->pop();
1624  checkOpenPanel();
1625  hp_ = curHocPanel;
1626  curHocPanel = NULL;
1627  hm_->item()->menu(hm_->menu());
1628 }
1629 
1630 // HocAction
1631 HocAction::HocAction(const char* action, Object* pyact) {
1632  hi_ = NULL;
1633  if (pyact) {
1634  action_ = new HocCommand(pyact);
1635  } else if (action && action[0] != '\0') {
1636  action_ = new HocCommand(action);
1637  } else {
1638  action_ = NULL;
1639  }
1640 }
1641 
1643  if (action_) {
1644  delete action_;
1645  }
1646 }
1647 
1648 void HocAction::hoc_item(HocItem* hi) {
1649  hi_ = hi;
1650 }
1651 
1652 void HocAction::execute() {
1653  if (Oc::helpmode()) {
1654  help();
1655  return;
1656  }
1658  if (action_) {
1659  action_->audit();
1660  action_->execute();
1661  } else {
1662  Oc oc;
1663  oc.notify();
1664  }
1665 }
1666 
1667 void HocAction::help() {
1668  if (hi_) {
1669  hi_->help();
1670  }
1671 }
1672 
1673 const char* HocAction::name() const {
1674  if (action_) {
1675  return action_->name();
1676  } else {
1677  return "";
1678  }
1679 }
1680 
1681 #if UseFieldEditor
1682 declareFieldEditorCallback(HocValAction) implementFieldEditorCallback(HocValAction)
1683 #else
1686 #endif
1687  // HocValAction
1688  HocValAction::HocValAction(const char* action, Object* pyact)
1689  : HocAction(action, pyact) {
1690  fe_ = NULL;
1691 #if UseFieldEditor
1692  fea_ = new FieldEditorCallback(HocValAction)(
1693 #else
1694  fea_ = new FieldSEditorCallback(HocValAction)(
1695 #endif
1696  this, &HocValAction::accept, NULL);
1697  fea_->ref();
1698 }
1699 
1701  // printf("~HocValAction\n");
1702  fea_->unref();
1703 }
1704 
1706  fe_ = fe; // but not referenced since this action is referenced by fe
1707 }
1708 
1710  if (fe_->active()) {
1711  fe_->field_editor()->parent()->focus(NULL);
1712  } else {
1713  fe_->evalField();
1714  }
1715  fe_->audit();
1717 }
1718 
1719 void HocValAction::execute() {
1720  if (Oc::helpmode()) {
1721  fe_->help();
1722  return;
1723  }
1724  accept(fe_->field_editor());
1725 }
1726 
1727 class HocDefaultCheckbox: public Button {
1728  public:
1729  HocDefaultCheckbox(HocDefaultValEditor*, Glyph*, Style*, TelltaleState*, Action*);
1730  virtual ~HocDefaultCheckbox();
1731  static HocDefaultCheckbox* instance(HocDefaultValEditor*);
1732  virtual void release(const Event&);
1733 
1734  private:
1735  HocDefaultValEditor* dve_;
1736 };
1737 
1738 HocDefaultCheckbox::HocDefaultCheckbox(HocDefaultValEditor* dve,
1739  Glyph* g,
1740  Style* s,
1741  TelltaleState* t,
1742  Action* a)
1743  : Button(g, s, t, a) {
1744  dve_ = dve;
1745 }
1746 
1747 HocDefaultCheckbox::~HocDefaultCheckbox() {}
1748 
1749 HocDefaultCheckbox* HocDefaultCheckbox::instance(HocDefaultValEditor* dve) {
1750  Glyph* g;
1751  TelltaleState* t;
1752  WidgetKit& k = *WidgetKit::instance();
1753  Style* s;
1754  k.begin_style("ToggleButton", "Button");
1755  t = new TelltaleState(TelltaleState::is_enabled | TelltaleState::is_toggle);
1756  g = k.check_box_look(NULL, t);
1757  s = k.style();
1758  HocDefaultCheckbox* cb = new HocDefaultCheckbox(dve, g, s, t, NULL);
1759  k.end_style();
1760  return cb;
1761 }
1762 
1763 void HocDefaultCheckbox::release(const Event& e) {
1764  if (Oc::helpmode()) {
1765  Button::release(e);
1766  }
1767  if (e.pointer_button() == Event::right) {
1768  dve_->def_change(e.pointer_root_x(), e.pointer_root_y());
1769  }
1770  Button::release(e);
1771 }
1772 
1773 declareActionCallback(HocDefaultValEditor);
1774 implementActionCallback(HocDefaultValEditor);
1775 
1776 // HocDefaultValEditor
1778  const char* variable,
1779  ValEdLabel* prompt,
1780  HocValAction* a,
1781  double* pd,
1782  bool canrun,
1783  HocItem* hi,
1784  Object* pyvar)
1785  : HocValEditor(name, variable, prompt, a, pd, canrun, hi, pyvar) {
1786  checkbox_ = HocDefaultCheckbox::instance(this);
1787  checkbox_->ref();
1788  checkbox_->action(
1789  new ActionCallback(HocDefaultValEditor)(this, &HocDefaultValEditor::def_action));
1790  evalField();
1791  deflt_ = most_recent_ = get_val();
1792  vs_ = HocValStepper::instance(this);
1793  Resource::ref(vs_);
1794 }
1795 
1797  checkbox_->unref();
1798  vs_->unref();
1799 }
1800 
1801 void HocDefaultValEditor::def_change(float x0, float y0) {
1802  evalField();
1803  double x = get_val();
1804  if (x != deflt_) {
1805  char form[200], buf[200];
1806  sprintf(form,
1807  "Permanently replace default value %s with %s",
1808  xvalue_format->string(),
1809  xvalue_format->string());
1810  sprintf(buf, form, deflt_, x);
1811  if (boolean_dialog(buf, "Replace", "Cancel", NULL, x0, y0)) {
1812  deflt_ = x;
1813  most_recent_ = x;
1814  }
1815  }
1816 }
1817 
1820  TelltaleState* t = checkbox_->state();
1821  // printf("telltale flag %x\n", t->flags());
1822  bool same = (hoc_ac_ == deflt_);
1823  bool chosen = t->test(TelltaleState::is_chosen);
1824  if (same && chosen) {
1825  t->set(TelltaleState::is_chosen, false);
1826  } else if (!same) {
1828  if (!chosen) {
1829  t->set(TelltaleState::is_chosen, true);
1830  }
1831  }
1832 }
1833 
1834 void HocDefaultValEditor::deflt(double d) {
1835  deflt_ = d;
1836 }
1837 
1839  if (Oc::helpmode()) {
1840  checkbox_->state()->set(TelltaleState::is_chosen,
1841  !checkbox_->state()->test(TelltaleState::is_chosen));
1842  Oc::help(Editor_Default);
1843  return;
1844  }
1845  bool chosen = checkbox_->state()->test(TelltaleState::is_chosen);
1846  if (chosen) {
1847  if (most_recent_ != deflt_) {
1849  }
1850  } else {
1851  double x = get_val();
1852  if (deflt_ != x) {
1853  most_recent_ = x;
1854  set_val(deflt_);
1855  }
1856  }
1857  // Oc oc;
1858  // oc.notifyHocValue();
1859  updateField();
1860  exec_action();
1861 }
1862 
1863 // HocValEditorKeepUpdated
1865  const char* variable,
1866  ValEdLabel* prompt,
1867  HocValAction* act,
1868  double* pd,
1869  HocItem* hi,
1870  Object* pyvar)
1871  : HocValEditor(name, variable, prompt, act, pd, false, hi, pyvar) {
1872  // printf("~HocValEditorKeepUpdated\n");
1873  HocPanel::keep_updated(this, true);
1874 }
1876  // printf("~HocValEditorKeepUpdated\n");
1877  HocPanel::keep_updated(this, false);
1878 }
1879 
1880 // HocEditorForItem g++ doesn't do multiple inheritance of same base classes.
1881 
1883  : FieldSEditor("", WidgetKit::instance(), Session::instance()->style(), a->fea()) {
1884  hve_ = he;
1885 #ifdef WIN32
1887 #endif
1888  // hve_->ref();
1889 }
1891  // hve_->unref();
1892 }
1893 
1894 
1895 static void set_format() {
1896  static Coord len;
1897  if (!xvalue_format) {
1898  xvalue_format = new String("%.5g");
1899  WidgetKit::instance()->style()->find_attribute("xvalue_format", *xvalue_format);
1900  char buf[100];
1901  sprintf(buf, xvalue_format->string(), -8.888888888888888e-18);
1902  Glyph* g = WidgetKit::instance()->label(buf);
1903  g->ref();
1904  Requisition r;
1905  g->request(r);
1906 
1907  // mike_neubig_ivoc_xmenu
1908  float fct;
1909  Style* s = WidgetKit::instance()->style();
1910  if (!s->find_attribute("xvalue_field_size_increase", fct)) {
1911  fct = 10;
1912  }
1913  xvalue_field_size = r.x_requirement().natural() + fct;
1914  g->unref();
1915  }
1916 }
1917 
1918 double MyMath::resolution(double x) {
1919  if (!xvalue_format) {
1920  set_format();
1921  }
1922  char buf[100];
1923  sprintf(buf, xvalue_format->string(), Math::abs(x));
1924  char* cp;
1925  char* least = NULL;
1926  for (cp = buf; *cp; ++cp) {
1927  if (isdigit(*cp)) {
1928  least = cp;
1929  break;
1930  }
1931  }
1932  for (; *cp; ++cp) {
1933  if (*cp >= '1' && *cp <= '9') {
1934  *cp = '0';
1935  least = cp;
1936  }
1937  if (isalpha(*cp)) {
1938  break;
1939  }
1940  }
1941  assert(least);
1942  *least = '1';
1943  double y;
1944  sscanf(buf, "%lf", &y);
1945  return y;
1946 }
1947 
1948 // HocValEditor
1949 HocValEditor::HocValEditor(const char* name,
1950  const char* variable,
1951  ValEdLabel* prompt,
1952  HocValAction* a,
1953  double* pd,
1954  bool canrun,
1955  HocItem* hi,
1956  Object* pyvar)
1957  : HocUpdateItem(name, hi) {
1958  if (!xvalue_format) {
1959  set_format();
1960  }
1961  action_ = a;
1962  fe_ = new HocEditorForItem(this, a);
1963  fe_->ref();
1964  Resource::ref(a);
1965  prompt_ = prompt;
1966  prompt->ref();
1967  canrun_ = canrun;
1968  active_ = false;
1969  domain_limits_ = NULL;
1970  variable_ = NULL;
1971  pyvar_ = pyvar;
1972  pval_ = NULL;
1973  if (pd) {
1974  pval_ = pd;
1975  }
1976  if (pyvar) {
1977  hoc_obj_ref(pyvar);
1978  } else if (variable) {
1979  variable_ = new CopyString(variable);
1980  Symbol* sym = hoc_get_symbol(variable);
1981  if (sym && sym->extra) {
1982  domain_limits_ = sym->extra->parmlimits;
1983  }
1984  }
1986  fe_->focus_out();
1987 }
1988 
1990  // printf("~HocValEditor\n");
1991  if (variable_) {
1992  delete variable_;
1993  }
1994  if (pyvar_) {
1996  }
1999  fe_->unref();
2000 }
2001 
2002 void HocValEditor::setlimits(float* limits) {
2004 }
2005 
2007  updateField();
2008 }
2009 
2011  if (action_) {
2012  action_->execute();
2013  } else {
2014  Oc oc;
2015  oc.notify();
2016  }
2017 }
2018 
2019 void HocValEditor::print(Printer* p, const Allocation& a) const {
2020  // printf("HocvalEditor::print\n");
2021  Glyph* l = WidgetKit::instance()->label(*fe_->text());
2022  l->ref();
2023  l->print(p, a);
2024  l->unref();
2025 }
2026 
2027 void HocValEditor::set_val(double x) {
2028  char buf[200];
2029  if (pyvar_) {
2030  (*nrnpy_guisetval)(pyvar_, x);
2031  return;
2032  }
2033  hoc_ac_ = x;
2034  Oc oc;
2035  if (pval_) {
2036  *pval_ = hoc_ac_;
2037  } else if (variable_) {
2038  sprintf(buf, "%s = hoc_ac_\n", variable_->string());
2039  oc.run(buf);
2040  }
2041 }
2042 
2043 double HocValEditor::get_val() {
2044  char buf[200];
2045  if (pyvar_) {
2046  return (*nrnpy_guigetval)(pyvar_);
2047  } else if (pval_) {
2048  return *pval_;
2049  } else if (variable_) {
2050  Oc oc;
2051  sprintf(buf, "hoc_ac_ = %s\n", variable_->string());
2052  oc.run(buf);
2053  return hoc_ac_;
2054  } else {
2055  return 0.;
2056  }
2057 }
2058 
2059 double HocValEditor::domain_limits(double val) {
2060  return check_domain_limits(domain_limits_, val);
2061 }
2062 
2063 void HocValEditor::evalField() {
2064  char buf[200];
2065  Oc oc;
2066  sprintf(buf, "hoc_ac_ = %s\n", fe_->text()->string());
2067  oc.run(buf);
2069  set_val(hoc_ac_);
2070  // prompt_->state()->set(TelltaleState::is_active, false);
2071  prompt_->state(false);
2072 }
2073 
2074 void HocValEditor::audit() {
2075  char buf[200];
2076  if (pyvar_) {
2077  return;
2078  } else if (variable_) {
2079  sprintf(buf, "%s = %s\n", variable_->string(), fe_->text()->string());
2080  } else if (pval_) {
2081  sprintf(buf, "// %p pointer set to %s\n", pval_, fe_->text()->string());
2082  }
2084 }
2085 
2087  if (active_)
2088  return;
2089  char buf[200];
2090  if (pyvar_) {
2091  hoc_ac_ = get_val();
2092  sprintf(buf, xvalue_format->string(), hoc_ac_);
2093  } else if (pval_) {
2094  sprintf(buf, xvalue_format->string(), *pval_);
2095  hoc_ac_ = *pval_;
2096  } else if (variable_) {
2097  Oc oc;
2098  sprintf(buf, "hoc_ac_ = %s\n", variable_->string());
2099  if (oc.run(buf, 0)) {
2100  strcpy(buf, "Doesn't exist");
2101  } else {
2102  sprintf(buf, xvalue_format->string(), hoc_ac_);
2103  }
2104  } else {
2105  sprintf(buf, "Free'd");
2106  }
2107  if (strcmp(buf, fe_->text()->string()) != 0) {
2108  fe_->field(buf);
2109  }
2110 }
2111 
2112 void HocValEditor::write(ostream& o) {
2113  char buf[200];
2114  Oc oc;
2115  if (variable_) {
2116  sprintf(buf, "hoc_ac_ = %s\n", variable_->string());
2117  oc.run(buf);
2118  sprintf(buf, "%s = %g", variable_->string(), hoc_ac_);
2119  } else if (pval_) {
2120  sprintf(buf, "/* don't know the hoc path to %g", *pval_);
2121  return;
2122  } else {
2123  sprintf(buf, "/* variable freed */");
2124  return;
2125  }
2126  o << buf << endl;
2127 
2128  int usepointer;
2129  if (pval_) {
2130  usepointer = 1;
2131  } else {
2132  usepointer = 0;
2133  }
2134  nrn_assert(snprintf(buf,
2135  200,
2136  "xvalue(\"%s\",\"%s\", %d,\"%s\", %d, %d )",
2137  getStr(),
2138  variable_->string(),
2140  hideQuote(action_->name()),
2141  (int) canrun_,
2142  usepointer) < 200);
2143  o << buf << endl;
2144 }
2145 
2146 const char* HocValEditor::variable() const {
2147  if (variable_) {
2148  return variable_->string();
2149  } else {
2150  return NULL;
2151  }
2152 }
2153 
2154 
2155 void HocValEditorKeepUpdated::write(ostream& o) {
2156  char buf[200];
2157  Oc oc;
2158  sprintf(buf, "hoc_ac_ = %s\n", variable());
2159  oc.run(buf);
2160  sprintf(buf, "%s = %g", variable(), hoc_ac_);
2161  o << buf << endl;
2162  sprintf(buf, "xvalue(\"%s\",\"%s\", 2 )", getStr(), variable());
2163  o << buf << endl;
2164 }
2165 
2166 void HocEditorForItem::keystroke(const Event& e) {
2167  bool unfocus = false;
2168  if (!hve_->active_) {
2169  return;
2170  }
2171  if (Oc::helpmode()) {
2172  hve_->help();
2173  return;
2174  }
2175  char buf[2];
2176  if (e.mapkey(buf, 1) > 0)
2177  switch (buf[0]) {
2178  case '\n':
2179  case '\r':
2180  unfocus = true;
2181  break;
2182  case '\033':
2183  hve_->active_ = false;
2184  hve_->updateField();
2185  hve_->active_ = true;
2186  parent()->focus(NULL);
2187  return;
2188  case '\007':
2189  hve_->active_ = false;
2190  hve_->updateField();
2191  hve_->active_ = true;
2192  return;
2193  default:
2194  break;
2195  }
2197  if (unfocus) {
2198  parent()->focus(NULL);
2199  }
2200 }
2201 class HocEditorTempData {
2202  public:
2203  void init(const Event&);
2204  int sn(const Event&);
2205 #if 0
2206  Coord x_, y_;
2207  Coord xd_, yd_;
2208 #endif
2209  int sn_;
2210  int index_;
2211  EventButton b_;
2212 };
2213 
2214 static HocEditorTempData etd;
2215 
2216 void HocEditorTempData::init(const Event& e) {
2217 #if 0
2218  x_ = e.pointer_x();
2219  y_ = e.pointer_y();
2220  xd_ = 1.;
2221  yd_ = 1.;
2222 #endif
2223  b_ = e.pointer_button();
2224  if (b_ == Event::right) {
2225  sn_ = -1;
2226  } else {
2227  sn_ = 1;
2228  }
2229 }
2230 
2231 int HocEditorTempData::sn(const Event&) {
2232 #if 0
2233  float xnew = e.pointer_x();
2234  float ynew = e.pointer_y();
2235 #undef RES
2236 #define RES 3
2237  if (Math::equal(x_, xnew, float(RES)) && Math::equal(y_, ynew, float(RES))) {
2238  return 0;
2239  }
2240  sn_ = ( ((xnew - x_)*xd_ + (ynew - y_)*yd_ >= 0.)) ? sn_ : -sn_;
2241  xd_ = xnew - x_;
2242  yd_ = ynew - y_;
2243  x_ = xnew;
2244  y_ = ynew;
2245 #endif
2246  return sn_;
2247 }
2248 
2249 void HocEditorForItem::press(const Event& e) {
2250  if (Oc::helpmode()) {
2251  hve_->help();
2252  return;
2253  }
2254  // if (!hve_->active_) {
2255  // focus_in();
2256  // }
2258 #if !UseFieldEditor
2259  int start;
2261  etd.init(e);
2262 #endif
2263 }
2264 
2265 void HocEditorForItem::drag(const Event& e) {
2266 #ifdef WIN32
2268 #else
2269  if (etd.b_ == Event::left) {
2271  } else {
2272  val_inc(e);
2273  }
2274 #endif
2275 }
2276 
2277 void HocEditorForItem::val_inc(const Event& e) {
2278  int index = index_;
2279  int i, sn;
2280  i = index;
2281  sn = etd.sn(e);
2282  if (sn == 0) {
2283  return;
2284  }
2285  const char* s = text()->string();
2286  char abuf[100];
2287  char* buf = abuf + 1;
2288  strcpy(buf, s);
2289  if (i == strlen(buf)) {
2290  buf[i] = '0';
2291  buf[i + 1] = '\0';
2292  }
2293  while (i >= 0) {
2294  if (isdigit(buf[i])) {
2295  buf[i] = (((buf[i] - '0') + sn + 100) % 10) + '0';
2296  if (sn == 1 && buf[i] != '0') {
2297  break;
2298  } else if (sn == -1 && buf[i] != '9') {
2299  break;
2300  }
2301  }
2302  --i;
2303  }
2304  if (i < 0) {
2305  if (buf[0] == '-') {
2306  if (sn == 1) {
2307  buf[0] = '1';
2308  abuf[0] = '-';
2309  buf = abuf;
2310  ++index_;
2311  } else {
2312  strcpy(buf, s);
2313  }
2314  } else {
2315  if (sn == 1) {
2316  abuf[0] = '1';
2317  buf = abuf;
2318  ++index_;
2319  } else {
2320  strcpy(buf, s);
2321  }
2322  }
2323  }
2324  field(buf);
2325 }
2326 
2327 void HocEditorForItem::release(const Event& e) {
2329 }
2330 
2331 
2333  // printf("HocEditorForItem::focus_in()\n");
2334  if (Oc::helpmode()) {
2335  return NULL;
2336  }
2337  if (!hve_->active_) {
2338  // hve_->prompt_->state()->set(TelltaleState::is_active, true);
2339  hve_->prompt_->state(true);
2340  hve_->active_ = true;
2341  return FieldSEditor::focus_in();
2342  } else {
2343  return InputHandler::focus_in();
2344  }
2345 }
2346 
2348  if (hve_->active_) {
2349  hve_->active_ = false;
2350  // hve_->prompt_->state()->set(TelltaleState::is_active, false);
2351  hve_->prompt_->state(false);
2352  hve_->evalField();
2353  }
2355  if (PanelInputHandler::has_old_focus()) {
2356  // printf("old focus out %p\n", (InputHandler*)this);
2357  hve_->exec_action();
2358  }
2359 }
2360 
2361 void Oc::notifyHocValue() {
2362  // static int j=0;
2363  // printf("notifyHocValue %d\n", ++j);
2364  ParseTopLevel ptl;
2365  ptl.save();
2366  if (hoc_panel_list)
2367  for (long i = hoc_panel_list->count() - 1; i >= 0; --i) {
2368  hoc_panel_list->item(i)->notifyHocValue();
2369  }
2370  ptl.restore();
2371 }
2372 
2373 void HocPanel::notifyHocValue() {
2374  for (long i = elist_.count() - 1; i >= 0; --i) {
2375  elist_.item(i)->update_hoc_item();
2376  }
2377 }
2378 
2379 void HocPanel::check_valid_pointers(void* v, int size) {
2380  for (long i = elist_.count() - 1; i >= 0; --i) {
2381  elist_.item(i)->check_pointer(v, size);
2382  }
2383 }
2384 
2385 void HocValEditor::check_pointer(void* v, int size) {
2386  if (pval_) {
2387  double* pd = (double*) v;
2388  if (size == 1) {
2389  if (pd != pval_)
2390  return;
2391  } else {
2392  if (pval_ < pd || pval_ >= pd + size)
2393  return;
2394  }
2395  pval_ = 0;
2396  }
2397 }
2398 void HocVarLabel::check_pointer(void* v, int) {
2399  char** cpp = (char**) v;
2400  if (cpp_ == cpp) {
2401  cpp_ = 0;
2402  }
2403 }
2404 
2405 void HocPanel::data_path(HocDataPaths* hdp, bool append) {
2406  for (long i = elist_.count() - 1; i >= 0; --i) {
2407  elist_.item(i)->data_path(hdp, append);
2408  }
2409 }
2410 
2411 void HocValEditor::data_path(HocDataPaths* hdp, bool append) {
2412  if (!variable_) {
2413  if (append) {
2414  hdp->append(pval_);
2415  } else {
2416  String* s = hdp->retrieve(pval_);
2417  if (s) {
2418  variable_ = new CopyString(s->string());
2419  }
2420  }
2421  }
2422 }
2423 
2424 void HocVarLabel::data_path(HocDataPaths* hdp, bool append) {
2425  if (cpp_ && !variable_) {
2426  if (append) {
2427  hdp->append(cpp_);
2428  } else {
2429  String* s = hdp->retrieve(cpp_);
2430  if (s) {
2431  variable_ = new CopyString(s->string());
2432  }
2433  }
2434  }
2435 }
2436 
2437 class StepperMenuAction: public Action {
2438  public:
2439  StepperMenuAction(bool, double);
2440  virtual ~StepperMenuAction();
2441  virtual void execute();
2442 
2443  private:
2444  double x_;
2445  bool geometric_;
2446 };
2447 
2448 class StepperMenu: public PopupMenu {
2449  public:
2450  StepperMenu();
2451  virtual ~StepperMenu();
2452  void stepper(HocValStepper* vs) {
2453  vs_ = vs;
2454  }
2455  HocValStepper* stepper() {
2456  return vs_;
2457  }
2458  virtual bool event(Event&);
2459  void active(bool b) {
2460  active_ = b;
2461  }
2462  bool active() {
2463  return active_;
2464  }
2465 
2466  private:
2467  bool active_;
2468  HocValStepper* vs_;
2469 };
2470 
2471 StepperMenu* HocValStepper::menu_;
2472 
2473 StepperMenuAction::StepperMenuAction(bool b, double x) {
2474  x_ = x;
2475  geometric_ = b;
2476 }
2477 StepperMenuAction::~StepperMenuAction() {}
2479  HocValStepper::menu()->stepper()->default_inc(geometric_, x_);
2480 }
2481 StepperMenu::StepperMenu() {
2482  WidgetKit& k = *WidgetKit::instance();
2483  char buf[50];
2484  active_ = false;
2485  vs_ = NULL;
2486  MenuItem* m;
2487  m = K::menu_item("Res");
2488  m->action(new StepperMenuAction(false, 0));
2489  append_item(m);
2490  m = K::menu_item("*10");
2491  m->action(new StepperMenuAction(true, 10));
2492  append_item(m);
2493  m = K::menu_item("*10^.1");
2494  m->action(new StepperMenuAction(true, pow(10., .1)));
2495  append_item(m);
2496  m = K::menu_item("*e");
2497  m->action(new StepperMenuAction(true, exp(1.)));
2498  append_item(m);
2499  m = K::menu_item("*e^.1");
2500  m->action(new StepperMenuAction(true, exp(.1)));
2501  append_item(m);
2502  m = K::menu_item("*2");
2503  m->action(new StepperMenuAction(true, 2));
2504  append_item(m);
2505  m = K::menu_item("*2^.1");
2506  m->action(new StepperMenuAction(true, pow(2., .1)));
2507  append_item(m);
2508  for (double x = 1000; x > .0005; x /= 10.) {
2509  sprintf(buf, "+%g", x);
2510  m = K::menu_item(buf);
2511  m->action(new StepperMenuAction(false, x));
2512  append_item(m);
2513  }
2514 }
2515 StepperMenu::~StepperMenu() {}
2516 bool StepperMenu::event(Event& e) {
2518  if (e.type() == Event::up) {
2519  vs_->menu_up(e);
2520  }
2521  return true;
2522 }
2523 
2524 /* static */ class NrnUpDown: public Glyph {
2525  public:
2526  static NrnUpDown* instance();
2527  virtual ~NrnUpDown();
2528  virtual void request(Requisition&) const;
2529  virtual void draw(Canvas*, const Allocation&) const;
2530 
2531  private:
2532  NrnUpDown(const Color*);
2533  static NrnUpDown* instance_;
2534  const Color* color_;
2535 };
2536 
2537 NrnUpDown* NrnUpDown::instance_;
2538 
2539 NrnUpDown::NrnUpDown(const Color* c)
2540  : Glyph() {
2541  color_ = c;
2542  Resource::ref(c);
2543 }
2544 
2545 NrnUpDown::~NrnUpDown() {
2546  Resource::unref(color_);
2547 }
2548 
2549 NrnUpDown* NrnUpDown::instance() {
2550  if (!instance_) {
2551  instance_ = new NrnUpDown(WidgetKit::instance()->foreground());
2552  instance_->ref();
2553  }
2554  return instance_;
2555 }
2556 
2557 #if 1
2558 void NrnUpDown::request(Requisition& r) const {
2559  Requirement x(10);
2560  Requirement y(20);
2561  r.require_x(x);
2562  r.require_y(y);
2563 }
2564 #endif
2565 
2566 void NrnUpDown::draw(Canvas* c, const Allocation& a) const {
2567  Coord x1 = a.left();
2568  Coord y1 = a.bottom();
2569  Coord x2 = a.right();
2570  Coord y2 = a.top();
2571  // printf("draw %g %g %g %g\n", x1, y1, x2, y2);
2572  Coord x = (x1 + x2) * .5;
2573  Coord y = (y1 + y2) * .5;
2574 
2575  c->new_path();
2576  c->move_to(x1, y + 1);
2577  c->line_to(x, y2);
2578  c->line_to(x2, y + 1);
2579  c->close_path();
2580  c->fill(color_);
2581 
2582 #if 1
2583  c->new_path();
2584  c->move_to(x1, y - 1);
2585  c->line_to(x, y1);
2586  c->line_to(x2, y - 1);
2587  c->close_path();
2588  c->fill(color_);
2589 #endif
2590 }
2591 
2592 static Glyph* up_down_mover_look(TelltaleState* t) {
2593  return WidgetKit::instance()->push_button_look(NrnUpDown::instance(), t);
2594 }
2595 
2597  Glyph* g;
2598  TelltaleState* t;
2599  WidgetKit& k = *WidgetKit::instance();
2600  Style* s;
2601  k.begin_style("UpMover", "Button");
2602  t = new TelltaleState(TelltaleState::is_enabled);
2603  g = up_down_mover_look(t);
2604  // g = k.up_mover_look(t);
2605  s = k.style();
2606  HocValStepper* vs = new HocValStepper(ve, g, s, t);
2607  k.end_style();
2608  return vs;
2609 }
2610 
2612  : Stepper(g, s, t) {
2613  if (!menu_) {
2614  menu_ = new StepperMenu();
2615  menu_->ref();
2616  }
2617  hve_ = ve;
2618  default_inc_ = MyMath::resolution(hve_->get_val());
2619  geometric_ = false;
2620 }
2622 void HocValStepper::press(const Event& e) {
2623  steps_ = 0;
2624  inc_ = default_inc_;
2625  menu_->active(false);
2626  if (Oc::helpmode()) {
2627  return;
2628  }
2629  switch (e.pointer_button()) {
2630  case Event::left:
2631  case Event::middle: {
2632  const Allocation& a = allocation();
2633  if (e.pointer_y() < (a.bottom() + a.top()) * .5) {
2634  if (geometric_) {
2635  inc_ = 1. / default_inc_;
2636  } else {
2637  inc_ *= -1;
2638  }
2639  }
2640  menu_->stepper(this);
2641  Stepper::press(e);
2642  break;
2643  }
2644  case Event::right: {
2645  menu_->active(true);
2646  menu_->stepper(this);
2647  Event e1(e);
2648  menu_->event(e1);
2649  } break;
2650  }
2651 }
2652 void HocValStepper::default_inc(bool g, double x) {
2653  if (x == 0.) {
2655  geometric_ = false;
2656  } else {
2657  default_inc_ = x;
2658  geometric_ = g;
2659  }
2660 }
2661 
2662 void HocValStepper::release(const Event& e) {
2663  if (Oc::helpmode()) {
2664  Oc::help(Editor_Stepper);
2665  return;
2666  }
2667  if (menu_->active()) {
2668  menu_->active(false);
2669  Button::release(e);
2670  return;
2671  }
2673  Oc oc;
2674  hve_->exec_action();
2675  oc.notify();
2676 }
2678  menu_->active(true);
2679 #ifdef WIN32
2680  handler()->event(e);
2681 #else
2682  e.unread();
2683 #endif
2684 }
2685 
2686 void HocValStepper::adjust() {
2687  double x, y;
2688  x = hve_->get_val();
2689  if (geometric_) {
2690  y = x * inc_;
2691  } else {
2692  y = x + inc_;
2693  }
2694  y = hve_->domain_limits(y);
2695  if (steps_ > 0 && x * y <= 0.) {
2696  y = 0.;
2697  inc_ = 0.;
2698  }
2699  hve_->set_val(y);
2700  hve_->updateField();
2701  if (!geometric_ && ((++steps_) % 20) == 0) {
2702  inc_ *= 10.;
2703  }
2704 }
2705 void HocValStepper::left() {
2706  inc_ = default_inc_;
2707 }
2708 void HocValStepper::middle() {
2709  inc_ = default_inc_;
2710 }
2711 void HocValStepper::right() {}
2712 
2713 // OcSlider
2714 
2715 // ZFM added vert_
2716 OcSlider::OcSlider(double* pd,
2717  float low,
2718  float high,
2719  float resolution,
2720  int nsteps,
2721  const char* send,
2722  bool vert,
2723  bool slow,
2724  Object* pyvar,
2725  Object* pysend)
2726  : HocUpdateItem("") {
2727  resolution_ = resolution;
2728  variable_ = NULL;
2729  pval_ = pd;
2730  pyvar_ = pyvar;
2731  if (pyvar_) {
2732  hoc_obj_ref(pyvar_);
2733  }
2734  vert_ = vert;
2735  slow_ = slow;
2736  bv_ = new BoundedValue(low, high);
2737  bv_->scroll_incr((high - low) / nsteps);
2738  if (send) {
2739  send_ = new HocCommand(send);
2740  } else if (pysend) {
2741  send_ = new HocCommand(pysend);
2742  } else {
2743  send_ = NULL;
2744  }
2745  bv_->attach(Dimension_X, this);
2746  scrolling_ = false;
2747 }
2749  if (send_) {
2750  delete send_;
2751  }
2752  delete bv_;
2753  if (variable_) {
2754  delete variable_;
2755  }
2756  if (pyvar_) {
2758  }
2759 }
2761  return bv_;
2762 }
2763 
2764 static double last_send;
2766  double x = slider_val();
2767  if (pval_) {
2768  *pval_ = x;
2769  } else if (pyvar_) {
2770  (*nrnpy_guisetval)(pyvar_, x);
2771  } else {
2772  return;
2773  }
2774  if (!scrolling_) {
2775  scrolling_ = true;
2776  while (Coord(x) != last_send) {
2777  audit();
2778  last_send = Coord(x);
2779  if (send_) {
2780  send_->execute();
2781  } else {
2782  Oc oc;
2783  oc.notify();
2784  }
2785  }
2786  scrolling_ = false;
2787  }
2788 }
2789 
2790 void OcSlider::audit() {
2791  char buf[200];
2792  if (variable_) {
2793  sprintf(buf, "%s = %g\n", variable_->string(), *pval_);
2794  } else if (pval_) {
2795  sprintf(buf, "// %p pointer set to %g\n", pval_, *pval_);
2796  }
2798  if (send_) {
2799  send_->audit();
2800  }
2801 }
2802 
2803 double OcSlider::slider_val() {
2804  double x = double(bv_->cur_lower(Dimension_X));
2805  x = MyMath::anint(x / resolution_);
2806  x = x * resolution_;
2807  if (x > bv_->upper(Dimension_X) - resolution_ / 2.)
2808  x = bv_->upper(Dimension_X);
2809  if (x < bv_->lower(Dimension_X) + resolution_ / 2.)
2810  x = bv_->lower(Dimension_X);
2811 
2812  return x;
2813 }
2814 
2816  Coord x = 0.;
2817  if (pyvar_) {
2818  x = Coord((*nrnpy_guigetval)(pyvar_));
2819  } else if (pval_) {
2820  x = Coord(*pval_);
2821  } else {
2822  return;
2823  }
2824  if (x != bv_->cur_lower(Dimension_X)) {
2825  bool old = scrolling_;
2826  scrolling_ = true;
2827  bv_->scroll_to(Dimension_X, x);
2828  scrolling_ = old;
2829  }
2830 }
2831 void OcSlider::check_pointer(void* v, int size) {
2832  if (pval_) {
2833  double* pd = (double*) v;
2834  if (size == 1) {
2835  if (pd != pval_)
2836  return;
2837  } else {
2838  if (pval_ < pd || pval_ >= pd + size)
2839  return;
2840  }
2841  pval_ = 0;
2842  }
2843 }
2844 void OcSlider::data_path(HocDataPaths* hdp, bool append) {
2845  if (!variable_ && pval_) {
2846  if (append) {
2847  hdp->append(pval_);
2848  } else {
2849  String* s = hdp->retrieve(pval_);
2850  if (s) {
2851  variable_ = new CopyString(s->string());
2852  }
2853  }
2854  }
2855 }
2856 void OcSlider::write(ostream& o) {
2857  if (variable_) {
2858  char buf[256];
2859  if (send_) {
2860  sprintf(buf,
2861  "xslider(&%s, %g, %g, \"%s\", %d, %d)",
2862  variable_->string(),
2863  bv_->lower(Dimension_X),
2864  bv_->upper(Dimension_X),
2865  hideQuote(send_->name()),
2866  vert_,
2867  slow_);
2868  } else {
2869  sprintf(buf,
2870  "xslider(&%s, %g, %g, %d, %d)",
2871  variable_->string(),
2872  bv_->lower(Dimension_X),
2873  bv_->upper(Dimension_X),
2874  vert_,
2875  slow_);
2876  }
2877  o << buf << endl;
2878  }
2879 }
2880 
2881 
2882 // Button with state
2883 
2884 void HocPanel::stateButton(double* pd,
2885  const char* name,
2886  const char* action,
2887  int style,
2888  Object* pyvar,
2889  Object* pyact) {
2890  HocAction* act = new HocAction(action, pyact);
2891  Button* button;
2892  if (style == HocStateButton::PALETTE) {
2893  button = WidgetKit::instance()->palette_button(name, act);
2894  } else {
2895  button = WidgetKit::instance()->check_box(name, act);
2896  }
2897  box()->append(button);
2898  HocStateButton* hsb = new HocStateButton(pd, name, button, act, style, hoc_item(), pyvar);
2899  item_append(hsb);
2900  elist_.append(hsb);
2901  hsb->ref();
2902 }
2903 
2904 declareActionCallback(HocStateButton);
2905 implementActionCallback(HocStateButton);
2906 
2908  const char* text,
2909  Button* button,
2910  HocAction* action,
2911  int style,
2912  HocItem* hi,
2913  Object* pyvar)
2914  : HocUpdateItem("", hi) {
2915  style_ = style;
2916  pval_ = pd;
2917  pyvar_ = pyvar;
2918  if (pyvar_) {
2919  hoc_obj_ref(pyvar_);
2920  }
2921  variable_ = NULL;
2922  name_ = new CopyString(text);
2923  action_ = action;
2924  action->hoc_item(this);
2925  Resource::ref(action_);
2926 
2927  b_ = button;
2928  // b_->ref(); // mutually reffed so don't
2929  b_->action(new ActionCallback(HocStateButton)(this, &HocStateButton::button_action));
2930 }
2931 
2932 
2934  if (variable_)
2935  delete variable_;
2936  if (pyvar_) {
2938  }
2939  delete name_;
2941  // only come here when b is being deleted
2942  // Resource::unref(b_);
2943  // delete b_;
2944 }
2945 
2946 void HocStateButton::print(Printer* pr, const Allocation& a) const {
2947  Glyph* l = WidgetKit::instance()->label(name_->string());
2948  l->ref();
2949  l->print(pr, a);
2950  l->unref();
2951 }
2952 
2953 bool HocStateButton::chosen() {
2954  return b_->state()->test(TelltaleState::is_chosen);
2955 }
2956 
2958  if (Oc::helpmode()) {
2959  help();
2960  b_->state()->set(TelltaleState::is_chosen, !chosen());
2961  return;
2962  }
2963  if (pval_) {
2964  TelltaleState* t = b_->state();
2965  if (chosen() != bool(*pval_)) {
2966  *pval_ = double(chosen());
2967  }
2968  }
2969  if (pyvar_) {
2970  TelltaleState* t = b_->state();
2971  if (chosen() != bool((*nrnpy_guigetval)(pyvar_))) {
2972  (*nrnpy_guisetval)(pyvar_, double(chosen()));
2973  }
2974  }
2975  if (action_) {
2976  action_->execute();
2977  } else {
2978  Oc oc;
2979  oc.notify();
2980  }
2981 }
2982 
2983 
2984 // set state of button to match variable
2986  double x = 0.;
2987  if (pyvar_) {
2988  x = nrnpy_guigetval(pyvar_);
2989  } else if (pval_) {
2990  x = *pval_;
2991  }
2992  if (x) {
2993  b_->state()->set(TelltaleState::is_chosen, true);
2994  } else {
2995  b_->state()->set(TelltaleState::is_chosen, false);
2996  }
2997 }
2998 
2999 void HocStateButton::check_pointer(void* v, int size) {
3000  if (pval_) {
3001  double* pd = (double*) v;
3002  if (size == 1) {
3003  if (pd != pval_)
3004  return;
3005  } else {
3006  if (pval_ < pd || pval_ >= pd + size)
3007  return;
3008  }
3009  pval_ = 0;
3010  }
3011 }
3012 
3014  if (!variable_ && pval_) {
3015  if (append) {
3016  hdp->append(pval_);
3017  } else {
3018  String* s = hdp->retrieve(pval_);
3019  if (s) {
3020  variable_ = new CopyString(s->string());
3021  }
3022  }
3023  }
3024 }
3025 void HocStateButton::write(ostream& o) {
3026  if (variable_) {
3027  char buf[256];
3028  if (style_ == PALETTE) {
3029  sprintf(buf,
3030  "xstatebutton(\"%s\",&%s,\"%s\")",
3031  name_->string(),
3032  variable_->string(),
3033  hideQuote(action_->name()));
3034  } else {
3035  sprintf(buf,
3036  "xcheckbox(\"%s\",&%s,\"%s\")",
3037  name_->string(),
3038  variable_->string(),
3039  hideQuote(action_->name()));
3040  }
3041  o << buf << endl;
3042  }
3043 }
3044 
3045 
3046 // menu item with state
3047 
3048 
3049 MenuItem* HocPanel::menuStateItem(double* pd,
3050  const char* name,
3051  const char* action,
3052  Object* pyvar,
3053  Object* pyact) {
3054  MenuItem* mi = WidgetKit::instance()->check_menu_item(name);
3055  HocAction* act = new HocAction(action, pyact);
3056  HocStateMenuItem* hsb = new HocStateMenuItem(pd, name, mi, act, hoc_item(), pyvar);
3057  item_append(hsb);
3058  elist_.append(hsb);
3059  hsb->ref();
3060  return mi;
3061 }
3062 
3063 
3064 declareActionCallback(HocStateMenuItem);
3065 implementActionCallback(HocStateMenuItem);
3066 
3068  const char* text,
3069  MenuItem* mi,
3070  HocAction* action,
3071  HocItem* hi,
3072  Object* pyvar)
3073  : HocUpdateItem("", hi) {
3074  pval_ = pd;
3075  pyvar_ = pyvar;
3076  if (pyvar_) {
3077  hoc_obj_ref(pyvar_);
3078  }
3079  variable_ = NULL;
3080  name_ = new CopyString(text);
3081  action_ = action;
3082  action->hoc_item(this);
3083  Resource::ref(action_);
3084 
3085  b_ = mi;
3086  // Resource::ref(b_);
3087  b_->action(new ActionCallback(HocStateMenuItem)(this, &HocStateMenuItem::button_action));
3088 }
3089 
3090 
3092  if (variable_)
3093  delete variable_;
3094  delete name_;
3095  if (pyvar_) {
3097  }
3099  // Resource::unref(b_);
3100  // delete b_;
3101 }
3102 
3103 void HocStateMenuItem::print(Printer* pr, const Allocation& a) const {
3104  Glyph* l = WidgetKit::instance()->label(name_->string());
3105  l->ref();
3106  l->print(pr, a);
3107  l->unref();
3108 }
3109 
3110 bool HocStateMenuItem::chosen() {
3111  return b_->state()->test(TelltaleState::is_chosen);
3112 }
3113 
3114 
3116  if (Oc::helpmode()) {
3117  help();
3118  b_->state()->set(TelltaleState::is_chosen, !chosen());
3119  return;
3120  }
3121  if (pval_) {
3122  TelltaleState* t = b_->state();
3123  if (chosen() != bool(*pval_)) {
3124  *pval_ = double(chosen());
3125  }
3126  }
3127  if (pyvar_) {
3128  TelltaleState* t = b_->state();
3129  if (chosen() != bool((*nrnpy_guigetval)(pyvar_))) {
3130  (*nrnpy_guisetval)(pyvar_, double(chosen()));
3131  }
3132  }
3133  if (action_) {
3134  action_->execute();
3135  } else {
3136  Oc oc;
3137  oc.notify();
3138  }
3139 }
3140 
3141 
3142 // set state of button to match variable
3144  double x = 0.;
3145  if (pyvar_) {
3146  x = nrnpy_guigetval(pyvar_);
3147  } else if (pval_) {
3148  x = *pval_;
3149  }
3150  if (x) {
3151  b_->state()->set(TelltaleState::is_chosen, true);
3152  } else {
3153  b_->state()->set(TelltaleState::is_chosen, false);
3154  }
3155 }
3156 
3157 void HocStateMenuItem::check_pointer(void* v, int size) {
3158  if (pval_) {
3159  double* pd = (double*) v;
3160  if (size == 1) {
3161  if (pd != pval_)
3162  return;
3163  } else {
3164  if (pval_ < pd || pval_ >= pd + size)
3165  return;
3166  }
3167  pval_ = 0;
3168  }
3169 }
3170 
3172  if (!variable_ && pval_) {
3173  if (append) {
3174  hdp->append(pval_);
3175  } else {
3176  String* s = hdp->retrieve(pval_);
3177  if (s) {
3178  variable_ = new CopyString(s->string());
3179  }
3180  }
3181  }
3182 }
3183 
3184 void HocStateMenuItem::write(ostream& o) {
3185  if (variable_) {
3186  char buf[256];
3187  sprintf(buf,
3188  "xcheckbox(\"%s\",&%s,\"%s\")",
3189  name_->string(),
3190  variable_->string(),
3191  hideQuote(action_->name()));
3192 
3193  o << buf << endl;
3194  }
3195 }
3196 
3197 
3198 #endif // HAVE_IV
3199 static void* vfe_cons(Object*) {
3200  TRY_GUI_REDIRECT_OBJ("ValueFieldEditor", NULL);
3201 #if HAVE_IV
3202  IFGUI
3203  if (!ifarg(2) || hoc_is_str_arg(2)) {
3204  hoc_xvalue_helper();
3205  } else {
3206  hoc_xpvalue_helper();
3207  }
3208  HocValEditor* fe = last_fe_constructed_;
3209  Resource::ref(fe);
3210  return (void*) fe;
3211  ENDGUI
3212 #endif
3213  return 0;
3214 }
3215 static void vfe_destruct(void* v) {
3216  TRY_GUI_REDIRECT_NO_RETURN("~ValueFieldEditor", v);
3217 #if HAVE_IV
3218  IFGUI
3219  HocValEditor* fe = (HocValEditor*) v;
3220  Resource::unref(fe);
3221  ENDGUI
3222 #endif
3223 }
3224 static double vfe_default(void* v) {
3225  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("ValueFieldEditor.default", v);
3226  double x = 0.;
3227 #if HAVE_IV
3228  IFGUI
3229  if (((HocValEditor*) v)->hoc_default_val_editor()) {
3231  dfe->deflt(x = dfe->get_val());
3232  }
3233  ENDGUI
3234 #endif
3235  return x;
3236 }
3237 static Member_func vfe_members[] = {"default", vfe_default, 0, 0};
3239  class2oc("ValueFieldEditor", vfe_cons, vfe_destruct, vfe_members, NULL, NULL, NULL);
3240 }
3241 
3242 #if HAVE_IV
3245 }
3246 
3247 void OcSlider::update_ptrs() {
3249 }
3250 
3253 }
3254 
3257 }
3258 
3259 void HocUpdateItem::update_ptrs_helper(double** p) {
3260  if (*p) {
3261  double* pd = nrn_recalc_ptr(*p);
3262  *p = pd;
3263  }
3264 }
3265 
3266 #endif
#define InputHandler
Definition: _defines.h:151
#define Patch
Definition: _defines.h:201
#define TelltaleState
Definition: _defines.h:296
#define Background
Definition: _defines.h:43
#define Color
Definition: _defines.h:74
#define Menu
Definition: _defines.h:176
#define ScrollBox
Definition: _defines.h:253
#define Border
Definition: _defines.h:49
#define Canvas
Definition: _defines.h:65
#define Style
Definition: _defines.h:281
#define Coord
Definition: _defines.h:19
#define Adjustable
Definition: _defines.h:29
#define Hit
Definition: _defines.h:147
#define WidgetKit
Definition: _defines.h:331
#define Printer
Definition: _defines.h:211
#define MonoGlyph
Definition: _defines.h:181
#define GlyphIndex
Definition: _defines.h:23
#define MenuItem
Definition: _defines.h:179
#define Event
Definition: _defines.h:107
#define Button
Definition: _defines.h:62
#define EventButton
Definition: _defines.h:21
#define PolyGlyph
Definition: _defines.h:207
#define TelltaleGroup
Definition: _defines.h:295
#define Stepper
Definition: _defines.h:275
#define LayoutKit
Definition: _defines.h:161
#define Action
Definition: _defines.h:27
#define Glyph
Definition: _defines.h:132
#define String
Definition: enter-scope.h:48
#define CopyString
Definition: _defines.h:2
static double restore(void *v)
void cb(const char *s)
Definition: bbstest.cpp:5
short index
Definition: cabvars.h:10
Coord right() const
Definition: geometry.h:293
Coord top() const
Definition: geometry.h:295
Coord left() const
Definition: geometry.h:292
Coord bottom() const
Definition: geometry.h:294
virtual Coord lower(DimensionName) const
virtual void scroll_to(DimensionName, Coord position)
virtual Coord cur_lower(DimensionName) const
virtual Coord upper(DimensionName) const
virtual void focus_out()
virtual void release(const Event &)
virtual const String * text() const
virtual void selection(int &start, int &index) const
virtual void press(const Event &)
virtual void keystroke(const Event &)
virtual void drag(const Event &)
virtual InputHandler * focus_in()
virtual void field(const char *)
virtual ~HocAction()
const char * name() const
HocAction(const char *action, Object *pyact=NULL)
virtual void help()
HocItem * hi_
Definition: xmenu.h:243
virtual void execute()
void hoc_item(HocItem *)
HocCommand * action_
Definition: xmenu.h:242
virtual void audit()
Definition: objcmd.cpp:89
int execute(bool notify=true)
Definition: objcmd.cpp:102
const char * name()
Definition: objcmd.cpp:81
String * retrieve(double *)
Definition: datapath.cpp:152
void append(double *)
Definition: datapath.cpp:133
void search()
Definition: datapath.cpp:141
void deflt(double)
virtual ~HocDefaultValEditor()
double most_recent_
Definition: xmenu.h:391
Button * checkbox()
Definition: xmenu.h:384
HocValStepper * vs_
Definition: xmenu.h:392
virtual void updateField()
HocDefaultValEditor(const char *name, const char *variable, ValEdLabel *, HocValAction *, double *pd=0, bool canrun=false, HocItem *parent=NULL, Object *pyvar=NULL)
Button * checkbox_
Definition: xmenu.h:389
void def_change(float, float)
HocEditorForItem(HocValEditor *, HocValAction *)
virtual void release(const Event &)
virtual void val_inc(const Event &)
virtual void press(const Event &)
virtual void keystroke(const Event &)
virtual ~HocEditorForItem()
virtual void focus_out()
virtual void drag(const Event &)
HocValEditor * hve_
Definition: xmenu.h:272
virtual InputHandler * focus_in()
Definition: xmenu.h:137
CopyString str_
Definition: xmenu.h:149
HocItem * help_parent_
Definition: xmenu.h:150
virtual void help_parent(HocItem *)
virtual void write(ostream &)
HocItem(const char *, HocItem *parent=NULL)
virtual ~HocItem()
virtual void help(const char *childpath=NULL)
const char * getStr()
virtual void write(ostream &)
HocLabel(const char *)
virtual ~HocLabel()
virtual ~HocMenuAction()
HocPanel * hp_
Definition: xmenu.h:254
virtual void execute()
HocMenuAction(const char *action, Object *pyact, HocMenu *)
HocMenu * hm_
Definition: xmenu.h:253
Definition: xmenu.h:177
HocMenu(const char *, Menu *, MenuItem *, HocItem *parent=NULL, bool add2menubar=false)
virtual ~HocMenu()
virtual void write(ostream &)
virtual Menu * menu()
Definition: xmenu.h:182
bool add2menubar_
Definition: xmenu.h:194
Menu * menu_
Definition: xmenu.h:193
virtual MenuItem * item()
Definition: xmenu.h:185
HocAction * a_
Definition: xmenu.h:162
HocPushButton(const char *, HocAction *, HocItem *parent=NULL)
virtual ~HocPushButton()
virtual void write(ostream &)
virtual void write(ostream &)
HocRadioAction * a_
Definition: xmenu.h:174
HocRadioButton(const char *, HocRadioAction *, HocItem *parent=NULL)
virtual ~HocRadioButton()
void button_action()
virtual void update_hoc_item()
virtual ~HocStateButton()
HocAction * action_
Definition: xmenu.h:506
CopyString * variable_
Definition: xmenu.h:501
Button * b_
Definition: xmenu.h:505
virtual void data_path(HocDataPaths *, bool)
double * pval_
Definition: xmenu.h:503
virtual void check_pointer(void *, int)
virtual void update_ptrs()
HocStateButton(double *, const char *, Button *, HocAction *, int, HocItem *parent=NULL, Object *pyvar=NULL)
CopyString * name_
Definition: xmenu.h:502
virtual void write(ostream &)
virtual void print(Printer *, const Allocation &) const
int style_
Definition: xmenu.h:500
Object * pyvar_
Definition: xmenu.h:504
MenuItem * b_
Definition: xmenu.h:535
virtual void check_pointer(void *, int)
virtual void write(ostream &)
virtual void data_path(HocDataPaths *, bool)
double * pval_
Definition: xmenu.h:533
virtual void update_hoc_item()
HocAction * action_
Definition: xmenu.h:536
virtual void update_ptrs()
CopyString * variable_
Definition: xmenu.h:531
CopyString * name_
Definition: xmenu.h:532
HocStateMenuItem(double *, const char *, MenuItem *, HocAction *, HocItem *parent=NULL, Object *pyvar=NULL)
Object * pyvar_
Definition: xmenu.h:534
virtual void print(Printer *, const Allocation &) const
virtual ~HocStateMenuItem()
virtual void update_hoc_item()
HocUpdateItem(const char *, HocItem *parent=NULL)
void update_ptrs_helper(double **)
virtual void check_pointer(void *, int vector_size)
virtual ~HocUpdateItem()
virtual void data_path(HocDataPaths *, bool)
FieldSEditorAction * fea_
Definition: xmenu.h:430
void accept(FieldSEditor *)
HocValAction(const char *action, Object *pyact=0)
HocValEditor * fe_
Definition: xmenu.h:426
virtual ~HocValAction()
void execute()
void setFieldSEditor(HocValEditor *)
double * pval_
Definition: xmenu.h:357
Object * pyvar_
Definition: xmenu.h:360
virtual void write(ostream &)
HocAction * action_
Definition: xmenu.h:355
virtual void updateField()
virtual int hoc_default_val_editor()
Definition: xmenu.h:335
virtual void update_hoc_item()
CopyString * variable_
Definition: xmenu.h:356
virtual void print(Printer *, const Allocation &) const
double get_val()
virtual ~HocValEditor()
HocValEditor(const char *name, const char *variable, ValEdLabel *, HocValAction *, double *pd=0, bool canrun=false, HocItem *parent=NULL, Object *pvar=NULL)
bool canrun_
Definition: xmenu.h:354
const char * variable() const
virtual void exec_action()
virtual Stepper * stepper()
Definition: xmenu.h:324
ValEdLabel * prompt_
Definition: xmenu.h:358
virtual void setlimits(float *)
void evalField()
virtual void data_path(HocDataPaths *, bool)
void set_val(double)
bool active_
Definition: xmenu.h:353
FieldSEditor * field_editor()
Definition: xmenu.h:321
virtual void check_pointer(void *, int)
float * domain_limits_
Definition: xmenu.h:359
virtual double domain_limits(double)
HocEditorForItem * fe_
Definition: xmenu.h:352
bool active()
Definition: xmenu.h:344
virtual void update_ptrs()
virtual ~HocValEditorKeepUpdated()
HocValEditorKeepUpdated(const char *name, const char *variable, ValEdLabel *, HocValAction *, double *, HocItem *parent=NULL, Object *pyvar=NULL)
virtual void write(ostream &)
float inc_
Definition: xmenu.h:305
HocValStepper(HocValEditor *, Glyph *, Style *, TelltaleState *)
virtual void menu_up(Event &)
virtual ~HocValStepper()
double default_inc()
static HocValStepper * instance(HocValEditor *)
virtual void release(const Event &)
float default_inc_
Definition: xmenu.h:304
HocValEditor * hve_
Definition: xmenu.h:306
bool geometric_
Definition: xmenu.h:302
virtual void adjust()
virtual void press(const Event &)
static StepperMenu * menu_
Definition: xmenu.h:307
int steps_
Definition: xmenu.h:303
static StepperMenu * menu()
Definition: xmenu.h:289
virtual void data_path(HocDataPaths *, bool)
virtual void write(ostream &)
virtual ~HocVarLabel()
Object * pyvar_
Definition: xmenu.h:229
char ** cpp_
Definition: xmenu.h:226
char * cp_
Definition: xmenu.h:227
CopyString * variable_
Definition: xmenu.h:228
Patch * p_
Definition: xmenu.h:225
HocVarLabel(char **, PolyGlyph *, Object *pyvar=NULL)
virtual void check_pointer(void *, int)
virtual void update_hoc_item()
static MenuItem * radio_menu_item(TelltaleGroup *, const char *)
static MenuItem * menu_item(const char *)
static bool equal(float x, float y, float e)
Definition: math.h:108
static int abs(int)
Definition: math.cpp:43
static double anint(double)
Definition: mymath.cpp:87
static double resolution(double)
virtual PrintableWindow * make_window(Coord left=-1, Coord bottom=-1, Coord width=-1, Coord height=-1)
Definition: ivoc.h:36
static void help(const char *)
void notify()
int run(int argc, const char **argv)
void notify_freed(void(*pf)(void *, int))
void notifyHocValue()
static bool helpmode()
Definition: ivoc.h:70
void audit()
virtual void data_path(HocDataPaths *, bool)
double * pval_
Definition: xmenu.h:468
bool vert_
Definition: xmenu.h:472
CopyString * variable_
Definition: xmenu.h:470
virtual void write(ostream &)
virtual double slider_val()
float resolution_
Definition: xmenu.h:465
virtual void update(Observable *)
bool slow_
Definition: xmenu.h:473
OcSlider(double *, float low, float high, float resolution, int nsteps, const char *send_cmd, bool vert, bool slow=false, Object *pyvar=NULL, Object *pysend=NULL)
BoundedValue * bv_
Definition: xmenu.h:466
virtual void update_ptrs()
Object * pyvar_
Definition: xmenu.h:469
virtual void update_hoc_item()
virtual void check_pointer(void *, int vector_size)
Adjustable * adjustable()
bool scrolling_
Definition: xmenu.h:471
virtual ~OcSlider()
HocCommand * send_
Definition: xmenu.h:467
void save()
Definition: oc2iv.cpp:54
void restore()
Definition: oc2iv.cpp:72
virtual bool event(Event &)
virtual void map()
void natural(Coord)
Definition: geometry.h:235
void require_x(const Requirement &)
Definition: geometry.h:247
const Requirement & x_requirement() const
Definition: geometry.h:249
void require_y(const Requirement &)
Definition: geometry.h:248
virtual void ref() const
Definition: resource.cpp:47
virtual void unref() const
Definition: resource.cpp:52
MenuItem * add_radio_menu(const char *, Action *, Menu *=NULL)
Button * radio_button(const char *, Action *)
Definition: string.h:34
const char * string() const
Definition: string.h:139
void execute(Inst *p)
Definition: code.cpp:2661
#define fil
Definition: coord.h:42
Symbol * hoc_get_last_pointer_symbol()
Definition: code.cpp:1780
double t
Definition: cvodeobj.cpp:59
static double active(void *v)
Definition: cvodeobj.cpp:212
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)
double chkarg(int, double low, double high)
Definition: code2.cpp:638
#define c
static HocParmLimits limits[]
Definition: extcelln.cpp:38
static void update(NrnThread *)
Definition: fadvance.cpp:597
#define FieldSEditorCallback(T)
Definition: field.h:58
#define declareFieldSEditorCallback(T)
Definition: field.h:63
#define implementFieldSEditorCallback(T)
Definition: field.h:81
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
@ Dimension_X
Definition: geometry.h:43
char buf[512]
Definition: init.cpp:13
int hoc_is_object_arg(int narg)
Definition: code.cpp:756
void hoc_audit_command(const char *buf)
Definition: audit.cpp:122
Symbol * hoc_get_symbol(const char *var)
Definition: code.cpp:1759
double check_domain_limits(float *limits, double val)
Definition: code2.cpp:114
int hoc_is_str_arg(int narg)
Definition: code.cpp:752
double * hoc_val_pointer(const char *s)
Definition: code2.cpp:727
void hoc_ret()
double hoc_ac_
Definition: hoc_init.cpp:397
void hoc_obj_ref(Object *obj)
Definition: hoc_oop.cpp:1810
int hoc_is_pdouble_arg(int narg)
Definition: code.cpp:748
double * hoc_pgetarg(int narg)
Definition: code.cpp:1623
void hoc_obj_unref(Object *obj)
Definition: hoc_oop.cpp:1828
char ** hoc_pgargstr(int narg)
Definition: code.cpp:1599
#define TRY_GUI_REDIRECT_ACTUAL_DOUBLE(name, obj)
Definition: gui-redirect.h:71
#define TRY_GUI_REDIRECT_DOUBLE(name, obj)
Definition: gui-redirect.h:58
#define TRY_GUI_REDIRECT_NO_RETURN(name, obj)
Definition: gui-redirect.h:47
#define TRY_GUI_REDIRECT_OBJ(name, obj)
Definition: gui-redirect.h:12
#define TRY_GUI_REDIRECT_DOUBLE_SEND_STRREF(name, obj)
Definition: gui-redirect.h:104
void start()
Definition: hel2mos.cpp:204
void stop()
Definition: hel2mos.cpp:212
void send(const char *url)
Definition: hel2mos.cpp:214
static void help(const char *)
Definition: hel2mos.cpp:107
#define assert(ex)
Definition: hocassrt.h:32
#define IFGUI
Definition: hocdec.h:372
#define getarg
Definition: hocdec.h:15
#define gargstr
Definition: hocdec.h:14
#define ENDGUI
Definition: hocdec.h:373
Object ** hoc_objgetarg(int)
Definition: code.cpp:1587
void
int units_on_flag_
Definition: code2.cpp:17
#define Session
Definition: ivocmain.cpp:7
void hoc_notify_value()
Definition: ivocmain.cpp:892
int ifarg(int)
Definition: code.cpp:1581
void hoc_pushx(double)
#define implementPtrList(PtrList, T)
#define declarePtrList(PtrList, T)
#define pval
Definition: md1redef.h:32
#define v
Definition: md1redef.h:4
#define i
Definition: md1redef.h:12
exp
Definition: extdef.h:5
pow
Definition: extdef.h:4
void init()
Definition: init.cpp:291
char * name
Definition: init.cpp:16
void append(Item *ql, Item *q)
Definition: list.cpp:318
#define printf
Definition: mwprefix.h:26
#define fprintf
Definition: mwprefix.h:30
double * nrn_recalc_ptr(double *)
Definition: treeset.cpp:2179
static int active_
Definition: netpar.cpp:205
#define nrn_assert(ex)
Definition: nrnassrt.h:53
size_t p
size_t j
void class2oc(const char *, void *(*cons)(Object *), void(*destruct)(void *), Member_func *, int(*checkpoint)(void **), Member_ret_obj_func *, Member_ret_str_func *)
Definition: hoc_oop.cpp:1560
static philox4x32_key_t k
Definition: nrnran123.cpp:11
static N_Vector y_
static void pr(N_Vector x)
static realtype a_
static realtype b_
static N_Vector x_
#define CChar
Definition: oc2iv.h:10
void hoc_ivvarlabel(char **, Object *pyvar=0)
void hoc_ivvaluerun_ex(CChar *name, CChar *var, double *pvar, Object *pyvar, CChar *action, Object *pyact, bool deflt=false, bool canrun=false, bool usepointer=false, HocSymExtension *extra=NULL)
void hoc_ivvalue(CChar *name, CChar *variable, bool deflt=false, Object *pyvar=0)
void hoc_ivbutton(CChar *name, CChar *action, Object *pyact=0)
void hoc_ivmenu(CChar *, bool add2menubar=false)
void hoc_ivvalue_keep_updated(CChar *name, CChar *variable, Object *pyvar=0)
void hoc_ivradiobutton(CChar *name, CChar *action, bool activate=false, Object *pyact=0)
void hoc_ivpanelmap(int scroll=-1)
void hoc_ivpvalue(CChar *name, double *, bool deflt=false, HocSymExtension *extra=NULL)
void hoc_ivfixedvalue(CChar *name, CChar *variable, bool deflt=false, bool usepointer=false)
void hoc_ivvaluerun(CChar *name, CChar *variable, CChar *action, bool deflt=false, bool canrun=false, bool usepointer=false, Object *pyvar=0, Object *pyact=0)
void hoc_ivslider(double *, float low=0, float high=100, float resolution=1, int steps=10, const char *send_cmd=NULL, bool vert=false, bool slow=false, Object *pyvar=0, Object *pyact=0)
void hoc_ivstatebutton(double *, CChar *name, CChar *action, int style, Object *pyvar=0, Object *pyact=0)
void hoc_ivpanel(CChar *, bool h=false)
void hoc_ivlabel(CChar *)
void hoc_ivvarmenu(CChar *, CChar *, bool add2menubar=false, Object *pyvar=NULL)
void hoc_ivpvaluerun(CChar *name, double *, CChar *action, bool deflt=false, bool canrun=false, HocSymExtension *extra=NULL)
static double save(void *v)
Definition: ocbox.cpp:346
static double remove(void *v)
Definition: ocdeck.cpp:207
virtual void press(const Event &e)
Definition: ocinput.h:29
virtual void release(const Event &e)
Definition: ocinput.h:35
void handle_old_focus()
void hoc_xpanel()
Definition: ocnoiv1.cpp:76
void hoc_xvalue()
Definition: ocnoiv1.cpp:69
void hoc_xbutton()
Definition: ocnoiv1.cpp:41
void hoc_xfixedvalue()
Definition: ocnoiv1.cpp:90
void hoc_xlabel()
Definition: ocnoiv1.cpp:34
void hoc_xstatebutton()
Definition: ocnoiv1.cpp:55
void hoc_xmenu()
Definition: ocnoiv1.cpp:62
void hoc_xpvalue()
Definition: ocnoiv1.cpp:27
void hoc_xvarlabel()
Definition: ocnoiv1.cpp:97
void hoc_xslider()
Definition: ocnoiv1.cpp:104
void hoc_xradiobutton()
Definition: ocnoiv1.cpp:83
void hoc_xcheckbox()
Definition: ocnoiv1.cpp:48
#define g
Definition: passive0.cpp:21
#define e
Definition: passive0.cpp:22
#define text
Definition: plot.cpp:85
static void activate()
#define left
Definition: rbtqueue.cpp:45
#define parent
Definition: rbtqueue.cpp:47
#define right
Definition: rbtqueue.cpp:46
#define add
Definition: redef.h:24
#define lookup
Definition: redef.h:90
#define print
Definition: redef.h:109
o
Definition: seclist.cpp:175
#define cnt
Definition: spt2queue.cpp:19
#define key
Definition: spt2queue.cpp:20
#define NULL
Definition: sptree.h:16
float * parmlimits
Definition: hocdec.h:111
char * units
Definition: hocdec.h:112
Definition: hocdec.h:227
Definition: model.h:57
HocSymExtension * extra
Definition: hocdec.h:160
static double least(void *v)
Definition: tqueue.cpp:33
bool boolean_dialog(const char *label, const char *accept, const char *cancel, Window *w=NULL, Coord x=400., Coord y=400.)
static Member_func vfe_members[]
Definition: xmenu.cpp:3237
static void vfe_destruct(void *v)
Definition: xmenu.cpp:3215
static double vfe_default(void *v)
Definition: xmenu.cpp:3224
double(* nrnpy_object_to_double_)(Object *)
Definition: xmenu.cpp:14
int(* nrnpy_guigetstr)(Object *, char **)
Definition: xmenu.cpp:9
double(* nrnpy_guigetval)(Object *)
Definition: xmenu.cpp:7
void ValueFieldEditor_reg()
Definition: xmenu.cpp:3238
void(* nrnpy_guisetval)(Object *, double)
Definition: xmenu.cpp:8
static void * vfe_cons(Object *)
Definition: xmenu.cpp:3199