- Joined
- Mar 18, 2012
- Messages
- 1,716
UIScreen
Struct UIScreen is the parent struct you base your UIs on.
JASS:
library UIScreen uses UIBasic, UICamera optional UIBoard optional UISound/* v1.1
*****************************************************************************
*
* Each custom UI is build of one UIScreen having a unlimited amount of UIWindows.
* Struct UIScreen is the parent struct you base your UIs on.
*
* Realistic example: CustomInventory extends UIScreen.
*
****************************************************************************
*/
globals
private integer array current
endglobals
//* Parent struct of all custom UIs.
struct UIScreen
//* System safety:
//* ==============
method operator exists takes nothing returns boolean
return (user != null)
endmethod
//* Stub method:
//* ============
//* Fires after calling method show.
stub method onShow takes boolean flag returns nothing
endmethod
//* Readonly members:
//* =================
readonly player user
readonly real tileSize
readonly real originX
readonly real originY
readonly real width
readonly real height
readonly boolean enabled
method setTileSize takes real newSize returns nothing
set tileSize = newSize
endmethod
method operator scale takes nothing returns real
return tileSize/UI_TILE_SIZE
endmethod
method operator centerX takes nothing returns real
return originX + (width/2)
endmethod
method operator centerY takes nothing returns real
return originY + (height/2)
endmethod
//* User-friendly. Operator overloading.
method operator userId takes nothing returns integer
debug call ThrowError((user == null), "UIScreen", "userId", "user", this, "Attempt access a deallocated instance!")
return GetPlayerId(user)
endmethod
//* private members:
//* ================
private Table windows
method openWindowOfType takes integer typeId returns boolean
if (enabled) and (windows.has(-typeId)) and not windows.boolean.has(-typeId) then
set windows.boolean[-typeId] = true
return true
endif
return false
endmethod
method closeWindowOfType takes integer typeId returns boolean
if (windows.boolean.has(-typeId)) then
call windows.boolean.remove(-typeId)
return true
endif
return false
endmethod
//* UIWindow related API:
//* Get(), Has(), IsOpen() and Add()
method hasWindowOfType takes integer typeId returns boolean
debug call ThrowError((user == null), "UIScreen", "hasWindowOfType", "user", this, "Attempt access a deallocated instance!")
return windows.has(-typeId)
endmethod
method getWindowOfType takes integer typeId returns UIWindow
debug call ThrowError((user == null), "UIScreen", "getWindowOfType", "user", this, "Attempt access a deallocated instance!")
return windows[-typeId]
endmethod
method isWindowOfTypeOpen takes integer typeId returns boolean
debug call ThrowError((user == null), "UIScreen", "isWindowOfTypeOpen", "user", this, "Attempt access a deallocated instance!")
return windows.boolean.has(-typeId)
endmethod
method addWindowOfType takes integer typeId, integer index, boolean autostart returns nothing
debug call ThrowError(windows.has(-typeId), "UIScreen", "addWindowOfType", "typeId", this, "UIWindow already added!")
set windows.boolean[typeId] = autostart
set windows[-typeId] = index
set windows[typeId] = windows[0]
set windows[0] = typeId
endmethod
//* Optional getters:
//* =================
static if LIBRARY_UIBoard then
method operator board takes nothing returns UIBoard
return userId
endmethod
endif
static if LIBRARY_UISound then
method operator audio takes nothing returns UISound
return userId
endmethod
endif
//* Not so nice, but required.
private method autoShowWindows takes boolean flag returns nothing
local integer index = windows[0]
loop
exitwhen index == 0
if not (flag) and windows.boolean.has(-index) then
call UIWindow.recursiveShow.execute(windows[-index], flag)
elseif (flag) and (windows.boolean[index]) then
call UIWindow.recursiveShow.execute(windows[-index], flag)
endif
set index = windows[index]
endloop
endmethod
method show takes boolean flag returns nothing
local thistype prev = current[userId]
if (flag) and not (enabled) then
//* Close previously seen screens first.
if (0 != prev) then
call prev.show(false)
endif
set enabled = true
set current[userId] = this
if GetLocalClient() == user then
call FogEnable(false)
call FogMaskEnable(false)
endif
call autoShowWindows(true)
call onShow(flag)
call UI_StartCamera(user, originX, originY, width, height)
call UI_FireEvent(userId, EVENT_PLAYER_UI)
elseif not (flag) and (enabled) then
set enabled = false
call autoShowWindows(false)
if GetLocalClient() == user then
call FogEnable(true)
call FogMaskEnable(true)
endif
call UI_StopCamera(user)
call onShow(flag)
static if LIBRARY_UIBoard then
call board.release()
endif
call UI_FireEvent(userId, EVENT_PLAYER_UI)
set current[userId] = 0
endif
endmethod
static method create takes player p, real x, real y, real sx, real sy returns thistype
debug local string msg = GetPlayerName(p) + " is a computer player! Only non-computer players can see an UIWindow!"
debug local boolean error1 = (x + sx > WorldBounds.maxX) or (x < WorldBounds.minX)
debug local boolean error2 = (y + sy > WorldBounds.maxY) or (y < WorldBounds.minY)
//**
local thistype this = allocate()
set user = p
set tileSize = UI_TILE_SIZE
set windows = Table.create()
set originX = x
set originY = y
set width = sx
set height = sy
set enabled = false
//* DEBUG_MODE:
//* ===========
debug call ThrowError(IsPlayerComputer(p), "UIScreen", "create", "user", this, msg)
debug call ThrowError(error1, "UIScreen", "create", "error1", this, "X coordinates of the UI screen are out of WorldBounds!")
debug call ThrowError(error2, "UIScreen", "create", "error2", this, "Y coordinates of the UI screen are out of WorldBounds!")
return this
endmethod
private method destroyWindows takes nothing returns nothing
local integer index = windows[0]
loop
exitwhen index == 0
call UIWindow.recursiveDestroy.execute(windows[-index])
set index = windows[index]
endloop
endmethod
method destroy takes nothing returns nothing
call ThrowError(not exists, "UIScreen", "destroy", "not exists", this, "Attempt to destroy an invalid UI Screen!")
if (enabled) then
debug call ThrowWarning(enabled, "UIScreen", "destroy", "enabled", this, "Attempt to destroy an UI screen, which is yet enabled!")
call show(false)
endif
call deallocate()
call destroyWindows()
call windows.destroy()
set user = null
endmethod
//* Only available in debug mode. Highlights the borders of your screen.
//* So you can check ingame, that you settings are correct.
debug public method highlight takes nothing returns nothing
debug local string flash = "DRAB"
debug call AddLightning(flash, false, originX, originY, originX, originY + height)
debug call AddLightning(flash, false, originX, originY + height, originX + width, originY + height)
debug call AddLightning(flash, false, originX + width, originY, originX, originY)
debug call AddLightning(flash, false, originX + width, originY + height, originX + width, originY)
debug endmethod
endstruct
function IsPlayerInUI takes player p returns boolean
return (current[GetPlayerId(p)] != 0)
endfunction
function GetPlayerUI takes player p returns UIScreen
return current[GetPlayerId(p)]
endfunction
endlibrary
Last edited: