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(ButtonState* bs, const char* sample, WidgetKit*, Style*);
60  virtual ~FieldStringSEditor();
61 
62  virtual void print(Printer*, const Allocation&) const;
63  virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
64 
65  void press(const Event&);
66  void drag(const Event&);
67  void release(const Event&);
68  bool keystroke(const Event&);
69  void cursor_on();
70  void cursor_off();
71  void focus_in();
72  void focus_out();
73  void cut(SelectionManager*);
74  void paste(SelectionManager*);
75 
76  void Select(int pos);
77  void Select(int left, int right);
78  void selection(int& start, int& index);
79 
80  protected:
81  virtual void Reconfig();
82 
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) implementSelectionCallback(FieldStringSEditor)
97 
98  FieldStringSEditor::FieldStringSEditor(ButtonState* bs,
99  const char* sample,
100  WidgetKit* kit,
101  Style* style)
102  : StringEditor(bs, sample) {
103  kit_ = kit;
104  style_ = style;
105  Resource::ref(style);
106  delete input;
107  input = NULL;
108  start_ = index_ = -1;
109 }
110 
111 FieldStringSEditor::~FieldStringSEditor() {
112  Resource::unref(style_);
113 }
114 
115 void FieldStringSEditor::Select(int pos) {
116  start_ = index_ = pos;
117  StringEditor::Select(pos);
118 }
119 void FieldStringSEditor::Select(int left, int right) {
120  start_ = left;
121  index_ = right;
122  StringEditor::Select(left, right);
123 }
124 void FieldStringSEditor::selection(int& start, int& index) {
125  start = start_;
126  index = index_;
127 }
128 
129 void FieldStringSEditor::print(Printer* p, const Allocation& a) const {
130  const Font* f = output->GetFont();
131  const Color* fg = output->GetFgColor();
132  FontBoundingBox b;
133  f->font_bbox(b);
134  Coord x = a.left(), y = a.bottom() + b.font_descent();
135  FieldStringSEditor* e = (FieldStringSEditor*) this;
136  for (const char* s = e->Text(); *s != '\0'; s++) {
137  Coord w = f->width(*s);
138  p->character(f, *s, w, fg, x, y);
139  x += w;
140  }
141 }
142 
143 void FieldStringSEditor::pick(Canvas*, const Allocation& a, int depth, Hit& h) {
144  const Event* ep = h.event();
145  if (ep != NULL && h.left() < a.right() && h.right() >= a.left() && h.bottom() < a.top() &&
146  h.top() >= a.bottom()) {
147  h.target(depth, this, 0);
148  }
149 }
150 
151 void FieldStringSEditor::press(const Event& event) {
152  Event e;
153  display->Draw(output, canvas);
154  switch (event.pointer_button()) {
155  case Event::left:
156  case Event::middle:
157  case Event::right:
158  origin_ = display->Left(0, 0);
159  width_ = display->Width();
160  Poll(e);
161  start_ = display->LineIndex(0, e.x);
162  do_select(e);
163  break;
164 #if 0
165  case Event::middle:
166  do_grab_scroll(e);
167  break;
168  case Event::right:
169  do_rate_scroll(e);
170  break;
171 #endif
172  }
173 }
174 
175 void FieldStringSEditor::drag(const Event&) {
176  Event e;
177  // I have no idea why the event.pointer_button() is 0.
178  Poll(e);
179  // if (e.leftmouse)
180  { do_select(e); }
181 }
182 
183 void FieldStringSEditor::release(const Event& event) {
184  Event e;
185  switch (event.pointer_button()) {
186  case Event::left:
187  case Event::middle:
188  case Event::right: {
189  Poll(e);
190  do_select(e);
191  SelectionManager* s = e.display()->primary_selection();
192  s->own(new SelectionCallback(FieldStringSEditor)(this, &FieldStringSEditor::cut));
193  } break;
194  }
195 }
196 
197 void FieldStringSEditor::do_select(Event& e) {
198  if (e.x < 0) {
199  origin_ = Math::min(0, origin_ - e.x);
200  } else if (e.x > xmax) {
201  origin_ = Math::max(xmax - width_, origin_ - (e.x - xmax));
202  }
203  display->Scroll(0, origin_, ymax);
204  index_ = display->LineIndex(0, e.x);
205  DoSelect(start_, index_);
206 }
207 
208 void FieldStringSEditor::do_grab_scroll(Event& e) {
209  Window* w = canvas->window();
210  Cursor* c = w->cursor();
211  w->cursor(kit_->hand_cursor());
212  int origin = display->Left(0, 0);
213  int width = display->Width();
214  Poll(e);
215  int x = e.x;
216  do {
217  origin += e.x - x;
218  origin = Math::min(0, Math::max(Math::min(0, xmax - width), origin));
219  display->Scroll(0, origin, ymax);
220  x = e.x;
221  Poll(e);
222  } while (e.middlemouse);
223  w->cursor(c);
224 }
225 
226 void FieldStringSEditor::do_rate_scroll(Event& e) {
227  Window* w = canvas->window();
228  Cursor* c = w->cursor();
229  WidgetKit& kit = *kit_;
230  Cursor* left = kit.lfast_cursor();
231  Cursor* right = kit.rfast_cursor();
232  int origin = display->Left(0, 0);
233  int width = display->Width();
234  Poll(e);
235  int x = e.x;
236  do {
237  origin += x - e.x;
238  origin = Math::min(0, Math::max(Math::min(0, xmax - width), origin));
239  display->Scroll(0, origin, ymax);
240  if (e.x - x < 0) {
241  w->cursor(left);
242  } else {
243  w->cursor(right);
244  }
245  Poll(e);
246  } while (e.rightmouse);
247  w->cursor(c);
248 }
249 
250 bool FieldStringSEditor::keystroke(const Event& e) {
251  char c;
252  return e.mapkey(&c, 1) != 0 && HandleChar(c) && c == '\t';
253 }
254 
255 void FieldStringSEditor::cursor_on() {
256  if (canvas != NULL) {
257  display->CaretStyle(BarCaret);
258  }
259 }
260 
261 void FieldStringSEditor::cursor_off() {
262  if (canvas != NULL) {
263  display->CaretStyle(NoCaret);
264  }
265 }
266 
267 void FieldStringSEditor::focus_in() {}
268 void FieldStringSEditor::focus_out() {}
269 
270 void FieldStringSEditor::cut(SelectionManager* s) {
271  // s->put_value(Text() + start_, index_ - start_);
272  int st = Math::min(start_, index_);
273  int i = Math::max(index_, start_);
274  s->put_value(Text() + st, i - st);
275 }
276 
277 void FieldStringSEditor::paste(SelectionManager*) {
278  /* unimplemented */
279 }
280 
281 void FieldStringSEditor::Reconfig() {
282  kit_->push_style();
283  kit_->style(style_);
284  Painter* p = new Painter(output);
285  p->SetColors(kit_->foreground(), kit_->background());
286  p->SetFont(kit_->font());
287  Resource::unref(output);
288  output = p;
289  StringEditor::Reconfig();
290  kit_->pop_style();
291 }
292 
293 class FieldSButton: public ButtonState {
294  public:
295  FieldSButton(FieldSEditor*, FieldSEditorAction*);
296  virtual ~FieldSButton();
297 
298  virtual void Notify();
299 
300  private:
301  FieldSEditor* editor_;
302  FieldSEditorAction* action_;
303 };
304 
305 class FieldSEditorImpl {
306  private:
307  friend class FieldSEditor;
308 
309  WidgetKit* kit_;
310  FieldStringSEditor* editor_;
311  FieldSButton* bs_;
312  String text_;
313  bool cursor_is_on_;
314  IOHandler* blink_handler_;
315  long flash_rate_;
316 
317  void build(FieldSEditor*, const char*, FieldSEditorAction*);
318  void blink_cursor(long, long);
319  void stop_blinking();
320 };
321 
322 declareIOCallback(FieldSEditorImpl) implementIOCallback(FieldSEditorImpl)
323 
324  FieldSEditor::FieldSEditor(const String& sample,
325  WidgetKit* kit,
326  Style* s,
327  FieldSEditorAction* action)
328  : InputHandler(NULL, s) {
329  impl_ = new FieldSEditorImpl;
330  impl_->kit_ = kit;
331  NullTerminatedString ns(sample);
332  impl_->build(this, ns.string(), action);
333 }
334 
336  FieldSEditorImpl* i = impl_;
337  i->stop_blinking();
338  Resource::unref(i->editor_);
339  Resource::unref(i->bs_);
340  delete i->blink_handler_;
341  delete i;
342 }
343 
344 void FieldSEditor::undraw() {
345  FieldSEditorImpl& f = *impl_;
346  f.stop_blinking();
347  InputHandler::undraw();
348 }
349 
350 void FieldSEditor::press(const Event& e) {
351  impl_->editor_->press(e);
352 }
353 
354 void FieldSEditor::drag(const Event& e) {
355  impl_->editor_->drag(e);
356 }
357 void FieldSEditor::release(const Event& e) {
358  impl_->editor_->release(e);
359 }
360 
361 void FieldSEditor::keystroke(const Event& e) {
362  FieldSEditorImpl& f = *impl_;
363  if (f.editor_->keystroke(e)) {
364  select(text()->length());
365  next_focus();
366  }
367 }
368 
370  FieldSEditorImpl& f = *impl_;
371  f.blink_cursor(0, 0);
372  f.editor_->focus_in();
373  return InputHandler::focus_in();
374 }
375 
377  FieldSEditorImpl& f = *impl_;
378  f.stop_blinking();
379  f.editor_->cursor_off();
380  f.editor_->focus_out();
381  InputHandler::focus_out();
382 }
383 
384 void FieldSEditor::field(const char* str) {
385  impl_->editor_->Message(str);
386 }
387 
388 void FieldSEditor::field(const String& s) {
389  NullTerminatedString ns(s);
390  impl_->editor_->Message(ns.string());
391 }
392 
393 void FieldSEditor::select(int pos) {
394  impl_->editor_->Select(pos);
395 }
396 
397 void FieldSEditor::select(int l, int r) {
398  impl_->editor_->Select(l, r);
399 }
400 
401 void FieldSEditor::selection(int& start, int& index) const {
402  impl_->editor_->selection(start, index);
403 }
404 
405 void FieldSEditor::edit() {
406  impl_->editor_->Edit();
407 }
408 
409 void FieldSEditor::edit(const char* str, int left, int right) {
410  impl_->editor_->Edit(str, left, right);
411 }
412 
413 void FieldSEditor::edit(const String& str, int left, int right) {
414  NullTerminatedString ns(str);
415  impl_->editor_->Edit(ns.string(), left, right);
416 }
417 
418 const String* FieldSEditor::text() const {
419  impl_->text_ = String(impl_->editor_->Text());
420  return &impl_->text_;
421 }
422 
423 /** class FieldSEditorImpl **/
424 
425 void FieldSEditorImpl::build(FieldSEditor* e, const char* str, FieldSEditorAction* a) {
426  WidgetKit& kit = *kit_;
427  kit.begin_style("FieldEditor");
428  Style* s = kit.style();
429  bs_ = new FieldSButton(e, a);
430  editor_ = new FieldStringSEditor(bs_, str, kit_, s);
431  Glyph* g = editor_;
432  if (s->value_is_on("beveled")) {
433  g = kit.inset_frame(
434  new Background(LayoutKit::instance()->h_margin(editor_, 2.0), kit.background()));
435  }
436  e->body(g);
437  cursor_is_on_ = false;
438  blink_handler_ = new IOCallback(FieldSEditorImpl)(this, &FieldSEditorImpl::blink_cursor);
439  float sec = 0.5;
440  s->find_attribute("cursorFlashRate", sec);
441  flash_rate_ = long(sec * 1000000);
442  kit.end_style();
443 }
444 
445 void FieldSEditorImpl::blink_cursor(long, long) {
446  if (cursor_is_on_) {
447  editor_->cursor_off();
448  cursor_is_on_ = false;
449  } else {
450  editor_->cursor_on();
451  cursor_is_on_ = true;
452  }
453  if (flash_rate_ > 10) {
454  Dispatcher::instance().startTimer(0, flash_rate_, blink_handler_);
455  }
456 }
457 
458 void FieldSEditorImpl::stop_blinking() {
459  Dispatcher::instance().stopTimer(blink_handler_);
460  editor_->cursor_off();
461  cursor_is_on_ = false;
462 }
463 
464 /** class FieldSButton **/
465 
466 FieldSButton::FieldSButton(FieldSEditor* editor, FieldSEditorAction* action) {
467  editor_ = editor;
468  action_ = action;
469  Resource::ref(action_);
470 }
471 
472 FieldSButton::~FieldSButton() {
473  Resource::unref(action_);
474 }
475 
476 /*
477  * We need to reset the button state's value so that we'll get
478  * notified again. If we call SetValue, then it will call
479  * Notify again! Alas, we must access the protected value member (sigh).
480  */
481 
482 void FieldSButton::Notify() {
483  int v;
484  GetValue(v);
485  value = 0;
486  if (action_ != NULL) {
487  switch (v) {
488  case '\r':
489  action_->accept(editor_);
490  break;
491  case /* ^G */ '\007':
492  case /* Esc */ '\033':
493  action_->cancel(editor_);
494  break;
495  default:
496  break;
497  }
498  }
499 }
500 
501 /** class FieldSEditorAction **/
502 
507 #endif
#define InputHandler
Definition: _defines.h:151
#define Window
Definition: _defines.h:333
#define Painter
Definition: _defines.h:198
#define Background
Definition: _defines.h:43
#define Color
Definition: _defines.h:74
#define FontBoundingBox
Definition: _defines.h:121
#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 WidgetKit
Definition: _defines.h:331
#define Printer
Definition: _defines.h:211
#define Event
Definition: _defines.h:107
#define Font
Definition: _defines.h:120
#define ButtonState
Definition: _defines.h:64
#define SelectionManager
Definition: _defines.h:257
#define Text
Definition: _defines.h:297
#define Cursor
Definition: _defines.h:85
#define Glyph
Definition: _defines.h:132
#define StringEditor
Definition: _defines.h:280
#define String
Definition: enter-scope.h:48
short index
Definition: cabvars.h:10
Coord right() const
Definition: geometry.h:293
Coord top() const
Definition: geometry.h:295
Coord left() const
Definition: geometry.h:292
Coord bottom() const
Definition: geometry.h:294
virtual void cancel(FieldSEditor *)
virtual ~FieldSEditorAction()
virtual void accept(FieldSEditor *)
FieldSEditorImpl * impl_
Definition: field.h:127
virtual void focus_out()
virtual void release(const Event &)
virtual void edit()
virtual const String * text() const
virtual void selection(int &start, int &index) const
virtual void press(const Event &)
virtual ~FieldSEditor()
virtual void undraw()
virtual void select(int pos)
virtual void keystroke(const Event &)
virtual void drag(const Event &)
virtual InputHandler * focus_in()
FieldSEditor(const String &sample, WidgetKit *, Style *, FieldSEditorAction *=NULL)
virtual void field(const char *)
virtual void ref() const
Definition: resource.cpp:47
virtual void unref() const
Definition: resource.cpp:52
Definition: string.h:34
#define c
static void display(int imenu)
Definition: fmenu.cpp:400
void start()
Definition: hel2mos.cpp:204
#define input(prompt, fmt, var)
Definition: matrix.h:368
#define min(a, b)
Definition: matrix.h:157
#define max(a, b)
Definition: matrix.h:154
#define v
Definition: md1redef.h:4
#define sec
Definition: md1redef.h:13
#define i
Definition: md1redef.h:12
size_t p
virtual void press(const Event &e)
Definition: ocinput.h:29
virtual void drag(const Event &e)
Definition: ocinput.h:32
virtual void release(const Event &e)
Definition: ocinput.h:35
#define g
Definition: passive0.cpp:21
#define e
Definition: passive0.cpp:22
#define left
Definition: rbtqueue.cpp:45
#define right
Definition: rbtqueue.cpp:46
#define print
Definition: redef.h:109
static uint32_t value
Definition: scoprand.cpp:25
#define NULL
Definition: sptree.h:16