Make `TreeView` follow the current tab (#1411)
* Make `TreeView` follow the current tab * Use `TreeView:toggle_expand` in `TreeView:set_selection_to_path` We can't use `item.expanded` directly because we need to update the cached tree structure.
This commit is contained in:
parent
94e2df991c
commit
e66174f9d8
|
@ -9,10 +9,15 @@ local View = require "core.view"
|
||||||
local ContextMenu = require "core.contextmenu"
|
local ContextMenu = require "core.contextmenu"
|
||||||
local RootView = require "core.rootview"
|
local RootView = require "core.rootview"
|
||||||
local CommandView = require "core.commandview"
|
local CommandView = require "core.commandview"
|
||||||
|
local DocView = require "core.docview"
|
||||||
|
|
||||||
config.plugins.treeview = common.merge({
|
config.plugins.treeview = common.merge({
|
||||||
-- Default treeview width
|
-- Default treeview width
|
||||||
size = 200 * SCALE
|
size = 200 * SCALE,
|
||||||
|
highlight_focused_file = true,
|
||||||
|
expand_dirs_to_focused_file = false,
|
||||||
|
scroll_to_focused_file = false,
|
||||||
|
animate_scroll_to_focused_file = true
|
||||||
}, config.plugins.treeview)
|
}, config.plugins.treeview)
|
||||||
|
|
||||||
local tooltip_offset = style.font:get_height()
|
local tooltip_offset = style.font:get_height()
|
||||||
|
@ -169,20 +174,73 @@ function TreeView:each_item()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function TreeView:set_selection(selection, selection_y)
|
function TreeView:set_selection(selection, selection_y, center, instant)
|
||||||
self.selected_item = selection
|
self.selected_item = selection
|
||||||
if selection and selection_y
|
if selection and selection_y
|
||||||
and (selection_y <= 0 or selection_y >= self.size.y) then
|
and (selection_y <= 0 or selection_y >= self.size.y) then
|
||||||
|
|
||||||
local lh = self:get_item_height()
|
local lh = self:get_item_height()
|
||||||
if selection_y >= self.size.y - lh then
|
if not center and selection_y >= self.size.y - lh then
|
||||||
selection_y = selection_y - self.size.y + lh
|
selection_y = selection_y - self.size.y + lh
|
||||||
end
|
end
|
||||||
|
if center then
|
||||||
|
selection_y = selection_y - (self.size.y - lh) / 2
|
||||||
|
end
|
||||||
local _, y = self:get_content_offset()
|
local _, y = self:get_content_offset()
|
||||||
self.scroll.to.y = selection and (selection_y - y)
|
self.scroll.to.y = selection_y - y
|
||||||
|
self.scroll.to.y = common.clamp(self.scroll.to.y, 0, self:get_scrollable_size() - self.size.y)
|
||||||
|
if instant then
|
||||||
|
self.scroll.y = self.scroll.to.y
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Sets the selection to the file with the specified path.
|
||||||
|
---
|
||||||
|
---@param path string #Absolute path of item to select
|
||||||
|
---@param expand boolean #Expand dirs leading to the item
|
||||||
|
---@param scroll_to boolean #Scroll to make the item visible
|
||||||
|
---@param instant boolean #Don't animate the scroll
|
||||||
|
---@return table? #The selected item
|
||||||
|
function TreeView:set_selection_to_path(path, expand, scroll_to, instant)
|
||||||
|
local to_select, to_select_y
|
||||||
|
local let_it_finish, done
|
||||||
|
::restart::
|
||||||
|
for item, x,y,w,h in self:each_item() do
|
||||||
|
if not done then
|
||||||
|
if item.type == "dir" then
|
||||||
|
local _, to = string.find(path, item.abs_filename..PATHSEP, 1, true)
|
||||||
|
if to and to == #item.abs_filename + #PATHSEP then
|
||||||
|
to_select, to_select_y = item, y
|
||||||
|
if expand and not item.expanded then
|
||||||
|
-- Use TreeView:toggle_expand to update the directory structure.
|
||||||
|
-- Directly using item.expanded doesn't update the cached tree.
|
||||||
|
self:toggle_expand(true, item)
|
||||||
|
-- Because we altered the size of the TreeView
|
||||||
|
-- and because TreeView:get_scrollable_size uses self.count_lines
|
||||||
|
-- which gets updated only when TreeView:each_item finishes,
|
||||||
|
-- we can't stop here or we risk that the scroll
|
||||||
|
-- gets clamped by View:clamp_scroll_position.
|
||||||
|
let_it_finish = true
|
||||||
|
-- We need to restart the process because if TreeView:toggle_expand
|
||||||
|
-- altered the cache, TreeView:each_item risks looping indefinitely.
|
||||||
|
goto restart
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if item.abs_filename == path then
|
||||||
|
to_select, to_select_y = item, y
|
||||||
|
done = true
|
||||||
|
if not let_it_finish then break end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if to_select then
|
||||||
|
self:set_selection(to_select, scroll_to and to_select_y, true, instant)
|
||||||
|
end
|
||||||
|
return to_select
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function TreeView:get_text_bounding_box(item, x, y, w, h)
|
function TreeView:get_text_bounding_box(item, x, y, w, h)
|
||||||
local icon_width = style.icon_font:get_width("D")
|
local icon_width = style.icon_font:get_width("D")
|
||||||
|
@ -233,7 +291,7 @@ function TreeView:update()
|
||||||
self:move_towards(self.size, "x", dest, nil, "treeview")
|
self:move_towards(self.size, "x", dest, nil, "treeview")
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.visible then return end
|
if self.size.x == 0 or self.size.y == 0 or not self.visible then return end
|
||||||
|
|
||||||
local duration = system.get_time() - self.tooltip.begin
|
local duration = system.get_time() - self.tooltip.begin
|
||||||
if self.hovered_item and self.tooltip.x and duration > tooltip_delay then
|
if self.hovered_item and self.tooltip.x and duration > tooltip_delay then
|
||||||
|
@ -252,6 +310,26 @@ function TreeView:update()
|
||||||
self:on_mouse_moved(self.cursor_pos.x, self.cursor_pos.y, 0, 0)
|
self:on_mouse_moved(self.cursor_pos.x, self.cursor_pos.y, 0, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local config = config.plugins.treeview
|
||||||
|
if config.highlight_focused_file then
|
||||||
|
-- Try to only highlight when we actually change tabs
|
||||||
|
local current_node = core.root_view:get_active_node()
|
||||||
|
local current_active_view = core.active_view
|
||||||
|
if current_node and not current_node.locked
|
||||||
|
and current_active_view ~= self and current_active_view ~= self.last_active_view then
|
||||||
|
self.selected_item = nil
|
||||||
|
self.last_active_view = current_active_view
|
||||||
|
if DocView:is_extended_by(current_active_view) then
|
||||||
|
local abs_filename = current_active_view.doc
|
||||||
|
and current_active_view.doc.abs_filename or ""
|
||||||
|
self:set_selection_to_path(abs_filename,
|
||||||
|
config.expand_dirs_to_focused_file,
|
||||||
|
config.scroll_to_focused_file,
|
||||||
|
not config.animate_scroll_to_focused_file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
TreeView.super.update(self)
|
TreeView.super.update(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -422,8 +500,8 @@ function TreeView:get_previous(item)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function TreeView:toggle_expand(toggle)
|
function TreeView:toggle_expand(toggle, item)
|
||||||
local item = self.selected_item
|
item = item or self.selected_item
|
||||||
|
|
||||||
if not item then return end
|
if not item then return end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue