diff --git a/src/controller_base.cpp b/src/controller_base.cpp index bca39447ca4..28f48f8297d 100644 --- a/src/controller_base.cpp +++ b/src/controller_base.cpp @@ -176,7 +176,7 @@ bool controller_base::handle_scroll(int mousex, int mousey, int mouse_flags, dou dy -= scroll_speed; } - if(mousey > get_display().h() - scroll_threshold) { + if(mousey > get_display().video().get_height() - scroll_threshold) { dy += scroll_speed; } @@ -184,7 +184,7 @@ bool controller_base::handle_scroll(int mousex, int mousey, int mouse_flags, dou dx -= scroll_speed; } - if(mousex > get_display().w() - scroll_threshold) { + if(mousex > get_display().video().get_width() - scroll_threshold) { dx += scroll_speed; } } @@ -245,7 +245,7 @@ void controller_base::play_slice(bool is_delay_enabled) const theme::menu* const m = get_display().menu_pressed(); if(m != nullptr) { - const SDL_Rect& menu_loc = m->location(get_display().screen_area()); + const SDL_Rect& menu_loc = m->location(get_display().video().screen_area()); show_menu(m->items(), menu_loc.x + 1, menu_loc.y + menu_loc.h + 1, false, get_display()); return; @@ -253,7 +253,7 @@ void controller_base::play_slice(bool is_delay_enabled) const theme::action* const a = get_display().action_pressed(); if(a != nullptr) { - const SDL_Rect& action_loc = a->location(get_display().screen_area()); + const SDL_Rect& action_loc = a->location(get_display().video().screen_area()); execute_action(a->items(), action_loc.x + 1, action_loc.y + action_loc.h + 1, false); return; diff --git a/src/display.cpp b/src/display.cpp index 95879bed912..9b0b36eaa60 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -167,7 +167,7 @@ display::display(const display_context * dc, std::weak_ptr wb, repo xpos_(0), ypos_(0), view_locked_(false), - theme_(theme_cfg, screen_area()), + theme_(theme_cfg, screen_.screen_area()), zoom_index_(0), fake_unit_man_(new fake_unit_manager(*this)), builder_(new terrain_builder(level, &dc_->map(), theme_.border().tile_image)), @@ -276,7 +276,7 @@ display::~display() } void display::set_theme(config theme_cfg) { - theme_ = theme(theme_cfg, screen_area()); + theme_ = theme(theme_cfg, screen_.screen_area()); menu_buttons_.clear(); action_buttons_.clear(); create_buttons(); @@ -876,7 +876,7 @@ void display::layout_buttons() for(const auto& menu : theme_.menus()) { std::shared_ptr b = find_menu_button(menu.get_id()); if(b) { - const SDL_Rect& loc = menu.location(screen_area()); + const SDL_Rect& loc = menu.location(screen_.screen_area()); b->set_location(loc); b->set_measurements(0,0); b->set_label(menu.title()); @@ -888,7 +888,7 @@ void display::layout_buttons() for(const auto& action : theme_.actions()) { std::shared_ptr b = find_action_button(action.get_id()); if(b) { - const SDL_Rect& loc = action.location(screen_area()); + const SDL_Rect& loc = action.location(screen_.screen_area()); b->set_location(loc); b->set_measurements(0,0); b->set_label(action.title()); @@ -1437,7 +1437,7 @@ static void draw_panel(CVideo &video, const theme::panel& panel, std::vector #include @@ -60,7 +61,7 @@ floating_label::floating_label(const std::string& text, const surface& surf) , lifetime_(-1) , width_(-1) , height_(-1) - , clip_rect_(screen_area()) + , clip_rect_(CVideo::get_singleton().screen_area()) , alpha_change_(0) , visible_(true) , align_(CENTER_ALIGN) diff --git a/src/gui/dialogs/multiplayer/lobby.cpp b/src/gui/dialogs/multiplayer/lobby.cpp index c4f2b2accc8..5171b91b313 100644 --- a/src/gui/dialogs/multiplayer/lobby.cpp +++ b/src/gui/dialogs/multiplayer/lobby.cpp @@ -1022,7 +1022,7 @@ void mp_lobby::show_preferences_button_callback(window& window) * * @todo This might no longer be needed when gui2 is done. */ - const SDL_Rect rect = screen_area(); + const SDL_Rect rect = window.video().screen_area(); gui2::settings::gamemap_width += rect.w - gui2::settings::screen_width; gui2::settings::gamemap_height += rect.h - gui2::settings::screen_height; diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index 65ab3cd059d..1f60cae3d6d 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -429,7 +429,8 @@ window* window::window_instance(const unsigned handle) void window::update_screen_size() { - const SDL_Rect rect = screen_area(); + const SDL_Rect rect = CVideo::get_singleton().screen_area(); + settings::screen_width = rect.w; settings::screen_height = rect.h; @@ -703,7 +704,7 @@ void window::draw() assert(!item.empty()); const SDL_Rect dirty_rect - = new_widgets ? screen_area() + = new_widgets ? video().screen_area() : item.back()->get_dirty_rectangle(); // For testing we disable the clipping rect and force the entire screen to diff --git a/src/help/help.cpp b/src/help/help.cpp index 2451fa7bad5..6b51ec243b5 100644 --- a/src/help/help.cpp +++ b/src/help/help.cpp @@ -162,11 +162,10 @@ void show_help(CVideo& video, const section &toplevel_sec, const events::event_context dialog_events_context; const gui::dialog_manager manager; - CVideo& screen = video; - const surface& scr = screen.getSurface(); + SDL_Rect screen_area = video.screen_area(false); - const int width = std::min(font::relative_size(1200), scr->w - font::relative_size(20)); - const int height = std::min(font::relative_size(850), scr->h - font::relative_size(150)); + const int width = std::min(font::relative_size(1200), screen_area.w - font::relative_size(20)); + const int height = std::min(font::relative_size(850), screen_area.h - font::relative_size(150)); const int left_padding = font::relative_size(10); const int right_padding = font::relative_size(10); const int top_padding = font::relative_size(10); @@ -175,8 +174,8 @@ void show_help(CVideo& video, const section &toplevel_sec, // If not both locations were supplied, put the dialog in the middle // of the screen. if (yloc <= -1 || xloc <= -1) { - xloc = scr->w / 2 - width / 2; - yloc = scr->h / 2 - height / 2; + xloc = screen_area.w / 2 - width / 2; + yloc = screen_area.h / 2 - height / 2; } std::vector buttons_ptr; gui::button close_button_(video, _("Close")); diff --git a/src/help/help_topic_generators.cpp b/src/help/help_topic_generators.cpp index 899244250e0..b85ff0ae008 100644 --- a/src/help/help_topic_generators.cpp +++ b/src/help/help_topic_generators.cpp @@ -240,7 +240,7 @@ std::string unit_topic_generator::operator()() const { const unit_type& female_type = type_.get_gender_unit_type(unit_race::FEMALE); const unit_type& male_type = type_.get_gender_unit_type(unit_race::MALE); - const int screen_width = CVideo::get_singleton().getx(); + const int screen_width = CVideo::get_singleton().get_width(); ss << "Level " << type_.level(); ss << "\n\n"; diff --git a/src/show_dialog.cpp b/src/show_dialog.cpp index d0301d17658..5160d30ceb2 100644 --- a/src/show_dialog.cpp +++ b/src/show_dialog.cpp @@ -204,7 +204,7 @@ dialog_frame::dimension_measurements dialog_frame::layout(int x, int y, int w, i h += dim_.title.h + dim_.button_row.h; dim_.button_row.x += x + w; - SDL_Rect bounds = screen_area(); + SDL_Rect bounds = video_.screen_area(); if(have_border_) { bounds.x += left_->w; bounds.y += top_->h; @@ -324,7 +324,7 @@ void dialog_frame::draw_background() SDL_Rect dialog_frame::draw_title(CVideo* video) { - SDL_Rect rect = screen_area(); + SDL_Rect rect = CVideo::get_singleton().screen_area(); return font::draw_text(video, rect, font::SIZE_TITLE, font::TITLE_COLOR, title_, dim_.title.x, dim_.title.y, false, TTF_STYLE_NORMAL); } diff --git a/src/tooltips.cpp b/src/tooltips.cpp index f1315d4e5e7..e9ce46d35d7 100644 --- a/src/tooltips.cpp +++ b/src/tooltips.cpp @@ -62,14 +62,16 @@ static void clear_tooltip() static void show_tooltip(const tooltip& tip) { - if(CVideo::get_singleton().faked()) { + CVideo& video = CVideo::get_singleton(); + + if(video.faked()) { return; } clear_tooltip(); const color_t bgcolor {0,0,0,160}; - SDL_Rect area = screen_area(); + SDL_Rect area = video.screen_area(); unsigned int border = 10; diff --git a/src/video.cpp b/src/video.cpp index d1ca0f88f15..bc6d6bc9811 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -136,17 +136,6 @@ bool CVideo::non_interactive() const return fake_interactive ? false : (window == nullptr); } -SDL_Rect screen_area() -{ - sdl::window* w = CVideo::get_singleton().get_window(); - if(!w) { - return {0, 0, frameBuffer->w, frameBuffer->h}; - } - - SDL_Point size = w->get_size(); - return {0, 0, size.x, size.y}; -} - void CVideo::video_event_handler::handle_window_event(const SDL_Event& event) { if(event.type == SDL_WINDOWEVENT) { @@ -303,22 +292,35 @@ void CVideo::set_window_mode(const MODE_EVENT mode, const point& size) } } -int CVideo::getx() const +SDL_Rect CVideo::screen_area(bool as_pixels) const { if(!window) { - return frameBuffer->w; + return {0, 0, frameBuffer->w, frameBuffer->h}; } - return window->get_size().x; + // First, get the renderer size in pixels. + SDL_Point size = window->get_output_size(); + + // Then convert the dimensions into screen coordinates, if applicable. + if(!as_pixels) { + float scale_x, scale_y; + std::tie(scale_x, scale_y) = get_dpi_scale_factor(); + + size.x /= scale_x; + size.y /= scale_y; + } + + return {0, 0, size.x, size.y}; } -int CVideo::gety() const +int CVideo::get_width(bool as_pixels) const { - if(!window) { - return frameBuffer->h; - } + return screen_area(as_pixels).w; +} - return window->get_size().y; +int CVideo::get_height(bool as_pixels) const +{ + return screen_area(as_pixels).h; } void CVideo::delay(unsigned int milliseconds) @@ -487,7 +489,7 @@ int CVideo::set_help_string(const std::string& str) int size = font::SIZE_LARGE; while(size > 0) { - if(font::line_width(str, size) > getx()) { + if(font::line_width(str, size) > get_width()) { size--; } else { break; @@ -498,7 +500,7 @@ int CVideo::set_help_string(const std::string& str) font::floating_label flabel(str); flabel.set_font_size(size); - flabel.set_position(getx() / 2, gety()); + flabel.set_position(get_width() / 2, get_height()); flabel.set_bg_color(color); flabel.set_border_size(border); diff --git a/src/video.hpp b/src/video.hpp index 08b46b6d288..79ef030461a 100644 --- a/src/video.hpp +++ b/src/video.hpp @@ -28,8 +28,6 @@ namespace sdl class window; } -SDL_Rect screen_area(); - class CVideo { public: @@ -98,7 +96,7 @@ public: * Set the window resolution. * * @param resolution The new width and height. - * + * * @returns Whether the resolution was sucessfully changed. */ bool set_resolution(const point& resolution); @@ -108,11 +106,19 @@ public: /** Returns the list of available screen resolutions. */ std::vector get_available_resolutions(const bool include_current = false); - /** The current width of the window, is screen coordinates. */ - int getx() const; + /** + * Returns the current window renderer area, either in pixels or screen coordinates. + * + * @param as_pixels Whether to return the area in pixels (default true) or + * DPI-independent (DIP) screen coordinates. + */ + SDL_Rect screen_area(bool as_pixels = true) const; - /** The current height of the window, is screen coordinates. */ - int gety() const; + /** Returns the window renderer width in pixels or screen coordinates. */ + int get_width(bool as_pixels = true) const; + + /** Returns the window renderer height in pixels or in screen coordinates. */ + int get_height(bool as_pixels = true) const; /** The current scale factor on High-DPI screens. */ std::pair get_dpi_scale_factor() const; diff --git a/src/widgets/button.cpp b/src/widgets/button.cpp index 0b1c9a0ff39..3727a3d6d2c 100644 --- a/src/widgets/button.cpp +++ b/src/widgets/button.cpp @@ -228,7 +228,7 @@ void button::calculate_size() } if (type_ != TYPE_IMAGE){ - textRect_ = font::draw_text(nullptr, screen_area(), font_size, + textRect_ = font::draw_text(nullptr, video().screen_area(), font_size, font::BUTTON_COLOR, label_text_, 0, 0); } diff --git a/src/widgets/menu.cpp b/src/widgets/menu.cpp index 8b235991066..9e28061c001 100644 --- a/src/widgets/menu.cpp +++ b/src/widgets/menu.cpp @@ -486,7 +486,7 @@ size_t menu::max_items_onscreen() const return size_t(max_items_); } - const size_t max_height = (max_height_ == -1 ? (video().gety()*66)/100 : max_height_) - heading_height(); + const size_t max_height = (max_height_ == -1 ? (video().get_height()*66)/100 : max_height_) - heading_height(); std::vector heights; size_t n; @@ -912,7 +912,7 @@ void menu::draw_row(const size_t row_index, const SDL_Rect& rect, ROW_TYPE type) { //called from style, draws one row's contents in a generic and adaptable way const std::vector& row = (type == HEADING_ROW) ? heading_ : items_[row_index].fields; - SDL_Rect const &area = screen_area(); + SDL_Rect const &area = video().screen_area(); SDL_Rect const &loc = inner_location(); const std::vector& widths = column_widths(); bool lang_rtl = current_language_rtl(); @@ -1137,7 +1137,7 @@ SDL_Rect menu::get_item_rect_internal(size_t item) const SDL_Rect res = sdl::create_rect(loc.x, y, loc.w, get_item_height(item)); - SDL_Rect const &screen_area = ::screen_area(); + SDL_Rect const &screen_area = video().screen_area(); if(res.x > screen_area.w) { return sdl::empty_rect; diff --git a/src/widgets/textbox.cpp b/src/widgets/textbox.cpp index db60e93f97a..8100c4ca83f 100644 --- a/src/widgets/textbox.cpp +++ b/src/widgets/textbox.cpp @@ -39,7 +39,7 @@ textbox::textbox(CVideo &video, int width, const std::string& text, bool editabl edit_target_(nullptr) ,listening_(false) { - // static const SDL_Rect area = d.screen_area(); + // static const SDL_Rect area = video.screen_area(); // const int height = font::draw_text(nullptr,area,font_size,font::NORMAL_COLOR,"ABCD",0,0).h; set_measurements(width, font::get_max_height(font_size_)); set_scroll_rate(font::get_max_height(font_size_) / 2); @@ -206,7 +206,7 @@ void textbox::draw_contents() src.w = std::min(loc.w,text_image_->w); src.h = std::min(loc.h,text_image_->h); src.x = text_pos_; - SDL_Rect dest = screen_area(); + SDL_Rect dest = video().screen_area(); dest.x = loc.x; dest.y = loc.y;