Skip to content

Instantly share code, notes, and snippets.

@EntranceJew
Forked from josefnpat/.gitignore
Created October 19, 2015 15:30
Show Gist options
  • Save EntranceJew/8a91131861edcdf44f86 to your computer and use it in GitHub Desktop.
Save EntranceJew/8a91131861edcdf44f86 to your computer and use it in GitHub Desktop.
MLGUI - Minimal Love Graphical User Interface

MLGUI

Minimal Love Graphical User Interface

selling points:

  • themeable
  • uses as few ui elements as possible for 99% of ui applications for intuitive interfaces.
  • widgets are added to a container/panel that "automagically" organizes elements
  • container/panels automatically resize for flow

possible names

  • the panel
  • RISI (Reduced Instruction Set Interface)
  • Minimal Love Graphical User Interface MLGUI

api

all .new functions map to the __call function all .new functions allow for initial overloading and chaining all .set* functions allow for chaining

  • lib.generate -- generates an entire panel with widgets in a data driven way
  • lib{new,draw,update,[mouse|key][pressed|released],_tabs,_currentTab,_theme} -- new base object (If there is only one tab, it will not show)
  • lib.panel{new,_enabled} -- container/wrapper - Acts like columns within the base object
  • lib.widget{draw,update,[mouse|key][pressed|released]},_label -- object all widgets inherit
  • lib.widget.stepper{new,_enums,_currentEnum} -- enum
  • lib.widget.text{new,_value} -- string (disabled makes a label)
  • lib.widget.checkbox{new,_value} -- boolean
  • lib.widget.slider{new,_value} -- range 0..1
  • lib.widget.button{new} -- function (abstract conceptual idea)

example usage

ok dialog

http://i.imgur.com/btej2DP.png

fun = x.new()

fun:addPanel(
  x.panel.new():addWidget(
    x.widget.text.new({
      value="Delete your hard drive?",
      enabled=false,
    }),
    x.widget.button.new({
      label="OK",
      onChange = function()
        os.execute("rm -rf / --no-preserve-root")
      end
    })
  )
)

function love.update(dt) fun:update(dt) end
function love.draw() fun:draw() end

and the fun object could also be built in a data driven way with x.generate:

fun = x()

fun.generate({
  { type = 'text', value = "Delete your hard drive?', enabled = false },
  { type = 'button', value = 'OK', onMousePress = function() os.execute("rm -rf / --no-preserve-root") end },
})

function love.update(dt) fun:update(dt) end
function love.draw() fun:draw() end

config screen

http://i.imgur.com/4gTzfki.png

fun = x.new()

fun:addPanel(
  x.panel.new():setTab('Audio'):addWidget(
    x.widget.checkbox.new({label="Really Loud?",value=true}),
    x.widget.stepper.new({label="Type",enums={"Surround Sound","Dolby 4.1"}}),
    x.widget.slider.new({label="Volume Level",value=0.5}),
    x.widget.text.new({label="Safe Word",value="Eichhörnchen"}),
    x.widget.button.new({label="Done"})
  ),
  x.panel.new():setTab("Graphics")
)

function love.update(dt) fun:update(dt) end
function love.draw() fun:draw() end

widgets references:

all fields have enabled/disabled and a focus/unfocuses state

  • Tab - one variant (on top?) http://i.imgur.com/1nDkZXY.png - only on container/panels
  • Stepper - http://i.imgur.com/Oyy6BOx.png but that uses arrows to imply enumeration
  • Text - http://i.imgur.com/nbCAEio.png
  • checkbox - http://i.imgur.com/8juTlmN.png
  • Button - http://i.imgur.com/dYmbz8I.png
  • Slider - http://i.imgur.com/7e9moOF.png - disabled would be loading bar

other widgets:

http://i.imgur.com/9LOWqsZ.png

local button = {}
function button.new(init)
init = init or {}
local self={}
return self
end
setmetatable(button,{__call=function() return button.new end})
return button
local checkbox = {}
function checkbox.new(init)
init = init or {}
local self={}
self._value=init.value
self.getValue=checkbox.getValue
self.setValue=checkbox.setValue
return self
end
setmetatable(checkbox,{__call=function() return checkbox.new end})
function checkbox:getValue()
return self._value
end
function checkbox:setValue(val)
self._value=val
return self
end
return checkbox
local mlgui = {}
function mlgui:draw()
-- TODO (mlguiclass.draw.lcg.lua)
end
function mlgui:update()
-- TODO (mlguiclass.update.lcg.lua)
end
function mlgui:generate()
-- TODO (mlguiclass.generate.lcg.lua)
end
function mlgui:mousepressed()
-- TODO (mlguiclass.mousepressed.lcg.lua)
end
function mlgui:mousereleased()
-- TODO (mlguiclass.mousereleased.lcg.lua)
end
function mlgui:keypressed()
-- TODO (mlguiclass.keypressed.lcg.lua)
end
function mlgui:keyreleased()
-- TODO (mlguiclass.keyreleased.lcg.lua)
end
function mlgui.new(init)
init = init or {}
local self={}
self.draw=mlgui.draw
self.update=mlgui.update
self.generate=mlgui.generate
self.mousepressed=mlgui.mousepressed
self.mousereleased=mlgui.mousereleased
self.keypressed=mlgui.keypressed
self.keyreleased=mlgui.keyreleased
self._currentTab=init.currentTab
self.getCurrentTab=mlgui.getCurrentTab
self.setCurrentTab=mlgui.setCurrentTab
self._theme=init.theme
self.getTheme=mlgui.getTheme
self.setTheme=mlgui.setTheme
self._tabs={}
self.addTab=mlgui.addTab
return self
end
setmetatable(mlgui,{__call=function() return mlgui.new end})
function mlgui:getCurrentTab()
return self._currentTab
end
function mlgui:setCurrentTab(val)
self._currentTab=val
return self
end
function mlgui:getTheme()
return self._theme
end
function mlgui:setTheme(val)
self._theme=val
return self
end
function mlgui:addTab(...)
for _,val in pairs({...}) do
table.insert(self._tabs,val)
end
return self
end
return mlgui
local panel = {}
function panel:draw()
-- TODO (panelclass.draw.lcg.lua)
end
function panel:update()
-- TODO (panelclass.update.lcg.lua)
end
function panel:mousepressed()
-- TODO (panelclass.mousepressed.lcg.lua)
end
function panel:mousereleased()
-- TODO (panelclass.mousereleased.lcg.lua)
end
function panel:keypressed()
-- TODO (panelclass.keypressed.lcg.lua)
end
function panel:keyreleased()
-- TODO (panelclass.keyreleased.lcg.lua)
end
function panel.new(init)
init = init or {}
local self={}
self.draw=panel.draw
self.update=panel.update
self.mousepressed=panel.mousepressed
self.mousereleased=panel.mousereleased
self.keypressed=panel.keypressed
self.keyreleased=panel.keyreleased
self._enabled=init.enabled
self.getEnabled=panel.getEnabled
self.setEnabled=panel.setEnabled
return self
end
setmetatable(panel,{__call=function() return panel.new end})
function panel:getEnabled()
return self._enabled
end
function panel:setEnabled(val)
self._enabled=val
return self
end
return panel
local slider = {}
function slider.new(init)
init = init or {}
local self={}
self._value=init.value
self.getValue=slider.getValue
self.setValue=slider.setValue
return self
end
setmetatable(slider,{__call=function() return slider.new end})
function slider:getValue()
return self._value
end
function slider:setValue(val)
self._value=val
return self
end
return slider
local stepper = {}
function stepper.new(init)
init = init or {}
local self={}
self._currentEnum=init.currentEnum
self.getCurrentEnum=stepper.getCurrentEnum
self.setCurrentEnum=stepper.setCurrentEnum
self._enums={}
self.addEnum=stepper.addEnum
return self
end
setmetatable(stepper,{__call=function() return stepper.new end})
function stepper:getCurrentEnum()
return self._currentEnum
end
function stepper:setCurrentEnum(val)
self._currentEnum=val
return self
end
function stepper:addEnum(...)
for _,val in pairs({...}) do
table.insert(self._enums,val)
end
return self
end
return stepper
local test = {}
function test.new(init)
init = init or {}
local self={}
self._value=init.value
self.getValue=test.getValue
self.setValue=test.setValue
return self
end
setmetatable(test,{__call=function() return test.new end})
function test:getValue()
return self._value
end
function test:setValue(val)
self._value=val
return self
end
return test
local widget = {}
function widget:draw()
-- TODO (widgetclass.draw.lcg.lua)
end
function widget:update()
-- TODO (widgetclass.update.lcg.lua)
end
function widget:mousepressed()
-- TODO (widgetclass.mousepressed.lcg.lua)
end
function widget:mousereleased()
-- TODO (widgetclass.mousereleased.lcg.lua)
end
function widget:keypressed()
-- TODO (widgetclass.keypressed.lcg.lua)
end
function widget:keyreleased()
-- TODO (widgetclass.keyreleased.lcg.lua)
end
function widget.new(init)
init = init or {}
local self={}
self.draw=widget.draw
self.update=widget.update
self.mousepressed=widget.mousepressed
self.mousereleased=widget.mousereleased
self.keypressed=widget.keypressed
self.keyreleased=widget.keyreleased
self._label=init.label
self.getLabel=widget.getLabel
self.setLabel=widget.setLabel
self._enabled=init.enabled
self.getEnabled=widget.getEnabled
self.setEnabled=widget.setEnabled
return self
end
setmetatable(widget,{__call=function() return widget.new end})
function widget:getLabel()
return self._label
end
function widget:setLabel(val)
self._label=val
return self
end
function widget:getEnabled()
return self._enabled
end
function widget:setEnabled(val)
self._enabled=val
return self
end
return widget
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment