mirror of https://github.com/buggins/dlangui.git
support multiple views for same EditableContent
This commit is contained in:
parent
ec31e0838c
commit
8b0570b22e
|
@ -258,8 +258,9 @@ class UndoBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Editable Content change listener
|
||||
interface EditableContentListener {
|
||||
bool onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter);
|
||||
bool onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter, Object source);
|
||||
}
|
||||
|
||||
/// editable plain text (singleline/multiline)
|
||||
|
@ -332,8 +333,8 @@ class EditableContent {
|
|||
return m;
|
||||
}
|
||||
|
||||
bool handleContentChange(EditOperation op, ref TextRange rangeBefore, ref TextRange rangeAfter) {
|
||||
return contentChangeListeners(this, op, rangeBefore, rangeAfter);
|
||||
bool handleContentChange(EditOperation op, ref TextRange rangeBefore, ref TextRange rangeAfter, Object source) {
|
||||
return contentChangeListeners(this, op, rangeBefore, rangeAfter, source);
|
||||
}
|
||||
|
||||
/// return text for specified range
|
||||
|
@ -415,7 +416,7 @@ class EditableContent {
|
|||
}
|
||||
}
|
||||
|
||||
bool performOperation(EditOperation op) {
|
||||
bool performOperation(EditOperation op, Object source) {
|
||||
if (op.action == EditAction.Replace) {
|
||||
TextRange rangeBefore = op.range;
|
||||
dstring[] oldcontent = rangeText(rangeBefore);
|
||||
|
@ -435,7 +436,7 @@ class EditableContent {
|
|||
op.newRange = rangeAfter;
|
||||
op.oldContent = oldcontent;
|
||||
replaceRange(rangeBefore, rangeAfter, newcontent);
|
||||
handleContentChange(op, rangeBefore, rangeAfter);
|
||||
handleContentChange(op, rangeBefore, rangeAfter, source);
|
||||
_undoBuffer.saveForUndo(op);
|
||||
return true;
|
||||
}
|
||||
|
@ -461,7 +462,7 @@ class EditableContent {
|
|||
TextRange rangeAfter = op.range;
|
||||
//Log.d("Undoing op rangeBefore=", rangeBefore, " contentBefore=`", oldcontent, "` rangeAfter=", rangeAfter, " contentAfter=`", newcontent, "`");
|
||||
replaceRange(rangeBefore, rangeAfter, newcontent);
|
||||
handleContentChange(op, rangeBefore, rangeAfter);
|
||||
handleContentChange(op, rangeBefore, rangeAfter, this);
|
||||
return true;
|
||||
}
|
||||
/// redoes last undone change
|
||||
|
@ -475,7 +476,7 @@ class EditableContent {
|
|||
TextRange rangeAfter = op.newRange;
|
||||
//Log.d("Redoing op rangeBefore=", rangeBefore, " contentBefore=`", oldcontent, "` rangeAfter=", rangeAfter, " contentAfter=`", newcontent, "`");
|
||||
replaceRange(rangeBefore, rangeAfter, newcontent);
|
||||
handleContentChange(op, rangeBefore, rangeAfter);
|
||||
handleContentChange(op, rangeBefore, rangeAfter, this);
|
||||
return true;
|
||||
}
|
||||
/// clear undo/redp history
|
||||
|
@ -594,6 +595,11 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
|
||||
protected bool _replaceMode;
|
||||
|
||||
// TODO: move to styles
|
||||
protected uint _selectionColorFocused = 0xB060A0FF;
|
||||
protected uint _selectionColorNormal = 0xD060A0FF;
|
||||
|
||||
|
||||
this(string ID) {
|
||||
super(ID);
|
||||
focusable = true;
|
||||
|
@ -760,12 +766,17 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
protected void updateMaxLineWidth() {
|
||||
}
|
||||
|
||||
override bool onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter) {
|
||||
override bool onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter, Object source) {
|
||||
updateMaxLineWidth();
|
||||
measureVisibleText();
|
||||
_caretPos = rangeAfter.end;
|
||||
_selectionRange.start = _caretPos;
|
||||
_selectionRange.end = _caretPos;
|
||||
if (source is this) {
|
||||
_caretPos = rangeAfter.end;
|
||||
_selectionRange.start = _caretPos;
|
||||
_selectionRange.end = _caretPos;
|
||||
} else {
|
||||
correctCaretPos();
|
||||
// TODO: do something better (e.g. take into account ranges when correcting)
|
||||
}
|
||||
ensureCaretVisible();
|
||||
invalidate();
|
||||
return true;
|
||||
|
@ -1014,7 +1025,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
if (!_selectionRange.empty) {
|
||||
// clear selection
|
||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, [""d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
ensureCaretVisible();
|
||||
return true;
|
||||
}
|
||||
|
@ -1024,7 +1035,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
TextRange range = TextRange(_caretPos, _caretPos);
|
||||
range.start.pos--;
|
||||
EditOperation op = new EditOperation(EditAction.Replace, range, [""d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
} else if (_caretPos.line > 0) {
|
||||
// merge with previous line
|
||||
TextRange range = TextRange(_caretPos, _caretPos);
|
||||
|
@ -1032,7 +1043,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
dstring prevLine = _content[range.start.line];
|
||||
range.start.pos = cast(int)prevLine.length;
|
||||
EditOperation op = new EditOperation(EditAction.Replace, range, [""d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
}
|
||||
return true;
|
||||
case EditorActions.DelNextChar:
|
||||
|
@ -1040,7 +1051,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
return true;
|
||||
if (!_selectionRange.empty) {
|
||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, [""d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
return true;
|
||||
}
|
||||
correctCaretPos();
|
||||
|
@ -1049,14 +1060,14 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
TextRange range = TextRange(_caretPos, _caretPos);
|
||||
range.end.pos++;
|
||||
EditOperation op = new EditOperation(EditAction.Replace, range, [""d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
} else if (_caretPos.line < _content.length - 1) {
|
||||
// merge with next line
|
||||
TextRange range = TextRange(_caretPos, _caretPos);
|
||||
range.end.line++;
|
||||
range.end.pos = 0;
|
||||
EditOperation op = new EditOperation(EditAction.Replace, range, [""d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
}
|
||||
return true;
|
||||
case EditorActions.Copy:
|
||||
|
@ -1072,7 +1083,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
if (readOnly)
|
||||
return true;
|
||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, [""d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
}
|
||||
return true;
|
||||
case EditorActions.Paste:
|
||||
|
@ -1087,7 +1098,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
lines = [replaceEolsWithSpaces(selectionText)];
|
||||
}
|
||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, lines);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
}
|
||||
return true;
|
||||
case EditorActions.Undo:
|
||||
|
@ -1112,11 +1123,11 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
if (_useSpacesForTabs) {
|
||||
// insert one or more spaces to
|
||||
EditOperation op = new EditOperation(EditAction.Replace, TextRange(_caretPos, _caretPos), [spacesForTab(_caretPos.pos)]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
} else {
|
||||
// just insert tab character
|
||||
EditOperation op = new EditOperation(EditAction.Replace, TextRange(_caretPos, _caretPos), ["\t"d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
}
|
||||
} else {
|
||||
if (wholeLinesSelected()) {
|
||||
|
@ -1127,11 +1138,11 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
if (_useSpacesForTabs) {
|
||||
// insert one or more spaces to
|
||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, [spacesForTab(_selectionRange.start.pos)]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
} else {
|
||||
// just insert tab character
|
||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, ["\t"d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1147,7 +1158,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
TextRange r = spaceBefore(_caretPos);
|
||||
if (!r.empty) {
|
||||
EditOperation op = new EditOperation(EditAction.Replace, r, [""d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
}
|
||||
} else {
|
||||
if (wholeLinesSelected()) {
|
||||
|
@ -1161,7 +1172,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
TextRange saveRange = _selectionRange;
|
||||
TextPosition saveCursor = _caretPos;
|
||||
EditOperation op = new EditOperation(EditAction.Replace, r, [""d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
if (saveCursor.line == saveRange.start.line)
|
||||
saveCursor.pos -= nchars;
|
||||
if (saveRange.end.line == saveRange.start.line)
|
||||
|
@ -1264,7 +1275,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
TextRange saveRange = _selectionRange;
|
||||
TextPosition saveCursor = _caretPos;
|
||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, newContent);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
_selectionRange = saveRange;
|
||||
_caretPos = saveCursor;
|
||||
ensureCaretVisible();
|
||||
|
@ -1292,10 +1303,10 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
|||
TextRange range = _selectionRange;
|
||||
range.end.pos += cast(int)event.text.length;
|
||||
EditOperation op = new EditOperation(EditAction.Replace, range, [event.text]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
} else {
|
||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, [event.text]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -1459,6 +1470,7 @@ class EditLine : EditWidgetBase {
|
|||
applyPadding(_clientRc);
|
||||
}
|
||||
|
||||
|
||||
/// override to custom highlight of line background
|
||||
protected void drawLineBackground(DrawBuf buf, Rect lineRect, Rect visibleRect) {
|
||||
if (!_selectionRange.empty) {
|
||||
|
@ -1472,7 +1484,7 @@ class EditLine : EditWidgetBase {
|
|||
rc.right = endx;
|
||||
if (!rc.empty) {
|
||||
// draw selection rect for line
|
||||
buf.fillRect(rc, 0xB060A0FF);
|
||||
buf.fillRect(rc, focused ? _selectionColorFocused : _selectionColorNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1687,14 +1699,14 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
correctCaretPos();
|
||||
_caretPos.pos = 0;
|
||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, [""d, ""d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
}
|
||||
return true;
|
||||
case EditorActions.InsertNewLine:
|
||||
{
|
||||
correctCaretPos();
|
||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, [""d, ""d]);
|
||||
_content.performOperation(op);
|
||||
_content.performOperation(op, this);
|
||||
}
|
||||
return true;
|
||||
case EditorActions.Up:
|
||||
|
@ -1852,7 +1864,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
rc.right = endx;
|
||||
if (!rc.empty) {
|
||||
// draw selection rect for line
|
||||
buf.fillRect(rc, 0xB060A0FF);
|
||||
buf.fillRect(rc, focused ? _selectionColorFocused : _selectionColorNormal);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue