Skip to content

Commit bc18d01

Browse files
committed
Added combinedProperty "selectionColor"
Removed selectItem from ComboBox Fixed a bug in Input when manually setting text property Added a callback for Toast elements Readded the state plugin as store plugin
1 parent c91c902 commit bc18d01

7 files changed

Lines changed: 296 additions & 39 deletions

File tree

src/elements/Collection.lua

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ Collection.defineProperty(Collection, "selectedBackground", {default = colors.bl
1717
---@property selectedForeground color white Text color for selected items
1818
Collection.defineProperty(Collection, "selectedForeground", {default = colors.white, type = "color", canTriggerRender = true})
1919

20+
---@combinedProperty selectionColor {x number, y number} Combined x, y position
21+
Collection.combineProperties(Collection, "selectionColor", "selectedForeground", "selectedBackground")
22+
2023
---@event onSelect {index number, item table} Fired when an item is selected
2124

2225
--- Creates a new Collection instance
@@ -123,29 +126,20 @@ end
123126

124127
function Collection:selectItem(index)
125128
local items = self.getResolved("items")
126-
if index < 1 or index > #items then return end
127-
local _index = index
128-
if type(index) == "string" then
129+
if type(index) == "number" then
130+
if items[index] and type(items[index]) == "table" then
131+
items[index].selected = true
132+
end
133+
else
129134
for k,v in pairs(items)do
130135
if v == index then
131-
_index = k
136+
if type(v) == "table" then
137+
v.selected = true
138+
end
132139
break
133140
end
134141
end
135142
end
136-
if not self.getResolved("multiSelection") then
137-
for _, otherItem in ipairs(items) do
138-
if type(otherItem) == "table" then
139-
otherItem.selected = false
140-
end
141-
end
142-
end
143-
local item = items[_index]
144-
item.selected = true
145-
if item.callback then
146-
item.callback(self)
147-
end
148-
self:fireEvent("select", index, item)
149143
self:updateRender()
150144
return self
151145
end

src/elements/ComboBox.lua

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,6 @@ function ComboBox:init(props, basalt)
7474
return self
7575
end
7676

77-
function ComboBox:selectItem(index)
78-
DropDown.selectItem(self, index)
79-
local selectedItem = self:getSelectedItem()
80-
if selectedItem and selectedItem.text then
81-
self.set("text", selectedItem.text)
82-
self.set("cursorPos", #selectedItem.text + 1)
83-
self:updateViewport()
84-
end
85-
self:updateRender()
86-
end
87-
8877
--- Filters items based on current text for auto-complete
8978
--- @shortDescription Filters items for auto-complete
9079
--- @private

src/elements/Input.lua

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@ local Input = setmetatable({}, VisualElement)
99
Input.__index = Input
1010

1111
---@property text string - The current text content of the input
12-
Input.defineProperty(Input, "text", {default = "", type = "string", canTriggerRender = true})
12+
Input.defineProperty(Input, "text", {
13+
default = "",
14+
type = "string",
15+
canTriggerRender = true,
16+
setter = function(self, value)
17+
self.set("cursorPos", math.min(#value + 1, self.getResolved("cursorPos")))
18+
self:updateViewport()
19+
return value
20+
end
21+
})
1322
---@property cursorPos number 1 The current cursor position in the text
1423
Input.defineProperty(Input, "cursorPos", {default = 1, type = "number"})
1524
---@property viewOffset number 0 The horizontal scroll offset for viewing long text
@@ -122,6 +131,20 @@ function Input:key(key, held)
122131
self:updateRender()
123132
self:updateViewport()
124133
end
134+
elseif key == keys.delete then
135+
if pos <= #text then
136+
self.set("text", text:sub(1, pos-1) .. text:sub(pos+1))
137+
self:updateRender()
138+
self:updateViewport()
139+
end
140+
elseif key == keys.home then
141+
self.set("cursorPos", 1)
142+
self.set("viewOffset", 0)
143+
elseif key == keys["end"] then
144+
self.set("cursorPos", #text + 1)
145+
self:set("viewOffset", math.max(0, #text - width + 1))
146+
elseif key == keys.enter then
147+
self:fireEvent("submit", self.getResolved("text"))
125148
end
126149

127150
local relativePos = self.getResolved("cursorPos") - self.getResolved("viewOffset")
@@ -174,6 +197,15 @@ function Input:updateViewport()
174197
return self
175198
end
176199

200+
--- Registers a callback for the submit event
201+
--- @shortDescription Registers a callback for the submit event
202+
--- @param callback function The callback function to register
203+
--- @return Input self The Input instance
204+
function Input:onSubmit(callback)
205+
self:registerCallback("submit", callback)
206+
return self
207+
end
208+
177209
--- @shortDescription Handles a focus event
178210
--- @protected
179211
function Input:focus()

src/elements/Program.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ function BasaltProgram:run(path, width, height)
145145
local errorCallback = self.program.get("errorCallback")
146146
if errorCallback then
147147
local trace = debug.traceback(self.coroutine, result)
148+
if trace == nil then trace = "" end
149+
result = result or "Unknown error"
148150
local _result = errorCallback(self.program, result, trace:gsub(result, ""))
149151
if(_result==false)then
150152
self.filter = nil

src/elements/Toast.lua

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ Toast.defineProperty(Toast, "duration", {default = 3, type = "number"})
2121
---@property toastType string "default" Type of toast: default, success, error, warning, info
2222
Toast.defineProperty(Toast, "toastType", {default = "default", type = "string", canTriggerRender = true})
2323

24+
---@property callback function nil Callback function to call when the toast hides
25+
Toast.defineProperty(Toast, "callback", {default = nil, type = "function"})
26+
2427
---@property autoHide boolean true Whether the toast should automatically hide after duration
2528
Toast.defineProperty(Toast, "autoHide", {default = true, type = "boolean"})
2629

@@ -70,8 +73,9 @@ end
7073
--- @param titleOrMessage string The title (if message provided) or the message (if no message)
7174
--- @param messageOrDuration? string|number The message (if string) or duration (if number)
7275
--- @param duration? number Duration in seconds
76+
--- @param callback? function Callback function to call when the toast hides
7377
--- @return Toast self The Toast instance
74-
function Toast:show(titleOrMessage, messageOrDuration, duration)
78+
function Toast:show(titleOrMessage, messageOrDuration, duration, callback)
7579
local title, message, dur
7680
if type(messageOrDuration) == "string" then
7781
title = titleOrMessage
@@ -90,6 +94,7 @@ function Toast:show(titleOrMessage, messageOrDuration, duration)
9094
self.set("title", title)
9195
self.set("message", message)
9296
self.set("active", true)
97+
self.set("callback", callback)
9398

9499
if self._hideTimerId then
95100
os.cancelTimer(self._hideTimerId)
@@ -123,43 +128,47 @@ end
123128
--- @param titleOrMessage string The title or message
124129
--- @param messageOrDuration? string|number The message or duration
125130
--- @param duration? number Duration in seconds
131+
--- @param callback? function Callback function to call when the toast hides
126132
--- @return Toast self The Toast instance
127-
function Toast:success(titleOrMessage, messageOrDuration, duration)
133+
function Toast:success(titleOrMessage, messageOrDuration, duration, callback)
128134
self.set("toastType", "success")
129-
return self:show(titleOrMessage, messageOrDuration, duration)
135+
return self:show(titleOrMessage, messageOrDuration, duration, callback)
130136
end
131137

132138
--- Shows an error toast
133139
--- @shortDescription Shows an error toast
134140
--- @param titleOrMessage string The title or message
135141
--- @param messageOrDuration? string|number The message or duration
136142
--- @param duration? number Duration in seconds
143+
--- @param callback? function Callback function to call when the toast hides
137144
--- @return Toast self The Toast instance
138-
function Toast:error(titleOrMessage, messageOrDuration, duration)
145+
function Toast:error(titleOrMessage, messageOrDuration, duration, callback)
139146
self.set("toastType", "error")
140-
return self:show(titleOrMessage, messageOrDuration, duration)
147+
return self:show(titleOrMessage, messageOrDuration, duration, callback)
141148
end
142149

143150
--- Shows a warning toast
144151
--- @shortDescription Shows a warning toast
145152
--- @param titleOrMessage string The title or message
146153
--- @param messageOrDuration? string|number The message or duration
147154
--- @param duration? number Duration in seconds
155+
--- @param callback? function Callback function to call when the toast hides
148156
--- @return Toast self The Toast instance
149-
function Toast:warning(titleOrMessage, messageOrDuration, duration)
157+
function Toast:warning(titleOrMessage, messageOrDuration, duration, callback)
150158
self.set("toastType", "warning")
151-
return self:show(titleOrMessage, messageOrDuration, duration)
159+
return self:show(titleOrMessage, messageOrDuration, duration, callback)
152160
end
153161

154162
--- Shows an info toast
155163
--- @shortDescription Shows an info toast
156164
--- @param titleOrMessage string The title or message
157165
--- @param messageOrDuration? string|number The message or duration
158166
--- @param duration? number Duration in seconds
167+
--- @param callback? function Callback function to call when the toast hides
159168
--- @return Toast self The Toast instance
160-
function Toast:info(titleOrMessage, messageOrDuration, duration)
169+
function Toast:info(titleOrMessage, messageOrDuration, duration, callback)
161170
self.set("toastType", "info")
162-
return self:show(titleOrMessage, messageOrDuration, duration)
171+
return self:show(titleOrMessage, messageOrDuration, duration, callback)
163172
end
164173

165174
--- @shortDescription Dispatches events to the Toast instance
@@ -169,6 +178,11 @@ function Toast:dispatchEvent(event, ...)
169178
if event == "timer" then
170179
local timerId = select(1, ...)
171180
if timerId == self._hideTimerId then
181+
self._hideTimerId = nil
182+
local callback = self.getResolved("callback")
183+
if callback then
184+
callback(self)
185+
end
172186
self:hide()
173187
end
174188
end

src/elements/VisualElement.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ end
162162
--- @param offset number The offset to apply (negative = inside, positive = outside, fractional = percentage)
163163
--- @return VisualElement self The element instance
164164
function VisualElement:setConstraint(property, targetElement, targetProperty, offset)
165-
local constraints = self.getResolved("constraints")
165+
local constraints = self.get("constraints")
166166
if constraints[property] then
167167
self:_removeConstraintObservers(property, constraints[property])
168168
end

0 commit comments

Comments
 (0)