diff options
| author | jussi | 2022-12-01 23:15:54 +0200 |
|---|---|---|
| committer | jussi | 2022-12-01 23:15:54 +0200 |
| commit | 2479049e1a1cd754df486df0142fabe67723de72 (patch) | |
| tree | 603326cc83872e87b3443a3efa9c6323fb4e0760 /examples/resources/lib/gui.lua | |
| parent | 08ef5b435273eaa3de860eac1c031219cd815587 (diff) | |
| download | reilua-enhanced-2479049e1a1cd754df486df0142fabe67723de72.tar.gz reilua-enhanced-2479049e1a1cd754df486df0142fabe67723de72.tar.bz2 reilua-enhanced-2479049e1a1cd754df486df0142fabe67723de72.zip | |
ReiLuaGui basics.
Diffstat (limited to 'examples/resources/lib/gui.lua')
| -rw-r--r-- | examples/resources/lib/gui.lua | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/examples/resources/lib/gui.lua b/examples/resources/lib/gui.lua new file mode 100644 index 0000000..1377335 --- /dev/null +++ b/examples/resources/lib/gui.lua @@ -0,0 +1,384 @@ +util = require( "utillib" ) +Rect = require( "rectangle" ) +Vec2 = require( "vector2" ) + +-- NOTE!!! Work in progress! Do not use. + +Gui = { + ALING = { + LEFT = 1, + RIGHT = 2, + CENTER = 3, + TOP = 1, + BOTTOM = 2, + }, + CONTAINER = { + HORIZONTAL = 1, + VERTICAL = 2, + }, + + font = 0, + fontSize = 30, + textSpacing = 1, + padding = 2, + spacing = 4, + + _elements = {}, +} + +function Gui.process( mousePosition ) + for _, element in ipairs( Gui._elements ) do + if element.notMouseOver ~= nil then + element:notMouseOver() + end + end + + -- Go backwards on process check so we trigger the top most ui first and stop there. + for i = #Gui._elements, 1, -1 do + local element = Gui._elements[i] + + if element:isMouseOver( mousePosition ) and not element.disabled then + if element.isClicked ~= nil then + element:isClicked() + end + + break + end + end +end + +function Gui.draw() + for _, element in ipairs( Gui._elements ) do + if element.draw ~= nil and element.visible then + -- //TODO Check here if needs scrissor mode. + -- if element + + element:draw() + end + end +end + +-- Label + +Label = {} +Label.__index = Label + +function Label:new( set ) + local o = { + _ID = #Gui._elements + 1, + bounds = set ~= nil and set.bounds ~= nil and set.bounds or Rect:new( 0, 0, 0, 0 ), + font = set ~= nil and set.font ~= nil and set.font or Gui.font, + text = set ~= nil and set.text ~= nil and set.text or "", + fontSize = set ~= nil and set.fontSize ~= nil and set.fontSize or Gui.fontSize, + textSpacing = set ~= nil and set.textSpacing ~= nil and set.textSpacing or Gui.textSpacing, + color = set ~= nil and set.color ~= nil and set.color or BLACK, + maxTextLen = set ~= nil and set.maxTextLen ~= nil and set.maxTextLen or nil, + padding = set ~= nil and set.padding ~= nil and set.padding or Gui.padding, + HAling = set ~= nil and set.HAling ~= nil and set.HAling or Gui.ALING.LEFT, + VAling = set ~= nil and set.VAling ~= nil and set.VAling or Gui.ALING.BOTTOM, + + visible = set ~= nil and set.visible ~= nil and set.visible or true, + disabled = set ~= nil and set.disabled ~= nil and set.disabled or false, + drawBounds = set ~= nil and set.drawBounds ~= nil and set.drawBounds or false, + + _textRect = Rect:new( 0, 0, 0, 0 ), + _visibilityBounds = nil, + -- Callbacks. + onMouseOver = set ~= nil and set.onMouseOver ~= nil and set.onMouseOver or nil, + notMouseOver = set ~= nil and set.notMouseOver ~= nil and set.notMouseOver or nil, + onClicked = set ~= nil and set.onClicked ~= nil and set.onClicked or nil, + } + setmetatable( o, self ) + + o:setText( o.text ) -- To measure bounds. + table.insert( Gui._elements, o ) + return o +end + +function Label:setText( text ) + if self.maxTextLen ~= nil then + self.text = text:sub( 1, self.maxTextLen ) + else + self.text = text + end + + local textSize = Vec2:new( RL_MeasureText( self.font, self.text, self.fontSize, self.textSpacing ) ) + + -- Set bounds to text size if not given. + if self.bounds.width == nil then + self.bounds.width = textSize.x + end + if self.bounds.height == nil then + self.bounds.height = textSize.y + end + + -- Horizontal aling. + if self.HAling == Gui.ALING.CENTER then + self._textRect.x = self.bounds.width / 2 - textSize.x / 2 + elseif self.HAling == Gui.ALING.LEFT then + self._textRect.x = self.padding + elseif self.HAling == Gui.ALING.RIGHT then + self._textRect.x = self.bounds.width - textSize.x - self.padding + end + -- Vertical aling. + if self.VAling == Gui.ALING.CENTER then + self._textRect.y = self.bounds.height / 2 - textSize.y / 2 + elseif self.VAling == Gui.ALING.TOP then + self._textRect.y = self.padding + elseif self.VAling == Gui.ALING.BOTTOM then + self._textRect.y = self.bounds.height - textSize.y - self.padding + end + + self._textRect.width = textSize.x + self._textRect.height = textSize.y +end + +function Label:setPosition( pos ) + self.bounds.x = pos.x + self.bounds.y = pos.y +end + +function Label:isMouseOver( mousePosition ) + local over = RL_CheckCollisionPointRec( mousePosition, self.bounds ) + + if over and self._visibilityBounds ~= nil then + over = RL_CheckCollisionPointRec( mousePosition, self._visibilityBounds ) + end + + if over and self.onMouseOver ~= nil then + self:onMouseOver() + end + + return over +end + +function Label:isClicked() + local clicked = RL_IsMouseButtonPressed( MOUSE_BUTTON_LEFT ) + + if clicked and self.onClicked ~= nil then + self:onClicked() + end + + return clicked +end + +function Label:draw() + local usedScissor = false + + if self._visibilityBounds ~= nil then + local rect = Rect:new( RL_GetCollisionRec( self.bounds, self._visibilityBounds ) ) + + -- Use scissor mode only on partyally visible. + if rect.width == 0 and rect.height == 0 then + return + elseif math.floor( rect.width ) ~= math.floor( self.bounds.width ) + or math.floor( rect.height ) ~= math.floor( self.bounds.height ) then + usedScissor = true + RL_BeginScissorMode( self._visibilityBounds ) + end + end + + RL_DrawText( self.font, self.text, { self.bounds.x + self._textRect.x, self.bounds.y + self._textRect.y }, self.fontSize, self.textSpacing, self.color ) + + if self.drawBounds then + RL_DrawRectangleLines( self.bounds, self.color ) + end + + if usedScissor then + RL_EndScissorMode() + end + +end + +function Label:delete() + table.remove( Gui._elements, self._ID ) +end + +function Label:set2Top() + util.tableMove( Gui._elements, self._ID, 1, #Gui._elements ) +end + +function Label:set2Back() + util.tableMove( Gui._elements, self._ID, 1, 1 ) +end + +-- Panel. + +Panel = {} +Panel.__index = Panel + +function Panel:new( set ) + local o = { + _ID = #Gui._elements + 1, + bounds = set ~= nil and set.bounds ~= nil and set.bounds or Rect:new( 0, 0, 0, 0 ), + color = set ~= nil and set.color ~= nil and set.color or LIGHTGRAY, + + visible = set ~= nil and set.visible ~= nil and set.visible or true, + disabled = set ~= nil and set.disabled ~= nil and set.disabled or false, + } + setmetatable( o, self ) + table.insert( Gui._elements, o ) + + return o +end + +function Panel:setPosition( pos ) + self.bounds.x = pos.x + self.bounds.y = pos.y +end + +function Panel:isMouseOver( mousePosition ) + return RL_CheckCollisionPointRec( mousePosition, self.bounds ) +end + +function Panel:draw() + RL_DrawRectangle( self.bounds, self.color ) +end + +function Panel:delete() + table.remove( Gui._elements, self._ID ) +end + +function Panel:set2Top() + util.tableMove( Gui._elements, self._ID, 1, #Gui._elements ) +end + +function Panel:set2Back() + util.tableMove( Gui._elements, self._ID, 1, 1 ) +end + +-- Container. + +Container = {} +Container.__index = Container + +function Container:new( set ) + local o = { + _ID = #Gui._elements + 1, + bounds = set ~= nil and set.bounds ~= nil and set.bounds or Rect:new( 0, 0, 0, 0 ), + color = set ~= nil and set.color ~= nil and set.color or LIGHTGRAY, + spacing = set ~= nil and set.spacing ~= nil and set.spacing or Gui.spacing, + type = set ~= nil and set.type ~= nil and set.type or Gui.CONTAINER.VERTICAL, + HAling = set ~= nil and set.HAling ~= nil and set.HAling or Gui.ALING.LEFT, + VAling = set ~= nil and set.VAling ~= nil and set.VAling or Gui.ALING.TOP, + + visible = set ~= nil and set.visible ~= nil and set.visible or true, + disabled = set ~= nil and set.disabled ~= nil and set.disabled or false, + drawBounds = set ~= nil and set.drawBounds ~= nil and set.drawBounds or false, + scrollable = set ~= nil and set.scrollable ~= nil and set.scrollable or false, + + cells = {}, + + _visibilityBounds = nil, -- Will give this to it's children. + _scrollRect = Rect:new( 0, 0, 0, 0 ), + } + setmetatable( o, self ) + table.insert( Gui._elements, o ) + return o +end + +function Container:setPosition( pos ) + self.bounds.x = pos.x + self.bounds.y = pos.y +end + +function Container:isMouseOver( mousePosition ) + return RL_CheckCollisionPointRec( mousePosition, self.bounds ) +end + +function Container:add( cell ) + table.insert( self.cells, cell ) + + self:update() + + if cell.update ~= nil then + cell:update() + end +end + +function Container:scroll( pos ) + if not self.scrollable then + return + end + + self._scrollRect.x = util.clamp( pos.x, 0, self._scrollRect.width - self.bounds.width ) + self._scrollRect.y = util.clamp( pos.y, 0, self._scrollRect.height - self.bounds.height ) + -- self._scrollRect.x = pos.x + -- self._scrollRect.y = pos.y + + self:update() +end + +function Container:update() + local pos = Vec2:new( self.bounds.x + self.spacing, self.bounds.y + self.spacing ) + + if self.scrollable then + self._visibilityBounds = self.bounds + self._scrollRect.width = 0 + self._scrollRect.height = 0 + end + + for i, cell in ipairs( self.cells ) do + if self._visibilityBounds ~= nil then + cell._visibilityBounds = self._visibilityBounds + end + + if self.type == Gui.CONTAINER.VERTICAL then + if self.HAling == Gui.ALING.CENTER then + pos.x = self.bounds.x + self.bounds.width / 2 - cell.bounds.width / 2 + elseif self.HAling == Gui.ALING.RIGHT then + pos.x = self.bounds.x + self.bounds.width - cell.bounds.width - self.spacing + end + + cell.bounds.x = pos.x - self._scrollRect.x + cell.bounds.y = pos.y - self._scrollRect.y + + self._scrollRect.width = math.max( self._scrollRect.width, pos.x + cell.bounds.width + self.spacing - self.bounds.x ) + self._scrollRect.height = math.max( self._scrollRect.height, pos.y + cell.bounds.height + self.spacing - self.bounds.y ) + + pos.y = pos.y + cell.bounds.height + self.spacing + elseif self.type == Gui.CONTAINER.HORIZONTAL then + if self.VAling == Gui.ALING.CENTER then + pos.y = self.bounds.y + self.bounds.height / 2 - cell.bounds.height / 2 + elseif self.VAling == Gui.ALING.BOTTOM then + pos.y = self.bounds.y + self.bounds.height - cell.bounds.height - self.spacing + end + + cell.bounds.x = pos.x - self._scrollRect.x + cell.bounds.y = pos.y - self._scrollRect.y + + self._scrollRect.width = math.max( self._scrollRect.width, pos.x + cell.bounds.width + self.spacing - self.bounds.x ) + self._scrollRect.height = math.max( self._scrollRect.height, pos.y + cell.bounds.height + self.spacing - self.bounds.y ) + + pos.x = pos.x + cell.bounds.width + self.spacing + end + + if cell.update ~= nil then + cell:update() + end + end +end + +function Container:draw() + if self.drawBounds then + RL_DrawRectangleLines( self.bounds, self.color ) + RL_DrawRectangleLines( { + self.bounds.x - self._scrollRect.x, + self.bounds.y - self._scrollRect.y, + self._scrollRect.width, + self._scrollRect.height, + }, RED ) + end +end + +function Container:delete() + table.remove( Gui._elements, self._ID ) +end + +--Assingments. + +Gui.label = Label +Gui.panel = Panel +Gui.container = Container + +return Gui |
