Leviathan  0.8.0.0
Leviathan game engine
Leviathan::GUI::GuiManager Class Reference

GUI controller for a Window. More...

#include <GuiManager.h>

Classes

struct  CutscenePlayStatus
 

Public Member Functions

DLLEXPORT GuiManager ()
 
DLLEXPORT ~GuiManager ()
 
DLLEXPORT bool Init (Graphics *graph, Window *window)
 
DLLEXPORT void Release ()
 
DLLEXPORT void GuiTick (float elapsed)
 
DLLEXPORT void Render (float elapsed)
 
DLLEXPORT void OnResize ()
 Notifies internal browsers. More...
 
DLLEXPORT void OnFocusChanged (bool focused)
 Notifies contexts about the change to appropriately lose focus on fields. More...
 
DLLEXPORT bool LoadGUIFile (const std::string &urlorpath, bool nochangelistener=false)
 Loads a GUI file. More...
 
DLLEXPORT void PlayCutscene (const std::string &file, std::function< void()> onfinished, std::function< void(const std::string &)> onerror, bool allowskip=true)
 Creates a new GUI layer that uses a widget layout. More...
 
DLLEXPORT void CancelCutscene ()
 Cancels a playing video started by PlayCutscene. More...
 
DLLEXPORT LayerGetTargetLayerForInput (INPUT_EVENT_TYPE type, int mousex, int mousey)
 Returns the Layer that should receive the event. More...
 
DLLEXPORT auto GetLayerCount () const
 Returns the Layer count. More...
 
DLLEXPORT LayerGetLayerByIndex (size_t index)
 Gets a Layer by index. More...
 
DLLEXPORT void OnForceGUIOn ()
 
DLLEXPORT void SetDisableMouseCapture (bool newvalue)
 If true the GUI will be inactive and things like mouse movement will be passed to the player movement (but key presses goe through the GUI so that it can react to GUI activation buttons) More...
 
DLLEXPORT void NotifyAboutLayer (int layernumber, const bs::HTexture &texture)
 This is a temporary thing to just render a few image layers with BSF. More...
 

Protected Member Functions

void _FileChanged (const std::string &file, ResourceFolderListener &caller)
 Is called by folder listeners to notify of Gui file changes. More...
 
void _SendChangedLayers () const
 

Detailed Description

GUI controller for a Window.

Definition at line 20 of file GuiManager.h.

Constructor & Destructor Documentation

◆ GuiManager()

GuiManager::GuiManager ( )

Definition at line 39 of file GuiManager.cpp.

39 : ID(IDFactory::GetID()), GuiViewCounter(0) {}
static int GetID()
Definition: IDFactory.h:17

◆ ~GuiManager()

GuiManager::~GuiManager ( )

Definition at line 40 of file GuiManager.cpp.

40 {}

Member Function Documentation

◆ _FileChanged()

void GuiManager::_FileChanged ( const std::string &  file,
ResourceFolderListener caller 
)
protected

Is called by folder listeners to notify of Gui file changes.

Definition at line 347 of file GuiManager.cpp.

348 {
349  // Any updated file will cause whole reload //
350  LOG_WRITE("TODO: invoke file reload on main thread");
351  //
352 
353  // ReloadQueued = true;
354 
355  // // Mark everything as non-updated //
356  // caller.MarkAllAsNotUpdated();
357 }
#define LOG_WRITE(x)
Definition: Define.h:93

◆ _SendChangedLayers()

void GuiManager::_SendChangedLayers ( ) const
protected

Definition at line 365 of file GuiManager.cpp.

366 {
367  std::vector<bs::SPtr<bs::Texture>> overlays;
368 
369  for(auto iter = TempRenderedLayers.begin(); iter != TempRenderedLayers.end(); ++iter) {
370  if(iter->second) {
371  overlays.push_back(iter->second.getInternalPtr());
372  }
373  }
374 
375  Engine::Get()->GetGraphics()->UpdateShownOverlays(*ThisWindow->GetBSFWindow(), overlays);
376 }
DLLEXPORT const auto & GetBSFWindow() const
Definition: Window.h:166
DLLEXPORT void UpdateShownOverlays(bs::RenderTarget &target, const std::vector< bs::SPtr< bs::Texture >> &overlays)
Definition: Graphics.cpp:548
Graphics * GetGraphics()
Definition: Engine.h:185
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:86

◆ CancelCutscene()

DLLEXPORT void GuiManager::CancelCutscene ( )

Cancels a playing video started by PlayCutscene.

Definition at line 274 of file GuiManager.cpp.

275 {
276  if(CurrentlyPlayingCutscene) {
277 
278  // Just stop it and that will destroy it on next tick (immediately after this call a
279  // new video can be played)
280  CurrentlyPlayingCutscene->Player->Stop();
281  }
282 }

◆ GetLayerByIndex()

DLLEXPORT Layer * Leviathan::GUI::GuiManager::GetLayerByIndex ( size_t  index)

Gets a Layer by index.

Note
The pointer is only safe to hang onto until UnLoadGUIFile is called

Definition at line 284 of file GuiManager.cpp.

285 {
286  if(index >= ManagedLayers.size())
287  return nullptr;
288 
289  return ManagedLayers[index].get();
290 }

◆ GetLayerCount()

DLLEXPORT auto Leviathan::GUI::GuiManager::GetLayerCount ( ) const
inline

Returns the Layer count.

Definition at line 71 of file GuiManager.h.

72  {
73  return ManagedLayers.size();
74  }

◆ GetTargetLayerForInput()

DLLEXPORT Layer * Leviathan::GUI::GuiManager::GetTargetLayerForInput ( INPUT_EVENT_TYPE  type,
int  mousex,
int  mousey 
)

Returns the Layer that should receive the event.

See also
Window::GetGUIEventReceiver
Todo:
Add support for multiple views inside a window. And prefer the active input if this is a keypress

Definition at line 292 of file GuiManager.cpp.

294 {
295  Layer* bestFound = nullptr;
296 
297  for(size_t i = 0; i < ManagedLayers.size(); i++) {
298 
299  Layer* view = ManagedLayers[i].get();
300 
301  const auto mode = view->GetInputMode();
302  if(mode == INPUT_MODE::None)
303  continue;
304 
305  // TODO: coordinate check
306 
307  // TODO: proper Z-order and mouse position checking should be done
308  if(mode == INPUT_MODE::Menu &&
309  (!bestFound || bestFound->GetInputMode() != INPUT_MODE::Menu)) {
310 
311  bestFound = view;
312  continue;
313  }
314 
315  // The mode Gameplay is only best if nothing has been found so far
316  if(bestFound)
317  continue;
318 
319  LEVIATHAN_ASSERT(mode == INPUT_MODE::Gameplay, "Some input mode is not handled");
320 
321  // Allow mouse events except scroll but keyboard events are
322  // only allowed if a text box is focused
323  if(type == INPUT_EVENT_TYPE::Keypress) {
324 
325  if(view->HasFocusedInputElement()) {
326 
327  bestFound = view;
328  continue;
329  }
330  } else if(type == INPUT_EVENT_TYPE::Scroll) {
331 
332  // Allow scroll events when over something scrollable
333  if(view->HasScrollableElementUnderCursor()) {
334  bestFound = view;
335  continue;
336  }
337  } else {
338 
339  // Mouse movement
340  bestFound = view;
341  }
342  }
343 
344  return bestFound;
345 }
DLLEXPORT bool HasScrollableElementUnderCursor() const
Definition: GuiLayer.h:70
In this mode the View doesn't take any input under any circumstances.
Base class for WidgetLayer and View (browser containers / CEF) to add to a GuiManager.
Definition: GuiLayer.h:18
DLLEXPORT bool HasFocusedInputElement() const
Definition: GuiLayer.h:64
virtual DLLEXPORT INPUT_MODE GetInputMode() const
Definition: GuiLayer.h:58
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:100
In this mode the View takes all key press events.

◆ GuiTick()

void GuiManager::GuiTick ( float  elapsed)

Definition at line 84 of file GuiManager.cpp.

85 {
86  if(ReloadQueued) {
87 
88  ReloadQueued = false;
89 
90  // Reload //
91  LOG_INFO("GuiManager: reloading file: " + MainGUIFile);
92  DEBUG_BREAK;
93 
94  // Now load it //
95  if(!LoadGUIFile(MainGUIFile, true)) {
96 
97  Logger::Get()->Error(
98  "GuiManager: file changed: couldn't load updated file: " + MainGUIFile);
99  }
100 
101  // Apply back the old states //
102  // ApplyGuiStates(currentstate.get());
103  }
104 
105  // check if we want mouse //
106  if(GuiMouseUseUpdated) {
107 
108  GuiMouseUseUpdated = false;
109 
110  if(GuiDisallowMouseCapture) {
111  // disable mouse capture //
112  ThisWindow->SetMouseCapture(false);
113 
114  // Show the cursor
115  LOG_WRITE("TODO: this needs some property when a custom cursor is used");
116  ThisWindow->SetHideCursor(false);
117 
118  } else {
119 
120  // activate direct mouse capture //
121  if(!ThisWindow->SetMouseCapture(true)) {
122  // failed, GUI must be forced to stay on //
123  OnForceGUIOn();
124  GuiDisallowMouseCapture = true;
125  GuiMouseUseUpdated = true;
126  } else {
127  // Success, hide GUI cursor
128  ThisWindow->SetHideCursor(true);
129  DEBUG_BREAK;
130  // GuiContext->getCursor().hide();
131  }
132  }
133  }
134 }
#define LOG_INFO(x)
Definition: Define.h:90
DLLEXPORT void SetHideCursor(bool toset)
Definition: Window.cpp:784
DLLEXPORT bool LoadGUIFile(const std::string &urlorpath, bool nochangelistener=false)
Loads a GUI file.
Definition: GuiManager.cpp:171
DLLEXPORT void OnForceGUIOn()
Definition: GuiManager.cpp:136
#define LOG_WRITE(x)
Definition: Define.h:93
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT bool SetMouseCapture(bool state)
Definition: Window.cpp:747
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177

◆ Init()

bool GuiManager::Init ( Graphics graph,
Window window 
)

Definition at line 42 of file GuiManager.cpp.

43 {
44  ThisWindow = window;
45 
46  // All rendering is now handled by individual Layers and the
47  // Window full screen compositor passes
48 
49  return true;
50 }

◆ LoadGUIFile()

DLLEXPORT bool GuiManager::LoadGUIFile ( const std::string &  urlorpath,
bool  nochangelistener = false 
)

Loads a GUI file.

Todo:
Make sure that loading a path with spaces in it works
Note
This is the CEF version of a GUI layer

Definition at line 171 of file GuiManager.cpp.

172 {
173  MainGUIFile = urlorpath;
174 
175  // Create the view //
176  boost::intrusive_ptr<View> loadingView(new View(this, ThisWindow, GuiViewCounter++));
177 
178  // Create the final page //
179  std::string finalpath;
180 
181  // If this is an internet page pass it unmodified //
182  if(urlorpath.find("http") < 2 || urlorpath.find("file://") < 2) {
183 
184  finalpath = urlorpath;
185  } else {
186  // Local file, add to the end //
187  if(!boost::filesystem::exists(urlorpath)) {
188  LOG_ERROR("GuiManager: LoadGUIFile: failed to get canonical path (is "
189  "the file missing?) for file: " +
190  urlorpath);
191  return false;
192  }
193 
194  // TODO: Probably needs to convert spaces here
195  finalpath = StringOperations::CombineURL("http://leviathan-local/", urlorpath);
196  }
197 
198  LOG_INFO("GuiManager: loading GUI: " + finalpath);
199 
200  // TODO: extra configuration
201  NamedVars varlist;
202 
203  // Initialize it //
204  if(!loadingView->Init(finalpath, varlist)) {
205 
206  loadingView->ReleaseResources();
207  loadingView->Release();
208 
209  Logger::Get()->Error(
210  "GuiManager: LoadGUIFile: failed to initialize view for file: " + urlorpath);
211  return false;
212  }
213 
214  // Add the page //
215  ManagedLayers.push_back(loadingView);
216 
217  // Set focus to the new Layer //
218  ManagedLayers.back()->NotifyFocusUpdate(ThisWindow->IsWindowFocused());
219  return true;
220 }
static DLLEXPORT std::string CombineURL(const std::string &first, const std::string &second)
#define LOG_INFO(x)
Definition: Define.h:90
DLLEXPORT bool IsWindowFocused() const
Returns whether this window is focused.
Definition: Window.h:137
#define LOG_ERROR(x)
Definition: Define.h:92
FORCE_INLINE void Release() const
removes a reference and deletes the object if reference count reaches zero
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177
A class that represents a single GUI layer that has it's own chromium browser.
Definition: GuiView.h:53

◆ NotifyAboutLayer()

DLLEXPORT void GuiManager::NotifyAboutLayer ( int  layernumber,
const bs::HTexture &  texture 
)

This is a temporary thing to just render a few image layers with BSF.

Definition at line 359 of file GuiManager.cpp.

360 {
361  TempRenderedLayers[layernumber] = texture;
363 }
void _SendChangedLayers() const
Definition: GuiManager.cpp:365

◆ OnFocusChanged()

DLLEXPORT void GuiManager::OnFocusChanged ( bool  focused)

Notifies contexts about the change to appropriately lose focus on fields.

Definition at line 163 of file GuiManager.cpp.

164 {
165  // Notify all CEF browsers on this window //
166  for(size_t i = 0; i < ManagedLayers.size(); i++) {
167  ManagedLayers[i]->NotifyFocusUpdate(focused);
168  }
169 }

◆ OnForceGUIOn()

DLLEXPORT void GuiManager::OnForceGUIOn ( )

Definition at line 136 of file GuiManager.cpp.

137 {
138  DEBUG_BREAK;
139 }

◆ OnResize()

DLLEXPORT void GuiManager::OnResize ( )

Notifies internal browsers.

Definition at line 155 of file GuiManager.cpp.

156 {
157  // Resize all CEF browsers on this window //
158  for(size_t i = 0; i < ManagedLayers.size(); i++) {
159  ManagedLayers[i]->NotifyWindowResized();
160  }
161 }

◆ PlayCutscene()

DLLEXPORT void GuiManager::PlayCutscene ( const std::string &  file,
std::function< void()>  onfinished,
std::function< void(const std::string &)>  onerror,
bool  allowskip = true 
)

Creates a new GUI layer that uses a widget layout.

Parameters
layoutnameThe name of the layout file to load. If "" then creates an empty layer
Createsa new Widget Layer and plays a fullscreen video in it

This is a pretty huge function and the functionality should maybe split more

Parameters
onfinishedCallback called when the video finishes or the user has skipped it
onerrorCallback for when an error occurs and the file can't be played. Only one of these callbacks is called

Definition at line 222 of file GuiManager.cpp.

225 {
226  if(CurrentlyPlayingCutscene) {
227  LOG_ERROR("GuiManager: PlayCutscene: can't play multiple cutscenes at the same time");
228 
229  onerror("can't play multiple cutscenes at the same time");
230  return;
231  }
232 
233  if(!boost::filesystem::exists(file)) {
234  onerror("file doesn't exist");
235  return;
236  }
237 
238  auto container = WidgetLayer::MakeShared<WidgetLayer>(this, ThisWindow, GuiViewCounter++);
239 
240  auto player = VideoPlayerWidget::MakeShared<VideoPlayerWidget>();
241 
242  container->AddWidget(player);
243 
244  player->SetEndCallback([=]() {
245  // TODO: figure out if an error happened
246  CurrentlyPlayingCutscene.reset();
247 
248  for(auto iter = ManagedLayers.begin(); iter != ManagedLayers.end(); ++iter) {
249 
250  if(*iter == container) {
251  (*iter)->ReleaseResources();
252  ManagedLayers.erase(iter);
253  break;
254  }
255  }
256 
257  onfinished();
258 
259  // Due to release order we do clear the callback like this to destroy the player object
260  // later
261  Engine::Get()->Invoke([=]() { player->SetEndCallback(nullptr); });
262  });
263 
264  player->Play(file);
265 
266  ManagedLayers.push_back(container);
267 
268  CurrentlyPlayingCutscene = std::make_unique<CutscenePlayStatus>(player);
269 
270  // TODO: focus setting and also focus fixing when popping
271  // ManagedLayers.back()->NotifyFocusUpdate(ThisWindow->IsWindowFocused());
272 }
DLLEXPORT void Invoke(const std::function< void()> &function)
Runs function on the main thread before the next tick.
Definition: Engine.cpp:1169
#define LOG_ERROR(x)
Definition: Define.h:92
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:86

◆ Release()

void GuiManager::Release ( )

Definition at line 52 of file GuiManager.cpp.

53 {
54  // Stop with the file updates //
55  if(FileChangeID) {
56 
57  auto tmphandler = ResourceRefreshHandler::Get();
58 
59  if(tmphandler) {
60 
61  tmphandler->StopListeningForFileChanges(FileChangeID);
62  }
63 
64  FileChangeID = 0;
65  }
66 
67  // // Default mouse back //
68  // // show default window cursor //
69  // ThisWindow->SetHideCursor(false);
70 
71  // Destroy the views //
72  for(size_t i = 0; i < ManagedLayers.size(); i++) {
73 
74  ManagedLayers[i]->ReleaseResources();
75  ManagedLayers[i]->Release();
76  }
77 
78  TempRenderedLayers.clear();
80 
81  LOG_INFO("GuiManager: Gui successfully closed on window");
82 }
#define LOG_INFO(x)
Definition: Define.h:90
static DLLEXPORT ResourceRefreshHandler * Get()
void _SendChangedLayers() const
Definition: GuiManager.cpp:365

◆ Render()

void GuiManager::Render ( float  elapsed)

Definition at line 149 of file GuiManager.cpp.

150 {
151  // Browser textures are now updated in the event loop (on the main thread between
152  // rendering)
153 }

◆ SetDisableMouseCapture()

DLLEXPORT void GuiManager::SetDisableMouseCapture ( bool  newvalue)

If true the GUI will be inactive and things like mouse movement will be passed to the player movement (but key presses goe through the GUI so that it can react to GUI activation buttons)

Definition at line 141 of file GuiManager.cpp.

142 {
143  DisableGuiMouseCapture = newvalue;
144  // This will cause the capture state to be checked next tick
145  GuiMouseUseUpdated = true;
146 }

The documentation for this class was generated from the following files: