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"
})
```
This commit is contained in:
Guldoman 2023-02-09 17:51:41 +01:00 committed by George Sokianos
parent 51ab72f715
commit 7e0ddf2817
5 changed files with 86 additions and 25 deletions

View File

@ -4,6 +4,7 @@ local DocView = require "core.docview"
local command = require "core.command" local command = require "core.command"
local common = require "core.common" local common = require "core.common"
local config = require "core.config" local config = require "core.config"
local Node = require "core.node"
local t = { local t = {
@ -29,20 +30,6 @@ local t = {
core.confirm_close_docs(docs, core.root_view.close_all_docviews, core.root_view, true) core.confirm_close_docs(docs, core.root_view.close_all_docviews, core.root_view, true)
end, 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) ["root:move-tab-left"] = function(node)
local idx = node:get_view_idx(core.active_view) local idx = node:get_view_idx(core.active_view)
if idx > 1 then if idx > 1 then
@ -133,3 +120,59 @@ command.add(nil, {
return false return false
end 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
}
)

View File

@ -36,6 +36,8 @@ local function keymap_macos(keymap)
["wheel"] = "root:scroll", ["wheel"] = "root:scroll",
["hwheel"] = "root:horizontal-scroll", ["hwheel"] = "root:horizontal-scroll",
["shift+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+f"] = "find-replace:find",
["cmd+r"] = "find-replace:replace", ["cmd+r"] = "find-replace:replace",

View File

@ -302,6 +302,8 @@ keymap.add_direct {
["wheel"] = "root:scroll", ["wheel"] = "root:scroll",
["hwheel"] = "root:horizontal-scroll", ["hwheel"] = "root:horizontal-scroll",
["shift+wheel"] = "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+f"] = "find-replace:find",
["ctrl+r"] = "find-replace:replace", ["ctrl+r"] = "find-replace:replace",

View File

@ -27,6 +27,13 @@ function Object:is(T)
return getmetatable(self) == T return getmetatable(self) == T
end 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. ---Check if the object inherits from the given type.
---@param T any ---@param T any
---@return boolean ---@return boolean
@ -41,6 +48,22 @@ function Object:extends(T)
return false return false
end 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. ---Metamethod to get a string representation of an object.
---@return string ---@return string
function Object:__tostring() function Object:__tostring()

View File

@ -323,19 +323,10 @@ function RootView:on_file_dropped(filename, x, y)
end end
function RootView:on_mouse_wheel(dy, dx) function RootView:on_mouse_wheel(...)
local x, y = self.mouse.x, self.mouse.y local x, y = self.mouse.x, self.mouse.y
local node = self.root_node:get_child_overlapping_point(x, y) local node = self.root_node:get_child_overlapping_point(x, y)
return node.active_view:on_mouse_wheel(...)
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)
end end