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