page api update

This commit is contained in:
Hersi 2022-05-22 03:05:24 +02:00
parent e68fcd5bfe
commit 9b170a519f
7 changed files with 235 additions and 44 deletions

View File

@ -0,0 +1,108 @@
@startuml page class
skinparam PackageStyle rectangle
package api.page {
class Page {
- {static} __name : string
+ content : Field[]
+ viewHandler : PageView
-- construction --
+ {static} Page new(params : table<Page>)
+ void init()
.. content manipulation ..
+ void addField(field : Field)
+ void refreshFields()
.. input handling ..
+ boolean handleButtonInput(button : integer)
+ boolean handleKnobInput(knob : integer, delta : number)
+ boolean handleMouseInput(x : number, y : number, button : integer)
.. event callbacks ..
+ void onInit()
+ void onInvalidation()
.. drawing ..
+ void drawBackground(deltaTime : number)
+ void drawContent(deltaTime : number)
+ void drawForeground(deltaTime : number)
+ void render(deltaTime : number)
}
class Field {
- {static} __name : string
+ parent : Page|ContainerField
+ posX : number
+ posY : number
+ aabbW : number
+ aabbH : number
+ active : boolean
+ focused : boolean
-- construction --
+ {static} Field new(params : table<Field>)
+ void init()
..
+ Page getParentPage()
.. state manipulation ..
+ void activate()
+ void focus()
+ void unfocus()
+ void deactivate()
.. input handling ..
+ boolean handleButtonInput(button : integer)
+ boolean handleKnobInput(knob : integer, delta : number)
+ boolean handleMouseInput(x : number, y : number, button : integer)
.. event callback ..
+ void onInit()
+ void onActivated()
+ void onFocusChanged(focus : boolean)
+ void onDeactivated()
.. drawing ..
+ void drawContent(deltaTime : number)
+ void render(deltaTime : number)
}
class PageView {
- {static} __name : string
+ pageStack : Page[]
-- construction --
+ {static} PageView new(params : table<PageView>)
.. page manipulation ..
+ Page get(index=0 : integer)
+ void navigate(page : Page)
+ void replace(rootPage : Page)
+ void back()
+ void clear()
.. event callbacks ..
+ void onNavigated(back : boolean)
+ void onEmptied()
.. drawing ..
+ void render(deltaTime : number)
}
class LinkField {
+ link : Page
}
class ContainerField {
+ content : Field[]
-- content manipulation --
+ void addField(field : Field)
+ void refreshFields()
.. drawing ..
+ void drawBackground(deltaTime : number)
+ void drawContent(deltaTime : number)
+ void drawForeground(deltaTime : number)
+ void render(deltaTime : number)
}
Field <|-- LinkField
Field <|-- ContainerField
Field "references" o-- Page
LinkField "references" o-- Page
Page *-- Field
Page "references" o-- PageView
PageView *-- Page
}
@enduml

View File

@ -1,35 +1,37 @@
@startuml titlescreen onScreenChange event
!theme materia-outline
skinparam DefaultFontName Courier
skinparam Shadowing false
participant usc
participant "titlescreen.lua" as main
collections screens
participant pageview
collections pages
activate main
activate screens
activate pageview
activate pages
hnote across
Screen loaded and page displayed
endhnote
pages -> screens : change screen event\n(eg. goes out of scope)
pages --> main : onInvalidation() event
deactivate pages
screens --> main : onDeactivation(obj)
deactivate screens
main -> main : handle replacing screen\nby inspecting `obj`
main -> pageview : replace screen
main -> screens : call current screen's init()
activate screens
screens -> usc : set current screen as last screen value
screens -> pages : init()
pageview --> main : onNavigated() event
activate main
main -> pages : init()
activate pages
pages --> main : onInit() event
activate main
deactivate main
deactivate main
main -> usc : set current screen as last screen value
@enduml

View File

@ -1,11 +1,10 @@
@startuml titlescreen startup
!theme materia-outline
skinparam DefaultFontName Courier
skinparam Shadowing false
participant usc
participant "titlescreen.lua" as main
collections screens
participant pageview
collections pages
usc -> main : load titlescreen.lua
@ -13,13 +12,12 @@ usc -> main : load titlescreen.lua
activate main
group construct screens
main -> screens : create
screens -> pages : create
screens -> pages : set callbacks
main -> screens : set callbacks
main -> pageview : create
main -> pageview : set callbacks
main -> pages : create
main -> pages : set callbacks
main -> usc : get persistent states
main <-- usc
main -> screens : load persistent previous state values
end
main -> usc : get last screen value
@ -27,21 +25,25 @@ main <-- usc
main -> main : set last screen value as current screen
main -> screens : call current screen's init()
main -> pageview : set current screen as rootPage
activate screens
pageview --> main : onNavigated() event
activate main
screens -> usc : set current screen as last screen value
main -> usc : set current screen as last screen value
deactivate main
screens -> pages : init()
main -> pages : init()
activate pages
pages --> main : onInit() event fired
activate main
deactivate main
loop main render loop
main -> screens : call current screen's render()
activate screens
screens -> pages : render()
main -> pageview : render()
pageview -> pages : render()
activate pages
deactivate screens
deactivate pages
end

View File

@ -6,6 +6,8 @@ require("common.class")
---@field posY number
---@field aabbW number
---@field aabbH number
---@field focused boolean
---@field active boolean
local Field = {
__name = "Field"
}
@ -23,10 +25,16 @@ function Field.new(params)
params.posY = params.posY or 0
params.aabbW = params.aabbW or 0
params.aabbH = params.aabbH or 0
params.focused = params.focused or false
params.active = params.active or false
return CreateInstance(Field, params)
end
function Field:init()
self:onInit()
end
---Get the containing top-level parent page
---@return Field|Page
function Field:getParentPage()
@ -37,14 +45,25 @@ function Field:getParentPage()
end
end
---@param obj? any # message object for the field
function Field:activate(obj) end
function Field:activate()
self.active = true
self:onActivated()
end
---@param obj? any # message object for the field
function Field:focus(obj) end
function Field:focus()
self.focused = true
self:onFocusChange(self.focused)
end
---@param obj? any # message object for the field
function Field:deactivate(obj) end
function Field:unfocus()
self.focused = false
self:onFocusChange(self.focused)
end
function Field:deactivate()
self.active = false
self:onDeactivated()
end
---@param button integer # options are under the `game` table prefixed with `BUTTON`
---@return boolean # true if further button input processing should be stopped, otherwise false
@ -59,6 +78,24 @@ function Field:handleKnobInput(knob, delta)
return false
end
---@param x number
---@param y number
---@param button integer
---@return boolean # true if further button input processing should be stopped, otherwise false
function Field:handleMouseInput(x, y, button)
return false
end
function Field:onInit() end
function Field:onActivated() end
---Callback function for focus change event
---@param focus boolean # weather the field is focused
function Field:onFocusChange(focus) end
function Field:onDeactivated() end
---@param deltaTime number # frametime in seconds
function Field:drawContent(deltaTime)
-- dummy field content

View File

@ -1,4 +1,6 @@
require("common.globals")
require("common.class")
local Util = require("common.util")
local Field = require("api.page.field")
---@class LinkField: Field
@ -18,6 +20,18 @@ function LinkField.new(params)
return CreateInstance(LinkField, params, Field)
end
function LinkField:_navigate()
local parentPage = self:getParentPage()
if parentPage and parentPage.viewHandler then
game.Log(tostring(self) .. " viewHandler:navigate(" .. tostring(self.link) .. ") called", game.LOGGER_INFO)
parentPage.viewHandler:navigate(self.link)
return true
else
local target = (parentPage and parentPage.viewHandler or "PageView")
game.Log(tostring(self) .. " can't access " .. tostring(target) .. " instance", game.LOGGER_ERROR)
end
end
---@param button integer # options are under the `game` table prefixed with `BUTTON`
---@return boolean # true if further button input processing should be stopped, otherwise false
function LinkField:handleButtonInput(button)
@ -27,18 +41,29 @@ function LinkField:handleButtonInput(button)
end
if button == game.BUTTON_STA then
local parentPage = self:getParentPage()
if parentPage and parentPage.viewHandler then
game.Log(tostring(self) .. " viewHandler:navigate(" .. tostring(self.link) .. ") called", game.LOGGER_INFO)
parentPage.viewHandler:navigate(self.link)
return true
else
local target = (parentPage and parentPage.viewHandler or "PageView")
game.Log(tostring(self) .. " can't access " .. tostring(target) .. " instance", game.LOGGER_ERROR)
end
self:_navigate()
end
return false
end
---@param x number
---@param y number
---@param button integer
---@return boolean # true if further button input processing should be stopped, otherwise false
function LinkField:handleMouseInput(x, y, button)
if not Util.areaOverlap(x, y, self.posX, self.posY, self.aabbW, self.aabbH) then
return false
end
if not self.link then
game.Log(tostring(self) .. " does not have a valid link", game.LOGGER_ERROR)
return false
end
if button == game.MOUSE_LEFT then
self:_navigate()
end
end
return LinkField

View File

@ -23,7 +23,9 @@ function Page.new(params)
end
---Initialize Page
function Page:init() end
function Page:init()
self:onInit()
end
---Add field to page
---@param field Field
@ -57,6 +59,10 @@ function Page:handleKnobInput(knob, delta) end
---@param button integer
function Page:handleMouseInput(x, y, button) end
function Page:onInit() end
function Page:onInvalidation() end
---@param deltaTime number # frametime in seconds
function Page:drawBackground(deltaTime) end

View File

@ -36,6 +36,7 @@ end
function PageView:navigate(page)
page.viewHandler = self
pushStack(self.pageStack, page)
self:onNavigated(false)
end
---Replace the current pageStack with a new root page
@ -54,6 +55,11 @@ function PageView:back()
self:get().viewHandler = nil
popStack(self.pageStack)
self:onNavigated(true)
if not self:get() then
self:onEmptied()
end
end
---Clear the pageStack
@ -64,6 +70,11 @@ function PageView:clear()
end
end
---@param back boolean # whether it's called in the back() function
function PageView:onNavigated(back) end
function PageView:onEmptied() end
---@param deltaTime number # frametime in seconds
function PageView:render(deltaTime)
if self:get() then