statusview: respect right padding of item tooltip

When the tooltip was rendered on the last item of right items the right
padding was not properly getting accounted as part of the tooltip width.

This commit also fixes:

* Passing StatusView to item.get_item() instead of StatusView.item
* Some adjustments to annotations.
This commit is contained in:
jgmdev 2022-11-24 12:30:03 -04:00
parent 718791857b
commit 0373d29f99
1 changed files with 62 additions and 71 deletions

View File

@ -11,26 +11,27 @@ local Object = require "core.object"
---@alias core.statusview.styledtext table<integer, renderer.font|renderer.color|string> ---@alias core.statusview.styledtext table<integer, renderer.font|renderer.color|string>
---@alias core.statusview.position '"left"' | '"right"'
---A status bar implementation for lite, check core.status_view. ---A status bar implementation for lite, check core.status_view.
---@class core.statusview : core.view ---@class core.statusview : core.view
---@field public super core.view ---@field super core.view
---@field private items core.statusview.item[] ---@field items core.statusview.item[]
---@field private active_items core.statusview.item[] ---@field active_items core.statusview.item[]
---@field private hovered_item core.statusview.item ---@field hovered_item core.statusview.item
---@field private message_timeout number ---@field message_timeout number
---@field private message core.statusview.styledtext ---@field message core.statusview.styledtext
---@field private tooltip_mode boolean ---@field tooltip_mode boolean
---@field private tooltip core.statusview.styledtext ---@field tooltip core.statusview.styledtext
---@field private left_width number ---@field left_width number
---@field private right_width number ---@field right_width number
---@field private r_left_width number ---@field r_left_width number
---@field private r_right_width number ---@field r_right_width number
---@field private left_xoffset number ---@field left_xoffset number
---@field private right_xoffset number ---@field right_xoffset number
---@field private dragged_panel '"left"' | '"right"' ---@field dragged_panel '""' | core.statusview.position
---@field private hovered_panel '"left"' | '"right"' ---@field hovered_panel '""' | core.statusview.position
---@field private hide_messages boolean ---@field hide_messages boolean
local StatusView = View:extend() local StatusView = View:extend()
---Space separator ---Space separator
@ -42,81 +43,73 @@ StatusView.separator = " "
StatusView.separator2 = " | " StatusView.separator2 = " | "
---@alias core.statusview.item.separator ---@alias core.statusview.item.separator
---|>'core.statusview.separator' # Space separator ---|>`StatusView.separator`
---| 'core.statusview.separator2' # Pipe separator ---| `StatusView.separator2`
---@alias core.statusview.item.predicate fun():boolean ---@alias core.statusview.item.predicate fun():boolean
---@alias core.statusview.item.onclick fun(button: string, x: number, y: number) ---@alias core.statusview.item.onclick fun(button: string, x: number, y: number)
---@alias core.statusview.item.get_item fun():core.statusview.styledtext,core.statusview.styledtext ---@alias core.statusview.item.get_item fun(self: core.statusview.item):core.statusview.styledtext?,core.statusview.styledtext?
---@alias core.statusview.item.ondraw fun(x, y, h, hovered: boolean, calc_only?: boolean):number ---@alias core.statusview.item.ondraw fun(x, y, h, hovered: boolean, calc_only?: boolean):number
---@class core.statusview.item : core.object ---@class core.statusview.item : core.object
---@field name string ---@field name string
---@field predicate core.statusview.item.predicate ---@field predicate core.statusview.item.predicate
---@field alignment core.statusview.item.alignment ---@field alignment core.statusview.item.alignment
---@field tooltip string | nil ---@field tooltip string
---@field command string | nil @Command to perform when the item is clicked. ---@field command string | nil @Command to perform when the item is clicked.
---@field on_click core.statusview.item.onclick | nil @Function called when item is clicked and no command is set. ---Function called when item is clicked and no command is set.
---@field on_draw core.statusview.item.ondraw | nil @Custom drawing that when passed calc true should return the needed width for drawing and when false should draw. ---@field on_click core.statusview.item.onclick | nil
---Custom drawing that when passed calc true should return the needed width for
---drawing and when false should draw.
---@field on_draw core.statusview.item.ondraw | nil
---@field background_color renderer.color | nil ---@field background_color renderer.color | nil
---@field background_color_hover renderer.color | nil ---@field background_color_hover renderer.color | nil
---@field visible boolean ---@field visible boolean
---@field separator core.statusview.item.separator ---@field separator core.statusview.item.separator
---@field private active boolean ---@field active boolean
---@field private x number ---@field x number
---@field private w number ---@field w number
---@field private cached_item core.statusview.styledtext ---@field cached_item core.statusview.styledtext
local StatusViewItem = Object:extend() local StatusViewItem = Object:extend()
---Available StatusViewItem options. ---Available StatusViewItem options.
---@class core.statusview.item.options : table ---@class core.statusview.item.options : table
---A condition to evaluate if the item should be displayed. If a string
---is given it is treated as a require import that should return a valid object
---which is checked against the current active view, the sames applies if a
---table is given. A function that returns a boolean can be used instead to
---perform a custom evaluation, setting to nil means always evaluates to true.
---@field predicate string | table | core.statusview.item.predicate ---@field predicate string | table | core.statusview.item.predicate
---@field name string ---A unique name to identify the item on the status bar.
---@field name string @A unique name to identify the item on the status bar.
---@field alignment core.statusview.item.alignment ---@field alignment core.statusview.item.alignment
---A function that should return a core.statusview.styledtext element,
---returning an empty table is allowed.
---@field get_item core.statusview.item.get_item ---@field get_item core.statusview.item.get_item
---@field command? string | core.statusview.item.onclick ---The name of a valid registered command or a callback function to execute
---when the item is clicked.
---@field command string | core.statusview.item.onclick | nil
---The position in which to insert the given item on the internal table,
---a value of -1 inserts the item at the end which is the default. A value
---of 1 will insert the item at the beggining.
---@field position? integer ---@field position? integer
---@field tooltip? string ---@field tooltip? string @Text displayed when mouse hovers the item.
---@field visible boolean @Flag to show or hide the item
---The type of separator rendered to the right of the item if another item
---follows it.
---@field separator? core.statusview.item.separator ---@field separator? core.statusview.item.separator
local StatusViewItemOptions = {
---A condition to evaluate if the item should be displayed. If a string
---is given it is treated as a require import that should return a valid object
---which is checked against the current active view, the sames applies if a
---table is given. A function that returns a boolean can be used instead to
---perform a custom evaluation, setting to nil means always evaluates to true.
predicate = nil,
---A unique name to identify the item on the status bar.
name = nil,
alignment = nil,
---A function that should return a core.statusview.styledtext element,
---returning empty table is allowed.
get_item = nil,
---The name of a valid registered command or a callback function to execute
---when the item is clicked.
command = nil,
---The position in which to insert the given item on the internal table,
---a value of -1 inserts the item at the end which is the default. A value
---of 1 will insert the item at the beggining.
position = nil,
---Displayed when mouse hovers the item
tooltip = nil,
separator = nil,
}
StatusViewItem.options = StatusViewItemOptions
---Flag to tell the item should me aligned on left side of status bar. ---Flag to tell the item should me aligned on left side of status bar.
---@type number ---@type integer
StatusViewItem.LEFT = 1 StatusViewItem.LEFT = 1
---Flag to tell the item should me aligned on right side of status bar. ---Flag to tell the item should me aligned on right side of status bar.
---@type number ---@type integer
StatusViewItem.RIGHT = 2 StatusViewItem.RIGHT = 2
---@alias core.statusview.item.alignment ---@alias core.statusview.item.alignment
---|>'core.statusview.item.LEFT' ---|>`StatusView.Item.LEFT`
---| 'core.statusview.item.RIGHT' ---| `StatusView.Item.RIGHT`
---Constructor ---Constructor
---@param options core.statusview.item.options ---@param options core.statusview.item.options
@ -470,7 +463,7 @@ end
---Hides the given items from the status view or all if no names given. ---Hides the given items from the status view or all if no names given.
---@param names table<integer, string> | string | nil ---@param names? table<integer, string> | string
function StatusView:hide_items(names) function StatusView:hide_items(names)
if type(names) == "string" then if type(names) == "string" then
names = {names} names = {names}
@ -489,7 +482,7 @@ end
---Shows the given items from the status view or all if no names given. ---Shows the given items from the status view or all if no names given.
---@param names table<integer, string> | string | nil ---@param names? table<integer, string> | string
function StatusView:show_items(names) function StatusView:show_items(names)
if type(names) == "string" then if type(names) == "string" then
names = {names} names = {names}
@ -607,8 +600,8 @@ function StatusView:draw_item_tooltip(item)
local x = self.pointer.x - (w / 2) - (style.padding.x * 2) local x = self.pointer.x - (w / 2) - (style.padding.x * 2)
if x < 0 then x = 0 end if x < 0 then x = 0 end
if x + w + (style.padding.x * 2) > self.size.x then if (x + w + (style.padding.x * 3)) > self.size.x then
x = self.size.x - w - (style.padding.x * 2) x = self.size.x - w - (style.padding.x * 3)
end end
renderer.draw_rect( renderer.draw_rect(
@ -783,7 +776,7 @@ function StatusView:update_active_items()
item.cached_item = {} item.cached_item = {}
if item.visible and item:predicate() then if item.visible and item:predicate() then
local styled_text = type(item.get_item) == "function" local styled_text = type(item.get_item) == "function"
and item.get_item(self) or item.get_item and item.get_item(item) or item.get_item
if #styled_text > 0 then if #styled_text > 0 then
remove_spacing(self, styled_text) remove_spacing(self, styled_text)
@ -881,7 +874,7 @@ end
---Drag the given panel if possible. ---Drag the given panel if possible.
---@param panel '"left"' | '"right"' ---@param panel core.statusview.position
---@param dx number ---@param dx number
function StatusView:drag_panel(panel, dx) function StatusView:drag_panel(panel, dx)
if panel == "left" and self.r_left_width > self.left_width then if panel == "left" and self.r_left_width > self.left_width then
@ -915,10 +908,8 @@ end
function StatusView:get_hovered_panel(x, y) function StatusView:get_hovered_panel(x, y)
if y >= self.position.y and x <= self.left_width + style.padding.x then if y >= self.position.y and x <= self.left_width + style.padding.x then
return "left" return "left"
else
return "right"
end end
return "" return "right"
end end
@ -1054,7 +1045,7 @@ end
function StatusView:on_mouse_wheel(y, x) function StatusView:on_mouse_wheel(y, x)
if not self.visible then return end if not self.visible or self.hovered_panel == "" then return end
if x ~= 0 then if x ~= 0 then
self:drag_panel(self.hovered_panel, x * self.left_width / 10) self:drag_panel(self.hovered_panel, x * self.left_width / 10)
else else