aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gtk/ScintillaGTK.cxx13
-rw-r--r--src/Editor.cxx65
-rw-r--r--src/Editor.h5
-rw-r--r--win32/ScintillaWin.cxx61
4 files changed, 91 insertions, 53 deletions
diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx
index 2e0291eeb..a873f1ada 100644
--- a/gtk/ScintillaGTK.cxx
+++ b/gtk/ScintillaGTK.cxx
@@ -156,6 +156,7 @@ private:
virtual void Initialise();
virtual void Finalise();
virtual void DisplayCursor(Window::Cursor c);
+ virtual bool DragThreshold(Point ptStart, Point ptNow);
virtual void StartDrag();
int TargetAsUTF8(char *text);
int EncodedFromUTF8(char *utf8, char *encoded);
@@ -788,8 +789,18 @@ void ScintillaGTK::DisplayCursor(Window::Cursor c) {
wText.SetCursor(static_cast<Window::Cursor>(cursorMode));
}
+bool ScintillaGTK::DragThreshold(Point ptStart, Point ptNow) {
+#if GTK_MAJOR_VERSION < 2
+ return Editor::DragThreshold(ptStart, ptNow);
+#else
+ return gtk_drag_check_threshold(GTK_WIDGET(PWidget(wMain)),
+ ptStart.x, ptStart.y, ptNow.x, ptNow.y);
+#endif
+}
+
void ScintillaGTK::StartDrag() {
dragWasDropped = false;
+ inDragDrop = ddDragging;
static const GtkTargetEntry targets[] = {
{ "UTF8_STRING", 0, TARGET_UTF8_STRING },
{ "STRING", 0, TARGET_STRING },
@@ -2345,7 +2356,6 @@ gboolean ScintillaGTK::DragMotion(GtkWidget *widget, GdkDragContext *context,
gint x, gint y, guint dragtime) {
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
Point npt(x, y);
- sciThis->inDragDrop = true;
sciThis->SetDragPosition(sciThis->PositionFromLocation(npt));
GdkDragAction preferredAction = context->suggested_action;
if (context->actions == static_cast<GdkDragAction>
@@ -2369,6 +2379,7 @@ void ScintillaGTK::DragEnd(GtkWidget *widget, GdkDragContext * /*context*/) {
sciThis->SetEmptySelection(sciThis->posDrag);
sciThis->SetDragPosition(invalidPosition);
//Platform::DebugPrintf("DragEnd %x %d\n", sciThis, sciThis->dragWasDropped);
+ sciThis->inDragDrop = ddNone;
}
gboolean ScintillaGTK::Drop(GtkWidget *widget, GdkDragContext * /*context*/,
diff --git a/src/Editor.cxx b/src/Editor.cxx
index addfedf6e..8a2000090 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -362,7 +362,7 @@ Editor::Editor() {
dwelling = false;
ptMouseLast.x = 0;
ptMouseLast.y = 0;
- inDragDrop = false;
+ inDragDrop = ddNone;
dropWentOutside = false;
posDrag = invalidPosition;
posDrop = invalidPosition;
@@ -5000,6 +5000,13 @@ void Editor::DisplayCursor(Window::Cursor c) {
wMain.SetCursor(static_cast<Window::Cursor>(cursorMode));
}
+bool Editor::DragThreshold(Point ptStart, Point ptNow) {
+ int xMove = ptStart.x - ptNow.x;
+ int yMove = ptStart.y - ptNow.y;
+ int distanceSquared = xMove * xMove + yMove * yMove;
+ return distanceSquared > 16;
+}
+
void Editor::StartDrag() {
// Always handled by subclasses
//SetMouseCapture(true);
@@ -5007,8 +5014,8 @@ void Editor::StartDrag() {
}
void Editor::DropAt(int position, const char *value, bool moving, bool rectangular) {
- //Platform::DebugPrintf("DropAt %d\n", inDragDrop);
- if (inDragDrop)
+ //Platform::DebugPrintf("DropAt %d %d\n", inDragDrop, position);
+ if (inDragDrop == ddDragging)
dropWentOutside = false;
int positionWasInSelection = PositionInSelection(position);
@@ -5016,7 +5023,7 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul
bool positionOnEdgeOfSelection =
(position == SelectionStart()) || (position == SelectionEnd());
- if ((!inDragDrop) || !(0 == positionWasInSelection) ||
+ if ((inDragDrop != ddDragging) || !(0 == positionWasInSelection) ||
(positionOnEdgeOfSelection && !moving)) {
int selStart = SelectionStart();
@@ -5025,7 +5032,7 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul
pdoc->BeginUndoAction();
int positionAfterDeletion = position;
- if (inDragDrop && moving) {
+ if ((inDragDrop == ddDragging) && moving) {
// Remove dragged out text
if (rectangular || selType == selLines) {
SelectionLineIterator lineIterator(this);
@@ -5059,7 +5066,7 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul
}
pdoc->EndUndoAction();
}
- } else if (inDragDrop) {
+ } else if (inDragDrop == ddDragging) {
SetEmptySelection(position);
}
}
@@ -5161,11 +5168,11 @@ void Editor::DwellEnd(bool mouseMoved) {
}
void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
- //Platform::DebugPrintf("Scintilla:ButtonDown %d %d = %d alt=%d\n", curTime, lastClickTime, curTime - lastClickTime, alt);
+ //Platform::DebugPrintf("ButtonDown %d %d = %d alt=%d %d\n", curTime, lastClickTime, curTime - lastClickTime, alt, inDragDrop);
ptMouseLast = pt;
int newPos = PositionFromLocation(pt);
newPos = MovePositionOutsideChar(newPos, currentPos - newPos);
- inDragDrop = false;
+ inDragDrop = ddNone;
moveExtendsSelection = false;
bool processed = NotifyMarginClick(pt, shift, ctrl, alt);
@@ -5250,16 +5257,14 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
NotifyHotSpotClicked(newPos, shift, ctrl, alt);
}
if (!shift) {
- inDragDrop = PointInSelection(pt) && !SelectionEmpty();
+ if (PointInSelection(pt) && !SelectionEmpty())
+ inDragDrop = ddInitial;
+ else
+ inDragDrop = ddNone;
}
- if (inDragDrop) {
- SetMouseCapture(false);
- SetDragPosition(newPos);
- CopySelectionRange(&drag);
- StartDrag();
- } else {
+ SetMouseCapture(true);
+ if (inDragDrop != ddInitial) {
SetDragPosition(invalidPosition);
- SetMouseCapture(true);
if (!shift) {
SetEmptySelection(newPos);
}
@@ -5328,6 +5333,20 @@ void Editor::ButtonMove(Point pt) {
if ((ptMouseLast.x != pt.x) || (ptMouseLast.y != pt.y)) {
DwellEnd(true);
}
+
+ int movePos = PositionFromLocation(pt);
+ movePos = MovePositionOutsideChar(movePos, currentPos - movePos);
+
+ if (inDragDrop == ddInitial) {
+ if (DragThreshold(ptMouseLast, pt)) {
+ SetMouseCapture(false);
+ SetDragPosition(movePos);
+ CopySelectionRange(&drag);
+ StartDrag();
+ }
+ return;
+ }
+
ptMouseLast = pt;
//Platform::DebugPrintf("Move %d %d\n", pt.x, pt.y);
if (HaveMouseCapture()) {
@@ -5339,8 +5358,6 @@ void Editor::ButtonMove(Point pt) {
autoScrollTimer.ticksToWait = autoScrollDelay;
// Adjust selection
- int movePos = PositionFromLocation(pt);
- movePos = MovePositionOutsideChar(movePos, currentPos - movePos);
if (posDrag >= 0) {
SetDragPosition(movePos);
} else {
@@ -5416,7 +5433,13 @@ void Editor::ButtonMove(Point pt) {
}
void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
- //Platform::DebugPrintf("ButtonUp %d\n", HaveMouseCapture());
+ //Platform::DebugPrintf("ButtonUp %d %d\n", HaveMouseCapture(), inDragDrop);
+ int newPos = PositionFromLocation(pt);
+ newPos = MovePositionOutsideChar(newPos, currentPos - newPos);
+ if (inDragDrop == ddInitial) {
+ inDragDrop = ddNone;
+ SetEmptySelection(newPos);
+ }
if (HaveMouseCapture()) {
if (PointInSelMargin(pt)) {
DisplayCursor(Window::cursorReverseArrow);
@@ -5429,7 +5452,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
int newPos = PositionFromLocation(pt);
newPos = MovePositionOutsideChar(newPos, currentPos - newPos);
NotifyIndicatorClick(false, newPos, false, false, false);
- if (inDragDrop) {
+ if (inDragDrop == ddDragging) {
int selStart = SelectionStart();
int selEnd = SelectionEnd();
if (selStart < selEnd) {
@@ -5468,7 +5491,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
if (selType == selStream) {
SetLastXChosen();
}
- inDragDrop = false;
+ inDragDrop = ddNone;
EnsureCaretVisible(false);
}
}
diff --git a/src/Editor.h b/src/Editor.h
index 04bf21958..ef061e46f 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -246,7 +246,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool dwelling;
enum { selChar, selWord, selLine } selectionType;
Point ptMouseLast;
- bool inDragDrop;
+ enum { ddNone, ddInitial, ddDragging } inDragDrop;
bool dropWentOutside;
int posDrag;
int posDrop;
@@ -415,7 +415,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
void ClearSelection();
void ClearAll();
- void ClearDocumentStyle();
+ void ClearDocumentStyle();
void Cut();
void PasteRectangular(int pos, const char *ptr, int len);
virtual void Copy() = 0;
@@ -489,6 +489,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void CopyText(int length, const char *text);
void SetDragPosition(int newPos);
virtual void DisplayCursor(Window::Cursor c);
+ virtual bool DragThreshold(Point ptStart, Point ptNow);
virtual void StartDrag();
void DropAt(int position, const char *value, bool moving, bool rectangular);
/** PositionInSelection returns 0 if position in selection, -1 if position before selection, and 1 if after.
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx
index 62d87fd9d..6d7f1268d 100644
--- a/win32/ScintillaWin.cxx
+++ b/win32/ScintillaWin.cxx
@@ -183,6 +183,7 @@ class ScintillaWin :
enum { invalidTimerID, standardTimerID, idleTimerID };
+ virtual bool DragThreshold(Point ptStart, Point ptNow);
virtual void StartDrag();
sptr_t WndPaint(uptr_t wParam);
sptr_t HandleComposition(uptr_t wParam, sptr_t lParam);
@@ -224,6 +225,7 @@ class ScintillaWin :
void FullPaint();
void FullPaintDC(HDC dc);
bool IsCompatibleDC(HDC dc);
+ DWORD EffectFromState(DWORD grfKeyState);
virtual int SetScrollInfo(int nBar, LPCSCROLLINFO lpsi, BOOL bRedraw);
virtual bool GetScrollInfo(int nBar, LPSCROLLINFO lpsi);
@@ -335,7 +337,15 @@ HWND ScintillaWin::MainHWND() {
return reinterpret_cast<HWND>(wMain.GetID());
}
+bool ScintillaWin::DragThreshold(Point ptStart, Point ptNow) {
+ int xMove = abs(ptStart.x - ptNow.x);
+ int yMove = abs(ptStart.y - ptNow.y);
+ return (xMove > ::GetSystemMetrics(SM_CXDRAG)) ||
+ (yMove > ::GetSystemMetrics(SM_CYDRAG));
+}
+
void ScintillaWin::StartDrag() {
+ inDragDrop = ddDragging;
DWORD dwEffect = 0;
dropWentOutside = true;
IDataObject *pDataObject = reinterpret_cast<IDataObject *>(&dob);
@@ -352,7 +362,7 @@ void ScintillaWin::StartDrag() {
ClearSelection();
}
}
- inDragDrop = false;
+ inDragDrop = ddNone;
SetDragPosition(invalidPosition);
}
@@ -696,7 +706,7 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
case WM_SETCURSOR:
if (LoWord(lParam) == HTCLIENT) {
- if (inDragDrop) {
+ if (inDragDrop == ddDragging) {
DisplayCursor(Window::cursorUp);
} else {
// Display regular (drag) cursor over selection
@@ -868,8 +878,8 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
capturedMouse = false;
return 0;
- // These are not handled in Scintilla and its faster to dispatch them here.
- // Also moves time out to here so profile doesn't count lots of empty message calls.
+ // These are not handled in Scintilla and its faster to dispatch them here.
+ // Also moves time out to here so profile doesn't count lots of empty message calls.
case WM_MOVE:
case WM_MOUSEACTIVATE:
@@ -1978,6 +1988,20 @@ bool ScintillaWin::IsCompatibleDC(HDC hOtherDC) {
return isCompatible;
}
+DWORD ScintillaWin::EffectFromState(DWORD grfKeyState) {
+ // These are the Wordpad semantics.
+ DWORD dwEffect;
+ if (inDragDrop == ddDragging) // Internal defaults to move
+ dwEffect = DROPEFFECT_MOVE;
+ else
+ dwEffect = DROPEFFECT_COPY;
+ if (grfKeyState & MK_ALT)
+ dwEffect = DROPEFFECT_MOVE;
+ if (grfKeyState & MK_CONTROL)
+ dwEffect = DROPEFFECT_COPY;
+ return dwEffect;
+}
+
/// Implement IUnknown
STDMETHODIMP ScintillaWin::QueryInterface(REFIID riid, PVOID *ppv) {
*ppv = NULL;
@@ -2020,14 +2044,7 @@ STDMETHODIMP ScintillaWin::DragEnter(LPDATAOBJECT pIDataSource, DWORD grfKeyStat
return S_OK;
}
- if (inDragDrop) // Internal defaults to move
- *pdwEffect = DROPEFFECT_MOVE;
- else
- *pdwEffect = DROPEFFECT_COPY;
- if (grfKeyState & MK_ALT)
- *pdwEffect = DROPEFFECT_MOVE;
- if (grfKeyState & MK_CONTROL)
- *pdwEffect = DROPEFFECT_COPY;
+ *pdwEffect = EffectFromState(grfKeyState);
return S_OK;
}
@@ -2037,15 +2054,8 @@ STDMETHODIMP ScintillaWin::DragOver(DWORD grfKeyState, POINTL pt, PDWORD pdwEffe
return S_OK;
}
- // These are the Wordpad semantics.
- if (inDragDrop) // Internal defaults to move
- *pdwEffect = DROPEFFECT_MOVE;
- else
- *pdwEffect = DROPEFFECT_COPY;
- if (grfKeyState & MK_ALT)
- *pdwEffect = DROPEFFECT_MOVE;
- if (grfKeyState & MK_CONTROL)
- *pdwEffect = DROPEFFECT_COPY;
+ *pdwEffect = EffectFromState(grfKeyState);
+
// Update the cursor.
POINT rpt = {pt.x, pt.y};
::ScreenToClient(MainHWND(), &rpt);
@@ -2061,14 +2071,7 @@ STDMETHODIMP ScintillaWin::DragLeave() {
STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState,
POINTL pt, PDWORD pdwEffect) {
- if (inDragDrop) // Internal defaults to move
- *pdwEffect = DROPEFFECT_MOVE;
- else
- *pdwEffect = DROPEFFECT_COPY;
- if (grfKeyState & MK_ALT)
- *pdwEffect = DROPEFFECT_MOVE;
- if (grfKeyState & MK_CONTROL)
- *pdwEffect = DROPEFFECT_COPY;
+ *pdwEffect = EffectFromState(grfKeyState);
if (pIDataSource == NULL)
return E_POINTER;