Skip to content

Commit 9cd0008

Browse files
Enable non-resizable windows (SDL2 only)
Add a hidden setting to control whether the window is resizable. Fixes #1512
1 parent df3aa8c commit 9cd0008

File tree

21 files changed

+222
-88
lines changed

21 files changed

+222
-88
lines changed

extras/videoDrivers/SDL2/VideoSDL2.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ void VideoSDL2::UpdateCurrentSizes()
9191
SetNewSize(VideoMode(w, h), Extent(w2, h2));
9292
}
9393

94-
bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bool fullscreen)
94+
bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, DisplayMode displayMode)
9595
{
9696
if(!initialized)
9797
return false;
@@ -113,30 +113,33 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo
113113
CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8));
114114
CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1));
115115

116-
int wndPos = SDL_WINDOWPOS_CENTERED;
117-
116+
const int wndPos = SDL_WINDOWPOS_CENTERED;
117+
const auto fullscreen = (displayMode & DisplayMode::Fullscreen) != DisplayMode::None;
118+
const auto resizable = (displayMode & DisplayMode::Resizable) != DisplayMode::None;
118119
const auto requestedSize = fullscreen ? FindClosestVideoMode(size) : size;
120+
const unsigned commonFlags = SDL_WINDOW_OPENGL | (resizable ? SDL_WINDOW_RESIZABLE : 0);
121+
const unsigned fullscreenFlag = (fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
119122

120123
window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height,
121-
SDL_WINDOW_OPENGL | (fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE));
124+
commonFlags | fullscreenFlag);
122125

123126
// Fallback to non-fullscreen
124127
if(!window && fullscreen)
125-
{
126-
window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height,
127-
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
128-
}
128+
window =
129+
SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height, commonFlags);
129130

130131
if(!window)
131132
{
132133
PrintError(SDL_GetError());
133134
return false;
134135
}
135136

136-
isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0;
137+
const auto flags = SDL_GetWindowFlags(window);
138+
SetFullscreenFlag((flags & SDL_WINDOW_FULLSCREEN) != 0);
139+
SetResizableFlag((flags & SDL_WINDOW_RESIZABLE) != 0);
137140
UpdateCurrentSizes();
138141

139-
if(!isFullscreen_)
142+
if(!IsFullscreen())
140143
MoveWindowToCenter();
141144

142145
SDL_Surface* iconSurf =
@@ -161,27 +164,34 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo
161164
return true;
162165
}
163166

164-
bool VideoSDL2::ResizeScreen(const VideoMode& newSize, bool fullscreen)
167+
bool VideoSDL2::ResizeScreen(const VideoMode& newSize, DisplayMode displayMode)
165168
{
166169
if(!initialized)
167170
return false;
168171

169-
if(isFullscreen_ != fullscreen)
172+
const auto fullscreen = (displayMode & DisplayMode::Fullscreen) != DisplayMode::None;
173+
const auto resizable = (displayMode & DisplayMode::Resizable) != DisplayMode::None;
174+
175+
if(IsFullscreen() != fullscreen)
170176
{
171177
SDL_SetWindowFullscreen(window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
172-
isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0;
173-
if(!isFullscreen_)
174-
{
178+
SetFullscreenFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0);
179+
if(!IsFullscreen())
180+
MoveWindowToCenter();
181+
}
182+
183+
if(displayMode_ != displayMode)
184+
{
185+
if(!IsFullscreen())
175186
#if SDL_VERSION_ATLEAST(2, 0, 5)
176-
SDL_SetWindowResizable(window, SDL_TRUE);
187+
SDL_SetWindowResizable(window, static_cast<SDL_bool>(resizable));
177188
#endif
178-
MoveWindowToCenter();
179-
}
189+
SetResizableFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_RESIZABLE) != 0);
180190
}
181191

182192
if(newSize != GetWindowSize())
183193
{
184-
if(isFullscreen_)
194+
if(IsFullscreen())
185195
{
186196
auto const targetMode = FindClosestVideoMode(newSize);
187197
SDL_DisplayMode target;
@@ -203,6 +213,7 @@ bool VideoSDL2::ResizeScreen(const VideoMode& newSize, bool fullscreen)
203213
}
204214
UpdateCurrentSizes();
205215
}
216+
206217
return true;
207218
}
208219

@@ -265,7 +276,7 @@ bool VideoSDL2::MessageLoop()
265276
{
266277
case SDL_WINDOWEVENT_RESIZED:
267278
{
268-
isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0;
279+
SetFullscreenFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0);
269280
VideoMode newSize(ev.window.data1, ev.window.data2);
270281
if(newSize != GetWindowSize())
271282
{

extras/videoDrivers/SDL2/VideoSDL2.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ class VideoSDL2 final : public VideoDriver
2424

2525
bool Initialize() override;
2626

27-
bool CreateScreen(const std::string& title, const VideoMode& size, bool fullscreen) override;
28-
bool ResizeScreen(const VideoMode& newSize, bool fullscreen) override;
27+
bool CreateScreen(const std::string& title, const VideoMode& size, DisplayMode displayMode) override;
28+
bool ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) override;
2929

3030
void DestroyScreen() override;
3131

extras/videoDrivers/WinAPI/WinAPI.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,26 +129,25 @@ void VideoWinAPI::CleanUp()
129129
/**
130130
* Erstellt das Fenster mit entsprechenden Werten.
131131
*
132-
* @param[in] width Breite des Fensters
133-
* @param[in] height Höhe des Fensters
134-
* @param[in] fullscreen Vollbildmodus ja oder nein
132+
* @param[in] width Breite des Fensters
133+
* @param[in] height Höhe des Fensters
134+
* @param[in] displayMode Fullscreen on/off, window resizable?
135135
*
136136
* @return @p true bei Erfolg, @p false bei Fehler
137137
*
138138
* @bug Hardwarecursor ist bei Fenstermodus sichtbar,
139139
* Cursor deaktivieren ist fehlerhaft
140140
*/
141-
bool VideoWinAPI::CreateScreen(const std::string& title, const VideoMode& newSize, bool fullscreen)
141+
bool VideoWinAPI::CreateScreen(const std::string& title, const VideoMode& newSize, DisplayMode displayMode)
142142
{
143143
if(!initialized)
144144
return false;
145145

146-
if(!RegisterAndCreateWindow(title, newSize, fullscreen))
146+
if(!RegisterAndCreateWindow(title, newSize, displayMode))
147147
return false;
148148

149-
if(fullscreen && !MakeFullscreen(GetWindowSize()))
149+
if(bitset::isSet(displayMode, DisplayMode::Fullscreen) && !MakeFullscreen(GetWindowSize()))
150150
return false;
151-
isFullscreen_ = fullscreen;
152151

153152
if(!InitOGL())
154153
return false;
@@ -174,30 +173,31 @@ bool VideoWinAPI::CreateScreen(const std::string& title, const VideoMode& newSiz
174173
*
175174
* @todo Vollbildmodus ggf. wechseln
176175
*/
177-
bool VideoWinAPI::ResizeScreen(const VideoMode& newSize, bool fullscreen)
176+
bool VideoWinAPI::ResizeScreen(const VideoMode& newSize, DisplayMode displayMode)
178177
{
179178
if(!initialized || !isWindowResizable)
180179
return false;
181180

182-
if(isFullscreen_ == fullscreen && newSize == GetWindowSize())
181+
const auto fullscreen = bitset::isSet(displayMode, DisplayMode::Fullscreen);
182+
if(IsFullscreen() == fullscreen && newSize == GetWindowSize())
183183
return true;
184184

185185
ShowWindow(screen, SW_HIDE);
186186

187187
VideoMode windowSize = fullscreen ? FindClosestVideoMode(newSize) : newSize;
188188
// Try to switch full screen first
189-
if(isFullscreen_ && !fullscreen)
189+
if(IsFullscreen() && !fullscreen)
190190
{
191191
if(ChangeDisplaySettings(nullptr, 0) != DISP_CHANGE_SUCCESSFUL)
192192
return false;
193-
} else if(isFullscreen_ || fullscreen)
193+
} else if(IsFullscreen() || fullscreen)
194194
{
195195
if(!MakeFullscreen(windowSize))
196196
return false;
197197
}
198198

199199
// Fensterstyle ggf. ändern
200-
std::pair<DWORD, DWORD> style = GetStyleFlags(isFullscreen_);
200+
std::pair<DWORD, DWORD> style = GetStyleFlags(IsFullscreen());
201201
SetWindowLongPtr(screen, GWL_STYLE, style.first);
202202
SetWindowLongPtr(screen, GWL_EXSTYLE, style.second);
203203

@@ -253,7 +253,7 @@ RECT VideoWinAPI::CalculateWindowRect(bool fullscreen, VideoMode& size) const
253253
return wRect;
254254
}
255255

256-
bool VideoWinAPI::RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, bool fullscreen)
256+
bool VideoWinAPI::RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, DisplayMode displayMode)
257257
{
258258
std::wstring wTitle = boost::nowide::widen(title);
259259
windowClassName = wTitle.substr(0, wTitle.find(' '));
@@ -275,6 +275,7 @@ bool VideoWinAPI::RegisterAndCreateWindow(const std::string& title, const VideoM
275275
return false;
276276

277277
// Create window
278+
const auto fullscreen = bitset::isSet(displayMode, DisplayMode::Fullscreen);
278279
auto adjWindowSize = fullscreen ? FindClosestVideoMode(wndSize) : wndSize;
279280
RECT wRect = CalculateWindowRect(fullscreen, adjWindowSize);
280281

@@ -405,7 +406,7 @@ void VideoWinAPI::DestroyScreen()
405406

406407
UnregisterClassW(windowClassName.c_str(), GetModuleHandle(nullptr));
407408

408-
isFullscreen_ = false;
409+
displayMode_ = bitset::set(displayMode_, DisplayMode::Fullscreen, false);
409410
}
410411

411412
/**

extras/videoDrivers/WinAPI/WinAPI.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ class VideoWinAPI final : public VideoDriver
3030
bool Initialize() override;
3131

3232
/// Erstellt das Fenster mit entsprechenden Werten.
33-
bool CreateScreen(const std::string& title, const VideoMode& newSize, bool fullscreen) override;
33+
bool CreateScreen(const std::string& title, const VideoMode& newSize, DisplayMode displayMode) override;
3434

3535
/// Erstellt oder verändert das Fenster mit entsprechenden Werten.
36-
bool ResizeScreen(const VideoMode& newSize, bool fullscreen) override;
36+
bool ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) override;
3737

3838
/// Schliesst das Fenster.
3939
void DestroyScreen() override;
@@ -66,7 +66,7 @@ class VideoWinAPI final : public VideoDriver
6666
std::pair<DWORD, DWORD> GetStyleFlags(bool fullscreen) const;
6767
/// Calculate the rect for the window and adjusts the (usable) size if required
6868
RECT CalculateWindowRect(bool fullscreen, VideoMode& size) const;
69-
bool RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, bool fullscreen);
69+
bool RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, DisplayMode displayMode);
7070
bool InitOGL();
7171
static bool MakeFullscreen(const VideoMode& resolution);
7272

libs/driver/include/driver/VideoDriver.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ class VideoDriver : public IVideoDriver
2929

3030
VideoMode GetWindowSize() const override final { return windowSize_; }
3131
Extent GetRenderSize() const override final { return renderSize_; }
32-
bool IsFullscreen() const override final { return isFullscreen_; }
32+
DisplayMode GetDisplayMode() const override final { return displayMode_; }
33+
bool IsFullscreen() const override final { return bitset::isSet(displayMode_, DisplayMode::Fullscreen); }
34+
bool IsResizable() const override final { return bitset::isSet(displayMode_, DisplayMode::Fullscreen); }
3335

3436
/// prüft auf Initialisierung.
3537
bool IsInitialized() const override final { return initialized; }
@@ -39,11 +41,14 @@ class VideoDriver : public IVideoDriver
3941
VideoMode FindClosestVideoMode(const VideoMode& mode) const;
4042
void SetNewSize(VideoMode windowSize, Extent renderSize);
4143

44+
void SetFullscreenFlag(bool fullscreen) { displayMode_ = fullscreen ? (displayMode_ | DisplayMode::Fullscreen) : (displayMode_ & ~DisplayMode::Fullscreen); }
45+
void SetResizableFlag(bool resizable) { displayMode_ = bitset::set(displayMode_, DisplayMode::Resizable, resizable); }
46+
4247
VideoDriverLoaderInterface* CallBack; /// Das DriverCallback für Rückmeldungen.
4348
bool initialized; /// Initialisierungsstatus.
4449
MouseCoords mouse_xy; /// Status der Maus.
4550
std::array<bool, 512> keyboard; /// Status der Tastatur;
46-
bool isFullscreen_; /// Vollbild an/aus?
51+
DisplayMode displayMode_; /// Fullscreen/resizable?
4752
private:
4853
// cached as possibly used often
4954
VideoMode windowSize_;

libs/driver/include/driver/VideoInterface.h

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,96 @@
88
#include "Point.h"
99
#include "VideoMode.h"
1010
#include "exportImport.h"
11+
// #include "s25util/enumUtils.h"
1112
#include <string>
13+
#include <type_traits>
1214
#include <vector>
1315

1416
/// Function type for loading OpenGL methods
1517
using OpenGL_Loader_Proc = void* (*)(const char*);
1618

19+
template<typename Enum>
20+
struct IsBitset : std::false_type
21+
{};
22+
23+
template<typename Enum>
24+
using IsValidBitset =
25+
std::integral_constant<bool, IsBitset<Enum>::value && std::is_unsigned<std::underlying_type_t<Enum>>::value>;
26+
27+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
28+
constexpr auto operator~(Enum val) noexcept
29+
{
30+
using T = std::underlying_type_t<Enum>;
31+
return Enum(~static_cast<T>(val));
32+
}
33+
34+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
35+
constexpr auto operator&(Enum lhs, Enum rhs) noexcept
36+
{
37+
using T = std::underlying_type_t<Enum>;
38+
return Enum(static_cast<T>(lhs) & static_cast<T>(rhs));
39+
}
40+
41+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
42+
constexpr auto operator|(Enum lhs, Enum rhs) noexcept
43+
{
44+
using T = std::underlying_type_t<Enum>;
45+
return Enum(static_cast<T>(lhs) | static_cast<T>(rhs));
46+
}
47+
48+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
49+
constexpr auto operator^(Enum lhs, Enum rhs) noexcept
50+
{
51+
using T = std::underlying_type_t<Enum>;
52+
return Enum(static_cast<T>(lhs) ^ static_cast<T>(rhs));
53+
}
54+
55+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
56+
constexpr auto operator&=(Enum& lhs, Enum rhs) noexcept
57+
{
58+
lhs = lhs & rhs;
59+
return lhs;
60+
}
61+
62+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
63+
constexpr auto operator|=(Enum& lhs, Enum rhs) noexcept
64+
{
65+
lhs = lhs | rhs;
66+
return lhs;
67+
}
68+
69+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
70+
constexpr auto operator^=(Enum& lhs, Enum rhs) noexcept
71+
{
72+
lhs = lhs ^ rhs;
73+
return lhs;
74+
}
75+
76+
namespace bitset {
77+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
78+
constexpr bool isSet(Enum val, Enum flag)
79+
{
80+
return (val & flag) != Enum(0);
81+
}
82+
83+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
84+
[[nodiscard]] constexpr Enum set(Enum val, Enum flag, bool state)
85+
{
86+
return state ? (val | flag) : (val & ~flag);
87+
}
88+
} // namespace bitset
89+
90+
enum class DisplayMode : unsigned
91+
{
92+
None,
93+
Fullscreen = (1 << 0),
94+
Resizable = (1 << 1)
95+
};
96+
97+
template<>
98+
struct IsBitset<DisplayMode> : std::true_type
99+
{};
100+
17101
class BOOST_SYMBOL_VISIBLE IVideoDriver
18102
{
19103
public:
@@ -25,9 +109,9 @@ class BOOST_SYMBOL_VISIBLE IVideoDriver
25109
virtual bool Initialize() = 0;
26110

27111
/// Erstellt das Fenster mit entsprechenden Werten.
28-
virtual bool CreateScreen(const std::string& title, const VideoMode& newSize, bool fullscreen) = 0;
112+
virtual bool CreateScreen(const std::string& title, const VideoMode& newSize, DisplayMode displayMode) = 0;
29113

30-
virtual bool ResizeScreen(const VideoMode& newSize, bool fullscreen) = 0;
114+
virtual bool ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) = 0;
31115

32116
/// Schliesst das Fenster.
33117
virtual void DestroyScreen() = 0;
@@ -61,7 +145,9 @@ class BOOST_SYMBOL_VISIBLE IVideoDriver
61145
virtual VideoMode GetWindowSize() const = 0;
62146
/// Get the size of the render region in pixels
63147
virtual Extent GetRenderSize() const = 0;
148+
virtual DisplayMode GetDisplayMode() const = 0;
64149
virtual bool IsFullscreen() const = 0;
150+
virtual bool IsResizable() const = 0;
65151

66152
/// Get state of the modifier keys
67153
virtual KeyEvent GetModKeyState() const = 0;

libs/driver/src/VideoDriver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ IVideoDriver::~IVideoDriver() = default;
1717
* @param[in] CallBack DriverCallback für Rückmeldungen.
1818
*/
1919
VideoDriver::VideoDriver(VideoDriverLoaderInterface* CallBack)
20-
: CallBack(CallBack), initialized(false), isFullscreen_(false), renderSize_(0, 0)
20+
: CallBack(CallBack), initialized(false), displayMode_(DisplayMode::Resizable), renderSize_(0, 0)
2121
{
2222
std::fill(keyboard.begin(), keyboard.end(), false);
2323
}

0 commit comments

Comments
 (0)