gui.widgets.LineEdit = { new: func(parent, style, cfg) { var m = gui.Widget.new(gui.widgets.LineEdit); m._cfg = Config.new(cfg); m._focus_policy = m.StrongFocus; m._setView( style.createWidget(parent, "line-edit", m._cfg) ); m.setLayoutMinimumSize([28, 16]); m.setLayoutSizeHint([150, 28]); m._text = ""; m._max_length = 32767; m._cursor = 0; m._selection_start = 0; m._selection_end = 0; return m; }, setText: func(text) { if (text == nil) { me.clear(); return me; } me._text = utf8.substr(text, 0, me._max_length); me._cursor = utf8.size(me._text); me._selection_start = me._cursor; me._selection_end = me._cursor; if( me._view != nil ) me._view.setText(me, me._text); return me; }, clear: func { me._text = ""; me._cursor = 0; me._selection_start = 0; me._selection_end = 0; if( me._view != nil ) me._view.setText(me, ""); }, text: func() { return me._text; }, setMaxLength: func(len) { me._max_length = len; if( utf8.size(me._text) <= len ) return me; me._text = utf8.substr(me._text, 0, me._max_length); me.moveCursor(me._cursor); return me; }, moveCursor: func(pos, mark = 0) { var len = utf8.size(me._text); me._cursor = math.max(0, math.min(pos, len)); me._selection_start = me._cursor; me._selection_end = me._cursor; me._onStateChange(); return me; }, home: func() { me.moveCursor(0); }, end: func() { me.moveCursor(utf8.size(me._text)); }, # Insert given text after cursor (and first remove selection if set) insert: func(text) { var after = utf8.substr(me._text, me._selection_end); me._text = utf8.substr(me._text, 0, me._selection_start); # Replace selected text, insert new text and place cursor after inserted # text var remaining = me._max_length - me._selection_start - utf8.size(after); if( remaining != 0 ) me._text ~= utf8.substr(text, 0, remaining); me._cursor = utf8.size(me._text); me._selection_start = me._cursor; me._selection_end = me._cursor; me._text ~= after; if( me._view != nil ) me._view.setText(me, me._text); return me; }, paste: func(mode = nil) { me.insert(clipboard.getText(mode != nil ? mode : clipboard.CLIPBOARD)); }, # Remove selected text removeSelection: func() { if( me._selection_start == me._selection_end ) return me; me._text = utf8.substr(me._text, 0, me._selection_start) ~ utf8.substr(me._text, me._selection_end); me._cursor = me._selection_start; me._selection_end = me._selection_start; if( me._view != nil ) me._view.setText(me, me._text); return me; }, # Remove selection or if nothing is selected the character before the cursor backspace: func() { if( me._selection_start == me._selection_end ) { if( me._selection_start == 0 ) # Before first character... return me; me._selection_start -= 1; } me.removeSelection(); return me; }, # Remove selection or if nothing is selected the character after the cursor del: func() { if( me._selection_start == me._selection_end ) { if( me._selection_end == utf8.size(me._text) ) # After last character... return me; me._selection_end += 1; } me.removeSelection(); return me; }, # protected: _setView: func(view) { call(gui.Widget._setView, [view], me); var el = view._root; el.addEventListener("keypress", func (e) me.insert(e.key)); el.addEventListener("keydown", func (e) { if( me._view == nil ) return; if( e.key == "Enter" ) me._trigger("editingFinished", {text: me.text()}); # TODO validator/etc. else if( e.key == "Backspace" ) me.backspace(); else if( e.key == "Delete" ) me.del(); else if( e.key == "Left" ) me.moveCursor(me._cursor - 1); else if( e.key == "Right") me.moveCursor(me._cursor + 1); else if( e.key == "Home" ) me.home(); else if( e.key == "End" ) me.end(); else if( e.keyCode == `v` and e.ctrlKey ) me.paste(); }); } };