Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/usability/data/gui/scripts/SheetManager.lua @ 8040

Last change on this file since 8040 was 8035, checked in by dafrick, 14 years ago

Replacing hard coded keys for the menu navigation with keys specified in the keybindings.ini file (note: You have to delete your keybindings.ini file for it to be regenerated and work correctly).
The upside is, that now we need less hackish, stuff, it's better integrated, toggling of OrxonoxOverlays (e.g. QuestGUI and PickupInventory, among others) is working again. Closing the InGameConsole with ESC no longer requires a workaround to work.
The downside is, that now GUI sheets that require input, e.g. GraphicsMenu or MiscConfigMenu, no longer support menu navigation and ESC doesn't work there. However, I don't know how to work around that, yet. But since all that ESC business is a hack anyway, I'd rather have the hacks there…

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