improve logview

The logview is now less cluttered.
The filename and stack trace (if any) is hidden by default.
The user can click on the log entry to expand it.
This commit is contained in:
takase1121 2021-08-22 19:29:21 +08:00 committed by Francesco Abbate
parent 28e8a98ffc
commit afaf0a718d
1 changed files with 131 additions and 15 deletions

View File

@ -1,8 +1,37 @@
local core = require "core" local core = require "core"
local common = require "core.common"
local style = require "core.style" local style = require "core.style"
local View = require "core.view" local View = require "core.view"
local function lines(text)
if text == "" then return 0 end
local l = 1
for _ in string.gmatch(text, "\n") do
l = l + 1
end
return l
end
local item_height_result = {}
local function get_item_height(item)
local h = item_height_result[item]
if not h then
h = {}
local l = 1 + lines(item.text) + lines(item.info or "")
h.normal = style.font:get_height() + style.padding.y
h.expanded = l * style.font:get_height() + style.padding.y
h.current = h.normal
h.target = h.current
item_height_result[item] = h
end
return h
end
local LogView = View:extend() local LogView = View:extend()
LogView.context = "session" LogView.context = "session"
@ -10,6 +39,7 @@ LogView.context = "session"
function LogView:new() function LogView:new()
LogView.super.new(self) LogView.super.new(self)
self.last_item = core.log_items[#core.log_items] self.last_item = core.log_items[#core.log_items]
self.expanding = {}
self.scrollable = true self.scrollable = true
self.yoffset = 0 self.yoffset = 0
end end
@ -20,6 +50,55 @@ function LogView:get_name()
end end
local function is_expanded(item)
local item_height = get_item_height(item)
return item_height.target == item_height.expanded
end
function LogView:expand_item(item)
item = get_item_height(item)
item.target = item.target == item.expanded and item.normal or item.expanded
table.insert(self.expanding, item)
end
function LogView:each_item()
local x, y = self:get_content_offset()
y = y + style.padding.y + self.yoffset
return coroutine.wrap(function()
for i = #core.log_items, 1, -1 do
local item = core.log_items[i]
local h = get_item_height(item).current
coroutine.yield(i, item, x, y, self.size.x, h)
y = y + h
end
end)
end
function LogView:on_mouse_moved(px, py, ...)
LogView.super.on_mouse_moved(self, px, py, ...)
local hovered = false
for _, item, x, y, w, h in self:each_item() do
if px >= x and py >= y and px < x + w and py < y + h then
hovered = true
self.hovered_item = item
break
end
end
if not hovered then self.hovered_item = nil end
end
function LogView:on_mouse_pressed(button, mx, my, clicks)
if LogView.super.on_mouse_pressed(self, button, mx, my, clicks) then return end
if self.hovered_item then
self:expand_item(self.hovered_item)
end
end
function LogView:update() function LogView:update()
local item = core.log_items[#core.log_items] local item = core.log_items[#core.log_items]
if self.last_item ~= item then if self.last_item ~= item then
@ -28,6 +107,14 @@ function LogView:update()
self.yoffset = -(style.font:get_height() + style.padding.y) self.yoffset = -(style.font:get_height() + style.padding.y)
end end
local expanding = self.expanding[1]
if expanding then
self:move_towards(expanding, "current", expanding.target)
if expanding.current == expanding.target then
table.remove(self.expanding, 1)
end
end
self:move_towards("yoffset", 0) self:move_towards("yoffset", 0)
LogView.super.update(self) LogView.super.update(self)
@ -46,28 +133,57 @@ local function draw_text_multiline(font, text, x, y, color)
end end
local function draw_text_elipsis(font, color, text, x, y, w, h, elipsis_style)
elipsis_style = elipsis_style or "end"
local c = font:get_width("_")
local approxc = math.floor(w / c)
if #text > approxc then
if elipsis_style == "end" then
text = string.sub(text, 1, approxc - 3) .. "..."
elseif elipsis_style == "middle" then
local mid = math.floor(#text / 2)
text = string.sub(text, 1, mid - 3) .. "..." .. string.sub(text, mid)
end
end
return common.draw_text(font, color, text, "left", x, y, w, h)
end
function LogView:draw() function LogView:draw()
self:draw_background(style.background) self:draw_background(style.background)
local ox, oy = self:get_content_offset()
local th = style.font:get_height() local th = style.font:get_height()
local y = oy + style.padding.y + self.yoffset local lh = th + style.padding.y -- for one line
for _, item, x, y, w, h in self:each_item() do
for i = #core.log_items, 1, -1 do core.push_clip_rect(x, y, w, h)
local x = ox + style.padding.x
local item = core.log_items[i]
local time = os.date(nil, item.time)
x = renderer.draw_text(style.font, time, x, y, style.dim)
x = x + style.padding.x x = x + style.padding.x
local subx = x
x, y = draw_text_multiline(style.font, item.text, x, y, style.text) local time = os.date(nil, item.time)
renderer.draw_text(style.font, " at " .. item.at, x, y, style.dim) x = common.draw_text(style.font, style.dim, time, "left", x, y, w, lh)
x = x + style.padding.x
x = common.draw_text(style.code_font, style.dim, is_expanded(item) and "-" or "+", "left", x, y, w, lh)
x = x + style.padding.x
w = w - (x - self:get_content_offset())
if is_expanded(item) then
y = y + common.round(style.padding.y / 2)
draw_text_multiline(style.font, item.text, x, y, style.text)
y = y + th y = y + th
local at = "at " .. common.home_encode(item.at)
draw_text_elipsis(style.font, style.dim, at, x, y, w, lh, "middle")
y = y + th
if item.info then if item.info then
subx, y = draw_text_multiline(style.font, item.info, subx, y, style.dim) draw_text_multiline(style.font, item.info, x, y, style.dim)
end
else
draw_text_elipsis(style.font, style.text, item.text, x, y, w, lh)
y = y + th y = y + th
end end
y = y + style.padding.y
core.pop_clip_rect()
end end
end end