Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/data/gui/scripts/SheetManager.lua @ 8572

Last change on this file since 8572 was 8529, checked in by landauf, 14 years ago

fixed lua error when pressing ESC ingame after closing the console

  • Property svn:eol-style set to native
File size: 9.2 KB
RevLine 
[6737]1-- SheetManager.lua
[6595]2
[6737]3local cursor = CEGUI.MouseCursor:getSingleton()
[6662]4local loadedSheets = {}
[6718]5local activeMenuSheets = {size = 0, topSheetTuple = nil}
[6737]6local menuSheetsRoot = guiMgr:getMenuRootWindow()
[8484]7local bInGameConsoleClosed = false
[7689]8local mainMenuLoaded = false
9orxonox.GUIManager:subscribeEventHelper(menuSheetsRoot, "KeyDown", "keyPressed")
[8079]10orxonox.GUIManager:subscribeEventHelper(menuSheetsRoot, "Sized", "windowResized")
[5491]11
[8079]12------------------------
13--- Global functions ---
14------------------------
[6662]15
[8079]16function hideCursor()
[6662]17    if cursor:isVisible() then
18        cursor:hide()
19    end
20end
21
[8079]22function showCursor()
[6737]23    if not cursor:isVisible() and inputMgr:isMouseExclusive() then
[6662]24        cursor:show()
25    end
26end
27
[6737]28-- Loads the GUI with the specified name
29-- The name corresponds to the filename of the *.lua and *.layout files
30-- but without the extension
31function loadSheet(name)
32    -- Check if it has already been loaded
33    local sheet = loadedSheets[name]
34    if sheet == nil then
35        -- Load the sheet
36        sheet = require(name)
37        sheet:load()
38        loadedSheets[name] = sheet
39    end
40    return sheet
41end
42
[6662]43-- ?
[7403]44function showMenuSheet(name, bHidePrevious, bNoInput, ptr)
45    local sheet = showMenuSheet(name, bHidePrevious, bNoInput)
[6718]46    sheet.overlay = ptr
47    return sheet
[5491]48end
49
[6662]50-- Shows the specified menu sheet and loads it if neccessary
[7403]51function showMenuSheet(name, bHidePrevious, bNoInput)
[6737]52    if name == "" then
53        return nil
54    end
[6718]55    -- Get sheet (or load it)
56    local menuSheet = loadSheet(name)
[5491]57
[6718]58    -- Use sheet's value if nil was provided
59    if bHidePrevious == nil then
60        bHidePrevious = menuSheet.bHidePrevious
61        assert(bHidePrevious ~= nil)
62    end
63
[7403]64    -- Set bNoInput to false if it hasn't been set.
65    if bNoInput == nil then
66        bNoInput = false
67    end
68
69    -- Count the number of sheets that don't need input till the first that does.
[7689]70    local counter = noInputSheetIndex()
[6721]71    -- Pause game control if this is the first menu to be displayed
72    -- HUGE HACK?
[7403]73    if bNoInput == false and counter == 0 then
[6721]74        orxonox.HumanController:pauseControl()
75    end
76
[6662]77    -- Hide if already displayed (to make sure it is up front in the end)
78    if activeMenuSheets[name] ~= nil then
[6722]79        hideMenuSheet(name)
[6662]80    end
81
[7403]82    if bNoInput == true then
83        menuSheet.tShowCursor = TriBool.Dontcare
84    end
85
[6718]86    -- Add the sheet in a tuple of additional information
87    local sheetTuple =
88    {
89        ["sheet"]          = menuSheet,
[7403]90        ["bHidePrevious"]  = bHidePrevious,
[8079]91        ["bNoInput"]       = bNoInput,
92        ["name"]           = name
[6718]93    }
94    table.insert(activeMenuSheets, sheetTuple) -- indexed array access
95    activeMenuSheets[name] = sheetTuple -- name access
96    activeMenuSheets.size = activeMenuSheets.size + 1
97    activeMenuSheets.topSheetTuple = sheetTuple
98
[6662]99    -- Add sheet to the root window
[6737]100    menuSheetsRoot:addChildWindow(menuSheet.window)
[6662]101
[7689]102    -- If sheet is the MainMenu
103    if name == "MainMenu" then
104        mainMenuLoaded = true
105    end
106
[6662]107    -- Handle input distribution
[7403]108    if bNoInput == false then
109        inputMgr:enterState(menuSheet.inputState)
110    end
[6662]111
[6718]112    -- Only change cursor situation if menuSheet.tShowCursor ~= TriBool.Dontcare
113    if menuSheet.tShowCursor == TriBool.True then
[6417]114        showCursor()
[6718]115    elseif menuSheet.tShowCursor == TriBool.False then
[6417]116        hideCursor()
[5491]117    end
[6417]118
[6662]119    -- Hide all previous sheets if necessary
[8079]120    local previous
[6662]121    if bHidePrevious then
122        for i = 1, activeMenuSheets.size - 1 do
[8079]123            previous = activeMenuSheets[i].sheet
124            previous:hide()
[6417]125        end
126    end
[8079]127
[6662]128    menuSheet:show()
[7689]129    menuSheetsRoot:activate()
[6718]130
[8079]131    -- select first button if the menu was opened with the keyboard
132    if previous and previous.pressedEnter and menuSheet:hasSelection() == false then
133        menuSheet:setSelectionNear(1, 1)
134    end
135
[6662]136    return menuSheet
[5491]137end
138
[6722]139function hideMenuSheet(name)
[6662]140    local sheetTuple = activeMenuSheets[name]
141    if sheetTuple == nil then
142        return
[6417]143    end
[5491]144
[6662]145    -- Hide the sheet
[6718]146    sheetTuple.sheet:hide()
[6662]147
148    -- Show sheets that were hidden by the sheet to be removed
149    local i = activeMenuSheets.size
150    -- Only do something if all sheets on top of sheetTuple
[6718]151    -- have bHidePrevious == true and sheetTuple.bHidePrevious == true
[6662]152    while i > 0 do
[6718]153        if activeMenuSheets[i].bHidePrevious then
[6662]154            if activeMenuSheets[i] == sheetTuple then
155                i = i - 1
156                while i > 0 do
[6718]157                    activeMenuSheets[i].sheet:show()
158                    if activeMenuSheets[i].bHidePrevious then
[6662]159                        break
160                    end
161                    i = i - 1
[6417]162                end
163            end
[6662]164            break
[6417]165        end
[6662]166        i = i - 1
[6417]167    end
[6662]168
169    -- Remove sheet with its tuple from the table
[6737]170    menuSheetsRoot:removeChildWindow(sheetTuple.sheet.window)
[6671]171    table.remove(activeMenuSheets, table.findIndex(activeMenuSheets, sheetTuple))
[6662]172    activeMenuSheets[name] = nil
173    activeMenuSheets.size = activeMenuSheets.size - 1
[6718]174    activeMenuSheets.topSheetTuple = activeMenuSheets[activeMenuSheets.size]
[6662]175
[7689]176    -- If sheet is the MainMenu
177    if name == "MainMenu" then
178        mainMenuLoaded = false
179    end
180
[6662]181    -- Leave the input state
[7403]182    if not sheetTuple.bNoInput then
183        inputMgr:leaveState(sheetTuple.sheet.inputState)
184    end
[8079]185
[6718]186    -- CURSOR SHOWING
187    local i = activeMenuSheets.size
188    -- Find top most sheet that doesn't have tShowCusor == TriBool.Dontcare
189    while i > 0 and activeMenuSheets[i].sheet.tShowCursor == TriBool.Dontcare do
190        i = i - 1
191    end
192    if i > 0 and activeMenuSheets[i].sheet.tShowCursor == TriBool.True then
[6662]193        showCursor()
194    else
195        hideCursor()
196    end
197
[7403]198    -- Count the number of sheets that don't need input till the first that does.
[7689]199    local counter = noInputSheetIndex()
[7403]200    -- Resume control if the last (non-noInput) menu is hidden
201    if counter == 0 then
[6417]202        orxonox.HumanController:resumeControl()
203        hideCursor()
204    end
[7403]205
[8079]206    sheetTuple.sheet:quit()
[5491]207end
[6417]208
[6662]209-- Hides all menu GUI sheets
[6722]210function hideAllMenuSheets()
[6662]211    while activeMenuSheets.size ~= 0 do
[6722]212        hideMenuSheet(activeMenuSheets.topSheetTuple.sheet.name)
[6417]213    end
214end
215
216function keyESC()
[6662]217    -- HUGE, very HUGE hacks!
[8529]218
[8484]219    -- If the InGameConsole is active, ignore the ESC command.
220    if bInGameConsoleClosed == true then
221        bInGameConsoleClosed = false
[8529]222        if activeMenuSheets[1] and activeMenuSheets[1].sheet.name == "MainMenu" then
[8484]223            return
224        end
225    end
[7403]226
[8485]227    -- Count the number of sheets that don't need input till the first that does.
228    local counter = noInputSheetIndex()
229
[7403]230    -- If the first sheet that needs input is the MainMenu.
[7689]231    if noInputSheetCounter() == 1 and activeMenuSheets[counter].sheet.name == "MainMenu" then
[6417]232        orxonox.execute("exit")
[7403]233    -- If there is at least one sheet that needs input.
234    elseif counter > 0 then
235        orxonox.execute("hideGUI "..activeMenuSheets[counter].sheet.name)
[6417]236    else
[6722]237        showMenuSheet("InGameMenu")
[6417]238    end
239end
240
[7689]241function keyPressed(e)
242    local we = tolua.cast(e, "CEGUI::KeyEventArgs")
243    local sheet = activeMenuSheets[activeMenuSheets.size]
244    code = tostring(we.scancode)
245    -- Some preprocessing
246    if not mainMenuLoaded and not sheet.bNoInput then
247        if code == "1" then
248            keyESC()
249        elseif code == "0"then
[8079]250            orxonox.CommandExecutor:execute("InGameConsole openConsole")
[7689]251        end
252    end
[8079]253    sheet.sheet:keyPressed()
[7689]254end
255
[8079]256function windowResized(e)
257    for name, sheet in pairs(loadedSheets) do
258        if orxonox.GraphicsManager:getInstance():isFullScreen() or sheet.tShowCursor == TriBool.False then
259            inputMgr:setMouseExclusive(sheet.inputState, TriBool.True)
260        else
261            inputMgr:setMouseExclusive(sheet.inputState, TriBool.False)
262        end
263    end
264    local sheetTuple = activeMenuSheets[activeMenuSheets.size]
265    if sheetTuple then
266        if orxonox.GraphicsManager:getInstance():isFullScreen() and sheetTuple.sheet.tShowCursor ~= TriBool.False then
267            showCursor()
268        else
269            hideCursor()
270        end
271        sheetTuple.sheet:windowResized()
272    end
273end
274
[6737]275function setBackgroundImage(imageSet, imageName)
276    guiMgr:setBackgroundImage(imageSet, imageName)
[6417]277end
[6737]278
[7689]279function noInputSheetIndex()
280    -- Count the number of sheets that don't need input till the first that does.
281    local index = activeMenuSheets.size
282    while index > 0 and activeMenuSheets[index].bNoInput do
283        index = index - 1
284    end
285    return index
286end
287
[7403]288function noInputSheetCounter()
[7689]289    -- Count the number of sheets that do need input.
[7403]290    local counter = activeMenuSheets.size
[7689]291    for i = 1,activeMenuSheets.size do
292        if activeMenuSheets[i].bNoInput then
293            counter = counter - 1
294        end
[7403]295    end
296    return counter
297end
298
[8484]299function inGameConsoleClosed()
300    bInGameConsoleClosed = not bInGameConsoleClosed;
301end
302
[8079]303function getGUIFirstActive(name, bHidePrevious, bNoInput)
304    local sheet = activeMenuSheets.topSheetTuple
305    -- If the topmost gui sheet has the input name
306    if sheet ~= nil and sheet.name == name then
307        guiMgr:toggleGUIHelper(name, bHidePrevious, bNoInput, false);
308    else
309        guiMgr:toggleGUIHelper(name, bHidePrevious, bNoInput, true);
310    end
311end
312
[6737]313----------------------
314--- Initialisation ---
315----------------------
316
317hideCursor()
Note: See TracBrowser for help on using the repository browser.