aboutsummaryrefslogtreecommitdiff
path: root/plugins/dragdropselected.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/dragdropselected.lua')
-rw-r--r--plugins/dragdropselected.lua112
1 files changed, 112 insertions, 0 deletions
diff --git a/plugins/dragdropselected.lua b/plugins/dragdropselected.lua
new file mode 100644
index 0000000..d5f0d04
--- /dev/null
+++ b/plugins/dragdropselected.lua
@@ -0,0 +1,112 @@
+--[[
+ draganddropselectedtext.lua
+ provides basic drag and drop of selected text (in same document)
+ version: 20200626_013631
+ 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
+