You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
6.9 KiB
Lua
265 lines
6.9 KiB
Lua
--- Options screen example
|
|
--
|
|
-- A fairly complete configuration menu to demonstrate
|
|
-- several types of widgets coexisting.
|
|
-- Many widgets' behavior is tuned by their attributes.
|
|
--
|
|
-- Relevant code to build UI inside: makeOptionsMenu().
|
|
--
|
|
-- Layout: Rows, Columns
|
|
-- Widget: Button, Checkbox, Choice, Input, Label, Slider, Spacer
|
|
|
|
local yui = require 'lib.yui'
|
|
|
|
local Button = yui.Button
|
|
local Checkbox = yui.Checkbox
|
|
local Choice = yui.Choice
|
|
local Columns = yui.Columns
|
|
local Input = yui.Input
|
|
local Label = yui.Label
|
|
local Rows = yui.Rows
|
|
local Slider = yui.Slider
|
|
local Spacer = yui.Spacer
|
|
local Ui = yui.Ui
|
|
|
|
local GUI_WIDTH = 500
|
|
local GUI_HEIGHT = 300
|
|
local FONT_SIZE = 32
|
|
|
|
-- A dummy save file, for demo purposes.
|
|
local dummySave = {}
|
|
|
|
-- Dummy config load mock.
|
|
function dummySave.load()
|
|
local config = {}
|
|
|
|
-- The default configuration
|
|
local defconfig = {
|
|
name = "Player 1",
|
|
graphics = 'medium',
|
|
lang = 'en',
|
|
fullscreen = false,
|
|
musicVolume = 80,
|
|
sfxVolume = 90
|
|
}
|
|
|
|
local saved = dummySave.latest or defconfig
|
|
|
|
print("Loading configuration: {")
|
|
for k,v in pairs(saved) do
|
|
config[k] = v
|
|
|
|
print(("\t%s = %s,"):format(k, v))
|
|
end
|
|
print("}")
|
|
|
|
return config
|
|
end
|
|
-- Dummy config save mock
|
|
function dummySave.save(config)
|
|
dummySave.latest = {}
|
|
|
|
print("Saving configuration: {")
|
|
for k,v in pairs(config) do
|
|
dummySave.latest[k] = v
|
|
|
|
print(("\t%s = %s,"):format(k, v))
|
|
end
|
|
print("}")
|
|
end
|
|
|
|
-- Center rectangle on screen.
|
|
local function centerRectOnScreen(w, h)
|
|
local x = math.floor((love.graphics.getWidth() - w) / 2)
|
|
local y = math.floor((love.graphics.getHeight() - h) / 2)
|
|
|
|
return x, y
|
|
end
|
|
|
|
-- Actual menu creation.
|
|
local function makeOptionsMenu()
|
|
-- Position the UI
|
|
local x,y = centerRectOnScreen(GUI_WIDTH, GUI_HEIGHT)
|
|
local vpad = 8
|
|
local hpad = 4
|
|
|
|
local w = (GUI_WIDTH - hpad) / 2 -- cut away padding from widget width
|
|
local h = (GUI_HEIGHT - vpad) / 9 -- 9 rows (Spacer counts as 2)
|
|
|
|
-- Load configuration "from disk"
|
|
local config = dummySave.load()
|
|
|
|
-- Make configuration editable via UI
|
|
return Ui.new {
|
|
x = x, y = y,
|
|
|
|
Rows {
|
|
padding = vpad,
|
|
|
|
Columns {
|
|
padding = hpad,
|
|
|
|
Label {
|
|
w = w, h = h,
|
|
text = "Name"
|
|
},
|
|
Input {
|
|
text = config.name, -- populate initial value
|
|
|
|
onChange = function(_, text)
|
|
config.name = text -- write changed value back
|
|
end
|
|
}
|
|
},
|
|
Columns {
|
|
padding = hpad,
|
|
|
|
Label {
|
|
w = w, h = h,
|
|
text = "Language"
|
|
},
|
|
Choice {
|
|
-- We don't want languages to be translated.
|
|
notranslate = true,
|
|
|
|
choices = {
|
|
{ text = "English", value = 'en' }, -- just kidding, only English in demo :)
|
|
-- { text = "Français", value = 'fr' },
|
|
-- { text = "Italiano", value = 'it' },
|
|
-- { text = "日本語", value = 'ja' }
|
|
},
|
|
default = config.lang,
|
|
nowrap = true,
|
|
|
|
onChange = function(_, choice) config.lang = choice.value end
|
|
}
|
|
},
|
|
Columns {
|
|
padding = hpad,
|
|
|
|
Label {
|
|
w = w, h = h,
|
|
text = "Graphics"
|
|
},
|
|
Choice {
|
|
choices = {
|
|
-- Text may be localized,
|
|
-- so map entries to well known enum values.
|
|
{ text = "Fastest", value = 'low' },
|
|
{ text = "Normal", value = 'medium' },
|
|
{ text = "Best", value = 'high' }
|
|
},
|
|
default = config.graphics,
|
|
nowrap = true,
|
|
|
|
onChange = function(_, choice) config.graphics = choice.value end
|
|
}
|
|
},
|
|
Columns {
|
|
padding = hpad,
|
|
|
|
Label {
|
|
w = w, h = h,
|
|
text = "Fullscreen"
|
|
},
|
|
Checkbox {
|
|
checked = config.fullscreen,
|
|
|
|
onChange = function(_, checked) config.fullscreen = checked end
|
|
}
|
|
},
|
|
Columns {
|
|
padding = hpad,
|
|
|
|
Label {
|
|
w = w, h = h,
|
|
text = "Music"
|
|
},
|
|
Slider {
|
|
min = 0, max = 100,
|
|
value = config.musicVolume,
|
|
|
|
onChange = function(_, value) config.musicVolume = value end
|
|
}
|
|
},
|
|
Columns {
|
|
padding = hpad,
|
|
|
|
Label {
|
|
w = w, h = h,
|
|
text = "Effects"
|
|
},
|
|
Slider {
|
|
min = 0, max = 100,
|
|
value = config.sfxVolume,
|
|
|
|
onChange = function(_, value) config.sfxVolume = value end
|
|
}
|
|
},
|
|
|
|
Spacer { h = 2*h }, -- leave 2 rows out.
|
|
|
|
Columns {
|
|
padding = hpad,
|
|
|
|
Button {
|
|
w = w, h = h,
|
|
text = "Back",
|
|
|
|
cancelfocus = true, -- gets focused on ESC.
|
|
|
|
onHit = function() love.event.quit() end
|
|
},
|
|
Button {
|
|
text = "Apply",
|
|
|
|
onHit = function()
|
|
-- Save configuration "on disk"
|
|
dummySave.save(config)
|
|
end
|
|
}
|
|
}
|
|
}
|
|
}
|
|
end
|
|
|
|
function love.load()
|
|
guiFont = love.graphics.newFont('fonts/PixelDroidMenu.ttf', FONT_SIZE)
|
|
gui = makeOptionsMenu()
|
|
end
|
|
|
|
function love.update(dt)
|
|
-- Let the UI update its status
|
|
gui:update(dt)
|
|
end
|
|
|
|
-- Options menu contains a text input field,
|
|
-- this requires propagating LÖVE input events to UI.
|
|
function love.keypressed(key, scan, isrepeat)
|
|
gui:keypressed(key, scan, isrepeat)
|
|
end
|
|
function love.keyreleased(key, scan)
|
|
gui:keyreleased(key, scan)
|
|
end
|
|
function love.textinput(text)
|
|
gui:textinput(text)
|
|
end
|
|
function love.textedited(text, start, len)
|
|
gui:textedited(text, start, len)
|
|
end
|
|
|
|
function love.draw()
|
|
love.graphics.setFont(guiFont)
|
|
|
|
-- Draw menu title
|
|
local title = "Options"
|
|
local tw = guiFont:getWidth(title)
|
|
local th = guiFont:getHeight()
|
|
local tx = (love.graphics.getWidth() - tw) / 2
|
|
local ty = th*2
|
|
love.graphics.print(title, tx,ty)
|
|
|
|
-- Draw UI
|
|
gui:draw()
|
|
end
|