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

--- 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