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