Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4f5e179
window scaling limit - unfinished version.
Noseey Feb 21, 2026
bedbb7e
Revert "window scaling limit - unfinished version."
Noseey Feb 21, 2026
50c9e06
window scaling limit - simplified solution
Noseey Feb 22, 2026
4d6c700
window scaling limit - consider only for ctrlTextButton
Noseey Feb 22, 2026
63c0ba8
window scaling - slow scaling instead of limiting
Noseey Feb 27, 2026
22b56d9
rework checks and remove unnecessary functions
Noseey Feb 28, 2026
96a25b4
fixing style and updating testControls.cpp
Noseey Feb 28, 2026
eedc195
fixing style
Noseey Feb 28, 2026
e7b3add
Introdouce LimitFactors Typedef, renaming and update comments
Noseey Feb 28, 2026
311036b
fixing style
Noseey Feb 28, 2026
75225dc
fixing whitespace issue
Noseey Feb 28, 2026
a80169e
Move scaling by factor into window constructor
Noseey Mar 14, 2026
f12f9e6
Largely remove ScaleIf calls from Window.cpp
Noseey Mar 14, 2026
a6dd3e3
Merge ScaleWindowPropUp and RescaleWindowProp
Noseey Mar 14, 2026
4af1ae4
Properly consider scaling for Scrollbars, Tables and Lists
Noseey Mar 22, 2026
87589d3
apply size limiting to specific desktops
Noseey Mar 22, 2026
b920a18
Change GUI scaling limit to percentage based value
Noseey Apr 7, 2026
87436cf
Refactor Limit Scaling to Scale Percentage
Noseey Apr 7, 2026
3282130
introduce default parameter for scaling / rescaling
Noseey Apr 8, 2026
1933aed
Fixing CI issues
Noseey Apr 8, 2026
52de561
fixing indentation in windows.h
Noseey Apr 8, 2026
d3468eb
Refactor Limit Scaling to Scale Percentage #2
Noseey Apr 8, 2026
3d3b4a9
fixing style issue
Noseey Apr 8, 2026
47ad84b
aligning constructor parameters for ctrlButton
Noseey Apr 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 31 additions & 27 deletions libs/s25main/RescaleWindowProp.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,54 @@

#pragma once

/// Functor or static method to scale a window propertie from the real coordinates
/// (relative to 800x600 resolution) to new coordinates given a size
struct ScaleWindowPropUp
/// Functor or static method to (Re-) scale window properties from the real coordinates
/// (relative to reference resolution) to new coordinates given a size
struct ScaleWindowProp
{
Extent size;
ScaleWindowPropUp(const Extent& size) : size(size) {}
/// ScalingPercentage Type for proportional scaling, capped range from 0 - 100%
/// 100%: scales GUI element base size fully proportional to target size
/// 50%: considers only half of target size
/// 0% does not apply any scaling at all
/// The target size is normalized against the reference solution
using ScaleLimPercent = Point<unsigned>;

template<typename T_Pt>
static T_Pt scale(const T_Pt& value, const Extent& size);
template<typename T_Pt>
T_Pt operator()(const T_Pt& value) const;
};
/// Reference Resolution used
static constexpr Extent REFERENCE_RESOLUTION = Extent(800, 600);

/// Rescales a window's properties (size or positions)
struct RescaleWindowProp
{
Extent oldSize, newSize;
RescaleWindowProp(Extent oldSize, Extent newSize) : oldSize(oldSize), newSize(newSize) {}
ScaleWindowProp(Extent oldSize, Extent newSize) : oldSize(oldSize), newSize(newSize) {}

template<typename T_Pt>
static T_Pt scale(const T_Pt& value, const Extent& size,
const ScaleLimPercent& scalePercentage = ScaleLimPercent(100, 100));

/// Scale the point or size from beeing relative to the oldSize to relative to the newSize
template<typename T_Pt>
T_Pt operator()(const T_Pt& oldValue) const;
T_Pt operator()(const T_Pt& oldValue, const ScaleLimPercent& scalePercentage = ScaleLimPercent(100, 100)) const;
};

template<typename T_Pt>
inline T_Pt ScaleWindowPropUp::scale(const T_Pt& value, const Extent& sizeToScale)
{
return T_Pt(value * sizeToScale / Extent(800, 600));
}

template<typename T_Pt>
inline T_Pt ScaleWindowPropUp::operator()(const T_Pt& value) const
inline T_Pt ScaleWindowProp::scale(const T_Pt& value, const Extent& sizeToScale, const ScaleLimPercent& scalePercentage)
{
return scale(value, size);
T_Pt diff(sizeToScale - REFERENCE_RESOLUTION);
T_Pt limScaledValue(value * (sizeToScale - diff + (diff * scalePercentage / 100)) / REFERENCE_RESOLUTION);
return limScaledValue;
}

template<typename T_Pt>
inline T_Pt RescaleWindowProp::operator()(const T_Pt& oldValue) const
inline T_Pt ScaleWindowProp::operator()(const T_Pt& oldValue, const ScaleLimPercent& scalePercentage) const
{
T_Pt realValue(oldValue.x * 800 / oldSize.x, oldValue.y * 600 / oldSize.y);
T_Pt realValue;
T_Pt diff(oldSize - REFERENCE_RESOLUTION);
T_Pt limUnscaleValue(
oldValue.x * REFERENCE_RESOLUTION.x / (oldSize.x - diff.x + (diff.x * scalePercentage.x / 100)),
oldValue.y * REFERENCE_RESOLUTION.y / (oldSize.y - diff.y + (diff.y * scalePercentage.y / 100)));
realValue = limUnscaleValue;
// Check for rounding errors
T_Pt checkValue = ScaleWindowPropUp::scale(realValue, oldSize);
T_Pt checkValue = ScaleWindowProp::scale(realValue, oldSize, scalePercentage);
if(checkValue.x < oldValue.x)
realValue.x++;
if(checkValue.y < oldValue.y)
realValue.y++;
return ScaleWindowPropUp::scale(realValue, newSize);
return ScaleWindowProp::scale(realValue, newSize, scalePercentage);
}
105 changes: 69 additions & 36 deletions libs/s25main/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,19 @@
#include <boost/range/adaptor/reversed.hpp>
#include <cstdarg>

Window::Window(Window* parent, unsigned id, const DrawPoint& pos, const Extent& size)
: parent_(parent), id_(id), pos_(pos), size_(size), active_(false), visible_(true), scale_(false),
isInMouseRelay(false), animations_(this)
{}
Window::Window(Window* parent, unsigned id, const DrawPoint& pos, const Extent& size,
const ScaleLimPercent& scalePercentage)
: parent_(parent), id_(id), pos_(pos), size_(size), scalePercentage_(scalePercentage), active_(false),
visible_(true), scale_(false), limit_(false), isInMouseRelay(false), animations_(this)
{
SetScalePercentage(scalePercentage);
if(parent != nullptr && parent->GetScale())
{
scale_ = parent->GetScale();
limit_ = parent->GetLimit();
Scale();
}
}

Window::~Window()
{
Expand Down Expand Up @@ -65,6 +74,22 @@ Extent Window::GetSize() const
return size_;
}

ScaleLimPercent Window::GetScalePercentage() const
{
return scalePercentage_;
}

void Window::SetScalePercentage(ScaleLimPercent scalePercentage)
{
if(scalePercentage.x > 100)
scalePercentage.x = 100;

if(scalePercentage.y > 100)
scalePercentage.y = 100;

scalePercentage_ = scalePercentage;
}

Rect Window::GetDrawRect() const
{
return Rect(GetDrawPos(), GetSize());
Expand Down Expand Up @@ -214,25 +239,25 @@ void Window::DeleteCtrl(unsigned id)
ctrlBuildingIcon* Window::AddBuildingIcon(unsigned id, const DrawPoint& pos, BuildingType type, const Nation nation,
unsigned short size, const std::string& tooltip)
{
return AddCtrl(new ctrlBuildingIcon(this, id, ScaleIf(pos), type, nation, ScaleIf(Extent(size, 0)).x, tooltip));
return AddCtrl(new ctrlBuildingIcon(this, id, pos, type, nation, Extent(size, 0).x, tooltip));
}

ctrlButton* Window::AddTextButton(unsigned id, const DrawPoint& pos, const Extent& size, const TextureColor tc,
const std::string& text, const glFont* font, const std::string& tooltip)
{
return AddCtrl(new ctrlTextButton(this, id, ScaleIf(pos), ScaleIf(size), tc, text, font, tooltip));
return AddCtrl(new ctrlTextButton(this, id, pos, size, tc, text, font, tooltip, ScaleLimPercent(30, 50)));
}

ctrlButton* Window::AddColorButton(unsigned id, const DrawPoint& pos, const Extent& size, const TextureColor tc,
const unsigned fillColor, const std::string& tooltip)
{
return AddCtrl(new ctrlColorButton(this, id, ScaleIf(pos), ScaleIf(size), tc, fillColor, tooltip));
return AddCtrl(new ctrlColorButton(this, id, pos, size, tc, fillColor, tooltip));
}

ctrlButton* Window::AddImageButton(unsigned id, const DrawPoint& pos, const Extent& size, const TextureColor tc,
ITexture* const image, const std::string& tooltip)
{
return AddCtrl(new ctrlImageButton(this, id, ScaleIf(pos), ScaleIf(size), tc, image, tooltip));
return AddCtrl(new ctrlImageButton(this, id, pos, size, tc, image, tooltip));
}

ctrlButton* Window::AddImageButton(unsigned id, const DrawPoint& pos, const Extent& size, const TextureColor tc,
Expand All @@ -244,37 +269,37 @@ ctrlButton* Window::AddImageButton(unsigned id, const DrawPoint& pos, const Exte
ctrlChat* Window::AddChatCtrl(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
const glFont* font)
{
return AddCtrl(new ctrlChat(this, id, ScaleIf(pos), ScaleIf(size), tc, font));
return AddCtrl(new ctrlChat(this, id, pos, size, tc, font));
}

ctrlCheck* Window::AddCheckBox(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
const std::string& text, const glFont* font, bool readonly)
{
return AddCtrl(new ctrlCheck(this, id, ScaleIf(pos), ScaleIf(size), tc, text, font, readonly));
return AddCtrl(new ctrlCheck(this, id, pos, size, tc, text, font, readonly));
}

ctrlComboBox* Window::AddComboBox(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
const glFont* font, unsigned short max_list_height, bool readonly)
{
return AddCtrl(new ctrlComboBox(this, id, ScaleIf(pos), ScaleIf(size), tc, font, max_list_height, readonly));
return AddCtrl(new ctrlComboBox(this, id, pos, size, tc, font, max_list_height, readonly));
}

ctrlDeepening* Window::AddTextDeepening(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
const std::string& text, const glFont* font, unsigned color, FontStyle style)
{
return AddCtrl(new ctrlTextDeepening(this, id, ScaleIf(pos), ScaleIf(size), tc, text, font, color, style));
return AddCtrl(new ctrlTextDeepening(this, id, pos, size, tc, text, font, color, style));
}

ctrlDeepening* Window::AddColorDeepening(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
unsigned fillColor)
{
return AddCtrl(new ctrlColorDeepening(this, id, ScaleIf(pos), ScaleIf(size), tc, fillColor));
return AddCtrl(new ctrlColorDeepening(this, id, pos, size, tc, fillColor));
}

ctrlDeepening* Window::AddImageDeepening(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
ITexture* image)
{
return AddCtrl(new ctrlImageDeepening(this, id, ScaleIf(pos), ScaleIf(size), tc, image));
return AddCtrl(new ctrlImageDeepening(this, id, pos, size, tc, image));
}

ctrlDeepening* Window::AddImageDeepening(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
Expand All @@ -286,8 +311,7 @@ ctrlDeepening* Window::AddImageDeepening(unsigned id, const DrawPoint& pos, cons
ctrlEdit* Window::AddEdit(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc, const glFont* font,
unsigned short maxlength, bool password, bool disabled, bool notify)
{
return AddCtrl(
new ctrlEdit(this, id, ScaleIf(pos), ScaleIf(size), tc, font, maxlength, password, disabled, notify));
return AddCtrl(new ctrlEdit(this, id, pos, size, tc, font, maxlength, password, disabled, notify));
}

ctrlGroup* Window::AddGroup(unsigned id)
Expand All @@ -297,7 +321,7 @@ ctrlGroup* Window::AddGroup(unsigned id)

ctrlImage* Window::AddImage(unsigned id, const DrawPoint& pos, ITexture* image, const std::string& tooltip)
{
return AddCtrl(new ctrlImage(this, id, ScaleIf(pos), image, tooltip));
return AddCtrl(new ctrlImage(this, id, pos, image, tooltip));
}

ctrlImage* Window::AddImage(unsigned id, const DrawPoint& pos, glArchivItem_Bitmap* image, const std::string& tooltip)
Expand All @@ -307,13 +331,13 @@ ctrlImage* Window::AddImage(unsigned id, const DrawPoint& pos, glArchivItem_Bitm

ctrlList* Window::AddList(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc, const glFont* font)
{
return AddCtrl(new ctrlList(this, id, ScaleIf(pos), ScaleIf(size), tc, font));
return AddCtrl(new ctrlList(this, id, pos, size, tc, font));
}

ctrlMultiline* Window::AddMultiline(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
const glFont* font, FontStyle format)
{
return AddCtrl(new ctrlMultiline(this, id, ScaleIf(pos), ScaleIf(size), tc, font, format));
return AddCtrl(new ctrlMultiline(this, id, pos, size, tc, font, format));
}

/**
Expand Down Expand Up @@ -345,29 +369,29 @@ ctrlMultiSelectGroup* Window::AddMultiSelectGroup(unsigned id, GroupSelectType s
ctrlPercent* Window::AddPercent(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
unsigned text_color, const glFont* font, const unsigned short* percentage)
{
return AddCtrl(new ctrlPercent(this, id, ScaleIf(pos), ScaleIf(size), tc, text_color, font, percentage));
return AddCtrl(new ctrlPercent(this, id, pos, size, tc, text_color, font, percentage));
}

ctrlProgress* Window::AddProgress(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
unsigned short button_minus, unsigned short button_plus, unsigned short maximum,
const std::string& tooltip, const Extent& padding, unsigned force_color,
const std::string& button_minus_tooltip, const std::string& button_plus_tooltip)
{
return AddCtrl(new ctrlProgress(this, id, ScaleIf(pos), ScaleIf(size), tc, button_minus, button_plus, maximum,
padding, force_color, tooltip, button_minus_tooltip, button_plus_tooltip));
return AddCtrl(new ctrlProgress(this, id, pos, size, tc, button_minus, button_plus, maximum, padding, force_color,
tooltip, button_minus_tooltip, button_plus_tooltip));
}

ctrlScrollBar* Window::AddScrollBar(unsigned id, const DrawPoint& pos, const Extent& size, unsigned short button_height,
TextureColor tc, unsigned short page_size)
{
button_height = ScaleIf(Extent(0, button_height)).y;
button_height = Extent(0, button_height).y;

return AddCtrl(new ctrlScrollBar(this, id, ScaleIf(pos), ScaleIf(size), button_height, tc, page_size));
return AddCtrl(new ctrlScrollBar(this, id, pos, size, button_height, tc, page_size));
}

ctrlTab* Window::AddTabCtrl(unsigned id, const DrawPoint& pos, unsigned short width)
{
return AddCtrl(new ctrlTab(this, id, ScaleIf(pos), ScaleIf(Extent(width, 0)).x));
return AddCtrl(new ctrlTab(this, id, pos, Extent(width, 0).x));
}

/**
Expand All @@ -377,7 +401,7 @@ ctrlTab* Window::AddTabCtrl(unsigned id, const DrawPoint& pos, unsigned short wi
ctrlTable* Window::AddTable(unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc, const glFont* font,
std::vector<TableColumn> columns)
{
return AddCtrl(new ctrlTable(this, id, ScaleIf(pos), ScaleIf(size), tc, font, std::move(columns)));
return AddCtrl(new ctrlTable(this, id, pos, size, tc, font, std::move(columns)));
}

ctrlTimer* Window::AddTimer(unsigned id, std::chrono::milliseconds timeout)
Expand All @@ -404,13 +428,13 @@ ctrlTimer* Window::AddTimer(unsigned id, std::chrono::milliseconds timeout)
ctrlText* Window::AddText(unsigned id, const DrawPoint& pos, const std::string& text, unsigned color, FontStyle format,
const glFont* font)
{
return AddCtrl(new ctrlText(this, id, ScaleIf(pos), text, color, format, font));
return AddCtrl(new ctrlText(this, id, pos, text, color, format, font));
}

ctrlMapSelection* Window::AddMapSelection(unsigned id, const DrawPoint& pos, const Extent& size,
const SelectionMapInputData& inputData)
{
return AddCtrl(new ctrlMapSelection(this, id, ScaleIf(pos), ScaleIf(size), inputData));
return AddCtrl(new ctrlMapSelection(this, id, pos, size, inputData));
}

TextFormatSetter Window::AddFormattedText(unsigned id, const DrawPoint& pos, const std::string& text, unsigned color,
Expand All @@ -426,8 +450,7 @@ ctrlVarDeepening* Window::AddVarDeepening(unsigned id, const DrawPoint& pos, con
va_list liste;
va_start(liste, parameters);

auto* ctrl =
new ctrlVarDeepening(this, id, ScaleIf(pos), ScaleIf(size), tc, formatstr, font, color, parameters, liste);
auto* ctrl = new ctrlVarDeepening(this, id, pos, size, tc, formatstr, font, color, parameters, liste);

va_end(liste);

Expand Down Expand Up @@ -458,7 +481,7 @@ ctrlVarText* Window::AddVarText(unsigned id, const DrawPoint& pos, const std::st
va_list liste;
va_start(liste, parameters);

auto* ctrl = new ctrlVarText(this, id, ScaleIf(pos), formatstr, color, format, font, parameters, liste);
auto* ctrl = new ctrlVarText(this, id, pos, formatstr, color, format, font, parameters, liste);

va_end(liste);

Expand All @@ -468,7 +491,7 @@ ctrlVarText* Window::AddVarText(unsigned id, const DrawPoint& pos, const std::st
ctrlPreviewMinimap* Window::AddPreviewMinimap(const unsigned id, const DrawPoint& pos, const Extent& size,
libsiedler2::ArchivItem_Map* const map)
{
return AddCtrl(new ctrlPreviewMinimap(this, id, ScaleIf(pos), ScaleIf(size), map));
return AddCtrl(new ctrlPreviewMinimap(this, id, pos, size, map));
}

void Window::Draw3D(const Rect& rect, TextureColor tc, bool elevated, bool highlighted, bool illuminated,
Expand Down Expand Up @@ -534,13 +557,16 @@ void Window::Msg_ScreenResize(const ScreenResizeEvent& sr)
// If the window elements don't get scaled there is nothing to do
if(!scale_)
return;
RescaleWindowProp rescale(sr.oldSize, sr.newSize);
ScaleWindowProp rescale(sr.oldSize, sr.newSize);
for(Window* ctrl : childIdToWnd_ | boost::adaptors::map_values)
{
if(!ctrl)
continue;
// Save new size (could otherwise be changed(?) in Msg_ScreenResize)
Extent newSize = rescale(ctrl->GetSize());
ScaleLimPercent limits(100, 100);
if(limit_)
limits = ctrl->GetScalePercentage();
Extent newSize = rescale(ctrl->GetSize(), limits);
ctrl->SetPos(rescale(ctrl->GetPos()));
ctrl->Msg_ScreenResize(sr);
ctrl->Resize(newSize);
Expand All @@ -549,9 +575,16 @@ void Window::Msg_ScreenResize(const ScreenResizeEvent& sr)
}

template<class T_Pt>
T_Pt Window::Scale(const T_Pt& pt)
T_Pt Window::Scale(const T_Pt& pt, const ScaleLimPercent& scalePercentage)
{
return ScaleWindowProp::scale(pt, VIDEODRIVER.GetRenderSize(), scalePercentage);
}

void Window::Scale()
{
return ScaleWindowPropUp::scale(pt, VIDEODRIVER.GetRenderSize());
pos_ = ScaleWindowProp::scale(pos_, VIDEODRIVER.GetRenderSize());
size_ =
ScaleWindowProp::scale(size_, VIDEODRIVER.GetRenderSize(), limit_ ? scalePercentage_ : ScaleLimPercent(100, 100));
}

template<class T_Pt>
Expand Down
Loading
Loading