• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

UIScreen

Level 19
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:
Top