-- main responsibilities: -- render widgets based on current viewport settings -- dispatch keyboard and touch events to appropriate widget -- pan viewport based on one-finger touch (from either mouse or touchscreen) -- adjust zoom based on two-finger touch (touchscreen only) ui_state = {} -- for buttons; recreated each frame widgets = {} -- more versatile UI elements function car.draw() ui_state.button_handlers = {} for _,w in ipairs(widgets) do w.draw() end draw_hud() end function car.update(dt) for _,w in ipairs(widgets) do if w.update then w.update(dt, App.mouse_x(), App.mouse_y()) end end end function car.mouse_press(x,y, b) skip_touch = nil if mouse_press_consumed_by_any_button(ui_state, x,y, b) then skip_touch = true return end cursor = nil for _,w in ipairs(widgets) do if w.ispress(x,y) then skip_touch = true return w.press(x,y, b) end end if f == nil then start.mouse = {x=x, y=y} curr.mouse = {x=x, y=y} f = 'mouse' initpos = {x=v.x, y=v.y} end end function car.touch_press(id, x,y, ...) if skip_touch then return end start[id] = {x=x, y=y} curr[id] = {x=x, y=y} if f == 'mouse' then f = id elseif f then s = id initzoom = v.zoom initpos = nil end end function car.mouse_move(x,y) if start.mouse then curr.mouse = {x=x, y=y} if not s then v.x = initpos.x + iscale(start.mouse.x - x) v.y = initpos.y + iscale(start.mouse.y - y) end end end function car.touch_move(id, x,y, ...) if start[id] then curr[id] = {x=x, y=y} if s then local oldzoom = v.zoom v.zoom = dist(curr[f], curr[s])/dist(start[f], start[s])*initzoom local c = centroid(curr[f], curr[s]) v.x = v.x + c.x/oldzoom - c.x/v.zoom v.y = v.y + c.y/oldzoom - c.y/v.zoom for _,w in ipairs(widgets) do if w.refresh_font then w.refresh_font() end end end end end function car.mouse_release(x,y, b) for _,w in ipairs(widgets) do if w.release then w.release(x,y, b) end end f,s = nil start, curr = {}, {} skip_touch = nil initzoom = nil initpos = nil end function car.keychord_press(chord, key) if cursor then cursor.presschord(chord, key) end end function car.text_input(t) if cursor then cursor.textinput(t) end end function car.key_release(key) if cursor then cursor.releasekey(key) end end function car.quit() for name,w in pairs(widgets) do if w.quit then w.quit() end end end