Dylan Smith : richedit: Implemented triple click selection.

Alexandre Julliard julliard at winehq.org
Tue Jul 8 06:10:48 CDT 2008


Module: wine
Branch: master
Commit: 69cf4e9ac4427db7a8c6136db813246b83fb639f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=69cf4e9ac4427db7a8c6136db813246b83fb639f

Author: Dylan Smith <dylan.ah.smith at gmail.com>
Date:   Mon Jul  7 11:04:02 2008 -0400

richedit: Implemented triple click selection.

---

 dlls/riched20/caret.c   |   26 ++++++++++++++++++---
 dlls/riched20/editor.c  |   56 +++++++++++++++++++++++++++++++++++++++++++++-
 dlls/riched20/editstr.h |    3 +-
 3 files changed, 78 insertions(+), 7 deletions(-)

diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c
index 0be4cf5..b2dbd97 100644
--- a/dlls/riched20/caret.c
+++ b/dlls/riched20/caret.c
@@ -787,6 +787,14 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
       editor->pCursors[1].nOffset = 0;
       break;
     }
+    case stDocument:
+      /* Select everything with cursor anchored from the start of the text */
+      editor->nSelectionType = stDocument;
+      editor->pCursors[1].pRun = ME_FindItemFwd(editor->pBuffer->pFirst, diRun);
+      editor->pCursors[1].nOffset = 0;
+      editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
+      editor->pCursors[0].nOffset = 0;
+      break;
     default: assert(0);
   }
   /* Store the anchor positions for extending the selection. */
@@ -925,7 +933,7 @@ static void ME_ExtendAnchorSelection(ME_TextEditor *editor)
 {
   ME_Cursor tmp_cursor;
   int curOfs, anchorStartOfs, anchorEndOfs;
-  if (editor->nSelectionType == stPosition)
+  if (editor->nSelectionType == stPosition || editor->nSelectionType == stDocument)
       return;
   curOfs = ME_GetCursorOfs(editor, 0);
   anchorStartOfs = ME_GetCursorOfs(editor, 2);
@@ -992,10 +1000,16 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum)
     if (clickNum > 1)
     {
       editor->pCursors[1] = editor->pCursors[0];
-      if (x >= editor->selofs)
+      if (is_shift) {
+          if (x >= editor->selofs)
+              ME_SelectByType(editor, stWord);
+          else
+              ME_SelectByType(editor, stParagraph);
+      } else if (clickNum % 2 == 0) {
           ME_SelectByType(editor, stWord);
-      else
+      } else {
           ME_SelectByType(editor, stParagraph);
+      }
     }
     else if (!is_shift)
     {
@@ -1016,8 +1030,10 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum)
   {
     if (clickNum < 2) {
         ME_SelectByType(editor, stLine);
-    } else {
+    } else if (clickNum % 2 == 0 || is_shift) {
         ME_SelectByType(editor, stParagraph);
+    } else {
+        ME_SelectByType(editor, stDocument);
     }
   }
   ME_InvalidateSelection(editor);
@@ -1032,6 +1048,8 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y)
 {
   ME_Cursor tmp_cursor;
   
+  if (editor->nSelectionType == stDocument)
+      return;
   y += ME_GetYScrollPos(editor);
 
   tmp_cursor = editor->pCursors[0];
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index de89022..e763090 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -1612,6 +1612,57 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
   return FALSE;
 }
 
+/* Process the message and calculate the new click count.
+ *
+ * returns: The click count if it is mouse down event, else returns 0. */
+static int ME_CalculateClickCount(HWND hWnd, UINT msg, WPARAM wParam,
+                                  LPARAM lParam)
+{
+    static int clickNum = 0;
+    if (msg < WM_MOUSEFIRST || msg > WM_MOUSELAST)
+        return 0;
+
+    if ((msg == WM_LBUTTONDBLCLK) ||
+        (msg == WM_RBUTTONDBLCLK) ||
+        (msg == WM_MBUTTONDBLCLK) ||
+        (msg == WM_XBUTTONDBLCLK))
+    {
+        msg -= (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
+    }
+
+    if ((msg == WM_LBUTTONDOWN) ||
+        (msg == WM_RBUTTONDOWN) ||
+        (msg == WM_MBUTTONDOWN) ||
+        (msg == WM_XBUTTONDOWN))
+    {
+        static MSG prevClickMsg;
+        MSG clickMsg;
+        clickMsg.hwnd = hWnd;
+        clickMsg.message = msg;
+        clickMsg.wParam = wParam;
+        clickMsg.lParam = lParam;
+        clickMsg.time = GetMessageTime();
+        clickMsg.pt.x = LOWORD(lParam);
+        clickMsg.pt.x = HIWORD(lParam);
+        if ((clickNum != 0) &&
+            (clickMsg.message == prevClickMsg.message) &&
+            (clickMsg.hwnd == prevClickMsg.hwnd) &&
+            (clickMsg.wParam == prevClickMsg.wParam) &&
+            (clickMsg.time - prevClickMsg.time < GetDoubleClickTime()) &&
+            (abs(clickMsg.pt.x - prevClickMsg.pt.x) < GetSystemMetrics(SM_CXDOUBLECLK)/2) &&
+            (abs(clickMsg.pt.y - prevClickMsg.pt.y) < GetSystemMetrics(SM_CYDOUBLECLK)/2))
+        {
+            clickNum++;
+        } else {
+            clickNum = 1;
+        }
+        prevClickMsg = clickMsg;
+    } else {
+        return 0;
+    }
+    return clickNum;
+}
+
 static BOOL ME_SetCursor(ME_TextEditor *editor, int x)
 {
   if ((GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_SELECTIONBAR) &&
@@ -2979,14 +3030,13 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   case WM_LBUTTONDBLCLK:
   case WM_LBUTTONDOWN:
   {
-    int clickNum = (msg == WM_LBUTTONDBLCLK) ? 2 : 1;
     ME_CommitUndo(editor); /* End coalesced undos for typed characters */
     if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
         !ME_FilterEvent(editor, msg, &wParam, &lParam))
       return 0;
     SetFocus(hWnd);
     ME_LButtonDown(editor, (short)LOWORD(lParam), (short)HIWORD(lParam),
-                   clickNum);
+                   ME_CalculateClickCount(hWnd, msg, wParam, lParam));
     SetCapture(hWnd);
     ME_LinkNotify(editor,msg,wParam,lParam);
     if (!ME_SetCursor(editor, LOWORD(lParam))) goto do_default;
@@ -3004,6 +3054,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   case WM_LBUTTONUP:
     if (GetCapture() == hWnd)
       ReleaseCapture();
+    if (editor->nSelectionType == stDocument)
+      editor->nSelectionType = stPosition;
     if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
         !ME_FilterEvent(editor, msg, &wParam, &lParam))
       return 0;
diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h
index 40e1b70..98769e4 100644
--- a/dlls/riched20/editstr.h
+++ b/dlls/riched20/editstr.h
@@ -248,7 +248,8 @@ typedef enum {
   stPosition = 0,
   stWord,
   stLine,
-  stParagraph
+  stParagraph,
+  stDocument
 } ME_SelectionType;
 
 typedef struct tagME_FontTableItem {




More information about the wine-cvs mailing list