NEURON
utility.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #if HAVE_IV // to end of file
3 
4 #include <ivstream.h>
5 #include <string.h>
6 #include <stdio.h>
7 #include <errno.h>
8 
9 #include <InterViews/dialog.h>
10 #include <InterViews/session.h>
11 #include <InterViews/display.h>
12 #include <InterViews/action.h>
13 #include <InterViews/layout.h>
14 #include <InterViews/style.h>
15 #include <InterViews/hit.h>
16 #include <InterViews/event.h>
17 #include <IV-look/kit.h>
18 #include <IV-look/dialogs.h>
19 #include <OS/string.h>
20 
21 #define Input IOS_IN
22 #define Output IOS_OUT
23 #define Append IOS_APP | IOS_OUT
24 
25 #include "graph.h"
26 #include "utility.h"
27 #include "oc2iv.h"
28 #include "ivoc.h"
29 
30 extern Object** (*nrnpy_gui_helper_)(const char* name, Object* obj);
31 extern double (*nrnpy_object_to_double_)(Object*);
32 extern Object** (*nrnpy_gui_helper3_)(const char* name, Object* obj, int handle_strptr);
33 
34 bool nrn_spec_dialog_pos(Coord& x, Coord& y) {
35  Style* s = Session::instance()->style();
36  if (s->value_is_on("dialog_spec_position")) {
37  s->find_attribute("dialog_left_position", x);
38  s->find_attribute("dialog_bottom_position", y);
39  return true;
40  }
41  return false;
42 }
43 
44 bool oc_post_dialog(Dialog* d, Coord x, Coord y) {
45  if (nrn_spec_dialog_pos(x, y)) {
46  return d->post_at_aligned(x, y, 0.0, 0.0);
47  }
48  if (x != 400. || y != 400.) {
49  return d->post_at_aligned(x, y, .5, .5);
50  } else {
51  Display* dis = Session::instance()->default_display();
52  return d->post_at_aligned(dis->width() / 2, dis->height() / 2, .5, .5);
53  }
54 }
55 
56 bool ok_to_write(const String& s, Window* w) {
57  return ok_to_write(s.string(), w);
58 }
59 bool ok_to_read(const String& s, Window* w) {
60  return ok_to_read(s.string(), w);
61 }
62 
63 class OcGlyphDialog: public Dialog {
64  public:
65  OcGlyphDialog(Glyph*, Style*);
66  virtual ~OcGlyphDialog();
67  virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
68 };
69 
70 /*static*/ class DialogAction: public Action {
71  public:
72  DialogAction(Dialog*, bool);
73  virtual ~DialogAction();
74  virtual void execute() {
75  d_->dismiss(accept_);
76  }
77 
78  private:
79  Dialog* d_;
80  bool accept_;
81 };
82 DialogAction::DialogAction(Dialog* d, bool accept) {
83  accept_ = accept;
84  d_ = d;
85 }
86 DialogAction::~DialogAction() {
87  // printf("~DialogAction\n");
88 }
89 
90 bool boolean_dialog(const char* label,
91  const char* accept,
92  const char* cancel,
93  Window* w,
94  Coord x,
95  Coord y) {
96  WidgetKit& k = *WidgetKit::instance();
97  LayoutKit& l = *LayoutKit::instance();
98  PolyGlyph* vbox = l.vbox();
99  bool ok;
100  Dialog* d = new Dialog(k.outset_frame(l.margin(vbox, 5)), Session::instance()->style());
101  d->ref();
102  vbox->append(l.hcenter(k.inset_frame(l.margin(k.label(label), 10))));
103  vbox->append(l.hcenter(l.hbox(k.push_button(accept, new DialogAction(d, true)),
104  l.hspace(10),
105  k.push_button(cancel, new DialogAction(d, false)))));
106  if (w) {
107  ok = d->post_for(w);
108  } else {
109  ok = oc_post_dialog(d, x, y);
110  }
111  d->unref();
112  return ok;
113 }
114 
115 void continue_dialog(const char* label, Window* w, Coord x, Coord y) {
116  WidgetKit& k = *WidgetKit::instance();
117  LayoutKit& l = *LayoutKit::instance();
118  PolyGlyph* vbox = l.vbox();
119  Dialog* d = new Dialog(k.outset_frame(l.margin(vbox, 5)), Session::instance()->style());
120  d->ref();
121  vbox->append(l.hcenter(k.inset_frame(l.margin(k.label(label), 10))));
122  vbox->append(l.hcenter(k.push_button("Continue", new DialogAction(d, true))));
123  if (w) {
124  d->post_for(w);
125  } else {
126  oc_post_dialog(d, x, y);
127  }
128  d->unref();
129 }
130 
131 static bool ok_if_already_exists(const char* s, Window* w) {
132  char buf[256];
133  sprintf(buf, "%s already exists: Write?", s);
134  return boolean_dialog(buf, "Go Ahead", "Don't", w);
135 }
136 
137 static void open_fail(const char* s, Window* w, const char* io) {
138  char buf[256];
139  sprintf(buf, "Couldn't open %s for %sing", s, io);
140  continue_dialog(buf, w);
141 }
142 
143 bool ok_to_write(const char* s, Window* w) {
144  filebuf obuf;
145  if (obuf.open(s, Input)) {
146  obuf.close();
147  if (!ok_if_already_exists(s, w)) {
148  errno = 0;
149  return false;
150  }
151  }
152  if (obuf.open(s, Append)) {
153  obuf.close();
154  } else {
155  open_fail(s, w, "writ");
156  errno = 0;
157  return false;
158  }
159  errno = 0;
160  return true;
161 }
162 
163 bool ok_to_read(const char* s, Window* w) {
164  filebuf obuf;
165  if (obuf.open(s, Input)) {
166  obuf.close();
167  errno = 0;
168  return true;
169  } else {
170  open_fail(s, w, "read");
171  errno = 0;
172  return false;
173  }
174 }
175 
176 bool var_pair_chooser(const char* caption, float& x, float& y, Window* w, Coord x2, Coord y2) {
177  char buf[200];
178  float x1 = x, y1 = y;
179  for (;;) {
180  sprintf(buf, "%g %g", x, y);
181  if (str_chooser(caption, buf, w, x2, y2)) {
182  if (sscanf(buf, "%f%f", &x1, &y1) == 2) {
183  x = x1;
184  y = y1;
185  return true;
186  } else {
187  continue_dialog("Invalid entry: Enter pair of numbers separated by space.", w);
188  }
189  } else {
190  return false;
191  }
192  }
193 }
194 
195 bool str_chooser(const char* caption, char* buf, Window* w, Coord x, Coord y) {
196  WidgetKit& k = *WidgetKit::instance();
197  LayoutKit& l = *LayoutKit::instance();
198  Style* style = new Style(k.style());
199  style->attribute("caption", caption);
200  bool ok;
202  d->ref();
203  if (w) {
204  ok = d->post_for(w);
205  } else {
206  ok = oc_post_dialog(d, x, y);
207  }
208  if (ok) {
209  strcpy(buf, d->text()->string());
210  }
211  d->unref();
212  return ok;
213 }
214 
215 declareFieldEditorCallback(FieldDialog);
216 implementFieldEditorCallback(FieldDialog);
217 
219  : Dialog(g, s) {}
220 
223 }
224 
225 bool FieldDialog::run() {
226  fe_->select(0, fe_->text()->length());
227  return Dialog::run();
228 }
229 void FieldDialog::dismiss(bool accept) {
230  if (accept) {
231  s_ = *fe_->text();
232  } else {
233  fe_->field(s_);
234  }
235  Dialog::dismiss(accept);
236 }
237 
238 FieldDialog* FieldDialog::field_dialog_instance(const char* str, Style* style, Glyph* extra) {
239  Glyph* g;
240  WidgetKit& widgets = *WidgetKit::instance();
241  DialogKit& dialogs = *DialogKit::instance();
242  LayoutKit& layout = *LayoutKit::instance();
243 
244  String caption("");
245  String accept("Accept");
246  String cancel("Cancel");
247  style->find_attribute("caption", caption);
248  style->find_attribute("accept", accept);
249  style->find_attribute("cancel", cancel);
250  PolyGlyph* hb = layout.hbox(5);
251  PolyGlyph* vb = layout.vbox(5);
252  g = widgets.inset_frame(layout.margin(layout.flexible(vb, fil, 0), 10.0));
253 
254  FieldDialog* fd = new FieldDialog(g, style);
255  FieldEditor* fe = dialogs.field_editor(
256  str,
257  style,
258  new FieldEditorCallback(FieldDialog)(fd, &FieldDialog::accept, &FieldDialog::cancel));
259 
260  fd->fe_ = fe;
261  Resource::ref(fe);
262  fd->s_ = *fe->text();
263 
264  vb->append(layout.flexible(widgets.label(caption)));
265  vb->append(layout.vglue(10));
266  vb->append(fd->fe_);
267  if (extra) {
268  vb->append(layout.vglue(10));
269  vb->append(extra);
270  }
271  vb->append(layout.vglue(10));
272  vb->append(hb);
273 
274  hb->append(layout.hglue(20, fil, 20));
275  hb->append(widgets.default_button(accept, new DialogAction(fd, true)));
276  hb->append(layout.hglue(5));
277  hb->append(widgets.push_button(cancel, new DialogAction(fd, false)));
278  hb->append(layout.hglue(20, fil, 20));
279 
280  return fd;
281 }
282 
284  dismiss(true);
285 }
287  dismiss(false);
288 }
289 
290 
291 void hoc_boolean_dialog() {
292  bool b = false;
293  if (nrnpy_gui_helper_) {
294  Object** const result = nrnpy_gui_helper_("boolean_dialog", NULL);
295  if (result) {
296  hoc_ret();
298  return;
299  }
300  }
301  IFGUI
302  if (ifarg(3)) {
303  b = boolean_dialog(gargstr(1), gargstr(2), gargstr(3));
304  } else {
305  b = boolean_dialog(gargstr(1), "Yes", "No");
306  }
307  ENDGUI
308  hoc_ret();
309  hoc_pushx(double(b));
310 }
311 void hoc_continue_dialog() {
312  TRY_GUI_REDIRECT_DOUBLE("continue_dialog", NULL);
313  IFGUI
315  ENDGUI
316  hoc_ret();
317  hoc_pushx(1.);
318 }
319 void hoc_string_dialog() {
320  TRY_GUI_REDIRECT_DOUBLE_SEND_STRREF("string_dialog", NULL);
321  bool b = false;
322  IFGUI
323  char buf[256];
324  sprintf(buf, "%s", gargstr(2));
325  b = str_chooser(gargstr(1), buf);
326  if (b) {
328  }
329  ENDGUI
330  hoc_ret();
331  hoc_pushx(double(b));
332 }
333 
334 
335 /*static*/ class LabelChooserAction: public Action {
336  public:
337  LabelChooserAction(GLabel*);
338  virtual ~LabelChooserAction();
339  void state(TelltaleState*);
340  virtual void execute();
341 
342  private:
343  TelltaleState* ts_;
344  GLabel* gl_;
345 };
346 
347 bool Graph::label_chooser(const char* caption, char* buf, GLabel* gl, Coord x, Coord y) {
348  WidgetKit& k = *WidgetKit::instance();
349  LayoutKit& l = *LayoutKit::instance();
350  Style* style = new Style(k.style());
351  style->attribute("caption", caption);
352  bool ok;
353  LabelChooserAction* lca = new LabelChooserAction(gl);
354  Button* b = k.check_box("vfixed", lca);
355  lca->state(b->state());
356 
358 
359  d->ref();
360  ok = oc_post_dialog(d, x, y);
361  if (ok) {
362  strcpy(buf, d->text()->string());
363  }
364  d->unref();
365  return ok;
366 }
367 
368 LabelChooserAction::LabelChooserAction(GLabel* gl) {
369  gl_ = gl;
370  gl->ref();
371  ts_ = NULL;
372 }
373 LabelChooserAction::~LabelChooserAction() {
374  gl_->unref();
375  ts_->unref();
376 }
377 void LabelChooserAction::state(TelltaleState* t) {
378  t->ref();
379  ts_ = t;
380  if (gl_->fixed()) {
381  ts_->set(TelltaleState::is_chosen, false);
382  } else {
383  ts_->set(TelltaleState::is_chosen, true);
384  }
385 }
386 
388  if (ts_->test(TelltaleState::is_chosen)) {
389  if (gl_->fixed()) {
390  gl_->vfixed(gl_->scale());
391  }
392  } else {
393  if (!gl_->fixed()) {
394  gl_->fixed(gl_->scale());
395  }
396  }
397 }
398 
399 bool OcGlyph::dialog_dismiss(bool accept) {
400  if (d_) {
401  d_->dismiss(accept);
402  return true;
403  }
404  return false;
405 }
406 
407 bool OcGlyph::dialog(const char* label, const char* accept, const char* cancel) {
408  WidgetKit& k = *WidgetKit::instance();
409  LayoutKit& l = *LayoutKit::instance();
410  PolyGlyph* vbox = l.vbox();
411  bool ok;
412  d_ = new OcGlyphDialog(k.outset_frame(l.margin(vbox, 5)), Session::instance()->style());
413  d_->ref();
414  vbox->append(l.hcenter(l.hflexible(l.margin(k.label(label), 10), fil, 0)));
415  vbox->append(l.hcenter(this));
416  vbox->append(l.hcenter(l.hflexible(l.hbox(k.push_button(accept, new DialogAction(d_, true)),
417  l.hspace(10),
418  k.push_button(cancel, new DialogAction(d_, false))),
419  fil,
420  0)));
422  ok = oc_post_dialog(d_, 400., 400.);
424  d_->unref();
425  d_ = NULL;
426  return ok;
427 }
428 
429 OcGlyphDialog::OcGlyphDialog(Glyph* g, Style* s)
430  : Dialog(g, s) {}
431 OcGlyphDialog::~OcGlyphDialog() {}
432 void OcGlyphDialog::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
433  const Event* e = h.event();
434  EventType t = (e == NULL) ? Event::undefined : e->type();
435  switch (t) {
436  case Event::key:
437  if (e && inside(*e)) {
438  body()->pick(c, a, depth + 1, h);
439  }
440  break;
441  default:
442  Dialog::pick(c, a, depth, h);
443  }
444 }
445 #endif
#define EventType
Definition: _defines.h:20
#define Window
Definition: _defines.h:333
#define TelltaleState
Definition: _defines.h:296
#define Canvas
Definition: _defines.h:65
#define Style
Definition: _defines.h:281
#define Coord
Definition: _defines.h:19
#define Hit
Definition: _defines.h:147
#define Display
Definition: _defines.h:97
#define Dialog
Definition: _defines.h:94
#define WidgetKit
Definition: _defines.h:331
#define DialogKit
Definition: _defines.h:95
#define Event
Definition: _defines.h:107
#define Button
Definition: _defines.h:62
#define PolyGlyph
Definition: _defines.h:207
#define FieldEditor
Definition: _defines.h:111
#define LayoutKit
Definition: _defines.h:161
#define Action
Definition: _defines.h:27
#define Glyph
Definition: _defines.h:132
FieldDialog(Glyph *, Style *)
virtual void cancel(FieldEditor *)
CopyString s_
Definition: utility.h:37
virtual bool run()
virtual void accept(FieldEditor *)
virtual void dismiss(bool accept)
static FieldDialog * field_dialog_instance(const char *, Style *, Glyph *extra=NULL)
const String * text() const
Definition: utility.h:24
virtual ~FieldDialog()
FieldEditor * fe_
Definition: utility.h:36
Definition: graph.h:424
static bool label_chooser(const char *, char *, GLabel *, Coord x=400., Coord y=400.)
virtual bool dialog(const char *label, const char *accept, const char *cancel)
bool dialog_dismiss(bool b)
Dialog * d_
Definition: ocglyph.h:45
virtual void ref() const
Definition: resource.cpp:47
virtual void unref() const
Definition: resource.cpp:52
Definition: string.h:34
const char * string() const
Definition: string.h:139
void execute(Inst *p)
Definition: code.cpp:2661
#define fil
Definition: coord.h:42
double t
Definition: cvodeobj.cpp:59
sprintf(buf, " if (secondorder) {\n" " int _i;\n" " for (_i = 0; _i < %d; ++_i) {\n" " _p[_slist%d[_i]] += dt*_p[_dlist%d[_i]];\n" " }}\n", numeqn, listnum, listnum)
#define c
Object **(* nrnpy_gui_helper_)(const char *name, Object *obj)
Definition: xmenu.cpp:13
double(* nrnpy_object_to_double_)(Object *)
Definition: xmenu.cpp:14
char buf[512]
Definition: init.cpp:13
void hoc_assign_str(char **cpp, const char *buf)
Definition: code.cpp:2350
void hoc_ret()
char ** hoc_pgargstr(int narg)
Definition: code.cpp:1599
#define TRY_GUI_REDIRECT_DOUBLE(name, obj)
Definition: gui-redirect.h:58
#define TRY_GUI_REDIRECT_DOUBLE_SEND_STRREF(name, obj)
Definition: gui-redirect.h:104
#define IFGUI
Definition: hocdec.h:372
#define gargstr
Definition: hocdec.h:14
#define ENDGUI
Definition: hocdec.h:373
int ifarg(int)
Definition: code.cpp:1581
void hoc_pushx(double)
char * name
Definition: init.cpp:16
static double inside(void *)
Definition: mymath.cpp:21
static philox4x32_key_t k
Definition: nrnran123.cpp:11
void handle_old_focus()
void hoc_continue_dialog()
Definition: ocnoiv1.cpp:123
void hoc_boolean_dialog()
Definition: ocnoiv1.cpp:111
void hoc_string_dialog()
Definition: ocnoiv1.cpp:130
#define g
Definition: passive0.cpp:21
#define e
Definition: passive0.cpp:22
#define run
Definition: redef.h:125
#define key
Definition: spt2queue.cpp:20
#define NULL
Definition: sptree.h:16
Definition: hocdec.h:227
bool var_pair_chooser(const char *, float &x, float &y, Window *w=NULL, Coord x1=400., Coord y1=400.)
bool nrn_spec_dialog_pos(Coord &x, Coord &y)
true if Style 'dialog_spec_position: on' and fills x,y with dialog_left_position and dialog_bottom_po...
bool str_chooser(const char *, char *, Window *w=NULL, Coord x=400., Coord y=400.)
bool ok_to_write(const String &, Window *w=NULL)
bool ok_to_read(const String &, Window *w=NULL)
bool boolean_dialog(const char *label, const char *accept, const char *cancel, Window *w=NULL, Coord x=400., Coord y=400.)
void continue_dialog(const char *label, Window *w=NULL, Coord x=400., Coord y=400.)