Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/data/gui/scripts/SheetManager.lua @ 8584

Last change on this file since 8584 was 8584, checked in by dafrick, 13 years ago

Apparently this bug was already fixed by landauf in the trunk. So let's fix it here, the same way he did.

  • 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[i] 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.