From c793b81235eba6e9e9144792dcd0366c8d73c2eb Mon Sep 17 00:00:00 2001 From: Maximilian Wagenbach Date: Wed, 7 Feb 2018 15:31:02 +0100 Subject: [PATCH] Implementation for the new window states API on MacOS. --- include/SFML/Window/Window.hpp | 27 +++++++++- include/SFML/Window/WindowState.hpp | 47 ++++++++++++++++ include/SFML/Window/WindowStyle.hpp | 1 + src/SFML/Window/CMakeLists.txt | 1 + src/SFML/Window/OSX/SFWindowController.mm | 53 ++++++++++++++++++- src/SFML/Window/OSX/WindowImplCocoa.hpp | 17 ++++++ src/SFML/Window/OSX/WindowImplCocoa.mm | 47 ++++++++++++++++ .../Window/OSX/WindowImplDelegateProtocol.h | 42 +++++++++++++++ src/SFML/Window/Window.cpp | 25 +++++++-- src/SFML/Window/WindowImpl.hpp | 19 ++++++- 10 files changed, 271 insertions(+), 8 deletions(-) create mode 100644 include/SFML/Window/WindowState.hpp diff --git a/include/SFML/Window/Window.hpp b/include/SFML/Window/Window.hpp index 7ff81e294..3bdb5a273 100644 --- a/include/SFML/Window/Window.hpp +++ b/include/SFML/Window/Window.hpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -472,6 +473,30 @@ public: //////////////////////////////////////////////////////////// bool hasFocus() const; + //////////////////////////////////////////////////////////// + /// \brief Set the window state + /// + /// Set the window state. + /// + /// \param state The new state + /// + /// \see getState + /// + //////////////////////////////////////////////////////////// + void setState(State state); + + //////////////////////////////////////////////////////////// + /// \brief Get the windows state + /// + /// Get the window state. + /// + /// \return The window state + /// + /// \see setState + /// + //////////////////////////////////////////////////////////// + State getState() const; + //////////////////////////////////////////////////////////// /// \brief Display on screen what has been rendered to the window so far /// @@ -537,7 +562,7 @@ private: /// \brief Perform some common internal initializations /// //////////////////////////////////////////////////////////// - void initialize(); + void initialize(Uint32 style); //////////////////////////////////////////////////////////// // Member data diff --git a/include/SFML/Window/WindowState.hpp b/include/SFML/Window/WindowState.hpp new file mode 100644 index 000000000..16c441c8b --- /dev/null +++ b/include/SFML/Window/WindowState.hpp @@ -0,0 +1,47 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2018 Foaly (foaly@posteo.de) +// +// 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_WINDOWSTATE_HPP +#define SFML_WINDOWSTATE_HPP + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// \ingroup window +/// \brief Enumeration of the window states +/// +//////////////////////////////////////////////////////////// +enum State +{ + Windowed, + Minimized, + Maximized, + Fullscreen +}; + +} // namespace sf + + +#endif // SFML_WINDOWSTATE_HPP diff --git a/include/SFML/Window/WindowStyle.hpp b/include/SFML/Window/WindowStyle.hpp index 53e2c9df5..8847efb16 100644 --- a/include/SFML/Window/WindowStyle.hpp +++ b/include/SFML/Window/WindowStyle.hpp @@ -42,6 +42,7 @@ namespace Style Resize = 1 << 1, ///< Title bar + resizable border + maximize button Close = 1 << 2, ///< Title bar + close button Fullscreen = 1 << 3, ///< Fullscreen mode (this flag and all others are mutually exclusive) + Hidden = 1 << 4, ///< Hidden window Default = Titlebar | Resize | Close ///< Default window style }; diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index 98ea43946..f9f4ae5b1 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -45,6 +45,7 @@ set(SRC ${SRCROOT}/WindowImpl.cpp ${SRCROOT}/WindowImpl.hpp ${INCROOT}/WindowStyle.hpp + ${INCROOT}/WindowState.hpp ) if(SFML_OPENGL_ES AND NOT SFML_OS_IOS) list(APPEND SRC ${SRCROOT}/EGLCheck.cpp) diff --git a/src/SFML/Window/OSX/SFWindowController.mm b/src/SFML/Window/OSX/SFWindowController.mm index 186a0fbe5..cb5148e08 100644 --- a/src/SFML/Window/OSX/SFWindowController.mm +++ b/src/SFML/Window/OSX/SFWindowController.mm @@ -158,6 +158,9 @@ [self setupWindowWithMode:mode andStyle:style]; [m_oglView finishInit]; + + if (style & sf::Style::Hidden) + [m_window orderOut:self]; } return self; } @@ -492,7 +495,7 @@ //////////////////////////////////////////////////////// -(void)hideWindow { - [m_window orderOut:nil]; + [m_window orderOut:self]; } @@ -530,6 +533,54 @@ } +//////////////////////////////////////////////////////// +-(void)minimize +{ + [m_window miniaturize:self]; +} + + +//////////////////////////////////////////////////////// +-(void)unminimize +{ + [m_window deminiaturize:self]; +} + + +//////////////////////////////////////////////////////// +-(void)toogleMaximize +{ + [m_window zoom:self]; +} + + +//////////////////////////////////////////////////////// +-(BOOL)isMinimized +{ + return [m_window isMiniaturized]; +} + + +//////////////////////////////////////////////////////// +-(BOOL)isMaximized +{ + // isZoomed is always true when the windows has the style NSBorderlessWindowMask or is fullscreen + // also the other SFML styles besides Resize can't be maximized, so we filter here + NSUInteger style = [m_window styleMask]; + if ( !(style & NSResizableWindowMask) ) + return NO; + + return [m_window isZoomed]; +} + + +//////////////////////////////////////////////////////// +-(BOOL)isFullscreen +{ + return m_fullscreen; +} + + //////////////////////////////////////////////////////// -(void)enableKeyRepeat { diff --git a/src/SFML/Window/OSX/WindowImplCocoa.hpp b/src/SFML/Window/OSX/WindowImplCocoa.hpp index eea318de2..9c4d09c3e 100644 --- a/src/SFML/Window/OSX/WindowImplCocoa.hpp +++ b/src/SFML/Window/OSX/WindowImplCocoa.hpp @@ -352,6 +352,23 @@ public: //////////////////////////////////////////////////////////// virtual bool hasFocus() const; + //////////////////////////////////////////////////////////// + /// \brief Set the window state + /// + /// \param state The new state + /// + //////////////////////////////////////////////////////////// + virtual void setState(State state); + + + //////////////////////////////////////////////////////////// + /// \brief Get the window state + /// + /// \return The window state + /// + //////////////////////////////////////////////////////////// + virtual State getState() const; + protected: //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/OSX/WindowImplCocoa.mm b/src/SFML/Window/OSX/WindowImplCocoa.mm index edb69358f..2206b4f82 100644 --- a/src/SFML/Window/OSX/WindowImplCocoa.mm +++ b/src/SFML/Window/OSX/WindowImplCocoa.mm @@ -524,6 +524,53 @@ bool WindowImplCocoa::hasFocus() const } +//////////////////////////////////////////////////////////// +void WindowImplCocoa::setState(State state) +{ + State currentState = getState(); + + switch(state) + { + case State::Minimized: + [m_delegate minimize]; + break; + + case State::Maximized: + if (currentState == State::Windowed) + [m_delegate toogleMaximize]; + if (currentState == State::Minimized) + { + [m_delegate unminimize]; + [m_delegate toogleMaximize]; + } + break; + + case State::Windowed: + if (currentState == State::Minimized) + [m_delegate unminimize]; + else if (currentState == State::Maximized) + [m_delegate toogleMaximize]; + break; + + case Fullscreen: + sf::err() << "Switching to fullscreen is not implemtent on OSX yet." << std::endl; + break; + } +} + + +//////////////////////////////////////////////////////////// +State WindowImplCocoa::getState() const +{ + if ([m_delegate isFullscreen]) + return State::Fullscreen; + if ([m_delegate isMinimized]) + return State::Minimized; + if ([m_delegate isMaximized]) + return State::Maximized; + return State::Windowed; +} + } // namespace priv } // namespace sf diff --git a/src/SFML/Window/OSX/WindowImplDelegateProtocol.h b/src/SFML/Window/OSX/WindowImplDelegateProtocol.h index d6cfa9011..9d92be093 100644 --- a/src/SFML/Window/OSX/WindowImplDelegateProtocol.h +++ b/src/SFML/Window/OSX/WindowImplDelegateProtocol.h @@ -195,6 +195,48 @@ namespace sf { //////////////////////////////////////////////////////////// -(BOOL)hasFocus; +//////////////////////////////////////////////////////////// +/// \brief Minimize the window +/// +//////////////////////////////////////////////////////////// +-(void)minimize; + +//////////////////////////////////////////////////////////// +/// \brief Unminimize the window +/// +//////////////////////////////////////////////////////////// +-(void)unminimize; + +//////////////////////////////////////////////////////////// +/// \brief Maximize or unmaximizes the window +/// +//////////////////////////////////////////////////////////// +-(void)toogleMaximize; + +//////////////////////////////////////////////////////////// +/// \brief Check whether the window is minimized +/// +/// \return True if window is minimized, false otherwise +/// +//////////////////////////////////////////////////////////// +-(BOOL)isMinimized; + +//////////////////////////////////////////////////////////// +/// \brief Check whether the window is maximized +/// +/// \return True if window is maximized, false otherwise +/// +//////////////////////////////////////////////////////////// +-(BOOL)isMaximized; + +//////////////////////////////////////////////////////////// +/// \brief Check whether the window is fullscreen +/// +/// \return True if window is fullscreen, false otherwise +/// +//////////////////////////////////////////////////////////// +-(BOOL)isFullscreen; + //////////////////////////////////////////////////////////// /// \brief Enable key repeat /// diff --git a/src/SFML/Window/Window.cpp b/src/SFML/Window/Window.cpp index b1ed548ab..ef70f57b9 100644 --- a/src/SFML/Window/Window.cpp +++ b/src/SFML/Window/Window.cpp @@ -127,7 +127,7 @@ void Window::create(VideoMode mode, const String& title, Uint32 style, const Con m_context = priv::GlContext::create(settings, m_impl, mode.bitsPerPixel); // Perform common initializations - initialize(); + initialize(style); } @@ -144,7 +144,7 @@ void Window::create(WindowHandle handle, const ContextSettings& settings) m_context = priv::GlContext::create(settings, m_impl, VideoMode::getDesktopMode().bitsPerPixel); // Perform common initializations - initialize(); + initialize(sf::Style::Default); } @@ -368,7 +368,21 @@ bool Window::hasFocus() const //////////////////////////////////////////////////////////// +void Window::setState(State state) +{ + if (m_impl) + m_impl->setState(state); +} + +//////////////////////////////////////////////////////////// +State Window::getState() const +{ + return m_impl ? m_impl->getState() : State::Windowed; +} + + +//////////////////////////////////////////////////////////// void Window::display() { // Display the backbuffer on screen @@ -424,15 +438,16 @@ bool Window::filterEvent(const Event& event) //////////////////////////////////////////////////////////// -void Window::initialize() +void Window::initialize(Uint32 style) { // Setup default behaviors (to get a consistent behavior across different implementations) - setVisible(true); - setMouseCursorVisible(true); setVerticalSyncEnabled(false); setKeyRepeatEnabled(true); setFramerateLimit(0); + if (!(style & Style::Hidden)) + setVisible(true); + // Get and cache the initial size of the window m_size = m_impl->getSize(); diff --git a/src/SFML/Window/WindowImpl.hpp b/src/SFML/Window/WindowImpl.hpp index a360a0184..ead8822f4 100644 --- a/src/SFML/Window/WindowImpl.hpp +++ b/src/SFML/Window/WindowImpl.hpp @@ -39,8 +39,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -227,6 +228,22 @@ public: //////////////////////////////////////////////////////////// virtual bool hasFocus() const = 0; + //////////////////////////////////////////////////////////// + /// \brief Set the window state + /// + /// \param state The new state + /// + //////////////////////////////////////////////////////////// + virtual void setState(State state) = 0; + + //////////////////////////////////////////////////////////// + /// \brief Get the window state + /// + /// \return The window state + /// + //////////////////////////////////////////////////////////// + virtual State getState() const = 0; + protected: ////////////////////////////////////////////////////////////