2019-12-28 12:16:32 +01:00
|
|
|
local core = require "core"
|
|
|
|
local common = require "core.common"
|
|
|
|
local style = require "core.style"
|
|
|
|
local keymap = require "core.keymap"
|
|
|
|
local Object = require "core.object"
|
|
|
|
local View = require "core.view"
|
|
|
|
local DocView = require "core.docview"
|
2021-02-03 19:27:55 +01:00
|
|
|
local Node = require "core.node"
|
2019-12-28 12:16:32 +01:00
|
|
|
|
|
|
|
local function copy_position_and_size(dst, src)
|
|
|
|
dst.position.x, dst.position.y = src.position.x, src.position.y
|
|
|
|
dst.size.x, dst.size.y = src.size.x, src.size.y
|
|
|
|
end
|
|
|
|
|
|
|
|
local RootView = View:extend()
|
|
|
|
|
|
|
|
function RootView:new()
|
|
|
|
RootView.super.new(self)
|
|
|
|
self.root_node = Node()
|
|
|
|
self.deferred_draws = {}
|
|
|
|
self.mouse = { x = 0, y = 0 }
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function RootView:defer_draw(fn, ...)
|
|
|
|
table.insert(self.deferred_draws, 1, { fn = fn, ... })
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function RootView:get_active_node()
|
2020-05-19 13:58:41 +02:00
|
|
|
return self.root_node:get_node_for_view(core.active_view)
|
2019-12-28 12:16:32 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function RootView:open_doc(doc)
|
|
|
|
local node = self:get_active_node()
|
2020-05-22 16:43:47 +02:00
|
|
|
if node.locked and core.last_active_view then
|
|
|
|
core.set_active_view(core.last_active_view)
|
|
|
|
node = self:get_active_node()
|
|
|
|
end
|
2019-12-28 12:16:32 +01:00
|
|
|
assert(not node.locked, "Cannot open doc on locked node")
|
|
|
|
for i, view in ipairs(node.views) do
|
|
|
|
if view.doc == doc then
|
|
|
|
node:set_active_view(node.views[i])
|
|
|
|
return view
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local view = DocView(doc)
|
|
|
|
node:add_view(view)
|
|
|
|
self.root_node:update_layout()
|
|
|
|
view:scroll_to_line(view.doc:get_selection(), true, true)
|
|
|
|
return view
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function RootView:on_mouse_pressed(button, x, y, clicks)
|
|
|
|
local div = self.root_node:get_divider_overlapping_point(x, y)
|
|
|
|
if div then
|
|
|
|
self.dragged_divider = div
|
|
|
|
return
|
|
|
|
end
|
|
|
|
local node = self.root_node:get_child_overlapping_point(x, y)
|
|
|
|
local idx = node:get_tab_overlapping_point(x, y)
|
|
|
|
if idx then
|
|
|
|
node:set_active_view(node.views[idx])
|
|
|
|
if button == "middle" then
|
|
|
|
node:close_active_view(self.root_node)
|
|
|
|
end
|
|
|
|
else
|
2020-05-19 13:58:41 +02:00
|
|
|
core.set_active_view(node.active_view)
|
2019-12-28 12:16:32 +01:00
|
|
|
node.active_view:on_mouse_pressed(button, x, y, clicks)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function RootView:on_mouse_released(...)
|
|
|
|
if self.dragged_divider then
|
|
|
|
self.dragged_divider = nil
|
|
|
|
end
|
|
|
|
self.root_node:on_mouse_released(...)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function RootView:on_mouse_moved(x, y, dx, dy)
|
|
|
|
if self.dragged_divider then
|
2020-05-23 10:40:42 +02:00
|
|
|
local node = self.dragged_divider
|
|
|
|
if node.type == "hsplit" then
|
|
|
|
node.divider = node.divider + dx / node.size.x
|
2019-12-28 12:16:32 +01:00
|
|
|
else
|
2020-05-23 10:40:42 +02:00
|
|
|
node.divider = node.divider + dy / node.size.y
|
2019-12-28 12:16:32 +01:00
|
|
|
end
|
2020-05-23 10:40:42 +02:00
|
|
|
node.divider = common.clamp(node.divider, 0.01, 0.99)
|
2019-12-28 12:16:32 +01:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
self.mouse.x, self.mouse.y = x, y
|
|
|
|
self.root_node:on_mouse_moved(x, y, dx, dy)
|
|
|
|
|
|
|
|
local node = self.root_node:get_child_overlapping_point(x, y)
|
|
|
|
local div = self.root_node:get_divider_overlapping_point(x, y)
|
|
|
|
if div then
|
|
|
|
system.set_cursor(div.type == "hsplit" and "sizeh" or "sizev")
|
|
|
|
elseif node:get_tab_overlapping_point(x, y) then
|
|
|
|
system.set_cursor("arrow")
|
|
|
|
else
|
|
|
|
system.set_cursor(node.active_view.cursor)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
node.active_view:on_mouse_wheel(...)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function RootView:on_text_input(...)
|
|
|
|
core.active_view:on_text_input(...)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function RootView:update()
|
|
|
|
copy_position_and_size(self.root_node, self)
|
|
|
|
self.root_node:update()
|
|
|
|
self.root_node:update_layout()
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function RootView:draw()
|
|
|
|
self.root_node:draw()
|
|
|
|
while #self.deferred_draws > 0 do
|
|
|
|
local t = table.remove(self.deferred_draws)
|
|
|
|
t.fn(table.unpack(t))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
return RootView
|