aboutsummaryrefslogtreecommitdiff
path: root/plugins/dragdropselected.lua
diff options
context:
space:
mode:
authorGuldoman <giulio.lettieri@gmail.com>2021-08-30 23:33:21 +0200
committerGuldoman <giulio.lettieri@gmail.com>2021-08-30 23:33:21 +0200
commite47539e9b5d00e564cb9685a0eff56ca421d975b (patch)
treed8555374ab3422e75bda452a4c9ba111f3c2741e /plugins/dragdropselected.lua
parent733c111519a8ecc69dfcf6a7039cab99259e43ac (diff)
downloadlite-xl-plugins-e47539e9b5d00e564cb9685a0eff56ca421d975b.tar.gz
lite-xl-plugins-e47539e9b5d00e564cb9685a0eff56ca421d975b.zip
`dragdropselected`: Avoid accidental drags
Also only remove the selection after the drag ends
Diffstat (limited to 'plugins/dragdropselected.lua')
-rw-r--r--plugins/dragdropselected.lua92
1 files changed, 70 insertions, 22 deletions
diff --git a/plugins/dragdropselected.lua b/plugins/dragdropselected.lua
index 4dbaa84..a26a82c 100644
--- a/plugins/dragdropselected.lua
+++ b/plugins/dragdropselected.lua
@@ -12,6 +12,7 @@
local DocView = require "core.docview"
local core = require "core"
local keymap = require "core.keymap"
+local style = require "core.style"
-- helper function for on_mouse_pressed to determine if mouse down is in selection
-- iLine is line number where mouse down happened
@@ -28,6 +29,13 @@ local function isInSelection(iLine, iCol, iSelLine1, iSelCol1, iSelLine2, iSelCo
return true
end -- isInSelection
+-- distance between two points
+local function distance(x1, y1, x2, y2)
+ return math.sqrt(math.pow(x2-x1, 2)+math.pow(y2-y1, 2))
+end
+
+local min_drag = style.code_font:get_width(" ")
+
-- override DocView:on_mouse_moved
local on_mouse_moved = DocView.on_mouse_moved
function DocView:on_mouse_moved(x, y, ...)
@@ -35,29 +43,29 @@ function DocView:on_mouse_moved(x, y, ...)
local sCursor = nil
-- make sure we only act if previously on_mouse_pressed was in selection
- if self.bClickedIntoSelection then
+ if self.bClickedIntoSelection and
+ ( -- we are already dragging or we moved enough to start dragging
+ not self.drag_start_loc or
+ distance(self.drag_start_loc[1],self.drag_start_loc[2], x, y) > min_drag
+ ) then
+ self.drag_start_loc = nil
-- show that we are dragging something
sCursor = 'hand'
- -- check for modifier to duplicate
- -- (may want to set a flag as this only needs to be done once)
- -- TODO: make image to drag with and/or hand over to OS dnd event
- if not keymap.modkeys['ctrl'] then
- -- TODO: maybe check if moved at all and only delete then or
- -- as some editors do, only when dropped. I do like it going
- -- instantly as that reduces the travel-distance.
- self.doc:delete_to(0)
- --sCursor = 'arrowWithPlus' -- 'handWithPlus'
- end
-
-- calculate line and column for current mouse position
local iLine, iCol = self:resolve_screen_position(x, y)
- -- move text cursor
- self.doc:set_selection(iLine, iCol)
+ local iSelLine1 = self.dragged_selection[1]
+ local iSelCol1 = self.dragged_selection[2]
+ local iSelLine2 = self.dragged_selection[3]
+ local iSelCol2 = self.dragged_selection[4]
+ self.doc:set_selection(iSelLine1, iSelCol1, iSelLine2, iSelCol2)
+ if not isInSelection(iLine, iCol, iSelLine1, iSelCol1, iSelLine2, iSelCol2) then
+ -- show cursor only if outside selection
+ self.doc:add_selection(iLine, iCol)
+ end
-- update scroll position
self:scroll_to_line(iLine, true)
-
end -- if previously clicked into selection
-- hand off to 'old' on_mouse_moved()
@@ -70,7 +78,6 @@ end -- DocView:on_mouse_moved
-- override DocView:on_mouse_pressed
local on_mouse_pressed = DocView.on_mouse_pressed
function DocView:on_mouse_pressed(button, x, y, clicks)
-
-- no need to proceed if not left button or has no selection
if ('left' ~= button)
or (not self.doc:has_selection())
@@ -85,29 +92,70 @@ function DocView:on_mouse_pressed(button, x, y, clicks)
self.bClickedIntoSelection = isInSelection(iLine, iCol, iSelLine1, iSelCol1,
iSelLine2, iSelCol2)
if self.bClickedIntoSelection then
+ self.drag_start_loc = { x, y }
-- stash selection for inserting later
self.sDraggedText = self.doc:get_text(self.doc:get_selection())
+ self.dragged_selection = { iSelLine1, iSelCol1, iSelLine2, iSelCol2 }
else
+ self.bClickedIntoSelection = nil
+ self.dragged_selection = nil
-- let 'old' on_mouse_pressed() do whatever it needs to do
on_mouse_pressed(self, button, x, y, clicks)
end
-
end -- DocView:on_mouse_pressed
-- override DocView:on_mouse_released()
local on_mouse_released = DocView.on_mouse_released
-function DocView:on_mouse_released(button)
-
+function DocView:on_mouse_released(button, x, y)
+ local iLine, iCol = self:resolve_screen_position(x, y)
if self.bClickedIntoSelection then
- -- insert stashed selected text at current position
- self.doc:text_input(self.sDraggedText)
+ local iSelLine1, iSelCol1, iSelLine2, iSelCol2 = table.unpack(self.dragged_selection)
+ if not self.drag_start_loc
+ and not isInSelection(iLine, iCol, iSelLine1, iSelCol1, iSelLine2, iSelCol2) then
+ -- insert stashed selected text at current position
+ if iLine < iSelLine1 or (iLine == iSelLine1 and iCol < iSelCol1) then
+ -- delete first
+ self.doc:set_selection(iSelLine1, iSelCol1, iSelLine2, iSelCol2)
+ if not keymap.modkeys['ctrl'] then
+ self.doc:delete_to(0)
+ end
+ self.doc:set_selection(iLine, iCol)
+ self.doc:text_input(self.sDraggedText)
+ else
+ -- insert first
+ self.doc:set_selection(iLine, iCol)
+ self.doc:text_input(self.sDraggedText)
+ self.doc:set_selection(iSelLine1, iSelCol1, iSelLine2, iSelCol2)
+ if not keymap.modkeys['ctrl'] then
+ self.doc:delete_to(0)
+ end
+ self.doc:set_selection(iLine, iCol)
+ end
+ elseif self.drag_start_loc then
+ -- deselect only if the drag never happened
+ self.doc:set_selection(iLine, iCol)
+ end
-- unset stash and flag(s) TODO:
self.sDraggedText = ''
self.bClickedIntoSelection = nil
end
-- hand over to old handler
- on_mouse_released(self, button)
+ on_mouse_released(self, button, x, y)
end -- DocView:on_mouse_released
+-- override DocView:draw_caret()
+local draw_caret = DocView.draw_caret
+function DocView:draw_caret(x, y)
+ if self.bClickedIntoSelection then
+ local iLine, iCol = self:resolve_screen_position(x, y)
+ -- don't show carets inside selections
+ if isInSelection(iLine, iCol,
+ self.dragged_selection[1], self.dragged_selection[2],
+ self.dragged_selection[3], self.dragged_selection[4]) then
+ return
+ end
+ end
+ draw_caret(self, x, y)
+end -- DocView:draw_caret()