Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ai2/data/gui/scripts/SheetManager.lua @ 8740

Last change on this file since 8740 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
Line 
1-- SheetManager.lua
2
3local cursor = CEGUI.MouseCursor:getSingleton()
4local loadedSheets = {}
5local activeMenuSheets = {size = 0, topSheetTuple = nil}
6local menuSheetsRoot = guiMgr:getMenuRootWindow()
7local bInGameConsoleClosed = false
8local mainMenuLoaded = false
9orxonox.GUIManager:subscribeEventHelper(menuSheetsRoot, "KeyDown", "keyPressed")
10orxonox.GUIManager:subscribeEventHelper(menuSheetsRoot, "Sized", "windowResized")
11
12------------------------
13--- Global functions ---
14------------------------
15
16function hideCursor()
17    if cursor:isVisible() then
18        cursor:hide()
19    end
20end
21
22function showCursor()
23    if not cursor:isVisible() and inputMgr:isMouseExclusive() then
24        cursor:show()
25    end
26end
27
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
43-- ?
44function showMenuSheet(name, bHidePrevious, bNoInput, ptr)
45    local sheet = showMenuSheet(name, bHidePrevious, bNoInput)
46    sheet.overlay = ptr
47    return sheet
48end
49
50-- Shows the specified menu sheet and loads it if neccessary
51function showMenuSheet(name, bHidePrevious, bNoInput)
52    if name == "" then
53        return nil
54    end
55    -- Get sheet (or load it)
56    local menuSheet = loadSheet(name)
57
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
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.
70    local counter = noInputSheetIndex()
71    -- Pause game control if this is the first menu to be displayed
72    -- HUGE HACK?
73    if bNoInput == false and counter == 0 then
74        orxonox.HumanController:pauseControl()
75    end
76
77    -- Hide if already displayed (to make sure it is up front in the end)
78    if activeMenuSheets[name] ~= nil then
79        hideMenuSheet(name)
80    end
81
82    if bNoInput == true then
83        menuSheet.tShowCursor = TriBool.Dontcare
84    end
85
86    -- Add the sheet in a tuple of additional information
87    local sheetTuple =
88    {
89        ["sheet"]          = menuSheet,
90        ["bHidePrevious"]  = bHidePrevious,
91        ["bNoInput"]       = bNoInput,
92        ["name"]           = name
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
99    -- Add sheet to the root window
100    menuSheetsRoot:addChildWindow(menuSheet.window)
101
102    -- If sheet is the MainMenu
103    if name == "MainMenu" then
104        mainMenuLoaded = true
105    end
106
107    -- Handle input distribution
108    if bNoInput == false then
109        inputMgr:enterState(menuSheet.inputState)
110    end
111
112    -- Only change cursor situation if menuSheet.tShowCursor ~= TriBool.Dontcare
113    if menuSheet.tShowCursor == TriBool.True then
114        showCursor()
115    elseif menuSheet.tShowCursor == TriBool.False then
116        hideCursor()
117    end
118
119    -- Hide all previous sheets if necessary
120    local previous
121    if bHidePrevious then
122        for i = 1, activeMenuSheets.size - 1 do
123            previous = activeMenuSheets[i].sheet
124            previous:hide()
125        end
126    end
127
128    menuSheet:show()
129    menuSheetsRoot:activate()
130
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
136    return menuSheet
137end
138
139function hideMenuSheet(name)
140    local sheetTuple = activeMenuSheets[name]
141    if sheetTuple == nil then
142        return
143    end
144
145    -- Hide the sheet
146    sheetTuple.sheet:hide()
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
151    -- have bHidePrevious == true and sheetTuple.bHidePrevious == true
152    while i > 0 do
153        if activeMenuSheets[i].bHidePrevious then
154            if activeMenuSheets[i] == sheetTuple then
155                i = i - 1
156                while i > 0 do
157                    activeMenuSheets[i].sheet:show()
158                    if activeMenuSheets[i].bHidePrevious then
159                        break
160                    end
161                    i = i - 1
162                end
163            end
164            break
165        end
166        i = i - 1
167    end
168
169    -- Remove sheet with its tuple from the table
170    menuSheetsRoot:removeChildWindow(sheetTuple.sheet.window)
171    table.remove(activeMenuSheets, table.findIndex(activeMenuSheets, sheetTuple))
172    activeMenuSheets[name] = nil
173    activeMenuSheets.size = activeMenuSheets.size - 1
174    activeMenuSheets.topSheetTuple = activeMenuSheets[activeMenuSheets.size]
175
176    -- If sheet is the MainMenu
177    if name == "MainMenu" then
178        mainMenuLoaded = false
179    end
180
181    -- Leave the input state
182    if not sheetTuple.bNoInput then
183        inputMgr:leaveState(sheetTuple.sheet.inputState)
184    end
185
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
193        showCursor()
194    else
195        hideCursor()
196    end
197
198    -- Count the number of sheets that don't need input till the first that does.
199    local counter = noInputSheetIndex()
200    -- Resume control if the last (non-noInput) menu is hidden
201    if counter == 0 then
202        orxonox.HumanController:resumeControl()
203        hideCursor()
204    end
205
206    sheetTuple.sheet:quit()
207end
208
209-- Hides all menu GUI sheets
210function hideAllMenuSheets()
211    while activeMenuSheets.size ~= 0 do
212        hideMenuSheet(activeMenuSheets.topSheetTuple.sheet.name)
213    end
214end
215
216function keyESC()
217    -- HUGE, very HUGE hacks!
218
219    -- If the InGameConsole is active, ignore the ESC command.
220    if bInGameConsoleClosed == true then
221        bInGameConsoleClosed = false
222        if activeMenuSheets[1] and activeMenuSheets[1].sheet.name == "MainMenu" then
223            return
224        end
225    end
226
227    -- Count the number of sheets that don't need input till the first that does.
228    local counter = noInputSheetIndex()
229
230    -- If the first sheet that needs input is the MainMenu.
231    if noInputSheetCounter() == 1 and activeMenuSheets[counter].sheet.name == "MainMenu" then
232        orxonox.execute("exit")
233    -- If there is at least one sheet that needs input.
234    elseif counter > 0 then
235        orxonox.execute("hideGUI "..activeMenuSheets[counter].sheet.name)
236    else
237        showMenuSheet("InGameMenu")
238    end
239end
240
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
250            orxonox.CommandExecutor:execute("InGameConsole openConsole")
251        end
252    end
253    sheet.sheet:keyPressed()
254end
255
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
275function setBackgroundImage(imageSet, imageName)
276    guiMgr:setBackgroundImage(imageSet, imageName)
277end
278
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
288function noInputSheetCounter()
289    -- Count the number of sheets that do need input.
290    local counter = activeMenuSheets.size
291    for i = 1,activeMenuSheets.size do
292        if activeMenuSheets[i].bNoInput then
293            counter = counter - 1
294        end
295    end
296    return counter
297end
298
299function inGameConsoleClosed()
300    bInGameConsoleClosed = not bInGameConsoleClosed;
301end
302
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
313----------------------
314--- Initialisation ---
315----------------------
316
317hideCursor()
Note: See TracBrowser for help on using the repository browser.