From 662fde364bc45d8cf5f089c85abd4cd283f1bb71 Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 7 Apr 2023 19:15:50 +0200 Subject: [PATCH] Add View dragging (#1402) --- data/core/init.lua | 6 ++++++ data/core/node.lua | 7 +++++++ data/core/rootview.lua | 43 ++++++++++++++++++++++++++++++++++++++++++ data/core/view.lua | 17 +++++++++++++++++ 4 files changed, 73 insertions(+) diff --git a/data/core/init.lua b/data/core/init.lua index 016385fd..050a8ee2 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -1289,6 +1289,12 @@ function core.on_event(type, ...) if not core.root_view:on_mouse_wheel(...) then did_keymap = keymap.on_mouse_wheel(...) end + elseif type == "touchpressed" then + core.root_view:on_touch_pressed(...) + elseif type == "touchreleased" then + core.root_view:on_touch_released(...) + elseif type == "touchmoved" then + core.root_view:on_touch_moved(...) elseif type == "resized" then core.window_mode = system.get_window_mode() elseif type == "minimized" or type == "maximized" or type == "restored" then diff --git a/data/core/node.lua b/data/core/node.lua index 2ce52cc2..aff4bb11 100644 --- a/data/core/node.lua +++ b/data/core/node.lua @@ -60,6 +60,13 @@ function Node:on_mouse_left() end end +function Node:on_touch_moved(...) + if self.type == "leaf" then + self.active_view:on_touch_moved(...) + else + self:propagate("on_touch_moved", ...) + end +end function Node:consume(node) for k, _ in pairs(self) do self[k] = nil end diff --git a/data/core/rootview.lua b/data/core/rootview.lua index 7230e8e1..f9bde17e 100644 --- a/data/core/rootview.lua +++ b/data/core/rootview.lua @@ -334,6 +334,49 @@ function RootView:on_text_input(...) core.active_view:on_text_input(...) end +function RootView:on_touch_pressed(x, y, ...) + self.touched_node = self.root_node:get_child_overlapping_point(x, y) +end + +function RootView:on_touch_released(x, y, ...) + self.touched_node = nil +end + +function RootView:on_touch_moved(x, y, dx, dy, ...) + if not self.touched_node then return end + if core.active_view == core.nag_view then + core.active_view:on_touch_moved(x, y, dx, dy, ...) + return + end + + if self.dragged_divider then + local node = self.dragged_divider + if node.type == "hsplit" then + x = common.clamp(x, 0, self.root_node.size.x * 0.95) + resize_child_node(node, "x", x, dx) + elseif node.type == "vsplit" then + y = common.clamp(y, 0, self.root_node.size.y * 0.95) + resize_child_node(node, "y", y, dy) + end + node.divider = common.clamp(node.divider, 0.01, 0.99) + return + end + + local dn = self.dragged_node + if dn and not dn.dragging then + -- start dragging only after enough movement + dn.dragging = common.distance(x, y, dn.drag_start_x, dn.drag_start_y) > style.tab_width * .05 + if dn.dragging then + core.request_cursor("hand") + end + end + + -- avoid sending on_touch_moved events when dragging tabs + if dn then return end + + self.touched_node:on_touch_moved(x, y, dx, dy, ...) +end + function RootView:on_ime_text_editing(...) core.active_view:on_ime_text_editing(...) end diff --git a/data/core/view.lua b/data/core/view.lua index 36580677..02560ff8 100644 --- a/data/core/view.lua +++ b/data/core/view.lua @@ -248,6 +248,23 @@ function View:get_content_bounds() return x, y, x + self.size.x, y + self.size.y end +---@param x number +---@param y number +---@param dx number +---@param dy number +---@param i number +function View:on_touch_moved(x, y, dx, dy, i) + if not self.scrollable then return end + if self.dragging_scrollbar then + local delta = self:get_scrollable_size() / self.size.y * dy + self.scroll.to.y = self.scroll.to.y + delta + end + self.hovered_scrollbar = self:scrollbar_overlaps_point(x, y) + + self.scroll.to.y = self.scroll.to.y + -dy + self.scroll.to.x = self.scroll.to.x + -dx +end + ---@return number x ---@return number y