From cd8ec70d7812fd5b1d1e6dfcbafddc608505c488 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Thu, 9 Feb 2023 17:51:41 +0100 Subject: [PATCH] Make tab scrolling more flexible (#1384) * Add `Object:{is_class_of,is_extended_by}` to check inverse relationships * Make tab scrolling more flexible This adds tab scrolling commands and connects them to mouse scroll events. This way scrolling behavior can be customized more easily. For example an alternative behavior could be: ```lua keymap.add({ ["wheelup"] = "root:switch-to-hovered-previous-tab", ["wheeldown"] = "root:switch-to-hovered-next-tab" }) ``` --- data/core/commands/root.lua | 71 +++++++++++++++++++++++++++++-------- data/core/keymap-macos.lua | 2 ++ data/core/keymap.lua | 2 ++ data/core/object.lua | 23 ++++++++++++ data/core/rootview.lua | 13 ++----- 5 files changed, 86 insertions(+), 25 deletions(-) diff --git a/data/core/commands/root.lua b/data/core/commands/root.lua index 61e3890b..acbd697c 100644 --- a/data/core/commands/root.lua +++ b/data/core/commands/root.lua @@ -4,6 +4,7 @@ local DocView = require "core.docview" local command = require "core.command" local common = require "core.common" local config = require "core.config" +local Node = require "core.node" local t = { @@ -29,20 +30,6 @@ local t = { core.confirm_close_docs(docs, core.root_view.close_all_docviews, core.root_view, true) end, - ["root:switch-to-previous-tab"] = function(node) - local idx = node:get_view_idx(core.active_view) - idx = idx - 1 - if idx < 1 then idx = #node.views end - node:set_active_view(node.views[idx]) - end, - - ["root:switch-to-next-tab"] = function(node) - local idx = node:get_view_idx(core.active_view) - idx = idx + 1 - if idx > #node.views then idx = 1 end - node:set_active_view(node.views[idx]) - end, - ["root:move-tab-left"] = function(node) local idx = node:get_view_idx(core.active_view) if idx > 1 then @@ -133,3 +120,59 @@ command.add(nil, { return false end }) + +command.add(function(node) + if not Node:is_extended_by(node) then node = nil end + -- No node was specified, use the active one + node = node or core.root_view:get_active_node() + if not node then return false end + return true, node + end, + { + ["root:switch-to-previous-tab"] = function(node) + local idx = node:get_view_idx(node.active_view) + idx = idx - 1 + if idx < 1 then idx = #node.views end + node:set_active_view(node.views[idx]) + end, + + ["root:switch-to-next-tab"] = function(node) + local idx = node:get_view_idx(node.active_view) + idx = idx + 1 + if idx > #node.views then idx = 1 end + node:set_active_view(node.views[idx]) + end, + + ["root:scroll-tabs-backward"] = function(node) + node:scroll_tabs(1) + end, + + ["root:scroll-tabs-forward"] = function(node) + node:scroll_tabs(2) + end + } +) + +command.add(function() + local node = core.root_view.overlapping_node + if not node then return false end + return (node.hovered_tab or node.hovered_scroll_button > 0) and true, node + end, + { + ["root:switch-to-hovered-previous-tab"] = function(node) + command.perform("root:switch-to-previous-tab", node) + end, + + ["root:switch-to-hovered-next-tab"] = function(node) + command.perform("root:switch-to-next-tab", node) + end, + + ["root:scroll-hovered-tabs-backward"] = function(node) + command.perform("root:scroll-tabs-backward", node) + end, + + ["root:scroll-hovered-tabs-forward"] = function(node) + command.perform("root:scroll-tabs-forward", node) + end + } +) diff --git a/data/core/keymap-macos.lua b/data/core/keymap-macos.lua index 8fe04b39..965191ef 100644 --- a/data/core/keymap-macos.lua +++ b/data/core/keymap-macos.lua @@ -36,6 +36,8 @@ local function keymap_macos(keymap) ["wheel"] = "root:scroll", ["hwheel"] = "root:horizontal-scroll", ["shift+hwheel"] = "root:horizontal-scroll", + ["wheelup"] = "root:scroll-hovered-tabs-backward", + ["wheeldown"] = "root:scroll-hovered-tabs-forward", ["cmd+f"] = "find-replace:find", ["cmd+r"] = "find-replace:replace", diff --git a/data/core/keymap.lua b/data/core/keymap.lua index 28dc9521..f804bcc7 100644 --- a/data/core/keymap.lua +++ b/data/core/keymap.lua @@ -304,6 +304,8 @@ keymap.add_direct { ["wheel"] = "root:scroll", ["hwheel"] = "root:horizontal-scroll", ["shift+wheel"] = "root:horizontal-scroll", + ["wheelup"] = "root:scroll-hovered-tabs-backward", + ["wheeldown"] = "root:scroll-hovered-tabs-forward", ["ctrl+f"] = "find-replace:find", ["ctrl+r"] = "find-replace:replace", diff --git a/data/core/object.lua b/data/core/object.lua index afd13cdf..7b712cff 100644 --- a/data/core/object.lua +++ b/data/core/object.lua @@ -27,6 +27,13 @@ function Object:is(T) return getmetatable(self) == T end +---Check if the parameter is strictly of the object type. +---@param T any +---@return boolean +function Object:is_class_of(T) + return getmetatable(T) == self +end + ---Check if the object inherits from the given type. ---@param T any ---@return boolean @@ -41,6 +48,22 @@ function Object:extends(T) return false end +---Check if the parameter inherits from the object. +---@param T any +---@return boolean +function Object:is_extended_by(T) + local mt = getmetatable(T) + while mt do + if mt == self then + return true + end + local _mt = getmetatable(T) + if mt == _mt then break end + mt = _mt + end + return false +end + ---Metamethod to get a string representation of an object. ---@return string function Object:__tostring() diff --git a/data/core/rootview.lua b/data/core/rootview.lua index 002029c4..7230e8e1 100644 --- a/data/core/rootview.lua +++ b/data/core/rootview.lua @@ -323,19 +323,10 @@ function RootView:on_file_dropped(filename, x, y) end -function RootView:on_mouse_wheel(dy, dx) +function RootView:on_mouse_wheel(...) local x, y = self.mouse.x, self.mouse.y local node = self.root_node:get_child_overlapping_point(x, y) - - local idx = node:get_tab_overlapping_point(x, y) - if idx then - local delta = dx == 0.0 and dy or dx - local button = delta < 0 and 2 or 1 - node:scroll_tabs(button) - return true - end - - return node.active_view:on_mouse_wheel(dy, dx) + return node.active_view:on_mouse_wheel(...) end