From abea2a09b9da20b1278915ccf2b183570e0632a5 Mon Sep 17 00:00:00 2001
From: tibetiroka <68112292+tibetiroka@users.noreply.github.com>
Date: Tue, 3 Dec 2024 01:09:16 +0100
Subject: [PATCH] refactor(ui): Extract magic numbers from Dialog (#10323)
Co-authored-by: Rising Leaf <85687254+RisingLeaf@users.noreply.github.com>
---
source/Dialog.cpp | 132 +++++++++++++++++++++++-------------
source/Dialog.h | 4 +-
source/text/WrappedText.cpp | 4 +-
3 files changed, 91 insertions(+), 49 deletions(-)
diff --git a/source/Dialog.cpp b/source/Dialog.cpp
index dd50d386332a..119cd9385658 100644
--- a/source/Dialog.cpp
+++ b/source/Dialog.cpp
@@ -40,9 +40,6 @@ this program. If not, see .
using namespace std;
namespace {
- const int WIDTH = 250;
- const int WIDE_WIDTH = 450;
-
// Map any conceivable numeric keypad keys to their ASCII values. Most of
// these will presumably only exist on special programming keyboards.
const map KEY_MAP = {
@@ -85,6 +82,40 @@ namespace {
{SDLK_KP_SPACE, ' '},
{SDLK_KP_VERTICALBAR, '|'}
};
+
+ // The width of the margin on the right/left sides of the dialog. This area is part of the sprite,
+ // but shouldn't have any text or other graphics rendered over it. (It's mostly transparent.)
+ constexpr double LEFT_MARGIN = 20;
+ constexpr double RIGHT_MARGIN = 20;
+ constexpr double HORIZONTAL_MARGIN = LEFT_MARGIN + RIGHT_MARGIN;
+ // The margin on the right/left sides of the button sprite. The bottom segment also includes a button
+ // that uses the same value.
+ constexpr double BUTTON_LEFT_MARGIN = 10;
+ constexpr double BUTTON_RIGHT_MARGIN = 10;
+ constexpr double BUTTON_HORIZONTAL_MARGIN = BUTTON_LEFT_MARGIN + BUTTON_RIGHT_MARGIN;
+ // The margin on the top/bottom sides of the button sprite. The bottom segment also includes a button
+ // that uses the same value.
+ constexpr double BUTTON_TOP_MARGIN = 10;
+ constexpr double BUTTON_BOTTOM_MARGIN = 10;
+ constexpr double BUTTON_VERTICAL_MARGIN = BUTTON_TOP_MARGIN + BUTTON_BOTTOM_MARGIN;
+ // The width of the padding used on the left/right sides of each segment, in pixels.
+ constexpr double LEFT_PADDING = 10;
+ constexpr double RIGHT_PADDING = 10;
+ constexpr double HORIZONTAL_PADDING = RIGHT_PADDING + LEFT_PADDING;
+ // The height of the padding used by the top/bottom segment, in pixels.
+ constexpr double TOP_PADDING = 10;
+ constexpr double BOTTOM_PADDING = 10;
+ constexpr double VERTICAL_PADDING = TOP_PADDING + BOTTOM_PADDING;
+ // The width of the padding at the beginning/end of an input field.
+ constexpr double INPUT_LEFT_PADDING = 5;
+ constexpr double INPUT_RIGHT_PADDING = 5;
+ constexpr double INPUT_HORIZONTAL_PADDING = INPUT_LEFT_PADDING + INPUT_RIGHT_PADDING;
+ // The height of the padding at the top/bottom of an input field.
+ constexpr double INPUT_TOP_PADDING = 2;
+ constexpr double INPUT_BOTTOM_PADDING = 2;
+ constexpr double INPUT_VERTICAL_PADDING = INPUT_TOP_PADDING + INPUT_BOTTOM_PADDING;
+ // The height of an input field in pixels.
+ constexpr double INPUT_HEIGHT = 20;
}
@@ -129,10 +160,9 @@ void Dialog::Draw()
const Sprite *bottom = SpriteSet::Get(isWide ? "ui/dialog bottom wide" : "ui/dialog bottom");
const Sprite *cancel = SpriteSet::Get("ui/dialog cancel");
- // Get the position of the top of this dialog, and of the text and input.
- Point pos(0., (top->Height() + height * middle->Height() + bottom->Height()) * -.5f);
- Point textPos(Width() * -.5 + 10., pos.Y() + 20.);
- Point inputPos = Point(0., -70.) - pos;
+ // Get the position of the top of this dialog, and of the input.
+ Point pos(0., (top->Height() + extensionCount * middle->Height() + bottom->Height()) * -.5);
+ Point inputPos = Point(0., -(cancel->Height() + INPUT_HEIGHT)) - pos;
// Draw the top section of the dialog box.
pos.Y() += top->Height() * .5;
@@ -140,7 +170,7 @@ void Dialog::Draw()
pos.Y() += top->Height() * .5;
// The middle section is duplicated depending on how long the text is.
- for(int i = 0; i < height; ++i)
+ for(int i = 0; i < extensionCount; ++i)
{
pos.Y() += middle->Height() * .5;
SpriteShader::Draw(middle, pos);
@@ -151,43 +181,44 @@ void Dialog::Draw()
const Font &font = FontSet::Get(14);
pos.Y() += bottom->Height() * .5;
SpriteShader::Draw(bottom, pos);
- pos.Y() += bottom->Height() * .5 - 25.;
+ pos.Y() += (bottom->Height() - cancel->Height()) * .5;
// Draw the buttons, including optionally the cancel button.
const Color &bright = *GameData::Colors().Get("bright");
const Color &dim = *GameData::Colors().Get("medium");
const Color &back = *GameData::Colors().Get("faint");
const Color &inactive = *GameData::Colors().Get("inactive");
+ const string okText = isMission ? "Accept" : "OK";
+ okPos = pos + Point((top->Width() - RIGHT_MARGIN - cancel->Width()) * .5, 0.);
+ Point labelPos(
+ okPos.X() - .5 * font.Width(okText),
+ okPos.Y() - .5 * font.Height());
+ font.Draw(okText, labelPos, isOkDisabled ? inactive : (okIsActive ? bright : dim));
if(canCancel)
{
string cancelText = isMission ? "Decline" : "Cancel";
- cancelPos = pos + Point(isWide ? 110. : 10., 0.);
+ cancelPos = pos + Point(okPos.X() - cancel->Width() + BUTTON_RIGHT_MARGIN, 0.);
SpriteShader::Draw(cancel, cancelPos);
- Point labelPos(
- cancelPos.X() - .5 * font.Width(cancelText),
- cancelPos.Y() - .5 * font.Height());
+ labelPos = {
+ cancelPos.X() - .5 * font.Width(cancelText),
+ cancelPos.Y() - .5 * font.Height()};
font.Draw(cancelText, labelPos, !okIsActive ? bright : dim);
}
- string okText = isMission ? "Accept" : "OK";
- okPos = pos + Point(isWide ? 190. : 90., 0.);
- Point labelPos(
- okPos.X() - .5 * font.Width(okText),
- okPos.Y() - .5 * font.Height());
- font.Draw(okText, labelPos, isOkDisabled ? inactive : (okIsActive ? bright : dim));
// Draw the input, if any.
if(!isMission && (intFun || stringFun))
{
- FillShader::Fill(inputPos, Point(Width() - 20., 20.), back);
+ FillShader::Fill(inputPos, Point(Width() - HORIZONTAL_PADDING, INPUT_HEIGHT), back);
Point stringPos(
- inputPos.X() - (Width() - 20) * .5 + 5.,
+ inputPos.X() - (Width() - HORIZONTAL_PADDING) * .5 + INPUT_LEFT_PADDING,
inputPos.Y() - .5 * font.Height());
- const auto inputText = DisplayText(input, {Width() - 30, Truncate::FRONT});
+ const auto inputText = DisplayText(input, {static_cast(Width() - HORIZONTAL_PADDING - INPUT_HORIZONTAL_PADDING),
+ Truncate::FRONT});
font.Draw(inputText, stringPos, bright);
- Point barPos(stringPos.X() + font.FormattedWidth(inputText) + 2., inputPos.Y());
- FillShader::Fill(barPos, Point(1., 16.), dim);
+ Point barPos(stringPos.X() + font.FormattedWidth(inputText) + INPUT_TOP_PADDING, inputPos.Y());
+ FillShader::Fill(barPos, Point(1., INPUT_HEIGHT - INPUT_VERTICAL_PADDING), dim);
}
}
@@ -295,8 +326,12 @@ bool Dialog::Click(int x, int y, int clicks)
{
Point clickPos(x, y);
+ const Sprite *sprite = SpriteSet::Get("ui/dialog cancel");
+ const double toleranceX = (sprite->Width() - BUTTON_HORIZONTAL_MARGIN) / 2.;
+ const double toleranceY = (sprite->Height() - BUTTON_VERTICAL_MARGIN) / 2.;
+
Point ok = clickPos - okPos;
- if(fabs(ok.X()) < 40. && fabs(ok.Y()) < 20.)
+ if(fabs(ok.X()) < toleranceX && fabs(ok.Y()) < toleranceY)
{
okIsActive = true;
return DoKey(SDLK_RETURN);
@@ -305,7 +340,7 @@ bool Dialog::Click(int x, int y, int clicks)
if(canCancel)
{
Point cancel = clickPos - cancelPos;
- if(fabs(cancel.X()) < 40. && fabs(cancel.Y()) < 20.)
+ if(fabs(cancel.X()) < toleranceX && fabs(cancel.Y()) < toleranceY)
{
okIsActive = false;
return DoKey(SDLK_RETURN);
@@ -327,7 +362,7 @@ void Dialog::Init(const string &message, Truncate truncate, bool canCancel, bool
okIsActive = true;
isWide = false;
- Point textRectSize(Width() - 20, 0);
+ Point textRectSize(Width() - HORIZONTAL_PADDING, 0);
text = std::make_shared