1 #include <../../nrnconf.h>
32 #include <Dispatch/dispatcher.h>
33 #include <Dispatch/iocallback.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>
54 #include <OS/string.h>
60 virtual ~FieldStringSEditor();
65 void press(
const Event&);
66 void drag(
const Event&);
67 void release(
const Event&);
68 bool keystroke(
const Event&);
77 void Select(
int left,
int right);
78 void selection(
int& start,
int&
index);
81 virtual void Reconfig();
91 void do_select(
Event&);
92 void do_grab_scroll(
Event&);
93 void do_rate_scroll(
Event&);
96 declareSelectionCallback(FieldStringSEditor)
97 implementSelectionCallback(FieldStringSEditor)
99 FieldStringSEditor::FieldStringSEditor(
ButtonState* bs,
109 start_ = index_ = -1;
112 FieldStringSEditor::~FieldStringSEditor() {
116 void FieldStringSEditor::Select(
int pos) {
117 start_ = index_ = pos;
118 StringEditor::Select(pos);
120 void FieldStringSEditor::Select(
int left,
int right) {
123 StringEditor::Select(left, right);
125 void FieldStringSEditor::selection(
int& start,
int&
index) {
131 const Font* f = output->GetFont();
132 const Color* fg = output->GetFgColor();
136 FieldStringSEditor* e = (FieldStringSEditor*)
this;
137 for (
const char*
s = e->Text(); *
s !=
'\0';
s++) {
139 p->character(f, *
s, w, fg, x, y);
145 const Event* ep = h.event();
146 if (ep !=
NULL && h.left() < a.
right() && h.right() >= a.
left() && h.bottom() < a.
top() &&
148 h.target(depth,
this, 0);
152 void FieldStringSEditor::press(
const Event& event) {
154 display->Draw(output, canvas);
155 switch (event.pointer_button()) {
159 origin_ = display->Left(0, 0);
160 width_ = display->Width();
162 start_ = display->LineIndex(0, e.x);
176 void FieldStringSEditor::drag(
const Event&) {
184 void FieldStringSEditor::release(
const Event& event) {
186 switch (event.pointer_button()) {
193 s->own(
new SelectionCallback(FieldStringSEditor)(
this, &FieldStringSEditor::cut));
198 void FieldStringSEditor::do_select(
Event& e) {
200 origin_ = Math::min(0, origin_ - e.x);
201 }
else if (e.x > xmax) {
202 origin_ = Math::max(xmax - width_, origin_ - (e.x - xmax));
204 display->Scroll(0, origin_, ymax);
205 index_ = display->LineIndex(0, e.x);
206 DoSelect(start_, index_);
209 void FieldStringSEditor::do_grab_scroll(
Event& e) {
210 Window* w = canvas->window();
212 w->cursor(kit_->hand_cursor());
213 int origin = display->Left(0, 0);
214 int width = display->Width();
219 origin = Math::min(0, Math::max(Math::min(0, xmax - width), origin));
220 display->Scroll(0, origin, ymax);
223 }
while (e.middlemouse);
227 void FieldStringSEditor::do_rate_scroll(
Event& e) {
228 Window* w = canvas->window();
233 int origin = display->Left(0, 0);
234 int width = display->Width();
239 origin = Math::min(0, Math::max(Math::min(0, xmax - width), origin));
240 display->Scroll(0, origin, ymax);
247 }
while (e.rightmouse);
251 bool FieldStringSEditor::keystroke(
const Event& e) {
253 return e.mapkey(&
c, 1) != 0 && HandleChar(
c) &&
c ==
'\t';
256 void FieldStringSEditor::cursor_on() {
257 if (canvas !=
NULL) {
258 display->CaretStyle(BarCaret);
262 void FieldStringSEditor::cursor_off() {
263 if (canvas !=
NULL) {
264 display->CaretStyle(NoCaret);
268 void FieldStringSEditor::focus_in() {}
269 void FieldStringSEditor::focus_out() {}
273 int st = Math::min(start_, index_);
274 int i = Math::max(index_, start_);
275 s->put_value(
Text() + st,
i - st);
282 void FieldStringSEditor::Reconfig() {
286 p->SetColors(kit_->foreground(), kit_->background());
287 p->SetFont(kit_->font());
290 StringEditor::Reconfig();
297 virtual ~FieldSButton();
299 virtual void Notify();
306 class FieldSEditorImpl {
311 FieldStringSEditor* editor_;
315 IOHandler* blink_handler_;
319 void blink_cursor(
long,
long);
320 void stop_blinking();
323 declareIOCallback(FieldSEditorImpl)
324 implementIOCallback(FieldSEditorImpl)
331 impl_ =
new FieldSEditorImpl;
333 NullTerminatedString ns(sample);
334 impl_->build(
this, ns.string(), action);
338 FieldSEditorImpl*
i =
impl_;
342 delete i->blink_handler_;
347 FieldSEditorImpl& f = *
impl_;
349 InputHandler::undraw();
353 impl_->editor_->press(e);
357 impl_->editor_->drag(e);
360 impl_->editor_->release(e);
364 FieldSEditorImpl& f = *
impl_;
365 if (f.editor_->keystroke(e)) {
372 FieldSEditorImpl& f = *
impl_;
373 f.blink_cursor(0, 0);
374 f.editor_->focus_in();
375 return InputHandler::focus_in();
379 FieldSEditorImpl& f = *
impl_;
381 f.editor_->cursor_off();
382 f.editor_->focus_out();
383 InputHandler::focus_out();
387 impl_->editor_->Message(str);
391 NullTerminatedString ns(
s);
392 impl_->editor_->Message(ns.string());
396 impl_->editor_->Select(pos);
400 impl_->editor_->Select(l, r);
408 impl_->editor_->Edit();
412 impl_->editor_->Edit(str, left, right);
416 NullTerminatedString ns(str);
417 impl_->editor_->Edit(ns.string(), left, right);
421 impl_->text_ = String(
impl_->editor_->Text());
422 return &
impl_->text_;
429 kit.begin_style(
"FieldEditor");
431 bs_ =
new FieldSButton(e, a);
432 editor_ =
new FieldStringSEditor(bs_, str, kit_,
s);
434 if (
s->value_is_on(
"beveled")) {
436 new Background(LayoutKit::instance()->h_margin(editor_, 2.0), kit.background()));
439 cursor_is_on_ =
false;
440 blink_handler_ =
new IOCallback(FieldSEditorImpl)(
this, &FieldSEditorImpl::blink_cursor);
442 s->find_attribute(
"cursorFlashRate",
sec);
443 flash_rate_ = long(
sec * 1000000);
447 void FieldSEditorImpl::blink_cursor(
long,
long) {
449 editor_->cursor_off();
450 cursor_is_on_ =
false;
452 editor_->cursor_on();
453 cursor_is_on_ =
true;
455 if (flash_rate_ > 10) {
456 Dispatcher::instance().startTimer(0, flash_rate_, blink_handler_);
460 void FieldSEditorImpl::stop_blinking() {
461 Dispatcher::instance().stopTimer(blink_handler_);
462 editor_->cursor_off();
463 cursor_is_on_ =
false;
474 FieldSButton::~FieldSButton() {
484 void FieldSButton::Notify() {
488 if (action_ !=
NULL) {
491 action_->accept(editor_);
495 action_->cancel(editor_);
virtual void cancel(FieldSEditor *)
virtual ~FieldSEditorAction()
virtual void accept(FieldSEditor *)
virtual void release(const Event &)
virtual const String * text() const
virtual void selection(int &start, int &index) const
virtual void press(const Event &)
virtual void 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 unref() const