mirror of https://github.com/buggins/dlangui.git
can enter text into editline
This commit is contained in:
parent
8e4897aa9b
commit
083241ce3f
|
@ -180,6 +180,10 @@ struct Signal(T1) if (is(T1 == interface) && __traits(allMembers, T1).length ==
|
||||||
if (listener !is null)
|
if (listener !is null)
|
||||||
_listeners ~= listener;
|
_listeners ~= listener;
|
||||||
}
|
}
|
||||||
|
/// replace all previously assigned listeners with new one (if null passed, remove all listeners)
|
||||||
|
final void opAssign(T1 listener) {
|
||||||
|
opAssign(&__traits(getMember, listener, __traits(allMembers, T1)[0]));
|
||||||
|
}
|
||||||
/// call all listeners; for signals having non-void return type, stop iterating when first return value is nonzero
|
/// call all listeners; for signals having non-void return type, stop iterating when first return value is nonzero
|
||||||
static if (is (return_t == void)) {
|
static if (is (return_t == void)) {
|
||||||
// call all listeners
|
// call all listeners
|
||||||
|
|
|
@ -748,7 +748,6 @@ LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
int repeatCount = lParam & 0xFFFF;
|
int repeatCount = lParam & 0xFFFF;
|
||||||
if (window.onKey(message == WM_KEYDOWN ? KeyAction.KeyDown : KeyAction.KeyUp, wParam, repeatCount))
|
if (window.onKey(message == WM_KEYDOWN ? KeyAction.KeyDown : KeyAction.KeyUp, wParam, repeatCount))
|
||||||
return 0; // processed
|
return 0; // processed
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WM_UNICHAR:
|
case WM_UNICHAR:
|
||||||
|
@ -759,6 +758,14 @@ LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case WM_CHAR:
|
||||||
|
if (window !is null) {
|
||||||
|
int repeatCount = lParam & 0xFFFF;
|
||||||
|
if (window.onKey(KeyAction.Text, wParam, repeatCount, wParam == UNICODE_NOCHAR ? 0 : wParam))
|
||||||
|
return 1; // processed
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case WM_GETMINMAXINFO:
|
case WM_GETMINMAXINFO:
|
||||||
case WM_NCCREATE:
|
case WM_NCCREATE:
|
||||||
case WM_NCCALCSIZE:
|
case WM_NCCALCSIZE:
|
||||||
|
|
|
@ -76,15 +76,38 @@ enum EditAction {
|
||||||
/// edit operation details for EditableContent
|
/// edit operation details for EditableContent
|
||||||
class EditOperation {
|
class EditOperation {
|
||||||
/// action performed
|
/// action performed
|
||||||
EditAction action;
|
protected EditAction _action;
|
||||||
|
@property EditAction action() { return _action; }
|
||||||
/// range
|
/// range
|
||||||
TextRange range;
|
protected TextRange _range;
|
||||||
|
@property ref TextRange range() { return _range; }
|
||||||
/// new content for range (if required for this action)
|
/// new content for range (if required for this action)
|
||||||
dstring[] content;
|
protected dstring[] _content;
|
||||||
|
@property ref dstring[] content() { return _content; }
|
||||||
|
|
||||||
|
this(EditAction action) {
|
||||||
|
_action = action;
|
||||||
|
}
|
||||||
|
this(EditAction action, TextPosition pos, dstring text) {
|
||||||
|
this(action, TextRange(pos, pos), text);
|
||||||
|
}
|
||||||
|
this(EditAction action, TextRange range, dstring text) {
|
||||||
|
_action = action;
|
||||||
|
_range = range;
|
||||||
|
_content.length = 1;
|
||||||
|
_content[0] = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EditableContentListener {
|
||||||
|
bool onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// editable plain text (multiline)
|
/// editable plain text (multiline)
|
||||||
class EditableContent {
|
class EditableContent {
|
||||||
|
/// listeners for edit operations
|
||||||
|
Signal!EditableContentListener contentChangeListeners;
|
||||||
|
|
||||||
this(bool multiline) {
|
this(bool multiline) {
|
||||||
_multiline = multiline;
|
_multiline = multiline;
|
||||||
_lines.length = 1; // initial state: single empty line
|
_lines.length = 1; // initial state: single empty line
|
||||||
|
@ -121,6 +144,31 @@ class EditableContent {
|
||||||
dstring line(int index) {
|
dstring line(int index) {
|
||||||
return _lines[index];
|
return _lines[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool handleContentChange(EditOperation op, ref TextRange rangeBefore, ref TextRange rangeAfter) {
|
||||||
|
return contentChangeListeners(this, op, rangeBefore, rangeAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool performOperation(EditOperation op) {
|
||||||
|
if (op.action == EditAction.Insert) {
|
||||||
|
// TODO: multiline
|
||||||
|
TextPosition pos = op.range.start;
|
||||||
|
TextRange rangeBefore = TextRange(pos, pos);
|
||||||
|
dchar[] buf;
|
||||||
|
dstring srcline = _lines[pos.line];
|
||||||
|
dstring newline = op.content[0];
|
||||||
|
buf ~= srcline[0 .. pos.pos];
|
||||||
|
buf ~= newline;
|
||||||
|
buf ~= srcline[pos.pos .. $];
|
||||||
|
_lines[pos.line] = cast(dstring)buf;
|
||||||
|
TextPosition newPos = pos;
|
||||||
|
newPos.pos += newline.length;
|
||||||
|
TextRange rangeAfter = TextRange(pos, newPos);
|
||||||
|
handleContentChange(op, rangeBefore, rangeAfter);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum EditorActions {
|
enum EditorActions {
|
||||||
|
@ -140,14 +188,21 @@ enum EditorActions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// single line editor
|
/// single line editor
|
||||||
class EditLine : Widget {
|
class EditLine : Widget, EditableContentListener {
|
||||||
protected EditableContent _content;
|
protected EditableContent _content;
|
||||||
protected Rect _clientRc;
|
protected Rect _clientRc;
|
||||||
|
|
||||||
|
override bool onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter) {
|
||||||
|
measureText();
|
||||||
|
_caretPos = rangeAfter.end;
|
||||||
|
invalidate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
this(string ID, dstring initialContent = null) {
|
this(string ID, dstring initialContent = null) {
|
||||||
super(ID);
|
super(ID);
|
||||||
_content = new EditableContent(false);
|
_content = new EditableContent(false);
|
||||||
|
_content.contentChangeListeners = this;
|
||||||
styleId = "EDIT_LINE";
|
styleId = "EDIT_LINE";
|
||||||
focusable = true;
|
focusable = true;
|
||||||
text = initialContent;
|
text = initialContent;
|
||||||
|
@ -295,6 +350,11 @@ class EditLine : Widget {
|
||||||
//switch(event.keyCode) {
|
//switch(event.keyCode) {
|
||||||
//
|
//
|
||||||
//}
|
//}
|
||||||
|
} else if (event.action == KeyAction.Text && event.text.length) {
|
||||||
|
Log.d("text entered: ", event.text);
|
||||||
|
EditOperation op = new EditOperation(EditAction.Insert, _caretPos, event.text);
|
||||||
|
_content.performOperation(op);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return super.onKeyEvent(event);
|
return super.onKeyEvent(event);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue