bug fixes and new conf values

This commit is contained in:
Elmārs Āboliņš 2021-07-03 21:13:03 +03:00
parent 91e3441201
commit 81b24eee59
25 changed files with 459 additions and 199 deletions

View File

@ -1,6 +1,10 @@
![alt text](https://i.imgur.com/ZQBQfsa.png "Helium") ![alt text](https://i.imgur.com/ZQBQfsa.png "Helium")
# Helium # Helium
![Helium main menu demo](https://j.gifs.com/nRrKmp.gif)
*a main menu demo made with helium, in action, find [it here](https://github.com/qeffects/main-menu-example)*
## Basic overview: ## Basic overview:
Helium is practically more like a UI framework than a fully fledged UI library. Helium is practically more like a UI framework than a fully fledged UI library.
The idea is to build custom and build simple. The idea is to build custom and build simple.
@ -119,4 +123,6 @@ Or continue on to the State and Input guide: [Here](./docs/State-Input-Guide.md)
If you are using gamestates, scene guide will be of interest: [Here](./docs/core/Scenes.md) If you are using gamestates, scene guide will be of interest: [Here](./docs/core/Scenes.md)
For a more general overview of the whole library: [Module index](./docs/Modules-Index.md) For a more general overview of the whole library: [Module index](./docs/Modules-Index.md)
Also check out the helium configuration values: [Config](./docs/Configuration.md)
There's also a main menu example project available here: [Project](https://github.com/qeffects/main-menu-example) There's also a main menu example project available here: [Project](https://github.com/qeffects/main-menu-example)

View File

@ -1,4 +1,15 @@
---@class __HELIUM_CONFIG
---@field DEBUG boolean
---@field LOAD_HOOKS boolean
---@field LOAD_LAYOUT boolean
---@field LOAD_SHELL boolean
---@field MANUAL_CACHING boolean
---@type __HELIUM_CONFIG
return { return {
AUTO_RUN = true, --Replaces the default love.run DEBUG = true, --Reserved for later
DEBUG = true, --Reserved for later LOAD_HOOKS = false, --Loads the hooks module in to helium table
LOAD_LAYOUT = false, --Loads the layout module in to helium table
LOAD_SHELL = false, --Loads the shell mocule in to helium table
MANUAL_CACHING = false, --Whether or not to perform automatic caching
} }

View File

@ -3,7 +3,8 @@
Copyright (c) 2021 Elmārs Āboliņš Copyright (c) 2021 Elmārs Āboliņš
https://github.com/qeffects/helium https://github.com/qeffects/helium
----------------------------------------------------]] ----------------------------------------------------]]
local path = string.sub(..., 1, string.len(...) - string.len(".core.atlas"))
local helium = require(path..'.dummy')
local atlas = {} local atlas = {}
atlas.__index = atlas atlas.__index = atlas
---@class atlases ---@class atlases
@ -39,20 +40,22 @@ end
function atlases:assign(element) function atlases:assign(element)
local avg, sum, canvasID = 0, 0, element.context:getCanvasIndex(true) or 1 local avg, sum, canvasID = 0, 0, element.context:getCanvasIndex(true) or 1
for i, e in ipairs(element.renderBench) do if not helium.conf.MANUAL_CACHING then
sum = sum + e for i, e in ipairs(element.renderBench) do
end sum = sum + e
end
avg = sum/#element.renderBench avg = sum/#element.renderBench
local areaBelow = self:getFreeArea(canvasID) local areaBelow = self:getFreeArea(canvasID)
local area = element.view.h*element.view.w local area = element.view.h*element.view.w
local areaCoef = (2-(self:getRatio(canvasID)) )-(area/(areaBelow/(4+3*self:getRatio(canvasID)))) local areaCoef = (2-(self:getRatio(canvasID)) )-(area/(areaBelow/(4+3*self:getRatio(canvasID))))
local speedCoef = avg/selfRenderTime local speedCoef = avg/selfRenderTime
if not ((areaCoef+speedCoef)>coefficient) then if not ((areaCoef+speedCoef)>coefficient) then
return return
end
end end
local elW = element.view.w local elW = element.view.w

View File

@ -125,7 +125,6 @@ function element:posChange(i, v)
self.deferRepos = true self.deferRepos = true
end end
if self.callbacks.onPosChange then if self.callbacks.onPosChange then
for i, cb in ipairs(self.callbacks.onPosChange) do for i, cb in ipairs(self.callbacks.onPosChange) do
cb(self.view.x, self.view.y) cb(self.view.x, self.view.y)
@ -258,13 +257,13 @@ local setColor, rectangle, setFont, printf = love.graphics.setColor, love.graphi
local calcT local calcT
function element:internalRender() function element:internalRender()
if self.settings.testRenderPasses > 0 and selfRenderTime then if self.settings.testRenderPasses > 0 and selfRenderTime and not helium.conf.MANUAL_CACHING then
calcT = love.timer.getTime() calcT = love.timer.getTime()
end end
self.renderer() self.renderer()
if self.settings.testRenderPasses > 0 and selfRenderTime then if self.settings.testRenderPasses > 0 and selfRenderTime and not helium.conf.MANUAL_CACHING then
self.settings.testRenderPasses = self.settings.testRenderPasses-1 self.settings.testRenderPasses = self.settings.testRenderPasses-1
local selfTime = love.timer.getTime()-calcT local selfTime = love.timer.getTime()-calcT
table.insert(self.renderBench, selfTime) table.insert(self.renderBench, selfTime)
@ -334,10 +333,12 @@ end
function element:externalUpdate() function element:externalUpdate()
self.context:set() self.context:set()
self.context:zIndex() self.context:zIndex()
if not self.settings.failedCanvas if ((not self.settings.failedCanvas
and self.settings.testRenderPasses == 0 and self.settings.testRenderPasses == 0
and not self.settings.hasCanvas and scene.activeScene.cached
and scene.activeScene.cached then and not helium.conf.MANUAL_CACHING)
or self.settings.forcedCanvas)
and not self.settings.hasCanvas then
self:createCanvas() self:createCanvas()

17
core/init.lua Normal file
View File

@ -0,0 +1,17 @@
local path = ...
---@class __HELIUM_CORE
---@field atlas any
---@field element any
---@field events any
---@field input any
---@field scene any
---@field stack any
return {
atlas = require(path..'.atlas'),
element = require(path..'.element'),
events = require(path..'.events'),
input = require(path..'.input'),
scene = require(path..'.scene'),
stack = require(path..'.stack'),
}

View File

@ -172,11 +172,11 @@ function subscription:emit(...)
end end
function subscription:checkInside(x, y) function subscription:checkInside(x, y)
return x>self.stack.absX and x<self.stack.absX+self.w and y>self.stack.absY and y<self.stack.absY+self.h return x>self.x and x<self.x+self.w and y>self.y and y<self.y+self.h
end end
function subscription:checkOutside(x, y) function subscription:checkOutside(x, y)
return not (x>self.stack.absX and x<self.stack.absX+self.w and y>self.stack.absY and y<self.stack.absY+self.h) return not (x>self.x and x<self.x+self.w and y>self.y and y<self.y+self.h)
end end
---@alias InputMouseClickSubscriptionCallback fun(x:number, y:number, mouseButton:string) ---@alias InputMouseClickSubscriptionCallback fun(x:number, y:number, mouseButton:string)

View File

@ -98,8 +98,8 @@ end
function scene:drawAtlases(x, y) function scene:drawAtlases(x, y)
if self.atlas then if self.atlas then
local aw = self.atlas.atlases[1].canvas:getWidth() local aw = self.atlas.atlases[1].canvas:getWidth()
love.graphics.draw(self.atlas.atlases[1].canvas, x, y, 0, 0.5, 0.5) love.graphics.draw(self.atlas.atlases[1].canvas, x, y)
love.graphics.draw(self.atlas.atlases[2].canvas, x+aw/2, y, 0, 0.5, 0.5) love.graphics.draw(self.atlas.atlases[2].canvas, x+aw, y)
end end
end end

View File

@ -8,13 +8,16 @@ local helium = require(path .. ".dummy")
local event = require(path..'.core.events') local event = require(path..'.core.events')
---@class context ---@class context
local context = {} ---@field element Element
local context = {
type = 'context'
}
context.__index = context context.__index = context
local activeContext local activeContext
local currentTemporalZ = 0 local currentTemporalZ = 0
---@param elem element ---@param elem Element
function context.new(elem) function context.new(elem)
local ctx = setmetatable({ local ctx = setmetatable({
capturedChilds = {}, capturedChilds = {},
@ -203,9 +206,21 @@ end
--To be used by the element --To be used by the element
function context:sizeChanged() function context:sizeChanged()
if self.parentCtx then
self.absX = self.parentCtx.absX + self.view.x
self.absY = self.parentCtx.absY + self.view.y
else
self.absX = self.view.x
self.absY = self.view.y
end
self.events:push('resize') self.events:push('resize')
end end
local posPropogator = function(elem)
elem:posChanged()
end
function context:posChanged() function context:posChanged()
if self.parentCtx then if self.parentCtx then
self.absX = self.parentCtx.absX + self.view.x self.absX = self.parentCtx.absX + self.view.x
@ -215,6 +230,8 @@ function context:posChanged()
self.absY = self.view.y self.absY = self.view.y
end end
self:doOnEveryChild(posPropogator)
self.events:push('poschange') self.events:push('poschange')
end end
@ -235,10 +252,16 @@ function context:offPosChange(callback)
self.events:unsub('poschange', callback) self.events:unsub('poschange', callback)
end end
function context:onEveryChild(func) function context:doOnEveryChild(func)
func(self.element)
for i, e in ipairs(self.childrenContexts) do for i, e in ipairs(self.childrenContexts) do
self.childrenContexts:onEveryChild(func) e:onEveryChild(func)
end
end
function context:onEveryChild(func)
func(self)
for i, e in ipairs(self.childrenContexts) do
e:onEveryChild(func)
end end
end end

85
docs/Configuration.md Normal file
View File

@ -0,0 +1,85 @@
## Configuration
Helium offers some configuration values, exposed to you, the user with HELIUM_CONFIG table.
To start configuring, create a global table before the first helium require like this:
```lua
HELIUM_CONFIG = {
LOAD_SHELL = true
}
local helium = require('helium')
```
If the configuration isn't working, you're probably not defining the `HELIUM_CONFIG` table early enough
After the first require it's safe to remove `HELIUM_CONFIG` as the values will be copied to an internal table.
## The current configuration values
the default value is indicated with () around em:
options: `other / (default)`
### LOAD_SHELL
options: `true / (false)`
This is an optional config that starts off by default, but it will load all of the ./shell/ modules in to the helium table
so you can use it like this later:
```lua
local helium = require('helium')
--
helium.shell.button()
```
The table structure mirrors the folders exactly, so, instead of
```lua
local checkbox = require('helium.shell.checkbox')
```
You can do
```lua
local helium = require('helium')
--
helium.shell.checkbox()
```
### LOAD_LAYOUT
options: `true / (false)`
This one is extremely similar to LOAD_SHELL, the result is exactly the same, except it loads the ./layout/ folder, and it's also off by default
so you can do
```lua
local helium = require('helium')
--
helium.layout.container.new()
```
### LOAD_HOOKS
options: `true / (false)`
This one is similar to LOAD_LAYOUT and LOAD_SHELL, the result is the same, except it loads the modules in ./hook/ folder, and it's also off by default
so you can do
```lua
local helium = require('helium')
--
helium.hooks.state({blah = false})
```
### MANUAL_CACHING
options: `true / (false)`
Manual caching can be enabled if you want manual control over which elements are atlassed, use together with the `setCaching()` hook
Make sure to enable caching for the scenes you intend to use your element class for.

View File

@ -14,7 +14,7 @@ Element is the class for every ui element, in practice it's glue between the cod
Input allows to create callbacks for helium internal input events Input allows to create callbacks for helium internal input events
[Find more here](./core/State-Input-Guide.md) [Find more here](./State-Input-Guide.md)
[and here](./core/Input-events.md) [and here](./core/Input-events.md)

View File

@ -245,3 +245,23 @@ function(param, view)
end end
end end
``` ```
### /hooks/setCaching.lua
Makes this element get cached, you'll need to set MANUAL_CACHING in config for this to work
Keep in mind that it won't make a magical performance benefit to an element that is being re-rendered by changes in children components, it's own state, resizing or position changes.
`setCaching()`
Usage:
```lua
local setCaching = require('helium.hooks.setCaching')
function(param, view)
setCaching()
return function()
end
end
```

View File

@ -1,5 +1,5 @@
--Allows to expose a function to outside the element simply --Allows to expose a function to outside the element simply
local path = string.sub(..., 1, string.len(...) - string.len(".hooks.onDestroy")) local path = string.sub(..., 1, string.len(...) - string.len(".hooks.callback"))
local context = require(path.. ".core.stack") local context = require(path.. ".core.stack")
---Creates a callback on the 'name' field for the current element ---Creates a callback on the 'name' field for the current element

28
hooks/init.lua Normal file
View File

@ -0,0 +1,28 @@
local path = ...
---@class __HELIUM_HOOKS
---@field callback any
---@field context any
---@field onDestroy any
---@field onLoad any
---@field onPosChange any
---@field onSizeChange any
---@field onUpdate any
---@field setMinSize any
---@field setPos any
---@field setSize any
---@field state any
return {
callback = require(path..'.callback'),
context = require(path..'.context'),
onDestroy = require(path..'.onDestroy'),
onLoad = require(path..'.onLoad'),
onPosChange = require(path..'.onPosChange'),
onSizeChange = require(path..'.onSizeChange'),
onUpdate = require(path..'.onUpdate'),
setMinSize = require(path..'.setMinSize'),
setCaching = require(path..'.setCaching'),
setPos = require(path..'.setPos'),
setSize = require(path..'.setSize'),
state = require(path..'.state'),
}

15
hooks/setCaching.lua Normal file
View File

@ -0,0 +1,15 @@
local path = string.sub(..., 1, string.len(...) - string.len(".hooks.setCaching"))
---@type context
local context = require(path.. ".core.stack")
local helium = require(path.. ".dummy")
return function ()
local activeContext = context.getContext()
if not helium.conf.MANUAL_CACHING then
error('use setCaching only with manual caching enabled, check your configs')
end
activeContext.element:createCanvas()
activeContext.element.settings.forcedCanvas = true
activeContext.element.settings.pendingUpdate = true
end

View File

@ -11,7 +11,8 @@ return function (base)
local activeContext = context.getContext() local activeContext = context.getContext()
return setmetatable({},{ return setmetatable({},{
__index = function(t, index) __index = function(t, index)
return fakeBase[index] or base[index] local f = fakeBase[index] ~= nil and fakeBase[index] or base[index]
return f
end, end,
__newindex = function(t, index, val) __newindex = function(t, index, val)
if fakeBase[index] ~= val then if fakeBase[index] ~= val then

View File

@ -4,10 +4,20 @@
https://github.com/qeffects/helium https://github.com/qeffects/helium
----------------------------------------------------]] ----------------------------------------------------]]
local path = ... local path = ...
local helium = require(path..'.dummy')
---@class __HELIUM
---@field private scene any
---@field private element any
---@field private atlas any
---@field private stack any
---@field private input any
local helium = require(path..'.dummy')
helium.__index = helium
---@type __HELIUM_CONFIG
local defaultConf = require(path..".conf") local defaultConf = require(path..".conf")
helium.conf = {} helium.conf = {}
if HELIUM_CONFIG then if HELIUM_CONFIG then
for i, e in pairs(defaultConf) do for i, e in pairs(defaultConf) do
helium.conf[i] = HELIUM_CONFIG[i] or e helium.conf[i] = HELIUM_CONFIG[i] or e
@ -16,12 +26,28 @@ else
helium.conf = defaultConf helium.conf = defaultConf
end end
if helium.conf.LOAD_HOOKS then
---@type __HELIUM_HOOKS
helium.hooks = require(path..'.hooks')
end
if helium.conf.LOAD_SHELL then
---@type __HELIUM_SHELL
helium.shell = require(path..'.shell')
end
if helium.conf.LOAD_LAYOUT then
---@type __HELIUM_LAYOUT
helium.layout = require(path..'.layout')
end
helium.core = require(path..'.core')
helium.scene = require(path..".core.scene") helium.scene = require(path..".core.scene")
helium.element = require(path..".core.element") helium.element = require(path..".core.element")
helium.input = require(path..".core.input") helium.input = require(path..".core.input")
helium.stack = require(path..".core.stack") helium.stack = require(path..".core.stack")
helium.atlas = require(path..".core.atlas") helium.atlas = require(path..".core.atlas")
helium.__index = helium
function helium.setBench(time) function helium.setBench(time)
helium.benchNum = time helium.benchNum = time
@ -39,6 +65,4 @@ setmetatable(helium, {__call = function(s, chunk)
end,}) end,})
end}) end})
--Typescript
helium.helium = helium
return helium return helium

View File

@ -1,5 +1,5 @@
local path = string.sub(..., 1, string.len(...) - string.len(".column")) local path = string.sub(..., 1, string.len(...) - string.len(".column"))
local layout = require(path..'.init') local layout = require(path..'.layout')
---@class Column ---@class Column
local column = {} local column = {}
column.__index = column column.__index = column

View File

@ -1,5 +1,5 @@
local path = string.sub(..., 1, string.len(...) - string.len(".container")) local path = string.sub(..., 1, string.len(...) - string.len(".container"))
local layout = require(path..'.init') local layout = require(path..'.layout')
---@class Container ---@class Container
local container = {} local container = {}

View File

@ -1,7 +1,7 @@
local column = require "helium.layout.column" local column = require "helium.layout.column"
--my copy of the cssssss grids --my copy of the cssssss grids
local path = string.sub(..., 1, string.len(...) - string.len(".grid")) local path = string.sub(..., 1, string.len(...) - string.len(".grid"))
local layout = require(path..'.init') local layout = require(path..'.layout')
---@class GridCell ---@class GridCell
---@field name string @Will find the element with the relevant flag ---@field name string @Will find the element with the relevant flag
@ -350,7 +350,7 @@ function grid:draw(xRoot, yRoot, width, height, children)
y = alignHandlerY(self.gridLayout.verticalAlignMode, carriagePos, rowSize, h) y = alignHandlerY(self.gridLayout.verticalAlignMode, carriagePos, rowSize, h)
end end
e:draw(x, y, w, h) e:draw(x, y + yRoot, w, h)
carriagePos = carriagePos + self.gridLayout.rowSpacing + rowSize carriagePos = carriagePos + self.gridLayout.rowSpacing + rowSize
row = row + 1 row = row + 1

View File

@ -1,156 +1,15 @@
local path = string.sub(..., 1, string.len(...) - string.len(".layout.init")) local path = ...
---@class layout ---@class __HELIUM_LAYOUT
---@field protected vars table ---@field column any
---@field protected type function ---@field container any
local layout = {} ---@field grid any
local layouts = {} ---@field layout any
layout.__index = layout ---@field row any
local element = require(path..'.core.element') return {
local stack = require(path..'.core.stack') column = require(path..'.column'),
container = require(path..'.container'),
--Start prep phase grid = require(path..'.grid'),
function layout.type(binder, callback) layout = require(path..'.layout'),
local curStack = stack.getContext() row = require(path..'.row'),
curStack:startDeferingChildren() }
local self = {
vars = {
offLeft = 0,
offTop = 0,
width = 1,
hpad = 3,
vpad = 3,
height = 1,
},
stack = curStack,
binder = binder,
callback = callback,
}
return setmetatable(self, layout)
end
---Aligns the container vertically
---@param pos 'left'|'center'|'right'
function layout:alignVert(pos)
self.vars.alignY = pos
return self
end
---Aligns the container horizontally
---@param pos 'top'|'center'|'bottom'
function layout:alignHoriz(pos)
self.vars.alignX = pos
return self
end
---Sets up the width of the box of the layout
---@param w number width in pixels or absolute 0-1
function layout:width(w)
self.vars.width = w
return self
end
---Sets up the height of the box of the layout
---@param h number width in pixels or absolute 0-1
function layout:height(h)
self.vars.height = h
return self
end
---Offset from the left
---@param x number offset in pixels or absolute 0-1
function layout:left(x)
self.vars.offLeft = x
return self
end
---Offset from the right
---@param x number offset in pixels or absolute 0-1
function layout:right(x)
self.vars.offRight = x
return self
end
---Offset from the top
---@param y number offset in pixels or absolute 0-1
function layout:top(y)
self.vars.offTop = y
return self
end
---Offset from the bottom
---@param y number offset in pixels or absolute 0-1
function layout:bottom(y)
self.vars.offBot = y
return self
end
---Padding for the elements vertically
---@param px number offset in pixels
function layout:vPadding(px)
self.vars.vpad = px
return self
end
---Padding for the elements horizontally
---@param px number offset in pixels
function layout:hPadding(px)
self.vars.hpad = px
return self
end
--Schemes: left + right = width ignored
--top + bottom = height ignored
--top px + bottom relative works
--left relative + bottom px works
function layout:draw()
local stack = self.stack
local children = stack:stopDeferingChildren()
local height, width, x, y, _, marginV, marginH
local maxW, maxH = stack:normalizeSize(1,1)
if self.vars.offTop and self.vars.offBot then
marginV = stack:normY(self.vars.offTop) + stack:normY(self.vars.offBot)
height = stack:normY(1) - marginV
y = self.vars.offTop
elseif self.vars.offTop then
y = stack:normY(self.vars.offTop)
height = math.min(stack:normY(self.vars.height), maxH-y)
elseif self.vars.offBot then
y = stack:normY(self.vars.offBot)
height = math.min(stack:normY(self.vars.height), maxH-y)
y = 0
end
if self.vars.offLeft and self.vars.offRight then
marginH = stack:normX(self.vars.offLeft) + stack:normX(self.vars.offRight)
width = stack:normX(1) - marginH
x = self.vars.offLeft
elseif self.vars.offLeft then
x = stack:normX(self.vars.offLeft)
width = math.min(stack:normX(self.vars.width), maxW-x)
elseif self.vars.offRight then
x = stack:normX(self.vars.offRight)
height = math.min(stack:normX(self.vars.width), maxW-x)
x = 0
end
self.callback(self.binder, x, y, width, height, children, self.vars.hpad, self.vars.vpad)
end
setmetatable(layout, {__call = function(s, binder, callback) return layout.type(binder, callback) end })
return layout

154
layout/layout.lua Normal file
View File

@ -0,0 +1,154 @@
local path = string.sub(..., 1, string.len(...) - string.len(".layout.layout"))
---@class layout
---@field protected vars table
---@field protected type function
local layout = {}
local layouts = {}
layout.__index = layout
local element = require(path..'.core.element')
local stack = require(path..'.core.stack')
--Start prep phase
function layout.type(binder, callback)
local curStack = stack.getContext()
curStack:startDeferingChildren()
local self = {
vars = {
width = 1,
hpad = 3,
vpad = 3,
height = 1,
},
stack = curStack,
binder = binder,
callback = callback,
}
return setmetatable(self, layout)
end
---Aligns the container vertically
---@param pos 'left'|'center'|'right'
function layout:alignVert(pos)
self.vars.alignY = pos
return self
end
---Aligns the container horizontally
---@param pos 'top'|'center'|'bottom'
function layout:alignHoriz(pos)
self.vars.alignX = pos
return self
end
---Sets up the width of the box of the layout
---@param w number width in pixels or absolute 0-1
function layout:width(w)
self.vars.width = w
return self
end
---Sets up the height of the box of the layout
---@param h number width in pixels or absolute 0-1
function layout:height(h)
self.vars.height = h
return self
end
---Offset from the left
---@param x number offset in pixels or absolute 0-1
function layout:left(x)
self.vars.offLeft = x
return self
end
---Offset from the right
---@param x number offset in pixels or absolute 0-1
function layout:right(x)
self.vars.offRight = x
return self
end
---Offset from the top
---@param y number offset in pixels or absolute 0-1
function layout:top(y)
self.vars.offTop = y
return self
end
---Offset from the bottom
---@param y number offset in pixels or absolute 0-1
function layout:bottom(y)
self.vars.offBot = y
return self
end
---Padding for the elements vertically
---@param px number offset in pixels
function layout:vPadding(px)
self.vars.vpad = px
return self
end
---Padding for the elements horizontally
---@param px number offset in pixels
function layout:hPadding(px)
self.vars.hpad = px
return self
end
--Schemes: left + right = width ignored
--top + bottom = height ignored
--top px + bottom relative works
--left relative + bottom px works
function layout:draw()
local stack = self.stack
local children = stack:stopDeferingChildren()
local height, width, x, y, _, marginV, marginH
local maxW, maxH = stack:normalizeSize(1,1)
if self.vars.offTop and self.vars.offBot then
marginV = stack:normY(self.vars.offTop) + stack:normY(self.vars.offBot)
height = stack:normY(1) - marginV
y = stack:normY(self.vars.offTop)
elseif self.vars.offBot then
y = stack:normY(self.vars.offBot)
height = math.min(stack:normY(self.vars.height), maxH-y)
y = maxH - height - y
else
y = stack:normY(self.vars.offTop or 0)
height = math.min(stack:normY(self.vars.height), maxH-y)
end
if self.vars.offLeft and self.vars.offRight then
marginH = stack:normX(self.vars.offLeft) + stack:normX(self.vars.offRight)
width = stack:normX(1) - marginH
x = stack:normX(self.vars.offLeft)
elseif self.vars.offRight then
x = stack:normX(self.vars.offRight)
width = math.min(stack:normX(self.vars.width), maxW-x)
x = maxW - width -h
else
x = stack:normX(self.vars.offLeft or 0)
width = math.min(stack:normX(self.vars.width), maxW-x)
end
self.callback(self.binder, x, y, width, height, children, self.vars.hpad, self.vars.vpad)
end
setmetatable(layout, {__call = function(s, binder, callback) return layout.type(binder, callback) end })
return layout

View File

@ -1,5 +1,5 @@
local path = string.sub(..., 1, string.len(...) - string.len(".row")) local path = string.sub(..., 1, string.len(...) - string.len(".row"))
local layout = require(path..'.init') local layout = require(path..'.layout')
---@class Row ---@class Row
local row = {} local row = {}

View File

@ -1,4 +1,4 @@
local path = string.sub(..., 1, string.len(...) - string.len(".shell.button")) local path = string.sub(..., 1, string.len(...) - string.len(".shell.checkbox"))
local state = require(path.. ".hooks.state") local state = require(path.. ".hooks.state")
local input = require(path.. ".core.input") local input = require(path.. ".core.input")

13
shell/init.lua Normal file
View File

@ -0,0 +1,13 @@
local path = ...
---@class __HELIUM_SHELL
---@field button any
---@field checkbox any
---@field input any
---@field slider any
return {
button = require(path..'.button'),
checkbox = require(path..'.checkbox'),
input = require(path..'.input'),
slider = require(path..'.slider'),
}

View File

@ -47,14 +47,14 @@ return function(onChange, onFinish, startStr, onEnter, onExit, x, y, w, h)
onFinish(textState.text) onFinish(textState.text)
end end
end end
end) end, false)
textInput = input('textinput', function(text) textInput = input('textinput', function(text)
textState.text = textState.text .. text textState.text = textState.text .. text
if onChange then if onChange then
onChange(textState.text) onChange(textState.text)
end end
end) end, false)
input('mousepressed', function() input('mousepressed', function()
textState.focused = true textState.focused = true