StatusView: implemented dragging and scrolling.

This commit is contained in:
jgmdev 2022-02-23 19:25:25 -04:00
parent 3452d499e5
commit c5648e1f02
1 changed files with 93 additions and 20 deletions

View File

@ -28,6 +28,7 @@ local Object = require "core.object"
---@field private left_xoffset number ---@field private left_xoffset number
---@field private right_xoffset number ---@field private right_xoffset number
---@field private dragged_panel '"left"' | '"right"' ---@field private dragged_panel '"left"' | '"right"'
---@field private hovered_panel '"left"' | '"right"'
---@field private hide_messages boolean ---@field private hide_messages boolean
local StatusView = View:extend() local StatusView = View:extend()
@ -159,6 +160,7 @@ function StatusView:new()
self.left_xoffset = 0 self.left_xoffset = 0
self.right_xoffset = 0 self.right_xoffset = 0
self.dragged_panel = "" self.dragged_panel = ""
self.hovered_panel = ""
self.hide_messages = false self.hide_messages = false
self:register_docview_items() self:register_docview_items()
@ -705,6 +707,9 @@ function StatusView:update_active_items()
if lw + rw + (style.padding.x * 2) > self.size.x then if lw + rw + (style.padding.x * 2) > self.size.x then
lw = self.size.x / 2 - (style.padding.x * 2) lw = self.size.x / 2 - (style.padding.x * 2)
rw = self.size.x / 2 - (style.padding.x * 2) rw = self.size.x / 2 - (style.padding.x * 2)
else
self.left_xoffset = 0
self.right_xoffset = 0
end end
self.left_width, self.right_width = lw, rw self.left_width, self.right_width = lw, rw
@ -718,13 +723,57 @@ function StatusView:update_active_items()
end end
function StatusView:on_mouse_pressed() ---Drag the given panel if possible.
core.set_active_view(core.last_active_view) ---@param panel '"left"' | '"right"'
if system.get_time() < self.message_timeout ---@param distance number
and not core.active_view:is(LogView) then function StatusView:drag_panel(panel, dx)
command.perform "core:open-log" if panel == "left" and self.r_left_width > self.left_width then
local nonvisible_w = self.r_left_width - self.left_width
local new_offset = self.left_xoffset + dx
if new_offset >= 0 - nonvisible_w and new_offset <= 0 then
self.left_xoffset = new_offset
end
elseif panel == "right" and self.r_right_width > self.right_width then
local nonvisible_w = self.r_right_width - self.right_width
local new_offset = self.right_xoffset + dx
if new_offset >= 0 - nonvisible_w and new_offset <= 0 then
self.right_xoffset = new_offset
end
end
end
---Return the currently hovered panel or empty string if none.
---@param x number
---@param y number
---@return string
function StatusView:get_hovered_panel(x, y)
if y >= self.position.y and x <= self.left_width + style.padding.x then
return "left"
else
return "right"
end
return ""
end
function StatusView:on_mouse_pressed(button, x, y, clicks)
core.set_active_view(core.last_active_view)
if
system.get_time() < self.message_timeout
and
not core.active_view:is(LogView)
then
command.perform "core:open-log"
else
if y >= self.position.y and button == "left" and clicks == 1 then
self.position.dx = x
if self.r_left_width > self.left_width then
self.dragged_panel = self:get_hovered_panel(x, y)
self.cursor = "hand"
end
end
end end
self.mouse_pressed = true
return true return true
end end
@ -732,6 +781,13 @@ end
function StatusView:on_mouse_moved(x, y, dx, dy) function StatusView:on_mouse_moved(x, y, dx, dy)
StatusView.super.on_mouse_moved(self, x, y, dx, dy) StatusView.super.on_mouse_moved(self, x, y, dx, dy)
self.hovered_panel = self:get_hovered_panel(x, y)
if self.dragged_panel ~= "" then
self:drag_panel(self.dragged_panel, dx)
return
end
if y < self.position.y or system.get_time() <= self.message_timeout then if y < self.position.y or system.get_time() <= self.message_timeout then
self.cursor = "arrow" self.cursor = "arrow"
self.hovered_item = {} self.hovered_item = {}
@ -744,7 +800,11 @@ function StatusView:on_mouse_moved(x, y, dx, dy)
and and
(item.command or item.on_click or item.tooltip ~= "") (item.command or item.on_click or item.tooltip ~= "")
then then
local item_x = item.x + style.padding.x local item_ox = item.alignment == StatusView.Item.LEFT and
self.left_xoffset or self.right_xoffset
local item_x = item_ox + item.x + style.padding.x
if x > item_x and (item_x + item.w) > x then if x > item_x and (item_x + item.w) > x then
self.pointer.x = x self.pointer.x = x
self.pointer.y = y self.pointer.y = y
@ -766,22 +826,35 @@ end
function StatusView:on_mouse_released(button, x, y) function StatusView:on_mouse_released(button, x, y)
StatusView.super.on_mouse_released(self, button, x, y) StatusView.super.on_mouse_released(self, button, x, y)
self.mouse_pressed = false if self.dragged_panel ~= "" then
self.dragged_panel = ""
self.cursor = "arrow"
if self.position.dx ~= x then
return
end
end
if y < self.position.y or not self.hovered_item.active then return end if y < self.position.y or not self.hovered_item.active then return end
local item = self.hovered_item local item = self.hovered_item
local item_x = item.x + style.padding.x local item_ox = item.alignment == StatusView.Item.LEFT and
self.left_xoffset or self.right_xoffset
local item_x = item_ox + item.x + style.padding.x
if x > item_x and (item_x + item.w) > x then if x > item_x and (item_x + item.w) > x then
if item.command then if item.command then
command.perform(item.command) command.perform(item.command)
elseif item.on_click then elseif item.on_click then
self.hovered_item.on_click(button, x, y) item.on_click(button, x, y)
end end
end end
end end
function StatusView:on_mouse_wheel(y)
self:drag_panel(self.hovered_panel, y * self.left_width / 10)
end
function StatusView:update() function StatusView:update()
self.size.y = style.font:get_height() + style.padding.y * 2 self.size.y = style.font:get_height() + style.padding.y * 2
@ -812,19 +885,20 @@ function StatusView:draw()
self.left_width + style.padding.x, self.size.y self.left_width + style.padding.x, self.size.y
) )
for _, item in ipairs(self.active_items) do for _, item in ipairs(self.active_items) do
local item_x = self.left_xoffset + item.x + style.padding.x
if item.alignment == StatusView.Item.LEFT then if item.alignment == StatusView.Item.LEFT then
if type(item.background_color) == "table" then if type(item.background_color) == "table" then
renderer.draw_rect( renderer.draw_rect(
item.x + style.padding.x, self.position.y, item_x, self.position.y,
item.w, self.size.y, item.background_color item.w, self.size.y, item.background_color
) )
end end
if item.on_draw then if item.on_draw then
core.push_clip_rect(item.x + style.padding.x, self.position.y, item.w, self.size.y) core.push_clip_rect(item_x, self.position.y, item.w, self.size.y)
item.on_draw(item.x + style.padding.x, self.position.y, self.size.y) item.on_draw(item_x, self.position.y, self.size.y)
core.pop_clip_rect() core.pop_clip_rect()
else else
self:draw_items(item.cached_item, false, item.x) self:draw_items(item.cached_item, false, item_x - style.padding.x)
end end
end end
end end
@ -835,23 +909,22 @@ function StatusView:draw()
self.size.x - (self.right_width + style.padding.x), self.position.y, self.size.x - (self.right_width + style.padding.x), self.position.y,
self.right_width + style.padding.x, self.size.y self.right_width + style.padding.x, self.size.y
) )
local rx = 0
for _, item in ipairs(self.active_items) do for _, item in ipairs(self.active_items) do
local item_x = self.right_xoffset + item.x + style.padding.x
if item.alignment == StatusView.Item.RIGHT then if item.alignment == StatusView.Item.RIGHT then
if type(item.background_color) == "table" then if type(item.background_color) == "table" then
renderer.draw_rect( renderer.draw_rect(
item.x + style.padding.x, self.position.y, item_x, self.position.y,
item.w, self.size.y, item.background_color item.w, self.size.y, item.background_color
) )
end end
if item.on_draw then if item.on_draw then
core.push_clip_rect(item.x + style.padding.x, self.position.y, item.w, self.size.y) core.push_clip_rect(item_x, self.position.y, item.w, self.size.y)
item.on_draw(item.x + style.padding.x, self.position.y, self.size.y) item.on_draw(item_x, self.position.y, self.size.y)
core.pop_clip_rect() core.pop_clip_rect()
else else
self:draw_items(item.cached_item, false, item.x) self:draw_items(item.cached_item, false, item_x - style.padding.x)
end end
rx = rx + item.w
end end
end end
core.pop_clip_rect() core.pop_clip_rect()