1 /*
2  * \file   Gui.cpp
3  * \date   05 April 2011
4  * \author StefanP.MUC
5  * \brief  Class Gui containing all the stuff for the GUI, including translation.
6  *
7  *  Copyright (C) 2011-2016  OpenDungeons Team
8  *
9  *  This program is free software: you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation, either version 3 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include "render/Gui.h"
24 
25 #include "ODApplication.h"
26 #include "sound/SoundEffectsManager.h"
27 #include "utils/LogManager.h"
28 
29 #include <CEGUI/CEGUI.h>
30 #include <CEGUI/RendererModules/Ogre/Renderer.h>
31 #include <CEGUI/RendererModules/Ogre/ResourceProvider.h>
32 #include <CEGUI/RendererModules/Ogre/ImageCodec.h>
33 #include <CEGUI/SchemeManager.h>
34 #include <CEGUI/System.h>
35 #include <CEGUI/WindowManager.h>
36 #include <CEGUI/widgets/PushButton.h>
37 #include <CEGUI/Event.h>
38 
Gui(SoundEffectsManager * soundEffectsManager,const std::string & ceguiLogFileName)39 Gui::Gui(SoundEffectsManager* soundEffectsManager, const std::string& ceguiLogFileName)
40   : mSoundEffectsManager(soundEffectsManager)
41 {
42     OD_LOG_INF("*** Initializing CEGUI ***");
43     CEGUI::OgreRenderer& renderer = CEGUI::OgreRenderer::create();
44     OD_LOG_INF("OgreRenderer created");
45     CEGUI::OgreResourceProvider& rp = CEGUI::OgreRenderer::createOgreResourceProvider();
46     OD_LOG_INF("OgreResourceProvider created");
47     CEGUI::OgreImageCodec& ic = CEGUI::OgreRenderer::createOgreImageCodec();
48     OD_LOG_INF("OgreImageCodec created");
49     CEGUI::System::create(renderer, &rp, static_cast<CEGUI::XMLParser*>(nullptr), &ic, nullptr, "",
50                           reinterpret_cast<const CEGUI::utf8*>(ceguiLogFileName.c_str()));
51     OD_LOG_INF("CEGUI::System created");
52 
53     CEGUI::SchemeManager::getSingleton().createFromFile("ODSkin.scheme");
54     OD_LOG_INF("CEGUI::SchemeManager created");
55 
56     // We want Ogre overlays to be displayed in front of CEGUI. According to
57     // http://cegui.org.uk/forum/viewtopic.php?f=10&t=5694
58     // the best way is to disable CEGUI auto rendering by calling setFrameControlExecutionEnabled
59     // and render CEGUI in an Ogre::RenderQueueListener (done in ODFrameListener) by calling
60     // CEGUI::System::getSingleton().renderAllGUIContexts();
61     renderer.setFrameControlExecutionEnabled(false);
62 
63     // Needed to get the correct offset when using up to CEGUI 0.8.4
64     // We're thus using an empty mouse cursor.
65     CEGUI::GUIContext& context = CEGUI::System::getSingleton().getDefaultGUIContext();
66     context.getMouseCursor().setDefaultImage("OpenDungeonsSkin/MouseArrow");
67     context.getMouseCursor().setVisible(true);
68     context.setDefaultTooltipType("OD/Tooltip");
69     CEGUI::WindowManager* wmgr = CEGUI::WindowManager::getSingletonPtr();
70     mSheets[hideGui] = wmgr->createWindow("DefaultWindow", "DummyWindow");
71     mSheets[inGameMenu] = wmgr->loadLayoutFromFile("ModeGame.layout");
72     mSheets[mainMenu] = wmgr->loadLayoutFromFile("MenuMain.layout");
73     mSheets[skirmishMenu] = wmgr->loadLayoutFromFile("MenuSkirmish.layout");
74     mSheets[multiplayerClientMenu] = wmgr->loadLayoutFromFile("MenuMultiplayerClient.layout");
75     mSheets[multiplayerServerMenu] = wmgr->loadLayoutFromFile("MenuMultiplayerServer.layout");
76     mSheets[multiMasterServerJoinMenu] = wmgr->loadLayoutFromFile("MenuMasterServerJoin.layout");
77     mSheets[editorModeGui] =  wmgr->loadLayoutFromFile("ModeEditor.layout");
78     mSheets[editorNewMenu] =  wmgr->loadLayoutFromFile("MenuEditorNew.layout");
79     mSheets[editorLoadMenu] =  wmgr->loadLayoutFromFile("MenuEditorLoad.layout");
80     mSheets[configureSeats] =  wmgr->loadLayoutFromFile("MenuConfigureSeats.layout");
81     mSheets[replayMenu] =  wmgr->loadLayoutFromFile("MenuReplay.layout");
82     mSheets[loadSavedGameMenu] =  wmgr->loadLayoutFromFile("MenuLoad.layout");
83     mSheets[console] = wmgr->loadLayoutFromFile("WindowConsole.layout");
84 
85     // Set the game version
86     mSheets[mainMenu]->getChild("VersionText")->setText(ODApplication::VERSION);
87     mSheets[skirmishMenu]->getChild("VersionText")->setText(ODApplication::VERSION);
88     mSheets[multiplayerServerMenu]->getChild("VersionText")->setText(ODApplication::VERSION);
89     mSheets[multiplayerClientMenu]->getChild("VersionText")->setText(ODApplication::VERSION);
90     mSheets[editorNewMenu]->getChild("VersionText")->setText(ODApplication::VERSION);
91     mSheets[editorLoadMenu]->getChild("VersionText")->setText(ODApplication::VERSION);
92     mSheets[replayMenu]->getChild("VersionText")->setText(ODApplication::VERSION);
93     mSheets[loadSavedGameMenu]->getChild("VersionText")->setText(ODApplication::VERSION);
94     mSheets[multiMasterServerJoinMenu]->getChild("VersionText")->setText(ODApplication::VERSION);
95 
96     // Add sound to button clicks
97     CEGUI::GlobalEventSet& ges = CEGUI::GlobalEventSet::getSingleton();
98     ges.subscribeEvent(
99         CEGUI::PushButton::EventNamespace + "/" + CEGUI::PushButton::EventClicked,
100         CEGUI::Event::Subscriber(&Gui::playButtonClickSound, this));
101 }
102 
~Gui()103 Gui::~Gui()
104 {
105     //This also calls CEGUI::System::destroy();
106     CEGUI::OgreRenderer::destroySystem();
107 }
108 
convertButton(OIS::MouseButtonID buttonID)109 CEGUI::MouseButton Gui::convertButton(OIS::MouseButtonID buttonID)
110 {
111     //OIS has 2 more button ids than CEGUI.
112     if(static_cast<int>(buttonID) < static_cast<int>(CEGUI::MouseButton::MouseButtonCount))
113         return static_cast<CEGUI::MouseButton>(buttonID);
114     return CEGUI::MouseButton::NoButton;
115 }
116 
loadGuiSheet(guiSheet newSheet)117 void Gui::loadGuiSheet(guiSheet newSheet)
118 {
119     CEGUI::System::getSingletonPtr()->getDefaultGUIContext().setRootWindow(mSheets[newSheet]);
120     // This shouldn't be needed, but the gui seems to not allways change when using hideGui without it.
121     CEGUI::System::getSingletonPtr()->getDefaultGUIContext().markAsDirty();
122 }
123 
getGuiSheet(guiSheet sheet)124 CEGUI::Window* Gui::getGuiSheet(guiSheet sheet)
125 {
126     auto it = mSheets.find(sheet);
127     if(it != mSheets.end())
128     {
129         return it->second;
130     }
131     return nullptr;
132 }
133 
playButtonClickSound(const CEGUI::EventArgs &)134 bool Gui::playButtonClickSound(const CEGUI::EventArgs&)
135 {
136     mSoundEffectsManager->playRelativeSound(SoundRelativeInterface::Click);
137     return true;
138 }
139 
140 /* These constants are used to access the GUI element
141  * NOTE: when add/remove/rename a GUI element, don't forget to change it here
142  */
143 const std::string Gui::DISPLAY_GOLD = "HorizontalPipe/GoldDisplay";
144 const std::string Gui::DISPLAY_MANA = "HorizontalPipe/ManaDisplay";
145 const std::string Gui::DISPLAY_TERRITORY = "HorizontalPipe/TerritoryDisplay";
146 const std::string Gui::DISPLAY_CREATURES = "HorizontalPipe/CreaturesDisplay";
147 const std::string Gui::MINIMAP = "MiniMap";
148 const std::string Gui::OBJECTIVE_TEXT = "ObjectivesWindow/ObjectivesText";
149 const std::string Gui::MAIN_TABCONTROL = "MainTabControl";
150 const std::string Gui::TAB_ROOMS = "MainTabControl/Rooms";
151 const std::string Gui::BUTTON_TEMPLE = "MainTabControl/Rooms/TempleButton";
152 const std::string Gui::BUTTON_PORTAL = "MainTabControl/Rooms/PortalButton";
153 const std::string Gui::BUTTON_DESTROY_ROOM = "MainTabControl/Rooms/DestroyRoomButton";
154 const std::string Gui::TAB_TRAPS = "MainTabControl/Traps";
155 const std::string Gui::BUTTON_DESTROY_TRAP = "MainTabControl/Traps/DestroyTrapButton";
156 const std::string Gui::TAB_SPELLS = "MainTabControl/Spells";
157 const std::string Gui::TAB_CREATURES = "MainTabControl/Creatures";
158 const std::string Gui::BUTTON_CREATURE_WORKER = "MainTabControl/Creatures/WorkerButton";
159 const std::string Gui::BUTTON_CREATURE_FIGHTER = "MainTabControl/Creatures/FighterButton";
160 const std::string Gui::TAB_COMBAT = "MainTabControl/Combat";
161 
162 const std::string Gui::MM_BACKGROUND = "Background";
163 const std::string Gui::MM_WELCOME_MESSAGE = "WelcomeBanner";
164 const std::string Gui::EXIT_CONFIRMATION_POPUP = "ConfirmExit";
165 const std::string Gui::EXIT_CONFIRMATION_POPUP_YES_BUTTON = "ConfirmExit/YesOption";
166 const std::string Gui::EXIT_CONFIRMATION_POPUP_NO_BUTTON = "ConfirmExit/NoOption";
167 
168 const std::string Gui::SKM_TEXT_LOADING = "LoadingText";
169 const std::string Gui::SKM_BUTTON_LAUNCH = "LevelWindowFrame/LaunchGameButton";
170 const std::string Gui::SKM_BUTTON_BACK = "LevelWindowFrame/BackButton";
171 const std::string Gui::SKM_LIST_LEVEL_TYPES = "LevelWindowFrame/LevelTypeSelect";
172 const std::string Gui::SKM_LIST_LEVELS = "LevelWindowFrame/LevelSelect";
173 
174 const std::string Gui::MPM_TEXT_LOADING = "LoadingText";
175 const std::string Gui::MPM_BUTTON_SERVER = "LevelWindowFrame/ServerButton";
176 const std::string Gui::MPM_BUTTON_CLIENT = "LevelWindowFrame/ClientButton";
177 const std::string Gui::MPM_BUTTON_BACK = "LevelWindowFrame/BackButton";
178 const std::string Gui::MPM_LIST_LEVELS = "LevelWindowFrame/LevelSelect";
179 const std::string Gui::MPM_EDIT_IP = "LevelWindowFrame/IpEdit";
180 const std::string Gui::MPM_EDIT_NICK = "LevelWindowFrame/NickEdit";
181 
182 const std::string Gui::EDM_TEXT_LOADING = "LoadingText";
183 const std::string Gui::EDM_BUTTON_LAUNCH = "LevelWindowFrame/LaunchEditorButton";
184 const std::string Gui::EDM_BUTTON_BACK = "LevelWindowFrame/BackButton";
185 const std::string Gui::EDM_LIST_LEVELS = "LevelWindowFrame/LevelSelect";
186 const std::string Gui::EDM_LIST_LEVEL_TYPES = "LevelWindowFrame/LevelTypeSelect";
187 
188 const std::string Gui::EDITOR = "MainTabControl";
189 const std::string Gui::EDITOR_LAVA_BUTTON = "MainTabControl/Tiles/LavaButton";
190 const std::string Gui::EDITOR_GOLD_BUTTON = "MainTabControl/Tiles/GoldButton";
191 const std::string Gui::EDITOR_DIRT_BUTTON = "MainTabControl/Tiles/DirtButton";
192 const std::string Gui::EDITOR_WATER_BUTTON = "MainTabControl/Tiles/WaterButton";
193 const std::string Gui::EDITOR_ROCK_BUTTON = "MainTabControl/Tiles/RockButton";
194 const std::string Gui::EDITOR_CLAIMED_BUTTON = "MainTabControl/Tiles/ClaimedButton";
195 const std::string Gui::EDITOR_GEM_BUTTON = "MainTabControl/Tiles/GemButton";
196 const std::string Gui::EDITOR_FULLNESS = "HorizontalPipe/FullnessDisplay";
197 const std::string Gui::EDITOR_CURSOR_POS = "HorizontalPipe/PositionDisplay";
198 const std::string Gui::EDITOR_SEAT_ID = "HorizontalPipe/SeatIdDisplay";
199 const std::string Gui::EDITOR_CREATURE_SPAWN = "HorizontalPipe/CreatureSpawnDisplay";
200 const std::string Gui::EDITOR_MAPLIGHT_BUTTON = "MainTabControl/Lights/MapLightButton";
201 
202 const std::string Gui::REM_TEXT_LOADING = "LoadingText";
203 const std::string Gui::REM_BUTTON_LAUNCH = "LevelWindowFrame/LaunchReplayButton";
204 const std::string Gui::REM_BUTTON_DELETE = "LevelWindowFrame/DeleteReplayButton";
205 const std::string Gui::REM_BUTTON_BACK = "LevelWindowFrame/BackButton";
206 const std::string Gui::REM_LIST_REPLAYS = "LevelWindowFrame/ReplaySelect";
207