Leviathan  0.8.0.0
Leviathan game engine
Leviathan::Window Class Reference

#include <Window.h>

Public Member Functions

DLLEXPORT Window (Graphics *windowcreater, AppDef *windowproperties)
 
DLLEXPORT ~Window ()
 
DLLEXPORT void Tick (int mspassed)
 Called by Engine. More...
 
DLLEXPORT bool Render (int mspassed, int tick, int timeintick)
 This function uses the LinkObjects function objects. More...
 
DLLEXPORT void LinkObjects (std::shared_ptr< GameWorld > world)
 This function also updates the camera aspect ratio. More...
 
DLLEXPORT void UnlinkAll ()
 
DLLEXPORT bool SetMouseCapture (bool state)
 
DLLEXPORT void SaveScreenShot (const std::string &filename)
 
DLLEXPORT void OnResize (int width, int height)
 
DLLEXPORT void OnFocusChange (bool focused)
 
DLLEXPORT void SetCustomInputController (std::shared_ptr< InputController > controller)
 Overwrites the default InputController with a custom one. More...
 
DLLEXPORT float GetAspectRatio () const
 
DLLEXPORT void GetSize (int32_t &width, int32_t &height) const
 
DLLEXPORT void GetPosition (int32_t &x, int32_t &y) const
 
DLLEXPORT void SetHideCursor (bool toset)
 
DLLEXPORT void GetRelativeMouse (int &x, int &y)
 
DLLEXPORT void GetNormalizedRelativeMouse (float &x, float &y)
 
DLLEXPORT void SetMouseToCenter ()
 
DLLEXPORT bool IsMouseOutsideWindowClientArea ()
 
DLLEXPORT void InputEnd ()
 Translates a client space coordinate to screen coordinate. More...
 
DLLEXPORT uint32_t GetSDLID () const
 Passes initial mouse position to gui. More...
 
DLLEXPORT uint32_t GetNativeHandle () const
 
DLLEXPORT bool IsWindowFocused () const
 Returns whether this window is focused. More...
 
DLLEXPORT void InjectMouseMove (const SDL_Event &event)
 
DLLEXPORT void InjectMouseWheel (const SDL_Event &event)
 
DLLEXPORT void InjectMouseButtonDown (const SDL_Event &event)
 
DLLEXPORT void InjectMouseButtonUp (const SDL_Event &event)
 
DLLEXPORT void InjectCodePoint (const SDL_Event &event)
 Injects text. More...
 
DLLEXPORT void InjectKeyDown (const SDL_Event &event)
 
DLLEXPORT void InjectKeyUp (const SDL_Event &event)
 
DLLEXPORT GUI::GuiManagerGetGui ()
 
DLLEXPORT InputControllerGetInputController ()
 
DLLEXPORT bool GetVsync () const
 
DLLEXPORT Ogre::RenderWindow * GetOgreWindow () const
 
DLLEXPORT Ogre::SceneManager * GetOverlayScene ()
 
DLLEXPORT int GetWindowNumber () const
 

Static Public Member Functions

static DLLEXPORT int GetGlobalWindowCount ()
 

Protected Member Functions

DLLEXPORT void _StartGatherInput ()
 Detects state of modifier keys. Called whenever input is injected and is stored until InputEnd is called. More...
 
void _CheckMouseVisibilityStates ()
 
bool DoCEFInputPass (const SDL_Event &sdlevent, bool down, bool textinput, int mousex, int mousey)
 
GUI::ViewGetGUIEventReceiver (bool iskeypress, int mousex, int mousey)
 Retrieves the active gui object that is going to receive an event. More...
 
void _CreateOverlayScene ()
 Creates an Ogre scene to display GUI on this window. More...
 
void _DestroyOverlay ()
 

Detailed Description

window class

Todo:
Implement global lock for input handling

Definition at line 41 of file Window.h.

Constructor & Destructor Documentation

◆ Window()

DLLEXPORT Leviathan::Window::Window ( Graphics windowcreater,
AppDef windowproperties 
)
Exceptions
InvalidArgumentif creation fails

Definition at line 54 of file Window.cpp.

54  :
55  CurrentCursor(nullptr, nullptr), CurrentCursorImage(nullptr, nullptr),
56  ID(IDFactory::GetID())
57 {
58  // Create window //
59 
60  const WindowDataDetails& WData = windowproperties->GetWindowDetails();
61 
62  // set some rendering specific parameters //
63  Ogre::NameValuePairList WParams;
64 
65  // variables //
66  Ogre::String fsaastr = Convert::ToString(WData.FSAA);
67 
68  WParams["FSAA"] = fsaastr;
69  WParams["vsync"] = WData.VSync ? "true" : "false";
70  WParams["gamma"] = WData.UseGamma ? "true" : "false";
71 
72  Ogre::String wcaption = WData.Title;
73 
74  int extraFlags = 0;
75 
76  if(WData.FullScreen == "no" || WData.FullScreen == "0") {
77  } else if(WData.FullScreen == "fullscreendesktop") {
78  extraFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
79  } else if(WData.FullScreen == "fullscreenvideomode") {
80  extraFlags |= SDL_WINDOW_FULLSCREEN;
81  } else {
82 
83  LOG_ERROR("Window: invalid fullscreen value: " + WData.FullScreen);
84  }
85 
86  // TODO: On Apple's OS X you must set the NSHighResolutionCapable
87  // Info.plist property to YES, otherwise you will not receive a
88  // High DPI OpenGL
89  // canvas. https://wiki.libsdl.org/SDL_CreateWindow
90 
91  SDL_Window* sdlWindow = SDL_CreateWindow(WData.Title.c_str(),
92  SDL_WINDOWPOS_UNDEFINED_DISPLAY(WData.DisplayNumber),
93  SDL_WINDOWPOS_UNDEFINED_DISPLAY(WData.DisplayNumber), WData.Width, WData.Height,
94  // This seems to cause issues on Windows
95  // SDL_WINDOW_OPENGL |
96  SDL_WINDOW_RESIZABLE | extraFlags);
97 
98  // SDL_WINDOW_FULLSCREEN_DESKTOP works so much better than
99  // SDL_WINDOW_FULLSCREEN so it should be always used
100 
101  // SDL_WINDOW_BORDERLESS
102  // SDL_WINDOWPOS_UNDEFINED_DISPLAY(x)
103  // SDL_WINDOWPOS_CENTERED_DISPLAY(x)
104 
105  if(!sdlWindow) {
106 
107  LOG_FATAL("SDL Window creation failed, error: " + std::string(SDL_GetError()));
108  }
109 
110  // SDL_GLContext glContext = SDL_GL_CreateContext(sdlWindow);
111 
112  SDL_SysWMinfo wmInfo;
113  SDL_VERSION(&wmInfo.version);
114  if(!SDL_GetWindowWMInfo(sdlWindow, &wmInfo)) {
115 
116  LOG_FATAL("Window: created sdl window failed to retrieve info");
117  }
118 
119 #ifdef _WIN32
120  auto winHandle = reinterpret_cast<size_t>(wmInfo.info.win.window);
121  // WParams["parentWindowHandle"] = Ogre::StringConverter::toString(winHandle);
122  // This seems to be the right name on windows
123  WParams["externalWindowHandle"] = Ogre::StringConverter::toString(winHandle);
124  // externalWindowHandle
125 #else
126  WParams["parentWindowHandle"] =
127  Ogre::StringConverter::toString((unsigned long)wmInfo.info.x11.display) + ":" +
128  Ogre::StringConverter::toString(
129  (unsigned int)XDefaultScreen(wmInfo.info.x11.display)) +
130  ":" + Ogre::StringConverter::toString((unsigned long)wmInfo.info.x11.window);
131 
132 #endif
133 
134  Ogre::RenderWindow* tmpwindow;
135 
136  try {
137  tmpwindow = windowcreater->GetOgreRoot()->createRenderWindow(
138  wcaption, WData.Width, WData.Height, false, &WParams);
139  } catch(const Ogre::RenderingAPIException& e) {
140 
141  LOG_ERROR("Failed to create Ogre window, exception: " + std::string(e.what()));
142  throw;
143  }
144 
145  int windowsafter = ++OpenWindowCount;
146 
147  // Do some first window initialization //
148  if(windowsafter == 1) {
149 
150  // Notify engine to register threads to work with Ogre //
152 
153  // Hlms is needed to parse scripts etc.
154  windowcreater->_LoadOgreHLMS();
155 
157  }
158 
159  // Store this window's number
160  WindowNumber = ++TotalCreatedWindows;
161 
162  OWindow = tmpwindow;
163 
164 #ifdef _WIN32
165  // Fetch the windows handle from SDL //
166  HWND ourHWND = wmInfo.info.win.window;
167 
168  // apply style settings (mainly ICON) //
169  if(ourHWND) {
170 
171  WData.ApplyIconToHandle(ourHWND);
172 
173  } else {
174  LOG_WARNING("Window: failed to get window HWND for styling");
175  }
176 #else
177  // \todo linux icon
178 #endif
179  tmpwindow->setDeactivateOnFocusChange(false);
180 
181  // set the new window to be active //
182  tmpwindow->setActive(true);
183  Focused = true;
184 
185  // Overlay is needed for the GUI to register its views
187 
188  // create GUI //
189  WindowsGui = std::make_unique<GUI::GuiManager>();
190  if(!WindowsGui) {
191  // TODO: the window must be destroyed here
192  DEBUG_BREAK;
193  throw NULLPtr("cannot create GUI manager instance");
194  }
195 
196  if(!WindowsGui->Init(windowcreater, this)) {
197 
198  LOG_ERROR("Window: Gui init failed");
199  throw NULLPtr("invalid GUI manager");
200  }
201 
202  // create receiver interface //
203  TertiaryReceiver = std::shared_ptr<InputController>(new InputController());
204 
205  SDLWindow = sdlWindow;
206 
207  // TODO: this needs to be only used when a text box etc. is used
208  // But that is quite hard to detect
209  SDL_StartTextInput();
210 
211  // cursor on top of window isn't hidden //
212  ApplicationWantCursorState = false;
213 }
void _NotifyThreadsRegisterOgre()
Definition: Engine.cpp:1193
#define LOG_ERROR(x)
Definition: Define.h:83
#define LOG_FATAL(x)
Definition: Define.h:85
void _CreateOverlayScene()
Creates an Ogre scene to display GUI on this window.
Definition: Window.cpp:633
static int GetID()
Definition: IDFactory.h:17
#define LOG_WARNING(x)
Definition: Define.h:82
static std::string ToString(const T &val)
Definition: Convert.h:72
static DLLEXPORT Engine * GetEngine()
Definition: Engine.cpp:77
static DLLEXPORT void RegisterOGREResourceGroups(bool testload=false)
Definition: FileSystem.cpp:927

◆ ~Window()

DLLEXPORT Leviathan::Window::~Window ( )

Definition at line 215 of file Window.cpp.

216 {
217  // GUI is very picky about delete order
218  if(WindowsGui) {
219  WindowsGui->Release();
220  WindowsGui.reset();
221  }
222 
223  if(MouseCaptured) {
224 
225  SDL_SetRelativeMouseMode(SDL_FALSE);
226  }
227 
228  // Un fullscreen to make sure nothing is screwed up
229  if(SDL_GetWindowFlags(SDLWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP) {
230 
231  LOG_INFO("Window: unfullscreened before quit");
232  SDL_SetWindowFullscreen(SDLWindow, 0);
233  }
234 
235  // Report that the window is now closed //
236  Logger::Get()->Info(
237  "Window: closing window(" + Convert::ToString(GetWindowNumber()) + ")");
238 
239  _DestroyOverlay();
240 
241  // Close the window //
242  OWindow->destroy();
243 
244  TertiaryReceiver.reset();
245 
246  int windowsafter = --OpenWindowCount;
247 
248  if(windowsafter == 0) {
249 
250  Logger::Get()->Info("Window: all windows have been closed, "
251  "should quit soon");
252  }
253 
254  LOG_WRITE("TODO: check why calling SDL_DestroyWindow crashes in Ogre "
255  "GLX plugin uninstall");
256  // SDL_DestroyWindow(SDLWindow);
257  SDL_HideWindow(SDLWindow);
258  SDLWindow = nullptr;
259 }
#define LOG_INFO(x)
Definition: Define.h:81
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
void _DestroyOverlay()
Definition: Window.cpp:650
#define LOG_WRITE(x)
Definition: Define.h:84
static std::string ToString(const T &val)
Definition: Convert.h:72
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT int GetWindowNumber() const
Definition: Window.h:171

Member Function Documentation

◆ _CheckMouseVisibilityStates()

void Leviathan::Window::_CheckMouseVisibilityStates ( )
protected

Definition at line 738 of file Window.cpp.

739 {
740  const bool outsideArea = IsMouseOutsideWindowClientArea();
741 
742  // force cursor visible check (if outside client area or mouse is unfocused on the window)
743  if(outsideArea || !Focused) {
744 
745  ForceMouseVisible = true;
746 
747  } else {
748 
749  ForceMouseVisible = false;
750  }
751 
752  // update cursor state //
753  SetHideCursor(ApplicationWantCursorState);
754 }
DLLEXPORT void SetHideCursor(bool toset)
Definition: Window.cpp:474
DLLEXPORT bool IsMouseOutsideWindowClientArea()
Definition: Window.cpp:554

◆ _CreateOverlayScene()

void Leviathan::Window::_CreateOverlayScene ( )
protected

Creates an Ogre scene to display GUI on this window.

Definition at line 633 of file Window.cpp.

634 {
635  Ogre::Root& ogre = Ogre::Root::getSingleton();
636 
637  // create scene manager //
638  OverlayScene = ogre.createSceneManager(Ogre::ST_GENERIC, 1,
639  Ogre::INSTANCING_CULLING_SINGLETHREAD, "Overlay_window_" + Convert::ToString(ID));
640 
641  // create camera //
642  OverlayCamera = OverlayScene->createCamera("overlay camera");
643 
644  // Create the workspace for this scene
645  // Which will render after the normal scene
646  OverlayWorkspace = ogre.getCompositorManager2()->addWorkspace(
647  OverlayScene, OWindow, OverlayCamera, "OverlayWorkspace", true, 1000);
648 }
static std::string ToString(const T &val)
Definition: Convert.h:72

◆ _DestroyOverlay()

void Leviathan::Window::_DestroyOverlay ( )
protected

Definition at line 650 of file Window.cpp.

651 {
652  // Destroy the compositor //
653  Ogre::Root& ogre = Ogre::Root::getSingleton();
654 
655  // Allow releasing twice
656  if(OverlayWorkspace) {
657  ogre.getCompositorManager2()->removeWorkspace(OverlayWorkspace);
658  OverlayWorkspace = nullptr;
659  }
660 
661  if(OverlayScene) {
662  ogre.destroySceneManager(OverlayScene);
663  OverlayScene = nullptr;
664  OverlayCamera = nullptr;
665  }
666 }

◆ _StartGatherInput()

DLLEXPORT void Leviathan::Window::_StartGatherInput ( )
protected

Detects state of modifier keys. Called whenever input is injected and is stored until InputEnd is called.

Todo:
Move to KeyMapping.cpp
Todo:
Fix mouse capture

Definition at line 679 of file Window.cpp.

680 {
681  // Quit if window closed //
682  if(!SDLWindow) {
683 
684  LOG_WARNING("Window: GatherInput: window is closed");
685  return;
686  }
687 
688  InputGatherStarted = true;
689 
691 
692  SpecialKeyModifiers = 0;
693  CEFSpecialKeyModifiers = EVENTFLAG_NONE;
694 
695  const auto mods = SDL_GetModState();
696 
697  if(mods & KMOD_CTRL) {
698  SpecialKeyModifiers |= KEYSPECIAL_CTRL;
699  CEFSpecialKeyModifiers |= EVENTFLAG_CONTROL_DOWN;
700  }
701  if(mods & KMOD_ALT) {
702  SpecialKeyModifiers |= KEYSPECIAL_ALT;
703  CEFSpecialKeyModifiers |= EVENTFLAG_ALT_DOWN;
704  }
705  if(mods & KMOD_SHIFT) {
706  SpecialKeyModifiers |= KEYSPECIAL_SHIFT;
707  CEFSpecialKeyModifiers |= EVENTFLAG_SHIFT_DOWN;
708  }
709  if(mods & KMOD_CAPS) {
710  SpecialKeyModifiers |= KEYSPECIAL_CAPS;
711  CEFSpecialKeyModifiers |= EVENTFLAG_CAPS_LOCK_ON;
712  }
713  if(mods & KMOD_GUI) {
714  SpecialKeyModifiers |= KEYSPECIAL_SUPER;
715  }
716 
717  // TODO: EVENTFLAG_NUM_LOCK_ON;
718 
719  // TODO: fix mouse capture
720  // // Handle mouse capture
721  // if(MouseCaptured && Focused) {
722 
723  // // get mouse relative to window center //
724  // int xmoved = 0, ymoved = 0;
725 
726  // SDL_GetRelativeMouseState(&xmoved, &ymoved);
727 
728  // // Pass input //
729  // GetInputController()->SendMouseMovement(xmoved, ymoved);
730  // }
731 }
virtual DLLEXPORT void StartInputGather()
#define LOG_WARNING(x)
Definition: Define.h:82
DLLEXPORT InputController * GetInputController()
Definition: Window.h:154

◆ DoCEFInputPass()

bool Leviathan::Window::DoCEFInputPass ( const SDL_Event &  sdlevent,
bool  down,
bool  textinput,
int  mousex,
int  mousey 
)
protected
Returns
True if the event was passed to CEF

It is difficult to get the events back in a guaranteed time so we use GUI_INPUT_MODE to only send events to the GUI when they wouldn't be used by any player character controllers or similar

Definition at line 756 of file Window.cpp.

758 {
759  // Find active gui view that wants the event
760  GUI::View* receiver = GetGUIEventReceiver(true, mousex, mousey);
761 
762  // Don't pass to GUI
763  if(!receiver)
764  return false;
765 
766  CefKeyEvent key_event;
767  key_event.modifiers = CEFSpecialKeyModifiers;
768 
769 #if defined(OS_WIN)
770  if(!textinput) {
771  // GDK compatible key code
772  int asX11KeyCode = KeyMapping::SDLKeyToX11Key(sdlevent.key.keysym);
773 
774  // Modified to work here
775  // Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
776  // reserved. Use of this source code is governed by a BSD-style license that
777  // can be found in the LICENSE file.
778  // Based on WebKeyboardEventBuilder::Build from
779  // content/browser/renderer_host/input/web_input_event_builders_gtk.cc.
780 
781  KeyboardCode windows_key_code = KeyMapping::GdkEventToWindowsKeyCode(asX11KeyCode);
782  key_event.windows_key_code =
784 
785  // List is the lParam of WM_KEYDOWN or WM_SYSKEYDOWN
786  // https://msdn.microsoft.com/en-us/library/windows/desktop/ms646280(v=vs.85).aspx
787  // Also set the repeat count to 1 here
788  key_event.native_key_code = 1;
789 
790  // WM_SYSKEYDOWN detection (hopefully...)
791  if(key_event.modifiers & EVENTFLAG_ALT_DOWN)
792  key_event.is_system_key = true;
793 
794  } else {
795  // text input
796  try {
797  auto begin = std::begin(sdlevent.text.text);
798  key_event.windows_key_code = utf8::next(begin, begin + strlen(sdlevent.text.text));
799  } catch(const utf8::exception& e) {
800  LOG_ERROR(
801  "Window: CEF input handling failed to convert utf8 to utf32 codepoint: " +
802  std::string(e.what()));
803  }
804 
805  // This is the lParam of WM_CHAR
806  // https://msdn.microsoft.com/en-us/library/windows/desktop/ms646276(v=vs.85).aspx
807  // Just set the repeat count to 1 here
808  key_event.native_key_code = 1;
809  }
810 
811 #elif defined(OS_LINUX)
812  if(!textinput) {
813 
814  // GDK compatible key code
815  int asX11KeyCode = KeyMapping::SDLKeyToX11Key(sdlevent.key.keysym);
816 
817  // Modified to work here
818  // Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
819  // reserved. Use of this source code is governed by a BSD-style license that
820  // can be found in the LICENSE file.
821  // Based on WebKeyboardEventBuilder::Build from
822  // content/browser/renderer_host/input/web_input_event_builders_gtk.cc.
823 
824  KeyboardCode windows_key_code = KeyMapping::GdkEventToWindowsKeyCode(asX11KeyCode);
825  key_event.windows_key_code =
827 
828  key_event.native_key_code = windows_key_code;
829  // key_event.native_key_code = asX11KeyCode;
830 
831 
832  // if(event->keyval >= GDK_KP_Space && event->keyval <= GDK_KP_9)
833  // key_event.modifiers |= EVENTFLAG_IS_KEY_PAD;
834  if(key_event.modifiers & EVENTFLAG_ALT_DOWN)
835  key_event.is_system_key = true;
836 
837  // This is VKEY_RETURN = 0x0D
838  if(windows_key_code == 0x0D) {
839  // We need to treat the enter key as a key press of character \r. This
840  // is apparently just how webkit handles it and what it expects.
841  key_event.unmodified_character = '\r';
842  } else {
843  key_event.unmodified_character = sdlevent.key.keysym.sym;
844  }
845 
846  // If ctrl key is pressed down, then control character shall be input.
847  if(key_event.modifiers & EVENTFLAG_CONTROL_DOWN) {
848  key_event.character = KeyMapping::GetControlCharacter(
849  windows_key_code, key_event.modifiers & EVENTFLAG_SHIFT_DOWN);
850  } else {
851 
852  // key_event.character = key_event.unmodified_character;
853  }
854  } else {
855  // text input
856  try {
857  auto begin = std::begin(sdlevent.text.text);
858  key_event.character = utf8::next(begin, begin + strlen(sdlevent.text.text));
859  key_event.unmodified_character = key_event.character;
860  // VKEY_A 0x41 (this isn't used so this is just to quiet warnings)
861  key_event.windows_key_code = 0x41;
862  // Not needed
863  // key_event.native_key_code = ;
864  } catch(const utf8::exception& e) {
865  LOG_ERROR(
866  "Window: CEF input handling failed to convert utf8 to utf32 codepoint: " +
867  std::string(e.what()));
868  }
869  }
870 #elif defined(OS_MACOSX)
871 #error TODO: mac version. See: cef/tests/cefclient/browser/browser_window_osr_mac.mm
872 // for how the event should be structured
873 #else
874 #error Unknown platform
875 #endif // _WIN32
876 
877  // Skip input if unkown key
878  if(key_event.windows_key_code == 0)
879  return false;
880 
881  if(down) {
882 
883  if(!textinput) {
884  key_event.type = KEYEVENT_RAWKEYDOWN;
885  receiver->GetBrowserHost()->SendKeyEvent(key_event);
886  } else {
887  // Send char event //
888  key_event.type = KEYEVENT_CHAR;
889  receiver->GetBrowserHost()->SendKeyEvent(key_event);
890  }
891  } else {
892  if(!textinput) {
893  key_event.type = KEYEVENT_KEYUP;
894  receiver->GetBrowserHost()->SendKeyEvent(key_event);
895  }
896  }
897 
898 
899  // Detecting if the key press was actually used is pretty difficult and might cause lag so
900  // we don't do that
901  return true;
902 }
DLLEXPORT int GetControlCharacter(KeyboardCode windows_key_code, bool shift)
Definition: KeyMapping.cpp:934
DLLEXPORT KeyboardCode GdkEventToWindowsKeyCode(int key)
Definition: KeyMapping.cpp:764
#define LOG_ERROR(x)
Definition: Define.h:83
uint32_t next(octet_iterator &it, octet_iterator end)
Definition: checked.h:137
DLLEXPORT KeyboardCode GetWindowsKeyCodeWithoutLocation(KeyboardCode key_code)
Definition: KeyMapping.cpp:917
KeyboardCode
Definition: KeyMapping.cpp:280
DLLEXPORT int SDLKeyToX11Key(const SDL_Keysym &key)
Definition: KeyMapping.cpp:63
GUI::View * GetGUIEventReceiver(bool iskeypress, int mousex, int mousey)
Retrieves the active gui object that is going to receive an event.
Definition: Window.cpp:669

◆ GetAspectRatio()

DLLEXPORT float Leviathan::Window::GetAspectRatio ( ) const
inline

Definition at line 80 of file Window.h.

81  {
82  int32_t width, height;
83  GetSize(width, height);
84 
85  return (static_cast<float>(width)) / height;
86  }
DLLEXPORT void GetSize(int32_t &width, int32_t &height) const
Definition: Window.cpp:571

◆ GetGlobalWindowCount()

static DLLEXPORT int Leviathan::Window::GetGlobalWindowCount ( )
inlinestatic

Returns how many windows are open

See also
OpenWindowCount

Definition at line 178 of file Window.h.

179  {
180  return OpenWindowCount;
181  }

◆ GetGui()

DLLEXPORT GUI::GuiManager* Leviathan::Window::GetGui ( )
inline

Definition at line 150 of file Window.h.

151  {
152  return WindowsGui.get();
153  }

◆ GetGUIEventReceiver()

GUI::View * Leviathan::Window::GetGUIEventReceiver ( bool  iskeypress,
int  mousex,
int  mousey 
)
protected

Retrieves the active gui object that is going to receive an event.

Parameters
iskeypressIf true then only the currently input receiving window (controlled by GUI_INPUT_MODE) is returned if there is one. For mouse events the gui object under the cursor position is returned (unless mouse capture is on then no thing is returned even if iskeypress is true)

Definition at line 669 of file Window.cpp.

670 {
671  // Don't pass to GUI if mouse capture is enabled
672  if(MouseCaptured)
673  return nullptr;
674 
675  GUI::View* view = WindowsGui->GetTargetViewForInput(iskeypress, mousex, mousey);
676  return view;
677 }

◆ GetInputController()

DLLEXPORT InputController* Leviathan::Window::GetInputController ( )
inline

Definition at line 154 of file Window.h.

155  {
156  return TertiaryReceiver.get();
157  }

◆ GetNativeHandle()

DLLEXPORT uint32_t Leviathan::Window::GetNativeHandle ( ) const

Definition at line 592 of file Window.cpp.

594 {
595  SDL_SysWMinfo wmInfo;
596  SDL_VERSION(&wmInfo.version);
597  if(!SDL_GetWindowWMInfo(SDLWindow, &wmInfo)) {
598 
599  LOG_FATAL("Window: GetNativeHandle: failed to retrieve wm info");
600 #ifdef _WIN32
601  return 0;
602 #else
603  return -1;
604 #endif //_WIN32
605  }
606 #if defined(_WIN32)
607  return wmInfo.info.win.window;
608 #else
609 #if defined(__linux)
610  return wmInfo.info.x11.window;
611 #else
612 #error Fix this for mac
613 #endif
614 #endif
615 }
#define LOG_FATAL(x)
Definition: Define.h:85

◆ GetNormalizedRelativeMouse()

DLLEXPORT void Leviathan::Window::GetNormalizedRelativeMouse ( float &  x,
float &  y 
)
Returns
The normalized mouse x and y positions (in range [0, 1])

Definition at line 535 of file Window.cpp.

536 {
537 
538  int xInt, yInt;
539  GetRelativeMouse(xInt, yInt);
540 
541  int32_t width, height;
542  GetSize(width, height);
543 
544  if(width == 0 || height == 0) {
545  x = 0.5f;
546  y = 0.5f;
547  return;
548  }
549 
550  x = static_cast<float>(xInt) / width;
551  y = static_cast<float>(yInt) / height;
552 }
DLLEXPORT void GetSize(int32_t &width, int32_t &height) const
Definition: Window.cpp:571
DLLEXPORT void GetRelativeMouse(int &x, int &y)
Definition: Window.cpp:513

◆ GetOgreWindow()

DLLEXPORT Ogre::RenderWindow* Leviathan::Window::GetOgreWindow ( ) const
inline

Definition at line 159 of file Window.h.

160  {
161  return OWindow;
162  };

◆ GetOverlayScene()

DLLEXPORT Ogre::SceneManager* Leviathan::Window::GetOverlayScene ( )
inline

Definition at line 164 of file Window.h.

165  {
166  return OverlayScene;
167  }

◆ GetPosition()

DLLEXPORT void Leviathan::Window::GetPosition ( int32_t &  x,
int32_t &  y 
) const

Definition at line 576 of file Window.cpp.

577 {
578  SDL_GetWindowPosition(SDLWindow, &x, &y);
579 }

◆ GetRelativeMouse()

DLLEXPORT void Leviathan::Window::GetRelativeMouse ( int &  x,
int &  y 
)
Note
This is clamped to range [0, width / height]

Definition at line 513 of file Window.cpp.

514 {
515  if(!SDLWindow)
516  return;
517 
518  int globalX, globalY;
519  SDL_GetGlobalMouseState(&globalX, &globalY);
520 
521  int windowX, windowY;
522  SDL_GetWindowPosition(SDLWindow, &windowX, &windowY);
523 
524 
525  globalX -= windowX;
526  globalY -= windowY;
527 
528  int32_t width, height;
529  GetSize(width, height);
530 
531  x = std::clamp(globalX, 0, width);
532  y = std::clamp(globalY, 0, height);
533 }
DLLEXPORT void GetSize(int32_t &width, int32_t &height) const
Definition: Window.cpp:571

◆ GetSDLID()

DLLEXPORT uint32_t Leviathan::Window::GetSDLID ( ) const

Passes initial mouse position to gui.

Definition at line 581 of file Window.cpp.

582 {
583  if(!SDLWindow)
584  return -1;
585 
586  return SDL_GetWindowID(SDLWindow);
587 }

◆ GetSize()

DLLEXPORT void Leviathan::Window::GetSize ( int32_t &  width,
int32_t &  height 
) const

Definition at line 571 of file Window.cpp.

572 {
573  SDL_GetWindowSize(SDLWindow, &width, &height);
574 }

◆ GetVsync()

DLLEXPORT bool Leviathan::Window::GetVsync ( ) const
inline

Definition at line 623 of file Window.cpp.

624 {
625  return OWindow->isVSyncEnabled();
626 }

◆ GetWindowNumber()

DLLEXPORT int Leviathan::Window::GetWindowNumber ( ) const
inline

Returns this windows creation number

Note
This is quaranteed to be unique among all windows

Definition at line 171 of file Window.h.

172  {
173  return WindowNumber;
174  }

◆ InjectCodePoint()

DLLEXPORT void Leviathan::Window::InjectCodePoint ( const SDL_Event &  event)

Injects text.

Definition at line 1010 of file Window.cpp.

1011 {
1012  if(!InputGatherStarted)
1014 
1015  // Try to pass to CEF //
1016  int mouseX;
1017  int mouseY;
1018  GetRelativeMouse(mouseX, mouseY);
1019 
1020  if(!DoCEFInputPass(event, true, true, mouseX, mouseY)) {
1021 
1022  // CEF didn't want it
1023  }
1024 }
DLLEXPORT void _StartGatherInput()
Detects state of modifier keys. Called whenever input is injected and is stored until InputEnd is cal...
Definition: Window.cpp:679
DLLEXPORT void GetRelativeMouse(int &x, int &y)
Definition: Window.cpp:513
bool DoCEFInputPass(const SDL_Event &sdlevent, bool down, bool textinput, int mousex, int mousey)
Definition: Window.cpp:756

◆ InjectKeyDown()

DLLEXPORT void Leviathan::Window::InjectKeyDown ( const SDL_Event &  event)

Definition at line 1026 of file Window.cpp.

1027 {
1028  if(!InputGatherStarted)
1030 
1031  bool SentToController = false;
1032 
1033  // Try to pass to CEF //
1034  int mouseX;
1035  int mouseY;
1036  GetRelativeMouse(mouseX, mouseY);
1037 
1038  const auto handled = DoCEFInputPass(event, true, false, mouseX, mouseY);
1039 
1040  if(!handled) {
1041 
1042  // CEF didn't want it
1043  // Then try disabling collections //
1044  // LOG_WRITE("TODO: check is a text box active");
1045  // if(!OwningWindow->GetGui()->ProcessKeyDown(sdlkey, SpecialKeyModifiers)) {
1046 
1047  // Finally send to a controller //
1048  SentToController = true;
1049  GetInputController()->OnInputGet(event.key.keysym.sym, SpecialKeyModifiers, true);
1050  // }
1051  }
1052 
1053  if(!SentToController) {
1054  GetInputController()->OnBlockedInput(event.key.keysym.sym, SpecialKeyModifiers, true);
1055  }
1056 }
virtual DLLEXPORT void OnBlockedInput(int32_t key, int specialmodifiers, bool down)
DLLEXPORT void _StartGatherInput()
Detects state of modifier keys. Called whenever input is injected and is stored until InputEnd is cal...
Definition: Window.cpp:679
virtual DLLEXPORT void OnInputGet(int32_t key, int specialmodifiers, bool down)
DLLEXPORT void GetRelativeMouse(int &x, int &y)
Definition: Window.cpp:513
bool DoCEFInputPass(const SDL_Event &sdlevent, bool down, bool textinput, int mousex, int mousey)
Definition: Window.cpp:756
DLLEXPORT InputController * GetInputController()
Definition: Window.h:154

◆ InjectKeyUp()

DLLEXPORT void Leviathan::Window::InjectKeyUp ( const SDL_Event &  event)

Definition at line 1058 of file Window.cpp.

1059 {
1060  if(!InputGatherStarted)
1062 
1063  // Send to CEF if GUI is active //
1064  int mouseX;
1065  int mouseY;
1066  GetRelativeMouse(mouseX, mouseY);
1067  DoCEFInputPass(event, false, false, mouseX, mouseY);
1068 
1069  // This should always be passed here //
1070  GetInputController()->OnInputGet(event.key.keysym.sym, SpecialKeyModifiers, false);
1071 }
DLLEXPORT void _StartGatherInput()
Detects state of modifier keys. Called whenever input is injected and is stored until InputEnd is cal...
Definition: Window.cpp:679
virtual DLLEXPORT void OnInputGet(int32_t key, int specialmodifiers, bool down)
DLLEXPORT void GetRelativeMouse(int &x, int &y)
Definition: Window.cpp:513
bool DoCEFInputPass(const SDL_Event &sdlevent, bool down, bool textinput, int mousex, int mousey)
Definition: Window.cpp:756
DLLEXPORT InputController * GetInputController()
Definition: Window.h:154

◆ InjectMouseButtonDown()

DLLEXPORT void Leviathan::Window::InjectMouseButtonDown ( const SDL_Event &  event)

Definition at line 960 of file Window.cpp.

961 {
962  if(!InputGatherStarted)
964 
965  if(!MouseCaptured) {
966 
967  GUI::View* receiver = GetGUIEventReceiver(false, event.button.x, event.button.y);
968 
969  if(receiver) {
970  CefMouseEvent cevent;
971  cevent.x = event.button.x;
972  cevent.y = event.button.y;
973 
974  int type = KeyMapping::GetCEFButtonFromSdlMouseButton(event.button.button);
975  if(type == -1)
976  return;
977 
978  cef_mouse_button_type_t btype = static_cast<cef_mouse_button_type_t>(type);
979 
980  receiver->GetBrowserHost()->SendMouseClickEvent(cevent, btype, false, 1);
981  }
982  }
983 }
DLLEXPORT void _StartGatherInput()
Detects state of modifier keys. Called whenever input is injected and is stored until InputEnd is cal...
Definition: Window.cpp:679
DLLEXPORT int GetCEFButtonFromSdlMouseButton(uint32_t whichbutton)
Definition: KeyMapping.cpp:22
GUI::View * GetGUIEventReceiver(bool iskeypress, int mousex, int mousey)
Retrieves the active gui object that is going to receive an event.
Definition: Window.cpp:669

◆ InjectMouseButtonUp()

DLLEXPORT void Leviathan::Window::InjectMouseButtonUp ( const SDL_Event &  event)

Definition at line 985 of file Window.cpp.

986 {
987  if(!InputGatherStarted)
989 
990  if(!MouseCaptured) {
991 
992  GUI::View* receiver = GetGUIEventReceiver(false, event.button.x, event.button.y);
993 
994  if(receiver) {
995  CefMouseEvent cevent;
996  cevent.x = event.button.x;
997  cevent.y = event.button.y;
998 
999  int type = KeyMapping::GetCEFButtonFromSdlMouseButton(event.button.button);
1000  if(type == -1)
1001  return;
1002 
1003  cef_mouse_button_type_t btype = static_cast<cef_mouse_button_type_t>(type);
1004 
1005  receiver->GetBrowserHost()->SendMouseClickEvent(cevent, btype, true, 1);
1006  }
1007  }
1008 }
DLLEXPORT void _StartGatherInput()
Detects state of modifier keys. Called whenever input is injected and is stored until InputEnd is cal...
Definition: Window.cpp:679
DLLEXPORT int GetCEFButtonFromSdlMouseButton(uint32_t whichbutton)
Definition: KeyMapping.cpp:22
GUI::View * GetGUIEventReceiver(bool iskeypress, int mousex, int mousey)
Retrieves the active gui object that is going to receive an event.
Definition: Window.cpp:669

◆ InjectMouseMove()

DLLEXPORT void Leviathan::Window::InjectMouseMove ( const SDL_Event &  event)

Definition at line 904 of file Window.cpp.

905 {
906  if(!InputGatherStarted)
908 
909  // Only pass this data if we aren't going to pass our own captured mouse //
910  if(!MouseCaptured) {
911 
912  GUI::View* receiver = GetGUIEventReceiver(false, event.motion.x, event.motion.y);
913 
914  if(receiver) {
915 
916  CefMouseEvent cevent;
917  cevent.x = event.motion.x;
918  cevent.y = event.motion.y;
919 
920  // TODO: IsMouseOutsideWindowClientArea needs to be updated once we support
921  // multiple browsers in a single window
922  receiver->GetBrowserHost()->SendMouseMoveEvent(
924  }
925  }
926 
928 }
DLLEXPORT void _StartGatherInput()
Detects state of modifier keys. Called whenever input is injected and is stored until InputEnd is cal...
Definition: Window.cpp:679
void _CheckMouseVisibilityStates()
Definition: Window.cpp:738
DLLEXPORT bool IsMouseOutsideWindowClientArea()
Definition: Window.cpp:554
GUI::View * GetGUIEventReceiver(bool iskeypress, int mousex, int mousey)
Retrieves the active gui object that is going to receive an event.
Definition: Window.cpp:669

◆ InjectMouseWheel()

DLLEXPORT void Leviathan::Window::InjectMouseWheel ( const SDL_Event &  event)
Todo:
allow configuring if mouse wheel is considered a key (for Gameplay input mode)

Definition at line 930 of file Window.cpp.

931 {
932  if(!InputGatherStarted)
934 
935  if(!MouseCaptured) {
936 
937  int mouseX;
938  int mouseY;
939  GetRelativeMouse(mouseX, mouseY);
940  // TODO: allow configuring if mouse wheel is considered a key
941  GUI::View* receiver = GetGUIEventReceiver(true, mouseX, mouseY);
942 
943  if(receiver) {
944 
945  int x = static_cast<int>(event.wheel.x * MOUSE_SCROLL_MULTIPLIER);
946  int y = static_cast<int>(event.wheel.y * MOUSE_SCROLL_MULTIPLIER);
947 
948  if(SDL_MOUSEWHEEL_FLIPPED == event.wheel.direction) {
949  y *= -1;
950  } else {
951  x *= -1;
952  }
953 
954  CefMouseEvent cevent;
955  receiver->GetBrowserHost()->SendMouseWheelEvent(cevent, x, y);
956  }
957  }
958 }
DLLEXPORT void _StartGatherInput()
Detects state of modifier keys. Called whenever input is injected and is stored until InputEnd is cal...
Definition: Window.cpp:679
DLLEXPORT void GetRelativeMouse(int &x, int &y)
Definition: Window.cpp:513
constexpr auto MOUSE_SCROLL_MULTIPLIER
The default CEF scroll speed is ridiculously slow so we multiply it with this.
Definition: Window.h:37
GUI::View * GetGUIEventReceiver(bool iskeypress, int mousex, int mousey)
Retrieves the active gui object that is going to receive an event.
Definition: Window.cpp:669

◆ InputEnd()

DLLEXPORT void Leviathan::Window::InputEnd ( )

Translates a client space coordinate to screen coordinate.

Exceptions
ExceptionNotFoundIf the window is not found (the internal translate fails)
Note
Doesn't work on linux, returns the input point Called by the engine event loop after key events are sent

This is used to reset modifier key states

Definition at line 733 of file Window.cpp.

734 {
735  InputGatherStarted = false;
736 }

◆ IsMouseOutsideWindowClientArea()

DLLEXPORT bool Leviathan::Window::IsMouseOutsideWindowClientArea ( )

Definition at line 554 of file Window.cpp.

555 {
556  int X, Y;
557  GetRelativeMouse(X, Y);
558 
559  int32_t width, height;
560  GetSize(width, height);
561 
562  // check the coordinates //
563 
564  if(X < 0 || Y < 0 || X > width || Y > height) {
565  return true;
566  }
567 
568  return false;
569 }
DLLEXPORT void GetSize(int32_t &width, int32_t &height) const
Definition: Window.cpp:571
DLLEXPORT void GetRelativeMouse(int &x, int &y)
Definition: Window.cpp:513

◆ IsWindowFocused()

DLLEXPORT bool Leviathan::Window::IsWindowFocused ( ) const
inline

Returns whether this window is focused.

Returns
True when the window has focus

Definition at line 131 of file Window.h.

132  {
133  return Focused;
134  }

◆ LinkObjects()

DLLEXPORT void Leviathan::Window::LinkObjects ( std::shared_ptr< GameWorld world)

This function also updates the camera aspect ratio.

Definition at line 261 of file Window.cpp.

262 {
263  if(LinkedWorld == world)
264  return;
265 
266  if(LinkedWorld) {
267 
268  LinkedWorld->OnUnLinkedFromWindow(this, Graphics::Get()->GetOgreRoot());
269  }
270 
271  LinkedWorld = world;
272 
273  if(LinkedWorld) {
274 
275  LinkedWorld->OnLinkToWindow(this, Graphics::Get()->GetOgreRoot());
276  }
277 }
static DLLEXPORT Graphics * Get()
Definition: Graphics.cpp:65

◆ OnFocusChange()

DLLEXPORT void Leviathan::Window::OnFocusChange ( bool  focused)

Definition at line 326 of file Window.cpp.

327 {
328  if(Focused == focused)
329  return;
330 
331  LOG_INFO("Focus change in Window");
332 
333  // Update mouse //
334  Focused = focused;
336 
337  WindowsGui->OnFocusChanged(focused);
338 
339  if(!Focused && MouseCaptured) {
340 
341  LOG_WRITE("TODO: We need to force GUI on to stop mouse capture");
342  LOG_FATAL("Not implemented unfocus when mouse capture is on");
343  }
344 }
#define LOG_INFO(x)
Definition: Define.h:81
#define LOG_FATAL(x)
Definition: Define.h:85
#define LOG_WRITE(x)
Definition: Define.h:84
void _CheckMouseVisibilityStates()
Definition: Window.cpp:738

◆ OnResize()

DLLEXPORT void Leviathan::Window::OnResize ( int  width,
int  height 
)

Definition at line 313 of file Window.cpp.

314 {
315 // Notify Ogre //
316 // This causes issues on Windows
317 #ifdef __linux__
318  GetOgreWindow()->resize(width, height);
319 #endif
320  GetOgreWindow()->windowMovedOrResized();
321 
322  // send to GUI //
323  WindowsGui->OnResize();
324 }
DLLEXPORT Ogre::RenderWindow * GetOgreWindow() const
Definition: Window.h:159

◆ Render()

DLLEXPORT bool Leviathan::Window::Render ( int  mspassed,
int  tick,
int  timeintick 
)

This function uses the LinkObjects function objects.

Definition at line 290 of file Window.cpp.

291 {
292  if(LinkedWorld)
293  LinkedWorld->Render(mspassed, tick, timeintick);
294 
295  // Update GUI before each frame //
296  WindowsGui->Render();
297 
298  // update window //
299  Ogre::RenderWindow* tmpwindow = GetOgreWindow();
300 
301  // finish rendering the window //
302 
303  // We don't actually want to swap buffers here because the Engine
304  // method that called us will call Ogre::Root::renderOneFrame
305  // after Render has been called on all active windows, so if we
306  // have this call here we may do double swap depending on the
307  // drivers.
308  // tmpwindow->swapBuffers();
309 
310  return true;
311 }
DLLEXPORT Ogre::RenderWindow * GetOgreWindow() const
Definition: Window.h:159

◆ SaveScreenShot()

DLLEXPORT void Leviathan::Window::SaveScreenShot ( const std::string &  filename)

Definition at line 617 of file Window.cpp.

618 {
619  // uses render target's capability to save it's contents //
620  GetOgreWindow()->writeContentsToTimestampedFile(filename, "_window1.png");
621 }
DLLEXPORT Ogre::RenderWindow * GetOgreWindow() const
Definition: Window.h:159

◆ SetCustomInputController()

DLLEXPORT void Leviathan::Window::SetCustomInputController ( std::shared_ptr< InputController controller)

Overwrites the default InputController with a custom one.

Definition at line 628 of file Window.cpp.

629 {
630  TertiaryReceiver = controller;
631 }

◆ SetHideCursor()

DLLEXPORT void Leviathan::Window::SetHideCursor ( bool  toset)

Definition at line 474 of file Window.cpp.

475 {
476  ApplicationWantCursorState = toset;
477 
478  if(!ApplicationWantCursorState || ForceMouseVisible) {
479  // show cursor //
480  if(!CursorState) {
481  CursorState = true;
482  Logger::Get()->Info("Showing cursor");
483 
484  // Don't do anything if window is not valid anymore //
485  if(!SDLWindow)
486  return;
487 
488  SDL_ShowCursor(SDL_ENABLE);
489  }
490  } else {
491  // hide cursor //
492  if(CursorState) {
493 
494  CursorState = false;
495  Logger::Get()->Info("Hiding cursor");
496 
497  // Don't do anything if window is not valid anymore //
498  if(!SDLWindow)
499  return;
500 
501  SDL_ShowCursor(SDL_DISABLE);
502  }
503  }
504 }
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106

◆ SetMouseCapture()

DLLEXPORT bool Leviathan::Window::SetMouseCapture ( bool  state)
Returns
true if succeeds, false if another window has input

Definition at line 438 of file Window.cpp.

439 {
440  if(MouseCaptureState == state)
441  return true;
442 
443  MouseCaptureState = state;
444 
445  // handle changing state //
446  if(!MouseCaptureState) {
447 
448  // set mouse visible and disable capturing //
449  SDL_SetRelativeMouseMode(SDL_FALSE);
450  // reset pointer to indicate that this object no longer captures mouse to this window
451  // //
452  InputCapturer = nullptr;
453 
454  } else {
455 
456  if(InputCapturer != this && InputCapturer != nullptr) {
457  // another window has input //
458  MouseCaptureState = false;
459  return false;
460  }
461 
462  SDL_SetRelativeMouseMode(SDL_TRUE);
463 
464  // hide mouse and tell window to capture //
465  // DisplayWindow->SetMouseToCenter();
466 
467  // set static ptr to this //
468  InputCapturer = this;
469  }
470  return true;
471 }

◆ SetMouseToCenter()

DLLEXPORT void Leviathan::Window::SetMouseToCenter ( )

Definition at line 506 of file Window.cpp.

507 {
508  int32_t width, height;
509  GetSize(width, height);
510  SDL_WarpMouseInWindow(SDLWindow, width / 2, height / 2);
511 }
DLLEXPORT void GetSize(int32_t &width, int32_t &height) const
Definition: Window.cpp:571

◆ Tick()

DLLEXPORT void Leviathan::Window::Tick ( int  mspassed)

Called by Engine.

Definition at line 284 of file Window.cpp.

285 {
286  // pass to GUI //
287  WindowsGui->GuiTick(mspassed);
288 }

◆ UnlinkAll()

DLLEXPORT void Leviathan::Window::UnlinkAll ( )

Definition at line 279 of file Window.cpp.

280 {
281  LinkObjects(nullptr);
282 }
DLLEXPORT void LinkObjects(std::shared_ptr< GameWorld > world)
This function also updates the camera aspect ratio.
Definition: Window.cpp:261

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