From 602cf48de740ce349ccfbfaf00d3d90f28dfd3b6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 27 Sep 2025 20:42:40 +0000 Subject: [PATCH] Update config, BasaltLS definitions, bundle and changelog --- BasaltLS.lua | 7602 +++++++++++++++++++++++--------------------- config.lua | 692 ++-- release/basalt.lua | 6013 ++++++++++++++++++----------------- 3 files changed, 7388 insertions(+), 6919 deletions(-) diff --git a/BasaltLS.lua b/BasaltLS.lua index 12ef464..ca8e169 100644 --- a/BasaltLS.lua +++ b/BasaltLS.lua @@ -1,546 +1,76 @@ ---@meta ----@class AnimationInstance -local AnimationInstance = {} +---@class Animation +local Animation = {} + +---Adds a new animation to the sequence +---@param type string The type of animation +---@param args table The animation arguments +---@param duration number The duration in seconds +---@param easing string The easing function name +function Animation:addAnimation(type, args, duration, easing) end + +---Registers a callback for the complete event +---@param callback function The callback function to register +---@return Animation self The animation instance +function Animation:onComplete(callback) end + +---Stops the animation immediately: cancels timers, completes running anim instances and clears the element property +function Animation:stop() end + +---Creates a new Animation +---@param element VisualElement The element to animate +---@return Animation The new animation +function Animation.new(element) end + +---Registers a new animation type +---@param name string The name of the animation +---@param handlers table Table containing start, update and complete handlers +function Animation.registerAnimation(name, handlers) end ---Starts the animation ----@return AnimationInstance self The animation instance -function AnimationInstance:start() end +---@return Animation self The animation instance +function Animation:start() end ----Gets called when the animation is completed -function AnimationInstance:complete() end - ----Updates the animation ----@param elapsed number The elapsed time in seconds ----@return boolean Whether the animation is finished -function AnimationInstance:update(elapsed) end - ----Creates a new AnimationInstance ----@param element VisualElement The element to animate ----@param animType string The type of animation ----@param args table The animation arguments ----@param duration number Duration in seconds ----@param easing string The easing function name ----@return AnimationInstance The new animation instance -function AnimationInstance.new(element, animType, args, duration, easing) end - ----@class Switch : VisualElement ----@field offBackground number color when OFF ----@field text string to display next to switch ----@field checked boolean switch is checked ----@field autoSize boolean to automatically size the element to fit switch and text ----@field onBackground number color when ON -local Switch = {} - ----Gets the value of the AutoSize property. ----@param self Switch self ----@return boolean Whether to automatically size the element to fit switch and text -function Switch:getAutoSize(self) end - ----Gets the value of the Checked property. ----@param self Switch self ----@return boolean Whether switch is checked -function Switch:getChecked(self) end - ----Sets the value of the AutoSize property. ----@param self Switch self ----@param AutoSize boolean to automatically size the element to fit switch and text -function Switch:setAutoSize(self, AutoSize) end - ----Sets the value of the OffBackground property. ----@param self Switch self ----@param OffBackground number color when OFF -function Switch:setOffBackground(self, OffBackground) end - ----Gets the value of the OffBackground property. ----@param self Switch self ----@return number Background color when OFF -function Switch:getOffBackground(self) end - ----Sets the value of the Checked property. ----@param self Switch self ----@param Checked boolean switch is checked -function Switch:setChecked(self, Checked) end - ----Sets the value of the Text property. ----@param self Switch self ----@param Text string to display next to switch -function Switch:setText(self, Text) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean Whether the event was handled ----@protected -function Switch:mouse_click(button, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Switch:render() end - ----Sets the value of the OnBackground property. ----@param self Switch self ----@param OnBackground number color when ON -function Switch:setOnBackground(self, OnBackground) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function Switch:init(props, basalt) end - ----Gets the value of the OnBackground property. ----@param self Switch self ----@return number Background color when ON -function Switch:getOnBackground(self) end - ----Gets the value of the Text property. ----@param self Switch self ----@return string Text to display next to switch -function Switch:getText(self) end - ----@class Image : VisualElement ----@field currentFrame number Current animation frame ----@field offsetX number Horizontal offset for viewing larger images ----@field bimg table The bimg image data ----@field offsetY number Vertical offset for viewing larger images ----@field autoResize boolean Whether to automatically resize the image when content exceeds bounds -local Image = {} - ----Gets the value of the Bimg property. ----@param self Image self ----@return table {} The bimg image data -function Image:getBimg(self) end - ----Sets the foreground color at the specified position ----@param x number The x position ----@param y number The y position ----@param pattern string The foreground color pattern ----@return Image self The Image instance -function Image:setFg(x, y, pattern) end - ----Gets the text at the specified position ----@param x number The x position ----@param y number The y position ----@param length number The length of the text to get ----@return string text The text at the specified position -function Image:getText(x, y, length) end - ----Sets the value of the Bimg property. ----@param self Image self ----@param Bimg table The bimg image data -function Image:setBimg(self, Bimg) end - ----Gets the value of the AutoResize property. ----@param self Image self ----@return boolean false Whether to automatically resize the image when content exceeds bounds -function Image:getAutoResize(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Image:render() end - ----Sets the background color at the specified position ----@param x number The x position ----@param y number The y position ----@param pattern string The background color pattern ----@return Image self The Image instance -function Image:setBg(x, y, pattern) end - ----Advances to the next frame in the animation ----@return Image self The Image instance -function Image:nextFrame() end - ----Sets the metadata of the image ----@param key string The key of the metadata to set ----@param value string The value of the metadata to set ----@return Image self The Image instance -function Image:setMetadata(key, value) end - ----Gets the metadata of the image ----@return table metadata The metadata of the image -function Image:getMetadata() end - ----Gets the specified frame ----@param frameIndex number The index of the frame to get ----@return table frame The frame data -function Image:getFrame(frameIndex) end - ----Updates the specified frame with the provided data ----@param frameIndex number The index of the frame to update ----@param frame table The new frame data ----@return Image self The Image instance -function Image:updateFrame(frameIndex, frame) end - ----Sets the value of the OffsetY property. ----@param self Image self ----@param OffsetY number Vertical offset for viewing larger images -function Image:setOffsetY(self, OffsetY) end - ----Sets the value of the AutoResize property. ----@param self Image self ----@param AutoResize boolean Whether to automatically resize the image when content exceeds bounds -function Image:setAutoResize(self, AutoResize) end - ----Gets the value of the OffsetX property. ----@param self Image self ----@return number 0 Horizontal offset for viewing larger images -function Image:getOffsetX(self) end - ----Adds a new frame to the image ----@return Image self The Image instance -function Image:addFrame() end - ----Sets the pixel at the specified position ----@param x number The x position ----@param y number The y position ----@param char string The character to set ----@param fg string The foreground color pattern ----@param bg string The background color pattern ----@return Image self The Image instance -function Image:setPixel(x, y, char, fg, bg) end - ----Gets the value of the OffsetY property. ----@param self Image self ----@return number 0 Vertical offset for viewing larger images -function Image:getOffsetY(self) end - ----Gets the background color at the specified position ----@param x number The x position ----@param y number The y position ----@param length number The length of the background color pattern to get ----@return string bg The background color pattern -function Image:getBg(x, y, length) end - ----Sets the value of the CurrentFrame property. ----@param self Image self ----@param CurrentFrame number Current animation frame -function Image:setCurrentFrame(self, CurrentFrame) end - ----Sets the value of the OffsetX property. ----@param self Image self ----@param OffsetX number Horizontal offset for viewing larger images -function Image:setOffsetX(self, OffsetX) end - ----Gets the size of the image ----@return number width The width of the image ----@return number height The height of the image -function Image:getImageSize() end - ----Gets the value of the CurrentFrame property. ----@param self Image self ----@return number 1 Current animation frame -function Image:getCurrentFrame(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Image self The initialized instance ----@protected -function Image:init(props, basalt) end - ----Sets the text at the specified position ----@param x number The x position ----@param y number The y position ----@param text string The text to set ----@return Image self The Image instance -function Image:setText(x, y, text) end - ----Gets pixel information at position ----@param x number X position ----@param y number Y position ----@return number ? fg Foreground color ----@return number ? bg Background color ----@return string ? char Character at position -function Image:getPixelData(x, y) end - ----Gets the foreground color at the specified position ----@param x number The x position ----@param y number The y position ----@param length number The length of the foreground color pattern to get ----@return string fg The foreground color pattern -function Image:getFg(x, y, length) end - ----Resizes the image to the specified width and height ----@param width number The new width of the image ----@param height number The new height of the image ----@return Image self The Image instance -function Image:resizeImage(width, height) end - ----@class List : VisualElement ----@field selectedBackground color Background color for selected items ----@field multiSelection boolean Whether multiple items can be selected at once ----@field offset number Current scroll offset for viewing long lists ----@field selectable boolean Whether items in the list can be selected ----@field items table List of items to display. Items can be tables with properties including selected state ----@field selectedForeground color Text color for selected items -local List = {} - ----Sets the value of the SelectedBackground property. ----@param self List self ----@param SelectedBackground color Background color for selected items -function List:setSelectedBackground(self, SelectedBackground) end - ----Gets the currently selected items ----@return table selected List of selected items -function List:getSelectedItems() end - ----Scrolls the list to the top ----@return List self The List instance -function List:scrollToTop() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The direction of the scroll (1 for down, -1 for up) ----@param x number The x-coordinate of the scroll ----@param y number The y-coordinate of the scroll ----@return boolean Whether the event was handled ----@protected -function List:mouse_scroll(direction, x, y) end - ----Gets first selected item ----@return table ? selected The first item -function List:getSelectedItem() end - ----Sets the value of the Selectable property. ----@param self List self ----@param Selectable boolean Whether items in the list can be selected -function List:setSelectable(self, Selectable) end - ----Scrolls the list to the bottom ----@return List self The List instance -function List:scrollToBottom() end - ----Sets the value of the Items property. ----@param self List self ----@param Items table List of items to display. Items can be tables with properties including selected state -function List:setItems(self, Items) end - ----Gets the value of the SelectedBackground property. ----@param self List self ----@return color blue Background color for selected items -function List:getSelectedBackground(self) end - ----Gets the value of the Offset property. ----@param self List self ----@return number 0 Current scroll offset for viewing long lists -function List:getOffset(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return List self The initialized instance ----@protected -function List:init(props, basalt) end - ----Sets the value of the SelectedForeground property. ----@param self List self ----@param SelectedForeground color Text color for selected items -function List:setSelectedForeground(self, SelectedForeground) end - ----Adds an item to the list ----@param text string |table The item to add (string or item table) ----@return List self The List instance -function List:addItem(text) end - ----Gets the value of the Items property. ----@param self List self ----@return table {} List of items to display. Items can be tables with properties including selected state -function List:getItems(self) end - ----Removes an item from the list ----@param index number The index of the item to remove ----@return List self The List instance -function List:removeItem(index) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function List:render() end - ----Registers a callback for the select event +---Registers a callback for the start event ---@param callback function The callback function to register ----@return List self The List instance -function List:onSelect(callback) end +function Animation:onStart(callback) end ----Gets the value of the MultiSelection property. ----@param self List self ----@return boolean false Whether multiple items can be selected at once -function List:getMultiSelection(self) end +---Registers a new easing function +---@param name string The name of the easing function +---@param func function The easing function (takes progress 0-1, returns modified progress) +function Animation.registerEasing(name, func) end ----Registers a function to handle the onSelect event. ----@param index number ----@param item table ----@param self List self ----@param func function The function to be called when the event fires -function List:onOnSelect(self, func) end +---The event handler for the animation (listens to timer events) +---@param event string The event type +---@param timerId number The timer ID +function Animation:event(event, timerId) end ----Clears all items from the list ----@return List self The List instance -function List:clear() end +---Registers a callback for the update event +---@param callback function The callback function to register +---@return Animation self The animation instance +function Animation:onUpdate(callback) end ----Sets the value of the MultiSelection property. ----@param self List self ----@param MultiSelection boolean Whether multiple items can be selected at once -function List:setMultiSelection(self, MultiSelection) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button that was clicked ----@param x number The x-coordinate of the click ----@param y number The y-coordinate of the click ----@return boolean Whether the event was handled ----@protected -function List:mouse_click(button, x, y) end - ----Sets the value of the Offset property. ----@param self List self ----@param Offset number Current scroll offset for viewing long lists -function List:setOffset(self, Offset) end - ----Gets the value of the SelectedForeground property. ----@param self List self ----@return color white Text color for selected items -function List:getSelectedForeground(self) end - ----Gets the value of the Selectable property. ----@param self List self ----@return boolean true Whether items in the list can be selected -function List:getSelectable(self) end - ----@class Frame : Container ----@field draggingMap table The map of dragging positions ----@field scrollable boolean Whether the frame is scrollable ----@field draggable boolean Whether the frame is draggable -local Frame = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Frame self The initialized instance ----@protected -function Frame:init(props, basalt) end - ----Gets the value of the DraggingMap property. ----@param self Frame self ----@return table {} The map of dragging positions -function Frame:getDraggingMap(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was released ----@param x number The x position of the release ----@param y number The y position of the release ----@return boolean handled Whether the event was handled ----@protected -function Frame:mouse_up(button, x, y) end - ----Sets the value of the Draggable property. ----@param self Frame self ----@param Draggable boolean Whether the frame is draggable -function Frame:setDraggable(self, Draggable) end - ----Gets the value of the Draggable property. ----@param self Frame self ----@return boolean false Whether the frame is draggable -function Frame:getDraggable(self) end - ----Sets the value of the Scrollable property. ----@param self Frame self ----@param Scrollable boolean Whether the frame is scrollable -function Frame:setScrollable(self, Scrollable) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The scroll direction ----@param x number The x position of the scroll ----@param y number The y position of the scroll ----@return boolean handled Whether the event was handled ----@protected -function Frame:mouse_scroll(direction, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Frame:mouse_click(button, x, y) end - ----Sets the value of the DraggingMap property. ----@param self Frame self ----@param DraggingMap table The map of dragging positions -function Frame:setDraggingMap(self, DraggingMap) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@return number height The total height needed for all children ----@protected -function Frame:getChildrenHeight() end - ----Gets the value of the Scrollable property. ----@param self Frame self ----@return boolean false Whether the frame is scrollable -function Frame:getScrollable(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the drag position ----@param y number The y position of the drag position ----@return boolean handled Whether the event was handled ----@protected -function Frame:mouse_drag(button, x, y) end +---Creates a new sequence +---@return Animation self The animation instance +function Animation:sequence() end ---@class Render local Render = {} +---Blits text to the screen with a background color +---@param x number The x position to blit to +---@param y number The y position to blit to +---@param text string The text to blit +---@param bg colors The background color of the text +---@return Render +function Render:textBg(x, y, text, bg) end + ---Clears the screen ---@param bg colors The background color to clear the screen with ---@return Render function Render:clear(bg) end ----Blits a foreground color to the screen ----@param x number The x position ----@param y number The y position ----@param fg string The foreground color to blit ----@return Render -function Render:fg(x, y, fg) end - ----Adds a dirty rectangle to the buffer ----@param x number The x position of the rectangle ----@param y number The y position of the rectangle ----@param width number The width of the rectangle ----@param height number The height of the rectangle ----@return Render -function Render:addDirtyRect(x, y, width, height) end - ----Clears an area of the screen ----@param x number The x position of the area ----@param y number The y position of the area ----@param width number The width of the area ----@param height number The height of the area ----@param bg colors The background color to clear the area with ----@return Render -function Render:clearArea(x, y, width, height, bg) end - ----Renders the buffer to the screen ----@return Render -function Render:render() end - ----Merges two rectangles ----@param target table The target rectangle ----@param source table The source rectangle ----@return Render -function Render:mergeRects(target, source) end - ----Gets the size of the render ----@return number , number -function Render:getSize() end - ----Blits text to the screen ----@param x number The x position to blit to ----@param y number The y position to blit to ----@param text string The text to blit ----@param fg string The foreground color of the text ----@param bg string The background color of the text ----@return Render -function Render:blit(x, y, text, fg, bg) end - ---Checks if two rectangles overlap ---@param r1 table The first rectangle ---@param r2 table The second rectangle @@ -554,6 +84,17 @@ function Render:rectOverlaps(r1, r2) end ---@return Render function Render:bg(x, y, bg) end +---Sets the cursor position +---@param x number The x position of the cursor +---@param y number The y position of the cursor +---@param blink boolean Whether the cursor should blink +---@return Render +function Render:setCursor(x, y, blink) end + +---Renders the buffer to the screen +---@return Render +function Render:render() end + ---Blits text to the screen with multiple lines ---@param x number The x position to blit to ---@param y number The y position to blit to @@ -565,13 +106,31 @@ function Render:bg(x, y, bg) end ---@return Render function Render:multiBlit(x, y, width, height, text, fg, bg) end ----Blits text to the screen with a background color +---Blits text to the screen ---@param x number The x position to blit to ---@param y number The y position to blit to ---@param text string The text to blit ----@param bg colors The background color of the text ---@return Render -function Render:textBg(x, y, text, bg) end +function Render:text(x, y, text) end + +---Gets the size of the render +---@return number , number +function Render:getSize() end + +---Clears an area of the screen +---@param x number The x position of the area +---@param y number The y position of the area +---@param width number The width of the area +---@param height number The height of the area +---@param bg colors The background color to clear the area with +---@return Render +function Render:clearArea(x, y, width, height, bg) end + +---Merges two rectangles +---@param target table The target rectangle +---@param source table The source rectangle +---@return Render +function Render:mergeRects(target, source) end ---Sets the size of the render ---@param width number The width of the render @@ -579,12 +138,27 @@ function Render:textBg(x, y, text, bg) end ---@return Render function Render:setSize(width, height) end +---Creates a new Render object +---@param terminal table The terminal object to render to +---@return Render +function Render.new(terminal) end + ---Blits text to the screen ---@param x number The x position to blit to ---@param y number The y position to blit to ---@param text string The text to blit +---@param fg string The foreground color of the text +---@param bg string The background color of the text ---@return Render -function Render:text(x, y, text) end +function Render:blit(x, y, text, fg, bg) end + +---Adds a dirty rectangle to the buffer +---@param x number The x position of the rectangle +---@param y number The y position of the rectangle +---@param width number The width of the rectangle +---@param height number The height of the rectangle +---@return Render +function Render:addDirtyRect(x, y, width, height) end ---Blits text to the screen with a foreground color ---@param x number The x position to blit to @@ -594,94 +168,949 @@ function Render:text(x, y, text) end ---@return Render function Render:textFg(x, y, text, fg) end ----Sets the cursor position ----@param x number The x position of the cursor ----@param y number The y position of the cursor ----@param blink boolean Whether the cursor should blink +---Blits a foreground color to the screen +---@param x number The x position +---@param y number The y position +---@param fg string The foreground color to blit ---@return Render -function Render:setCursor(x, y, blink) end +function Render:fg(x, y, fg) end ----Creates a new Render object ----@param terminal table The terminal object to render to ----@return Render -function Render.new(terminal) end +---@class Table : VisualElement +---@field selectedColor color Background color of selected row +---@field sortDirection string Sort direction ("asc" or "desc") +---@field customSortFunction table Custom sort functions for columns +---@field scrollOffset number Current scroll position +---@field gridColor color Color of grid lines +---@field selectedRow number nil Currently selected row index +---@field data table The table data as array of row arrays +---@field sortColumn number nil Currently sorted column index +---@field headerColor color Color of the column headers +---@field columns table List of column definitions with {name, width} properties +local Table = {} + +---Gets the value of the SelectedColor property. +---@param self Table self +---@return color lightBlue Background color of selected row +function Table:getSelectedColor(self) end + +---Gets the value of the SortDirection property. +---@param self Table self +---@return string "asc" Sort direction ("asc" or "desc") +function Table:getSortDirection(self) end + +---Set data with automatic formatting +---@param rawData table The raw data array +---@param formatters table Optional formatter functions for columns {[2] = function(value) return value end} +---@return Table self The Table instance +function Table:setData(rawData, formatters) end + +---Gets the value of the GridColor property. +---@param self Table self +---@return color gray Color of grid lines +function Table:getGridColor(self) end + +---Sorts the table data by column +---@param columnIndex number The index of the column to sort by +---@param fn function ? Optional custom sorting function +---@return Table self The Table instance +function Table:sortData(columnIndex, fn) end + +---Gets the value of the Columns property. +---@param self Table self +---@return table {} List of column definitions with {name, width} properties +function Table:getColumns(self) end + +---Sets the value of the HeaderColor property. +---@param self Table self +---@param HeaderColor color Color of the column headers +function Table:setHeaderColor(self, HeaderColor) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param direction number The scroll direction (-1 up, 1 down) +---@param x number The x position of the scroll +---@param y number The y position of the scroll +---@return boolean handled Whether the event was handled +---@protected +function Table:mouse_scroll(direction, x, y) end + +---Sets the value of the GridColor property. +---@param self Table self +---@param GridColor color Color of grid lines +function Table:setGridColor(self, GridColor) end + +---Gets the value of the SelectedRow property. +---@param self Table self +---@return number ? nil Currently selected row index +function Table:getSelectedRow(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Table:mouse_click(button, x, y) end + +---Gets the value of the ScrollOffset property. +---@param self Table self +---@return number 0 Current scroll position +function Table:getScrollOffset(self) end + +---Sets the value of the ScrollOffset property. +---@param self Table self +---@param ScrollOffset number Current scroll position +function Table:setScrollOffset(self, ScrollOffset) end + +---Adds a new column to the table +---@param name string The name of the column +---@param width number The width of the column +---@return Table self The Table instance +function Table:addColumn(name, width) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Table:render() end + +---Gets the value of the SortColumn property. +---@param self Table self +---@return number ? nil Currently sorted column index +function Table:getSortColumn(self) end + +---Adds data with both display and sort values +---@param displayData table The formatted data for display +---@param sortData table The raw data for sorting (optional) +---@return Table self The Table instance +function Table:setFormattedData(displayData, sortData) end + +---Gets the value of the HeaderColor property. +---@param self Table self +---@return color blue Color of the column headers +function Table:getHeaderColor(self) end + +---Sets the value of the SelectedRow property. +---@param self Table self +---@param SelectedRow number nil Currently selected row index +function Table:setSelectedRow(self, SelectedRow) end + +---Sets the value of the SortColumn property. +---@param self Table self +---@param SortColumn number nil Currently sorted column index +function Table:setSortColumn(self, SortColumn) end + +---Sets a custom sort function for a specific column +---@param columnIndex number The index of the column +---@param sortFn function Function that takes (rowA, rowB) and returns comparison result +---@return Table self The Table instance +function Table:setColumnSortFunction(columnIndex, sortFn) end + +---Sets the value of the SortDirection property. +---@param self Table self +---@param SortDirection string Sort direction ("asc" or "desc") +function Table:setSortDirection(self, SortDirection) end + +---Adds a new row of data to the table +---@return Table self The Table instance +function Table:addData() end + +---Gets the value of the Data property. +---@param self Table self +---@return table {} The table data as array of row arrays +function Table:getData(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Table self The initialized instance +---@protected +function Table:init(props, basalt) end + +---Gets the value of the CustomSortFunction property. +---@param self Table self +---@return table {} Custom sort functions for columns +function Table:getCustomSortFunction(self) end + +---Sets the value of the CustomSortFunction property. +---@param self Table self +---@param CustomSortFunction table Custom sort functions for columns +function Table:setCustomSortFunction(self, CustomSortFunction) end + +---Sets the value of the Columns property. +---@param self Table self +---@param Columns table List of column definitions with {name, width} properties +function Table:setColumns(self, Columns) end + +---Sets the value of the SelectedColor property. +---@param self Table self +---@param SelectedColor color Background color of selected row +function Table:setSelectedColor(self, SelectedColor) end + +---@class ComboBox : DropDown +---@field placeholderColor color Color of the placeholder text +---@field editable boolean Whether the ComboBox allows text input +---@field focusedForeground color Foreground color when ComboBox is focused +---@field cursorPos number The current cursor position in the text +---@field manuallyOpened boolean Whether the dropdown was manually opened (not by auto-complete) +---@field focusedBackground color Background color when ComboBox is focused +---@field autoComplete boolean Whether to enable auto-complete filtering when typing +---@field placeholder string Text to display when input is empty +---@field text string The current text content of the ComboBox +---@field viewOffset number The horizontal scroll offset for viewing long text +local ComboBox = {} + +---Gets the current text content +---@return string text The current text +function ComboBox:getText() end + +---Sets whether the ComboBox is editable +---@param editable boolean Whether the ComboBox should be editable +---@return ComboBox self +function ComboBox:setEditable(editable) end + +---Gets the value of the FocusedBackground property. +---@param self ComboBox self +---@return color blue Background color when ComboBox is focused +function ComboBox:getFocusedBackground(self) end + +---Called when the ComboBox loses focus +function ComboBox:blur() end + +---Gets the value of the ViewOffset property. +---@param self ComboBox self +---@return number 0 The horizontal scroll offset for viewing long text +function ComboBox:getViewOffset(self) end + +---Renders the ComboBox +function ComboBox:render() end + +---Handles mouse clicks +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button (1 = left, 2 = right, 3 = middle) +---@param x number The x coordinate of the click +---@param y number The y coordinate of the click +---@return boolean handled Whether the event was handled +---@protected +function ComboBox:mouse_click(button, x, y) end + +---Gets the value of the PlaceholderColor property. +---@param self ComboBox self +---@return color gray Color of the placeholder text +function ComboBox:getPlaceholderColor(self) end + +---Sets the value of the FocusedBackground property. +---@param self ComboBox self +---@param FocusedBackground color Background color when ComboBox is focused +function ComboBox:setFocusedBackground(self, FocusedBackground) end + +---Sets the value of the Placeholder property. +---@param self ComboBox self +---@param Placeholder string Text to display when input is empty +function ComboBox:setPlaceholder(self, Placeholder) end + +---Called when the ComboBox gains focus +function ComboBox:focus() end + +---Creates a new ComboBox instance +---@return ComboBox self The newly created ComboBox instance +function ComboBox.new() end + +---Handles key input when editable +---@param key number The key code that was pressed +---@param held boolean Whether the key is being held +function ComboBox:key(key, held) end + +---Sets the value of the CursorPos property. +---@param self ComboBox self +---@param CursorPos number The current cursor position in the text +function ComboBox:setCursorPos(self, CursorPos) end + +---Gets the value of the ManuallyOpened property. +---@param self ComboBox self +---@return boolean false Whether the dropdown was manually opened (not by auto-complete) +function ComboBox:getManuallyOpened(self) end + +---Sets the value of the AutoComplete property. +---@param self ComboBox self +---@param AutoComplete boolean Whether to enable auto-complete filtering when typing +function ComboBox:setAutoComplete(self, AutoComplete) end + +---Gets the value of the AutoComplete property. +---@param self ComboBox self +---@return boolean false Whether to enable auto-complete filtering when typing +function ComboBox:getAutoComplete(self) end + +---Sets the value of the FocusedForeground property. +---@param self ComboBox self +---@param FocusedForeground color Foreground color when ComboBox is focused +function ComboBox:setFocusedForeground(self, FocusedForeground) end + +---Sets the value of the PlaceholderColor property. +---@param self ComboBox self +---@param PlaceholderColor color Color of the placeholder text +function ComboBox:setPlaceholderColor(self, PlaceholderColor) end + +---Handles character input when editable +---@param char string The character that was typed +function ComboBox:char(char) end + +---Gets the value of the CursorPos property. +---@param self ComboBox self +---@return number 1 The current cursor position in the text +function ComboBox:getCursorPos(self) end + +---Gets the value of the Placeholder property. +---@param self ComboBox self +---@return string "..." Text to display when input is empty +function ComboBox:getPlaceholder(self) end + +---Sets the value of the ManuallyOpened property. +---@param self ComboBox self +---@param ManuallyOpened boolean Whether the dropdown was manually opened (not by auto-complete) +function ComboBox:setManuallyOpened(self, ManuallyOpened) end + +---Gets the value of the Editable property. +---@param self ComboBox self +---@return boolean true Whether the ComboBox allows text input +function ComboBox:getEditable(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return ComboBox self The initialized instance +---@protected +function ComboBox:init(props, basalt) end + +---Gets the value of the FocusedForeground property. +---@param self ComboBox self +---@return color white Foreground color when ComboBox is focused +function ComboBox:getFocusedForeground(self) end + +---Sets the value of the ViewOffset property. +---@param self ComboBox self +---@param ViewOffset number The horizontal scroll offset for viewing long text +function ComboBox:setViewOffset(self, ViewOffset) end + +---Sets the text content of the ComboBox +---@param text string The text to set +---@return ComboBox self +function ComboBox:setText(text) end + +---@class Container : VisualElement +---@field eventListenerCount table The event listener count of the container +---@field childrenEventsSorted boolean Whether the children events are sorted +---@field offsetX number Horizontal content offset +---@field offsetY number Vertical content offset +---@field children table The children of the container +---@field childrenEvents table The children events of the container +---@field visibleChildrenEvents table The visible children events of the container +---@field childrenSorted boolean Whether the children are sorted +---@field focusedChild table The focused child of the container +---@field visibleChildren table The visible children of the container +local Container = {} + +---Creates a new VisualElement element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return VisualElement element A new VisualElement element. +function Container:addVisualElement(self, props) end + +---Sets the value of the VisibleChildrenEvents property. +---@param self Container self +---@param VisibleChildrenEvents table The visible children events of the container +function Container:setVisibleChildrenEvents(self, VisibleChildrenEvents) end + +---Creates a new List element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return List element A new List element. +function Container:addList(self, props) end + +---Creates a new Tree element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Tree element A new Tree element. +function Container:addTree(self, props) end + +---Creates a new Image element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Image element A new Image element. +function Container:addImage(self, props) end + +---Creates a new Program element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Program element A new Program element. +function Container:addProgram(self, props) end + +---Enables debugging for this container and all its children +---@param self Container The container to debug +---@param level number The debug level +function Container.debugChildren(self, level) end + +---Creates a new Container element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Container element A new Container element. +function Container:addContainer(self, props) end + +---Sets the value of the Children property. +---@param self Container self +---@param Children table The children of the container +function Container:setChildren(self, Children) end + +---Sets the value of the EventListenerCount property. +---@param self Container self +---@param EventListenerCount table The event listener count of the container +function Container:setEventListenerCount(self, EventListenerCount) end + +---Sets the value of the OffsetX property. +---@param self Container self +---@param OffsetX number Horizontal content offset +function Container:setOffsetX(self, OffsetX) end + +---Calls a event on all children +---@param visibleOnly boolean Whether to only call the event on visible children +---@param event string The event to call +---@return boolean handled Whether the event was handled +---@return table ? child The child that handled the event +function Container:callChildrenEvent(visibleOnly, event) end + +---Creates a new Timer element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Timer element A new Timer element. +function Container:addTimer(self, props) end + +function Container:drawFg() end + +---Adds a child to the container +---@param child table The child to add +---@return Container self The container instance +function Container:addChild(child) end + +---Creates a new Input element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Input element A new Input element. +function Container:addInput(self, props) end + +---Creates a new BarChart element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return BarChart element A new BarChart element. +function Container:addBarChart(self, props) end + +---Creates a new BaseElement element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return BaseElement element A new BaseElement element. +function Container:addBaseElement(self, props) end + +---Creates a new BigFont element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return BigFont element A new BigFont element. +function Container:addBigFont(self, props) end + +---Creates a new Switch element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Switch element A new Switch element. +function Container:addSwitch(self, props) end + +---Creates a new ComboBox element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return ComboBox element A new ComboBox element. +function Container:addComboBox(self, props) end + +function Container:drawText() end + +---Gets the value of the EventListenerCount property. +---@param self Container self +---@return table {} The event listener count of the container +function Container:getEventListenerCount(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@protected +function Container:mouse_release(button, x, y) end + +---Gets the value of the ChildrenEvents property. +---@param self Container self +---@return table {} The children events of the container +function Container:getChildrenEvents(self) end + +---Returns whether a child is visible +---@param child table The child to check +---@return boolean boolean the child is visible +function Container:isChildVisible(child) end + +---Creates a new FlexBox element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return FlexBox element A new FlexBox element. +function Container:addFlexBox(self, props) end + +---Registers the children events of the container +---@param child table The child to register events for +---@return Container self The container instance +function Container:registerChildrenEvents(child) end + +---Creates a new Button element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Button element A new Button element. +function Container:addButton(self, props) end + +---Creates a new Graph element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Graph element A new Graph element. +function Container:addGraph(self, props) end + +---Creates a new DropDown element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return DropDown element A new DropDown element. +function Container:addDropDown(self, props) end + +---Creates a new TabControl element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return TabControl element A new TabControl element. +function Container:addTabControl(self, props) end + +---Sets the value of the OffsetY property. +---@param self Container self +---@param OffsetY number Vertical content offset +function Container:setOffsetY(self, OffsetY) end + +---Gets the value of the ChildrenEventsSorted property. +---@param self Container self +---@return boolean true Whether the children events are sorted +function Container:getChildrenEventsSorted(self) end + +---Sorts the children of the container +---@return Container self The container instance +function Container:sortChildren() end + +---Gets the value of the FocusedChild property. +---@param self Container self +---@return table nil The focused child of the container +function Container:getFocusedChild(self) end + +---Sets the value of the ChildrenSorted property. +---@param self Container self +---@param ChildrenSorted boolean Whether the children are sorted +function Container:setChildrenSorted(self, ChildrenSorted) end + +---Sets the value of the VisibleChildren property. +---@param self Container self +---@param VisibleChildren table The visible children of the container +function Container:setVisibleChildren(self, VisibleChildren) end + +---Registers the children events of the container +---@param child table The child to register events for +---@param eventName string The event name to register +---@return Container self The container instance +function Container:registerChildEvent(child, eventName) end + +function Container:drawBg() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw the text +---@param y number The y position to draw the text +---@param text string The text to draw +---@param bg color The background color of the text +---@return Container self The container instance +---@protected +function Container:textBg(x, y, text, bg) end + +---Gets the value of the OffsetX property. +---@param self Container self +---@return number 0 Horizontal content offset +function Container:getOffsetX(self) end + +---Sorts the children events of the container +---@param eventName string The event name to sort +---@return Container self The container instance +function Container:sortChildrenEvents(eventName) end + +---Unregisters the children events of the container +---@param child table The child to unregister events for +---@return Container self The container instance +function Container:removeChildrenEvents(child) end + +---Sets the value of the ChildrenEvents property. +---@param self Container self +---@param ChildrenEvents table The children events of the container +function Container:setChildrenEvents(self, ChildrenEvents) end + +---Creates a new Display element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Display element A new Display element. +function Container:addDisplay(self, props) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function Container:init(props, basalt) end + +---Creates a new Slider element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Slider element A new Slider element. +function Container:addSlider(self, props) end + +---Clears the container +---@return Container self The container instance +function Container:clear() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Container:mouse_drag(button, x, y) end + +---Removes a child from the container +---@param path string The path to the child to remove +---@return Container ? self The container instance +function Container:getChild(path) end + +---Gets the value of the VisibleChildrenEvents property. +---@param self Container self +---@return table {} The visible children events of the container +function Container:getVisibleChildrenEvents(self) end + +---Logs benchmark statistics for a container and all its children +---@param methodName string The method to log +---@return Container self The container instance +function Container:logContainerBenchmarks(methodName) end + +---Creates a new Table element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Table element A new Table element. +function Container:addTable(self, props) end + +---Gets the value of the ChildrenSorted property. +---@param self Container self +---@return boolean true Whether the children are sorted +function Container:getChildrenSorted(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Container:mouse_up(button, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw the text +---@param y number The y position to draw the text +---@param text string The text to draw +---@param fg color The foreground color of the text +---@return Container self The container instance +---@protected +function Container:textFg(x, y, text, fg) end + +---Gets the value of the OffsetY property. +---@param self Container self +---@return number 0 Vertical content offset +function Container:getOffsetY(self) end + +---Gets the value of the VisibleChildren property. +---@param self Container self +---@return table {} The visible children of the container +function Container:getVisibleChildren(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Container:mouse_click(button, x, y) end + +---Enables benchmarking for a container and all its children +---@param methodName string The method to benchmark +---@return Container self The container instance +function Container:benchmarkContainer(methodName) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was released +---@return boolean handled Whether the event was handled +---@protected +function Container:key_up(key) end + +---Creates a new Menu element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Menu element A new Menu element. +function Container:addMenu(self, props) end + +---Creates a new BaseFrame element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return BaseFrame element A new BaseFrame element. +function Container:addBaseFrame(self, props) end + +---Gets the value of the Children property. +---@param self Container self +---@return table {} The children of the container +function Container:getChildren(self) end + +---Sets the value of the FocusedChild property. +---@param self Container self +---@param FocusedChild table The focused child of the container +function Container:setFocusedChild(self, FocusedChild) end + +---Removes a child from the container +---@param child table The child to remove +---@return Container self The container instance +function Container:removeChild(child) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param direction number The direction of the scroll +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Container:mouse_scroll(direction, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param _ number unknown +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Container:mouse_move(_, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw the text +---@param y number The y position to draw the text +---@param width number The width of the text +---@param height number The height of the text +---@param text string The text to draw +---@param fg string The foreground color of the text +---@param bg string The background color of the text +---@return Container self The container instance +---@protected +function Container:multiBlit(x, y, width, height, text, fg, bg) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Container:render() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was pressed +---@return boolean handled Whether the event was handled +---@protected +function Container:key(key) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param char string The character that was pressed +---@return boolean handled Whether the event was handled +---@protected +function Container:char(char) end + +---Creates a new ScrollBar element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return ScrollBar element A new ScrollBar element. +function Container:addScrollBar(self, props) end + +---Creates a new CheckBox element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return CheckBox element A new CheckBox element. +function Container:addCheckBox(self, props) end + +---Creates a new Label element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Label element A new Label element. +function Container:addLabel(self, props) end + +---Stops benchmarking for a container and all its children +---@param methodName string The method to stop benchmarking +---@return Container self The container instance +function Container:stopContainerBenchmark(methodName) end + +---Creates a new LineChart element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return LineChart element A new LineChart element. +function Container:addLineChart(self, props) end + +---Creates a new Frame element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return Frame element A new Frame element. +function Container:addFrame(self, props) end + +---Unregisters the children events of the container +---@param child table The child to unregister events for +---@param eventName string The event name to unregister +---@return Container self The container instance +function Container:unregisterChildEvent(child, eventName) end + +---Creates a new ProgressBar element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return ProgressBar element A new ProgressBar element. +function Container:addProgressBar(self, props) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param event string The event to handle +---@return boolean handled Whether the event was handled +---@protected +function Container:handleEvent(event) end + +---Sets the value of the ChildrenEventsSorted property. +---@param self Container self +---@param ChildrenEventsSorted boolean Whether the children events are sorted +function Container:setChildrenEventsSorted(self, ChildrenEventsSorted) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw the text +---@param y number The y position to draw the text +---@param text string The text to draw +---@param fg string The foreground color of the text +---@param bg string The background color of the text +---@return Container self The container instance +---@protected +function Container:blit(x, y, text, fg, bg) end + +---Creates a new TextBox element. +---@param self Container self +---@param props? table Optional: properties for the element. +---@return TextBox element A new TextBox element. +function Container:addTextBox(self, props) end + +---@class Program : VisualElement +---@field errorCallback function The error callback function +---@field path string The path to the program +---@field running boolean Whether the program is running +---@field program table The program instance +---@field doneCallback function The done callback function +local Program = {} + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Program self The initialized instance +---@protected +function Program:init(props, basalt) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Program:focus() end + +---Sets the value of the ErrorCallback property. +---@param self Program self +---@param ErrorCallback function The error callback function +function Program:setErrorCallback(self, ErrorCallback) end + +---Stops the program +---@return Program self The Program instance +function Program:stop() end + +function BasaltProgram:setArgs() end + +---Sets the value of the Program property. +---@param self Program self +---@param Program table The program instance +function Program:setProgram(self, Program) end + +---Gets the value of the Program property. +---@param self Program self +---@return table nil The program instance +function Program:getProgram(self) end + +---Executes a program +---@param path string The path to the program +---@return Program self The Program instance +function Program:execute(path) end + +---Sends an event to the program +---@param event string The event to send +---@return Program self The Program instance +function Program:sendEvent(event) end + +---Gets the value of the Running property. +---@param self Program self +---@return boolean false Whether the program is running +function Program:getRunning(self) end + +---Gets the value of the DoneCallback property. +---@param self Program self +---@return function nil The done callback function +function Program:getDoneCallback(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Program:render() end + +---Gets the value of the ErrorCallback property. +---@param self Program self +---@return function nil The error callback function +function Program:getErrorCallback(self) end + +---Registers a callback for the program's error event, if the function returns false, the program won't stop +---@param fn function The callback function to register +---@return Program self The Program instance +function Program:onError(fn) end + +---Sets the value of the Running property. +---@param self Program self +---@param Running boolean Whether the program is running +function Program:setRunning(self, Running) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param event string The event to handle +---@return any result The event result +---@protected +function Program:dispatchEvent(event) end + +---Registers a callback for the program's done event +---@param fn function The callback function to register +---@return Program self The Program instance +function Program:onDone(fn) end + +---Gets the value of the Path property. +---@param self Program self +---@return string "" The path to the program +function Program:getPath(self) end + +---Sets the value of the Path property. +---@param self Program self +---@param Path string The path to the program +function Program:setPath(self, Path) end + +---Sets the value of the DoneCallback property. +---@param self Program self +---@param DoneCallback function The done callback function +function Program:setDoneCallback(self, DoneCallback) end ---@class BaseElement : PropertySystem ---@field id string The unique identifier for the element ----@field name string The name of the element ----@field type string The type identifier of the element ----@field enabled boolean Whether the element is enabled or not ---@field eventCallbacks table The event callbacks for the element +---@field name string The name of the element +---@field enabled boolean Whether the element is enabled or not +---@field type string The type identifier of the element local BaseElement = {} ----Gets the value of the Name property. ----@param self BaseElement self ----@return string BaseElement The name of the element -function BaseElement:getName(self) end - ----Logs benchmark statistics for a method ----@param methodName string The name of the method to log ----@return BaseElement self The element instance -function BaseElement:logBenchmark(methodName) end - ----Gets the value of the Type property. ----@param self BaseElement self ----@return string BaseElement The type identifier of the element -function BaseElement:getType(self) end - ----Returns the base frame of the element ----@return BaseFrame BaseFrame The base frame of the element -function BaseElement:getBaseFrame() end - ----Sets the value of the Type property. ----@param self BaseElement self ----@param Type string The type identifier of the element -function BaseElement:setType(self, Type) end - ----Requests a render update for this element ----@return table self The BaseElement instance -function BaseElement:updateRender() end - ----Checks if the element is a specific type ----@param type string The type to check for ----@return boolean isType Whether the element is of the specified type -function BaseElement:isType(type) end - function BaseElement:computed() end ----Gets the value of a state ----@param self BaseElement The element to get state from ----@param name string The name of the state ----@return any value The current state value -function BaseElement:getState(self, name) end - ----Registers a callback for state changes ----@param self BaseElement The element to watch ----@param stateName string The state to watch ----@param callback function Called with (element, newValue, oldValue) ----@return BaseElement self The element instance -function BaseElement:onStateChange(self, stateName, callback) end - ----Stops benchmarking for a method ----@param methodName string The name of the method to stop benchmarking ----@return BaseElement self The element instance -function BaseElement:stopBenchmark(methodName) end - ----Gets the value of the Enabled property. ----@param self BaseElement self ----@return boolean BaseElement Whether the element is enabled or not -function BaseElement:getEnabled(self) end - ----Registers a new event callback for the element (on class level) ----@param class table The class to register ----@param callbackName string The name of the callback to register -function BaseElement.registerEventCallback(class, callbackName) end - ----Triggers an event and calls all registered callbacks ----@param event string The event to fire ----@return table self The BaseElement instance -function BaseElement:fireEvent(event) end - ---Binds a property to a state ---@param self BaseElement The element to bind ---@param propertyName string The property to bind @@ -689,42 +1118,27 @@ function BaseElement:fireEvent(event) end ---@return BaseElement self The element instance function BaseElement:bind(self, propertyName, stateName) end ----Starts profiling a method ----@param methodName string The name of the method to profile ----@return BaseElement self The element instance -function BaseElement:startProfile(methodName) end - ----Removes a state change observer ----@param self BaseElement The element to remove observer from ----@param stateName string The state to remove observer from ----@param callback function The callback function to remove ----@return BaseElement self The element instance -function BaseElement:removeStateChange(self, stateName, callback) end - ----Registers a callback function for an event ----@param event string The event to register the callback for ----@param callback function The callback function to register ----@return table self The BaseElement instance -function BaseElement:registerCallback(event, callback) end - ----Dumps debug information for this element ----@param self BaseElement The element to dump debug info for -function BaseElement.dumpDebug(self) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param event string The event to handle +---@return boolean ? handled Whether the event was handled +---@protected +function BaseElement:handleEvent(event) end ---Gets benchmark statistics for a method ---@param methodName string The name of the method to get statistics for ---@return table ? stats The benchmark statistics or nil function BaseElement:getBenchmarkStats(methodName) end ----Gets the value of the Id property. +---Gets the value of the Enabled property. ---@param self BaseElement self ----@return string BaseElement The unique identifier for the element -function BaseElement:getId(self) end +---@return boolean BaseElement Whether the element is enabled or not +function BaseElement:getEnabled(self) end ----Sets the value of the Name property. ----@param self BaseElement self ----@param Name string The name of the element -function BaseElement:setName(self, Name) end +---Registers a callback function for an event +---@param event string The event to register the callback for +---@param callback function The callback function to register +---@return table self The BaseElement instance +function BaseElement:registerCallback(event, callback) end ---Registers a new event listener for the element (on class level) ---@param class table The class to register @@ -737,10 +1151,22 @@ function BaseElement.defineEvent(class, eventName) end ---@return BaseElement self The element instance function BaseElement:applyTheme(self, applyToChildren) end ----Sets the value of the Id property. +---Registers a callback for state changes +---@param self BaseElement The element to watch +---@param stateName string The state to watch +---@param callback function Called with (element, newValue, oldValue) +---@return BaseElement self The element instance +function BaseElement:onStateChange(self, stateName, callback) end + +---Logs benchmark statistics for a method +---@param methodName string The name of the method to log +---@return BaseElement self The element instance +function BaseElement:logBenchmark(methodName) end + +---Sets the value of the Type property. ---@param self BaseElement self ----@param Id string The unique identifier for the element -function BaseElement:setId(self, Id) end +---@param Type string The type identifier of the element +function BaseElement:setType(self, Type) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param props table The properties to initialize the element with @@ -749,25 +1175,10 @@ function BaseElement:setId(self, Id) end ---@protected function BaseElement:init(props, basalt) end ----Sets the value of the Enabled property. ----@param self BaseElement self ----@param Enabled boolean Whether the element is enabled or not -function BaseElement:setEnabled(self, Enabled) end - ----Enables benchmarking for a method ----@param methodName string The name of the method to benchmark ----@return BaseElement self The element instance -function BaseElement:benchmark(methodName) end - ----Gets the theme properties for this element ----@param self BaseElement The element to get theme for ----@return table styles The theme properties -function BaseElement:getTheme(self) end - ----Enables debugging for this element ----@param self BaseElement The element to debug ----@param level number The debug level -function BaseElement.debug(self, level) end +---Triggers an event and calls all registered callbacks +---@param event string The event to fire +---@return table self The BaseElement instance +function BaseElement:fireEvent(event) end ---Observes a property and calls a callback when it changes ---@param property string The property to observe @@ -775,6 +1186,123 @@ function BaseElement.debug(self, level) end ---@return table self The BaseElement instance function BaseElement:onChange(property, callback) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@return table self The BaseElement instance +---@protected +function BaseElement:postInit() end + +---Gets the theme properties for this element +---@param self BaseElement The element to get theme for +---@return table styles The theme properties +function BaseElement:getTheme(self) end + +---Gets the value of the Name property. +---@param self BaseElement self +---@return string BaseElement The name of the element +function BaseElement:getName(self) end + +---Gets the value of a state +---@param self BaseElement The element to get state from +---@param name string The name of the state +---@return any value The current state value +function BaseElement:getState(self, name) end + +---Sets the value of the Enabled property. +---@param self BaseElement self +---@param Enabled boolean Whether the element is enabled or not +function BaseElement:setEnabled(self, Enabled) end + +---Stops benchmarking for a method +---@param methodName string The name of the method to stop benchmarking +---@return BaseElement self The element instance +function BaseElement:stopBenchmark(methodName) end + +---Requests a render update for this element +---@return table self The BaseElement instance +function BaseElement:updateRender() end + +---Gets the value of the Type property. +---@param self BaseElement self +---@return string BaseElement The type identifier of the element +function BaseElement:getType(self) end + +---Ends profiling a method +---@param methodName string The name of the method to stop profiling +---@return BaseElement self The element instance +function BaseElement:endProfile(methodName) end + +---Registers a new event callback for the element (on class level) +---@param class table The class to register +---@param callbackName string The name of the callback to register +function BaseElement.registerEventCallback(class, callbackName) end + +---Gets the value of the Id property. +---@param self BaseElement self +---@return string BaseElement The unique identifier for the element +function BaseElement:getId(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param event string The event to handle +---@return boolean ? handled Whether the event was handled +---@protected +function BaseElement:dispatchEvent(event) end + +---Returns the base frame of the element +---@return BaseFrame BaseFrame The base frame of the element +function BaseElement:getBaseFrame() end + +---Sets the value of the Id property. +---@param self BaseElement self +---@param Id string The unique identifier for the element +function BaseElement:setId(self, Id) end + +---Enables benchmarking for a method +---@param methodName string The name of the method to benchmark +---@return BaseElement self The element instance +function BaseElement:benchmark(methodName) end + +---Sets the value of the Name property. +---@param self BaseElement self +---@param Name string The name of the element +function BaseElement:setName(self, Name) end + +---Gets the value of the EventCallbacks property. +---@param self BaseElement self +---@return table BaseElement The event callbacks for the element +function BaseElement:getEventCallbacks(self) end + +---Destroys the element and cleans up all references +function BaseElement:destroy() end + +---Enables debugging for this element +---@param self BaseElement The element to debug +---@param level number The debug level +function BaseElement.debug(self, level) end + +---Sets the value of the EventCallbacks property. +---@param self BaseElement self +---@param EventCallbacks table The event callbacks for the element +function BaseElement:setEventCallbacks(self, EventCallbacks) end + +---Enables or disables event listening for a specific event +---@param eventName string The name of the event to listen for +---@return table self The BaseElement instance +function BaseElement:listenEvent(eventName) end + +---Starts profiling a method +---@param methodName string The name of the method to profile +---@return BaseElement self The element instance +function BaseElement:startProfile(methodName) end + +---Checks if the element is a specific type +---@param type string The type to check for +---@return boolean isType Whether the element is of the specified type +function BaseElement:isType(type) end + +---Dumps debug information for this element +---@param self BaseElement The element to dump debug info for +function BaseElement.dumpDebug(self) end + ---Sets the value of a state ---@param self BaseElement The element to set state for ---@param name string The name of the state @@ -782,72 +1310,58 @@ function BaseElement:onChange(property, callback) end ---@return BaseElement self The element instance function BaseElement:setState(self, name, value) end ----Destroys the element and cleans up all references -function BaseElement:destroy() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@return table self The BaseElement instance ----@protected -function BaseElement:postInit() end - ----Enables or disables event listening for a specific event ----@param eventName string The name of the event to listen for ----@return table self The BaseElement instance -function BaseElement:listenEvent(eventName) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param event string The event to handle ----@return boolean ? handled Whether the event was handled ----@protected -function BaseElement:handleEvent(event) end - ----Ends profiling a method ----@param methodName string The name of the method to stop profiling +---Removes a state change observer +---@param self BaseElement The element to remove observer from +---@param stateName string The state to remove observer from +---@param callback function The callback function to remove ---@return BaseElement self The element instance -function BaseElement:endProfile(methodName) end +function BaseElement:removeStateChange(self, stateName, callback) end + +---@class ThemeAPI +local ThemeAPI = {} + +---Loads a theme from a JSON file +---@param path string Path to the theme JSON file +function ThemeAPI.loadTheme(path) end + +---Gets the current theme configuration +---@return table theme The current theme configuration +function ThemeAPI.getTheme() end + +---Sets the current theme +---@param newTheme table The theme configuration to set +function ThemeAPI.setTheme(newTheme) end + +---@class ErrorHandler +local ErrorHandler = {} + +---Handles an error +---@param errMsg string The error message +function errorHandler.error(errMsg) end + +---@class BarChart : Graph +local BarChart = {} ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param event string The event to handle ----@return boolean ? handled Whether the event was handled +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return BarChart self The initialized instance ---@protected -function BaseElement:dispatchEvent(event) end +function BarChart:init(props, basalt) end ----Sets the value of the EventCallbacks property. ----@param self BaseElement self ----@param EventCallbacks table The event callbacks for the element -function BaseElement:setEventCallbacks(self, EventCallbacks) end - ----Gets the value of the EventCallbacks property. ----@param self BaseElement self ----@return table BaseElement The event callbacks for the element -function BaseElement:getEventCallbacks(self) end - ----@class ElementManager -local ElementManager = {} - ----Loads an element by name. This will load the element and apply any plugins to it. ----@param name string The name of the element to load -function ElementManager.loadElement(name) end - ----Gets a list of all elements ----@return table ElementList A list of all elements -function ElementManager.getElementList() end - ----Gets an Plugin API by name ----@param name string The name of the API to get ----@return table API The API -function ElementManager.getAPI(name) end - ----Gets an element by name. If the element is not loaded, it will try to load it first. ----@param name string The name of the element to get ----@return table Element The element class -function ElementManager.getElement(name) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function BarChart:render() end ---@class BigFont : VisualElement ---@field text string BigFont text ---@field fontSize number The font size of the BigFont local BigFont = {} +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function BigFont:render() end + ---Gets the value of the FontSize property. ---@param self BigFont self ---@return number 1 The font size of the BigFont @@ -858,10 +1372,6 @@ function BigFont:getFontSize(self) end ---@param FontSize number The font size of the BigFont function BigFont:setFontSize(self, FontSize) end ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function BigFont:render() end - ---Gets the value of the Text property. ---@param self BigFont self ---@return string BigFont BigFont text @@ -878,1469 +1388,17 @@ function BigFont:setText(self, Text) end ---@protected function BigFont:init(props, basalt) end ----@class Container : VisualElement ----@field childrenSorted boolean Whether the children are sorted ----@field children table The children of the container ----@field focusedChild table The focused child of the container ----@field childrenEventsSorted boolean Whether the children events are sorted ----@field visibleChildrenEvents table The visible children events of the container ----@field offsetX number Horizontal content offset ----@field eventListenerCount table The event listener count of the container ----@field childrenEvents table The children events of the container ----@field offsetY number Vertical content offset ----@field visibleChildren table The visible children of the container -local Container = {} - ----Creates a new BaseElement element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return BaseElement element A new BaseElement element. -function Container:addBaseElement(self, props) end - ----Creates a new ProgressBar element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return ProgressBar element A new ProgressBar element. -function Container:addProgressBar(self, props) end - ----Sorts the children of the container ----@return Container self The container instance -function Container:sortChildren() end - ----Creates a new Graph element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Graph element A new Graph element. -function Container:addGraph(self, props) end - ----Sets the value of the ChildrenEvents property. ----@param self Container self ----@param ChildrenEvents table The children events of the container -function Container:setChildrenEvents(self, ChildrenEvents) end - ----Creates a new Display element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Display element A new Display element. -function Container:addDisplay(self, props) end - ----Creates a new FlexBox element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return FlexBox element A new FlexBox element. -function Container:addFlexBox(self, props) end - ----Logs benchmark statistics for a container and all its children ----@param methodName string The method to log ----@return Container self The container instance -function Container:logContainerBenchmarks(methodName) end - ----Creates a new Frame element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Frame element A new Frame element. -function Container:addFrame(self, props) end - ----Creates a new ComboBox element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return ComboBox element A new ComboBox element. -function Container:addComboBox(self, props) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The direction of the scroll ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Container:mouse_scroll(direction, x, y) end - ----Creates a new Image element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Image element A new Image element. -function Container:addImage(self, props) end - ----Creates a new Button element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Button element A new Button element. -function Container:addButton(self, props) end - -function Container:drawFg() end - ----Sets the value of the EventListenerCount property. ----@param self Container self ----@param EventListenerCount table The event listener count of the container -function Container:setEventListenerCount(self, EventListenerCount) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw the text ----@param y number The y position to draw the text ----@param width number The width of the text ----@param height number The height of the text ----@param text string The text to draw ----@param fg string The foreground color of the text ----@param bg string The background color of the text ----@return Container self The container instance ----@protected -function Container:multiBlit(x, y, width, height, text, fg, bg) end - ----Creates a new LineChart element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return LineChart element A new LineChart element. -function Container:addLineChart(self, props) end - ----Creates a new Timer element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Timer element A new Timer element. -function Container:addTimer(self, props) end - -function Container:drawBg() end - ----Gets the value of the ChildrenEvents property. ----@param self Container self ----@return table {} The children events of the container -function Container:getChildrenEvents(self) end - ----Sorts the children events of the container ----@param eventName string The event name to sort ----@return Container self The container instance -function Container:sortChildrenEvents(eventName) end - ----Enables benchmarking for a container and all its children ----@param methodName string The method to benchmark ----@return Container self The container instance -function Container:benchmarkContainer(methodName) end - ----Gets the value of the VisibleChildrenEvents property. ----@param self Container self ----@return table {} The visible children events of the container -function Container:getVisibleChildrenEvents(self) end - ----Stops benchmarking for a container and all its children ----@param methodName string The method to stop benchmarking ----@return Container self The container instance -function Container:stopContainerBenchmark(methodName) end - ----Gets the value of the Children property. ----@param self Container self ----@return table {} The children of the container -function Container:getChildren(self) end - ----Sets the value of the VisibleChildrenEvents property. ----@param self Container self ----@param VisibleChildrenEvents table The visible children events of the container -function Container:setVisibleChildrenEvents(self, VisibleChildrenEvents) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@protected -function Container:mouse_release(button, x, y) end - ----Gets the value of the EventListenerCount property. ----@param self Container self ----@return table {} The event listener count of the container -function Container:getEventListenerCount(self) end - ----Calls a event on all children ----@param visibleOnly boolean Whether to only call the event on visible children ----@param event string The event to call ----@return boolean handled Whether the event was handled ----@return table ? child The child that handled the event -function Container:callChildrenEvent(visibleOnly, event) end - ----Creates a new Slider element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Slider element A new Slider element. -function Container:addSlider(self, props) end - ----Creates a new List element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return List element A new List element. -function Container:addList(self, props) end - ----Removes a child from the container ----@param path string The path to the child to remove ----@return Container ? self The container instance -function Container:getChild(path) end - ----Creates a new Container element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Container element A new Container element. -function Container:addContainer(self, props) end - ----Sets the value of the OffsetX property. ----@param self Container self ----@param OffsetX number Horizontal content offset -function Container:setOffsetX(self, OffsetX) end - ----Gets the value of the FocusedChild property. ----@param self Container self ----@return table nil The focused child of the container -function Container:getFocusedChild(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw the text ----@param y number The y position to draw the text ----@param text string The text to draw ----@param bg color The background color of the text ----@return Container self The container instance ----@protected -function Container:textBg(x, y, text, bg) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw the text ----@param y number The y position to draw the text ----@param text string The text to draw ----@param fg color The foreground color of the text ----@return Container self The container instance ----@protected -function Container:textFg(x, y, text, fg) end - ----Creates a new BigFont element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return BigFont element A new BigFont element. -function Container:addBigFont(self, props) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Container:mouse_click(button, x, y) end - ----Creates a new Label element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Label element A new Label element. -function Container:addLabel(self, props) end - ----Creates a new BarChart element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return BarChart element A new BarChart element. -function Container:addBarChart(self, props) end - ----Creates a new VisualElement element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return VisualElement element A new VisualElement element. -function Container:addVisualElement(self, props) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Container:render() end - ----Creates a new Tree element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Tree element A new Tree element. -function Container:addTree(self, props) end - ----Returns whether a child is visible ----@param child table The child to check ----@return boolean boolean the child is visible -function Container:isChildVisible(child) end - ----Registers the children events of the container ----@param child table The child to register events for ----@return Container self The container instance -function Container:registerChildrenEvents(child) end - ----Creates a new ScrollBar element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return ScrollBar element A new ScrollBar element. -function Container:addScrollBar(self, props) end - ----Gets the value of the ChildrenSorted property. ----@param self Container self ----@return boolean true Whether the children are sorted -function Container:getChildrenSorted(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function Container:init(props, basalt) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Container:mouse_drag(button, x, y) end - ----Removes a child from the container ----@param child table The child to remove ----@return Container self The container instance -function Container:removeChild(child) end - ----Creates a new Menu element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Menu element A new Menu element. -function Container:addMenu(self, props) end - ----Gets the value of the VisibleChildren property. ----@param self Container self ----@return table {} The visible children of the container -function Container:getVisibleChildren(self) end - ----Creates a new TabControl element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return TabControl element A new TabControl element. -function Container:addTabControl(self, props) end - ----Creates a new TextBox element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return TextBox element A new TextBox element. -function Container:addTextBox(self, props) end - ----Sets the value of the Children property. ----@param self Container self ----@param Children table The children of the container -function Container:setChildren(self, Children) end - ----Clears the container ----@return Container self The container instance -function Container:clear() end - ----Creates a new Program element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Program element A new Program element. -function Container:addProgram(self, props) end - ----Creates a new DropDown element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return DropDown element A new DropDown element. -function Container:addDropDown(self, props) end - ----Enables debugging for this container and all its children ----@param self Container The container to debug ----@param level number The debug level -function Container.debugChildren(self, level) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param event string The event to handle ----@return boolean handled Whether the event was handled ----@protected -function Container:handleEvent(event) end - ----Creates a new Table element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Table element A new Table element. -function Container:addTable(self, props) end - ----Creates a new Switch element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Switch element A new Switch element. -function Container:addSwitch(self, props) end - ----Creates a new Input element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return Input element A new Input element. -function Container:addInput(self, props) end - ----Creates a new CheckBox element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return CheckBox element A new CheckBox element. -function Container:addCheckBox(self, props) end - ----Sets the value of the VisibleChildren property. ----@param self Container self ----@param VisibleChildren table The visible children of the container -function Container:setVisibleChildren(self, VisibleChildren) end - ----Creates a new BaseFrame element. ----@param self Container self ----@param props? table Optional: properties for the element. ----@return BaseFrame element A new BaseFrame element. -function Container:addBaseFrame(self, props) end - ----Sets the value of the OffsetY property. ----@param self Container self ----@param OffsetY number Vertical content offset -function Container:setOffsetY(self, OffsetY) end - ----Gets the value of the OffsetY property. ----@param self Container self ----@return number 0 Vertical content offset -function Container:getOffsetY(self) end - ----Unregisters the children events of the container ----@param child table The child to unregister events for ----@param eventName string The event name to unregister ----@return Container self The container instance -function Container:unregisterChildEvent(child, eventName) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw the text ----@param y number The y position to draw the text ----@param text string The text to draw ----@param fg string The foreground color of the text ----@param bg string The background color of the text ----@return Container self The container instance ----@protected -function Container:blit(x, y, text, fg, bg) end - -function Container:drawText() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was released ----@return boolean handled Whether the event was handled ----@protected -function Container:key_up(key) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Container:mouse_up(button, x, y) end - ----Sets the value of the FocusedChild property. ----@param self Container self ----@param FocusedChild table The focused child of the container -function Container:setFocusedChild(self, FocusedChild) end - ----Registers the children events of the container ----@param child table The child to register events for ----@param eventName string The event name to register ----@return Container self The container instance -function Container:registerChildEvent(child, eventName) end - ----Sets the value of the ChildrenSorted property. ----@param self Container self ----@param ChildrenSorted boolean Whether the children are sorted -function Container:setChildrenSorted(self, ChildrenSorted) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param _ number unknown ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Container:mouse_move(_, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was pressed ----@return boolean handled Whether the event was handled ----@protected -function Container:key(key) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param char string The character that was pressed ----@return boolean handled Whether the event was handled ----@protected -function Container:char(char) end - ----Gets the value of the ChildrenEventsSorted property. ----@param self Container self ----@return boolean true Whether the children events are sorted -function Container:getChildrenEventsSorted(self) end - ----Sets the value of the ChildrenEventsSorted property. ----@param self Container self ----@param ChildrenEventsSorted boolean Whether the children events are sorted -function Container:setChildrenEventsSorted(self, ChildrenEventsSorted) end - ----Adds a child to the container ----@param child table The child to add ----@return Container self The container instance -function Container:addChild(child) end - ----Gets the value of the OffsetX property. ----@param self Container self ----@return number 0 Horizontal content offset -function Container:getOffsetX(self) end - ----Unregisters the children events of the container ----@param child table The child to unregister events for ----@return Container self The container instance -function Container:removeChildrenEvents(child) end - ----@class ErrorHandler -local ErrorHandler = {} - ----Handles an error ----@param errMsg string The error message -function errorHandler.error(errMsg) end - ----@class TabControl : Container ----@field tabHeight number of the tab header area ----@field tabs table of tab definitions ----@field activeTab number currently active tab ID ----@field activeTabBackground color color for the active tab ----@field activeTabTextColor color color for the active tab text ----@field headerBackground color color for the tab header area -local TabControl = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function TabControl:init(props, basalt) end - ----Gets the value of the Tabs property. ----@param self TabControl self ----@return table List of tab definitions -function TabControl:getTabs(self) end - ----Gets the value of the ActiveTab property. ----@param self TabControl self ----@return number The currently active tab ID -function TabControl:getActiveTab(self) end - ----Gets the value of the TabHeight property. ----@param self TabControl self ----@return number Height of the tab header area -function TabControl:getTabHeight(self) end - -function TabControl:mouse_drag() end - -function TabControl:drawText() end - -function TabControl:textBg() end - ----Gets the value of the HeaderBackground property. ----@param self TabControl self ----@return color Background color for the tab header area -function TabControl:getHeaderBackground(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@return number yOffset The Y offset for content ----@protected -function TabControl:getContentYOffset() end - ----@param elementType string The type of element to add ----@param tabId number Optional tab ID, defaults to active tab ----@return table element The created element -function TabControl:addElement(elementType, tabId) end - -function TabControl:drawBg() end - -function TabControl:mouse_release() end - -function TabControl:textFg() end - ----Sets the value of the Tabs property. ----@param self TabControl self ----@param Tabs table of tab definitions -function TabControl:setTabs(self, Tabs) end - ----Sets the value of the HeaderBackground property. ----@param self TabControl self ----@param HeaderBackground color color for the tab header area -function TabControl:setHeaderBackground(self, HeaderBackground) end - ----Sets the value of the ActiveTabTextColor property. ----@param self TabControl self ----@param ActiveTabTextColor color color for the active tab text -function TabControl:setActiveTabTextColor(self, ActiveTabTextColor) end - ----Gets the value of the ActiveTabBackground property. ----@param self TabControl self ----@return color Background color for the active tab -function TabControl:getActiveTabBackground(self) end - ----Sets the value of the ActiveTabBackground property. ----@param self TabControl self ----@param ActiveTabBackground color color for the active tab -function TabControl:setActiveTabBackground(self, ActiveTabBackground) end - -function TabControl:mouse_up() end - ----@param element table The element to assign to a tab ----@param tabId number The ID of the tab to assign the element to ----@return TabControl self For method chaining -function TabControl:setTab(element, tabId) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function TabControl:sortChildrenEvents() end - -function TabControl:drawFg() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function TabControl:render() end - -function TabControl:getRelativePosition() end - ----Sets the value of the TabHeight property. ----@param self TabControl self ----@param TabHeight number of the tab header area -function TabControl:setTabHeight(self, TabHeight) end - -function TabControl:setCursor() end - -function TabControl:mouse_scroll() end - -function TabControl:blit() end - ----Gets the value of the ActiveTabTextColor property. ----@param self TabControl self ----@return color Foreground color for the active tab text -function TabControl:getActiveTabTextColor(self) end - -function TabControl:multiBlit() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param child table The child element to check ----@return boolean Whether the child should be visible ----@protected -function TabControl:isChildVisible(child) end - -function TabControl:mouse_move() end - ----returns a proxy for adding elements to the tab ----@param title string The title of the tab ----@return table tabHandler The tab handler proxy for adding elements to the new tab -function TabControl:newTab(title) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click (global) ----@param y number The y position of the click (global) ----@return boolean Whether the event was handled ----@protected -function TabControl:mouse_click(button, x, y) end - ----@param tabId number The ID of the tab to activate -function TabControl:setActiveTab(tabId) end - -function TabControl:_getHeaderMetrics() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param child table The child element to add ----@return Container self For method chaining ----@protected -function TabControl:addChild(child) end - ----@class Log -local Log = {} - ----Sends a debug message to the logger. -function Log.debug() end - ----Sets if the logger should log -function Log.setEnabled() end - ----Sets if the logger should log to a file. -function Log.setLogToFile() end - ----Sends a warning message to the logger. -function Log.warn() end - ----Sends an error message to the logger. -function Log.error() end - ----Sends an info message to the logger. -function Log.info() end - ----@class Reactive -local Reactive = {} - ----@class Input : VisualElement ----@field placeholderColor color Color of the placeholder text ----@field focusedForeground color Foreground color when input is focused ----@field placeholder string Text to display when input is empty ----@field maxLength number nil Maximum length of input text (optional) ----@field replaceChar string Character to replace the input with (for password fields) ----@field text string The current text content of the input ----@field cursorPos number The current cursor position in the text ----@field cursorColor number Color of the cursor ----@field focusedBackground color Background color when input is focused ----@field viewOffset number The horizontal scroll offset for viewing long text ----@field pattern string nil Regular expression pattern for input validation -local Input = {} - ----Sets the value of the ReplaceChar property. ----@param self Input self ----@param ReplaceChar string Character to replace the input with (for password fields) -function Input:setReplaceChar(self, ReplaceChar) end - ----Sets the value of the PlaceholderColor property. ----@param self Input self ----@param PlaceholderColor color Color of the placeholder text -function Input:setPlaceholderColor(self, PlaceholderColor) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Input:render() end - ----Gets the value of the ViewOffset property. ----@param self Input self ----@return number 0 The horizontal scroll offset for viewing long text -function Input:getViewOffset(self) end - ----Sets the cursor position and color ----@param x number The x position of the cursor ----@param y number The y position of the cursor ----@param blink boolean Whether the cursor should blink ----@param color number The color of the cursor -function Input:setCursor(x, y, blink, color) end - ----Sets the value of the MaxLength property. ----@param self Input self ----@param MaxLength number nil Maximum length of input text (optional) -function Input:setMaxLength(self, MaxLength) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Input:blur() end - ----Sets the value of the CursorColor property. ----@param self Input self ----@param CursorColor number Color of the cursor -function Input:setCursorColor(self, CursorColor) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Input:focus() end - ----Gets the value of the FocusedForeground property. ----@param self Input self ----@return color white Foreground color when input is focused -function Input:getFocusedForeground(self) end - ----Sets the value of the FocusedForeground property. ----@param self Input self ----@param FocusedForeground color Foreground color when input is focused -function Input:setFocusedForeground(self, FocusedForeground) end - ----Updates the input's viewport ----@return Input self The updated instance -function Input:updateViewport() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Input:mouse_click(button, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was pressed ----@return boolean handled Whether the event was handled ----@protected -function Input:key(key) end - ----Sets the value of the ViewOffset property. ----@param self Input self ----@param ViewOffset number The horizontal scroll offset for viewing long text -function Input:setViewOffset(self, ViewOffset) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param char string The character that was typed ----@return boolean handled Whether the event was handled ----@protected -function Input:char(char) end - ----Gets the value of the CursorColor property. ----@param self Input self ----@return number nil Color of the cursor -function Input:getCursorColor(self) end - ----Gets the value of the PlaceholderColor property. ----@param self Input self ----@return color gray Color of the placeholder text -function Input:getPlaceholderColor(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Input:paste() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Input self The initialized instance ----@protected -function Input:init(props, basalt) end - ----Gets the value of the ReplaceChar property. ----@param self Input self ----@return string nil Character to replace the input with (for password fields) -function Input:getReplaceChar(self) end - ----Gets the value of the CursorPos property. ----@param self Input self ----@return number 1 The current cursor position in the text -function Input:getCursorPos(self) end - ----Sets the value of the Placeholder property. ----@param self Input self ----@param Placeholder string Text to display when input is empty -function Input:setPlaceholder(self, Placeholder) end - ----Sets the value of the Text property. ----@param self Input self ----@param Text string The current text content of the input -function Input:setText(self, Text) end - ----Gets the value of the FocusedBackground property. ----@param self Input self ----@return color blue Background color when input is focused -function Input:getFocusedBackground(self) end - ----Gets the value of the Text property. ----@param self Input self ----@return string - The current text content of the input -function Input:getText(self) end - ----Gets the value of the Pattern property. ----@param self Input self ----@return string ? nil Regular expression pattern for input validation -function Input:getPattern(self) end - ----Gets the value of the MaxLength property. ----@param self Input self ----@return number ? nil Maximum length of input text (optional) -function Input:getMaxLength(self) end - ----Gets the value of the Placeholder property. ----@param self Input self ----@return string ... Text to display when input is empty -function Input:getPlaceholder(self) end - ----Sets the value of the CursorPos property. ----@param self Input self ----@param CursorPos number The current cursor position in the text -function Input:setCursorPos(self, CursorPos) end - ----Sets the value of the Pattern property. ----@param self Input self ----@param Pattern string nil Regular expression pattern for input validation -function Input:setPattern(self, Pattern) end - ----Sets the value of the FocusedBackground property. ----@param self Input self ----@param FocusedBackground color Background color when input is focused -function Input:setFocusedBackground(self, FocusedBackground) end - ----@class Animation -local Animation = {} - ----Creates a new sequence ----@return Animation self The animation instance -function Animation:sequence() end - ----Registers a new animation type ----@param name string The name of the animation ----@param handlers table Table containing start, update and complete handlers -function Animation.registerAnimation(name, handlers) end - ----Adds a new animation to the sequence ----@param type string The type of animation ----@param args table The animation arguments ----@param duration number The duration in seconds ----@param easing string The easing function name -function Animation:addAnimation(type, args, duration, easing) end - ----Registers a callback for the start event ----@param callback function The callback function to register -function Animation:onStart(callback) end - ----Starts the animation ----@return Animation self The animation instance -function Animation:start() end - ----Registers a callback for the update event ----@param callback function The callback function to register ----@return Animation self The animation instance -function Animation:onUpdate(callback) end - ----Creates a new Animation ----@param element VisualElement The element to animate ----@return Animation The new animation -function Animation.new(element) end - ----Stops the animation immediately: cancels timers, completes running anim instances and clears the element property -function Animation:stop() end - ----Registers a callback for the complete event ----@param callback function The callback function to register ----@return Animation self The animation instance -function Animation:onComplete(callback) end - ----The event handler for the animation (listens to timer events) ----@param event string The event type ----@param timerId number The timer ID -function Animation:event(event, timerId) end - ----Registers a new easing function ----@param name string The name of the easing function ----@param func function The easing function (takes progress 0-1, returns modified progress) -function Animation.registerEasing(name, func) end - ----@class VisualElement : BaseElement ----@field height number The height of the element ----@field foreground color The text/foreground color ----@field z number The z-index for layering elements ----@field y number The vertical position relative to parent ----@field x number The horizontal position relative to parent ----@field ignoreOffset boolean Whether to ignore the parent's offset ----@field clicked boolean Whether the element is currently clicked ----@field visible boolean Whether the element is visible ----@field backgroundEnabled boolean Whether to render the background ----@field width number The width of the element ----@field hover boolean Whether the mouse is currently hover over the element (Craftos-PC only) ----@field background color The background color ----@field focused boolean Whether the element has input focus -local VisualElement = {} - ----Sets the value of the Background property. ----@param self VisualElement self ----@param Background color The background color -function VisualElement:setBackground(self, Background) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function VisualElement:focus() end - ----Gets the value of the Width property. ----@param self VisualElement self ----@return number 1 The width of the element -function VisualElement:getWidth(self) end - ----Sets the value of the Foreground property. ----@param self VisualElement self ----@param Foreground color The text/foreground color -function VisualElement:setForeground(self, Foreground) end - ----Sets the value of the Z property. ----@param self VisualElement self ----@param Z number The z-index for layering elements -function VisualElement:setZ(self, Z) end - ----Gets the value of the Height property. ----@param self VisualElement self ----@return number 1 The height of the element -function VisualElement:getHeight(self) end - ----Registers a function to handle the onEnter event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnEnter(self, func) end - ----Gets the value of the Background property. ----@param self VisualElement self ----@return color black The background color -function VisualElement:getBackground(self) end - ----Gets the value of the Clicked property. ----@param self VisualElement self ----@return boolean false Whether the element is currently clicked -function VisualElement:getClicked(self) end - ----Sets the value of the Y property. ----@param self VisualElement self ----@param Y number The vertical position relative to parent -function VisualElement:setY(self, Y) end - ----Registers a function to handle the onChar event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnChar(self, func) end - -function VisualElement:drawBg() end - -function VisualElement:drawFg() end - ----Calculates the position of the element relative to its parent ----@return number x The x position ----@return number y The y position -function VisualElement:calculatePosition() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param char string The character that was pressed ----@protected -function VisualElement:char(char) end - ----Registers a function to handle the onScroll event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnScroll(self, func) end - ----Sets the value of the X property. ----@param self VisualElement self ----@param X number The horizontal position relative to parent -function VisualElement:setX(self, X) end - ----Creates a new Animation Object ----@return Animation animation The new animation -function VisualElement:animate() end - ----Sets the value of the Clicked property. ----@param self VisualElement self ----@param Clicked boolean Whether the element is currently clicked -function VisualElement:setClicked(self, Clicked) end - ----Registers a function to handle the onMouseUp event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnMouseUp(self, func) end - ----Sets the value of the Hover property. ----@param self VisualElement self ----@param Hover boolean Whether the mouse is currently hover over the element (Craftos-PC only) -function VisualElement:setHover(self, Hover) end - ----Convenience to stop animations from the element -function VisualElement.stopAnimation() end - ----Checks if the specified coordinates are within the bounds of the element ----@param x number The x position to check ----@param y number The y position to check ----@return boolean isInBounds Whether the coordinates are within the bounds of the element -function VisualElement:isInBounds(x, y) end - ----Gets the value of the Z property. ----@param self VisualElement self ----@return number 1 The z-index for layering elements -function VisualElement:getZ(self) end - ----Sets the value of the Focused property. ----@param self VisualElement self ----@param Focused boolean Whether the element has input focus -function VisualElement:setFocused(self, Focused) end - ----Gets the value of the IgnoreOffset property. ----@param self VisualElement self ----@return boolean false Whether to ignore the parent's offset -function VisualElement:getIgnoreOffset(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function VisualElement:init(props, basalt) end - ----Gets the value of the X property. ----@param self VisualElement self ----@return number 1 The horizontal position relative to parent -function VisualElement:getX(self) end - ----Sets the value of the Width property. ----@param self VisualElement self ----@param Width number The width of the element -function VisualElement:setWidth(self, Width) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw ----@param y number The y position to draw ----@param text string The text char to draw ----@param fg color The foreground color ----@protected -function VisualElement:textFg(x, y, text, fg) end - ----Registers a function to handle the onDrag event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnDrag(self, func) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The scroll direction ----@param x number The x position of the scroll ----@param y number The y position of the scroll ----@return boolean scroll Whether the element was scrolled ----@protected -function VisualElement:mouse_scroll(direction, x, y) end - ----Gets the value of the Focused property. ----@param self VisualElement self ----@return boolean false Whether the element has input focus -function VisualElement:getFocused(self) end - ----Registers a function to handle the onFocus event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnFocus(self, func) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param _ number unknown ----@param x number The x position of the mouse ----@param y number The y position of the mouse ----@return boolean hover Whether the mouse has moved over the element ----@protected -function VisualElement:mouse_move(_, x, y) end - ----Registers a function to handle the onRelease event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnRelease(self, func) end - ----Sets the value of the Height property. ----@param self VisualElement self ----@param Height number The height of the element -function VisualElement:setHeight(self, Height) end - ----Registers a function to handle the onClick event. ----@param button string ----@param x number ----@param y number ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnClick(self, func) end - ----Registers a function to handle the onKeyUp event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnKeyUp(self, func) end - ----Registers a function to handle the onBlur event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnBlur(self, func) end - ----Gets the value of the Foreground property. ----@param self VisualElement self ----@return color white The text/foreground color -function VisualElement:getForeground(self) end - ----This function is used to prioritize the element by moving it to the top of its parent's children. It removes the element from its parent and adds it back, effectively changing its order. ----@return VisualElement self The VisualElement instance -function VisualElement:prioritize() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function VisualElement:postRender() end - ----Registers a function to handle the onLeave event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnLeave(self, func) end - ----Gets the value of the Hover property. ----@param self VisualElement self ----@return boolean false Whether the mouse is currently hover over the element (Craftos-PC only) -function VisualElement:getHover(self) end - ----Returns the relative position of the element or the given coordinates. ----@return number x The relative x position ----@return number y The relative y position -function VisualElement:getRelativePosition() end - -function VisualElement:destroy() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw ----@param y number The y position to draw ----@param text string The text char to draw ----@param bg color The background color ----@protected -function VisualElement:textBg(x, y, text, bg) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position of the cursor ----@param y number The y position of the cursor ----@param blink boolean Whether the cursor should blink ----@param color number The color of the cursor ----@return VisualElement self The VisualElement instance ----@protected -function VisualElement:setCursor(x, y, blink, color) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function VisualElement:blur() end - ----Gets the value of the Visible property. ----@param self VisualElement self ----@return boolean true Whether the element is visible -function VisualElement:getVisible(self) end - ----Gets the value of the BackgroundEnabled property. ----@param self VisualElement self ----@return boolean true Whether to render the background -function VisualElement:getBackgroundEnabled(self) end - ----Sets the value of the BackgroundEnabled property. ----@param self VisualElement self ----@param BackgroundEnabled boolean Whether to render the background -function VisualElement:setBackgroundEnabled(self, BackgroundEnabled) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw ----@param y number The y position to draw ----@param width number The width of the area to draw ----@param height number The height of the area to draw ----@param text string The text to draw ----@param fg string The foreground color ----@param bg string The background color ----@protected -function VisualElement:multiBlit(x, y, width, height, text, fg, bg) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked while dragging ----@param x number The x position of the drag ----@param y number The y position of the drag ----@return boolean drag Whether the element was dragged ----@protected -function VisualElement:mouse_drag(button, x, y) end - ----Registers a function to handle the onKey event. ----@param self VisualElement self ----@param func function The function to be called when the event fires -function VisualElement:onOnKey(self, func) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was pressed ----@protected -function VisualElement:key(key) end - ----Sets the value of the IgnoreOffset property. ----@param self VisualElement self ----@param IgnoreOffset boolean Whether to ignore the parent's offset -function VisualElement:setIgnoreOffset(self, IgnoreOffset) end - ----Returns the absolute position of the element or the given coordinates. ----@return number x The absolute x position ----@return number y The absolute y position -function VisualElement:getAbsolutePosition() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was released ----@param x number The x position of the release ----@param y number The y position of the release ----@protected -function VisualElement:mouse_release(button, x, y) end - ----Gets the value of the Y property. ----@param self VisualElement self ----@return number 1 The vertical position relative to parent -function VisualElement:getY(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was released ----@protected -function VisualElement:key_up(key) end - ----Sets the value of the Visible property. ----@param self VisualElement self ----@param Visible boolean Whether the element is visible -function VisualElement:setVisible(self, Visible) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean clicked Whether the element was clicked ----@protected -function VisualElement:mouse_click(button, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to draw ----@param y number The y position to draw ----@param text string The text char to draw ----@param fg string The foreground color ----@param bg string The background color ----@protected -function VisualElement:blit(x, y, text, fg, bg) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was released ----@param x number The x position of the release ----@param y number The y position of the release ----@return boolean release Whether the element was released on the element ----@protected -function VisualElement:mouse_up(button, x, y) end - -function VisualElement:drawText() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function VisualElement:render() end - ----@class BarChart : Graph -local BarChart = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return BarChart self The initialized instance ----@protected -function BarChart:init(props, basalt) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function BarChart:render() end - ----@class Graph : VisualElement ----@field maxValue number The maximum value of the graph ----@field minValue number The minimum value of the graph ----@field series table The series of the graph -local Graph = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Graph:render() end - ----Clears all points from a series ----@return Graph self The graph instance -function Graph:clear() end - ----@param name string The name of the series ----@param count number The number of points in the series ----@return Graph self The graph instance -function Graph:setSeriesPointCount(name, count) end - ----@param name string The name of the series ----@return Graph self The graph instance -function Graph:removeSeries(name) end - ----@param name string The name of the series ----@return Graph self The graph instance -function Graph:focusSeries(name) end - ----@param name string The name of the series ----@param visible boolean Whether the series should be visible ----@return Graph self The graph instance -function Graph:changeSeriesVisibility(name, visible) end - ----@param name string The name of the series ----@param value number The value of the point ----@return Graph self The graph instance -function Graph:addPoint(name, value) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Graph self The initialized instance ----@protected -function Graph:init(props, basalt) end - ----Gets the value of the MaxValue property. ----@param self Graph self ----@return number 100 The maximum value of the graph -function Graph:getMaxValue(self) end - ----Sets the value of the MaxValue property. ----@param self Graph self ----@param MaxValue number The maximum value of the graph -function Graph:setMaxValue(self, MaxValue) end - ----Gets the value of the MinValue property. ----@param self Graph self ----@return number 0 The minimum value of the graph -function Graph:getMinValue(self) end - ----Sets the value of the MinValue property. ----@param self Graph self ----@param MinValue number The minimum value of the graph -function Graph:setMinValue(self, MinValue) end - ----@param name string The name of the series ----@param symbol string The symbol of the series ----@param bgCol number The background color of the series ----@param fgCol number The foreground color of the series ----@param pointCount number The number of points in the series ----@return Graph self The graph instance -function Graph:addSeries(name, symbol, bgCol, fgCol, pointCount) end - ----@param name string The name of the series ----@return table ? series The series -function Graph:getSeries(name) end - ----Sets the value of the Series property. ----@param self Graph self ----@param Series table The series of the graph -function Graph:setSeries(self, Series) end - ----@class Timer : BaseElement ----@field running boolean Indicates whether the timer is currently running or not. ----@field interval number The interval in seconds at which the timer will trigger its action. ----@field amount number The amount of time the timer should run. ----@field action function The action to be performed when the timer triggers. -local Timer = {} - ----Sets the value of the Running property. ----@param self Timer self ----@param Running boolean Indicates whether the timer is currently running or not. -function Timer:setRunning(self, Running) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function Timer:init(props, basalt) end - ----Starts the timer with the specified interval. ----@param self Timer The Timer instance to start ----@return Timer self The Timer instance -function Timer:start(self) end - ----Sets the value of the Amount property. ----@param self Timer self ----@param Amount number The amount of time the timer should run. -function Timer:setAmount(self, Amount) end - ----Gets the value of the Amount property. ----@param self Timer self ----@return number -1 The amount of time the timer should run. -function Timer:getAmount(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Timer:dispatchEvent() end - ----Gets the value of the Running property. ----@param self Timer self ----@return boolean false Indicates whether the timer is currently running or not. -function Timer:getRunning(self) end - ----Gets the value of the Action property. ----@param self Timer self ----@return function function The action to be performed when the timer triggers. -function Timer:getAction(self) end - ----Stops the timer if it is currently running. ----@param self Timer The Timer instance to stop ----@return Timer self The Timer instance -function Timer:stop(self) end - ----Sets the value of the Action property. ----@param self Timer self ----@param Action function The action to be performed when the timer triggers. -function Timer:setAction(self, Action) end - ----Gets the value of the Interval property. ----@param self Timer self ----@return number 1 The interval in seconds at which the timer will trigger its action. -function Timer:getInterval(self) end - ----Sets the value of the Interval property. ----@param self Timer self ----@param Interval number The interval in seconds at which the timer will trigger its action. -function Timer:setInterval(self, Interval) end - ---@class PropertySystem local PropertySystem = {} ----Initializes the PropertySystem IS USED INTERNALLY ----@return table self The PropertySystem -function PropertySystem:__init() end +---Gets a property configuration +---@param name string The name of the property +---@return table config The configuration of the property +function PropertySystem:getPropertyConfig(name) end + +---Adds a setter hook to the PropertySystem. Setter hooks are functions that are called before a property is set. +---@param hook function The hook function to add +function PropertySystem.addSetterHook(hook) end ---Defines a property for an element class ---@param class table The element class to define the property for @@ -2348,334 +1406,242 @@ function PropertySystem:__init() end ---@param config table The configuration of the property function PropertySystem.defineProperty(class, name, config) end ----Creates a blueprint of an element class with all its properties ----@param elementClass table The element class to create a blueprint from ----@return table blueprint A table containing all property definitions -function PropertySystem.blueprint(elementClass) end - ----Observers a property ----@param name string The name of the property ----@param callback function The callback function to call when the property changes ----@return table self The PropertySystem -function PropertySystem:observe(name, callback) end - ---Removes all observers from a property ---@return table self The PropertySystem function PropertySystem:removeAllObservers() end ----Gets a property configuration ----@param name string The name of the property ----@return table config The configuration of the property -function PropertySystem:getPropertyConfig(name) end - ----Creates an element from a blueprint ----@param elementClass table The element class to create from the blueprint ----@param blueprint table The blueprint to create the element from ----@return table element The created element -function PropertySystem.createFromBlueprint(elementClass, blueprint) end - ----Removes a property from the PropertySystem on instance level ----@param name string The name of the property ----@return table self The PropertySystem -function PropertySystem:removeProperty(name) end - ----Combines multiple properties into a single getter and setter ----@param class table The element class to combine the properties for ----@param name string The name of the combined property -function PropertySystem.combineProperties(class, name) end - ----Adds a property to the PropertySystem on instance level ----@param name string The name of the property ----@param config table The configuration of the property ----@return table self The PropertySystem -function PropertySystem:instanceProperty(name, config) end - ----Removes an observer from a property ----@param name string The name of the property ----@param callback function The callback function to remove ----@return table self The PropertySystem -function PropertySystem:removeObserver(name, callback) end - ---Update call for a property IS USED INTERNALLY ---@param name string The name of the property ---@param value any The value of the property ---@return table self The PropertySystem function PropertySystem:_updateProperty(name, value) end ----Adds a setter hook to the PropertySystem. Setter hooks are functions that are called before a property is set. ----@param hook function The hook function to add -function PropertySystem.addSetterHook(hook) end +---Combines multiple properties into a single getter and setter +---@param class table The element class to combine the properties for +---@param name string The name of the combined property +function PropertySystem.combineProperties(class, name) end + +---Removes an observer from a property +---@param name string The name of the property +---@param callback function The callback function to remove +---@return table self The PropertySystem +function PropertySystem:removeObserver(name, callback) end + +---Observers a property +---@param name string The name of the property +---@param callback function The callback function to call when the property changes +---@return table self The PropertySystem +function PropertySystem:observe(name, callback) end + +---Creates an element from a blueprint +---@param elementClass table The element class to create from the blueprint +---@param blueprint table The blueprint to create the element from +---@return table element The created element +function PropertySystem.createFromBlueprint(elementClass, blueprint) end + +---Creates a blueprint of an element class with all its properties +---@param elementClass table The element class to create a blueprint from +---@return table blueprint A table containing all property definitions +function PropertySystem.blueprint(elementClass) end + +---Removes a property from the PropertySystem on instance level +---@param name string The name of the property +---@return table self The PropertySystem +function PropertySystem:removeProperty(name) end + +---Initializes the PropertySystem IS USED INTERNALLY +---@return table self The PropertySystem +function PropertySystem:__init() end + +---Adds a property to the PropertySystem on instance level +---@param name string The name of the property +---@param config table The configuration of the property +---@return table self The PropertySystem +function PropertySystem:instanceProperty(name, config) end + +---@class Menu : List +---@field separatorColor color The color used for separator items in the menu +local Menu = {} + +---Sets the value of the SeparatorColor property. +---@param self Menu self +---@param SeparatorColor color The color used for separator items in the menu +function Menu:setSeparatorColor(self, SeparatorColor) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Menu self The initialized instance +---@protected +function Menu:init(props, basalt) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Menu:render() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean Whether the event was handled +---@protected +function Menu:mouse_click(button, x, y) end + +---Sets the menu items +---@param items table [] List of items with {text, separator, callback, foreground, background} properties +---@return Menu self The Menu instance +function Menu:setItems(items) end + +---Gets the value of the SeparatorColor property. +---@param self Menu self +---@return color gray The color used for separator items in the menu +function Menu:getSeparatorColor(self) end + +---@class Label : VisualElement +---@field text string The text content to display. Can be a string or a function that returns a string +---@field autoSize boolean Whether the label should automatically resize its width based on the text content +local Label = {} + +---Sets the value of the AutoSize property. +---@param self Label self +---@param AutoSize boolean Whether the label should automatically resize its width based on the text content +function Label:setAutoSize(self, AutoSize) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Label:render() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Label self The initialized instance +---@protected +function Label:init(props, basalt) end + +---Sets the value of the Text property. +---@param self Label self +---@param Text string The text content to display. Can be a string or a function that returns a string +function Label:setText(self, Text) end + +---Gets the wrapped lines of the Label +---@return table wrappedText The wrapped lines of the Label +function Label:getWrappedText() end + +---Gets the value of the AutoSize property. +---@param self Label self +---@return boolean true Whether the label should automatically resize its width based on the text content +function Label:getAutoSize(self) end + +---Gets the value of the Text property. +---@param self Label self +---@return string Label The text content to display. Can be a string or a function that returns a string +function Label:getText(self) end + +---@class basalt +local basalt = {} + +---Starts the Basalt runtime +function basalt.run() end + +---Returns the focused frame +---@return BaseFrame ? BaseFrame The focused frame +function basalt.getFocus() end + +---Runs basalt once, can be used to update the UI manually, but you have to feed it the events +function basalt.update() end + +---Stops the Basalt runtime +function basalt.stop() end + +---Sets the active frame +---@param frame BaseFrame The frame to set as active +function basalt.setActiveFrame(frame) end + +---Gets or creates the main frame +---@return BaseFrame BaseFrame The main frame instance +function basalt.getMainFrame() end + +---Returns the element manager instance +---@return table ElementManager The element manager +function basalt.getElementManager() end + +---Returns the error manager instance +---@return table ErrorManager The error manager +function basalt.getErrorManager() end + +---Creates and returns a new UI element of the specified type. +---@param type string The type of element to create (e.g. "Button", "Label", "BaseFrame") +---@return table element The created element instance +function basalt.create(type) end + +---Removes a scheduled update +---@param func thread The scheduled function to remove +---@return boolean success Whether the scheduled function was removed +function basalt.removeSchedule(func) end + +---Returns the active frame +---@return BaseFrame ? BaseFrame The frame to set as active +function basalt.getActiveFrame() end + +---Returns an element's class without creating a instance +---@param name string The name of the element +---@return table Element The element class +function basalt.getElementClass(name) end + +---Registers a callback function for a specific event +---@param eventName string The name of the event to listen for (e.g. "mouse_click", "key", "timer") +---@param callback function The callback function to execute when the event occurs +function basalt.onEvent(eventName, callback) end + +---Sets a frame as focused +---@param frame BaseFrame The frame to set as focused +function basalt.setFocus(frame) end + +---Triggers a custom event and calls all registered callbacks +---@param eventName string The name of the event to trigger +function basalt.triggerEvent(eventName) end + +---Removes a callback function for a specific event +---@param eventName string The name of the event +---@param callback function The callback function to remove +---@return boolean success Whether the callback was found and removed +function basalt.removeEvent(eventName, callback) end + +---Returns a Plugin API +---@param name string The name of the plugin +---@return table Plugin The plugin API +function basalt.getAPI(name) end + +---Creates and returns a new BaseFrame +---@return BaseFrame BaseFrame The created frame instance +function basalt.createFrame() end + +---Schedules a function to run in a coroutine +---@param func function The function to schedule +---@return thread func The scheduled function +function basalt.schedule(func) end ---@class BigFontText local BigFontText = {} ----@class ComboBox : DropDown ----@field placeholderColor color Color of the placeholder text ----@field focusedForeground color Foreground color when ComboBox is focused ----@field placeholder string Text to display when input is empty ----@field manuallyOpened boolean Whether the dropdown was manually opened (not by auto-complete) ----@field text string The current text content of the ComboBox ----@field cursorPos number The current cursor position in the text ----@field autoComplete boolean Whether to enable auto-complete filtering when typing ----@field focusedBackground color Background color when ComboBox is focused ----@field viewOffset number The horizontal scroll offset for viewing long text ----@field editable boolean Whether the ComboBox allows text input -local ComboBox = {} +---@class Frame : Container +---@field draggingMap table The map of dragging positions +---@field draggable boolean Whether the frame is draggable +---@field scrollable boolean Whether the frame is scrollable +local Frame = {} ----Sets the value of the AutoComplete property. ----@param self ComboBox self ----@param AutoComplete boolean Whether to enable auto-complete filtering when typing -function ComboBox:setAutoComplete(self, AutoComplete) end - ----Sets the value of the Placeholder property. ----@param self ComboBox self ----@param Placeholder string Text to display when input is empty -function ComboBox:setPlaceholder(self, Placeholder) end - ----Called when the ComboBox loses focus -function ComboBox:blur() end - ----Gets the current text content ----@return string text The current text -function ComboBox:getText() end - ----Gets the value of the PlaceholderColor property. ----@param self ComboBox self ----@return color gray Color of the placeholder text -function ComboBox:getPlaceholderColor(self) end - ----Handles character input when editable ----@param char string The character that was typed -function ComboBox:char(char) end - ----Creates a new ComboBox instance ----@return ComboBox self The newly created ComboBox instance -function ComboBox.new() end - ----Gets the value of the FocusedForeground property. ----@param self ComboBox self ----@return color white Foreground color when ComboBox is focused -function ComboBox:getFocusedForeground(self) end +---Gets the value of the Scrollable property. +---@param self Frame self +---@return boolean false Whether the frame is scrollable +function Frame:getScrollable(self) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return ComboBox self The initialized instance ----@protected -function ComboBox:init(props, basalt) end - ----Gets the value of the ManuallyOpened property. ----@param self ComboBox self ----@return boolean false Whether the dropdown was manually opened (not by auto-complete) -function ComboBox:getManuallyOpened(self) end - ----Sets whether the ComboBox is editable ----@param editable boolean Whether the ComboBox should be editable ----@return ComboBox self -function ComboBox:setEditable(editable) end - ----Handles key input when editable ----@param key number The key code that was pressed ----@param held boolean Whether the key is being held -function ComboBox:key(key, held) end - ----Renders the ComboBox -function ComboBox:render() end - ----Gets the value of the Editable property. ----@param self ComboBox self ----@return boolean true Whether the ComboBox allows text input -function ComboBox:getEditable(self) end - ----Sets the value of the ManuallyOpened property. ----@param self ComboBox self ----@param ManuallyOpened boolean Whether the dropdown was manually opened (not by auto-complete) -function ComboBox:setManuallyOpened(self, ManuallyOpened) end - ----Gets the value of the Placeholder property. ----@param self ComboBox self ----@return string "..." Text to display when input is empty -function ComboBox:getPlaceholder(self) end - ----Sets the value of the FocusedBackground property. ----@param self ComboBox self ----@param FocusedBackground color Background color when ComboBox is focused -function ComboBox:setFocusedBackground(self, FocusedBackground) end - ----Gets the value of the ViewOffset property. ----@param self ComboBox self ----@return number 0 The horizontal scroll offset for viewing long text -function ComboBox:getViewOffset(self) end - ----Called when the ComboBox gains focus -function ComboBox:focus() end - ----Sets the value of the ViewOffset property. ----@param self ComboBox self ----@param ViewOffset number The horizontal scroll offset for viewing long text -function ComboBox:setViewOffset(self, ViewOffset) end - ----Sets the text content of the ComboBox ----@param text string The text to set ----@return ComboBox self -function ComboBox:setText(text) end - ----Gets the value of the CursorPos property. ----@param self ComboBox self ----@return number 1 The current cursor position in the text -function ComboBox:getCursorPos(self) end - ----Sets the value of the PlaceholderColor property. ----@param self ComboBox self ----@param PlaceholderColor color Color of the placeholder text -function ComboBox:setPlaceholderColor(self, PlaceholderColor) end - ----Sets the value of the FocusedForeground property. ----@param self ComboBox self ----@param FocusedForeground color Foreground color when ComboBox is focused -function ComboBox:setFocusedForeground(self, FocusedForeground) end - ----Gets the value of the AutoComplete property. ----@param self ComboBox self ----@return boolean false Whether to enable auto-complete filtering when typing -function ComboBox:getAutoComplete(self) end - ----Handles mouse clicks ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button (1 = left, 2 = right, 3 = middle) ----@param x number The x coordinate of the click ----@param y number The y coordinate of the click +---@param button number The button that was released +---@param x number The x position of the release +---@param y number The y position of the release ---@return boolean handled Whether the event was handled ---@protected -function ComboBox:mouse_click(button, x, y) end - ----Sets the value of the CursorPos property. ----@param self ComboBox self ----@param CursorPos number The current cursor position in the text -function ComboBox:setCursorPos(self, CursorPos) end - ----Gets the value of the FocusedBackground property. ----@param self ComboBox self ----@return color blue Background color when ComboBox is focused -function ComboBox:getFocusedBackground(self) end - ----@class Display : VisualElement -local Display = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function Display:init(props, basalt) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Display:render() end - ----Returns the current window object ----@return table window The current window object -function Display:getWindow() end - ----Writes text to the display at the given position with the given foreground and background colors ----@param x number The x position to write to ----@param y number The y position to write to ----@param text string The text to write ----@return Display self The display instance -function Display:write(x, y, text) end - ----@class TextBox : VisualElement ----@field lines table Array of text lines ----@field cursorX number Cursor X position ----@field syntaxPatterns table Syntax highlighting patterns ----@field scrollX number Horizontal scroll offset ----@field editable boolean Whether text can be edited ----@field cursorY number Cursor Y position (line number) ----@field cursorColor number Color of the cursor ----@field scrollY number Vertical scroll offset -local TextBox = {} - ----Gets the value of the Lines property. ----@param self TextBox self ----@return table {} Array of text lines -function TextBox:getLines(self) end - ----Sets the value of the CursorColor property. ----@param self TextBox self ----@param CursorColor number Color of the cursor -function TextBox:setCursorColor(self, CursorColor) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param char string The character that was typed ----@return boolean handled Whether the event was handled ----@protected -function TextBox:char(char) end - ----Sets the value of the CursorY property. ----@param self TextBox self ----@param CursorY number Cursor Y position (line number) -function TextBox:setCursorY(self, CursorY) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The scroll direction ----@param x number The x position of the scroll ----@param y number The y position of the scroll ----@return boolean handled Whether the event was handled ----@protected -function TextBox:mouse_scroll(direction, x, y) end - ----Sets the value of the Lines property. ----@param self TextBox self ----@param Lines table Array of text lines -function TextBox:setLines(self, Lines) end - ----Sets the value of the Editable property. ----@param self TextBox self ----@param Editable boolean Whether text can be edited -function TextBox:setEditable(self, Editable) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function TextBox:render() end - ----Gets the value of the SyntaxPatterns property. ----@param self TextBox self ----@return table {} Syntax highlighting patterns -function TextBox:getSyntaxPatterns(self) end - ----Gets the text of the TextBox ----@return string text The text of the TextBox -function TextBox:getText() end - ----Sets the value of the CursorX property. ----@param self TextBox self ----@param CursorX number Cursor X position -function TextBox:setCursorX(self, CursorX) end - ----Sets the text of the TextBox ----@param text string The text to set ----@return TextBox self The TextBox instance -function TextBox:setText(text) end - ----Sets the value of the ScrollY property. ----@param self TextBox self ----@param ScrollY number Vertical scroll offset -function TextBox:setScrollY(self, ScrollY) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function TextBox:paste() end - ----Gets the value of the ScrollY property. ----@param self TextBox self ----@return number 0 Vertical scroll offset -function TextBox:getScrollY(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return TextBox self The initialized instance ----@protected -function TextBox:init(props, basalt) end +function Frame:mouse_up(button, x, y) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param button number The button that was clicked @@ -2683,94 +1649,73 @@ function TextBox:init(props, basalt) end ---@param y number The y position of the click ---@return boolean handled Whether the event was handled ---@protected -function TextBox:mouse_click(button, x, y) end +function Frame:mouse_click(button, x, y) end ----Clears all syntax highlighting patterns ----@return TextBox self -function TextBox:clearSyntaxPatterns() end - ----Gets the value of the CursorColor property. ----@param self TextBox self ----@return number nil Color of the cursor -function TextBox:getCursorColor(self) end - ----Updates the viewport to keep the cursor in view ----@return TextBox self The TextBox instance -function TextBox:updateViewport() end +---Gets the value of the Draggable property. +---@param self Frame self +---@return boolean false Whether the frame is draggable +function Frame:getDraggable(self) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was pressed +---@param direction number The scroll direction +---@param x number The x position of the scroll +---@param y number The y position of the scroll ---@return boolean handled Whether the event was handled ---@protected -function TextBox:key(key) end +function Frame:mouse_scroll(direction, x, y) end ----Gets the value of the ScrollX property. ----@param self TextBox self ----@return number 0 Horizontal scroll offset -function TextBox:getScrollX(self) end +---Sets the value of the DraggingMap property. +---@param self Frame self +---@param DraggingMap table The map of dragging positions +function Frame:setDraggingMap(self, DraggingMap) end ----Gets the value of the CursorX property. ----@param self TextBox self ----@return number 1 Cursor X position -function TextBox:getCursorX(self) end +---Sets the value of the Draggable property. +---@param self Frame self +---@param Draggable boolean Whether the frame is draggable +function Frame:setDraggable(self, Draggable) end ----Gets the value of the CursorY property. ----@param self TextBox self ----@return number 1 Cursor Y position (line number) -function TextBox:getCursorY(self) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@return number height The total height needed for all children +---@protected +function Frame:getChildrenHeight() end ----Sets the value of the SyntaxPatterns property. ----@param self TextBox self ----@param SyntaxPatterns table Syntax highlighting patterns -function TextBox:setSyntaxPatterns(self, SyntaxPatterns) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the drag position +---@param y number The y position of the drag position +---@return boolean handled Whether the event was handled +---@protected +function Frame:mouse_drag(button, x, y) end ----Adds a new syntax highlighting pattern ----@param pattern string The regex pattern to match ----@param color number The color to apply ----@return TextBox self The TextBox instance -function TextBox:addSyntaxPattern(pattern, color) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Frame self The initialized instance +---@protected +function Frame:init(props, basalt) end ----Sets the value of the ScrollX property. ----@param self TextBox self ----@param ScrollX number Horizontal scroll offset -function TextBox:setScrollX(self, ScrollX) end +---Sets the value of the Scrollable property. +---@param self Frame self +---@param Scrollable boolean Whether the frame is scrollable +function Frame:setScrollable(self, Scrollable) end ----Gets the value of the Editable property. ----@param self TextBox self ----@return boolean true Whether text can be edited -function TextBox:getEditable(self) end - ----Removes a syntax pattern by index (1-based) ----@param index number The index of the pattern to remove ----@return TextBox self -function TextBox:removeSyntaxPattern(index) end +---Gets the value of the DraggingMap property. +---@param self Frame self +---@return table {} The map of dragging positions +function Frame:getDraggingMap(self) end ---@class ProgressBar : VisualElement ---@field direction string The direction of the progress bar ("up", "down", "left", "right") ----@field progress number Current progress value (0-100) ---@field progressColor color The color used for the filled portion of the progress bar +---@field progress number Current progress value (0-100) ---@field showPercentage boolean Whether to show the percentage text in the center local ProgressBar = {} ----Sets the value of the Progress property. ----@param self ProgressBar self ----@param Progress number Current progress value (0-100) -function ProgressBar:setProgress(self, Progress) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function ProgressBar:render() end - ---Gets the value of the ShowPercentage property. ---@param self ProgressBar self ---@return boolean false Whether to show the percentage text in the center function ProgressBar:getShowPercentage(self) end ----Gets the value of the Progress property. ----@param self ProgressBar self ----@return number 0 Current progress value (0-100) -function ProgressBar:getProgress(self) end - ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param props table The properties to initialize the element with ---@param basalt table The basalt instance @@ -2778,10 +1723,24 @@ function ProgressBar:getProgress(self) end ---@protected function ProgressBar:init(props, basalt) end ----Sets the value of the ProgressColor property. +---Gets the value of the Progress property. ---@param self ProgressBar self ----@param ProgressColor color The color used for the filled portion of the progress bar -function ProgressBar:setProgressColor(self, ProgressColor) end +---@return number 0 Current progress value (0-100) +function ProgressBar:getProgress(self) end + +---Sets the value of the ShowPercentage property. +---@param self ProgressBar self +---@param ShowPercentage boolean Whether to show the percentage text in the center +function ProgressBar:setShowPercentage(self, ShowPercentage) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function ProgressBar:render() end + +---Sets the value of the Progress property. +---@param self ProgressBar self +---@param Progress number Current progress value (0-100) +function ProgressBar:setProgress(self, Progress) end ---Gets the value of the ProgressColor property. ---@param self ProgressBar self @@ -2798,60 +1757,1660 @@ function ProgressBar:setDirection(self, Direction) end ---@return string right The direction of the progress bar ("up", "down", "left", "right") function ProgressBar:getDirection(self) end ----Sets the value of the ShowPercentage property. +---Sets the value of the ProgressColor property. ---@param self ProgressBar self ----@param ShowPercentage boolean Whether to show the percentage text in the center -function ProgressBar:setShowPercentage(self, ShowPercentage) end +---@param ProgressColor color The color used for the filled portion of the progress bar +function ProgressBar:setProgressColor(self, ProgressColor) end + +---@class VisualElement : BaseElement +---@field backgroundEnabled boolean Whether to render the background +---@field clicked boolean Whether the element is currently clicked +---@field width number The width of the element +---@field x number The horizontal position relative to parent +---@field y number The vertical position relative to parent +---@field background color The background color +---@field hover boolean Whether the mouse is currently hover over the element (Craftos-PC only) +---@field z number The z-index for layering elements +---@field ignoreOffset boolean Whether to ignore the parent's offset +---@field visible boolean Whether the element is visible +---@field foreground color The text/foreground color +---@field height number The height of the element +---@field focused boolean Whether the element has input focus +local VisualElement = {} + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param _ number unknown +---@param x number The x position of the mouse +---@param y number The y position of the mouse +---@return boolean hover Whether the mouse has moved over the element +---@protected +function VisualElement:mouse_move(_, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was released +---@param x number The x position of the release +---@param y number The y position of the release +---@return boolean release Whether the element was released on the element +---@protected +function VisualElement:mouse_up(button, x, y) end + +function VisualElement:drawFg() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was pressed +---@protected +function VisualElement:key(key) end + +---Registers a function to handle the onRelease event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnRelease(self, func) end + +---Gets the value of the Visible property. +---@param self VisualElement self +---@return boolean true Whether the element is visible +function VisualElement:getVisible(self) end + +---Gets the value of the Background property. +---@param self VisualElement self +---@return color black The background color +function VisualElement:getBackground(self) end + +---Gets the value of the Width property. +---@param self VisualElement self +---@return number 1 The width of the element +function VisualElement:getWidth(self) end + +---Registers a function to handle the onDrag event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnDrag(self, func) end + +---Registers a function to handle the onLeave event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnLeave(self, func) end + +---Sets the value of the Hover property. +---@param self VisualElement self +---@param Hover boolean Whether the mouse is currently hover over the element (Craftos-PC only) +function VisualElement:setHover(self, Hover) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw +---@param y number The y position to draw +---@param text string The text char to draw +---@param bg color The background color +---@protected +function VisualElement:textBg(x, y, text, bg) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw +---@param y number The y position to draw +---@param text string The text char to draw +---@param fg color The foreground color +---@protected +function VisualElement:textFg(x, y, text, fg) end + +---Registers a function to handle the onFocus event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnFocus(self, func) end + +---Sets the value of the Y property. +---@param self VisualElement self +---@param Y number The vertical position relative to parent +function VisualElement:setY(self, Y) end + +---Sets the value of the Width property. +---@param self VisualElement self +---@param Width number The width of the element +function VisualElement:setWidth(self, Width) end + +---Gets the value of the Height property. +---@param self VisualElement self +---@return number 1 The height of the element +function VisualElement:getHeight(self) end + +---Calculates the position of the element relative to its parent +---@return number x The x position +---@return number y The y position +function VisualElement:calculatePosition() end + +---Registers a function to handle the onScroll event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnScroll(self, func) end + +---Registers a function to handle the onKeyUp event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnKeyUp(self, func) end + +---Registers a function to handle the onChar event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnChar(self, func) end + +function VisualElement:drawText() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw +---@param y number The y position to draw +---@param text string The text char to draw +---@param fg string The foreground color +---@param bg string The background color +---@protected +function VisualElement:blit(x, y, text, fg, bg) end + +---Sets the value of the Background property. +---@param self VisualElement self +---@param Background color The background color +function VisualElement:setBackground(self, Background) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked while dragging +---@param x number The x position of the drag +---@param y number The y position of the drag +---@return boolean drag Whether the element was dragged +---@protected +function VisualElement:mouse_drag(button, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function VisualElement:render() end + +---Registers a function to handle the onMouseUp event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnMouseUp(self, func) end + +---This function is used to prioritize the element by moving it to the top of its parent's children. It removes the element from its parent and adds it back, effectively changing its order. +---@return VisualElement self The VisualElement instance +function VisualElement:prioritize() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function VisualElement:postRender() end + +---Gets the value of the BackgroundEnabled property. +---@param self VisualElement self +---@return boolean true Whether to render the background +function VisualElement:getBackgroundEnabled(self) end + +---Gets the value of the Z property. +---@param self VisualElement self +---@return number 1 The z-index for layering elements +function VisualElement:getZ(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param direction number The scroll direction +---@param x number The x position of the scroll +---@param y number The y position of the scroll +---@return boolean scroll Whether the element was scrolled +---@protected +function VisualElement:mouse_scroll(direction, x, y) end + +---Creates a new Animation Object +---@return Animation animation The new animation +function VisualElement:animate() end + +---Gets the value of the Foreground property. +---@param self VisualElement self +---@return color white The text/foreground color +function VisualElement:getForeground(self) end + +---Sets the value of the Foreground property. +---@param self VisualElement self +---@param Foreground color The text/foreground color +function VisualElement:setForeground(self, Foreground) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function VisualElement:blur() end + +---Sets the value of the BackgroundEnabled property. +---@param self VisualElement self +---@param BackgroundEnabled boolean Whether to render the background +function VisualElement:setBackgroundEnabled(self, BackgroundEnabled) end + +---Gets the value of the Focused property. +---@param self VisualElement self +---@return boolean false Whether the element has input focus +function VisualElement:getFocused(self) end + +---Returns the relative position of the element or the given coordinates. +---@return number x The relative x position +---@return number y The relative y position +function VisualElement:getRelativePosition() end + +function VisualElement:destroy() end + +---Sets the value of the Clicked property. +---@param self VisualElement self +---@param Clicked boolean Whether the element is currently clicked +function VisualElement:setClicked(self, Clicked) end + +---Registers a function to handle the onKey event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnKey(self, func) end + +function VisualElement:drawBg() end + +---Gets the value of the Clicked property. +---@param self VisualElement self +---@return boolean false Whether the element is currently clicked +function VisualElement:getClicked(self) end + +---Convenience to stop animations from the element +function VisualElement.stopAnimation() end + +---Gets the value of the Hover property. +---@param self VisualElement self +---@return boolean false Whether the mouse is currently hover over the element (Craftos-PC only) +function VisualElement:getHover(self) end + +---Registers a function to handle the onEnter event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnEnter(self, func) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function VisualElement:init(props, basalt) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to draw +---@param y number The y position to draw +---@param width number The width of the area to draw +---@param height number The height of the area to draw +---@param text string The text to draw +---@param fg string The foreground color +---@param bg string The background color +---@protected +function VisualElement:multiBlit(x, y, width, height, text, fg, bg) end + +---Sets the value of the IgnoreOffset property. +---@param self VisualElement self +---@param IgnoreOffset boolean Whether to ignore the parent's offset +function VisualElement:setIgnoreOffset(self, IgnoreOffset) end + +---Gets the value of the X property. +---@param self VisualElement self +---@return number 1 The horizontal position relative to parent +function VisualElement:getX(self) end + +---Sets the value of the Z property. +---@param self VisualElement self +---@param Z number The z-index for layering elements +function VisualElement:setZ(self, Z) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param char string The character that was pressed +---@protected +function VisualElement:char(char) end + +---Sets the value of the Height property. +---@param self VisualElement self +---@param Height number The height of the element +function VisualElement:setHeight(self, Height) end + +---Registers a function to handle the onBlur event. +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnBlur(self, func) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean clicked Whether the element was clicked +---@protected +function VisualElement:mouse_click(button, x, y) end + +---Sets the value of the X property. +---@param self VisualElement self +---@param X number The horizontal position relative to parent +function VisualElement:setX(self, X) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was released +---@protected +function VisualElement:key_up(key) end + +---Sets the value of the Visible property. +---@param self VisualElement self +---@param Visible boolean Whether the element is visible +function VisualElement:setVisible(self, Visible) end + +---Checks if the specified coordinates are within the bounds of the element +---@param x number The x position to check +---@param y number The y position to check +---@return boolean isInBounds Whether the coordinates are within the bounds of the element +function VisualElement:isInBounds(x, y) end + +---Gets the value of the IgnoreOffset property. +---@param self VisualElement self +---@return boolean false Whether to ignore the parent's offset +function VisualElement:getIgnoreOffset(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function VisualElement:focus() end + +---Sets the value of the Focused property. +---@param self VisualElement self +---@param Focused boolean Whether the element has input focus +function VisualElement:setFocused(self, Focused) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was released +---@param x number The x position of the release +---@param y number The y position of the release +---@protected +function VisualElement:mouse_release(button, x, y) end + +---Registers a function to handle the onClick event. +---@param button string +---@param x number +---@param y number +---@param self VisualElement self +---@param func function The function to be called when the event fires +function VisualElement:onOnClick(self, func) end + +---Gets the value of the Y property. +---@param self VisualElement self +---@return number 1 The vertical position relative to parent +function VisualElement:getY(self) end + +---Returns the absolute position of the element or the given coordinates. +---@return number x The absolute x position +---@return number y The absolute y position +function VisualElement:getAbsolutePosition() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position of the cursor +---@param y number The y position of the cursor +---@param blink boolean Whether the cursor should blink +---@param color number The color of the cursor +---@return VisualElement self The VisualElement instance +---@protected +function VisualElement:setCursor(x, y, blink, color) end + +---@class Slider : VisualElement +---@field step number Current position of the slider handle (1 to width/height) +---@field barColor color Color of the slider track +---@field max number Maximum value for value conversion (maps slider position to this range) +---@field horizontal boolean Whether the slider is horizontal (false for vertical) +---@field sliderColor color Color of the slider handle +local Slider = {} + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Slider:render() end + +---Sets the value of the Max property. +---@param self Slider self +---@param Max number Maximum value for value conversion (maps slider position to this range) +function Slider:setMax(self, Max) end + +---Gets the value of the Max property. +---@param self Slider self +---@return number 100 Maximum value for value conversion (maps slider position to this range) +function Slider:getMax(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Slider self The initialized instance +---@protected +function Slider:init(props, basalt) end + +---Gets the value of the BarColor property. +---@param self Slider self +---@return color gray Color of the slider track +function Slider:getBarColor(self) end + +---Gets the current value of the slider +---@return number value The current value (0 to max) +function Slider:getValue() end + +---Sets the value of the SliderColor property. +---@param self Slider self +---@param SliderColor color Color of the slider handle +function Slider:setSliderColor(self, SliderColor) end + +---Sets the value of the Step property. +---@param self Slider self +---@param Step number Current position of the slider handle (1 to width/height) +function Slider:setStep(self, Step) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Slider:mouse_click(button, x, y) end + +---Registers a function to handle the onChange event. +---@param value number +---@param self Slider self +---@param func function The function to be called when the event fires +function Slider:onOnChange(self, func) end + +---Gets the value of the Horizontal property. +---@param self Slider self +---@return boolean true Whether the slider is horizontal (false for vertical) +function Slider:getHorizontal(self) end + +---Gets the value of the SliderColor property. +---@param self Slider self +---@return color blue Color of the slider handle +function Slider:getSliderColor(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button that was released +---@param x number The x position of the release +---@param y number The y position of the release +---@return boolean handled Whether the event was handled +---@protected +function Slider:mouse_scroll(button, x, y) end + +---Sets the value of the BarColor property. +---@param self Slider self +---@param BarColor color Color of the slider track +function Slider:setBarColor(self, BarColor) end + +---Gets the value of the Step property. +---@param self Slider self +---@return number 1 Current position of the slider handle (1 to width/height) +function Slider:getStep(self) end + +---Sets the value of the Horizontal property. +---@param self Slider self +---@param Horizontal boolean Whether the slider is horizontal (false for vertical) +function Slider:setHorizontal(self, Horizontal) end + +---@class Timer : BaseElement +---@field interval number The interval in seconds at which the timer will trigger its action. +---@field amount number The amount of time the timer should run. +---@field action function The action to be performed when the timer triggers. +---@field running boolean Indicates whether the timer is currently running or not. +local Timer = {} + +---Starts the timer with the specified interval. +---@param self Timer The Timer instance to start +---@return Timer self The Timer instance +function Timer:start(self) end + +---Sets the value of the Amount property. +---@param self Timer self +---@param Amount number The amount of time the timer should run. +function Timer:setAmount(self, Amount) end + +---Stops the timer if it is currently running. +---@param self Timer The Timer instance to stop +---@return Timer self The Timer instance +function Timer:stop(self) end + +---Gets the value of the Amount property. +---@param self Timer self +---@return number -1 The amount of time the timer should run. +function Timer:getAmount(self) end + +---Sets the value of the Interval property. +---@param self Timer self +---@param Interval number The interval in seconds at which the timer will trigger its action. +function Timer:setInterval(self, Interval) end + +---Sets the value of the Action property. +---@param self Timer self +---@param Action function The action to be performed when the timer triggers. +function Timer:setAction(self, Action) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function Timer:init(props, basalt) end + +---Gets the value of the Interval property. +---@param self Timer self +---@return number 1 The interval in seconds at which the timer will trigger its action. +function Timer:getInterval(self) end + +---Sets the value of the Running property. +---@param self Timer self +---@param Running boolean Indicates whether the timer is currently running or not. +function Timer:setRunning(self, Running) end + +---Gets the value of the Action property. +---@param self Timer self +---@return function function The action to be performed when the timer triggers. +function Timer:getAction(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Timer:dispatchEvent() end + +---Gets the value of the Running property. +---@param self Timer self +---@return boolean false Indicates whether the timer is currently running or not. +function Timer:getRunning(self) end + +---@class LineChart : Graph +local LineChart = {} + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function LineChart:render() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return LineChart self The initialized instance +---@protected +function LineChart:init(props, basalt) end + +---@class Graph : VisualElement +---@field maxValue number The maximum value of the graph +---@field series table The series of the graph +---@field minValue number The minimum value of the graph +local Graph = {} + +---Sets the value of the MinValue property. +---@param self Graph self +---@param MinValue number The minimum value of the graph +function Graph:setMinValue(self, MinValue) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Graph self The initialized instance +---@protected +function Graph:init(props, basalt) end + +---Clears all points from a series +---@return Graph self The graph instance +function Graph:clear() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Graph:render() end + +---@param name string The name of the series +---@param symbol string The symbol of the series +---@param bgCol number The background color of the series +---@param fgCol number The foreground color of the series +---@param pointCount number The number of points in the series +---@return Graph self The graph instance +function Graph:addSeries(name, symbol, bgCol, fgCol, pointCount) end + +---@param name string The name of the series +---@param count number The number of points in the series +---@return Graph self The graph instance +function Graph:setSeriesPointCount(name, count) end + +---@param name string The name of the series +---@return Graph self The graph instance +function Graph:removeSeries(name) end + +---Gets the value of the MinValue property. +---@param self Graph self +---@return number 0 The minimum value of the graph +function Graph:getMinValue(self) end + +---@param name string The name of the series +---@param value number The value of the point +---@return Graph self The graph instance +function Graph:addPoint(name, value) end + +---Sets the value of the MaxValue property. +---@param self Graph self +---@param MaxValue number The maximum value of the graph +function Graph:setMaxValue(self, MaxValue) end + +---@param name string The name of the series +---@return Graph self The graph instance +function Graph:focusSeries(name) end + +---Gets the value of the MaxValue property. +---@param self Graph self +---@return number 100 The maximum value of the graph +function Graph:getMaxValue(self) end + +---@param name string The name of the series +---@return table ? series The series +function Graph:getSeries(name) end + +---Sets the value of the Series property. +---@param self Graph self +---@param Series table The series of the graph +function Graph:setSeries(self, Series) end + +---@param name string The name of the series +---@param visible boolean Whether the series should be visible +---@return Graph self The graph instance +function Graph:changeSeriesVisibility(name, visible) end + +---@class CheckBox : VisualElement +---@field autoSize boolean Whether to automatically size the checkbox +---@field checkedText string when checked +---@field text string Text to display +---@field checked boolean checkbox is checked +local CheckBox = {} + +---Gets the value of the AutoSize property. +---@param self CheckBox self +---@return boolean true Whether to automatically size the checkbox +function CheckBox:getAutoSize(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean Clicked Whether the event was handled +---@protected +function CheckBox:mouse_click(button, x, y) end + +---Gets the value of the CheckedText property. +---@param self CheckBox self +---@return string Text when checked +function CheckBox:getCheckedText(self) end + +---Gets the value of the Text property. +---@param self CheckBox self +---@return string empty Text to display +function CheckBox:getText(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function CheckBox:init(props, basalt) end + +---Sets the value of the CheckedText property. +---@param self CheckBox self +---@param CheckedText string when checked +function CheckBox:setCheckedText(self, CheckedText) end + +---Gets the value of the Checked property. +---@param self CheckBox self +---@return boolean Whether checkbox is checked +function CheckBox:getChecked(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@return CheckBox self The created instance +---@protected +function CheckBox.new() end + +---Sets the value of the AutoSize property. +---@param self CheckBox self +---@param AutoSize boolean Whether to automatically size the checkbox +function CheckBox:setAutoSize(self, AutoSize) end + +---Sets the value of the Text property. +---@param self CheckBox self +---@param Text string Text to display +function CheckBox:setText(self, Text) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function CheckBox:render() end + +---Sets the value of the Checked property. +---@param self CheckBox self +---@param Checked boolean checkbox is checked +function CheckBox:setChecked(self, Checked) end + +---@class FlexBox : Container +---@field flexAlignItems string The alignment of flex items along the cross axis +---@field flexSpacing number The spacing between flex items +---@field flexCrossPadding number The padding on both sides of the cross axis +---@field flexDirection string The direction of the flexbox layout "row" or "column" +---@field flexUpdateLayout boolean Whether to update the layout of the flexbox +---@field flexJustifyContent string The alignment of flex items along the main axis +---@field flexWrap boolean Whether to wrap flex items onto multiple lines +local FlexBox = {} + +---Sets the value of the FlexSpacing property. +---@param self FlexBox self +---@param FlexSpacing number The spacing between flex items +function FlexBox:setFlexSpacing(self, FlexSpacing) end + +---Sets the value of the FlexAlignItems property. +---@param self FlexBox self +---@param FlexAlignItems string The alignment of flex items along the cross axis +function FlexBox:setFlexAlignItems(self, FlexAlignItems) end + +---Adds a child element to the flexbox +---@param element Element The child element to add +---@return FlexBox self The flexbox instance +function FlexBox:addChild(element) end + +---Sets the value of the FlexUpdateLayout property. +---@param self FlexBox self +---@param FlexUpdateLayout boolean Whether to update the layout of the flexbox +function FlexBox:setFlexUpdateLayout(self, FlexUpdateLayout) end + +---Gets the value of the FlexCrossPadding property. +---@param self FlexBox self +---@return number 0 The padding on both sides of the cross axis +function FlexBox:getFlexCrossPadding(self) end + +---Sets the value of the FlexDirection property. +---@param self FlexBox self +---@param FlexDirection string The direction of the flexbox layout "row" or "column" +function FlexBox:setFlexDirection(self, FlexDirection) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return FlexBox self The initialized instance +---@protected +function FlexBox:init(props, basalt) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param element Element The child element to remove +---@return FlexBox self The flexbox instance +---@protected +function FlexBox:removeChild(element) end + +---Gets the value of the FlexJustifyContent property. +---@param self FlexBox self +---@return string "flex-start" The alignment of flex items along the main axis +function FlexBox:getFlexJustifyContent(self) end + +---Gets the value of the FlexDirection property. +---@param self FlexBox self +---@return string "row" The direction of the flexbox layout "row" or "column" +function FlexBox:getFlexDirection(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function FlexBox:render() end + +---Adds a new line break to the flexbox +---@param self FlexBox The element itself +---@return FlexBox +function FlexBox:addLineBreak(self) end + +---Sets the value of the FlexCrossPadding property. +---@param self FlexBox self +---@param FlexCrossPadding number The padding on both sides of the cross axis +function FlexBox:setFlexCrossPadding(self, FlexCrossPadding) end + +---Gets the value of the FlexAlignItems property. +---@param self FlexBox self +---@return string "flex-start" The alignment of flex items along the cross axis +function FlexBox:getFlexAlignItems(self) end + +---Sets the value of the FlexJustifyContent property. +---@param self FlexBox self +---@param FlexJustifyContent string The alignment of flex items along the main axis +function FlexBox:setFlexJustifyContent(self, FlexJustifyContent) end + +---Gets the value of the FlexUpdateLayout property. +---@param self FlexBox self +---@return boolean false Whether to update the layout of the flexbox +function FlexBox:getFlexUpdateLayout(self) end + +---Gets the value of the FlexSpacing property. +---@param self FlexBox self +---@return number 1 The spacing between flex items +function FlexBox:getFlexSpacing(self) end + +---Gets the value of the FlexWrap property. +---@param self FlexBox self +---@return boolean false Whether to wrap flex items onto multiple lines +function FlexBox:getFlexWrap(self) end + +---Sets the value of the FlexWrap property. +---@param self FlexBox self +---@param FlexWrap boolean Whether to wrap flex items onto multiple lines +function FlexBox:setFlexWrap(self, FlexWrap) end + +---@class ScrollBar : VisualElement +---@field symbol string " Symbol used for the ScrollBar handle +---@field attachedProperty string nil The property being controlled +---@field handleSize number Size of the ScrollBar handle in characters +---@field max number Maximum scroll value +---@field value number Current scroll value +---@field backgroundSymbol string Symbol used for the ScrollBar background +---@field min number Minimum scroll value +---@field step number Step size for scroll operations +---@field orientation string Orientation of the ScrollBar ("vertical" or "horizontal") +---@field maxValue number 100 Maximum value or function that returns it +---@field minValue number 0 Minimum value or function that returns it +---@field attachedElement table nil The element this ScrollBar is attached to +---@field dragMultiplier number How fast the ScrollBar moves when dragging +---@field symbolBackgroundColor color Background color of the ScrollBar handle +local ScrollBar = {} + +---Sets the value of the Max property. +---@param self ScrollBar self +---@param Max number Maximum scroll value +function ScrollBar:setMax(self, Max) end + +---Sets the value of the MinValue property. +---@param self ScrollBar self +---@param MinValue number 0 Minimum value or function that returns it +function ScrollBar:setMinValue(self, MinValue) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param direction number The scroll direction (1 for up, -1 for down) +---@param x number The x position of the scroll +---@param y number The y position of the scroll +---@return boolean Whether the event was handled +---@protected +function ScrollBar:mouse_scroll(direction, x, y) end + +---Sets the value of the SymbolBackgroundColor property. +---@param self ScrollBar self +---@param SymbolBackgroundColor color Background color of the ScrollBar handle +function ScrollBar:setSymbolBackgroundColor(self, SymbolBackgroundColor) end + +---Sets the value of the DragMultiplier property. +---@param self ScrollBar self +---@param DragMultiplier number How fast the ScrollBar moves when dragging +function ScrollBar:setDragMultiplier(self, DragMultiplier) end + +---Gets the value of the Symbol property. +---@param self ScrollBar self +---@return string " " Symbol used for the ScrollBar handle +function ScrollBar:getSymbol(self) end + +---Updates the attached element's property based on the ScrollBar value +---@return ScrollBar self The ScrollBar instance +function ScrollBar:updateAttachedElement() end + +---Gets the value of the MinValue property. +---@param self ScrollBar self +---@return number |function 0 Minimum value or function that returns it +function ScrollBar:getMinValue(self) end + +---Sets the value of the MaxValue property. +---@param self ScrollBar self +---@param MaxValue number 100 Maximum value or function that returns it +function ScrollBar:setMaxValue(self, MaxValue) end + +---Sets the value of the AttachedProperty property. +---@param self ScrollBar self +---@param AttachedProperty string nil The property being controlled +function ScrollBar:setAttachedProperty(self, AttachedProperty) end + +---Sets the value of the Value property. +---@param self ScrollBar self +---@param Value number Current scroll value +function ScrollBar:setValue(self, Value) end + +---Gets the value of the Value property. +---@param self ScrollBar self +---@return number 0 Current scroll value +function ScrollBar:getValue(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return ScrollBar self The initialized instance +---@protected +function ScrollBar:init(props, basalt) end + +---Gets the value of the AttachedProperty property. +---@param self ScrollBar self +---@return string ? nil The property being controlled +function ScrollBar:getAttachedProperty(self) end + +---Sets the value of the Step property. +---@param self ScrollBar self +---@param Step number Step size for scroll operations +function ScrollBar:setStep(self, Step) end + +---Gets the value of the Max property. +---@param self ScrollBar self +---@return number 100 Maximum scroll value +function ScrollBar:getMax(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function ScrollBar:render() end + +---Gets the value of the Min property. +---@param self ScrollBar self +---@return number 0 Minimum scroll value +function ScrollBar:getMin(self) end + +---Sets the value of the BackgroundSymbol property. +---@param self ScrollBar self +---@param BackgroundSymbol string Symbol used for the ScrollBar background +function ScrollBar:setBackgroundSymbol(self, BackgroundSymbol) end + +---Gets the value of the MaxValue property. +---@param self ScrollBar self +---@return number |function 100 Maximum value or function that returns it +function ScrollBar:getMaxValue(self) end + +---Gets the value of the Step property. +---@param self ScrollBar self +---@return number 1 Step size for scroll operations +function ScrollBar:getStep(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean Whether the event was handled +---@protected +function ScrollBar:mouse_click(button, x, y) end + +---Gets the value of the Orientation property. +---@param self ScrollBar self +---@return string vertical Orientation of the ScrollBar ("vertical" or "horizontal") +function ScrollBar:getOrientation(self) end + +---Gets the value of the DragMultiplier property. +---@param self ScrollBar self +---@return number 1 How fast the ScrollBar moves when dragging +function ScrollBar:getDragMultiplier(self) end + +---Sets the value of the Min property. +---@param self ScrollBar self +---@param Min number Minimum scroll value +function ScrollBar:setMin(self, Min) end + +---Sets the value of the Symbol property. +---@param self ScrollBar self +---@param Symbol string " Symbol used for the ScrollBar handle +function ScrollBar:setSymbol(self, Symbol) end + +---Gets the value of the BackgroundSymbol property. +---@param self ScrollBar self +---@return string "\127" Symbol used for the ScrollBar background +function ScrollBar:getBackgroundSymbol(self) end + +---Gets the value of the AttachedElement property. +---@param self ScrollBar self +---@return table ? nil The element this ScrollBar is attached to +function ScrollBar:getAttachedElement(self) end + +---Attaches the ScrollBar to an element's property +---@param element BaseElement The element to attach to +---@param config table Configuration {property = "propertyName", min = number|function, max = number|function} +---@return ScrollBar self The ScrollBar instance +function ScrollBar:attach(element, config) end + +---Sets the value of the HandleSize property. +---@param self ScrollBar self +---@param HandleSize number Size of the ScrollBar handle in characters +function ScrollBar:setHandleSize(self, HandleSize) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button being dragged +---@param x number The x position of the drag +---@param y number The y position of the drag +---@return boolean Whether the event was handled +---@protected +function ScrollBar:mouse_drag(button, x, y) end + +---Gets the value of the SymbolBackgroundColor property. +---@param self ScrollBar self +---@return color black Background color of the ScrollBar handle +function ScrollBar:getSymbolBackgroundColor(self) end + +---Sets the value of the AttachedElement property. +---@param self ScrollBar self +---@param AttachedElement table nil The element this ScrollBar is attached to +function ScrollBar:setAttachedElement(self, AttachedElement) end + +---Sets the value of the Orientation property. +---@param self ScrollBar self +---@param Orientation string Orientation of the ScrollBar ("vertical" or "horizontal") +function ScrollBar:setOrientation(self, Orientation) end + +---Gets the value of the HandleSize property. +---@param self ScrollBar self +---@return number 2 Size of the ScrollBar handle in characters +function ScrollBar:getHandleSize(self) end + +---@class Input : VisualElement +---@field placeholderColor color Color of the placeholder text +---@field replaceChar string Character to replace the input with (for password fields) +---@field pattern string nil Regular expression pattern for input validation +---@field maxLength number nil Maximum length of input text (optional) +---@field focusedForeground color Foreground color when input is focused +---@field cursorPos number The current cursor position in the text +---@field focusedBackground color Background color when input is focused +---@field viewOffset number The horizontal scroll offset for viewing long text +---@field placeholder string Text to display when input is empty +---@field text string The current text content of the input +---@field cursorColor number Color of the cursor +local Input = {} + +---Gets the value of the ReplaceChar property. +---@param self Input self +---@return string nil Character to replace the input with (for password fields) +function Input:getReplaceChar(self) end + +---Updates the input's viewport +---@return Input self The updated instance +function Input:updateViewport() end + +---Gets the value of the PlaceholderColor property. +---@param self Input self +---@return color gray Color of the placeholder text +function Input:getPlaceholderColor(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Input:blur() end + +---Sets the value of the FocusedBackground property. +---@param self Input self +---@param FocusedBackground color Background color when input is focused +function Input:setFocusedBackground(self, FocusedBackground) end + +---Sets the value of the Placeholder property. +---@param self Input self +---@param Placeholder string Text to display when input is empty +function Input:setPlaceholder(self, Placeholder) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Input:render() end + +---Gets the value of the CursorPos property. +---@param self Input self +---@return number 1 The current cursor position in the text +function Input:getCursorPos(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Input:focus() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Input:paste() end + +---Sets the value of the ViewOffset property. +---@param self Input self +---@param ViewOffset number The horizontal scroll offset for viewing long text +function Input:setViewOffset(self, ViewOffset) end + +---Sets the value of the ReplaceChar property. +---@param self Input self +---@param ReplaceChar string Character to replace the input with (for password fields) +function Input:setReplaceChar(self, ReplaceChar) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param key number The key that was pressed +---@return boolean handled Whether the event was handled +---@protected +function Input:key(key) end + +---Gets the value of the FocusedForeground property. +---@param self Input self +---@return color white Foreground color when input is focused +function Input:getFocusedForeground(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param char string The character that was typed +---@return boolean handled Whether the event was handled +---@protected +function Input:char(char) end + +---Gets the value of the Placeholder property. +---@param self Input self +---@return string ... Text to display when input is empty +function Input:getPlaceholder(self) end + +---Sets the cursor position and color +---@param x number The x position of the cursor +---@param y number The y position of the cursor +---@param blink boolean Whether the cursor should blink +---@param color number The color of the cursor +function Input:setCursor(x, y, blink, color) end + +---Gets the value of the CursorColor property. +---@param self Input self +---@return number nil Color of the cursor +function Input:getCursorColor(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Input self The initialized instance +---@protected +function Input:init(props, basalt) end + +---Sets the value of the CursorColor property. +---@param self Input self +---@param CursorColor number Color of the cursor +function Input:setCursorColor(self, CursorColor) end + +---Sets the value of the Pattern property. +---@param self Input self +---@param Pattern string nil Regular expression pattern for input validation +function Input:setPattern(self, Pattern) end + +---Gets the value of the Pattern property. +---@param self Input self +---@return string ? nil Regular expression pattern for input validation +function Input:getPattern(self) end + +---Sets the value of the CursorPos property. +---@param self Input self +---@param CursorPos number The current cursor position in the text +function Input:setCursorPos(self, CursorPos) end + +---Gets the value of the ViewOffset property. +---@param self Input self +---@return number 0 The horizontal scroll offset for viewing long text +function Input:getViewOffset(self) end + +---Sets the value of the FocusedForeground property. +---@param self Input self +---@param FocusedForeground color Foreground color when input is focused +function Input:setFocusedForeground(self, FocusedForeground) end + +---Sets the value of the MaxLength property. +---@param self Input self +---@param MaxLength number nil Maximum length of input text (optional) +function Input:setMaxLength(self, MaxLength) end + +---Gets the value of the Text property. +---@param self Input self +---@return string - The current text content of the input +function Input:getText(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function Input:mouse_click(button, x, y) end + +---Gets the value of the MaxLength property. +---@param self Input self +---@return number ? nil Maximum length of input text (optional) +function Input:getMaxLength(self) end + +---Sets the value of the Text property. +---@param self Input self +---@param Text string The current text content of the input +function Input:setText(self, Text) end + +---Sets the value of the PlaceholderColor property. +---@param self Input self +---@param PlaceholderColor color Color of the placeholder text +function Input:setPlaceholderColor(self, PlaceholderColor) end + +---Gets the value of the FocusedBackground property. +---@param self Input self +---@return color blue Background color when input is focused +function Input:getFocusedBackground(self) end + +---@class Switch : VisualElement +---@field offBackground number color when OFF +---@field onBackground number color when ON +---@field checked boolean switch is checked +---@field text string to display next to switch +---@field autoSize boolean to automatically size the element to fit switch and text +local Switch = {} + +---Gets the value of the AutoSize property. +---@param self Switch self +---@return boolean Whether to automatically size the element to fit switch and text +function Switch:getAutoSize(self) end + +---Sets the value of the Checked property. +---@param self Switch self +---@param Checked boolean switch is checked +function Switch:setChecked(self, Checked) end + +---Gets the value of the Text property. +---@param self Switch self +---@return string Text to display next to switch +function Switch:getText(self) end + +---Sets the value of the OnBackground property. +---@param self Switch self +---@param OnBackground number color when ON +function Switch:setOnBackground(self, OnBackground) end + +---Sets the value of the OffBackground property. +---@param self Switch self +---@param OffBackground number color when OFF +function Switch:setOffBackground(self, OffBackground) end + +---Gets the value of the Checked property. +---@param self Switch self +---@return boolean Whether switch is checked +function Switch:getChecked(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function Switch:init(props, basalt) end + +---Sets the value of the Text property. +---@param self Switch self +---@param Text string to display next to switch +function Switch:setText(self, Text) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Switch:render() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean Whether the event was handled +---@protected +function Switch:mouse_click(button, x, y) end + +---Sets the value of the AutoSize property. +---@param self Switch self +---@param AutoSize boolean to automatically size the element to fit switch and text +function Switch:setAutoSize(self, AutoSize) end + +---Gets the value of the OffBackground property. +---@param self Switch self +---@return number Background color when OFF +function Switch:getOffBackground(self) end + +---Gets the value of the OnBackground property. +---@param self Switch self +---@return number Background color when ON +function Switch:getOnBackground(self) end + +---@class TabControl : Container +---@field activeTabTextColor color color for the active tab text +---@field headerBackground color color for the tab header area +---@field activeTabBackground color color for the active tab +---@field tabHeight number of the tab header area +---@field tabs table of tab definitions +---@field activeTab number currently active tab ID +local TabControl = {} + +---Sets the value of the TabHeight property. +---@param self TabControl self +---@param TabHeight number of the tab header area +function TabControl:setTabHeight(self, TabHeight) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click (global) +---@param y number The y position of the click (global) +---@return boolean Whether the event was handled +---@protected +function TabControl:mouse_click(button, x, y) end + +---@param elementType string The type of element to add +---@param tabId number Optional tab ID, defaults to active tab +---@return table element The created element +function TabControl:addElement(elementType, tabId) end + +function TabControl:_getHeaderMetrics() end + +---@param tabId number The ID of the tab to activate +function TabControl:setActiveTab(tabId) end + +function TabControl:getRelativePosition() end + +---Gets the value of the ActiveTabTextColor property. +---@param self TabControl self +---@return color Foreground color for the active tab text +function TabControl:getActiveTabTextColor(self) end + +---Gets the value of the ActiveTabBackground property. +---@param self TabControl self +---@return color Background color for the active tab +function TabControl:getActiveTabBackground(self) end + +function TabControl:drawBg() end + +function TabControl:blit() end + +function TabControl:mouse_release() end + +---Gets the value of the ActiveTab property. +---@param self TabControl self +---@return number The currently active tab ID +function TabControl:getActiveTab(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function TabControl:init(props, basalt) end + +---returns a proxy for adding elements to the tab +---@param title string The title of the tab +---@return table tabHandler The tab handler proxy for adding elements to the new tab +function TabControl:newTab(title) end + +---Sets the value of the ActiveTabTextColor property. +---@param self TabControl self +---@param ActiveTabTextColor color color for the active tab text +function TabControl:setActiveTabTextColor(self, ActiveTabTextColor) end + +---Gets the value of the TabHeight property. +---@param self TabControl self +---@return number Height of the tab header area +function TabControl:getTabHeight(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param child table The child element to add +---@return Container self For method chaining +---@protected +function TabControl:addChild(child) end + +function TabControl:mouse_scroll() end + +---Sets the value of the Tabs property. +---@param self TabControl self +---@param Tabs table of tab definitions +function TabControl:setTabs(self, Tabs) end + +function TabControl:drawText() end + +function TabControl:mouse_up() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function TabControl:sortChildrenEvents() end + +function TabControl:setCursor() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function TabControl:render() end + +function TabControl:mouse_drag() end + +---Gets the value of the Tabs property. +---@param self TabControl self +---@return table List of tab definitions +function TabControl:getTabs(self) end + +---@param element table The element to assign to a tab +---@param tabId number The ID of the tab to assign the element to +---@return TabControl self For method chaining +function TabControl:setTab(element, tabId) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param child table The child element to check +---@return boolean Whether the child should be visible +---@protected +function TabControl:isChildVisible(child) end + +function TabControl:textBg() end + +---Gets the value of the HeaderBackground property. +---@param self TabControl self +---@return color Background color for the tab header area +function TabControl:getHeaderBackground(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@return number yOffset The Y offset for content +---@protected +function TabControl:getContentYOffset() end + +---Sets the value of the HeaderBackground property. +---@param self TabControl self +---@param HeaderBackground color color for the tab header area +function TabControl:setHeaderBackground(self, HeaderBackground) end + +function TabControl:multiBlit() end + +function TabControl:textFg() end + +function TabControl:mouse_move() end + +---Sets the value of the ActiveTabBackground property. +---@param self TabControl self +---@param ActiveTabBackground color color for the active tab +function TabControl:setActiveTabBackground(self, ActiveTabBackground) end + +function TabControl:drawFg() end + +---@class ElementManager +local ElementManager = {} + +---Gets an Plugin API by name +---@param name string The name of the API to get +---@return table API The API +function ElementManager.getAPI(name) end + +---Gets an element by name. If the element is not loaded, it will try to load it first. +---@param name string The name of the element to get +---@return table Element The element class +function ElementManager.getElement(name) end + +---Loads an element by name. This will load the element and apply any plugins to it. +---@param name string The name of the element to load +function ElementManager.loadElement(name) end + +---Gets a list of all elements +---@return table ElementList A list of all elements +function ElementManager.getElementList() end + +---@class List : VisualElement +---@field selectedForeground color Text color for selected items +---@field items table List of items to display. Items can be tables with properties including selected state +---@field selectable boolean Whether items in the list can be selected +---@field multiSelection boolean Whether multiple items can be selected at once +---@field offset number Current scroll offset for viewing long lists +---@field selectedBackground color Background color for selected items +local List = {} + +---Sets the value of the Selectable property. +---@param self List self +---@param Selectable boolean Whether items in the list can be selected +function List:setSelectable(self, Selectable) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The mouse button that was clicked +---@param x number The x-coordinate of the click +---@param y number The y-coordinate of the click +---@return boolean Whether the event was handled +---@protected +function List:mouse_click(button, x, y) end + +---Clears all items from the list +---@return List self The List instance +function List:clear() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param direction number The direction of the scroll (1 for down, -1 for up) +---@param x number The x-coordinate of the scroll +---@param y number The y-coordinate of the scroll +---@return boolean Whether the event was handled +---@protected +function List:mouse_scroll(direction, x, y) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function List:render() end + +---Scrolls the list to the top +---@return List self The List instance +function List:scrollToTop() end + +---Scrolls the list to the bottom +---@return List self The List instance +function List:scrollToBottom() end + +---Registers a callback for the select event +---@param callback function The callback function to register +---@return List self The List instance +function List:onSelect(callback) end + +---Sets the value of the SelectedForeground property. +---@param self List self +---@param SelectedForeground color Text color for selected items +function List:setSelectedForeground(self, SelectedForeground) end + +---Gets the value of the MultiSelection property. +---@param self List self +---@return boolean false Whether multiple items can be selected at once +function List:getMultiSelection(self) end + +---Gets first selected item +---@return table ? selected The first item +function List:getSelectedItem() end + +---Gets the currently selected items +---@return table selected List of selected items +function List:getSelectedItems() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return List self The initialized instance +---@protected +function List:init(props, basalt) end + +---Adds an item to the list +---@param text string |table The item to add (string or item table) +---@return List self The List instance +function List:addItem(text) end + +---Sets the value of the MultiSelection property. +---@param self List self +---@param MultiSelection boolean Whether multiple items can be selected at once +function List:setMultiSelection(self, MultiSelection) end + +---Registers a function to handle the onSelect event. +---@param index number +---@param item table +---@param self List self +---@param func function The function to be called when the event fires +function List:onOnSelect(self, func) end + +---Removes an item from the list +---@param index number The index of the item to remove +---@return List self The List instance +function List:removeItem(index) end + +---Gets the value of the Items property. +---@param self List self +---@return table {} List of items to display. Items can be tables with properties including selected state +function List:getItems(self) end + +---Sets the value of the SelectedBackground property. +---@param self List self +---@param SelectedBackground color Background color for selected items +function List:setSelectedBackground(self, SelectedBackground) end + +---Gets the value of the SelectedForeground property. +---@param self List self +---@return color white Text color for selected items +function List:getSelectedForeground(self) end + +---Gets the value of the Offset property. +---@param self List self +---@return number 0 Current scroll offset for viewing long lists +function List:getOffset(self) end + +---Gets the value of the SelectedBackground property. +---@param self List self +---@return color blue Background color for selected items +function List:getSelectedBackground(self) end + +---Sets the value of the Offset property. +---@param self List self +---@param Offset number Current scroll offset for viewing long lists +function List:setOffset(self, Offset) end + +---Gets the value of the Selectable property. +---@param self List self +---@return boolean true Whether items in the list can be selected +function List:getSelectable(self) end + +---Sets the value of the Items property. +---@param self List self +---@param Items table List of items to display. Items can be tables with properties including selected state +function List:setItems(self, Items) end + +---@class Button : VisualElement +---@field text string Button text +local Button = {} + +---Gets the value of the Text property. +---@param self Button self +---@return string Button Button text +function Button:getText(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@protected +function Button:init(props, basalt) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Button:render() end + +---Sets the value of the Text property. +---@param self Button self +---@param Text string Button text +function Button:setText(self, Text) end + +---@class Benchmark +local Benchmark = {} + +---Starts a custom benchmark +---@param name string The name of the benchmark +function API.start(name) end + +---Stops a custom benchmark +---@param name string The name of the benchmark to stop +function API.stop(name) end + +---Gets statistics for a benchmark +---@param name string The name of the benchmark +---@return table ? stats The benchmark statistics or nil +function API.getStats(name) end + +---Clears all custom benchmarks +function API.clearAll() end + +---Clears a specific benchmark +---@param name string The name of the benchmark to clear +function API.clear(name) end ---@class Tree : VisualElement ----@field selectedNode table nil Currently selected node ---@field horizontalOffset number Current horizontal scroll position ----@field nodes table The tree structure containing node objects with {text, children} properties +---@field selectedNode table nil Currently selected node ---@field expandedNodes table Table of nodes that are currently expanded ----@field nodeColor color Color of unselected nodes +---@field nodes table The tree structure containing node objects with {text, children} properties ---@field scrollOffset number Current vertical scroll position ---@field selectedColor color Background color of selected node +---@field nodeColor color Color of unselected nodes local Tree = {} ----Gets the size of the tree ----@return number width The width of the tree ----@return number height The height of the tree -function Tree:getNodeSize() end - ----Sets the value of the SelectedColor property. ----@param self Tree self ----@param SelectedColor color Background color of selected node -function Tree:setSelectedColor(self, SelectedColor) end - ----Sets the value of the SelectedNode property. ----@param self Tree self ----@param SelectedNode table nil Currently selected node -function Tree:setSelectedNode(self, SelectedNode) end - ----Gets the value of the Nodes property. ----@param self Tree self ----@return table {} The tree structure containing node objects with {text, children} properties -function Tree:getNodes(self) end - ----Sets the value of the NodeColor property. ----@param self Tree self ----@param NodeColor color Color of unselected nodes -function Tree:setNodeColor(self, NodeColor) end - ---Gets the value of the ScrollOffset property. ---@param self Tree self ---@return number 0 Current vertical scroll position function Tree:getScrollOffset(self) end ----Gets the value of the SelectedColor property. +---Gets the value of the SelectedNode property. ---@param self Tree self ----@return color lightBlue Background color of selected node -function Tree:getSelectedColor(self) end +---@return table ? nil Currently selected node +function Tree:getSelectedNode(self) end ----Sets the value of the ExpandedNodes property. ----@param self Tree self ----@param ExpandedNodes table Table of nodes that are currently expanded -function Tree:setExpandedNodes(self, ExpandedNodes) end +---Collapses a node +---@param node table The node to collapse +---@return Tree self The Tree instance +function Tree:collapseNode(node) end ---Gets the value of the NodeColor property. ---@param self Tree self @@ -2868,19 +3427,67 @@ function Tree:getExpandedNodes(self) end ---@return Tree self The Tree instance function Tree:expandNode(node) end ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Tree:render() end +---Gets the value of the SelectedColor property. +---@param self Tree self +---@return color lightBlue Background color of selected node +function Tree:getSelectedColor(self) end + +---Toggles a node's expanded state +---@param node table The node to toggle +---@return Tree self The Tree instance +function Tree:toggleNode(node) end ---Sets the value of the HorizontalOffset property. ---@param self Tree self ---@param HorizontalOffset number Current horizontal scroll position function Tree:setHorizontalOffset(self, HorizontalOffset) end ----Gets the value of the SelectedNode property. +---Sets the value of the SelectedNode property. ---@param self Tree self ----@return table ? nil Currently selected node -function Tree:getSelectedNode(self) end +---@param SelectedNode table nil Currently selected node +function Tree:setSelectedNode(self, SelectedNode) end + +---Sets the value of the Nodes property. +---@param self Tree self +---@param Nodes table The tree structure containing node objects with {text, children} properties +function Tree:setNodes(self, Nodes) end + +---Gets the value of the Nodes property. +---@param self Tree self +---@return table {} The tree structure containing node objects with {text, children} properties +function Tree:getNodes(self) end + +---Gets the size of the tree +---@return number width The width of the tree +---@return number height The height of the tree +function Tree:getNodeSize() end + +---Initializes the Tree instance +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Tree self The initialized instance +---@protected +function Tree:init(props, basalt) end + +---Gets the value of the HorizontalOffset property. +---@param self Tree self +---@return number 0 Current horizontal scroll position +function Tree:getHorizontalOffset(self) end + +---Registers a callback for when a node is selected +---@param callback function The callback function +---@return Tree self The Tree instance +function Tree:onSelect(callback) end + +---Sets the value of the ExpandedNodes property. +---@param self Tree self +---@param ExpandedNodes table Table of nodes that are currently expanded +function Tree:setExpandedNodes(self, ExpandedNodes) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Tree:render() end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param direction number The scroll direction (1 for up, -1 for down) @@ -2890,16 +3497,6 @@ function Tree:getSelectedNode(self) end ---@protected function Tree:mouse_scroll(direction, x, y) end ----Sets the value of the Nodes property. ----@param self Tree self ----@param Nodes table The tree structure containing node objects with {text, children} properties -function Tree:setNodes(self, Nodes) end - ----Registers a callback for when a node is selected ----@param callback function The callback function ----@return Tree self The Tree instance -function Tree:onSelect(callback) end - ---Handles mouse click events ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param button number The button that was clicked @@ -2909,405 +3506,336 @@ function Tree:onSelect(callback) end ---@protected function Tree:mouse_click(button, x, y) end +---Sets the value of the SelectedColor property. +---@param self Tree self +---@param SelectedColor color Background color of selected node +function Tree:setSelectedColor(self, SelectedColor) end + +---Sets the value of the NodeColor property. +---@param self Tree self +---@param NodeColor color Color of unselected nodes +function Tree:setNodeColor(self, NodeColor) end + ---Sets the value of the ScrollOffset property. ---@param self Tree self ---@param ScrollOffset number Current vertical scroll position function Tree:setScrollOffset(self, ScrollOffset) end ----Initializes the Tree instance ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Tree self The initialized instance ----@protected -function Tree:init(props, basalt) end +---@class Log +local Log = {} ----Toggles a node's expanded state ----@param node table The node to toggle ----@return Tree self The Tree instance -function Tree:toggleNode(node) end +---Sends a debug message to the logger. +function Log.debug() end ----Collapses a node ----@param node table The node to collapse ----@return Tree self The Tree instance -function Tree:collapseNode(node) end +---Sends an error message to the logger. +function Log.error() end ----Gets the value of the HorizontalOffset property. ----@param self Tree self ----@return number 0 Current horizontal scroll position -function Tree:getHorizontalOffset(self) end +---Sends a warning message to the logger. +function Log.warn() end ----@class Program : VisualElement ----@field errorCallback function The error callback function ----@field doneCallback function The done callback function ----@field program table The program instance ----@field running boolean Whether the program is running ----@field path string The path to the program -local Program = {} +---Sets if the logger should log to a file. +function Log.setLogToFile() end -function BasaltProgram:setArgs() end +---Sends an info message to the logger. +function Log.info() end ----Sets the value of the ErrorCallback property. ----@param self Program self ----@param ErrorCallback function The error callback function -function Program:setErrorCallback(self, ErrorCallback) end +---Sets if the logger should log +function Log.setEnabled() end ----Stops the program ----@return Program self The Program instance -function Program:stop() end +---@class AnimationInstance +local AnimationInstance = {} ----Gets the value of the Running property. ----@param self Program self ----@return boolean false Whether the program is running -function Program:getRunning(self) end +---Creates a new AnimationInstance +---@param element VisualElement The element to animate +---@param animType string The type of animation +---@param args table The animation arguments +---@param duration number Duration in seconds +---@param easing string The easing function name +---@return AnimationInstance The new animation instance +function AnimationInstance.new(element, animType, args, duration, easing) end ----Sets the value of the Running property. ----@param self Program self ----@param Running boolean Whether the program is running -function Program:setRunning(self, Running) end +---Gets called when the animation is completed +function AnimationInstance:complete() end ----Gets the value of the Program property. ----@param self Program self ----@return table nil The program instance -function Program:getProgram(self) end +---Starts the animation +---@return AnimationInstance self The animation instance +function AnimationInstance:start() end ----Registers a callback for the program's done event ----@param fn function The callback function to register ----@return Program self The Program instance -function Program:onDone(fn) end +---Updates the animation +---@param elapsed number The elapsed time in seconds +---@return boolean Whether the animation is finished +function AnimationInstance:update(elapsed) end ----Sets the value of the DoneCallback property. ----@param self Program self ----@param DoneCallback function The done callback function -function Program:setDoneCallback(self, DoneCallback) end +---@class Reactive +local Reactive = {} ----Gets the value of the ErrorCallback property. ----@param self Program self ----@return function nil The error callback function -function Program:getErrorCallback(self) end +---@class Display : VisualElement +local Display = {} ----Gets the value of the Path property. ----@param self Program self ----@return string "" The path to the program -function Program:getPath(self) end - ----Sets the value of the Path property. ----@param self Program self ----@param Path string The path to the program -function Program:setPath(self, Path) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Program:focus() end - ----Registers a callback for the program's error event, if the function returns false, the program won't stop ----@param fn function The callback function to register ----@return Program self The Program instance -function Program:onError(fn) end - ----Gets the value of the DoneCallback property. ----@param self Program self ----@return function nil The done callback function -function Program:getDoneCallback(self) end - ----Sets the value of the Program property. ----@param self Program self ----@param Program table The program instance -function Program:setProgram(self, Program) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param event string The event to handle ----@return any result The event result ----@protected -function Program:dispatchEvent(event) end - ----Executes a program ----@param path string The path to the program ----@return Program self The Program instance -function Program:execute(path) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Program self The initialized instance ----@protected -function Program:init(props, basalt) end - ----Sends an event to the program ----@param event string The event to send ----@return Program self The Program instance -function Program:sendEvent(event) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Program:render() end - ----@class basalt -local basalt = {} - ----Sets the active frame ----@param frame BaseFrame The frame to set as active -function basalt.setActiveFrame(frame) end - ----Creates and returns a new BaseFrame ----@return BaseFrame BaseFrame The created frame instance -function basalt.createFrame() end - ----Returns the active frame ----@return BaseFrame ? BaseFrame The frame to set as active -function basalt.getActiveFrame() end - ----Returns an element's class without creating a instance ----@param name string The name of the element ----@return table Element The element class -function basalt.getElementClass(name) end - ----Schedules a function to run in a coroutine ----@param func function The function to schedule ----@return thread func The scheduled function -function basalt.schedule(func) end - ----Creates and returns a new UI element of the specified type. ----@param type string The type of element to create (e.g. "Button", "Label", "BaseFrame") ----@return table element The created element instance -function basalt.create(type) end - ----Gets or creates the main frame ----@return BaseFrame BaseFrame The main frame instance -function basalt.getMainFrame() end - ----Removes a scheduled update ----@param func thread The scheduled function to remove ----@return boolean success Whether the scheduled function was removed -function basalt.removeSchedule(func) end - ----Starts the Basalt runtime -function basalt.run() end - ----Stops the Basalt runtime -function basalt.stop() end - ----Triggers a custom event and calls all registered callbacks ----@param eventName string The name of the event to trigger -function basalt.triggerEvent(eventName) end - ----Returns a Plugin API ----@param name string The name of the plugin ----@return table Plugin The plugin API -function basalt.getAPI(name) end - ----Runs basalt once, can be used to update the UI manually, but you have to feed it the events -function basalt.update() end - ----Removes a callback function for a specific event ----@param eventName string The name of the event ----@param callback function The callback function to remove ----@return boolean success Whether the callback was found and removed -function basalt.removeEvent(eventName, callback) end - ----Returns the error manager instance ----@return table ErrorManager The error manager -function basalt.getErrorManager() end - ----Returns the focused frame ----@return BaseFrame ? BaseFrame The focused frame -function basalt.getFocus() end - ----Registers a callback function for a specific event ----@param eventName string The name of the event to listen for (e.g. "mouse_click", "key", "timer") ----@param callback function The callback function to execute when the event occurs -function basalt.onEvent(eventName, callback) end - ----Returns the element manager instance ----@return table ElementManager The element manager -function basalt.getElementManager() end - ----Sets a frame as focused ----@param frame BaseFrame The frame to set as focused -function basalt.setFocus(frame) end - ----@class ThemeAPI -local ThemeAPI = {} - ----Gets the current theme configuration ----@return table theme The current theme configuration -function ThemeAPI.getTheme() end - ----Sets the current theme ----@param newTheme table The theme configuration to set -function ThemeAPI.setTheme(newTheme) end - ----Loads a theme from a JSON file ----@param path string Path to the theme JSON file -function ThemeAPI.loadTheme(path) end - ----@class LineChart : Graph -local LineChart = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return LineChart self The initialized instance ----@protected -function LineChart:init(props, basalt) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function LineChart:render() end - ----@class CheckBox : VisualElement ----@field checkedText string when checked ----@field autoSize boolean Whether to automatically size the checkbox ----@field text string Text to display ----@field checked boolean checkbox is checked -local CheckBox = {} - ----Gets the value of the AutoSize property. ----@param self CheckBox self ----@return boolean true Whether to automatically size the checkbox -function CheckBox:getAutoSize(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function CheckBox:render() end - ----Gets the value of the CheckedText property. ----@param self CheckBox self ----@return string Text when checked -function CheckBox:getCheckedText(self) end - ----Sets the value of the Text property. ----@param self CheckBox self ----@param Text string Text to display -function CheckBox:setText(self, Text) end - ----Gets the value of the Text property. ----@param self CheckBox self ----@return string empty Text to display -function CheckBox:getText(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@return CheckBox self The created instance ----@protected -function CheckBox.new() end - ----Sets the value of the Checked property. ----@param self CheckBox self ----@param Checked boolean checkbox is checked -function CheckBox:setChecked(self, Checked) end - ----Sets the value of the CheckedText property. ----@param self CheckBox self ----@param CheckedText string when checked -function CheckBox:setCheckedText(self, CheckedText) end - ----Sets the value of the AutoSize property. ----@param self CheckBox self ----@param AutoSize boolean Whether to automatically size the checkbox -function CheckBox:setAutoSize(self, AutoSize) end - ----Gets the value of the Checked property. ----@param self CheckBox self ----@return boolean Whether checkbox is checked -function CheckBox:getChecked(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean Clicked Whether the event was handled ----@protected -function CheckBox:mouse_click(button, x, y) end +---Returns the current window object +---@return table window The current window object +function Display:getWindow() end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param props table The properties to initialize the element with ---@param basalt table The basalt instance ---@protected -function CheckBox:init(props, basalt) end +function Display:init(props, basalt) end ----@class Table : VisualElement ----@field selectedRow number nil Currently selected row index ----@field customSortFunction table Custom sort functions for columns ----@field gridColor color Color of grid lines ----@field data table The table data as array of row arrays ----@field sortDirection string Sort direction ("asc" or "desc") ----@field selectedColor color Background color of selected row ----@field headerColor color Color of the column headers ----@field columns table List of column definitions with {name, width} properties ----@field scrollOffset number Current scroll position ----@field sortColumn number nil Currently sorted column index -local Table = {} - ----Gets the value of the HeaderColor property. ----@param self Table self ----@return color blue Color of the column headers -function Table:getHeaderColor(self) end +---Writes text to the display at the given position with the given foreground and background colors +---@param x number The x position to write to +---@param y number The y position to write to +---@param text string The text to write +---@return Display self The display instance +function Display:write(x, y, text) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@protected -function Table:render() end +function Display:render() end ----Adds a new column to the table ----@param name string The name of the column ----@param width number The width of the column ----@return Table self The Table instance -function Table:addColumn(name, width) end +---@class TextBox : VisualElement +---@field cursorX number Cursor X position +---@field autoCompleteMinChars number Minimum characters required before showing suggestions +---@field autoCompleteMaxItems number Maximum number of visible suggestions +---@field autoCompleteEnabled boolean Whether autocomplete suggestions are enabled +---@field autoCompleteMaxWidth number Maximum width of the autocomplete popup (0 uses the textbox width) +---@field autoCompleteBackground color Background color of the suggestion popup +---@field autoCompleteZOffset number Z-index offset applied to the popup frame +---@field autoCompleteOffsetY number Vertical offset applied to the popup frame relative to the TextBox bottom edge +---@field autoCompleteAcceptOnClick boolean Whether clicking a suggestion accepts it immediately +---@field lines table Array of text lines +---@field autoCompleteTokenPattern string Pattern used to extract the current token for suggestions +---@field autoCompleteForeground color Foreground color of the suggestion popup +---@field autoCompleteSelectedForeground color Foreground color for the selected suggestion +---@field scrollX number Horizontal scroll offset +---@field autoCompleteSelectedBackground color Background color for the selected suggestion +---@field autoCompleteAcceptOnEnter boolean Whether pressing Enter accepts the current suggestion +---@field editable boolean Whether text can be edited +---@field autoCompleteBorderColor color Color of the popup border when enabled +---@field autoCompleteOffsetX number Horizontal offset applied to the popup frame relative to the TextBox +---@field autoCompleteShowBorder boolean Whether to render a character border around the popup +---@field autoCompleteCloseOnEscape boolean Whether pressing Escape closes the popup +---@field syntaxPatterns table Syntax highlighting patterns +---@field autoCompleteProvider function Optional suggestion provider returning a list for the current prefix +---@field scrollY number Vertical scroll offset +---@field autoCompleteItems table List of suggestions used when no provider is supplied +---@field cursorY number Cursor Y position (line number) +---@field autoCompleteCaseInsensitive boolean Whether suggestions should match case-insensitively +---@field cursorColor number Color of the cursor +local TextBox = {} ----Gets the value of the Data property. ----@param self Table self ----@return table {} The table data as array of row arrays -function Table:getData(self) end +---Sets the value of the AutoCompleteZOffset property. +---@param self TextBox self +---@param AutoCompleteZOffset number Z-index offset applied to the popup frame +function TextBox:setAutoCompleteZOffset(self, AutoCompleteZOffset) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The scroll direction (-1 up, 1 down) +---@param key number The key that was pressed +---@return boolean handled Whether the event was handled +---@protected +function TextBox:key(key) end + +---Sets the value of the Editable property. +---@param self TextBox self +---@param Editable boolean Whether text can be edited +function TextBox:setEditable(self, Editable) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function TextBox:render() end + +---Sets the value of the ScrollY property. +---@param self TextBox self +---@param ScrollY number Vertical scroll offset +function TextBox:setScrollY(self, ScrollY) end + +---Gets the value of the CursorY property. +---@param self TextBox self +---@return number 1 Cursor Y position (line number) +function TextBox:getCursorY(self) end + +---Gets the value of the AutoCompleteBorderColor property. +---@param self TextBox self +---@return color black Color of the popup border when enabled +function TextBox:getAutoCompleteBorderColor(self) end + +---Sets the value of the AutoCompleteAcceptOnClick property. +---@param self TextBox self +---@param AutoCompleteAcceptOnClick boolean Whether clicking a suggestion accepts it immediately +function TextBox:setAutoCompleteAcceptOnClick(self, AutoCompleteAcceptOnClick) end + +---Gets the value of the AutoCompleteItems property. +---@param self TextBox self +---@return table {} List of suggestions used when no provider is supplied +function TextBox:getAutoCompleteItems(self) end + +---Gets the value of the Editable property. +---@param self TextBox self +---@return boolean true Whether text can be edited +function TextBox:getEditable(self) end + +---Gets the value of the AutoCompleteMaxItems property. +---@param self TextBox self +---@return number 6 Maximum number of visible suggestions +function TextBox:getAutoCompleteMaxItems(self) end + +---Gets the value of the AutoCompleteBackground property. +---@param self TextBox self +---@return color lightGray Background color of the suggestion popup +function TextBox:getAutoCompleteBackground(self) end + +---Gets the value of the AutoCompleteAcceptOnClick property. +---@param self TextBox self +---@return boolean true Whether clicking a suggestion accepts it immediately +function TextBox:getAutoCompleteAcceptOnClick(self) end + +---Gets the value of the AutoCompleteZOffset property. +---@param self TextBox self +---@return number 1 Z-index offset applied to the popup frame +function TextBox:getAutoCompleteZOffset(self) end + +---Clears all syntax highlighting patterns +---@return TextBox self +function TextBox:clearSyntaxPatterns() end + +---Gets the value of the AutoCompleteCaseInsensitive property. +---@param self TextBox self +---@return boolean true Whether suggestions should match case-insensitively +function TextBox:getAutoCompleteCaseInsensitive(self) end + +---Sets the value of the AutoCompleteTokenPattern property. +---@param self TextBox self +---@param AutoCompleteTokenPattern string Pattern used to extract the current token for suggestions +function TextBox:setAutoCompleteTokenPattern(self, AutoCompleteTokenPattern) end + +---Sets the value of the AutoCompleteShowBorder property. +---@param self TextBox self +---@param AutoCompleteShowBorder boolean Whether to render a character border around the popup +function TextBox:setAutoCompleteShowBorder(self, AutoCompleteShowBorder) end + +---Gets the value of the AutoCompleteCloseOnEscape property. +---@param self TextBox self +---@return boolean true Whether pressing Escape closes the popup +function TextBox:getAutoCompleteCloseOnEscape(self) end + +---Sets the value of the AutoCompleteProvider property. +---@param self TextBox self +---@param AutoCompleteProvider function Optional suggestion provider returning a list for the current prefix +function TextBox:setAutoCompleteProvider(self, AutoCompleteProvider) end + +---Sets the value of the Lines property. +---@param self TextBox self +---@param Lines table Array of text lines +function TextBox:setLines(self, Lines) end + +---Updates the viewport to keep the cursor in view +---@return TextBox self The TextBox instance +function TextBox:updateViewport() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param direction number The scroll direction ---@param x number The x position of the scroll ---@param y number The y position of the scroll ---@return boolean handled Whether the event was handled ---@protected -function Table:mouse_scroll(direction, x, y) end +function TextBox:mouse_scroll(direction, x, y) end ----Gets the value of the GridColor property. ----@param self Table self ----@return color gray Color of grid lines -function Table:getGridColor(self) end +---Gets the value of the CursorX property. +---@param self TextBox self +---@return number 1 Cursor X position +function TextBox:getCursorX(self) end ----Set data with automatic formatting ----@param rawData table The raw data array ----@param formatters table Optional formatter functions for columns {[2] = function(value) return value end} ----@return Table self The Table instance -function Table:setData(rawData, formatters) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return TextBox self The initialized instance +---@protected +function TextBox:init(props, basalt) end ----Adds data with both display and sort values ----@param displayData table The formatted data for display ----@param sortData table The raw data for sorting (optional) ----@return Table self The Table instance -function Table:setFormattedData(displayData, sortData) end +---Gets the value of the AutoCompleteForeground property. +---@param self TextBox self +---@return color black Foreground color of the suggestion popup +function TextBox:getAutoCompleteForeground(self) end ----Sets the value of the SortColumn property. ----@param self Table self ----@param SortColumn number nil Currently sorted column index -function Table:setSortColumn(self, SortColumn) end +---Sets the value of the AutoCompleteSelectedBackground property. +---@param self TextBox self +---@param AutoCompleteSelectedBackground color Background color for the selected suggestion +function TextBox:setAutoCompleteSelectedBackground(self, AutoCompleteSelectedBackground) end ----Sets a custom sort function for a specific column ----@param columnIndex number The index of the column ----@param sortFn function Function that takes (rowA, rowB) and returns comparison result ----@return Table self The Table instance -function Table:setColumnSortFunction(columnIndex, sortFn) end +---Sets the value of the AutoCompleteItems property. +---@param self TextBox self +---@param AutoCompleteItems table List of suggestions used when no provider is supplied +function TextBox:setAutoCompleteItems(self, AutoCompleteItems) end ----Sets the value of the SelectedRow property. ----@param self Table self ----@param SelectedRow number nil Currently selected row index -function Table:setSelectedRow(self, SelectedRow) end +---Sets the value of the AutoCompleteAcceptOnEnter property. +---@param self TextBox self +---@param AutoCompleteAcceptOnEnter boolean Whether pressing Enter accepts the current suggestion +function TextBox:setAutoCompleteAcceptOnEnter(self, AutoCompleteAcceptOnEnter) end ----Gets the value of the SortColumn property. ----@param self Table self ----@return number ? nil Currently sorted column index -function Table:getSortColumn(self) end +---Sets the value of the AutoCompleteBorderColor property. +---@param self TextBox self +---@param AutoCompleteBorderColor color Color of the popup border when enabled +function TextBox:setAutoCompleteBorderColor(self, AutoCompleteBorderColor) end ----Gets the value of the SortDirection property. ----@param self Table self ----@return string "asc" Sort direction ("asc" or "desc") -function Table:getSortDirection(self) end +---Sets the value of the CursorX property. +---@param self TextBox self +---@param CursorX number Cursor X position +function TextBox:setCursorX(self, CursorX) end + +---Gets the value of the AutoCompleteEnabled property. +---@param self TextBox self +---@return boolean false Whether autocomplete suggestions are enabled +function TextBox:getAutoCompleteEnabled(self) end + +---Sets the value of the AutoCompleteMaxItems property. +---@param self TextBox self +---@param AutoCompleteMaxItems number Maximum number of visible suggestions +function TextBox:setAutoCompleteMaxItems(self, AutoCompleteMaxItems) end + +---Gets the value of the AutoCompleteAcceptOnEnter property. +---@param self TextBox self +---@return boolean true Whether pressing Enter accepts the current suggestion +function TextBox:getAutoCompleteAcceptOnEnter(self) end + +---Gets the text of the TextBox +---@return string text The text of the TextBox +function TextBox:getText() end + +---Gets the value of the AutoCompleteProvider property. +---@param self TextBox self +---@return function nil Optional suggestion provider returning a list for the current prefix +function TextBox:getAutoCompleteProvider(self) end + +---Sets the value of the AutoCompleteOffsetY property. +---@param self TextBox self +---@param AutoCompleteOffsetY number Vertical offset applied to the popup frame relative to the TextBox bottom edge +function TextBox:setAutoCompleteOffsetY(self, AutoCompleteOffsetY) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function TextBox:paste() end + +---Sets the value of the SyntaxPatterns property. +---@param self TextBox self +---@param SyntaxPatterns table Syntax highlighting patterns +function TextBox:setSyntaxPatterns(self, SyntaxPatterns) end + +---Sets the text of the TextBox +---@param text string The text to set +---@return TextBox self The TextBox instance +function TextBox:setText(text) end + +---Sets the value of the AutoCompleteMaxWidth property. +---@param self TextBox self +---@param AutoCompleteMaxWidth number Maximum width of the autocomplete popup (0 uses the textbox width) +function TextBox:setAutoCompleteMaxWidth(self, AutoCompleteMaxWidth) end + +function TextBox:destroy() end + +---Sets the value of the AutoCompleteMinChars property. +---@param self TextBox self +---@param AutoCompleteMinChars number Minimum characters required before showing suggestions +function TextBox:setAutoCompleteMinChars(self, AutoCompleteMinChars) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param button number The button that was clicked @@ -3315,749 +3843,174 @@ function Table:getSortDirection(self) end ---@param y number The y position of the click ---@return boolean handled Whether the event was handled ---@protected -function Table:mouse_click(button, x, y) end +function TextBox:mouse_click(button, x, y) end ----Sets the value of the Columns property. ----@param self Table self ----@param Columns table List of column definitions with {name, width} properties -function Table:setColumns(self, Columns) end +---Sets the value of the AutoCompleteEnabled property. +---@param self TextBox self +---@param AutoCompleteEnabled boolean Whether autocomplete suggestions are enabled +function TextBox:setAutoCompleteEnabled(self, AutoCompleteEnabled) end ----Sets the value of the CustomSortFunction property. ----@param self Table self ----@param CustomSortFunction table Custom sort functions for columns -function Table:setCustomSortFunction(self, CustomSortFunction) end +---Sets the value of the CursorColor property. +---@param self TextBox self +---@param CursorColor number Color of the cursor +function TextBox:setCursorColor(self, CursorColor) end ----Adds a new row of data to the table ----@return Table self The Table instance -function Table:addData() end +---Gets the value of the AutoCompleteShowBorder property. +---@param self TextBox self +---@return boolean true Whether to render a character border around the popup +function TextBox:getAutoCompleteShowBorder(self) end ----Gets the value of the SelectedColor property. ----@param self Table self ----@return color lightBlue Background color of selected row -function Table:getSelectedColor(self) end - ----Sets the value of the GridColor property. ----@param self Table self ----@param GridColor color Color of grid lines -function Table:setGridColor(self, GridColor) end - ----Gets the value of the CustomSortFunction property. ----@param self Table self ----@return table {} Custom sort functions for columns -function Table:getCustomSortFunction(self) end - ----Sets the value of the ScrollOffset property. ----@param self Table self ----@param ScrollOffset number Current scroll position -function Table:setScrollOffset(self, ScrollOffset) end - ----Sorts the table data by column ----@param columnIndex number The index of the column to sort by ----@param fn function ? Optional custom sorting function ----@return Table self The Table instance -function Table:sortData(columnIndex, fn) end - ----Gets the value of the Columns property. ----@param self Table self ----@return table {} List of column definitions with {name, width} properties -function Table:getColumns(self) end - ----Gets the value of the ScrollOffset property. ----@param self Table self ----@return number 0 Current scroll position -function Table:getScrollOffset(self) end - ----Sets the value of the HeaderColor property. ----@param self Table self ----@param HeaderColor color Color of the column headers -function Table:setHeaderColor(self, HeaderColor) end +---Sets the value of the ScrollX property. +---@param self TextBox self +---@param ScrollX number Horizontal scroll offset +function TextBox:setScrollX(self, ScrollX) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Table self The initialized instance ----@protected -function Table:init(props, basalt) end - ----Sets the value of the SortDirection property. ----@param self Table self ----@param SortDirection string Sort direction ("asc" or "desc") -function Table:setSortDirection(self, SortDirection) end - ----Gets the value of the SelectedRow property. ----@param self Table self ----@return number ? nil Currently selected row index -function Table:getSelectedRow(self) end - ----Sets the value of the SelectedColor property. ----@param self Table self ----@param SelectedColor color Background color of selected row -function Table:setSelectedColor(self, SelectedColor) end - ----@class Button : VisualElement ----@field text string Button text -local Button = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@protected -function Button:init(props, basalt) end - ----Sets the value of the Text property. ----@param self Button self ----@param Text string Button text -function Button:setText(self, Text) end - ----Gets the value of the Text property. ----@param self Button self ----@return string Button Button text -function Button:getText(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Button:render() end - ----@class Menu : List ----@field separatorColor color The color used for separator items in the menu -local Menu = {} - ----Gets the value of the SeparatorColor property. ----@param self Menu self ----@return color gray The color used for separator items in the menu -function Menu:getSeparatorColor(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Menu:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Menu self The initialized instance ----@protected -function Menu:init(props, basalt) end - ----Sets the menu items ----@param items table [] List of items with {text, separator, callback, foreground, background} properties ----@return Menu self The Menu instance -function Menu:setItems(items) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean Whether the event was handled ----@protected -function Menu:mouse_click(button, x, y) end - ----Sets the value of the SeparatorColor property. ----@param self Menu self ----@param SeparatorColor color The color used for separator items in the menu -function Menu:setSeparatorColor(self, SeparatorColor) end - ----@class Label : VisualElement ----@field text string The text content to display. Can be a string or a function that returns a string ----@field autoSize boolean Whether the label should automatically resize its width based on the text content -local Label = {} - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Label:render() end - ----Gets the wrapped lines of the Label ----@return table wrappedText The wrapped lines of the Label -function Label:getWrappedText() end - ----Gets the value of the AutoSize property. ----@param self Label self ----@return boolean true Whether the label should automatically resize its width based on the text content -function Label:getAutoSize(self) end - ----Sets the value of the Text property. ----@param self Label self ----@param Text string The text content to display. Can be a string or a function that returns a string -function Label:setText(self, Text) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Label self The initialized instance ----@protected -function Label:init(props, basalt) end - ----Sets the value of the AutoSize property. ----@param self Label self ----@param AutoSize boolean Whether the label should automatically resize its width based on the text content -function Label:setAutoSize(self, AutoSize) end - ----Gets the value of the Text property. ----@param self Label self ----@return string Label The text content to display. Can be a string or a function that returns a string -function Label:getText(self) end - ----@class ScrollBar : VisualElement ----@field value number Current scroll value ----@field orientation string Orientation of the ScrollBar ("vertical" or "horizontal") ----@field step number Step size for scroll operations ----@field dragMultiplier number How fast the ScrollBar moves when dragging ----@field attachedElement table nil The element this ScrollBar is attached to ----@field handleSize number Size of the ScrollBar handle in characters ----@field symbolBackgroundColor color Background color of the ScrollBar handle ----@field backgroundSymbol string Symbol used for the ScrollBar background ----@field min number Minimum scroll value ----@field symbol string " Symbol used for the ScrollBar handle ----@field maxValue number 100 Maximum value or function that returns it ----@field attachedProperty string nil The property being controlled ----@field minValue number 0 Minimum value or function that returns it ----@field max number Maximum scroll value -local ScrollBar = {} - ----Gets the value of the MinValue property. ----@param self ScrollBar self ----@return number |function 0 Minimum value or function that returns it -function ScrollBar:getMinValue(self) end - ----Sets the value of the HandleSize property. ----@param self ScrollBar self ----@param HandleSize number Size of the ScrollBar handle in characters -function ScrollBar:setHandleSize(self, HandleSize) end - ----Gets the value of the HandleSize property. ----@param self ScrollBar self ----@return number 2 Size of the ScrollBar handle in characters -function ScrollBar:getHandleSize(self) end - ----Sets the value of the MinValue property. ----@param self ScrollBar self ----@param MinValue number 0 Minimum value or function that returns it -function ScrollBar:setMinValue(self, MinValue) end - ----Sets the value of the BackgroundSymbol property. ----@param self ScrollBar self ----@param BackgroundSymbol string Symbol used for the ScrollBar background -function ScrollBar:setBackgroundSymbol(self, BackgroundSymbol) end - ----Gets the value of the SymbolBackgroundColor property. ----@param self ScrollBar self ----@return color black Background color of the ScrollBar handle -function ScrollBar:getSymbolBackgroundColor(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param direction number The scroll direction (1 for up, -1 for down) ----@param x number The x position of the scroll ----@param y number The y position of the scroll ----@return boolean Whether the event was handled ----@protected -function ScrollBar:mouse_scroll(direction, x, y) end - ----Sets the value of the MaxValue property. ----@param self ScrollBar self ----@param MaxValue number 100 Maximum value or function that returns it -function ScrollBar:setMaxValue(self, MaxValue) end - ----Gets the value of the BackgroundSymbol property. ----@param self ScrollBar self ----@return string "\127" Symbol used for the ScrollBar background -function ScrollBar:getBackgroundSymbol(self) end - ----Gets the value of the Symbol property. ----@param self ScrollBar self ----@return string " " Symbol used for the ScrollBar handle -function ScrollBar:getSymbol(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean Whether the event was handled ----@protected -function ScrollBar:mouse_click(button, x, y) end - ----Attaches the ScrollBar to an element's property ----@param element BaseElement The element to attach to ----@param config table Configuration {property = "propertyName", min = number|function, max = number|function} ----@return ScrollBar self The ScrollBar instance -function ScrollBar:attach(element, config) end - ----Sets the value of the Orientation property. ----@param self ScrollBar self ----@param Orientation string Orientation of the ScrollBar ("vertical" or "horizontal") -function ScrollBar:setOrientation(self, Orientation) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function ScrollBar:render() end - ----Sets the value of the Min property. ----@param self ScrollBar self ----@param Min number Minimum scroll value -function ScrollBar:setMin(self, Min) end - ----Sets the value of the Step property. ----@param self ScrollBar self ----@param Step number Step size for scroll operations -function ScrollBar:setStep(self, Step) end - ----Gets the value of the Max property. ----@param self ScrollBar self ----@return number 100 Maximum scroll value -function ScrollBar:getMax(self) end - ----Sets the value of the Value property. ----@param self ScrollBar self ----@param Value number Current scroll value -function ScrollBar:setValue(self, Value) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return ScrollBar self The initialized instance ----@protected -function ScrollBar:init(props, basalt) end - ----Updates the attached element's property based on the ScrollBar value ----@return ScrollBar self The ScrollBar instance -function ScrollBar:updateAttachedElement() end - ----Gets the value of the DragMultiplier property. ----@param self ScrollBar self ----@return number 1 How fast the ScrollBar moves when dragging -function ScrollBar:getDragMultiplier(self) end - ----Sets the value of the AttachedElement property. ----@param self ScrollBar self ----@param AttachedElement table nil The element this ScrollBar is attached to -function ScrollBar:setAttachedElement(self, AttachedElement) end - ----Gets the value of the Value property. ----@param self ScrollBar self ----@return number 0 Current scroll value -function ScrollBar:getValue(self) end - ----Gets the value of the Orientation property. ----@param self ScrollBar self ----@return string vertical Orientation of the ScrollBar ("vertical" or "horizontal") -function ScrollBar:getOrientation(self) end - ----Gets the value of the Step property. ----@param self ScrollBar self ----@return number 1 Step size for scroll operations -function ScrollBar:getStep(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button being dragged ----@param x number The x position of the drag ----@param y number The y position of the drag ----@return boolean Whether the event was handled ----@protected -function ScrollBar:mouse_drag(button, x, y) end - ----Sets the value of the DragMultiplier property. ----@param self ScrollBar self ----@param DragMultiplier number How fast the ScrollBar moves when dragging -function ScrollBar:setDragMultiplier(self, DragMultiplier) end - ----Gets the value of the MaxValue property. ----@param self ScrollBar self ----@return number |function 100 Maximum value or function that returns it -function ScrollBar:getMaxValue(self) end - ----Sets the value of the Symbol property. ----@param self ScrollBar self ----@param Symbol string " Symbol used for the ScrollBar handle -function ScrollBar:setSymbol(self, Symbol) end - ----Gets the value of the Min property. ----@param self ScrollBar self ----@return number 0 Minimum scroll value -function ScrollBar:getMin(self) end - ----Gets the value of the AttachedElement property. ----@param self ScrollBar self ----@return table ? nil The element this ScrollBar is attached to -function ScrollBar:getAttachedElement(self) end - ----Sets the value of the Max property. ----@param self ScrollBar self ----@param Max number Maximum scroll value -function ScrollBar:setMax(self, Max) end - ----Sets the value of the SymbolBackgroundColor property. ----@param self ScrollBar self ----@param SymbolBackgroundColor color Background color of the ScrollBar handle -function ScrollBar:setSymbolBackgroundColor(self, SymbolBackgroundColor) end - ----Sets the value of the AttachedProperty property. ----@param self ScrollBar self ----@param AttachedProperty string nil The property being controlled -function ScrollBar:setAttachedProperty(self, AttachedProperty) end - ----Gets the value of the AttachedProperty property. ----@param self ScrollBar self ----@return string ? nil The property being controlled -function ScrollBar:getAttachedProperty(self) end - ----@class FlexBox : Container ----@field flexWrap boolean Whether to wrap flex items onto multiple lines ----@field flexCrossPadding number The padding on both sides of the cross axis ----@field flexJustifyContent string The alignment of flex items along the main axis ----@field flexDirection string The direction of the flexbox layout "row" or "column" ----@field flexSpacing number The spacing between flex items ----@field flexAlignItems string The alignment of flex items along the cross axis ----@field flexUpdateLayout boolean Whether to update the layout of the flexbox -local FlexBox = {} - ----Sets the value of the FlexJustifyContent property. ----@param self FlexBox self ----@param FlexJustifyContent string The alignment of flex items along the main axis -function FlexBox:setFlexJustifyContent(self, FlexJustifyContent) end - ----Adds a child element to the flexbox ----@param element Element The child element to add ----@return FlexBox self The flexbox instance -function FlexBox:addChild(element) end - ----Sets the value of the FlexSpacing property. ----@param self FlexBox self ----@param FlexSpacing number The spacing between flex items -function FlexBox:setFlexSpacing(self, FlexSpacing) end - ----Gets the value of the FlexDirection property. ----@param self FlexBox self ----@return string "row" The direction of the flexbox layout "row" or "column" -function FlexBox:getFlexDirection(self) end - ----Sets the value of the FlexWrap property. ----@param self FlexBox self ----@param FlexWrap boolean Whether to wrap flex items onto multiple lines -function FlexBox:setFlexWrap(self, FlexWrap) end - ----Sets the value of the FlexUpdateLayout property. ----@param self FlexBox self ----@param FlexUpdateLayout boolean Whether to update the layout of the flexbox -function FlexBox:setFlexUpdateLayout(self, FlexUpdateLayout) end - ----Gets the value of the FlexWrap property. ----@param self FlexBox self ----@return boolean false Whether to wrap flex items onto multiple lines -function FlexBox:getFlexWrap(self) end - ----Gets the value of the FlexCrossPadding property. ----@param self FlexBox self ----@return number 0 The padding on both sides of the cross axis -function FlexBox:getFlexCrossPadding(self) end - ----Adds a new line break to the flexbox ----@param self FlexBox The element itself ----@return FlexBox -function FlexBox:addLineBreak(self) end - ----Sets the value of the FlexDirection property. ----@param self FlexBox self ----@param FlexDirection string The direction of the flexbox layout "row" or "column" -function FlexBox:setFlexDirection(self, FlexDirection) end - ----Sets the value of the FlexAlignItems property. ----@param self FlexBox self ----@param FlexAlignItems string The alignment of flex items along the cross axis -function FlexBox:setFlexAlignItems(self, FlexAlignItems) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return FlexBox self The initialized instance ----@protected -function FlexBox:init(props, basalt) end - ----Gets the value of the FlexJustifyContent property. ----@param self FlexBox self ----@return string "flex-start" The alignment of flex items along the main axis -function FlexBox:getFlexJustifyContent(self) end - ----Gets the value of the FlexSpacing property. ----@param self FlexBox self ----@return number 1 The spacing between flex items -function FlexBox:getFlexSpacing(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function FlexBox:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param element Element The child element to remove ----@return FlexBox self The flexbox instance ----@protected -function FlexBox:removeChild(element) end - ----Gets the value of the FlexAlignItems property. ----@param self FlexBox self ----@return string "flex-start" The alignment of flex items along the cross axis -function FlexBox:getFlexAlignItems(self) end - ----Sets the value of the FlexCrossPadding property. ----@param self FlexBox self ----@param FlexCrossPadding number The padding on both sides of the cross axis -function FlexBox:setFlexCrossPadding(self, FlexCrossPadding) end - ----Gets the value of the FlexUpdateLayout property. ----@param self FlexBox self ----@return boolean false Whether to update the layout of the flexbox -function FlexBox:getFlexUpdateLayout(self) end - ----@class DropDown : List ----@field dropSymbol string The symbol to show for DropDown indication ----@field selectedText string The text to show when no item is selected ----@field isOpen boolean Whether the DropDown menu is currently open ----@field dropdownHeight number Maximum height of the DropDown menu when open -local DropDown = {} - ----Gets the value of the DropSymbol property. ----@param self DropDown self ----@return string "\31" The symbol to show for DropDown indication -function DropDown:getDropSymbol(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return DropDown self The initialized instance ----@protected -function DropDown:init(props, basalt) end - ----Gets the value of the SelectedText property. ----@param self DropDown self ----@return string "" The text to show when no item is selected -function DropDown:getSelectedText(self) end - ----Sets the value of the SelectedText property. ----@param self DropDown self ----@param SelectedText string The text to show when no item is selected -function DropDown:setSelectedText(self, SelectedText) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function DropDown:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click +---@param char string The character that was typed ---@return boolean handled Whether the event was handled ---@protected -function DropDown:mouse_click(button, x, y) end +function TextBox:char(char) end ----Sets the value of the IsOpen property. ----@param self DropDown self ----@param IsOpen boolean Whether the DropDown menu is currently open -function DropDown:setIsOpen(self, IsOpen) end +---Sets the value of the AutoCompleteCaseInsensitive property. +---@param self TextBox self +---@param AutoCompleteCaseInsensitive boolean Whether suggestions should match case-insensitively +function TextBox:setAutoCompleteCaseInsensitive(self, AutoCompleteCaseInsensitive) end ----Sets the value of the DropdownHeight property. ----@param self DropDown self ----@param DropdownHeight number Maximum height of the DropDown menu when open -function DropDown:setDropdownHeight(self, DropdownHeight) end +---Gets the value of the AutoCompleteSelectedForeground property. +---@param self TextBox self +---@return color white Foreground color for the selected suggestion +function TextBox:getAutoCompleteSelectedForeground(self) end ----Gets the value of the IsOpen property. ----@param self DropDown self ----@return boolean false Whether the DropDown menu is currently open -function DropDown:getIsOpen(self) end +---Adds a new syntax highlighting pattern +---@param pattern string The regex pattern to match +---@param color number The color to apply +---@return TextBox self The TextBox instance +function TextBox:addSyntaxPattern(pattern, color) end ----Gets the value of the DropdownHeight property. ----@param self DropDown self ----@return number 5 Maximum height of the DropDown menu when open -function DropDown:getDropdownHeight(self) end +---Gets the value of the AutoCompleteTokenPattern property. +---@param self TextBox self +---@return string "[%w_]+" Pattern used to extract the current token for suggestions +function TextBox:getAutoCompleteTokenPattern(self) end ----Sets the value of the DropSymbol property. ----@param self DropDown self ----@param DropSymbol string The symbol to show for DropDown indication -function DropDown:setDropSymbol(self, DropSymbol) end +---Gets the value of the AutoCompleteMaxWidth property. +---@param self TextBox self +---@return number 0 Maximum width of the autocomplete popup (0 uses the textbox width) +function TextBox:getAutoCompleteMaxWidth(self) end ----@class Slider : VisualElement ----@field horizontal boolean Whether the slider is horizontal (false for vertical) ----@field step number Current position of the slider handle (1 to width/height) ----@field sliderColor color Color of the slider handle ----@field max number Maximum value for value conversion (maps slider position to this range) ----@field barColor color Color of the slider track -local Slider = {} +---Gets the value of the AutoCompleteOffsetY property. +---@param self TextBox self +---@return number 1 Vertical offset applied to the popup frame relative to the TextBox bottom edge +function TextBox:getAutoCompleteOffsetY(self) end ----Gets the value of the Max property. ----@param self Slider self ----@return number 100 Maximum value for value conversion (maps slider position to this range) -function Slider:getMax(self) end +---Sets the value of the AutoCompleteOffsetX property. +---@param self TextBox self +---@param AutoCompleteOffsetX number Horizontal offset applied to the popup frame relative to the TextBox +function TextBox:setAutoCompleteOffsetX(self, AutoCompleteOffsetX) end ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button that was released ----@param x number The x position of the release ----@param y number The y position of the release ----@return boolean handled Whether the event was handled ----@protected -function Slider:mouse_scroll(button, x, y) end +---Gets the value of the CursorColor property. +---@param self TextBox self +---@return number nil Color of the cursor +function TextBox:getCursorColor(self) end ----Gets the value of the SliderColor property. ----@param self Slider self ----@return color blue Color of the slider handle -function Slider:getSliderColor(self) end +---Gets the value of the ScrollX property. +---@param self TextBox self +---@return number 0 Horizontal scroll offset +function TextBox:getScrollX(self) end ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The mouse button that was clicked ----@param x number The x position of the click ----@param y number The y position of the click ----@return boolean handled Whether the event was handled ----@protected -function Slider:mouse_click(button, x, y) end +---Sets the value of the CursorY property. +---@param self TextBox self +---@param CursorY number Cursor Y position (line number) +function TextBox:setCursorY(self, CursorY) end ----Gets the value of the Step property. ----@param self Slider self ----@return number 1 Current position of the slider handle (1 to width/height) -function Slider:getStep(self) end +---Gets the value of the SyntaxPatterns property. +---@param self TextBox self +---@return table {} Syntax highlighting patterns +function TextBox:getSyntaxPatterns(self) end ----Gets the value of the BarColor property. ----@param self Slider self ----@return color gray Color of the slider track -function Slider:getBarColor(self) end +---Gets the value of the AutoCompleteMinChars property. +---@param self TextBox self +---@return number 1 Minimum characters required before showing suggestions +function TextBox:getAutoCompleteMinChars(self) end ----Sets the value of the SliderColor property. ----@param self Slider self ----@param SliderColor color Color of the slider handle -function Slider:setSliderColor(self, SliderColor) end +---Sets the value of the AutoCompleteCloseOnEscape property. +---@param self TextBox self +---@param AutoCompleteCloseOnEscape boolean Whether pressing Escape closes the popup +function TextBox:setAutoCompleteCloseOnEscape(self, AutoCompleteCloseOnEscape) end ----Gets the current value of the slider ----@return number value The current value (0 to max) -function Slider:getValue() end +---Gets the value of the AutoCompleteSelectedBackground property. +---@param self TextBox self +---@return color gray Background color for the selected suggestion +function TextBox:getAutoCompleteSelectedBackground(self) end ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param props table The properties to initialize the element with ----@param basalt table The basalt instance ----@return Slider self The initialized instance ----@protected -function Slider:init(props, basalt) end +---Gets the value of the Lines property. +---@param self TextBox self +---@return table {} Array of text lines +function TextBox:getLines(self) end ----Sets the value of the Max property. ----@param self Slider self ----@param Max number Maximum value for value conversion (maps slider position to this range) -function Slider:setMax(self, Max) end +---Sets the value of the AutoCompleteForeground property. +---@param self TextBox self +---@param AutoCompleteForeground color Foreground color of the suggestion popup +function TextBox:setAutoCompleteForeground(self, AutoCompleteForeground) end ----Sets the value of the BarColor property. ----@param self Slider self ----@param BarColor color Color of the slider track -function Slider:setBarColor(self, BarColor) end +---Sets the value of the AutoCompleteBackground property. +---@param self TextBox self +---@param AutoCompleteBackground color Background color of the suggestion popup +function TextBox:setAutoCompleteBackground(self, AutoCompleteBackground) end ----Registers a function to handle the onChange event. ----@param value number ----@param self Slider self ----@param func function The function to be called when the event fires -function Slider:onOnChange(self, func) end +---Sets the value of the AutoCompleteSelectedForeground property. +---@param self TextBox self +---@param AutoCompleteSelectedForeground color Foreground color for the selected suggestion +function TextBox:setAutoCompleteSelectedForeground(self, AutoCompleteSelectedForeground) end ----Sets the value of the Step property. ----@param self Slider self ----@param Step number Current position of the slider handle (1 to width/height) -function Slider:setStep(self, Step) end +---Gets the value of the ScrollY property. +---@param self TextBox self +---@return number 0 Vertical scroll offset +function TextBox:getScrollY(self) end ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function Slider:render() end +---Gets the value of the AutoCompleteOffsetX property. +---@param self TextBox self +---@return number 0 Horizontal offset applied to the popup frame relative to the TextBox +function TextBox:getAutoCompleteOffsetX(self) end ----Gets the value of the Horizontal property. ----@param self Slider self ----@return boolean true Whether the slider is horizontal (false for vertical) -function Slider:getHorizontal(self) end - ----Sets the value of the Horizontal property. ----@param self Slider self ----@param Horizontal boolean Whether the slider is horizontal (false for vertical) -function Slider:setHorizontal(self, Horizontal) end +---Removes a syntax pattern by index (1-based) +---@param index number The index of the pattern to remove +---@return TextBox self +function TextBox:removeSyntaxPattern(index) end ---@class BaseFrame : Container ---@field term term term.current() The terminal or (monitor) peripheral object to render to local BaseFrame = {} ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to render to ----@param y number The y position to render to ----@param text string The text to render ----@param fg string The foreground color ----@param bg string The background color ----@protected -function BaseFrame:blit(x, y, text, fg, bg) end - ----Sets the cursor position ----@param x number The x position to set the cursor to ----@param y number The y position to set the cursor to ----@param blink boolean Whether the cursor should blink -function BaseFrame:setCursor(x, y, blink) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to render to ----@param y number The y position to render to ----@param text string The text to render ----@param fg colors The foreground color ----@protected -function BaseFrame:textFg(x, y, text, fg) end - -function BaseFrame:drawBg() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to render to ----@param y number The y position to render to ----@param text string The text to render ----@param bg colors The background color ----@protected -function BaseFrame:drawText(x, y, text, bg) end - -function BaseFrame.setup() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param char string The character that was pressed ----@protected -function BaseFrame:char(char) end - ----Toggles the debug log frame ----@param self BaseFrame The frame to toggle debug log for -function BaseFrame.toggleConsole(self) end - -function BaseFrame:dispatchEvent() end - ----Hides the debug log frame ----@param self BaseFrame The frame to hide debug log for -function BaseFrame.closeConsole(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function BaseFrame:render() end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param button number The button that was released ----@param x number The x position of the mouse ----@param y number The y position of the mouse ----@protected -function BaseFrame:mouse_up(button, x, y) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@protected -function BaseFrame:term_resize() end - ----Shows the debug log frame ----@param self BaseFrame The frame to show debug log in -function BaseFrame.openConsole(self) end - ----This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param key number The key that was pressed ----@protected -function BaseFrame:key(key) end - ---Sets the value of the Term property. ---@param self BaseFrame self ---@param Term term term.current() The terminal or (monitor) peripheral object to render to function BaseFrame:setTerm(self, Term) end -function BaseFrame:drawFg() end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return table self The initialized instance +---@protected +function BaseFrame:init(props, basalt) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ----@param x number The x position to render to ----@param y number The y position to render to ----@param text string The text to render ----@param bg colors The background color +---@param key number The key that was pressed ---@protected -function BaseFrame:textBg(x, y, text, bg) end +function BaseFrame:key(key) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param char string The character that was pressed +---@protected +function BaseFrame:char(char) end + +---Gets the value of the Term property. +---@param self BaseFrame self +---@return term |peripheral term.current() The terminal or (monitor) peripheral object to render to +function BaseFrame:getTerm(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function BaseFrame:term_resize() end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param x number The x position to render to @@ -4070,11 +4023,46 @@ function BaseFrame:textBg(x, y, text, bg) end ---@protected function BaseFrame:multiBlit(x, y, width, height, text, fg, bg) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to render to +---@param y number The y position to render to +---@param text string The text to render +---@param bg colors The background color +---@protected +function BaseFrame:drawText(x, y, text, bg) end + +function BaseFrame:drawBg() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to render to +---@param y number The y position to render to +---@param text string The text to render +---@param fg colors The foreground color +---@protected +function BaseFrame:textFg(x, y, text, fg) end + ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param key number The key that was released ---@protected function BaseFrame:key_up(key) end +---Initializes a new state for this element +---@param self BaseFrame The element to initialize state for +---@param name string The name of the state +---@param default any The default value of the state +---@return BaseFrame self The element instance +function BaseFrame:initializeState(self, name, default) end + +---Shows the debug log frame +---@param self BaseFrame The frame to show debug log in +function BaseFrame.openConsole(self) end + +---Toggles the debug log frame +---@param self BaseFrame The frame to toggle debug log for +function BaseFrame.toggleConsole(self) end + +function BaseFrame:dispatchEvent() end + ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param button number The button that was clicked ---@param x number The x position of the mouse @@ -4082,6 +4070,46 @@ function BaseFrame:key_up(key) end ---@protected function BaseFrame:mouse_click(button, x, y) end +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to render to +---@param y number The y position to render to +---@param text string The text to render +---@param bg colors The background color +---@protected +function BaseFrame:textBg(x, y, text, bg) end + +---Hides the debug log frame +---@param self BaseFrame The frame to hide debug log for +function BaseFrame.closeConsole(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function BaseFrame:render() end + +---Sets the cursor position +---@param x number The x position to set the cursor to +---@param y number The y position to set the cursor to +---@param blink boolean Whether the cursor should blink +function BaseFrame:setCursor(x, y, blink) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param x number The x position to render to +---@param y number The y position to render to +---@param text string The text to render +---@param fg string The foreground color +---@param bg string The background color +---@protected +function BaseFrame:blit(x, y, text, fg, bg) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was released +---@param x number The x position of the mouse +---@param y number The y position of the mouse +---@protected +function BaseFrame:mouse_up(button, x, y) end + +function BaseFrame:drawFg() end + ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param name string The name of the monitor that was touched ---@param x number The x position of the mouse @@ -4089,45 +4117,239 @@ function BaseFrame:mouse_click(button, x, y) end ---@protected function BaseFrame:monitor_touch(name, x, y) end ----Gets the value of the Term property. ----@param self BaseFrame self ----@return term |peripheral term.current() The terminal or (monitor) peripheral object to render to -function BaseFrame:getTerm(self) end +function BaseFrame.setup() end + +---@class DropDown : List +---@field dropSymbol string The symbol to show for DropDown indication +---@field isOpen boolean Whether the DropDown menu is currently open +---@field selectedText string The text to show when no item is selected +---@field dropdownHeight number Maximum height of the DropDown menu when open +local DropDown = {} + +---Sets the value of the IsOpen property. +---@param self DropDown self +---@param IsOpen boolean Whether the DropDown menu is currently open +function DropDown:setIsOpen(self, IsOpen) end + +---Sets the value of the DropSymbol property. +---@param self DropDown self +---@param DropSymbol string The symbol to show for DropDown indication +function DropDown:setDropSymbol(self, DropSymbol) end + +---Gets the value of the IsOpen property. +---@param self DropDown self +---@return boolean false Whether the DropDown menu is currently open +function DropDown:getIsOpen(self) end + +---Sets the value of the SelectedText property. +---@param self DropDown self +---@param SelectedText string The text to show when no item is selected +function DropDown:setSelectedText(self, SelectedText) end + +---Gets the value of the SelectedText property. +---@param self DropDown self +---@return string "" The text to show when no item is selected +function DropDown:getSelectedText(self) end + +---Sets the value of the DropdownHeight property. +---@param self DropDown self +---@param DropdownHeight number Maximum height of the DropDown menu when open +function DropDown:setDropdownHeight(self, DropdownHeight) end + +---Gets the value of the DropSymbol property. +---@param self DropDown self +---@return string "\31" The symbol to show for DropDown indication +function DropDown:getDropSymbol(self) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function DropDown:render() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param button number The button that was clicked +---@param x number The x position of the click +---@param y number The y position of the click +---@return boolean handled Whether the event was handled +---@protected +function DropDown:mouse_click(button, x, y) end ---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. ---@param props table The properties to initialize the element with ---@param basalt table The basalt instance ----@return table self The initialized instance +---@return DropDown self The initialized instance ---@protected -function BaseFrame:init(props, basalt) end +function DropDown:init(props, basalt) end ----Initializes a new state for this element ----@param self BaseFrame The element to initialize state for ----@param name string The name of the state ----@param default any The default value of the state ----@return BaseFrame self The element instance -function BaseFrame:initializeState(self, name, default) end +---Gets the value of the DropdownHeight property. +---@param self DropDown self +---@return number 5 Maximum height of the DropDown menu when open +function DropDown:getDropdownHeight(self) end ----@class Benchmark -local Benchmark = {} +---@class Image : VisualElement +---@field currentFrame number Current animation frame +---@field bimg table The bimg image data +---@field autoResize boolean Whether to automatically resize the image when content exceeds bounds +---@field offsetX number Horizontal offset for viewing larger images +---@field offsetY number Vertical offset for viewing larger images +local Image = {} ----Starts a custom benchmark ----@param name string The name of the benchmark -function API.start(name) end +---Gets the value of the Bimg property. +---@param self Image self +---@return table {} The bimg image data +function Image:getBimg(self) end ----Clears all custom benchmarks -function API.clearAll() end +---Gets pixel information at position +---@param x number X position +---@param y number Y position +---@return number ? fg Foreground color +---@return number ? bg Background color +---@return string ? char Character at position +function Image:getPixelData(x, y) end ----Clears a specific benchmark ----@param name string The name of the benchmark to clear -function API.clear(name) end +---Advances to the next frame in the animation +---@return Image self The Image instance +function Image:nextFrame() end ----Stops a custom benchmark ----@param name string The name of the benchmark to stop -function API.stop(name) end +---Adds a new frame to the image +---@return Image self The Image instance +function Image:addFrame() end ----Gets statistics for a benchmark ----@param name string The name of the benchmark ----@return table ? stats The benchmark statistics or nil -function API.getStats(name) end +---Sets the value of the Bimg property. +---@param self Image self +---@param Bimg table The bimg image data +function Image:setBimg(self, Bimg) end + +---Resizes the image to the specified width and height +---@param width number The new width of the image +---@param height number The new height of the image +---@return Image self The Image instance +function Image:resizeImage(width, height) end + +---Gets the text at the specified position +---@param x number The x position +---@param y number The y position +---@param length number The length of the text to get +---@return string text The text at the specified position +function Image:getText(x, y, length) end + +---Sets the value of the AutoResize property. +---@param self Image self +---@param AutoResize boolean Whether to automatically resize the image when content exceeds bounds +function Image:setAutoResize(self, AutoResize) end + +---Gets the value of the OffsetY property. +---@param self Image self +---@return number 0 Vertical offset for viewing larger images +function Image:getOffsetY(self) end + +---Gets the specified frame +---@param frameIndex number The index of the frame to get +---@return table frame The frame data +function Image:getFrame(frameIndex) end + +---Gets the foreground color at the specified position +---@param x number The x position +---@param y number The y position +---@param length number The length of the foreground color pattern to get +---@return string fg The foreground color pattern +function Image:getFg(x, y, length) end + +---Gets the background color at the specified position +---@param x number The x position +---@param y number The y position +---@param length number The length of the background color pattern to get +---@return string bg The background color pattern +function Image:getBg(x, y, length) end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@protected +function Image:render() end + +---Sets the value of the OffsetY property. +---@param self Image self +---@param OffsetY number Vertical offset for viewing larger images +function Image:setOffsetY(self, OffsetY) end + +---Sets the background color at the specified position +---@param x number The x position +---@param y number The y position +---@param pattern string The background color pattern +---@return Image self The Image instance +function Image:setBg(x, y, pattern) end + +---Sets the value of the OffsetX property. +---@param self Image self +---@param OffsetX number Horizontal offset for viewing larger images +function Image:setOffsetX(self, OffsetX) end + +---Gets the size of the image +---@return number width The width of the image +---@return number height The height of the image +function Image:getImageSize() end + +---Sets the value of the CurrentFrame property. +---@param self Image self +---@param CurrentFrame number Current animation frame +function Image:setCurrentFrame(self, CurrentFrame) end + +---Sets the pixel at the specified position +---@param x number The x position +---@param y number The y position +---@param char string The character to set +---@param fg string The foreground color pattern +---@param bg string The background color pattern +---@return Image self The Image instance +function Image:setPixel(x, y, char, fg, bg) end + +---Gets the value of the CurrentFrame property. +---@param self Image self +---@return number 1 Current animation frame +function Image:getCurrentFrame(self) end + +---Updates the specified frame with the provided data +---@param frameIndex number The index of the frame to update +---@param frame table The new frame data +---@return Image self The Image instance +function Image:updateFrame(frameIndex, frame) end + +---Sets the metadata of the image +---@param key string The key of the metadata to set +---@param value string The value of the metadata to set +---@return Image self The Image instance +function Image:setMetadata(key, value) end + +---Sets the foreground color at the specified position +---@param x number The x position +---@param y number The y position +---@param pattern string The foreground color pattern +---@return Image self The Image instance +function Image:setFg(x, y, pattern) end + +---Gets the value of the AutoResize property. +---@param self Image self +---@return boolean false Whether to automatically resize the image when content exceeds bounds +function Image:getAutoResize(self) end + +---Sets the text at the specified position +---@param x number The x position +---@param y number The y position +---@param text string The text to set +---@return Image self The Image instance +function Image:setText(x, y, text) end + +---Gets the metadata of the image +---@return table metadata The metadata of the image +function Image:getMetadata() end + +---This function is protected and should not be called outside of basalt, however you can overwrite it if you know what you're doing. +---@param props table The properties to initialize the element with +---@param basalt table The basalt instance +---@return Image self The initialized instance +---@protected +function Image:init(props, basalt) end + +---Gets the value of the OffsetX property. +---@param self Image self +---@return number 0 Horizontal offset for viewing larger images +function Image:getOffsetX(self) end diff --git a/config.lua b/config.lua index 8397292..bfbf751 100644 --- a/config.lua +++ b/config.lua @@ -1,440 +1,440 @@ return { ["metadata"] = { - ["generated"] = "Mon Sep 15 08:45:49 2025", ["version"] = "2.0", + ["generated"] = "Sat Sep 27 20:42:39 2025", }, ["categories"] = { ["plugins"] = { + ["description"] = "Plugins", ["files"] = { - ["reactive"] = { - ["path"] = "plugins/reactive.lua", - ["size"] = 7580, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, - }, ["benchmark"] = { - ["path"] = "plugins/benchmark.lua", - ["size"] = 12581, ["description"] = "", + ["size"] = 12581, + ["path"] = "plugins/benchmark.lua", + ["default"] = true, ["requires"] = { [1] = "VisualElement", }, - ["default"] = true, }, - ["debug"] = { - ["path"] = "plugins/debug.lua", - ["size"] = 6250, + ["theme"] = { ["description"] = "", + ["size"] = 7042, + ["path"] = "plugins/theme.lua", + ["default"] = true, ["requires"] = { }, - ["default"] = true, - }, - ["xml"] = { - ["path"] = "plugins/xml.lua", - ["size"] = 9940, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, }, ["state"] = { - ["path"] = "plugins/state.lua", - ["size"] = 6896, ["description"] = "", + ["size"] = 6896, + ["path"] = "plugins/state.lua", + ["default"] = true, ["requires"] = { [1] = "Container", }, - ["default"] = true, }, - ["theme"] = { - ["path"] = "plugins/theme.lua", - ["size"] = 7042, + ["reactive"] = { ["description"] = "", + ["size"] = 7580, + ["path"] = "plugins/reactive.lua", + ["default"] = true, ["requires"] = { }, - ["default"] = true, }, - ["animation"] = { - ["path"] = "plugins/animation.lua", - ["size"] = 18421, + ["xml"] = { ["description"] = "", + ["size"] = 9940, + ["path"] = "plugins/xml.lua", + ["default"] = true, ["requires"] = { }, - ["default"] = true, }, ["canvas"] = { - ["path"] = "plugins/canvas.lua", + ["description"] = "", ["size"] = 7873, - ["description"] = "", + ["path"] = "plugins/canvas.lua", + ["default"] = true, ["requires"] = { }, + }, + ["debug"] = { + ["description"] = "", + ["size"] = 6250, + ["path"] = "plugins/debug.lua", ["default"] = true, + ["requires"] = { + }, + }, + ["animation"] = { + ["description"] = "", + ["size"] = 18421, + ["path"] = "plugins/animation.lua", + ["default"] = true, + ["requires"] = { + }, }, }, - ["description"] = "Plugins", - }, - ["core"] = { - ["files"] = { - ["log"] = { - ["path"] = "log.lua", - ["size"] = 3142, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, - }, - ["errorManager"] = { - ["path"] = "errorManager.lua", - ["size"] = 3789, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, - }, - ["render"] = { - ["path"] = "render.lua", - ["size"] = 12422, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, - }, - ["propertySystem"] = { - ["path"] = "propertySystem.lua", - ["size"] = 15524, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, - }, - ["main"] = { - ["path"] = "main.lua", - ["size"] = 14085, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, - }, - ["init"] = { - ["path"] = "init.lua", - ["size"] = 622, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, - }, - ["elementManager"] = { - ["path"] = "elementManager.lua", - ["size"] = 6297, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, - }, - }, - ["description"] = "Core Files", - }, - ["libraries"] = { - ["files"] = { - ["expect"] = { - ["path"] = "libraries/expect.lua", - ["size"] = 846, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, - }, - ["utils"] = { - ["path"] = "libraries/utils.lua", - ["size"] = 2661, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, - }, - ["colorHex"] = { - ["path"] = "libraries/colorHex.lua", - ["size"] = 132, - ["description"] = "", - ["requires"] = { - }, - ["default"] = true, - }, - }, - ["description"] = "Libraries", }, ["elements"] = { + ["description"] = "UI Elements", ["files"] = { - ["Container"] = { - ["path"] = "elements/Container.lua", - ["size"] = 25383, - ["description"] = "The container class. It is a visual element that can contain other elements. It is the base class for all containers", - ["requires"] = { - [1] = "VisualElement", - }, + ["TabControl"] = { + ["description"] = "A TabControl element that provides tabbed interface with multiple content areas.", + ["size"] = 15300, + ["path"] = "elements/TabControl.lua", ["default"] = true, + ["requires"] = { + [1] = "Container", + }, }, - ["BigFont"] = { - ["path"] = "elements/BigFont.lua", - ["size"] = 21049, - ["description"] = "", + ["List"] = { + ["description"] = "A scrollable list of selectable items", + ["size"] = 8758, + ["path"] = "elements/List.lua", + ["default"] = true, ["requires"] = { [1] = "VisualElement", }, + }, + ["BarChart"] = { + ["description"] = "", + ["size"] = 3190, + ["path"] = "elements/BarChart.lua", ["default"] = false, + ["requires"] = { + }, + }, + ["BaseFrame"] = { + ["description"] = "This is the base frame class. It is the root element of all elements and the only element without a parent.", + ["size"] = 8466, + ["path"] = "elements/BaseFrame.lua", + ["default"] = true, + ["requires"] = { + [1] = "Container", + }, + }, + ["Container"] = { + ["description"] = "The container class. It is a visual element that can contain other elements. It is the base class for all containers", + ["size"] = 25383, + ["path"] = "elements/Container.lua", + ["default"] = true, + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Program"] = { + ["description"] = "", + ["size"] = 11430, + ["path"] = "elements/Program.lua", + ["default"] = true, + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Table"] = { + ["description"] = "", + ["size"] = 16214, + ["path"] = "elements/Table.lua", + ["default"] = true, + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Menu"] = { + ["description"] = "A horizontal menu bar with selectable items.", + ["size"] = 4679, + ["path"] = "elements/Menu.lua", + ["default"] = true, + ["requires"] = { + [1] = "List", + }, + }, + ["FlexBox"] = { + ["description"] = "A flexbox container that arranges its children in a flexible layout.", + ["size"] = 32431, + ["path"] = "elements/FlexBox.lua", + ["default"] = true, + ["requires"] = { + [1] = "Container", + }, + }, + ["Tree"] = { + ["description"] = "", + ["size"] = 7942, + ["path"] = "elements/Tree.lua", + ["default"] = true, + ["requires"] = { + [1] = "VisualElement", + }, }, ["VisualElement"] = { - ["path"] = "elements/VisualElement.lua", - ["size"] = 18564, ["description"] = "The Visual Element class which is the base class for all visual UI elements", + ["size"] = 18564, + ["path"] = "elements/VisualElement.lua", + ["default"] = true, ["requires"] = { [1] = "BaseElement", }, - ["default"] = true, - }, - ["FlexBox"] = { - ["path"] = "elements/FlexBox.lua", - ["size"] = 32431, - ["description"] = "A flexbox container that arranges its children in a flexible layout.", - ["requires"] = { - [1] = "Container", - }, - ["default"] = true, - }, - ["Tree"] = { - ["path"] = "elements/Tree.lua", - ["size"] = 7942, - ["description"] = "", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = true, - }, - ["BarChart"] = { - ["path"] = "elements/BarChart.lua", - ["size"] = 3190, - ["description"] = "", - ["requires"] = { - }, - ["default"] = false, - }, - ["Input"] = { - ["path"] = "elements/Input.lua", - ["size"] = 9558, - ["description"] = "A text input field with various features", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = true, - }, - ["Graph"] = { - ["path"] = "elements/Graph.lua", - ["size"] = 6989, - ["description"] = "A point based graph element", - ["requires"] = { - }, - ["default"] = false, - }, - ["Label"] = { - ["path"] = "elements/Label.lua", - ["size"] = 3092, - ["description"] = "A simple text display element that automatically resizes its width based on the text content.", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = true, - }, - ["Program"] = { - ["path"] = "elements/Program.lua", - ["size"] = 11430, - ["description"] = "", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = true, - }, - ["CheckBox"] = { - ["path"] = "elements/CheckBox.lua", - ["size"] = 2928, - ["description"] = "", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = true, - }, - ["Switch"] = { - ["path"] = "elements/Switch.lua", - ["size"] = 3269, - ["description"] = "The Switch is a standard Switch element with click handling and state management.", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = true, - }, - ["Display"] = { - ["path"] = "elements/Display.lua", - ["size"] = 4243, - ["description"] = "The Display is a special element which uses the cc window API which you can use.", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = false, - }, - ["LineChart"] = { - ["path"] = "elements/LineChart.lua", - ["size"] = 3227, - ["description"] = "", - ["requires"] = { - }, - ["default"] = false, }, ["ScrollBar"] = { - ["path"] = "elements/ScrollBar.lua", - ["size"] = 9665, ["description"] = "A ScrollBar element that can be attached to other elements to control their scroll properties.", + ["size"] = 9665, + ["path"] = "elements/ScrollBar.lua", + ["default"] = true, ["requires"] = { [1] = "VisualElement", }, + }, + ["Button"] = { + ["description"] = "", + ["size"] = 1656, + ["path"] = "elements/Button.lua", ["default"] = true, + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Image"] = { + ["description"] = "An element that displays an image in bimg format", + ["size"] = 15125, + ["path"] = "elements/Image.lua", + ["default"] = false, + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Switch"] = { + ["description"] = "The Switch is a standard Switch element with click handling and state management.", + ["size"] = 3269, + ["path"] = "elements/Switch.lua", + ["default"] = true, + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Timer"] = { + ["description"] = "", + ["size"] = 2914, + ["path"] = "elements/Timer.lua", + ["default"] = true, + ["requires"] = { + [1] = "BaseElement", + }, + }, + ["CheckBox"] = { + ["description"] = "", + ["size"] = 2928, + ["path"] = "elements/CheckBox.lua", + ["default"] = true, + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["BigFont"] = { + ["description"] = "", + ["size"] = 21049, + ["path"] = "elements/BigFont.lua", + ["default"] = false, + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["BaseElement"] = { + ["description"] = "The base class for all UI elements in Basalt.", + ["size"] = 9686, + ["path"] = "elements/BaseElement.lua", + ["default"] = true, + ["requires"] = { + }, + }, + ["LineChart"] = { + ["description"] = "", + ["size"] = 3227, + ["path"] = "elements/LineChart.lua", + ["default"] = false, + ["requires"] = { + }, + }, + ["Input"] = { + ["description"] = "A text input field with various features", + ["size"] = 9558, + ["path"] = "elements/Input.lua", + ["default"] = true, + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["ProgressBar"] = { + ["description"] = "", + ["size"] = 3397, + ["path"] = "elements/ProgressBar.lua", + ["default"] = true, + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["TextBox"] = { + ["description"] = "A multi-line text editor component with cursor support and text manipulation features", + ["size"] = 38993, + ["path"] = "elements/TextBox.lua", + ["default"] = false, + ["requires"] = { + [1] = "VisualElement", + }, }, ["DropDown"] = { - ["path"] = "elements/DropDown.lua", - ["size"] = 6359, ["description"] = "A DropDown menu that shows a list of selectable items", - ["requires"] = { - [1] = "List", - }, + ["size"] = 6359, + ["path"] = "elements/DropDown.lua", ["default"] = false, - }, - ["Menu"] = { - ["path"] = "elements/Menu.lua", - ["size"] = 4679, - ["description"] = "A horizontal menu bar with selectable items.", ["requires"] = { [1] = "List", }, - ["default"] = true, }, ["Slider"] = { - ["path"] = "elements/Slider.lua", - ["size"] = 4977, ["description"] = "", + ["size"] = 4977, + ["path"] = "elements/Slider.lua", + ["default"] = true, + ["requires"] = { + [1] = "VisualElement", + }, + }, + ["Graph"] = { + ["description"] = "A point based graph element", + ["size"] = 6989, + ["path"] = "elements/Graph.lua", + ["default"] = false, + ["requires"] = { + }, + }, + ["Display"] = { + ["description"] = "The Display is a special element which uses the cc window API which you can use.", + ["size"] = 4243, + ["path"] = "elements/Display.lua", + ["default"] = false, ["requires"] = { [1] = "VisualElement", }, - ["default"] = true, }, ["Frame"] = { - ["path"] = "elements/Frame.lua", - ["size"] = 6508, ["description"] = "A frame element that serves as a grouping container for other elements.", + ["size"] = 6508, + ["path"] = "elements/Frame.lua", + ["default"] = true, ["requires"] = { [1] = "Container", }, - ["default"] = true, - }, - ["Button"] = { - ["path"] = "elements/Button.lua", - ["size"] = 1656, - ["description"] = "", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = true, - }, - ["ProgressBar"] = { - ["path"] = "elements/ProgressBar.lua", - ["size"] = 3397, - ["description"] = "", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = true, }, ["ComboBox"] = { - ["path"] = "elements/ComboBox.lua", - ["size"] = 14649, ["description"] = "A ComboBox that combines dropdown selection with editable text input", + ["size"] = 14649, + ["path"] = "elements/ComboBox.lua", + ["default"] = false, ["requires"] = { [1] = "DropDown", }, - ["default"] = false, }, - ["TextBox"] = { - ["path"] = "elements/TextBox.lua", - ["size"] = 12667, - ["description"] = "A multi-line text editor component with cursor support and text manipulation features", + ["Label"] = { + ["description"] = "A simple text display element that automatically resizes its width based on the text content.", + ["size"] = 3092, + ["path"] = "elements/Label.lua", + ["default"] = true, ["requires"] = { [1] = "VisualElement", }, - ["default"] = false, - }, - ["List"] = { - ["path"] = "elements/List.lua", - ["size"] = 8758, - ["description"] = "A scrollable list of selectable items", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = true, - }, - ["BaseElement"] = { - ["path"] = "elements/BaseElement.lua", - ["size"] = 9686, - ["description"] = "The base class for all UI elements in Basalt.", - ["requires"] = { - }, - ["default"] = true, - }, - ["TabControl"] = { - ["path"] = "elements/TabControl.lua", - ["size"] = 15300, - ["description"] = "A TabControl element that provides tabbed interface with multiple content areas.", - ["requires"] = { - [1] = "Container", - }, - ["default"] = true, - }, - ["Image"] = { - ["path"] = "elements/Image.lua", - ["size"] = 15125, - ["description"] = "An element that displays an image in bimg format", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = false, - }, - ["BaseFrame"] = { - ["path"] = "elements/BaseFrame.lua", - ["size"] = 8466, - ["description"] = "This is the base frame class. It is the root element of all elements and the only element without a parent.", - ["requires"] = { - [1] = "Container", - }, - ["default"] = true, - }, - ["Timer"] = { - ["path"] = "elements/Timer.lua", - ["size"] = 2914, - ["description"] = "", - ["requires"] = { - [1] = "BaseElement", - }, - ["default"] = true, - }, - ["Table"] = { - ["path"] = "elements/Table.lua", - ["size"] = 16214, - ["description"] = "", - ["requires"] = { - [1] = "VisualElement", - }, - ["default"] = true, }, }, - ["description"] = "UI Elements", + }, + ["core"] = { + ["description"] = "Core Files", + ["files"] = { + ["errorManager"] = { + ["description"] = "", + ["size"] = 3789, + ["path"] = "errorManager.lua", + ["default"] = true, + ["requires"] = { + }, + }, + ["main"] = { + ["description"] = "", + ["size"] = 14085, + ["path"] = "main.lua", + ["default"] = true, + ["requires"] = { + }, + }, + ["elementManager"] = { + ["description"] = "", + ["size"] = 6297, + ["path"] = "elementManager.lua", + ["default"] = true, + ["requires"] = { + }, + }, + ["init"] = { + ["description"] = "", + ["size"] = 622, + ["path"] = "init.lua", + ["default"] = true, + ["requires"] = { + }, + }, + ["render"] = { + ["description"] = "", + ["size"] = 12422, + ["path"] = "render.lua", + ["default"] = true, + ["requires"] = { + }, + }, + ["propertySystem"] = { + ["description"] = "", + ["size"] = 15524, + ["path"] = "propertySystem.lua", + ["default"] = true, + ["requires"] = { + }, + }, + ["log"] = { + ["description"] = "", + ["size"] = 3142, + ["path"] = "log.lua", + ["default"] = true, + ["requires"] = { + }, + }, + }, + }, + ["libraries"] = { + ["description"] = "Libraries", + ["files"] = { + ["utils"] = { + ["description"] = "", + ["size"] = 2661, + ["path"] = "libraries/utils.lua", + ["default"] = true, + ["requires"] = { + }, + }, + ["colorHex"] = { + ["description"] = "", + ["size"] = 132, + ["path"] = "libraries/colorHex.lua", + ["default"] = true, + ["requires"] = { + }, + }, + ["expect"] = { + ["description"] = "", + ["size"] = 846, + ["path"] = "libraries/expect.lua", + ["default"] = true, + ["requires"] = { + }, + }, + }, }, }, } \ No newline at end of file diff --git a/release/basalt.lua b/release/basalt.lua index 29c5885..08b7787 100644 --- a/release/basalt.lua +++ b/release/basalt.lua @@ -5,44 +5,3146 @@ local project = {} local loadedProject = {} local baseRequire = require require = function(path) if(project[path..".lua"])then if(loadedProject[path]==nil)then loadedProject[path] = project[path..".lua"]() end return loadedProject[path] end return baseRequire(path) end -minified_elementDirectory["TextBox"] = {} -minified_elementDirectory["Frame"] = {} -minified_elementDirectory["Slider"] = {} -minified_elementDirectory["Menu"] = {} -minified_elementDirectory["TabControl"] = {} -minified_elementDirectory["ProgressBar"] = {} -minified_elementDirectory["Table"] = {} -minified_elementDirectory["Display"] = {} -minified_elementDirectory["BaseElement"] = {} -minified_elementDirectory["Input"] = {} +minified_elementDirectory["BaseFrame"] = {} minified_elementDirectory["Timer"] = {} +minified_elementDirectory["Program"] = {} +minified_elementDirectory["Image"] = {} +minified_elementDirectory["BarChart"] = {} +minified_elementDirectory["ComboBox"] = {} +minified_elementDirectory["TabControl"] = {} +minified_elementDirectory["TextBox"] = {} minified_elementDirectory["Button"] = {} -minified_elementDirectory["VisualElement"] = {} -minified_elementDirectory["FlexBox"] = {} -minified_elementDirectory["CheckBox"] = {} -minified_elementDirectory["BigFont"] = {} minified_elementDirectory["Label"] = {} +minified_elementDirectory["Input"] = {} +minified_elementDirectory["BigFont"] = {} +minified_elementDirectory["Switch"] = {} +minified_elementDirectory["Frame"] = {} +minified_elementDirectory["Container"] = {} minified_elementDirectory["Tree"] = {} minified_elementDirectory["DropDown"] = {} -minified_elementDirectory["ComboBox"] = {} -minified_elementDirectory["Switch"] = {} -minified_elementDirectory["ScrollBar"] = {} -minified_elementDirectory["BaseFrame"] = {} -minified_elementDirectory["Image"] = {} -minified_elementDirectory["List"] = {} -minified_elementDirectory["Program"] = {} -minified_elementDirectory["Container"] = {} -minified_elementDirectory["Graph"] = {} -minified_elementDirectory["BarChart"] = {} +minified_elementDirectory["Display"] = {} minified_elementDirectory["LineChart"] = {} -minified_pluginDirectory["debug"] = {} +minified_elementDirectory["Graph"] = {} +minified_elementDirectory["FlexBox"] = {} +minified_elementDirectory["Table"] = {} +minified_elementDirectory["Menu"] = {} +minified_elementDirectory["Slider"] = {} +minified_elementDirectory["ScrollBar"] = {} +minified_elementDirectory["VisualElement"] = {} +minified_elementDirectory["ProgressBar"] = {} +minified_elementDirectory["CheckBox"] = {} +minified_elementDirectory["BaseElement"] = {} +minified_elementDirectory["List"] = {} minified_pluginDirectory["canvas"] = {} +minified_pluginDirectory["theme"] = {} minified_pluginDirectory["reactive"] = {} minified_pluginDirectory["state"] = {} -minified_pluginDirectory["benchmark"] = {} -minified_pluginDirectory["animation"] = {} minified_pluginDirectory["xml"] = {} -minified_pluginDirectory["theme"] = {} +minified_pluginDirectory["debug"] = {} +minified_pluginDirectory["animation"] = {} +minified_pluginDirectory["benchmark"] = {} +project["errorManager.lua"] = function(...) local d=require("log") +local _a={tracebackEnabled=true,header="Basalt Error"}local function aa(ba,ca)term.setTextColor(ca)print(ba) +term.setTextColor(colors.white)end +function _a.error(ba) +if _a.errorHandled then error()end;term.setBackgroundColor(colors.black) +term.clear()term.setCursorPos(1,1) +aa(_a.header..":",colors.red)print()local ca=2;local da;while true do local db=debug.getinfo(ca,"Sl") +if not db then break end;da=db;ca=ca+1 end;local _b=da or +debug.getinfo(2,"Sl")local ab=_b.source:sub(2) +local bb=_b.currentline;local cb=ba +if(_a.tracebackEnabled)then local db=debug.traceback() +if db then +for _c in db:gmatch("[^\r\n]+")do +local ac,bc=_c:match("([^:]+):(%d+):") +if ac and bc then term.setTextColor(colors.lightGray) +term.write(ac)term.setTextColor(colors.gray)term.write(":") +term.setTextColor(colors.lightBlue)term.write(bc)term.setTextColor(colors.gray)_c=_c:gsub( +ac..":"..bc,"")end;aa(_c,colors.gray)end;print()end end +if ab and bb then term.setTextColor(colors.red) +term.write("Error in ")term.setTextColor(colors.white)term.write(ab) +term.setTextColor(colors.red)term.write(":") +term.setTextColor(colors.lightBlue)term.write(bb)term.setTextColor(colors.red) +term.write(": ") +if cb then cb=string.gsub(cb,"stack traceback:.*","") +if cb~=""then +aa(cb,colors.red)else aa("Error message not available",colors.gray)end else aa("Error message not available",colors.gray)end;local db=fs.open(ab,"r") +if db then local _c=""local ac=1 +repeat _c=db.readLine()if +ac==tonumber(bb)then aa("\149Line "..bb,colors.cyan) +aa(_c,colors.lightGray)break end;ac=ac+1 until not _c;db.close()end end;term.setBackgroundColor(colors.black) +d.error(ba)_a.errorHandled=true;error()end;return _a end +project["render.lua"] = function(...) local _a=require("libraries/colorHex")local aa=require("log") +local ba={}ba.__index=ba;local ca=string.sub +function ba.new(da)local _b=setmetatable({},ba) +_b.terminal=da;_b.width,_b.height=da.getSize() +_b.buffer={text={},fg={},bg={},dirtyRects={}} +for y=1,_b.height do _b.buffer.text[y]=string.rep(" ",_b.width) +_b.buffer.fg[y]=string.rep("0",_b.width)_b.buffer.bg[y]=string.rep("f",_b.width)end;return _b end;function ba:addDirtyRect(da,_b,ab,bb) +table.insert(self.buffer.dirtyRects,{x=da,y=_b,width=ab,height=bb})return self end +function ba:blit(da,_b,ab,bb,cb)if +_b<1 or _b>self.height then return self end;if(#ab~=#bb or +#ab~=#cb)then +error("Text, fg, and bg must be the same length")end +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width) +self.buffer.fg[_b]=ca( +self.buffer.fg[_b]:sub(1,da-1)..bb..self.buffer.fg[_b]:sub(da+#bb),1,self.width) +self.buffer.bg[_b]=ca( +self.buffer.bg[_b]:sub(1,da-1)..cb..self.buffer.bg[_b]:sub(da+#cb),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:multiBlit(da,_b,ab,bb,cb,db,_c)if _b<1 or _b>self.height then return self end;if( +#cb~=#db or#cb~=#_c)then +error("Text, fg, and bg must be the same length")end;cb=cb:rep(ab) +db=db:rep(ab)_c=_c:rep(ab) +for dy=0,bb-1 do local ac=_b+dy +if ac>=1 and ac<=self.height then +self.buffer.text[ac]=ca(self.buffer.text[ac]:sub(1, +da-1)..cb.. +self.buffer.text[ac]:sub(da+#cb),1,self.width) +self.buffer.fg[ac]=ca( +self.buffer.fg[ac]:sub(1,da-1)..db..self.buffer.fg[ac]:sub(da+#db),1,self.width) +self.buffer.bg[ac]=ca( +self.buffer.bg[ac]:sub(1,da-1).._c..self.buffer.bg[ac]:sub(da+#_c),1,self.width)end end;self:addDirtyRect(da,_b,ab,bb)return self end +function ba:textFg(da,_b,ab,bb)if _b<1 or _b>self.height then return self end +bb=_a[bb]or"0"bb=bb:rep(#ab) +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width) +self.buffer.fg[_b]=ca( +self.buffer.fg[_b]:sub(1,da-1)..bb..self.buffer.fg[_b]:sub(da+#bb),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:textBg(da,_b,ab,bb)if _b<1 or _b>self.height then return self end +bb=_a[bb]or"f" +self.buffer.text[_b]=ca( +self.buffer.text[_b]:sub(1,da-1).. +ab..self.buffer.text[_b]:sub(da+#ab),1,self.width) +self.buffer.bg[_b]=ca( +self.buffer.bg[_b]:sub(1,da-1).. +bb:rep(#ab)..self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:text(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:fg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.fg[_b]=ca(self.buffer.fg[_b]:sub(1, +da-1)..ab.. +self.buffer.fg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:bg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.bg[_b]=ca(self.buffer.bg[_b]:sub(1, +da-1)..ab.. +self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:text(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, +da-1)..ab.. +self.buffer.text[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:fg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.fg[_b]=ca(self.buffer.fg[_b]:sub(1, +da-1)..ab.. +self.buffer.fg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:bg(da,_b,ab)if _b<1 or _b>self.height then return self end +self.buffer.bg[_b]=ca(self.buffer.bg[_b]:sub(1, +da-1)..ab.. +self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end +function ba:clear(da)local _b=_a[da]or"f" +for y=1,self.height do +self.buffer.text[y]=string.rep(" ",self.width)self.buffer.fg[y]=string.rep("0",self.width) +self.buffer.bg[y]=string.rep(_b,self.width)self:addDirtyRect(1,y,self.width,1)end;return self end +function ba:render()local da={} +for _b,ab in ipairs(self.buffer.dirtyRects)do local bb=false;for cb,db in ipairs(da)do +if +self:rectOverlaps(ab,db)then self:mergeRects(db,ab)bb=true;break end end;if not bb then +table.insert(da,ab)end end +for _b,ab in ipairs(da)do +for y=ab.y,ab.y+ab.height-1 do +if y>=1 and y<=self.height then +self.terminal.setCursorPos(ab.x,y) +self.terminal.blit(self.buffer.text[y]:sub(ab.x,ab.x+ab.width-1),self.buffer.fg[y]:sub(ab.x, +ab.x+ab.width-1),self.buffer.bg[y]:sub(ab.x, +ab.x+ab.width-1))end end end;self.buffer.dirtyRects={} +if self.blink then +self.terminal.setTextColor(self.cursorColor or +colors.white) +self.terminal.setCursorPos(self.xCursor,self.yCursor)self.terminal.setCursorBlink(true)else +self.terminal.setCursorBlink(false)end;return self end +function ba:rectOverlaps(da,_b)return +not( +da.x+da.width<=_b.x or _b.x+_b.width<=da.x or da.y+da.height<=_b.y or +_b.y+_b.height<=da.y)end +function ba:mergeRects(da,_b)local ab=math.min(da.x,_b.x) +local bb=math.min(da.y,_b.y) +local cb=math.max(da.x+da.width,_b.x+_b.width) +local db=math.max(da.y+da.height,_b.y+_b.height)da.x=ab;da.y=bb;da.width=cb-ab;da.height=db-bb;return self end +function ba:setCursor(da,_b,ab,bb) +if bb~=nil then self.terminal.setTextColor(bb)end;self.terminal.setCursorPos(da,_b) +self.terminal.setCursorBlink(ab)self.xCursor=da;self.yCursor=_b;self.blink=ab;self.cursorColor=bb +return self end +function ba:clearArea(da,_b,ab,bb,cb)local db=_a[cb]or"f" +for dy=0,bb-1 do local _c=_b+dy;if +_c>=1 and _c<=self.height then local ac=string.rep(" ",ab)local bc=string.rep(db,ab) +self:blit(da,_c,ac,"0",db)end end;return self end;function ba:getSize()return self.width,self.height end +function ba:setSize(da,_b) +self.width=da;self.height=_b +for y=1,self.height do +self.buffer.text[y]=string.rep(" ",self.width)self.buffer.fg[y]=string.rep("0",self.width) +self.buffer.bg[y]=string.rep("f",self.width)end;return self end;return ba end +project["init.lua"] = function(...) local da={...}local _b=fs.getDir(da[2])local ab=package.path +local bb="path;/path/?.lua;/path/?/init.lua;"local cb=bb:gsub("path",_b)package.path=cb.."rom/?;"..ab +local function db(bc)package.path= +cb.."rom/?"local cc=require("errorManager") +package.path=ab;cc.header="Basalt Loading Error"cc.error(bc)end;local _c,ac=pcall(require,"main")package.loaded.log=nil +package.path=ab;if not _c then db(ac)else return ac end end +project["elements/BaseFrame.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("Container")local da=require("errorManager")local _b=require("render") +local ab=setmetatable({},ca)ab.__index=ab +local function bb(cb) +local db,_c=pcall(function()return peripheral.getType(cb)end)if db then return true end;return false end +ab.defineProperty(ab,"term",{default=nil,type="table",setter=function(cb,db)cb._peripheralName=nil;if +cb.basalt.getActiveFrame(cb._values.term)==cb then +cb.basalt.setActiveFrame(cb,false)end;if +db==nil or db.setCursorPos==nil then return db end;if(bb(db))then +cb._peripheralName=peripheral.getName(db)end;cb._values.term=db +if +cb.basalt.getActiveFrame(db)==nil then cb.basalt.setActiveFrame(cb)end;cb._render=_b.new(db)cb._renderUpdate=true;local _c,ac=db.getSize() +cb.set("width",_c)cb.set("height",ac)return db end})function ab.new()local cb=setmetatable({},ab):__init() +cb.class=ab;return cb end;function ab:init(cb,db) +ca.init(self,cb,db)self.set("term",term.current()) +self.set("type","BaseFrame")return self end +function ab:multiBlit(cb,db,_c,ac,bc,cc,dc)if +(cb<1)then _c=_c+cb-1;cb=1 end;if(db<1)then ac=ac+db-1;db=1 end +self._render:multiBlit(cb,db,_c,ac,bc,cc,dc)end;function ab:textFg(cb,db,_c,ac)if cb<1 then _c=string.sub(_c,1 -cb)cb=1 end +self._render:textFg(cb,db,_c,ac)end;function ab:textBg(cb,db,_c,ac)if cb<1 then _c=string.sub(_c,1 - +cb)cb=1 end +self._render:textBg(cb,db,_c,ac)end;function ab:drawText(cb,db,_c)if cb<1 then _c=string.sub(_c, +1 -cb)cb=1 end +self._render:text(cb,db,_c)end +function ab:drawFg(cb,db,_c)if cb<1 then +_c=string.sub(_c,1 -cb)cb=1 end;self._render:fg(cb,db,_c)end;function ab:drawBg(cb,db,_c)if cb<1 then _c=string.sub(_c,1 -cb)cb=1 end +self._render:bg(cb,db,_c)end +function ab:blit(cb,db,_c,ac,bc) +if cb<1 then +_c=string.sub(_c,1 -cb)ac=string.sub(ac,1 -cb)bc=string.sub(bc,1 -cb)cb=1 end;self._render:blit(cb,db,_c,ac,bc)end;function ab:setCursor(cb,db,_c,ac)local bc=self.get("term") +self._render:setCursor(cb,db,_c,ac)end +function ab:monitor_touch(cb,db,_c) +local ac=self.get("term")if ac==nil then return end +if(bb(ac))then if self._peripheralName==cb then +self:mouse_click(1,db,_c) +self.basalt.schedule(function()sleep(0.1)self:mouse_up(1,db,_c)end)end end end;function ab:mouse_click(cb,db,_c)ca.mouse_click(self,cb,db,_c) +self.basalt.setFocus(self)end +function ab:mouse_up(cb,db,_c) +ca.mouse_up(self,cb,db,_c)ca.mouse_release(self,cb,db,_c)end +function ab:term_resize()local cb,db=self.get("term").getSize() +if(cb== +self.get("width")and db==self.get("height"))then return end;self.set("width",cb)self.set("height",db) +self._render:setSize(cb,db)self._renderUpdate=true end +function ab:key(cb)self:fireEvent("key",cb)ca.key(self,cb)end +function ab:key_up(cb)self:fireEvent("key_up",cb)ca.key_up(self,cb)end +function ab:char(cb)self:fireEvent("char",cb)ca.char(self,cb)end +function ab:dispatchEvent(cb,...)local db=self.get("term")if db==nil then return end;if(bb(db))then if +cb=="mouse_click"then return end end +ca.dispatchEvent(self,cb,...)end;function ab:render() +if(self._renderUpdate)then if self._render~=nil then ca.render(self) +self._render:render()self._renderUpdate=false end end end +return ab end +project["elements/Timer.lua"] = function(...) local d=require("elementManager") +local _a=d.getElement("BaseElement")local aa=setmetatable({},_a)aa.__index=aa +aa.defineProperty(aa,"interval",{default=1,type="number"}) +aa.defineProperty(aa,"action",{default=function()end,type="function"}) +aa.defineProperty(aa,"running",{default=false,type="boolean"}) +aa.defineProperty(aa,"amount",{default=-1,type="number"})aa.defineEvent(aa,"timer")function aa.new() +local ba=setmetatable({},aa):__init()ba.class=aa;return ba end;function aa:init(ba,ca) +_a.init(self,ba,ca)self.set("type","Timer")end +function aa:start()if +not self.running then self.running=true;local ba=self.get("interval") +self.timerId=os.startTimer(ba)end;return self end +function aa:stop()if self.running then self.running=false +os.cancelTimer(self.timerId)end;return self end +function aa:dispatchEvent(ba,...)_a.dispatchEvent(self,ba,...) +if ba=="timer"then +local ca=select(1,...) +if ca==self.timerId then self.action()local da=self.get("amount")if da>0 then self.set("amount", +da-1)end;if da~=0 then +self.timerId=os.startTimer(self.get("interval"))end end end end;return aa end +project["elements/Program.lua"] = function(...) local ca=require("elementManager") +local da=ca.getElement("VisualElement")local _b=require("errorManager")local ab=setmetatable({},da) +ab.__index=ab +ab.defineProperty(ab,"program",{default=nil,type="table"}) +ab.defineProperty(ab,"path",{default="",type="string"}) +ab.defineProperty(ab,"running",{default=false,type="boolean"}) +ab.defineProperty(ab,"errorCallback",{default=nil,type="function"}) +ab.defineProperty(ab,"doneCallback",{default=nil,type="function"})ab.defineEvent(ab,"*")local bb={}bb.__index=bb +local cb=dofile("rom/modules/main/cc/require.lua").make +function bb.new(_c,ac,bc)local cc=setmetatable({},bb)cc.env=ac or{}cc.args={}cc.addEnvironment= +bc==nil and true or bc;cc.program=_c;return cc end;function bb:setArgs(...)self.args={...}end +local function db(_c) +local ac={shell=shell,multishell=multishell}ac.require,ac.package=cb(ac,_c)return ac end +function bb:run(_c,ac,bc) +self.window=window.create(self.program:getBaseFrame():getTerm(),1,1,ac,bc,false) +local cc=shell.resolveProgram(_c)or fs.exists(_c)and _c or nil +if(cc~=nil)then +if(fs.exists(cc))then local dc=fs.open(cc,"r")local _d=dc.readAll() +dc.close() +local ad=setmetatable(db(fs.getDir(_c)),{__index=_ENV})ad.term=self.window;ad.term.current=term.current +ad.term.redirect=term.redirect;ad.term.native=function()return self.window end +if +(self.addEnvironment)then for __a,a_a in pairs(self.env)do ad[__a]=a_a end else ad=self.env end +self.coroutine=coroutine.create(function()local __a=load(_d,"@/".._c,nil,ad)if __a then +local a_a=__a(table.unpack(self.args))return a_a end end)local bd=term.current()term.redirect(self.window) +local cd,dd=coroutine.resume(self.coroutine)term.redirect(bd) +if not cd then +local __a=self.program.get("doneCallback")if __a then __a(self.program,cd,dd)end +local a_a=self.program.get("errorCallback") +if a_a then local b_a=debug.traceback(self.coroutine,dd) +local c_a=a_a(self.program,dd,b_a:gsub(dd,""))if(c_a==false)then self.filter=nil;return cd,dd end end;_b.header="Basalt Program Error ".._c;_b.error(dd)end +if coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)self.program.set("program",nil) +local __a=self.program.get("doneCallback")if __a then __a(self.program,cd,dd)end end else _b.header="Basalt Program Error ".._c +_b.error("File not found")end else _b.header="Basalt Program Error" +_b.error("Program ".._c.." not found")end end;function bb:resize(_c,ac)self.window.reposition(1,1,_c,ac) +self:resume("term_resize",_c,ac)end +function bb:resume(_c,...)local ac={...}if +(_c:find("mouse_"))then +ac[2],ac[3]=self.program:getRelativePosition(ac[2],ac[3])end;if self.coroutine==nil or +coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)return end +if +(self.filter~=nil)then if(_c~=self.filter)then return end;self.filter=nil end;local bc=term.current()term.redirect(self.window) +local cc,dc=coroutine.resume(self.coroutine,_c,table.unpack(ac))term.redirect(bc) +if cc then self.filter=dc +if +coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)self.program.set("program",nil) +local _d=self.program.get("doneCallback")if _d then _d(self.program,cc,dc)end end else local _d=self.program.get("doneCallback")if _d then +_d(self.program,cc,dc)end +local ad=self.program.get("errorCallback") +if ad then local bd=debug.traceback(self.coroutine,dc) +bd=bd==nil and""or bd;dc=dc or"Unknown error" +local cd=ad(self.program,dc,bd:gsub(dc,""))if(cd==false)then self.filter=nil;return cc,dc end end;_b.header="Basalt Program Error"_b.error(dc)end;return cc,dc end +function bb:stop()if self.coroutine==nil or +coroutine.status(self.coroutine)=="dead"then +self.program.set("running",false)return end +coroutine.close(self.coroutine)self.coroutine=nil end;function ab.new()local _c=setmetatable({},ab):__init() +_c.class=ab;_c.set("z",5)_c.set("width",30)_c.set("height",12) +return _c end +function ab:init(_c,ac) +da.init(self,_c,ac)self.set("type","Program") +self:observe("width",function(bc,cc) +local dc=bc.get("program") +if dc then dc:resize(cc,bc.get("height"))end end) +self:observe("height",function(bc,cc)local dc=bc.get("program")if dc then +dc:resize(bc.get("width"),cc)end end)return self end +function ab:execute(_c,ac,bc,...)self.set("path",_c)self.set("running",true) +local cc=bb.new(self,ac,bc)self.set("program",cc)cc:setArgs(...) +cc:run(_c,self.get("width"),self.get("height"),...)self:updateRender()return self end;function ab:stop()local _c=self.get("program")if _c then _c:stop() +self.set("running",false)self.set("program",nil)end +return self end;function ab:sendEvent(_c,...) +self:dispatchEvent(_c,...)return self end;function ab:onError(_c) +self.set("errorCallback",_c)return self end;function ab:onDone(_c) +self.set("doneCallback",_c)return self end +function ab:dispatchEvent(_c,...) +local ac=self.get("program")local bc=da.dispatchEvent(self,_c,...) +if ac then ac:resume(_c,...) +if +(self.get("focused"))then local cc=ac.window.getCursorBlink() +local dc,_d=ac.window.getCursorPos() +self:setCursor(dc,_d,cc,ac.window.getTextColor())end;self:updateRender()end;return bc end +function ab:focus() +if(da.focus(self))then local _c=self.get("program")if _c then +local ac=_c.window.getCursorBlink()local bc,cc=_c.window.getCursorPos() +self:setCursor(bc,cc,ac,_c.window.getTextColor())end end end +function ab:render()da.render(self)local _c=self.get("program") +if _c then +local ac,bc=_c.window.getSize()for y=1,bc do local cc,dc,_d=_c.window.getLine(y)if cc then +self:blit(1,y,cc,dc,_d)end end end end;return ab end +project["elements/Image.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("VisualElement")local da=require("libraries/colorHex") +local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"bimg",{default={{}},type="table",canTriggerRender=true}) +_b.defineProperty(_b,"currentFrame",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"autoResize",{default=false,type="boolean"}) +_b.defineProperty(_b,"offsetX",{default=0,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"offsetY",{default=0,type="number",canTriggerRender=true}) +_b.combineProperties(_b,"offset","offsetX","offsetY") +function _b.new()local cb=setmetatable({},_b):__init() +cb.class=_b;cb.set("width",12)cb.set("height",6) +cb.set("background",colors.black)cb.set("z",5)return cb end;function _b:init(cb,db)ca.init(self,cb,db)self.set("type","Image") +return self end +function _b:resizeImage(cb,db) +local _c=self.get("bimg") +for ac,bc in ipairs(_c)do local cc={} +for y=1,db do local dc=string.rep(" ",cb) +local _d=string.rep("f",cb)local ad=string.rep("0",cb) +if bc[y]and bc[y][1]then local bd=bc[y][1] +local cd=bc[y][2]local dd=bc[y][3] +dc=(bd..string.rep(" ",cb)):sub(1,cb) +_d=(cd..string.rep("f",cb)):sub(1,cb) +ad=(dd..string.rep("0",cb)):sub(1,cb)end;cc[y]={dc,_d,ad}end;_c[ac]=cc end;self:updateRender()return self end +function _b:getImageSize()local cb=self.get("bimg")if not cb[1]or not cb[1][1]then +return 0,0 end;return#cb[1][1][1],#cb[1]end +function _b:getPixelData(cb,db) +local _c=self.get("bimg")[self.get("currentFrame")]if not _c or not _c[db]then return end;local ac=_c[db][1] +local bc=_c[db][2]local cc=_c[db][3] +if not ac or not bc or not cc then return end;local dc=tonumber(bc:sub(cb,cb),16) +local _d=tonumber(cc:sub(cb,cb),16)local ad=ac:sub(cb,cb)return dc,_d,ad end +local function ab(cb,db) +local _c=cb.get("bimg")[cb.get("currentFrame")]if not _c then _c={} +cb.get("bimg")[cb.get("currentFrame")]=_c end +if not _c[db]then _c[db]={"","",""}end;return _c end +local function bb(cb,db,_c)if not cb.get("autoResize")then return end +local ac=cb.get("bimg")local bc=db;local cc=_c +for dc,_d in ipairs(ac)do for ad,bd in pairs(_d)do bc=math.max(bc,#bd[1]) +cc=math.max(cc,ad)end end +for dc,_d in ipairs(ac)do +for y=1,cc do if not _d[y]then _d[y]={"","",""}end;local ad=_d[y]while#ad[1]< +bc do ad[1]=ad[1].." "end;while#ad[2]dc then return self end end;local ac=ab(self,db)if self.get("autoResize")then +bb(self,cb+#_c-1,db)else local cc=#ac[db][1]if cb>cc then return self end +_c=_c:sub(1,cc-cb+1)end +local bc=ac[db][1] +ac[db][1]=bc:sub(1,cb-1).._c..bc:sub(cb+#_c)self:updateRender()return self end +function _b:getText(cb,db,_c)if not cb or not db then return""end +local ac=self.get("bimg")[self.get("currentFrame")]if not ac or not ac[db]then return""end;local bc=ac[db][1]if not bc then +return""end +if _c then return bc:sub(cb,cb+_c-1)else return bc:sub(cb,cb)end end +function _b:setFg(cb,db,_c)if +type(_c)~="string"or#_c<1 or cb<1 or db<1 then return self end +if +not self.get("autoResize")then local cc,dc=self:getImageSize()if db>dc then return self end end;local ac=ab(self,db)if self.get("autoResize")then +bb(self,cb+#_c-1,db)else local cc=#ac[db][2]if cb>cc then return self end +_c=_c:sub(1,cc-cb+1)end +local bc=ac[db][2] +ac[db][2]=bc:sub(1,cb-1).._c..bc:sub(cb+#_c)self:updateRender()return self end +function _b:getFg(cb,db,_c)if not cb or not db then return""end +local ac=self.get("bimg")[self.get("currentFrame")]if not ac or not ac[db]then return""end;local bc=ac[db][2]if not bc then +return""end +if _c then return bc:sub(cb,cb+_c-1)else return bc:sub(cb)end end +function _b:setBg(cb,db,_c)if +type(_c)~="string"or#_c<1 or cb<1 or db<1 then return self end +if +not self.get("autoResize")then local cc,dc=self:getImageSize()if db>dc then return self end end;local ac=ab(self,db)if self.get("autoResize")then +bb(self,cb+#_c-1,db)else local cc=#ac[db][3]if cb>cc then return self end +_c=_c:sub(1,cc-cb+1)end +local bc=ac[db][3] +ac[db][3]=bc:sub(1,cb-1).._c..bc:sub(cb+#_c)self:updateRender()return self end +function _b:getBg(cb,db,_c)if not cb or not db then return""end +local ac=self.get("bimg")[self.get("currentFrame")]if not ac or not ac[db]then return""end;local bc=ac[db][3]if not bc then +return""end +if _c then return bc:sub(cb,cb+_c-1)else return bc:sub(cb)end end +function _b:setPixel(cb,db,_c,ac,bc)if _c then self:setText(cb,db,_c)end;if ac then +self:setFg(cb,db,ac)end;if bc then self:setBg(cb,db,bc)end;return self end +function _b:nextFrame() +if not self.get("bimg").animation then return self end;local cb=self.get("bimg")local db=self.get("currentFrame") +local _c=db+1;if _c>#cb then _c=1 end;self.set("currentFrame",_c)return self end +function _b:addFrame()local cb=self.get("bimg") +local db=cb.width or#cb[1][1][1]local _c=cb.height or#cb[1]local ac={}local bc=string.rep(" ",db) +local cc=string.rep("f",db)local dc=string.rep("0",db)for y=1,_c do ac[y]={bc,cc,dc}end +table.insert(cb,ac)return self end;function _b:updateFrame(cb,db)local _c=self.get("bimg")_c[cb]=db +self:updateRender()return self end;function _b:getFrame(cb) +local db=self.get("bimg") +return db[cb or self.get("currentFrame")]end +function _b:getMetadata()local cb={} +local db=self.get("bimg") +for _c,ac in pairs(db)do if(type(ac)=="string")then cb[_c]=ac end end;return cb end +function _b:setMetadata(cb,db)if(type(cb)=="table")then +for ac,bc in pairs(cb)do self:setMetadata(ac,bc)end;return self end +local _c=self.get("bimg")if(type(db)=="string")then _c[cb]=db end;return self end +function _b:render()ca.render(self) +local cb=self.get("bimg")[self.get("currentFrame")]if not cb then return end;local db=self.get("offsetX") +local _c=self.get("offsetY")local ac=self.get("width")local bc=self.get("height") +for y=1,bc do local cc=y+_c +local dc=cb[cc] +if dc then local _d=dc[1]local ad=dc[2]local bd=dc[3] +if _d and ad and bd then +local cd=ac-math.max(0,db) +if cd>0 then if db<0 then local dd=math.abs(db)+1;_d=_d:sub(dd)ad=ad:sub(dd) +bd=bd:sub(dd)end;_d=_d:sub(1,cd) +ad=ad:sub(1,cd)bd=bd:sub(1,cd) +self:blit(math.max(1,1 +db),y,_d,ad,bd)end end end end end;return _b end +project["elements/BarChart.lua"] = function(...) local aa=require("elementManager") +local ba=aa.getElement("VisualElement")local ca=aa.getElement("Graph") +local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b;function _b.new() +local ab=setmetatable({},_b):__init()ab.class=_b;return ab end +function _b:init(ab,bb) +ca.init(self,ab,bb)self.set("type","BarChart")return self end +function _b:render()ba.render(self)local ab=self.get("width") +local bb=self.get("height")local cb=self.get("minValue")local db=self.get("maxValue") +local _c=self.get("series")local ac=0;local bc={} +for ad,bd in pairs(_c)do if(bd.visible)then if#bd.data>0 then ac=ac+1 +table.insert(bc,bd)end end end;local cc=ac;local dc=1 +local _d=math.min(bc[1]and bc[1].pointCount or 0,math.floor((ab+dc)/ ( +cc+dc))) +for groupIndex=1,_d do local ad=( (groupIndex-1)* (cc+dc))+1 +for bd,cd in ipairs(bc)do +local dd=cd.data[groupIndex] +if dd then local __a=ad+ (bd-1)local a_a=(dd-cb)/ (db-cb) +local b_a=math.floor(bb- (a_a* (bb-1)))b_a=math.max(1,math.min(b_a,bb))for barY=b_a,bb do +self:blit(__a,barY,cd.symbol,da[cd.fgColor],da[cd.bgColor])end end end end end;return _b end +project["elements/ComboBox.lua"] = function(...) local _a=require("elements/VisualElement") +local aa=require("elements/DropDown")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"editable",{default=true,type="boolean",canTriggerRender=true}) +ca.defineProperty(ca,"text",{default="",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"cursorPos",{default=1,type="number"}) +ca.defineProperty(ca,"viewOffset",{default=0,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"placeholder",{default="...",type="string"}) +ca.defineProperty(ca,"placeholderColor",{default=colors.gray,type="color"}) +ca.defineProperty(ca,"focusedBackground",{default=colors.blue,type="color"}) +ca.defineProperty(ca,"focusedForeground",{default=colors.white,type="color"}) +ca.defineProperty(ca,"autoComplete",{default=false,type="boolean"}) +ca.defineProperty(ca,"manuallyOpened",{default=false,type="boolean"})function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",16)da.set("height",1)da.set("z",8) +return da end +function ca:init(da,_b) +aa.init(self,da,_b)self.set("type","ComboBox") +self.set("cursorPos",1)self.set("viewOffset",0)return self end +function ca:setText(da)if da==nil then da=""end +self.set("text",tostring(da)) +self.set("cursorPos",#self.get("text")+1)self:updateViewport()return self end;function ca:getText()return self.get("text")end;function ca:setEditable(da) +self.set("editable",da)return self end +function ca:getFilteredItems() +local da=self.get("items")or{}local _b=self.get("text"):lower()if not +self.get("autoComplete")or#_b==0 then return da end +local ab={} +for bb,cb in ipairs(da)do local db="" +if type(cb)=="string"then db=cb:lower()elseif type(cb)=="table"and +cb.text then db=cb.text:lower()end;if db:find(_b,1,true)then table.insert(ab,cb)end end;return ab end +function ca:updateFilteredDropdown() +if not self.get("autoComplete")then return end;local da=self:getFilteredItems()local _b=#da>0 and +#self.get("text")>0 +if _b then self.set("isOpen",true) +self.set("manuallyOpened",false)local ab=self.get("dropdownHeight")or 5 +local bb=math.min(ab,#da)self.set("height",1 +bb)else self.set("isOpen",false) +self.set("manuallyOpened",false)self.set("height",1)end;self:updateRender()end +function ca:updateViewport()local da=self.get("text") +local _b=self.get("cursorPos")local ab=self.get("width")local bb=self.get("dropSymbol") +local cb=ab-#bb;if cb<1 then cb=1 end;local db=self.get("viewOffset")if _b-db>cb then db=_b-cb elseif +_b-1 1 then local cb=ab:sub(1,bb-2).. +ab:sub(bb)self.set("text",cb) +self.set("cursorPos",bb-1)self:updateViewport()if self.get("autoComplete")then +self:updateFilteredDropdown()else self:updateRender()end end elseif da==keys.delete then +if bb<=#ab then +local cb=ab:sub(1,bb-1)..ab:sub(bb+1)self.set("text",cb)self:updateViewport() +if +self.get("autoComplete")then self:updateFilteredDropdown()else self:updateRender()end end elseif da==keys.home then self.set("cursorPos",1) +self:updateViewport()elseif da==keys["end"]then self.set("cursorPos",#ab+1) +self:updateViewport()elseif da==keys.enter then +self.set("isOpen",not self.get("isOpen"))self:updateRender()end end +function ca:mouse_click(da,_b,ab) +if not _a.mouse_click(self,da,_b,ab)then return false end;local bb,cb=self:getRelativePosition(_b,ab) +local db=self.get("width")local _c=self.get("dropSymbol") +if cb==1 then +if +bb>=db-#_c+1 and bb<=db then local ac=self.get("isOpen")self.set("isOpen",not ac) +if +self.get("isOpen")then local bc=self.get("items")or{} +local cc=self.get("dropdownHeight")or 5;local dc=math.min(cc,#bc)self.set("height",1 +dc) +self.set("manuallyOpened",true)else self.set("height",1) +self.set("manuallyOpened",false)end;self:updateRender()return true end +if bb<=db-#_c and self.get("editable")then +local ac=self.get("text")local bc=self.get("viewOffset")local cc=#ac+1 +local dc=math.min(cc,bc+bb)self.set("cursorPos",dc)self:updateRender()return true end;return true elseif +self.get("isOpen")and cb>1 and self.get("selectable")then local ac=(cb-1)+self.get("offset") +local bc=self.get("items") +if ac<=#bc then local cc=bc[ac] +if type(cc)=="string"then cc={text=cc}bc[ac]=cc end +if not self.get("multiSelection")then for dc,_d in ipairs(bc)do if type(_d)=="table"then +_d.selected=false end end end;cc.selected=true;if cc.text then self:setText(cc.text)end +self.set("isOpen",false)self.set("height",1)self:updateRender()return true end end;return false end +function ca:render()_a.render(self)local da=self.get("text") +local _b=self.get("width")local ab=self.get("dropSymbol")local bb=self.get("focused") +local cb=self.get("isOpen")local db=self.get("viewOffset") +local _c=self.get("placeholder") +local ac=bb and self.get("focusedBackground")or self.get("background") +local bc=bb and self.get("focusedForeground")or self.get("foreground")local cc=da;local dc=_b-#ab;if#da==0 and not bb and#_c>0 then cc=_c +bc=self.get("placeholderColor")end +if#cc>0 then cc=cc:sub(db+1,db+dc)end;cc=cc..string.rep(" ",dc-#cc)local _d=cc.. +(cb and"\31"or"\17") +self:blit(1,1,_d,string.rep(ba[bc],_b),string.rep(ba[ac],_b)) +if bb and self.get("editable")then local ad=self.get("cursorPos") +local bd=ad-db;if bd>=1 and bd<=dc then +self:setCursor(bd,1,true,self.get("foreground"))end end +if cb then local ad +if +self.get("autoComplete")and not self.get("manuallyOpened")then ad=self:getFilteredItems()else ad=self.get("items")end +local bd=math.min(self.get("dropdownHeight"),#ad) +if bd>0 then local cd=self.get("offset") +for i=1,bd do local dd=i+cd +if ad[dd]then local __a=ad[dd] +local a_a=__a.text or""local b_a=__a.selected or false +local c_a= +b_a and self.get("selectedBackground")or self.get("background") +local d_a=b_a and self.get("selectedForeground")or self.get("foreground")if#a_a>_b then a_a=a_a:sub(1,_b)end;a_a=a_a.. +string.rep(" ",_b-#a_a) +self:blit(1,i+1,a_a,string.rep(ba[d_a],_b),string.rep(ba[c_a],_b))end end end end end;function ca:focus()aa.focus(self)end +function ca:blur()aa.blur(self) +self.set("isOpen",false)self.set("height",1)self:updateRender()end;return ca end +project["elements/TabControl.lua"] = function(...) local ba=require("elementManager") +local ca=require("elements/VisualElement")local da=ba.getElement("Container") +local _b=require("libraries/colorHex")local ab=require("log")local bb=setmetatable({},da)bb.__index=bb +bb.defineProperty(bb,"activeTab",{default= +nil,type="number",allowNil=true,canTriggerRender=true,setter=function(cb,db)return db end}) +bb.defineProperty(bb,"tabHeight",{default=1,type="number",canTriggerRender=true}) +bb.defineProperty(bb,"tabs",{default={},type="table"}) +bb.defineProperty(bb,"headerBackground",{default=colors.gray,type="color",canTriggerRender=true}) +bb.defineProperty(bb,"activeTabBackground",{default=colors.white,type="color",canTriggerRender=true}) +bb.defineProperty(bb,"activeTabTextColor",{default=colors.black,type="color",canTriggerRender=true})bb.defineEvent(bb,"tabChanged")function bb.new() +local cb=setmetatable({},bb):__init()cb.class=bb;cb.set("width",20)cb.set("height",10) +cb.set("z",10)return cb end +function bb:init(cb,db) +da.init(self,cb,db)self.set("type","TabControl")end +function bb:newTab(cb)local db=self.get("tabs")or{}local _c=#db+1 +table.insert(db,{id=_c,title=tostring( +cb or("Tab ".._c))})self.set("tabs",db)if not self.get("activeTab")then +self.set("activeTab",_c)end;self:updateTabVisibility() +local ac=self;local bc={} +setmetatable(bc,{__index=function(cc,dc) +if +type(dc)=="string"and dc:sub(1,3)=="add"and type(ac[dc])=="function"then +return +function(ad,...) +local bd=ac[dc](ac,...) +if bd then bd._tabId=_c;ac.set("childrenSorted",false) +ac.set("childrenEventsSorted",false)ac:updateRender()end;return bd end end;local _d=ac[dc]if type(_d)=="function"then +return function(ad,...)return _d(ac,...)end end;return _d end})return bc end +function bb:setTab(cb,db)cb._tabId=db;self:updateTabVisibility()return self end +function bb:addElement(cb,db)local _c=da.addElement(self,cb) +local ac=db or self.get("activeTab") +if ac then _c._tabId=ac;self:updateTabVisibility()end;return _c end +function bb:addChild(cb)da.addChild(self,cb)if not cb._tabId then +local db=self.get("tabs")or{} +if#db>0 then cb._tabId=1;self:updateTabVisibility()end end;return self end;function bb:updateTabVisibility()self.set("childrenSorted",false) +self.set("childrenEventsSorted",false)end +function bb:setActiveTab(cb) +local db=self.get("activeTab")if db==cb then return self end;self.set("activeTab",cb) +self:updateTabVisibility()self:dispatchEvent("tabChanged",cb,db)return self end +function bb:isChildVisible(cb) +if not da.isChildVisible(self,cb)then return false end +if cb._tabId then return cb._tabId==self.get("activeTab")end;return true end +function bb:getContentYOffset()local cb=self:_getHeaderMetrics()return cb.headerHeight end +function bb:_getHeaderMetrics()local cb=self.get("tabs")or{} +local db=self.get("width")or 1;local _c=self.get("tabHeight")or 1;local ac={}local bc=1;local cc=1 +for ad,bd in +ipairs(cb)do local cd=#bd.title+2;if cd>db then cd=db end +if cc+cd-1 >db then bc=bc+1;cc=1 end +table.insert(ac,{id=bd.id,title=bd.title,line=bc,x1=cc,x2=cc+cd-1,width=cd})cc=cc+cd end;local dc=bc;local _d=math.max(_c,dc) +return{headerHeight=_d,lines=dc,positions=ac}end +function bb:mouse_click(cb,db,_c) +if not ca.mouse_click(self,cb,db,_c)then return false end;local ac,bc=ca.getRelativePosition(self,db,_c) +local cc=self:_getHeaderMetrics() +if bc<=cc.headerHeight then if#cc.positions==0 then return true end +for dc,_d in +ipairs(cc.positions)do +if _d.line==bc and ac>=_d.x1 and ac<=_d.x2 then +self:setActiveTab(_d.id)self.set("focusedChild",nil)return true end end;return true end;return da.mouse_click(self,cb,db,_c)end +function bb:getRelativePosition(cb,db) +local _c=self:_getHeaderMetrics().headerHeight +if cb==nil or db==nil then return ca.getRelativePosition(self)else +local ac,bc=ca.getRelativePosition(self,cb,db)return ac,bc-_c end end +function bb:multiBlit(cb,db,_c,ac,bc,cc,dc)local _d=self:_getHeaderMetrics().headerHeight;return da.multiBlit(self,cb,( +db or 1)+_d,_c,ac,bc,cc,dc)end +function bb:textFg(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight;return da.textFg(self,cb,( +db or 1)+bc,_c,ac)end +function bb:textBg(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight;return da.textBg(self,cb,( +db or 1)+bc,_c,ac)end +function bb:drawText(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawText(self,cb,( +db or 1)+ac,_c)end +function bb:drawFg(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawFg(self,cb,( +db or 1)+ac,_c)end +function bb:drawBg(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawBg(self,cb,( +db or 1)+ac,_c)end +function bb:blit(cb,db,_c,ac,bc)local cc=self:_getHeaderMetrics().headerHeight;return da.blit(self,cb,( +db or 1)+cc,_c,ac,bc)end +function bb:mouse_up(cb,db,_c) +if not ca.mouse_up(self,cb,db,_c)then return false end;local ac,bc=ca.getRelativePosition(self,db,_c) +local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then return true end;return da.mouse_up(self,cb,db,_c)end +function bb:mouse_release(cb,db,_c)ca.mouse_release(self,cb,db,_c) +local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight +if bc<=cc then return end;return da.mouse_release(self,cb,db,_c)end +function bb:mouse_move(cb,db,_c) +if ca.mouse_move(self,cb,db,_c)then +local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then +return true end +local dc={self:getRelativePosition(db,_c)} +local _d,ad=self:callChildrenEvent(true,"mouse_move",table.unpack(dc))if _d then return true end end;return false end +function bb:mouse_drag(cb,db,_c) +if ca.mouse_drag(self,cb,db,_c)then +local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then +return true end;return da.mouse_drag(self,cb,db,_c)end;return false end +function bb:mouse_scroll(cb,db,_c) +if ca.mouse_scroll(self,cb,db,_c)then +local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then +return true end;return da.mouse_scroll(self,cb,db,_c)end;return false end +function bb:setCursor(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight +if +self.parent then local cc,dc=self:calculatePosition()local _d=cb+cc-1 +local ad=db+dc-1 +bc +if + +(_d<1)or(_d>self.parent.get("width"))or(ad<1)or(ad>self.parent.get("height"))then return self.parent:setCursor(_d,ad,false)end;return self.parent:setCursor(_d,ad,_c,ac)end;return self end +function bb:render()ca.render(self)local cb=self.get("width") +local db=self:_getHeaderMetrics()local _c=db.headerHeight or 1 +ca.multiBlit(self,1,1,cb,_c," ",_b[self.get("foreground")],_b[self.get("headerBackground")])local ac=self.get("activeTab") +for bc,cc in ipairs(db.positions)do +local dc=(cc.id==ac)and +self.get("activeTabBackground")or self.get("headerBackground")local _d=(cc.id==ac)and self.get("activeTabTextColor")or +self.get("foreground") +ca.multiBlit(self,cc.x1,cc.line,cc.width,1," ",_b[self.get("foreground")],_b[dc])ca.textFg(self,cc.x1 +1,cc.line,cc.title,_d)end +if not self.get("childrenSorted")then self:sortChildren()end +if not self.get("childrenEventsSorted")then for bc in pairs(self._values.childrenEvents or +{})do +self:sortChildrenEvents(bc)end end +for bc,cc in ipairs(self.get("visibleChildren")or{})do if cc==self then +error("CIRCULAR REFERENCE DETECTED!")return end;cc:render()cc:postRender()end end +function bb:sortChildrenEvents(cb) +local db=self._values.childrenEvents and self._values.childrenEvents[cb] +if db then local _c={}for ac,bc in ipairs(db)do +if self:isChildVisible(bc)then table.insert(_c,bc)end end +for i=2,#_c do local ac=_c[i] +local bc=ac.get("z")local cc=i-1 +while cc>0 do local dc=_c[cc].get("z")if dc>bc then _c[cc+1]=_c[cc] +cc=cc-1 else break end end;_c[cc+1]=ac end +self._values.visibleChildrenEvents=self._values.visibleChildrenEvents or{}self._values.visibleChildrenEvents[cb]=_c end;self.set("childrenEventsSorted",true)return self end;return bb end +project["elements/TextBox.lua"] = function(...) local a_a=require("elements/VisualElement") +local b_a=require("libraries/colorHex")local c_a=setmetatable({},a_a)c_a.__index=c_a +c_a.defineProperty(c_a,"lines",{default={""},type="table",canTriggerRender=true}) +c_a.defineProperty(c_a,"cursorX",{default=1,type="number"}) +c_a.defineProperty(c_a,"cursorY",{default=1,type="number"}) +c_a.defineProperty(c_a,"scrollX",{default=0,type="number",canTriggerRender=true}) +c_a.defineProperty(c_a,"scrollY",{default=0,type="number",canTriggerRender=true}) +c_a.defineProperty(c_a,"editable",{default=true,type="boolean"}) +c_a.defineProperty(c_a,"syntaxPatterns",{default={},type="table"}) +c_a.defineProperty(c_a,"cursorColor",{default=nil,type="color"}) +c_a.defineProperty(c_a,"autoCompleteEnabled",{default=false,type="boolean"}) +c_a.defineProperty(c_a,"autoCompleteItems",{default={},type="table"}) +c_a.defineProperty(c_a,"autoCompleteProvider",{default=nil,type="function",allowNil=true}) +c_a.defineProperty(c_a,"autoCompleteMinChars",{default=1,type="number"}) +c_a.defineProperty(c_a,"autoCompleteMaxItems",{default=6,type="number"}) +c_a.defineProperty(c_a,"autoCompleteCaseInsensitive",{default=true,type="boolean"}) +c_a.defineProperty(c_a,"autoCompleteTokenPattern",{default="[%w_]+",type="string"}) +c_a.defineProperty(c_a,"autoCompleteOffsetX",{default=0,type="number"}) +c_a.defineProperty(c_a,"autoCompleteOffsetY",{default=1,type="number"}) +c_a.defineProperty(c_a,"autoCompleteZOffset",{default=1,type="number"}) +c_a.defineProperty(c_a,"autoCompleteMaxWidth",{default=0,type="number"}) +c_a.defineProperty(c_a,"autoCompleteShowBorder",{default=true,type="boolean"}) +c_a.defineProperty(c_a,"autoCompleteBorderColor",{default=colors.black,type="color"}) +c_a.defineProperty(c_a,"autoCompleteBackground",{default=colors.lightGray,type="color"}) +c_a.defineProperty(c_a,"autoCompleteForeground",{default=colors.black,type="color"}) +c_a.defineProperty(c_a,"autoCompleteSelectedBackground",{default=colors.gray,type="color"}) +c_a.defineProperty(c_a,"autoCompleteSelectedForeground",{default=colors.white,type="color"}) +c_a.defineProperty(c_a,"autoCompleteAcceptOnEnter",{default=true,type="boolean"}) +c_a.defineProperty(c_a,"autoCompleteAcceptOnClick",{default=true,type="boolean"}) +c_a.defineProperty(c_a,"autoCompleteCloseOnEscape",{default=true,type="boolean"})c_a.defineEvent(c_a,"mouse_click") +c_a.defineEvent(c_a,"key")c_a.defineEvent(c_a,"char") +c_a.defineEvent(c_a,"mouse_scroll")c_a.defineEvent(c_a,"paste") +c_a.defineEvent(c_a,"auto_complete_open")c_a.defineEvent(c_a,"auto_complete_close") +c_a.defineEvent(c_a,"auto_complete_accept")local d_a;local _aa;local function aaa(a_b)local b_b=a_b._autoCompleteFrame +return +b_b and not b_b._destroyed and b_b.get and b_b.get("visible")end +local function baa(a_b)return +a_b.get("autoCompleteShowBorder")and 1 or 0 end +local function caa(a_b)local b_b=a_b._autoCompleteFrame;local c_b=a_b._autoCompleteList;if +not b_b or b_b._destroyed then return end +b_b:setBackground(a_b.get("autoCompleteBackground")) +b_b:setForeground(a_b.get("autoCompleteForeground")) +if c_b and not c_b._destroyed then +c_b:setBackground(a_b.get("autoCompleteBackground")) +c_b:setForeground(a_b.get("autoCompleteForeground")) +c_b:setSelectedBackground(a_b.get("autoCompleteSelectedBackground")) +c_b:setSelectedForeground(a_b.get("autoCompleteSelectedForeground"))c_b:updateRender()end;_aa(a_b)d_a(a_b)b_b:updateRender()end +local function daa(a_b,b_b,c_b)local d_b=a_b._autoCompleteList +if not d_b or d_b._destroyed then return end;local _ab=d_b.get("items")local aab=#_ab;if aab==0 then return end +if b_b<1 then b_b=1 end;if b_b>aab then b_b=aab end;a_b._autoCompleteIndex=b_b +for dab,_bb in ipairs(_ab)do if +type(_bb)=="table"then _bb.selected=(dab==b_b)end end;local bab=d_b.get("height")or 0 +local cab=d_b.get("offset")or 0;if not c_b and bab>0 then +if b_b>cab+bab then +d_b:setOffset(math.max(0,b_b-bab))elseif b_b<=cab then d_b:setOffset(math.max(0,b_b-1))end end +d_b:updateRender()end +local function _ba(a_b,b_b)if aaa(a_b)then +a_b._autoCompleteFrame:setVisible(false) +if not b_b then a_b:fireEvent("auto_complete_close")end end +a_b._autoCompleteIndex=nil;a_b._autoCompleteSuggestions=nil;a_b._autoCompleteToken=nil +a_b._autoCompleteTokenStart=nil;a_b._autoCompletePopupWidth=nil end +local function aba(a_b,b_b)local c_b=a_b._autoCompleteSuggestions or{} +local d_b=a_b._autoCompleteIndex or 1;local _ab=b_b or c_b[d_b]if not _ab then return end +local aab=_ab.insert or _ab.text or""if aab==""then return end;local bab=a_b.get("lines") +local cab=a_b.get("cursorY")local dab=a_b.get("cursorX")local _bb=bab[cab]or"" +local abb=a_b._autoCompleteTokenStart or dab;if abb<1 then abb=1 end;local bbb=_bb:sub(1,abb-1)local cbb=_bb:sub(dab)bab[cab]= +bbb..aab..cbb;a_b.set("cursorX",abb+#aab) +a_b:updateViewport()a_b:updateRender()_ba(a_b,true) +a_b:fireEvent("auto_complete_accept",aab,_ab.source or _ab)end +local function bba(a_b) +if not a_b.get("autoCompleteEnabled")then return nil end;local b_b=a_b._autoCompleteFrame;if b_b and not b_b._destroyed then +return a_b._autoCompleteList end;local c_b=a_b:getBaseFrame()if not c_b or not +c_b.addFrame then return nil end +b_b=c_b:addFrame({width=a_b.get("width"),height=1,x=1,y=1,visible=false,background=a_b.get("autoCompleteBackground"),foreground=a_b.get("autoCompleteForeground"),ignoreOffset=true,z= +a_b.get("z")+a_b.get("autoCompleteZOffset")})b_b:setIgnoreOffset(true)b_b:setVisible(false) +local d_b=baa(a_b) +local _ab=b_b:addList({x=d_b+1,y=d_b+1,width=math.max(1,b_b.get("width")-d_b*2),height=math.max(1, +b_b.get("height")-d_b*2),selectable=true,multiSelection=false,background=a_b.get("autoCompleteBackground"),foreground=a_b.get("autoCompleteForeground")}) +_ab:setSelectedBackground(a_b.get("autoCompleteSelectedBackground")) +_ab:setSelectedForeground(a_b.get("autoCompleteSelectedForeground"))_ab:setOffset(0) +_ab:onSelect(function(aab,bab,cab)if not aaa(a_b)then return end +daa(a_b,bab) +if a_b.get("autoCompleteAcceptOnClick")then aba(a_b,cab)end end)a_b._autoCompleteFrame=b_b;a_b._autoCompleteList=_ab;caa(a_b)return _ab end +_aa=function(a_b,b_b,c_b)local d_b=a_b._autoCompleteFrame;local _ab=a_b._autoCompleteList +if +not d_b or d_b._destroyed or not _ab or _ab._destroyed then return end;local aab=baa(a_b) +local bab= +tonumber(b_b)or rawget(a_b,"_autoCompletePopupWidth")or _ab.get("width")or d_b.get("width") +local cab=tonumber(c_b)or(_ab.get and _ab.get("height"))or(# ( +rawget(a_b,"_autoCompleteSuggestions")or{}))bab=math.max(1,bab or 1)cab=math.max(1,cab or 1)local dab= +d_b.get and d_b.get("width")or bab;local _bb= +d_b.get and d_b.get("height")or cab;local abb=math.max(1, +dab-aab*2) +local bbb=math.max(1,_bb-aab*2)if bab>abb then bab=abb end;if cab>bbb then cab=bbb end +_ab:setPosition(aab+1,aab+1)_ab:setWidth(math.max(1,bab)) +_ab:setHeight(math.max(1,cab))end +d_a=function(a_b)local b_b=a_b._autoCompleteFrame +if not b_b or b_b._destroyed then return end;local c_b=b_b.get and b_b.get("canvas") +if not c_b then return end;c_b:setType("post") +if b_b._autoCompleteBorderCommand then +c_b:removeCommand(b_b._autoCompleteBorderCommand)b_b._autoCompleteBorderCommand=nil end;if not a_b.get("autoCompleteShowBorder")then +b_b:updateRender()return end;local d_b=a_b.get("autoCompleteBorderColor")or +colors.black +local _ab=c_b:addCommand(function(aab)local bab= +aab.get("width")or 0;local cab=aab.get("height")or 0;if bab<1 or +cab<1 then return end +local dab=aab.get("background")or colors.black;local _bb=b_a[dab]or b_a[colors.black]local abb=b_a[d_b]or +b_a[colors.black] +aab:textFg(1,1,("\131"):rep(bab),d_b)aab:multiBlit(1,cab,bab,1,"\143",_bb,abb) +aab:multiBlit(1,1,1,cab,"\149",abb,_bb)aab:multiBlit(bab,1,1,cab,"\149",_bb,abb) +aab:blit(1,1,"\151",abb,_bb)aab:blit(bab,1,"\148",_bb,abb) +aab:blit(1,cab,"\138",_bb,abb)aab:blit(bab,cab,"\133",_bb,abb)end)b_b._autoCompleteBorderCommand=_ab;b_b:updateRender()end +local function cba(a_b)local b_b=a_b.get("lines")local c_b=a_b.get("cursorY") +local d_b=a_b.get("cursorX")local _ab=b_b[c_b]or"" +local aab=_ab:sub(1,math.max(d_b-1,0)) +local bab=a_b.get("autoCompleteTokenPattern")or"[%w_]+"local cab=""if bab~=""then +cab=aab:match("("..bab..")$")or""end;local dab=d_b-#cab;if dab<1 then dab=1 end;return cab,dab end +local function dba(a_b) +if type(a_b)=="string"then return{text=a_b,insert=a_b,source=a_b}elseif +type(a_b)=="table"then local b_b= +a_b.text or a_b.label or a_b.value or a_b.insert or a_b[1]if not b_b then return +nil end +local c_b={text=b_b,insert=a_b.insert or a_b.value or b_b,source=a_b}if a_b.foreground then c_b.foreground=a_b.foreground end;if +a_b.background then c_b.background=a_b.background end;if a_b.selectedForeground then +c_b.selectedForeground=a_b.selectedForeground end;if a_b.selectedBackground then +c_b.selectedBackground=a_b.selectedBackground end +if a_b.icon then c_b.icon=a_b.icon end;if a_b.info then c_b.info=a_b.info end;return c_b end end +local function _ca(a_b,b_b)if type(a_b)~="table"then return end;local c_b=#a_b +if c_b>0 then for index=1,c_b do +b_b(a_b[index])end else for d_b,_ab in pairs(a_b)do b_b(_ab)end end end +local function aca(a_b,b_b)local c_b=a_b.get("autoCompleteProvider")local d_b={} +if c_b then +local dab,_bb=pcall(c_b,a_b,b_b)if dab and type(_bb)=="table"then d_b=_bb end else d_b= +a_b.get("autoCompleteItems")or{}end;local _ab={}local aab=a_b.get("autoCompleteCaseInsensitive")local bab=aab and +b_b:lower()or b_b +_ca(d_b,function(dab)local _bb=dba(dab) +if _bb and _bb.text then +local abb= +aab and _bb.text:lower()or _bb.text;if bab==""or abb:find(bab,1,true)==1 then +table.insert(_ab,_bb)end end end)local cab=a_b.get("autoCompleteMaxItems")if#_ab>cab then while#_ab>cab do +table.remove(_ab)end end;return _ab end +local function bca(a_b,b_b)local c_b=0 +for cab,dab in ipairs(b_b)do local _bb=dab;if type(dab)=="table"then +_bb= +dab.text or dab.label or dab.value or dab.insert or dab[1]end;if _bb~=nil then +local abb=#tostring(_bb)if abb>c_b then c_b=abb end end end;local d_b=a_b.get("autoCompleteMaxWidth") +local _ab=a_b.get("width")if d_b and d_b>0 then _ab=math.min(_ab,d_b)end +local aab=baa(a_b)local bab=a_b:getBaseFrame() +if bab and bab.get then +local cab=bab.get("width")if cab and cab>0 then local dab=cab-aab*2;if dab<1 then dab=1 end +_ab=math.min(_ab,dab)end end;c_b=math.min(c_b,_ab)return math.max(1,c_b)end +local function cca(a_b,b_b,c_b)local d_b=a_b._autoCompleteFrame;local _ab=a_b._autoCompleteList;if +not d_b or d_b._destroyed then return end;local aab=baa(a_b) +local bab=math.max(1,c_b or a_b.get("width"))local cab=math.max(1,b_b or 1)local dab=a_b:getBaseFrame()if not dab then +return end;local _bb=dab.get and dab.get("width")local abb=dab.get and +dab.get("height") +if _bb and _bb>0 then local _ac=_bb-aab*2;if _ac<1 then +_ac=1 end;if bab>_ac then bab=_ac end end;if abb and abb>0 then local _ac=abb-aab*2;if _ac<1 then _ac=1 end +if cab>_ac then cab=_ac end end;local bbb=bab+aab*2 +local cbb=cab+aab*2;local dbb,_cb=a_b:calculatePosition() +local acb=a_b.get("scrollX")or 0;local bcb=a_b.get("scrollY")or 0;local ccb=(a_b._autoCompleteTokenStart or +a_b.get("cursorX"))local dcb=ccb-acb +dcb=math.max(1,math.min(a_b.get("width"),dcb))local _db=a_b.get("cursorY")-bcb +_db=math.max(1,math.min(a_b.get("height"),_db))local adb=a_b.get("autoCompleteOffsetX") +local bdb=a_b.get("autoCompleteOffsetY")local cdb=dbb+dcb-1 +adb;local ddb=cdb-aab +if aab>0 then ddb=ddb+1 end;local __c=_cb+_db+bdb;local a_c=_cb+_db-bdb-1;local b_c=__c-aab;local c_c= +a_c-cab+1 -aab;local d_c=b_c +if _bb and _bb>0 then if bbb>_bb then bbb=_bb +bab=math.max(1,bbb-aab*2)end;if ddb+bbb-1 >_bb then +ddb=math.max(1,_bb-bbb+1)end;if ddb<1 then ddb=1 end else if ddb<1 then ddb=1 end end +if abb and abb>0 then if d_c+cbb-1 >abb then d_c=c_c;if d_c<1 then +d_c=math.max(1,abb-cbb+1)end end +if d_c<1 then d_c=1 end else if d_c<1 then d_c=1 end end;d_b:setPosition(ddb,d_c)d_b:setWidth(bbb) +d_b:setHeight(cbb) +d_b:setZ(a_b.get("z")+a_b.get("autoCompleteZOffset"))_aa(a_b,bab,cab)if _ab and not _ab._destroyed then +_ab:updateRender()end;d_b:updateRender()end +local function dca(a_b) +if not a_b.get("autoCompleteEnabled")then _ba(a_b,true)return end +if not a_b.get("focused")then _ba(a_b,true)return end;local b_b,c_b=cba(a_b)a_b._autoCompleteToken=b_b +a_b._autoCompleteTokenStart=c_b +if#b_b=1 and _bb<=bab then +daa(a_b,_bb)else c_b:updateRender()end;return true end +function c_a.new()local a_b=setmetatable({},c_a):__init() +a_b.class=c_a;a_b.set("width",20)a_b.set("height",10)return a_b end +function c_a:init(a_b,b_b)a_a.init(self,a_b,b_b) +self.set("type","TextBox") +local function c_b()if +self.get("autoCompleteEnabled")and self.get("focused")then dca(self)end end;local function d_b()caa(self)end +local function _ab() +if aaa(self)then +local aab=rawget(self,"_autoCompleteSuggestions")or{} +cca(self,math.max(#aab,1),rawget(self,"_autoCompletePopupWidth")or +self.get("width"))end end +self:observe("autoCompleteEnabled",function(aab,bab)if not bab then _ba(self,true)elseif self.get("focused")then +dca(self)end end) +self:observe("focused",function(aab,bab)if bab then c_b()else _ba(self,true)end end)self:observe("foreground",d_b) +self:observe("background",d_b)self:observe("autoCompleteBackground",d_b) +self:observe("autoCompleteForeground",d_b) +self:observe("autoCompleteSelectedBackground",d_b) +self:observe("autoCompleteSelectedForeground",d_b)self:observe("autoCompleteBorderColor",d_b) +self:observe("autoCompleteZOffset",function() +if + +self._autoCompleteFrame and not self._autoCompleteFrame._destroyed then +self._autoCompleteFrame:setZ(self.get("z")+self.get("autoCompleteZOffset"))end end) +self:observe("z",function() +if +self._autoCompleteFrame and not self._autoCompleteFrame._destroyed then +self._autoCompleteFrame:setZ(self.get("z")+self.get("autoCompleteZOffset"))end end) +self:observe("autoCompleteShowBorder",function()d_b()_ab()end) +for aab,bab in +ipairs({"autoCompleteItems","autoCompleteProvider","autoCompleteMinChars","autoCompleteMaxItems","autoCompleteCaseInsensitive","autoCompleteTokenPattern","autoCompleteOffsetX","autoCompleteOffsetY"})do self:observe(bab,c_b)end;self:observe("x",_ab)self:observe("y",_ab)self:observe("width",function() +_ab()c_b()end) +self:observe("height",_ab)self:observe("cursorX",_ab) +self:observe("cursorY",_ab)self:observe("scrollX",_ab) +self:observe("scrollY",_ab)self:observe("autoCompleteOffsetX",_ab) +self:observe("autoCompleteOffsetY",_ab) +self:observe("autoCompleteMaxWidth",function() +if aaa(self)then +local aab=rawget(self,"_autoCompleteSuggestions")or{}if#aab>0 then local bab=bca(self,aab)self._autoCompletePopupWidth=bab +cca(self,math.max(#aab,1),bab)end end end)return self end;function c_a:addSyntaxPattern(a_b,b_b) +table.insert(self.get("syntaxPatterns"),{pattern=a_b,color=b_b})return self end +function c_a:removeSyntaxPattern(a_b)local b_b= +self.get("syntaxPatterns")or{} +if type(a_b)~="number"then return self end +if a_b>=1 and a_b<=#b_b then table.remove(b_b,a_b) +self.set("syntaxPatterns",b_b)self:updateRender()end;return self end;function c_a:clearSyntaxPatterns()self.set("syntaxPatterns",{}) +self:updateRender()return self end +local function bda(a_b,b_b) +local c_b=a_b.get("lines")local d_b=a_b.get("cursorX")local _ab=a_b.get("cursorY") +local aab=c_b[_ab] +c_b[_ab]=aab:sub(1,d_b-1)..b_b..aab:sub(d_b)a_b.set("cursorX",d_b+1)a_b:updateViewport() +a_b:updateRender()end +local function cda(a_b)local b_b=a_b.get("lines")local c_b=a_b.get("cursorX") +local d_b=a_b.get("cursorY")local _ab=b_b[d_b]local aab=_ab:sub(c_b) +b_b[d_b]=_ab:sub(1,c_b-1)table.insert(b_b,d_b+1,aab)a_b.set("cursorX",1)a_b.set("cursorY", +d_b+1)a_b:updateViewport() +a_b:updateRender()end +local function dda(a_b)local b_b=a_b.get("lines")local c_b=a_b.get("cursorX") +local d_b=a_b.get("cursorY")local _ab=b_b[d_b] +if c_b>1 then +b_b[d_b]=_ab:sub(1,c_b-2).._ab:sub(c_b)a_b.set("cursorX",c_b-1)elseif d_b>1 then local aab=b_b[d_b-1]a_b.set("cursorX", +#aab+1)a_b.set("cursorY",d_b-1)b_b[d_b-1]= +aab.._ab;table.remove(b_b,d_b)end;a_b:updateViewport()a_b:updateRender()end +function c_a:updateViewport()local a_b=self.get("cursorX") +local b_b=self.get("cursorY")local c_b=self.get("scrollX")local d_b=self.get("scrollY") +local _ab=self.get("width")local aab=self.get("height") +if a_b-c_b>_ab then +self.set("scrollX",a_b-_ab)elseif a_b-c_b<1 then self.set("scrollX",a_b-1)end +if b_b-d_b>aab then self.set("scrollY",b_b-aab)elseif b_b-d_b<1 then self.set("scrollY", +b_b-1)end;return self end;function c_a:char(a_b)if +not self.get("editable")or not self.get("focused")then return false end;bda(self,a_b) +dca(self)return true end +function c_a:key(a_b)if + +not self.get("editable")or not self.get("focused")then return false end +if _da(self,a_b)then return true end;local b_b=self.get("lines")local c_b=self.get("cursorX") +local d_b=self.get("cursorY") +if a_b==keys.enter then cda(self)elseif a_b==keys.backspace then dda(self)elseif +a_b==keys.left then +if c_b>1 then self.set("cursorX",c_b-1)elseif d_b>1 then +self.set("cursorY",d_b-1)self.set("cursorX",#b_b[d_b-1]+1)end elseif a_b==keys.right then if c_b<=#b_b[d_b]then +self.set("cursorX",c_b+1)elseif d_b<#b_b then self.set("cursorY",d_b+1) +self.set("cursorX",1)end elseif a_b==keys.up and +d_b>1 then self.set("cursorY",d_b-1) +self.set("cursorX",math.min(c_b,# +b_b[d_b-1]+1))elseif a_b==keys.down and d_b<#b_b then +self.set("cursorY",d_b+1) +self.set("cursorX",math.min(c_b,#b_b[d_b+1]+1))end;self:updateRender()self:updateViewport()dca(self)return +true end +function c_a:mouse_scroll(a_b,b_b,c_b)if ada(self,a_b)then return true end +if self:isInBounds(b_b,c_b)then +local d_b=self.get("scrollY")local _ab=self.get("height")local aab=self.get("lines")local bab=math.max(0,#aab- +_ab+2) +local cab=math.max(0,math.min(bab,d_b+a_b))self.set("scrollY",cab)self:updateRender()return true end;return false end +function c_a:mouse_click(a_b,b_b,c_b) +if a_a.mouse_click(self,a_b,b_b,c_b)then +local d_b,_ab=self:getRelativePosition(b_b,c_b)local aab=self.get("scrollX")local bab=self.get("scrollY")local cab= +(_ab or 0)+ (bab or 0) +local dab=self.get("lines")or{}if cab<1 then cab=1 end +if cab<=#dab and dab[cab]~=nil then +self.set("cursorY",cab)local _bb=#tostring(dab[cab]) +self.set("cursorX",math.min((d_b or 1)+ (aab or 0), +_bb+1))end;self:updateRender()dca(self)return true end +if aaa(self)then local d_b=self._autoCompleteFrame;if +not +(d_b and d_b:isInBounds(b_b,c_b))and not self:isInBounds(b_b,c_b)then _ba(self)end end;return false end +function c_a:paste(a_b)if +not self.get("editable")or not self.get("focused")then return false end +for b_b in a_b:gmatch(".")do if b_b=="\n"then +cda(self)else bda(self,b_b)end end;dca(self)return true end +function c_a:setText(a_b)local b_b={} +if a_b==""then b_b={""}else for c_b in(a_b.."\n"):gmatch("([^\n]*)\n")do +table.insert(b_b,c_b)end end;self.set("lines",b_b)_ba(self,true)return self end +function c_a:getText()return table.concat(self.get("lines"),"\n")end +local function __b(a_b,b_b)local c_b=b_b +local d_b=string.rep(b_a[a_b.get("foreground")],#c_b)local _ab=a_b.get("syntaxPatterns") +for aab,bab in ipairs(_ab)do local cab=1 +while true do +local dab,_bb=c_b:find(bab.pattern,cab)if not dab then break end;local abb=_bb-dab+1 +if abb<=0 then +d_b=d_b:sub(1,dab-1).. +string.rep(b_a[bab.color],1)..d_b:sub(dab+1)cab=dab+1 else +d_b=d_b:sub(1,dab-1)..string.rep(b_a[bab.color],abb)..d_b:sub( +_bb+1)cab=_bb+1 end end end;return c_b,d_b end +function c_a:render()a_a.render(self)local a_b=self.get("lines") +local b_b=self.get("scrollX")local c_b=self.get("scrollY")local d_b=self.get("width") +local _ab=self.get("height")local aab=b_a[self.get("foreground")] +local bab=b_a[self.get("background")] +for y=1,_ab do local cab=y+c_b;local dab=a_b[cab]or""local _bb,abb=__b(self,dab)local bbb=_bb:sub(b_b+1,b_b+ +d_b)local cbb=abb:sub(b_b+1,b_b+d_b)local dbb= +d_b-#bbb +if dbb>0 then bbb=bbb..string.rep(" ",dbb)cbb=cbb.. +string.rep(b_a[self.get("foreground")],dbb)end +self:blit(1,y,bbb,cbb,string.rep(bab,#bbb))end +if self.get("focused")then local cab=self.get("cursorX")-b_b;local dab= +self.get("cursorY")-c_b;if cab>=1 and cab<=d_b and dab>=1 and +dab<=_ab then +self:setCursor(cab,dab,true,self.get("cursorColor")or +self.get("foreground"))end end end +function c_a:destroy() +if +self._autoCompleteFrame and not self._autoCompleteFrame._destroyed then self._autoCompleteFrame:destroy()end;self._autoCompleteFrame=nil;self._autoCompleteList=nil +self._autoCompletePopupWidth=nil;a_a.destroy(self)end;return c_a end +project["elements/Button.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement") +local ba=require("libraries/utils").getCenteredPosition;local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"text",{default="Button",type="string",canTriggerRender=true})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_up")function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",10)da.set("height",3)da.set("z",5) +return da end;function ca:init(da,_b) +aa.init(self,da,_b)self.set("type","Button")end +function ca:render() +aa.render(self)local da=self.get("text") +da=da:sub(1,self.get("width")) +local _b,ab=ba(da,self.get("width"),self.get("height")) +self:textFg(_b,ab,da,self.get("foreground"))end;return ca end +project["elements/Label.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/utils").wrapText +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"text",{default="Label",type="string",canTriggerRender=true,setter=function(da,_b) +if(type(_b)=="function")then _b=_b()end +if(da.get("autoSize"))then da.set("width",#_b)else da.set("height",# +ba(_b,da.get("width")))end;return _b end}) +ca.defineProperty(ca,"autoSize",{default=true,type="boolean",canTriggerRender=true,setter=function(da,_b)if(_b)then +da.set("width",#da.get("text"))else +da.set("height",#ba(da.get("text"),da.get("width")))end;return _b end}) +function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("z",3)da.set("foreground",colors.black) +da.set("backgroundEnabled",false)return da end +function ca:init(da,_b)aa.init(self,da,_b)if(self.parent)then +self.set("background",self.parent.get("background")) +self.set("foreground",self.parent.get("foreground"))end +self.set("type","Label")return self end;function ca:getWrappedText()local da=self.get("text") +local _b=ba(da,self.get("width"))return _b end +function ca:render() +aa.render(self)local da=self.get("text") +if(self.get("autoSize"))then +self:textFg(1,1,da,self.get("foreground"))else local _b=ba(da,self.get("width"))for ab,bb in ipairs(_b)do +self:textFg(1,ab,bb,self.get("foreground"))end end end;return ca end +project["elements/Input.lua"] = function(...) local d=require("elements/VisualElement") +local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa +aa.defineProperty(aa,"text",{default="",type="string",canTriggerRender=true}) +aa.defineProperty(aa,"cursorPos",{default=1,type="number"}) +aa.defineProperty(aa,"viewOffset",{default=0,type="number",canTriggerRender=true}) +aa.defineProperty(aa,"maxLength",{default=nil,type="number"}) +aa.defineProperty(aa,"placeholder",{default="...",type="string"}) +aa.defineProperty(aa,"placeholderColor",{default=colors.gray,type="color"}) +aa.defineProperty(aa,"focusedBackground",{default=colors.blue,type="color"}) +aa.defineProperty(aa,"focusedForeground",{default=colors.white,type="color"}) +aa.defineProperty(aa,"pattern",{default=nil,type="string"}) +aa.defineProperty(aa,"cursorColor",{default=nil,type="number"}) +aa.defineProperty(aa,"replaceChar",{default=nil,type="string",canTriggerRender=true})aa.defineEvent(aa,"mouse_click") +aa.defineEvent(aa,"key")aa.defineEvent(aa,"char") +aa.defineEvent(aa,"paste") +function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;ba.set("width",8)ba.set("z",3)return ba end +function aa:init(ba,ca)d.init(self,ba,ca)self.set("type","Input")return self end +function aa:setCursor(ba,ca,da,_b) +ba=math.min(self.get("width"),math.max(1,ba))return d.setCursor(self,ba,ca,da,_b)end +function aa:char(ba)if not self.get("focused")then return false end +local ca=self.get("text")local da=self.get("cursorPos")local _b=self.get("maxLength") +local ab=self.get("pattern")if _b and#ca>=_b then return false end;if ab and not ba:match(ab)then return +false end +self.set("text",ca:sub(1,da-1)..ba..ca:sub(da))self.set("cursorPos",da+1)self:updateViewport()local bb= +self.get("cursorPos")-self.get("viewOffset") +self:setCursor(bb,1,true, +self.get("cursorColor")or self.get("foreground"))d.char(self,ba)return true end +function aa:key(ba,ca)if not self.get("focused")then return false end +local da=self.get("cursorPos")local _b=self.get("text")local ab=self.get("viewOffset") +local bb=self.get("width") +if ba==keys.left then if da>1 then self.set("cursorPos",da-1) +if da-1 <=ab then self.set("viewOffset",math.max(0, +da-2))end end elseif ba==keys.right then if da<=#_b then self.set("cursorPos", +da+1)if da-ab>=bb then +self.set("viewOffset",da-bb+1)end end elseif +ba==keys.backspace then if da>1 then +self.set("text",_b:sub(1,da-2).._b:sub(da))self.set("cursorPos",da-1)self:updateRender() +self:updateViewport()end end +local cb=self.get("cursorPos")-self.get("viewOffset") +self:setCursor(cb,1,true,self.get("cursorColor")or self.get("foreground"))d.key(self,ba,ca)return true end +function aa:mouse_click(ba,ca,da) +if d.mouse_click(self,ba,ca,da)then +local _b,ab=self:getRelativePosition(ca,da)local bb=self.get("text")local cb=self.get("viewOffset") +local db=#bb+1;local _c=math.min(db,cb+_b)self.set("cursorPos",_c) +local ac=_c-cb +self:setCursor(ac,1,true,self.get("cursorColor")or self.get("foreground"))return true end;return false end +function aa:updateViewport()local ba=self.get("width") +local ca=self.get("cursorPos")local da=self.get("viewOffset") +local _b=#self.get("text") +if ca-da>=ba then self.set("viewOffset",ca-ba+1)elseif ca<=da then self.set("viewOffset", +ca-1)end +self.set("viewOffset",math.max(0,math.min(self.get("viewOffset"),_b-ba+1)))return self end +function aa:focus()d.focus(self) +self:setCursor(self.get("cursorPos")- +self.get("viewOffset"),1,true,self.get("cursorColor")or self.get("foreground"))self:updateRender()end +function aa:blur()d.blur(self) +self:setCursor(1,1,false,self.get("cursorColor")or +self.get("foreground"))self:updateRender()end +function aa:paste(ba)if not self.get("focused")then return false end +local ca=self.get("text")local da=self.get("cursorPos")local _b=self.get("maxLength") +local ab=self.get("pattern")local bb=ca:sub(1,da-1)..ba..ca:sub(da)if +_b and#bb>_b then bb=bb:sub(1,_b)end;if ab and not bb:match(ab)then +return false end;self.set("text",bb) +self.set("cursorPos",da+#ba)self:updateViewport()end +function aa:render()local ba=self.get("text")local ca=self.get("viewOffset") +local da=self.get("width")local _b=self.get("placeholder") +local ab=self.get("focusedBackground")local bb=self.get("focusedForeground") +local cb=self.get("focused")local db,_c=self.get("width"),self.get("height") +local ac=self.get("replaceChar") +self:multiBlit(1,1,db,_c," ",_a[cb and bb or self.get("foreground")],_a[ +cb and ab or self.get("background")])if +#ba==0 and#_b~=0 and self.get("focused")==false then +self:textFg(1,1,_b:sub(1,db),self.get("placeholderColor"))return end;if(cb)then +self:setCursor( +self.get("cursorPos")-ca,1,true,self.get("cursorColor")or self.get("foreground"))end +local bc=ba:sub(ca+1,ca+db)if ac and#ac>0 then bc=ac:rep(#bc)end +self:textFg(1,1,bc,self.get("foreground"))end;return aa end +project["elements/BigFont.lua"] = function(...) local _b=require("libraries/colorHex") +local ab={{"\32\32\32\137\156\148\158\159\148\135\135\144\159\139\32\136\157\32\159\139\32\32\143\32\32\143\32\32\32\32\32\32\32\32\147\148\150\131\148\32\32\32\151\140\148\151\140\147","\32\32\32\149\132\149\136\156\149\144\32\133\139\159\129\143\159\133\143\159\133\138\32\133\138\32\133\32\32\32\32\32\32\150\150\129\137\156\129\32\32\32\133\131\129\133\131\132","\32\32\32\130\131\32\130\131\32\32\129\32\32\32\32\130\131\32\130\131\32\32\32\32\143\143\143\32\32\32\32\32\32\130\129\32\130\135\32\32\32\32\131\32\32\131\32\131","\139\144\32\32\143\148\135\130\144\149\32\149\150\151\149\158\140\129\32\32\32\135\130\144\135\130\144\32\149\32\32\139\32\159\148\32\32\32\32\159\32\144\32\148\32\147\131\132","\159\135\129\131\143\149\143\138\144\138\32\133\130\149\149\137\155\149\159\143\144\147\130\132\32\149\32\147\130\132\131\159\129\139\151\129\148\32\32\139\131\135\133\32\144\130\151\32","\32\32\32\32\32\32\130\135\32\130\32\129\32\129\129\131\131\32\130\131\129\140\141\132\32\129\32\32\129\32\32\32\32\32\32\32\131\131\129\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\159\154\133\133\133\144\152\141\132\133\151\129\136\153\32\32\154\32\159\134\129\130\137\144\159\32\144\32\148\32\32\32\32\32\32\32\32\32\32\32\151\129","\32\32\32\32\133\32\32\32\32\145\145\132\141\140\132\151\129\144\150\146\129\32\32\32\138\144\32\32\159\133\136\131\132\131\151\129\32\144\32\131\131\129\32\144\32\151\129\32","\32\32\32\32\129\32\32\32\32\130\130\32\32\129\32\129\32\129\130\129\129\32\32\32\32\130\129\130\129\32\32\32\32\32\32\32\32\133\32\32\32\32\32\129\32\129\32\32","\150\156\148\136\149\32\134\131\148\134\131\148\159\134\149\136\140\129\152\131\32\135\131\149\150\131\148\150\131\148\32\148\32\32\148\32\32\152\129\143\143\144\130\155\32\134\131\148","\157\129\149\32\149\32\152\131\144\144\131\148\141\140\149\144\32\149\151\131\148\32\150\32\150\131\148\130\156\133\32\144\32\32\144\32\130\155\32\143\143\144\32\152\129\32\134\32","\130\131\32\131\131\129\131\131\129\130\131\32\32\32\129\130\131\32\130\131\32\32\129\32\130\131\32\130\129\32\32\129\32\32\133\32\32\32\129\32\32\32\130\32\32\32\129\32","\150\140\150\137\140\148\136\140\132\150\131\132\151\131\148\136\147\129\136\147\129\150\156\145\138\143\149\130\151\32\32\32\149\138\152\129\149\32\32\157\152\149\157\144\149\150\131\148","\149\143\142\149\32\149\149\32\149\149\32\144\149\32\149\149\32\32\149\32\32\149\32\149\149\32\149\32\149\32\144\32\149\149\130\148\149\32\32\149\32\149\149\130\149\149\32\149","\130\131\129\129\32\129\131\131\32\130\131\32\131\131\32\131\131\129\129\32\32\130\131\32\129\32\129\130\131\32\130\131\32\129\32\129\131\131\129\129\32\129\129\32\129\130\131\32","\136\140\132\150\131\148\136\140\132\153\140\129\131\151\129\149\32\149\149\32\149\149\32\149\137\152\129\137\152\129\131\156\133\149\131\32\150\32\32\130\148\32\152\137\144\32\32\32","\149\32\32\149\159\133\149\32\149\144\32\149\32\149\32\149\32\149\150\151\129\138\155\149\150\130\148\32\149\32\152\129\32\149\32\32\32\150\32\32\149\32\32\32\32\32\32\32","\129\32\32\130\129\129\129\32\129\130\131\32\32\129\32\130\131\32\32\129\32\129\32\129\129\32\129\32\129\32\131\131\129\130\131\32\32\32\129\130\131\32\32\32\32\140\140\132","\32\154\32\159\143\32\149\143\32\159\143\32\159\144\149\159\143\32\159\137\145\159\143\144\149\143\32\32\145\32\32\32\145\149\32\144\32\149\32\143\159\32\143\143\32\159\143\32","\32\32\32\152\140\149\151\32\149\149\32\145\149\130\149\157\140\133\32\149\32\154\143\149\151\32\149\32\149\32\144\32\149\149\153\32\32\149\32\149\133\149\149\32\149\149\32\149","\32\32\32\130\131\129\131\131\32\130\131\32\130\131\129\130\131\129\32\129\32\140\140\129\129\32\129\32\129\32\137\140\129\130\32\129\32\130\32\129\32\129\129\32\129\130\131\32","\144\143\32\159\144\144\144\143\32\159\143\144\159\138\32\144\32\144\144\32\144\144\32\144\144\32\144\144\32\144\143\143\144\32\150\129\32\149\32\130\150\32\134\137\134\134\131\148","\136\143\133\154\141\149\151\32\129\137\140\144\32\149\32\149\32\149\154\159\133\149\148\149\157\153\32\154\143\149\159\134\32\130\148\32\32\149\32\32\151\129\32\32\32\32\134\32","\133\32\32\32\32\133\129\32\32\131\131\32\32\130\32\130\131\129\32\129\32\130\131\129\129\32\129\140\140\129\131\131\129\32\130\129\32\129\32\130\129\32\32\32\32\32\129\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32","\32\32\32\32\145\32\159\139\32\151\131\132\155\143\132\134\135\145\32\149\32\158\140\129\130\130\32\152\147\155\157\134\32\32\144\144\32\32\32\32\32\32\152\131\155\131\131\129","\32\32\32\32\149\32\149\32\145\148\131\32\149\32\149\140\157\132\32\148\32\137\155\149\32\32\32\149\154\149\137\142\32\153\153\32\131\131\149\131\131\129\149\135\145\32\32\32","\32\32\32\32\129\32\130\135\32\131\131\129\134\131\132\32\129\32\32\129\32\131\131\32\32\32\32\130\131\129\32\32\32\32\129\129\32\32\32\32\32\32\130\131\129\32\32\32","\150\150\32\32\148\32\134\32\32\132\32\32\134\32\32\144\32\144\150\151\149\32\32\32\32\32\32\145\32\32\152\140\144\144\144\32\133\151\129\133\151\129\132\151\129\32\145\32","\130\129\32\131\151\129\141\32\32\142\32\32\32\32\32\149\32\149\130\149\149\32\143\32\32\32\32\142\132\32\154\143\133\157\153\132\151\150\148\151\158\132\151\150\148\144\130\148","\32\32\32\140\140\132\32\32\32\32\32\32\32\32\32\151\131\32\32\129\129\32\32\32\32\134\32\32\32\32\32\32\32\129\129\32\129\32\129\129\130\129\129\32\129\130\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\150\151\129\150\131\132\140\143\144\143\141\145\137\140\148\141\141\144\157\142\32\159\140\32\151\134\32\157\141\32","\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\151\151\32\154\143\132\157\140\32\157\140\32\157\140\32\157\140\32\32\149\32\32\149\32\32\149\32\32\149\32","\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\131\129\32\134\32\131\131\129\131\131\129\131\131\129\131\131\129\130\131\32\130\131\32\130\131\32\130\131\32","\151\131\148\152\137\145\155\140\144\152\142\145\153\140\132\153\137\32\154\142\144\155\159\132\150\156\148\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\136\32\151\140\132","\151\32\149\151\155\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\152\137\144\157\129\149\149\32\149\149\32\149\149\32\149\149\32\149\130\150\32\32\157\129\149\32\149","\131\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\129\32\130\131\32\133\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\159\159\144\152\140\144\156\143\32\159\141\129\153\140\132\157\141\32\130\145\32\32\147\32\136\153\32\130\146\32","\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\149\157\134\154\143\132\157\140\133\157\140\133\157\140\133\157\140\133\32\149\32\32\149\32\32\149\32\32\149\32","\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\130\131\32\134\32\130\131\129\130\131\129\130\131\129\130\131\129\32\129\32\32\129\32\32\129\32\32\129\32","\159\134\144\137\137\32\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\32\132\32\159\143\32\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\138\32\146\130\144","\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\131\147\129\138\134\149\149\32\149\149\32\149\149\32\149\149\32\149\154\143\149\32\157\129\154\143\149","\130\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\129\130\131\129\130\131\129\130\131\129\140\140\129\130\131\32\140\140\129"},{"000110000110110000110010101000000010000000100101","000000110110000000000010101000000010000000100101","000000000000000000000000000000000000000000000000","100010110100000010000110110000010100000100000110","000000110000000010110110000110000000000000110000","000000000000000000000000000000000000000000000000","000000110110000010000000100000100000000000000010","000000000110110100010000000010000000000000000100","000000000000000000000000000000000000000000000000","010000000000100110000000000000000000000110010000","000000000000000000000000000010000000010110000000","000000000000000000000000000000000000000000000000","011110110000000100100010110000000100000000000000","000000000000000000000000000000000000000000000000","000000000000000000000000000000000000000000000000","110000110110000000000000000000010100100010000000","000010000000000000110110000000000100010010000000","000000000000000000000000000000000000000000000000","010110010110100110110110010000000100000110110110","000000000000000000000110000000000110000000000000","000000000000000000000000000000000000000000000000","010100010110110000000000000000110000000010000000","110110000000000000110000110110100000000010000000","000000000000000000000000000000000000000000000000","000100011111000100011111000100011111000100011111","000000000000100100100100011011011011111111111111","000000000000000000000000000000000000000000000000","000100011111000100011111000100011111000100011111","000000000000100100100100011011011011111111111111","100100100100100100100100100100100100100100100100","000000110100110110000010000011110000000000011000","000000000100000000000010000011000110000000001000","000000000000000000000000000000000000000000000000","010000100100000000000000000100000000010010110000","000000000000000000000000000000110110110110110000","000000000000000000000000000000000000000000000000","110110110110110110000000110110110110110110110110","000000000000000000000110000000000000000000000000","000000000000000000000000000000000000000000000000","000000000000110110000110010000000000000000010010","000010000000000000000000000000000000000000000000","000000000000000000000000000000000000000000000000","110110110110110110110000110110110110000000000000","000000000000000000000110000000000000000000000000","000000000000000000000000000000000000000000000000","110110110110110110110000110000000000000000010000","000000000000000000000000100000000000000110000110","000000000000000000000000000000000000000000000000"}}local bb={}local cb={} +do local dc=0;local _d=#ab[1]local ad=#ab[1][1] +for i=1,_d,3 do +for j=1,ad,3 do +local bd=string.char(dc)local cd={}cd[1]=ab[1][i]:sub(j,j+2) +cd[2]=ab[1][i+1]:sub(j,j+2)cd[3]=ab[1][i+2]:sub(j,j+2)local dd={}dd[1]=ab[2][i]:sub(j, +j+2)dd[2]=ab[2][i+1]:sub(j,j+2)dd[3]=ab[2][ +i+2]:sub(j,j+2)cb[bd]={cd,dd}dc=dc+1 end end;bb[1]=cb end +local function db(dc,_d)local ad={["0"]="1",["1"]="0"}if dc<=#bb then return true end +for f=#bb+1,dc do local bd={}local cd=bb[ +f-1] +for char=0,255 do local dd=string.char(char)local __a={}local a_a={} +local b_a=cd[dd][1]local c_a=cd[dd][2] +for i=1,#b_a do local d_a,_aa,aaa,baa,caa,daa={},{},{},{},{},{} +for j=1,#b_a[1]do +local _ba=cb[b_a[i]:sub(j,j)][1]table.insert(d_a,_ba[1]) +table.insert(_aa,_ba[2])table.insert(aaa,_ba[3]) +local aba=cb[b_a[i]:sub(j,j)][2] +if c_a[i]:sub(j,j)=="1"then +table.insert(baa,(aba[1]:gsub("[01]",ad))) +table.insert(caa,(aba[2]:gsub("[01]",ad))) +table.insert(daa,(aba[3]:gsub("[01]",ad)))else table.insert(baa,aba[1]) +table.insert(caa,aba[2])table.insert(daa,aba[3])end end;table.insert(__a,table.concat(d_a)) +table.insert(__a,table.concat(_aa))table.insert(__a,table.concat(aaa)) +table.insert(a_a,table.concat(baa))table.insert(a_a,table.concat(caa)) +table.insert(a_a,table.concat(daa))end;bd[dd]={__a,a_a}if _d then _d="Font"..f.."Yeld"..char +os.queueEvent(_d)os.pullEvent(_d)end end;bb[f]=bd end;return true end +local function _c(dc,_d,ad,bd,cd) +if not type(_d)=="string"then error("Not a String",3)end +local dd=type(ad)=="string"and ad:sub(1,1)or _b[ad]or +error("Wrong Front Color",3) +local __a=type(bd)=="string"and bd:sub(1,1)or _b[bd]or +error("Wrong Back Color",3)if(bb[dc]==nil)then db(3,false)end;local a_a=bb[dc]or +error("Wrong font size selected",3)if _d==""then +return{{""},{""},{""}}end;local b_a={} +for daa in _d:gmatch('.')do table.insert(b_a,daa)end;local c_a={}local d_a=#a_a[b_a[1]][1] +for nLine=1,d_a do local daa={}for i=1,#b_a do +daa[i]= +a_a[b_a[i]]and a_a[b_a[i]][1][nLine]or""end;c_a[nLine]=table.concat(daa)end;local _aa={}local aaa={}local baa={["0"]=dd,["1"]=__a}local caa={["0"]=__a,["1"]=dd} +for nLine=1,d_a +do local daa={}local _ba={} +for i=1,#b_a do local aba= +a_a[b_a[i]]and a_a[b_a[i]][2][nLine]or"" +daa[i]=aba:gsub("[01]",cd and +{["0"]=ad:sub(i,i),["1"]=bd:sub(i,i)}or baa) +_ba[i]=aba:gsub("[01]", +cd and{["0"]=bd:sub(i,i),["1"]=ad:sub(i,i)}or caa)end;_aa[nLine]=table.concat(daa) +aaa[nLine]=table.concat(_ba)end;return{c_a,_aa,aaa}end;local ac=require("elementManager") +local bc=ac.getElement("VisualElement")local cc=setmetatable({},bc)cc.__index=cc +cc.defineProperty(cc,"text",{default="BigFont",type="string",canTriggerRender=true,setter=function(dc,_d) +dc.bigfontText=_c(dc.get("fontSize"),_d,dc.get("foreground"),dc.get("background"))return _d end}) +cc.defineProperty(cc,"fontSize",{default=1,type="number",canTriggerRender=true,setter=function(dc,_d) +dc.bigfontText=_c(_d,dc.get("text"),dc.get("foreground"),dc.get("background"))return _d end})function cc.new()local dc=setmetatable({},cc):__init() +dc.class=cc;dc.set("width",16)dc.set("height",3)dc.set("z",5) +return dc end +function cc:init(dc,_d) +bc.init(self,dc,_d)self.set("type","BigFont") +self:observe("background",function(ad,bd) +ad.bigfontText=_c(ad.get("fontSize"),ad.get("text"),ad.get("foreground"),bd)end) +self:observe("foreground",function(ad,bd) +ad.bigfontText=_c(ad.get("fontSize"),ad.get("text"),bd,ad.get("background"))end)end +function cc:render()bc.render(self) +if(self.bigfontText)then +local dc,_d=self.get("x"),self.get("y") +for i=1,#self.bigfontText[1]do +local ad=self.bigfontText[1][i]:sub(1,self.get("width")) +local bd=self.bigfontText[2][i]:sub(1,self.get("width")) +local cd=self.bigfontText[3][i]:sub(1,self.get("width"))self:blit(dc,_d+i-1,ad,bd,cd)end end end;return cc end +project["elements/Switch.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"checked",{default=false,type="boolean",canTriggerRender=true}) +ca.defineProperty(ca,"text",{default="",type="string",canTriggerRender=true}) +ca.defineProperty(ca,"autoSize",{default=false,type="boolean"}) +ca.defineProperty(ca,"onBackground",{default=colors.green,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"offBackground",{default=colors.red,type="number",canTriggerRender=true})ca.defineEvent(ca,"mouse_click") +ca.defineEvent(ca,"mouse_up") +function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",2)da.set("height",1)da.set("z",5) +da.set("backgroundEnabled",true)return da end +function ca:init(da,_b)aa.init(self,da,_b)self.set("type","Switch")end +function ca:mouse_click(da,_b,ab)if aa.mouse_click(self,da,_b,ab)then +self.set("checked",not self.get("checked"))return true end;return false end +function ca:render()local da=self.get("checked")local _b=self.get("text") +local ab=self.get("width")local bb=self.get("height")local cb=da and self.get("onBackground")or +self.get("offBackground") +self:multiBlit(1,1,ab,bb," ",ba[self.get("foreground")],ba[cb])local db=math.floor(ab/2)local _c=da and(ab-db+1)or 1 +self:multiBlit(_c,1,db,bb," ",ba[self.get("foreground")],ba[self.get("background")])if _b~=""then +self:textFg(ab+2,1,_b,self.get("foreground"))end end;return ca end +project["elements/Frame.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=_a.getElement("Container")local ca=setmetatable({},ba) +ca.__index=ca +ca.defineProperty(ca,"draggable",{default=false,type="boolean",setter=function(da,_b) +if _b then da:listenEvent("mouse_click",true) +da:listenEvent("mouse_up",true)da:listenEvent("mouse_drag",true)end;return _b end}) +ca.defineProperty(ca,"draggingMap",{default={{x=1,y=1,width="width",height=1}},type="table"}) +ca.defineProperty(ca,"scrollable",{default=false,type="boolean",setter=function(da,_b)if _b then +da:listenEvent("mouse_scroll",true)end;return _b end}) +function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",12)da.set("height",6) +da.set("background",colors.gray)da.set("z",10)return da end;function ca:init(da,_b)ba.init(self,da,_b)self.set("type","Frame") +return self end +function ca:mouse_click(da,_b,ab) +if +aa.mouse_click(self,da,_b,ab)then +if self.get("draggable")then local bb,cb=self:getRelativePosition(_b,ab) +local db=self.get("draggingMap") +for _c,ac in ipairs(db)do local bc=ac.width or 1;local cc=ac.height or 1;if +type(bc)=="string"and bc=="width"then bc=self.get("width")elseif +type(bc)=="function"then bc=bc(self)end +if type(cc)== +"string"and cc=="height"then cc=self.get("height")elseif +type(cc)=="function"then cc=cc(self)end;local dc=ac.y or 1 +if +bb>=ac.x and bb<=ac.x+bc-1 and cb>=dc and cb<=dc+cc-1 then +self.dragStartX=_b-self.get("x")self.dragStartY=ab-self.get("y")self.dragging=true +return true end end end;return ba.mouse_click(self,da,_b,ab)end;return false end +function ca:mouse_up(da,_b,ab)if self.dragging then self.dragging=false;self.dragStartX=nil +self.dragStartY=nil;return true end;return +ba.mouse_up(self,da,_b,ab)end +function ca:mouse_drag(da,_b,ab) +if self.get("clicked")and self.dragging then +local bb=_b-self.dragStartX;local cb=ab-self.dragStartY;self.set("x",bb) +self.set("y",cb)return true end +if not self.dragging then return ba.mouse_drag(self,da,_b,ab)end;return false end +function ca:getChildrenHeight()local da=0;local _b=self.get("children") +for ab,bb in ipairs(_b)do if +bb.get("visible")then local cb=bb.get("y")local db=bb.get("height")local _c=cb+db-1 +if _c>da then da=_c end end end;return da end +function ca:mouse_scroll(da,_b,ab)if ba.mouse_scroll(self,da,_b,ab)then return true end +if +self.get("scrollable")then local bb,cb=self:getRelativePosition(_b,ab) +local db=self.get("width")local _c=self.get("height") +if +bb>=1 and bb<=db and cb>=1 and cb<=_c then local ac=self:getChildrenHeight() +local bc=self.get("offsetY")local cc=math.max(0,ac-_c)local dc=bc+da +dc=math.max(0,math.min(cc,dc))self.set("offsetY",dc)return true end end;return false end;return ca end +project["elements/Container.lua"] = function(...) local da=require("elementManager") +local _b=require("errorManager")local ab=da.getElement("VisualElement") +local bb=require("libraries/expect")local cb=require("libraries/utils").split +local db=setmetatable({},ab)db.__index=db +db.defineProperty(db,"children",{default={},type="table"}) +db.defineProperty(db,"childrenSorted",{default=true,type="boolean"}) +db.defineProperty(db,"childrenEventsSorted",{default=true,type="boolean"}) +db.defineProperty(db,"childrenEvents",{default={},type="table"}) +db.defineProperty(db,"eventListenerCount",{default={},type="table"}) +db.defineProperty(db,"focusedChild",{default=nil,type="table",allowNil=true,setter=function(bc,cc,dc)local _d=bc._values.focusedChild +if cc==_d then return cc end +if _d then +if _d:isType("Container")then _d.set("focusedChild",nil,true)end;_d.set("focused",false,true)end +if cc and not dc then cc.set("focused",true,true)if bc.parent then +bc.parent:setFocusedChild(bc)end end;return cc end}) +db.defineProperty(db,"visibleChildren",{default={},type="table"}) +db.defineProperty(db,"visibleChildrenEvents",{default={},type="table"}) +db.defineProperty(db,"offsetX",{default=0,type="number",canTriggerRender=true,setter=function(bc,cc)bc.set("childrenSorted",false) +bc.set("childrenEventsSorted",false)return cc end}) +db.defineProperty(db,"offsetY",{default=0,type="number",canTriggerRender=true,setter=function(bc,cc)bc.set("childrenSorted",false) +bc.set("childrenEventsSorted",false)return cc end}) +db.combineProperties(db,"offset","offsetX","offsetY") +for bc,cc in pairs(da:getElementList())do +local dc=bc:sub(1,1):upper()..bc:sub(2) +if dc~="BaseFrame"then +db["add"..dc]=function(_d,...)bb(1,_d,"table") +local ad=_d.basalt.create(bc,...)_d:addChild(ad)ad:postInit()return ad end +db["addDelayed"..dc]=function(_d,ad)bb(1,_d,"table") +local bd=_d.basalt.create(bc,ad,true,_d)return bd end end end;function db.new()local bc=setmetatable({},db):__init() +bc.class=db;return bc end +function db:init(bc,cc) +ab.init(self,bc,cc)self.set("type","Container") +self:observe("width",function() +self.set("childrenSorted",false)self.set("childrenEventsSorted",false)end) +self:observe("height",function()self.set("childrenSorted",false) +self.set("childrenEventsSorted",false)end)end +function db:isChildVisible(bc) +if not bc:isType("VisualElement")then return false end;if(bc.get("visible")==false)then return false end;if(bc._destroyed)then return +false end +local cc,dc=self.get("width"),self.get("height")local _d,ad=self.get("offsetX"),self.get("offsetY") +local bd,cd=bc.get("x"),bc.get("y")local dd,__a=bc.get("width"),bc.get("height")local a_a;local b_a;if +(bc.get("ignoreOffset"))then a_a=bd;b_a=cd else a_a=bd-_d;b_a=cd-ad end;return + +(a_a+dd>0)and(a_a<=cc)and(b_a+__a>0)and(b_a<=dc)end +function db:addChild(bc) +if bc==self then error("Cannot add container to itself")end;if(bc~=nil)then table.insert(self._values.children,bc) +bc.parent=self;bc:postInit()self.set("childrenSorted",false) +self:registerChildrenEvents(bc)end;return +self end +local function _c(bc,cc)local dc={}for _d,ad in ipairs(cc)do +if bc:isChildVisible(ad)and ad.get("visible")and not +ad._destroyed then table.insert(dc,ad)end end +for i=2,#dc do +local _d=dc[i]local ad=_d.get("z")local bd=i-1 +while bd>0 do local cd=dc[bd].get("z")if cd>ad then +dc[bd+1]=dc[bd]bd=bd-1 else break end end;dc[bd+1]=_d end;return dc end +function db:clear()self.set("children",{}) +self.set("childrenEvents",{})self.set("visibleChildren",{}) +self.set("visibleChildrenEvents",{})self.set("childrenSorted",true) +self.set("childrenEventsSorted",true)return self end +function db:sortChildren() +self.set("visibleChildren",_c(self,self._values.children))self.set("childrenSorted",true)return self end +function db:sortChildrenEvents(bc)if self._values.childrenEvents[bc]then +self._values.visibleChildrenEvents[bc]=_c(self,self._values.childrenEvents[bc])end +self.set("childrenEventsSorted",true)return self end +function db:registerChildrenEvents(bc)if(bc._registeredEvents==nil)then return end +for cc in +pairs(bc._registeredEvents)do self:registerChildEvent(bc,cc)end;return self end +function db:registerChildEvent(bc,cc) +if not self._values.childrenEvents[cc]then +self._values.childrenEvents[cc]={}self._values.eventListenerCount[cc]=0;if self.parent then +self.parent:registerChildEvent(self,cc)end end +for dc,_d in ipairs(self._values.childrenEvents[cc])do if _d.get("id")== +bc.get("id")then return self end end;self.set("childrenEventsSorted",false) +table.insert(self._values.childrenEvents[cc],bc)self._values.eventListenerCount[cc]= +self._values.eventListenerCount[cc]+1;return self end +function db:removeChildrenEvents(bc) +if bc~=nil then +if(bc._registeredEvents==nil)then return self end;for cc in pairs(bc._registeredEvents)do +self:unregisterChildEvent(bc,cc)end end;return self end +function db:unregisterChildEvent(bc,cc) +if self._values.childrenEvents[cc]then +for dc,_d in +ipairs(self._values.childrenEvents[cc])do +if _d.get("id")==bc.get("id")then +table.remove(self._values.childrenEvents[cc],dc)self._values.eventListenerCount[cc]= +self._values.eventListenerCount[cc]-1 +if +self._values.eventListenerCount[cc]<=0 then +self._values.childrenEvents[cc]=nil;self._values.eventListenerCount[cc]=nil;if self.parent then +self.parent:unregisterChildEvent(self,cc)end end;self.set("childrenEventsSorted",false) +self:updateRender()break end end end;return self end +function db:removeChild(bc)if bc==nil then return self end +for cc,dc in ipairs(self._values.children)do if +dc.get("id")==bc.get("id")then +table.remove(self._values.children,cc)bc.parent=nil;break end end;self:removeChildrenEvents(bc)self:updateRender() +self.set("childrenSorted",false)return self end +function db:getChild(bc) +if type(bc)=="string"then local cc=cb(bc,"/") +for dc,_d in +pairs(self._values.children)do if _d.get("name")==cc[1]then +if#cc==1 then return _d else if(_d:isType("Container"))then return +_d:find(table.concat(cc,"/",2))end end end end end;return nil end +local function ac(bc,cc,...)local dc={...} +if cc and cc:find("mouse_")then local _d,ad,bd=... +local cd,dd=bc.get("offsetX"),bc.get("offsetY")local __a,a_a=bc:getRelativePosition(ad+cd,bd+dd) +dc={_d,__a,a_a}end;return dc end +function db:callChildrenEvent(bc,cc,...)local dc=bc and self.get("visibleChildrenEvents")or +self.get("childrenEvents") +if +dc[cc]then local _d=dc[cc]for i=#_d,1,-1 do local ad=_d[i] +if(ad:dispatchEvent(cc,...))then return true,ad end end end +if(dc["*"])then local _d=dc["*"]for i=#_d,1,-1 do local ad=_d[i] +if(ad:dispatchEvent(cc,...))then return true,ad end end end;return false end +function db:handleEvent(bc,...)ab.handleEvent(self,bc,...)local cc=ac(self,bc,...)return +self:callChildrenEvent(false,bc,table.unpack(cc))end +function db:mouse_click(bc,cc,dc) +if ab.mouse_click(self,bc,cc,dc)then +local _d=ac(self,"mouse_click",bc,cc,dc) +local ad,bd=self:callChildrenEvent(true,"mouse_click",table.unpack(_d)) +if(ad)then self.set("focusedChild",bd)return true end;self.set("focusedChild",nil)return true end;return false end +function db:mouse_up(bc,cc,dc) +if ab.mouse_up(self,bc,cc,dc)then local _d=ac(self,"mouse_up",bc,cc,dc) +local ad,bd=self:callChildrenEvent(true,"mouse_up",table.unpack(_d))if(ad)then return true end end;return false end +function db:mouse_release(bc,cc,dc)ab.mouse_release(self,bc,cc,dc) +local _d=ac(self,"mouse_release",bc,cc,dc) +self:callChildrenEvent(false,"mouse_release",table.unpack(_d))end +function db:mouse_move(bc,cc,dc) +if ab.mouse_move(self,bc,cc,dc)then +local _d=ac(self,"mouse_move",bc,cc,dc) +local ad,bd=self:callChildrenEvent(true,"mouse_move",table.unpack(_d))if(ad)then return true end end;return false end +function db:mouse_drag(bc,cc,dc) +if ab.mouse_drag(self,bc,cc,dc)then +local _d=ac(self,"mouse_drag",bc,cc,dc) +local ad,bd=self:callChildrenEvent(true,"mouse_drag",table.unpack(_d))if(ad)then return true end end;return false end +function db:mouse_scroll(bc,cc,dc) +if(ab.mouse_scroll(self,bc,cc,dc))then +local _d=ac(self,"mouse_scroll",bc,cc,dc) +local ad,bd=self:callChildrenEvent(true,"mouse_scroll",table.unpack(_d))return ad end;return false end;function db:key(bc)if self.get("focusedChild")then return +self.get("focusedChild"):dispatchEvent("key",bc)end +return true end +function db:char(bc)if +self.get("focusedChild")then +return self.get("focusedChild"):dispatchEvent("char",bc)end;return true end;function db:key_up(bc) +if self.get("focusedChild")then return +self.get("focusedChild"):dispatchEvent("key_up",bc)end;return true end +function db:multiBlit(bc,cc,dc,_d,ad,bd,cd) +local dd,__a=self.get("width"),self.get("height")dc=bc<1 and math.min(dc+bc-1,dd)or +math.min(dc,math.max(0,dd-bc+1))_d=cc<1 and math.min( +_d+cc-1,__a)or +math.min(_d,math.max(0,__a-cc+1))if dc<=0 or +_d<=0 then return self end +ab.multiBlit(self,math.max(1,bc),math.max(1,cc),dc,_d,ad,bd,cd)return self end +function db:textFg(bc,cc,dc,_d)local ad,bd=self.get("width"),self.get("height")if +cc<1 or cc>bd then return self end;local cd=bc<1 and(2 -bc)or 1 +local dd=math.min(#dc- +cd+1,ad-math.max(1,bc)+1)if dd<=0 then return self end +ab.textFg(self,math.max(1,bc),math.max(1,cc),dc:sub(cd,cd+dd-1),_d)return self end +function db:textBg(bc,cc,dc,_d)local ad,bd=self.get("width"),self.get("height")if +cc<1 or cc>bd then return self end;local cd=bc<1 and(2 -bc)or 1 +local dd=math.min(#dc- +cd+1,ad-math.max(1,bc)+1)if dd<=0 then return self end +ab.textBg(self,math.max(1,bc),math.max(1,cc),dc:sub(cd,cd+dd-1),_d)return self end +function db:drawText(bc,cc,dc)local _d,ad=self.get("width"),self.get("height")if cc<1 or +cc>ad then return self end;local bd=bc<1 and(2 -bc)or 1 +local cd=math.min( +#dc-bd+1,_d-math.max(1,bc)+1)if cd<=0 then return self end +ab.drawText(self,math.max(1,bc),math.max(1,cc),dc:sub(bd,bd+cd-1))return self end +function db:drawFg(bc,cc,dc)local _d,ad=self.get("width"),self.get("height")if +cc<1 or cc>ad then return self end;local bd=bc<1 and(2 -bc)or 1 +local cd=math.min(#dc- +bd+1,_d-math.max(1,bc)+1)if cd<=0 then return self end +ab.drawFg(self,math.max(1,bc),math.max(1,cc),dc:sub(bd,bd+cd-1))return self end +function db:drawBg(bc,cc,dc)local _d,ad=self.get("width"),self.get("height")if +cc<1 or cc>ad then return self end;local bd=bc<1 and(2 -bc)or 1 +local cd=math.min(#dc- +bd+1,_d-math.max(1,bc)+1)if cd<=0 then return self end +ab.drawBg(self,math.max(1,bc),math.max(1,cc),dc:sub(bd,bd+cd-1))return self end +function db:blit(bc,cc,dc,_d,ad)local bd,cd=self.get("width"),self.get("height")if +cc<1 or cc>cd then return self end;local dd=bc<1 and(2 -bc)or 1 +local __a=math.min(#dc- +dd+1,bd-math.max(1,bc)+1) +local a_a=math.min(#_d-dd+1,bd-math.max(1,bc)+1) +local b_a=math.min(#ad-dd+1,bd-math.max(1,bc)+1)if __a<=0 then return self end;local c_a=dc:sub(dd,dd+__a-1)local d_a=_d:sub(dd, +dd+a_a-1)local _aa=ad:sub(dd,dd+b_a-1) +ab.blit(self,math.max(1,bc),math.max(1,cc),c_a,d_a,_aa)return self end +function db:render()ab.render(self)if not self.get("childrenSorted")then +self:sortChildren()end +if +not self.get("childrenEventsSorted")then for bc in pairs(self._values.childrenEvents)do +self:sortChildrenEvents(bc)end end;for bc,cc in ipairs(self.get("visibleChildren"))do if cc==self then +_b.error("CIRCULAR REFERENCE DETECTED!")return end;cc:render() +cc:postRender()end end +function db:destroy()if not self:isType("BaseFrame")then ab.destroy(self) +return self else _b.header="Basalt Error" +_b.error("Cannot destroy a BaseFrame.")end end;return db end +project["elements/Tree.lua"] = function(...) local _a=require("elements/VisualElement")local aa=string.sub +local ba=setmetatable({},_a)ba.__index=ba +ba.defineProperty(ba,"nodes",{default={},type="table",canTriggerRender=true,setter=function(da,_b)if#_b>0 then +da.get("expandedNodes")[_b[1]]=true end;return _b end}) +ba.defineProperty(ba,"selectedNode",{default=nil,type="table",canTriggerRender=true}) +ba.defineProperty(ba,"expandedNodes",{default={},type="table",canTriggerRender=true}) +ba.defineProperty(ba,"scrollOffset",{default=0,type="number",canTriggerRender=true}) +ba.defineProperty(ba,"horizontalOffset",{default=0,type="number",canTriggerRender=true}) +ba.defineProperty(ba,"nodeColor",{default=colors.white,type="color"}) +ba.defineProperty(ba,"selectedColor",{default=colors.lightBlue,type="color"})ba.defineEvent(ba,"mouse_click") +ba.defineEvent(ba,"mouse_scroll")function ba.new()local da=setmetatable({},ba):__init() +da.class=ba;da.set("width",30)da.set("height",10)da.set("z",5) +return da end +function ba:init(da,_b) +_a.init(self,da,_b)self.set("type","Tree")return self end;function ba:expandNode(da)self.get("expandedNodes")[da]=true +self:updateRender()return self end +function ba:collapseNode(da)self.get("expandedNodes")[da]= +nil;self:updateRender()return self end;function ba:toggleNode(da)if self.get("expandedNodes")[da]then +self:collapseNode(da)else self:expandNode(da)end +return self end +local function ca(da,_b,ab,bb)bb=bb or{}ab= +ab or 0;for cb,db in ipairs(da)do table.insert(bb,{node=db,level=ab}) +if +_b[db]and db.children then ca(db.children,_b,ab+1,bb)end end;return bb end +function ba:mouse_click(da,_b,ab) +if _a.mouse_click(self,da,_b,ab)then +local bb,cb=self:getRelativePosition(_b,ab) +local db=ca(self.get("nodes"),self.get("expandedNodes"))local _c=cb+self.get("scrollOffset") +if db[_c]then local ac=db[_c] +local bc=ac.node +if bb<=ac.level*2 +2 then self:toggleNode(bc)end;self.set("selectedNode",bc) +self:fireEvent("node_select",bc)end;return true end;return false end +function ba:onSelect(da)self:registerCallback("node_select",da)return self end +function ba:mouse_scroll(da,_b,ab) +if _a.mouse_scroll(self,da,_b,ab)then +local bb=ca(self.get("nodes"),self.get("expandedNodes")) +local cb=math.max(0,#bb-self.get("height")) +local db=math.min(cb,math.max(0,self.get("scrollOffset")+da))self.set("scrollOffset",db)return true end;return false end +function ba:getNodeSize()local da,_b=0,0 +local ab=ca(self.get("nodes"),self.get("expandedNodes"))for bb,cb in ipairs(ab)do +da=math.max(da,cb.level+#cb.node.text)end;_b=#ab;return da,_b end +function ba:render()_a.render(self) +local da=ca(self.get("nodes"),self.get("expandedNodes"))local _b=self.get("height")local ab=self.get("selectedNode") +local bb=self.get("expandedNodes")local cb=self.get("scrollOffset") +local db=self.get("horizontalOffset") +for y=1,_b do local _c=da[y+cb] +if _c then local ac=_c.node;local bc=_c.level +local cc=string.rep(" ",bc)local dc=" "if ac.children and#ac.children>0 then +dc=bb[ac]and"\31"or"\16"end +local _d= +ac==ab and self.get("selectedColor")or self.get("background") +local ad=cc..dc.." ".. (ac.text or"Node")local bd=aa(ad,db+1,db+self.get("width")) +self:textFg(1,y, +bd..string.rep(" ",self.get("width")-#bd),self.get("foreground"))else +self:textFg(1,y,string.rep(" ",self.get("width")),self.get("foreground"),self.get("background"))end end end;return ba end +project["elements/DropDown.lua"] = function(...) local _a=require("elements/VisualElement") +local aa=require("elements/List")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"isOpen",{default=false,type="boolean",canTriggerRender=true}) +ca.defineProperty(ca,"dropdownHeight",{default=5,type="number"}) +ca.defineProperty(ca,"selectedText",{default="",type="string"}) +ca.defineProperty(ca,"dropSymbol",{default="\31",type="string"})function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;da.set("width",16)da.set("height",1)da.set("z",8) +return da end +function ca:init(da,_b) +aa.init(self,da,_b)self.set("type","DropDown")return self end +function ca:mouse_click(da,_b,ab) +if not _a.mouse_click(self,da,_b,ab)then return false end;local bb,cb=self:getRelativePosition(_b,ab) +if cb==1 then self.set("isOpen",not +self.get("isOpen"))if +not self.get("isOpen")then self.set("height",1)else +self.set("height",1 +math.min(self.get("dropdownHeight"),# +self.get("items")))end +return true elseif +self.get("isOpen")and cb>1 and self.get("selectable")then local db=(cb-1)+self.get("offset") +local _c=self.get("items") +if db<=#_c then local ac=_c[db] +if type(ac)=="string"then ac={text=ac}_c[db]=ac end +if not self.get("multiSelection")then for bc,cc in ipairs(_c)do if type(cc)=="table"then +cc.selected=false end end end;ac.selected=not ac.selected +if ac.callback then ac.callback(self)end;self:fireEvent("select",db,ac) +self.set("isOpen",false)self.set("height",1)self:updateRender()return true end end;return false end +function ca:render()_a.render(self)local da=self.get("selectedText") +local _b=self:getSelectedItems()if#_b>0 then local ab=_b[1]da=ab.text or"" +da=da:sub(1,self.get("width")-2)end +self:blit(1,1,da..string.rep(" ",self.get("width")-# +da-1).. ( +self.get("isOpen")and"\31"or"\17"),string.rep(ba[self.get("foreground")],self.get("width")),string.rep(ba[self.get("background")],self.get("width"))) +if self.get("isOpen")then local ab=self.get("items") +local bb=self.get("height")-1;local cb=self.get("offset")local db=self.get("width") +for i=1,bb do local _c=i+cb +local ac=ab[_c] +if ac then if type(ac)=="string"then ac={text=ac}ab[_c]=ac end +if +ac.separator then local bc=(ac.text or"-"):sub(1,1) +local cc=string.rep(bc,db)local dc=ac.foreground or self.get("foreground")local _d= +ac.background or self.get("background")self:textBg(1, +i+1,string.rep(" ",db),_d) +self:textFg(1,i+1,cc,dc)else local bc=ac.text;local cc=ac.selected;bc=bc:sub(1,db) +local dc=cc and(ac.selectedBackground or +self.get("selectedBackground"))or(ac.background or +self.get("background")) +local _d= +cc and(ac.selectedForeground or self.get("selectedForeground"))or(ac.foreground or self.get("foreground"))self:textBg(1,i+1,string.rep(" ",db),dc)self:textFg(1, +i+1,bc,_d)end end end end end;return ca end +project["elements/Display.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("VisualElement") +local da=require("libraries/utils").getCenteredPosition;local _b=require("libraries/utils").deepcopy +local ab=require("libraries/colorHex")local bb=setmetatable({},ca)bb.__index=bb;function bb.new() +local cb=setmetatable({},bb):__init()cb.class=bb;cb.set("width",25)cb.set("height",8) +cb.set("z",5)return cb end +function bb:init(cb,db) +ca.init(self,cb,db)self.set("type","Display") +self._window=window.create(db.getActiveFrame():getTerm(),1,1,self.get("width"),self.get("height"),false)local _c=self._window.reposition;local ac=self._window.blit +local bc=self._window.write +self._window.reposition=function(cc,dc,_d,ad)self.set("x",cc)self.set("y",dc) +self.set("width",_d)self.set("height",ad)_c(1,1,_d,ad)end +self._window.getPosition=function(cc)return cc.get("x"),cc.get("y")end +self._window.setVisible=function(cc)self.set("visible",cc)end +self._window.isVisible=function(cc)return cc.get("visible")end +self._window.blit=function(cc,dc,_d,ad,bd)ac(cc,dc,_d,ad,bd)self:updateRender()end +self._window.write=function(cc,dc,_d)bc(cc,dc,_d)self:updateRender()end +self:observe("width",function(cc,dc)local _d=cc._window;if _d then +_d.reposition(1,1,dc,cc.get("height"))end end) +self:observe("height",function(cc,dc)local _d=cc._window;if _d then +_d.reposition(1,1,cc.get("width"),dc)end end)end;function bb:getWindow()return self._window end +function bb:write(cb,db,_c,ac,bc)local cc=self._window +if cc then if ac then +cc.setTextColor(ac)end;if bc then cc.setBackgroundColor(bc)end +cc.setCursorPos(cb,db)cc.write(_c)end;self:updateRender()return self end +function bb:render()ca.render(self)local cb=self._window;local db,_c=cb.getSize() +if cb then for y=1,_c do +local ac,bc,cc=cb.getLine(y)self:blit(1,y,ac,bc,cc)end end end;return bb end +project["elements/LineChart.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("VisualElement")local da=ba.getElement("Graph") +local _b=require("libraries/colorHex")local ab=setmetatable({},da)ab.__index=ab;function ab.new() +local cb=setmetatable({},ab):__init()cb.class=ab;return cb end +function ab:init(cb,db) +da.init(self,cb,db)self.set("type","LineChart")return self end +local function bb(cb,db,_c,ac,bc,cc,dc,_d)local ad=ac-db;local bd=bc-_c +local cd=math.max(math.abs(ad),math.abs(bd)) +for i=0,cd do local dd=cd==0 and 0 or i/cd +local __a=math.floor(db+ad*dd)local a_a=math.floor(_c+bd*dd) +if + +__a>=1 and __a<=cb.get("width")and a_a>=1 and a_a<=cb.get("height")then cb:blit(__a,a_a,cc,_b[dc],_b[_d])end end end +function ab:render()ca.render(self)local cb=self.get("width") +local db=self.get("height")local _c=self.get("minValue")local ac=self.get("maxValue") +local bc=self.get("series") +for cc,dc in pairs(bc)do +if(dc.visible)then local _d,ad;local bd=#dc.data +local cd=(cb-1)/math.max((bd-1),1) +for dd,__a in ipairs(dc.data)do local a_a=math.floor(( (dd-1)*cd)+1)local b_a= +(__a-_c)/ (ac-_c) +local c_a=math.floor(db- (b_a* (db-1)))c_a=math.max(1,math.min(c_a,db))if _d then +bb(self,_d,ad,a_a,c_a,dc.symbol,dc.bgColor,dc.fgColor)end;_d,ad=a_a,c_a end end end end;return ab end +project["elements/Graph.lua"] = function(...) local _a=require("elementManager") +local aa=_a.getElement("VisualElement")local ba=require("libraries/colorHex") +local ca=setmetatable({},aa)ca.__index=ca +ca.defineProperty(ca,"minValue",{default=0,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"maxValue",{default=100,type="number",canTriggerRender=true}) +ca.defineProperty(ca,"series",{default={},type="table",canTriggerRender=true})function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;return da end;function ca:init(da,_b) +aa.init(self,da,_b)self.set("type","Graph")self.set("width",20) +self.set("height",10)return self end +function ca:addSeries(da,_b,ab,bb,cb) +local db=self.get("series") +table.insert(db,{name=da,symbol=_b or" ",bgColor=ab or colors.white,fgColor=bb or colors.black,pointCount=cb or self.get("width"),data={},visible=true})self:updateRender()return self end +function ca:removeSeries(da)local _b=self.get("series")for ab,bb in ipairs(_b)do if bb.name==da then +table.remove(_b,ab)break end end +self:updateRender()return self end +function ca:getSeries(da)local _b=self.get("series")for ab,bb in ipairs(_b)do +if bb.name==da then return bb end end;return nil end +function ca:changeSeriesVisibility(da,_b)local ab=self.get("series")for bb,cb in ipairs(ab)do if cb.name==da then +cb.visible=_b;break end end +self:updateRender()return self end +function ca:addPoint(da,_b)local ab=self.get("series") +for bb,cb in ipairs(ab)do if cb.name==da then +table.insert(cb.data,_b) +while#cb.data>cb.pointCount do table.remove(cb.data,1)end;break end end;self:updateRender()return self end +function ca:focusSeries(da)local _b=self.get("series") +for ab,bb in ipairs(_b)do if bb.name==da then +table.remove(_b,ab)table.insert(_b,bb)break end end;self:updateRender()return self end +function ca:setSeriesPointCount(da,_b)local ab=self.get("series") +for bb,cb in ipairs(ab)do if cb.name==da then +cb.pointCount=_b;while#cb.data>_b do table.remove(cb.data,1)end +break end end;self:updateRender()return self end +function ca:clear(da)local _b=self.get("series") +if da then for ab,bb in ipairs(_b)do +if bb.name==da then bb.data={}break end end else for ab,bb in ipairs(_b)do bb.data={}end end;return self end +function ca:render()aa.render(self)local da=self.get("width") +local _b=self.get("height")local ab=self.get("minValue")local bb=self.get("maxValue") +local cb=self.get("series") +for db,_c in pairs(cb)do +if(_c.visible)then local ac=#_c.data +local bc=(da-1)/math.max((ac-1),1) +for cc,dc in ipairs(_c.data)do local _d=math.floor(( (cc-1)*bc)+1)local ad= +(dc-ab)/ (bb-ab) +local bd=math.floor(_b- (ad* (_b-1)))bd=math.max(1,math.min(bd,_b)) +self:blit(_d,bd,_c.symbol,ba[_c.bgColor],ba[_c.fgColor])end end end end;return ca end +project["elements/FlexBox.lua"] = function(...) local da=require("elementManager") +local _b=da.getElement("Container")local ab=setmetatable({},_b)ab.__index=ab +ab.defineProperty(ab,"flexDirection",{default="row",type="string"}) +ab.defineProperty(ab,"flexSpacing",{default=1,type="number"}) +ab.defineProperty(ab,"flexJustifyContent",{default="flex-start",type="string",setter=function(bc,cc)if not cc:match("^flex%-")then +cc="flex-"..cc end;return cc end}) +ab.defineProperty(ab,"flexAlignItems",{default="flex-start",type="string",setter=function(bc,cc)if +not cc:match("^flex%-")and cc~="stretch"then cc="flex-"..cc end;return cc end}) +ab.defineProperty(ab,"flexCrossPadding",{default=0,type="number"}) +ab.defineProperty(ab,"flexWrap",{default=false,type="boolean"}) +ab.defineProperty(ab,"flexUpdateLayout",{default=false,type="boolean"}) +local bb={getHeight=function(bc)return 0 end,getWidth=function(bc)return 0 end,getZ=function(bc)return 1 end,getPosition=function(bc)return 0,0 end,getSize=function(bc)return 0,0 end,isType=function(bc)return +false end,getType=function(bc)return"lineBreak"end,getName=function(bc)return"lineBreak"end,setPosition=function(bc) +end,setParent=function(bc)end,setSize=function(bc)end,getFlexGrow=function(bc)return 0 end,getFlexShrink=function(bc)return 0 end,getFlexBasis=function(bc)return 0 end,init=function(bc)end,getVisible=function(bc)return +true end} +local function cb(bc,cc,dc,_d)local ad={}local bd={}local cd=0 +for __a,a_a in pairs(bc.get("children"))do if a_a.get("visible")then +table.insert(bd,a_a)if a_a~=bb then cd=cd+1 end end end;if cd==0 then return ad end +if not _d then ad[1]={offset=1} +for __a,a_a in ipairs(bd)do if a_a==bb then local b_a=#ad+1;if +ad[b_a]==nil then ad[b_a]={offset=1}end else +table.insert(ad[#ad],a_a)end end else +local __a=cc=="row"and bc.get("width")or bc.get("height")local a_a={{}}local b_a=1 +for c_a,d_a in ipairs(bd)do if d_a==bb then b_a=b_a+1;a_a[b_a]={}else +table.insert(a_a[b_a],d_a)end end +for c_a,d_a in ipairs(a_a)do +if#d_a==0 then ad[#ad+1]={offset=1}else local _aa={}local aaa={}local baa=0 +for caa,daa in ipairs(d_a)do +local _ba=0 +local aba=cc=="row"and daa.get("width")or daa.get("height")local bba=false +if cc=="row"then +local _ca,aca=pcall(function()return daa.get("intrinsicWidth")end)if _ca and aca then _ba=aca;bba=true end else +local _ca,aca=pcall(function() +return daa.get("intrinsicHeight")end)if _ca and aca then _ba=aca;bba=true end end;local cba=bba and _ba or aba;local dba=cba;if#aaa>0 then dba=dba+dc end +if +baa+dba<=__a or#aaa==0 then table.insert(aaa,daa) +baa=baa+dba else table.insert(_aa,aaa)aaa={daa}baa=cba end end;if#aaa>0 then table.insert(_aa,aaa)end;for caa,daa in ipairs(_aa)do +ad[#ad+1]={offset=1} +for _ba,aba in ipairs(daa)do table.insert(ad[#ad],aba)end end end end end;local dd={} +for __a,a_a in ipairs(ad)do if#a_a>0 then table.insert(dd,a_a)end end;return dd end +local function db(bc,cc,dc,_d)local ad={} +for dca,_da in ipairs(cc)do if _da~=bb then table.insert(ad,_da)end end;if#ad==0 then return end;local bd=bc.get("width") +local cd=bc.get("height")local dd=bc.get("flexAlignItems") +local __a=bc.get("flexCrossPadding")local a_a=bc.get("flexWrap")if bd<=0 then return end;local b_a=cd- (__a*2)if b_a< +1 then b_a=cd;__a=0 end;local c_a=math.max;local d_a=math.min +local _aa=math.floor;local aaa=math.ceil;local baa=0;local caa=0;local daa={}local _ba={}local aba={} +for dca,_da in ipairs(ad)do local ada= +_da.get("flexGrow")or 0 +local bda=_da.get("flexShrink")or 0;local cda=_da.get("width")_ba[_da]=ada;aba[_da]=bda;daa[_da]=cda;if +ada>0 then caa=caa+ada else baa=baa+cda end end;local bba=#ad;local cba=(bba>1)and( (bba-1)*dc)or 0;local dba= +bd-baa-cba +if dba>0 and caa>0 then +for dca,_da in ipairs(ad)do local ada=_ba[_da]if ada>0 then +local bda=daa[_da]local cda=_aa((ada/caa)*dba) +_da.set("width",c_a(cda,1))end end elseif dba<0 then local dca=0;local _da={}for ada,bda in ipairs(ad)do local cda=aba[bda]if cda>0 then dca=dca+cda +table.insert(_da,bda)end end +if +dca>0 and#_da>0 then local ada=-dba;for bda,cda in ipairs(_da)do local dda=cda.get("width") +local __b=aba[cda]local a_b=__b/dca;local b_b=aaa(ada*a_b) +cda.set("width",c_a(1,dda-b_b))end end;baa=0 +for ada,bda in ipairs(ad)do baa=baa+bda.get("width")end +if caa>0 then local ada={}local bda=0 +for cda,dda in ipairs(ad)do if _ba[dda]>0 then table.insert(ada,dda)bda=bda+ +dda.get("width")end end +if#ada>0 and bda>0 then local cda=c_a(_aa(bd*0.2),#ada) +local dda=d_a(cda,bd-cba) +for __b,a_b in ipairs(ada)do local b_b=_ba[a_b]local c_b=b_b/caa +local d_b=c_a(1,_aa(dda*c_b))a_b.set("width",d_b)end end end end;local _ca=1 +for dca,_da in ipairs(ad)do _da.set("x",_ca) +if not a_a then +if dd=="stretch"then +_da.set("height",b_a)_da.set("y",1 +__a)else local bda=_da.get("height")local cda=1;if +dd=="flex-end"then cda=cd-bda+1 elseif dd=="flex-center"or dd=="center"then cda= +_aa((cd-bda)/2)+1 end +_da.set("y",c_a(1,cda))end end +local ada=_da.get("y")+_da.get("height")-1;if +ada>cd and(_da.get("flexShrink")or 0)>0 then +_da.set("height",c_a(1,cd-_da.get("y")+1))end;_ca= +_ca+_da.get("width")+dc end;local aca=ad[#ad]local bca=0;if aca then +bca=aca.get("x")+aca.get("width")-1 end;local cca=bd-bca +if cca>0 then +if _d=="flex-end"then for dca,_da in ipairs(ad)do _da.set("x", +_da.get("x")+cca)end elseif _d== +"flex-center"or _d=="center"then local dca=_aa(cca/2)for _da,ada in ipairs(ad)do ada.set("x", +ada.get("x")+dca)end end end end +local function _c(bc,cc,dc,_d)local ad={} +for dca,_da in ipairs(cc)do if _da~=bb then table.insert(ad,_da)end end;if#ad==0 then return end;local bd=bc.get("width") +local cd=bc.get("height")local dd=bc.get("flexAlignItems") +local __a=bc.get("flexCrossPadding")local a_a=bc.get("flexWrap")if cd<=0 then return end;local b_a=bd- (__a*2)if b_a< +1 then b_a=bd;__a=0 end;local c_a=math.max;local d_a=math.min +local _aa=math.floor;local aaa=math.ceil;local baa=0;local caa=0;local daa={}local _ba={}local aba={} +for dca,_da in ipairs(ad)do local ada= +_da.get("flexGrow")or 0 +local bda=_da.get("flexShrink")or 0;local cda=_da.get("height")_ba[_da]=ada;aba[_da]=bda;daa[_da]=cda;if +ada>0 then caa=caa+ada else baa=baa+cda end end;local bba=#ad;local cba=(bba>1)and( (bba-1)*dc)or 0;local dba= +cd-baa-cba +if dba>0 and caa>0 then +for dca,_da in ipairs(ad)do local ada=_ba[_da]if ada>0 then +local bda=daa[_da]local cda=_aa((ada/caa)*dba) +_da.set("height",c_a(cda,1))end end elseif dba<0 then local dca=0;local _da={}for ada,bda in ipairs(ad)do local cda=aba[bda]if cda>0 then dca=dca+cda +table.insert(_da,bda)end end +if +dca>0 and#_da>0 then local ada=-dba +for bda,cda in ipairs(_da)do local dda=cda.get("height") +local __b=aba[cda]local a_b=__b/dca;local b_b=aaa(ada*a_b) +cda.set("height",c_a(1,dda-b_b))end end;baa=0 +for ada,bda in ipairs(ad)do baa=baa+bda.get("height")end +if caa>0 then local ada={}local bda=0 +for cda,dda in ipairs(ad)do if _ba[dda]>0 then table.insert(ada,dda)bda=bda+ +dda.get("height")end end +if#ada>0 and bda>0 then local cda=c_a(_aa(cd*0.2),#ada) +local dda=d_a(cda,cd-cba) +for __b,a_b in ipairs(ada)do local b_b=_ba[a_b]local c_b=b_b/caa +local d_b=c_a(1,_aa(dda*c_b))a_b.set("height",d_b)end end end end;local _ca=1 +for dca,_da in ipairs(ad)do _da.set("y",_ca) +if not a_a then +if dd=="stretch"then +_da.set("width",b_a)_da.set("x",1 +__a)else local bda=_da.get("width")local cda=1;if +dd=="flex-end"then cda=bd-bda+1 elseif dd=="flex-center"or dd=="center"then cda= +_aa((bd-bda)/2)+1 end +_da.set("x",c_a(1,cda))end end +local ada=_da.get("x")+_da.get("width")-1;if +ada>bd and(_da.get("flexShrink")or 0)>0 then +_da.set("width",c_a(1,bd-_da.get("x")+1))end;_ca= +_ca+_da.get("height")+dc end;local aca=ad[#ad]local bca=0;if aca then +bca=aca.get("y")+aca.get("height")-1 end;local cca=cd-bca +if cca>0 then +if _d=="flex-end"then for dca,_da in ipairs(ad)do _da.set("y", +_da.get("y")+cca)end elseif _d== +"flex-center"or _d=="center"then local dca=_aa(cca/2)for _da,ada in ipairs(ad)do ada.set("y", +ada.get("y")+dca)end end end end +local function ac(bc,cc,dc,_d,ad) +if bc.get("width")<=0 or bc.get("height")<=0 then return end +cc=(cc=="row"or cc=="column")and cc or"row"local bd,cd=bc.get("width"),bc.get("height") +local dd= +bd~=bc._lastLayoutWidth or cd~=bc._lastLayoutHeight;bc._lastLayoutWidth=bd;bc._lastLayoutHeight=cd +if +ad and dd and(bd>bc._lastLayoutWidth or +cd>bc._lastLayoutHeight)then +for b_a,c_a in pairs(bc.get("children"))do +if +c_a~=bb and c_a:getVisible()and +c_a.get("flexGrow")and c_a.get("flexGrow")>0 then +if cc=="row"then +local d_a,_aa=pcall(function()return c_a.get("intrinsicWidth")end)if d_a and _aa then c_a.set("width",_aa)end else +local d_a,_aa=pcall(function()return +c_a.get("intrinsicHeight")end)if d_a and _aa then c_a.set("height",_aa)end end end end end;local __a=cb(bc,cc,dc,ad)if#__a==0 then return end +local a_a=cc=="row"and db or _c +if cc=="row"and ad then local b_a=1 +for c_a,d_a in ipairs(__a)do +if#d_a>0 then for aaa,baa in ipairs(d_a)do if baa~=bb then +baa.set("y",b_a)end end;a_a(bc,d_a,dc,_d) +local _aa=0;for aaa,baa in ipairs(d_a)do if baa~=bb then +_aa=math.max(_aa,baa.get("height"))end end;if c_a< +#__a then b_a=b_a+_aa+dc else b_a=b_a+_aa end end end elseif cc=="column"and ad then local b_a=1 +for c_a,d_a in ipairs(__a)do +if#d_a>0 then for aaa,baa in ipairs(d_a)do if baa~=bb then +baa.set("x",b_a)end end;a_a(bc,d_a,dc,_d) +local _aa=0;for aaa,baa in ipairs(d_a)do +if baa~=bb then _aa=math.max(_aa,baa.get("width"))end end;if c_a<#__a then b_a=b_a+_aa+dc else b_a= +b_a+_aa end end end else for b_a,c_a in ipairs(__a)do a_a(bc,c_a,dc,_d)end end;bc:sortChildren() +bc.set("childrenEventsSorted",false)bc.set("flexUpdateLayout",false)end +function ab.new()local bc=setmetatable({},ab):__init() +bc.class=ab;bc.set("width",12)bc.set("height",6) +bc.set("background",colors.blue)bc.set("z",10)bc._lastLayoutWidth=0;bc._lastLayoutHeight=0 +bc:observe("width",function() +bc.set("flexUpdateLayout",true)end) +bc:observe("height",function()bc.set("flexUpdateLayout",true)end) +bc:observe("flexDirection",function()bc.set("flexUpdateLayout",true)end) +bc:observe("flexSpacing",function()bc.set("flexUpdateLayout",true)end) +bc:observe("flexWrap",function()bc.set("flexUpdateLayout",true)end) +bc:observe("flexJustifyContent",function()bc.set("flexUpdateLayout",true)end) +bc:observe("flexAlignItems",function()bc.set("flexUpdateLayout",true)end) +bc:observe("flexCrossPadding",function()bc.set("flexUpdateLayout",true)end)return bc end;function ab:init(bc,cc)_b.init(self,bc,cc)self.set("type","FlexBox") +return self end +function ab:addChild(bc) +_b.addChild(self,bc) +if(bc~=bb)then +bc:instanceProperty("flexGrow",{default=0,type="number"}) +bc:instanceProperty("flexShrink",{default=0,type="number"}) +bc:instanceProperty("flexBasis",{default=0,type="number"}) +bc:instanceProperty("intrinsicWidth",{default=bc.get("width"),type="number"}) +bc:instanceProperty("intrinsicHeight",{default=bc.get("height"),type="number"}) +bc:observe("flexGrow",function()self.set("flexUpdateLayout",true)end) +bc:observe("flexShrink",function()self.set("flexUpdateLayout",true)end) +bc:observe("width",function(cc,dc,_d)if bc.get("flexGrow")==0 then +bc.set("intrinsicWidth",dc)end +self.set("flexUpdateLayout",true)end) +bc:observe("height",function(cc,dc,_d)if bc.get("flexGrow")==0 then +bc.set("intrinsicHeight",dc)end +self.set("flexUpdateLayout",true)end)end;self.set("flexUpdateLayout",true)return self end +function ab:removeChild(bc)_b.removeChild(self,bc) +if(bc~=bb)then bc.setFlexGrow=nil;bc.setFlexShrink= +nil;bc.setFlexBasis=nil;bc.getFlexGrow=nil;bc.getFlexShrink=nil;bc.getFlexBasis= +nil;bc.set("flexGrow",nil) +bc.set("flexShrink",nil)bc.set("flexBasis",nil)end;self.set("flexUpdateLayout",true)return self end;function ab:addLineBreak()self:addChild(bb)return self end +function ab:render() +if +(self.get("flexUpdateLayout"))then +ac(self,self.get("flexDirection"),self.get("flexSpacing"),self.get("flexJustifyContent"),self.get("flexWrap"))end;_b.render(self)end;return ab end +project["elements/Table.lua"] = function(...) local d=require("elements/VisualElement") +local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa +aa.defineProperty(aa,"columns",{default={},type="table",canTriggerRender=true,setter=function(ba,ca)local da={} +for _b,ab in +ipairs(ca)do +if type(ab)=="string"then da[_b]={name=ab,width=#ab+1}elseif type(ab)=="table"then +da[_b]={name= +ab.name or"",width=ab.width,minWidth=ab.minWidth or 3,maxWidth=ab.maxWidth or nil}end end;return da end}) +aa.defineProperty(aa,"data",{default={},type="table",canTriggerRender=true,setter=function(ba,ca)ba.set("scrollOffset",0) +ba.set("selectedRow",nil)ba.set("sortColumn",nil) +ba.set("sortDirection","asc")return ca end}) +aa.defineProperty(aa,"selectedRow",{default=nil,type="number",canTriggerRender=true}) +aa.defineProperty(aa,"headerColor",{default=colors.blue,type="color"}) +aa.defineProperty(aa,"selectedColor",{default=colors.lightBlue,type="color"}) +aa.defineProperty(aa,"gridColor",{default=colors.gray,type="color"}) +aa.defineProperty(aa,"sortColumn",{default=nil,type="number",canTriggerRender=true}) +aa.defineProperty(aa,"sortDirection",{default="asc",type="string",canTriggerRender=true}) +aa.defineProperty(aa,"scrollOffset",{default=0,type="number",canTriggerRender=true}) +aa.defineProperty(aa,"customSortFunction",{default={},type="table"})aa.defineEvent(aa,"mouse_click") +aa.defineEvent(aa,"mouse_scroll")function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;ba.set("width",30)ba.set("height",10)ba.set("z",5) +return ba end +function aa:init(ba,ca) +d.init(self,ba,ca)self.set("type","Table")return self end +function aa:addColumn(ba,ca)local da=self.get("columns") +table.insert(da,{name=ba,width=ca})self.set("columns",da)return self end;function aa:addData(...)local ba=self.get("data")table.insert(ba,{...}) +self.set("data",ba)return self end +function aa:setColumnSortFunction(ba,ca) +local da=self.get("customSortFunction")da[ba]=ca;self.set("customSortFunction",da)return self end +function aa:setFormattedData(ba,ca)local da={}for _b,ab in ipairs(ba)do local bb={}for cb,db in ipairs(ab)do bb[cb]=db end;if ca and +ca[_b]then bb._sortValues=ca[_b]end +table.insert(da,bb)end +self.set("data",da)return self end +function aa:setData(ba,ca)if not ca then self.set("data",ba)return self end +local da={} +for _b,ab in ipairs(ba)do local bb={}for cb,db in ipairs(ab)do +if ca[cb]then bb[cb]=ca[cb](db)else bb[cb]=db end end;table.insert(da,bb)end;return self:setFormattedData(da,ba)end +function aa:calculateColumnWidths(ba,ca)local da={}local _b=ca;local ab={}local bb=0 +for db,_c in ipairs(ba)do +da[db]={name=_c.name,width=_c.width,minWidth=_c.minWidth or 3,maxWidth=_c.maxWidth} +if type(_c.width)=="number"then +da[db].visibleWidth=math.max(_c.width,da[db].minWidth)if da[db].maxWidth then +da[db].visibleWidth=math.min(da[db].visibleWidth,da[db].maxWidth)end +_b=_b-da[db].visibleWidth;bb=bb+da[db].visibleWidth elseif type(_c.width)=="string"and +_c.width:match("%%$")then +local ac=tonumber(_c.width:match("(%d+)%%")) +if ac then da[db].visibleWidth=math.floor(ca*ac/100) +da[db].visibleWidth=math.max(da[db].visibleWidth,da[db].minWidth)if da[db].maxWidth then +da[db].visibleWidth=math.min(da[db].visibleWidth,da[db].maxWidth)end +_b=_b-da[db].visibleWidth;bb=bb+da[db].visibleWidth else table.insert(ab,db)end else table.insert(ab,db)end end +if#ab>0 and _b>0 then local db=math.floor(_b/#ab) +for _c,ac in ipairs(ab)do +da[ac].visibleWidth=math.max(db,da[ac].minWidth)if da[ac].maxWidth then +da[ac].visibleWidth=math.min(da[ac].visibleWidth,da[ac].maxWidth)end end end;local cb=0 +for db,_c in ipairs(da)do cb=cb+ (_c.visibleWidth or 0)end;if cb>ca then local db=ca/cb +for _c,ac in ipairs(da)do if ac.visibleWidth then +ac.visibleWidth=math.max(1,math.floor(ac.visibleWidth*db))end end end +return da end +function aa:sortData(ba,ca)local da=self.get("data") +local _b=self.get("sortDirection")local ab=self.get("customSortFunction")local bb=ca or ab[ba] +if bb then +table.sort(da,function(cb,db)return +bb(cb,db,_b)end)else +table.sort(da,function(cb,db)if not cb or not db then return false end;local _c,ac +if cb._sortValues and +cb._sortValues[ba]then _c=cb._sortValues[ba]else _c=cb[ba]end;if db._sortValues and db._sortValues[ba]then ac=db._sortValues[ba]else +ac=db[ba]end +if type(_c)=="number"and +type(ac)=="number"then if _b=="asc"then return _cac end else local bc=tostring( +_c or"")local cc=tostring(ac or"")if _b=="asc"then +return bccc end end end)end;return self end +function aa:mouse_click(ba,ca,da) +if not d.mouse_click(self,ba,ca,da)then return false end;local _b,ab=self:getRelativePosition(ca,da) +if ab==1 then +local bb=self.get("columns")local cb=self.get("width") +local db=self:calculateColumnWidths(bb,cb)local _c=1 +for ac,bc in ipairs(db)do +local cc=bc.visibleWidth or bc.width or 10 +if _b>=_c and _b<_c+cc then +if self.get("sortColumn")==ac then +self.set("sortDirection", +self.get("sortDirection")=="asc"and"desc"or"asc")else self.set("sortColumn",ac) +self.set("sortDirection","asc")end;self:sortData(ac)break end;_c=_c+cc end end +if ab>1 then local bb=ab-2 +self.get("scrollOffset")if bb>=0 and bb<# +self.get("data")then +self.set("selectedRow",bb+1)end end;return true end +function aa:mouse_scroll(ba,ca,da) +if(d.mouse_scroll(self,ba,ca,da))then local _b=self.get("data") +local ab=self.get("height")local bb=ab-2;local cb=math.max(0,#_b-bb-1) +local db=math.min(cb,math.max(0, +self.get("scrollOffset")+ba))self.set("scrollOffset",db)return true end;return false end +function aa:render()d.render(self)local ba=self.get("columns") +local ca=self.get("data")local da=self.get("selectedRow") +local _b=self.get("sortColumn")local ab=self.get("scrollOffset")local bb=self.get("height") +local cb=self.get("width")local db=self:calculateColumnWidths(ba,cb)local _c=0;local ac=#db;for cc,dc in +ipairs(db)do if _c+dc.visibleWidth>cb then ac=cc-1;break end +_c=_c+dc.visibleWidth end;local bc=1 +for cc,dc in ipairs(db)do +if cc>ac then break end;local _d=dc.name;if cc==_b then +_d=_d.. ( +self.get("sortDirection")=="asc"and"\30"or"\31")end +self:textFg(bc,1,_d:sub(1,dc.visibleWidth),self.get("headerColor"))bc=bc+dc.visibleWidth end +for y=2,bb do local cc=y-2 +ab;local dc=ca[cc+1] +if dc and(cc+1)<=#ca then bc=1 +local _d=(cc+1)==da and +self.get("selectedColor")or self.get("background") +for ad,bd in ipairs(db)do if ad>ac then break end;local cd=tostring(dc[ad]or"")local dd=cd..string.rep(" ", +bd.visibleWidth-#cd)if +ad=cb and bb=bc and cc0 and-1 or 1;local db=self.get("step") +local _c=self.get("value")local ac=_c-ab*db +self.set("value",math.min(100,math.max(0,ac)))self:updateAttachedElement()return true end +function ca:render()aa.render(self)local ab=da(self)local bb=self.get("value") +local cb=self.get("handleSize")local db=self.get("symbol")local _c=self.get("symbolColor") +local ac=self.get("symbolBackgroundColor")local bc=self.get("backgroundSymbol")local cc=self.get("orientation")== +"vertical"local dc= +math.floor((bb/100)* (ab-cb))+1 +for i=1,ab do +if cc then +self:blit(1,i,bc,ba[self.get("foreground")],ba[self.get("background")])else +self:blit(i,1,bc,ba[self.get("foreground")],ba[self.get("background")])end end +for i=dc,dc+cb-1 do if cc then self:blit(1,i,db,ba[_c],ba[ac])else +self:blit(i,1,db,ba[_c],ba[ac])end end end;return ca end +project["elements/VisualElement.lua"] = function(...) local ba=require("elementManager") +local ca=ba.getElement("BaseElement")local da=require("libraries/colorHex") +local _b=setmetatable({},ca)_b.__index=_b +_b.defineProperty(_b,"x",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"y",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"z",{default=1,type="number",canTriggerRender=true,setter=function(cb,db) +if cb.parent then cb.parent:sortChildren()end;return db end}) +_b.defineProperty(_b,"width",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"height",{default=1,type="number",canTriggerRender=true}) +_b.defineProperty(_b,"background",{default=colors.black,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"foreground",{default=colors.white,type="color",canTriggerRender=true}) +_b.defineProperty(_b,"clicked",{default=false,type="boolean"}) +_b.defineProperty(_b,"hover",{default=false,type="boolean"}) +_b.defineProperty(_b,"backgroundEnabled",{default=true,type="boolean",canTriggerRender=true}) +_b.defineProperty(_b,"focused",{default=false,type="boolean",setter=function(cb,db,_c)local ac=cb.get("focused") +if db==ac then return db end;if db then cb:focus()else cb:blur()end;if not _c and cb.parent then +if db then +cb.parent:setFocusedChild(cb)else cb.parent:setFocusedChild(nil)end end;return db end}) +_b.defineProperty(_b,"visible",{default=true,type="boolean",canTriggerRender=true,setter=function(cb,db) +if(cb.parent~=nil)then +cb.parent.set("childrenSorted",false)cb.parent.set("childrenEventsSorted",false)end;if(db==false)then cb.set("clicked",false)end;return db end}) +_b.defineProperty(_b,"ignoreOffset",{default=false,type="boolean"})_b.combineProperties(_b,"position","x","y") +_b.combineProperties(_b,"size","width","height") +_b.combineProperties(_b,"color","foreground","background")_b.defineEvent(_b,"focus") +_b.defineEvent(_b,"blur") +_b.registerEventCallback(_b,"Click","mouse_click","mouse_up") +_b.registerEventCallback(_b,"ClickUp","mouse_up","mouse_click") +_b.registerEventCallback(_b,"Drag","mouse_drag","mouse_click","mouse_up") +_b.registerEventCallback(_b,"Scroll","mouse_scroll") +_b.registerEventCallback(_b,"Enter","mouse_enter","mouse_move") +_b.registerEventCallback(_b,"LeEave","mouse_leave","mouse_move")_b.registerEventCallback(_b,"Focus","focus","blur") +_b.registerEventCallback(_b,"Blur","blur","focus")_b.registerEventCallback(_b,"Key","key","key_up") +_b.registerEventCallback(_b,"Char","char")_b.registerEventCallback(_b,"KeyUp","key_up","key") +local ab,bb=math.max,math.min;function _b.new()local cb=setmetatable({},_b):__init() +cb.class=_b;return cb end +function _b:init(cb,db) +ca.init(self,cb,db)self.set("type","VisualElement") +self:observe("x",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("y",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("width",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("height",function()if self.parent then +self.parent.set("childrenSorted",false)end end) +self:observe("visible",function()if self.parent then +self.parent.set("childrenSorted",false)end end)end +function _b:multiBlit(cb,db,_c,ac,bc,cc,dc)local _d,ad=self:calculatePosition()cb=cb+_d-1 +db=db+ad-1;self.parent:multiBlit(cb,db,_c,ac,bc,cc,dc)end +function _b:textFg(cb,db,_c,ac)local bc,cc=self:calculatePosition()cb=cb+bc-1 +db=db+cc-1;self.parent:textFg(cb,db,_c,ac)end +function _b:textBg(cb,db,_c,ac)local bc,cc=self:calculatePosition()cb=cb+bc-1 +db=db+cc-1;self.parent:textBg(cb,db,_c,ac)end +function _b:drawText(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 +db=db+bc-1;self.parent:drawText(cb,db,_c)end +function _b:drawFg(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 +db=db+bc-1;self.parent:drawFg(cb,db,_c)end +function _b:drawBg(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 +db=db+bc-1;self.parent:drawBg(cb,db,_c)end +function _b:blit(cb,db,_c,ac,bc)local cc,dc=self:calculatePosition()cb=cb+cc-1 +db=db+dc-1;self.parent:blit(cb,db,_c,ac,bc)end +function _b:isInBounds(cb,db)local _c,ac=self.get("x"),self.get("y") +local bc,cc=self.get("width"),self.get("height")if(self.get("ignoreOffset"))then +if(self.parent)then +cb=cb-self.parent.get("offsetX")db=db-self.parent.get("offsetY")end end;return +cb>=_c and cb<= +_c+bc-1 and db>=ac and db<=ac+cc-1 end +function _b:mouse_click(cb,db,_c)if self:isInBounds(db,_c)then self.set("clicked",true) +self:fireEvent("mouse_click",cb,self:getRelativePosition(db,_c))return true end;return +false end +function _b:mouse_up(cb,db,_c)if self:isInBounds(db,_c)then self.set("clicked",false) +self:fireEvent("mouse_up",cb,self:getRelativePosition(db,_c))return true end;return +false end +function _b:mouse_release(cb,db,_c) +self:fireEvent("mouse_release",cb,self:getRelativePosition(db,_c))self.set("clicked",false)end +function _b:mouse_move(cb,db,_c)if(db==nil)or(_c==nil)then return end +local ac=self.get("hover") +if(self:isInBounds(db,_c))then if(not ac)then self.set("hover",true) +self:fireEvent("mouse_enter",self:getRelativePosition(db,_c))end;return true else if(ac)then +self.set("hover",false) +self:fireEvent("mouse_leave",self:getRelativePosition(db,_c))end end;return false end +function _b:mouse_scroll(cb,db,_c)if(self:isInBounds(db,_c))then +self:fireEvent("mouse_scroll",cb,self:getRelativePosition(db,_c))return true end;return false end +function _b:mouse_drag(cb,db,_c)if(self.get("clicked"))then +self:fireEvent("mouse_drag",cb,self:getRelativePosition(db,_c))return true end;return false end;function _b:focus()self:fireEvent("focus")end;function _b:blur() +self:fireEvent("blur")self:setCursor(1,1,false)end +function _b:key(cb,db)if +(self.get("focused"))then self:fireEvent("key",cb,db)end end;function _b:key_up(cb) +if(self.get("focused"))then self:fireEvent("key_up",cb)end end;function _b:char(cb)if(self.get("focused"))then +self:fireEvent("char",cb)end end +function _b:calculatePosition() +local cb,db=self.get("x"),self.get("y") +if not self.get("ignoreOffset")then if self.parent~=nil then +local _c,ac=self.parent.get("offsetX"),self.parent.get("offsetY")cb=cb-_c;db=db-ac end end;return cb,db end +function _b:getAbsolutePosition(cb,db)local _c,ac=self.get("x"),self.get("y")if(cb~=nil)then +_c=_c+cb-1 end;if(db~=nil)then ac=ac+db-1 end;local bc=self.parent +while bc do +local cc,dc=bc.get("x"),bc.get("y")_c=_c+cc-1;ac=ac+dc-1;bc=bc.parent end;return _c,ac end +function _b:getRelativePosition(cb,db)if(cb==nil)or(db==nil)then +cb,db=self.get("x"),self.get("y")end;local _c,ac=1,1;if self.parent then +_c,ac=self.parent:getRelativePosition()end +local bc,cc=self.get("x"),self.get("y")return cb- (bc-1)- (_c-1),db- (cc-1)- (ac-1)end +function _b:setCursor(cb,db,_c,ac) +if self.parent then local bc,cc=self:calculatePosition() +if +(cb+bc-1 <1)or( +cb+bc-1 >self.parent.get("width"))or(db+cc-1 <1)or(db+cc-1 > +self.parent.get("height"))then return self.parent:setCursor( +cb+bc-1,db+cc-1,false)end +return self.parent:setCursor(cb+bc-1,db+cc-1,_c,ac)end;return self end +function _b:prioritize() +if(self.parent)then local cb=self.parent;cb:removeChild(self) +cb:addChild(self)self:updateRender()end;return self end +function _b:render() +if(not self.get("backgroundEnabled"))then return end;local cb,db=self.get("width"),self.get("height") +self:multiBlit(1,1,cb,db," ",da[self.get("foreground")],da[self.get("background")])end;function _b:postRender()end;function _b:destroy()self.set("visible",false) +ca.destroy(self)end;return _b end +project["elements/ProgressBar.lua"] = function(...) local d=require("elements/VisualElement") +local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa +aa.defineProperty(aa,"progress",{default=0,type="number",canTriggerRender=true}) +aa.defineProperty(aa,"showPercentage",{default=false,type="boolean"}) +aa.defineProperty(aa,"progressColor",{default=colors.black,type="color"}) +aa.defineProperty(aa,"direction",{default="right",type="string"}) +function aa.new()local ba=setmetatable({},aa):__init() +ba.class=aa;ba.set("width",25)ba.set("height",3)return ba end;function aa:init(ba,ca)d.init(self,ba,ca) +self.set("type","ProgressBar")end +function aa:render()d.render(self) +local ba=self.get("width")local ca=self.get("height") +local da=math.min(100,math.max(0,self.get("progress")))local _b=math.floor((ba*da)/100) +local ab=math.floor((ca*da)/100)local bb=self.get("direction") +local cb=self.get("progressColor") +if bb=="right"then +self:multiBlit(1,1,_b,ca," ",_a[self.get("foreground")],_a[cb])elseif bb=="left"then +self:multiBlit(ba-_b+1,1,_b,ca," ",_a[self.get("foreground")],_a[cb])elseif bb=="up"then +self:multiBlit(1,ca-ab+1,ba,ab," ",_a[self.get("foreground")],_a[cb])elseif bb=="down"then +self:multiBlit(1,1,ba,ab," ",_a[self.get("foreground")],_a[cb])end +if self.get("showPercentage")then local db=tostring(da).."%"local _c=math.floor( +(ba-#db)/2)+1 +local ac=math.floor((ca-1)/2)+1 +self:textFg(_c,ac,db,self.get("foreground"))end end;return aa end +project["elements/CheckBox.lua"] = function(...) local c=require("elements/VisualElement") +local d=setmetatable({},c)d.__index=d +d.defineProperty(d,"checked",{default=false,type="boolean",canTriggerRender=true}) +d.defineProperty(d,"text",{default=" ",type="string",canTriggerRender=true,setter=function(_a,aa)local ba=_a.get("checkedText") +local ca=math.max(#aa,#ba)if(_a.get("autoSize"))then _a.set("width",ca)end;return aa end}) +d.defineProperty(d,"checkedText",{default="x",type="string",canTriggerRender=true,setter=function(_a,aa)local ba=_a.get("text") +local ca=math.max(#aa,#ba)if(_a.get("autoSize"))then _a.set("width",ca)end;return aa end}) +d.defineProperty(d,"autoSize",{default=true,type="boolean"})d.defineEvent(d,"mouse_click") +d.defineEvent(d,"mouse_up")function d.new()local _a=setmetatable({},d):__init()_a.class=d +_a.set("backgroundEnabled",false)return _a end +function d:init(_a,aa) +c.init(self,_a,aa)self.set("type","CheckBox")end +function d:mouse_click(_a,aa,ba)if c.mouse_click(self,_a,aa,ba)then +self.set("checked",not self.get("checked"))return true end;return false end +function d:render()c.render(self)local _a=self.get("checked") +local aa=self.get("text")local ba=self.get("checkedText") +local ca=string.sub(_a and ba or aa,1,self.get("width"))self:textFg(1,1,ca,self.get("foreground"))end;return d end +project["elements/BaseElement.lua"] = function(...) local _a=require("propertySystem") +local aa=require("libraries/utils").uuid;local ba=require("errorManager")local ca=setmetatable({},_a) +ca.__index=ca +ca.defineProperty(ca,"type",{default={"BaseElement"},type="string",setter=function(da,_b)if type(_b)=="string"then +table.insert(da._values.type,1,_b)return da._values.type end;return _b end,getter=function(da,_b,ab)if +ab~=nil and ab<1 then return da._values.type end;return da._values.type[ +ab or 1]end}) +ca.defineProperty(ca,"id",{default="",type="string",readonly=true}) +ca.defineProperty(ca,"name",{default="",type="string"}) +ca.defineProperty(ca,"eventCallbacks",{default={},type="table"}) +ca.defineProperty(ca,"enabled",{default=true,type="boolean"}) +function ca.defineEvent(da,_b,ab) +if not rawget(da,'_eventConfigs')then da._eventConfigs={}end;da._eventConfigs[_b]={requires=ab and ab or _b}end +function ca.registerEventCallback(da,_b,...) +local ab=_b:match("^on")and _b or"on".._b;local bb={...}local cb=bb[1] +da[ab]=function(db,...) +for _c,ac in ipairs(bb)do if not db._registeredEvents[ac]then +db:listenEvent(ac,true)end end;db:registerCallback(cb,...)return db end end;function ca.new()local da=setmetatable({},ca):__init() +da.class=ca;return da end +function ca:init(da,_b) +if self._initialized then return self end;self._initialized=true;self._props=da;self._values.id=aa() +self.basalt=_b;self._registeredEvents={}local ab=getmetatable(self).__index +local bb={}ab=self.class +while ab do +if type(ab)=="table"and ab._eventConfigs then for cb,db in +pairs(ab._eventConfigs)do if not bb[cb]then bb[cb]=db end end end +ab=getmetatable(ab)and getmetatable(ab).__index end +for cb,db in pairs(bb)do self._registeredEvents[db.requires]=true end;if self._callbacks then +for cb,db in pairs(self._callbacks)do self[db]=function(_c,...) +_c:registerCallback(cb,...)return _c end end end +return self end +function ca:postInit()if self._postInitialized then return self end +self._postInitialized=true;if(self._props)then +for da,_b in pairs(self._props)do self.set(da,_b)end end;self._props=nil;return self end;function ca:isType(da) +for _b,ab in ipairs(self._values.type)do if ab==da then return true end end;return false end +function ca:listenEvent(da,_b)_b= +_b~=false +if +_b~= (self._registeredEvents[da]or false)then +if _b then self._registeredEvents[da]=true;if self.parent then +self.parent:registerChildEvent(self,da)end else self._registeredEvents[da]=nil +if +self.parent then self.parent:unregisterChildEvent(self,da)end end end;return self end +function ca:registerCallback(da,_b)if not self._registeredEvents[da]then +self:listenEvent(da,true)end +if +not self._values.eventCallbacks[da]then self._values.eventCallbacks[da]={}end +table.insert(self._values.eventCallbacks[da],_b)return self end +function ca:fireEvent(da,...) +if self.get("eventCallbacks")[da]then for _b,ab in +ipairs(self.get("eventCallbacks")[da])do local bb=ab(self,...)return bb end end;return self end +function ca:dispatchEvent(da,...) +if self.get("enabled")==false then return false end;if self[da]then return self[da](self,...)end;return +self:handleEvent(da,...)end;function ca:handleEvent(da,...)return false end;function ca:onChange(da,_b) +self:observe(da,_b)return self end +function ca:getBaseFrame()if self.parent then return +self.parent:getBaseFrame()end;return self end;function ca:destroy() +if(self.parent)then self.parent:removeChild(self)end;self._destroyed=true;self:removeAllObservers() +self:setFocused(false)end;function ca:updateRender() +if +(self.parent)then self.parent:updateRender()else self._renderUpdate=true end;return self end;return ca end +project["elements/List.lua"] = function(...) local c=require("elements/VisualElement") +local d=setmetatable({},c)d.__index=d +d.defineProperty(d,"items",{default={},type="table",canTriggerRender=true}) +d.defineProperty(d,"selectable",{default=true,type="boolean"}) +d.defineProperty(d,"multiSelection",{default=false,type="boolean"}) +d.defineProperty(d,"offset",{default=0,type="number",canTriggerRender=true}) +d.defineProperty(d,"selectedBackground",{default=colors.blue,type="color"}) +d.defineProperty(d,"selectedForeground",{default=colors.white,type="color"})d.defineEvent(d,"mouse_click") +d.defineEvent(d,"mouse_scroll") +function d.new()local _a=setmetatable({},d):__init()_a.class=d +_a.set("width",16)_a.set("height",8)_a.set("z",5) +_a.set("background",colors.gray)return _a end +function d:init(_a,aa)c.init(self,_a,aa)self.set("type","List")return self end;function d:addItem(_a)local aa=self.get("items")table.insert(aa,_a) +self:updateRender()return self end +function d:removeItem(_a) +local aa=self.get("items")table.remove(aa,_a)self:updateRender()return self end +function d:clear()self.set("items",{})self:updateRender()return self end +function d:getSelectedItems()local _a={}for aa,ba in ipairs(self.get("items"))do +if +type(ba)=="table"and ba.selected then local ca=ba;ca.index=aa;table.insert(_a,ca)end end;return _a end +function d:getSelectedItem()local _a=self.get("items")for aa,ba in ipairs(_a)do if +type(ba)=="table"and ba.selected then return ba end end;return +nil end +function d:mouse_click(_a,aa,ba) +if +self:isInBounds(aa,ba)and self.get("selectable")then local ca,da=self:getRelativePosition(aa,ba) +local _b=da+self.get("offset")local ab=self.get("items") +if _b<=#ab then local bb=ab[_b]if type(bb)=="string"then +bb={text=bb}ab[_b]=bb end;if +not self.get("multiSelection")then +for cb,db in ipairs(ab)do if type(db)=="table"then db.selected=false end end end +bb.selected=not bb.selected;if bb.callback then bb.callback(self)end +self:fireEvent("mouse_click",_a,aa,ba)self:fireEvent("select",_b,bb)self:updateRender()end;return true end;return false end +function d:mouse_scroll(_a,aa,ba) +if self:isInBounds(aa,ba)then local ca=self.get("offset") +local da=math.max(0,# +self.get("items")-self.get("height"))ca=math.min(da,math.max(0,ca+_a)) +self.set("offset",ca)self:fireEvent("mouse_scroll",_a,aa,ba)return true end;return false end +function d:onSelect(_a)self:registerCallback("select",_a)return self end +function d:scrollToBottom() +local _a=math.max(0,#self.get("items")-self.get("height"))self.set("offset",_a)return self end;function d:scrollToTop()self.set("offset",0)return self end +function d:render() +c.render(self)local _a=self.get("items")local aa=self.get("height") +local ba=self.get("offset")local ca=self.get("width") +for i=1,aa do local da=i+ba;local _b=_a[da] +if _b then if +type(_b)=="string"then _b={text=_b}_a[da]=_b end +if _b.separator then +local ab=(_b.text or"-"):sub(1,1)local bb=string.rep(ab,ca) +local cb=_b.foreground or self.get("foreground")local db=_b.background or self.get("background") +self:textBg(1,i,string.rep(" ",ca),db)self:textFg(1,i,bb:sub(1,ca),cb)else local ab=_b.text +local bb=_b.selected +local cb= +bb and(_b.selectedBackground or self.get("selectedBackground"))or(_b.background or self.get("background")) +local db= +bb and(_b.selectedForeground or self.get("selectedForeground"))or(_b.foreground or self.get("foreground"))self:textBg(1,i,string.rep(" ",ca),cb) +self:textFg(1,i,ab:sub(1,ca),db)end end end end;return d end +project["plugins/canvas.lua"] = function(...) local ba=require("libraries/colorHex") +local ca=require("errorManager")local da={}da.__index=da;local _b,ab=string.sub,string.rep +function da.new(cb) +local db=setmetatable({},da)db.commands={pre={},post={}}db.type="pre"db.element=cb;return db end +function da:clear()self.commands={pre={},post={}}return self end;function da:getValue(cb) +if type(cb)=="function"then return cb(self.element)end;return cb end +function da:setType(cb)if +cb=="pre"or cb=="post"then self.type=cb else +ca.error("Invalid type. Use 'pre' or 'post'.")end;return self end +function da:addCommand(cb) +local db=#self.commands[self.type]+1;self.commands[self.type][db]=cb;return db end +function da:setCommand(cb,db)self.commands[cb]=db;return self end;function da:removeCommand(cb) +table.remove(self.commands[self.type],cb)return self end +function da:text(cb,db,_c,ac,bc) +return +self:addCommand(function(cc) +local dc,_d=self:getValue(cb),self:getValue(db)local ad=self:getValue(_c)local bd=self:getValue(ac) +local cd=self:getValue(bc) +local dd=type(bd)=="number"and ba[bd]:rep(#_c)or bd +local __a=type(cd)=="number"and ba[cd]:rep(#_c)or cd;cc:drawText(dc,_d,ad) +if dd then cc:drawFg(dc,_d,dd)end;if __a then cc:drawBg(dc,_d,__a)end end)end;function da:bg(cb,db,_c)return +self:addCommand(function(ac)ac:drawBg(cb,db,_c)end)end +function da:fg(cb,db,_c)return self:addCommand(function(ac) +ac:drawFg(cb,db,_c)end)end +function da:rect(cb,db,_c,ac,bc,cc,dc) +return +self:addCommand(function(_d)local ad,bd=self:getValue(cb),self:getValue(db) +local cd,dd=self:getValue(_c),self:getValue(ac)local __a=self:getValue(bc)local a_a=self:getValue(cc) +local b_a=self:getValue(dc)if(type(a_a)=="number")then a_a=ba[a_a]end;if +(type(b_a)=="number")then b_a=ba[b_a]end +local c_a=b_a and _b(b_a:rep(cd),1,cd)local d_a=a_a and _b(a_a:rep(cd),1,cd)local _aa=__a and +_b(__a:rep(cd),1,cd) +for i=0,dd-1 do +if b_a then _d:drawBg(ad,bd+i,c_a)end;if a_a then _d:drawFg(ad,bd+i,d_a)end;if __a then +_d:drawText(ad,bd+i,_aa)end end end)end +function da:line(cb,db,_c,ac,bc,cc,dc) +local function _d(cd,dd,__a,a_a)local b_a={}local c_a=0;local d_a=math.abs(__a-cd) +local _aa=math.abs(a_a-dd)local aaa=(cd<__a)and 1 or-1 +local baa=(dd-_aa then caa=caa-_aa;cd=cd+aaa end;if daa0 do +aaa=aaa-1;daa=daa-2 *c_a;if baa>0 then baa=baa+c_a-daa else _aa=_aa+1 +caa=caa+2 *d_a;baa=baa+c_a-daa+caa end +_ba(_aa,aaa)end +return a_a end;local ad=_d(cb,db,_c,ac) +return +self:addCommand(function(bd)local cd=self:getValue(bc) +local dd=self:getValue(cc)local __a=self:getValue(dc) +local a_a=type(dd)=="number"and ba[dd]or dd +local b_a=type(__a)=="number"and ba[__a]or __a +for c_a,d_a in pairs(ad)do local _aa=math.floor(d_a.x)local aaa=math.floor(d_a.y)if cd then +bd:drawText(_aa,aaa,cd)end;if a_a then bd:drawFg(_aa,aaa,a_a)end;if b_a then +bd:drawBg(_aa,aaa,b_a)end end end)end;local bb={hooks={}} +function bb.setup(cb) +cb.defineProperty(cb,"canvas",{default=nil,type="table",getter=function(db)if not db._values.canvas then +db._values.canvas=da.new(db)end;return db._values.canvas end})end;function bb.hooks.render(cb)local db=cb.get("canvas") +if +db and#db.commands.pre>0 then for _c,ac in pairs(db.commands.pre)do ac(cb)end end end +function bb.hooks.postRender(cb) +local db=cb.get("canvas")if db and#db.commands.post>0 then for _c,ac in pairs(db.commands.post)do +ac(cb)end end end;return{VisualElement=bb,API=da} end +project["plugins/theme.lua"] = function(...) local ab=require("errorManager") +local bb={default={background=colors.lightGray,foreground=colors.black},BaseFrame={background=colors.white,foreground=colors.black,Frame={background=colors.black,names={basaltDebugLogClose={background=colors.blue,foreground=colors.white}}},Button={background="{self.clicked and colors.black or colors.cyan}",foreground="{self.clicked and colors.cyan or colors.black}"},names={basaltDebugLog={background=colors.red,foreground=colors.white},test={background="{self.clicked and colors.black or colors.green}",foreground="{self.clicked and colors.green or colors.black}"}}}}local cb={default=bb}local db="default" +local _c={hooks={postInit={pre=function(ad)if ad._postInitialized then return ad end +ad:applyTheme()end}}} +function _c.____getElementPath(ad,bd)if bd then table.insert(bd,1,ad._values.type)else +bd={ad._values.type}end;local cd=ad.parent;if cd then return +cd.____getElementPath(cd,bd)else return bd end end +local function ac(ad,bd)local cd=ad +for i=1,#bd do local dd=false;local __a=bd[i]for a_a,b_a in ipairs(__a)do +if cd[b_a]then cd=cd[b_a]dd=true;break end end;if not dd then return nil end end;return cd end +local function bc(ad,bd)local cd={} +if ad.default then for dd,__a in pairs(ad.default)do +if type(__a)~="table"then cd[dd]=__a end end;if ad.default[bd]then +for dd,__a in +pairs(ad.default[bd])do if type(__a)~="table"then cd[dd]=__a end end end end;return cd end +local function cc(ad,bd,cd,dd,__a) +if +bd.default and bd.default.names and bd.default.names[dd]then for a_a,b_a in pairs(bd.default.names[dd])do +if type(b_a)~="table"then ad[a_a]=b_a end end end +if + +bd.default and bd.default[cd]and bd.default[cd].names and bd.default[cd].names[dd]then +for a_a,b_a in pairs(bd.default[cd].names[dd])do if +type(b_a)~="table"then ad[a_a]=b_a end end end;if __a and __a.names and __a.names[dd]then +for a_a,b_a in pairs(__a.names[dd])do if +type(b_a)~="table"then ad[a_a]=b_a end end end end +local function dc(ad,bd,cd,dd)local __a={}local a_a=ac(ad,bd) +if a_a then for b_a,c_a in pairs(a_a)do +if type(c_a)~="table"then __a[b_a]=c_a end end end;if next(__a)==nil then __a=bc(ad,cd)end +cc(__a,ad,cd,dd,a_a)return __a end +function _c:applyTheme(ad)local bd=self:getTheme() +if(bd~=nil)then +for cd,dd in pairs(bd)do +local __a=self._properties[cd] +if(__a)then +if( (__a.type)=="color")then if(type(dd)=="string")then +if(colors[dd])then dd=colors[dd]end end end;self.set(cd,dd)end end end +if(ad~=false)then if(self:isType("Container"))then local cd=self.get("children") +for dd,__a in +ipairs(cd)do if(__a and __a.applyTheme)then __a:applyTheme()end end end end;return self end +function _c:getTheme()local ad=self:____getElementPath() +local bd=self.get("type")local cd=self.get("name")return dc(cb[db],ad,bd,cd)end;local _d={}function _d.setTheme(ad)cb.default=ad end +function _d.getTheme()return cb.default end +function _d.loadTheme(ad)local bd=fs.open(ad,"r") +if bd then local cd=bd.readAll()bd.close() +cb.default=textutils.unserializeJSON(cd)if not cb.default then +ab.error("Failed to load theme from "..ad)end else +ab.error("Could not open theme file: "..ad)end end;return{BaseElement=_c,API=_d} end +project["plugins/reactive.lua"] = function(...) local ab=require("errorManager") +local bb=require("propertySystem")local cb={colors=true,math=true,clamp=true,round=true} +local db={clamp=function(ad,bd,cd)return +math.min(math.max(ad,bd),cd)end,round=function(ad) +return math.floor(ad+0.5)end,floor=math.floor,ceil=math.ceil,abs=math.abs} +local function _c(ad,bd,cd)ad=ad:gsub("^{(.+)}$","%1") +ad=ad:gsub("([%w_]+)%$([%w_]+)",function(b_a,c_a) +if b_a=="self"then return +string.format('__getState("%s")',c_a)elseif b_a=="parent"then return +string.format('__getParentState("%s")',c_a)else return +string.format('__getElementState("%s", "%s")',b_a,c_a)end end) +ad=ad:gsub("([%w_]+)%.([%w_]+)",function(b_a,c_a)if cb[b_a]then return b_a.."."..c_a end;if +tonumber(b_a)then return b_a.."."..c_a end;return +string.format('__getProperty("%s", "%s")',b_a,c_a)end) +local dd=setmetatable({colors=colors,math=math,tostring=tostring,tonumber=tonumber,__getState=function(b_a)return bd:getState(b_a)end,__getParentState=function(b_a)return +bd.parent:getState(b_a)end,__getElementState=function(b_a,c_a)if tonumber(b_a)then return nil end +local d_a=bd:getBaseFrame():getChild(b_a)if not d_a then ab.header="Reactive evaluation error" +ab.error("Could not find element: "..b_a)return nil end;return +d_a:getState(c_a).value end,__getProperty=function(b_a,c_a)if +tonumber(b_a)then return nil end +if b_a=="self"then return bd.get(c_a)elseif b_a=="parent"then return +bd.parent.get(c_a)else local d_a=bd.parent:getChild(b_a)if not d_a then +ab.header="Reactive evaluation error" +ab.error("Could not find element: "..b_a)return nil end +return d_a.get(c_a)end end},{__index=db})if(bd._properties[cd].type=="string")then +ad="tostring("..ad..")"elseif(bd._properties[cd].type=="number")then +ad="tonumber("..ad..")"end;local __a,a_a=load("return ".. +ad,"reactive","t",dd) +if not __a then +ab.header="Reactive evaluation error"ab.error("Invalid expression: "..a_a)return +function()return nil end end;return __a end +local function ac(ad,bd) +for cd in ad:gmatch("([%w_]+)%.")do +if not cb[cd]then +if cd=="self"then elseif cd=="parent"then +if not bd.parent then +ab.header="Reactive evaluation error"ab.error("No parent element available")return false end else +if(tonumber(cd)==nil)then local dd=bd.parent:getChild(cd)if not dd then +ab.header="Reactive evaluation error" +ab.error("Referenced element not found: "..cd)return false end end end end end;return true end;local bc=setmetatable({},{__mode="k"}) +local cc=setmetatable({},{__mode="k",__index=function(ad,bd)ad[bd]={} +return ad[bd]end}) +local function dc(ad,bd,cd) +if cc[ad][cd]then for __a,a_a in ipairs(cc[ad][cd])do +a_a.target:removeObserver(a_a.property,a_a.callback)end end;local dd={} +for __a,a_a in bd:gmatch("([%w_]+)%.([%w_]+)")do +if not cb[__a]then local b_a;if __a=="self"then b_a=ad elseif +__a=="parent"then b_a=ad.parent else +b_a=ad:getBaseFrame():getChild(__a)end;if b_a then +local c_a={target=b_a,property=a_a,callback=function() +ad:updateRender()end}b_a:observe(a_a,c_a.callback) +table.insert(dd,c_a)end end end;cc[ad][cd]=dd end +bb.addSetterHook(function(ad,bd,cd,dd) +if type(cd)=="string"and cd:match("^{.+}$")then +local __a=cd:gsub("^{(.+)}$","%1")if not ac(__a,ad)then return dd.default end;dc(ad,__a,bd)if +not bc[ad]then bc[ad]={}end;if not bc[ad][cd]then local a_a=_c(cd,ad,bd) +bc[ad][cd]=a_a end +return +function(a_a)local b_a,c_a=pcall(bc[ad][cd]) +if not b_a then +ab.header="Reactive evaluation error" +if type(c_a)=="string"then +ab.error("Error evaluating expression: "..c_a)else ab.error("Error evaluating expression")end;return dd.default end;return c_a end end end)local _d={} +_d.hooks={destroy=function(ad) +if cc[ad]then +for bd,cd in pairs(cc[ad])do for dd,__a in ipairs(cd)do +__a.target:removeObserver(__a.property,__a.callback)end end;cc[ad]=nil end end}return{BaseElement=_d} end +project["plugins/state.lua"] = function(...) local _a=require("propertySystem") +local aa=require("errorManager")local ba={}function ba.setup(da) +da.defineProperty(da,"states",{default={},type="table"}) +da.defineProperty(da,"stateObserver",{default={},type="table"})end +function ba:initializeState(da,_b,ab,bb) +local cb=self.get("states")if cb[da]then +aa.error("State '"..da.."' already exists")return self end;local db=bb or"states/".. +self.get("name")..".state"local _c={} +if ab and +fs.exists(db)then local ac=fs.open(db,"r")_c= +textutils.unserialize(ac.readAll())or{}ac.close()end;cb[da]={value=ab and _c[da]or _b,persist=ab} +return self end;local ca={} +function ca:setState(da,_b)local ab=self:getBaseFrame() +local bb=ab.get("states")local cb=ab.get("stateObserver") +if not bb[da]then aa.error("State '".. +da.."' not initialized")end +if bb[da].persist then +local db="states/"..ab.get("name")..".state"local _c={} +if fs.exists(db)then local cc=fs.open(db,"r")_c= +textutils.unserialize(cc.readAll())or{}cc.close()end;_c[da]=_b;local ac=fs.getDir(db)if not fs.exists(ac)then +fs.makeDir(ac)end;local bc=fs.open(db,"w") +bc.write(textutils.serialize(_c))bc.close()end;bb[da].value=_b +if cb[da]then for db,_c in ipairs(cb[da])do _c(da,_b)end end;for db,_c in pairs(bb)do +if _c.computed then _c.value=_c.computeFn(self)if cb[db]then for ac,bc in ipairs(cb[db])do +bc(db,_c.value)end end end end +return self end +function ca:getState(da)local _b=self:getBaseFrame()local ab=_b.get("states")if +not ab[da]then +aa.error("State '"..da.."' not initialized")end;if ab[da].computed then +return ab[da].computeFn(self)end;return ab[da].value end +function ca:onStateChange(da,_b)local ab=self:getBaseFrame() +local bb=ab.get("states")[da]if not bb then +aa.error("Cannot observe state '"..da.."': State not initialized")return self end +local cb=ab.get("stateObserver")if not cb[da]then cb[da]={}end;table.insert(cb[da],_b) +return self end +function ca:removeStateChange(da,_b)local ab=self:getBaseFrame() +local bb=ab.get("stateObserver") +if bb[da]then for cb,db in ipairs(bb[da])do +if db==_b then table.remove(bb[da],cb)break end end end;return self end +function ca:computed(da,_b)local ab=self:getBaseFrame()local bb=ab.get("states")if bb[da]then +aa.error( +"Computed state '"..da.."' already exists")return self end +bb[da]={computeFn=_b,value=_b(self),computed=true}return self end +function ca:bind(da,_b)_b=_b or da;local ab=self:getBaseFrame()local bb=false +if +self.get(da)~=nil then self.set(da,ab:getState(_b))end +self:onChange(da,function(cb,db)if bb then return end;bb=true;cb:setState(_b,db)bb=false end) +self:onStateChange(_b,function(cb,db)if bb then return end;bb=true;if self.get(da)~=nil then +self.set(da,db)end;bb=false end)return self end;return{BaseElement=ca,BaseFrame=ba} end +project["plugins/xml.lua"] = function(...) local ab=require("errorManager")local bb=require("log") +local cb={new=function(ad) +return +{tag=ad,value=nil,attributes={},children={},addChild=function(bd,cd) +table.insert(bd.children,cd)end,addAttribute=function(bd,cd,dd)bd.attributes[cd]=dd end}end} +local db=function(ad,bd) +local cd,dd=string.gsub(bd,"(%w+)=([\"'])(.-)%2",function(b_a,c_a,d_a) +ad:addAttribute(b_a,"\""..d_a.."\"")end) +local __a,a_a=string.gsub(bd,"(%w+)={(.-)}",function(b_a,c_a)ad:addAttribute(b_a,c_a)end)end +local _c={parseText=function(ad)local bd={}local cd=cb.new()table.insert(bd,cd)local dd,__a,a_a,b_a,c_a;local d_a,_aa=1,1 +while +true do +dd,_aa,__a,a_a,b_a,c_a=string.find(ad,"<(%/?)([%w_:]+)(.-)(%/?)>",d_a)if not dd then break end;local aaa=string.sub(ad,d_a,dd-1)if not +string.find(aaa,"^%s*$")then local baa=(cd.value or"")..aaa +bd[#bd].value=baa end +if c_a=="/"then local baa=cb.new(a_a) +db(baa,b_a)cd:addChild(baa)elseif __a==""then local baa=cb.new(a_a)db(baa,b_a) +table.insert(bd,baa)cd=baa else local baa=table.remove(bd)cd=bd[#bd] +if#bd<1 then ab.error( +"XMLParser: nothing to close with "..a_a)end;if baa.tag~=a_a then +ab.error("XMLParser: trying to close "..baa.tag.." with "..a_a)end;cd:addChild(baa)end;d_a=_aa+1 end;if#bd>1 then +error("XMLParser: unclosed "..bd[#bd].tag)end;return cd.children end} +local function ac(ad)local bd={}local cd=1 +while true do local dd,__a,a_a=ad:find("%${([^}]+)}",cd) +if not dd then break end +table.insert(bd,{start=dd,ending=__a,expression=a_a,raw=ad:sub(dd,__a)})cd=__a+1 end;return bd end +local function bc(ad,bd)if not ad then return ad end;if +ad:sub(1,1)=="\""and ad:sub(-1)=="\""then ad=ad:sub(2,-2)end;local cd=ac(ad) +for dd,__a in ipairs(cd)do +local a_a=__a.expression;local b_a=__a.start-1;local c_a=__a.ending+1;if bd[a_a]then ad=ad:sub(1,b_a).. +tostring(bd[a_a])..ad:sub(c_a)else +ab.error( +"XMLParser: variable '"..a_a.."' not found in scope")end end +if ad:match("^%s*%s*$")then +local dd=ad:match("")local __a=_ENV;for a_a,b_a in pairs(bd)do __a[a_a]=b_a end;return +load("return "..dd,nil,"bt",__a)()end +if ad=="true"then return true elseif ad=="false"then return false elseif colors[ad]then return colors[ad]elseif tonumber(ad)then return +tonumber(ad)else return ad end end +local function cc(ad,bd)local cd={} +for dd,__a in pairs(ad.children)do +if __a.tag=="item"or __a.tag=="entry"then +local a_a={} +for b_a,c_a in pairs(__a.attributes)do a_a[b_a]=bc(c_a,bd)end;for b_a,c_a in pairs(__a.children)do +if c_a.value then a_a[c_a.tag]=bc(c_a.value,bd)elseif# +c_a.children>0 then a_a[c_a.tag]=cc(c_a)end end +table.insert(cd,a_a)else if __a.value then cd[__a.tag]=bc(__a.value,bd)elseif#__a.children>0 then +cd[__a.tag]=cc(__a)end end end;return cd end;local dc={}function dc.setup(ad) +ad.defineProperty(ad,"customXML",{default={attributes={},children={}},type="table"})end +function dc:fromXML(ad,bd) +if(ad.attributes)then +for cd,dd in +pairs(ad.attributes)do +if(self._properties[cd])then self.set(cd,bc(dd,bd))elseif self[cd]then +if( +cd:sub(1,2)=="on")then local __a=dd:gsub("\"","") +if(bd[__a])then if +(type(bd[__a])~="function")then +ab.error("XMLParser: variable '"..__a.. +"' is not a function for element '"..self:getType().."' "..cd)end +self[cd](self,bd[__a])else +ab.error("XMLParser: variable '"..__a.."' not found in scope")end else +ab.error("XMLParser: property '"..cd.. +"' not found in element '"..self:getType().."'")end else local __a=self.get("customXML") +__a.attributes[cd]=bc(dd,bd)end end end +if(ad.children)then +for cd,dd in pairs(ad.children)do +if(self._properties[dd.tag])then if( +self._properties[dd.tag].type=="table")then self.set(dd.tag,cc(dd,bd))else +self.set(dd.tag,bc(dd.value,bd))end else local __a={} +if(dd.children)then +for a_a,b_a in +pairs(dd.children)do +if(b_a.tag=="param")then +table.insert(__a,bc(b_a.value,bd))elseif(b_a.tag=="table")then table.insert(__a,cc(b_a,bd))end end end +if(self[dd.tag])then if(#__a>0)then +self[dd.tag](self,table.unpack(__a))elseif(dd.value)then self[dd.tag](self,bc(dd.value,bd))else +self[dd.tag](self)end else +local a_a=self.get("customXML")dd.value=bc(dd.value,bd)a_a.children[dd.tag]=dd end end end end;return self end;local _d={} +function _d:loadXML(ad,bd)bd=bd or{}local cd=_c.parseText(ad) +self:fromXML(cd,bd) +if(cd)then +for dd,__a in ipairs(cd)do +local a_a=__a.tag:sub(1,1):upper()..__a.tag:sub(2)if self["add"..a_a]then local b_a=self["add"..a_a](self) +b_a:fromXML(__a,bd)end end end;return self end +function _d:fromXML(ad,bd)dc.fromXML(self,ad,bd) +if(ad.children)then +for cd,dd in ipairs(ad.children)do local __a= +dd.tag:sub(1,1):upper()..dd.tag:sub(2) +if +self["add"..__a]then local a_a=self["add"..__a](self)a_a:fromXML(dd,bd)end end end;return self end;return{API=_c,Container=_d,BaseElement=dc} end +project["plugins/debug.lua"] = function(...) local _b=require("log")local ab=require("libraries/colorHex") +local bb=10;local cb=false;local db={ERROR=1,WARN=2,INFO=3,DEBUG=4} +local function _c(dc) +local _d={renderCount=0,eventCount={},lastRender=os.epoch("utc"),properties={},children={}} +return +{trackProperty=function(ad,bd)_d.properties[ad]=bd end,trackRender=function() +_d.renderCount=_d.renderCount+1;_d.lastRender=os.epoch("utc")end,trackEvent=function(ad)_d.eventCount[ad]=( +_d.eventCount[ad]or 0)+1 end,dump=function()return +{type=dc.get("type"),id=dc.get("id"),stats=_d}end}end;local ac={} +function ac.debug(dc,_d)dc._debugger=_c(dc)dc._debugLevel=_d or db.INFO;return dc end;function ac.dumpDebug(dc)if not dc._debugger then return end +return dc._debugger.dump()end;local bc={} +function bc.openConsole(dc) +if +not dc._debugFrame then local _d=dc.get("width")local ad=dc.get("height") +dc._debugFrame=dc:addFrame("basaltDebugLog"):setWidth(_d):setHeight(ad):listenEvent("mouse_scroll",true) +dc._debugFrame:addButton("basaltDebugLogClose"):setWidth(9):setHeight(1):setX( +_d-8):setY(ad):setText("Close"):onClick(function() +dc:closeConsole()end)dc._debugFrame._scrollOffset=0 +dc._debugFrame._processedLogs={} +local function bd(b_a,c_a)local d_a={}while#b_a>0 do local _aa=b_a:sub(1,c_a)table.insert(d_a,_aa)b_a=b_a:sub( +c_a+1)end;return d_a end +local function cd()local b_a={}local c_a=dc._debugFrame.get("width") +for d_a,_aa in +ipairs(_b._logs)do local aaa=bd(_aa.message,c_a)for baa,caa in ipairs(aaa)do +table.insert(b_a,{text=caa,level=_aa.level})end end;return b_a end;local dd=#cd()-dc.get("height")dc._scrollOffset=dd +local __a=dc._debugFrame.render +dc._debugFrame.render=function(b_a)__a(b_a)b_a._processedLogs=cd() +local c_a=b_a.get("height")-2;local d_a=#b_a._processedLogs;local _aa=math.max(0,d_a-c_a) +b_a._scrollOffset=math.min(b_a._scrollOffset,_aa) +for i=1,c_a-2 do local aaa=i+b_a._scrollOffset +local baa=b_a._processedLogs[aaa] +if baa then +local caa= + +baa.level==_b.LEVEL.ERROR and colors.red or baa.level== +_b.LEVEL.WARN and colors.yellow or baa.level==_b.LEVEL.DEBUG and colors.lightGray or colors.white;b_a:textFg(2,i,baa.text,caa)end end end;local a_a=dc._debugFrame.dispatchEvent +dc._debugFrame.dispatchEvent=function(b_a,c_a,d_a,...) +if +(c_a=="mouse_scroll")then +b_a._scrollOffset=math.max(0,b_a._scrollOffset+d_a)b_a:updateRender()return true else return a_a(b_a,c_a,d_a,...)end end end +dc._debugFrame.set("width",dc.get("width")) +dc._debugFrame.set("height",dc.get("height"))dc._debugFrame.set("visible",true)return dc end +function bc.closeConsole(dc)if dc._debugFrame then +dc._debugFrame.set("visible",false)end;return dc end;function bc.toggleConsole(dc)if dc._debugFrame and dc._debugFrame:getVisible()then +dc:closeConsole()else dc:openConsole()end +return dc end +local cc={} +function cc.debugChildren(dc,_d)dc:debug(_d)for ad,bd in pairs(dc.get("children"))do if bd.debug then +bd:debug(_d)end end;return dc end;return{BaseElement=ac,Container=cc,BaseFrame=bc} end +project["plugins/animation.lua"] = function(...) local aa={} +local ba={linear=function(ab)return ab end,easeInQuad=function(ab)return ab*ab end,easeOutQuad=function(ab)return +1 - (1 -ab)* (1 -ab)end,easeInOutQuad=function(ab)if ab<0.5 then return 2 *ab*ab end;return 1 - ( +-2 *ab+2)^2 /2 end}local ca={}ca.__index=ca +function ca.new(ab,bb,cb,db,_c)local ac=setmetatable({},ca)ac.element=ab +ac.type=bb;ac.args=cb;ac.duration=db or 1;ac.startTime=0;ac.isPaused=false +ac.handlers=aa[bb]ac.easing=_c;return ac end;function ca:start()self.startTime=os.epoch("local")/1000;if +self.handlers.start then self.handlers.start(self)end +return self end +function ca:update(ab)local bb=math.min(1, +ab/self.duration) +local cb=ba[self.easing](bb)return self.handlers.update(self,cb)end;function ca:complete()if self.handlers.complete then +self.handlers.complete(self)end end +local da={}da.__index=da +function da.registerAnimation(ab,bb)aa[ab]=bb +da[ab]=function(cb,...)local db={...}local _c="linear" +if( +type(db[#db])=="string")then _c=table.remove(db,#db)end;local ac=table.remove(db,#db) +return cb:addAnimation(ab,db,ac,_c)end end;function da.registerEasing(ab,bb)ba[ab]=bb end +function da.new(ab)local bb={}bb.element=ab +bb.sequences={{}}bb.sequenceCallbacks={}bb.currentSequence=1;bb.timer=nil +setmetatable(bb,da)return bb end +function da:sequence()table.insert(self.sequences,{})self.currentSequence=# +self.sequences;self.sequenceCallbacks[self.currentSequence]={start=nil,update=nil,complete= +nil}return self end +function da:onStart(ab) +if +not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end +self.sequenceCallbacks[self.currentSequence].start=ab;return self end +function da:onUpdate(ab) +if +not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end +self.sequenceCallbacks[self.currentSequence].update=ab;return self end +function da:onComplete(ab) +if +not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end +self.sequenceCallbacks[self.currentSequence].complete=ab;return self end +function da:addAnimation(ab,bb,cb,db)local _c=ca.new(self.element,ab,bb,cb,db) +table.insert(self.sequences[self.currentSequence],_c)return self end +function da:start()self.currentSequence=1;self.timer=nil +if +(self.sequenceCallbacks[self.currentSequence])then if(self.sequenceCallbacks[self.currentSequence].start)then +self.sequenceCallbacks[self.currentSequence].start(self.element)end end +if +#self.sequences[self.currentSequence]>0 then self.timer=os.startTimer(0.05)for ab,bb in +ipairs(self.sequences[self.currentSequence])do bb:start()end end;return self end +function da:event(ab,bb) +if ab=="timer"and bb==self.timer then +local cb=os.epoch("local")/1000;local db=true;local _c={} +local ac=self.sequenceCallbacks[self.currentSequence] +for bc,cc in ipairs(self.sequences[self.currentSequence])do +local dc=cb-cc.startTime;local _d=dc/cc.duration;local ad=cc:update(dc)if ac and ac.update then +ac.update(self.element,_d)end;if not ad then table.insert(_c,cc)db=false else +cc:complete()end end +if db then +if ac and ac.complete then ac.complete(self.element)end +if self.currentSequence<#self.sequences then +self.currentSequence=self.currentSequence+1;_c={} +local bc=self.sequenceCallbacks[self.currentSequence]if bc and bc.start then bc.start(self.element)end +for cc,dc in +ipairs(self.sequences[self.currentSequence])do dc:start()table.insert(_c,dc)end end end;if#_c>0 then self.timer=os.startTimer(0.05)end +return true end end +function da:stop()if self.timer then pcall(os.cancelTimer,self.timer) +self.timer=nil end +for ab,bb in ipairs(self.sequences)do for cb,db in ipairs(bb)do +pcall(function()if db and +db.complete then db:complete()end end)end end;if +self.element and type(self.element.set)=="function"then +pcall(function()self.element.set("animation",nil)end)end end +da.registerAnimation("move",{start=function(ab)ab.startX=ab.element.get("x") +ab.startY=ab.element.get("y")end,update=function(ab,bb)local cb=ab.startX+ +(ab.args[1]-ab.startX)*bb;local db=ab.startY+ +(ab.args[2]-ab.startY)*bb +ab.element.set("x",math.floor(cb))ab.element.set("y",math.floor(db))return bb>=1 end,complete=function(ab) +ab.element.set("x",ab.args[1])ab.element.set("y",ab.args[2])end}) +da.registerAnimation("resize",{start=function(ab)ab.startW=ab.element.get("width") +ab.startH=ab.element.get("height")end,update=function(ab,bb)local cb=ab.startW+ +(ab.args[1]-ab.startW)*bb;local db=ab.startH+ +(ab.args[2]-ab.startH)*bb +ab.element.set("width",math.floor(cb))ab.element.set("height",math.floor(db)) +return bb>=1 end,complete=function(ab) +ab.element.set("width",ab.args[1])ab.element.set("height",ab.args[2])end}) +da.registerAnimation("moveOffset",{start=function(ab)ab.startX=ab.element.get("offsetX") +ab.startY=ab.element.get("offsetY")end,update=function(ab,bb)local cb=ab.startX+ (ab.args[1]-ab.startX)* +bb;local db=ab.startY+ (ab.args[2]- +ab.startY)*bb +ab.element.set("offsetX",math.floor(cb))ab.element.set("offsetY",math.floor(db))return +bb>=1 end,complete=function(ab) +ab.element.set("offsetX",ab.args[1])ab.element.set("offsetY",ab.args[2])end}) +da.registerAnimation("number",{start=function(ab) +ab.startValue=ab.element.get(ab.args[1])ab.targetValue=ab.args[2]end,update=function(ab,bb) +local cb= +ab.startValue+ (ab.targetValue-ab.startValue)*bb +ab.element.set(ab.args[1],math.floor(cb))return bb>=1 end,complete=function(ab) +ab.element.set(ab.args[1],ab.targetValue)end}) +da.registerAnimation("entries",{start=function(ab) +ab.startColor=ab.element.get(ab.args[1])ab.colorList=ab.args[2]end,update=function(ab,bb) +local cb=ab.colorList;local db=math.floor(#cb*bb)+1;if db>#cb then db=#cb end +ab.element.set(ab.args[1],cb[db])end,complete=function(ab) +ab.element.set(ab.args[1],ab.colorList[ +#ab.colorList])end}) +da.registerAnimation("morphText",{start=function(ab)local bb=ab.element.get(ab.args[1]) +local cb=ab.args[2]local db=math.max(#bb,#cb) +local _c=string.rep(" ",math.floor(db-#bb)/2)ab.startText=_c..bb.._c +ab.targetText=cb..string.rep(" ",db-#cb)ab.length=db end,update=function(ab,bb) +local cb="" +for i=1,ab.length do local db=ab.startText:sub(i,i) +local _c=ab.targetText:sub(i,i) +if bb<0.5 then +cb=cb.. (math.random()>bb*2 and db or" ")else cb=cb.. +(math.random()> (bb-0.5)*2 and" "or _c)end end;ab.element.set(ab.args[1],cb)return bb>=1 end,complete=function(ab) +ab.element.set(ab.args[1],ab.targetText:gsub("%s+$",""))end}) +da.registerAnimation("typewrite",{start=function(ab)ab.targetText=ab.args[2] +ab.element.set(ab.args[1],"")end,update=function(ab,bb) +local cb=math.floor(#ab.targetText*bb) +ab.element.set(ab.args[1],ab.targetText:sub(1,cb))return bb>=1 end}) +da.registerAnimation("fadeText",{start=function(ab)ab.chars={}for i=1,#ab.args[2]do +ab.chars[i]={char=ab.args[2]:sub(i,i),visible=false}end end,update=function(ab,bb) +local cb=""for db,_c in ipairs(ab.chars)do +if math.random()=1 end}) +da.registerAnimation("scrollText",{start=function(ab)ab.width=ab.element.get("width")ab.startText= +ab.element.get(ab.args[1])or"" +ab.targetText=ab.args[2]or""ab.startText=tostring(ab.startText) +ab.targetText=tostring(ab.targetText)end,update=function(ab,bb) +local cb=ab.width +if bb<0.5 then local db=bb/0.5;local _c=math.floor(cb*db) +local ac=( +ab.startText:sub(_c+1)..string.rep(" ",cb)):sub(1,cb)ab.element.set(ab.args[1],ac)else +local db=(bb-0.5)/0.5;local _c=math.floor(cb* (1 -db)) +local ac=string.rep(" ",_c)..ab.targetText;local bc=ac:sub(1,cb)ab.element.set(ab.args[1],bc)end;return bb>=1 end,complete=function(ab)local bb=( +ab.targetText..string.rep(" ",ab.width)) +ab.element.set(ab.args[1],bb)end}) +da.registerAnimation("marquee",{start=function(ab)ab.width=ab.element.get("width")ab.text=tostring( +ab.args[2]or"") +ab.speed=tonumber(ab.args[3])or 0.15;ab.offset=0;ab.lastShift=-1 +ab.padded=ab.text..string.rep(" ",ab.width)end,update=function(ab,bb)local cb= +os.epoch("local")/1000 -ab.startTime +local db=math.max(0.01,ab.speed)local _c=math.floor(cb/db) +if _c~=ab.lastShift then ab.lastShift=_c +local ac=#ab.padded;local bc=(_c%ac)+1;local cc=ab.padded..ab.padded +local dc=cc:sub(bc,bc+ab.width-1)ab.element.set(ab.args[1],dc)end;return false end,complete=function(ab) +end})local _b={hooks={}} +function _b.hooks.handleEvent(ab,bb,...)if bb=="timer"then local cb=ab.get("animation")if cb then +cb:event(bb,...)end end end +function _b.setup(ab) +ab.defineProperty(ab,"animation",{default=nil,type="table"})ab.defineEvent(ab,"timer")end +function _b.stopAnimation(ab)local bb=ab.get("animation") +if +bb and type(bb.stop)=="function"then bb:stop()else ab.set("animation",nil)end;return ab end +function _b:animate()local ab=da.new(self)self.set("animation",ab)return ab end;return{VisualElement=_b} end +project["plugins/benchmark.lua"] = function(...) local ca=require("log")local da=setmetatable({},{__mode="k"})local function _b()return +{methods={}}end +local function ab(_c,ac)local bc=_c[ac] +if not da[_c]then da[_c]=_b()end +if not da[_c].methods[ac]then +da[_c].methods[ac]={calls=0,totalTime=0,minTime=math.huge,maxTime=0,lastTime=0,startTime=0,path={},methodName=ac,originalMethod=bc}end +_c[ac]=function(cc,...)cc:startProfile(ac)local dc=bc(cc,...) +cc:endProfile(ac)return dc end end;local bb={} +function bb:startProfile(_c)local ac=da[self]if not ac then ac=_b()da[self]=ac end;if not +ac.methods[_c]then +ac.methods[_c]={calls=0,totalTime=0,minTime=math.huge,maxTime=0,lastTime=0,startTime=0,path={},methodName=_c}end +local bc=ac.methods[_c]bc.startTime=os.clock()*1000;bc.path={}local cc=self;while cc do +table.insert(bc.path,1, +cc.get("name")or cc.get("id"))cc=cc.parent end;return self end +function bb:endProfile(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c]local cc=os.clock()*1000 +local dc=cc-bc.startTime;bc.calls=bc.calls+1;bc.totalTime=bc.totalTime+dc +bc.minTime=math.min(bc.minTime,dc)bc.maxTime=math.max(bc.maxTime,dc)bc.lastTime=dc;return self end +function bb:benchmark(_c)if not self[_c]then +ca.error("Method ".._c.." does not exist")return self end;da[self]=_b() +da[self].methodName=_c;da[self].isRunning=true;ab(self,_c)return self end +function bb:logBenchmark(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c] +if bc then local cc= +bc.calls>0 and(bc.totalTime/bc.calls)or 0 +ca.info(string.format( +"Benchmark results for %s.%s: ".. +"Path: %s ".."Calls: %d ".. +"Average time: %.2fms ".."Min time: %.2fms ".."Max time: %.2fms ".. +"Last time: %.2fms ".."Total time: %.2fms",table.concat(bc.path,"."),bc.methodName,table.concat(bc.path,"/"),bc.calls,cc, +bc.minTime~=math.huge and bc.minTime or 0,bc.maxTime,bc.lastTime,bc.totalTime))end;return self end +function bb:stopBenchmark(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c]if bc and bc.originalMethod then +self[_c]=bc.originalMethod end;ac.methods[_c]=nil;if +not next(ac.methods)then da[self]=nil end;return self end +function bb:getBenchmarkStats(_c)local ac=da[self] +if not ac or not ac.methods[_c]then return nil end;local bc=ac.methods[_c]return +{averageTime=bc.totalTime/bc.calls,totalTime=bc.totalTime,calls=bc.calls,minTime=bc.minTime,maxTime=bc.maxTime,lastTime=bc.lastTime}end;local cb={} +function cb:benchmarkContainer(_c)self:benchmark(_c) +for ac,bc in +pairs(self.get("children"))do bc:benchmark(_c)if bc:isType("Container")then +bc:benchmarkContainer(_c)end end;return self end +function cb:logContainerBenchmarks(_c,ac)ac=ac or 0;local bc=string.rep(" ",ac)local cc=0;local dc={} +for ad,bd in +pairs(self.get("children"))do local cd=da[bd] +if cd and cd.methods[_c]then local dd=cd.methods[_c] +cc=cc+dd.totalTime +table.insert(dc,{element=bd,type=bd.get("type"),calls=dd.calls,totalTime=dd.totalTime,avgTime=dd.totalTime/dd.calls})end end;local _d=da[self] +if _d and _d.methods[_c]then local ad=_d.methods[_c] +local bd=ad.totalTime-cc;local cd=bd/ad.calls +ca.info(string.format("%sBenchmark %s (%s): ".."%.2fms/call (Self: %.2fms/call) ".. +"[Total: %dms, Calls: %d]",bc,self.get("type"),_c, +ad.totalTime/ad.calls,cd,ad.totalTime,ad.calls)) +if#dc>0 then +for dd,__a in ipairs(dc)do +if __a.element:isType("Container")then __a.element:logContainerBenchmarks(_c, +ac+1)else +ca.info(string.format("%s> %s: %.2fms/call [Total: %dms, Calls: %d]", +bc.." ",__a.type,__a.avgTime,__a.totalTime,__a.calls))end end end end;return self end +function cb:stopContainerBenchmark(_c) +for ac,bc in pairs(self.get("children"))do if bc:isType("Container")then +bc:stopContainerBenchmark(_c)else bc:stopBenchmark(_c)end end;self:stopBenchmark(_c)return self end;local db={} +function db.start(_c,ac)ac=ac or{}local bc=_b()bc.name=_c +bc.startTime=os.clock()*1000;bc.custom=true;bc.calls=0;bc.totalTime=0;bc.minTime=math.huge;bc.maxTime=0 +bc.lastTime=0;da[_c]=bc end +function db.stop(_c)local ac=da[_c]if not ac or not ac.custom then return end;local bc= +os.clock()*1000;local cc=bc-ac.startTime;ac.calls=ac.calls+1;ac.totalTime= +ac.totalTime+cc;ac.minTime=math.min(ac.minTime,cc) +ac.maxTime=math.max(ac.maxTime,cc)ac.lastTime=cc +ca.info(string.format("Custom Benchmark '%s': ".. +"Calls: %d ".."Average time: %.2fms ".. +"Min time: %.2fms ".. +"Max time: %.2fms ".."Last time: %.2fms ".."Total time: %.2fms",_c,ac.calls, +ac.totalTime/ac.calls,ac.minTime,ac.maxTime,ac.lastTime,ac.totalTime))end +function db.getStats(_c)local ac=da[_c]if not ac then return nil end;return +{averageTime=ac.totalTime/ac.calls,totalTime=ac.totalTime,calls=ac.calls,minTime=ac.minTime,maxTime=ac.maxTime,lastTime=ac.lastTime}end;function db.clear(_c)da[_c]=nil end;function db.clearAll()for _c,ac in pairs(da)do +if ac.custom then da[_c]=nil end end end;return +{BaseElement=bb,Container=cb,API=db} end +project["elementManager.lua"] = function(...) local ab=table.pack(...) +local bb=fs.getDir(ab[2]or"basalt")local cb=ab[1]if(bb==nil)then +error("Unable to find directory ".. +ab[2].." please report this bug to our discord.")end +local db=require("log")local _c=package.path;local ac="path;/path/?.lua;/path/?/init.lua;" +local bc=ac:gsub("path",bb)local cc={}cc._elements={}cc._plugins={}cc._APIs={} +local dc=fs.combine(bb,"elements")local _d=fs.combine(bb,"plugins") +db.info("Loading elements from "..dc) +if fs.exists(dc)then +for ad,bd in ipairs(fs.list(dc))do local cd=bd:match("(.+).lua")if cd then db.debug( +"Found element: "..cd) +cc._elements[cd]={class=nil,plugins={},loaded=false}end end end;db.info("Loading plugins from ".._d) +if +fs.exists(_d)then +for ad,bd in ipairs(fs.list(_d))do local cd=bd:match("(.+).lua") +if cd then +db.debug("Found plugin: "..cd)local dd=require(fs.combine("plugins",cd)) +if +type(dd)=="table"then +for __a,a_a in pairs(dd)do if(__a~="API")then +if(cc._plugins[__a]==nil)then cc._plugins[__a]={}end;table.insert(cc._plugins[__a],a_a)else +cc._APIs[cd]=a_a end end end end end end +if(minified)then if(minified_elementDirectory==nil)then +error("Unable to find minified_elementDirectory please report this bug to our discord.")end;for ad,bd in +pairs(minified_elementDirectory)do +cc._elements[ad:gsub(".lua","")]={class=nil,plugins={},loaded=false}end;if +(minified_pluginDirectory==nil)then +error("Unable to find minified_pluginDirectory please report this bug to our discord.")end +for ad,bd in +pairs(minified_pluginDirectory)do local cd=ad:gsub(".lua","") +local dd=require(fs.combine("plugins",cd)) +if type(dd)=="table"then +for __a,a_a in pairs(dd)do +if(__a~="API")then if(cc._plugins[__a]==nil)then +cc._plugins[__a]={}end +table.insert(cc._plugins[__a],a_a)else cc._APIs[cd]=a_a end end end end end +function cc.loadElement(ad) +if not cc._elements[ad].loaded then +package.path=bc.."rom/?"local bd=require(fs.combine("elements",ad)) +package.path=_c;cc._elements[ad]={class=bd,plugins=bd.plugins,loaded=true}db.debug( +"Loaded element: "..ad) +if(cc._plugins[ad]~=nil)then +for cd,dd in +pairs(cc._plugins[ad])do if(dd.setup)then dd.setup(bd)end +if(dd.hooks)then +for __a,a_a in pairs(dd.hooks)do +local b_a=bd[__a]if(type(b_a)~="function")then +error("Element ".. +ad.." does not have a method "..__a)end +if(type(a_a)=="function")then +bd[__a]=function(c_a,...) +local d_a=b_a(c_a,...)local _aa=a_a(c_a,...)return _aa==nil and d_a or _aa end elseif(type(a_a)=="table")then +bd[__a]=function(c_a,...)if a_a.pre then a_a.pre(c_a,...)end +local d_a=b_a(c_a,...)if a_a.post then a_a.post(c_a,...)end;return d_a end end end end;for __a,a_a in pairs(dd)do +if __a~="setup"and __a~="hooks"then bd[__a]=a_a end end end end end end +function cc.getElement(ad)if not cc._elements[ad].loaded then +cc.loadElement(ad)end;return cc._elements[ad].class end;function cc.getElementList()return cc._elements end;function cc.getAPI(ad) +return cc._APIs[ad]end;return cc end +project["log.lua"] = function(...) local aa={}aa._logs={}aa._enabled=false;aa._logToFile=false +aa._logFile="basalt.log"fs.delete(aa._logFile) +aa.LEVEL={DEBUG=1,INFO=2,WARN=3,ERROR=4} +local ba={[aa.LEVEL.DEBUG]="Debug",[aa.LEVEL.INFO]="Info",[aa.LEVEL.WARN]="Warn",[aa.LEVEL.ERROR]="Error"} +local ca={[aa.LEVEL.DEBUG]=colors.lightGray,[aa.LEVEL.INFO]=colors.white,[aa.LEVEL.WARN]=colors.yellow,[aa.LEVEL.ERROR]=colors.red}function aa.setLogToFile(ab)aa._logToFile=ab end +function aa.setEnabled(ab)aa._enabled=ab end;local function da(ab) +if aa._logToFile then local bb=io.open(aa._logFile,"a")if bb then +bb:write(ab.."\n")bb:close()end end end +local function _b(ab,...)if +not aa._enabled then return end;local bb=os.date("%H:%M:%S") +local cb=debug.getinfo(3,"Sl")local db=cb.source:match("@?(.*)")local _c=cb.currentline +local ac=string.format("[%s:%d]",db:match("([^/\\]+)%.lua$"),_c)local bc="["..ba[ab].."]"local cc="" +for _d,ad in ipairs(table.pack(...))do if _d>1 then cc= +cc.." "end;cc=cc..tostring(ad)end;local dc=string.format("%s %s%s %s",bb,ac,bc,cc)da(dc) +table.insert(aa._logs,{time=bb,level=ab,message=cc})end;function aa.debug(...)_b(aa.LEVEL.DEBUG,...)end;function aa.info(...) +_b(aa.LEVEL.INFO,...)end +function aa.warn(...)_b(aa.LEVEL.WARN,...)end;function aa.error(...)_b(aa.LEVEL.ERROR,...)end;return aa end project["propertySystem.lua"] = function(...) local ba=require("libraries/utils").deepCopy local ca=require("libraries/expect")local da=require("errorManager")local _b={}_b.__index=_b _b._properties={}local ab={}_b._setterHooks={}function _b.addSetterHook(cb) @@ -245,2146 +3347,6 @@ for bca,cca in ipairs(__a._events[aca])do local dca,_da=pcall(cca,...)if not dca then bd.header="Basalt Event Callback Error" bd.error( "Error in event callback for '"..aca.."': "..tostring(_da))end end end end;return __a end -project["render.lua"] = function(...) local _a=require("libraries/colorHex")local aa=require("log") -local ba={}ba.__index=ba;local ca=string.sub -function ba.new(da)local _b=setmetatable({},ba) -_b.terminal=da;_b.width,_b.height=da.getSize() -_b.buffer={text={},fg={},bg={},dirtyRects={}} -for y=1,_b.height do _b.buffer.text[y]=string.rep(" ",_b.width) -_b.buffer.fg[y]=string.rep("0",_b.width)_b.buffer.bg[y]=string.rep("f",_b.width)end;return _b end;function ba:addDirtyRect(da,_b,ab,bb) -table.insert(self.buffer.dirtyRects,{x=da,y=_b,width=ab,height=bb})return self end -function ba:blit(da,_b,ab,bb,cb)if -_b<1 or _b>self.height then return self end;if(#ab~=#bb or -#ab~=#cb)then -error("Text, fg, and bg must be the same length")end -self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, -da-1)..ab.. -self.buffer.text[_b]:sub(da+#ab),1,self.width) -self.buffer.fg[_b]=ca( -self.buffer.fg[_b]:sub(1,da-1)..bb..self.buffer.fg[_b]:sub(da+#bb),1,self.width) -self.buffer.bg[_b]=ca( -self.buffer.bg[_b]:sub(1,da-1)..cb..self.buffer.bg[_b]:sub(da+#cb),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end -function ba:multiBlit(da,_b,ab,bb,cb,db,_c)if _b<1 or _b>self.height then return self end;if( -#cb~=#db or#cb~=#_c)then -error("Text, fg, and bg must be the same length")end;cb=cb:rep(ab) -db=db:rep(ab)_c=_c:rep(ab) -for dy=0,bb-1 do local ac=_b+dy -if ac>=1 and ac<=self.height then -self.buffer.text[ac]=ca(self.buffer.text[ac]:sub(1, -da-1)..cb.. -self.buffer.text[ac]:sub(da+#cb),1,self.width) -self.buffer.fg[ac]=ca( -self.buffer.fg[ac]:sub(1,da-1)..db..self.buffer.fg[ac]:sub(da+#db),1,self.width) -self.buffer.bg[ac]=ca( -self.buffer.bg[ac]:sub(1,da-1).._c..self.buffer.bg[ac]:sub(da+#_c),1,self.width)end end;self:addDirtyRect(da,_b,ab,bb)return self end -function ba:textFg(da,_b,ab,bb)if _b<1 or _b>self.height then return self end -bb=_a[bb]or"0"bb=bb:rep(#ab) -self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, -da-1)..ab.. -self.buffer.text[_b]:sub(da+#ab),1,self.width) -self.buffer.fg[_b]=ca( -self.buffer.fg[_b]:sub(1,da-1)..bb..self.buffer.fg[_b]:sub(da+#bb),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end -function ba:textBg(da,_b,ab,bb)if _b<1 or _b>self.height then return self end -bb=_a[bb]or"f" -self.buffer.text[_b]=ca( -self.buffer.text[_b]:sub(1,da-1).. -ab..self.buffer.text[_b]:sub(da+#ab),1,self.width) -self.buffer.bg[_b]=ca( -self.buffer.bg[_b]:sub(1,da-1).. -bb:rep(#ab)..self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end -function ba:text(da,_b,ab)if _b<1 or _b>self.height then return self end -self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, -da-1)..ab.. -self.buffer.text[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end -function ba:fg(da,_b,ab)if _b<1 or _b>self.height then return self end -self.buffer.fg[_b]=ca(self.buffer.fg[_b]:sub(1, -da-1)..ab.. -self.buffer.fg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end -function ba:bg(da,_b,ab)if _b<1 or _b>self.height then return self end -self.buffer.bg[_b]=ca(self.buffer.bg[_b]:sub(1, -da-1)..ab.. -self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end -function ba:text(da,_b,ab)if _b<1 or _b>self.height then return self end -self.buffer.text[_b]=ca(self.buffer.text[_b]:sub(1, -da-1)..ab.. -self.buffer.text[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end -function ba:fg(da,_b,ab)if _b<1 or _b>self.height then return self end -self.buffer.fg[_b]=ca(self.buffer.fg[_b]:sub(1, -da-1)..ab.. -self.buffer.fg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end -function ba:bg(da,_b,ab)if _b<1 or _b>self.height then return self end -self.buffer.bg[_b]=ca(self.buffer.bg[_b]:sub(1, -da-1)..ab.. -self.buffer.bg[_b]:sub(da+#ab),1,self.width)self:addDirtyRect(da,_b,#ab,1)return self end -function ba:clear(da)local _b=_a[da]or"f" -for y=1,self.height do -self.buffer.text[y]=string.rep(" ",self.width)self.buffer.fg[y]=string.rep("0",self.width) -self.buffer.bg[y]=string.rep(_b,self.width)self:addDirtyRect(1,y,self.width,1)end;return self end -function ba:render()local da={} -for _b,ab in ipairs(self.buffer.dirtyRects)do local bb=false;for cb,db in ipairs(da)do -if -self:rectOverlaps(ab,db)then self:mergeRects(db,ab)bb=true;break end end;if not bb then -table.insert(da,ab)end end -for _b,ab in ipairs(da)do -for y=ab.y,ab.y+ab.height-1 do -if y>=1 and y<=self.height then -self.terminal.setCursorPos(ab.x,y) -self.terminal.blit(self.buffer.text[y]:sub(ab.x,ab.x+ab.width-1),self.buffer.fg[y]:sub(ab.x, -ab.x+ab.width-1),self.buffer.bg[y]:sub(ab.x, -ab.x+ab.width-1))end end end;self.buffer.dirtyRects={} -if self.blink then -self.terminal.setTextColor(self.cursorColor or -colors.white) -self.terminal.setCursorPos(self.xCursor,self.yCursor)self.terminal.setCursorBlink(true)else -self.terminal.setCursorBlink(false)end;return self end -function ba:rectOverlaps(da,_b)return -not( -da.x+da.width<=_b.x or _b.x+_b.width<=da.x or da.y+da.height<=_b.y or -_b.y+_b.height<=da.y)end -function ba:mergeRects(da,_b)local ab=math.min(da.x,_b.x) -local bb=math.min(da.y,_b.y) -local cb=math.max(da.x+da.width,_b.x+_b.width) -local db=math.max(da.y+da.height,_b.y+_b.height)da.x=ab;da.y=bb;da.width=cb-ab;da.height=db-bb;return self end -function ba:setCursor(da,_b,ab,bb) -if bb~=nil then self.terminal.setTextColor(bb)end;self.terminal.setCursorPos(da,_b) -self.terminal.setCursorBlink(ab)self.xCursor=da;self.yCursor=_b;self.blink=ab;self.cursorColor=bb -return self end -function ba:clearArea(da,_b,ab,bb,cb)local db=_a[cb]or"f" -for dy=0,bb-1 do local _c=_b+dy;if -_c>=1 and _c<=self.height then local ac=string.rep(" ",ab)local bc=string.rep(db,ab) -self:blit(da,_c,ac,"0",db)end end;return self end;function ba:getSize()return self.width,self.height end -function ba:setSize(da,_b) -self.width=da;self.height=_b -for y=1,self.height do -self.buffer.text[y]=string.rep(" ",self.width)self.buffer.fg[y]=string.rep("0",self.width) -self.buffer.bg[y]=string.rep("f",self.width)end;return self end;return ba end -project["elements/TextBox.lua"] = function(...) local ca=require("elements/VisualElement") -local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b -_b.defineProperty(_b,"lines",{default={""},type="table",canTriggerRender=true}) -_b.defineProperty(_b,"cursorX",{default=1,type="number"}) -_b.defineProperty(_b,"cursorY",{default=1,type="number"}) -_b.defineProperty(_b,"scrollX",{default=0,type="number",canTriggerRender=true}) -_b.defineProperty(_b,"scrollY",{default=0,type="number",canTriggerRender=true}) -_b.defineProperty(_b,"editable",{default=true,type="boolean"}) -_b.defineProperty(_b,"syntaxPatterns",{default={},type="table"}) -_b.defineProperty(_b,"cursorColor",{default=nil,type="color"})_b.defineEvent(_b,"mouse_click") -_b.defineEvent(_b,"key")_b.defineEvent(_b,"char") -_b.defineEvent(_b,"mouse_scroll")_b.defineEvent(_b,"paste") -function _b.new() -local _c=setmetatable({},_b):__init()_c.class=_b;_c.set("width",20)_c.set("height",10)return _c end;function _b:init(_c,ac)ca.init(self,_c,ac)self.set("type","TextBox") -return self end;function _b:addSyntaxPattern(_c,ac) -table.insert(self.get("syntaxPatterns"),{pattern=_c,color=ac})return self end -function _b:removeSyntaxPattern(_c)local ac= -self.get("syntaxPatterns")or{} -if type(_c)~="number"then return self end -if _c>=1 and _c<=#ac then table.remove(ac,_c) -self.set("syntaxPatterns",ac)self:updateRender()end;return self end;function _b:clearSyntaxPatterns()self.set("syntaxPatterns",{}) -self:updateRender()return self end -local function ab(_c,ac) -local bc=_c.get("lines")local cc=_c.get("cursorX")local dc=_c.get("cursorY")local _d=bc[dc]bc[dc]=_d:sub(1, -cc-1)..ac.._d:sub(cc) -_c.set("cursorX",cc+1)_c:updateViewport()_c:updateRender()end -local function bb(_c)local ac=_c.get("lines")local bc=_c.get("cursorX") -local cc=_c.get("cursorY")local dc=ac[cc]local _d=dc:sub(bc)ac[cc]=dc:sub(1,bc-1) -table.insert(ac,cc+1,_d)_c.set("cursorX",1)_c.set("cursorY",cc+1) -_c:updateViewport()_c:updateRender()end -local function cb(_c)local ac=_c.get("lines")local bc=_c.get("cursorX") -local cc=_c.get("cursorY")local dc=ac[cc] -if bc>1 then -ac[cc]=dc:sub(1,bc-2)..dc:sub(bc)_c.set("cursorX",bc-1)elseif cc>1 then local _d=ac[cc-1] -_c.set("cursorX",#_d+1)_c.set("cursorY",cc-1)ac[cc-1]=_d..dc -table.remove(ac,cc)end;_c:updateViewport()_c:updateRender()end -function _b:updateViewport()local _c=self.get("cursorX") -local ac=self.get("cursorY")local bc=self.get("scrollX")local cc=self.get("scrollY") -local dc=self.get("width")local _d=self.get("height") -if _c-bc>dc then -self.set("scrollX",_c-dc)elseif _c-bc<1 then self.set("scrollX",_c-1)end;if ac-cc>_d then self.set("scrollY",ac-_d)elseif ac-cc<1 then -self.set("scrollY",ac-1)end;return self end -function _b:char(_c)if -not self.get("editable")or not self.get("focused")then return false end;ab(self,_c)return true end -function _b:key(_c)if -not self.get("editable")or not self.get("focused")then return false end -local ac=self.get("lines")local bc=self.get("cursorX")local cc=self.get("cursorY") -if _c== -keys.enter then bb(self)elseif _c==keys.backspace then cb(self)elseif _c==keys.left then -if bc>1 then self.set("cursorX", -bc-1)elseif cc>1 then self.set("cursorY",cc-1)self.set("cursorX", -#ac[cc-1]+1)end elseif _c==keys.right then -if bc<=#ac[cc]then self.set("cursorX",bc+1)elseif cc<#ac then self.set("cursorY", -cc+1)self.set("cursorX",1)end elseif _c==keys.up and cc>1 then self.set("cursorY",cc-1) -self.set("cursorX",math.min(bc, -#ac[cc-1]+1))elseif _c==keys.down and cc<#ac then self.set("cursorY",cc+1) -self.set("cursorX",math.min(bc, -#ac[cc+1]+1))end;self:updateRender()self:updateViewport()return true end -function _b:mouse_scroll(_c,ac,bc) -if self:isInBounds(ac,bc)then local cc=self.get("scrollY") -local dc=self.get("height")local _d=self.get("lines")local ad=math.max(0,#_d-dc+2)local bd=math.max(0,math.min(ad, -cc+_c)) -self.set("scrollY",bd)self:updateRender()return true end;return false end -function _b:mouse_click(_c,ac,bc) -if ca.mouse_click(self,_c,ac,bc)then -local cc,dc=self:getRelativePosition(ac,bc)local _d=self.get("scrollX")local ad=self.get("scrollY")local bd=(dc or 0)+ (ad or -0)local cd=self.get("lines")or{}if -bd<1 then bd=1 end;if bd<=#cd and cd[bd]~=nil then -self.set("cursorY",bd)local dd=#tostring(cd[bd]) -self.set("cursorX",math.min((cc or 1)+ (_d or 0), -dd+1))end -self:updateRender()return true end;return false end -function _b:paste(_c)if -not self.get("editable")or not self.get("focused")then return false end;for ac in _c:gmatch(".")do if ac=="\n"then -bb(self)else ab(self,ac)end end;return -true end -function _b:setText(_c)local ac={} -if _c==""then ac={""}else for bc in(_c.."\n"):gmatch("([^\n]*)\n")do -table.insert(ac,bc)end end;self.set("lines",ac)return self end -function _b:getText()return table.concat(self.get("lines"),"\n")end -local function db(_c,ac)local bc=ac -local cc=string.rep(da[_c.get("foreground")],#bc)local dc=_c.get("syntaxPatterns") -for _d,ad in ipairs(dc)do local bd=1 -while true do -local cd,dd=bc:find(ad.pattern,bd)if not cd then break end;local __a=dd-cd+1 -if __a<=0 then -cc=cc:sub(1,cd-1).. -string.rep(da[ad.color],1)..cc:sub(cd+1)bd=cd+1 else cc=cc:sub(1,cd-1).. -string.rep(da[ad.color],__a)..cc:sub(dd+1)bd=dd+1 end end end;return bc,cc end -function _b:render()ca.render(self)local _c=self.get("lines") -local ac=self.get("scrollX")local bc=self.get("scrollY")local cc=self.get("width") -local dc=self.get("height")local _d=da[self.get("foreground")] -local ad=da[self.get("background")] -for y=1,dc do local bd=y+bc;local cd=_c[bd]or""local dd,__a=db(self,cd) -local a_a=dd:sub(ac+1,ac+cc)local b_a=__a:sub(ac+1,ac+cc)local c_a=cc-#a_a -if c_a>0 then a_a=a_a.. -string.rep(" ",c_a)b_a=b_a.. -string.rep(da[self.get("foreground")],c_a)end;self:blit(1,y,a_a,b_a,string.rep(ad,#a_a))end -if self.get("focused")then local bd=self.get("cursorX")-ac;local cd= -self.get("cursorY")-bc;if -bd>=1 and bd<=cc and cd>=1 and cd<=dc then -self:setCursor(bd,cd,true,self.get("cursorColor")or self.get("foreground"))end end end;return _b end -project["elements/Frame.lua"] = function(...) local _a=require("elementManager") -local aa=_a.getElement("VisualElement")local ba=_a.getElement("Container")local ca=setmetatable({},ba) -ca.__index=ca -ca.defineProperty(ca,"draggable",{default=false,type="boolean",setter=function(da,_b) -if _b then da:listenEvent("mouse_click",true) -da:listenEvent("mouse_up",true)da:listenEvent("mouse_drag",true)end;return _b end}) -ca.defineProperty(ca,"draggingMap",{default={{x=1,y=1,width="width",height=1}},type="table"}) -ca.defineProperty(ca,"scrollable",{default=false,type="boolean",setter=function(da,_b)if _b then -da:listenEvent("mouse_scroll",true)end;return _b end}) -function ca.new()local da=setmetatable({},ca):__init() -da.class=ca;da.set("width",12)da.set("height",6) -da.set("background",colors.gray)da.set("z",10)return da end;function ca:init(da,_b)ba.init(self,da,_b)self.set("type","Frame") -return self end -function ca:mouse_click(da,_b,ab) -if -aa.mouse_click(self,da,_b,ab)then -if self.get("draggable")then local bb,cb=self:getRelativePosition(_b,ab) -local db=self.get("draggingMap") -for _c,ac in ipairs(db)do local bc=ac.width or 1;local cc=ac.height or 1;if -type(bc)=="string"and bc=="width"then bc=self.get("width")elseif -type(bc)=="function"then bc=bc(self)end -if type(cc)== -"string"and cc=="height"then cc=self.get("height")elseif -type(cc)=="function"then cc=cc(self)end;local dc=ac.y or 1 -if -bb>=ac.x and bb<=ac.x+bc-1 and cb>=dc and cb<=dc+cc-1 then -self.dragStartX=_b-self.get("x")self.dragStartY=ab-self.get("y")self.dragging=true -return true end end end;return ba.mouse_click(self,da,_b,ab)end;return false end -function ca:mouse_up(da,_b,ab)if self.dragging then self.dragging=false;self.dragStartX=nil -self.dragStartY=nil;return true end;return -ba.mouse_up(self,da,_b,ab)end -function ca:mouse_drag(da,_b,ab) -if self.get("clicked")and self.dragging then -local bb=_b-self.dragStartX;local cb=ab-self.dragStartY;self.set("x",bb) -self.set("y",cb)return true end -if not self.dragging then return ba.mouse_drag(self,da,_b,ab)end;return false end -function ca:getChildrenHeight()local da=0;local _b=self.get("children") -for ab,bb in ipairs(_b)do if -bb.get("visible")then local cb=bb.get("y")local db=bb.get("height")local _c=cb+db-1 -if _c>da then da=_c end end end;return da end -function ca:mouse_scroll(da,_b,ab)if ba.mouse_scroll(self,da,_b,ab)then return true end -if -self.get("scrollable")then local bb,cb=self:getRelativePosition(_b,ab) -local db=self.get("width")local _c=self.get("height") -if -bb>=1 and bb<=db and cb>=1 and cb<=_c then local ac=self:getChildrenHeight() -local bc=self.get("offsetY")local cc=math.max(0,ac-_c)local dc=bc+da -dc=math.max(0,math.min(cc,dc))self.set("offsetY",dc)return true end end;return false end;return ca end -project["elements/Slider.lua"] = function(...) local d=require("elements/VisualElement") -local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa -aa.defineProperty(aa,"step",{default=1,type="number",canTriggerRender=true}) -aa.defineProperty(aa,"max",{default=100,type="number"}) -aa.defineProperty(aa,"horizontal",{default=true,type="boolean",canTriggerRender=true,setter=function(ba,ca)if ca then ba.set("backgroundEnabled",false)else -ba.set("backgroundEnabled",true)end end}) -aa.defineProperty(aa,"barColor",{default=colors.gray,type="color",canTriggerRender=true}) -aa.defineProperty(aa,"sliderColor",{default=colors.blue,type="color",canTriggerRender=true})aa.defineEvent(aa,"mouse_click") -aa.defineEvent(aa,"mouse_drag")aa.defineEvent(aa,"mouse_up") -aa.defineEvent(aa,"mouse_scroll") -function aa.new()local ba=setmetatable({},aa):__init() -ba.class=aa;ba.set("width",8)ba.set("height",1) -ba.set("backgroundEnabled",false)return ba end -function aa:init(ba,ca)d.init(self,ba,ca)self.set("type","Slider")end -function aa:getValue()local ba=self.get("step")local ca=self.get("max") -local da= -self.get("horizontal")and self.get("width")or self.get("height")return math.floor((ba-1)* (ca/ (da-1)))end -function aa:mouse_click(ba,ca,da) -if self:isInBounds(ca,da)then -local _b,ab=self:getRelativePosition(ca,da) -local bb=self.get("horizontal")and _b or ab;local cb=self.get("horizontal")and self.get("width")or -self.get("height") -self.set("step",math.min(cb,math.max(1,bb)))self:updateRender()return true end;return false end;aa.mouse_drag=aa.mouse_click -function aa:mouse_scroll(ba,ca,da) -if self:isInBounds(ca,da)then -local _b=self.get("step")local ab=self.get("horizontal")and self.get("width")or -self.get("height") -self.set("step",math.min(ab,math.max(1, -_b+ba)))self:updateRender()return true end;return false end -function aa:render()d.render(self)local ba=self.get("width") -local ca=self.get("height")local da=self.get("horizontal")local _b=self.get("step")local ab= -da and"\140"or" " -local bb=string.rep(ab,da and ba or ca) -if da then self:textFg(1,1,bb,self.get("barColor")) -self:textBg(_b,1," ",self.get("sliderColor"))else local cb=self.get("background") -for y=1,ca do self:textBg(1,y," ",cb)end -self:textBg(1,_b," ",self.get("sliderColor"))end end;return aa end -project["elements/Menu.lua"] = function(...) local _a=require("elements/VisualElement") -local aa=require("elements/List")local ba=require("libraries/colorHex") -local ca=setmetatable({},aa)ca.__index=ca -ca.defineProperty(ca,"separatorColor",{default=colors.gray,type="color"}) -function ca.new()local da=setmetatable({},ca):__init() -da.class=ca;da.set("width",30)da.set("height",1) -da.set("background",colors.gray)return da end -function ca:init(da,_b)aa.init(self,da,_b)self.set("type","Menu")return self end -function ca:setItems(da)local _b={}local ab=0 -for bb,cb in ipairs(da)do -if cb.separator then -table.insert(_b,{text=cb.text or"|",selectable=false})ab=ab+1 else local db=" "..cb.text.." "cb.text=db -table.insert(_b,cb)ab=ab+#db end end;self.set("width",ab)return aa.setItems(self,_b)end -function ca:render()_a.render(self)local da=1 -for _b,ab in ipairs(self.get("items"))do if type(ab)== -"string"then ab={text=" "..ab.." "} -self.get("items")[_b]=ab end;local bb=ab.selected -local cb= -ab.selectable==false and self.get("separatorColor")or(bb and(ab.selectedForeground or -self.get("selectedForeground"))or(ab.foreground or -self.get("foreground"))) -local db= -bb and(ab.selectedBackground or self.get("selectedBackground"))or(ab.background or self.get("background")) -self:blit(da,1,ab.text,string.rep(ba[cb],#ab.text),string.rep(ba[db],#ab.text))da=da+#ab.text end end -function ca:mouse_click(da,_b,ab) -if not _a.mouse_click(self,da,_b,ab)then return false end -if(self.get("selectable")==false)then return false end -local bb=select(1,self:getRelativePosition(_b,ab))local cb=1 -for db,_c in ipairs(self.get("items"))do -if -bb>=cb and bb0 then cb._tabId=1;self:updateTabVisibility()end end;return self end;function bb:updateTabVisibility()self.set("childrenSorted",false) -self.set("childrenEventsSorted",false)end -function bb:setActiveTab(cb) -local db=self.get("activeTab")if db==cb then return self end;self.set("activeTab",cb) -self:updateTabVisibility()self:dispatchEvent("tabChanged",cb,db)return self end -function bb:isChildVisible(cb) -if not da.isChildVisible(self,cb)then return false end -if cb._tabId then return cb._tabId==self.get("activeTab")end;return true end -function bb:getContentYOffset()local cb=self:_getHeaderMetrics()return cb.headerHeight end -function bb:_getHeaderMetrics()local cb=self.get("tabs")or{} -local db=self.get("width")or 1;local _c=self.get("tabHeight")or 1;local ac={}local bc=1;local cc=1 -for ad,bd in -ipairs(cb)do local cd=#bd.title+2;if cd>db then cd=db end -if cc+cd-1 >db then bc=bc+1;cc=1 end -table.insert(ac,{id=bd.id,title=bd.title,line=bc,x1=cc,x2=cc+cd-1,width=cd})cc=cc+cd end;local dc=bc;local _d=math.max(_c,dc) -return{headerHeight=_d,lines=dc,positions=ac}end -function bb:mouse_click(cb,db,_c) -if not ca.mouse_click(self,cb,db,_c)then return false end;local ac,bc=ca.getRelativePosition(self,db,_c) -local cc=self:_getHeaderMetrics() -if bc<=cc.headerHeight then if#cc.positions==0 then return true end -for dc,_d in -ipairs(cc.positions)do -if _d.line==bc and ac>=_d.x1 and ac<=_d.x2 then -self:setActiveTab(_d.id)self.set("focusedChild",nil)return true end end;return true end;return da.mouse_click(self,cb,db,_c)end -function bb:getRelativePosition(cb,db) -local _c=self:_getHeaderMetrics().headerHeight -if cb==nil or db==nil then return ca.getRelativePosition(self)else -local ac,bc=ca.getRelativePosition(self,cb,db)return ac,bc-_c end end -function bb:multiBlit(cb,db,_c,ac,bc,cc,dc)local _d=self:_getHeaderMetrics().headerHeight;return da.multiBlit(self,cb,( -db or 1)+_d,_c,ac,bc,cc,dc)end -function bb:textFg(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight;return da.textFg(self,cb,( -db or 1)+bc,_c,ac)end -function bb:textBg(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight;return da.textBg(self,cb,( -db or 1)+bc,_c,ac)end -function bb:drawText(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawText(self,cb,( -db or 1)+ac,_c)end -function bb:drawFg(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawFg(self,cb,( -db or 1)+ac,_c)end -function bb:drawBg(cb,db,_c)local ac=self:_getHeaderMetrics().headerHeight;return da.drawBg(self,cb,( -db or 1)+ac,_c)end -function bb:blit(cb,db,_c,ac,bc)local cc=self:_getHeaderMetrics().headerHeight;return da.blit(self,cb,( -db or 1)+cc,_c,ac,bc)end -function bb:mouse_up(cb,db,_c) -if not ca.mouse_up(self,cb,db,_c)then return false end;local ac,bc=ca.getRelativePosition(self,db,_c) -local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then return true end;return da.mouse_up(self,cb,db,_c)end -function bb:mouse_release(cb,db,_c)ca.mouse_release(self,cb,db,_c) -local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight -if bc<=cc then return end;return da.mouse_release(self,cb,db,_c)end -function bb:mouse_move(cb,db,_c) -if ca.mouse_move(self,cb,db,_c)then -local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then -return true end -local dc={self:getRelativePosition(db,_c)} -local _d,ad=self:callChildrenEvent(true,"mouse_move",table.unpack(dc))if _d then return true end end;return false end -function bb:mouse_drag(cb,db,_c) -if ca.mouse_drag(self,cb,db,_c)then -local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then -return true end;return da.mouse_drag(self,cb,db,_c)end;return false end -function bb:mouse_scroll(cb,db,_c) -if ca.mouse_scroll(self,cb,db,_c)then -local ac,bc=ca.getRelativePosition(self,db,_c)local cc=self:_getHeaderMetrics().headerHeight;if bc<=cc then -return true end;return da.mouse_scroll(self,cb,db,_c)end;return false end -function bb:setCursor(cb,db,_c,ac)local bc=self:_getHeaderMetrics().headerHeight -if -self.parent then local cc,dc=self:calculatePosition()local _d=cb+cc-1 -local ad=db+dc-1 +bc -if - -(_d<1)or(_d>self.parent.get("width"))or(ad<1)or(ad>self.parent.get("height"))then return self.parent:setCursor(_d,ad,false)end;return self.parent:setCursor(_d,ad,_c,ac)end;return self end -function bb:render()ca.render(self)local cb=self.get("width") -local db=self:_getHeaderMetrics()local _c=db.headerHeight or 1 -ca.multiBlit(self,1,1,cb,_c," ",_b[self.get("foreground")],_b[self.get("headerBackground")])local ac=self.get("activeTab") -for bc,cc in ipairs(db.positions)do -local dc=(cc.id==ac)and -self.get("activeTabBackground")or self.get("headerBackground")local _d=(cc.id==ac)and self.get("activeTabTextColor")or -self.get("foreground") -ca.multiBlit(self,cc.x1,cc.line,cc.width,1," ",_b[self.get("foreground")],_b[dc])ca.textFg(self,cc.x1 +1,cc.line,cc.title,_d)end -if not self.get("childrenSorted")then self:sortChildren()end -if not self.get("childrenEventsSorted")then for bc in pairs(self._values.childrenEvents or -{})do -self:sortChildrenEvents(bc)end end -for bc,cc in ipairs(self.get("visibleChildren")or{})do if cc==self then -error("CIRCULAR REFERENCE DETECTED!")return end;cc:render()cc:postRender()end end -function bb:sortChildrenEvents(cb) -local db=self._values.childrenEvents and self._values.childrenEvents[cb] -if db then local _c={}for ac,bc in ipairs(db)do -if self:isChildVisible(bc)then table.insert(_c,bc)end end -for i=2,#_c do local ac=_c[i] -local bc=ac.get("z")local cc=i-1 -while cc>0 do local dc=_c[cc].get("z")if dc>bc then _c[cc+1]=_c[cc] -cc=cc-1 else break end end;_c[cc+1]=ac end -self._values.visibleChildrenEvents=self._values.visibleChildrenEvents or{}self._values.visibleChildrenEvents[cb]=_c end;self.set("childrenEventsSorted",true)return self end;return bb end -project["elements/ProgressBar.lua"] = function(...) local d=require("elements/VisualElement") -local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa -aa.defineProperty(aa,"progress",{default=0,type="number",canTriggerRender=true}) -aa.defineProperty(aa,"showPercentage",{default=false,type="boolean"}) -aa.defineProperty(aa,"progressColor",{default=colors.black,type="color"}) -aa.defineProperty(aa,"direction",{default="right",type="string"}) -function aa.new()local ba=setmetatable({},aa):__init() -ba.class=aa;ba.set("width",25)ba.set("height",3)return ba end;function aa:init(ba,ca)d.init(self,ba,ca) -self.set("type","ProgressBar")end -function aa:render()d.render(self) -local ba=self.get("width")local ca=self.get("height") -local da=math.min(100,math.max(0,self.get("progress")))local _b=math.floor((ba*da)/100) -local ab=math.floor((ca*da)/100)local bb=self.get("direction") -local cb=self.get("progressColor") -if bb=="right"then -self:multiBlit(1,1,_b,ca," ",_a[self.get("foreground")],_a[cb])elseif bb=="left"then -self:multiBlit(ba-_b+1,1,_b,ca," ",_a[self.get("foreground")],_a[cb])elseif bb=="up"then -self:multiBlit(1,ca-ab+1,ba,ab," ",_a[self.get("foreground")],_a[cb])elseif bb=="down"then -self:multiBlit(1,1,ba,ab," ",_a[self.get("foreground")],_a[cb])end -if self.get("showPercentage")then local db=tostring(da).."%"local _c=math.floor( -(ba-#db)/2)+1 -local ac=math.floor((ca-1)/2)+1 -self:textFg(_c,ac,db,self.get("foreground"))end end;return aa end -project["elements/Table.lua"] = function(...) local d=require("elements/VisualElement") -local _a=require("libraries/colorHex")local aa=setmetatable({},d)aa.__index=aa -aa.defineProperty(aa,"columns",{default={},type="table",canTriggerRender=true,setter=function(ba,ca)local da={} -for _b,ab in -ipairs(ca)do -if type(ab)=="string"then da[_b]={name=ab,width=#ab+1}elseif type(ab)=="table"then -da[_b]={name= -ab.name or"",width=ab.width,minWidth=ab.minWidth or 3,maxWidth=ab.maxWidth or nil}end end;return da end}) -aa.defineProperty(aa,"data",{default={},type="table",canTriggerRender=true,setter=function(ba,ca)ba.set("scrollOffset",0) -ba.set("selectedRow",nil)ba.set("sortColumn",nil) -ba.set("sortDirection","asc")return ca end}) -aa.defineProperty(aa,"selectedRow",{default=nil,type="number",canTriggerRender=true}) -aa.defineProperty(aa,"headerColor",{default=colors.blue,type="color"}) -aa.defineProperty(aa,"selectedColor",{default=colors.lightBlue,type="color"}) -aa.defineProperty(aa,"gridColor",{default=colors.gray,type="color"}) -aa.defineProperty(aa,"sortColumn",{default=nil,type="number",canTriggerRender=true}) -aa.defineProperty(aa,"sortDirection",{default="asc",type="string",canTriggerRender=true}) -aa.defineProperty(aa,"scrollOffset",{default=0,type="number",canTriggerRender=true}) -aa.defineProperty(aa,"customSortFunction",{default={},type="table"})aa.defineEvent(aa,"mouse_click") -aa.defineEvent(aa,"mouse_scroll")function aa.new()local ba=setmetatable({},aa):__init() -ba.class=aa;ba.set("width",30)ba.set("height",10)ba.set("z",5) -return ba end -function aa:init(ba,ca) -d.init(self,ba,ca)self.set("type","Table")return self end -function aa:addColumn(ba,ca)local da=self.get("columns") -table.insert(da,{name=ba,width=ca})self.set("columns",da)return self end;function aa:addData(...)local ba=self.get("data")table.insert(ba,{...}) -self.set("data",ba)return self end -function aa:setColumnSortFunction(ba,ca) -local da=self.get("customSortFunction")da[ba]=ca;self.set("customSortFunction",da)return self end -function aa:setFormattedData(ba,ca)local da={}for _b,ab in ipairs(ba)do local bb={}for cb,db in ipairs(ab)do bb[cb]=db end;if ca and -ca[_b]then bb._sortValues=ca[_b]end -table.insert(da,bb)end -self.set("data",da)return self end -function aa:setData(ba,ca)if not ca then self.set("data",ba)return self end -local da={} -for _b,ab in ipairs(ba)do local bb={}for cb,db in ipairs(ab)do -if ca[cb]then bb[cb]=ca[cb](db)else bb[cb]=db end end;table.insert(da,bb)end;return self:setFormattedData(da,ba)end -function aa:calculateColumnWidths(ba,ca)local da={}local _b=ca;local ab={}local bb=0 -for db,_c in ipairs(ba)do -da[db]={name=_c.name,width=_c.width,minWidth=_c.minWidth or 3,maxWidth=_c.maxWidth} -if type(_c.width)=="number"then -da[db].visibleWidth=math.max(_c.width,da[db].minWidth)if da[db].maxWidth then -da[db].visibleWidth=math.min(da[db].visibleWidth,da[db].maxWidth)end -_b=_b-da[db].visibleWidth;bb=bb+da[db].visibleWidth elseif type(_c.width)=="string"and -_c.width:match("%%$")then -local ac=tonumber(_c.width:match("(%d+)%%")) -if ac then da[db].visibleWidth=math.floor(ca*ac/100) -da[db].visibleWidth=math.max(da[db].visibleWidth,da[db].minWidth)if da[db].maxWidth then -da[db].visibleWidth=math.min(da[db].visibleWidth,da[db].maxWidth)end -_b=_b-da[db].visibleWidth;bb=bb+da[db].visibleWidth else table.insert(ab,db)end else table.insert(ab,db)end end -if#ab>0 and _b>0 then local db=math.floor(_b/#ab) -for _c,ac in ipairs(ab)do -da[ac].visibleWidth=math.max(db,da[ac].minWidth)if da[ac].maxWidth then -da[ac].visibleWidth=math.min(da[ac].visibleWidth,da[ac].maxWidth)end end end;local cb=0 -for db,_c in ipairs(da)do cb=cb+ (_c.visibleWidth or 0)end;if cb>ca then local db=ca/cb -for _c,ac in ipairs(da)do if ac.visibleWidth then -ac.visibleWidth=math.max(1,math.floor(ac.visibleWidth*db))end end end -return da end -function aa:sortData(ba,ca)local da=self.get("data") -local _b=self.get("sortDirection")local ab=self.get("customSortFunction")local bb=ca or ab[ba] -if bb then -table.sort(da,function(cb,db)return -bb(cb,db,_b)end)else -table.sort(da,function(cb,db)if not cb or not db then return false end;local _c,ac -if cb._sortValues and -cb._sortValues[ba]then _c=cb._sortValues[ba]else _c=cb[ba]end;if db._sortValues and db._sortValues[ba]then ac=db._sortValues[ba]else -ac=db[ba]end -if type(_c)=="number"and -type(ac)=="number"then if _b=="asc"then return _cac end else local bc=tostring( -_c or"")local cc=tostring(ac or"")if _b=="asc"then -return bccc end end end)end;return self end -function aa:mouse_click(ba,ca,da) -if not d.mouse_click(self,ba,ca,da)then return false end;local _b,ab=self:getRelativePosition(ca,da) -if ab==1 then -local bb=self.get("columns")local cb=self.get("width") -local db=self:calculateColumnWidths(bb,cb)local _c=1 -for ac,bc in ipairs(db)do -local cc=bc.visibleWidth or bc.width or 10 -if _b>=_c and _b<_c+cc then -if self.get("sortColumn")==ac then -self.set("sortDirection", -self.get("sortDirection")=="asc"and"desc"or"asc")else self.set("sortColumn",ac) -self.set("sortDirection","asc")end;self:sortData(ac)break end;_c=_c+cc end end -if ab>1 then local bb=ab-2 +self.get("scrollOffset")if bb>=0 and bb<# -self.get("data")then -self.set("selectedRow",bb+1)end end;return true end -function aa:mouse_scroll(ba,ca,da) -if(d.mouse_scroll(self,ba,ca,da))then local _b=self.get("data") -local ab=self.get("height")local bb=ab-2;local cb=math.max(0,#_b-bb-1) -local db=math.min(cb,math.max(0, -self.get("scrollOffset")+ba))self.set("scrollOffset",db)return true end;return false end -function aa:render()d.render(self)local ba=self.get("columns") -local ca=self.get("data")local da=self.get("selectedRow") -local _b=self.get("sortColumn")local ab=self.get("scrollOffset")local bb=self.get("height") -local cb=self.get("width")local db=self:calculateColumnWidths(ba,cb)local _c=0;local ac=#db;for cc,dc in -ipairs(db)do if _c+dc.visibleWidth>cb then ac=cc-1;break end -_c=_c+dc.visibleWidth end;local bc=1 -for cc,dc in ipairs(db)do -if cc>ac then break end;local _d=dc.name;if cc==_b then -_d=_d.. ( -self.get("sortDirection")=="asc"and"\30"or"\31")end -self:textFg(bc,1,_d:sub(1,dc.visibleWidth),self.get("headerColor"))bc=bc+dc.visibleWidth end -for y=2,bb do local cc=y-2 +ab;local dc=ca[cc+1] -if dc and(cc+1)<=#ca then bc=1 -local _d=(cc+1)==da and -self.get("selectedColor")or self.get("background") -for ad,bd in ipairs(db)do if ad>ac then break end;local cd=tostring(dc[ad]or"")local dd=cd..string.rep(" ", -bd.visibleWidth-#cd)if -ad=_b then return false end;if ab and not ba:match(ab)then return -false end -self.set("text",ca:sub(1,da-1)..ba..ca:sub(da))self.set("cursorPos",da+1)self:updateViewport()local bb= -self.get("cursorPos")-self.get("viewOffset") -self:setCursor(bb,1,true, -self.get("cursorColor")or self.get("foreground"))d.char(self,ba)return true end -function aa:key(ba,ca)if not self.get("focused")then return false end -local da=self.get("cursorPos")local _b=self.get("text")local ab=self.get("viewOffset") -local bb=self.get("width") -if ba==keys.left then if da>1 then self.set("cursorPos",da-1) -if da-1 <=ab then self.set("viewOffset",math.max(0, -da-2))end end elseif ba==keys.right then if da<=#_b then self.set("cursorPos", -da+1)if da-ab>=bb then -self.set("viewOffset",da-bb+1)end end elseif -ba==keys.backspace then if da>1 then -self.set("text",_b:sub(1,da-2).._b:sub(da))self.set("cursorPos",da-1)self:updateRender() -self:updateViewport()end end -local cb=self.get("cursorPos")-self.get("viewOffset") -self:setCursor(cb,1,true,self.get("cursorColor")or self.get("foreground"))d.key(self,ba,ca)return true end -function aa:mouse_click(ba,ca,da) -if d.mouse_click(self,ba,ca,da)then -local _b,ab=self:getRelativePosition(ca,da)local bb=self.get("text")local cb=self.get("viewOffset") -local db=#bb+1;local _c=math.min(db,cb+_b)self.set("cursorPos",_c) -local ac=_c-cb -self:setCursor(ac,1,true,self.get("cursorColor")or self.get("foreground"))return true end;return false end -function aa:updateViewport()local ba=self.get("width") -local ca=self.get("cursorPos")local da=self.get("viewOffset") -local _b=#self.get("text") -if ca-da>=ba then self.set("viewOffset",ca-ba+1)elseif ca<=da then self.set("viewOffset", -ca-1)end -self.set("viewOffset",math.max(0,math.min(self.get("viewOffset"),_b-ba+1)))return self end -function aa:focus()d.focus(self) -self:setCursor(self.get("cursorPos")- -self.get("viewOffset"),1,true,self.get("cursorColor")or self.get("foreground"))self:updateRender()end -function aa:blur()d.blur(self) -self:setCursor(1,1,false,self.get("cursorColor")or -self.get("foreground"))self:updateRender()end -function aa:paste(ba)if not self.get("focused")then return false end -local ca=self.get("text")local da=self.get("cursorPos")local _b=self.get("maxLength") -local ab=self.get("pattern")local bb=ca:sub(1,da-1)..ba..ca:sub(da)if -_b and#bb>_b then bb=bb:sub(1,_b)end;if ab and not bb:match(ab)then -return false end;self.set("text",bb) -self.set("cursorPos",da+#ba)self:updateViewport()end -function aa:render()local ba=self.get("text")local ca=self.get("viewOffset") -local da=self.get("width")local _b=self.get("placeholder") -local ab=self.get("focusedBackground")local bb=self.get("focusedForeground") -local cb=self.get("focused")local db,_c=self.get("width"),self.get("height") -local ac=self.get("replaceChar") -self:multiBlit(1,1,db,_c," ",_a[cb and bb or self.get("foreground")],_a[ -cb and ab or self.get("background")])if -#ba==0 and#_b~=0 and self.get("focused")==false then -self:textFg(1,1,_b:sub(1,db),self.get("placeholderColor"))return end;if(cb)then -self:setCursor( -self.get("cursorPos")-ca,1,true,self.get("cursorColor")or self.get("foreground"))end -local bc=ba:sub(ca+1,ca+db)if ac and#ac>0 then bc=ac:rep(#bc)end -self:textFg(1,1,bc,self.get("foreground"))end;return aa end -project["elements/Timer.lua"] = function(...) local d=require("elementManager") -local _a=d.getElement("BaseElement")local aa=setmetatable({},_a)aa.__index=aa -aa.defineProperty(aa,"interval",{default=1,type="number"}) -aa.defineProperty(aa,"action",{default=function()end,type="function"}) -aa.defineProperty(aa,"running",{default=false,type="boolean"}) -aa.defineProperty(aa,"amount",{default=-1,type="number"})aa.defineEvent(aa,"timer")function aa.new() -local ba=setmetatable({},aa):__init()ba.class=aa;return ba end;function aa:init(ba,ca) -_a.init(self,ba,ca)self.set("type","Timer")end -function aa:start()if -not self.running then self.running=true;local ba=self.get("interval") -self.timerId=os.startTimer(ba)end;return self end -function aa:stop()if self.running then self.running=false -os.cancelTimer(self.timerId)end;return self end -function aa:dispatchEvent(ba,...)_a.dispatchEvent(self,ba,...) -if ba=="timer"then -local ca=select(1,...) -if ca==self.timerId then self.action()local da=self.get("amount")if da>0 then self.set("amount", -da-1)end;if da~=0 then -self.timerId=os.startTimer(self.get("interval"))end end end end;return aa end -project["elements/Button.lua"] = function(...) local _a=require("elementManager") -local aa=_a.getElement("VisualElement") -local ba=require("libraries/utils").getCenteredPosition;local ca=setmetatable({},aa)ca.__index=ca -ca.defineProperty(ca,"text",{default="Button",type="string",canTriggerRender=true})ca.defineEvent(ca,"mouse_click") -ca.defineEvent(ca,"mouse_up")function ca.new()local da=setmetatable({},ca):__init() -da.class=ca;da.set("width",10)da.set("height",3)da.set("z",5) -return da end;function ca:init(da,_b) -aa.init(self,da,_b)self.set("type","Button")end -function ca:render() -aa.render(self)local da=self.get("text") -da=da:sub(1,self.get("width")) -local _b,ab=ba(da,self.get("width"),self.get("height")) -self:textFg(_b,ab,da,self.get("foreground"))end;return ca end -project["elements/VisualElement.lua"] = function(...) local ba=require("elementManager") -local ca=ba.getElement("BaseElement")local da=require("libraries/colorHex") -local _b=setmetatable({},ca)_b.__index=_b -_b.defineProperty(_b,"x",{default=1,type="number",canTriggerRender=true}) -_b.defineProperty(_b,"y",{default=1,type="number",canTriggerRender=true}) -_b.defineProperty(_b,"z",{default=1,type="number",canTriggerRender=true,setter=function(cb,db) -if cb.parent then cb.parent:sortChildren()end;return db end}) -_b.defineProperty(_b,"width",{default=1,type="number",canTriggerRender=true}) -_b.defineProperty(_b,"height",{default=1,type="number",canTriggerRender=true}) -_b.defineProperty(_b,"background",{default=colors.black,type="color",canTriggerRender=true}) -_b.defineProperty(_b,"foreground",{default=colors.white,type="color",canTriggerRender=true}) -_b.defineProperty(_b,"clicked",{default=false,type="boolean"}) -_b.defineProperty(_b,"hover",{default=false,type="boolean"}) -_b.defineProperty(_b,"backgroundEnabled",{default=true,type="boolean",canTriggerRender=true}) -_b.defineProperty(_b,"focused",{default=false,type="boolean",setter=function(cb,db,_c)local ac=cb.get("focused") -if db==ac then return db end;if db then cb:focus()else cb:blur()end;if not _c and cb.parent then -if db then -cb.parent:setFocusedChild(cb)else cb.parent:setFocusedChild(nil)end end;return db end}) -_b.defineProperty(_b,"visible",{default=true,type="boolean",canTriggerRender=true,setter=function(cb,db) -if(cb.parent~=nil)then -cb.parent.set("childrenSorted",false)cb.parent.set("childrenEventsSorted",false)end;if(db==false)then cb.set("clicked",false)end;return db end}) -_b.defineProperty(_b,"ignoreOffset",{default=false,type="boolean"})_b.combineProperties(_b,"position","x","y") -_b.combineProperties(_b,"size","width","height") -_b.combineProperties(_b,"color","foreground","background")_b.defineEvent(_b,"focus") -_b.defineEvent(_b,"blur") -_b.registerEventCallback(_b,"Click","mouse_click","mouse_up") -_b.registerEventCallback(_b,"ClickUp","mouse_up","mouse_click") -_b.registerEventCallback(_b,"Drag","mouse_drag","mouse_click","mouse_up") -_b.registerEventCallback(_b,"Scroll","mouse_scroll") -_b.registerEventCallback(_b,"Enter","mouse_enter","mouse_move") -_b.registerEventCallback(_b,"LeEave","mouse_leave","mouse_move")_b.registerEventCallback(_b,"Focus","focus","blur") -_b.registerEventCallback(_b,"Blur","blur","focus")_b.registerEventCallback(_b,"Key","key","key_up") -_b.registerEventCallback(_b,"Char","char")_b.registerEventCallback(_b,"KeyUp","key_up","key") -local ab,bb=math.max,math.min;function _b.new()local cb=setmetatable({},_b):__init() -cb.class=_b;return cb end -function _b:init(cb,db) -ca.init(self,cb,db)self.set("type","VisualElement") -self:observe("x",function()if self.parent then -self.parent.set("childrenSorted",false)end end) -self:observe("y",function()if self.parent then -self.parent.set("childrenSorted",false)end end) -self:observe("width",function()if self.parent then -self.parent.set("childrenSorted",false)end end) -self:observe("height",function()if self.parent then -self.parent.set("childrenSorted",false)end end) -self:observe("visible",function()if self.parent then -self.parent.set("childrenSorted",false)end end)end -function _b:multiBlit(cb,db,_c,ac,bc,cc,dc)local _d,ad=self:calculatePosition()cb=cb+_d-1 -db=db+ad-1;self.parent:multiBlit(cb,db,_c,ac,bc,cc,dc)end -function _b:textFg(cb,db,_c,ac)local bc,cc=self:calculatePosition()cb=cb+bc-1 -db=db+cc-1;self.parent:textFg(cb,db,_c,ac)end -function _b:textBg(cb,db,_c,ac)local bc,cc=self:calculatePosition()cb=cb+bc-1 -db=db+cc-1;self.parent:textBg(cb,db,_c,ac)end -function _b:drawText(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 -db=db+bc-1;self.parent:drawText(cb,db,_c)end -function _b:drawFg(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 -db=db+bc-1;self.parent:drawFg(cb,db,_c)end -function _b:drawBg(cb,db,_c)local ac,bc=self:calculatePosition()cb=cb+ac-1 -db=db+bc-1;self.parent:drawBg(cb,db,_c)end -function _b:blit(cb,db,_c,ac,bc)local cc,dc=self:calculatePosition()cb=cb+cc-1 -db=db+dc-1;self.parent:blit(cb,db,_c,ac,bc)end -function _b:isInBounds(cb,db)local _c,ac=self.get("x"),self.get("y") -local bc,cc=self.get("width"),self.get("height")if(self.get("ignoreOffset"))then -if(self.parent)then -cb=cb-self.parent.get("offsetX")db=db-self.parent.get("offsetY")end end;return -cb>=_c and cb<= -_c+bc-1 and db>=ac and db<=ac+cc-1 end -function _b:mouse_click(cb,db,_c)if self:isInBounds(db,_c)then self.set("clicked",true) -self:fireEvent("mouse_click",cb,self:getRelativePosition(db,_c))return true end;return -false end -function _b:mouse_up(cb,db,_c)if self:isInBounds(db,_c)then self.set("clicked",false) -self:fireEvent("mouse_up",cb,self:getRelativePosition(db,_c))return true end;return -false end -function _b:mouse_release(cb,db,_c) -self:fireEvent("mouse_release",cb,self:getRelativePosition(db,_c))self.set("clicked",false)end -function _b:mouse_move(cb,db,_c)if(db==nil)or(_c==nil)then return end -local ac=self.get("hover") -if(self:isInBounds(db,_c))then if(not ac)then self.set("hover",true) -self:fireEvent("mouse_enter",self:getRelativePosition(db,_c))end;return true else if(ac)then -self.set("hover",false) -self:fireEvent("mouse_leave",self:getRelativePosition(db,_c))end end;return false end -function _b:mouse_scroll(cb,db,_c)if(self:isInBounds(db,_c))then -self:fireEvent("mouse_scroll",cb,self:getRelativePosition(db,_c))return true end;return false end -function _b:mouse_drag(cb,db,_c)if(self.get("clicked"))then -self:fireEvent("mouse_drag",cb,self:getRelativePosition(db,_c))return true end;return false end;function _b:focus()self:fireEvent("focus")end;function _b:blur() -self:fireEvent("blur")self:setCursor(1,1,false)end -function _b:key(cb,db)if -(self.get("focused"))then self:fireEvent("key",cb,db)end end;function _b:key_up(cb) -if(self.get("focused"))then self:fireEvent("key_up",cb)end end;function _b:char(cb)if(self.get("focused"))then -self:fireEvent("char",cb)end end -function _b:calculatePosition() -local cb,db=self.get("x"),self.get("y") -if not self.get("ignoreOffset")then if self.parent~=nil then -local _c,ac=self.parent.get("offsetX"),self.parent.get("offsetY")cb=cb-_c;db=db-ac end end;return cb,db end -function _b:getAbsolutePosition(cb,db)local _c,ac=self.get("x"),self.get("y")if(cb~=nil)then -_c=_c+cb-1 end;if(db~=nil)then ac=ac+db-1 end;local bc=self.parent -while bc do -local cc,dc=bc.get("x"),bc.get("y")_c=_c+cc-1;ac=ac+dc-1;bc=bc.parent end;return _c,ac end -function _b:getRelativePosition(cb,db)if(cb==nil)or(db==nil)then -cb,db=self.get("x"),self.get("y")end;local _c,ac=1,1;if self.parent then -_c,ac=self.parent:getRelativePosition()end -local bc,cc=self.get("x"),self.get("y")return cb- (bc-1)- (_c-1),db- (cc-1)- (ac-1)end -function _b:setCursor(cb,db,_c,ac) -if self.parent then local bc,cc=self:calculatePosition() -if -(cb+bc-1 <1)or( -cb+bc-1 >self.parent.get("width"))or(db+cc-1 <1)or(db+cc-1 > -self.parent.get("height"))then return self.parent:setCursor( -cb+bc-1,db+cc-1,false)end -return self.parent:setCursor(cb+bc-1,db+cc-1,_c,ac)end;return self end -function _b:prioritize() -if(self.parent)then local cb=self.parent;cb:removeChild(self) -cb:addChild(self)self:updateRender()end;return self end -function _b:render() -if(not self.get("backgroundEnabled"))then return end;local cb,db=self.get("width"),self.get("height") -self:multiBlit(1,1,cb,db," ",da[self.get("foreground")],da[self.get("background")])end;function _b:postRender()end;function _b:destroy()self.set("visible",false) -ca.destroy(self)end;return _b end -project["elements/FlexBox.lua"] = function(...) local da=require("elementManager") -local _b=da.getElement("Container")local ab=setmetatable({},_b)ab.__index=ab -ab.defineProperty(ab,"flexDirection",{default="row",type="string"}) -ab.defineProperty(ab,"flexSpacing",{default=1,type="number"}) -ab.defineProperty(ab,"flexJustifyContent",{default="flex-start",type="string",setter=function(bc,cc)if not cc:match("^flex%-")then -cc="flex-"..cc end;return cc end}) -ab.defineProperty(ab,"flexAlignItems",{default="flex-start",type="string",setter=function(bc,cc)if -not cc:match("^flex%-")and cc~="stretch"then cc="flex-"..cc end;return cc end}) -ab.defineProperty(ab,"flexCrossPadding",{default=0,type="number"}) -ab.defineProperty(ab,"flexWrap",{default=false,type="boolean"}) -ab.defineProperty(ab,"flexUpdateLayout",{default=false,type="boolean"}) -local bb={getHeight=function(bc)return 0 end,getWidth=function(bc)return 0 end,getZ=function(bc)return 1 end,getPosition=function(bc)return 0,0 end,getSize=function(bc)return 0,0 end,isType=function(bc)return -false end,getType=function(bc)return"lineBreak"end,getName=function(bc)return"lineBreak"end,setPosition=function(bc) -end,setParent=function(bc)end,setSize=function(bc)end,getFlexGrow=function(bc)return 0 end,getFlexShrink=function(bc)return 0 end,getFlexBasis=function(bc)return 0 end,init=function(bc)end,getVisible=function(bc)return -true end} -local function cb(bc,cc,dc,_d)local ad={}local bd={}local cd=0 -for __a,a_a in pairs(bc.get("children"))do if a_a.get("visible")then -table.insert(bd,a_a)if a_a~=bb then cd=cd+1 end end end;if cd==0 then return ad end -if not _d then ad[1]={offset=1} -for __a,a_a in ipairs(bd)do if a_a==bb then local b_a=#ad+1;if -ad[b_a]==nil then ad[b_a]={offset=1}end else -table.insert(ad[#ad],a_a)end end else -local __a=cc=="row"and bc.get("width")or bc.get("height")local a_a={{}}local b_a=1 -for c_a,d_a in ipairs(bd)do if d_a==bb then b_a=b_a+1;a_a[b_a]={}else -table.insert(a_a[b_a],d_a)end end -for c_a,d_a in ipairs(a_a)do -if#d_a==0 then ad[#ad+1]={offset=1}else local _aa={}local aaa={}local baa=0 -for caa,daa in ipairs(d_a)do -local _ba=0 -local aba=cc=="row"and daa.get("width")or daa.get("height")local bba=false -if cc=="row"then -local _ca,aca=pcall(function()return daa.get("intrinsicWidth")end)if _ca and aca then _ba=aca;bba=true end else -local _ca,aca=pcall(function() -return daa.get("intrinsicHeight")end)if _ca and aca then _ba=aca;bba=true end end;local cba=bba and _ba or aba;local dba=cba;if#aaa>0 then dba=dba+dc end -if -baa+dba<=__a or#aaa==0 then table.insert(aaa,daa) -baa=baa+dba else table.insert(_aa,aaa)aaa={daa}baa=cba end end;if#aaa>0 then table.insert(_aa,aaa)end;for caa,daa in ipairs(_aa)do -ad[#ad+1]={offset=1} -for _ba,aba in ipairs(daa)do table.insert(ad[#ad],aba)end end end end end;local dd={} -for __a,a_a in ipairs(ad)do if#a_a>0 then table.insert(dd,a_a)end end;return dd end -local function db(bc,cc,dc,_d)local ad={} -for dca,_da in ipairs(cc)do if _da~=bb then table.insert(ad,_da)end end;if#ad==0 then return end;local bd=bc.get("width") -local cd=bc.get("height")local dd=bc.get("flexAlignItems") -local __a=bc.get("flexCrossPadding")local a_a=bc.get("flexWrap")if bd<=0 then return end;local b_a=cd- (__a*2)if b_a< -1 then b_a=cd;__a=0 end;local c_a=math.max;local d_a=math.min -local _aa=math.floor;local aaa=math.ceil;local baa=0;local caa=0;local daa={}local _ba={}local aba={} -for dca,_da in ipairs(ad)do local ada= -_da.get("flexGrow")or 0 -local bda=_da.get("flexShrink")or 0;local cda=_da.get("width")_ba[_da]=ada;aba[_da]=bda;daa[_da]=cda;if -ada>0 then caa=caa+ada else baa=baa+cda end end;local bba=#ad;local cba=(bba>1)and( (bba-1)*dc)or 0;local dba= -bd-baa-cba -if dba>0 and caa>0 then -for dca,_da in ipairs(ad)do local ada=_ba[_da]if ada>0 then -local bda=daa[_da]local cda=_aa((ada/caa)*dba) -_da.set("width",c_a(cda,1))end end elseif dba<0 then local dca=0;local _da={}for ada,bda in ipairs(ad)do local cda=aba[bda]if cda>0 then dca=dca+cda -table.insert(_da,bda)end end -if -dca>0 and#_da>0 then local ada=-dba;for bda,cda in ipairs(_da)do local dda=cda.get("width") -local __b=aba[cda]local a_b=__b/dca;local b_b=aaa(ada*a_b) -cda.set("width",c_a(1,dda-b_b))end end;baa=0 -for ada,bda in ipairs(ad)do baa=baa+bda.get("width")end -if caa>0 then local ada={}local bda=0 -for cda,dda in ipairs(ad)do if _ba[dda]>0 then table.insert(ada,dda)bda=bda+ -dda.get("width")end end -if#ada>0 and bda>0 then local cda=c_a(_aa(bd*0.2),#ada) -local dda=d_a(cda,bd-cba) -for __b,a_b in ipairs(ada)do local b_b=_ba[a_b]local c_b=b_b/caa -local d_b=c_a(1,_aa(dda*c_b))a_b.set("width",d_b)end end end end;local _ca=1 -for dca,_da in ipairs(ad)do _da.set("x",_ca) -if not a_a then -if dd=="stretch"then -_da.set("height",b_a)_da.set("y",1 +__a)else local bda=_da.get("height")local cda=1;if -dd=="flex-end"then cda=cd-bda+1 elseif dd=="flex-center"or dd=="center"then cda= -_aa((cd-bda)/2)+1 end -_da.set("y",c_a(1,cda))end end -local ada=_da.get("y")+_da.get("height")-1;if -ada>cd and(_da.get("flexShrink")or 0)>0 then -_da.set("height",c_a(1,cd-_da.get("y")+1))end;_ca= -_ca+_da.get("width")+dc end;local aca=ad[#ad]local bca=0;if aca then -bca=aca.get("x")+aca.get("width")-1 end;local cca=bd-bca -if cca>0 then -if _d=="flex-end"then for dca,_da in ipairs(ad)do _da.set("x", -_da.get("x")+cca)end elseif _d== -"flex-center"or _d=="center"then local dca=_aa(cca/2)for _da,ada in ipairs(ad)do ada.set("x", -ada.get("x")+dca)end end end end -local function _c(bc,cc,dc,_d)local ad={} -for dca,_da in ipairs(cc)do if _da~=bb then table.insert(ad,_da)end end;if#ad==0 then return end;local bd=bc.get("width") -local cd=bc.get("height")local dd=bc.get("flexAlignItems") -local __a=bc.get("flexCrossPadding")local a_a=bc.get("flexWrap")if cd<=0 then return end;local b_a=bd- (__a*2)if b_a< -1 then b_a=bd;__a=0 end;local c_a=math.max;local d_a=math.min -local _aa=math.floor;local aaa=math.ceil;local baa=0;local caa=0;local daa={}local _ba={}local aba={} -for dca,_da in ipairs(ad)do local ada= -_da.get("flexGrow")or 0 -local bda=_da.get("flexShrink")or 0;local cda=_da.get("height")_ba[_da]=ada;aba[_da]=bda;daa[_da]=cda;if -ada>0 then caa=caa+ada else baa=baa+cda end end;local bba=#ad;local cba=(bba>1)and( (bba-1)*dc)or 0;local dba= -cd-baa-cba -if dba>0 and caa>0 then -for dca,_da in ipairs(ad)do local ada=_ba[_da]if ada>0 then -local bda=daa[_da]local cda=_aa((ada/caa)*dba) -_da.set("height",c_a(cda,1))end end elseif dba<0 then local dca=0;local _da={}for ada,bda in ipairs(ad)do local cda=aba[bda]if cda>0 then dca=dca+cda -table.insert(_da,bda)end end -if -dca>0 and#_da>0 then local ada=-dba -for bda,cda in ipairs(_da)do local dda=cda.get("height") -local __b=aba[cda]local a_b=__b/dca;local b_b=aaa(ada*a_b) -cda.set("height",c_a(1,dda-b_b))end end;baa=0 -for ada,bda in ipairs(ad)do baa=baa+bda.get("height")end -if caa>0 then local ada={}local bda=0 -for cda,dda in ipairs(ad)do if _ba[dda]>0 then table.insert(ada,dda)bda=bda+ -dda.get("height")end end -if#ada>0 and bda>0 then local cda=c_a(_aa(cd*0.2),#ada) -local dda=d_a(cda,cd-cba) -for __b,a_b in ipairs(ada)do local b_b=_ba[a_b]local c_b=b_b/caa -local d_b=c_a(1,_aa(dda*c_b))a_b.set("height",d_b)end end end end;local _ca=1 -for dca,_da in ipairs(ad)do _da.set("y",_ca) -if not a_a then -if dd=="stretch"then -_da.set("width",b_a)_da.set("x",1 +__a)else local bda=_da.get("width")local cda=1;if -dd=="flex-end"then cda=bd-bda+1 elseif dd=="flex-center"or dd=="center"then cda= -_aa((bd-bda)/2)+1 end -_da.set("x",c_a(1,cda))end end -local ada=_da.get("x")+_da.get("width")-1;if -ada>bd and(_da.get("flexShrink")or 0)>0 then -_da.set("width",c_a(1,bd-_da.get("x")+1))end;_ca= -_ca+_da.get("height")+dc end;local aca=ad[#ad]local bca=0;if aca then -bca=aca.get("y")+aca.get("height")-1 end;local cca=cd-bca -if cca>0 then -if _d=="flex-end"then for dca,_da in ipairs(ad)do _da.set("y", -_da.get("y")+cca)end elseif _d== -"flex-center"or _d=="center"then local dca=_aa(cca/2)for _da,ada in ipairs(ad)do ada.set("y", -ada.get("y")+dca)end end end end -local function ac(bc,cc,dc,_d,ad) -if bc.get("width")<=0 or bc.get("height")<=0 then return end -cc=(cc=="row"or cc=="column")and cc or"row"local bd,cd=bc.get("width"),bc.get("height") -local dd= -bd~=bc._lastLayoutWidth or cd~=bc._lastLayoutHeight;bc._lastLayoutWidth=bd;bc._lastLayoutHeight=cd -if -ad and dd and(bd>bc._lastLayoutWidth or -cd>bc._lastLayoutHeight)then -for b_a,c_a in pairs(bc.get("children"))do -if -c_a~=bb and c_a:getVisible()and -c_a.get("flexGrow")and c_a.get("flexGrow")>0 then -if cc=="row"then -local d_a,_aa=pcall(function()return c_a.get("intrinsicWidth")end)if d_a and _aa then c_a.set("width",_aa)end else -local d_a,_aa=pcall(function()return -c_a.get("intrinsicHeight")end)if d_a and _aa then c_a.set("height",_aa)end end end end end;local __a=cb(bc,cc,dc,ad)if#__a==0 then return end -local a_a=cc=="row"and db or _c -if cc=="row"and ad then local b_a=1 -for c_a,d_a in ipairs(__a)do -if#d_a>0 then for aaa,baa in ipairs(d_a)do if baa~=bb then -baa.set("y",b_a)end end;a_a(bc,d_a,dc,_d) -local _aa=0;for aaa,baa in ipairs(d_a)do if baa~=bb then -_aa=math.max(_aa,baa.get("height"))end end;if c_a< -#__a then b_a=b_a+_aa+dc else b_a=b_a+_aa end end end elseif cc=="column"and ad then local b_a=1 -for c_a,d_a in ipairs(__a)do -if#d_a>0 then for aaa,baa in ipairs(d_a)do if baa~=bb then -baa.set("x",b_a)end end;a_a(bc,d_a,dc,_d) -local _aa=0;for aaa,baa in ipairs(d_a)do -if baa~=bb then _aa=math.max(_aa,baa.get("width"))end end;if c_a<#__a then b_a=b_a+_aa+dc else b_a= -b_a+_aa end end end else for b_a,c_a in ipairs(__a)do a_a(bc,c_a,dc,_d)end end;bc:sortChildren() -bc.set("childrenEventsSorted",false)bc.set("flexUpdateLayout",false)end -function ab.new()local bc=setmetatable({},ab):__init() -bc.class=ab;bc.set("width",12)bc.set("height",6) -bc.set("background",colors.blue)bc.set("z",10)bc._lastLayoutWidth=0;bc._lastLayoutHeight=0 -bc:observe("width",function() -bc.set("flexUpdateLayout",true)end) -bc:observe("height",function()bc.set("flexUpdateLayout",true)end) -bc:observe("flexDirection",function()bc.set("flexUpdateLayout",true)end) -bc:observe("flexSpacing",function()bc.set("flexUpdateLayout",true)end) -bc:observe("flexWrap",function()bc.set("flexUpdateLayout",true)end) -bc:observe("flexJustifyContent",function()bc.set("flexUpdateLayout",true)end) -bc:observe("flexAlignItems",function()bc.set("flexUpdateLayout",true)end) -bc:observe("flexCrossPadding",function()bc.set("flexUpdateLayout",true)end)return bc end;function ab:init(bc,cc)_b.init(self,bc,cc)self.set("type","FlexBox") -return self end -function ab:addChild(bc) -_b.addChild(self,bc) -if(bc~=bb)then -bc:instanceProperty("flexGrow",{default=0,type="number"}) -bc:instanceProperty("flexShrink",{default=0,type="number"}) -bc:instanceProperty("flexBasis",{default=0,type="number"}) -bc:instanceProperty("intrinsicWidth",{default=bc.get("width"),type="number"}) -bc:instanceProperty("intrinsicHeight",{default=bc.get("height"),type="number"}) -bc:observe("flexGrow",function()self.set("flexUpdateLayout",true)end) -bc:observe("flexShrink",function()self.set("flexUpdateLayout",true)end) -bc:observe("width",function(cc,dc,_d)if bc.get("flexGrow")==0 then -bc.set("intrinsicWidth",dc)end -self.set("flexUpdateLayout",true)end) -bc:observe("height",function(cc,dc,_d)if bc.get("flexGrow")==0 then -bc.set("intrinsicHeight",dc)end -self.set("flexUpdateLayout",true)end)end;self.set("flexUpdateLayout",true)return self end -function ab:removeChild(bc)_b.removeChild(self,bc) -if(bc~=bb)then bc.setFlexGrow=nil;bc.setFlexShrink= -nil;bc.setFlexBasis=nil;bc.getFlexGrow=nil;bc.getFlexShrink=nil;bc.getFlexBasis= -nil;bc.set("flexGrow",nil) -bc.set("flexShrink",nil)bc.set("flexBasis",nil)end;self.set("flexUpdateLayout",true)return self end;function ab:addLineBreak()self:addChild(bb)return self end -function ab:render() -if -(self.get("flexUpdateLayout"))then -ac(self,self.get("flexDirection"),self.get("flexSpacing"),self.get("flexJustifyContent"),self.get("flexWrap"))end;_b.render(self)end;return ab end -project["elements/CheckBox.lua"] = function(...) local c=require("elements/VisualElement") -local d=setmetatable({},c)d.__index=d -d.defineProperty(d,"checked",{default=false,type="boolean",canTriggerRender=true}) -d.defineProperty(d,"text",{default=" ",type="string",canTriggerRender=true,setter=function(_a,aa)local ba=_a.get("checkedText") -local ca=math.max(#aa,#ba)if(_a.get("autoSize"))then _a.set("width",ca)end;return aa end}) -d.defineProperty(d,"checkedText",{default="x",type="string",canTriggerRender=true,setter=function(_a,aa)local ba=_a.get("text") -local ca=math.max(#aa,#ba)if(_a.get("autoSize"))then _a.set("width",ca)end;return aa end}) -d.defineProperty(d,"autoSize",{default=true,type="boolean"})d.defineEvent(d,"mouse_click") -d.defineEvent(d,"mouse_up")function d.new()local _a=setmetatable({},d):__init()_a.class=d -_a.set("backgroundEnabled",false)return _a end -function d:init(_a,aa) -c.init(self,_a,aa)self.set("type","CheckBox")end -function d:mouse_click(_a,aa,ba)if c.mouse_click(self,_a,aa,ba)then -self.set("checked",not self.get("checked"))return true end;return false end -function d:render()c.render(self)local _a=self.get("checked") -local aa=self.get("text")local ba=self.get("checkedText") -local ca=string.sub(_a and ba or aa,1,self.get("width"))self:textFg(1,1,ca,self.get("foreground"))end;return d end -project["elements/BigFont.lua"] = function(...) local _b=require("libraries/colorHex") -local ab={{"\32\32\32\137\156\148\158\159\148\135\135\144\159\139\32\136\157\32\159\139\32\32\143\32\32\143\32\32\32\32\32\32\32\32\147\148\150\131\148\32\32\32\151\140\148\151\140\147","\32\32\32\149\132\149\136\156\149\144\32\133\139\159\129\143\159\133\143\159\133\138\32\133\138\32\133\32\32\32\32\32\32\150\150\129\137\156\129\32\32\32\133\131\129\133\131\132","\32\32\32\130\131\32\130\131\32\32\129\32\32\32\32\130\131\32\130\131\32\32\32\32\143\143\143\32\32\32\32\32\32\130\129\32\130\135\32\32\32\32\131\32\32\131\32\131","\139\144\32\32\143\148\135\130\144\149\32\149\150\151\149\158\140\129\32\32\32\135\130\144\135\130\144\32\149\32\32\139\32\159\148\32\32\32\32\159\32\144\32\148\32\147\131\132","\159\135\129\131\143\149\143\138\144\138\32\133\130\149\149\137\155\149\159\143\144\147\130\132\32\149\32\147\130\132\131\159\129\139\151\129\148\32\32\139\131\135\133\32\144\130\151\32","\32\32\32\32\32\32\130\135\32\130\32\129\32\129\129\131\131\32\130\131\129\140\141\132\32\129\32\32\129\32\32\32\32\32\32\32\131\131\129\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\159\154\133\133\133\144\152\141\132\133\151\129\136\153\32\32\154\32\159\134\129\130\137\144\159\32\144\32\148\32\32\32\32\32\32\32\32\32\32\32\151\129","\32\32\32\32\133\32\32\32\32\145\145\132\141\140\132\151\129\144\150\146\129\32\32\32\138\144\32\32\159\133\136\131\132\131\151\129\32\144\32\131\131\129\32\144\32\151\129\32","\32\32\32\32\129\32\32\32\32\130\130\32\32\129\32\129\32\129\130\129\129\32\32\32\32\130\129\130\129\32\32\32\32\32\32\32\32\133\32\32\32\32\32\129\32\129\32\32","\150\156\148\136\149\32\134\131\148\134\131\148\159\134\149\136\140\129\152\131\32\135\131\149\150\131\148\150\131\148\32\148\32\32\148\32\32\152\129\143\143\144\130\155\32\134\131\148","\157\129\149\32\149\32\152\131\144\144\131\148\141\140\149\144\32\149\151\131\148\32\150\32\150\131\148\130\156\133\32\144\32\32\144\32\130\155\32\143\143\144\32\152\129\32\134\32","\130\131\32\131\131\129\131\131\129\130\131\32\32\32\129\130\131\32\130\131\32\32\129\32\130\131\32\130\129\32\32\129\32\32\133\32\32\32\129\32\32\32\130\32\32\32\129\32","\150\140\150\137\140\148\136\140\132\150\131\132\151\131\148\136\147\129\136\147\129\150\156\145\138\143\149\130\151\32\32\32\149\138\152\129\149\32\32\157\152\149\157\144\149\150\131\148","\149\143\142\149\32\149\149\32\149\149\32\144\149\32\149\149\32\32\149\32\32\149\32\149\149\32\149\32\149\32\144\32\149\149\130\148\149\32\32\149\32\149\149\130\149\149\32\149","\130\131\129\129\32\129\131\131\32\130\131\32\131\131\32\131\131\129\129\32\32\130\131\32\129\32\129\130\131\32\130\131\32\129\32\129\131\131\129\129\32\129\129\32\129\130\131\32","\136\140\132\150\131\148\136\140\132\153\140\129\131\151\129\149\32\149\149\32\149\149\32\149\137\152\129\137\152\129\131\156\133\149\131\32\150\32\32\130\148\32\152\137\144\32\32\32","\149\32\32\149\159\133\149\32\149\144\32\149\32\149\32\149\32\149\150\151\129\138\155\149\150\130\148\32\149\32\152\129\32\149\32\32\32\150\32\32\149\32\32\32\32\32\32\32","\129\32\32\130\129\129\129\32\129\130\131\32\32\129\32\130\131\32\32\129\32\129\32\129\129\32\129\32\129\32\131\131\129\130\131\32\32\32\129\130\131\32\32\32\32\140\140\132","\32\154\32\159\143\32\149\143\32\159\143\32\159\144\149\159\143\32\159\137\145\159\143\144\149\143\32\32\145\32\32\32\145\149\32\144\32\149\32\143\159\32\143\143\32\159\143\32","\32\32\32\152\140\149\151\32\149\149\32\145\149\130\149\157\140\133\32\149\32\154\143\149\151\32\149\32\149\32\144\32\149\149\153\32\32\149\32\149\133\149\149\32\149\149\32\149","\32\32\32\130\131\129\131\131\32\130\131\32\130\131\129\130\131\129\32\129\32\140\140\129\129\32\129\32\129\32\137\140\129\130\32\129\32\130\32\129\32\129\129\32\129\130\131\32","\144\143\32\159\144\144\144\143\32\159\143\144\159\138\32\144\32\144\144\32\144\144\32\144\144\32\144\144\32\144\143\143\144\32\150\129\32\149\32\130\150\32\134\137\134\134\131\148","\136\143\133\154\141\149\151\32\129\137\140\144\32\149\32\149\32\149\154\159\133\149\148\149\157\153\32\154\143\149\159\134\32\130\148\32\32\149\32\32\151\129\32\32\32\32\134\32","\133\32\32\32\32\133\129\32\32\131\131\32\32\130\32\130\131\129\32\129\32\130\131\129\129\32\129\140\140\129\131\131\129\32\130\129\32\129\32\130\129\32\32\32\32\32\129\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32","\32\32\32\32\145\32\159\139\32\151\131\132\155\143\132\134\135\145\32\149\32\158\140\129\130\130\32\152\147\155\157\134\32\32\144\144\32\32\32\32\32\32\152\131\155\131\131\129","\32\32\32\32\149\32\149\32\145\148\131\32\149\32\149\140\157\132\32\148\32\137\155\149\32\32\32\149\154\149\137\142\32\153\153\32\131\131\149\131\131\129\149\135\145\32\32\32","\32\32\32\32\129\32\130\135\32\131\131\129\134\131\132\32\129\32\32\129\32\131\131\32\32\32\32\130\131\129\32\32\32\32\129\129\32\32\32\32\32\32\130\131\129\32\32\32","\150\150\32\32\148\32\134\32\32\132\32\32\134\32\32\144\32\144\150\151\149\32\32\32\32\32\32\145\32\32\152\140\144\144\144\32\133\151\129\133\151\129\132\151\129\32\145\32","\130\129\32\131\151\129\141\32\32\142\32\32\32\32\32\149\32\149\130\149\149\32\143\32\32\32\32\142\132\32\154\143\133\157\153\132\151\150\148\151\158\132\151\150\148\144\130\148","\32\32\32\140\140\132\32\32\32\32\32\32\32\32\32\151\131\32\32\129\129\32\32\32\32\134\32\32\32\32\32\32\32\129\129\32\129\32\129\129\130\129\129\32\129\130\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\150\151\129\150\131\132\140\143\144\143\141\145\137\140\148\141\141\144\157\142\32\159\140\32\151\134\32\157\141\32","\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\151\151\32\154\143\132\157\140\32\157\140\32\157\140\32\157\140\32\32\149\32\32\149\32\32\149\32\32\149\32","\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\131\129\32\134\32\131\131\129\131\131\129\131\131\129\131\131\129\130\131\32\130\131\32\130\131\32\130\131\32","\151\131\148\152\137\145\155\140\144\152\142\145\153\140\132\153\137\32\154\142\144\155\159\132\150\156\148\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\136\32\151\140\132","\151\32\149\151\155\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\152\137\144\157\129\149\149\32\149\149\32\149\149\32\149\149\32\149\130\150\32\32\157\129\149\32\149","\131\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\129\32\130\131\32\133\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\159\159\144\152\140\144\156\143\32\159\141\129\153\140\132\157\141\32\130\145\32\32\147\32\136\153\32\130\146\32","\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\149\157\134\154\143\132\157\140\133\157\140\133\157\140\133\157\140\133\32\149\32\32\149\32\32\149\32\32\149\32","\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\130\131\32\134\32\130\131\129\130\131\129\130\131\129\130\131\129\32\129\32\32\129\32\32\129\32\32\129\32","\159\134\144\137\137\32\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\32\132\32\159\143\32\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\138\32\146\130\144","\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\131\147\129\138\134\149\149\32\149\149\32\149\149\32\149\149\32\149\154\143\149\32\157\129\154\143\149","\130\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\129\130\131\129\130\131\129\130\131\129\140\140\129\130\131\32\140\140\129"},{"000110000110110000110010101000000010000000100101","000000110110000000000010101000000010000000100101","000000000000000000000000000000000000000000000000","100010110100000010000110110000010100000100000110","000000110000000010110110000110000000000000110000","000000000000000000000000000000000000000000000000","000000110110000010000000100000100000000000000010","000000000110110100010000000010000000000000000100","000000000000000000000000000000000000000000000000","010000000000100110000000000000000000000110010000","000000000000000000000000000010000000010110000000","000000000000000000000000000000000000000000000000","011110110000000100100010110000000100000000000000","000000000000000000000000000000000000000000000000","000000000000000000000000000000000000000000000000","110000110110000000000000000000010100100010000000","000010000000000000110110000000000100010010000000","000000000000000000000000000000000000000000000000","010110010110100110110110010000000100000110110110","000000000000000000000110000000000110000000000000","000000000000000000000000000000000000000000000000","010100010110110000000000000000110000000010000000","110110000000000000110000110110100000000010000000","000000000000000000000000000000000000000000000000","000100011111000100011111000100011111000100011111","000000000000100100100100011011011011111111111111","000000000000000000000000000000000000000000000000","000100011111000100011111000100011111000100011111","000000000000100100100100011011011011111111111111","100100100100100100100100100100100100100100100100","000000110100110110000010000011110000000000011000","000000000100000000000010000011000110000000001000","000000000000000000000000000000000000000000000000","010000100100000000000000000100000000010010110000","000000000000000000000000000000110110110110110000","000000000000000000000000000000000000000000000000","110110110110110110000000110110110110110110110110","000000000000000000000110000000000000000000000000","000000000000000000000000000000000000000000000000","000000000000110110000110010000000000000000010010","000010000000000000000000000000000000000000000000","000000000000000000000000000000000000000000000000","110110110110110110110000110110110110000000000000","000000000000000000000110000000000000000000000000","000000000000000000000000000000000000000000000000","110110110110110110110000110000000000000000010000","000000000000000000000000100000000000000110000110","000000000000000000000000000000000000000000000000"}}local bb={}local cb={} -do local dc=0;local _d=#ab[1]local ad=#ab[1][1] -for i=1,_d,3 do -for j=1,ad,3 do -local bd=string.char(dc)local cd={}cd[1]=ab[1][i]:sub(j,j+2) -cd[2]=ab[1][i+1]:sub(j,j+2)cd[3]=ab[1][i+2]:sub(j,j+2)local dd={}dd[1]=ab[2][i]:sub(j, -j+2)dd[2]=ab[2][i+1]:sub(j,j+2)dd[3]=ab[2][ -i+2]:sub(j,j+2)cb[bd]={cd,dd}dc=dc+1 end end;bb[1]=cb end -local function db(dc,_d)local ad={["0"]="1",["1"]="0"}if dc<=#bb then return true end -for f=#bb+1,dc do local bd={}local cd=bb[ -f-1] -for char=0,255 do local dd=string.char(char)local __a={}local a_a={} -local b_a=cd[dd][1]local c_a=cd[dd][2] -for i=1,#b_a do local d_a,_aa,aaa,baa,caa,daa={},{},{},{},{},{} -for j=1,#b_a[1]do -local _ba=cb[b_a[i]:sub(j,j)][1]table.insert(d_a,_ba[1]) -table.insert(_aa,_ba[2])table.insert(aaa,_ba[3]) -local aba=cb[b_a[i]:sub(j,j)][2] -if c_a[i]:sub(j,j)=="1"then -table.insert(baa,(aba[1]:gsub("[01]",ad))) -table.insert(caa,(aba[2]:gsub("[01]",ad))) -table.insert(daa,(aba[3]:gsub("[01]",ad)))else table.insert(baa,aba[1]) -table.insert(caa,aba[2])table.insert(daa,aba[3])end end;table.insert(__a,table.concat(d_a)) -table.insert(__a,table.concat(_aa))table.insert(__a,table.concat(aaa)) -table.insert(a_a,table.concat(baa))table.insert(a_a,table.concat(caa)) -table.insert(a_a,table.concat(daa))end;bd[dd]={__a,a_a}if _d then _d="Font"..f.."Yeld"..char -os.queueEvent(_d)os.pullEvent(_d)end end;bb[f]=bd end;return true end -local function _c(dc,_d,ad,bd,cd) -if not type(_d)=="string"then error("Not a String",3)end -local dd=type(ad)=="string"and ad:sub(1,1)or _b[ad]or -error("Wrong Front Color",3) -local __a=type(bd)=="string"and bd:sub(1,1)or _b[bd]or -error("Wrong Back Color",3)if(bb[dc]==nil)then db(3,false)end;local a_a=bb[dc]or -error("Wrong font size selected",3)if _d==""then -return{{""},{""},{""}}end;local b_a={} -for daa in _d:gmatch('.')do table.insert(b_a,daa)end;local c_a={}local d_a=#a_a[b_a[1]][1] -for nLine=1,d_a do local daa={}for i=1,#b_a do -daa[i]= -a_a[b_a[i]]and a_a[b_a[i]][1][nLine]or""end;c_a[nLine]=table.concat(daa)end;local _aa={}local aaa={}local baa={["0"]=dd,["1"]=__a}local caa={["0"]=__a,["1"]=dd} -for nLine=1,d_a -do local daa={}local _ba={} -for i=1,#b_a do local aba= -a_a[b_a[i]]and a_a[b_a[i]][2][nLine]or"" -daa[i]=aba:gsub("[01]",cd and -{["0"]=ad:sub(i,i),["1"]=bd:sub(i,i)}or baa) -_ba[i]=aba:gsub("[01]", -cd and{["0"]=bd:sub(i,i),["1"]=ad:sub(i,i)}or caa)end;_aa[nLine]=table.concat(daa) -aaa[nLine]=table.concat(_ba)end;return{c_a,_aa,aaa}end;local ac=require("elementManager") -local bc=ac.getElement("VisualElement")local cc=setmetatable({},bc)cc.__index=cc -cc.defineProperty(cc,"text",{default="BigFont",type="string",canTriggerRender=true,setter=function(dc,_d) -dc.bigfontText=_c(dc.get("fontSize"),_d,dc.get("foreground"),dc.get("background"))return _d end}) -cc.defineProperty(cc,"fontSize",{default=1,type="number",canTriggerRender=true,setter=function(dc,_d) -dc.bigfontText=_c(_d,dc.get("text"),dc.get("foreground"),dc.get("background"))return _d end})function cc.new()local dc=setmetatable({},cc):__init() -dc.class=cc;dc.set("width",16)dc.set("height",3)dc.set("z",5) -return dc end -function cc:init(dc,_d) -bc.init(self,dc,_d)self.set("type","BigFont") -self:observe("background",function(ad,bd) -ad.bigfontText=_c(ad.get("fontSize"),ad.get("text"),ad.get("foreground"),bd)end) -self:observe("foreground",function(ad,bd) -ad.bigfontText=_c(ad.get("fontSize"),ad.get("text"),bd,ad.get("background"))end)end -function cc:render()bc.render(self) -if(self.bigfontText)then -local dc,_d=self.get("x"),self.get("y") -for i=1,#self.bigfontText[1]do -local ad=self.bigfontText[1][i]:sub(1,self.get("width")) -local bd=self.bigfontText[2][i]:sub(1,self.get("width")) -local cd=self.bigfontText[3][i]:sub(1,self.get("width"))self:blit(dc,_d+i-1,ad,bd,cd)end end end;return cc end -project["elements/Label.lua"] = function(...) local _a=require("elementManager") -local aa=_a.getElement("VisualElement")local ba=require("libraries/utils").wrapText -local ca=setmetatable({},aa)ca.__index=ca -ca.defineProperty(ca,"text",{default="Label",type="string",canTriggerRender=true,setter=function(da,_b) -if(type(_b)=="function")then _b=_b()end -if(da.get("autoSize"))then da.set("width",#_b)else da.set("height",# -ba(_b,da.get("width")))end;return _b end}) -ca.defineProperty(ca,"autoSize",{default=true,type="boolean",canTriggerRender=true,setter=function(da,_b)if(_b)then -da.set("width",#da.get("text"))else -da.set("height",#ba(da.get("text"),da.get("width")))end;return _b end}) -function ca.new()local da=setmetatable({},ca):__init() -da.class=ca;da.set("z",3)da.set("foreground",colors.black) -da.set("backgroundEnabled",false)return da end -function ca:init(da,_b)aa.init(self,da,_b)if(self.parent)then -self.set("background",self.parent.get("background")) -self.set("foreground",self.parent.get("foreground"))end -self.set("type","Label")return self end;function ca:getWrappedText()local da=self.get("text") -local _b=ba(da,self.get("width"))return _b end -function ca:render() -aa.render(self)local da=self.get("text") -if(self.get("autoSize"))then -self:textFg(1,1,da,self.get("foreground"))else local _b=ba(da,self.get("width"))for ab,bb in ipairs(_b)do -self:textFg(1,ab,bb,self.get("foreground"))end end end;return ca end -project["elements/Tree.lua"] = function(...) local _a=require("elements/VisualElement")local aa=string.sub -local ba=setmetatable({},_a)ba.__index=ba -ba.defineProperty(ba,"nodes",{default={},type="table",canTriggerRender=true,setter=function(da,_b)if#_b>0 then -da.get("expandedNodes")[_b[1]]=true end;return _b end}) -ba.defineProperty(ba,"selectedNode",{default=nil,type="table",canTriggerRender=true}) -ba.defineProperty(ba,"expandedNodes",{default={},type="table",canTriggerRender=true}) -ba.defineProperty(ba,"scrollOffset",{default=0,type="number",canTriggerRender=true}) -ba.defineProperty(ba,"horizontalOffset",{default=0,type="number",canTriggerRender=true}) -ba.defineProperty(ba,"nodeColor",{default=colors.white,type="color"}) -ba.defineProperty(ba,"selectedColor",{default=colors.lightBlue,type="color"})ba.defineEvent(ba,"mouse_click") -ba.defineEvent(ba,"mouse_scroll")function ba.new()local da=setmetatable({},ba):__init() -da.class=ba;da.set("width",30)da.set("height",10)da.set("z",5) -return da end -function ba:init(da,_b) -_a.init(self,da,_b)self.set("type","Tree")return self end;function ba:expandNode(da)self.get("expandedNodes")[da]=true -self:updateRender()return self end -function ba:collapseNode(da)self.get("expandedNodes")[da]= -nil;self:updateRender()return self end;function ba:toggleNode(da)if self.get("expandedNodes")[da]then -self:collapseNode(da)else self:expandNode(da)end -return self end -local function ca(da,_b,ab,bb)bb=bb or{}ab= -ab or 0;for cb,db in ipairs(da)do table.insert(bb,{node=db,level=ab}) -if -_b[db]and db.children then ca(db.children,_b,ab+1,bb)end end;return bb end -function ba:mouse_click(da,_b,ab) -if _a.mouse_click(self,da,_b,ab)then -local bb,cb=self:getRelativePosition(_b,ab) -local db=ca(self.get("nodes"),self.get("expandedNodes"))local _c=cb+self.get("scrollOffset") -if db[_c]then local ac=db[_c] -local bc=ac.node -if bb<=ac.level*2 +2 then self:toggleNode(bc)end;self.set("selectedNode",bc) -self:fireEvent("node_select",bc)end;return true end;return false end -function ba:onSelect(da)self:registerCallback("node_select",da)return self end -function ba:mouse_scroll(da,_b,ab) -if _a.mouse_scroll(self,da,_b,ab)then -local bb=ca(self.get("nodes"),self.get("expandedNodes")) -local cb=math.max(0,#bb-self.get("height")) -local db=math.min(cb,math.max(0,self.get("scrollOffset")+da))self.set("scrollOffset",db)return true end;return false end -function ba:getNodeSize()local da,_b=0,0 -local ab=ca(self.get("nodes"),self.get("expandedNodes"))for bb,cb in ipairs(ab)do -da=math.max(da,cb.level+#cb.node.text)end;_b=#ab;return da,_b end -function ba:render()_a.render(self) -local da=ca(self.get("nodes"),self.get("expandedNodes"))local _b=self.get("height")local ab=self.get("selectedNode") -local bb=self.get("expandedNodes")local cb=self.get("scrollOffset") -local db=self.get("horizontalOffset") -for y=1,_b do local _c=da[y+cb] -if _c then local ac=_c.node;local bc=_c.level -local cc=string.rep(" ",bc)local dc=" "if ac.children and#ac.children>0 then -dc=bb[ac]and"\31"or"\16"end -local _d= -ac==ab and self.get("selectedColor")or self.get("background") -local ad=cc..dc.." ".. (ac.text or"Node")local bd=aa(ad,db+1,db+self.get("width")) -self:textFg(1,y, -bd..string.rep(" ",self.get("width")-#bd),self.get("foreground"))else -self:textFg(1,y,string.rep(" ",self.get("width")),self.get("foreground"),self.get("background"))end end end;return ba end -project["elements/DropDown.lua"] = function(...) local _a=require("elements/VisualElement") -local aa=require("elements/List")local ba=require("libraries/colorHex") -local ca=setmetatable({},aa)ca.__index=ca -ca.defineProperty(ca,"isOpen",{default=false,type="boolean",canTriggerRender=true}) -ca.defineProperty(ca,"dropdownHeight",{default=5,type="number"}) -ca.defineProperty(ca,"selectedText",{default="",type="string"}) -ca.defineProperty(ca,"dropSymbol",{default="\31",type="string"})function ca.new()local da=setmetatable({},ca):__init() -da.class=ca;da.set("width",16)da.set("height",1)da.set("z",8) -return da end -function ca:init(da,_b) -aa.init(self,da,_b)self.set("type","DropDown")return self end -function ca:mouse_click(da,_b,ab) -if not _a.mouse_click(self,da,_b,ab)then return false end;local bb,cb=self:getRelativePosition(_b,ab) -if cb==1 then self.set("isOpen",not -self.get("isOpen"))if -not self.get("isOpen")then self.set("height",1)else -self.set("height",1 +math.min(self.get("dropdownHeight"),# -self.get("items")))end -return true elseif -self.get("isOpen")and cb>1 and self.get("selectable")then local db=(cb-1)+self.get("offset") -local _c=self.get("items") -if db<=#_c then local ac=_c[db] -if type(ac)=="string"then ac={text=ac}_c[db]=ac end -if not self.get("multiSelection")then for bc,cc in ipairs(_c)do if type(cc)=="table"then -cc.selected=false end end end;ac.selected=not ac.selected -if ac.callback then ac.callback(self)end;self:fireEvent("select",db,ac) -self.set("isOpen",false)self.set("height",1)self:updateRender()return true end end;return false end -function ca:render()_a.render(self)local da=self.get("selectedText") -local _b=self:getSelectedItems()if#_b>0 then local ab=_b[1]da=ab.text or"" -da=da:sub(1,self.get("width")-2)end -self:blit(1,1,da..string.rep(" ",self.get("width")-# -da-1).. ( -self.get("isOpen")and"\31"or"\17"),string.rep(ba[self.get("foreground")],self.get("width")),string.rep(ba[self.get("background")],self.get("width"))) -if self.get("isOpen")then local ab=self.get("items") -local bb=self.get("height")-1;local cb=self.get("offset")local db=self.get("width") -for i=1,bb do local _c=i+cb -local ac=ab[_c] -if ac then if type(ac)=="string"then ac={text=ac}ab[_c]=ac end -if -ac.separator then local bc=(ac.text or"-"):sub(1,1) -local cc=string.rep(bc,db)local dc=ac.foreground or self.get("foreground")local _d= -ac.background or self.get("background")self:textBg(1, -i+1,string.rep(" ",db),_d) -self:textFg(1,i+1,cc,dc)else local bc=ac.text;local cc=ac.selected;bc=bc:sub(1,db) -local dc=cc and(ac.selectedBackground or -self.get("selectedBackground"))or(ac.background or -self.get("background")) -local _d= -cc and(ac.selectedForeground or self.get("selectedForeground"))or(ac.foreground or self.get("foreground"))self:textBg(1,i+1,string.rep(" ",db),dc)self:textFg(1, -i+1,bc,_d)end end end end end;return ca end -project["elements/ComboBox.lua"] = function(...) local _a=require("elements/VisualElement") -local aa=require("elements/DropDown")local ba=require("libraries/colorHex") -local ca=setmetatable({},aa)ca.__index=ca -ca.defineProperty(ca,"editable",{default=true,type="boolean",canTriggerRender=true}) -ca.defineProperty(ca,"text",{default="",type="string",canTriggerRender=true}) -ca.defineProperty(ca,"cursorPos",{default=1,type="number"}) -ca.defineProperty(ca,"viewOffset",{default=0,type="number",canTriggerRender=true}) -ca.defineProperty(ca,"placeholder",{default="...",type="string"}) -ca.defineProperty(ca,"placeholderColor",{default=colors.gray,type="color"}) -ca.defineProperty(ca,"focusedBackground",{default=colors.blue,type="color"}) -ca.defineProperty(ca,"focusedForeground",{default=colors.white,type="color"}) -ca.defineProperty(ca,"autoComplete",{default=false,type="boolean"}) -ca.defineProperty(ca,"manuallyOpened",{default=false,type="boolean"})function ca.new()local da=setmetatable({},ca):__init() -da.class=ca;da.set("width",16)da.set("height",1)da.set("z",8) -return da end -function ca:init(da,_b) -aa.init(self,da,_b)self.set("type","ComboBox") -self.set("cursorPos",1)self.set("viewOffset",0)return self end -function ca:setText(da)if da==nil then da=""end -self.set("text",tostring(da)) -self.set("cursorPos",#self.get("text")+1)self:updateViewport()return self end;function ca:getText()return self.get("text")end;function ca:setEditable(da) -self.set("editable",da)return self end -function ca:getFilteredItems() -local da=self.get("items")or{}local _b=self.get("text"):lower()if not -self.get("autoComplete")or#_b==0 then return da end -local ab={} -for bb,cb in ipairs(da)do local db="" -if type(cb)=="string"then db=cb:lower()elseif type(cb)=="table"and -cb.text then db=cb.text:lower()end;if db:find(_b,1,true)then table.insert(ab,cb)end end;return ab end -function ca:updateFilteredDropdown() -if not self.get("autoComplete")then return end;local da=self:getFilteredItems()local _b=#da>0 and -#self.get("text")>0 -if _b then self.set("isOpen",true) -self.set("manuallyOpened",false)local ab=self.get("dropdownHeight")or 5 -local bb=math.min(ab,#da)self.set("height",1 +bb)else self.set("isOpen",false) -self.set("manuallyOpened",false)self.set("height",1)end;self:updateRender()end -function ca:updateViewport()local da=self.get("text") -local _b=self.get("cursorPos")local ab=self.get("width")local bb=self.get("dropSymbol") -local cb=ab-#bb;if cb<1 then cb=1 end;local db=self.get("viewOffset")if _b-db>cb then db=_b-cb elseif -_b-1 1 then local cb=ab:sub(1,bb-2).. -ab:sub(bb)self.set("text",cb) -self.set("cursorPos",bb-1)self:updateViewport()if self.get("autoComplete")then -self:updateFilteredDropdown()else self:updateRender()end end elseif da==keys.delete then -if bb<=#ab then -local cb=ab:sub(1,bb-1)..ab:sub(bb+1)self.set("text",cb)self:updateViewport() -if -self.get("autoComplete")then self:updateFilteredDropdown()else self:updateRender()end end elseif da==keys.home then self.set("cursorPos",1) -self:updateViewport()elseif da==keys["end"]then self.set("cursorPos",#ab+1) -self:updateViewport()elseif da==keys.enter then -self.set("isOpen",not self.get("isOpen"))self:updateRender()end end -function ca:mouse_click(da,_b,ab) -if not _a.mouse_click(self,da,_b,ab)then return false end;local bb,cb=self:getRelativePosition(_b,ab) -local db=self.get("width")local _c=self.get("dropSymbol") -if cb==1 then -if -bb>=db-#_c+1 and bb<=db then local ac=self.get("isOpen")self.set("isOpen",not ac) -if -self.get("isOpen")then local bc=self.get("items")or{} -local cc=self.get("dropdownHeight")or 5;local dc=math.min(cc,#bc)self.set("height",1 +dc) -self.set("manuallyOpened",true)else self.set("height",1) -self.set("manuallyOpened",false)end;self:updateRender()return true end -if bb<=db-#_c and self.get("editable")then -local ac=self.get("text")local bc=self.get("viewOffset")local cc=#ac+1 -local dc=math.min(cc,bc+bb)self.set("cursorPos",dc)self:updateRender()return true end;return true elseif -self.get("isOpen")and cb>1 and self.get("selectable")then local ac=(cb-1)+self.get("offset") -local bc=self.get("items") -if ac<=#bc then local cc=bc[ac] -if type(cc)=="string"then cc={text=cc}bc[ac]=cc end -if not self.get("multiSelection")then for dc,_d in ipairs(bc)do if type(_d)=="table"then -_d.selected=false end end end;cc.selected=true;if cc.text then self:setText(cc.text)end -self.set("isOpen",false)self.set("height",1)self:updateRender()return true end end;return false end -function ca:render()_a.render(self)local da=self.get("text") -local _b=self.get("width")local ab=self.get("dropSymbol")local bb=self.get("focused") -local cb=self.get("isOpen")local db=self.get("viewOffset") -local _c=self.get("placeholder") -local ac=bb and self.get("focusedBackground")or self.get("background") -local bc=bb and self.get("focusedForeground")or self.get("foreground")local cc=da;local dc=_b-#ab;if#da==0 and not bb and#_c>0 then cc=_c -bc=self.get("placeholderColor")end -if#cc>0 then cc=cc:sub(db+1,db+dc)end;cc=cc..string.rep(" ",dc-#cc)local _d=cc.. -(cb and"\31"or"\17") -self:blit(1,1,_d,string.rep(ba[bc],_b),string.rep(ba[ac],_b)) -if bb and self.get("editable")then local ad=self.get("cursorPos") -local bd=ad-db;if bd>=1 and bd<=dc then -self:setCursor(bd,1,true,self.get("foreground"))end end -if cb then local ad -if -self.get("autoComplete")and not self.get("manuallyOpened")then ad=self:getFilteredItems()else ad=self.get("items")end -local bd=math.min(self.get("dropdownHeight"),#ad) -if bd>0 then local cd=self.get("offset") -for i=1,bd do local dd=i+cd -if ad[dd]then local __a=ad[dd] -local a_a=__a.text or""local b_a=__a.selected or false -local c_a= -b_a and self.get("selectedBackground")or self.get("background") -local d_a=b_a and self.get("selectedForeground")or self.get("foreground")if#a_a>_b then a_a=a_a:sub(1,_b)end;a_a=a_a.. -string.rep(" ",_b-#a_a) -self:blit(1,i+1,a_a,string.rep(ba[d_a],_b),string.rep(ba[c_a],_b))end end end end end;function ca:focus()aa.focus(self)end -function ca:blur()aa.blur(self) -self.set("isOpen",false)self.set("height",1)self:updateRender()end;return ca end -project["elements/Switch.lua"] = function(...) local _a=require("elementManager") -local aa=_a.getElement("VisualElement")local ba=require("libraries/colorHex") -local ca=setmetatable({},aa)ca.__index=ca -ca.defineProperty(ca,"checked",{default=false,type="boolean",canTriggerRender=true}) -ca.defineProperty(ca,"text",{default="",type="string",canTriggerRender=true}) -ca.defineProperty(ca,"autoSize",{default=false,type="boolean"}) -ca.defineProperty(ca,"onBackground",{default=colors.green,type="number",canTriggerRender=true}) -ca.defineProperty(ca,"offBackground",{default=colors.red,type="number",canTriggerRender=true})ca.defineEvent(ca,"mouse_click") -ca.defineEvent(ca,"mouse_up") -function ca.new()local da=setmetatable({},ca):__init() -da.class=ca;da.set("width",2)da.set("height",1)da.set("z",5) -da.set("backgroundEnabled",true)return da end -function ca:init(da,_b)aa.init(self,da,_b)self.set("type","Switch")end -function ca:mouse_click(da,_b,ab)if aa.mouse_click(self,da,_b,ab)then -self.set("checked",not self.get("checked"))return true end;return false end -function ca:render()local da=self.get("checked")local _b=self.get("text") -local ab=self.get("width")local bb=self.get("height")local cb=da and self.get("onBackground")or -self.get("offBackground") -self:multiBlit(1,1,ab,bb," ",ba[self.get("foreground")],ba[cb])local db=math.floor(ab/2)local _c=da and(ab-db+1)or 1 -self:multiBlit(_c,1,db,bb," ",ba[self.get("foreground")],ba[self.get("background")])if _b~=""then -self:textFg(ab+2,1,_b,self.get("foreground"))end end;return ca end -project["elements/ScrollBar.lua"] = function(...) local aa=require("elements/VisualElement") -local ba=require("libraries/colorHex")local ca=setmetatable({},aa)ca.__index=ca -ca.defineProperty(ca,"value",{default=0,type="number",canTriggerRender=true}) -ca.defineProperty(ca,"min",{default=0,type="number",canTriggerRender=true}) -ca.defineProperty(ca,"max",{default=100,type="number",canTriggerRender=true}) -ca.defineProperty(ca,"step",{default=10,type="number"}) -ca.defineProperty(ca,"dragMultiplier",{default=1,type="number"}) -ca.defineProperty(ca,"symbol",{default=" ",type="string",canTriggerRender=true}) -ca.defineProperty(ca,"symbolColor",{default=colors.gray,type="color",canTriggerRender=true}) -ca.defineProperty(ca,"symbolBackgroundColor",{default=colors.black,type="color",canTriggerRender=true}) -ca.defineProperty(ca,"backgroundSymbol",{default="\127",type="string",canTriggerRender=true}) -ca.defineProperty(ca,"attachedElement",{default=nil,type="table"}) -ca.defineProperty(ca,"attachedProperty",{default=nil,type="string"}) -ca.defineProperty(ca,"minValue",{default=0,type="number"}) -ca.defineProperty(ca,"maxValue",{default=100,type="number"}) -ca.defineProperty(ca,"orientation",{default="vertical",type="string",canTriggerRender=true}) -ca.defineProperty(ca,"handleSize",{default=2,type="number",canTriggerRender=true})ca.defineEvent(ca,"mouse_click") -ca.defineEvent(ca,"mouse_release")ca.defineEvent(ca,"mouse_drag") -ca.defineEvent(ca,"mouse_scroll") -function ca.new()local ab=setmetatable({},ca):__init() -ab.class=ca;ab.set("width",1)ab.set("height",10)return ab end;function ca:init(ab,bb)aa.init(self,ab,bb)self.set("type","ScrollBar")return -self end -function ca:attach(ab,bb) -self.set("attachedElement",ab)self.set("attachedProperty",bb.property)self.set("minValue", -bb.min or 0) -self.set("maxValue",bb.max or 100) -ab:observe(bb.property,function(cb,db) -if db then local _c=self.get("minValue") -local ac=self.get("maxValue")if _c==ac then return end -self.set("value",math.floor((db-_c)/ (ac-_c)*100 +0.5))end end)return self end -function ca:updateAttachedElement()local ab=self.get("attachedElement") -if not ab then return end;local bb=self.get("value")local cb=self.get("minValue") -local db=self.get("maxValue")if type(cb)=="function"then cb=cb()end;if type(db)=="function"then -db=db()end;local _c=cb+ (bb/100)* (db-cb)ab.set(self.get("attachedProperty"),math.floor( -_c+0.5)) -return self end;local function da(ab) -return -ab.get("orientation")=="vertical"and ab.get("height")or ab.get("width")end -local function _b(ab,bb,cb) -local db,_c=ab:getRelativePosition(bb,cb)return -ab.get("orientation")=="vertical"and _c or db end -function ca:mouse_click(ab,bb,cb) -if aa.mouse_click(self,ab,bb,cb)then local db=da(self) -local _c=self.get("value")local ac=self.get("handleSize")local bc= -math.floor((_c/100)* (db-ac))+1;local cc=_b(self,bb,cb) -if -cc>=bc and cc0 and-1 or 1;local db=self.get("step") -local _c=self.get("value")local ac=_c-ab*db -self.set("value",math.min(100,math.max(0,ac)))self:updateAttachedElement()return true end -function ca:render()aa.render(self)local ab=da(self)local bb=self.get("value") -local cb=self.get("handleSize")local db=self.get("symbol")local _c=self.get("symbolColor") -local ac=self.get("symbolBackgroundColor")local bc=self.get("backgroundSymbol")local cc=self.get("orientation")== -"vertical"local dc= -math.floor((bb/100)* (ab-cb))+1 -for i=1,ab do -if cc then -self:blit(1,i,bc,ba[self.get("foreground")],ba[self.get("background")])else -self:blit(i,1,bc,ba[self.get("foreground")],ba[self.get("background")])end end -for i=dc,dc+cb-1 do if cc then self:blit(1,i,db,ba[_c],ba[ac])else -self:blit(i,1,db,ba[_c],ba[ac])end end end;return ca end -project["elements/BaseFrame.lua"] = function(...) local ba=require("elementManager") -local ca=ba.getElement("Container")local da=require("errorManager")local _b=require("render") -local ab=setmetatable({},ca)ab.__index=ab -local function bb(cb) -local db,_c=pcall(function()return peripheral.getType(cb)end)if db then return true end;return false end -ab.defineProperty(ab,"term",{default=nil,type="table",setter=function(cb,db)cb._peripheralName=nil;if -cb.basalt.getActiveFrame(cb._values.term)==cb then -cb.basalt.setActiveFrame(cb,false)end;if -db==nil or db.setCursorPos==nil then return db end;if(bb(db))then -cb._peripheralName=peripheral.getName(db)end;cb._values.term=db -if -cb.basalt.getActiveFrame(db)==nil then cb.basalt.setActiveFrame(cb)end;cb._render=_b.new(db)cb._renderUpdate=true;local _c,ac=db.getSize() -cb.set("width",_c)cb.set("height",ac)return db end})function ab.new()local cb=setmetatable({},ab):__init() -cb.class=ab;return cb end;function ab:init(cb,db) -ca.init(self,cb,db)self.set("term",term.current()) -self.set("type","BaseFrame")return self end -function ab:multiBlit(cb,db,_c,ac,bc,cc,dc)if -(cb<1)then _c=_c+cb-1;cb=1 end;if(db<1)then ac=ac+db-1;db=1 end -self._render:multiBlit(cb,db,_c,ac,bc,cc,dc)end;function ab:textFg(cb,db,_c,ac)if cb<1 then _c=string.sub(_c,1 -cb)cb=1 end -self._render:textFg(cb,db,_c,ac)end;function ab:textBg(cb,db,_c,ac)if cb<1 then _c=string.sub(_c,1 - -cb)cb=1 end -self._render:textBg(cb,db,_c,ac)end;function ab:drawText(cb,db,_c)if cb<1 then _c=string.sub(_c, -1 -cb)cb=1 end -self._render:text(cb,db,_c)end -function ab:drawFg(cb,db,_c)if cb<1 then -_c=string.sub(_c,1 -cb)cb=1 end;self._render:fg(cb,db,_c)end;function ab:drawBg(cb,db,_c)if cb<1 then _c=string.sub(_c,1 -cb)cb=1 end -self._render:bg(cb,db,_c)end -function ab:blit(cb,db,_c,ac,bc) -if cb<1 then -_c=string.sub(_c,1 -cb)ac=string.sub(ac,1 -cb)bc=string.sub(bc,1 -cb)cb=1 end;self._render:blit(cb,db,_c,ac,bc)end;function ab:setCursor(cb,db,_c,ac)local bc=self.get("term") -self._render:setCursor(cb,db,_c,ac)end -function ab:monitor_touch(cb,db,_c) -local ac=self.get("term")if ac==nil then return end -if(bb(ac))then if self._peripheralName==cb then -self:mouse_click(1,db,_c) -self.basalt.schedule(function()sleep(0.1)self:mouse_up(1,db,_c)end)end end end;function ab:mouse_click(cb,db,_c)ca.mouse_click(self,cb,db,_c) -self.basalt.setFocus(self)end -function ab:mouse_up(cb,db,_c) -ca.mouse_up(self,cb,db,_c)ca.mouse_release(self,cb,db,_c)end -function ab:term_resize()local cb,db=self.get("term").getSize() -if(cb== -self.get("width")and db==self.get("height"))then return end;self.set("width",cb)self.set("height",db) -self._render:setSize(cb,db)self._renderUpdate=true end -function ab:key(cb)self:fireEvent("key",cb)ca.key(self,cb)end -function ab:key_up(cb)self:fireEvent("key_up",cb)ca.key_up(self,cb)end -function ab:char(cb)self:fireEvent("char",cb)ca.char(self,cb)end -function ab:dispatchEvent(cb,...)local db=self.get("term")if db==nil then return end;if(bb(db))then if -cb=="mouse_click"then return end end -ca.dispatchEvent(self,cb,...)end;function ab:render() -if(self._renderUpdate)then if self._render~=nil then ca.render(self) -self._render:render()self._renderUpdate=false end end end -return ab end -project["elements/Image.lua"] = function(...) local ba=require("elementManager") -local ca=ba.getElement("VisualElement")local da=require("libraries/colorHex") -local _b=setmetatable({},ca)_b.__index=_b -_b.defineProperty(_b,"bimg",{default={{}},type="table",canTriggerRender=true}) -_b.defineProperty(_b,"currentFrame",{default=1,type="number",canTriggerRender=true}) -_b.defineProperty(_b,"autoResize",{default=false,type="boolean"}) -_b.defineProperty(_b,"offsetX",{default=0,type="number",canTriggerRender=true}) -_b.defineProperty(_b,"offsetY",{default=0,type="number",canTriggerRender=true}) -_b.combineProperties(_b,"offset","offsetX","offsetY") -function _b.new()local cb=setmetatable({},_b):__init() -cb.class=_b;cb.set("width",12)cb.set("height",6) -cb.set("background",colors.black)cb.set("z",5)return cb end;function _b:init(cb,db)ca.init(self,cb,db)self.set("type","Image") -return self end -function _b:resizeImage(cb,db) -local _c=self.get("bimg") -for ac,bc in ipairs(_c)do local cc={} -for y=1,db do local dc=string.rep(" ",cb) -local _d=string.rep("f",cb)local ad=string.rep("0",cb) -if bc[y]and bc[y][1]then local bd=bc[y][1] -local cd=bc[y][2]local dd=bc[y][3] -dc=(bd..string.rep(" ",cb)):sub(1,cb) -_d=(cd..string.rep("f",cb)):sub(1,cb) -ad=(dd..string.rep("0",cb)):sub(1,cb)end;cc[y]={dc,_d,ad}end;_c[ac]=cc end;self:updateRender()return self end -function _b:getImageSize()local cb=self.get("bimg")if not cb[1]or not cb[1][1]then -return 0,0 end;return#cb[1][1][1],#cb[1]end -function _b:getPixelData(cb,db) -local _c=self.get("bimg")[self.get("currentFrame")]if not _c or not _c[db]then return end;local ac=_c[db][1] -local bc=_c[db][2]local cc=_c[db][3] -if not ac or not bc or not cc then return end;local dc=tonumber(bc:sub(cb,cb),16) -local _d=tonumber(cc:sub(cb,cb),16)local ad=ac:sub(cb,cb)return dc,_d,ad end -local function ab(cb,db) -local _c=cb.get("bimg")[cb.get("currentFrame")]if not _c then _c={} -cb.get("bimg")[cb.get("currentFrame")]=_c end -if not _c[db]then _c[db]={"","",""}end;return _c end -local function bb(cb,db,_c)if not cb.get("autoResize")then return end -local ac=cb.get("bimg")local bc=db;local cc=_c -for dc,_d in ipairs(ac)do for ad,bd in pairs(_d)do bc=math.max(bc,#bd[1]) -cc=math.max(cc,ad)end end -for dc,_d in ipairs(ac)do -for y=1,cc do if not _d[y]then _d[y]={"","",""}end;local ad=_d[y]while#ad[1]< -bc do ad[1]=ad[1].." "end;while#ad[2]dc then return self end end;local ac=ab(self,db)if self.get("autoResize")then -bb(self,cb+#_c-1,db)else local cc=#ac[db][1]if cb>cc then return self end -_c=_c:sub(1,cc-cb+1)end -local bc=ac[db][1] -ac[db][1]=bc:sub(1,cb-1).._c..bc:sub(cb+#_c)self:updateRender()return self end -function _b:getText(cb,db,_c)if not cb or not db then return""end -local ac=self.get("bimg")[self.get("currentFrame")]if not ac or not ac[db]then return""end;local bc=ac[db][1]if not bc then -return""end -if _c then return bc:sub(cb,cb+_c-1)else return bc:sub(cb,cb)end end -function _b:setFg(cb,db,_c)if -type(_c)~="string"or#_c<1 or cb<1 or db<1 then return self end -if -not self.get("autoResize")then local cc,dc=self:getImageSize()if db>dc then return self end end;local ac=ab(self,db)if self.get("autoResize")then -bb(self,cb+#_c-1,db)else local cc=#ac[db][2]if cb>cc then return self end -_c=_c:sub(1,cc-cb+1)end -local bc=ac[db][2] -ac[db][2]=bc:sub(1,cb-1).._c..bc:sub(cb+#_c)self:updateRender()return self end -function _b:getFg(cb,db,_c)if not cb or not db then return""end -local ac=self.get("bimg")[self.get("currentFrame")]if not ac or not ac[db]then return""end;local bc=ac[db][2]if not bc then -return""end -if _c then return bc:sub(cb,cb+_c-1)else return bc:sub(cb)end end -function _b:setBg(cb,db,_c)if -type(_c)~="string"or#_c<1 or cb<1 or db<1 then return self end -if -not self.get("autoResize")then local cc,dc=self:getImageSize()if db>dc then return self end end;local ac=ab(self,db)if self.get("autoResize")then -bb(self,cb+#_c-1,db)else local cc=#ac[db][3]if cb>cc then return self end -_c=_c:sub(1,cc-cb+1)end -local bc=ac[db][3] -ac[db][3]=bc:sub(1,cb-1).._c..bc:sub(cb+#_c)self:updateRender()return self end -function _b:getBg(cb,db,_c)if not cb or not db then return""end -local ac=self.get("bimg")[self.get("currentFrame")]if not ac or not ac[db]then return""end;local bc=ac[db][3]if not bc then -return""end -if _c then return bc:sub(cb,cb+_c-1)else return bc:sub(cb)end end -function _b:setPixel(cb,db,_c,ac,bc)if _c then self:setText(cb,db,_c)end;if ac then -self:setFg(cb,db,ac)end;if bc then self:setBg(cb,db,bc)end;return self end -function _b:nextFrame() -if not self.get("bimg").animation then return self end;local cb=self.get("bimg")local db=self.get("currentFrame") -local _c=db+1;if _c>#cb then _c=1 end;self.set("currentFrame",_c)return self end -function _b:addFrame()local cb=self.get("bimg") -local db=cb.width or#cb[1][1][1]local _c=cb.height or#cb[1]local ac={}local bc=string.rep(" ",db) -local cc=string.rep("f",db)local dc=string.rep("0",db)for y=1,_c do ac[y]={bc,cc,dc}end -table.insert(cb,ac)return self end;function _b:updateFrame(cb,db)local _c=self.get("bimg")_c[cb]=db -self:updateRender()return self end;function _b:getFrame(cb) -local db=self.get("bimg") -return db[cb or self.get("currentFrame")]end -function _b:getMetadata()local cb={} -local db=self.get("bimg") -for _c,ac in pairs(db)do if(type(ac)=="string")then cb[_c]=ac end end;return cb end -function _b:setMetadata(cb,db)if(type(cb)=="table")then -for ac,bc in pairs(cb)do self:setMetadata(ac,bc)end;return self end -local _c=self.get("bimg")if(type(db)=="string")then _c[cb]=db end;return self end -function _b:render()ca.render(self) -local cb=self.get("bimg")[self.get("currentFrame")]if not cb then return end;local db=self.get("offsetX") -local _c=self.get("offsetY")local ac=self.get("width")local bc=self.get("height") -for y=1,bc do local cc=y+_c -local dc=cb[cc] -if dc then local _d=dc[1]local ad=dc[2]local bd=dc[3] -if _d and ad and bd then -local cd=ac-math.max(0,db) -if cd>0 then if db<0 then local dd=math.abs(db)+1;_d=_d:sub(dd)ad=ad:sub(dd) -bd=bd:sub(dd)end;_d=_d:sub(1,cd) -ad=ad:sub(1,cd)bd=bd:sub(1,cd) -self:blit(math.max(1,1 +db),y,_d,ad,bd)end end end end end;return _b end -project["elements/List.lua"] = function(...) local c=require("elements/VisualElement") -local d=setmetatable({},c)d.__index=d -d.defineProperty(d,"items",{default={},type="table",canTriggerRender=true}) -d.defineProperty(d,"selectable",{default=true,type="boolean"}) -d.defineProperty(d,"multiSelection",{default=false,type="boolean"}) -d.defineProperty(d,"offset",{default=0,type="number",canTriggerRender=true}) -d.defineProperty(d,"selectedBackground",{default=colors.blue,type="color"}) -d.defineProperty(d,"selectedForeground",{default=colors.white,type="color"})d.defineEvent(d,"mouse_click") -d.defineEvent(d,"mouse_scroll") -function d.new()local _a=setmetatable({},d):__init()_a.class=d -_a.set("width",16)_a.set("height",8)_a.set("z",5) -_a.set("background",colors.gray)return _a end -function d:init(_a,aa)c.init(self,_a,aa)self.set("type","List")return self end;function d:addItem(_a)local aa=self.get("items")table.insert(aa,_a) -self:updateRender()return self end -function d:removeItem(_a) -local aa=self.get("items")table.remove(aa,_a)self:updateRender()return self end -function d:clear()self.set("items",{})self:updateRender()return self end -function d:getSelectedItems()local _a={}for aa,ba in ipairs(self.get("items"))do -if -type(ba)=="table"and ba.selected then local ca=ba;ca.index=aa;table.insert(_a,ca)end end;return _a end -function d:getSelectedItem()local _a=self.get("items")for aa,ba in ipairs(_a)do if -type(ba)=="table"and ba.selected then return ba end end;return -nil end -function d:mouse_click(_a,aa,ba) -if -self:isInBounds(aa,ba)and self.get("selectable")then local ca,da=self:getRelativePosition(aa,ba) -local _b=da+self.get("offset")local ab=self.get("items") -if _b<=#ab then local bb=ab[_b]if type(bb)=="string"then -bb={text=bb}ab[_b]=bb end;if -not self.get("multiSelection")then -for cb,db in ipairs(ab)do if type(db)=="table"then db.selected=false end end end -bb.selected=not bb.selected;if bb.callback then bb.callback(self)end -self:fireEvent("mouse_click",_a,aa,ba)self:fireEvent("select",_b,bb)self:updateRender()end;return true end;return false end -function d:mouse_scroll(_a,aa,ba) -if self:isInBounds(aa,ba)then local ca=self.get("offset") -local da=math.max(0,# -self.get("items")-self.get("height"))ca=math.min(da,math.max(0,ca+_a)) -self.set("offset",ca)self:fireEvent("mouse_scroll",_a,aa,ba)return true end;return false end -function d:onSelect(_a)self:registerCallback("select",_a)return self end -function d:scrollToBottom() -local _a=math.max(0,#self.get("items")-self.get("height"))self.set("offset",_a)return self end;function d:scrollToTop()self.set("offset",0)return self end -function d:render() -c.render(self)local _a=self.get("items")local aa=self.get("height") -local ba=self.get("offset")local ca=self.get("width") -for i=1,aa do local da=i+ba;local _b=_a[da] -if _b then if -type(_b)=="string"then _b={text=_b}_a[da]=_b end -if _b.separator then -local ab=(_b.text or"-"):sub(1,1)local bb=string.rep(ab,ca) -local cb=_b.foreground or self.get("foreground")local db=_b.background or self.get("background") -self:textBg(1,i,string.rep(" ",ca),db)self:textFg(1,i,bb:sub(1,ca),cb)else local ab=_b.text -local bb=_b.selected -local cb= -bb and(_b.selectedBackground or self.get("selectedBackground"))or(_b.background or self.get("background")) -local db= -bb and(_b.selectedForeground or self.get("selectedForeground"))or(_b.foreground or self.get("foreground"))self:textBg(1,i,string.rep(" ",ca),cb) -self:textFg(1,i,ab:sub(1,ca),db)end end end end;return d end -project["elements/Program.lua"] = function(...) local ca=require("elementManager") -local da=ca.getElement("VisualElement")local _b=require("errorManager")local ab=setmetatable({},da) -ab.__index=ab -ab.defineProperty(ab,"program",{default=nil,type="table"}) -ab.defineProperty(ab,"path",{default="",type="string"}) -ab.defineProperty(ab,"running",{default=false,type="boolean"}) -ab.defineProperty(ab,"errorCallback",{default=nil,type="function"}) -ab.defineProperty(ab,"doneCallback",{default=nil,type="function"})ab.defineEvent(ab,"*")local bb={}bb.__index=bb -local cb=dofile("rom/modules/main/cc/require.lua").make -function bb.new(_c,ac,bc)local cc=setmetatable({},bb)cc.env=ac or{}cc.args={}cc.addEnvironment= -bc==nil and true or bc;cc.program=_c;return cc end;function bb:setArgs(...)self.args={...}end -local function db(_c) -local ac={shell=shell,multishell=multishell}ac.require,ac.package=cb(ac,_c)return ac end -function bb:run(_c,ac,bc) -self.window=window.create(self.program:getBaseFrame():getTerm(),1,1,ac,bc,false) -local cc=shell.resolveProgram(_c)or fs.exists(_c)and _c or nil -if(cc~=nil)then -if(fs.exists(cc))then local dc=fs.open(cc,"r")local _d=dc.readAll() -dc.close() -local ad=setmetatable(db(fs.getDir(_c)),{__index=_ENV})ad.term=self.window;ad.term.current=term.current -ad.term.redirect=term.redirect;ad.term.native=function()return self.window end -if -(self.addEnvironment)then for __a,a_a in pairs(self.env)do ad[__a]=a_a end else ad=self.env end -self.coroutine=coroutine.create(function()local __a=load(_d,"@/".._c,nil,ad)if __a then -local a_a=__a(table.unpack(self.args))return a_a end end)local bd=term.current()term.redirect(self.window) -local cd,dd=coroutine.resume(self.coroutine)term.redirect(bd) -if not cd then -local __a=self.program.get("doneCallback")if __a then __a(self.program,cd,dd)end -local a_a=self.program.get("errorCallback") -if a_a then local b_a=debug.traceback(self.coroutine,dd) -local c_a=a_a(self.program,dd,b_a:gsub(dd,""))if(c_a==false)then self.filter=nil;return cd,dd end end;_b.header="Basalt Program Error ".._c;_b.error(dd)end -if coroutine.status(self.coroutine)=="dead"then -self.program.set("running",false)self.program.set("program",nil) -local __a=self.program.get("doneCallback")if __a then __a(self.program,cd,dd)end end else _b.header="Basalt Program Error ".._c -_b.error("File not found")end else _b.header="Basalt Program Error" -_b.error("Program ".._c.." not found")end end;function bb:resize(_c,ac)self.window.reposition(1,1,_c,ac) -self:resume("term_resize",_c,ac)end -function bb:resume(_c,...)local ac={...}if -(_c:find("mouse_"))then -ac[2],ac[3]=self.program:getRelativePosition(ac[2],ac[3])end;if self.coroutine==nil or -coroutine.status(self.coroutine)=="dead"then -self.program.set("running",false)return end -if -(self.filter~=nil)then if(_c~=self.filter)then return end;self.filter=nil end;local bc=term.current()term.redirect(self.window) -local cc,dc=coroutine.resume(self.coroutine,_c,table.unpack(ac))term.redirect(bc) -if cc then self.filter=dc -if -coroutine.status(self.coroutine)=="dead"then -self.program.set("running",false)self.program.set("program",nil) -local _d=self.program.get("doneCallback")if _d then _d(self.program,cc,dc)end end else local _d=self.program.get("doneCallback")if _d then -_d(self.program,cc,dc)end -local ad=self.program.get("errorCallback") -if ad then local bd=debug.traceback(self.coroutine,dc) -bd=bd==nil and""or bd;dc=dc or"Unknown error" -local cd=ad(self.program,dc,bd:gsub(dc,""))if(cd==false)then self.filter=nil;return cc,dc end end;_b.header="Basalt Program Error"_b.error(dc)end;return cc,dc end -function bb:stop()if self.coroutine==nil or -coroutine.status(self.coroutine)=="dead"then -self.program.set("running",false)return end -coroutine.close(self.coroutine)self.coroutine=nil end;function ab.new()local _c=setmetatable({},ab):__init() -_c.class=ab;_c.set("z",5)_c.set("width",30)_c.set("height",12) -return _c end -function ab:init(_c,ac) -da.init(self,_c,ac)self.set("type","Program") -self:observe("width",function(bc,cc) -local dc=bc.get("program") -if dc then dc:resize(cc,bc.get("height"))end end) -self:observe("height",function(bc,cc)local dc=bc.get("program")if dc then -dc:resize(bc.get("width"),cc)end end)return self end -function ab:execute(_c,ac,bc,...)self.set("path",_c)self.set("running",true) -local cc=bb.new(self,ac,bc)self.set("program",cc)cc:setArgs(...) -cc:run(_c,self.get("width"),self.get("height"),...)self:updateRender()return self end;function ab:stop()local _c=self.get("program")if _c then _c:stop() -self.set("running",false)self.set("program",nil)end -return self end;function ab:sendEvent(_c,...) -self:dispatchEvent(_c,...)return self end;function ab:onError(_c) -self.set("errorCallback",_c)return self end;function ab:onDone(_c) -self.set("doneCallback",_c)return self end -function ab:dispatchEvent(_c,...) -local ac=self.get("program")local bc=da.dispatchEvent(self,_c,...) -if ac then ac:resume(_c,...) -if -(self.get("focused"))then local cc=ac.window.getCursorBlink() -local dc,_d=ac.window.getCursorPos() -self:setCursor(dc,_d,cc,ac.window.getTextColor())end;self:updateRender()end;return bc end -function ab:focus() -if(da.focus(self))then local _c=self.get("program")if _c then -local ac=_c.window.getCursorBlink()local bc,cc=_c.window.getCursorPos() -self:setCursor(bc,cc,ac,_c.window.getTextColor())end end end -function ab:render()da.render(self)local _c=self.get("program") -if _c then -local ac,bc=_c.window.getSize()for y=1,bc do local cc,dc,_d=_c.window.getLine(y)if cc then -self:blit(1,y,cc,dc,_d)end end end end;return ab end -project["elements/Container.lua"] = function(...) local da=require("elementManager") -local _b=require("errorManager")local ab=da.getElement("VisualElement") -local bb=require("libraries/expect")local cb=require("libraries/utils").split -local db=setmetatable({},ab)db.__index=db -db.defineProperty(db,"children",{default={},type="table"}) -db.defineProperty(db,"childrenSorted",{default=true,type="boolean"}) -db.defineProperty(db,"childrenEventsSorted",{default=true,type="boolean"}) -db.defineProperty(db,"childrenEvents",{default={},type="table"}) -db.defineProperty(db,"eventListenerCount",{default={},type="table"}) -db.defineProperty(db,"focusedChild",{default=nil,type="table",allowNil=true,setter=function(bc,cc,dc)local _d=bc._values.focusedChild -if cc==_d then return cc end -if _d then -if _d:isType("Container")then _d.set("focusedChild",nil,true)end;_d.set("focused",false,true)end -if cc and not dc then cc.set("focused",true,true)if bc.parent then -bc.parent:setFocusedChild(bc)end end;return cc end}) -db.defineProperty(db,"visibleChildren",{default={},type="table"}) -db.defineProperty(db,"visibleChildrenEvents",{default={},type="table"}) -db.defineProperty(db,"offsetX",{default=0,type="number",canTriggerRender=true,setter=function(bc,cc)bc.set("childrenSorted",false) -bc.set("childrenEventsSorted",false)return cc end}) -db.defineProperty(db,"offsetY",{default=0,type="number",canTriggerRender=true,setter=function(bc,cc)bc.set("childrenSorted",false) -bc.set("childrenEventsSorted",false)return cc end}) -db.combineProperties(db,"offset","offsetX","offsetY") -for bc,cc in pairs(da:getElementList())do -local dc=bc:sub(1,1):upper()..bc:sub(2) -if dc~="BaseFrame"then -db["add"..dc]=function(_d,...)bb(1,_d,"table") -local ad=_d.basalt.create(bc,...)_d:addChild(ad)ad:postInit()return ad end -db["addDelayed"..dc]=function(_d,ad)bb(1,_d,"table") -local bd=_d.basalt.create(bc,ad,true,_d)return bd end end end;function db.new()local bc=setmetatable({},db):__init() -bc.class=db;return bc end -function db:init(bc,cc) -ab.init(self,bc,cc)self.set("type","Container") -self:observe("width",function() -self.set("childrenSorted",false)self.set("childrenEventsSorted",false)end) -self:observe("height",function()self.set("childrenSorted",false) -self.set("childrenEventsSorted",false)end)end -function db:isChildVisible(bc) -if not bc:isType("VisualElement")then return false end;if(bc.get("visible")==false)then return false end;if(bc._destroyed)then return -false end -local cc,dc=self.get("width"),self.get("height")local _d,ad=self.get("offsetX"),self.get("offsetY") -local bd,cd=bc.get("x"),bc.get("y")local dd,__a=bc.get("width"),bc.get("height")local a_a;local b_a;if -(bc.get("ignoreOffset"))then a_a=bd;b_a=cd else a_a=bd-_d;b_a=cd-ad end;return - -(a_a+dd>0)and(a_a<=cc)and(b_a+__a>0)and(b_a<=dc)end -function db:addChild(bc) -if bc==self then error("Cannot add container to itself")end;if(bc~=nil)then table.insert(self._values.children,bc) -bc.parent=self;bc:postInit()self.set("childrenSorted",false) -self:registerChildrenEvents(bc)end;return -self end -local function _c(bc,cc)local dc={}for _d,ad in ipairs(cc)do -if bc:isChildVisible(ad)and ad.get("visible")and not -ad._destroyed then table.insert(dc,ad)end end -for i=2,#dc do -local _d=dc[i]local ad=_d.get("z")local bd=i-1 -while bd>0 do local cd=dc[bd].get("z")if cd>ad then -dc[bd+1]=dc[bd]bd=bd-1 else break end end;dc[bd+1]=_d end;return dc end -function db:clear()self.set("children",{}) -self.set("childrenEvents",{})self.set("visibleChildren",{}) -self.set("visibleChildrenEvents",{})self.set("childrenSorted",true) -self.set("childrenEventsSorted",true)return self end -function db:sortChildren() -self.set("visibleChildren",_c(self,self._values.children))self.set("childrenSorted",true)return self end -function db:sortChildrenEvents(bc)if self._values.childrenEvents[bc]then -self._values.visibleChildrenEvents[bc]=_c(self,self._values.childrenEvents[bc])end -self.set("childrenEventsSorted",true)return self end -function db:registerChildrenEvents(bc)if(bc._registeredEvents==nil)then return end -for cc in -pairs(bc._registeredEvents)do self:registerChildEvent(bc,cc)end;return self end -function db:registerChildEvent(bc,cc) -if not self._values.childrenEvents[cc]then -self._values.childrenEvents[cc]={}self._values.eventListenerCount[cc]=0;if self.parent then -self.parent:registerChildEvent(self,cc)end end -for dc,_d in ipairs(self._values.childrenEvents[cc])do if _d.get("id")== -bc.get("id")then return self end end;self.set("childrenEventsSorted",false) -table.insert(self._values.childrenEvents[cc],bc)self._values.eventListenerCount[cc]= -self._values.eventListenerCount[cc]+1;return self end -function db:removeChildrenEvents(bc) -if bc~=nil then -if(bc._registeredEvents==nil)then return self end;for cc in pairs(bc._registeredEvents)do -self:unregisterChildEvent(bc,cc)end end;return self end -function db:unregisterChildEvent(bc,cc) -if self._values.childrenEvents[cc]then -for dc,_d in -ipairs(self._values.childrenEvents[cc])do -if _d.get("id")==bc.get("id")then -table.remove(self._values.childrenEvents[cc],dc)self._values.eventListenerCount[cc]= -self._values.eventListenerCount[cc]-1 -if -self._values.eventListenerCount[cc]<=0 then -self._values.childrenEvents[cc]=nil;self._values.eventListenerCount[cc]=nil;if self.parent then -self.parent:unregisterChildEvent(self,cc)end end;self.set("childrenEventsSorted",false) -self:updateRender()break end end end;return self end -function db:removeChild(bc)if bc==nil then return self end -for cc,dc in ipairs(self._values.children)do if -dc.get("id")==bc.get("id")then -table.remove(self._values.children,cc)bc.parent=nil;break end end;self:removeChildrenEvents(bc)self:updateRender() -self.set("childrenSorted",false)return self end -function db:getChild(bc) -if type(bc)=="string"then local cc=cb(bc,"/") -for dc,_d in -pairs(self._values.children)do if _d.get("name")==cc[1]then -if#cc==1 then return _d else if(_d:isType("Container"))then return -_d:find(table.concat(cc,"/",2))end end end end end;return nil end -local function ac(bc,cc,...)local dc={...} -if cc and cc:find("mouse_")then local _d,ad,bd=... -local cd,dd=bc.get("offsetX"),bc.get("offsetY")local __a,a_a=bc:getRelativePosition(ad+cd,bd+dd) -dc={_d,__a,a_a}end;return dc end -function db:callChildrenEvent(bc,cc,...)local dc=bc and self.get("visibleChildrenEvents")or -self.get("childrenEvents") -if -dc[cc]then local _d=dc[cc]for i=#_d,1,-1 do local ad=_d[i] -if(ad:dispatchEvent(cc,...))then return true,ad end end end -if(dc["*"])then local _d=dc["*"]for i=#_d,1,-1 do local ad=_d[i] -if(ad:dispatchEvent(cc,...))then return true,ad end end end;return false end -function db:handleEvent(bc,...)ab.handleEvent(self,bc,...)local cc=ac(self,bc,...)return -self:callChildrenEvent(false,bc,table.unpack(cc))end -function db:mouse_click(bc,cc,dc) -if ab.mouse_click(self,bc,cc,dc)then -local _d=ac(self,"mouse_click",bc,cc,dc) -local ad,bd=self:callChildrenEvent(true,"mouse_click",table.unpack(_d)) -if(ad)then self.set("focusedChild",bd)return true end;self.set("focusedChild",nil)return true end;return false end -function db:mouse_up(bc,cc,dc) -if ab.mouse_up(self,bc,cc,dc)then local _d=ac(self,"mouse_up",bc,cc,dc) -local ad,bd=self:callChildrenEvent(true,"mouse_up",table.unpack(_d))if(ad)then return true end end;return false end -function db:mouse_release(bc,cc,dc)ab.mouse_release(self,bc,cc,dc) -local _d=ac(self,"mouse_release",bc,cc,dc) -self:callChildrenEvent(false,"mouse_release",table.unpack(_d))end -function db:mouse_move(bc,cc,dc) -if ab.mouse_move(self,bc,cc,dc)then -local _d=ac(self,"mouse_move",bc,cc,dc) -local ad,bd=self:callChildrenEvent(true,"mouse_move",table.unpack(_d))if(ad)then return true end end;return false end -function db:mouse_drag(bc,cc,dc) -if ab.mouse_drag(self,bc,cc,dc)then -local _d=ac(self,"mouse_drag",bc,cc,dc) -local ad,bd=self:callChildrenEvent(true,"mouse_drag",table.unpack(_d))if(ad)then return true end end;return false end -function db:mouse_scroll(bc,cc,dc) -if(ab.mouse_scroll(self,bc,cc,dc))then -local _d=ac(self,"mouse_scroll",bc,cc,dc) -local ad,bd=self:callChildrenEvent(true,"mouse_scroll",table.unpack(_d))return ad end;return false end;function db:key(bc)if self.get("focusedChild")then return -self.get("focusedChild"):dispatchEvent("key",bc)end -return true end -function db:char(bc)if -self.get("focusedChild")then -return self.get("focusedChild"):dispatchEvent("char",bc)end;return true end;function db:key_up(bc) -if self.get("focusedChild")then return -self.get("focusedChild"):dispatchEvent("key_up",bc)end;return true end -function db:multiBlit(bc,cc,dc,_d,ad,bd,cd) -local dd,__a=self.get("width"),self.get("height")dc=bc<1 and math.min(dc+bc-1,dd)or -math.min(dc,math.max(0,dd-bc+1))_d=cc<1 and math.min( -_d+cc-1,__a)or -math.min(_d,math.max(0,__a-cc+1))if dc<=0 or -_d<=0 then return self end -ab.multiBlit(self,math.max(1,bc),math.max(1,cc),dc,_d,ad,bd,cd)return self end -function db:textFg(bc,cc,dc,_d)local ad,bd=self.get("width"),self.get("height")if -cc<1 or cc>bd then return self end;local cd=bc<1 and(2 -bc)or 1 -local dd=math.min(#dc- -cd+1,ad-math.max(1,bc)+1)if dd<=0 then return self end -ab.textFg(self,math.max(1,bc),math.max(1,cc),dc:sub(cd,cd+dd-1),_d)return self end -function db:textBg(bc,cc,dc,_d)local ad,bd=self.get("width"),self.get("height")if -cc<1 or cc>bd then return self end;local cd=bc<1 and(2 -bc)or 1 -local dd=math.min(#dc- -cd+1,ad-math.max(1,bc)+1)if dd<=0 then return self end -ab.textBg(self,math.max(1,bc),math.max(1,cc),dc:sub(cd,cd+dd-1),_d)return self end -function db:drawText(bc,cc,dc)local _d,ad=self.get("width"),self.get("height")if cc<1 or -cc>ad then return self end;local bd=bc<1 and(2 -bc)or 1 -local cd=math.min( -#dc-bd+1,_d-math.max(1,bc)+1)if cd<=0 then return self end -ab.drawText(self,math.max(1,bc),math.max(1,cc),dc:sub(bd,bd+cd-1))return self end -function db:drawFg(bc,cc,dc)local _d,ad=self.get("width"),self.get("height")if -cc<1 or cc>ad then return self end;local bd=bc<1 and(2 -bc)or 1 -local cd=math.min(#dc- -bd+1,_d-math.max(1,bc)+1)if cd<=0 then return self end -ab.drawFg(self,math.max(1,bc),math.max(1,cc),dc:sub(bd,bd+cd-1))return self end -function db:drawBg(bc,cc,dc)local _d,ad=self.get("width"),self.get("height")if -cc<1 or cc>ad then return self end;local bd=bc<1 and(2 -bc)or 1 -local cd=math.min(#dc- -bd+1,_d-math.max(1,bc)+1)if cd<=0 then return self end -ab.drawBg(self,math.max(1,bc),math.max(1,cc),dc:sub(bd,bd+cd-1))return self end -function db:blit(bc,cc,dc,_d,ad)local bd,cd=self.get("width"),self.get("height")if -cc<1 or cc>cd then return self end;local dd=bc<1 and(2 -bc)or 1 -local __a=math.min(#dc- -dd+1,bd-math.max(1,bc)+1) -local a_a=math.min(#_d-dd+1,bd-math.max(1,bc)+1) -local b_a=math.min(#ad-dd+1,bd-math.max(1,bc)+1)if __a<=0 then return self end;local c_a=dc:sub(dd,dd+__a-1)local d_a=_d:sub(dd, -dd+a_a-1)local _aa=ad:sub(dd,dd+b_a-1) -ab.blit(self,math.max(1,bc),math.max(1,cc),c_a,d_a,_aa)return self end -function db:render()ab.render(self)if not self.get("childrenSorted")then -self:sortChildren()end -if -not self.get("childrenEventsSorted")then for bc in pairs(self._values.childrenEvents)do -self:sortChildrenEvents(bc)end end;for bc,cc in ipairs(self.get("visibleChildren"))do if cc==self then -_b.error("CIRCULAR REFERENCE DETECTED!")return end;cc:render() -cc:postRender()end end -function db:destroy()if not self:isType("BaseFrame")then ab.destroy(self) -return self else _b.header="Basalt Error" -_b.error("Cannot destroy a BaseFrame.")end end;return db end -project["elements/Graph.lua"] = function(...) local _a=require("elementManager") -local aa=_a.getElement("VisualElement")local ba=require("libraries/colorHex") -local ca=setmetatable({},aa)ca.__index=ca -ca.defineProperty(ca,"minValue",{default=0,type="number",canTriggerRender=true}) -ca.defineProperty(ca,"maxValue",{default=100,type="number",canTriggerRender=true}) -ca.defineProperty(ca,"series",{default={},type="table",canTriggerRender=true})function ca.new()local da=setmetatable({},ca):__init() -da.class=ca;return da end;function ca:init(da,_b) -aa.init(self,da,_b)self.set("type","Graph")self.set("width",20) -self.set("height",10)return self end -function ca:addSeries(da,_b,ab,bb,cb) -local db=self.get("series") -table.insert(db,{name=da,symbol=_b or" ",bgColor=ab or colors.white,fgColor=bb or colors.black,pointCount=cb or self.get("width"),data={},visible=true})self:updateRender()return self end -function ca:removeSeries(da)local _b=self.get("series")for ab,bb in ipairs(_b)do if bb.name==da then -table.remove(_b,ab)break end end -self:updateRender()return self end -function ca:getSeries(da)local _b=self.get("series")for ab,bb in ipairs(_b)do -if bb.name==da then return bb end end;return nil end -function ca:changeSeriesVisibility(da,_b)local ab=self.get("series")for bb,cb in ipairs(ab)do if cb.name==da then -cb.visible=_b;break end end -self:updateRender()return self end -function ca:addPoint(da,_b)local ab=self.get("series") -for bb,cb in ipairs(ab)do if cb.name==da then -table.insert(cb.data,_b) -while#cb.data>cb.pointCount do table.remove(cb.data,1)end;break end end;self:updateRender()return self end -function ca:focusSeries(da)local _b=self.get("series") -for ab,bb in ipairs(_b)do if bb.name==da then -table.remove(_b,ab)table.insert(_b,bb)break end end;self:updateRender()return self end -function ca:setSeriesPointCount(da,_b)local ab=self.get("series") -for bb,cb in ipairs(ab)do if cb.name==da then -cb.pointCount=_b;while#cb.data>_b do table.remove(cb.data,1)end -break end end;self:updateRender()return self end -function ca:clear(da)local _b=self.get("series") -if da then for ab,bb in ipairs(_b)do -if bb.name==da then bb.data={}break end end else for ab,bb in ipairs(_b)do bb.data={}end end;return self end -function ca:render()aa.render(self)local da=self.get("width") -local _b=self.get("height")local ab=self.get("minValue")local bb=self.get("maxValue") -local cb=self.get("series") -for db,_c in pairs(cb)do -if(_c.visible)then local ac=#_c.data -local bc=(da-1)/math.max((ac-1),1) -for cc,dc in ipairs(_c.data)do local _d=math.floor(( (cc-1)*bc)+1)local ad= -(dc-ab)/ (bb-ab) -local bd=math.floor(_b- (ad* (_b-1)))bd=math.max(1,math.min(bd,_b)) -self:blit(_d,bd,_c.symbol,ba[_c.bgColor],ba[_c.fgColor])end end end end;return ca end -project["elements/BarChart.lua"] = function(...) local aa=require("elementManager") -local ba=aa.getElement("VisualElement")local ca=aa.getElement("Graph") -local da=require("libraries/colorHex")local _b=setmetatable({},ca)_b.__index=_b;function _b.new() -local ab=setmetatable({},_b):__init()ab.class=_b;return ab end -function _b:init(ab,bb) -ca.init(self,ab,bb)self.set("type","BarChart")return self end -function _b:render()ba.render(self)local ab=self.get("width") -local bb=self.get("height")local cb=self.get("minValue")local db=self.get("maxValue") -local _c=self.get("series")local ac=0;local bc={} -for ad,bd in pairs(_c)do if(bd.visible)then if#bd.data>0 then ac=ac+1 -table.insert(bc,bd)end end end;local cc=ac;local dc=1 -local _d=math.min(bc[1]and bc[1].pointCount or 0,math.floor((ab+dc)/ ( -cc+dc))) -for groupIndex=1,_d do local ad=( (groupIndex-1)* (cc+dc))+1 -for bd,cd in ipairs(bc)do -local dd=cd.data[groupIndex] -if dd then local __a=ad+ (bd-1)local a_a=(dd-cb)/ (db-cb) -local b_a=math.floor(bb- (a_a* (bb-1)))b_a=math.max(1,math.min(b_a,bb))for barY=b_a,bb do -self:blit(__a,barY,cd.symbol,da[cd.fgColor],da[cd.bgColor])end end end end end;return _b end -project["elements/LineChart.lua"] = function(...) local ba=require("elementManager") -local ca=ba.getElement("VisualElement")local da=ba.getElement("Graph") -local _b=require("libraries/colorHex")local ab=setmetatable({},da)ab.__index=ab;function ab.new() -local cb=setmetatable({},ab):__init()cb.class=ab;return cb end -function ab:init(cb,db) -da.init(self,cb,db)self.set("type","LineChart")return self end -local function bb(cb,db,_c,ac,bc,cc,dc,_d)local ad=ac-db;local bd=bc-_c -local cd=math.max(math.abs(ad),math.abs(bd)) -for i=0,cd do local dd=cd==0 and 0 or i/cd -local __a=math.floor(db+ad*dd)local a_a=math.floor(_c+bd*dd) -if - -__a>=1 and __a<=cb.get("width")and a_a>=1 and a_a<=cb.get("height")then cb:blit(__a,a_a,cc,_b[dc],_b[_d])end end end -function ab:render()ca.render(self)local cb=self.get("width") -local db=self.get("height")local _c=self.get("minValue")local ac=self.get("maxValue") -local bc=self.get("series") -for cc,dc in pairs(bc)do -if(dc.visible)then local _d,ad;local bd=#dc.data -local cd=(cb-1)/math.max((bd-1),1) -for dd,__a in ipairs(dc.data)do local a_a=math.floor(( (dd-1)*cd)+1)local b_a= -(__a-_c)/ (ac-_c) -local c_a=math.floor(db- (b_a* (db-1)))c_a=math.max(1,math.min(c_a,db))if _d then -bb(self,_d,ad,a_a,c_a,dc.symbol,dc.bgColor,dc.fgColor)end;_d,ad=a_a,c_a end end end end;return ab end -project["log.lua"] = function(...) local aa={}aa._logs={}aa._enabled=false;aa._logToFile=false -aa._logFile="basalt.log"fs.delete(aa._logFile) -aa.LEVEL={DEBUG=1,INFO=2,WARN=3,ERROR=4} -local ba={[aa.LEVEL.DEBUG]="Debug",[aa.LEVEL.INFO]="Info",[aa.LEVEL.WARN]="Warn",[aa.LEVEL.ERROR]="Error"} -local ca={[aa.LEVEL.DEBUG]=colors.lightGray,[aa.LEVEL.INFO]=colors.white,[aa.LEVEL.WARN]=colors.yellow,[aa.LEVEL.ERROR]=colors.red}function aa.setLogToFile(ab)aa._logToFile=ab end -function aa.setEnabled(ab)aa._enabled=ab end;local function da(ab) -if aa._logToFile then local bb=io.open(aa._logFile,"a")if bb then -bb:write(ab.."\n")bb:close()end end end -local function _b(ab,...)if -not aa._enabled then return end;local bb=os.date("%H:%M:%S") -local cb=debug.getinfo(3,"Sl")local db=cb.source:match("@?(.*)")local _c=cb.currentline -local ac=string.format("[%s:%d]",db:match("([^/\\]+)%.lua$"),_c)local bc="["..ba[ab].."]"local cc="" -for _d,ad in ipairs(table.pack(...))do if _d>1 then cc= -cc.." "end;cc=cc..tostring(ad)end;local dc=string.format("%s %s%s %s",bb,ac,bc,cc)da(dc) -table.insert(aa._logs,{time=bb,level=ab,message=cc})end;function aa.debug(...)_b(aa.LEVEL.DEBUG,...)end;function aa.info(...) -_b(aa.LEVEL.INFO,...)end -function aa.warn(...)_b(aa.LEVEL.WARN,...)end;function aa.error(...)_b(aa.LEVEL.ERROR,...)end;return aa end project["libraries/colorHex.lua"] = function(...) local b={}for i=0,15 do b[2 ^i]=("%x"):format(i) b[("%x"):format(i)]=2 ^i end;return b end project["libraries/utils.lua"] = function(...) local d,_a=math.floor,string.len;local aa={} @@ -2417,719 +3379,4 @@ aa.get("type")~=nil then return true end end if ba=="color"then if ca=="number"then return true end;if ca=="string"and colors[aa]then return true end end;if ca~=ba then c.header="Basalt Type Error" c.error(string.format("Bad argument #%d: expected %s, got %s",_a,ba,ca))end;return true end;return d end -project["init.lua"] = function(...) local da={...}local _b=fs.getDir(da[2])local ab=package.path -local bb="path;/path/?.lua;/path/?/init.lua;"local cb=bb:gsub("path",_b)package.path=cb.."rom/?;"..ab -local function db(bc)package.path= -cb.."rom/?"local cc=require("errorManager") -package.path=ab;cc.header="Basalt Loading Error"cc.error(bc)end;local _c,ac=pcall(require,"main")package.loaded.log=nil -package.path=ab;if not _c then db(ac)else return ac end end -project["plugins/debug.lua"] = function(...) local _b=require("log")local ab=require("libraries/colorHex") -local bb=10;local cb=false;local db={ERROR=1,WARN=2,INFO=3,DEBUG=4} -local function _c(dc) -local _d={renderCount=0,eventCount={},lastRender=os.epoch("utc"),properties={},children={}} -return -{trackProperty=function(ad,bd)_d.properties[ad]=bd end,trackRender=function() -_d.renderCount=_d.renderCount+1;_d.lastRender=os.epoch("utc")end,trackEvent=function(ad)_d.eventCount[ad]=( -_d.eventCount[ad]or 0)+1 end,dump=function()return -{type=dc.get("type"),id=dc.get("id"),stats=_d}end}end;local ac={} -function ac.debug(dc,_d)dc._debugger=_c(dc)dc._debugLevel=_d or db.INFO;return dc end;function ac.dumpDebug(dc)if not dc._debugger then return end -return dc._debugger.dump()end;local bc={} -function bc.openConsole(dc) -if -not dc._debugFrame then local _d=dc.get("width")local ad=dc.get("height") -dc._debugFrame=dc:addFrame("basaltDebugLog"):setWidth(_d):setHeight(ad):listenEvent("mouse_scroll",true) -dc._debugFrame:addButton("basaltDebugLogClose"):setWidth(9):setHeight(1):setX( -_d-8):setY(ad):setText("Close"):onClick(function() -dc:closeConsole()end)dc._debugFrame._scrollOffset=0 -dc._debugFrame._processedLogs={} -local function bd(b_a,c_a)local d_a={}while#b_a>0 do local _aa=b_a:sub(1,c_a)table.insert(d_a,_aa)b_a=b_a:sub( -c_a+1)end;return d_a end -local function cd()local b_a={}local c_a=dc._debugFrame.get("width") -for d_a,_aa in -ipairs(_b._logs)do local aaa=bd(_aa.message,c_a)for baa,caa in ipairs(aaa)do -table.insert(b_a,{text=caa,level=_aa.level})end end;return b_a end;local dd=#cd()-dc.get("height")dc._scrollOffset=dd -local __a=dc._debugFrame.render -dc._debugFrame.render=function(b_a)__a(b_a)b_a._processedLogs=cd() -local c_a=b_a.get("height")-2;local d_a=#b_a._processedLogs;local _aa=math.max(0,d_a-c_a) -b_a._scrollOffset=math.min(b_a._scrollOffset,_aa) -for i=1,c_a-2 do local aaa=i+b_a._scrollOffset -local baa=b_a._processedLogs[aaa] -if baa then -local caa= - -baa.level==_b.LEVEL.ERROR and colors.red or baa.level== -_b.LEVEL.WARN and colors.yellow or baa.level==_b.LEVEL.DEBUG and colors.lightGray or colors.white;b_a:textFg(2,i,baa.text,caa)end end end;local a_a=dc._debugFrame.dispatchEvent -dc._debugFrame.dispatchEvent=function(b_a,c_a,d_a,...) -if -(c_a=="mouse_scroll")then -b_a._scrollOffset=math.max(0,b_a._scrollOffset+d_a)b_a:updateRender()return true else return a_a(b_a,c_a,d_a,...)end end end -dc._debugFrame.set("width",dc.get("width")) -dc._debugFrame.set("height",dc.get("height"))dc._debugFrame.set("visible",true)return dc end -function bc.closeConsole(dc)if dc._debugFrame then -dc._debugFrame.set("visible",false)end;return dc end;function bc.toggleConsole(dc)if dc._debugFrame and dc._debugFrame:getVisible()then -dc:closeConsole()else dc:openConsole()end -return dc end -local cc={} -function cc.debugChildren(dc,_d)dc:debug(_d)for ad,bd in pairs(dc.get("children"))do if bd.debug then -bd:debug(_d)end end;return dc end;return{BaseElement=ac,Container=cc,BaseFrame=bc} end -project["plugins/canvas.lua"] = function(...) local ba=require("libraries/colorHex") -local ca=require("errorManager")local da={}da.__index=da;local _b,ab=string.sub,string.rep -function da.new(cb) -local db=setmetatable({},da)db.commands={pre={},post={}}db.type="pre"db.element=cb;return db end -function da:clear()self.commands={pre={},post={}}return self end;function da:getValue(cb) -if type(cb)=="function"then return cb(self.element)end;return cb end -function da:setType(cb)if -cb=="pre"or cb=="post"then self.type=cb else -ca.error("Invalid type. Use 'pre' or 'post'.")end;return self end -function da:addCommand(cb) -local db=#self.commands[self.type]+1;self.commands[self.type][db]=cb;return db end -function da:setCommand(cb,db)self.commands[cb]=db;return self end;function da:removeCommand(cb) -table.remove(self.commands[self.type],cb)return self end -function da:text(cb,db,_c,ac,bc) -return -self:addCommand(function(cc) -local dc,_d=self:getValue(cb),self:getValue(db)local ad=self:getValue(_c)local bd=self:getValue(ac) -local cd=self:getValue(bc) -local dd=type(bd)=="number"and ba[bd]:rep(#_c)or bd -local __a=type(cd)=="number"and ba[cd]:rep(#_c)or cd;cc:drawText(dc,_d,ad) -if dd then cc:drawFg(dc,_d,dd)end;if __a then cc:drawBg(dc,_d,__a)end end)end;function da:bg(cb,db,_c)return -self:addCommand(function(ac)ac:drawBg(cb,db,_c)end)end -function da:fg(cb,db,_c)return self:addCommand(function(ac) -ac:drawFg(cb,db,_c)end)end -function da:rect(cb,db,_c,ac,bc,cc,dc) -return -self:addCommand(function(_d)local ad,bd=self:getValue(cb),self:getValue(db) -local cd,dd=self:getValue(_c),self:getValue(ac)local __a=self:getValue(bc)local a_a=self:getValue(cc) -local b_a=self:getValue(dc)if(type(a_a)=="number")then a_a=ba[a_a]end;if -(type(b_a)=="number")then b_a=ba[b_a]end -local c_a=b_a and _b(b_a:rep(cd),1,cd)local d_a=a_a and _b(a_a:rep(cd),1,cd)local _aa=__a and -_b(__a:rep(cd),1,cd) -for i=0,dd-1 do -if b_a then _d:drawBg(ad,bd+i,c_a)end;if a_a then _d:drawFg(ad,bd+i,d_a)end;if __a then -_d:drawText(ad,bd+i,_aa)end end end)end -function da:line(cb,db,_c,ac,bc,cc,dc) -local function _d(cd,dd,__a,a_a)local b_a={}local c_a=0;local d_a=math.abs(__a-cd) -local _aa=math.abs(a_a-dd)local aaa=(cd<__a)and 1 or-1 -local baa=(dd-_aa then caa=caa-_aa;cd=cd+aaa end;if daa0 do -aaa=aaa-1;daa=daa-2 *c_a;if baa>0 then baa=baa+c_a-daa else _aa=_aa+1 -caa=caa+2 *d_a;baa=baa+c_a-daa+caa end -_ba(_aa,aaa)end -return a_a end;local ad=_d(cb,db,_c,ac) -return -self:addCommand(function(bd)local cd=self:getValue(bc) -local dd=self:getValue(cc)local __a=self:getValue(dc) -local a_a=type(dd)=="number"and ba[dd]or dd -local b_a=type(__a)=="number"and ba[__a]or __a -for c_a,d_a in pairs(ad)do local _aa=math.floor(d_a.x)local aaa=math.floor(d_a.y)if cd then -bd:drawText(_aa,aaa,cd)end;if a_a then bd:drawFg(_aa,aaa,a_a)end;if b_a then -bd:drawBg(_aa,aaa,b_a)end end end)end;local bb={hooks={}} -function bb.setup(cb) -cb.defineProperty(cb,"canvas",{default=nil,type="table",getter=function(db)if not db._values.canvas then -db._values.canvas=da.new(db)end;return db._values.canvas end})end;function bb.hooks.render(cb)local db=cb.get("canvas") -if -db and#db.commands.pre>0 then for _c,ac in pairs(db.commands.pre)do ac(cb)end end end -function bb.hooks.postRender(cb) -local db=cb.get("canvas")if db and#db.commands.post>0 then for _c,ac in pairs(db.commands.post)do -ac(cb)end end end;return{VisualElement=bb,API=da} end -project["plugins/reactive.lua"] = function(...) local ab=require("errorManager") -local bb=require("propertySystem")local cb={colors=true,math=true,clamp=true,round=true} -local db={clamp=function(ad,bd,cd)return -math.min(math.max(ad,bd),cd)end,round=function(ad) -return math.floor(ad+0.5)end,floor=math.floor,ceil=math.ceil,abs=math.abs} -local function _c(ad,bd,cd)ad=ad:gsub("^{(.+)}$","%1") -ad=ad:gsub("([%w_]+)%$([%w_]+)",function(b_a,c_a) -if b_a=="self"then return -string.format('__getState("%s")',c_a)elseif b_a=="parent"then return -string.format('__getParentState("%s")',c_a)else return -string.format('__getElementState("%s", "%s")',b_a,c_a)end end) -ad=ad:gsub("([%w_]+)%.([%w_]+)",function(b_a,c_a)if cb[b_a]then return b_a.."."..c_a end;if -tonumber(b_a)then return b_a.."."..c_a end;return -string.format('__getProperty("%s", "%s")',b_a,c_a)end) -local dd=setmetatable({colors=colors,math=math,tostring=tostring,tonumber=tonumber,__getState=function(b_a)return bd:getState(b_a)end,__getParentState=function(b_a)return -bd.parent:getState(b_a)end,__getElementState=function(b_a,c_a)if tonumber(b_a)then return nil end -local d_a=bd:getBaseFrame():getChild(b_a)if not d_a then ab.header="Reactive evaluation error" -ab.error("Could not find element: "..b_a)return nil end;return -d_a:getState(c_a).value end,__getProperty=function(b_a,c_a)if -tonumber(b_a)then return nil end -if b_a=="self"then return bd.get(c_a)elseif b_a=="parent"then return -bd.parent.get(c_a)else local d_a=bd.parent:getChild(b_a)if not d_a then -ab.header="Reactive evaluation error" -ab.error("Could not find element: "..b_a)return nil end -return d_a.get(c_a)end end},{__index=db})if(bd._properties[cd].type=="string")then -ad="tostring("..ad..")"elseif(bd._properties[cd].type=="number")then -ad="tonumber("..ad..")"end;local __a,a_a=load("return ".. -ad,"reactive","t",dd) -if not __a then -ab.header="Reactive evaluation error"ab.error("Invalid expression: "..a_a)return -function()return nil end end;return __a end -local function ac(ad,bd) -for cd in ad:gmatch("([%w_]+)%.")do -if not cb[cd]then -if cd=="self"then elseif cd=="parent"then -if not bd.parent then -ab.header="Reactive evaluation error"ab.error("No parent element available")return false end else -if(tonumber(cd)==nil)then local dd=bd.parent:getChild(cd)if not dd then -ab.header="Reactive evaluation error" -ab.error("Referenced element not found: "..cd)return false end end end end end;return true end;local bc=setmetatable({},{__mode="k"}) -local cc=setmetatable({},{__mode="k",__index=function(ad,bd)ad[bd]={} -return ad[bd]end}) -local function dc(ad,bd,cd) -if cc[ad][cd]then for __a,a_a in ipairs(cc[ad][cd])do -a_a.target:removeObserver(a_a.property,a_a.callback)end end;local dd={} -for __a,a_a in bd:gmatch("([%w_]+)%.([%w_]+)")do -if not cb[__a]then local b_a;if __a=="self"then b_a=ad elseif -__a=="parent"then b_a=ad.parent else -b_a=ad:getBaseFrame():getChild(__a)end;if b_a then -local c_a={target=b_a,property=a_a,callback=function() -ad:updateRender()end}b_a:observe(a_a,c_a.callback) -table.insert(dd,c_a)end end end;cc[ad][cd]=dd end -bb.addSetterHook(function(ad,bd,cd,dd) -if type(cd)=="string"and cd:match("^{.+}$")then -local __a=cd:gsub("^{(.+)}$","%1")if not ac(__a,ad)then return dd.default end;dc(ad,__a,bd)if -not bc[ad]then bc[ad]={}end;if not bc[ad][cd]then local a_a=_c(cd,ad,bd) -bc[ad][cd]=a_a end -return -function(a_a)local b_a,c_a=pcall(bc[ad][cd]) -if not b_a then -ab.header="Reactive evaluation error" -if type(c_a)=="string"then -ab.error("Error evaluating expression: "..c_a)else ab.error("Error evaluating expression")end;return dd.default end;return c_a end end end)local _d={} -_d.hooks={destroy=function(ad) -if cc[ad]then -for bd,cd in pairs(cc[ad])do for dd,__a in ipairs(cd)do -__a.target:removeObserver(__a.property,__a.callback)end end;cc[ad]=nil end end}return{BaseElement=_d} end -project["plugins/state.lua"] = function(...) local _a=require("propertySystem") -local aa=require("errorManager")local ba={}function ba.setup(da) -da.defineProperty(da,"states",{default={},type="table"}) -da.defineProperty(da,"stateObserver",{default={},type="table"})end -function ba:initializeState(da,_b,ab,bb) -local cb=self.get("states")if cb[da]then -aa.error("State '"..da.."' already exists")return self end;local db=bb or"states/".. -self.get("name")..".state"local _c={} -if ab and -fs.exists(db)then local ac=fs.open(db,"r")_c= -textutils.unserialize(ac.readAll())or{}ac.close()end;cb[da]={value=ab and _c[da]or _b,persist=ab} -return self end;local ca={} -function ca:setState(da,_b)local ab=self:getBaseFrame() -local bb=ab.get("states")local cb=ab.get("stateObserver") -if not bb[da]then aa.error("State '".. -da.."' not initialized")end -if bb[da].persist then -local db="states/"..ab.get("name")..".state"local _c={} -if fs.exists(db)then local cc=fs.open(db,"r")_c= -textutils.unserialize(cc.readAll())or{}cc.close()end;_c[da]=_b;local ac=fs.getDir(db)if not fs.exists(ac)then -fs.makeDir(ac)end;local bc=fs.open(db,"w") -bc.write(textutils.serialize(_c))bc.close()end;bb[da].value=_b -if cb[da]then for db,_c in ipairs(cb[da])do _c(da,_b)end end;for db,_c in pairs(bb)do -if _c.computed then _c.value=_c.computeFn(self)if cb[db]then for ac,bc in ipairs(cb[db])do -bc(db,_c.value)end end end end -return self end -function ca:getState(da)local _b=self:getBaseFrame()local ab=_b.get("states")if -not ab[da]then -aa.error("State '"..da.."' not initialized")end;if ab[da].computed then -return ab[da].computeFn(self)end;return ab[da].value end -function ca:onStateChange(da,_b)local ab=self:getBaseFrame() -local bb=ab.get("states")[da]if not bb then -aa.error("Cannot observe state '"..da.."': State not initialized")return self end -local cb=ab.get("stateObserver")if not cb[da]then cb[da]={}end;table.insert(cb[da],_b) -return self end -function ca:removeStateChange(da,_b)local ab=self:getBaseFrame() -local bb=ab.get("stateObserver") -if bb[da]then for cb,db in ipairs(bb[da])do -if db==_b then table.remove(bb[da],cb)break end end end;return self end -function ca:computed(da,_b)local ab=self:getBaseFrame()local bb=ab.get("states")if bb[da]then -aa.error( -"Computed state '"..da.."' already exists")return self end -bb[da]={computeFn=_b,value=_b(self),computed=true}return self end -function ca:bind(da,_b)_b=_b or da;local ab=self:getBaseFrame()local bb=false -if -self.get(da)~=nil then self.set(da,ab:getState(_b))end -self:onChange(da,function(cb,db)if bb then return end;bb=true;cb:setState(_b,db)bb=false end) -self:onStateChange(_b,function(cb,db)if bb then return end;bb=true;if self.get(da)~=nil then -self.set(da,db)end;bb=false end)return self end;return{BaseElement=ca,BaseFrame=ba} end -project["plugins/benchmark.lua"] = function(...) local ca=require("log")local da=setmetatable({},{__mode="k"})local function _b()return -{methods={}}end -local function ab(_c,ac)local bc=_c[ac] -if not da[_c]then da[_c]=_b()end -if not da[_c].methods[ac]then -da[_c].methods[ac]={calls=0,totalTime=0,minTime=math.huge,maxTime=0,lastTime=0,startTime=0,path={},methodName=ac,originalMethod=bc}end -_c[ac]=function(cc,...)cc:startProfile(ac)local dc=bc(cc,...) -cc:endProfile(ac)return dc end end;local bb={} -function bb:startProfile(_c)local ac=da[self]if not ac then ac=_b()da[self]=ac end;if not -ac.methods[_c]then -ac.methods[_c]={calls=0,totalTime=0,minTime=math.huge,maxTime=0,lastTime=0,startTime=0,path={},methodName=_c}end -local bc=ac.methods[_c]bc.startTime=os.clock()*1000;bc.path={}local cc=self;while cc do -table.insert(bc.path,1, -cc.get("name")or cc.get("id"))cc=cc.parent end;return self end -function bb:endProfile(_c)local ac=da[self] -if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c]local cc=os.clock()*1000 -local dc=cc-bc.startTime;bc.calls=bc.calls+1;bc.totalTime=bc.totalTime+dc -bc.minTime=math.min(bc.minTime,dc)bc.maxTime=math.max(bc.maxTime,dc)bc.lastTime=dc;return self end -function bb:benchmark(_c)if not self[_c]then -ca.error("Method ".._c.." does not exist")return self end;da[self]=_b() -da[self].methodName=_c;da[self].isRunning=true;ab(self,_c)return self end -function bb:logBenchmark(_c)local ac=da[self] -if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c] -if bc then local cc= -bc.calls>0 and(bc.totalTime/bc.calls)or 0 -ca.info(string.format( -"Benchmark results for %s.%s: ".. -"Path: %s ".."Calls: %d ".. -"Average time: %.2fms ".."Min time: %.2fms ".."Max time: %.2fms ".. -"Last time: %.2fms ".."Total time: %.2fms",table.concat(bc.path,"."),bc.methodName,table.concat(bc.path,"/"),bc.calls,cc, -bc.minTime~=math.huge and bc.minTime or 0,bc.maxTime,bc.lastTime,bc.totalTime))end;return self end -function bb:stopBenchmark(_c)local ac=da[self] -if not ac or not ac.methods[_c]then return self end;local bc=ac.methods[_c]if bc and bc.originalMethod then -self[_c]=bc.originalMethod end;ac.methods[_c]=nil;if -not next(ac.methods)then da[self]=nil end;return self end -function bb:getBenchmarkStats(_c)local ac=da[self] -if not ac or not ac.methods[_c]then return nil end;local bc=ac.methods[_c]return -{averageTime=bc.totalTime/bc.calls,totalTime=bc.totalTime,calls=bc.calls,minTime=bc.minTime,maxTime=bc.maxTime,lastTime=bc.lastTime}end;local cb={} -function cb:benchmarkContainer(_c)self:benchmark(_c) -for ac,bc in -pairs(self.get("children"))do bc:benchmark(_c)if bc:isType("Container")then -bc:benchmarkContainer(_c)end end;return self end -function cb:logContainerBenchmarks(_c,ac)ac=ac or 0;local bc=string.rep(" ",ac)local cc=0;local dc={} -for ad,bd in -pairs(self.get("children"))do local cd=da[bd] -if cd and cd.methods[_c]then local dd=cd.methods[_c] -cc=cc+dd.totalTime -table.insert(dc,{element=bd,type=bd.get("type"),calls=dd.calls,totalTime=dd.totalTime,avgTime=dd.totalTime/dd.calls})end end;local _d=da[self] -if _d and _d.methods[_c]then local ad=_d.methods[_c] -local bd=ad.totalTime-cc;local cd=bd/ad.calls -ca.info(string.format("%sBenchmark %s (%s): ".."%.2fms/call (Self: %.2fms/call) ".. -"[Total: %dms, Calls: %d]",bc,self.get("type"),_c, -ad.totalTime/ad.calls,cd,ad.totalTime,ad.calls)) -if#dc>0 then -for dd,__a in ipairs(dc)do -if __a.element:isType("Container")then __a.element:logContainerBenchmarks(_c, -ac+1)else -ca.info(string.format("%s> %s: %.2fms/call [Total: %dms, Calls: %d]", -bc.." ",__a.type,__a.avgTime,__a.totalTime,__a.calls))end end end end;return self end -function cb:stopContainerBenchmark(_c) -for ac,bc in pairs(self.get("children"))do if bc:isType("Container")then -bc:stopContainerBenchmark(_c)else bc:stopBenchmark(_c)end end;self:stopBenchmark(_c)return self end;local db={} -function db.start(_c,ac)ac=ac or{}local bc=_b()bc.name=_c -bc.startTime=os.clock()*1000;bc.custom=true;bc.calls=0;bc.totalTime=0;bc.minTime=math.huge;bc.maxTime=0 -bc.lastTime=0;da[_c]=bc end -function db.stop(_c)local ac=da[_c]if not ac or not ac.custom then return end;local bc= -os.clock()*1000;local cc=bc-ac.startTime;ac.calls=ac.calls+1;ac.totalTime= -ac.totalTime+cc;ac.minTime=math.min(ac.minTime,cc) -ac.maxTime=math.max(ac.maxTime,cc)ac.lastTime=cc -ca.info(string.format("Custom Benchmark '%s': ".. -"Calls: %d ".."Average time: %.2fms ".. -"Min time: %.2fms ".. -"Max time: %.2fms ".."Last time: %.2fms ".."Total time: %.2fms",_c,ac.calls, -ac.totalTime/ac.calls,ac.minTime,ac.maxTime,ac.lastTime,ac.totalTime))end -function db.getStats(_c)local ac=da[_c]if not ac then return nil end;return -{averageTime=ac.totalTime/ac.calls,totalTime=ac.totalTime,calls=ac.calls,minTime=ac.minTime,maxTime=ac.maxTime,lastTime=ac.lastTime}end;function db.clear(_c)da[_c]=nil end;function db.clearAll()for _c,ac in pairs(da)do -if ac.custom then da[_c]=nil end end end;return -{BaseElement=bb,Container=cb,API=db} end -project["plugins/animation.lua"] = function(...) local aa={} -local ba={linear=function(ab)return ab end,easeInQuad=function(ab)return ab*ab end,easeOutQuad=function(ab)return -1 - (1 -ab)* (1 -ab)end,easeInOutQuad=function(ab)if ab<0.5 then return 2 *ab*ab end;return 1 - ( --2 *ab+2)^2 /2 end}local ca={}ca.__index=ca -function ca.new(ab,bb,cb,db,_c)local ac=setmetatable({},ca)ac.element=ab -ac.type=bb;ac.args=cb;ac.duration=db or 1;ac.startTime=0;ac.isPaused=false -ac.handlers=aa[bb]ac.easing=_c;return ac end;function ca:start()self.startTime=os.epoch("local")/1000;if -self.handlers.start then self.handlers.start(self)end -return self end -function ca:update(ab)local bb=math.min(1, -ab/self.duration) -local cb=ba[self.easing](bb)return self.handlers.update(self,cb)end;function ca:complete()if self.handlers.complete then -self.handlers.complete(self)end end -local da={}da.__index=da -function da.registerAnimation(ab,bb)aa[ab]=bb -da[ab]=function(cb,...)local db={...}local _c="linear" -if( -type(db[#db])=="string")then _c=table.remove(db,#db)end;local ac=table.remove(db,#db) -return cb:addAnimation(ab,db,ac,_c)end end;function da.registerEasing(ab,bb)ba[ab]=bb end -function da.new(ab)local bb={}bb.element=ab -bb.sequences={{}}bb.sequenceCallbacks={}bb.currentSequence=1;bb.timer=nil -setmetatable(bb,da)return bb end -function da:sequence()table.insert(self.sequences,{})self.currentSequence=# -self.sequences;self.sequenceCallbacks[self.currentSequence]={start=nil,update=nil,complete= -nil}return self end -function da:onStart(ab) -if -not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end -self.sequenceCallbacks[self.currentSequence].start=ab;return self end -function da:onUpdate(ab) -if -not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end -self.sequenceCallbacks[self.currentSequence].update=ab;return self end -function da:onComplete(ab) -if -not self.sequenceCallbacks[self.currentSequence]then self.sequenceCallbacks[self.currentSequence]={}end -self.sequenceCallbacks[self.currentSequence].complete=ab;return self end -function da:addAnimation(ab,bb,cb,db)local _c=ca.new(self.element,ab,bb,cb,db) -table.insert(self.sequences[self.currentSequence],_c)return self end -function da:start()self.currentSequence=1;self.timer=nil -if -(self.sequenceCallbacks[self.currentSequence])then if(self.sequenceCallbacks[self.currentSequence].start)then -self.sequenceCallbacks[self.currentSequence].start(self.element)end end -if -#self.sequences[self.currentSequence]>0 then self.timer=os.startTimer(0.05)for ab,bb in -ipairs(self.sequences[self.currentSequence])do bb:start()end end;return self end -function da:event(ab,bb) -if ab=="timer"and bb==self.timer then -local cb=os.epoch("local")/1000;local db=true;local _c={} -local ac=self.sequenceCallbacks[self.currentSequence] -for bc,cc in ipairs(self.sequences[self.currentSequence])do -local dc=cb-cc.startTime;local _d=dc/cc.duration;local ad=cc:update(dc)if ac and ac.update then -ac.update(self.element,_d)end;if not ad then table.insert(_c,cc)db=false else -cc:complete()end end -if db then -if ac and ac.complete then ac.complete(self.element)end -if self.currentSequence<#self.sequences then -self.currentSequence=self.currentSequence+1;_c={} -local bc=self.sequenceCallbacks[self.currentSequence]if bc and bc.start then bc.start(self.element)end -for cc,dc in -ipairs(self.sequences[self.currentSequence])do dc:start()table.insert(_c,dc)end end end;if#_c>0 then self.timer=os.startTimer(0.05)end -return true end end -function da:stop()if self.timer then pcall(os.cancelTimer,self.timer) -self.timer=nil end -for ab,bb in ipairs(self.sequences)do for cb,db in ipairs(bb)do -pcall(function()if db and -db.complete then db:complete()end end)end end;if -self.element and type(self.element.set)=="function"then -pcall(function()self.element.set("animation",nil)end)end end -da.registerAnimation("move",{start=function(ab)ab.startX=ab.element.get("x") -ab.startY=ab.element.get("y")end,update=function(ab,bb)local cb=ab.startX+ -(ab.args[1]-ab.startX)*bb;local db=ab.startY+ -(ab.args[2]-ab.startY)*bb -ab.element.set("x",math.floor(cb))ab.element.set("y",math.floor(db))return bb>=1 end,complete=function(ab) -ab.element.set("x",ab.args[1])ab.element.set("y",ab.args[2])end}) -da.registerAnimation("resize",{start=function(ab)ab.startW=ab.element.get("width") -ab.startH=ab.element.get("height")end,update=function(ab,bb)local cb=ab.startW+ -(ab.args[1]-ab.startW)*bb;local db=ab.startH+ -(ab.args[2]-ab.startH)*bb -ab.element.set("width",math.floor(cb))ab.element.set("height",math.floor(db)) -return bb>=1 end,complete=function(ab) -ab.element.set("width",ab.args[1])ab.element.set("height",ab.args[2])end}) -da.registerAnimation("moveOffset",{start=function(ab)ab.startX=ab.element.get("offsetX") -ab.startY=ab.element.get("offsetY")end,update=function(ab,bb)local cb=ab.startX+ (ab.args[1]-ab.startX)* -bb;local db=ab.startY+ (ab.args[2]- -ab.startY)*bb -ab.element.set("offsetX",math.floor(cb))ab.element.set("offsetY",math.floor(db))return -bb>=1 end,complete=function(ab) -ab.element.set("offsetX",ab.args[1])ab.element.set("offsetY",ab.args[2])end}) -da.registerAnimation("number",{start=function(ab) -ab.startValue=ab.element.get(ab.args[1])ab.targetValue=ab.args[2]end,update=function(ab,bb) -local cb= -ab.startValue+ (ab.targetValue-ab.startValue)*bb -ab.element.set(ab.args[1],math.floor(cb))return bb>=1 end,complete=function(ab) -ab.element.set(ab.args[1],ab.targetValue)end}) -da.registerAnimation("entries",{start=function(ab) -ab.startColor=ab.element.get(ab.args[1])ab.colorList=ab.args[2]end,update=function(ab,bb) -local cb=ab.colorList;local db=math.floor(#cb*bb)+1;if db>#cb then db=#cb end -ab.element.set(ab.args[1],cb[db])end,complete=function(ab) -ab.element.set(ab.args[1],ab.colorList[ -#ab.colorList])end}) -da.registerAnimation("morphText",{start=function(ab)local bb=ab.element.get(ab.args[1]) -local cb=ab.args[2]local db=math.max(#bb,#cb) -local _c=string.rep(" ",math.floor(db-#bb)/2)ab.startText=_c..bb.._c -ab.targetText=cb..string.rep(" ",db-#cb)ab.length=db end,update=function(ab,bb) -local cb="" -for i=1,ab.length do local db=ab.startText:sub(i,i) -local _c=ab.targetText:sub(i,i) -if bb<0.5 then -cb=cb.. (math.random()>bb*2 and db or" ")else cb=cb.. -(math.random()> (bb-0.5)*2 and" "or _c)end end;ab.element.set(ab.args[1],cb)return bb>=1 end,complete=function(ab) -ab.element.set(ab.args[1],ab.targetText:gsub("%s+$",""))end}) -da.registerAnimation("typewrite",{start=function(ab)ab.targetText=ab.args[2] -ab.element.set(ab.args[1],"")end,update=function(ab,bb) -local cb=math.floor(#ab.targetText*bb) -ab.element.set(ab.args[1],ab.targetText:sub(1,cb))return bb>=1 end}) -da.registerAnimation("fadeText",{start=function(ab)ab.chars={}for i=1,#ab.args[2]do -ab.chars[i]={char=ab.args[2]:sub(i,i),visible=false}end end,update=function(ab,bb) -local cb=""for db,_c in ipairs(ab.chars)do -if math.random()=1 end}) -da.registerAnimation("scrollText",{start=function(ab)ab.width=ab.element.get("width")ab.startText= -ab.element.get(ab.args[1])or"" -ab.targetText=ab.args[2]or""ab.startText=tostring(ab.startText) -ab.targetText=tostring(ab.targetText)end,update=function(ab,bb) -local cb=ab.width -if bb<0.5 then local db=bb/0.5;local _c=math.floor(cb*db) -local ac=( -ab.startText:sub(_c+1)..string.rep(" ",cb)):sub(1,cb)ab.element.set(ab.args[1],ac)else -local db=(bb-0.5)/0.5;local _c=math.floor(cb* (1 -db)) -local ac=string.rep(" ",_c)..ab.targetText;local bc=ac:sub(1,cb)ab.element.set(ab.args[1],bc)end;return bb>=1 end,complete=function(ab)local bb=( -ab.targetText..string.rep(" ",ab.width)) -ab.element.set(ab.args[1],bb)end}) -da.registerAnimation("marquee",{start=function(ab)ab.width=ab.element.get("width")ab.text=tostring( -ab.args[2]or"") -ab.speed=tonumber(ab.args[3])or 0.15;ab.offset=0;ab.lastShift=-1 -ab.padded=ab.text..string.rep(" ",ab.width)end,update=function(ab,bb)local cb= -os.epoch("local")/1000 -ab.startTime -local db=math.max(0.01,ab.speed)local _c=math.floor(cb/db) -if _c~=ab.lastShift then ab.lastShift=_c -local ac=#ab.padded;local bc=(_c%ac)+1;local cc=ab.padded..ab.padded -local dc=cc:sub(bc,bc+ab.width-1)ab.element.set(ab.args[1],dc)end;return false end,complete=function(ab) -end})local _b={hooks={}} -function _b.hooks.handleEvent(ab,bb,...)if bb=="timer"then local cb=ab.get("animation")if cb then -cb:event(bb,...)end end end -function _b.setup(ab) -ab.defineProperty(ab,"animation",{default=nil,type="table"})ab.defineEvent(ab,"timer")end -function _b.stopAnimation(ab)local bb=ab.get("animation") -if -bb and type(bb.stop)=="function"then bb:stop()else ab.set("animation",nil)end;return ab end -function _b:animate()local ab=da.new(self)self.set("animation",ab)return ab end;return{VisualElement=_b} end -project["plugins/xml.lua"] = function(...) local ab=require("errorManager")local bb=require("log") -local cb={new=function(ad) -return -{tag=ad,value=nil,attributes={},children={},addChild=function(bd,cd) -table.insert(bd.children,cd)end,addAttribute=function(bd,cd,dd)bd.attributes[cd]=dd end}end} -local db=function(ad,bd) -local cd,dd=string.gsub(bd,"(%w+)=([\"'])(.-)%2",function(b_a,c_a,d_a) -ad:addAttribute(b_a,"\""..d_a.."\"")end) -local __a,a_a=string.gsub(bd,"(%w+)={(.-)}",function(b_a,c_a)ad:addAttribute(b_a,c_a)end)end -local _c={parseText=function(ad)local bd={}local cd=cb.new()table.insert(bd,cd)local dd,__a,a_a,b_a,c_a;local d_a,_aa=1,1 -while -true do -dd,_aa,__a,a_a,b_a,c_a=string.find(ad,"<(%/?)([%w_:]+)(.-)(%/?)>",d_a)if not dd then break end;local aaa=string.sub(ad,d_a,dd-1)if not -string.find(aaa,"^%s*$")then local baa=(cd.value or"")..aaa -bd[#bd].value=baa end -if c_a=="/"then local baa=cb.new(a_a) -db(baa,b_a)cd:addChild(baa)elseif __a==""then local baa=cb.new(a_a)db(baa,b_a) -table.insert(bd,baa)cd=baa else local baa=table.remove(bd)cd=bd[#bd] -if#bd<1 then ab.error( -"XMLParser: nothing to close with "..a_a)end;if baa.tag~=a_a then -ab.error("XMLParser: trying to close "..baa.tag.." with "..a_a)end;cd:addChild(baa)end;d_a=_aa+1 end;if#bd>1 then -error("XMLParser: unclosed "..bd[#bd].tag)end;return cd.children end} -local function ac(ad)local bd={}local cd=1 -while true do local dd,__a,a_a=ad:find("%${([^}]+)}",cd) -if not dd then break end -table.insert(bd,{start=dd,ending=__a,expression=a_a,raw=ad:sub(dd,__a)})cd=__a+1 end;return bd end -local function bc(ad,bd)if not ad then return ad end;if -ad:sub(1,1)=="\""and ad:sub(-1)=="\""then ad=ad:sub(2,-2)end;local cd=ac(ad) -for dd,__a in ipairs(cd)do -local a_a=__a.expression;local b_a=__a.start-1;local c_a=__a.ending+1;if bd[a_a]then ad=ad:sub(1,b_a).. -tostring(bd[a_a])..ad:sub(c_a)else -ab.error( -"XMLParser: variable '"..a_a.."' not found in scope")end end -if ad:match("^%s*%s*$")then -local dd=ad:match("")local __a=_ENV;for a_a,b_a in pairs(bd)do __a[a_a]=b_a end;return -load("return "..dd,nil,"bt",__a)()end -if ad=="true"then return true elseif ad=="false"then return false elseif colors[ad]then return colors[ad]elseif tonumber(ad)then return -tonumber(ad)else return ad end end -local function cc(ad,bd)local cd={} -for dd,__a in pairs(ad.children)do -if __a.tag=="item"or __a.tag=="entry"then -local a_a={} -for b_a,c_a in pairs(__a.attributes)do a_a[b_a]=bc(c_a,bd)end;for b_a,c_a in pairs(__a.children)do -if c_a.value then a_a[c_a.tag]=bc(c_a.value,bd)elseif# -c_a.children>0 then a_a[c_a.tag]=cc(c_a)end end -table.insert(cd,a_a)else if __a.value then cd[__a.tag]=bc(__a.value,bd)elseif#__a.children>0 then -cd[__a.tag]=cc(__a)end end end;return cd end;local dc={}function dc.setup(ad) -ad.defineProperty(ad,"customXML",{default={attributes={},children={}},type="table"})end -function dc:fromXML(ad,bd) -if(ad.attributes)then -for cd,dd in -pairs(ad.attributes)do -if(self._properties[cd])then self.set(cd,bc(dd,bd))elseif self[cd]then -if( -cd:sub(1,2)=="on")then local __a=dd:gsub("\"","") -if(bd[__a])then if -(type(bd[__a])~="function")then -ab.error("XMLParser: variable '"..__a.. -"' is not a function for element '"..self:getType().."' "..cd)end -self[cd](self,bd[__a])else -ab.error("XMLParser: variable '"..__a.."' not found in scope")end else -ab.error("XMLParser: property '"..cd.. -"' not found in element '"..self:getType().."'")end else local __a=self.get("customXML") -__a.attributes[cd]=bc(dd,bd)end end end -if(ad.children)then -for cd,dd in pairs(ad.children)do -if(self._properties[dd.tag])then if( -self._properties[dd.tag].type=="table")then self.set(dd.tag,cc(dd,bd))else -self.set(dd.tag,bc(dd.value,bd))end else local __a={} -if(dd.children)then -for a_a,b_a in -pairs(dd.children)do -if(b_a.tag=="param")then -table.insert(__a,bc(b_a.value,bd))elseif(b_a.tag=="table")then table.insert(__a,cc(b_a,bd))end end end -if(self[dd.tag])then if(#__a>0)then -self[dd.tag](self,table.unpack(__a))elseif(dd.value)then self[dd.tag](self,bc(dd.value,bd))else -self[dd.tag](self)end else -local a_a=self.get("customXML")dd.value=bc(dd.value,bd)a_a.children[dd.tag]=dd end end end end;return self end;local _d={} -function _d:loadXML(ad,bd)bd=bd or{}local cd=_c.parseText(ad) -self:fromXML(cd,bd) -if(cd)then -for dd,__a in ipairs(cd)do -local a_a=__a.tag:sub(1,1):upper()..__a.tag:sub(2)if self["add"..a_a]then local b_a=self["add"..a_a](self) -b_a:fromXML(__a,bd)end end end;return self end -function _d:fromXML(ad,bd)dc.fromXML(self,ad,bd) -if(ad.children)then -for cd,dd in ipairs(ad.children)do local __a= -dd.tag:sub(1,1):upper()..dd.tag:sub(2) -if -self["add"..__a]then local a_a=self["add"..__a](self)a_a:fromXML(dd,bd)end end end;return self end;return{API=_c,Container=_d,BaseElement=dc} end -project["plugins/theme.lua"] = function(...) local ab=require("errorManager") -local bb={default={background=colors.lightGray,foreground=colors.black},BaseFrame={background=colors.white,foreground=colors.black,Frame={background=colors.black,names={basaltDebugLogClose={background=colors.blue,foreground=colors.white}}},Button={background="{self.clicked and colors.black or colors.cyan}",foreground="{self.clicked and colors.cyan or colors.black}"},names={basaltDebugLog={background=colors.red,foreground=colors.white},test={background="{self.clicked and colors.black or colors.green}",foreground="{self.clicked and colors.green or colors.black}"}}}}local cb={default=bb}local db="default" -local _c={hooks={postInit={pre=function(ad)if ad._postInitialized then return ad end -ad:applyTheme()end}}} -function _c.____getElementPath(ad,bd)if bd then table.insert(bd,1,ad._values.type)else -bd={ad._values.type}end;local cd=ad.parent;if cd then return -cd.____getElementPath(cd,bd)else return bd end end -local function ac(ad,bd)local cd=ad -for i=1,#bd do local dd=false;local __a=bd[i]for a_a,b_a in ipairs(__a)do -if cd[b_a]then cd=cd[b_a]dd=true;break end end;if not dd then return nil end end;return cd end -local function bc(ad,bd)local cd={} -if ad.default then for dd,__a in pairs(ad.default)do -if type(__a)~="table"then cd[dd]=__a end end;if ad.default[bd]then -for dd,__a in -pairs(ad.default[bd])do if type(__a)~="table"then cd[dd]=__a end end end end;return cd end -local function cc(ad,bd,cd,dd,__a) -if -bd.default and bd.default.names and bd.default.names[dd]then for a_a,b_a in pairs(bd.default.names[dd])do -if type(b_a)~="table"then ad[a_a]=b_a end end end -if - -bd.default and bd.default[cd]and bd.default[cd].names and bd.default[cd].names[dd]then -for a_a,b_a in pairs(bd.default[cd].names[dd])do if -type(b_a)~="table"then ad[a_a]=b_a end end end;if __a and __a.names and __a.names[dd]then -for a_a,b_a in pairs(__a.names[dd])do if -type(b_a)~="table"then ad[a_a]=b_a end end end end -local function dc(ad,bd,cd,dd)local __a={}local a_a=ac(ad,bd) -if a_a then for b_a,c_a in pairs(a_a)do -if type(c_a)~="table"then __a[b_a]=c_a end end end;if next(__a)==nil then __a=bc(ad,cd)end -cc(__a,ad,cd,dd,a_a)return __a end -function _c:applyTheme(ad)local bd=self:getTheme() -if(bd~=nil)then -for cd,dd in pairs(bd)do -local __a=self._properties[cd] -if(__a)then -if( (__a.type)=="color")then if(type(dd)=="string")then -if(colors[dd])then dd=colors[dd]end end end;self.set(cd,dd)end end end -if(ad~=false)then if(self:isType("Container"))then local cd=self.get("children") -for dd,__a in -ipairs(cd)do if(__a and __a.applyTheme)then __a:applyTheme()end end end end;return self end -function _c:getTheme()local ad=self:____getElementPath() -local bd=self.get("type")local cd=self.get("name")return dc(cb[db],ad,bd,cd)end;local _d={}function _d.setTheme(ad)cb.default=ad end -function _d.getTheme()return cb.default end -function _d.loadTheme(ad)local bd=fs.open(ad,"r") -if bd then local cd=bd.readAll()bd.close() -cb.default=textutils.unserializeJSON(cd)if not cb.default then -ab.error("Failed to load theme from "..ad)end else -ab.error("Could not open theme file: "..ad)end end;return{BaseElement=_c,API=_d} end -project["elementManager.lua"] = function(...) local ab=table.pack(...) -local bb=fs.getDir(ab[2]or"basalt")local cb=ab[1]if(bb==nil)then -error("Unable to find directory ".. -ab[2].." please report this bug to our discord.")end -local db=require("log")local _c=package.path;local ac="path;/path/?.lua;/path/?/init.lua;" -local bc=ac:gsub("path",bb)local cc={}cc._elements={}cc._plugins={}cc._APIs={} -local dc=fs.combine(bb,"elements")local _d=fs.combine(bb,"plugins") -db.info("Loading elements from "..dc) -if fs.exists(dc)then -for ad,bd in ipairs(fs.list(dc))do local cd=bd:match("(.+).lua")if cd then db.debug( -"Found element: "..cd) -cc._elements[cd]={class=nil,plugins={},loaded=false}end end end;db.info("Loading plugins from ".._d) -if -fs.exists(_d)then -for ad,bd in ipairs(fs.list(_d))do local cd=bd:match("(.+).lua") -if cd then -db.debug("Found plugin: "..cd)local dd=require(fs.combine("plugins",cd)) -if -type(dd)=="table"then -for __a,a_a in pairs(dd)do if(__a~="API")then -if(cc._plugins[__a]==nil)then cc._plugins[__a]={}end;table.insert(cc._plugins[__a],a_a)else -cc._APIs[cd]=a_a end end end end end end -if(minified)then if(minified_elementDirectory==nil)then -error("Unable to find minified_elementDirectory please report this bug to our discord.")end;for ad,bd in -pairs(minified_elementDirectory)do -cc._elements[ad:gsub(".lua","")]={class=nil,plugins={},loaded=false}end;if -(minified_pluginDirectory==nil)then -error("Unable to find minified_pluginDirectory please report this bug to our discord.")end -for ad,bd in -pairs(minified_pluginDirectory)do local cd=ad:gsub(".lua","") -local dd=require(fs.combine("plugins",cd)) -if type(dd)=="table"then -for __a,a_a in pairs(dd)do -if(__a~="API")then if(cc._plugins[__a]==nil)then -cc._plugins[__a]={}end -table.insert(cc._plugins[__a],a_a)else cc._APIs[cd]=a_a end end end end end -function cc.loadElement(ad) -if not cc._elements[ad].loaded then -package.path=bc.."rom/?"local bd=require(fs.combine("elements",ad)) -package.path=_c;cc._elements[ad]={class=bd,plugins=bd.plugins,loaded=true}db.debug( -"Loaded element: "..ad) -if(cc._plugins[ad]~=nil)then -for cd,dd in -pairs(cc._plugins[ad])do if(dd.setup)then dd.setup(bd)end -if(dd.hooks)then -for __a,a_a in pairs(dd.hooks)do -local b_a=bd[__a]if(type(b_a)~="function")then -error("Element ".. -ad.." does not have a method "..__a)end -if(type(a_a)=="function")then -bd[__a]=function(c_a,...) -local d_a=b_a(c_a,...)local _aa=a_a(c_a,...)return _aa==nil and d_a or _aa end elseif(type(a_a)=="table")then -bd[__a]=function(c_a,...)if a_a.pre then a_a.pre(c_a,...)end -local d_a=b_a(c_a,...)if a_a.post then a_a.post(c_a,...)end;return d_a end end end end;for __a,a_a in pairs(dd)do -if __a~="setup"and __a~="hooks"then bd[__a]=a_a end end end end end end -function cc.getElement(ad)if not cc._elements[ad].loaded then -cc.loadElement(ad)end;return cc._elements[ad].class end;function cc.getElementList()return cc._elements end;function cc.getAPI(ad) -return cc._APIs[ad]end;return cc end -project["errorManager.lua"] = function(...) local d=require("log") -local _a={tracebackEnabled=true,header="Basalt Error"}local function aa(ba,ca)term.setTextColor(ca)print(ba) -term.setTextColor(colors.white)end -function _a.error(ba) -if _a.errorHandled then error()end;term.setBackgroundColor(colors.black) -term.clear()term.setCursorPos(1,1) -aa(_a.header..":",colors.red)print()local ca=2;local da;while true do local db=debug.getinfo(ca,"Sl") -if not db then break end;da=db;ca=ca+1 end;local _b=da or -debug.getinfo(2,"Sl")local ab=_b.source:sub(2) -local bb=_b.currentline;local cb=ba -if(_a.tracebackEnabled)then local db=debug.traceback() -if db then -for _c in db:gmatch("[^\r\n]+")do -local ac,bc=_c:match("([^:]+):(%d+):") -if ac and bc then term.setTextColor(colors.lightGray) -term.write(ac)term.setTextColor(colors.gray)term.write(":") -term.setTextColor(colors.lightBlue)term.write(bc)term.setTextColor(colors.gray)_c=_c:gsub( -ac..":"..bc,"")end;aa(_c,colors.gray)end;print()end end -if ab and bb then term.setTextColor(colors.red) -term.write("Error in ")term.setTextColor(colors.white)term.write(ab) -term.setTextColor(colors.red)term.write(":") -term.setTextColor(colors.lightBlue)term.write(bb)term.setTextColor(colors.red) -term.write(": ") -if cb then cb=string.gsub(cb,"stack traceback:.*","") -if cb~=""then -aa(cb,colors.red)else aa("Error message not available",colors.gray)end else aa("Error message not available",colors.gray)end;local db=fs.open(ab,"r") -if db then local _c=""local ac=1 -repeat _c=db.readLine()if -ac==tonumber(bb)then aa("\149Line "..bb,colors.cyan) -aa(_c,colors.lightGray)break end;ac=ac+1 until not _c;db.close()end end;term.setBackgroundColor(colors.black) -d.error(ba)_a.errorHandled=true;error()end;return _a end return project["main.lua"]() \ No newline at end of file