From ec31e0838c4429fad0a76213f967fe883651f056 Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Thu, 24 Apr 2014 15:38:15 +0400 Subject: [PATCH] editor content enhancements --- src/dlangui/core/signals.d | 8 +++++ src/dlangui/widgets/editors.d | 60 +++++++++++++++++++++++++++++------ 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/dlangui/core/signals.d b/src/dlangui/core/signals.d index ec78ccb8..04998159 100644 --- a/src/dlangui/core/signals.d +++ b/src/dlangui/core/signals.d @@ -219,6 +219,14 @@ struct Signal(T1) if (is(T1 == interface) && __traits(allMembers, T1).length == final void disconnect(slot_t listener) { _listeners -= listener; } + /// add listener - as interface member + final void connect(T1 listener) { + connect(&__traits(getMember, listener, __traits(allMembers, T1)[0])); + } + /// add listener - as interface member + final void disconnect(T1 listener) { + disconnect(&__traits(getMember, listener, __traits(allMembers, T1)[0])); + } } /// Multiple listeners; implicitly specified return and parameter types diff --git a/src/dlangui/widgets/editors.d b/src/dlangui/widgets/editors.d index e3d6e59a..acd81ed2 100644 --- a/src/dlangui/widgets/editors.d +++ b/src/dlangui/widgets/editors.d @@ -725,6 +725,38 @@ class EditWidgetBase : WidgetGroup, EditableContentListener { return this; } + /// editor content object + @property EditableContent content() { + return _content; + } + + /// when _ownContent is false, _content should not be destroyed in editor destructor + protected bool _ownContent = true; + /// set content object + @property EditWidgetBase content(EditableContent content) { + if (_content is content) + return this; // not changed + if (_content !is null) { + // disconnect old content + _content.contentChangeListeners.disconnect(this); + if (_ownContent) { + destroy(_content); + } + } + _content = content; + _ownContent = false; + _content.contentChangeListeners.connect(this); + return this; + } + + /// free resources + ~this() { + if (_ownContent) { + destroy(_content); + _content = null; + } + } + protected void updateMaxLineWidth() { } @@ -813,16 +845,26 @@ class EditWidgetBase : WidgetGroup, EditableContentListener { protected void updateScrollbars() { } + /// when position is out of content bounds, fix it to nearest valid position + protected void correctPosition(ref TextPosition position) { + if (position.line >= _content.length) + position.line = _content.length - 1; + if (position.line < 0) + position.line = 0; + dstring currentLine = _content[position.line]; + if (position.pos > currentLine.length) + position.pos = cast(int)currentLine.length; + if (position.pos < 0) + position.pos = 0; + } + + /// when cursor position or selection is out of content bounds, fix it to nearest valid position protected void correctCaretPos() { - if (_caretPos.line >= _content.length) - _caretPos.line = _content.length - 1; - if (_caretPos.line < 0) - _caretPos.line = 0; - dstring currentLine = _content[_caretPos.line]; - if (_caretPos.pos > currentLine.length) - _caretPos.pos = cast(int)currentLine.length; - if (_caretPos.pos < 0) - _caretPos.pos = 0; + correctPosition(_caretPos); + correctPosition(_selectionRange.start); + correctPosition(_selectionRange.end); + if (_selectionRange.empty) + _selectionRange = TextRange(_caretPos, _caretPos); }