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