Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8395 was 8079, checked in by landauf, 14 years ago

merged usability branch back to trunk

incomplete summary of the changes in this branch:

  • enhanced keyboard navigation in GUIs
  • implemented new graphics menu and changeable window size at runtime
  • added developer mode
  • HUD shows if game is paused, game pauses if ingame menu is opened
  • removed a few obsolete commands and hid some that are more for internal use
  • numpad works in console and gui
  • faster loading of level info
  • enhanced usage of compositors (Shader class)
  • improved camera handling, configurable FOV and aspect ratio
  • Property svn:eol-style set to native
File size: 9.1 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()
[7689]7local bInGameConsoleClosed = false
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!
[7403]218
[7689]219    -- If the InGameConsole is active, ignore the ESC command.
220    if bInGameConsoleClosed == true then
221        bInGameConsoleClosed = false
222        return
223    end
224
[7403]225    -- Count the number of sheets that don't need input till the first that does.
[7689]226    local counter = noInputSheetIndex()
[7403]227
228    -- If the first sheet that needs input is the MainMenu.
[7689]229    if noInputSheetCounter() == 1 and activeMenuSheets[counter].sheet.name == "MainMenu" then
[6417]230        orxonox.execute("exit")
[7403]231    -- If there is at least one sheet that needs input.
232    elseif counter > 0 then
233        orxonox.execute("hideGUI "..activeMenuSheets[counter].sheet.name)
[6417]234    else
[6722]235        showMenuSheet("InGameMenu")
[6417]236    end
237end
238
[7689]239function keyPressed(e)
240    local we = tolua.cast(e, "CEGUI::KeyEventArgs")
241    local sheet = activeMenuSheets[activeMenuSheets.size]
242    code = tostring(we.scancode)
243    -- Some preprocessing
244    if not mainMenuLoaded and not sheet.bNoInput then
245        if code == "1" then
246            keyESC()
247        elseif code == "0"then
[8079]248            orxonox.CommandExecutor:execute("InGameConsole openConsole")
[7689]249        end
250    end
[8079]251    sheet.sheet:keyPressed()
[7689]252end
253
[8079]254function windowResized(e)
255    for name, sheet in pairs(loadedSheets) do
256        if orxonox.GraphicsManager:getInstance():isFullScreen() or sheet.tShowCursor == TriBool.False then
257            inputMgr:setMouseExclusive(sheet.inputState, TriBool.True)
258        else
259            inputMgr:setMouseExclusive(sheet.inputState, TriBool.False)
260        end
261    end
262    local sheetTuple = activeMenuSheets[activeMenuSheets.size]
263    if sheetTuple then
264        if orxonox.GraphicsManager:getInstance():isFullScreen() and sheetTuple.sheet.tShowCursor ~= TriBool.False then
265            showCursor()
266        else
267            hideCursor()
268        end
269        sheetTuple.sheet:windowResized()
270    end
271end
272
[6737]273function setBackgroundImage(imageSet, imageName)
274    guiMgr:setBackgroundImage(imageSet, imageName)
[6417]275end
[6737]276
[7689]277function noInputSheetIndex()
278    -- Count the number of sheets that don't need input till the first that does.
279    local index = activeMenuSheets.size
280    while index > 0 and activeMenuSheets[index].bNoInput do
281        index = index - 1
282    end
283    return index
284end
285
[7403]286function noInputSheetCounter()
[7689]287    -- Count the number of sheets that do need input.
[7403]288    local counter = activeMenuSheets.size
[7689]289    for i = 1,activeMenuSheets.size do
290        if activeMenuSheets[i].bNoInput then
291            counter = counter - 1
292        end
[7403]293    end
294    return counter
295end
296
[7689]297function inGameConsoleClosed()
298    bInGameConsoleClosed = not bInGameConsoleClosed;
299end
300
[8079]301function getGUIFirstActive(name, bHidePrevious, bNoInput)
302    local sheet = activeMenuSheets.topSheetTuple
303    -- If the topmost gui sheet has the input name
304    if sheet ~= nil and sheet.name == name then
305        guiMgr:toggleGUIHelper(name, bHidePrevious, bNoInput, false);
306    else
307        guiMgr:toggleGUIHelper(name, bHidePrevious, bNoInput, true);
308    end
309end
310
[6737]311----------------------
312--- Initialisation ---
313----------------------
314
315hideCursor()
Note: See TracBrowser for help on using the repository browser.