honeylisp/vendor/lite-plugins/plugins/dragdropselected.lua
Jeremy Penner cb5132f393 git subrepo clone https://github.com/rxi/lite-plugins vendor/lite-plugins
subrepo:
  subdir:   "vendor/lite-plugins"
  merged:   "de4227d"
upstream:
  origin:   "https://github.com/rxi/lite-plugins"
  branch:   "master"
  commit:   "de4227d"
git-subrepo:
  version:  "0.4.2"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "65fde50"
2020-11-19 21:04:39 -05:00

113 lines
4.1 KiB
Lua

--[[
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