diff --git a/src/game_launcher.cpp b/src/game_launcher.cpp index dbb33b910751c..cef9e8a205e88 100644 --- a/src/game_launcher.cpp +++ b/src/game_launcher.cpp @@ -213,7 +213,7 @@ game_launcher::game_launcher(const commandline_options& cmdline_opts, const char const int xres = std::get<0>(*cmdline_opts_.resolution); const int yres = std::get<1>(*cmdline_opts_.resolution); if(xres > 0 && yres > 0) { - preferences::_set_resolution(std::make_pair(xres, yres)); + preferences::_set_resolution(point(xres, yres)); preferences::_set_maximized(false); } } diff --git a/src/gui/dialogs/multiplayer/lobby.cpp b/src/gui/dialogs/multiplayer/lobby.cpp index e78a8c70937b1..c4f2b2accc8ea 100644 --- a/src/gui/dialogs/multiplayer/lobby.cpp +++ b/src/gui/dialogs/multiplayer/lobby.cpp @@ -179,7 +179,7 @@ void mp_lobby::post_build(window& win) { /** @todo Should become a global hotkey after 1.8, then remove it here. */ win.register_hotkey(hotkey::HOTKEY_FULLSCREEN, - std::bind(&CVideo::set_fullscreen, std::ref(win.video()), !preferences::fullscreen())); + std::bind(&CVideo::toggle_fullscreen, std::ref(win.video()))); /*** Local hotkeys. ***/ win.register_hotkey(hotkey::HOTKEY_PREFERENCES, diff --git a/src/gui/dialogs/preferences_dialog.cpp b/src/gui/dialogs/preferences_dialog.cpp index 9b98d6c2320ce..d5e8324e603f7 100644 --- a/src/gui/dialogs/preferences_dialog.cpp +++ b/src/gui/dialogs/preferences_dialog.cpp @@ -119,18 +119,20 @@ void preferences_dialog::set_resolution_list(menu_button& res_list, CVideo& vide resolutions_ = video.get_available_resolutions(true); std::vector options; - for(const auto& res : resolutions_) - { + for(const point& res : resolutions_) { config option; - option["label"] = formatter() << res.first << font::unicode_multiplication_sign << res.second; + option["label"] = formatter() << res.x << font::unicode_multiplication_sign << res.y; - const int div = boost::math::gcd(res.first, res.second); - const int ratio[2] {res.first/div, res.second/div}; - if(ratio[0] <= 10 || ratio[1] <= 10) { - option["details"] = formatter() << "(" << ratio[0] << ':' << ratio[1] << ")"; + const int div = boost::math::gcd(res.x, res.y); + + const int x_ratio = res.x / div; + const int y_ratio = res.y / div; + + if(x_ratio <= 10 || y_ratio <= 10) { + option["details"] = formatter() << "(" << y_ratio << ':' << y_ratio << ")"; } - options.push_back(option); + options.push_back(std::move(option)); } const unsigned current_res = std::find(resolutions_.begin(), resolutions_.end(), @@ -1037,15 +1039,10 @@ void preferences_dialog::fullscreen_toggle_callback(window& window) void preferences_dialog::handle_res_select(window& window) { menu_button& res_list = find_widget(&window, "resolution_set", false); - const int choice = res_list.get_value(); - if(resolutions_[static_cast(choice)] == window.video().current_resolution()) { - return; + if(window.video().set_resolution(resolutions_[res_list.get_value()])) { + set_resolution_list(res_list, window.video()); } - - window.video().set_resolution(resolutions_[static_cast(choice)]); - events::raise_resize_event(); - set_resolution_list(res_list, window.video()); } void preferences_dialog::on_page_select(window& window) diff --git a/src/gui/dialogs/preferences_dialog.hpp b/src/gui/dialogs/preferences_dialog.hpp index 08cd395a33dc1..bc47449793a93 100644 --- a/src/gui/dialogs/preferences_dialog.hpp +++ b/src/gui/dialogs/preferences_dialog.hpp @@ -30,6 +30,8 @@ namespace hotkey { struct hotkey_command; } +struct point; + namespace preferences { enum PREFERENCE_VIEW { VIEW_DEFAULT, @@ -125,7 +127,7 @@ class preferences_dialog : public modal_dialog (SPECIAL, "custom") ) - std::vector > resolutions_; + std::vector resolutions_; std::vector adv_preferences_cfg_; int last_selected_item_; diff --git a/src/gui/dialogs/title_screen.cpp b/src/gui/dialogs/title_screen.cpp index ac70bcea2bf13..ae1e124265b9b 100644 --- a/src/gui/dialogs/title_screen.cpp +++ b/src/gui/dialogs/title_screen.cpp @@ -216,7 +216,7 @@ void title_screen::pre_show(window& win) std::bind(&title_screen::hotkey_callback_select_tests, this, std::ref(win))); win.register_hotkey(hotkey::HOTKEY_FULLSCREEN, - std::bind(&CVideo::set_fullscreen, std::ref(win.video()), !preferences::fullscreen())); + std::bind(&CVideo::toggle_fullscreen, std::ref(win.video()))); // A wrapper is needed here since the relevant display function is overloaded, and // since the wrapper's signature doesn't exactly match what register_hotkey expects. diff --git a/src/hotkey/command_executor.cpp b/src/hotkey/command_executor.cpp index d5b533bed2020..afc3e3c9fbe7d 100644 --- a/src/hotkey/command_executor.cpp +++ b/src/hotkey/command_executor.cpp @@ -561,7 +561,7 @@ void execute_command(const hotkey_command& command, command_executor* executor, executor->recalculate_minimap(); break; case HOTKEY_FULLSCREEN: - executor->get_video().set_fullscreen(!preferences::fullscreen()); + executor->get_video().toggle_fullscreen(); break; case HOTKEY_SCREENSHOT: make_screenshot(_("Screenshot"), executor->get_video(), &::screenshot); diff --git a/src/preferences/general.cpp b/src/preferences/general.cpp index beb86cc9167df..40e2d43d20178 100644 --- a/src/preferences/general.cpp +++ b/src/preferences/general.cpp @@ -19,18 +19,20 @@ #define GETTEXT_DOMAIN "wesnoth-lib" +#include "preferences/general.hpp" + #include "config.hpp" +#include "credentials.hpp" #include "filesystem.hpp" #include "game_config.hpp" #include "hotkey/hotkey_item.hpp" #include "lexical_cast.hpp" #include "log.hpp" -#include "credentials.hpp" -#include "preferences/general.hpp" -#include "sound.hpp" -#include "video.hpp" // non_interactive() +#include "sdl/point.hpp" #include "serialization/parser.hpp" +#include "sound.hpp" #include "utils/general.hpp" +#include "video.hpp" // non_interactive() #include // for setting the permissions of the preferences file #ifndef _WIN32 @@ -135,7 +137,7 @@ void prefs_event_handler::handle_window_event(const SDL_Event& event) switch(event.window.event) { case SDL_WINDOWEVENT_RESIZED: - _set_resolution(std::make_pair(event.window.data1,event.window.data2)); + _set_resolution(point(event.window.data1,event.window.data2)); break; @@ -370,19 +372,19 @@ void set_scroll_to_action(bool ison) prefs["scroll_to_action"] = ison; } -std::pair resolution() +point resolution() { const std::string& x = prefs["xresolution"], y = prefs["yresolution"]; if (!x.empty() && !y.empty()) { try { - return std::make_pair( + return point( std::max(std::stoi(x), min_window_width), std::max(std::stoi(y), min_window_height)); } catch(std::invalid_argument) {} } - return std::pair(def_window_width, def_window_height); + return point(def_window_width, def_window_height); } bool maximized() @@ -395,10 +397,10 @@ bool fullscreen() return get("fullscreen", false); } -void _set_resolution(const std::pair& res) +void _set_resolution(const point& res) { - preferences::set("xresolution", std::to_string(res.first)); - preferences::set("yresolution", std::to_string(res.second)); + preferences::set("xresolution", std::to_string(res.x)); + preferences::set("yresolution", std::to_string(res.y)); } void _set_maximized(bool ison) diff --git a/src/preferences/general.hpp b/src/preferences/general.hpp index 9cd9ef37efe04..d02d0dfb89c62 100644 --- a/src/preferences/general.hpp +++ b/src/preferences/general.hpp @@ -24,6 +24,8 @@ class display; #include +struct point; + namespace hotkey { class hotkey_item; } @@ -81,8 +83,8 @@ namespace preferences { bool scroll_to_action(); void set_scroll_to_action(bool ison); - std::pair resolution(); - void _set_resolution(const std::pair& res); + point resolution(); + void _set_resolution(const point& res); bool maximized(); void _set_maximized(bool ison); diff --git a/src/sdl/point.hpp b/src/sdl/point.hpp index 4eca9f46c65bd..ed2cd124d7fd9 100644 --- a/src/sdl/point.hpp +++ b/src/sdl/point.hpp @@ -21,11 +21,21 @@ /** Holds a 2D point. */ struct point { - point() : x(0), y(0) + point() + : x(0) + , y(0) { } - point(const int x_, const int y_) : x(x_), y(y_) + point(const int x_, const int y_) + : x(x_) + , y(y_) + { + } + + point(const SDL_Point& p) + : x(p.x) + , y(p.y) { } @@ -42,10 +52,12 @@ struct point { return x == point.x && y == point.y; } + bool operator!=(const point& point) const { - return x != point.x || y != point.y; + return !operator==(point); } + bool operator<(const point& point) const { return x < point.x || (x == point.x && y < point.y); diff --git a/src/video.cpp b/src/video.cpp index 6f4328aaa991d..31710cc8b80a6 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -19,6 +19,7 @@ #include "image.hpp" #include "log.hpp" #include "preferences/general.hpp" +#include "sdl/point.hpp" #include "sdl/userevent.hpp" #include "sdl/utils.hpp" #include "sdl/window.hpp" @@ -233,8 +234,8 @@ void CVideo::init_window() const int y = preferences::fullscreen() ? SDL_WINDOWPOS_UNDEFINED : SDL_WINDOWPOS_CENTERED; // Dimensions - const int w = preferences::resolution().first; - const int h = preferences::resolution().second; + const int w = preferences::resolution().x; + const int h = preferences::resolution().y; // Video flags int video_flags = 0; @@ -267,7 +268,7 @@ void CVideo::init_window() } } -void CVideo::set_window_mode(int x, int y, const MODE_EVENT mode) +void CVideo::set_window_mode(const MODE_EVENT mode, const point& size) { assert(window); if(fake_screen_) { @@ -291,7 +292,7 @@ void CVideo::set_window_mode(int x, int y, const MODE_EVENT mode) case TO_RES: window->restore(); - window->set_size(x, y); + window->set_size(size.x, size.y); window->center(); break; } @@ -412,9 +413,9 @@ std::pair CVideo::get_dpi_scale_factor() const return result; } -std::vector> CVideo::get_available_resolutions(const bool include_current) +std::vector CVideo::get_available_resolutions(const bool include_current) { - std::vector> result; + std::vector result; if(!window) { return result; @@ -428,8 +429,7 @@ std::vector> CVideo::get_available_resolutions(const bool in return result; } - const std::pair min_res = std::make_pair(preferences::min_window_width, preferences::min_window_height); - const std::pair current_res = current_resolution(); + const point min_res(preferences::min_window_width, preferences::min_window_height); #if 0 // DPI scale factor. @@ -451,7 +451,7 @@ std::vector> CVideo::get_available_resolutions(const bool in continue; } - if(mode.w >= min_res.first && mode.h >= min_res.second) { + if(mode.w >= min_res.x && mode.h >= min_res.y) { result.emplace_back(mode.w, mode.h); } } @@ -462,7 +462,7 @@ std::vector> CVideo::get_available_resolutions(const bool in } if(include_current) { - result.push_back(current_res); + result.push_back(current_resolution()); } std::sort(result.begin(), result.end()); @@ -476,10 +476,9 @@ surface& CVideo::getSurface() return frameBuffer; } -std::pair CVideo::current_resolution() +point CVideo::current_resolution() { - SDL_Point size = window->get_size(); - return std::make_pair(size.x, size.y); + return point(window->get_size()); // Convert from plain SDL_Point } bool CVideo::is_fullscreen() const @@ -535,7 +534,7 @@ void CVideo::clear_all_help_strings() void CVideo::set_fullscreen(bool ison) { if(window && is_fullscreen() != ison) { - const std::pair& res = preferences::resolution(); + const point& res = preferences::resolution(); MODE_EVENT mode; @@ -545,10 +544,10 @@ void CVideo::set_fullscreen(bool ison) mode = preferences::maximized() ? TO_MAXIMIZED_WINDOW : TO_WINDOWED; } - set_window_mode(res.first, res.second, mode); + set_window_mode(mode, res); - if(display::get_singleton()) { - display::get_singleton()->redraw_everything(); + if(display* d = display::get_singleton()) { + d->redraw_everything(); } } @@ -556,27 +555,37 @@ void CVideo::set_fullscreen(bool ison) preferences::_set_fullscreen(ison); } -void CVideo::set_resolution(const std::pair& resolution) +void CVideo::toggle_fullscreen() { - set_resolution(resolution.first, resolution.second); + set_fullscreen(!preferences::fullscreen()); } -void CVideo::set_resolution(const unsigned width, const unsigned height) +bool CVideo::set_resolution(const unsigned width, const unsigned height) { - if(static_cast(current_resolution().first) == width - && static_cast(current_resolution().second) == height) { - return; + return set_resolution(point(width, height)); +} + +bool CVideo::set_resolution(const point& resolution) +{ + if(resolution == current_resolution()) { + return false; } - set_window_mode(width, height, TO_RES); + set_window_mode(TO_RES, resolution); - if(display::get_singleton()) { - display::get_singleton()->redraw_everything(); + if(display* d = display::get_singleton()) { + d->redraw_everything(); } - // Change the config values. - preferences::_set_resolution(std::make_pair(width, height)); + // Change the saved values in preferences. + preferences::_set_resolution(resolution); preferences::_set_maximized(false); + + // Push a window-resized event to the queue. This is necessary so various areas + // of the game (like GUI2) update properly with the new size. + events::raise_resize_event(); + + return true; } void CVideo::lock_flips(bool lock) diff --git a/src/video.hpp b/src/video.hpp index e6207aa915402..08b46b6d28827 100644 --- a/src/video.hpp +++ b/src/video.hpp @@ -21,6 +21,7 @@ #include class surface; +struct point; namespace sdl { @@ -79,31 +80,33 @@ class CVideo /** * Sets the window's mode - ie, changing it to fullscreen, maximizing, etc. * - * @param x The new window width, if @a mode is TO_RES. - * @param y The new window height, if @a mode is TO_RES. * @param mode The action to perform. + * @param size The new window size. Utilized if @a mode is TO_RES. */ - void set_window_mode(int x, int y, const MODE_EVENT mode); + void set_window_mode(const MODE_EVENT mode, const point& size); public: void set_fullscreen(bool ison); + void toggle_fullscreen(); + bool is_fullscreen() const; - void set_resolution(const std::pair& res); + bool set_resolution(const unsigned width, const unsigned height); /** - * Set the resolution. + * Set the window resolution. * - * @param width The new width. - * @param height The new height. + * @param resolution The new width and height. + * + * @returns Whether the resolution was sucessfully changed. */ - void set_resolution(const unsigned width, const unsigned height); + bool set_resolution(const point& resolution); - std::pair current_resolution(); + point current_resolution(); /** Returns the list of available screen resolutions. */ - std::vector> get_available_resolutions(const bool include_current = false); + std::vector get_available_resolutions(const bool include_current = false); /** The current width of the window, is screen coordinates. */ int getx() const;