From 40dbc7134bae5cff48c2262d92721a3dd5394f84 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Tue, 7 Feb 2012 23:10:29 +0100 Subject: Initial commit --- core.lua | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 core.lua (limited to 'core.lua') diff --git a/core.lua b/core.lua new file mode 100644 index 0000000..f57caa9 --- /dev/null +++ b/core.lua @@ -0,0 +1,153 @@ +-- state +local context = {maxid = 0} +local NO_WIDGET = function()end + +local function generateID() + context.maxid = context.maxid + 1 + return context.maxid +end + +local function setHot(id) context.hot = id end +local function isHot(id) return context.hot == id end + +local function setActive(id) context.active = id end +local function isActive(id) return context.active == id end + +local function setKeyFocus(id) context.keyfocus = id end +local function hasKeyFocus(id) return context.keyfocus == id end + +-- input +local mouse = {x = 0, y = 0, down = false} +local keyboard = {key = nil, code = -1} + +function mouse.inRect(x,y,w,h) + return mouse.x >= x and mouse.x <= x+w and mouse.y >= y and mouse.y <= y+h +end + +function mouse.updateState(id, x,y,w,h) + if mouse.inRect(x,y,w,h) then + setHot(id) + if not context.active and mouse.down then + setActive(id) + end + end +end + +function mouse.releasedOn(id) + return not mouse.down and isHot(id) and isActive(id) +end + +function keyboard.pressed(key, code) + keyboard.key = key + keyboard.code = code +end + +function keyboard.tryGrab(id) + if not context.keyfocus then + context.keyfocus = id + end +end + +local function makeTabable(id) + keyboard.tryGrab(id) + if hasKeyFocus(id) and keyboard.key == 'tab' then + if love.keyboard.isDown('rshift', 'lshift') then + setKeyFocus(context.lastwidget) + else + setKeyFocus(nil) + end + keyboard.key = nil + end + context.lastwidget = id +end + +-- helper functions +local function strictAnd(...) + local n = select("#", ...) + local ret = true + for i = 1,n do ret = select(i, ...) and ret end + return ret +end + +local function strictOr(...) + local n = select("#", ...) + local ret = false + for i = 1,n do ret = select(i, ...) or ret end + return ret +end + +-- allow packed nil +local function save_pack(...) + return {n = select('#', ...), ...} +end + +local function save_unpack(t, i) + i = i or 1 + if i >= t.n then return t[i] end + return t[i], save_unpack(t, i+1) +end + +local draw_items = {n = 0} +local function registerDraw(id, f, ...) + assert(type(f) == 'function' or (getmetatable(f) or {}).__call, + 'Drawing function is not a callable type!') + + local state = 'normal' + if isHot(id) or hasKeyFocus(id) then + state = isActive(id) and 'active' or 'hot' + end + local rest = save_pack(...) + draw_items.n = draw_items.n + 1 + draw_items[draw_items.n] = function() f(state, save_unpack(rest)) end +end + +-- actually update-and-draw +local function draw() + -- close frame state + if not mouse.down then -- released + setActive(nil) + elseif not context.active then -- clicked outside + setActive(NO_WIDGET) + end + + for i = 1,draw_items.n do draw_items[i]() end + + -- prepare for next frame + draw_items.n = 0 + context.maxid = 0 + + -- update mouse status + setHot(nil) + mouse.x, mouse.y = love.mouse.getPosition() + mouse.down = love.mouse.isDown('l') + + -- clear keyboard focus if nobody wants it + if keyboard.key == 'tab' then + context.keyboardfocus = nil + end + keyboard.key, keyboard.code = nil, -1 +end + +return { + mouse = mouse, + keyboard = keyboard, + + generateID = generateID, + setHot = setHot, + setActive = setActive, + setKeyFocus = setKeyFocus, + isHot = isHot, + isActive = isActive, + hasKeyFocus = hasKeyFocus, + makeTabable = makeTabable, + + style = require((...):match("^(.+)%.[^%.]+") .. '.style-default'), + color = color, + registerDraw = registerDraw, + draw = draw, + + strictAnd = strictAnd, + strictOr = strictOr, + save_pack = save_pack, + save_unpack = save_unpack, +} -- cgit v1.2.3-54-g00ecf