1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
-- mod-version:1 -- lite-xl 2.00
--[[
dragdropselected.lua
provides basic drag and drop of selected text (in same document)
version: 20200627_133351
originally by SwissalpS
TODO: use OS drag and drop events
TODO: change mouse cursor when duplicating
TODO: add dragging image
--]]
local DocView = require "core.docview"
local core = require "core"
local keymap = require "core.keymap"
-- helper function for on_mouse_pressed to determine if mouse down is in selection
-- iLine is line number where mouse down happened
-- iCol is column where mouse down happened
-- iSelLine1 is line number where selection starts
-- iSelCol1 is column where selection starts
-- iSelLine2 is line number where selection ends
-- iSelCol2 is column where selection ends
local function isInSelection(iLine, iCol, iSelLine1, iSelCol1, iSelLine2, iSelCol2)
if iLine < iSelLine1 then return false end
if iLine > iSelLine2 then return false end
if (iLine == iSelLine1) and (iCol < iSelCol1) then return false end
if (iLine == iSelLine2) and (iCol > iSelCol2) then return false end
return true
end -- isInSelection
-- override DocView:on_mouse_moved
local on_mouse_moved = DocView.on_mouse_moved
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
-- 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)
-- update scroll position
self:scroll_to_line(iLine, true)
end -- if previously clicked into selection
-- hand off to 'old' on_mouse_moved()
on_mouse_moved(self, x, y, ...)
-- override cursor as needed
if sCursor then self.cursor = sCursor end
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())
or (1 < clicks) then
return on_mouse_pressed(self, button, x, y, clicks)
end
-- convert pixel coordinates to line and column coordinates
local iLine, iCol = self:resolve_screen_position(x, y)
-- get selection coordinates
local iSelLine1, iSelCol1, iSelLine2, iSelCol2 = self.doc:get_selection(true)
-- set flag for on_mouse_released and on_mouse_moved() methods to detect dragging
self.bClickedIntoSelection = isInSelection(iLine, iCol, iSelLine1, iSelCol1,
iSelLine2, iSelCol2)
if self.bClickedIntoSelection then
-- stash selection for inserting later
self.sDraggedText = self.doc:get_text(self.doc:get_selection())
else
-- 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)
if self.bClickedIntoSelection then
-- insert stashed selected text at current position
self.doc:text_input(self.sDraggedText)
-- unset stash and flag(s) TODO:
self.sDraggedText = ''
self.bClickedIntoSelection = nil
end
-- hand over to old handler
on_mouse_released(self, button)
end -- DocView:on_mouse_released
|