From 9fd6a1e513b1ef3461ca94b465102d1d7f201cff Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Tue, 10 Feb 2015 17:57:33 +0300 Subject: [PATCH] select word by double click in editors --- dlanguilib.visualdproj | 6 ++-- examples/example1/example1.visualdproj | 6 ++-- examples/tetris/tetris.visualdproj | 4 +-- src/dlangui/core/editable.d | 39 +++++++++++++++++++++++++ src/dlangui/platforms/common/platform.d | 3 +- src/dlangui/widgets/editors.d | 21 ++++++++++++- 6 files changed, 69 insertions(+), 10 deletions(-) diff --git a/dlanguilib.visualdproj b/dlanguilib.visualdproj index 366bd478..63ecfed8 100644 --- a/dlanguilib.visualdproj +++ b/dlanguilib.visualdproj @@ -141,8 +141,8 @@ 0 0 $(DMDInstallDir)windows\bin\dmd.exe - 3rdparty ../DerelictGL3/source $(SolutionDir)/../dlib - + 3rdparty ../DerelictGL3/source ../DerelictUtil/source ../DerelictFT/source ../de_image/source/interfaces ../de_image/source/png $(SolutionDir)/../dlib + $(SolutionDir)/views $(SolutionDir)/views/res $(SolutionDir)/views/res/i18n $(SolutionDir)/views/res/mdpi $(ConfigurationName) $(OutDir) @@ -160,7 +160,7 @@ 0 0 - Unicode + EmbedStandardResources Unicode USE_FREETYPE 0 0 0 diff --git a/examples/example1/example1.visualdproj b/examples/example1/example1.visualdproj index a0510bd7..f88ab696 100644 --- a/examples/example1/example1.visualdproj +++ b/examples/example1/example1.visualdproj @@ -141,8 +141,8 @@ 0 0 $(DMDInstallDir)windows\bin\dmd.exe - ../../src ../../3rdparty ../../3rdparty/libpng/source $(SolutionDir)/../dlib - + $(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/3rdparty/libpng/source $(SolutionDir)/../DerelictGL3/source $(SolutionDir)/../DerelictUtil/source $(SolutionDir)/../DerelictFT/source $(SolutionDir)/../DerelictSDL2/source $(SolutionDir)/../de_image/source/interfaces $(SolutionDir)/../de_image/source/png $(SolutionDir)/../dlib + views views/res views/res/i18n views/res/mdpi $(ConfigurationName) $(OutDir) @@ -160,7 +160,7 @@ 0 0 - Unicode + Unicode USE_FREETYPE 0 0 0 diff --git a/examples/tetris/tetris.visualdproj b/examples/tetris/tetris.visualdproj index 17dfdc14..5f803e3d 100644 --- a/examples/tetris/tetris.visualdproj +++ b/examples/tetris/tetris.visualdproj @@ -141,8 +141,8 @@ 0 0 $(DMDInstallDir)windows\bin\dmd.exe - ../../src ../../3rdparty ../../3rdparty/libpng/source $(SolutionDir)/../dlib - + $(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/3rdparty/libpng/source $(SolutionDir)/../DerelictGL3/source $(SolutionDir)/../DerelictUtil/source $(SolutionDir)/../DerelictFT/source $(SolutionDir)/../DerelictSDL2/source $(SolutionDir)/../de_image/source/interfaces $(SolutionDir)/../de_image/source/png $(SolutionDir)/../dlib + views views/res views/mdpi views/i18n $(ConfigurationName) $(OutDir) diff --git a/src/dlangui/core/editable.d b/src/dlangui/core/editable.d index e4eaf6ff..c1af6f02 100644 --- a/src/dlangui/core/editable.d +++ b/src/dlangui/core/editable.d @@ -577,6 +577,45 @@ class EditableContent { performOperation(op, this); } + static bool isAlphaForWordSelection(dchar ch) { + return ch == '_' || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); + } + + /// get word bounds by position + TextRange wordBounds(TextPosition pos) { + TextRange res; + res.start = pos; + res.end = pos; + if (pos.line < 0 || pos.line >= _lines.length) + return res; + dstring s = line(pos.line); + int p = pos.pos; + if (p < 0 || p > s.length) + return res; + dchar leftChar = p > 0 ? s[p - 1] : 0; + dchar rightChar = p < s.length - 1 ? s[p + 1] : 0; + dchar centerChar = p < s.length ? s[p] : 0; + if (isAlphaForWordSelection(centerChar)) { + // ok + } else if (isAlphaForWordSelection(leftChar)) { + p--; + } else if (isAlphaForWordSelection(rightChar)) { + p++; + } else { + return res; + } + int start = p; + int end = p; + while (start > 0 && isAlphaForWordSelection(s[start - 1])) + start--; + while (end + 1 < s.length && isAlphaForWordSelection(s[end + 1])) + end++; + end++; + res.start.pos = start; + res.end.pos = end; + return res; + } + /// call listener to say that whole content is replaced e.g. by loading from file void notifyContentReplaced() { clearEditMarks(); diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index 8f54a6fe..46e5b89c 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -1213,8 +1213,9 @@ mixin template APP_ENTRY_POINT() { char* lpCmdLine, int nCmdShow) { try { - return DLANGUIWinMain(hInstance, hPrevInstance, + int res = DLANGUIWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); + return res; } catch (Exception e) { Log.e("Exception: ", e); return 1; diff --git a/src/dlangui/widgets/editors.d b/src/dlangui/widgets/editors.d index d7ca6868..daa94880 100644 --- a/src/dlangui/widgets/editors.d +++ b/src/dlangui/widgets/editors.d @@ -851,6 +851,21 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction requestActionsUpdate(); } + protected void selectWordByMouse(int x, int y) { + TextPosition oldCaretPos = _caretPos; + TextPosition newPos = clientToTextPos(Point(x,y)); + TextRange r = content.wordBounds(newPos); + if (r.start < r.end) { + _selectionRange = r; + _caretPos = r.end; + invalidate(); + requestActionsUpdate(); + } else { + _caretPos = newPos; + updateSelectionAfterCursorMovement(oldCaretPos, false); + } + } + protected void updateCaretPositionByMouse(int x, int y, bool selecting) { TextPosition oldCaretPos = _caretPos; TextPosition newPos = clientToTextPos(Point(x,y)); @@ -1362,7 +1377,11 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) { setFocus(); startCaretBlinking(); - updateCaretPositionByMouse(event.x - _clientRect.left, event.y - _clientRect.top, false); + if (event.doubleClick) { + selectWordByMouse(event.x - _clientRect.left, event.y - _clientRect.top); + } else { + updateCaretPositionByMouse(event.x - _clientRect.left, event.y - _clientRect.top, false); + } invalidate(); return true; }