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 @startuml titlescreen onScreenChange event
!theme materia-outline
skinparam DefaultFontName Courier skinparam DefaultFontName Courier
skinparam Shadowing false skinparam Shadowing false
participant usc participant usc
participant "titlescreen.lua" as main participant "titlescreen.lua" as main
collections screens participant pageview
collections pages collections pages
activate main activate main
activate screens activate pageview
activate pages activate pages
hnote across hnote across
Screen loaded and page displayed Screen loaded and page displayed
endhnote endhnote
pages -> screens : change screen event\n(eg. goes out of scope) pages --> main : onInvalidation() event
deactivate pages 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() pageview --> main : onNavigated() event
activate screens activate main
screens -> usc : set current screen as last screen value
screens -> pages : init()
main -> pages : init()
activate pages activate pages
pages --> main : onInit() event
activate main
deactivate main
deactivate main
main -> usc : set current screen as last screen value
@enduml @enduml

View File

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

View File

@ -6,6 +6,8 @@ require("common.class")
---@field posY number ---@field posY number
---@field aabbW number ---@field aabbW number
---@field aabbH number ---@field aabbH number
---@field focused boolean
---@field active boolean
local Field = { local Field = {
__name = "Field" __name = "Field"
} }
@ -23,10 +25,16 @@ function Field.new(params)
params.posY = params.posY or 0 params.posY = params.posY or 0
params.aabbW = params.aabbW or 0 params.aabbW = params.aabbW or 0
params.aabbH = params.aabbH or 0 params.aabbH = params.aabbH or 0
params.focused = params.focused or false
params.active = params.active or false
return CreateInstance(Field, params) return CreateInstance(Field, params)
end end
function Field:init()
self:onInit()
end
---Get the containing top-level parent page ---Get the containing top-level parent page
---@return Field|Page ---@return Field|Page
function Field:getParentPage() function Field:getParentPage()
@ -37,14 +45,25 @@ function Field:getParentPage()
end end
end end
---@param obj? any # message object for the field function Field:activate()
function Field:activate(obj) end self.active = true
self:onActivated()
end
---@param obj? any # message object for the field function Field:focus()
function Field:focus(obj) end self.focused = true
self:onFocusChange(self.focused)
end
---@param obj? any # message object for the field function Field:unfocus()
function Field:deactivate(obj) end 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` ---@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 ---@return boolean # true if further button input processing should be stopped, otherwise false
@ -59,6 +78,24 @@ function Field:handleKnobInput(knob, delta)
return false return false
end 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 ---@param deltaTime number # frametime in seconds
function Field:drawContent(deltaTime) function Field:drawContent(deltaTime)
-- dummy field content -- dummy field content

View File

@ -1,4 +1,6 @@
require("common.globals")
require("common.class") require("common.class")
local Util = require("common.util")
local Field = require("api.page.field") local Field = require("api.page.field")
---@class LinkField: Field ---@class LinkField: Field
@ -18,6 +20,18 @@ function LinkField.new(params)
return CreateInstance(LinkField, params, Field) return CreateInstance(LinkField, params, Field)
end 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` ---@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 ---@return boolean # true if further button input processing should be stopped, otherwise false
function LinkField:handleButtonInput(button) function LinkField:handleButtonInput(button)
@ -27,18 +41,29 @@ function LinkField:handleButtonInput(button)
end end
if button == game.BUTTON_STA then if button == game.BUTTON_STA then
local parentPage = self:getParentPage() self:_navigate()
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 end
return false return false
end 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 return LinkField

View File

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

View File

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