working on in app editor

This commit is contained in:
2026-10-11 09:16:08 -07:00
parent 73b760e658
commit 39098cc206
10 changed files with 436 additions and 56 deletions
+1 -1
Submodule gui updated: 1a6ba8e09b...76abe31426
+368 -5
View File
@@ -71,11 +71,11 @@ end)
local loadLog = log:child("load") local loadLog = log:child("load")
local old = multi.error local old = multi.error
multi.error = function(self, err) -- multi.error = function(self, err)
loadLog:error("Error: %s", err) -- loadLog:error("Error: %s", err)
loadLog:error(debug.traceback()) -- loadLog:error(debug.traceback())
love.quit() -- love.quit()
end -- end
function readFileData(path) function readFileData(path)
return io.open(path,"r"):read("*a") return io.open(path,"r"):read("*a")
@@ -90,8 +90,358 @@ local picker = THREAD:newFunction(function()
return nil, "No file selected." .. (err and (" (" .. err .. ")") or "") return nil, "No file selected." .. (err and (" (" .. err .. ")") or "")
end end
end, true) end, true)
local nof = gui.noOf
function gui:newNumberPicker(x, y, w, h, sx, sy, sw, sh, opts)
opts = opts or {}
opts.value = opts.value or 0
opts.inc = opts.inc or 1
opts.decimals = opts.decimals or 0 -- 0 = integers only
-- opts.min / opts.max / opts.onChange are optional, leave nil for "no limit"
local picker = self:newFrame(x, y, w, h, sx, sy, sw, sh)
picker:setRoundness(6, 6)
picker.active = false
local leftF = picker:newFrame(0, 0, 0, 0, 0, 0, .15, 1)
local left = leftF:newTextButton("-", 0, 0, 0, 0, 0, 0, 1, 1)
local rightF = picker:newFrame(0, 0, 0, 0, .85, 0, .15, 1)
local right = rightF:newTextButton("+", 0, 0, 0, 0, 0, 0, 1, 1)
local textbox = picker:newTextBox("", 0, 0, 0, 0, .15, 0, .7, 1)
textbox.blink = false
gui.apply({
scaleFont = {.45},
centerFont = {},
run = {function(self)
if self.text == "-" or self.text == "+" then
self:centerX(true)
self:centerY(true) -- also center vertically, not just horizontally
end
end},
align = gui.ALIGN_CENTER,
}, textbox, left, right)
gui.apply({
visibility = 0,
drawBorder = false, -- flat, no boxy outline around the arrows
}, left, right, leftF, rightF)
-- ---- value handling ----------------------------------------------
local function clamp(n)
if opts.min and n < opts.min then n = opts.min end
if opts.max and n > opts.max then n = opts.max end
return n
end
local function round(n)
if opts.decimals > 0 then
local mult = 10 ^ opts.decimals
return math.floor(n * mult + 0.5) / mult
end
return math.floor(n + 0.5)
end
local function format(n)
if opts.decimals > 0 then
return string.format("%." .. opts.decimals .. "f", n)
end
return tostring(math.floor(n))
end
local function updateButtons()
local canDec = (opts.min == nil) or (opts.value > opts.min)
local canInc = (opts.max == nil) or (opts.value < opts.max)
left.active, right.active = canDec, canInc
left.textColor = canDec and {0, 0, 0, 1} or {.6, .6, .6, 1}
right.textColor = canInc and {0, 0, 0, 1} or {.6, .6, .6, 1}
end
function picker:setValue(n, silent)
n = round(clamp(n))
opts.value = n
textbox.text = format(n)
textbox.cur_pos = #textbox.text
updateButtons()
if not silent and opts.onChange then opts.onChange(n) end
end
function picker:getValue()
return opts.value
end
picker:setValue(opts.value, true)
left:OnReleased(function() picker:setValue(opts.value - opts.inc) end)
right:OnReleased(function() picker:setValue(opts.value + opts.inc) end)
textbox:OnWheelMoved(function(_,dx, dy)
if dy > 0 then picker:setValue(opts.value + opts.inc)
elseif dy < 0 then picker:setValue(opts.value - opts.inc) end
end)
-- ---- restrict typing to numbers only -------------------------------
local allowNegative = opts.min == nil or opts.min < 0
local allowDecimal = opts.decimals > 0
local function sanitize(s)
local out, seenDot = {}, false
for i = 1, #s do
local ch = s:sub(i, i)
if ch:match("%d") then
out[#out + 1] = ch
elseif ch == "-" and i == 1 and allowNegative then
out[#out + 1] = ch
elseif ch == "." and allowDecimal and not seenDot then
out[#out + 1] = ch
seenDot = true
end
end
return table.concat(out)
end
local tiRef = gui.Events.OnTextInputed(function(input)
if gui:getObjectFocus() ~= textbox then return end
local clean = sanitize(textbox.text)
if clean ~= textbox.text then
textbox.text = clean
textbox.cur_pos = math.min(textbox.cur_pos, #clean)
end
end)
local kpRef = gui.Events.OnKeyPressed(function(key)
if gui:getObjectFocus() ~= textbox then return end
if key == "up" then picker:setValue(opts.value + opts.inc)
elseif key == "down" then picker:setValue(opts.value - opts.inc) end
end)
-- re-normalize (round/clamp/reformat) whatever was typed once they
-- hit enter or click away, so "3." or "-" don't linger as invalid text
local function commit()
picker:setValue(tonumber(textbox.text) or opts.value)
end
textbox:OnReturn(commit)
textbox:OnPressedOuter(commit)
textbox:OnDestroy(function()
gui.Events.OnTextInputed:Unconnect(tiRef)
gui.Events.OnKeyPressed:Unconnect(kpRef)
end)
return picker
end
-- ---- HSV <-> RGB helpers ----
local function hsvToRgb(h, s, v)
local c = v * s
local x = c * (1 - math.abs((h / 60) % 2 - 1))
local m = v - c
local r, g, b
if h < 60 then r, g, b = c, x, 0
elseif h < 120 then r, g, b = x, c, 0
elseif h < 180 then r, g, b = 0, c, x
elseif h < 240 then r, g, b = 0, x, c
elseif h < 300 then r, g, b = x, 0, c
else r, g, b = c, 0, x end
return r + m, g + m, b + m
end
local function rgbToHsv(r, g, b)
local max, min = math.max(r, g, b), math.min(r, g, b)
local d = max - min
local h = 0
if d ~= 0 then
if max == r then h = ((g - b) / d) % 6
elseif max == g then h = (b - r) / d + 2
else h = (r - g) / d + 4 end
h = h * 60
end
local s = (max == 0) and 0 or (d / max)
return h, s, max
end
local function clampNum(n, lo, hi) return math.max(lo, math.min(hi, n)) end
local function newCornerGradient(tl, tr, br, bl)
return love.graphics.newMesh({
{0, 0, 0, 0, tl[1], tl[2], tl[3], tl[4]},
{1, 0, 0, 0, tr[1], tr[2], tr[3], tr[4]},
{1, 1, 0, 0, br[1], br[2], br[3], br[4]},
{0, 1, 0, 0, bl[1], bl[2], bl[3], bl[4]},
}, "fan")
end
local _whiteFade, _blackFade
local function getFadeImages()
if not _whiteFade then
-- opaque white on the left fading to transparent on the right
_whiteFade = newCornerGradient(
{1,1,1,1}, {1,1,1,0}, {1,1,1,0}, {1,1,1,1}
)
-- transparent at top fading to opaque black at bottom
_blackFade = newCornerGradient(
{0,0,0,0}, {0,0,0,0}, {0,0,0,1}, {0,0,0,1}
)
end
return _whiteFade, _blackFade
end
function gui:newColorPicker(x, y, w, h, sx, sy, sw, sh, opts)
opts = opts or {}
local r0 = (opts.r or 255) / 255
local g0 = (opts.g or 0) / 255
local b0 = (opts.b or 0) / 255
local picker = self:newFrame(x, y, w, h, sx, sy, sw, sh)
picker.active = false -- container only; don't compete for focus with its children
picker.drawBorder = false
picker.visibility = 0
local hue, sat, val = rgbToHsv(r0, g0, b0)
local hueR, hueG, hueB = hsvToRgb(hue, 1, 1)
-- ---- Saturation/Value square ----
local svFrame = picker:newFrame(6, 6, -12, -12, 0, 0, .55, 1)
svFrame.drawBorder = false
svFrame.visibility = 0
local whiteFade, blackFade = getFadeImages()
svFrame.post = function(self)
local sx2, sy2, sw2, sh2 = self:getAbsolutes()
love.graphics.setColor(hueR, hueG, hueB, 1)
love.graphics.rectangle("fill", sx2, sy2, sw2, sh2)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(whiteFade, sx2, sy2, 0, sw2, sh2)
love.graphics.setColor(1, 1, 1, .95)
love.graphics.draw(blackFade, sx2, sy2, 0, sw2, sh2)
love.graphics.setColor(0, 0, 0, .4)
love.graphics.rectangle("line", sx2, sy2, sw2, sh2)
love.graphics.setColor(1, 1, 1, 1)
end
local svThumb = svFrame:newFrame(0, 0, 0, 0)
svThumb:makeCircle(0, 0, 6)
svThumb.color = {1, 1, 1}
svThumb.borderColor = {0, 0, 0}
svThumb.drawBorder = true
-- ---- Hue strip ----
local hueSlider = picker:newFrame(0, 6, 0, -12, .57, 0, .10, 1)
-- applyGradient's "horizontal"/"vertical" naming is backwards from what
-- you'd expect visually (it names how colors are laid out in the source
-- image, not the on-screen direction) -- if this renders sideways for
-- you, just flip the string to "vertical".
hueSlider:applyGradient("horizontal",
{1, 0, 0, 1}, {1, 1, 0, 1}, {0, 1, 0, 1},
{0, 1, 1, 1}, {0, 0, 1, 1}, {1, 0, 1, 1}, {1, 0, 0, 1})
hueSlider.drawBorder = false
local hueThumb = hueSlider:newFrame(0, 0, 0, 4, 0, 0, 1, 0)
hueThumb.color = {1, 1, 1}
hueThumb.borderColor = {0, 0, 0}
hueThumb.drawBorder = true
-- ---- Preview + numeric fields ----
local preview = picker:newFrame(6, 6, -12, -6, .70, 0, .30, .20)
preview:setRoundness(4, 4)
local rPicker, gPicker, bPicker
local function refresh(fireChange)
local r, g, b = hsvToRgb(hue, sat, val)
hueR, hueG, hueB = hsvToRgb(hue, 1, 1)
preview.color = {r, g, b}
local _, _, sw2, sh2 = svFrame:getAbsolutes()
svThumb:rawSetDualDim(sat * sw2 - 12, (1 - val) * sh2 - 6)
local _, _, _, hh2 = hueSlider:getAbsolutes()
hueThumb:rawSetDualDim(nil, (hue / 360) * hh2 - 2)
local r255 = math.floor(r * 255 + .5)
local g255 = math.floor(g * 255 + .5)
local b255 = math.floor(b * 255 + .5)
if rPicker then
rPicker:setValue(r255, true)
gPicker:setValue(g255, true)
bPicker:setValue(b255, true)
end
if fireChange ~= false and opts.onChange then
opts.onChange(r255, g255, b255)
end
end
local function onRGBEdited()
local r = rPicker:getValue() / 255
local g = gPicker:getValue() / 255
local b = bPicker:getValue() / 255
hue, sat, val = rgbToHsv(r, g, b)
refresh(true)
end
rPicker = picker:newNumberPicker(6, 0, -12, -6, .70, .26, .30, .20,
{value = math.floor(r0 * 255 + .5), min = 0, max = 255, onChange = onRGBEdited})
gPicker = picker:newNumberPicker(6, 0, -12, -6, .70, .52, .30, .20,
{value = math.floor(g0 * 255 + .5), min = 0, max = 255, onChange = onRGBEdited})
bPicker = picker:newNumberPicker(6, 0, -12, -6, .70, .78, .30, .20,
{value = math.floor(b0 * 255 + .5), min = 0, max = 255, onChange = onRGBEdited})
gui.apply({
scaleFont={.1}
},rPicker,gPicker,bPicker)
-- ---- drag interaction (same press/move/release pattern the built-in
-- textbox uses for its own text-selection dragging) ----
local function setSV(mx, my)
local sx2, sy2, sw2, sh2 = svFrame:getAbsolutes()
local lx = clampNum(mx - sx2, 0, sw2)
local ly = clampNum(my - sy2, 0, sh2)
sat = sw2 > 0 and (lx / sw2) or 0
val = sh2 > 0 and (1 - ly / sh2) or 0
refresh(true)
end
local svDragging = false
svFrame:OnPressed(function(_, mx, my) svDragging = true; setSV(mx, my) end)
svFrame:OnMoved(function(_, mx, my) if svDragging then setSV(mx, my) end end)
svFrame:OnReleased(function() svDragging = false end)
svFrame:OnReleasedOuter(function() svDragging = false end)
local function setHue(mx, my)
local _, sy2, _, sh2 = hueSlider:getAbsolutes()
local ly = clampNum(my - sy2, 0, sh2)
hue = sh2 > 0 and (ly / sh2) * 360 or 0
refresh(true)
end
local hueDragging = false
hueSlider:OnPressed(function(_, mx, my) hueDragging = true; setHue(mx, my) end)
hueSlider:OnMoved(function(_, mx, my) if hueDragging then setHue(mx, my) end end)
hueSlider:OnReleased(function() hueDragging = false end)
hueSlider:OnReleasedOuter(function() hueDragging = false end)
-- ---- public API ----
function picker:getColor()
local r, g, b = hsvToRgb(hue, sat, val)
return math.floor(r * 255 + .5), math.floor(g * 255 + .5), math.floor(b * 255 + .5)
end
function picker:setColor(r255, g255, b255)
hue, sat, val = rgbToHsv(r255 / 255, g255 / 255, b255 / 255)
refresh(false)
end
refresh(false)
return picker
end
function love.load() function love.load()
love.keyboard.setKeyRepeat(true)
-- local z = zip.new() -- local z = zip.new()
-- z:add("main.lua",readFileData("main.lua")) -- z:add("main.lua",readFileData("main.lua"))
-- z:add("package.bat",readFileData("package.bat")) -- z:add("package.bat",readFileData("package.bat"))
@@ -105,6 +455,18 @@ function love.load()
-- print("File selected",file) -- print("File selected",file)
-- end).OnError(print) -- end).OnError(print)
-- local numpicker = gui:newNumberPicker(0, 0, 200, 40, .5, .5, 0, 0, {
-- value = 1, inc = 1, min = 1, max = 4,
-- onChange = function(v) print("value is now", v) end,
-- })
local frame = gui:newFrame(0, 0, 500, 250, .5, .5, 0, 0)
local colorpicker = frame:newColorPicker(0, 0, 0, 0, 0, 0, 1, 1, {
r = 255, g = 100, b = 50,
onChange = function(r, g, b) print("color:", r, g, b) end,
})
--[[ -- bootstrap
loadLog:info("Starting Jeopardy Game") loadLog:info("Starting Jeopardy Game")
loadLog:debug("Setting game identity to jeopardy") loadLog:debug("Setting game identity to jeopardy")
for i,v in ipairs(color.listColors(showAllColors)) do for i,v in ipairs(color.listColors(showAllColors)) do
@@ -129,6 +491,7 @@ function love.load()
menu.init(bg) menu.init(bg)
loadLog:debug("Displaying title menu") loadLog:debug("Displaying title menu")
title:visible(true) title:visible(true)
]]
end end
function love.update(dt) function love.update(dt)
+44 -15
View File
@@ -9,6 +9,14 @@ local menu = require("gui.core.menus")
local transition = require("gui.core.transitions") local transition = require("gui.core.transitions")
local logger = require("utils/logger") local logger = require("utils/logger")
-- Constants
local IMAGE = "image"
local AUDIO = "audio"
local VIDEO = "video"
local TEXT = "text"
local LIST = "list"
local NUMBER = "number"
local timesup = love.audio.newSource("assets/sounds/timesup.mp3", "static") local timesup = love.audio.newSource("assets/sounds/timesup.mp3", "static")
local double = love.audio.newSource("assets/sounds/double.mp3", "static") local double = love.audio.newSource("assets/sounds/double.mp3", "static")
@@ -174,12 +182,12 @@ function LoadTemplate(name, path)
ALIGN_LEFT = gui.ALIGN_LEFT, ALIGN_LEFT = gui.ALIGN_LEFT,
ALIGN_RIGHT = gui.ALIGN_RIGHT, ALIGN_RIGHT = gui.ALIGN_RIGHT,
ALIGN_JUSTIFY = gui.ALIGN_JUSTIFY, ALIGN_JUSTIFY = gui.ALIGN_JUSTIFY,
IMAGE = "image", IMAGE = IMAGE,
AUDIO = "audio", AUDIO = AUDIO,
VIDEO = "video", VIDEO = VIDEO,
TEXT = "text", TEXT = TEXT,
LIST = "list", LIST = LIST,
NUMBER = "number", NUMBER = NUMBER,
-- Global vars -- Global vars
color = color, color = color,
error = multi.error, error = multi.error,
@@ -265,13 +273,11 @@ function Menu(frame, path, deb)
local scoreboard = ScoreBoard(frameRef, 0, 0, 0, 0, .06, .1, .170, .8) local scoreboard = ScoreBoard(frameRef, 0, 0, 0, 0, .06, .1, .170, .8)
local properties = Properties(frameRef, 0, 0, 0, 0, .06, .1, .170, .8) local properties = Properties(frameRef, 0, 0, 0, 0, .06, .1, .170, .8)
gui:setHotKey({"lctrl","q"})(function() local function showProperties(b)
scoreboard.leaderboard.visible = not scoreboard.leaderboard.visible properties.visible = b
end) scoreboard.leaderboard.visible = not b
gui:setHotKey({"lctrl","e"})(function() end
properties.visible = not properties.visible showProperties(true)
end)
local qframe = frameRef:newFrame(0, 0, 0, 0, .24, .1, .70, .8) local qframe = frameRef:newFrame(0, 0, 0, 0, .24, .1, .70, .8)
qframe.visibility = 0 qframe.visibility = 0
@@ -542,6 +548,7 @@ function Menu(frame, path, deb)
end end
self.textVisibility = 0 self.textVisibility = 0
local template = LoadTemplate(q.template, path) local template = LoadTemplate(q.template, path)
if not template then boardLog:fatal("template returned nil. Likely an invalid template format. Did you return?") end
question.visible = true question.visible = true
board.visible = false board.visible = false
-- question.visibility = visibility -- question.visibility = visibility
@@ -569,7 +576,7 @@ function Menu(frame, path, deb)
end) end)
end end
local finished = false local finished = false
template.index(question, q, function(ans, m) local params = template.index(question, q, function(ans, m)
local m = m or 1 local m = m or 1
if finished then return end if finished then return end
player = GetActivePlayer() player = GetActivePlayer()
@@ -595,6 +602,7 @@ function Menu(frame, path, deb)
self.text = "" self.text = ""
end) end)
boardUpdater:newThread("QuestionUpdater",function() boardUpdater:newThread("QuestionUpdater",function()
if not template.update then return end
while true do while true do
template.update(dt) template.update(dt)
thread.sleep(.1) thread.sleep(.1)
@@ -640,6 +648,9 @@ function love.filedropped(file)
local data = file:read() local data = file:read()
print("Load file? " .. file:getFilename()) print("Load file? " .. file:getFilename())
end end
----------------
--- Sideboard
---
local C_BG_PANEL = color.scoreboard_panel_bg local C_BG_PANEL = color.scoreboard_panel_bg
local C_BG_HEADER = color.scoreboard_header_bg local C_BG_HEADER = color.scoreboard_header_bg
@@ -662,10 +673,28 @@ local PLAYER_HEIGHT = .05
function Properties(frame, x, y, w, h, sx, sy, sw, sh) function Properties(frame, x, y, w, h, sx, sy, sw, sh)
local prop = frame:newFrame(x, y, w, h, sx, sy, sw, sh) local prop = frame:newFrame(x, y, w, h, sx, sy, sw, sh)
prop.color = C_BORDER_NRM prop.color = C_BORDER_NRM
local header = prop:newTextLabel("PROPERTIES",0,0,0,0,0,0,1,LEADER_HEIGHT_SCALE)
header.borderColor = C_ACCENT
header.textColor = C_ACCENT
header.color = C_BG_HEADER
header.align = gui.ALIGN_CENTER
header:scaleFont(.7)
header:centerFont()
function prop:RenderAttributes(tab)
if tab == nil then
tab = {}
end
if not tab.title then -- make the first option
boardLog:fatal("Templates must define a title attribute")
end
if not tab.answer then -- append to the end
table.insert(tab,{answer=TEXT,description="The answer for the question"})
end
end
return prop return prop
end end
-- :newTextLabel(index,0,0,0,0,.015,.1,1/8,.8)
function ScoreBoard(frame, x, y, w, h, sx, sy, sw, sh) function ScoreBoard(frame, x, y, w, h, sx, sy, sw, sh)
-- Config stuff -- Config stuff
+4 -3
View File
@@ -6,7 +6,7 @@ local plusLabel
local function index(window, q, callback) local function index(window, q, callback)
frame = window:newFrame(0,0,0,-200,0,.2,1,.8) frame = window:newFrame(0,0,0,-200,0,.2,1,.8)
frame.visibility = 0 frame.visibility = 0
label = window:newTextLabel(" " ..q.title.. " ",0,0,0,0,0,0,1,.2) label = window:newTextLabel(q.title,0,0,0,0,0,0,1,.2)
label.align = ALIGN_CENTER label.align = ALIGN_CENTER
label.textColor = color.question_font label.textColor = color.question_font
label.color = color.question_bg label.color = color.question_bg
@@ -46,8 +46,9 @@ local function index(window, q, callback)
useDefaultHandler(callback) useDefaultHandler(callback)
return { return {
{imageA=IMAGE, description="First image to display"}, {title=label},
{imageB=IMAGE, description="Second image to display"}, {imageA=imageHolder, description="First image to display"},
{imageB=imageHolder2, description="Second image to display"},
} }
end end
+4 -7
View File
@@ -87,15 +87,12 @@ local function index(window, q, callback)
-- Return the expected types -- Return the expected types
return { return {
{choices=LIST, description="List of options"} {title=label},
{choices=LIST, description="List of options"},
{answer=NUMBER, description="Answer to multiple choice as a number"}
} }
end end
local function update(dt) -- time in seconds that has passed since
end
return { return {
index = index, index = index
update = update
} }
+3 -2
View File
@@ -12,7 +12,7 @@ local imageHolder
local function index(window, q, callback) local function index(window, q, callback)
frame = window:newFrame(0,0,0,0,0,.2,1,.8) frame = window:newFrame(0,0,0,0,0,.2,1,.8)
frame.visibility = 0 frame.visibility = 0
label = window:newTextLabel(" " ..q.title.. " ",0,0,0,0,0,0,1,.2) label = window:newTextLabel(q.title,0,0,0,0,0,0,1,.2)
label.align = ALIGN_CENTER label.align = ALIGN_CENTER
label.textColor = color.question_font label.textColor = color.question_font
label.color = color.question_bg label.color = color.question_bg
@@ -32,7 +32,8 @@ local function index(window, q, callback)
-- Return the expected types -- Return the expected types
return { return {
{image=IMGAE, description="Image the question is about"} {title=label},
{image=imageHolder, description="Image the question is about"}
} }
end end
+3 -7
View File
@@ -6,10 +6,9 @@
callback true/false correct/wrong callback true/false correct/wrong
]] ]]
local label
local function index(window, q, callback) local function index(window, q, callback)
label = window:newTextLabel(q.title) local label = window:newTextLabel(q.title)
label.visibility = 0--q.cosmetics.visibility label.visibility = 0--q.cosmetics.visibility
label.align = ALIGN_CENTER label.align = ALIGN_CENTER
label:fullFrame() label:fullFrame()
@@ -20,13 +19,10 @@ local function index(window, q, callback)
label.drawBorder = false label.drawBorder = false
useDefaultHandler(callback) useDefaultHandler(callback)
end
local function update(dt) -- time in seconds that has passed since return {title=label}
end end
return { return {
index = index, index = index
update = update
} }
+1
View File
@@ -46,6 +46,7 @@ local function index(window, q, callback)
-- Return the expected types -- Return the expected types
return { return {
{title=label},
{sound=AUDIO, description="Sound that will be played"} {sound=AUDIO, description="Sound that will be played"}
} }
end end
+2 -1
View File
@@ -15,7 +15,7 @@ local function index(window, q, callback)
callback() callback()
return return
end end
frame = window:newFrame(0,0,0,-200,0,.2,1,.8) local frame = window:newFrame(0,0,0,-200,0,.2,1,.8)
frame.visibility = 0 frame.visibility = 0
label = window:newTextLabel(" " ..q.title.. " ",0,0,0,0,0,0,1,.2) label = window:newTextLabel(" " ..q.title.. " ",0,0,0,0,0,0,1,.2)
label.align = ALIGN_CENTER label.align = ALIGN_CENTER
@@ -39,6 +39,7 @@ local function index(window, q, callback)
-- Return the expected types -- Return the expected types
return { return {
{title=label},
{video=VIDEO, description="Video that will be played"} {video=VIDEO, description="Video that will be played"}
} }
end end
+6 -15
View File
@@ -6,13 +6,12 @@
callback true/false correct/wrong callback true/false correct/wrong
]] ]]
local label
local imageHolder local imageHolder
local function index(window, q, callback) local function index(window, q, callback)
frame = window:newFrame(0,0,0,0,0,.2,1,.8) local frame = window:newFrame(0,0,0,0,0,.2,1,.8)
frame.visibility = 0 frame.visibility = 0
label = window:newTextLabel(" " ..q.title.. " ",0,0,0,0,0,0,1,.2) local label = window:newTextLabel(" " ..q.title.. " ",0,0,0,0,0,0,1,.2)
label.align = ALIGN_CENTER label.align = ALIGN_CENTER
label.textColor = color.question_font label.textColor = color.question_font
label.color = color.question_bg label.color = color.question_bg
@@ -76,18 +75,10 @@ local function index(window, q, callback)
-- Return the expected types -- Return the expected types
return { return {
{ {title=label},
zoom=IMAGE, {zoom=IMAGE,description = "Full zoom in on an image"},
description = "Full zoom in on an image" {minzoom=IMAGE,description = "Minimum zoom before the full image is revealed"},
}, {fullimage=IMAGE,description = "Full image to show"}
{
minzoom=IMAGE,
description = "Minimum zoom before the full image is revealed"
},
{
fullimage=IMAGE,
description = "Full image to show"
}
} }
end end