Files
deb-lite-xl/data/core/logview.lua
T
takase1121andFrancesco Abbate afaf0a718d 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.
2021-09-07 14:59:03 +02:00

192 lines
4.6 KiB
Lua

local core = require "core"
local common = require "core.common"
local style = require "core.style"
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()
LogView.context = "session"
function LogView:new()
LogView.super.new(self)
self.last_item = core.log_items[#core.log_items]
self.expanding = {}
self.scrollable = true
self.yoffset = 0
end
function LogView:get_name()
return "Log"
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()
local item = core.log_items[#core.log_items]
if self.last_item ~= item then
self.last_item = item
self.scroll.to.y = 0
self.yoffset = -(style.font:get_height() + style.padding.y)
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)
LogView.super.update(self)
end
local function draw_text_multiline(font, text, x, y, color)
local th = font:get_height()
local resx, resy = x, y
for line in text:gmatch("[^\n]+") do
resy = y
resx = renderer.draw_text(style.font, line, x, y, color)
y = y + th
end
return resx, resy
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()
self:draw_background(style.background)
local th = style.font:get_height()
local lh = th + style.padding.y -- for one line
for _, item, x, y, w, h in self:each_item() do
core.push_clip_rect(x, y, w, h)
x = x + style.padding.x
local time = os.date(nil, item.time)
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
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
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
end
core.pop_clip_rect()
end
end
return LogView