NEURON
field.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #if HAVE_IV // to end of file
3 
4 /*
5  * Copyright (c) 1991 Stanford University
6  * Copyright (c) 1991 Silicon Graphics, Inc.
7  *
8  * Permission to use, copy, modify, distribute, and sell this software and
9  * its documentation for any purpose is hereby granted without fee, provided
10  * that (i) the above copyright notices and this permission notice appear in
11  * all copies of the software and related documentation, and (ii) the names of
12  * Stanford and Silicon Graphics may not be used in any advertising or
13  * publicity relating to the software without the specific, prior written
14  * permission of Stanford and Silicon Graphics.
15  *
16  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR
21  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
22  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
23  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
24  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25  * OF THIS SOFTWARE.
26  */
27 
28 /*
29  * FieldSEditor -- simple editor for text fields
30  */
31 
32 #include <Dispatch/dispatcher.h>
33 #include <Dispatch/iocallback.h>
34 //#include <IV-look/field.h>
35 #include "field.h"
36 #include <IV-look/kit.h>
37 #include <InterViews/background.h>
38 #include <InterViews/canvas.h>
39 #include <InterViews/display.h>
40 #include <InterViews/font.h>
41 #include <InterViews/event.h>
42 #include <InterViews/hit.h>
43 #include <InterViews/layout.h>
44 #include <InterViews/printer.h>
45 #include <InterViews/selection.h>
46 #include <InterViews/style.h>
47 #include <InterViews/window.h>
48 #include <IV-2_6/InterViews/button.h>
49 #include <IV-2_6/InterViews/painter.h>
50 #include <IV-2_6/InterViews/sensor.h>
51 #include <IV-2_6/InterViews/streditor.h>
52 #include <IV-2_6/InterViews/textdisplay.h>
53 #include <OS/math.h>
54 #include <OS/string.h>
55 #include <stdio.h>
56 
57 class FieldStringSEditor : public StringEditor {
58 public:
59  FieldStringSEditor(
60  ButtonState* bs, const char* sample, WidgetKit*, Style*
61  );
62  virtual ~FieldStringSEditor();
63 
64  virtual void print(Printer*, const Allocation&) const;
65  virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
66 
67  void press(const Event&);
68  void drag(const Event&);
69  void release(const Event&);
70  bool keystroke(const Event&);
71  void cursor_on();
72  void cursor_off();
73  void focus_in();
74  void focus_out();
75  void cut(SelectionManager*);
76  void paste(SelectionManager*);
77 
78  void Select(int pos);
79  void Select(int left, int right);
80  void selection(int& start, int& index);
81 protected:
82  virtual void Reconfig();
83 private:
84  WidgetKit* kit_;
85  Style* style_;
86  int start_;
87  int index_;
88  int origin_;
89  int width_;
90 
91  void do_select(Event&);
92  void do_grab_scroll(Event&);
93  void do_rate_scroll(Event&);
94 };
95 
96 declareSelectionCallback(FieldStringSEditor)
97 implementSelectionCallback(FieldStringSEditor)
98 
99 FieldStringSEditor::FieldStringSEditor(
100  ButtonState* bs, const char* sample, WidgetKit* kit, Style* style
101 ) : StringEditor(bs, sample) {
102  kit_ = kit;
103  style_ = style;
104  Resource::ref(style);
105  delete input;
106  input = NULL;
107  start_ = index_ = -1;
108 }
109 
110 FieldStringSEditor::~FieldStringSEditor() {
111  Resource::unref(style_);
112 }
113 
114 void FieldStringSEditor::Select(int pos) {
115  start_ = index_ = pos;
116  StringEditor::Select(pos);
117 }
118 void FieldStringSEditor::Select(int left, int right) {
119  start_ = left;
120  index_ = right;
121  StringEditor::Select(left, right);
122 }
123 void FieldStringSEditor::selection(int& start, int& index) {
124  start = start_;
125  index = index_;
126 }
127 
128 void FieldStringSEditor::print(Printer* p, const Allocation& a) const {
129  const Font* f = output->GetFont();
130  const Color* fg = output->GetFgColor();
131  FontBoundingBox b;
132  f->font_bbox(b);
133  Coord x = a.left(), y = a.bottom() + b.font_descent();
134  FieldStringSEditor* e = (FieldStringSEditor*)this;
135  for (const char* s = e->Text(); *s != '\0'; s++) {
136  Coord w = f->width(*s);
137  p->character(f, *s, w, fg, x, y);
138  x += w;
139  }
140 }
141 
142 void FieldStringSEditor::pick(
143  Canvas*, const Allocation& a, int depth, Hit& h
144 ) {
145  const Event* ep = h.event();
146  if (ep != NULL && h.left() < a.right() && h.right() >= a.left() &&
147  h.bottom() < a.top() && h.top() >= a.bottom()
148  ) {
149  h.target(depth, this, 0);
150  }
151 }
152 
153 void FieldStringSEditor::press(const Event& event) {
154  Event e;
155  display->Draw(output, canvas);
156  switch (event.pointer_button()) {
157  case Event::left:
158  case Event::middle:
159  case Event::right:
160  origin_ = display->Left(0, 0);
161  width_ = display->Width();
162  Poll(e);
163  start_ = display->LineIndex(0, e.x);
164  do_select(e);
165  break;
166 #if 0
167  case Event::middle:
168  do_grab_scroll(e);
169  break;
170  case Event::right:
171  do_rate_scroll(e);
172  break;
173 #endif
174  }
175 }
176 
177 void FieldStringSEditor::drag(const Event&) {
178  Event e;
179 // I have no idea why the event.pointer_button() is 0.
180  Poll(e);
181 // if (e.leftmouse)
182  {
183  do_select(e);
184  }
185 }
186 
187 void FieldStringSEditor::release(const Event& event) {
188  Event e;
189  switch (event.pointer_button()) {
190  case Event::left:
191  case Event::middle:
192  case Event::right:
193  {
194  Poll(e);
195  do_select(e);
196  SelectionManager* s = e.display()->primary_selection();
197  s->own(
198  new SelectionCallback(FieldStringSEditor)(this, &FieldStringSEditor::cut)
199  );
200  }
201  break;
202  }
203 }
204 
205 void FieldStringSEditor::do_select(Event& e) {
206  if (e.x < 0) {
207  origin_ = Math::min(0, origin_ - e.x);
208  } else if (e.x > xmax) {
209  origin_ = Math::max(
210  xmax - width_, origin_ - (e.x - xmax)
211  );
212  }
213  display->Scroll(0, origin_, ymax);
214  index_ = display->LineIndex(0, e.x);
215  DoSelect(start_, index_);
216 }
217 
218 void FieldStringSEditor::do_grab_scroll(Event& e) {
219  Window* w = canvas->window();
220  Cursor* c = w->cursor();
221  w->cursor(kit_->hand_cursor());
222  int origin = display->Left(0, 0);
223  int width = display->Width();
224  Poll(e);
225  int x = e.x;
226  do {
227  origin += e.x - x;
228  origin = Math::min(
229  0, Math::max(Math::min(0, xmax - width), origin)
230  );
231  display->Scroll(0, origin, ymax);
232  x = e.x;
233  Poll(e);
234  } while (e.middlemouse);
235  w->cursor(c);
236 }
237 
238 void FieldStringSEditor::do_rate_scroll(Event& e) {
239  Window* w = canvas->window();
240  Cursor* c = w->cursor();
241  WidgetKit& kit = *kit_;
242  Cursor* left = kit.lfast_cursor();
243  Cursor* right = kit.rfast_cursor();
244  int origin = display->Left(0, 0);
245  int width = display->Width();
246  Poll(e);
247  int x = e.x;
248  do {
249  origin += x - e.x;
250  origin = Math::min(
251  0, Math::max(Math::min(0, xmax - width), origin)
252  );
253  display->Scroll(0, origin, ymax);
254  if (e.x - x < 0) {
255  w->cursor(left);
256  } else {
257  w->cursor(right);
258  }
259  Poll(e);
260  } while (e.rightmouse);
261  w->cursor(c);
262 }
263 
264 bool FieldStringSEditor::keystroke(const Event& e) {
265  char c;
266  return e.mapkey(&c, 1) != 0 && HandleChar(c) && c == '\t';
267 }
268 
269 void FieldStringSEditor::cursor_on() {
270  if (canvas != NULL) {
271  display->CaretStyle(BarCaret);
272  }
273 }
274 
275 void FieldStringSEditor::cursor_off() {
276  if (canvas != NULL) {
277  display->CaretStyle(NoCaret);
278  }
279 }
280 
281 void FieldStringSEditor::focus_in() { }
282 void FieldStringSEditor::focus_out() { }
283 
284 void FieldStringSEditor::cut(SelectionManager* s) {
285 // s->put_value(Text() + start_, index_ - start_);
286  int st = Math::min(start_, index_); int i = Math::max(index_, start_);
287  s->put_value(Text() + st, i - st);
288 }
289 
290 void FieldStringSEditor::paste(SelectionManager*) {
291  /* unimplemented */
292 }
293 
294 void FieldStringSEditor::Reconfig() {
295  kit_->push_style();
296  kit_->style(style_);
297  Painter* p = new Painter(output);
298  p->SetColors(kit_->foreground(), kit_->background());
299  p->SetFont(kit_->font());
300  Resource::unref(output);
301  output = p;
302  StringEditor::Reconfig();
303  kit_->pop_style();
304 }
305 
306 class FieldSButton : public ButtonState {
307 public:
308  FieldSButton(FieldSEditor*, FieldSEditorAction*);
309  virtual ~FieldSButton();
310 
311  virtual void Notify();
312 private:
313  FieldSEditor* editor_;
314  FieldSEditorAction* action_;
315 };
316 
317 class FieldSEditorImpl {
318 private:
319  friend class FieldSEditor;
320 
321  WidgetKit* kit_;
322  FieldStringSEditor* editor_;
323  FieldSButton* bs_;
324  String text_;
325  bool cursor_is_on_;
326  IOHandler* blink_handler_;
327  long flash_rate_;
328 
329  void build(FieldSEditor*, const char*, FieldSEditorAction*);
330  void blink_cursor(long, long);
331  void stop_blinking();
332 };
333 
334 declareIOCallback(FieldSEditorImpl)
335 implementIOCallback(FieldSEditorImpl)
336 
338  const String& sample, WidgetKit* kit, Style* s, FieldSEditorAction* action
339 ) : InputHandler(NULL, s) {
340  impl_ = new FieldSEditorImpl;
341  impl_->kit_ = kit;
342  NullTerminatedString ns(sample);
343  impl_->build(this, ns.string(), action);
344 }
345 
347  FieldSEditorImpl* i = impl_;
348  i->stop_blinking();
349  Resource::unref(i->editor_);
350  Resource::unref(i->bs_);
351  delete i->blink_handler_;
352  delete i;
353 }
354 
355 void FieldSEditor::undraw() {
356  FieldSEditorImpl& f = *impl_;
357  f.stop_blinking();
358  InputHandler::undraw();
359 }
360 
361 void FieldSEditor::press(const Event& e) {
362  impl_->editor_->press(e);
363 }
364 
365 void FieldSEditor::drag(const Event& e) {
366  impl_->editor_->drag(e);
367 }
368 void FieldSEditor::release(const Event& e) {
369  impl_->editor_->release(e);
370 }
371 
372 void FieldSEditor::keystroke(const Event& e) {
373  FieldSEditorImpl& f = *impl_;
374  if (f.editor_->keystroke(e)) {
375  select(text()->length());
376  next_focus();
377  }
378 }
379 
381  FieldSEditorImpl& f = *impl_;
382  f.blink_cursor(0, 0);
383  f.editor_->focus_in();
384  return InputHandler::focus_in();
385 }
386 
388  FieldSEditorImpl& f = *impl_;
389  f.stop_blinking();
390  f.editor_->cursor_off();
391  f.editor_->focus_out();
392  InputHandler::focus_out();
393 }
394 
395 void FieldSEditor::field(const char* str) {
396  impl_->editor_->Message(str);
397 }
398 
399 void FieldSEditor::field(const String& s) {
400  NullTerminatedString ns(s);
401  impl_->editor_->Message(ns.string());
402 }
403 
404 void FieldSEditor::select(int pos) {
405  impl_->editor_->Select(pos);
406 }
407 
408 void FieldSEditor::select(int l, int r) {
409  impl_->editor_->Select(l, r);
410 }
411 
412 void FieldSEditor::selection(int& start, int& index) const {
413  impl_->editor_->selection(start, index);
414 }
415 
416 void FieldSEditor::edit() {
417  impl_->editor_->Edit();
418 }
419 
420 void FieldSEditor::edit(const char* str, int left, int right) {
421  impl_->editor_->Edit(str, left, right);
422 }
423 
424 void FieldSEditor::edit(const String& str, int left, int right) {
425  NullTerminatedString ns(str);
426  impl_->editor_->Edit(ns.string(), left, right);
427 }
428 
429 const String* FieldSEditor::text() const {
430  impl_->text_ = String(impl_->editor_->Text());
431  return &impl_->text_;
432 }
433 
434 /** class FieldSEditorImpl **/
435 
436 void FieldSEditorImpl::build(
437  FieldSEditor* e, const char* str, FieldSEditorAction* a
438 ) {
439  WidgetKit& kit = *kit_;
440  kit.begin_style("FieldEditor");
441  Style* s = kit.style();
442  bs_ = new FieldSButton(e, a);
443  editor_ = new FieldStringSEditor(bs_, str, kit_, s);
444  Glyph* g = editor_;
445  if (s->value_is_on("beveled")) {
446  g = kit.inset_frame(
447  new Background(
448  LayoutKit::instance()->h_margin(editor_, 2.0),
449  kit.background()
450  )
451  );
452  }
453  e->body(g);
454  cursor_is_on_ = false;
455  blink_handler_ = new IOCallback(FieldSEditorImpl)(
456  this, &FieldSEditorImpl::blink_cursor
457  );
458  float sec = 0.5;
459  s->find_attribute("cursorFlashRate", sec);
460  flash_rate_ = long(sec * 1000000);
461  kit.end_style();
462 }
463 
464 void FieldSEditorImpl::blink_cursor(long, long) {
465  if (cursor_is_on_) {
466  editor_->cursor_off();
467  cursor_is_on_ = false;
468  } else {
469  editor_->cursor_on();
470  cursor_is_on_ = true;
471  }
472  if (flash_rate_ > 10) {
473  Dispatcher::instance().startTimer(0, flash_rate_, blink_handler_);
474  }
475 }
476 
477 void FieldSEditorImpl::stop_blinking() {
478  Dispatcher::instance().stopTimer(blink_handler_);
479  editor_->cursor_off();
480  cursor_is_on_ = false;
481 }
482 
483 /** class FieldSButton **/
484 
485 FieldSButton::FieldSButton(FieldSEditor* editor, FieldSEditorAction* action) {
486  editor_ = editor;
487  action_ = action;
488  Resource::ref(action_);
489 }
490 
491 FieldSButton::~FieldSButton() {
492  Resource::unref(action_);
493 }
494 
495 /*
496  * We need to reset the button state's value so that we'll get
497  * notified again. If we call SetValue, then it will call
498  * Notify again! Alas, we must access the protected value member (sigh).
499  */
500 
501 void FieldSButton::Notify() {
502  int v;
503  GetValue(v);
504  value = 0;
505  if (action_ != NULL) {
506  switch (v) {
507  case '\r':
508  action_->accept(editor_);
509  break;
510  case /* ^G */ '\007':
511  case /* Esc */ '\033':
512  action_->cancel(editor_);
513  break;
514  default:
515  break;
516  }
517  }
518 }
519 
520 /** class FieldSEditorAction **/
521 
526 #endif
double max(double a, double b)
Definition: geometry3d.cpp:22
FieldSEditor(const String &sample, WidgetKit *, Style *, FieldSEditorAction *=NULL)
#define Cursor
Definition: _defines.h:85
#define text
Definition: plot.cpp:81
#define WidgetKit
Definition: _defines.h:331
virtual void select(int pos)
#define min(a, b)
Definition: matrix.h:157
#define g
Definition: passive0.cpp:23
#define Glyph
Definition: _defines.h:132
#define Coord
Definition: _defines.h:19
#define InputHandler
Definition: _defines.h:151
size_t p
#define Color
Definition: _defines.h:74
#define print
Definition: redef.h:109
#define v
Definition: md1redef.h:4
#define ButtonState
Definition: _defines.h:64
virtual void press(const Event &)
virtual void field(const char *)
virtual void ref() const
Definition: resource.cpp:47
#define StringEditor
Definition: _defines.h:280
#define e
Definition: passive0.cpp:24
virtual const String * text() const
void start()
Definition: hel2mos.cpp:205
virtual void drag(const Event &)
#define FontBoundingBox
Definition: _defines.h:121
#define Text
Definition: _defines.h:297
long
Definition: netcvode.cpp:4792
#define Font
Definition: _defines.h:120
virtual InputHandler * focus_in()
#define Printer
Definition: _defines.h:211
virtual void selection(int &start, int &index) const
_CONST char * s
Definition: system.cpp:74
Coord top() const
Definition: geometry.h:295
virtual void keystroke(const Event &)
virtual void drag(const Event &e)
Definition: ocinput.h:21
FieldSEditorImpl * impl_
Definition: field.h:125
virtual void press(const Event &e)
Definition: ocinput.h:20
Coord left() const
Definition: geometry.h:292
#define Canvas
Definition: _defines.h:65
virtual void release(const Event &)
#define SelectionManager
Definition: _defines.h:257
virtual void unref() const
Definition: resource.cpp:52
virtual ~FieldSEditorAction()
Coord bottom() const
Definition: geometry.h:294
#define left
Definition: rbtqueue.cpp:45
#define Event
Definition: _defines.h:107
virtual void release(const Event &e)
Definition: ocinput.h:22
static uint32_t value
Definition: scoprand.cpp:26
virtual void edit()
#define right
Definition: rbtqueue.cpp:46
virtual void cancel(FieldSEditor *)
#define Painter
Definition: _defines.h:198
static void display(int imenu)
Definition: fmenu.cpp:394
Coord right() const
Definition: geometry.h:293
String
Definition: ustring.cpp:41
virtual void focus_out()
#define i
Definition: md1redef.h:12
#define c
virtual ~FieldSEditor()
Definition: string.h:34
sec
Definition: solve.cpp:885
#define Window
Definition: _defines.h:333
#define Style
Definition: _defines.h:281
#define input(prompt, fmt, var)
Definition: matrix.h:368
#define Background
Definition: _defines.h:43
virtual void accept(FieldSEditor *)
virtual void undraw()
return NULL
Definition: cabcode.cpp:461
short index
Definition: cabvars.h:11
#define Hit
Definition: _defines.h:147