From ae337952a98bfb71d228221015c947df94bdd6b4 Mon Sep 17 00:00:00 2001 From: binary1248 Date: Sat, 15 Sep 2018 13:08:28 +0200 Subject: [PATCH] Allow creation of a window without an OpenGL context in order to support use cases where the user wants to render using other graphics APIs. --- examples/X11/X11.cpp | 7 + examples/win32/Win32.cpp | 4 + include/SFML/Window/Cursor.hpp | 2 +- include/SFML/Window/Mouse.hpp | 6 +- include/SFML/Window/Touch.hpp | 4 +- include/SFML/Window/Window.hpp | 330 ++-------------- include/SFML/Window/WindowBase.hpp | 505 +++++++++++++++++++++++++ src/SFML/Graphics/RenderWindow.cpp | 4 +- src/SFML/Window/Android/InputImpl.cpp | 6 +- src/SFML/Window/Android/InputImpl.hpp | 6 +- src/SFML/Window/CMakeLists.txt | 2 + src/SFML/Window/Mouse.cpp | 4 +- src/SFML/Window/OSX/InputImpl.hpp | 6 +- src/SFML/Window/OSX/InputImpl.mm | 8 +- src/SFML/Window/Touch.cpp | 2 +- src/SFML/Window/Unix/InputImpl.cpp | 6 +- src/SFML/Window/Unix/InputImpl.hpp | 6 +- src/SFML/Window/Unix/WindowImplX11.cpp | 26 +- src/SFML/Window/Win32/InputImpl.cpp | 6 +- src/SFML/Window/Win32/InputImpl.hpp | 6 +- src/SFML/Window/Window.cpp | 253 ++----------- src/SFML/Window/WindowBase.cpp | 372 ++++++++++++++++++ src/SFML/Window/iOS/InputImpl.hpp | 6 +- src/SFML/Window/iOS/InputImpl.mm | 6 +- 24 files changed, 1009 insertions(+), 574 deletions(-) create mode 100644 include/SFML/Window/WindowBase.hpp create mode 100644 src/SFML/Window/WindowBase.cpp diff --git a/examples/X11/X11.cpp b/examples/X11/X11.cpp index 746bf075..fd919600 100644 --- a/examples/X11/X11.cpp +++ b/examples/X11/X11.cpp @@ -210,6 +210,13 @@ int main() sfmlView2.display(); } + // Close our SFML views before destroying the underlying window + sfmlView1.close(); + sfmlView2.close(); + + // Destroy the window + XDestroyWindow(display, window); + // Close the display XCloseDisplay(display); diff --git a/examples/win32/Win32.cpp b/examples/win32/Win32.cpp index aedfc76e..9b696c2c 100644 --- a/examples/win32/Win32.cpp +++ b/examples/win32/Win32.cpp @@ -122,6 +122,10 @@ int main() } } + // Close our SFML views before destroying the underlying window + SFMLView1.close(); + SFMLView2.close(); + // Destroy the main window (all its child controls will be destroyed) DestroyWindow(window); diff --git a/include/SFML/Window/Cursor.hpp b/include/SFML/Window/Cursor.hpp index 9daa13bd..d85bca63 100644 --- a/include/SFML/Window/Cursor.hpp +++ b/include/SFML/Window/Cursor.hpp @@ -161,7 +161,7 @@ public: private: - friend class Window; + friend class WindowBase; //////////////////////////////////////////////////////////// /// \brief Get access to the underlying implementation diff --git a/include/SFML/Window/Mouse.hpp b/include/SFML/Window/Mouse.hpp index 0d1e470b..4b5ba07a 100644 --- a/include/SFML/Window/Mouse.hpp +++ b/include/SFML/Window/Mouse.hpp @@ -34,7 +34,7 @@ namespace sf { -class Window; +class WindowBase; //////////////////////////////////////////////////////////// /// \brief Give access to the real-time state of the mouse @@ -101,7 +101,7 @@ public: /// \return Current position of the mouse /// //////////////////////////////////////////////////////////// - static Vector2i getPosition(const Window& relativeTo); + static Vector2i getPosition(const WindowBase& relativeTo); //////////////////////////////////////////////////////////// /// \brief Set the current position of the mouse in desktop coordinates @@ -124,7 +124,7 @@ public: /// \param relativeTo Reference window /// //////////////////////////////////////////////////////////// - static void setPosition(const Vector2i& position, const Window& relativeTo); + static void setPosition(const Vector2i& position, const WindowBase& relativeTo); }; } // namespace sf diff --git a/include/SFML/Window/Touch.hpp b/include/SFML/Window/Touch.hpp index 1c2b3fee..f97edddd 100644 --- a/include/SFML/Window/Touch.hpp +++ b/include/SFML/Window/Touch.hpp @@ -34,7 +34,7 @@ namespace sf { -class Window; +class WindowBase; //////////////////////////////////////////////////////////// /// \brief Give access to the real-time state of the touches @@ -79,7 +79,7 @@ public: /// \return Current position of \a finger, or undefined if it's not down /// //////////////////////////////////////////////////////////// - static Vector2i getPosition(unsigned int finger, const Window& relativeTo); + static Vector2i getPosition(unsigned int finger, const WindowBase& relativeTo); }; } // namespace sf diff --git a/include/SFML/Window/Window.hpp b/include/SFML/Window/Window.hpp index 7ff81e29..21f6239b 100644 --- a/include/SFML/Window/Window.hpp +++ b/include/SFML/Window/Window.hpp @@ -29,16 +29,8 @@ // Headers //////////////////////////////////////////////////////////// #include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include +#include namespace sf @@ -46,7 +38,6 @@ namespace sf namespace priv { class GlContext; - class WindowImpl; } class Event; @@ -55,7 +46,7 @@ class Event; /// \brief Window that serves as a target for OpenGL rendering /// //////////////////////////////////////////////////////////// -class SFML_WINDOW_API Window : GlResource, NonCopyable +class SFML_WINDOW_API Window : public WindowBase, GlResource { public: @@ -113,6 +104,20 @@ public: //////////////////////////////////////////////////////////// virtual ~Window(); + //////////////////////////////////////////////////////////// + /// \brief Create (or recreate) the window + /// + /// If the window was already created, it closes it first. + /// If \a style contains Style::Fullscreen, then \a mode + /// must be a valid video mode. + /// + /// \param mode Video mode to use (defines the width, height and depth of the rendering area of the window) + /// \param title Title of the window + /// \param style %Window style, a bitwise OR combination of sf::Style enumerators + /// + //////////////////////////////////////////////////////////// + virtual void create(VideoMode mode, const String& title, Uint32 style = Style::Default); + //////////////////////////////////////////////////////////// /// \brief Create (or recreate) the window /// @@ -130,7 +135,19 @@ public: /// \param settings Additional settings for the underlying OpenGL context /// //////////////////////////////////////////////////////////// - void create(VideoMode mode, const String& title, Uint32 style = Style::Default, const ContextSettings& settings = ContextSettings()); + virtual void create(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings); + + //////////////////////////////////////////////////////////// + /// \brief Create (or recreate) the window from an existing control + /// + /// Use this function if you want to create an OpenGL + /// rendering area into an already existing control. + /// If the window was already created, it closes it first. + /// + /// \param handle Platform-specific handle of the control + /// + //////////////////////////////////////////////////////////// + virtual void create(WindowHandle handle); //////////////////////////////////////////////////////////// /// \brief Create (or recreate) the window from an existing control @@ -147,7 +164,7 @@ public: /// \param settings Additional settings for the underlying OpenGL context /// //////////////////////////////////////////////////////////// - void create(WindowHandle handle, const ContextSettings& settings = ContextSettings()); + virtual void create(WindowHandle handle, const ContextSettings& settings); //////////////////////////////////////////////////////////// /// \brief Close the window and destroy all the attached resources @@ -159,19 +176,7 @@ public: /// and will have no effect on closed windows. /// //////////////////////////////////////////////////////////// - void close(); - - //////////////////////////////////////////////////////////// - /// \brief Tell whether or not the window is open - /// - /// This function returns whether or not the window exists. - /// Note that a hidden window (setVisible(false)) is open - /// (therefore this function would return true). - /// - /// \return True if the window is open, false if it has been closed - /// - //////////////////////////////////////////////////////////// - bool isOpen() const; + virtual void close(); //////////////////////////////////////////////////////////// /// \brief Get the settings of the OpenGL context of the window @@ -186,144 +191,6 @@ public: //////////////////////////////////////////////////////////// const ContextSettings& getSettings() const; - //////////////////////////////////////////////////////////// - /// \brief Pop the event on top of the event queue, if any, and return it - /// - /// This function is not blocking: if there's no pending event then - /// it will return false and leave \a event unmodified. - /// Note that more than one event may be present in the event queue, - /// thus you should always call this function in a loop - /// to make sure that you process every pending event. - /// \code - /// sf::Event event; - /// while (window.pollEvent(event)) - /// { - /// // process event... - /// } - /// \endcode - /// - /// \param event Event to be returned - /// - /// \return True if an event was returned, or false if the event queue was empty - /// - /// \see waitEvent - /// - //////////////////////////////////////////////////////////// - bool pollEvent(Event& event); - - //////////////////////////////////////////////////////////// - /// \brief Wait for an event and return it - /// - /// This function is blocking: if there's no pending event then - /// it will wait until an event is received. - /// After this function returns (and no error occurred), - /// the \a event object is always valid and filled properly. - /// This function is typically used when you have a thread that - /// is dedicated to events handling: you want to make this thread - /// sleep as long as no new event is received. - /// \code - /// sf::Event event; - /// if (window.waitEvent(event)) - /// { - /// // process event... - /// } - /// \endcode - /// - /// \param event Event to be returned - /// - /// \return False if any error occurred - /// - /// \see pollEvent - /// - //////////////////////////////////////////////////////////// - bool waitEvent(Event& event); - - //////////////////////////////////////////////////////////// - /// \brief Get the position of the window - /// - /// \return Position of the window, in pixels - /// - /// \see setPosition - /// - //////////////////////////////////////////////////////////// - Vector2i getPosition() const; - - //////////////////////////////////////////////////////////// - /// \brief Change the position of the window on screen - /// - /// This function only works for top-level windows - /// (i.e. it will be ignored for windows created from - /// the handle of a child window/control). - /// - /// \param position New position, in pixels - /// - /// \see getPosition - /// - //////////////////////////////////////////////////////////// - void setPosition(const Vector2i& position); - - //////////////////////////////////////////////////////////// - /// \brief Get the size of the rendering region of the window - /// - /// The size doesn't include the titlebar and borders - /// of the window. - /// - /// \return Size in pixels - /// - /// \see setSize - /// - //////////////////////////////////////////////////////////// - Vector2u getSize() const; - - //////////////////////////////////////////////////////////// - /// \brief Change the size of the rendering region of the window - /// - /// \param size New size, in pixels - /// - /// \see getSize - /// - //////////////////////////////////////////////////////////// - void setSize(const Vector2u& size); - - //////////////////////////////////////////////////////////// - /// \brief Change the title of the window - /// - /// \param title New title - /// - /// \see setIcon - /// - //////////////////////////////////////////////////////////// - void setTitle(const String& title); - - //////////////////////////////////////////////////////////// - /// \brief Change the window's icon - /// - /// \a pixels must be an array of \a width x \a height pixels - /// in 32-bits RGBA format. - /// - /// The OS default icon is used by default. - /// - /// \param width Icon's width, in pixels - /// \param height Icon's height, in pixels - /// \param pixels Pointer to the array of pixels in memory. The - /// pixels are copied, so you need not keep the - /// source alive after calling this function. - /// - /// \see setTitle - /// - //////////////////////////////////////////////////////////// - void setIcon(unsigned int width, unsigned int height, const Uint8* pixels); - - //////////////////////////////////////////////////////////// - /// \brief Show or hide the window - /// - /// The window is shown by default. - /// - /// \param visible True to show the window, false to hide it - /// - //////////////////////////////////////////////////////////// - void setVisible(bool visible); - //////////////////////////////////////////////////////////// /// \brief Enable or disable vertical synchronization /// @@ -339,62 +206,6 @@ public: //////////////////////////////////////////////////////////// void setVerticalSyncEnabled(bool enabled); - //////////////////////////////////////////////////////////// - /// \brief Show or hide the mouse cursor - /// - /// The mouse cursor is visible by default. - /// - /// \param visible True to show the mouse cursor, false to hide it - /// - //////////////////////////////////////////////////////////// - void setMouseCursorVisible(bool visible); - - //////////////////////////////////////////////////////////// - /// \brief Grab or release the mouse cursor - /// - /// If set, grabs the mouse cursor inside this window's client - /// area so it may no longer be moved outside its bounds. - /// Note that grabbing is only active while the window has - /// focus. - /// - /// \param grabbed True to enable, false to disable - /// - //////////////////////////////////////////////////////////// - void setMouseCursorGrabbed(bool grabbed); - - //////////////////////////////////////////////////////////// - /// \brief Set the displayed cursor to a native system cursor - /// - /// Upon window creation, the arrow cursor is used by default. - /// - /// \warning The cursor must not be destroyed while in use by - /// the window. - /// - /// \warning Features related to Cursor are not supported on - /// iOS and Android. - /// - /// \param cursor Native system cursor type to display - /// - /// \see sf::Cursor::loadFromSystem - /// \see sf::Cursor::loadFromPixels - /// - //////////////////////////////////////////////////////////// - void setMouseCursor(const Cursor& cursor); - - //////////////////////////////////////////////////////////// - /// \brief Enable or disable automatic key-repeat - /// - /// If key repeat is enabled, you will receive repeated - /// KeyPressed events while keeping a key pressed. If it is disabled, - /// you will only get a single event when the key is pressed. - /// - /// Key repeat is enabled by default. - /// - /// \param enabled True to enable, false to disable - /// - //////////////////////////////////////////////////////////// - void setKeyRepeatEnabled(bool enabled); - //////////////////////////////////////////////////////////// /// \brief Limit the framerate to a maximum fixed frequency /// @@ -412,19 +223,6 @@ public: //////////////////////////////////////////////////////////// void setFramerateLimit(unsigned int limit); - //////////////////////////////////////////////////////////// - /// \brief Change the joystick threshold - /// - /// The joystick threshold is the value below which - /// no JoystickMoved event will be generated. - /// - /// The threshold value is 0.1 by default. - /// - /// \param threshold New threshold, in the range [0, 100] - /// - //////////////////////////////////////////////////////////// - void setJoystickThreshold(float threshold); - //////////////////////////////////////////////////////////// /// \brief Activate or deactivate the window as the current target /// for OpenGL rendering @@ -443,35 +241,6 @@ public: //////////////////////////////////////////////////////////// bool setActive(bool active = true) const; - //////////////////////////////////////////////////////////// - /// \brief Request the current window to be made the active - /// foreground window - /// - /// At any given time, only one window may have the input focus - /// to receive input events such as keystrokes or mouse events. - /// If a window requests focus, it only hints to the operating - /// system, that it would like to be focused. The operating system - /// is free to deny the request. - /// This is not to be confused with setActive(). - /// - /// \see hasFocus - /// - //////////////////////////////////////////////////////////// - void requestFocus(); - - //////////////////////////////////////////////////////////// - /// \brief Check whether the window has the input focus - /// - /// At any given time, only one window may have the input focus - /// to receive input events such as keystrokes or most mouse - /// events. - /// - /// \return True if window has focus, false otherwise - /// \see requestFocus - /// - //////////////////////////////////////////////////////////// - bool hasFocus() const; - //////////////////////////////////////////////////////////// /// \brief Display on screen what has been rendered to the window so far /// @@ -482,41 +251,6 @@ public: //////////////////////////////////////////////////////////// void display(); - //////////////////////////////////////////////////////////// - /// \brief Get the OS-specific handle of the window - /// - /// The type of the returned handle is sf::WindowHandle, - /// which is a typedef to the handle type defined by the OS. - /// You shouldn't need to use this function, unless you have - /// very specific stuff to implement that SFML doesn't support, - /// or implement a temporary workaround until a bug is fixed. - /// - /// \return System handle of the window - /// - //////////////////////////////////////////////////////////// - WindowHandle getSystemHandle() const; - -protected: - - //////////////////////////////////////////////////////////// - /// \brief Function called after the window has been created - /// - /// This function is called so that derived classes can - /// perform their own specific initialization as soon as - /// the window is created. - /// - //////////////////////////////////////////////////////////// - virtual void onCreate(); - - //////////////////////////////////////////////////////////// - /// \brief Function called after the window has been resized - /// - /// This function is called so that derived classes can - /// perform custom actions when the size of the window changes. - /// - //////////////////////////////////////////////////////////// - virtual void onResize(); - private: //////////////////////////////////////////////////////////// @@ -542,11 +276,9 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - priv::WindowImpl* m_impl; ///< Platform-specific implementation of the window priv::GlContext* m_context; ///< Platform-specific implementation of the OpenGL context Clock m_clock; ///< Clock for measuring the elapsed time between frames Time m_frameTimeLimit; ///< Current framerate limit - Vector2u m_size; ///< Current size of the window }; } // namespace sf diff --git a/include/SFML/Window/WindowBase.hpp b/include/SFML/Window/WindowBase.hpp new file mode 100644 index 00000000..e157f5a5 --- /dev/null +++ b/include/SFML/Window/WindowBase.hpp @@ -0,0 +1,505 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2018 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_WINDOWBASE_HPP +#define SFML_WINDOWBASE_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace sf +{ +namespace priv +{ + class WindowImpl; +} + +class Event; + +//////////////////////////////////////////////////////////// +/// \brief Window that serves as a base for other windows +/// +//////////////////////////////////////////////////////////// +class SFML_WINDOW_API WindowBase : NonCopyable +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// This constructor doesn't actually create the window, + /// use the other constructors or call create() to do so. + /// + //////////////////////////////////////////////////////////// + WindowBase(); + + //////////////////////////////////////////////////////////// + /// \brief Construct a new window + /// + /// This constructor creates the window with the size and pixel + /// depth defined in \a mode. An optional style can be passed to + /// customize the look and behavior of the window (borders, + /// title bar, resizable, closable, ...). If \a style contains + /// Style::Fullscreen, then \a mode must be a valid video mode. + /// + /// \param mode Video mode to use (defines the width, height and depth of the rendering area of the window) + /// \param title Title of the window + /// \param style %Window style, a bitwise OR combination of sf::Style enumerators + /// + //////////////////////////////////////////////////////////// + WindowBase(VideoMode mode, const String& title, Uint32 style = Style::Default); + + //////////////////////////////////////////////////////////// + /// \brief Construct the window from an existing control + /// + /// \param handle Platform-specific handle of the control + /// + //////////////////////////////////////////////////////////// + explicit WindowBase(WindowHandle handle); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + /// Closes the window and frees all the resources attached to it. + /// + //////////////////////////////////////////////////////////// + virtual ~WindowBase(); + + //////////////////////////////////////////////////////////// + /// \brief Create (or recreate) the window + /// + /// If the window was already created, it closes it first. + /// If \a style contains Style::Fullscreen, then \a mode + /// must be a valid video mode. + /// + /// \param mode Video mode to use (defines the width, height and depth of the rendering area of the window) + /// \param title Title of the window + /// \param style %Window style, a bitwise OR combination of sf::Style enumerators + /// + //////////////////////////////////////////////////////////// + virtual void create(VideoMode mode, const String& title, Uint32 style = Style::Default); + + //////////////////////////////////////////////////////////// + /// \brief Create (or recreate) the window from an existing control + /// + /// \param handle Platform-specific handle of the control + /// + //////////////////////////////////////////////////////////// + virtual void create(WindowHandle handle); + + //////////////////////////////////////////////////////////// + /// \brief Close the window and destroy all the attached resources + /// + /// After calling this function, the sf::Window instance remains + /// valid and you can call create() to recreate the window. + /// All other functions such as pollEvent() or display() will + /// still work (i.e. you don't have to test isOpen() every time), + /// and will have no effect on closed windows. + /// + //////////////////////////////////////////////////////////// + virtual void close(); + + //////////////////////////////////////////////////////////// + /// \brief Tell whether or not the window is open + /// + /// This function returns whether or not the window exists. + /// Note that a hidden window (setVisible(false)) is open + /// (therefore this function would return true). + /// + /// \return True if the window is open, false if it has been closed + /// + //////////////////////////////////////////////////////////// + bool isOpen() const; + + //////////////////////////////////////////////////////////// + /// \brief Pop the event on top of the event queue, if any, and return it + /// + /// This function is not blocking: if there's no pending event then + /// it will return false and leave \a event unmodified. + /// Note that more than one event may be present in the event queue, + /// thus you should always call this function in a loop + /// to make sure that you process every pending event. + /// \code + /// sf::Event event; + /// while (window.pollEvent(event)) + /// { + /// // process event... + /// } + /// \endcode + /// + /// \param event Event to be returned + /// + /// \return True if an event was returned, or false if the event queue was empty + /// + /// \see waitEvent + /// + //////////////////////////////////////////////////////////// + bool pollEvent(Event& event); + + //////////////////////////////////////////////////////////// + /// \brief Wait for an event and return it + /// + /// This function is blocking: if there's no pending event then + /// it will wait until an event is received. + /// After this function returns (and no error occurred), + /// the \a event object is always valid and filled properly. + /// This function is typically used when you have a thread that + /// is dedicated to events handling: you want to make this thread + /// sleep as long as no new event is received. + /// \code + /// sf::Event event; + /// if (window.waitEvent(event)) + /// { + /// // process event... + /// } + /// \endcode + /// + /// \param event Event to be returned + /// + /// \return False if any error occurred + /// + /// \see pollEvent + /// + //////////////////////////////////////////////////////////// + bool waitEvent(Event& event); + + //////////////////////////////////////////////////////////// + /// \brief Get the position of the window + /// + /// \return Position of the window, in pixels + /// + /// \see setPosition + /// + //////////////////////////////////////////////////////////// + Vector2i getPosition() const; + + //////////////////////////////////////////////////////////// + /// \brief Change the position of the window on screen + /// + /// This function only works for top-level windows + /// (i.e. it will be ignored for windows created from + /// the handle of a child window/control). + /// + /// \param position New position, in pixels + /// + /// \see getPosition + /// + //////////////////////////////////////////////////////////// + void setPosition(const Vector2i& position); + + //////////////////////////////////////////////////////////// + /// \brief Get the size of the rendering region of the window + /// + /// The size doesn't include the titlebar and borders + /// of the window. + /// + /// \return Size in pixels + /// + /// \see setSize + /// + //////////////////////////////////////////////////////////// + Vector2u getSize() const; + + //////////////////////////////////////////////////////////// + /// \brief Change the size of the rendering region of the window + /// + /// \param size New size, in pixels + /// + /// \see getSize + /// + //////////////////////////////////////////////////////////// + void setSize(const Vector2u& size); + + //////////////////////////////////////////////////////////// + /// \brief Change the title of the window + /// + /// \param title New title + /// + /// \see setIcon + /// + //////////////////////////////////////////////////////////// + void setTitle(const String& title); + + //////////////////////////////////////////////////////////// + /// \brief Change the window's icon + /// + /// \a pixels must be an array of \a width x \a height pixels + /// in 32-bits RGBA format. + /// + /// The OS default icon is used by default. + /// + /// \param width Icon's width, in pixels + /// \param height Icon's height, in pixels + /// \param pixels Pointer to the array of pixels in memory. The + /// pixels are copied, so you need not keep the + /// source alive after calling this function. + /// + /// \see setTitle + /// + //////////////////////////////////////////////////////////// + void setIcon(unsigned int width, unsigned int height, const Uint8* pixels); + + //////////////////////////////////////////////////////////// + /// \brief Show or hide the window + /// + /// The window is shown by default. + /// + /// \param visible True to show the window, false to hide it + /// + //////////////////////////////////////////////////////////// + void setVisible(bool visible); + + //////////////////////////////////////////////////////////// + /// \brief Show or hide the mouse cursor + /// + /// The mouse cursor is visible by default. + /// + /// \param visible True to show the mouse cursor, false to hide it + /// + //////////////////////////////////////////////////////////// + void setMouseCursorVisible(bool visible); + + //////////////////////////////////////////////////////////// + /// \brief Grab or release the mouse cursor + /// + /// If set, grabs the mouse cursor inside this window's client + /// area so it may no longer be moved outside its bounds. + /// Note that grabbing is only active while the window has + /// focus. + /// + /// \param grabbed True to enable, false to disable + /// + //////////////////////////////////////////////////////////// + void setMouseCursorGrabbed(bool grabbed); + + //////////////////////////////////////////////////////////// + /// \brief Set the displayed cursor to a native system cursor + /// + /// Upon window creation, the arrow cursor is used by default. + /// + /// \warning The cursor must not be destroyed while in use by + /// the window. + /// + /// \warning Features related to Cursor are not supported on + /// iOS and Android. + /// + /// \param cursor Native system cursor type to display + /// + /// \see sf::Cursor::loadFromSystem + /// \see sf::Cursor::loadFromPixels + /// + //////////////////////////////////////////////////////////// + void setMouseCursor(const Cursor& cursor); + + //////////////////////////////////////////////////////////// + /// \brief Enable or disable automatic key-repeat + /// + /// If key repeat is enabled, you will receive repeated + /// KeyPressed events while keeping a key pressed. If it is disabled, + /// you will only get a single event when the key is pressed. + /// + /// Key repeat is enabled by default. + /// + /// \param enabled True to enable, false to disable + /// + //////////////////////////////////////////////////////////// + void setKeyRepeatEnabled(bool enabled); + + //////////////////////////////////////////////////////////// + /// \brief Change the joystick threshold + /// + /// The joystick threshold is the value below which + /// no JoystickMoved event will be generated. + /// + /// The threshold value is 0.1 by default. + /// + /// \param threshold New threshold, in the range [0, 100] + /// + //////////////////////////////////////////////////////////// + void setJoystickThreshold(float threshold); + + //////////////////////////////////////////////////////////// + /// \brief Request the current window to be made the active + /// foreground window + /// + /// At any given time, only one window may have the input focus + /// to receive input events such as keystrokes or mouse events. + /// If a window requests focus, it only hints to the operating + /// system, that it would like to be focused. The operating system + /// is free to deny the request. + /// This is not to be confused with setActive(). + /// + /// \see hasFocus + /// + //////////////////////////////////////////////////////////// + void requestFocus(); + + //////////////////////////////////////////////////////////// + /// \brief Check whether the window has the input focus + /// + /// At any given time, only one window may have the input focus + /// to receive input events such as keystrokes or most mouse + /// events. + /// + /// \return True if window has focus, false otherwise + /// \see requestFocus + /// + //////////////////////////////////////////////////////////// + bool hasFocus() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the OS-specific handle of the window + /// + /// The type of the returned handle is sf::WindowHandle, + /// which is a typedef to the handle type defined by the OS. + /// You shouldn't need to use this function, unless you have + /// very specific stuff to implement that SFML doesn't support, + /// or implement a temporary workaround until a bug is fixed. + /// + /// \return System handle of the window + /// + //////////////////////////////////////////////////////////// + WindowHandle getSystemHandle() const; + +protected: + + //////////////////////////////////////////////////////////// + /// \brief Function called after the window has been created + /// + /// This function is called so that derived classes can + /// perform their own specific initialization as soon as + /// the window is created. + /// + //////////////////////////////////////////////////////////// + virtual void onCreate(); + + //////////////////////////////////////////////////////////// + /// \brief Function called after the window has been resized + /// + /// This function is called so that derived classes can + /// perform custom actions when the size of the window changes. + /// + //////////////////////////////////////////////////////////// + virtual void onResize(); + +private: + + friend class Window; + + //////////////////////////////////////////////////////////// + /// \brief Processes an event before it is sent to the user + /// + /// This function is called every time an event is received + /// from the internal window (through pollEvent or waitEvent). + /// It filters out unwanted events, and performs whatever internal + /// stuff the window needs before the event is returned to the + /// user. + /// + /// \param event Event to filter + /// + //////////////////////////////////////////////////////////// + bool filterEvent(const Event& event); + + //////////////////////////////////////////////////////////// + /// \brief Perform some common internal initializations + /// + //////////////////////////////////////////////////////////// + void initialize(); + + //////////////////////////////////////////////////////////// + /// \brief Get the fullscreen window + /// + /// \return The fullscreen window or NULL if there is none + /// + //////////////////////////////////////////////////////////// + const WindowBase* getFullscreenWindow(); + + //////////////////////////////////////////////////////////// + /// \brief Set a window as the fullscreen window + /// + /// \param window Window to set as fullscreen window + /// + //////////////////////////////////////////////////////////// + void setFullscreenWindow(const WindowBase* window); + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + priv::WindowImpl* m_impl; ///< Platform-specific implementation of the window + Vector2u m_size; ///< Current size of the window +}; + +} // namespace sf + + +#endif // SFML_WINDOWBASE_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::WindowBase +/// \ingroup window +/// +/// sf::WindowBase serves as the base class for all Windows. +/// +/// A sf::WindowBase can create its own new window, or be embedded into +/// an already existing control using the create(handle) function. +/// +/// The sf::WindowBase class provides a simple interface for manipulating +/// the window: move, resize, show/hide, control mouse cursor, etc. +/// It also provides event handling through its pollEvent() and waitEvent() +/// functions. +/// +/// Usage example: +/// \code +/// // Declare and create a new window +/// sf::WindowBase window(sf::VideoMode(800, 600), "SFML window"); +/// +/// // The main loop - ends as soon as the window is closed +/// while (window.isOpen()) +/// { +/// // Event processing +/// sf::Event event; +/// while (window.pollEvent(event)) +/// { +/// // Request for closing the window +/// if (event.type == sf::Event::Closed) +/// window.close(); +/// } +/// +/// // Do things with the window here... +/// } +/// \endcode +/// +//////////////////////////////////////////////////////////// diff --git a/src/SFML/Graphics/RenderWindow.cpp b/src/SFML/Graphics/RenderWindow.cpp index 42f4ffea..9926fb45 100644 --- a/src/SFML/Graphics/RenderWindow.cpp +++ b/src/SFML/Graphics/RenderWindow.cpp @@ -46,7 +46,7 @@ RenderWindow::RenderWindow(VideoMode mode, const String& title, Uint32 style, co m_defaultFrameBuffer(0) { // Don't call the base class constructor because it contains virtual function calls - create(mode, title, style, settings); + Window::create(mode, title, style, settings); } @@ -55,7 +55,7 @@ RenderWindow::RenderWindow(WindowHandle handle, const ContextSettings& settings) m_defaultFrameBuffer(0) { // Don't call the base class constructor because it contains virtual function calls - create(handle, settings); + Window::create(handle, settings); } diff --git a/src/SFML/Window/Android/InputImpl.cpp b/src/SFML/Window/Android/InputImpl.cpp index 9da3a131..238c15bc 100644 --- a/src/SFML/Window/Android/InputImpl.cpp +++ b/src/SFML/Window/Android/InputImpl.cpp @@ -158,7 +158,7 @@ Vector2i InputImpl::getMousePosition() //////////////////////////////////////////////////////////// -Vector2i InputImpl::getMousePosition(const Window& relativeTo) +Vector2i InputImpl::getMousePosition(const WindowBase& relativeTo) { return getMousePosition(); } @@ -172,7 +172,7 @@ void InputImpl::setMousePosition(const Vector2i& position) //////////////////////////////////////////////////////////// -void InputImpl::setMousePosition(const Vector2i& position, const Window& relativeTo) +void InputImpl::setMousePosition(const Vector2i& position, const WindowBase& relativeTo) { setMousePosition(position); } @@ -203,7 +203,7 @@ Vector2i InputImpl::getTouchPosition(unsigned int finger) //////////////////////////////////////////////////////////// -Vector2i InputImpl::getTouchPosition(unsigned int finger, const Window& relativeTo) +Vector2i InputImpl::getTouchPosition(unsigned int finger, const WindowBase& relativeTo) { return getTouchPosition(finger); } diff --git a/src/SFML/Window/Android/InputImpl.hpp b/src/SFML/Window/Android/InputImpl.hpp index 37167b50..d2783e15 100644 --- a/src/SFML/Window/Android/InputImpl.hpp +++ b/src/SFML/Window/Android/InputImpl.hpp @@ -95,7 +95,7 @@ public: /// \return Current position of the mouse /// //////////////////////////////////////////////////////////// - static Vector2i getMousePosition(const Window& relativeTo); + static Vector2i getMousePosition(const WindowBase& relativeTo); //////////////////////////////////////////////////////////// /// \brief Set the current position of the mouse in desktop coordinates @@ -120,7 +120,7 @@ public: /// \param relativeTo Reference window /// //////////////////////////////////////////////////////////// - static void setMousePosition(const Vector2i& position, const Window& relativeTo); + static void setMousePosition(const Vector2i& position, const WindowBase& relativeTo); //////////////////////////////////////////////////////////// /// \brief Check if a touch event is currently down @@ -157,7 +157,7 @@ public: /// \return Current position of \a finger, or undefined if it's not down /// //////////////////////////////////////////////////////////// - static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo); + static Vector2i getTouchPosition(unsigned int finger, const WindowBase& relativeTo); }; } // namespace priv diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index 98ea4394..f25ebb83 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -41,6 +41,8 @@ set(SRC ${SRCROOT}/VideoModeImpl.hpp ${SRCROOT}/Window.cpp ${INCROOT}/Window.hpp + ${SRCROOT}/WindowBase.cpp + ${INCROOT}/WindowBase.hpp ${INCROOT}/WindowHandle.hpp ${SRCROOT}/WindowImpl.cpp ${SRCROOT}/WindowImpl.hpp diff --git a/src/SFML/Window/Mouse.cpp b/src/SFML/Window/Mouse.cpp index 862dc69a..e1d4bb8d 100644 --- a/src/SFML/Window/Mouse.cpp +++ b/src/SFML/Window/Mouse.cpp @@ -47,7 +47,7 @@ Vector2i Mouse::getPosition() //////////////////////////////////////////////////////////// -Vector2i Mouse::getPosition(const Window& relativeTo) +Vector2i Mouse::getPosition(const WindowBase& relativeTo) { return priv::InputImpl::getMousePosition(relativeTo); } @@ -61,7 +61,7 @@ void Mouse::setPosition(const Vector2i& position) //////////////////////////////////////////////////////////// -void Mouse::setPosition(const Vector2i& position, const Window& relativeTo) +void Mouse::setPosition(const Vector2i& position, const WindowBase& relativeTo) { priv::InputImpl::setMousePosition(position, relativeTo); } diff --git a/src/SFML/Window/OSX/InputImpl.hpp b/src/SFML/Window/OSX/InputImpl.hpp index 6f874bcd..d6322655 100644 --- a/src/SFML/Window/OSX/InputImpl.hpp +++ b/src/SFML/Window/OSX/InputImpl.hpp @@ -96,7 +96,7 @@ public: /// \return Current position of the mouse /// //////////////////////////////////////////////////////////// - static Vector2i getMousePosition(const Window& relativeTo); + static Vector2i getMousePosition(const WindowBase& relativeTo); //////////////////////////////////////////////////////////// /// \brief Set the current position of the mouse in desktop coordinates @@ -121,7 +121,7 @@ public: /// \param relativeTo Reference window /// //////////////////////////////////////////////////////////// - static void setMousePosition(const Vector2i& position, const Window& relativeTo); + static void setMousePosition(const Vector2i& position, const WindowBase& relativeTo); //////////////////////////////////////////////////////////// /// \brief Check if a touch event is currently down @@ -158,7 +158,7 @@ public: /// \return Current position of \a finger, or undefined if it's not down /// //////////////////////////////////////////////////////////// - static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo); + static Vector2i getTouchPosition(unsigned int finger, const WindowBase& relativeTo); }; } // namespace priv diff --git a/src/SFML/Window/OSX/InputImpl.mm b/src/SFML/Window/OSX/InputImpl.mm index 361e1be8..6783a845 100644 --- a/src/SFML/Window/OSX/InputImpl.mm +++ b/src/SFML/Window/OSX/InputImpl.mm @@ -55,7 +55,7 @@ namespace priv /// \return nil if something went wrong or a SFOpenGLView*. /// //////////////////////////////////////////////////////////// -SFOpenGLView* getSFOpenGLViewFromSFMLWindow(const Window& window) +SFOpenGLView* getSFOpenGLViewFromSFMLWindow(const WindowBase& window) { id nsHandle = (id)window.getSystemHandle(); @@ -158,7 +158,7 @@ Vector2i InputImpl::getMousePosition() //////////////////////////////////////////////////////////// -Vector2i InputImpl::getMousePosition(const Window& relativeTo) +Vector2i InputImpl::getMousePosition(const WindowBase& relativeTo) { SFOpenGLView* view = getSFOpenGLViewFromSFMLWindow(relativeTo); @@ -193,7 +193,7 @@ void InputImpl::setMousePosition(const Vector2i& position) //////////////////////////////////////////////////////////// -void InputImpl::setMousePosition(const Vector2i& position, const Window& relativeTo) +void InputImpl::setMousePosition(const Vector2i& position, const WindowBase& relativeTo) { SFOpenGLView* view = getSFOpenGLViewFromSFMLWindow(relativeTo); @@ -226,7 +226,7 @@ Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/) //////////////////////////////////////////////////////////// -Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const Window& /*relativeTo*/) +Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const WindowBase& /*relativeTo*/) { // Not applicable return Vector2i(); diff --git a/src/SFML/Window/Touch.cpp b/src/SFML/Window/Touch.cpp index aa63c728..90c36fb4 100644 --- a/src/SFML/Window/Touch.cpp +++ b/src/SFML/Window/Touch.cpp @@ -46,7 +46,7 @@ Vector2i Touch::getPosition(unsigned int finger) //////////////////////////////////////////////////////////// -Vector2i Touch::getPosition(unsigned int finger, const Window& relativeTo) +Vector2i Touch::getPosition(unsigned int finger, const WindowBase& relativeTo) { return priv::InputImpl::getTouchPosition(finger, relativeTo); } diff --git a/src/SFML/Window/Unix/InputImpl.cpp b/src/SFML/Window/Unix/InputImpl.cpp index b404dd51..c9f2a2cc 100644 --- a/src/SFML/Window/Unix/InputImpl.cpp +++ b/src/SFML/Window/Unix/InputImpl.cpp @@ -240,7 +240,7 @@ Vector2i InputImpl::getMousePosition() //////////////////////////////////////////////////////////// -Vector2i InputImpl::getMousePosition(const Window& relativeTo) +Vector2i InputImpl::getMousePosition(const WindowBase& relativeTo) { WindowHandle handle = relativeTo.getSystemHandle(); if (handle) @@ -284,7 +284,7 @@ void InputImpl::setMousePosition(const Vector2i& position) //////////////////////////////////////////////////////////// -void InputImpl::setMousePosition(const Vector2i& position, const Window& relativeTo) +void InputImpl::setMousePosition(const Vector2i& position, const WindowBase& relativeTo) { // Open a connection with the X server Display* display = OpenDisplay(); @@ -318,7 +318,7 @@ Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/) //////////////////////////////////////////////////////////// -Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const Window& /*relativeTo*/) +Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const WindowBase& /*relativeTo*/) { // Not applicable return Vector2i(); diff --git a/src/SFML/Window/Unix/InputImpl.hpp b/src/SFML/Window/Unix/InputImpl.hpp index 88dcc91c..1b1d6374 100644 --- a/src/SFML/Window/Unix/InputImpl.hpp +++ b/src/SFML/Window/Unix/InputImpl.hpp @@ -95,7 +95,7 @@ public: /// \return Current position of the mouse /// //////////////////////////////////////////////////////////// - static Vector2i getMousePosition(const Window& relativeTo); + static Vector2i getMousePosition(const WindowBase& relativeTo); //////////////////////////////////////////////////////////// /// \brief Set the current position of the mouse in desktop coordinates @@ -120,7 +120,7 @@ public: /// \param relativeTo Reference window /// //////////////////////////////////////////////////////////// - static void setMousePosition(const Vector2i& position, const Window& relativeTo); + static void setMousePosition(const Vector2i& position, const WindowBase& relativeTo); //////////////////////////////////////////////////////////// /// \brief Check if a touch event is currently down @@ -157,7 +157,7 @@ public: /// \return Current position of \a finger, or undefined if it's not down /// //////////////////////////////////////////////////////////// - static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo); + static Vector2i getTouchPosition(unsigned int finger, const WindowBase& relativeTo); }; } // namespace priv diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index 5f538f46..fc1324ca 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -572,12 +572,28 @@ m_lastInputTime (0) int width = mode.width; int height = mode.height; - // Choose the visual according to the context settings - XVisualInfo visualInfo = ContextType::selectBestVisual(m_display, mode.bitsPerPixel, settings); + Visual* visual = NULL; + int depth = 0; + + // Check if the user chose to not create an OpenGL context (settings.attributeFlags will be 0xFFFFFFFF) + if (settings.attributeFlags == 0xFFFFFFFF) + { + // Choose default visual since the user is going to use their own rendering API + visual = DefaultVisual(m_display, m_screen); + depth = DefaultDepth(m_display, m_screen); + } + else + { + // Choose the visual according to the context settings + XVisualInfo visualInfo = ContextType::selectBestVisual(m_display, mode.bitsPerPixel, settings); + + visual = visualInfo.visual; + depth = visualInfo.depth; + } // Define the window attributes XSetWindowAttributes attributes; - attributes.colormap = XCreateColormap(m_display, DefaultRootWindow(m_display), visualInfo.visual, AllocNone); + attributes.colormap = XCreateColormap(m_display, DefaultRootWindow(m_display), visual, AllocNone); attributes.event_mask = eventMask; attributes.override_redirect = (m_fullscreen && !ewmhSupported()) ? True : False; @@ -586,9 +602,9 @@ m_lastInputTime (0) windowPosition.x, windowPosition.y, width, height, 0, - visualInfo.depth, + depth, InputOutput, - visualInfo.visual, + visual, CWEventMask | CWOverrideRedirect | CWColormap, &attributes); diff --git a/src/SFML/Window/Win32/InputImpl.cpp b/src/SFML/Window/Win32/InputImpl.cpp index 04827400..52e57a1d 100644 --- a/src/SFML/Window/Win32/InputImpl.cpp +++ b/src/SFML/Window/Win32/InputImpl.cpp @@ -191,7 +191,7 @@ Vector2i InputImpl::getMousePosition() //////////////////////////////////////////////////////////// -Vector2i InputImpl::getMousePosition(const Window& relativeTo) +Vector2i InputImpl::getMousePosition(const WindowBase& relativeTo) { WindowHandle handle = relativeTo.getSystemHandle(); if (handle) @@ -216,7 +216,7 @@ void InputImpl::setMousePosition(const Vector2i& position) //////////////////////////////////////////////////////////// -void InputImpl::setMousePosition(const Vector2i& position, const Window& relativeTo) +void InputImpl::setMousePosition(const Vector2i& position, const WindowBase& relativeTo) { WindowHandle handle = relativeTo.getSystemHandle(); if (handle) @@ -245,7 +245,7 @@ Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/) //////////////////////////////////////////////////////////// -Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const Window& /*relativeTo*/) +Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const WindowBase& /*relativeTo*/) { // Not applicable return Vector2i(); diff --git a/src/SFML/Window/Win32/InputImpl.hpp b/src/SFML/Window/Win32/InputImpl.hpp index 17ac4822..5098bbad 100644 --- a/src/SFML/Window/Win32/InputImpl.hpp +++ b/src/SFML/Window/Win32/InputImpl.hpp @@ -95,7 +95,7 @@ public: /// \return Current position of the mouse /// //////////////////////////////////////////////////////////// - static Vector2i getMousePosition(const Window& relativeTo); + static Vector2i getMousePosition(const WindowBase& relativeTo); //////////////////////////////////////////////////////////// /// \brief Set the current position of the mouse in desktop coordinates @@ -120,7 +120,7 @@ public: /// \param relativeTo Reference window /// //////////////////////////////////////////////////////////// - static void setMousePosition(const Vector2i& position, const Window& relativeTo); + static void setMousePosition(const Vector2i& position, const WindowBase& relativeTo); //////////////////////////////////////////////////////////// /// \brief Check if a touch event is currently down @@ -157,7 +157,7 @@ public: /// \return Current position of \a finger, or undefined if it's not down /// //////////////////////////////////////////////////////////// - static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo); + static Vector2i getTouchPosition(unsigned int finger, const WindowBase& relativeTo); }; } // namespace priv diff --git a/src/SFML/Window/Window.cpp b/src/SFML/Window/Window.cpp index b1ed548a..34d1b439 100644 --- a/src/SFML/Window/Window.cpp +++ b/src/SFML/Window/Window.cpp @@ -32,20 +32,12 @@ #include -namespace -{ - const sf::Window* fullscreenWindow = NULL; -} - - namespace sf { //////////////////////////////////////////////////////////// Window::Window() : -m_impl (NULL), m_context (NULL), -m_frameTimeLimit(Time::Zero), -m_size (0, 0) +m_frameTimeLimit(Time::Zero) { } @@ -53,23 +45,19 @@ m_size (0, 0) //////////////////////////////////////////////////////////// Window::Window(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings) : -m_impl (NULL), m_context (NULL), -m_frameTimeLimit(Time::Zero), -m_size (0, 0) +m_frameTimeLimit(Time::Zero) { - create(mode, title, style, settings); + Window::create(mode, title, style, settings); } //////////////////////////////////////////////////////////// Window::Window(WindowHandle handle, const ContextSettings& settings) : -m_impl (NULL), m_context (NULL), -m_frameTimeLimit(Time::Zero), -m_size (0, 0) +m_frameTimeLimit(Time::Zero) { - create(handle, settings); + Window::create(handle, settings); } @@ -80,6 +68,13 @@ Window::~Window() } +//////////////////////////////////////////////////////////// +void Window::create(VideoMode mode, const String& title, Uint32 style) +{ + Window::create(mode, title, style, ContextSettings()); +} + + //////////////////////////////////////////////////////////// void Window::create(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings) { @@ -90,7 +85,7 @@ void Window::create(VideoMode mode, const String& title, Uint32 style, const Con if (style & Style::Fullscreen) { // Make sure there's not already a fullscreen window (only one is allowed) - if (fullscreenWindow) + if (getFullscreenWindow()) { err() << "Creating two fullscreen windows is not allowed, switching to windowed mode" << std::endl; style &= ~Style::Fullscreen; @@ -105,7 +100,7 @@ void Window::create(VideoMode mode, const String& title, Uint32 style, const Con } // Update the fullscreen window - fullscreenWindow = this; + setFullscreenWindow(this); } } @@ -131,6 +126,13 @@ void Window::create(VideoMode mode, const String& title, Uint32 style, const Con } +//////////////////////////////////////////////////////////// +void Window::create(WindowHandle handle) +{ + Window::create(handle, ContextSettings()); +} + + //////////////////////////////////////////////////////////// void Window::create(WindowHandle handle, const ContextSettings& settings) { @@ -138,7 +140,7 @@ void Window::create(WindowHandle handle, const ContextSettings& settings) close(); // Recreate the window implementation - m_impl = priv::WindowImpl::create(handle); + WindowBase::create(handle); // Recreate the context m_context = priv::GlContext::create(settings, m_impl, VideoMode::getDesktopMode().bitsPerPixel); @@ -155,20 +157,8 @@ void Window::close() delete m_context; m_context = NULL; - // Delete the window implementation - delete m_impl; - m_impl = NULL; - - // Update the fullscreen window - if (this == fullscreenWindow) - fullscreenWindow = NULL; -} - - -//////////////////////////////////////////////////////////// -bool Window::isOpen() const -{ - return m_impl != NULL; + // Close the base window + WindowBase::close(); } @@ -181,97 +171,6 @@ const ContextSettings& Window::getSettings() const } -//////////////////////////////////////////////////////////// -bool Window::pollEvent(Event& event) -{ - if (m_impl && m_impl->popEvent(event, false)) - { - return filterEvent(event); - } - else - { - return false; - } -} - - -//////////////////////////////////////////////////////////// -bool Window::waitEvent(Event& event) -{ - if (m_impl && m_impl->popEvent(event, true)) - { - return filterEvent(event); - } - else - { - return false; - } -} - - -//////////////////////////////////////////////////////////// -Vector2i Window::getPosition() const -{ - return m_impl ? m_impl->getPosition() : Vector2i(); -} - - -//////////////////////////////////////////////////////////// -void Window::setPosition(const Vector2i& position) -{ - if (m_impl) - m_impl->setPosition(position); -} - - -//////////////////////////////////////////////////////////// -Vector2u Window::getSize() const -{ - return m_size; -} - - -//////////////////////////////////////////////////////////// -void Window::setSize(const Vector2u& size) -{ - if (m_impl) - { - m_impl->setSize(size); - - // Cache the new size - m_size.x = size.x; - m_size.y = size.y; - - // Notify the derived class - onResize(); - } -} - - -//////////////////////////////////////////////////////////// -void Window::setTitle(const String& title) -{ - if (m_impl) - m_impl->setTitle(title); -} - - -//////////////////////////////////////////////////////////// -void Window::setIcon(unsigned int width, unsigned int height, const Uint8* pixels) -{ - if (m_impl) - m_impl->setIcon(width, height, pixels); -} - - -//////////////////////////////////////////////////////////// -void Window::setVisible(bool visible) -{ - if (m_impl) - m_impl->setVisible(visible); -} - - //////////////////////////////////////////////////////////// void Window::setVerticalSyncEnabled(bool enabled) { @@ -280,38 +179,6 @@ void Window::setVerticalSyncEnabled(bool enabled) } -//////////////////////////////////////////////////////////// -void Window::setMouseCursorVisible(bool visible) -{ - if (m_impl) - m_impl->setMouseCursorVisible(visible); -} - - -//////////////////////////////////////////////////////////// -void Window::setMouseCursorGrabbed(bool grabbed) -{ - if (m_impl) - m_impl->setMouseCursorGrabbed(grabbed); -} - - -//////////////////////////////////////////////////////////// -void Window::setMouseCursor(const Cursor& cursor) -{ - if (m_impl) - m_impl->setMouseCursor(cursor.getImpl()); -} - - -//////////////////////////////////////////////////////////// -void Window::setKeyRepeatEnabled(bool enabled) -{ - if (m_impl) - m_impl->setKeyRepeatEnabled(enabled); -} - - //////////////////////////////////////////////////////////// void Window::setFramerateLimit(unsigned int limit) { @@ -322,14 +189,6 @@ void Window::setFramerateLimit(unsigned int limit) } -//////////////////////////////////////////////////////////// -void Window::setJoystickThreshold(float threshold) -{ - if (m_impl) - m_impl->setJoystickThreshold(threshold); -} - - //////////////////////////////////////////////////////////// bool Window::setActive(bool active) const { @@ -353,22 +212,6 @@ bool Window::setActive(bool active) const //////////////////////////////////////////////////////////// -void Window::requestFocus() -{ - if (m_impl) - m_impl->requestFocus(); -} - - -//////////////////////////////////////////////////////////// -bool Window::hasFocus() const -{ - return m_impl && m_impl->hasFocus(); -} - - -//////////////////////////////////////////////////////////// - void Window::display() { // Display the backbuffer on screen @@ -384,66 +227,20 @@ void Window::display() } -//////////////////////////////////////////////////////////// -WindowHandle Window::getSystemHandle() const -{ - return m_impl ? m_impl->getSystemHandle() : 0; -} - - -//////////////////////////////////////////////////////////// -void Window::onCreate() -{ - // Nothing by default -} - - -//////////////////////////////////////////////////////////// -void Window::onResize() -{ - // Nothing by default -} - - -//////////////////////////////////////////////////////////// -bool Window::filterEvent(const Event& event) -{ - // Notify resize events to the derived class - if (event.type == Event::Resized) - { - // Cache the new size - m_size.x = event.size.width; - m_size.y = event.size.height; - - // Notify the derived class - onResize(); - } - - return true; -} - - //////////////////////////////////////////////////////////// void Window::initialize() { // Setup default behaviors (to get a consistent behavior across different implementations) - setVisible(true); - setMouseCursorVisible(true); setVerticalSyncEnabled(false); - setKeyRepeatEnabled(true); setFramerateLimit(0); - // Get and cache the initial size of the window - m_size = m_impl->getSize(); - // Reset frame time m_clock.restart(); // Activate the window setActive(); - // Notify the derived class - onCreate(); + WindowBase::initialize(); } } // namespace sf diff --git a/src/SFML/Window/WindowBase.cpp b/src/SFML/Window/WindowBase.cpp new file mode 100644 index 00000000..cece16b3 --- /dev/null +++ b/src/SFML/Window/WindowBase.cpp @@ -0,0 +1,372 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2018 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include + + +namespace +{ + const sf::WindowBase* fullscreenWindow = NULL; +} + + +namespace sf +{ +//////////////////////////////////////////////////////////// +WindowBase::WindowBase() : +m_impl (NULL), +m_size (0, 0) +{ + +} + + +//////////////////////////////////////////////////////////// +WindowBase::WindowBase(VideoMode mode, const String& title, Uint32 style) : +m_impl (NULL), +m_size (0, 0) +{ + WindowBase::create(mode, title, style); +} + + +//////////////////////////////////////////////////////////// +WindowBase::WindowBase(WindowHandle handle) : +m_impl (NULL), +m_size (0, 0) +{ + WindowBase::create(handle); +} + + +//////////////////////////////////////////////////////////// +WindowBase::~WindowBase() +{ + close(); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::create(VideoMode mode, const String& title, Uint32 style) +{ + // Destroy the previous window implementation + close(); + + // Fullscreen style requires some tests + if (style & Style::Fullscreen) + { + // Make sure there's not already a fullscreen window (only one is allowed) + if (getFullscreenWindow()) + { + err() << "Creating two fullscreen windows is not allowed, switching to windowed mode" << std::endl; + style &= ~Style::Fullscreen; + } + else + { + // Make sure that the chosen video mode is compatible + if (!mode.isValid()) + { + err() << "The requested video mode is not available, switching to a valid mode" << std::endl; + mode = VideoMode::getFullscreenModes()[0]; + } + + // Update the fullscreen window + setFullscreenWindow(this); + } + } + + // Check validity of style according to the underlying platform + #if defined(SFML_SYSTEM_IOS) || defined(SFML_SYSTEM_ANDROID) + if (style & Style::Fullscreen) + style &= ~Style::Titlebar; + else + style |= Style::Titlebar; + #else + if ((style & Style::Close) || (style & Style::Resize)) + style |= Style::Titlebar; + #endif + + // Recreate the window implementation + m_impl = priv::WindowImpl::create(mode, title, style, ContextSettings(0, 0, 0, 0, 0, 0xFFFFFFFF, false)); + + // Perform common initializations + initialize(); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::create(WindowHandle handle) +{ + // Destroy the previous window implementation + close(); + + // Recreate the window implementation + m_impl = priv::WindowImpl::create(handle); + + // Perform common initializations + initialize(); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::close() +{ + // Delete the window implementation + delete m_impl; + m_impl = NULL; + + // Update the fullscreen window + if (this == getFullscreenWindow()) + setFullscreenWindow(NULL); +} + + +//////////////////////////////////////////////////////////// +bool WindowBase::isOpen() const +{ + return m_impl != NULL; +} + + +//////////////////////////////////////////////////////////// +bool WindowBase::pollEvent(Event& event) +{ + if (m_impl && m_impl->popEvent(event, false)) + { + return filterEvent(event); + } + else + { + return false; + } +} + + +//////////////////////////////////////////////////////////// +bool WindowBase::waitEvent(Event& event) +{ + if (m_impl && m_impl->popEvent(event, true)) + { + return filterEvent(event); + } + else + { + return false; + } +} + + +//////////////////////////////////////////////////////////// +Vector2i WindowBase::getPosition() const +{ + return m_impl ? m_impl->getPosition() : Vector2i(); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::setPosition(const Vector2i& position) +{ + if (m_impl) + m_impl->setPosition(position); +} + + +//////////////////////////////////////////////////////////// +Vector2u WindowBase::getSize() const +{ + return m_size; +} + + +//////////////////////////////////////////////////////////// +void WindowBase::setSize(const Vector2u& size) +{ + if (m_impl) + { + m_impl->setSize(size); + + // Cache the new size + m_size.x = size.x; + m_size.y = size.y; + + // Notify the derived class + onResize(); + } +} + + +//////////////////////////////////////////////////////////// +void WindowBase::setTitle(const String& title) +{ + if (m_impl) + m_impl->setTitle(title); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::setIcon(unsigned int width, unsigned int height, const Uint8* pixels) +{ + if (m_impl) + m_impl->setIcon(width, height, pixels); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::setVisible(bool visible) +{ + if (m_impl) + m_impl->setVisible(visible); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::setMouseCursorVisible(bool visible) +{ + if (m_impl) + m_impl->setMouseCursorVisible(visible); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::setMouseCursorGrabbed(bool grabbed) +{ + if (m_impl) + m_impl->setMouseCursorGrabbed(grabbed); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::setMouseCursor(const Cursor& cursor) +{ + if (m_impl) + m_impl->setMouseCursor(cursor.getImpl()); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::setKeyRepeatEnabled(bool enabled) +{ + if (m_impl) + m_impl->setKeyRepeatEnabled(enabled); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::setJoystickThreshold(float threshold) +{ + if (m_impl) + m_impl->setJoystickThreshold(threshold); +} + + +//////////////////////////////////////////////////////////// +void WindowBase::requestFocus() +{ + if (m_impl) + m_impl->requestFocus(); +} + + +//////////////////////////////////////////////////////////// +bool WindowBase::hasFocus() const +{ + return m_impl && m_impl->hasFocus(); +} + + +//////////////////////////////////////////////////////////// +WindowHandle WindowBase::getSystemHandle() const +{ + return m_impl ? m_impl->getSystemHandle() : 0; +} + + +//////////////////////////////////////////////////////////// +void WindowBase::onCreate() +{ + // Nothing by default +} + + +//////////////////////////////////////////////////////////// +void WindowBase::onResize() +{ + // Nothing by default +} + + +//////////////////////////////////////////////////////////// +bool WindowBase::filterEvent(const Event& event) +{ + // Notify resize events to the derived class + if (event.type == Event::Resized) + { + // Cache the new size + m_size.x = event.size.width; + m_size.y = event.size.height; + + // Notify the derived class + onResize(); + } + + return true; +} + + +//////////////////////////////////////////////////////////// +void WindowBase::initialize() +{ + // Setup default behaviors (to get a consistent behavior across different implementations) + setVisible(true); + setMouseCursorVisible(true); + setKeyRepeatEnabled(true); + + // Get and cache the initial size of the window + m_size = m_impl->getSize(); + + // Notify the derived class + onCreate(); +} + + +//////////////////////////////////////////////////////////// +const WindowBase* WindowBase::getFullscreenWindow() +{ + return fullscreenWindow; +} + + +//////////////////////////////////////////////////////////// +void WindowBase::setFullscreenWindow(const WindowBase* window) +{ + fullscreenWindow = window; +} + +} // namespace sf diff --git a/src/SFML/Window/iOS/InputImpl.hpp b/src/SFML/Window/iOS/InputImpl.hpp index 0d62071c..75b02b06 100644 --- a/src/SFML/Window/iOS/InputImpl.hpp +++ b/src/SFML/Window/iOS/InputImpl.hpp @@ -95,7 +95,7 @@ public: /// \return Current position of the mouse /// //////////////////////////////////////////////////////////// - static Vector2i getMousePosition(const Window& relativeTo); + static Vector2i getMousePosition(const WindowBase& relativeTo); //////////////////////////////////////////////////////////// /// \brief Set the current position of the mouse in desktop coordinates @@ -120,7 +120,7 @@ public: /// \param relativeTo Reference window /// //////////////////////////////////////////////////////////// - static void setMousePosition(const Vector2i& position, const Window& relativeTo); + static void setMousePosition(const Vector2i& position, const WindowBase& relativeTo); //////////////////////////////////////////////////////////// /// \brief Check if a touch event is currently down @@ -157,7 +157,7 @@ public: /// \return Current position of \a finger, or undefined if it's not down /// //////////////////////////////////////////////////////////// - static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo); + static Vector2i getTouchPosition(unsigned int finger, const WindowBase& relativeTo); }; } // namespace priv diff --git a/src/SFML/Window/iOS/InputImpl.mm b/src/SFML/Window/iOS/InputImpl.mm index bada27d1..92a2fd16 100644 --- a/src/SFML/Window/iOS/InputImpl.mm +++ b/src/SFML/Window/iOS/InputImpl.mm @@ -67,7 +67,7 @@ Vector2i InputImpl::getMousePosition() //////////////////////////////////////////////////////////// -Vector2i InputImpl::getMousePosition(const Window& relativeTo) +Vector2i InputImpl::getMousePosition(const WindowBase& relativeTo) { (void)relativeTo; @@ -83,7 +83,7 @@ void InputImpl::setMousePosition(const Vector2i& position) //////////////////////////////////////////////////////////// -void InputImpl::setMousePosition(const Vector2i& position, const Window& relativeTo) +void InputImpl::setMousePosition(const Vector2i& position, const WindowBase& relativeTo) { // Not applicable } @@ -104,7 +104,7 @@ Vector2i InputImpl::getTouchPosition(unsigned int finger) //////////////////////////////////////////////////////////// -Vector2i InputImpl::getTouchPosition(unsigned int finger, const Window& relativeTo) +Vector2i InputImpl::getTouchPosition(unsigned int finger, const WindowBase& relativeTo) { (void)relativeTo;