From 7e0ddf2817be52c965663e5dc347e1234e71f798 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 35e34e6a..c0a78dd3 100644 --- a/data/core/keymap.lua +++ b/data/core/keymap.lua @@ -302,6 +302,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