Skip to content

Commit 0d4fc27

Browse files
authored
Enhance VisualElement with border properties
Added properties for border customization and updated rendering logic.
1 parent 64cb9c8 commit 0d4fc27

File tree

1 file changed

+82
-9
lines changed

1 file changed

+82
-9
lines changed

src/elements/VisualElement.lua

Lines changed: 82 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
---@diagnostic disable: duplicate-set-field, undefined-field, undefined-doc-name, param-type-mismatch, redundant-return-value
12
local elementManager = require("elementManager")
23
local BaseElement = elementManager.getElement("BaseElement")
34
local tHex = require("libraries/colorHex")
@@ -35,6 +36,16 @@ VisualElement.defineProperty(VisualElement, "clicked", {default = false, type =
3536
VisualElement.defineProperty(VisualElement, "hover", {default = false, type = "boolean"})
3637
---@property backgroundEnabled boolean true Whether to render the background
3738
VisualElement.defineProperty(VisualElement, "backgroundEnabled", {default = true, type = "boolean", canTriggerRender = true})
39+
---@property borderTop boolean false Draw top border
40+
VisualElement.defineProperty(VisualElement, "borderTop", {default = false, type = "boolean", canTriggerRender = true})
41+
---@property borderBottom boolean false Draw bottom border
42+
VisualElement.defineProperty(VisualElement, "borderBottom", {default = false, type = "boolean", canTriggerRender = true})
43+
---@property borderLeft boolean false Draw left border
44+
VisualElement.defineProperty(VisualElement, "borderLeft", {default = false, type = "boolean", canTriggerRender = true})
45+
---@property borderRight boolean false Draw right border
46+
VisualElement.defineProperty(VisualElement, "borderRight", {default = false, type = "boolean", canTriggerRender = true})
47+
---@property borderColor color white Border color
48+
VisualElement.defineProperty(VisualElement, "borderColor", {default = colors.white, type = "color", canTriggerRender = true})
3849
---@property focused boolean false Whether the element has input focus
3950
VisualElement.defineProperty(VisualElement, "focused", {default = false, type = "boolean", setter = function(self, value, internal)
4051
local curValue = self.get("focused")
@@ -295,9 +306,7 @@ end
295306
---@return boolean hover Whether the mouse has moved over the element
296307
--- @protected
297308
function VisualElement:mouse_move(_, x, y)
298-
if(x==nil)or(y==nil)then
299-
return
300-
end
309+
if(x==nil)or(y==nil)then return false end
301310
local hover = self.get("hover")
302311
if(self:isInBounds(x, y))then
303312
if(not hover)then
@@ -352,7 +361,49 @@ end
352361
--- @protected
353362
function VisualElement:blur()
354363
self:fireEvent("blur")
355-
self:setCursor(1,1, false)
364+
-- Attempt to clear cursor; signature may expect (x,y,blink,fg,bg)
365+
pcall(function() self:setCursor(1,1,false, self.get and self.get("foreground")) end)
366+
end
367+
368+
--- Adds or updates a drawable character border around the element using the canvas plugin.
369+
--- The border will automatically adapt to size/background changes because the command
370+
--- reads current properties each render.
371+
-- @param colorOrOptions any Border color or options table
372+
--- @return VisualElement self
373+
function VisualElement:addBorder(colorOrOptions, sideOptions)
374+
local col = nil
375+
local spec = nil
376+
if type(colorOrOptions) == "table" and (colorOrOptions.color or colorOrOptions.top ~= nil or colorOrOptions.left ~= nil) then
377+
col = colorOrOptions.color
378+
spec = colorOrOptions
379+
else
380+
col = colorOrOptions
381+
spec = sideOptions
382+
end
383+
if spec then
384+
if spec.top ~= nil then self.set("borderTop", spec.top) end
385+
if spec.bottom ~= nil then self.set("borderBottom", spec.bottom) end
386+
if spec.left ~= nil then self.set("borderLeft", spec.left) end
387+
if spec.right ~= nil then self.set("borderRight", spec.right) end
388+
else
389+
-- default: enable all sides
390+
self.set("borderTop", true)
391+
self.set("borderBottom", true)
392+
self.set("borderLeft", true)
393+
self.set("borderRight", true)
394+
end
395+
if col then self.set("borderColor", col) end
396+
return self
397+
end
398+
399+
--- Removes the previously added border (if any)
400+
--- @return VisualElement self
401+
function VisualElement:removeBorder()
402+
self.set("borderTop", false)
403+
self.set("borderBottom", false)
404+
self.set("borderLeft", false)
405+
self.set("borderRight", false)
406+
return self
356407
end
357408

358409
--- @shortDescription Handles a key event
@@ -480,11 +531,33 @@ end
480531
--- @shortDescription Renders the element
481532
--- @protected
482533
function VisualElement:render()
483-
if(not self.get("backgroundEnabled"))then
484-
return
485-
end
534+
if(not self.get("backgroundEnabled"))then return end
486535
local width, height = self.get("width"), self.get("height")
487-
self:multiBlit(1, 1, width, height, " ", tHex[self.get("foreground")], tHex[self.get("background")])
536+
local fgHex = tHex[self.get("foreground")]
537+
local bgHex = tHex[self.get("background")]
538+
self:multiBlit(1, 1, width, height, " ", fgHex, bgHex)
539+
-- Draw integrated border after background fill
540+
if (self.get("borderTop") or self.get("borderBottom") or self.get("borderLeft") or self.get("borderRight")) then
541+
local bColor = self.get("borderColor") or self.get("foreground")
542+
local bHex = tHex[bColor] or fgHex
543+
if self.get("borderTop") then
544+
self:textFg(1,1,("\131"):rep(width), bColor)
545+
end
546+
if self.get("borderBottom") then
547+
self:multiBlit(1,height,width,1,"\143", bgHex, bHex)
548+
end
549+
if self.get("borderLeft") then
550+
self:multiBlit(1,1,1,height,"\149", bHex, bgHex)
551+
end
552+
if self.get("borderRight") then
553+
self:multiBlit(width,1,1,height,"\149", bgHex, bHex)
554+
end
555+
-- Corners
556+
if self.get("borderTop") and self.get("borderLeft") then self:blit(1,1,"\151", bHex, bgHex) end
557+
if self.get("borderTop") and self.get("borderRight") then self:blit(width,1,"\148", bgHex, bHex) end
558+
if self.get("borderBottom") and self.get("borderLeft") then self:blit(1,height,"\138", bgHex, bHex) end
559+
if self.get("borderBottom") and self.get("borderRight") then self:blit(width,height,"\133", bgHex, bHex) end
560+
end
488561
end
489562

490563
--- @shortDescription Post-rendering function for the element
@@ -497,4 +570,4 @@ function VisualElement:destroy()
497570
BaseElement.destroy(self)
498571
end
499572

500-
return VisualElement
573+
return VisualElement

0 commit comments

Comments
 (0)