From 6f95e040058022b8811c0d692f2920c3c8fa1600 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 15 Oct 2022 16:55:47 +0100 Subject: [PATCH 01/26] Change: Use Rect helpers for widget drawing. This replaces repetitive and sometimes unwieldy use of constants. --- src/ai/ai_gui.cpp | 59 ++++---- src/airport_gui.cpp | 10 +- src/autoreplace_gui.cpp | 13 +- src/bootstrap_gui.cpp | 4 +- src/bridge_gui.cpp | 14 +- src/build_vehicle_gui.cpp | 7 +- src/cheat_gui.cpp | 50 ++++--- src/company_gui.cpp | 71 +++++----- src/error_gui.cpp | 4 +- src/fios_gui.cpp | 211 +++++++++++++++------------- src/game/game_gui.cpp | 30 ++-- src/genworld_gui.cpp | 10 +- src/goal_gui.cpp | 19 +-- src/graph_gui.cpp | 61 ++++---- src/group_gui.cpp | 26 ++-- src/industry_gui.cpp | 133 ++++++++---------- src/linkgraph/linkgraph_gui.cpp | 12 +- src/misc_gui.cpp | 23 ++- src/music_gui.cpp | 24 ++-- src/network/network_content_gui.cpp | 69 +++++---- src/network/network_gui.cpp | 73 +++++----- src/newgrf_debug_gui.cpp | 22 +-- src/newgrf_gui.cpp | 105 +++++++------- src/news_gui.cpp | 22 +-- src/object_gui.cpp | 22 +-- src/order_gui.cpp | 17 +-- src/rail_gui.cpp | 10 +- src/signs_gui.cpp | 15 +- src/smallmap_gui.cpp | 34 ++--- src/station_gui.cpp | 70 ++++----- src/statusbar_gui.cpp | 22 +-- src/story_gui.cpp | 12 +- src/subsidy_gui.cpp | 16 +-- src/textfile_gui.cpp | 12 +- src/timetable_gui.cpp | 45 +++--- src/toolbar_gui.cpp | 23 +-- src/town_gui.cpp | 109 +++++++------- src/transparency_gui.cpp | 10 +- src/tree_gui.cpp | 2 +- src/vehicle_gui.cpp | 104 +++++++------- src/widgets/dropdown.cpp | 6 +- 41 files changed, 792 insertions(+), 809 deletions(-) diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index a1cfade002..b9971ae1b6 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -125,18 +125,18 @@ struct AIListWindow : public Window { switch (widget) { case WID_AIL_LIST: { /* Draw a list of all available AIs. */ - int y = this->GetWidget(WID_AIL_LIST)->pos_y; + Rect tr = r.Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM); /* First AI in the list is hardcoded to random */ if (this->vscroll->IsVisible(0)) { - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_LEFT, y + WD_MATRIX_TOP, this->slot == OWNER_DEITY ? STR_AI_CONFIG_NONE : STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_ORANGE); - y += this->line_height; + DrawString(tr, this->slot == OWNER_DEITY ? STR_AI_CONFIG_NONE : STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_ORANGE); + tr.top += this->line_height; } int i = 0; for (const auto &item : *this->info_list) { i++; if (this->vscroll->IsVisible(i)) { - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, item.second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE); - y += this->line_height; + DrawString(tr, item.second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE); + tr.top += this->line_height; } } break; @@ -150,20 +150,20 @@ struct AIListWindow : public Window { } /* Some info about the currently selected AI. */ if (selected_info != nullptr) { - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM); SetDParamStr(0, selected_info->GetAuthor()); - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_AUTHOR); - y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; + DrawString(tr, STR_AI_LIST_AUTHOR); + tr.top += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; SetDParam(0, selected_info->GetVersion()); - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_VERSION); - y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; + DrawString(tr, STR_AI_LIST_VERSION); + tr.top += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; if (selected_info->GetURL() != nullptr) { SetDParamStr(0, selected_info->GetURL()); - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_URL); - y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; + DrawString(tr, STR_AI_LIST_URL); + tr.top += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; } SetDParamStr(0, selected_info->GetDescription()); - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, r.bottom - WD_FRAMERECT_BOTTOM, STR_JUST_RAW_STRING, TC_WHITE); + DrawStringMultiLine(tr, STR_JUST_RAW_STRING, TC_WHITE); } break; } @@ -359,11 +359,10 @@ struct AISettingsWindow : public Window { int i = 0; for (; !this->vscroll->IsVisible(i); i++) it++; + Rect ir = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); bool rtl = _current_text_dir == TD_RTL; - uint buttons_left = rtl ? r.right - SETTING_BUTTON_WIDTH - 3 : r.left + 4; - uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8); - uint text_right = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT); - + Rect br = ir.WithWidth(SETTING_BUTTON_WIDTH, rtl); + Rect tr = ir.Indent(SETTING_BUTTON_WIDTH + 8, rtl); int y = r.top; int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; @@ -392,13 +391,13 @@ struct AISettingsWindow : public Window { } if ((config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0) { - DrawBoolButton(buttons_left, y + button_y_offset, current_value != 0, editable); + DrawBoolButton(br.left, y + button_y_offset, current_value != 0, editable); SetDParam(idx++, current_value == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON); } else { if (config_item.complete_labels) { - DrawDropDownButton(buttons_left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && clicked_dropdown, editable); + DrawDropDownButton(br.left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && clicked_dropdown, editable); } else { - DrawArrowButtons(buttons_left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value); + DrawArrowButtons(br.left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value); } if (config_item.labels != nullptr && config_item.labels->Contains(current_value)) { SetDParam(idx++, STR_JUST_RAW_STRING); @@ -409,7 +408,7 @@ struct AISettingsWindow : public Window { } } - DrawString(text_left, text_right, y + text_y_offset, str, colour); + DrawString(tr.left, tr.right, y + text_y_offset, str, colour); y += this->line_height; } } @@ -427,8 +426,8 @@ struct AISettingsWindow : public Window { { switch (widget) { case WID_AIS_BACKGROUND: { - const NWidgetBase *wid = this->GetWidget(WID_AIS_BACKGROUND); - int num = (pt.y - wid->pos_y) / this->line_height + this->vscroll->GetPosition(); + Rect r = this->GetWidget(widget)->GetCurrentRect().Shrink(WD_MATRIX_LEFT, 0, WD_MATRIX_RIGHT, 0); + int num = (pt.y - r.top) / this->line_height + this->vscroll->GetPosition(); if (num >= (int)this->visible_settings.size()) break; VisibleSettingsList::const_iterator it = this->visible_settings.begin(); @@ -445,9 +444,8 @@ struct AISettingsWindow : public Window { bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0; - int x = pt.x - wid->pos_x; - if (_current_text_dir == TD_RTL) x = wid->current_x - 1 - x; - x -= 4; + int x = pt.x - r.left; + if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x; /* One of the arrows is clicked (or green/red rect in case of bool value) */ int old_val = this->ai_config->GetSetting(config_item.name); @@ -458,8 +456,7 @@ struct AISettingsWindow : public Window { this->clicked_dropdown = false; this->closing_dropdown = false; } else { - const NWidgetBase *wid = this->GetWidget(WID_AIS_BACKGROUND); - int rel_y = (pt.y - (int)wid->pos_y) % this->line_height; + int rel_y = (pt.y - r.top) % this->line_height; Rect wi_rect; wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x); @@ -794,7 +791,7 @@ struct AIConfigWindow : public Window { { switch (widget) { case WID_AIC_LIST: { - int y = r.top; + Rect tr = r.Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM); for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < MAX_COMPANIES; i++) { StringID text; @@ -806,9 +803,9 @@ struct AIConfigWindow : public Window { } else { text = STR_AI_CONFIG_RANDOM_AI; } - DrawString(r.left + 10, r.right - 10, y + WD_MATRIX_TOP, text, + DrawString(tr, text, (this->selected_slot == i) ? TC_WHITE : (IsEditable((CompanyID)i) ? TC_ORANGE : TC_SILVER)); - y += this->line_height; + tr.top += this->line_height; } break; } diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 665f778161..12eeb894e7 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -388,15 +388,17 @@ public: { switch (widget) { case WID_AP_AIRPORT_LIST: { - int y = r.top; + Rect row = r.WithHeight(this->line_height).Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); + Rect text = r.WithHeight(this->line_height).Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM); AirportClass *apclass = AirportClass::Get(_selected_airport_class); for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < apclass->GetSpecCount(); i++) { const AirportSpec *as = apclass->GetSpec(i); if (!as->IsAvailable()) { - GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->line_height - 2, PC_BLACK, FILLRECT_CHECKER); + GfxFillRect(row, PC_BLACK, FILLRECT_CHECKER); } - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK); - y += this->line_height; + DrawString(text, as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK); + row = row.Translate(0, this->line_height); + text = text.Translate(0, this->line_height); } break; } diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 4dae0eedc7..0e676c891d 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -422,7 +422,7 @@ public: str = STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED; } - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_BLACK, SA_HOR_CENTER); + DrawString(r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM), str, TC_BLACK, SA_HOR_CENTER); break; } @@ -433,7 +433,8 @@ public: EngineID end = static_cast(std::min(this->vscroll[side]->GetCapacity() + start, this->engines[side].size())); /* Do the actual drawing */ - DrawEngineList((VehicleType)this->window_number, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, + const Rect list = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); + DrawEngineList((VehicleType)this->window_number, list.left, list.right, list.top, &this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group); break; } @@ -485,10 +486,10 @@ public: ted.cargo = e->GetDefaultCargoType(); ted.capacity = e->GetDisplayDefaultCapacity(&ted.mail_capacity); - NWidgetBase *nwi = this->GetWidget(side == 0 ? WID_RV_LEFT_DETAILS : WID_RV_RIGHT_DETAILS); - int text_end = DrawVehiclePurchaseInfo(nwi->pos_x + WD_FRAMETEXT_LEFT, nwi->pos_x + nwi->current_x - WD_FRAMETEXT_RIGHT, - nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine[side], ted); - needed_height = std::max(needed_height, (text_end - (int)nwi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL); + const Rect r = this->GetWidget(side == 0 ? WID_RV_LEFT_DETAILS : WID_RV_RIGHT_DETAILS)->GetCurrentRect() + .Shrink(WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM); + int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine[side], ted); + needed_height = std::max(needed_height, (text_end - r.top) / FONT_HEIGHT_NORMAL); } } if (needed_height != this->details_height) { // Details window are not high enough, enlarge them. diff --git a/src/bootstrap_gui.cpp b/src/bootstrap_gui.cpp index ddfda8f50b..fa2a0aee99 100644 --- a/src/bootstrap_gui.cpp +++ b/src/bootstrap_gui.cpp @@ -108,7 +108,7 @@ public: void DrawWidget(const Rect &r, int widget) const override { if (widget == WID_BEM_MESSAGE) { - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMETEXT_BOTTOM, STR_MISSING_GRAPHICS_ERROR, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM), STR_MISSING_GRAPHICS_ERROR, TC_FROMSTRING, SA_CENTER); } } @@ -236,7 +236,7 @@ public: { if (widget != 0) return; - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMETEXT_BOTTOM, STR_MISSING_GRAPHICS_SET_MESSAGE, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM), STR_MISSING_GRAPHICS_SET_MESSAGE, TC_FROMSTRING, SA_CENTER); } void OnClick(Point pt, int widget, int click_count) override diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index 515a9318c3..416e529ded 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -194,10 +194,10 @@ public: } sprite_dim.height++; // Sprite is rendered one pixel down in the matrix field. text_dim.height++; // Allowing the bottom row pixels to be rendered on the edge of the matrix field. - resize->height = std::max(sprite_dim.height, text_dim.height) + 2; // Max of both sizes + account for matrix edges. + resize->height = std::max(sprite_dim.height, text_dim.height) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; // Max of both sizes + account for matrix edges. - this->bridgetext_offset = WD_MATRIX_LEFT + sprite_dim.width + 1; // Left edge of text, 1 pixel distance from the sprite. - size->width = this->bridgetext_offset + text_dim.width + WD_MATRIX_RIGHT; + this->bridgetext_offset = sprite_dim.width + 1; // Left edge of text, 1 pixel distance from the sprite. + size->width = WD_MATRIX_LEFT + this->bridgetext_offset + text_dim.width + WD_MATRIX_RIGHT; size->height = 4 * resize->height; // Smallest bridge gui is 4 entries high in the matrix. break; } @@ -222,7 +222,7 @@ public: break; case WID_BBS_BRIDGE_LIST: { - uint y = r.top; + Rect tr = r.WithHeight(this->resize.step_height).Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM); for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < (int)this->bridges->size(); i++) { const BridgeSpec *b = this->bridges->at(i).spec; @@ -230,10 +230,10 @@ public: SetDParam(1, b->speed); SetDParam(0, b->material); - DrawSprite(b->sprite, b->pal, r.left + WD_MATRIX_LEFT, y + this->resize.step_height - 1 - GetSpriteSize(b->sprite).height); - DrawStringMultiLine(r.left + this->bridgetext_offset, r.right, y + 2, y + this->resize.step_height, + DrawSprite(b->sprite, b->pal, tr.left, tr.bottom - GetSpriteSize(b->sprite).height); + DrawStringMultiLine(tr.Indent(this->bridgetext_offset, false), _game_mode == GM_EDITOR ? STR_SELECT_BRIDGE_SCENEDIT_INFO : STR_SELECT_BRIDGE_INFO); - y += this->resize.step_height; + tr = tr.Translate(0, this->resize.step_height); } break; } diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index bef76b4186..5e808c0615 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1622,10 +1622,9 @@ struct BuildVehicleWindow : Window { int needed_height = this->details_height; /* Draw details panels. */ if (this->sel_engine != INVALID_ENGINE) { - NWidgetBase *nwi = this->GetWidget(WID_BV_PANEL); - int text_end = DrawVehiclePurchaseInfo(nwi->pos_x + WD_FRAMETEXT_LEFT, nwi->pos_x + nwi->current_x - WD_FRAMETEXT_RIGHT, - nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine, this->te); - needed_height = std::max(needed_height, (text_end - (int)nwi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL); + const Rect r = this->GetWidget(WID_BV_PANEL)->GetCurrentRect().Shrink(WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM); + int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine, this->te); + needed_height = std::max(needed_height, (text_end - r.top) / FONT_HEIGHT_NORMAL); } if (needed_height != this->details_height) { // Details window are not high enough, enlarge them. int resize = needed_height - this->details_height; diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index eb62dc0317..1e96854df2 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -29,6 +29,7 @@ #include "newgrf.h" #include "error.h" #include "misc_cmd.h" +#include "core/geometry_func.hpp" #include "widgets/cheat_widget.h" @@ -216,33 +217,42 @@ struct CheatWindow : Window { int clicked; int clicked_widget; uint line_height; - int box_width; + Dimension box; ///< Dimension of box sprite + Dimension icon; ///< Dimension of company icon sprite CheatWindow(WindowDesc *desc) : Window(desc) { - this->box_width = GetSpriteSize(SPR_BOX_EMPTY).width; this->InitNested(); } + void OnInit() override + { + this->box = maxdim(GetSpriteSize(SPR_BOX_EMPTY), GetSpriteSize(SPR_BOX_CHECKED)); + this->icon = GetSpriteSize(SPR_COMPANY_ICON); + } + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_C_PANEL) return; - int y = r.top + WD_FRAMERECT_TOP + WD_PAR_VSEP_NORMAL; + const Rect ir = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); + int y = ir.top; bool rtl = _current_text_dir == TD_RTL; - uint box_left = rtl ? r.right - this->box_width - 5 : r.left + 5; - uint button_left = rtl ? r.right - this->box_width - 10 - SETTING_BUTTON_WIDTH : r.left + this->box_width + 10; - uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : 20 + this->box_width + SETTING_BUTTON_WIDTH); - uint text_right = r.right - (rtl ? 20 + this->box_width + SETTING_BUTTON_WIDTH : WD_FRAMERECT_RIGHT); + uint box_left = rtl ? ir.right - this->box.width - 5 : ir.left + 5; + uint button_left = rtl ? ir.right - this->box.width - 10 - SETTING_BUTTON_WIDTH : ir.left + this->box.width + 10; + uint text_left = ir.left + (rtl ? 0 : 20 + this->box.width + SETTING_BUTTON_WIDTH); + uint text_right = ir.right - (rtl ? 20 + this->box.width + SETTING_BUTTON_WIDTH : 0); int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; - int icon_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; + int box_y_offset = (this->line_height - this->box.height) / 2; + int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; + int icon_y_offset = (this->line_height - this->icon.height) / 2; for (int i = 0; i != lengthof(_cheats_ui); i++) { const CheatEntry *ce = &_cheats_ui[i]; - DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + icon_y_offset + 2); + DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + box_y_offset); switch (ce->type) { case SLE_BOOL: { @@ -258,7 +268,7 @@ struct CheatWindow : Window { char buf[512]; /* Draw [<][>] boxes for settings of an integer-type */ - DrawArrowButtons(button_left, y + icon_y_offset, COLOUR_YELLOW, clicked - (i * 2), true, true); + DrawArrowButtons(button_left, y + button_y_offset, COLOUR_YELLOW, clicked - (i * 2), true, true); switch (ce->str) { /* Display date for change date cheat */ @@ -269,7 +279,7 @@ struct CheatWindow : Window { SetDParam(0, val + 1); GetString(buf, STR_CHEAT_CHANGE_COMPANY, lastof(buf)); uint offset = 10 + GetStringBoundingBox(buf).width; - DrawCompanyIcon(_local_company, rtl ? text_right - offset - 10 : text_left + offset, y + icon_y_offset + 2); + DrawCompanyIcon(_local_company, rtl ? text_right - offset - 10 : text_left + offset, y + icon_y_offset); break; } @@ -327,15 +337,15 @@ struct CheatWindow : Window { this->line_height = std::max(this->line_height, SETTING_BUTTON_HEIGHT); this->line_height = std::max(this->line_height, FONT_HEIGHT_NORMAL) + WD_PAR_VSEP_NORMAL; - size->width = width + 20 + this->box_width + SETTING_BUTTON_WIDTH /* stuff on the left */ + 10 /* extra spacing on right */; - size->height = WD_FRAMERECT_TOP + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_BOTTOM + this->line_height * lengthof(_cheats_ui); + size->width = width + 20 + this->box.width + SETTING_BUTTON_WIDTH /* stuff on the left */ + 10 /* extra spacing on right */; + size->height = WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + this->line_height * lengthof(_cheats_ui); } void OnClick(Point pt, int widget, int click_count) override { const NWidgetBase *wid = this->GetWidget(WID_C_PANEL); - uint btn = (pt.y - wid->pos_y - WD_FRAMERECT_TOP - WD_PAR_VSEP_NORMAL) / this->line_height; - int x = pt.x - wid->pos_x; + uint btn = (pt.y - wid->pos_y - WD_FRAMERECT_TOP) / this->line_height; + uint x = pt.x - wid->pos_x; bool rtl = _current_text_dir == TD_RTL; if (rtl) x = wid->current_x - x; @@ -345,13 +355,13 @@ struct CheatWindow : Window { int value = (int32)ReadValue(ce->variable, ce->type); int oldvalue = value; - if (btn == CHT_CHANGE_DATE && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) { + if (btn == CHT_CHANGE_DATE && x >= 20 + this->box.width + SETTING_BUTTON_WIDTH) { /* Click at the date text directly. */ clicked_widget = CHT_CHANGE_DATE; SetDParam(0, value); ShowQueryString(STR_JUST_INT, STR_CHEAT_CHANGE_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED); return; - } else if (btn == CHT_EDIT_MAX_HL && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) { + } else if (btn == CHT_EDIT_MAX_HL && x >= 20 + this->box.width + SETTING_BUTTON_WIDTH) { clicked_widget = CHT_EDIT_MAX_HL; SetDParam(0, value); ShowQueryString(STR_JUST_INT, STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED); @@ -359,7 +369,7 @@ struct CheatWindow : Window { } /* Not clicking a button? */ - if (!IsInsideMM(x, 10 + this->box_width, 10 + this->box_width + SETTING_BUTTON_WIDTH)) return; + if (!IsInsideMM(x, 10 + this->box.width, 10 + this->box.width + SETTING_BUTTON_WIDTH)) return; *ce->been_used = true; @@ -371,10 +381,10 @@ struct CheatWindow : Window { default: /* Take whatever the function returns */ - value = ce->proc(value + ((x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1), (x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1); + value = ce->proc(value + ((x >= 10 + this->box.width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1), (x >= 10 + this->box.width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1); /* The first cheat (money), doesn't return a different value. */ - if (value != oldvalue || btn == CHT_MONEY) this->clicked = btn * 2 + 1 + ((x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) != rtl ? 1 : 0); + if (value != oldvalue || btn == CHT_MONEY) this->clicked = btn * 2 + 1 + ((x >= 10 + this->box.width + SETTING_BUTTON_WIDTH / 2) != rtl ? 1 : 0); break; } diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 203f9972f6..78bb7c2bd8 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -159,16 +159,15 @@ static uint GetMaxCategoriesWidth() */ static void DrawCategory(const Rect &r, int start_y, ExpensesList list) { - int offs_left = _current_text_dir == TD_LTR ? EXP_INDENT : 0; - int offs_right = _current_text_dir == TD_LTR ? 0 : EXP_INDENT; + Rect tr = r.Indent(EXP_INDENT, _current_text_dir == TD_RTL); - int y = start_y; + tr.top = start_y; ExpensesType et; for (uint i = 0; i < list.length; i++) { et = list.et[i]; - DrawString(r.left + offs_left, r.right - offs_right, y, STR_FINANCES_SECTION_CONSTRUCTION + et); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_FINANCES_SECTION_CONSTRUCTION + et); + tr.top += FONT_HEIGHT_NORMAL; } } @@ -608,11 +607,12 @@ public: bool rtl = _current_text_dir == TD_RTL; int icon_y = CenterBounds(r.top, r.bottom, 0); int text_y = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL); + Rect tr = r.Shrink(WD_DROPDOWNTEXT_LEFT, WD_DROPDOWNTEXT_TOP, WD_DROPDOWNTEXT_RIGHT, WD_DROPDOWNTEXT_BOTTOM); DrawSprite(SPR_VEH_BUS_SIDE_VIEW, PALETTE_RECOLOUR_START + (this->result % COLOUR_END), - rtl ? r.right - 2 - ScaleGUITrad(14) : r.left + ScaleGUITrad(14) + 2, - icon_y); - DrawString(rtl ? r.left + 2 : r.left + ScaleGUITrad(28) + 4, - rtl ? r.right - ScaleGUITrad(28) - 4 : r.right - 2, + rtl ? tr.right - ScaleGUITrad(14) : tr.left + ScaleGUITrad(14), + icon_y); + DrawString(rtl ? tr.left : tr.left + ScaleGUITrad(28) + 2, + rtl ? tr.right - ScaleGUITrad(28) - 2 : tr.right, text_y, this->String(), sel ? TC_WHITE : TC_BLACK); } }; @@ -917,40 +917,41 @@ public: bool rtl = _current_text_dir == TD_RTL; - /* Horizontal coordinates of scheme name column. */ + /* Coordinates of scheme name column. */ const NWidgetBase *nwi = this->GetWidget(WID_SCL_SPACER_DROPDOWN); - int sch_left = nwi->pos_x; - int sch_right = sch_left + nwi->current_x - 1; - /* Horizontal coordinates of first dropdown. */ + Rect sch = nwi->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); + /* Coordinates of first dropdown. */ nwi = this->GetWidget(WID_SCL_PRI_COL_DROPDOWN); - int pri_left = nwi->pos_x; - int pri_right = pri_left + nwi->current_x - 1; - /* Horizontal coordinates of second dropdown. */ + Rect pri = nwi->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); + /* Coordinates of second dropdown. */ nwi = this->GetWidget(WID_SCL_SEC_COL_DROPDOWN); - int sec_left = nwi->pos_x; - int sec_right = sec_left + nwi->current_x - 1; + Rect sec = nwi->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); - int text_left = (rtl ? (uint)WD_FRAMERECT_LEFT : (this->square.width + 5)); - int text_right = (rtl ? (this->square.width + 5) : (uint)WD_FRAMERECT_RIGHT); + Rect pri_squ = pri.WithWidth(this->square.width, rtl); + Rect sec_squ = sec.WithWidth(this->square.width, rtl); - int square_offs = (this->line_height - this->square.height) / 2 + 1; - int text_offs = (this->line_height - FONT_HEIGHT_NORMAL) / 2 + 1; + pri = pri.Indent(this->square.width + ScaleGUITrad(2), rtl); + sec = sec.Indent(this->square.width + ScaleGUITrad(2), rtl); - int y = r.top; + Rect ir = r.WithHeight(this->resize.step_height).Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM); + int square_offs = (ir.Height() - this->square.height) / 2; + int text_offs = (ir.Height() - FONT_HEIGHT_NORMAL) / 2; + + int y = ir.top; /* Helper function to draw livery info. */ auto draw_livery = [&](StringID str, const Livery &liv, bool sel, bool def, int indent) { /* Livery Label. */ - DrawString(sch_left + WD_FRAMERECT_LEFT + (rtl ? 0 : indent), sch_right - WD_FRAMERECT_RIGHT - (rtl ? indent : 0), y + text_offs, str, sel ? TC_WHITE : TC_BLACK); + DrawString(sch.left + (rtl ? 0 : indent), sch.right - (rtl ? indent : 0), y + text_offs, str, sel ? TC_WHITE : TC_BLACK); /* Text below the first dropdown. */ - DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour1), (rtl ? pri_right - (this->square.width + 5) + WD_FRAMERECT_RIGHT : pri_left) + WD_FRAMERECT_LEFT, y + square_offs); - DrawString(pri_left + text_left, pri_right - text_right, y + text_offs, (def || HasBit(liv.in_use, 0)) ? STR_COLOUR_DARK_BLUE + liv.colour1 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD); + DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour1), pri_squ.left, y + square_offs); + DrawString(pri.left, pri.right, y + text_offs, (def || HasBit(liv.in_use, 0)) ? STR_COLOUR_DARK_BLUE + liv.colour1 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD); /* Text below the second dropdown. */ - if (sec_right > sec_left) { // Second dropdown has non-zero size. - DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour2), (rtl ? sec_right - (this->square.width + 5) + WD_FRAMERECT_RIGHT : sec_left) + WD_FRAMERECT_LEFT, y + square_offs); - DrawString(sec_left + text_left, sec_right - text_right, y + text_offs, (def || HasBit(liv.in_use, 1)) ? STR_COLOUR_DARK_BLUE + liv.colour2 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD); + if (sec.right > sec.left) { // Second dropdown has non-zero size. + DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour2), sec_squ.left, y + square_offs); + DrawString(sec.left, sec.right, y + text_offs, (def || HasBit(liv.in_use, 1)) ? STR_COLOUR_DARK_BLUE + liv.colour2 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD); } y += this->line_height; @@ -1795,7 +1796,7 @@ static const NWidgetPart _nested_company_infrastructure_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_GREY), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_VERTICAL), SetPIP(WD_FRAMERECT_TOP, 4, WD_FRAMETEXT_BOTTOM), + NWidget(NWID_VERTICAL), SetPIP(WD_FRAMERECT_TOP, WD_PAR_VSEP_NORMAL * 2, WD_FRAMERECT_BOTTOM), NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_RAIL_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_RAIL_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1), @@ -2025,8 +2026,8 @@ struct CompanyInfrastructureWindow : Window if (_settings_game.economy.infrastructure_maintenance) { SetDParam(0, monthly_cost * 12); // Convert to per year - int left = _current_text_dir == TD_RTL ? r.right - this->total_width : r.left; - DrawString(left, left + this->total_width, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT); + Rect tr = r.WithWidth(this->total_width, _current_text_dir == TD_RTL); + DrawString(tr.left, tr.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT); } } @@ -2109,11 +2110,11 @@ struct CompanyInfrastructureWindow : Window case WID_CI_TOTAL: if (_settings_game.economy.infrastructure_maintenance) { - int left = _current_text_dir == TD_RTL ? r.right - this->total_width : r.left; - GfxFillRect(left, y, left + this->total_width, y, PC_WHITE); + Rect tr = r.WithWidth(this->total_width, _current_text_dir == TD_RTL); + GfxFillRect(tr.left, y, tr.right, y, PC_WHITE); y += EXP_LINESPACE; SetDParam(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year - DrawString(left, left + this->total_width, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT); + DrawString(tr.left, tr.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT); } break; diff --git a/src/error_gui.cpp b/src/error_gui.cpp index 004fac0796..e65df1bca4 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.cpp @@ -287,8 +287,8 @@ public: int extra = (r.Height() - this->height_summary - this->height_detailed - WD_PAR_VSEP_WIDE) / 2; /* Note: NewGRF supplied error message often do not start with a colour code, so default to white. */ - DrawStringMultiLine(r.SetHeight(this->height_summary + extra, false), this->summary_msg, TC_WHITE, SA_CENTER); - DrawStringMultiLine(r.SetHeight(this->height_detailed + extra, true), this->detailed_msg, TC_WHITE, SA_CENTER); + DrawStringMultiLine(r.WithHeight(this->height_summary + extra, false), this->summary_msg, TC_WHITE, SA_CENTER); + DrawStringMultiLine(r.WithHeight(this->height_detailed + extra, true), this->detailed_msg, TC_WHITE, SA_CENTER); } if (this->textref_stack_size > 0) StopTextRefStackUsage(); diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index a18429036a..28ac4a26c2 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -437,18 +437,21 @@ public: _fios_path_changed = false; } + Rect ir = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); + if (str != STR_ERROR_UNABLE_TO_READ_DRIVE) SetDParam(0, tot); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP, str); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, path, TC_BLACK); + DrawString(ir.left, ir.right, ir.top + FONT_HEIGHT_NORMAL, str); + DrawString(ir.left, ir.right, ir.top, path, TC_BLACK); break; } case WID_SL_DRIVES_DIRECTORIES_LIST: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); + const Rect br = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); + GfxFillRect(br, PC_BLACK); - uint y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_INSET_LEFT, WD_INSET_TOP, WD_INSET_RIGHT, 0).WithHeight(this->resize.step_height); uint scroll_pos = this->vscroll->GetPosition(); - for (uint row = 0; row < this->fios_items.size(); row++) { + for (uint row = 0; row < this->fios_items.size() && tr.top < br.bottom; row++) { if (!this->fios_items_shown[row]) { /* The current item is filtered out : we do not show it */ scroll_pos++; @@ -458,107 +461,117 @@ public: const FiosItem *item = &this->fios_items[row]; if (item == this->selected) { - GfxFillRect(r.left + 1, y, r.right - 1, y + this->resize.step_height - 1, PC_DARK_BLUE); + GfxFillRect(br.left, tr.top, br.right, tr.bottom, PC_DARK_BLUE); } else if (item == this->highlighted) { - GfxFillRect(r.left + 1, y, r.right - 1, y + this->resize.step_height - 1, PC_VERY_DARK_BLUE); + GfxFillRect(br.left, tr.top, br.right, tr.bottom, PC_VERY_DARK_BLUE); } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, item->title, _fios_colours[GetDetailedFileType(item->type)]); - y += this->resize.step_height; - if (y >= this->vscroll->GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break; + DrawString(tr, item->title, _fios_colours[GetDetailedFileType(item->type)]); + tr = tr.Translate(0, this->resize.step_height); } break; } - case WID_SL_DETAILS: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + FONT_HEIGHT_NORMAL * 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM, PC_GREY); - DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL / 2 + WD_FRAMERECT_TOP, STR_SAVELOAD_DETAIL_CAPTION, TC_FROMSTRING, SA_HOR_CENTER); - - if (this->selected == nullptr) break; - - uint y = r.top + FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; - uint y_max = r.bottom - FONT_HEIGHT_NORMAL - WD_FRAMERECT_BOTTOM; - - if (y > y_max) break; - if (!_load_check_data.checkable) { - /* Old savegame, no information available */ - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_NOT_AVAILABLE); - y += FONT_HEIGHT_NORMAL; - } else if (_load_check_data.error != INVALID_STRING_ID) { - /* Incompatible / broken savegame */ - SetDParamStr(0, _load_check_data.error_data); - y = DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, - y, r.bottom - WD_FRAMERECT_BOTTOM, _load_check_data.error, TC_RED); - } else { - /* Mapsize */ - SetDParam(0, _load_check_data.map_size_x); - SetDParam(1, _load_check_data.map_size_y); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_MAP_SIZE); - y += FONT_HEIGHT_NORMAL; - if (y > y_max) break; - - /* Climate */ - byte landscape = _load_check_data.settings.game_creation.landscape; - if (landscape < NUM_LANDSCAPE) { - SetDParam(0, STR_CLIMATE_TEMPERATE_LANDSCAPE + landscape); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_LANDSCAPE); - y += FONT_HEIGHT_NORMAL; - } - - y += WD_PAR_VSEP_NORMAL; - if (y > y_max) break; - - /* Start date (if available) */ - if (_load_check_data.settings.game_creation.starting_year != 0) { - SetDParam(0, ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1)); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_START_DATE); - y += FONT_HEIGHT_NORMAL; - } - if (y > y_max) break; - - /* Hide current date for scenarios */ - if (this->abstract_filetype != FT_SCENARIO) { - /* Current date */ - SetDParam(0, _load_check_data.current_date); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CURRENT_DATE); - y += FONT_HEIGHT_NORMAL; - } - - /* Hide the NewGRF stuff when saving. We also hide the button. */ - if (this->fop == SLO_LOAD && (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO)) { - y += WD_PAR_VSEP_NORMAL; - if (y > y_max) break; - - /* NewGrf compatibility */ - SetDParam(0, _load_check_data.grfconfig == nullptr ? STR_NEWGRF_LIST_NONE : - STR_NEWGRF_LIST_ALL_FOUND + _load_check_data.grf_compatibility); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_GRFSTATUS); - y += FONT_HEIGHT_NORMAL; - } - if (y > y_max) break; - - /* Hide the company stuff for scenarios */ - if (this->abstract_filetype != FT_SCENARIO) { - y += FONT_HEIGHT_NORMAL; - if (y > y_max) break; - - /* Companies / AIs */ - for (auto &pair : _load_check_data.companies) { - SetDParam(0, pair.first + 1); - const CompanyProperties &c = *pair.second; - if (!c.name.empty()) { - SetDParam(1, STR_JUST_RAW_STRING); - SetDParamStr(2, c.name); - } else { - SetDParam(1, c.name_1); - SetDParam(2, c.name_2); - } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_COMPANY_INDEX); - y += FONT_HEIGHT_NORMAL; - if (y > y_max) break; - } - } - } + case WID_SL_DETAILS: + this->DrawDetails(r); break; + } + } + + void DrawDetails(const Rect &r) const + { + /* Header panel */ + int HEADER_HEIGHT = FONT_HEIGHT_NORMAL + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM; + + Rect hr = r.WithHeight(HEADER_HEIGHT).Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); + Rect tr = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); + tr.top += HEADER_HEIGHT; + + /* Create the nice grayish rectangle at the details top */ + GfxFillRect(r.WithHeight(HEADER_HEIGHT).Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, 0), PC_GREY); + DrawString(hr.left, hr.right, hr.top, STR_SAVELOAD_DETAIL_CAPTION, TC_FROMSTRING, SA_HOR_CENTER); + + if (this->selected == nullptr) return; + + /* Details panel */ + tr.bottom -= FONT_HEIGHT_NORMAL - 1; + if (tr.top > tr.bottom) return; + + if (!_load_check_data.checkable) { + /* Old savegame, no information available */ + DrawString(tr, STR_SAVELOAD_DETAIL_NOT_AVAILABLE); + tr.top += FONT_HEIGHT_NORMAL; + } else if (_load_check_data.error != INVALID_STRING_ID) { + /* Incompatible / broken savegame */ + SetDParamStr(0, _load_check_data.error_data); + tr.top = DrawStringMultiLine(tr, _load_check_data.error, TC_RED); + } else { + /* Mapsize */ + SetDParam(0, _load_check_data.map_size_x); + SetDParam(1, _load_check_data.map_size_y); + DrawString(tr, STR_NETWORK_SERVER_LIST_MAP_SIZE); + tr.top += FONT_HEIGHT_NORMAL; + if (tr.top > tr.bottom) return; + + /* Climate */ + byte landscape = _load_check_data.settings.game_creation.landscape; + if (landscape < NUM_LANDSCAPE) { + SetDParam(0, STR_CLIMATE_TEMPERATE_LANDSCAPE + landscape); + DrawString(tr, STR_NETWORK_SERVER_LIST_LANDSCAPE); + tr.top += FONT_HEIGHT_NORMAL; + } + + tr.top += WD_PAR_VSEP_WIDE; + if (tr.top > tr.bottom) return; + + /* Start date (if available) */ + if (_load_check_data.settings.game_creation.starting_year != 0) { + SetDParam(0, ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1)); + DrawString(tr, STR_NETWORK_SERVER_LIST_START_DATE); + tr.top += FONT_HEIGHT_NORMAL; + } + if (tr.top > tr.bottom) return; + + /* Hide current date for scenarios */ + if (this->abstract_filetype != FT_SCENARIO) { + /* Current date */ + SetDParam(0, _load_check_data.current_date); + DrawString(tr, STR_NETWORK_SERVER_LIST_CURRENT_DATE); + tr.top += FONT_HEIGHT_NORMAL; + } + + /* Hide the NewGRF stuff when saving. We also hide the button. */ + if (this->fop == SLO_LOAD && (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO)) { + tr.top += WD_PAR_VSEP_NORMAL; + if (tr.top > tr.bottom) return; + + /* NewGrf compatibility */ + SetDParam(0, _load_check_data.grfconfig == nullptr ? STR_NEWGRF_LIST_NONE : + STR_NEWGRF_LIST_ALL_FOUND + _load_check_data.grf_compatibility); + DrawString(tr, STR_SAVELOAD_DETAIL_GRFSTATUS); + tr.top += FONT_HEIGHT_NORMAL; + } + if (tr.top > tr.bottom) return; + + /* Hide the company stuff for scenarios */ + if (this->abstract_filetype != FT_SCENARIO) { + tr.top += WD_PAR_VSEP_WIDE; + if (tr.top > tr.bottom) return; + + /* Companies / AIs */ + for (auto &pair : _load_check_data.companies) { + SetDParam(0, pair.first + 1); + const CompanyProperties &c = *pair.second; + if (!c.name.empty()) { + SetDParam(1, STR_JUST_RAW_STRING); + SetDParamStr(2, c.name); + } else { + SetDParam(1, c.name_1); + SetDParam(2, c.name_2); + } + DrawString(tr, STR_SAVELOAD_DETAIL_COMPANY_INDEX); + tr.top += FONT_HEIGHT_NORMAL; + if (tr.top > tr.bottom) break; + } } } } diff --git a/src/game/game_gui.cpp b/src/game/game_gui.cpp index 6b9dad8071..e6d482ced9 100644 --- a/src/game/game_gui.cpp +++ b/src/game/game_gui.cpp @@ -186,7 +186,7 @@ struct GSConfigWindow : public Window { } /* There is only one slot, unlike with the GS GUI, so it should never be white */ - DrawString(r.left + 10, r.right - 10, r.top + WD_MATRIX_TOP, text, (IsEditable() ? TC_ORANGE : TC_SILVER)); + DrawString(r.Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM), text, (IsEditable() ? TC_ORANGE : TC_SILVER)); break; } case WID_GSC_SETTINGS: { @@ -195,11 +195,10 @@ struct GSConfigWindow : public Window { int i = 0; for (; !this->vscroll->IsVisible(i); i++) it++; + Rect ir = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); bool rtl = _current_text_dir == TD_RTL; - uint buttons_left = rtl ? r.right - SETTING_BUTTON_WIDTH - 3 : r.left + 4; - uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8); - uint text_right = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT); - + Rect br = ir.WithWidth(SETTING_BUTTON_WIDTH, rtl); + Rect tr = ir.Indent(SETTING_BUTTON_WIDTH + 8, rtl); int y = r.top; int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; @@ -228,13 +227,13 @@ struct GSConfigWindow : public Window { } if ((config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0) { - DrawBoolButton(buttons_left, y + button_y_offset, current_value != 0, editable); + DrawBoolButton(br.left, y + button_y_offset, current_value != 0, editable); SetDParam(idx++, current_value == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON); } else { if (config_item.complete_labels) { - DrawDropDownButton(buttons_left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && clicked_dropdown, editable); + DrawDropDownButton(br.left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && clicked_dropdown, editable); } else { - DrawArrowButtons(buttons_left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value); + DrawArrowButtons(br.left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value); } if (config_item.labels != nullptr && config_item.labels->Contains(current_value)) { SetDParam(idx++, STR_JUST_RAW_STRING); @@ -245,7 +244,7 @@ struct GSConfigWindow : public Window { } } - DrawString(text_left, text_right, y + text_y_offset, str, colour); + DrawString(tr.left, tr.right, y + text_y_offset, str, colour); y += this->line_height; } break; @@ -289,9 +288,10 @@ struct GSConfigWindow : public Window { ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_GAME); } break; + case WID_GSC_SETTINGS: { - const NWidgetBase* wid = this->GetWidget(WID_GSC_SETTINGS); - int num = (pt.y - wid->pos_y) / this->line_height + this->vscroll->GetPosition(); + Rect r = this->GetWidget(widget)->GetCurrentRect().Shrink(WD_MATRIX_LEFT, 0, WD_MATRIX_RIGHT, 0); + int num = (pt.y - r.top) / this->line_height + this->vscroll->GetPosition(); if (num >= (int)this->visible_settings.size()) break; VisibleSettingsList::const_iterator it = this->visible_settings.begin(); @@ -308,9 +308,8 @@ struct GSConfigWindow : public Window { bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0; - int x = pt.x - wid->pos_x; - if (_current_text_dir == TD_RTL) x = wid->current_x - 1 - x; - x -= 4; + int x = pt.x - r.left; + if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x; /* One of the arrows is clicked (or green/red rect in case of bool value) */ int old_val = this->gs_config->GetSetting(config_item.name); @@ -321,8 +320,7 @@ struct GSConfigWindow : public Window { this->clicked_dropdown = false; this->closing_dropdown = false; } else { - const NWidgetBase* wid = this->GetWidget(WID_GSC_SETTINGS); - int rel_y = (pt.y - (int)wid->pos_y) % this->line_height; + int rel_y = (pt.y - r.top) % this->line_height; Rect wi_rect; wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x); diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 86253c6e3f..a33a7fa34b 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -1422,13 +1422,15 @@ struct GenerateProgressWindow : public Window { void DrawWidget(const Rect &r, int widget) const override { switch (widget) { - case WID_GP_PROGRESS_BAR: + case WID_GP_PROGRESS_BAR: { /* Draw the % complete with a bar and a text */ - DrawFrameRect(r.left, r.top, r.right, r.bottom, COLOUR_GREY, FR_BORDERONLY); - DrawFrameRect(r.left + 1, r.top + 1, (int)((r.right - r.left - 2) * _gws.percent / 100) + r.left + 1, r.bottom - 1, COLOUR_MAUVE, FR_NONE); + DrawFrameRect(r, COLOUR_GREY, FR_BORDERONLY); + Rect br = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); + DrawFrameRect(br.WithWidth(br.Width() * _gws.percent / 100, false), COLOUR_MAUVE, FR_NONE); SetDParam(0, _gws.percent); - DrawString(r.left, r.right, r.top + 5, STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(r.left, r.right, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER); break; + } case WID_GP_PROGRESS_TEXT: /* Tell which class we are generating */ diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index 639901ee5b..b6663000b6 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -192,9 +192,7 @@ struct GoalListWindow : public Window { void DrawListColumn(GoalColumn column, NWidgetBase *wid, uint progress_col_width) const { /* Get column draw area. */ - int y = wid->pos_y + WD_FRAMERECT_TOP; - int x = wid->pos_x + WD_FRAMERECT_LEFT; - int right = x + wid->current_x - WD_FRAMERECT_RIGHT; + Rect r = wid->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); bool rtl = _current_text_dir == TD_RTL; int pos = -this->vscroll->GetPosition(); @@ -209,7 +207,7 @@ struct GoalListWindow : public Window { /* Display the goal. */ SetDParamStr(0, s->text); uint width_reduction = progress_col_width > 0 ? progress_col_width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT : 0; - DrawString(x + (rtl ? width_reduction : 0), right - (rtl ? 0 : width_reduction), y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_TEXT); + DrawString(r.Indent(width_reduction, !rtl), STR_GOALS_TEXT); break; } @@ -217,12 +215,11 @@ struct GoalListWindow : public Window { if (s->progress != nullptr) { SetDParamStr(0, s->progress); StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS; - int progress_x = x; - int progress_right = rtl ? x + progress_col_width : right; - DrawString(progress_x, progress_right, y + pos * FONT_HEIGHT_NORMAL, str, TC_FROMSTRING, SA_RIGHT | SA_FORCE); + DrawString(r.WithWidth(progress_col_width, !rtl), str, TC_FROMSTRING, SA_RIGHT | SA_FORCE); } break; } + r.top += FONT_HEIGHT_NORMAL; } pos++; num++; @@ -231,9 +228,8 @@ struct GoalListWindow : public Window { if (num == 0) { if (column == GC_GOAL && IsInsideMM(pos, 0, cap)) { - DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_NONE); + DrawString(r, STR_GOALS_NONE); } - pos++; } } @@ -297,8 +293,7 @@ static const NWidgetPart _nested_goals_list_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_BROWN), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_PANEL, COLOUR_BROWN), SetDataTip(0x0, STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER), SetScrollbar(WID_GOAL_SCROLLBAR), - NWidget(WWT_EMPTY, COLOUR_GREY, WID_GOAL_LIST), SetResize(1, 1), SetMinimalTextLines(2, 0), SetFill(1, 1), SetPadding(WD_FRAMERECT_TOP, 2, WD_FRAMETEXT_BOTTOM, 2), + NWidget(WWT_PANEL, COLOUR_BROWN, WID_GOAL_LIST), SetDataTip(0x0, STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER), SetScrollbar(WID_GOAL_SCROLLBAR), SetResize(1, 1), SetMinimalTextLines(2, 0), EndContainer(), NWidget(NWID_VERTICAL), NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_GOAL_SCROLLBAR), @@ -412,7 +407,7 @@ struct GoalQuestionWindow : public Window { if (widget != WID_GQ_QUESTION) return; SetDParamStr(0, this->question); - DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, this->colour, SA_TOP | SA_HOR_CENTER); + DrawStringMultiLine(r, STR_JUST_RAW_STRING, this->colour, SA_TOP | SA_HOR_CENTER); } }; diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index cb4e793077..95be1d1fab 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -65,12 +65,14 @@ struct GraphLegendWindow : Window { bool rtl = _current_text_dir == TD_RTL; + const Rect ir = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); Dimension d = GetSpriteSize(SPR_COMPANY_ICON); - DrawCompanyIcon(cid, rtl ? r.right - d.width - ScaleGUITrad(2) : r.left + ScaleGUITrad(2), CenterBounds(r.top, r.bottom, d.height)); + DrawCompanyIcon(cid, rtl ? ir.right - d.width : ir.left, CenterBounds(ir.top, ir.bottom, d.height)); + const Rect tr = ir.Indent(d.width + ScaleGUITrad(2), rtl); SetDParam(0, cid); SetDParam(1, cid); - DrawString(r.left + (rtl ? (uint)WD_FRAMERECT_LEFT : (d.width + ScaleGUITrad(4))), r.right - (rtl ? (d.width + ScaleGUITrad(4)) : (uint)WD_FRAMERECT_RIGHT), CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), STR_COMPANY_NAME_COMPANY_NUM, HasBit(_legend_excluded_companies, cid) ? TC_BLACK : TC_WHITE); + DrawString(tr.left, tr.right, CenterBounds(tr.top, tr.bottom, FONT_HEIGHT_NORMAL), STR_COMPANY_NAME_COMPANY_NUM, HasBit(_legend_excluded_companies, cid) ? TC_BLACK : TC_WHITE); } void OnClick(Point pt, int widget, int click_count) override @@ -943,32 +945,31 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { bool rtl = _current_text_dir == TD_RTL; - int x = r.left + WD_FRAMERECT_LEFT; - int y = r.top; - uint row_height = FONT_HEIGHT_SMALL; - int padding = ScaleFontTrad(1); - int pos = this->vscroll->GetPosition(); int max = pos + this->vscroll->GetCapacity(); + Rect line = r.WithHeight(this->line_height); for (const CargoSpec *cs : _sorted_standard_cargo_specs) { if (pos-- > 0) continue; if (--max < 0) break; bool lowered = !HasBit(_legend_excluded_cargo, cs->Index()); - /* Redraw box if lowered */ - if (lowered) DrawFrameRect(r.left, y, r.right, y + this->line_height - 1, COLOUR_BROWN, FR_LOWERED); + /* Redraw frame if lowered */ + if (lowered) DrawFrameRect(line, COLOUR_BROWN, FR_LOWERED); - byte clk_dif = lowered ? 1 : 0; - int rect_x = clk_dif + (rtl ? r.right - this->legend_width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT); + const Rect text = line.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM).Translate(lowered ? 1 : 0, lowered ? 1 : 0); - GfxFillRect(rect_x, y + padding + clk_dif, rect_x + this->legend_width, y + row_height - 1 + clk_dif, PC_BLACK); - GfxFillRect(rect_x + 1, y + padding + 1 + clk_dif, rect_x + this->legend_width - 1, y + row_height - 2 + clk_dif, cs->legend_colour); + /* Cargo-colour box with outline */ + const Rect cargo = text.WithWidth(this->legend_width, rtl); + GfxFillRect(cargo, PC_BLACK); + GfxFillRect(cargo.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), cs->legend_colour); + + /* Cargo name */ SetDParam(0, cs->name); - DrawString(rtl ? r.left : x + this->legend_width + 4 + clk_dif, (rtl ? r.right - this->legend_width - 4 + clk_dif : r.right), y + clk_dif, STR_GRAPH_CARGO_PAYMENT_CARGO); + DrawString(text.Indent(this->legend_width + 4, rtl), STR_GRAPH_CARGO_PAYMENT_CARGO); - y += this->line_height; + line = line.Translate(0, this->line_height); } } @@ -1132,8 +1133,8 @@ private: GUIList companies; uint ordinal_width; ///< The width of the ordinal number uint text_width; ///< The width of the actual text - uint icon_width; ///< The width of the company icon int line_height; ///< Height of the text lines + Dimension icon; ///< Dimenion of the company icon. /** * (Re)Build the company league list @@ -1178,27 +1179,26 @@ public: { if (widget != WID_CL_BACKGROUND) return; - int icon_y_offset = 1 + (FONT_HEIGHT_NORMAL - this->line_height) / 2; - uint y = r.top + WD_FRAMERECT_TOP - icon_y_offset; + Rect ir = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); + int icon_y_offset = (this->line_height - this->icon.height) / 2; + int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; bool rtl = _current_text_dir == TD_RTL; - uint ordinal_left = rtl ? r.right - WD_FRAMERECT_LEFT - this->ordinal_width : r.left + WD_FRAMERECT_LEFT; - uint ordinal_right = rtl ? r.right - WD_FRAMERECT_LEFT : r.left + WD_FRAMERECT_LEFT + this->ordinal_width; - uint icon_left = r.left + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT + (rtl ? this->text_width : this->ordinal_width); - uint text_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.right - WD_FRAMERECT_LEFT - this->text_width; - uint text_right = rtl ? r.left + WD_FRAMERECT_LEFT + this->text_width : r.right - WD_FRAMERECT_LEFT; + Rect ordinal = ir.WithWidth(this->ordinal_width, rtl); + uint icon_left = ir.Indent(rtl ? this->text_width : this->ordinal_width, rtl).left; + Rect text = ir.WithWidth(this->text_width, !rtl); for (uint i = 0; i != this->companies.size(); i++) { const Company *c = this->companies[i]; - DrawString(ordinal_left, ordinal_right, y, i + STR_ORDINAL_NUMBER_1ST, i == 0 ? TC_WHITE : TC_YELLOW); + DrawString(ordinal.left, ordinal.right, ir.top + text_y_offset, i + STR_ORDINAL_NUMBER_1ST, i == 0 ? TC_WHITE : TC_YELLOW); - DrawCompanyIcon(c->index, icon_left, y + icon_y_offset); + DrawCompanyIcon(c->index, icon_left, ir.top + icon_y_offset); SetDParam(0, c->index); SetDParam(1, c->index); SetDParam(2, GetPerformanceTitleFromValue(c->old_economy[0].performance_history)); - DrawString(text_left, text_right, y, STR_COMPANY_LEAGUE_COMPANY_NAME); - y += this->line_height; + DrawString(text.left, text.right, ir.top + text_y_offset, STR_COMPANY_LEAGUE_COMPANY_NAME); + ir.top += this->line_height; } } @@ -1222,9 +1222,8 @@ public: } } - Dimension d = GetSpriteSize(SPR_COMPANY_ICON); - this->icon_width = d.width + 2; - this->line_height = std::max(d.height + 2, FONT_HEIGHT_NORMAL); + this->icon = GetSpriteSize(SPR_COMPANY_ICON); + this->line_height = std::max(this->icon.height + 2, FONT_HEIGHT_NORMAL); for (const Company *c : Company::Iterate()) { SetDParam(0, c->index); @@ -1235,7 +1234,7 @@ public: this->text_width = widest_width + 30; // Keep some extra spacing - size->width = WD_FRAMERECT_LEFT + this->ordinal_width + WD_FRAMERECT_RIGHT + this->icon_width + WD_FRAMERECT_LEFT + this->text_width + WD_FRAMERECT_RIGHT; + size->width = WD_FRAMERECT_LEFT + this->ordinal_width + WD_FRAMERECT_RIGHT + this->icon.width + WD_FRAMERECT_LEFT + this->text_width + WD_FRAMERECT_RIGHT; size->height = WD_FRAMERECT_TOP + this->line_height * MAX_COMPANIES + WD_FRAMERECT_BOTTOM; } diff --git a/src/group_gui.cpp b/src/group_gui.cpp index b463a236b8..9aa767b440 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -563,25 +563,23 @@ public: occupancy += v->trip_occupancy; } - const int left = r.left + WD_FRAMERECT_LEFT + 8; - const int right = r.right - WD_FRAMERECT_RIGHT - 8; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); - int y = r.top + WD_FRAMERECT_TOP; - DrawString(left, right, y, STR_GROUP_PROFIT_THIS_YEAR, TC_BLACK); + DrawString(tr, STR_GROUP_PROFIT_THIS_YEAR, TC_BLACK); SetDParam(0, this_year); - DrawString(left, right, y, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT); + DrawString(tr, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT); - y += FONT_HEIGHT_NORMAL; - DrawString(left, right, y, STR_GROUP_PROFIT_LAST_YEAR, TC_BLACK); + tr.top += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_GROUP_PROFIT_LAST_YEAR, TC_BLACK); SetDParam(0, last_year); - DrawString(left, right, y, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT); + DrawString(tr, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT); - y += FONT_HEIGHT_NORMAL; - DrawString(left, right, y, STR_GROUP_OCCUPANCY, TC_BLACK); + tr.top += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_GROUP_OCCUPANCY, TC_BLACK); const size_t vehicle_count = this->vehicles.size(); if (vehicle_count > 0) { SetDParam(0, occupancy / vehicle_count); - DrawString(left, right, y, STR_GROUP_OCCUPANCY_VALUE, TC_BLACK, SA_RIGHT); + DrawString(tr, STR_GROUP_OCCUPANCY_VALUE, TC_BLACK, SA_RIGHT); } break; @@ -612,14 +610,14 @@ public: case WID_GL_LIST_VEHICLE: if (this->vli.index != ALL_GROUP && this->grouping == GB_NONE) { /* Mark vehicles which are in sub-groups (only if we are not using shared order coalescing) */ - int y = r.top; + Rect mr = r.WithHeight(this->resize.step_height); uint max = static_cast(std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size())); for (uint i = this->vscroll->GetPosition(); i < max; ++i) { const Vehicle *v = this->vehgroups[i].GetSingleVehicle(); if (v->group_id != this->vli.index) { - GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 2, _colour_gradient[COLOUR_GREY][3], FILLRECT_CHECKER); + GfxFillRect(mr.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), _colour_gradient[COLOUR_GREY][3], FILLRECT_CHECKER); } - y += this->resize.step_height; + mr = mr.Translate(0, this->resize.step_height); } } diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 08c4b48410..6e8205fd02 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -513,52 +513,41 @@ public: { switch (widget) { case WID_DPI_MATRIX_WIDGET: { - uint text_left, text_right, icon_left, icon_right; - if (_current_text_dir == TD_RTL) { - icon_right = r.right - WD_MATRIX_RIGHT; - icon_left = icon_right - this->legend.width; - text_right = icon_left - ScaleFontTrad(7); - text_left = r.left + WD_MATRIX_LEFT; - } else { - icon_left = r.left + WD_MATRIX_LEFT; - icon_right = icon_left + this->legend.width; - text_left = icon_right + ScaleFontTrad(7); - text_right = r.right - WD_MATRIX_RIGHT; - } + bool rtl = _current_text_dir == TD_RTL; + Rect text = r.WithHeight(this->resize.step_height).Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM); + Rect icon = text.WithWidth(this->legend.width, rtl); + text = text.Indent(this->legend.width + ScaleFontTrad(7), rtl); /* Vertical offset for legend icon. */ - int icon_top = (this->resize.step_height - this->legend.height + 1) / 2; - int icon_bottom = icon_top + this->legend.height; + icon.top = r.top + (this->resize.step_height - this->legend.height + 1) / 2; + icon.bottom = icon.top + this->legend.height - 1; int y = r.top; for (uint16 i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->count; i++) { bool selected = this->selected_index == i + this->vscroll->GetPosition(); if (this->index[i + this->vscroll->GetPosition()] == INVALID_INDUSTRYTYPE) { - DrawString(text_left, text_right, y + WD_MATRIX_TOP, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES, selected ? TC_WHITE : TC_ORANGE); - y += this->resize.step_height; - continue; + DrawString(text, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES, selected ? TC_WHITE : TC_ORANGE); + } else { + const IndustrySpec *indsp = GetIndustrySpec(this->index[i + this->vscroll->GetPosition()]); + + /* Draw the name of the industry in white is selected, otherwise, in orange */ + DrawString(text, indsp->name, selected ? TC_WHITE : TC_ORANGE); + GfxFillRect(icon, selected ? PC_WHITE : PC_BLACK); + GfxFillRect(icon.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), indsp->map_colour); } - const IndustrySpec *indsp = GetIndustrySpec(this->index[i + this->vscroll->GetPosition()]); - /* Draw the name of the industry in white is selected, otherwise, in orange */ - DrawString(text_left, text_right, y + WD_MATRIX_TOP, indsp->name, selected ? TC_WHITE : TC_ORANGE); - GfxFillRect(icon_left, y + icon_top, icon_right, y + icon_bottom, selected ? PC_WHITE : PC_BLACK); - GfxFillRect(icon_left + 1, y + icon_top + 1, icon_right - 1, y + icon_bottom - 1, indsp->map_colour); - - y += this->resize.step_height; + text = text.Translate(0, this->resize.step_height); + icon = icon.Translate(0, this->resize.step_height); } break; } case WID_DPI_INFOPANEL: { - int y = r.top + WD_FRAMERECT_TOP; - int bottom = r.bottom - WD_FRAMERECT_BOTTOM; - int left = r.left + WD_FRAMERECT_LEFT; - int right = r.right - WD_FRAMERECT_RIGHT; + Rect ir = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); if (this->selected_type == INVALID_INDUSTRYTYPE) { - DrawStringMultiLine(left, right, y, bottom, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP); + DrawStringMultiLine(ir, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP); break; } @@ -566,8 +555,8 @@ public: if (_game_mode != GM_EDITOR) { SetDParam(0, indsp->GetConstructionCost()); - DrawString(left, right, y, STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST); - y += FONT_HEIGHT_NORMAL; + DrawString(ir, STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST); + ir.top += FONT_HEIGHT_NORMAL; } CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)]; @@ -575,12 +564,12 @@ public: /* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */ GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, nullptr, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix); std::string cargostring = this->MakeCargoListString(indsp->accepts_cargo, cargo_suffix, lengthof(indsp->accepts_cargo), STR_INDUSTRY_VIEW_REQUIRES_N_CARGO); - y = DrawStringMultiLine(left, right, y, bottom, cargostring); + ir.top = DrawStringMultiLine(ir, cargostring); /* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */ GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, nullptr, this->selected_type, indsp, indsp->produced_cargo, cargo_suffix); cargostring = this->MakeCargoListString(indsp->produced_cargo, cargo_suffix, lengthof(indsp->produced_cargo), STR_INDUSTRY_VIEW_PRODUCES_N_CARGO); - y = DrawStringMultiLine(left, right, y, bottom, cargostring); + ir.top = DrawStringMultiLine(ir, cargostring); /* Get the additional purchase info text, if it has not already been queried. */ if (HasBit(indsp->callback_mask, CBM_IND_FUND_MORE_TEXT)) { @@ -592,7 +581,7 @@ public: StringID str = GetGRFStringID(indsp->grf_prop.grffile->grfid, 0xD000 + callback_res); // No. here's the new string if (str != STR_UNDEFINED) { StartTextRefStackUsage(indsp->grf_prop.grffile, 6); - DrawStringMultiLine(left, right, y, bottom, str, TC_YELLOW); + DrawStringMultiLine(ir, str, TC_YELLOW); StopTextRefStackUsage(); } } @@ -848,10 +837,10 @@ public: if (this->IsShaded()) return; // Don't draw anything when the window is shaded. - NWidgetBase *nwi = this->GetWidget(WID_IV_INFO); - uint expected = this->DrawInfo(nwi->pos_x, nwi->pos_x + nwi->current_x - 1, nwi->pos_y) - nwi->pos_y; - if (expected > nwi->current_y - 1) { - this->info_height = expected + 1; + const Rect r = this->GetWidget(WID_IV_INFO)->GetCurrentRect(); + int expected = this->DrawInfo(r); + if (expected > r.bottom) { + this->info_height = expected - r.top + 1; this->ReInit(); return; } @@ -864,30 +853,29 @@ public: * @param top Top edge of the panel. * @return Expected position of the bottom edge of the panel. */ - int DrawInfo(uint left, uint right, uint top) + int DrawInfo(const Rect &r) { Industry *i = Industry::Get(this->window_number); const IndustrySpec *ind = GetIndustrySpec(i->type); - int y = top + WD_FRAMERECT_TOP; + Rect ir = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); bool first = true; bool has_accept = false; if (i->prod_level == PRODLEVEL_CLOSURE) { - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE); - y += 2 * FONT_HEIGHT_NORMAL; + DrawString(ir, STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE); + ir.top += 2 * FONT_HEIGHT_NORMAL; } CargoSuffix cargo_suffix[lengthof(i->accepts_cargo)]; GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_VIEW, i, i->type, ind, i->accepts_cargo, cargo_suffix); bool stockpiling = HasBit(ind->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(ind->callback_mask, CBM_IND_PRODUCTION_256_TICKS); - uint left_side = left + WD_FRAMERECT_LEFT * 4; // Indent accepted cargoes. for (byte j = 0; j < lengthof(i->accepts_cargo); j++) { if (i->accepts_cargo[j] == CT_INVALID) continue; has_accept = true; if (first) { - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_REQUIRES); - y += FONT_HEIGHT_NORMAL; + DrawString(ir, STR_INDUSTRY_VIEW_REQUIRES); + ir.top += FONT_HEIGHT_NORMAL; first = false; } SetDParam(0, CargoSpec::Get(i->accepts_cargo[j])->name); @@ -913,8 +901,8 @@ public: default: NOT_REACHED(); } - DrawString(left_side, right - WD_FRAMERECT_RIGHT, y, str); - y += FONT_HEIGHT_NORMAL; + DrawString(ir.Indent(10, _current_text_dir == TD_RTL), str); + ir.top += FONT_HEIGHT_NORMAL; } GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_VIEW, i, i->type, ind, i->produced_cargo, cargo_suffix); @@ -922,10 +910,10 @@ public: for (byte j = 0; j < lengthof(i->produced_cargo); j++) { if (i->produced_cargo[j] == CT_INVALID) continue; if (first) { - if (has_accept) y += WD_PAR_VSEP_WIDE; - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE); - y += FONT_HEIGHT_NORMAL; - if (this->editable == EA_RATE) this->production_offset_y = y; + if (has_accept) ir.top += WD_PAR_VSEP_WIDE; + DrawString(ir, STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE); + ir.top += FONT_HEIGHT_NORMAL; + if (this->editable == EA_RATE) this->production_offset_y = ir.top; first = false; } @@ -933,26 +921,24 @@ public: SetDParam(1, i->last_month_production[j]); SetDParamStr(2, cargo_suffix[j].text); SetDParam(3, ToPercent8(i->last_month_pct_transported[j])); - uint x = left + WD_FRAMETEXT_LEFT + (this->editable == EA_RATE ? SETTING_BUTTON_WIDTH + 10 : 0); - DrawString(x, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_TRANSPORTED); + DrawString(ir.Indent(this->editable == EA_RATE ? SETTING_BUTTON_WIDTH + 10 : 0, false), STR_INDUSTRY_VIEW_TRANSPORTED); /* Let's put out those buttons.. */ if (this->editable == EA_RATE) { - DrawArrowButtons(left + WD_FRAMETEXT_LEFT, y, COLOUR_YELLOW, (this->clicked_line == IL_RATE1 + j) ? this->clicked_button : 0, + DrawArrowButtons(ir.left, ir.top, COLOUR_YELLOW, (this->clicked_line == IL_RATE1 + j) ? this->clicked_button : 0, i->production_rate[j] > 0, i->production_rate[j] < 255); } - y += FONT_HEIGHT_NORMAL; + ir.top += FONT_HEIGHT_NORMAL; } /* Display production multiplier if editable */ if (this->editable == EA_MULTIPLIER) { - y += WD_PAR_VSEP_WIDE; - this->production_offset_y = y; + ir.top += WD_PAR_VSEP_WIDE; + this->production_offset_y = ir.top; SetDParam(0, RoundDivSU(i->prod_level * 100, PRODLEVEL_DEFAULT)); - uint x = left + WD_FRAMETEXT_LEFT + SETTING_BUTTON_WIDTH + 10; - DrawString(x, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LEVEL); - DrawArrowButtons(left + WD_FRAMETEXT_LEFT, y, COLOUR_YELLOW, (this->clicked_line == IL_MULTIPLIER) ? this->clicked_button : 0, + DrawString(ir.Indent(SETTING_BUTTON_WIDTH + 10, false), STR_INDUSTRY_VIEW_PRODUCTION_LEVEL); + DrawArrowButtons(ir.left, ir.top, COLOUR_YELLOW, (this->clicked_line == IL_MULTIPLIER) ? this->clicked_button : 0, i->prod_level > PRODLEVEL_MINIMUM, i->prod_level < PRODLEVEL_MAXIMUM); - y += FONT_HEIGHT_NORMAL; + ir.top += FONT_HEIGHT_NORMAL; } /* Get the extra message for the GUI */ @@ -964,13 +950,13 @@ public: } else { StringID message = GetGRFStringID(ind->grf_prop.grffile->grfid, 0xD000 + callback_res); if (message != STR_NULL && message != STR_UNDEFINED) { - y += WD_PAR_VSEP_WIDE; + ir.top += WD_PAR_VSEP_WIDE; StartTextRefStackUsage(ind->grf_prop.grffile, 6); /* Use all the available space left from where we stand up to the * end of the window. We ALSO enlarge the window if needed, so we * can 'go' wild with the bottom of the window. */ - y = DrawStringMultiLine(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, UINT16_MAX, message, TC_BLACK); + ir.top = DrawStringMultiLine(ir.left, ir.right, ir.top, UINT16_MAX, message, TC_BLACK); StopTextRefStackUsage(); } } @@ -979,11 +965,11 @@ public: if (!i->text.empty()) { SetDParamStr(0, i->text); - y += WD_PAR_VSEP_WIDE; - y = DrawStringMultiLine(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); + ir.top += WD_PAR_VSEP_WIDE; + ir.top = DrawStringMultiLine(ir.left, ir.right, ir.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); } - return y + WD_FRAMERECT_BOTTOM; + return ir.top - 1 + WD_FRAMERECT_BOTTOM; } void SetStringParameters(int widget) const override @@ -1661,9 +1647,9 @@ public: case WID_ID_INDUSTRY_LIST: { int n = 0; - int y = r.top + WD_FRAMERECT_TOP; + Rect ir = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); if (this->industries.size() == 0) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_DIRECTORY_NONE); + DrawString(ir, STR_INDUSTRY_DIRECTORY_NONE); break; } TextColour tc; @@ -1676,9 +1662,9 @@ public: tc = TC_GREY | TC_FORCED; } } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, this->GetIndustryString(this->industries[i]), tc); + DrawString(ir, this->GetIndustryString(this->industries[i]), tc); - y += this->resize.step_height; + ir.top += this->resize.step_height; if (++n == this->vscroll->GetCapacity()) break; // max number of industries in 1 window } break; @@ -2920,14 +2906,13 @@ struct IndustryCargoesWindow : public Window { { if (widget != WID_IC_PANEL) return; + Rect ir = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); DrawPixelInfo tmp_dpi, *old_dpi; - int width = r.Width(); - int height = r.Height() - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM; - if (!FillDrawPixelInfo(&tmp_dpi, r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, width, height)) return; + if (!FillDrawPixelInfo(&tmp_dpi, ir.left, ir.top, ir.Width(), ir.Height())) return; old_dpi = _cur_dpi; _cur_dpi = &tmp_dpi; - int left_pos = WD_FRAMERECT_LEFT; + int left_pos = ir.left; if (this->ind_cargo >= NUM_INDUSTRYTYPES) left_pos += (CargoesField::industry_width + CargoesField::cargo_field_width) / 2; int last_column = (this->ind_cargo < NUM_INDUSTRYTYPES) ? 4 : 2; diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index 1eff55e65e..84d5eaea5c 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -610,15 +610,17 @@ void LinkGraphLegendWindow::UpdateWidgetSize(int widget, Dimension *size, const void LinkGraphLegendWindow::DrawWidget(const Rect &r, int widget) const { + Rect br = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); + if (this->IsWidgetLowered(widget)) br = br.Translate(1, 1); if (IsInsideMM(widget, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST + 1)) { if (this->IsWidgetDisabled(widget)) return; CompanyID cid = (CompanyID)(widget - WID_LGL_COMPANY_FIRST); Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON); - DrawCompanyIcon(cid, CenterBounds(r.left, r.right, sprite_size.width), CenterBounds(r.top, r.bottom, sprite_size.height)); + DrawCompanyIcon(cid, CenterBounds(br.left, br.right, sprite_size.width), CenterBounds(br.top, br.bottom, sprite_size.height)); } if (IsInsideMM(widget, WID_LGL_SATURATION_FIRST, WID_LGL_SATURATION_LAST + 1)) { uint8 colour = LinkGraphOverlay::LINK_COLOURS[_settings_client.gui.linkgraph_colours][widget - WID_LGL_SATURATION_FIRST]; - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, colour); + GfxFillRect(br, colour); StringID str = STR_NULL; if (widget == WID_LGL_SATURATION_FIRST) { str = STR_LINKGRAPH_LEGEND_UNUSED; @@ -628,14 +630,14 @@ void LinkGraphLegendWindow::DrawWidget(const Rect &r, int widget) const str = STR_LINKGRAPH_LEGEND_SATURATED; } if (str != STR_NULL) { - DrawString(r.left, r.right, CenterBounds(r.top, r.bottom, FONT_HEIGHT_SMALL), str, GetContrastColour(colour) | TC_FORCED, SA_HOR_CENTER); + DrawString(br.left, br.right, CenterBounds(br.top, br.bottom, FONT_HEIGHT_SMALL), str, GetContrastColour(colour) | TC_FORCED, SA_HOR_CENTER); } } if (IsInsideMM(widget, WID_LGL_CARGO_FIRST, WID_LGL_CARGO_LAST + 1)) { if (this->IsWidgetDisabled(widget)) return; CargoSpec *cargo = CargoSpec::Get(widget - WID_LGL_CARGO_FIRST); - GfxFillRect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2, cargo->legend_colour); - DrawString(r.left, r.right, CenterBounds(r.top, r.bottom, FONT_HEIGHT_SMALL), cargo->abbrev, GetContrastColour(cargo->legend_colour, 73), SA_HOR_CENTER); + GfxFillRect(br, cargo->legend_colour); + DrawString(br.left, br.right, CenterBounds(br.top, br.bottom, FONT_HEIGHT_SMALL), cargo->abbrev, GetContrastColour(cargo->legend_colour, 73), SA_HOR_CENTER); } } diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 5017f885b5..a46a9304fb 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -75,16 +75,15 @@ public: { if (widget != WID_LI_BACKGROUND) return; - uint y = r.top + WD_TEXTPANEL_TOP; + Rect ir = r.Shrink(WD_FRAMETEXT_LEFT, WD_TEXTPANEL_TOP, WD_FRAMETEXT_RIGHT, WD_TEXTPANEL_BOTTOM); for (size_t i = 0; i < this->landinfo_data.size(); i++) { - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, this->landinfo_data[i], i == 0 ? TC_LIGHT_BLUE : TC_FROMSTRING, SA_HOR_CENTER); - y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; - if (i == 0) y += 4; + DrawString(ir, this->landinfo_data[i], i == 0 ? TC_LIGHT_BLUE : TC_FROMSTRING, SA_HOR_CENTER); + ir.top += FONT_HEIGHT_NORMAL + (i == 0 ? WD_PAR_VSEP_WIDE : WD_PAR_VSEP_NORMAL); } if (!this->cargo_acceptance.empty()) { SetDParamStr(0, this->cargo_acceptance); - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, r.bottom - WD_TEXTPANEL_BOTTOM, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(ir, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER); } } @@ -97,8 +96,7 @@ public: uint width = GetStringBoundingBox(this->landinfo_data[i]).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; size->width = std::max(size->width, width); - size->height += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; - if (i == 0) size->height += 4; + size->height += FONT_HEIGHT_NORMAL + (i == 0 ? WD_PAR_VSEP_WIDE : WD_PAR_VSEP_NORMAL); } if (!this->cargo_acceptance.empty()) { @@ -730,13 +728,13 @@ struct TooltipsWindow : public Window void DrawWidget(const Rect &r, int widget) const override { /* There is only one widget. */ - GfxFillRect(r.left, r.top, r.right, r.bottom, PC_BLACK); - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_LIGHT_YELLOW); + GfxFillRect(r, PC_BLACK); + GfxFillRect(r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_LIGHT_YELLOW); for (uint arg = 0; arg < this->paramcount; arg++) { SetDParam(arg, this->params[arg]); } - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, this->string_id, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM), this->string_id, TC_FROMSTRING, SA_CENTER); } void OnMouseLoop() override @@ -1041,8 +1039,7 @@ struct QueryStringWindow : public Window if (widget != WID_QS_WARNING) return; if (this->flags & QSF_PASSWORD) { - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT - WD_FRAMERECT_RIGHT, - r.top + WD_FRAMERECT_TOP + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMERECT_BOTTOM - WD_FRAMETEXT_BOTTOM, + DrawStringMultiLine(r.Shrink(WD_FRAMERECT_LEFT + WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP + WD_FRAMETEXT_TOP, WD_FRAMERECT_RIGHT + WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM + WD_FRAMETEXT_BOTTOM), STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER); } } @@ -1194,7 +1191,7 @@ struct QueryWindow : public Window { { if (widget != WID_Q_TEXT) return; - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, + DrawStringMultiLine(r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM), this->message, TC_FROMSTRING, SA_CENTER); } diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 392ffcb636..d7f6a41200 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -522,29 +522,29 @@ struct MusicTrackSelectionWindow : public Window { { switch (widget) { case WID_MTS_LIST_LEFT: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); + GfxFillRect(r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_BLACK); - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); for (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) { SetDParam(0, song->tracknr); SetDParam(1, 2); SetDParamStr(2, song->songname); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME); - y += FONT_HEIGHT_SMALL; + DrawString(tr, STR_PLAYLIST_TRACK_NAME); + tr.top += FONT_HEIGHT_SMALL; } break; } case WID_MTS_LIST_RIGHT: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); + GfxFillRect(r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_BLACK); - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); for (MusicSystem::Playlist::const_iterator song = _music.active_playlist.begin(); song != _music.active_playlist.end(); ++song) { SetDParam(0, song->tracknr); SetDParam(1, 2); SetDParamStr(2, song->songname); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME); - y += FONT_HEIGHT_SMALL; + DrawString(tr, STR_PLAYLIST_TRACK_NAME); + tr.top += FONT_HEIGHT_SMALL; } break; } @@ -712,7 +712,7 @@ struct MusicWindow : public Window { { switch (widget) { case WID_M_TRACK_NR: { - GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, PC_BLACK); + GfxFillRect(r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, 0, WD_BEVEL_BOTTOM), PC_BLACK); if (BaseMusic::GetUsedSet()->num_available == 0) { break; } @@ -722,12 +722,12 @@ struct MusicWindow : public Window { SetDParam(1, 2); str = STR_MUSIC_TRACK_DIGIT; } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str); + DrawString(r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM), str); break; } case WID_M_TRACK_NAME: { - GfxFillRect(r.left, r.top + 1, r.right - 1, r.bottom, PC_BLACK); + GfxFillRect(r.Shrink(0, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_BLACK); StringID str = STR_MUSIC_TITLE_NONE; MusicSystem::PlaylistEntry entry(_music.GetCurrentSong()); if (BaseMusic::GetUsedSet()->num_available == 0) { @@ -736,7 +736,7 @@ struct MusicWindow : public Window { str = STR_MUSIC_TITLE_NAME; SetDParamStr(0, entry.songname); } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM), str, TC_FROMSTRING, SA_HOR_CENTER); break; } diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 9903bb2644..255d1b8083 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -616,17 +616,15 @@ public: */ void DrawMatrix(const Rect &r) const { - const NWidgetBase *nwi_checkbox = this->GetWidget(WID_NCL_CHECKBOX); - const NWidgetBase *nwi_name = this->GetWidget(WID_NCL_NAME); - const NWidgetBase *nwi_type = this->GetWidget(WID_NCL_TYPE); - - int line_height = std::max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL); + Rect checkbox = this->GetWidget(WID_NCL_CHECKBOX)->GetCurrentRect(); + Rect name = this->GetWidget(WID_NCL_NAME)->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, 0, WD_FRAMERECT_RIGHT, 0); + Rect type = this->GetWidget(WID_NCL_TYPE)->GetCurrentRect(); /* Fill the matrix with the information */ - int sprite_y_offset = WD_MATRIX_TOP + (line_height - this->checkbox_size.height) / 2 - 1; - int text_y_offset = WD_MATRIX_TOP + (line_height - FONT_HEIGHT_NORMAL) / 2; - uint y = r.top; + int sprite_y_offset = (this->resize.step_height - this->checkbox_size.height) / 2; + int text_y_offset = (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2; + Rect mr = r.WithHeight(this->resize.step_height); auto iter = this->content.begin() + this->vscroll->GetPosition(); size_t last = this->vscroll->GetPosition() + this->vscroll->GetCapacity(); auto end = (last < this->content.size()) ? this->content.begin() + last : this->content.end(); @@ -634,7 +632,7 @@ public: for (/**/; iter != end; iter++) { const ContentInfo *ci = *iter; - if (ci == this->selected) GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 1, PC_GREY); + if (ci == this->selected) GfxFillRect(mr.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_GREY); SpriteID sprite; SpriteID pal = PAL_NONE; @@ -646,13 +644,13 @@ public: case ContentInfo::DOES_NOT_EXIST: sprite = SPR_BLOT; pal = PALETTE_TO_RED; break; default: NOT_REACHED(); } - DrawSprite(sprite, pal, nwi_checkbox->pos_x + (pal == PAL_NONE ? 2 : 3), y + sprite_y_offset + (pal == PAL_NONE ? 1 : 0)); + DrawSprite(sprite, pal, checkbox.left + (sprite == SPR_BLOT ? 3 : 2), mr.top + sprite_y_offset + (sprite == SPR_BLOT ? 0 : 1)); StringID str = STR_CONTENT_TYPE_BASE_GRAPHICS + ci->type - CONTENT_TYPE_BASE_GRAPHICS; - DrawString(nwi_type->pos_x, nwi_type->pos_x + nwi_type->current_x - 1, y + text_y_offset, str, TC_BLACK, SA_HOR_CENTER); + DrawString(type.left, type.right, mr.top + text_y_offset, str, TC_BLACK, SA_HOR_CENTER); - DrawString(nwi_name->pos_x + WD_FRAMERECT_LEFT, nwi_name->pos_x + nwi_name->current_x - WD_FRAMERECT_RIGHT, y + text_y_offset, ci->name, TC_BLACK); - y += this->resize.step_height; + DrawString(name.left, name.right, mr.top + text_y_offset, ci->name, TC_BLACK); + mr = mr.Translate(0, this->resize.step_height); } } @@ -662,60 +660,59 @@ public: */ void DrawDetails(const Rect &r) const { - static const int DETAIL_LEFT = 5; ///< Number of pixels at the left - static const int DETAIL_RIGHT = 5; ///< Number of pixels at the right - static const int DETAIL_TOP = 5; ///< Number of pixels at the top - /* Height for the title banner */ - int DETAIL_TITLE_HEIGHT = 5 * FONT_HEIGHT_NORMAL; + int HEADER_HEIGHT = 3 * FONT_HEIGHT_NORMAL + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM; + + Rect hr = r.WithHeight(HEADER_HEIGHT).Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); + Rect tr = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); + tr.top += HEADER_HEIGHT; /* Create the nice grayish rectangle at the details top */ - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + DETAIL_TITLE_HEIGHT, PC_DARK_BLUE); - DrawString(r.left + WD_INSET_LEFT, r.right - WD_INSET_RIGHT, r.top + FONT_HEIGHT_NORMAL + WD_INSET_TOP, STR_CONTENT_DETAIL_TITLE, TC_FROMSTRING, SA_HOR_CENTER); + GfxFillRect(r.WithHeight(HEADER_HEIGHT).Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, 0), PC_DARK_BLUE); + DrawString(hr.left, hr.right, hr.top, STR_CONTENT_DETAIL_TITLE, TC_FROMSTRING, SA_HOR_CENTER); /* Draw the total download size */ SetDParam(0, this->filesize_sum); - DrawString(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, r.bottom - FONT_HEIGHT_NORMAL - WD_PAR_VSEP_NORMAL, STR_CONTENT_TOTAL_DOWNLOAD_SIZE); + DrawString(tr.left, tr.right, tr.bottom - FONT_HEIGHT_NORMAL + 1, STR_CONTENT_TOTAL_DOWNLOAD_SIZE); if (this->selected == nullptr) return; /* And fill the rest of the details when there's information to place there */ - DrawStringMultiLine(r.left + WD_INSET_LEFT, r.right - WD_INSET_RIGHT, r.top + DETAIL_TITLE_HEIGHT / 2, r.top + DETAIL_TITLE_HEIGHT, STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED + this->selected->state, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(hr.left, hr.right, hr.top + FONT_HEIGHT_NORMAL, hr.bottom, STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED + this->selected->state, TC_FROMSTRING, SA_CENTER); /* Also show the total download size, so keep some space from the bottom */ - const uint max_y = r.bottom - FONT_HEIGHT_NORMAL - WD_PAR_VSEP_WIDE; - int y = r.top + DETAIL_TITLE_HEIGHT + DETAIL_TOP; + tr.bottom -= FONT_HEIGHT_NORMAL + WD_PAR_VSEP_WIDE; if (this->selected->upgrade) { SetDParam(0, STR_CONTENT_TYPE_BASE_GRAPHICS + this->selected->type - CONTENT_TYPE_BASE_GRAPHICS); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_UPDATE); - y += WD_PAR_VSEP_WIDE; + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_UPDATE); + tr.top += WD_PAR_VSEP_WIDE; } SetDParamStr(0, this->selected->name); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_NAME); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_NAME); if (!this->selected->version.empty()) { SetDParamStr(0, this->selected->version); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_VERSION); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_VERSION); } if (!this->selected->description.empty()) { SetDParamStr(0, this->selected->description); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_DESCRIPTION); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_DESCRIPTION); } if (!this->selected->url.empty()) { SetDParamStr(0, this->selected->url); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_URL); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_URL); } SetDParam(0, STR_CONTENT_TYPE_BASE_GRAPHICS + this->selected->type - CONTENT_TYPE_BASE_GRAPHICS); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_TYPE); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_TYPE); - y += WD_PAR_VSEP_WIDE; + tr.top += WD_PAR_VSEP_WIDE; SetDParam(0, this->selected->filesize); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_FILESIZE); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_FILESIZE); if (!this->selected->dependencies.empty()) { /* List dependencies */ @@ -733,7 +730,7 @@ public: } } SetDParamStr(0, buf); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_DEPENDENCIES); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_DEPENDENCIES); } if (!this->selected->tags.empty()) { @@ -744,7 +741,7 @@ public: p += seprintf(p, lastof(buf), p == buf ? "%s" : ", %s", tag.c_str()); } SetDParamStr(0, buf); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_TAGS); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_TAGS); } if (this->selected->IsSelected()) { @@ -761,7 +758,7 @@ public: } if (p != buf) { SetDParamStr(0, buf); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_SELECTED_BECAUSE_OF); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_SELECTED_BECAUSE_OF); } } } diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 1da48f0024..1d6e644b78 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -633,15 +633,19 @@ public: { NetworkGameList *sel = this->server; - const int detail_height = 6 + 8 + 6 + 3 * FONT_HEIGHT_NORMAL; + /* Height for the title banner */ + int HEADER_HEIGHT = 3 * FONT_HEIGHT_NORMAL + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM; + + Rect hr = r.WithHeight(HEADER_HEIGHT).Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); + Rect tr = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); + tr.top += HEADER_HEIGHT; /* Draw the right menu */ - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + detail_height - 1, PC_DARK_BLUE); + /* Create the nice grayish rectangle at the details top */ + GfxFillRect(r.WithHeight(HEADER_HEIGHT).Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, 0), PC_DARK_BLUE); if (sel == nullptr) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(hr.left, hr.right, hr.top, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER); } else if (sel->status != NGLS_ONLINE) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name - StringID message = INVALID_STRING_ID; switch (sel->status) { case NGLS_OFFLINE: message = STR_NETWORK_SERVER_LIST_SERVER_OFFLINE; break; @@ -652,63 +656,63 @@ public: /* Handled by the if-case above. */ case NGLS_ONLINE: NOT_REACHED(); } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + detail_height + 4, message, TC_FROMSTRING, SA_HOR_CENTER); // server offline + + DrawString(hr.left, hr.right, hr.top, message, TC_FROMSTRING, SA_HOR_CENTER); // server offline + DrawStringMultiLine(hr.left, hr.right, hr.top + FONT_HEIGHT_NORMAL, hr.bottom, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name + DrawString(tr.left, tr.right, tr.top, message, TC_FROMSTRING, SA_HOR_CENTER); // server offline } else { // show game info - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name - - uint16 y = r.top + detail_height + 4; + DrawString(hr.left, hr.right, hr.top, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER); + DrawStringMultiLine(hr.left, hr.right, hr.top + FONT_HEIGHT_NORMAL, hr.bottom, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name SetDParam(0, sel->info.clients_on); SetDParam(1, sel->info.clients_max); SetDParam(2, sel->info.companies_on); SetDParam(3, sel->info.companies_max); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CLIENTS); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_NETWORK_SERVER_LIST_CLIENTS); + tr.top += FONT_HEIGHT_NORMAL; SetDParam(0, STR_CLIMATE_TEMPERATE_LANDSCAPE + sel->info.landscape); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_LANDSCAPE); // landscape - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_NETWORK_SERVER_LIST_LANDSCAPE); // landscape + tr.top += FONT_HEIGHT_NORMAL; SetDParam(0, sel->info.map_width); SetDParam(1, sel->info.map_height); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_MAP_SIZE); // map size - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_NETWORK_SERVER_LIST_MAP_SIZE); // map size + tr.top += FONT_HEIGHT_NORMAL; SetDParamStr(0, sel->info.server_revision); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version + tr.top += FONT_HEIGHT_NORMAL; SetDParamStr(0, sel->connection_string); StringID invite_or_address = StrStartsWith(sel->connection_string, "+") ? STR_NETWORK_SERVER_LIST_INVITE_CODE : STR_NETWORK_SERVER_LIST_SERVER_ADDRESS; - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, invite_or_address); // server address / invite code - y += FONT_HEIGHT_NORMAL; + DrawString(tr, invite_or_address); // server address / invite code + tr.top += FONT_HEIGHT_NORMAL; SetDParam(0, sel->info.start_date); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_START_DATE); // start date - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_NETWORK_SERVER_LIST_START_DATE); // start date + tr.top += FONT_HEIGHT_NORMAL; SetDParam(0, sel->info.game_date); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CURRENT_DATE); // current date - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_NETWORK_SERVER_LIST_CURRENT_DATE); // current date + tr.top += FONT_HEIGHT_NORMAL; if (sel->info.gamescript_version != -1) { SetDParamStr(0, sel->info.gamescript_name); SetDParam(1, sel->info.gamescript_version); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_GAMESCRIPT); // gamescript name and version - y += FONT_HEIGHT_NORMAL; + tr.top = DrawStringMultiLine(tr, STR_NETWORK_SERVER_LIST_GAMESCRIPT); // gamescript name and version } - y += WD_PAR_VSEP_NORMAL; + tr.top += WD_PAR_VSEP_WIDE; if (!sel->info.compatible) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, sel->info.version_compatible ? STR_NETWORK_SERVER_LIST_GRF_MISMATCH : STR_NETWORK_SERVER_LIST_VERSION_MISMATCH, TC_FROMSTRING, SA_HOR_CENTER); // server mismatch + DrawString(tr, sel->info.version_compatible ? STR_NETWORK_SERVER_LIST_GRF_MISMATCH : STR_NETWORK_SERVER_LIST_VERSION_MISMATCH, TC_FROMSTRING, SA_HOR_CENTER); // server mismatch } else if (sel->info.clients_on == sel->info.clients_max) { /* Show: server full, when clients_on == max_clients */ - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_FULL, TC_FROMSTRING, SA_HOR_CENTER); // server full + DrawString(tr, STR_NETWORK_SERVER_LIST_SERVER_FULL, TC_FROMSTRING, SA_HOR_CENTER); // server full } else if (sel->info.use_password) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_PASSWORD, TC_FROMSTRING, SA_HOR_CENTER); // password warning + DrawString(tr, STR_NETWORK_SERVER_LIST_PASSWORD, TC_FROMSTRING, SA_HOR_CENTER); // password warning } } } @@ -2088,8 +2092,8 @@ public: uint line = 0; if (this->hover_index >= 0) { - uint offset = this->hover_index * this->line_height; - GfxFillRect(r.left + 2, r.top + offset, r.right - 1, r.top + offset + this->line_height - 2, GREY_SCALE(9)); + Rect br = r.WithHeight(this->line_height).Translate(0, this->hover_index * this->line_height); + GfxFillRect(br.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), GREY_SCALE(9)); } NetworkClientInfo *own_ci = NetworkClientInfo::GetByClientID(_network_own_client_id); @@ -2314,8 +2318,7 @@ struct NetworkCompanyPasswordWindow : public Window { { if (widget != WID_NCP_WARNING) return; - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, - r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, + DrawStringMultiLine(r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM), STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER); } @@ -2415,7 +2418,7 @@ struct NetworkAskRelayWindow : public Window { void DrawWidget(const Rect &r, int widget) const override { if (widget == WID_NAR_TEXT) { - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMETEXT_BOTTOM, STR_NETWORK_ASK_RELAY_TEXT, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM), STR_NETWORK_ASK_RELAY_TEXT, TC_FROMSTRING, SA_CENTER); } } diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index 9aa370aaf5..6e842de9e1 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -428,7 +428,8 @@ struct NewGRFInspectWindow : Window { if (u == v) sel_end = total_width; } - int width = r.Width() - WD_BEVEL_LEFT - WD_BEVEL_RIGHT; + Rect br = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); + int width = br.Width(); int skip = 0; if (total_width > width) { int sel_center = (sel_start + sel_end) / 2; @@ -437,8 +438,8 @@ struct NewGRFInspectWindow : Window { GrfSpecFeature f = GetFeatureNum(this->window_number); int h = GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height; - int y = CenterBounds(r.top, r.bottom, h); - DrawVehicleImage(v->First(), r.left + WD_BEVEL_LEFT, r.right - WD_BEVEL_RIGHT, y + 1, INVALID_VEHICLE, EIT_IN_DETAILS, skip); + int y = CenterBounds(br.top, br.bottom, h); + DrawVehicleImage(v->First(), br.left, br.right, y + 1, INVALID_VEHICLE, EIT_IN_DETAILS, skip); /* Highlight the articulated part (this is different to the whole-vehicle highlighting of DrawVehicleImage */ if (_current_text_dir == TD_RTL) { @@ -878,13 +879,12 @@ struct SpriteAlignerWindow : Window { case WID_SA_SPRITE: { /* Center the sprite ourselves */ const Sprite *spr = GetSprite(this->current_sprite, ST_NORMAL); - int width = r.Width() - WD_BEVEL_LEFT - WD_BEVEL_RIGHT; - int height = r.Height() - WD_BEVEL_TOP - WD_BEVEL_BOTTOM; - int x = -UnScaleGUI(spr->x_offs) + (width - UnScaleGUI(spr->width) ) / 2; - int y = -UnScaleGUI(spr->y_offs) + (height - UnScaleGUI(spr->height)) / 2; + Rect ir = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); + int x = -UnScaleGUI(spr->x_offs) + (ir.Width() - UnScaleGUI(spr->width) ) / 2; + int y = -UnScaleGUI(spr->y_offs) + (ir.Height() - UnScaleGUI(spr->height)) / 2; DrawPixelInfo new_dpi; - if (!FillDrawPixelInfo(&new_dpi, r.left + WD_BEVEL_LEFT, r.top + WD_BEVEL_TOP, width, height)) break; + if (!FillDrawPixelInfo(&new_dpi, ir.left, ir.top, ir.Width(), ir.Height())) break; DrawPixelInfo *old_dpi = _cur_dpi; _cur_dpi = &new_dpi; @@ -902,11 +902,11 @@ struct SpriteAlignerWindow : Window { std::vector &list = _newgrf_debug_sprite_picker.sprites; int max = std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)list.size()); - int y = r.top + WD_FRAMERECT_TOP; + Rect ir = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); for (int i = this->vscroll->GetPosition(); i < max; i++) { SetDParam(0, list[i]); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); - y += step_size; + DrawString(ir, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); + ir.top += step_size; } break; } diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 687c5e95b5..cfd075282b 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -66,8 +66,9 @@ void ShowNewGRFError() } } -static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint bottom, bool show_params) +static void ShowNewGRFInfo(const GRFConfig *c, const Rect &r, bool show_params) { + Rect tr = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); if (c->error != nullptr) { char message[512]; SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages @@ -79,34 +80,34 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint GetString(message, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message)); SetDParamStr(0, message); - y = DrawStringMultiLine(x, right, y, bottom, c->error->severity); + tr.top = DrawStringMultiLine(tr, c->error->severity); } /* Draw filename or not if it is not known (GRF sent over internet) */ if (c->filename != nullptr) { SetDParamStr(0, c->filename); - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_FILENAME); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_FILENAME); } /* Prepare and draw GRF ID */ char buff[256]; seprintf(buff, lastof(buff), "%08X", BSWAP32(c->ident.grfid)); SetDParamStr(0, buff); - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_GRF_ID); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_GRF_ID); if ((_settings_client.gui.newgrf_developer_tools || _settings_client.gui.newgrf_show_old_versions) && c->version != 0) { SetDParam(0, c->version); - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_VERSION); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_VERSION); } if ((_settings_client.gui.newgrf_developer_tools || _settings_client.gui.newgrf_show_old_versions) && c->min_loadable_version != 0) { SetDParam(0, c->min_loadable_version); - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_MIN_VERSION); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_MIN_VERSION); } /* Prepare and draw MD5 sum */ md5sumToString(buff, lastof(buff), c->ident.md5sum); SetDParamStr(0, buff); - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_MD5SUM); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_MD5SUM); /* Show GRF parameter list */ if (show_params) { @@ -117,7 +118,7 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint } else { SetDParam(0, STR_NEWGRF_SETTINGS_PARAMETER_NONE); } - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_PARAMETER); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_PARAMETER); /* Draw the palette of the NewGRF */ if (c->palette & GRFP_BLT_32BPP) { @@ -125,21 +126,21 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint } else { SetDParam(0, (c->palette & GRFP_USE_WINDOWS) ? STR_NEWGRF_SETTINGS_PALETTE_LEGACY : STR_NEWGRF_SETTINGS_PALETTE_DEFAULT); } - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_PALETTE); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_PALETTE); } /* Show flags */ - if (c->status == GCS_NOT_FOUND) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_NOT_FOUND); - if (c->status == GCS_DISABLED) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_DISABLED); - if (HasBit(c->flags, GCF_INVALID)) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_INCOMPATIBLE); - if (HasBit(c->flags, GCF_COMPATIBLE)) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_COMPATIBLE_LOADED); + if (c->status == GCS_NOT_FOUND) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_NOT_FOUND); + if (c->status == GCS_DISABLED) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_DISABLED); + if (HasBit(c->flags, GCF_INVALID)) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_INCOMPATIBLE); + if (HasBit(c->flags, GCF_COMPATIBLE)) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_COMPATIBLE_LOADED); /* Draw GRF info if it exists */ if (!StrEmpty(c->GetDescription())) { SetDParamStr(0, c->GetDescription()); - y = DrawStringMultiLine(x, right, y, bottom, STR_BLACK_RAW_STRING); + tr.top = DrawStringMultiLine(tr, STR_BLACK_RAW_STRING); } else { - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_NO_INFO); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_NO_INFO); } } @@ -252,18 +253,17 @@ struct NewGRFParametersWindow : public Window { if (par_info == nullptr) return; const char *desc = GetGRFStringFromGRFText(par_info->desc); if (desc == nullptr) return; - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_TEXTPANEL_TOP, r.bottom - WD_TEXTPANEL_BOTTOM, desc, TC_BLACK); + DrawStringMultiLine(r.Shrink(WD_FRAMERECT_LEFT, WD_TEXTPANEL_TOP, WD_FRAMERECT_RIGHT, WD_TEXTPANEL_BOTTOM), desc, TC_BLACK); return; } else if (widget != WID_NP_BACKGROUND) { return; } + Rect ir = r.Shrink(WD_FRAMERECT_LEFT, 0, WD_FRAMERECT_RIGHT, 0); bool rtl = _current_text_dir == TD_RTL; - uint buttons_left = rtl ? r.right - SETTING_BUTTON_WIDTH - 3 : r.left + 4; - uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8); - uint text_right = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT); + uint buttons_left = rtl ? ir.right - SETTING_BUTTON_WIDTH - 3 : ir.left + 4; + Rect tr = r.Indent(SETTING_BUTTON_WIDTH + 8, rtl); - int y = r.top; int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) { @@ -273,13 +273,13 @@ struct NewGRFParametersWindow : public Window { bool selected = (i == this->clicked_row); if (par_info->type == PTYPE_BOOL) { - DrawBoolButton(buttons_left, y + button_y_offset, current_value != 0, this->editable); + DrawBoolButton(buttons_left, ir.top + button_y_offset, current_value != 0, this->editable); SetDParam(2, par_info->GetValue(this->grf_config) == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON); } else if (par_info->type == PTYPE_UINT_ENUM) { if (par_info->complete_labels) { - DrawDropDownButton(buttons_left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && this->clicked_dropdown, this->editable); + DrawDropDownButton(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && this->clicked_dropdown, this->editable); } else { - DrawArrowButtons(buttons_left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, this->editable && current_value > par_info->min_value, this->editable && current_value < par_info->max_value); + DrawArrowButtons(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, this->editable && current_value > par_info->min_value, this->editable && current_value < par_info->max_value); } SetDParam(2, STR_JUST_INT); SetDParam(3, current_value); @@ -301,8 +301,8 @@ struct NewGRFParametersWindow : public Window { SetDParam(1, i + 1); } - DrawString(text_left, text_right, y + text_y_offset, STR_NEWGRF_PARAMETERS_SETTING, selected ? TC_WHITE : TC_LIGHT_BLUE); - y += this->line_height; + DrawString(tr.left, tr.right, ir.top + text_y_offset, STR_NEWGRF_PARAMETERS_SETTING, selected ? TC_WHITE : TC_LIGHT_BLUE); + ir.top += this->line_height; } } @@ -833,10 +833,11 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { { switch (widget) { case WID_NS_FILE_LIST: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); + const Rect br = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); + GfxFillRect(br, PC_BLACK); + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); uint step_height = this->GetWidget(WID_NS_FILE_LIST)->resize_y; - uint y = r.top + WD_FRAMERECT_TOP; Dimension square = GetSpriteSize(SPR_SQUARE); Dimension warning = GetSpriteSize(SPR_WARNING_SIGN); int square_offset_y = (step_height - square.height) / 2; @@ -844,10 +845,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; bool rtl = _current_text_dir == TD_RTL; - uint text_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.left + square.width + 15; - uint text_right = rtl ? r.right - square.width - 15 : r.right - WD_FRAMERECT_RIGHT; - uint square_left = rtl ? r.right - square.width - 5 : r.left + 5; - uint warning_left = rtl ? r.right - square.width - warning.width - 10 : r.left + square.width + 10; + uint text_left = rtl ? tr.left : tr.left + square.width + 13; + uint text_right = rtl ? tr.right - square.width - 13 : tr.right; + uint square_left = rtl ? tr.right - square.width - 3 : tr.left + 3; + uint warning_left = rtl ? tr.right - square.width - warning.width - 8 : tr.left + square.width + 8; int i = 0; for (const GRFConfig *c = this->actives; c != nullptr; c = c->next, i++) { @@ -857,35 +858,36 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { PaletteID pal = this->GetPalette(c); if (h) { - GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 1, PC_DARK_BLUE); + GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE); } else if (i == this->active_over) { /* Get index of current selection. */ int active_sel_pos = 0; for (GRFConfig *c = this->actives; c != nullptr && c != this->active_sel; c = c->next, active_sel_pos++) {} if (active_sel_pos != this->active_over) { - uint top = this->active_over < active_sel_pos ? y + 1 : y + step_height - 2; - GfxFillRect(r.left + WD_FRAMERECT_LEFT, top - 1, r.right - WD_FRAMERECT_RIGHT, top + 1, PC_GREY); + uint top = this->active_over < active_sel_pos ? tr.top + 1 : tr.top + step_height - 2; + GfxFillRect(tr.left, top - 1, tr.right, top + 1, PC_GREY); } } - DrawSprite(SPR_SQUARE, pal, square_left, y + square_offset_y); - if (c->error != nullptr) DrawSprite(SPR_WARNING_SIGN, 0, warning_left, y + warning_offset_y); + DrawSprite(SPR_SQUARE, pal, square_left, tr.top + square_offset_y); + if (c->error != nullptr) DrawSprite(SPR_WARNING_SIGN, 0, warning_left, tr.top + warning_offset_y); uint txtoffset = c->error == nullptr ? 0 : warning.width; - DrawString(text_left + (rtl ? 0 : txtoffset), text_right - (rtl ? txtoffset : 0), y + offset_y, text, h ? TC_WHITE : TC_ORANGE); - y += step_height; + DrawString(text_left + (rtl ? 0 : txtoffset), text_right - (rtl ? txtoffset : 0), tr.top + offset_y, text, h ? TC_WHITE : TC_ORANGE); + tr.top += step_height; } } if (i == this->active_over && this->vscroll->IsVisible(i)) { // Highlight is after the last GRF entry. - GfxFillRect(r.left + WD_FRAMERECT_LEFT, y, r.right - WD_FRAMERECT_RIGHT, y + 2, PC_GREY); + GfxFillRect(tr.left, tr.top, tr.right, tr.top + 2, PC_GREY); } break; } case WID_NS_AVAIL_LIST: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, this->active_over == -2 ? PC_DARK_GREY : PC_BLACK); + const Rect br = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); + GfxFillRect(br, this->active_over == -2 ? PC_DARK_GREY : PC_BLACK); + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); uint step_height = this->GetWidget(WID_NS_AVAIL_LIST)->resize_y; int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; - uint y = r.top + WD_FRAMERECT_TOP; uint min_index = this->vscroll2->GetPosition(); uint max_index = std::min(min_index + this->vscroll2->GetCapacity(), (uint)this->avails.size()); @@ -894,16 +896,16 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { bool h = (c == this->avail_sel); const char *text = c->GetName(); - if (h) GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 1, PC_DARK_BLUE); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y + offset_y, text, h ? TC_WHITE : TC_SILVER); - y += step_height; + if (h) GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE); + DrawString(tr.left, tr.right, tr.top + offset_y, text, h ? TC_WHITE : TC_SILVER); + tr.top += step_height; } break; } case WID_NS_NEWGRF_INFO_TITLE: /* Create the nice grayish rectangle at the details top. */ - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_DARK_BLUE); + GfxFillRect(r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_DARK_BLUE); DrawString(r.left, r.right, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), STR_NEWGRF_SETTINGS_INFO_TITLE, TC_FROMSTRING, SA_HOR_CENTER); break; @@ -911,7 +913,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { const GRFConfig *selected = this->active_sel; if (selected == nullptr) selected = this->avail_sel; if (selected != nullptr) { - ShowNewGRFInfo(selected, r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, r.right - WD_FRAMERECT_RIGHT, r.bottom - WD_FRAMERECT_BOTTOM, this->show_params); + ShowNewGRFInfo(selected, r, this->show_params); } break; } @@ -2091,20 +2093,21 @@ struct SavePresetWindow : public Window { { switch (widget) { case WID_SVP_PRESET_LIST: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); + const Rect br = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); + GfxFillRect(br, PC_BLACK); uint step_height = this->GetWidget(WID_SVP_PRESET_LIST)->resize_y; int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; - uint y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); uint min_index = this->vscroll->GetPosition(); uint max_index = std::min(min_index + this->vscroll->GetCapacity(), (uint)this->presets.size()); for (uint i = min_index; i < max_index; i++) { - if ((int)i == this->selected) GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 2, PC_DARK_BLUE); + if ((int)i == this->selected) GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE); const char *text = this->presets[i].c_str(); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right, y + offset_y, text, ((int)i == this->selected) ? TC_WHITE : TC_SILVER); - y += step_height; + DrawString(tr.left, tr.right, tr.top + offset_y, text, ((int)i == this->selected) ? TC_WHITE : TC_SILVER); + tr.top += step_height; } break; } diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 57b745b211..8f7a92cd58 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -1135,9 +1135,6 @@ static void DrawNewsString(uint left, uint right, int y, TextColour colour, cons } struct MessageHistoryWindow : Window { - static const int top_spacing; ///< Additional spacing at the top of the #WID_MH_BACKGROUND widget. - static const int bottom_spacing; ///< Additional spacing at the bottom of the #WID_MH_BACKGROUND widget. - int line_height; /// < Height of a single line in the news history window including spacing. int date_width; /// < Width needed for the date part. @@ -1154,7 +1151,7 @@ struct MessageHistoryWindow : Window { void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_MH_BACKGROUND) { - this->line_height = FONT_HEIGHT_NORMAL + 2; + this->line_height = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; resize->height = this->line_height; /* Months are off-by-one, so it's actually 8. Not using @@ -1162,7 +1159,7 @@ struct MessageHistoryWindow : Window { SetDParam(0, ConvertYMDToDate(ORIGINAL_MAX_YEAR, 7, 30)); this->date_width = GetStringBoundingBox(STR_SHORT_DATE).width; - size->height = 4 * resize->height + this->top_spacing + this->bottom_spacing; // At least 4 lines are visible. + size->height = 4 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; // At least 4 lines are visible. size->width = std::max(200u, size->width); // At least 200 pixels wide. } } @@ -1185,17 +1182,15 @@ struct MessageHistoryWindow : Window { } /* Fill the widget with news items. */ - int y = r.top + this->top_spacing; bool rtl = _current_text_dir == TD_RTL; - uint date_left = rtl ? r.right - WD_FRAMERECT_RIGHT - this->date_width : r.left + WD_FRAMERECT_LEFT; - uint date_right = rtl ? r.right - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT + this->date_width; - uint news_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.left + WD_FRAMERECT_LEFT + this->date_width + WD_FRAMERECT_RIGHT + ScaleFontTrad(5); - uint news_right = rtl ? r.right - WD_FRAMERECT_RIGHT - this->date_width - WD_FRAMERECT_RIGHT - ScaleFontTrad(5) : r.right - WD_FRAMERECT_RIGHT; + Rect news = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM).Indent(this->date_width + ScaleFontTrad(5), rtl); + Rect date = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM).WithWidth(this->date_width, rtl); + int y = news.top; for (int n = this->vscroll->GetCapacity(); n > 0; n--) { SetDParam(0, ni->date); - DrawString(date_left, date_right, y, STR_SHORT_DATE); + DrawString(date.left, date.right, y, STR_SHORT_DATE); - DrawNewsString(news_left, news_right, y, TC_WHITE, ni); + DrawNewsString(news.left, news.right, y, TC_WHITE, ni); y += this->line_height; ni = ni->prev; @@ -1235,9 +1230,6 @@ struct MessageHistoryWindow : Window { } }; -const int MessageHistoryWindow::top_spacing = WD_FRAMERECT_TOP + 4; -const int MessageHistoryWindow::bottom_spacing = WD_FRAMERECT_BOTTOM; - static const NWidgetPart _nested_message_history[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 2afd51e348..083292a87f 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -313,8 +313,8 @@ public: break; case WID_BO_SELECT_IMAGE: - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(58) + 2; + size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT; + size->height = ScaleGUITrad(58) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM; break; default: break; @@ -325,15 +325,15 @@ public: { switch (GB(widget, 0, 16)) { case WID_BO_CLASS_LIST: { - int y = r.top; + Rect mr = r.Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM); uint pos = 0; for (auto object_class_id : this->object_classes) { ObjectClass *objclass = ObjectClass::Get(object_class_id); if (objclass->GetUISpecCount() == 0) continue; if (!this->vscroll->IsVisible(pos++)) continue; - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, objclass->name, + DrawString(mr, objclass->name, (object_class_id == _selected_object_class) ? TC_WHITE : TC_BLACK); - y += this->line_height; + mr.top += this->line_height; } break; } @@ -360,9 +360,9 @@ public: if (spec->grf_prop.grffile == nullptr) { extern const DrawTileSprites _objects[]; const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; - DrawOrigTileSeqInGUI((r.right - r.left) / 2 - 1, (r.bottom - r.top + matrix_height / 2) / 2 - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), dts, PAL_NONE); + DrawOrigTileSeqInGUI(r.Width() / 2 - 1, (r.Height() + matrix_height / 2) / 2 - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), dts, PAL_NONE); } else { - DrawNewObjectTileInGUI((r.right - r.left) / 2 - 1, (r.bottom - r.top + matrix_height / 2) / 2 - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), spec, GB(widget, 16, 16)); + DrawNewObjectTileInGUI(r.Width() / 2 - 1, (r.Height() + matrix_height / 2) / 2 - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), spec, GB(widget, 16, 16)); } _cur_dpi = old_dpi; } @@ -377,19 +377,19 @@ public: if (spec == nullptr) break; if (!spec->IsAvailable()) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_BLACK, FILLRECT_CHECKER); } DrawPixelInfo tmp_dpi; /* Set up a clipping area for the preview. */ - if (FillDrawPixelInfo(&tmp_dpi, r.left + 1, r.top, (r.right - 1) - (r.left + 1) + 1, r.Height())) { + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { DrawPixelInfo *old_dpi = _cur_dpi; _cur_dpi = &tmp_dpi; if (spec->grf_prop.grffile == nullptr) { extern const DrawTileSprites _objects[]; const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; - DrawOrigTileSeqInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), dts, PAL_NONE); + DrawOrigTileSeqInGUI(r.Width() / 2 - 1, r.Height() - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), dts, PAL_NONE); } else { - DrawNewObjectTileInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), spec, + DrawNewObjectTileInGUI(r.Width() / 2 - 1, r.Height() - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), spec, std::min(_selected_object_view, spec->views - 1)); } _cur_dpi = old_dpi; diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 16f5d49447..adc38625ea 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -1074,12 +1074,13 @@ public: { if (widget != WID_O_ORDER_LIST) return; + Rect ir = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM); bool rtl = _current_text_dir == TD_RTL; SetDParamMaxValue(0, this->vehicle->GetNumOrders(), 2); int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + 3; - int middle = rtl ? r.right - WD_FRAMETEXT_RIGHT - index_column_width : r.left + WD_FRAMETEXT_LEFT + index_column_width; + int middle = rtl ? ir.right - index_column_width : ir.left + index_column_width; - int y = r.top + WD_FRAMERECT_TOP; + int y = ir.top; int line_height = this->GetWidget(WID_O_ORDER_LIST)->resize_y; int i = this->vscroll->GetPosition(); @@ -1093,9 +1094,9 @@ public: if (i != this->selected_order && i == this->order_over) { /* Highlight dragged order destination. */ int top = (this->order_over < this->selected_order ? y : y + line_height) - WD_FRAMERECT_TOP; - int bottom = std::min(top + 2, r.bottom - WD_FRAMERECT_BOTTOM); - top = std::max(top - 3, r.top + WD_FRAMERECT_TOP); - GfxFillRect(r.left + WD_FRAMETEXT_LEFT, top, r.right - WD_FRAMETEXT_RIGHT, bottom, _colour_gradient[COLOUR_GREY][7]); + int bottom = std::min(top + 2, ir.bottom); + top = std::max(top - 3, ir.top); + GfxFillRect(ir.left, top, ir.right, bottom, _colour_gradient[COLOUR_GREY][7]); break; } y += line_height; @@ -1105,7 +1106,7 @@ public: } /* Reset counters for drawing the orders. */ - y = r.top + WD_FRAMERECT_TOP; + y = ir.top; i = this->vscroll->GetPosition(); order = this->vehicle->GetOrder(i); } @@ -1115,7 +1116,7 @@ public: /* Don't draw anything if it extends past the end of the window. */ if (!this->vscroll->IsVisible(i)) break; - DrawOrderString(this->vehicle, order, i, y, i == this->selected_order, false, r.left + WD_FRAMETEXT_LEFT, middle, r.right - WD_FRAMETEXT_RIGHT); + DrawOrderString(this->vehicle, order, i, y, i == this->selected_order, false, ir.left, middle, ir.right); y += line_height; i++; @@ -1124,7 +1125,7 @@ public: if (this->vscroll->IsVisible(i)) { StringID str = this->vehicle->IsOrderListShared() ? STR_ORDERS_END_OF_SHARED_ORDERS : STR_ORDERS_END_OF_ORDERS; - DrawString(rtl ? r.left + WD_FRAMETEXT_LEFT : middle, rtl ? middle : r.right - WD_FRAMETEXT_RIGHT, y, str, (i == this->selected_order) ? TC_WHITE : TC_BLACK); + DrawString(rtl ? ir.left : middle, rtl ? middle : ir.right, y, str, (i == this->selected_order) ? TC_WHITE : TC_BLACK); } } diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 8c59336811..b0003c29a2 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1281,14 +1281,14 @@ public: break; case WID_BRAS_NEWST_LIST: { + Rect ir = r.Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM); uint statclass = 0; - uint row = 0; for (auto station_class : this->station_classes) { if (this->vscroll->IsVisible(statclass)) { - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, row * this->line_height + r.top + WD_MATRIX_TOP, + DrawString(ir, StationClass::Get(station_class)->name, station_class == _railstation.station_class ? TC_WHITE : TC_BLACK); - row++; + ir.top += this->line_height; } statclass++; } @@ -1301,7 +1301,7 @@ public: /* Check station availability callback */ const StationSpec *statspec = StationClass::Get(_railstation.station_class)->GetSpec(type); if (!IsStationAvailable(statspec)) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_BLACK, FILLRECT_CHECKER); } /* Set up a clipping area for the station preview. */ @@ -2043,7 +2043,7 @@ struct BuildRailWaypointWindow : PickerWindowBase { DrawWaypointSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), type, _cur_railtype); if (!IsStationAvailable(statspec)) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_BLACK, FILLRECT_CHECKER); } } } diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index a3685c5c50..0782162b0e 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -194,30 +194,29 @@ struct SignListWindow : Window, SignList { { switch (widget) { case WID_SIL_LIST: { - uint y = r.top + WD_FRAMERECT_TOP; // Offset from top of widget. + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); uint text_offset_y = (this->resize.step_height - FONT_HEIGHT_NORMAL + 1) / 2; /* No signs? */ if (this->vscroll->GetCount() == 0) { - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y + text_offset_y, STR_STATION_LIST_NONE); + DrawString(tr.left, tr.right, tr.top + text_offset_y, STR_STATION_LIST_NONE); return; } Dimension d = GetSpriteSize(SPR_COMPANY_ICON); bool rtl = _current_text_dir == TD_RTL; int sprite_offset_y = (this->resize.step_height - d.height + 1) / 2; - uint icon_left = 4 + (rtl ? r.right - this->text_offset : r.left); - uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : this->text_offset); - uint text_right = r.right - (rtl ? this->text_offset : WD_FRAMERECT_RIGHT); + uint icon_left = rtl ? tr.right - this->text_offset : tr.left; + tr = tr.Indent(this->text_offset, rtl); /* At least one sign available. */ for (uint16 i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) { const Sign *si = this->signs[i]; - if (si->owner != OWNER_NONE) DrawCompanyIcon(si->owner, icon_left, y + sprite_offset_y); + if (si->owner != OWNER_NONE) DrawCompanyIcon(si->owner, icon_left, tr.top + sprite_offset_y); SetDParam(0, si->index); - DrawString(text_left, text_right, y + text_offset_y, STR_SIGN_NAME, TC_YELLOW); - y += this->resize.step_height; + DrawString(tr.left, tr.right, tr.top + text_offset_y, STR_SIGN_NAME, TC_YELLOW); + tr.top += this->resize.step_height; } break; } diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index b8550a4e18..b56feb466b 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -1214,8 +1214,9 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() { switch (widget) { case WID_SM_MAP: { + Rect ir = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); DrawPixelInfo new_dpi; - if (!FillDrawPixelInfo(&new_dpi, r.left + 1, r.top + 1, r.Width(), r.Height())) return; + if (!FillDrawPixelInfo(&new_dpi, ir.left, ir.top, ir.Width(), ir.Height())) return; this->DrawSmallMap(&new_dpi); break; } @@ -1224,17 +1225,13 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() uint columns = this->GetNumberColumnsLegend(r.Width()); uint number_of_rows = this->GetNumberRowsLegend(columns); bool rtl = _current_text_dir == TD_RTL; - uint y_org = r.top + WD_FRAMERECT_TOP; - uint x = rtl ? r.right - this->column_width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT; - uint y = y_org; uint i = 0; // Row counter for industry legend. uint row_height = FONT_HEIGHT_SMALL; int padding = ScaleFontTrad(1); - uint text_left = rtl ? 0 : this->legend_width + WD_FRAMERECT_LEFT; - uint text_right = this->column_width - padding - (rtl ? this->legend_width + WD_FRAMERECT_RIGHT : 0); - uint blob_left = rtl ? this->column_width - padding - this->legend_width : 0; - uint blob_right = rtl ? this->column_width - padding : this->legend_width; + Rect origin = r.WithWidth(this->column_width, rtl).Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM).WithHeight(row_height); + Rect text = origin.Indent(this->legend_width + padding, rtl); + Rect icon = origin.WithWidth(this->legend_width, rtl).Shrink(0, padding, 0, 0); StringID string = STR_NULL; switch (this->map_type) { @@ -1255,8 +1252,10 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() if (tbl->col_break || ((this->map_type == SMT_INDUSTRY || this->map_type == SMT_OWNER || this->map_type == SMT_LINKSTATS) && i++ >= number_of_rows)) { /* Column break needed, continue at top, COLUMN_WIDTH pixels * (one "row") to the right. */ - x += rtl ? -(int)this->column_width : this->column_width; - y = y_org; + int x = rtl ? -(int)this->column_width : this->column_width; + int y = origin.top - text.top; + text = text.Translate(x, y); + icon = icon.Translate(x, y); i = 1; } @@ -1283,10 +1282,10 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() if (!tbl->show_on_map) { /* Simply draw the string, not the black border of the legend colour. * This will enforce the idea of the disabled item */ - DrawString(x + text_left, x + text_right, y, string, TC_GREY); + DrawString(text, string, TC_GREY); } else { - DrawString(x + text_left, x + text_right, y, string, TC_BLACK); - GfxFillRect(x + blob_left, y + padding, x + blob_right, y + row_height - 1, PC_BLACK); // Outer border of the legend colour + DrawString(text, string, TC_BLACK); + GfxFillRect(icon, PC_BLACK); // Outer border of the legend colour } break; } @@ -1295,13 +1294,14 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() default: if (this->map_type == SMT_CONTOUR) SetDParam(0, tbl->height * TILE_HEIGHT_STEP); /* Anything that is not an industry or a company is using normal process */ - GfxFillRect(x + blob_left, y + padding, x + blob_right, y + row_height - 1, PC_BLACK); - DrawString(x + text_left, x + text_right, y, tbl->legend); + GfxFillRect(icon, PC_BLACK); + DrawString(text, tbl->legend); break; } - GfxFillRect(x + blob_left + 1, y + padding + 1, x + blob_right - 1, y + row_height - 2, legend_colour); // Legend colour + GfxFillRect(icon.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), legend_colour); // Legend colour - y += row_height; + text = text.Translate(0, row_height); + icon = icon.Translate(0, row_height); } } } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 17f8a43c97..38a4c7a2ca 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -433,7 +433,7 @@ public: case WID_STL_LIST: { bool rtl = _current_text_dir == TD_RTL; int max = std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->stations.size()); - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); uint line_height = this->GetWidget(widget)->resize_y; /* Spacing between station name and first rating graph. */ int text_spacing = ScaleFontTrad(5); @@ -450,7 +450,7 @@ public: SetDParam(0, st->index); SetDParam(1, st->facilities); - int x = DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y + (line_height - FONT_HEIGHT_NORMAL) / 2, STR_STATION_LIST_STATION); + int x = DrawString(tr.left, tr.right, tr.top + (line_height - FONT_HEIGHT_NORMAL) / 2, STR_STATION_LIST_STATION); x += rtl ? -text_spacing : text_spacing; /* show cargo waiting and station ratings */ @@ -463,20 +463,20 @@ public: * the space. */ if (rtl) { x -= rating_width + rating_spacing; - if (x < r.left + WD_FRAMERECT_LEFT) break; + if (x < tr.left) break; } - StationsWndShowStationRating(x, x + rating_width, y, cid, st->goods[cid].cargo.TotalCount(), st->goods[cid].rating); + StationsWndShowStationRating(x, x + rating_width, tr.top, cid, st->goods[cid].cargo.TotalCount(), st->goods[cid].rating); if (!rtl) { x += rating_width + rating_spacing; - if (x > r.right - WD_FRAMERECT_RIGHT) break; + if (x > tr.right) break; } } } - y += line_height; + tr.top += line_height; } if (this->vscroll->GetCount() == 0) { // company has no stations - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_LIST_NONE); + DrawString(tr.left, tr.right, tr.top + (line_height - FONT_HEIGHT_NORMAL) / 2, STR_STATION_LIST_NONE); return; } break; @@ -484,11 +484,13 @@ public: default: if (widget >= WID_STL_CARGOSTART) { + Rect br = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); const CargoSpec *cs = _sorted_cargo_specs[widget - WID_STL_CARGOSTART]; int cg_ofst = HasBit(this->cargo_filter, cs->Index()) ? 1 : 0; - GfxFillRect(r.left + cg_ofst + 1, r.top + cg_ofst + 1, r.right - 1 + cg_ofst, r.bottom - 1 + cg_ofst, cs->rating_colour); + br = br.Translate(cg_ofst, cg_ofst); + GfxFillRect(br, cs->rating_colour); TextColour tc = GetContrastColour(cs->rating_colour); - DrawString(r.left + cg_ofst, r.right + cg_ofst, CenterBounds(r.top, r.bottom, FONT_HEIGHT_SMALL) + cg_ofst, cs->abbrev, tc, SA_HOR_CENTER); + DrawString(br.left, br.right, CenterBounds(br.top, br.bottom, FONT_HEIGHT_SMALL), cs->abbrev, tc, SA_HOR_CENTER); } break; } @@ -1367,7 +1369,7 @@ struct StationViewWindow : public Window { case WID_SV_WAITING: resize->height = FONT_HEIGHT_NORMAL; size->height = WD_FRAMERECT_TOP + 4 * resize->height + WD_FRAMERECT_BOTTOM; - this->expand_shrink_width = std::max(GetStringBoundingBox("-").width, GetStringBoundingBox("+").width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + this->expand_shrink_width = std::max(GetStringBoundingBox("-").width, GetStringBoundingBox("+").width); break; case WID_SV_ACCEPT_RATING_LIST: @@ -1439,7 +1441,7 @@ struct StationViewWindow : public Window { /* Draw waiting cargo. */ NWidgetBase *nwi = this->GetWidget(WID_SV_WAITING); - Rect waiting_rect = nwi->GetCurrentRect(); + Rect waiting_rect = nwi->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); this->DrawEntries(&cargo, waiting_rect, pos, maxrows, 0); scroll_to_row = INT_MAX; } @@ -1711,7 +1713,7 @@ struct StationViewWindow : public Window { * @param cargo Current cargo being drawn (if cargo column has been passed). * @return row (in "pos" counting) after the one we have last drawn to. */ - int DrawEntries(CargoDataEntry *entry, Rect &r, int pos, int maxrows, int column, CargoID cargo = CT_INVALID) + int DrawEntries(CargoDataEntry *entry, const Rect &r, int pos, int maxrows, int column, CargoID cargo = CT_INVALID) { if (this->sortings[column] == ST_AS_GROUPING) { if (this->groupings[column] != GR_CARGO) { @@ -1729,13 +1731,13 @@ struct StationViewWindow : public Window { if (pos > -maxrows && pos <= 0) { StringID str = STR_EMPTY; - int y = r.top + WD_FRAMERECT_TOP - pos * FONT_HEIGHT_NORMAL; + int y = r.top - pos * FONT_HEIGHT_NORMAL; SetDParam(0, cargo); SetDParam(1, cd->GetCount()); if (this->groupings[column] == GR_CARGO) { str = STR_STATION_VIEW_WAITING_CARGO; - DrawCargoIcons(cd->GetCargo(), cd->GetCount(), r.left + WD_FRAMERECT_LEFT + this->expand_shrink_width, r.right - WD_FRAMERECT_RIGHT - this->expand_shrink_width, y); + DrawCargoIcons(cd->GetCargo(), cd->GetCount(), r.left + this->expand_shrink_width, r.right - this->expand_shrink_width, y); } else { if (!auto_distributed) grouping = GR_SOURCE; StationID station = cd->GetStation(); @@ -1760,12 +1762,10 @@ struct StationViewWindow : public Window { } bool rtl = _current_text_dir == TD_RTL; - int text_left = rtl ? r.left + this->expand_shrink_width : r.left + WD_FRAMERECT_LEFT + column * this->expand_shrink_width; - int text_right = rtl ? r.right - WD_FRAMERECT_LEFT - column * this->expand_shrink_width : r.right - this->expand_shrink_width; - int shrink_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.right - this->expand_shrink_width + WD_FRAMERECT_LEFT; - int shrink_right = rtl ? r.left + this->expand_shrink_width - WD_FRAMERECT_RIGHT : r.right - WD_FRAMERECT_RIGHT; + Rect text = r.Indent(column * this->expand_shrink_width, rtl).Indent(this->expand_shrink_width, !rtl); + Rect shrink = r.WithWidth(this->expand_shrink_width, !rtl); - DrawString(text_left, text_right, y, str); + DrawString(text.left, text.right, y, str); if (column < NUM_COLUMNS - 1) { const char *sym = nullptr; @@ -1780,7 +1780,7 @@ struct StationViewWindow : public Window { sym = "+"; } } - if (sym) DrawString(shrink_left, shrink_right, y, sym, TC_YELLOW); + if (sym != nullptr) DrawString(shrink.left, shrink.right, y, sym, TC_YELLOW); } this->SetDisplayedRow(cd); } @@ -1800,13 +1800,14 @@ struct StationViewWindow : public Window { int DrawAcceptedCargo(const Rect &r) const { const Station *st = Station::Get(this->window_number); + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); CargoTypes cargo_mask = 0; for (CargoID i = 0; i < NUM_CARGO; i++) { if (HasBit(st->goods[i].status, GoodsEntry::GES_ACCEPTANCE)) SetBit(cargo_mask, i); } SetDParam(0, cargo_mask); - int bottom = DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, INT32_MAX, STR_STATION_VIEW_ACCEPTS_CARGO); + int bottom = DrawStringMultiLine(tr.left, tr.right, tr.top, INT32_MAX, STR_STATION_VIEW_ACCEPTS_CARGO); return CeilDiv(bottom - r.top - WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); } @@ -1818,16 +1819,17 @@ struct StationViewWindow : public Window { int DrawCargoRatings(const Rect &r) const { const Station *st = Station::Get(this->window_number); - int y = r.top + WD_FRAMERECT_TOP; + bool rtl = _current_text_dir == TD_RTL; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); if (st->town->exclusive_counter > 0) { SetDParam(0, st->town->exclusivity); - y = DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, r.bottom, st->town->exclusivity == st->owner ? STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF : STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY); - y += WD_PAR_VSEP_WIDE; + tr.top = DrawStringMultiLine(tr, st->town->exclusivity == st->owner ? STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF : STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY); + tr.top += WD_PAR_VSEP_WIDE; } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_VIEW_SUPPLY_RATINGS_TITLE); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_STATION_VIEW_SUPPLY_RATINGS_TITLE); + tr.top += FONT_HEIGHT_NORMAL; for (const CargoSpec *cs : _sorted_standard_cargo_specs) { const GoodsEntry *ge = &st->goods[cs->Index()]; @@ -1838,10 +1840,10 @@ struct StationViewWindow : public Window { SetDParam(1, lg != nullptr ? lg->Monthly((*lg)[ge->node].Supply()) : 0); SetDParam(2, STR_CARGO_RATING_APPALLING + (ge->rating >> 5)); SetDParam(3, ToPercent8(ge->rating)); - DrawString(r.left + WD_FRAMERECT_LEFT + 6, r.right - WD_FRAMERECT_RIGHT - 6, y, STR_STATION_VIEW_CARGO_SUPPLY_RATING); - y += FONT_HEIGHT_NORMAL; + DrawString(tr.Indent(6, rtl), STR_STATION_VIEW_CARGO_SUPPLY_RATING); + tr.top += FONT_HEIGHT_NORMAL; } - return CeilDiv(y - r.top - WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); + return CeilDiv(tr.top - r.top - WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); } /** @@ -2287,20 +2289,20 @@ struct SelectStationWindow : Window { { if (widget != WID_JS_PANEL) return; - uint y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); if (this->vscroll->GetPosition() == 0) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT : STR_JOIN_STATION_CREATE_SPLITTED_STATION); - y += this->resize.step_height; + DrawString(tr, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT : STR_JOIN_STATION_CREATE_SPLITTED_STATION); + tr.top += this->resize.step_height; } - for (uint i = std::max(1, this->vscroll->GetPosition()); i <= _stations_nearby_list.size(); ++i, y += this->resize.step_height) { + for (uint i = std::max(1, this->vscroll->GetPosition()); i <= _stations_nearby_list.size(); ++i, tr.top += this->resize.step_height) { /* Don't draw anything if it extends past the end of the window. */ if (i - this->vscroll->GetPosition() >= this->vscroll->GetCapacity()) break; const T *st = T::Get(_stations_nearby_list[i - 1]); SetDParam(0, st->index); SetDParam(1, st->facilities); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_STATION_LIST_WAYPOINT : STR_STATION_LIST_STATION); + DrawString(tr, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_STATION_LIST_WAYPOINT : STR_STATION_LIST_STATION); } } diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index b2500e609a..94fe8085ef 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -137,24 +137,24 @@ struct StatusBarWindow : Window { void DrawWidget(const Rect &r, int widget) const override { - int text_offset = std::max(0, (r.Height() - FONT_HEIGHT_NORMAL) / 2); // Offset for rendering the text vertically centered - int text_top = r.top + text_offset; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, 0, WD_FRAMERECT_RIGHT, 0); + tr.top = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL); switch (widget) { case WID_S_LEFT: /* Draw the date */ SetDParam(0, _date); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER); break; case WID_S_RIGHT: { if (_local_company == COMPANY_SPECTATOR) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_STATUSBAR_SPECTATOR, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_STATUSBAR_SPECTATOR, TC_FROMSTRING, SA_HOR_CENTER); } else { /* Draw company money, if any */ const Company *c = Company::GetIfValid(_local_company); if (c != nullptr) { SetDParam(0, c->money); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_COMPANY_MONEY, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_COMPANY_MONEY, TC_FROMSTRING, SA_HOR_CENTER); } } break; @@ -163,12 +163,12 @@ struct StatusBarWindow : Window { case WID_S_MIDDLE: /* Draw status bar */ if (this->saving) { // true when saving is active - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_STATUSBAR_SAVING_GAME, TC_FROMSTRING, SA_HOR_CENTER | SA_VERT_CENTER); + DrawString(tr, STR_STATUSBAR_SAVING_GAME, TC_FROMSTRING, SA_HOR_CENTER | SA_VERT_CENTER); } else if (_do_autosave) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_STATUSBAR_AUTOSAVE, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_STATUSBAR_AUTOSAVE, TC_FROMSTRING, SA_HOR_CENTER); } else if (_pause_mode != PM_UNPAUSED) { StringID msg = (_pause_mode & PM_PAUSED_LINK_GRAPH) ? STR_STATUSBAR_PAUSED_LINK_GRAPH : STR_STATUSBAR_PAUSED; - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, msg, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, msg, TC_FROMSTRING, SA_HOR_CENTER); } else if (this->ticker_scroll < TICKER_STOP && _statusbar_news_item != nullptr && _statusbar_news_item->string_id != 0) { /* Draw the scrolling news text */ if (!DrawScrollingStatusText(_statusbar_news_item, ScaleGUITrad(this->ticker_scroll), r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom)) { @@ -176,20 +176,20 @@ struct StatusBarWindow : Window { if (Company::IsValidID(_local_company)) { /* This is the default text */ SetDParam(0, _local_company); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER); } } } else { if (Company::IsValidID(_local_company)) { /* This is the default text */ SetDParam(0, _local_company); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER); } } if (!this->reminder_timeout.HasElapsed()) { Dimension icon_size = GetSpriteSize(SPR_UNREAD_NEWS); - DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, r.right - WD_FRAMERECT_RIGHT - icon_size.width, CenterBounds(r.top, r.bottom, icon_size.height)); + DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, tr.right - icon_size.width, CenterBounds(r.top, r.bottom, icon_size.height)); } break; } diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 255b084bec..e4b8b4a6d3 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -692,19 +692,17 @@ public: StoryPage *page = this->GetSelPage(); if (page == nullptr) return; - const int x = r.left + WD_FRAMETEXT_LEFT; - const int y = r.top + WD_FRAMETEXT_TOP; - const int right = r.right - WD_FRAMETEXT_RIGHT; - const int bottom = r.bottom - WD_FRAMETEXT_BOTTOM; + Rect fr = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); /* Set up a clipping region for the panel. */ DrawPixelInfo tmp_dpi; - if (!FillDrawPixelInfo(&tmp_dpi, x, y, right - x + 1, bottom - y + 1)) return; + if (!FillDrawPixelInfo(&tmp_dpi, fr.left, fr.top, fr.Width(), fr.Height())) return; DrawPixelInfo *old_dpi = _cur_dpi; _cur_dpi = &tmp_dpi; /* Draw content (now coordinates given to Draw** are local to the new clipping region). */ + fr = fr.Translate(-fr.left, -fr.top); int line_height = FONT_HEIGHT_NORMAL; const int scrollpos = this->vscroll->GetPosition(); int y_offset = -scrollpos; @@ -712,13 +710,13 @@ public: /* Date */ if (page->date != INVALID_DATE) { SetDParam(0, page->date); - DrawString(0, right - x, y_offset, STR_JUST_DATE_LONG, TC_BLACK); + DrawString(0, fr.right, y_offset, STR_JUST_DATE_LONG, TC_BLACK); } y_offset += line_height; /* Title */ SetDParamStr(0, page->title != nullptr ? page->title : this->selected_generic_title); - y_offset = DrawStringMultiLine(0, right - x, y_offset, bottom - y, STR_STORY_BOOK_TITLE, TC_BLACK, SA_TOP | SA_HOR_CENTER); + y_offset = DrawStringMultiLine(0, fr.right, y_offset, fr.bottom, STR_STORY_BOOK_TITLE, TC_BLACK, SA_TOP | SA_HOR_CENTER); /* Page elements */ this->EnsureStoryPageElementLayout(); diff --git a/src/subsidy_gui.cpp b/src/subsidy_gui.cpp index b46ca4da29..90d78e4bed 100644 --- a/src/subsidy_gui.cpp +++ b/src/subsidy_gui.cpp @@ -145,15 +145,13 @@ struct SubsidyListWindow : Window { YearMonthDay ymd; ConvertDateToYMD(_date, &ymd); - int right = r.right - WD_FRAMERECT_RIGHT; - int y = r.top + WD_FRAMERECT_TOP; - int x = r.left + WD_FRAMERECT_LEFT; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); int pos = -this->vscroll->GetPosition(); const int cap = this->vscroll->GetCapacity(); /* Section for drawing the offered subsidies */ - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_TITLE); + if (IsInsideMM(pos, 0, cap)) DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_TITLE); pos++; uint num = 0; @@ -163,7 +161,7 @@ struct SubsidyListWindow : Window { /* Displays the two offered towns */ SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::Gui); SetDParam(7, _date - ymd.day + s->remaining * 32); - DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_FROM_TO); + DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_FROM_TO); } pos++; num++; @@ -171,13 +169,13 @@ struct SubsidyListWindow : Window { } if (num == 0) { - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE); + if (IsInsideMM(pos, 0, cap)) DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE); pos++; } /* Section for drawing the already granted subsidies */ pos++; - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_TITLE); + if (IsInsideMM(pos, 0, cap)) DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_TITLE); pos++; num = 0; @@ -189,7 +187,7 @@ struct SubsidyListWindow : Window { SetDParam(8, _date - ymd.day + s->remaining * 32); /* Displays the two connected stations */ - DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_FROM_TO); + DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_FROM_TO); } pos++; num++; @@ -197,7 +195,7 @@ struct SubsidyListWindow : Window { } if (num == 0) { - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE); + if (IsInsideMM(pos, 0, cap)) DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE); pos++; } } diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index 2e8ff58515..cf632b7f4b 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -148,17 +148,15 @@ void TextfileWindow::SetupScrollbars(bool force_reflow) { if (widget != WID_TF_BACKGROUND) return; - const int x = r.left + WD_FRAMETEXT_LEFT; - const int y = r.top + WD_FRAMETEXT_TOP; - const int right = r.right - WD_FRAMETEXT_RIGHT; - const int bottom = r.bottom - WD_FRAMETEXT_BOTTOM; + Rect fr = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); DrawPixelInfo new_dpi; - if (!FillDrawPixelInfo(&new_dpi, x, y, right - x + 1, bottom - y + 1)) return; + if (!FillDrawPixelInfo(&new_dpi, fr.left, fr.top, fr.Width(), fr.Height())) return; DrawPixelInfo *old_dpi = _cur_dpi; _cur_dpi = &new_dpi; /* Draw content (now coordinates given to DrawString* are local to the new clipping region). */ + fr = fr.Translate(-fr.left, -fr.top); int line_height = FONT_HEIGHT_MONO; int pos = this->vscroll->GetPosition(); int cap = this->vscroll->GetCapacity(); @@ -169,9 +167,9 @@ void TextfileWindow::SetupScrollbars(bool force_reflow) int y_offset = (line.top - pos) * line_height; if (IsWidgetLowered(WID_TF_WRAPTEXT)) { - DrawStringMultiLine(0, right - x, y_offset, bottom - y, line.text, TC_WHITE, SA_TOP | SA_LEFT, false, FS_MONO); + DrawStringMultiLine(0, fr.right, y_offset, fr.bottom, line.text, TC_WHITE, SA_TOP | SA_LEFT, false, FS_MONO); } else { - DrawString(-this->hscroll->GetPosition(), right - x, y_offset, line.text, TC_WHITE, SA_TOP | SA_LEFT, false, FS_MONO); + DrawString(-this->hscroll->GetPosition(), fr.right, y_offset, line.text, TC_WHITE, SA_TOP | SA_LEFT, false, FS_MONO); } } diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 662919829f..4fbb47e640 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -356,7 +356,7 @@ struct TimetableWindow : Window { switch (widget) { case WID_VT_TIMETABLE_PANEL: { - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); int i = this->vscroll->GetPosition(); VehicleOrderID order_id = (i + 1) / 2; bool final_order = false; @@ -364,7 +364,7 @@ struct TimetableWindow : Window { bool rtl = _current_text_dir == TD_RTL; SetDParamMaxValue(0, v->GetNumOrders(), 2); int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + 3; - int middle = rtl ? r.right - WD_FRAMERECT_RIGHT - index_column_width : r.left + WD_FRAMERECT_LEFT + index_column_width; + int middle = rtl ? tr.right - index_column_width : tr.left + index_column_width; const Order *order = v->GetOrder(order_id); while (order != nullptr) { @@ -372,7 +372,7 @@ struct TimetableWindow : Window { if (!this->vscroll->IsVisible(i)) break; if (i % 2 == 0) { - DrawOrderString(v, order, order_id, y, i == selected, true, r.left + WD_FRAMERECT_LEFT, middle, r.right - WD_FRAMERECT_RIGHT); + DrawOrderString(v, order, order_id, tr.top, i == selected, true, tr.left, middle, tr.right); order_id++; @@ -408,13 +408,13 @@ struct TimetableWindow : Window { } SetDParam(2, order->GetMaxSpeed()); - DrawString(rtl ? r.left + WD_FRAMERECT_LEFT : middle, rtl ? middle : r.right - WD_FRAMERECT_LEFT, y, string, colour); + DrawString(rtl ? tr.left : middle, rtl ? middle : tr.right, tr.top, string, colour); if (final_order) break; } i++; - y += FONT_HEIGHT_NORMAL; + tr.top += FONT_HEIGHT_NORMAL; } break; } @@ -432,16 +432,13 @@ struct TimetableWindow : Window { VehicleOrderID earlyID = BuildArrivalDepartureList(v, arr_dep) ? cur_order : (VehicleOrderID)INVALID_VEH_ORDER_ID; - int y = r.top + WD_FRAMERECT_TOP; - + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); bool show_late = this->show_expected && v->lateness_counter > DAY_TICKS; Ticks offset = show_late ? 0 : -v->lateness_counter; bool rtl = _current_text_dir == TD_RTL; - int abbr_left = rtl ? r.right - WD_FRAMERECT_RIGHT - this->deparr_abbr_width : r.left + WD_FRAMERECT_LEFT; - int abbr_right = rtl ? r.right - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT + this->deparr_abbr_width; - int time_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.right - WD_FRAMERECT_RIGHT - this->deparr_time_width; - int time_right = rtl ? r.left + WD_FRAMERECT_LEFT + this->deparr_time_width : r.right - WD_FRAMERECT_RIGHT; + Rect abbr = tr.WithWidth(this->deparr_abbr_width, rtl); + Rect time = tr.WithWidth(this->deparr_time_width, !rtl); for (int i = this->vscroll->GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop /* Don't draw anything if it extends past the end of the window. */ @@ -449,54 +446,54 @@ struct TimetableWindow : Window { if (i % 2 == 0) { if (arr_dep[i / 2].arrival != INVALID_TICKS) { - DrawString(abbr_left, abbr_right, y, STR_TIMETABLE_ARRIVAL_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK); + DrawString(abbr.left, abbr.right, tr.top, STR_TIMETABLE_ARRIVAL_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK); if (this->show_expected && i / 2 == earlyID) { SetDParam(0, _date + arr_dep[i / 2].arrival / DAY_TICKS); - DrawString(time_left, time_right, y, STR_JUST_DATE_TINY, TC_GREEN); + DrawString(time.left, time.right, tr.top, STR_JUST_DATE_TINY, TC_GREEN); } else { SetDParam(0, _date + (arr_dep[i / 2].arrival + offset) / DAY_TICKS); - DrawString(time_left, time_right, y, STR_JUST_DATE_TINY, + DrawString(time.left, time.right, tr.top, STR_JUST_DATE_TINY, show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK); } } } else { if (arr_dep[i / 2].departure != INVALID_TICKS) { - DrawString(abbr_left, abbr_right, y, STR_TIMETABLE_DEPARTURE_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK); + DrawString(abbr.left, abbr.right, tr.top, STR_TIMETABLE_DEPARTURE_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK); SetDParam(0, _date + (arr_dep[i/2].departure + offset) / DAY_TICKS); - DrawString(time_left, time_right, y, STR_JUST_DATE_TINY, + DrawString(time.left, time.right, tr.top, STR_JUST_DATE_TINY, show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK); } } - y += FONT_HEIGHT_NORMAL; + tr.top += FONT_HEIGHT_NORMAL; } break; } case WID_VT_SUMMARY_PANEL: { - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0; if (total_time != 0) { SetTimetableParams(0, 1, total_time); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, v->orders->IsCompleteTimetable() ? STR_TIMETABLE_TOTAL_TIME : STR_TIMETABLE_TOTAL_TIME_INCOMPLETE); + DrawString(tr, v->orders->IsCompleteTimetable() ? STR_TIMETABLE_TOTAL_TIME : STR_TIMETABLE_TOTAL_TIME_INCOMPLETE); } - y += FONT_HEIGHT_NORMAL; + tr.top += FONT_HEIGHT_NORMAL; if (v->timetable_start != 0) { /* We are running towards the first station so we can start the * timetable at the given time. */ SetDParam(0, STR_JUST_DATE_TINY); SetDParam(1, v->timetable_start); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_TIMETABLE_STATUS_START_AT); + DrawString(tr, STR_TIMETABLE_STATUS_START_AT); } else if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) { /* We aren't running on a timetable yet, so how can we be "on time" * when we aren't even "on service"/"on duty"? */ - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_TIMETABLE_STATUS_NOT_STARTED); + DrawString(tr, STR_TIMETABLE_STATUS_NOT_STARTED); } else if (v->lateness_counter == 0 || (!_settings_client.gui.timetable_in_ticks && v->lateness_counter / DAY_TICKS == 0)) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_TIMETABLE_STATUS_ON_TIME); + DrawString(tr, STR_TIMETABLE_STATUS_ON_TIME); } else { SetTimetableParams(0, 1, abs(v->lateness_counter)); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, v->lateness_counter < 0 ? STR_TIMETABLE_STATUS_EARLY : STR_TIMETABLE_STATUS_LATE); + DrawString(tr, v->lateness_counter < 0 ? STR_TIMETABLE_STATUS_EARLY : STR_TIMETABLE_STATUS_LATE); } break; } diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 07376a3f56..ea5bbb38b9 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -106,10 +106,11 @@ public: void Draw(const Rect &r, bool sel, Colours bg_colour) const override { bool rtl = _current_text_dir == TD_RTL; + Rect tr = r.Shrink(WD_DROPDOWNTEXT_LEFT, 0, WD_DROPDOWNTEXT_RIGHT, 0); if (this->checked) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK); + DrawString(tr, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK); } - DrawString(r.left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), r.right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), r.top, this->String(), sel ? TC_WHITE : TC_BLACK); + DrawString(tr.Indent(this->checkmark_width, rtl), this->String(), sel ? TC_WHITE : TC_BLACK); } }; @@ -138,12 +139,12 @@ public: CompanyID company = (CompanyID)this->result; SetDParam(0, company); SetDParam(1, company); - return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + this->lock_size.width + 6; + return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + this->lock_size.width + WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT + 6; } uint Height(uint width) const override { - return std::max(std::max(this->icon_size.height, this->lock_size.height) + 2U, (uint)FONT_HEIGHT_NORMAL); + return std::max(std::max(this->icon_size.height, this->lock_size.height) + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM, (uint)FONT_HEIGHT_NORMAL); } void Draw(const Rect &r, bool sel, Colours bg_colour) const override @@ -154,13 +155,14 @@ public: /* It's possible the company is deleted while the dropdown is open */ if (!Company::IsValidID(company)) return; + Rect tr = r.Shrink(WD_DROPDOWNTEXT_LEFT, 0, WD_DROPDOWNTEXT_RIGHT, 0); int icon_y = CenterBounds(r.top, r.bottom, icon_size.height); int text_y = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL); int lock_y = CenterBounds(r.top, r.bottom, lock_size.height); - DrawCompanyIcon(company, rtl ? r.right - this->icon_size.width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT, icon_y); + DrawCompanyIcon(company, tr.WithWidth(this->icon_size.width, rtl).left, icon_y); if (NetworkCompanyIsPassworded(company)) { - DrawSprite(SPR_LOCK, PAL_NONE, rtl ? r.left + WD_FRAMERECT_LEFT : r.right - this->lock_size.width - WD_FRAMERECT_RIGHT, lock_y); + DrawSprite(SPR_LOCK, PAL_NONE, tr.WithWidth(this->lock_size.width, !rtl).left, lock_y); } SetDParam(0, company); @@ -171,7 +173,8 @@ public: } else { col = sel ? TC_WHITE : TC_BLACK; } - DrawString(r.left + WD_FRAMERECT_LEFT + (rtl ? 3 + this->lock_size.width : 3 + this->icon_size.width), r.right - WD_FRAMERECT_RIGHT - (rtl ? 3 + this->icon_size.width : 3 + this->lock_size.width), text_y, STR_COMPANY_NAME_COMPANY_NUM, col); + tr = tr.Indent(this->icon_size.width + 3, rtl).Indent(this->lock_size.width + 3, !rtl); + DrawString(tr.left, tr.right, text_y, STR_COMPANY_NAME_COMPANY_NUM, col); } }; @@ -2355,10 +2358,10 @@ struct ScenarioEditorToolbarWindow : Window { { switch (widget) { case WID_TE_SPACER: { - int height = r.bottom - r.top; + int height = r.Height(); if (height > 2 * FONT_HEIGHT_NORMAL) { - DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_HOR_CENTER); - DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(r.left, r.right, height / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(r.left, r.right, height / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER); } else { DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER); } diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 95a08a8e13..690082fc22 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -137,14 +137,10 @@ public: /** Draw the contents of the ratings panel. May request a resize of the window if the contents does not fit. */ void DrawRatings() { - NWidgetBase *nwid = this->GetWidget(WID_TA_RATING_INFO); - uint left = nwid->pos_x + WD_FRAMERECT_LEFT; - uint right = nwid->pos_x + nwid->current_x - 1 - WD_FRAMERECT_RIGHT; + Rect r = this->GetWidget(WID_TA_RATING_INFO)->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); - uint y = nwid->pos_y + WD_FRAMERECT_TOP; - - DrawString(left, right, y, STR_LOCAL_AUTHORITY_COMPANY_RATINGS); - y += FONT_HEIGHT_NORMAL; + DrawString(r, STR_LOCAL_AUTHORITY_COMPANY_RATINGS); + r.top += FONT_HEIGHT_NORMAL; Dimension icon_size = GetSpriteSize(SPR_COMPANY_ICON); int icon_width = icon_size.width; @@ -155,56 +151,52 @@ public: int exclusive_y_offset = (FONT_HEIGHT_NORMAL - exclusive_size.height) / 2; bool rtl = _current_text_dir == TD_RTL; - uint text_left = left + (rtl ? 0 : icon_width + exclusive_width + 4); - uint text_right = right - (rtl ? icon_width + exclusive_width + 4 : 0); - uint icon_left = rtl ? right - icon_width : left; - uint exclusive_left = rtl ? right - icon_width - exclusive_width - 2 : left + icon_width + 2; + Rect text = r.Indent(icon_width + exclusive_width + 4, rtl); + uint icon_left = r.WithWidth(icon_width, rtl).left; + uint exclusive_left = r.Indent(icon_width + 2, rtl).WithWidth(exclusive_width, rtl).left; /* Draw list of companies */ for (const Company *c : Company::Iterate()) { if ((HasBit(this->town->have_ratings, c->index) || this->town->exclusivity == c->index)) { - DrawCompanyIcon(c->index, icon_left, y + icon_y_offset); + DrawCompanyIcon(c->index, icon_left, text.top + icon_y_offset); SetDParam(0, c->index); SetDParam(1, c->index); - int r = this->town->ratings[c->index]; + int rating = this->town->ratings[c->index]; StringID str = STR_CARGO_RATING_APPALLING; - if (r > RATING_APPALLING) str++; - if (r > RATING_VERYPOOR) str++; - if (r > RATING_POOR) str++; - if (r > RATING_MEDIOCRE) str++; - if (r > RATING_GOOD) str++; - if (r > RATING_VERYGOOD) str++; - if (r > RATING_EXCELLENT) str++; + if (rating > RATING_APPALLING) str++; + if (rating > RATING_VERYPOOR) str++; + if (rating > RATING_POOR) str++; + if (rating > RATING_MEDIOCRE) str++; + if (rating > RATING_GOOD) str++; + if (rating > RATING_VERYGOOD) str++; + if (rating > RATING_EXCELLENT) str++; SetDParam(2, str); if (this->town->exclusivity == c->index) { - DrawSprite(SPR_EXCLUSIVE_TRANSPORT, COMPANY_SPRITE_COLOUR(c->index), exclusive_left, y + exclusive_y_offset); + DrawSprite(SPR_EXCLUSIVE_TRANSPORT, COMPANY_SPRITE_COLOUR(c->index), exclusive_left, r.top + exclusive_y_offset); } - DrawString(text_left, text_right, y, STR_LOCAL_AUTHORITY_COMPANY_RATING); - y += FONT_HEIGHT_NORMAL; + DrawString(text, STR_LOCAL_AUTHORITY_COMPANY_RATING); + text.top += FONT_HEIGHT_NORMAL; } } - y = y + WD_FRAMERECT_BOTTOM - nwid->pos_y; // Compute needed size of the widget. - if (y > nwid->current_y) { + text.bottom = text.top - 1; + if (text.bottom > r.bottom) { /* If the company list is too big to fit, mark ourself dirty and draw again. */ - ResizeWindow(this, 0, y - nwid->current_y, false); + ResizeWindow(this, 0, text.bottom - r.bottom, false); } } /** Draws the contents of the actions panel. May re-initialise window to resize panel, if the list does not fit. */ void DrawActions() { - NWidgetBase *nwid = this->GetWidget(WID_TA_COMMAND_LIST); - uint left = nwid->pos_x + WD_FRAMERECT_LEFT; - uint right = nwid->pos_x + nwid->current_x - 1 - WD_FRAMERECT_RIGHT; - uint y = nwid->pos_y + WD_FRAMERECT_TOP; + Rect r = this->GetWidget(WID_TA_COMMAND_LIST)->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_LOCAL_AUTHORITY_ACTIONS_TITLE); - y += FONT_HEIGHT_NORMAL; + DrawString(r, STR_LOCAL_AUTHORITY_ACTIONS_TITLE); + r.top += FONT_HEIGHT_NORMAL; /* Draw list of actions */ for (int i = 0; i < TACT_COUNT; i++) { @@ -216,8 +208,8 @@ public: if (HasBit(this->available_actions, i)) action_colour = TC_ORANGE; if (this->sel_index == i) action_colour = TC_WHITE; - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i, action_colour); - y += FONT_HEIGHT_NORMAL; + DrawString(r, STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i, action_colour); + r.top += FONT_HEIGHT_NORMAL; } } @@ -235,7 +227,7 @@ public: bool affordable = action_cost < Company::GetIfValid(_local_company)->money; SetDParam(0, action_cost); - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, + DrawStringMultiLine(r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM), STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING + this->sel_index, affordable ? TC_YELLOW : TC_RED); } @@ -389,21 +381,24 @@ public: { if (widget != WID_TV_INFO) return; - uint y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); SetDParam(0, this->town->cache.population); SetDParam(1, this->town->cache.num_houses); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y, STR_TOWN_VIEW_POPULATION_HOUSES); + DrawString(tr, STR_TOWN_VIEW_POPULATION_HOUSES); + tr.top += FONT_HEIGHT_NORMAL; SetDParam(0, 1 << CT_PASSENGERS); SetDParam(1, this->town->supplied[CT_PASSENGERS].old_act); SetDParam(2, this->town->supplied[CT_PASSENGERS].old_max); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX); + DrawString(tr, STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX); + tr.top += FONT_HEIGHT_NORMAL; SetDParam(0, 1 << CT_MAIL); SetDParam(1, this->town->supplied[CT_MAIL].old_act); SetDParam(2, this->town->supplied[CT_MAIL].old_max); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX); + DrawString(tr, STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX); + tr.top += FONT_HEIGHT_NORMAL; bool first = true; for (int i = TE_BEGIN; i < TE_END; i++) { @@ -412,13 +407,12 @@ public: if (this->town->goal[i] == TOWN_GROWTH_DESERT && (GetTropicZone(this->town->xy) != TROPICZONE_DESERT || this->town->cache.population <= 60)) continue; if (first) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH); + DrawString(tr, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH); + tr.top += FONT_HEIGHT_NORMAL; first = false; } bool rtl = _current_text_dir == TD_RTL; - uint cargo_text_left = r.left + WD_FRAMERECT_LEFT + (rtl ? 0 : 20); - uint cargo_text_right = r.right - WD_FRAMERECT_RIGHT - (rtl ? 20 : 0); const CargoSpec *cargo = FindFirstCargoWithTownEffect((TownEffect)i); assert(cargo != nullptr); @@ -448,26 +442,30 @@ public: SetDParam(2, cargo->Index()); SetDParam(3, this->town->goal[i]); } - DrawString(cargo_text_left, cargo_text_right, y += FONT_HEIGHT_NORMAL, string); + DrawString(tr.Indent(20, rtl), string); + tr.top += FONT_HEIGHT_NORMAL; } if (HasBit(this->town->flags, TOWN_IS_GROWING)) { SetDParam(0, RoundDivSU(this->town->growth_rate + 1, DAY_TICKS)); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED); + DrawString(tr, this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED); + tr.top += FONT_HEIGHT_NORMAL; } else { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_TOWN_GROW_STOPPED); + DrawString(tr, STR_TOWN_VIEW_TOWN_GROW_STOPPED); + tr.top += FONT_HEIGHT_NORMAL; } /* only show the town noise, if the noise option is activated. */ if (_settings_game.economy.station_noise_level) { SetDParam(0, this->town->noise_reached); SetDParam(1, this->town->MaxTownNoise()); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_NOISE_IN_TOWN); + DrawString(tr, STR_TOWN_VIEW_NOISE_IN_TOWN); + tr.top += FONT_HEIGHT_NORMAL; } if (!this->town->text.empty()) { SetDParamStr(0, this->town->text); - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y += FONT_HEIGHT_NORMAL, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); + tr.top = DrawStringMultiLine(tr, STR_JUST_RAW_STRING, TC_BLACK); } } @@ -821,18 +819,17 @@ public: case WID_TD_LIST: { int n = 0; - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); if (this->towns.size() == 0) { // No towns available. - DrawString(r.left + WD_FRAMERECT_LEFT, r.right, y, STR_TOWN_DIRECTORY_NONE); + DrawString(tr, STR_TOWN_DIRECTORY_NONE); break; } /* At least one town available. */ bool rtl = _current_text_dir == TD_RTL; Dimension icon_size = GetSpriteSize(SPR_TOWN_RATING_GOOD); - int text_left = r.left + WD_FRAMERECT_LEFT + (rtl ? 0 : icon_size.width + 2); - int text_right = r.right - WD_FRAMERECT_RIGHT - (rtl ? icon_size.width + 2 : 0); - int icon_x = rtl ? r.right - WD_FRAMERECT_RIGHT - icon_size.width : r.left + WD_FRAMERECT_LEFT; + int icon_x = tr.WithWidth(icon_size.width, rtl).left; + tr = tr.Indent(icon_size.width + 2, rtl); for (uint i = this->vscroll->GetPosition(); i < this->towns.size(); i++) { const Town *t = this->towns[i]; @@ -840,19 +837,19 @@ public: /* Draw rating icon. */ if (_game_mode == GM_EDITOR || !HasBit(t->have_ratings, _local_company)) { - DrawSprite(SPR_TOWN_RATING_NA, PAL_NONE, icon_x, y + (this->resize.step_height - icon_size.height) / 2); + DrawSprite(SPR_TOWN_RATING_NA, PAL_NONE, icon_x, tr.top + (this->resize.step_height - icon_size.height) / 2); } else { SpriteID icon = SPR_TOWN_RATING_APALLING; if (t->ratings[_local_company] > RATING_VERYPOOR) icon = SPR_TOWN_RATING_MEDIOCRE; if (t->ratings[_local_company] > RATING_GOOD) icon = SPR_TOWN_RATING_GOOD; - DrawSprite(icon, PAL_NONE, icon_x, y + (this->resize.step_height - icon_size.height) / 2); + DrawSprite(icon, PAL_NONE, icon_x, tr.top + (this->resize.step_height - icon_size.height) / 2); } SetDParam(0, t->index); SetDParam(1, t->cache.population); - DrawString(text_left, text_right, y + (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2, GetTownString(t)); + DrawString(tr.left, tr.right, tr.top + (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2, GetTownString(t)); - y += this->resize.step_height; + tr.top += this->resize.step_height; if (++n == this->vscroll->GetCapacity()) break; // max number of towns in 1 window } break; diff --git a/src/transparency_gui.cpp b/src/transparency_gui.cpp index 153dcb5d03..ece2e31bbc 100644 --- a/src/transparency_gui.cpp +++ b/src/transparency_gui.cpp @@ -52,18 +52,20 @@ public: case WID_TT_CATENARY: case WID_TT_LOADING: { uint i = widget - WID_TT_BEGIN; - if (HasBit(_transparency_lock, i)) DrawSprite(SPR_LOCK, PAL_NONE, r.left + 1, r.top + 1); + if (HasBit(_transparency_lock, i)) DrawSprite(SPR_LOCK, PAL_NONE, r.left + WD_BEVEL_LEFT, r.top + WD_BEVEL_TOP); break; } - case WID_TT_BUTTONS: + case WID_TT_BUTTONS: { + const Rect fr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); for (uint i = WID_TT_BEGIN; i < WID_TT_END; i++) { if (i == WID_TT_LOADING) continue; // Do not draw button for invisible loading indicators. - const NWidgetBase *wi = this->GetWidget(i); - DrawFrameRect(wi->pos_x + 1, r.top + 2, wi->pos_x + wi->current_x - 2, r.bottom - 2, COLOUR_PALE_GREEN, + const Rect wr = this->GetWidget(i)->GetCurrentRect().Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); + DrawFrameRect(wr.left, fr.top, wr.right, fr.bottom, COLOUR_PALE_GREEN, HasBit(_invisibility_opt, i - WID_TT_BEGIN) ? FR_LOWERED : FR_NONE); } break; + } } } diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index cb1a760502..81c2d4e43a 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -169,7 +169,7 @@ public: if (widget >= WID_BT_TYPE_BUTTON_FIRST) { const int index = widget - WID_BT_TYPE_BUTTON_FIRST; /* Trees "grow" in the centre on the bottom line of the buttons */ - DrawSprite(tree_sprites[index].sprite, tree_sprites[index].pal, CenterBounds(r.left, r.right, 0) + WD_FRAMERECT_LEFT, r.bottom - ScaleGUITrad(BUTTON_BOTTOM_OFFSET)); + DrawSprite(tree_sprites[index].sprite, tree_sprites[index].pal, CenterBounds(r.left, r.right, 0), r.bottom - ScaleGUITrad(BUTTON_BOTTOM_OFFSET)); } } diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index d0bb7910e9..a6138802fb 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -539,7 +539,7 @@ typedef std::vector SubtypeList; ///< List of refit subtypes associ */ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int sel[2], uint pos, uint rows, uint delta, const Rect &r) { - uint y = r.top + WD_MATRIX_TOP; + Rect ir = r.Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_LEFT); uint current = 0; bool rtl = _current_text_dir == TD_RTL; @@ -547,12 +547,11 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int uint iconheight = GetSpriteSize(SPR_CIRCLE_FOLDED).height; int linecolour = _colour_gradient[COLOUR_ORANGE][4]; - int iconleft = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth : r.left + WD_MATRIX_LEFT; - int iconcenter = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth / 2 : r.left + WD_MATRIX_LEFT + iconwidth / 2; - int iconinner = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth : r.left + WD_MATRIX_LEFT + iconwidth; + int iconleft = rtl ? ir.right - iconwidth : ir.left; + int iconcenter = rtl ? ir.right - iconwidth / 2 : ir.left + iconwidth / 2; + int iconinner = rtl ? ir.right - iconwidth : ir.left + iconwidth; - int textleft = r.left + WD_MATRIX_LEFT + (rtl ? 0 : iconwidth + 4); - int textright = r.right - WD_MATRIX_RIGHT - (rtl ? iconwidth + 4 : 0); + Rect tr = ir.Indent(iconwidth + 4, rtl); /* Draw the list of subtypes for each cargo, and find the selected refit option (by its position). */ for (uint i = 0; current < pos + rows && i < NUM_CARGO; i++) { @@ -571,12 +570,12 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int if (list[i].size() > 1) { if (refit.subtype != 0xFF) { /* Draw tree lines */ - int ycenter = y + FONT_HEIGHT_NORMAL / 2; - GfxDrawLine(iconcenter, y - WD_MATRIX_TOP, iconcenter, j == list[i].size() - 1 ? ycenter : y - WD_MATRIX_TOP + delta - 1, linecolour); + int ycenter = tr.top + FONT_HEIGHT_NORMAL / 2; + GfxDrawLine(iconcenter, tr.top - WD_MATRIX_TOP, iconcenter, j == list[i].size() - 1 ? ycenter : tr.top - WD_MATRIX_TOP + delta - 1, linecolour); GfxDrawLine(iconcenter, ycenter, iconinner, ycenter, linecolour); } else { /* Draw expand/collapse icon */ - DrawSprite(sel[0] == (int)i ? SPR_CIRCLE_UNFOLDED : SPR_CIRCLE_FOLDED, PAL_NONE, iconleft, y + (FONT_HEIGHT_NORMAL - iconheight) / 2); + DrawSprite(sel[0] == (int)i ? SPR_CIRCLE_UNFOLDED : SPR_CIRCLE_FOLDED, PAL_NONE, iconleft, tr.top + (FONT_HEIGHT_NORMAL - iconheight) / 2); } } @@ -584,9 +583,9 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int /* Get the cargo name. */ SetDParam(0, CargoSpec::Get(refit.cargo)->name); SetDParam(1, refit.string); - DrawString(textleft, textright, y, STR_JUST_STRING_STRING, colour); + DrawString(tr, STR_JUST_STRING_STRING, colour); - y += delta; + tr.top += delta; current++; } } @@ -999,8 +998,7 @@ struct RefitWindow : public Window { if (this->cargo != nullptr) { StringID string = this->GetCapacityString(this->cargo); if (string != INVALID_STRING_ID) { - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, - r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, string); + DrawStringMultiLine(r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM), string); } } break; @@ -1637,25 +1635,22 @@ uint GetVehicleListHeight(VehicleType type, uint divisor) */ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int line_height, const Rect &r) const { - int left = r.left + WD_MATRIX_LEFT; - int right = r.right - WD_MATRIX_RIGHT; - int width = right - left; + Rect ir = r.WithHeight(line_height).Shrink(WD_MATRIX_LEFT, 0, WD_MATRIX_RIGHT, 0); bool rtl = _current_text_dir == TD_RTL; - int text_offset = std::max(GetSpriteSize(SPR_PROFIT_LOT).width, GetDigitWidth() * this->unitnumber_digits) + WD_FRAMERECT_RIGHT; - int text_left = left + (rtl ? 0 : text_offset); - int text_right = right - (rtl ? text_offset : 0); + Dimension profit = GetSpriteSize(SPR_PROFIT_LOT); + int text_offset = std::max(profit.width, GetDigitWidth() * this->unitnumber_digits) + WD_FRAMERECT_RIGHT; + Rect tr = ir.Indent(text_offset, rtl); bool show_orderlist = this->vli.vtype >= VEH_SHIP; - int orderlist_left = left + (rtl ? 0 : std::max(ScaleGUITrad(100) + text_offset, width / 2)); - int orderlist_right = right - (rtl ? std::max(ScaleGUITrad(100) + text_offset, width / 2) : 0); + Rect olr = ir.Indent(std::max(ScaleGUITrad(100) + text_offset, ir.Width() / 2), rtl); - int image_left = (rtl && show_orderlist) ? orderlist_right : text_left; - int image_right = (!rtl && show_orderlist) ? orderlist_left : text_right; + int image_left = (rtl && show_orderlist) ? olr.right : tr.left; + int image_right = (!rtl && show_orderlist) ? olr.left : tr.right; + int image_height = ScaleGUITrad(GetVehicleHeight(this->vli.vtype)); - int vehicle_button_x = rtl ? right - GetSpriteSize(SPR_PROFIT_LOT).width : left; + int vehicle_button_x = rtl ? ir.right - profit.width : ir.left; - int y = r.top; uint max = static_cast(std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size())); for (uint i = this->vscroll->GetPosition(); i < max; ++i) { @@ -1663,31 +1658,31 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int SetDParam(0, vehgroup.GetDisplayProfitThisYear()); SetDParam(1, vehgroup.GetDisplayProfitLastYear()); - DrawString(text_left, text_right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1, STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR); + DrawString(tr.left, tr.right, ir.bottom - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM, STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR); - DrawVehicleProfitButton(vehgroup.GetOldestVehicleAge(), vehgroup.GetDisplayProfitLastYear(), vehgroup.NumVehicles(), vehicle_button_x, y + FONT_HEIGHT_NORMAL + 3); + DrawVehicleProfitButton(vehgroup.GetOldestVehicleAge(), vehgroup.GetDisplayProfitLastYear(), vehgroup.NumVehicles(), vehicle_button_x, ir.top + FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL); switch (this->grouping) { case GB_NONE: { const Vehicle *v = vehgroup.GetSingleVehicle(); if (HasBit(v->vehicle_flags, VF_PATHFINDER_LOST)) { - DrawSprite(SPR_WARNING_SIGN, PAL_NONE, vehicle_button_x, y + FONT_HEIGHT_NORMAL + 3 + GetSpriteSize(SPR_PROFIT_LOT).height); + DrawSprite(SPR_WARNING_SIGN, PAL_NONE, vehicle_button_x, ir.top + FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL + profit.height); } - DrawVehicleImage(v, image_left, image_right, y + FONT_HEIGHT_SMALL - 1, selected_vehicle, EIT_IN_LIST, 0); + DrawVehicleImage(v, image_left, image_right, CenterBounds(ir.top, ir.bottom, image_height), selected_vehicle, EIT_IN_LIST, 0); if (!v->name.empty()) { /* The vehicle got a name so we will print it */ SetDParam(0, v->index); - DrawString(text_left, text_right, y, STR_TINY_BLACK_VEHICLE); + DrawString(tr.left, tr.right, ir.top, STR_TINY_BLACK_VEHICLE); } else if (v->group_id != DEFAULT_GROUP) { /* The vehicle has no name, but is member of a group, so print group name */ SetDParam(0, v->group_id); - DrawString(text_left, text_right, y, STR_TINY_GROUP, TC_BLACK); + DrawString(tr.left, tr.right, ir.top, STR_TINY_GROUP, TC_BLACK); } - if (show_orderlist) DrawSmallOrderList(v, orderlist_left, orderlist_right, y, this->order_arrow_width, v->cur_real_order_index); + if (show_orderlist) DrawSmallOrderList(v, olr.left, olr.right, ir.top, this->order_arrow_width, v->cur_real_order_index); StringID str; if (v->IsChainInDepot()) { @@ -1697,7 +1692,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int } SetDParam(0, v->unitnumber); - DrawString(left, right, y + 2, str); + DrawString(ir.left, ir.right, ir.top + WD_FRAMERECT_TOP, str); break; } @@ -1706,20 +1701,20 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int for (int i = 0; i < static_cast(vehgroup.NumVehicles()); ++i) { if (image_left + 8 * i >= image_right) break; // Break if there is no more space to draw any more vehicles anyway. - DrawVehicleImage(vehgroup.vehicles_begin[i], image_left + 8 * i, image_right, y + FONT_HEIGHT_SMALL - 1, selected_vehicle, EIT_IN_LIST, 0); + DrawVehicleImage(vehgroup.vehicles_begin[i], image_left + 8 * i, image_right, CenterBounds(ir.top, ir.bottom, image_height), selected_vehicle, EIT_IN_LIST, 0); } - if (show_orderlist) DrawSmallOrderList((vehgroup.vehicles_begin[0])->GetFirstOrder(), orderlist_left, orderlist_right, y, this->order_arrow_width); + if (show_orderlist) DrawSmallOrderList((vehgroup.vehicles_begin[0])->GetFirstOrder(), olr.left, olr.right, ir.top, this->order_arrow_width); SetDParam(0, vehgroup.NumVehicles()); - DrawString(left, right, y + 2, STR_BLACK_COMMA); + DrawString(ir.left, ir.right, ir.top + WD_FRAMERECT_TOP, STR_BLACK_COMMA); break; default: NOT_REACHED(); } - y += line_height; + ir = ir.Translate(0, line_height); } } @@ -2434,15 +2429,15 @@ struct VehicleDetailsWindow : Window { switch (widget) { case WID_VD_TOP_DETAILS: { - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); /* Draw running cost */ SetDParam(1, v->age / DAYS_IN_LEAP_YEAR); SetDParam(0, (v->age + DAYS_IN_YEAR < v->max_age) ? STR_VEHICLE_INFO_AGE : STR_VEHICLE_INFO_AGE_RED); SetDParam(2, v->max_age / DAYS_IN_LEAP_YEAR); SetDParam(3, v->GetDisplayRunningCost()); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_AGE_RUNNING_COST_YR); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_VEHICLE_INFO_AGE_RUNNING_COST_YR); + tr.top += FONT_HEIGHT_NORMAL; /* Draw max speed */ StringID string; @@ -2473,24 +2468,24 @@ struct VehicleDetailsWindow : Window { string = STR_VEHICLE_INFO_MAX_SPEED; } } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, string); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, string); + tr.top += FONT_HEIGHT_NORMAL; /* Draw profit */ SetDParam(0, v->GetDisplayProfitThisYear()); SetDParam(1, v->GetDisplayProfitLastYear()); if (v->IsGroundVehicle()) { SetDParam(2, v->GetDisplayMinPowerToWeight()); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE); + DrawString(tr, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE); } else { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); + DrawString(tr, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); } - y += FONT_HEIGHT_NORMAL; + tr.top += FONT_HEIGHT_NORMAL; /* Draw breakdown & reliability */ SetDParam(0, ToPercent16(v->reliability)); SetDParam(1, v->breakdowns_since_last_service); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS); + DrawString(tr, STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS); break; } @@ -3032,16 +3027,13 @@ public: /* Draw the flag plus orders. */ bool rtl = (_current_text_dir == TD_RTL); - uint text_offset = std::max({GetSpriteSize(SPR_WARNING_SIGN).width, GetSpriteSize(SPR_FLAG_VEH_STOPPED).width, GetSpriteSize(SPR_FLAG_VEH_RUNNING).width}) + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; - int text_left = r.left + (rtl ? (uint)WD_FRAMERECT_LEFT : text_offset); - int text_right = r.right - (rtl ? text_offset : (uint)WD_FRAMERECT_RIGHT); - int text_top = CenterBounds(r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, FONT_HEIGHT_NORMAL); - int image = ((v->vehstatus & VS_STOPPED) != 0) ? SPR_FLAG_VEH_STOPPED : (HasBit(v->vehicle_flags, VF_PATHFINDER_LOST)) ? SPR_WARNING_SIGN : SPR_FLAG_VEH_RUNNING; - int image_left = (rtl ? text_right + 1 : r.left) + WD_IMGBTN_LEFT; - int image_top = CenterBounds(r.top + WD_IMGBTN_TOP, r.bottom - WD_IMGBTN_BOTTOM, GetSpriteSize(image).height); - int lowered = this->IsWidgetLowered(WID_VV_START_STOP) ? 1 : 0; - DrawSprite(image, PAL_NONE, image_left + lowered, image_top + lowered); - DrawString(text_left + lowered, text_right + lowered, text_top + lowered, str, text_colour, SA_HOR_CENTER); + uint icon_width = std::max({GetSpriteSize(SPR_WARNING_SIGN).width, GetSpriteSize(SPR_FLAG_VEH_STOPPED).width, GetSpriteSize(SPR_FLAG_VEH_RUNNING).width}); + int lowered = this->IsWidgetLowered(widget) ? 1 : 0; + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM).Translate(lowered, lowered); + SpriteID image = ((v->vehstatus & VS_STOPPED) != 0) ? SPR_FLAG_VEH_STOPPED : (HasBit(v->vehicle_flags, VF_PATHFINDER_LOST)) ? SPR_WARNING_SIGN : SPR_FLAG_VEH_RUNNING; + DrawSprite(image, PAL_NONE, tr.WithWidth(icon_width, rtl).left, CenterBounds(tr.top, tr.bottom, GetSpriteSize(image).height)); + tr = tr.Indent(icon_width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT, rtl); + DrawString(tr.left, tr.right, CenterBounds(tr.top, tr.bottom, FONT_HEIGHT_NORMAL), str, text_colour, SA_HOR_CENTER); } void OnClick(Point pt, int widget, int click_count) override diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index 3e0365a0bf..d65f8cd6f8 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -88,8 +88,10 @@ uint DropDownListIconItem::Width() const void DropDownListIconItem::Draw(const Rect &r, bool sel, Colours bg_colour) const { bool rtl = _current_text_dir == TD_RTL; - DrawSprite(this->sprite, this->pal, rtl ? r.right - this->dim.width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT, CenterBounds(r.top, r.bottom, this->sprite_y)); - DrawString(r.left + WD_FRAMERECT_LEFT + (rtl ? 0 : (this->dim.width + WD_FRAMERECT_LEFT)), r.right - WD_FRAMERECT_RIGHT - (rtl ? (this->dim.width + WD_FRAMERECT_RIGHT) : 0), CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), this->String(), sel ? TC_WHITE : TC_BLACK); + Rect ir = r.Shrink(WD_DROPDOWNTEXT_LEFT, WD_DROPDOWNTEXT_TOP, WD_DROPDOWNTEXT_RIGHT, WD_DROPDOWNTEXT_LEFT); + Rect tr = ir.Indent(this->dim.width + WD_FRAMERECT_LEFT, rtl); + DrawSprite(this->sprite, this->pal, ir.WithWidth(this->dim.width, rtl).left, CenterBounds(r.top, r.bottom, this->sprite_y)); + DrawString(tr.left, tr.right, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), this->String(), sel ? TC_WHITE : TC_BLACK); } void DropDownListIconItem::SetDimension(Dimension d) From fea7247072a6b3adb99ccb6170d4e25765e4304b Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 17 Oct 2022 19:23:11 +0100 Subject: [PATCH 02/26] Change: Use standard 'frametext' padding for settings window. --- src/newgrf_debug_gui.cpp | 13 ++++------- src/settings_gui.cpp | 48 +++++++++++++++------------------------- 2 files changed, 22 insertions(+), 39 deletions(-) diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index 6e842de9e1..da6ab7ba5f 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -273,11 +273,6 @@ static inline const NIHelper *GetFeatureHelper(uint window_number) /** Window used for inspecting NewGRFs. */ struct NewGRFInspectWindow : Window { - static const int LEFT_OFFSET = 5; ///< Position of left edge - static const int RIGHT_OFFSET = 5; ///< Position of right edge - static const int TOP_OFFSET = 5; ///< Position of top edge - static const int BOTTOM_OFFSET = 5; ///< Position of bottom edge - /** The value for the variable 60 parameters. */ static uint32 var60params[GSF_FAKE_END][0x20]; @@ -384,7 +379,7 @@ struct NewGRFInspectWindow : Window { resize->height = std::max(11, FONT_HEIGHT_NORMAL + 1); resize->width = 1; - size->height = 5 * resize->height + TOP_OFFSET + BOTTOM_OFFSET; + size->height = 5 * resize->height + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM; break; } } @@ -407,7 +402,7 @@ struct NewGRFInspectWindow : Window { offset -= this->vscroll->GetPosition(); if (offset < 0 || offset >= this->vscroll->GetCapacity()) return; - ::DrawString(r.left + LEFT_OFFSET, r.right - RIGHT_OFFSET, r.top + TOP_OFFSET + (offset * this->resize.step_height), buf, TC_BLACK); + ::DrawString(r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP + (offset * this->resize.step_height), WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM), buf, TC_BLACK); } void DrawWidget(const Rect &r, int widget) const override @@ -585,7 +580,7 @@ struct NewGRFInspectWindow : Window { if (nif->variables == nullptr) return; /* Get the line, make sure it's within the boundaries. */ - int line = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NGRFI_MAINPANEL, TOP_OFFSET); + int line = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NGRFI_MAINPANEL, WD_FRAMETEXT_TOP); if (line == INT_MAX) return; /* Find the variable related to the line */ @@ -611,7 +606,7 @@ struct NewGRFInspectWindow : Window { void OnResize() override { - this->vscroll->SetCapacityFromWidget(this, WID_NGRFI_MAINPANEL, TOP_OFFSET + BOTTOM_OFFSET); + this->vscroll->SetCapacityFromWidget(this, WID_NGRFI_MAINPANEL, WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM); } /** diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 3d09739476..035999e580 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1907,11 +1907,6 @@ static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed) /** Window to edit settings of the game. */ struct GameSettingsWindow : Window { - static const int SETTINGTREE_LEFT_OFFSET = 5; ///< Position of left edge of setting values - static const int SETTINGTREE_RIGHT_OFFSET = 5; ///< Position of right edge of setting values - static const int SETTINGTREE_TOP_OFFSET = 5; ///< Position of top edge of setting values - static const int SETTINGTREE_BOTTOM_OFFSET = 5; ///< Position of bottom edge of setting values - static GameSettings *settings_ptr; ///< Pointer to the game settings being displayed and modified. SettingEntry *valuewindow_entry; ///< If non-nullptr, pointer to setting for which a value-entering window has been opened. @@ -1966,7 +1961,7 @@ struct GameSettingsWindow : Window { resize->height = SETTING_HEIGHT = std::max({(int)_circle_size.height, SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL}) + 1; resize->width = 1; - size->height = 5 * resize->height + SETTINGTREE_TOP_OFFSET + SETTINGTREE_BOTTOM_OFFSET; + size->height = 5 * resize->height + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM; break; case WID_GS_HELP_TEXT: { @@ -2004,14 +1999,14 @@ struct GameSettingsWindow : Window { } /* Reserve the correct number of lines for the 'some search results are hidden' notice in the central settings display panel. */ - const NWidgetBase *panel = this->GetWidget(WID_GS_OPTIONSPANEL); + const Rect panel = this->GetWidget(WID_GS_OPTIONSPANEL)->GetCurrentRect().Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); StringID warn_str = STR_CONFIG_SETTING_CATEGORY_HIDES - 1 + this->warn_missing; int new_warn_lines; if (this->warn_missing == WHR_NONE) { new_warn_lines = 0; } else { SetDParam(0, _game_settings_restrict_dropdown[this->filter.min_cat]); - new_warn_lines = GetStringLineCount(warn_str, panel->current_x); + new_warn_lines = GetStringLineCount(warn_str, panel.Width()); } if (this->warn_lines != new_warn_lines) { this->vscroll->SetCount(this->vscroll->GetCount() - this->warn_lines + new_warn_lines); @@ -2022,16 +2017,8 @@ struct GameSettingsWindow : Window { /* Draw the 'some search results are hidden' notice. */ if (this->warn_missing != WHR_NONE) { - const int left = panel->pos_x; - const int right = left + panel->current_x - 1; - const int top = panel->pos_y + WD_FRAMETEXT_TOP + (SETTING_HEIGHT - FONT_HEIGHT_NORMAL) * this->warn_lines / 2; SetDParam(0, _game_settings_restrict_dropdown[this->filter.min_cat]); - if (this->warn_lines == 1) { - /* If the warning fits at one line, center it. */ - DrawString(left + WD_FRAMETEXT_LEFT, right - WD_FRAMETEXT_RIGHT, top, warn_str, TC_FROMSTRING, SA_HOR_CENTER); - } else { - DrawStringMultiLine(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, INT32_MAX, warn_str, TC_FROMSTRING, SA_HOR_CENTER); - } + DrawStringMultiLine(panel.WithHeight(this->warn_lines * FONT_HEIGHT_NORMAL), warn_str, TC_FROMSTRING, SA_CENTER); } } @@ -2081,11 +2068,12 @@ struct GameSettingsWindow : Window { { switch (widget) { case WID_GS_OPTIONSPANEL: { - int top_pos = r.top + SETTINGTREE_TOP_OFFSET + 1 + this->warn_lines * SETTING_HEIGHT; + Rect tr = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM); + tr.top += this->warn_lines * SETTING_HEIGHT; uint last_row = this->vscroll->GetPosition() + this->vscroll->GetCapacity() - this->warn_lines; - int next_row = GetSettingsTree().Draw(settings_ptr, r.left + SETTINGTREE_LEFT_OFFSET, r.right - SETTINGTREE_RIGHT_OFFSET, top_pos, + int next_row = GetSettingsTree().Draw(settings_ptr, tr.left, tr.right, tr.top, this->vscroll->GetPosition(), last_row, this->last_clicked); - if (next_row == 0) DrawString(r.left + SETTINGTREE_LEFT_OFFSET, r.right - SETTINGTREE_RIGHT_OFFSET, top_pos, STR_CONFIG_SETTINGS_NONE); + if (next_row == 0) DrawString(tr, STR_CONFIG_SETTINGS_NONE); break; } @@ -2093,21 +2081,21 @@ struct GameSettingsWindow : Window { if (this->last_clicked != nullptr) { const IntSettingDesc *sd = this->last_clicked->setting; - int y = r.top; + Rect tr = r; switch (sd->GetType()) { case ST_COMPANY: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_COMPANY_INGAME); break; case ST_CLIENT: SetDParam(0, STR_CONFIG_SETTING_TYPE_CLIENT); break; case ST_GAME: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_GAME_MENU : STR_CONFIG_SETTING_TYPE_GAME_INGAME); break; default: NOT_REACHED(); } - DrawString(r.left, r.right, y, STR_CONFIG_SETTING_TYPE); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_CONFIG_SETTING_TYPE); + tr.top += FONT_HEIGHT_NORMAL; this->last_clicked->SetValueDParams(0, sd->def); - DrawString(r.left, r.right, y, STR_CONFIG_SETTING_DEFAULT_VALUE); - y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; + DrawString(tr, STR_CONFIG_SETTING_DEFAULT_VALUE); + tr.top += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; - DrawStringMultiLine(r.left, r.right, y, r.bottom, this->last_clicked->GetHelpText(), TC_WHITE); + DrawStringMultiLine(tr, this->last_clicked->GetHelpText(), TC_WHITE); } break; @@ -2169,7 +2157,7 @@ struct GameSettingsWindow : Window { if (widget != WID_GS_OPTIONSPANEL) return; - uint btn = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GS_OPTIONSPANEL, SETTINGTREE_TOP_OFFSET); + uint btn = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GS_OPTIONSPANEL, WD_FRAMETEXT_TOP); if (btn == INT_MAX || (int)btn < this->warn_lines) return; btn -= this->warn_lines; @@ -2178,7 +2166,7 @@ struct GameSettingsWindow : Window { if (clicked_entry == nullptr) return; // Clicked below the last setting of the page - int x = (_current_text_dir == TD_RTL ? this->width - 1 - pt.x : pt.x) - SETTINGTREE_LEFT_OFFSET - (clicked_entry->level + 1) * LEVEL_WIDTH; // Shift x coordinate + int x = (_current_text_dir == TD_RTL ? this->width - 1 - pt.x : pt.x) - WD_FRAMETEXT_LEFT - (clicked_entry->level + 1) * LEVEL_WIDTH; // Shift x coordinate if (x < 0) return; // Clicked left of the entry SettingsPage *clicked_page = dynamic_cast(clicked_entry); @@ -2219,7 +2207,7 @@ struct GameSettingsWindow : Window { this->closing_dropdown = false; const NWidgetBase *wid = this->GetWidget(WID_GS_OPTIONSPANEL); - int rel_y = (pt.y - (int)wid->pos_y - SETTINGTREE_TOP_OFFSET) % wid->resize_y; + int rel_y = (pt.y - (int)wid->pos_y - WD_FRAMETEXT_TOP) % wid->resize_y; Rect wi_rect; wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x); @@ -2447,7 +2435,7 @@ struct GameSettingsWindow : Window { void OnResize() override { - this->vscroll->SetCapacityFromWidget(this, WID_GS_OPTIONSPANEL, SETTINGTREE_TOP_OFFSET + SETTINGTREE_BOTTOM_OFFSET); + this->vscroll->SetCapacityFromWidget(this, WID_GS_OPTIONSPANEL, WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM); } }; From cb059fc081b617be17ba6a9edad020848ecd9a03 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 17 Oct 2022 19:24:47 +0100 Subject: [PATCH 03/26] Change: Use Rect for QueryString editor. --- src/misc_gui.cpp | 62 +++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 38 deletions(-) diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index a46a9304fb..3c59414ae9 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -798,24 +798,21 @@ void QueryString::DrawEditBox(const Window *w, int wid) const Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); int clearbtn_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; - int clearbtn_left = wi->pos_x + (rtl ? 0 : wi->current_x - clearbtn_width); - int clearbtn_right = wi->pos_x + (rtl ? clearbtn_width : wi->current_x) - 1; - int left = wi->pos_x + (rtl ? clearbtn_width : 0); - int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1; + Rect r = wi->GetCurrentRect(); + Rect cr = r.WithWidth(clearbtn_width, !rtl); + Rect fr = r.Indent(clearbtn_width, !rtl); - int top = wi->pos_y; - int bottom = wi->pos_y + wi->current_y - 1; + DrawFrameRect(cr, wi->colour, wi->IsLowered() ? FR_LOWERED : FR_NONE); + DrawSprite(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT, PAL_NONE, cr.left + WD_IMGBTN_LEFT + (wi->IsLowered() ? 1 : 0), CenterBounds(r.top, r.bottom, sprite_size.height) + (wi->IsLowered() ? 1 : 0)); + if (this->text.bytes == 1) GfxFillRect(cr.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), _colour_gradient[wi->colour & 0xF][2], FILLRECT_CHECKER); - DrawFrameRect(clearbtn_left, top, clearbtn_right, bottom, wi->colour, wi->IsLowered() ? FR_LOWERED : FR_NONE); - DrawSprite(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT, PAL_NONE, clearbtn_left + WD_IMGBTN_LEFT + (wi->IsLowered() ? 1 : 0), CenterBounds(top, bottom, sprite_size.height) + (wi->IsLowered() ? 1 : 0)); - if (this->text.bytes == 1) GfxFillRect(clearbtn_left + 1, top + 1, clearbtn_right - 1, bottom - 1, _colour_gradient[wi->colour & 0xF][2], FILLRECT_CHECKER); - - DrawFrameRect(left, top, right, bottom, wi->colour, FR_LOWERED | FR_DARKENED); - GfxFillRect(left + 1, top + 1, right - 1, bottom - 1, PC_BLACK); + DrawFrameRect(fr, wi->colour, FR_LOWERED | FR_DARKENED); + GfxFillRect(fr.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_BLACK); + fr = fr.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); /* Limit the drawing of the string inside the widget boundaries */ DrawPixelInfo dpi; - if (!FillDrawPixelInfo(&dpi, left + WD_FRAMERECT_LEFT, top + WD_FRAMERECT_TOP, right - left - WD_FRAMERECT_RIGHT, bottom - top - WD_FRAMERECT_BOTTOM)) return; + if (!FillDrawPixelInfo(&dpi, fr.left, fr.top, fr.Width(), fr.Height())) return; DrawPixelInfo *old_dpi = _cur_dpi; _cur_dpi = &dpi; @@ -823,12 +820,12 @@ void QueryString::DrawEditBox(const Window *w, int wid) const /* We will take the current widget length as maximum width, with a small * space reserved at the end for the caret to show */ const Textbuf *tb = &this->text; - int delta = std::min(0, (right - left) - tb->pixels - 10); + int delta = std::min(0, (fr.right - fr.left) - tb->pixels - 10); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; /* If we have a marked area, draw a background highlight. */ - if (tb->marklength != 0) GfxFillRect(delta + tb->markxoffs, 0, delta + tb->markxoffs + tb->marklength - 1, bottom - top, PC_GREY); + if (tb->marklength != 0) GfxFillRect(delta + tb->markxoffs, 0, delta + tb->markxoffs + tb->marklength - 1, fr.bottom - fr.top, PC_GREY); DrawString(delta, tb->pixels, 0, tb->buf, TC_YELLOW); bool focussed = w->IsWidgetGloballyFocused(wid) || IsOSKOpenedFor(w, wid); @@ -856,15 +853,14 @@ Point QueryString::GetCaretPosition(const Window *w, int wid) const Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); int clearbtn_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; - int left = wi->pos_x + (rtl ? clearbtn_width : 0); - int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1; + Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); /* Clamp caret position to be inside out current width. */ const Textbuf *tb = &this->text; - int delta = std::min(0, (right - left) - tb->pixels - 10); + int delta = std::min(0, (r.right - r.left) - tb->pixels - 10); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; - Point pt = {left + WD_FRAMERECT_LEFT + tb->caretxoffs + delta, (int)wi->pos_y + WD_FRAMERECT_TOP}; + Point pt = {r.left + tb->caretxoffs + delta, r.top}; return pt; } @@ -886,24 +882,18 @@ Rect QueryString::GetBoundingRect(const Window *w, int wid, const char *from, co Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); int clearbtn_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; - int left = wi->pos_x + (rtl ? clearbtn_width : 0); - int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1; - - int top = wi->pos_y + WD_FRAMERECT_TOP; - int bottom = wi->pos_y + wi->current_y - 1 - WD_FRAMERECT_BOTTOM; + Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); /* Clamp caret position to be inside our current width. */ const Textbuf *tb = &this->text; - int delta = std::min(0, (right - left) - tb->pixels - 10); + int delta = std::min(0, r.Width() - tb->pixels - 10); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; /* Get location of first and last character. */ Point p1 = GetCharPosInString(tb->buf, from, FS_NORMAL); Point p2 = from != to ? GetCharPosInString(tb->buf, to, FS_NORMAL) : p1; - Rect r = { Clamp(left + p1.x + delta + WD_FRAMERECT_LEFT, left, right), top, Clamp(left + p2.x + delta + WD_FRAMERECT_LEFT, left, right - WD_FRAMERECT_RIGHT), bottom }; - - return r; + return { Clamp(r.left + p1.x + delta, r.left, r.right), r.top, Clamp(r.left + p2.x + delta, r.left, r.right), r.bottom }; } /** @@ -923,20 +913,16 @@ const char *QueryString::GetCharAtPosition(const Window *w, int wid, const Point Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); int clearbtn_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; - int left = wi->pos_x + (rtl ? clearbtn_width : 0); - int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1; + Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); - int top = wi->pos_y + WD_FRAMERECT_TOP; - int bottom = wi->pos_y + wi->current_y - 1 - WD_FRAMERECT_BOTTOM; - - if (!IsInsideMM(pt.y, top, bottom)) return nullptr; + if (!IsInsideMM(pt.y, r.top, r.bottom)) return nullptr; /* Clamp caret position to be inside our current width. */ const Textbuf *tb = &this->text; - int delta = std::min(0, (right - left) - tb->pixels - 10); + int delta = std::min(0, r.Width() - tb->pixels - 10); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; - return ::GetCharAtPosition(tb->buf, pt.x - delta - left); + return ::GetCharAtPosition(tb->buf, pt.x - delta - r.left); } void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bool focus_changed) @@ -948,9 +934,9 @@ void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bo bool rtl = _current_text_dir == TD_RTL; int clearbtn_width = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT).width; - int clearbtn_left = wi->pos_x + (rtl ? 0 : wi->current_x - clearbtn_width); + Rect cr = wi->GetCurrentRect().WithWidth(clearbtn_width, !rtl); - if (IsInsideBS(pt.x, clearbtn_left, clearbtn_width)) { + if (IsInsideMM(pt.x, cr.left, cr.right)) { if (this->text.bytes > 1) { this->text.DeleteAll(); w->HandleButtonClick(wid); From 1f1378c129207fe1086e8668c958b18322a3f5d1 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 17 Oct 2022 19:25:33 +0100 Subject: [PATCH 04/26] Change: Align picker previews to button centre. --- src/dock_gui.cpp | 34 ++++++++++++++++++++++------------ src/rail_gui.cpp | 45 +++++++++++++++++++++++++++++++-------------- src/road_gui.cpp | 29 +++++++++++++++++++++++------ 3 files changed, 76 insertions(+), 32 deletions(-) diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 87a49969ba..b0fc7f54ff 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -531,25 +531,35 @@ public: switch (widget) { case WID_BDD_X: case WID_BDD_Y: - size->width = ScaleGUITrad(96) + 2; - size->height = ScaleGUITrad(64) + 2; + size->width = ScaleGUITrad(96) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT; + size->height = ScaleGUITrad(64) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM; break; } } - void OnPaint() override + void DrawWidget(const Rect &r, int widget) const override { - this->DrawWidgets(); + DrawPixelInfo tmp_dpi; - int x1 = ScaleGUITrad(63) + 1; - int x2 = ScaleGUITrad(31) + 1; - int y1 = ScaleGUITrad(17) + 1; - int y2 = ScaleGUITrad(33) + 1; + switch (widget) { + case WID_BDD_X: + case WID_BDD_Y: { + Axis axis = widget == WID_BDD_X ? AXIS_X : AXIS_Y; - DrawShipDepotSprite(this->GetWidget(WID_BDD_X)->pos_x + x1, this->GetWidget(WID_BDD_X)->pos_y + y1, AXIS_X, DEPOT_PART_NORTH); - DrawShipDepotSprite(this->GetWidget(WID_BDD_X)->pos_x + x2, this->GetWidget(WID_BDD_X)->pos_y + y2, AXIS_X, DEPOT_PART_SOUTH); - DrawShipDepotSprite(this->GetWidget(WID_BDD_Y)->pos_x + x2, this->GetWidget(WID_BDD_Y)->pos_y + y1, AXIS_Y, DEPOT_PART_NORTH); - DrawShipDepotSprite(this->GetWidget(WID_BDD_Y)->pos_x + x1, this->GetWidget(WID_BDD_Y)->pos_y + y2, AXIS_Y, DEPOT_PART_SOUTH); + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + DrawPixelInfo *old_dpi = _cur_dpi; + _cur_dpi = &tmp_dpi; + int x = (r.Width() - ScaleGUITrad(96)) / 2; + int y = (r.Height() - ScaleGUITrad(64)) / 2; + int x1 = ScaleGUITrad(63); + int x2 = ScaleGUITrad(31); + DrawShipDepotSprite(x + (axis == AXIS_X ? x1 : x2), y + ScaleGUITrad(17), axis, DEPOT_PART_NORTH); + DrawShipDepotSprite(x + (axis == AXIS_X ? x2 : x1), y + ScaleGUITrad(33), axis, DEPOT_PART_SOUTH); + _cur_dpi = old_dpi; + } + break; + } + } } void OnClick(Point pt, int widget, int click_count) override diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index b0003c29a2..a41366fb09 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1232,8 +1232,8 @@ public: case WID_BRAS_PLATFORM_DIR_X: case WID_BRAS_PLATFORM_DIR_Y: case WID_BRAS_IMAGE: - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(58) + 2; + size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT; + size->height = ScaleGUITrad(58) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM; break; case WID_BRAS_COVERAGE_TEXTS: @@ -1257,8 +1257,8 @@ public: if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { DrawPixelInfo *old_dpi = _cur_dpi; _cur_dpi = &tmp_dpi; - int x = ScaleGUITrad(31) + 1; - int y = r.bottom - r.top - ScaleGUITrad(31); + int x = (r.Width() - ScaleGUITrad(64)) / 2 + ScaleGUITrad(31); + int y = (r.Height() + ScaleGUITrad(58)) / 2 - ScaleGUITrad(31); if (!DrawStationTile(x, y, _cur_railtype, AXIS_X, _railstation.station_class, _railstation.station_type)) { StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2); } @@ -1271,8 +1271,8 @@ public: if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { DrawPixelInfo *old_dpi = _cur_dpi; _cur_dpi = &tmp_dpi; - int x = ScaleGUITrad(31) + 1; - int y = r.bottom - r.top - ScaleGUITrad(31); + int x = (r.Width() - ScaleGUITrad(64)) / 2 + ScaleGUITrad(31); + int y = (r.Height() + ScaleGUITrad(58)) / 2 - ScaleGUITrad(31); if (!DrawStationTile(x, y, _cur_railtype, AXIS_Y, _railstation.station_class, _railstation.station_type)) { StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 3); } @@ -1308,8 +1308,8 @@ public: if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { DrawPixelInfo *old_dpi = _cur_dpi; _cur_dpi = &tmp_dpi; - int x = ScaleGUITrad(31) + 1; - int y = r.bottom - r.top - ScaleGUITrad(31); + int x = (r.Width() - ScaleGUITrad(64)) / 2 + ScaleGUITrad(31); + int y = (r.Height() + ScaleGUITrad(58)) / 2 - ScaleGUITrad(31); if (!DrawStationTile(x, y, _cur_railtype, _railstation.orientation, _railstation.station_class, type)) { StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2 + _railstation.orientation); } @@ -1929,15 +1929,23 @@ struct BuildRailDepotWindow : public PickerWindowBase { { if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return; - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(48) + 2; + size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT; + size->height = ScaleGUITrad(48) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM; } void DrawWidget(const Rect &r, int widget) const override { if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return; - DrawTrainDepotSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), widget - WID_BRAD_DEPOT_NE + DIAGDIR_NE, _cur_railtype); + DrawPixelInfo tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + DrawPixelInfo *old_dpi = _cur_dpi; + _cur_dpi = &tmp_dpi; + int x = (r.Width() - ScaleGUITrad(64)) / 2 + ScaleGUITrad(31); + int y = (r.Height() + ScaleGUITrad(48)) / 2 - ScaleGUITrad(31); + DrawTrainDepotSprite(x, y, widget - WID_BRAD_DEPOT_NE + DIAGDIR_NE, _cur_railtype); + _cur_dpi = old_dpi; + } } void OnClick(Point pt, int widget, int click_count) override @@ -2028,8 +2036,8 @@ struct BuildRailWaypointWindow : PickerWindowBase { break; case WID_BRW_WAYPOINT: - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(58) + 2; + size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT; + size->height = ScaleGUITrad(58) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM; break; } } @@ -2040,7 +2048,16 @@ struct BuildRailWaypointWindow : PickerWindowBase { case WID_BRW_WAYPOINT: { byte type = GB(widget, 16, 16); const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP)->GetSpec(type); - DrawWaypointSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), type, _cur_railtype); + + DrawPixelInfo tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + DrawPixelInfo *old_dpi = _cur_dpi; + _cur_dpi = &tmp_dpi; + int x = (r.Width() - ScaleGUITrad(64)) / 2 + ScaleGUITrad(31); + int y = (r.Height() + ScaleGUITrad(58)) / 2 - ScaleGUITrad(31); + DrawWaypointSprite(x, y, type, _cur_railtype); + _cur_dpi = old_dpi; + } if (!IsStationAvailable(statspec)) { GfxFillRect(r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_BLACK, FILLRECT_CHECKER); diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 86af0fb8c6..8fdb4dd592 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -974,15 +974,23 @@ struct BuildRoadDepotWindow : public PickerWindowBase { { if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return; - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(48) + 2; + size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT; + size->height = ScaleGUITrad(48) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM; } void DrawWidget(const Rect &r, int widget) const override { if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return; - DrawRoadDepotSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), (DiagDirection)(widget - WID_BROD_DEPOT_NE + DIAGDIR_NE), _cur_roadtype); + DrawPixelInfo tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + DrawPixelInfo *old_dpi = _cur_dpi; + _cur_dpi = &tmp_dpi; + int x = (r.Width() - ScaleGUITrad(64)) / 2 + ScaleGUITrad(31); + int y = (r.Height() + ScaleGUITrad(48)) / 2 - ScaleGUITrad(31); + DrawRoadDepotSprite(x, y, (DiagDirection)(widget - WID_BROD_DEPOT_NE + DIAGDIR_NE), _cur_roadtype); + _cur_dpi = old_dpi; + } } void OnClick(Point pt, int widget, int click_count) override @@ -1099,8 +1107,8 @@ struct BuildRoadStationWindow : public PickerWindowBase { { if (!IsInsideMM(widget, WID_BROS_STATION_NE, WID_BROS_STATION_Y + 1)) return; - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(48) + 2; + size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT; + size->height = ScaleGUITrad(48) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM; } void DrawWidget(const Rect &r, int widget) const override @@ -1108,7 +1116,16 @@ struct BuildRoadStationWindow : public PickerWindowBase { if (!IsInsideMM(widget, WID_BROS_STATION_NE, WID_BROS_STATION_Y + 1)) return; StationType st = (this->window_class == WC_BUS_STATION) ? STATION_BUS : STATION_TRUCK; - StationPickerDrawSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE); + + DrawPixelInfo tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + DrawPixelInfo *old_dpi = _cur_dpi; + _cur_dpi = &tmp_dpi; + int x = (r.Width() - ScaleGUITrad(64)) / 2 + ScaleGUITrad(31); + int y = (r.Height() + ScaleGUITrad(48)) / 2 - ScaleGUITrad(31); + StationPickerDrawSprite(x, y, st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE); + _cur_dpi = old_dpi; + } } void OnClick(Point pt, int widget, int click_count) override From 3ff05321dcb08abbbe0d500efad371212056e13c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 18 Oct 2022 13:11:16 +0100 Subject: [PATCH 05/26] Change: Use standard padding for AI Debug window. --- src/ai/ai_gui.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index b9971ae1b6..cd442d9fd6 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -939,9 +939,6 @@ static bool SetScriptButtonColour(NWidgetCore &button, bool dead, bool paused) * Window with everything an AI prints via ScriptLog. */ struct AIDebugWindow : public Window { - static const int top_offset; ///< Offset of the text at the top of the WID_AID_LOG_PANEL. - static const int bottom_offset; ///< Offset of the text at the bottom of the WID_AID_LOG_PANEL. - static const uint MAX_BREAK_STR_STRING_LENGTH = 256; ///< Maximum length of the break string. static CompanyID ai_debug_company; ///< The AI that is (was last) being debugged. @@ -1046,7 +1043,7 @@ struct AIDebugWindow : public Window { { if (widget == WID_AID_LOG_PANEL) { resize->height = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; - size->height = 14 * resize->height + this->top_offset + this->bottom_offset; + size->height = 14 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; } } @@ -1160,7 +1157,8 @@ struct AIDebugWindow : public Window { ScriptLog::LogData *log = this->GetLogPointer(); if (log == nullptr) return; - int y = this->top_offset; + Rect br = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM); + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < log->used; i++) { int pos = (i + log->pos + 1 - log->used + log->count) % log->count; if (log->lines[pos] == nullptr) break; @@ -1177,12 +1175,12 @@ struct AIDebugWindow : public Window { /* Check if the current line should be highlighted */ if (pos == this->highlight_row) { - GfxFillRect(r.left + 1, r.top + y, r.right - 1, r.top + y + this->resize.step_height - WD_PAR_VSEP_NORMAL, PC_BLACK); + GfxFillRect(br.left, tr.top, br.right, tr.top + this->resize.step_height - 1, PC_BLACK); if (colour == TC_BLACK) colour = TC_WHITE; // Make black text readable by inverting it to white. } - DrawString(r.left + 7, r.right - 7, r.top + y, log->lines[pos], colour, SA_LEFT | SA_FORCE); - y += this->resize.step_height; + DrawString(tr, log->lines[pos], colour, SA_LEFT | SA_FORCE); + tr.top += this->resize.step_height; } break; } @@ -1360,8 +1358,6 @@ struct AIDebugWindow : public Window { static HotkeyList hotkeys; }; -const int AIDebugWindow::top_offset = WD_FRAMERECT_TOP + 2; -const int AIDebugWindow::bottom_offset = WD_FRAMERECT_BOTTOM; CompanyID AIDebugWindow::ai_debug_company = INVALID_COMPANY; char AIDebugWindow::break_string[MAX_BREAK_STR_STRING_LENGTH] = ""; bool AIDebugWindow::break_check_enabled = true; From c9a81fd67b4cb4068ffc84ffd52cdfefc3946a01 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 18 Oct 2022 13:52:22 +0100 Subject: [PATCH 06/26] Change: Use Rect for drawing vehicle details. --- src/aircraft_gui.cpp | 21 +++++++++-------- src/roadveh_gui.cpp | 30 ++++++++++++------------ src/ship_gui.cpp | 19 ++++++++------- src/train_gui.cpp | 50 +++++++++++++++++----------------------- src/vehicle_gui.cpp | 55 +++++++++++++++++++++----------------------- 5 files changed, 84 insertions(+), 91 deletions(-) diff --git a/src/aircraft_gui.cpp b/src/aircraft_gui.cpp index a9e0a68224..3571394117 100644 --- a/src/aircraft_gui.cpp +++ b/src/aircraft_gui.cpp @@ -25,47 +25,48 @@ * Draw the details for the given vehicle at the given position * * @param v current vehicle - * @param left The left most coordinate to draw - * @param right The right most coordinate to draw - * @param y The y coordinate + * @param r the Rect to draw within */ -void DrawAircraftDetails(const Aircraft *v, int left, int right, int y) +void DrawAircraftDetails(const Aircraft *v, const Rect &r) { - int y_offset = (v->Next()->cargo_cap != 0) ? -(FONT_HEIGHT_NORMAL + 1): 0; Money feeder_share = 0; + int y = r.top; for (const Aircraft *u = v; u != nullptr; u = u->Next()) { if (u->IsNormalAircraft()) { SetDParam(0, u->engine_type); SetDParam(1, u->build_year); SetDParam(2, u->value); - DrawString(left, right, y, STR_VEHICLE_INFO_BUILT_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_BUILT_VALUE); + y += FONT_HEIGHT_NORMAL; SetDParam(0, u->cargo_type); SetDParam(1, u->cargo_cap); SetDParam(2, u->Next()->cargo_type); SetDParam(3, u->Next()->cargo_cap); SetDParam(4, GetCargoSubtypeText(u)); - DrawString(left, right, y + FONT_HEIGHT_NORMAL, (u->Next()->cargo_cap != 0) ? STR_VEHICLE_INFO_CAPACITY_CAPACITY : STR_VEHICLE_INFO_CAPACITY); + DrawString(r.left, r.right, y, (u->Next()->cargo_cap != 0) ? STR_VEHICLE_INFO_CAPACITY_CAPACITY : STR_VEHICLE_INFO_CAPACITY); + y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; } if (u->cargo_cap != 0) { uint cargo_count = u->cargo.StoredCount(); - y_offset += FONT_HEIGHT_NORMAL + 1; if (cargo_count != 0) { /* Cargo names (fix pluralness) */ SetDParam(0, u->cargo_type); SetDParam(1, cargo_count); SetDParam(2, u->cargo.Source()); - DrawString(left, right, y + 2 * FONT_HEIGHT_NORMAL + 1 + y_offset, STR_VEHICLE_DETAILS_CARGO_FROM); + DrawString(r.left, r.right, y, STR_VEHICLE_DETAILS_CARGO_FROM); + y += FONT_HEIGHT_NORMAL; feeder_share += u->cargo.FeederShare(); } } } + y += WD_PAR_VSEP_NORMAL; SetDParam(0, feeder_share); - DrawString(left, right, y + 3 * FONT_HEIGHT_NORMAL + 3 + y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); } diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp index f25bd734f9..5cd07bbdca 100644 --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -23,20 +23,19 @@ * Draw the details for the given vehicle at the given position * * @param v current vehicle - * @param left The left most coordinate to draw - * @param right The right most coordinate to draw - * @param y The y coordinate + * @param r the Rect to draw within */ -void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) +void DrawRoadVehDetails(const Vehicle *v, const Rect &r) { - uint y_offset = v->HasArticulatedPart() ? ScaleGUITrad(15) : 0; // Draw the first line below the sprite of an articulated RV instead of after it. + int y = r.top + (v->HasArticulatedPart() ? ScaleGUITrad(15) : 0); // Draw the first line below the sprite of an articulated RV instead of after it. StringID str; Money feeder_share = 0; SetDParam(0, v->engine_type); SetDParam(1, v->build_year); SetDParam(2, v->value); - DrawString(left, right, y + y_offset, STR_VEHICLE_INFO_BUILT_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_BUILT_VALUE); + y += FONT_HEIGHT_NORMAL; if (v->HasArticulatedPart()) { CargoArray max_cargo; @@ -76,7 +75,8 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) } } - DrawString(left, right, y + FONT_HEIGHT_NORMAL + y_offset, capacity, TC_BLUE); + DrawString(r.left, r.right, y, capacity, TC_BLUE); + y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; for (const Vehicle *u = v; u != nullptr; u = u->Next()) { if (u->cargo_cap == 0) continue; @@ -89,17 +89,16 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) str = STR_VEHICLE_DETAILS_CARGO_FROM; feeder_share += u->cargo.FeederShare(); } - DrawString(left, right, y + 2 * FONT_HEIGHT_NORMAL + 1 + y_offset, str); - - y_offset += FONT_HEIGHT_NORMAL + 1; + DrawString(r.left, r.right, y, str); + y += FONT_HEIGHT_NORMAL; } - - y_offset -= FONT_HEIGHT_NORMAL + 1; + y += WD_PAR_VSEP_NORMAL; } else { SetDParam(0, v->cargo_type); SetDParam(1, v->cargo_cap); SetDParam(4, GetCargoSubtypeText(v)); - DrawString(left, right, y + FONT_HEIGHT_NORMAL + y_offset, STR_VEHICLE_INFO_CAPACITY); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_CAPACITY); + y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; str = STR_VEHICLE_DETAILS_CARGO_EMPTY; if (v->cargo.StoredCount() > 0) { @@ -109,12 +108,13 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) str = STR_VEHICLE_DETAILS_CARGO_FROM; feeder_share += v->cargo.FeederShare(); } - DrawString(left, right, y + 2 * FONT_HEIGHT_NORMAL + 1 + y_offset, str); + DrawString(r.left, r.right, y, str); + y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; } /* Draw Transfer credits text */ SetDParam(0, feeder_share); - DrawString(left, right, y + 3 * FONT_HEIGHT_NORMAL + 3 + y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); } /** diff --git a/src/ship_gui.cpp b/src/ship_gui.cpp index 7525eb0da5..6154681547 100644 --- a/src/ship_gui.cpp +++ b/src/ship_gui.cpp @@ -57,21 +57,23 @@ void DrawShipImage(const Vehicle *v, int left, int right, int y, VehicleID selec * Draw the details for the given vehicle at the given position * * @param v current vehicle - * @param left The left most coordinate to draw - * @param right The right most coordinate to draw - * @param y The y coordinate + * @param r the Rect to draw within */ -void DrawShipDetails(const Vehicle *v, int left, int right, int y) +void DrawShipDetails(const Vehicle *v, const Rect &r) { + int y = r.top; + SetDParam(0, v->engine_type); SetDParam(1, v->build_year); SetDParam(2, v->value); - DrawString(left, right, y, STR_VEHICLE_INFO_BUILT_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_BUILT_VALUE); + y += FONT_HEIGHT_NORMAL; SetDParam(0, v->cargo_type); SetDParam(1, v->cargo_cap); SetDParam(4, GetCargoSubtypeText(v)); - DrawString(left, right, y + FONT_HEIGHT_NORMAL, STR_VEHICLE_INFO_CAPACITY); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_CAPACITY); + y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; StringID str = STR_VEHICLE_DETAILS_CARGO_EMPTY; if (v->cargo.StoredCount() > 0) { @@ -80,9 +82,10 @@ void DrawShipDetails(const Vehicle *v, int left, int right, int y) SetDParam(2, v->cargo.Source()); str = STR_VEHICLE_DETAILS_CARGO_FROM; } - DrawString(left, right, y + 2 * FONT_HEIGHT_NORMAL + 1, str); + DrawString(r.left, r.right, y, str); + y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; /* Draw Transfer credits text */ SetDParam(0, v->cargo.FeederShare()); - DrawString(left, right, y + 3 * FONT_HEIGHT_NORMAL + 3, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); } diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 9fe06a9383..a84b4161cb 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -352,32 +352,22 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab) * Draw the details for the given vehicle at the given position * * @param v current vehicle - * @param left The left most coordinate to draw - * @param right The right most coordinate to draw - * @param y The y coordinate + * @param r the Rect to draw within * @param vscroll_pos Position of scrollbar * @param vscroll_cap Number of lines currently displayed * @param det_tab Selected details tab */ -void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab) +void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab) { - /* get rid of awkward offset */ - y -= WD_MATRIX_TOP; - - /* Indent the total cargo capacity details */ - int offs_left = _current_text_dir == TD_LTR ? TRAIN_DETAILS_LIST_INDENT : 0; - int offs_right = _current_text_dir == TD_LTR ? 0 : TRAIN_DETAILS_LIST_INDENT; - - int sprite_height = ScaleGUITrad(GetVehicleHeight(VEH_TRAIN)); - int line_height = std::max(sprite_height, WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM); + bool rtl = _current_text_dir == TD_RTL; + int line_height = r.Height(); int sprite_y_offset = line_height / 2; int text_y_offset = (line_height - FONT_HEIGHT_NORMAL) / 2; /* draw the first 3 details tabs */ if (det_tab != TDW_TAB_TOTALS) { - bool rtl = _current_text_dir == TD_RTL; Direction dir = rtl ? DIR_E : DIR_W; - int x = rtl ? right : left; + int x = rtl ? r.right : r.left; for (; v != nullptr && vscroll_pos > -vscroll_cap; v = v->GetNextVehicle()) { GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary); @@ -397,7 +387,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); VehicleSpriteSeq seq; u->GetImage(dir, EIT_IN_DETAILS, &seq); - seq.Draw(px + (rtl ? -offset.x : offset.x), y - line_height * vscroll_pos + sprite_y_offset + pitch, pal, (v->vehstatus & VS_CRASHED) != 0); + seq.Draw(px + (rtl ? -offset.x : offset.x), r.top - line_height * vscroll_pos + sprite_y_offset + pitch, pal, (v->vehstatus & VS_CRASHED) != 0); } px += rtl ? -width : width; dx += width; @@ -410,35 +400,34 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po dx = 0; } + int sprite_width = std::max(dx, ScaleGUITrad(TRAIN_DETAILS_MIN_INDENT)) + 3; + Rect dr = r.Indent(sprite_width, rtl); uint num_lines = std::max(1u, (unsigned)_cargo_summary.size()); for (uint i = 0; i < num_lines; i++) { - int sprite_width = std::max(dx, ScaleGUITrad(TRAIN_DETAILS_MIN_INDENT)) + 3; - int data_left = left + (rtl ? 0 : sprite_width); - int data_right = right - (rtl ? sprite_width : 0); if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) { - int py = y - line_height * vscroll_pos + text_y_offset; + int py = r.top - line_height * vscroll_pos + text_y_offset; if (i > 0 || separate_sprite_row) { - if (vscroll_pos != 0) GfxFillRect(left, py - WD_MATRIX_TOP - 1, right, py - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][5]); + if (vscroll_pos != 0) GfxFillRect(r.left, py - WD_MATRIX_TOP - 1, r.right, py - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][5]); } switch (det_tab) { case TDW_TAB_CARGO: if (i < _cargo_summary.size()) { - TrainDetailsCargoTab(&_cargo_summary[i], data_left, data_right, py); + TrainDetailsCargoTab(&_cargo_summary[i], dr.left, dr.right, py); } else { - DrawString(data_left, data_right, py, STR_QUANTITY_N_A, TC_LIGHT_BLUE); + DrawString(dr.left, dr.right, py, STR_QUANTITY_N_A, TC_LIGHT_BLUE); } break; case TDW_TAB_INFO: - if (i == 0) TrainDetailsInfoTab(v, data_left, data_right, py); + if (i == 0) TrainDetailsInfoTab(v, dr.left, dr.right, py); break; case TDW_TAB_CAPACITY: if (i < _cargo_summary.size()) { - TrainDetailsCapacityTab(&_cargo_summary[i], data_left, data_right, py); + TrainDetailsCapacityTab(&_cargo_summary[i], dr.left, dr.right, py); } else { SetDParam(0, STR_EMPTY); - DrawString(data_left, data_right, py, STR_VEHICLE_INFO_NO_CAPACITY); + DrawString(dr.left, dr.right, py, STR_VEHICLE_INFO_NO_CAPACITY); } break; @@ -449,6 +438,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po } } } else { + int y = r.top; CargoArray act_cargo; CargoArray max_cargo; Money feeder_share = 0; @@ -460,9 +450,11 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po } /* draw total cargo tab */ - DrawString(left, right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT); + DrawString(r.left, r.right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT); y += line_height; + /* Indent the total cargo capacity details */ + Rect ir = r.Indent(TRAIN_DETAILS_LIST_INDENT, rtl); for (CargoID i = 0; i < NUM_CARGO; i++) { if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) { SetDParam(0, i); // {CARGO} #1 @@ -470,11 +462,11 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po SetDParam(2, i); // {SHORTCARGO} #1 SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2 SetDParam(4, _settings_game.vehicle.freight_trains); - DrawString(left + offs_left, right - offs_right, y + text_y_offset, FreightWagonMult(i) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY); + DrawString(ir.left, ir.right, y + text_y_offset, FreightWagonMult(i) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY); y += line_height; } } SetDParam(0, feeder_share); - DrawString(left, right, y + text_y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); + DrawString(r.left, r.right, y + text_y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); } } diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index a6138802fb..9df9268960 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2236,10 +2236,10 @@ static const NWidgetPart _nested_train_vehicle_details_widgets[] = { extern int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab); -extern void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab); -extern void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y); -extern void DrawShipDetails(const Vehicle *v, int left, int right, int y); -extern void DrawAircraftDetails(const Aircraft *v, int left, int right, int y); +extern void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab); +extern void DrawRoadVehDetails(const Vehicle *v, const Rect &r); +extern void DrawShipDetails(const Vehicle *v, const Rect &r); +extern void DrawAircraftDetails(const Aircraft *v, const Rect &r); static StringID _service_interval_dropdown[] = { STR_VEHICLE_DETAILS_DEFAULT, @@ -2300,13 +2300,13 @@ struct VehicleDetailsWindow : Window { uint desired_height; if (v->HasArticulatedPart()) { /* An articulated RV has its text drawn under the sprite instead of after it, hence 15 pixels extra. */ - desired_height = WD_FRAMERECT_TOP + ScaleGUITrad(15) + 3 * FONT_HEIGHT_NORMAL + 2 + WD_FRAMERECT_BOTTOM; + desired_height = WD_FRAMERECT_TOP + ScaleGUITrad(15) + 3 * FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL * 2 + WD_FRAMERECT_BOTTOM; /* Add space for the cargo amount for each part. */ for (const Vehicle *u = v; u != nullptr; u = u->Next()) { - if (u->cargo_cap != 0) desired_height += FONT_HEIGHT_NORMAL + 1; + if (u->cargo_cap != 0) desired_height += FONT_HEIGHT_NORMAL; } } else { - desired_height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM; + desired_height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL * 2 + WD_FRAMERECT_BOTTOM; } return desired_height; } @@ -2343,11 +2343,11 @@ struct VehicleDetailsWindow : Window { break; case VEH_SHIP: - size->height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM; + size->height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL * 2 + WD_FRAMERECT_BOTTOM; break; case VEH_AIRCRAFT: - size->height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + 4 + WD_FRAMERECT_BOTTOM; + size->height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL * 2 + WD_FRAMERECT_BOTTOM; break; default: @@ -2400,20 +2400,18 @@ struct VehicleDetailsWindow : Window { * Draw the details for the given vehicle at the position of the Details windows * * @param v current vehicle - * @param left The left most coordinate to draw - * @param right The right most coordinate to draw - * @param y The y coordinate + * @param r the Rect to draw within * @param vscroll_pos Position of scrollbar (train only) * @param vscroll_cap Number of lines currently displayed (train only) * @param det_tab Selected details tab (train only) */ - static void DrawVehicleDetails(const Vehicle *v, int left, int right, int y, int vscroll_pos, uint vscroll_cap, TrainDetailsWindowTabs det_tab) + static void DrawVehicleDetails(const Vehicle *v, const Rect &r, int vscroll_pos, uint vscroll_cap, TrainDetailsWindowTabs det_tab) { switch (v->type) { - case VEH_TRAIN: DrawTrainDetails(Train::From(v), left, right, y, vscroll_pos, vscroll_cap, det_tab); break; - case VEH_ROAD: DrawRoadVehDetails(v, left, right, y); break; - case VEH_SHIP: DrawShipDetails(v, left, right, y); break; - case VEH_AIRCRAFT: DrawAircraftDetails(Aircraft::From(v), left, right, y); break; + case VEH_TRAIN: DrawTrainDetails(Train::From(v), r, vscroll_pos, vscroll_cap, det_tab); break; + case VEH_ROAD: DrawRoadVehDetails(v, r); break; + case VEH_SHIP: DrawShipDetails(v, r); break; + case VEH_AIRCRAFT: DrawAircraftDetails(Aircraft::From(v), r); break; default: NOT_REACHED(); } } @@ -2491,37 +2489,36 @@ struct VehicleDetailsWindow : Window { case WID_VD_MATRIX: /* For trains only. */ - DrawVehicleDetails(v, r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, r.top + WD_MATRIX_TOP, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->tab); + DrawVehicleDetails(v, r.Shrink(WD_MATRIX_LEFT, 0, WD_MATRIX_RIGHT, 0).WithHeight(this->resize.step_height), this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->tab); break; case WID_VD_MIDDLE_DETAILS: { /* For other vehicles, at the place of the matrix. */ bool rtl = _current_text_dir == TD_RTL; uint sprite_width = GetSingleVehicleWidth(v, EIT_IN_DETAILS) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - - uint text_left = r.left + (rtl ? 0 : sprite_width); - uint text_right = r.right - (rtl ? sprite_width : 0); + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); /* Articulated road vehicles use a complete line. */ if (v->type == VEH_ROAD && v->HasArticulatedPart()) { - DrawVehicleImage(v, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, EIT_IN_DETAILS, 0); + DrawVehicleImage(v, tr.left, tr.right, tr.top, INVALID_VEHICLE, EIT_IN_DETAILS, 0); } else { - uint sprite_left = rtl ? text_right : r.left; - uint sprite_right = rtl ? r.right : text_left; - - DrawVehicleImage(v, sprite_left + WD_FRAMERECT_LEFT, sprite_right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, EIT_IN_DETAILS, 0); + Rect sr = tr.WithWidth(sprite_width, rtl); + DrawVehicleImage(v, sr.left, sr.right, sr.top, INVALID_VEHICLE, EIT_IN_DETAILS, 0); } - DrawVehicleDetails(v, text_left + WD_FRAMERECT_LEFT, text_right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, 0, 0, this->tab); + + DrawVehicleDetails(v, tr.Indent(sprite_width, rtl), 0, 0, this->tab); break; } - case WID_VD_SERVICING_INTERVAL: + case WID_VD_SERVICING_INTERVAL: { /* Draw service interval text */ + Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); SetDParam(0, v->GetServiceInterval()); SetDParam(1, v->date_of_last_service); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), + DrawString(tr.left, tr.right, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS); break; + } } } From 46a1ab09377fe9108585c9dfa9d6f6adb3cde20b Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 19 Oct 2022 12:28:15 +0100 Subject: [PATCH 07/26] Change: Use Rect when drawing infrastructure window. --- src/company_gui.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 78bb7c2bd8..7951f39d7c 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -2036,9 +2036,7 @@ struct CompanyInfrastructureWindow : Window const Company *c = Company::Get((CompanyID)this->window_number); int y = r.top; - int offs_left = _current_text_dir == TD_LTR ? WD_FRAMERECT_LEFT : 0; - int offs_right = _current_text_dir == TD_LTR ? 0 : WD_FRAMERECT_LEFT; - + Rect ir = r.Indent(LEVEL_WIDTH, _current_text_dir == TD_RTL); switch (widget) { case WID_CI_RAIL_DESC: DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT); @@ -2048,13 +2046,13 @@ struct CompanyInfrastructureWindow : Window for (const auto &rt : _sorted_railtypes) { if (HasBit(this->railtypes, rt)) { SetDParam(0, GetRailTypeInfo(rt)->strings.name); - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING); } } - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS); } else { /* No valid railtype. */ - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE); } break; @@ -2081,7 +2079,7 @@ struct CompanyInfrastructureWindow : Window for (const auto &rt : _sorted_roadtypes) { if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) { SetDParam(0, GetRoadTypeInfo(rt)->strings.name); - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING); } } @@ -2101,7 +2099,7 @@ struct CompanyInfrastructureWindow : Window case WID_CI_WATER_DESC: DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT); - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS); break; case WID_CI_WATER_COUNT: @@ -2120,8 +2118,8 @@ struct CompanyInfrastructureWindow : Window case WID_CI_STATION_DESC: DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT); - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS); - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS); break; case WID_CI_STATION_COUNT: From 5786d49143c447f00d244b40c054e863229422a9 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 21 Oct 2022 19:58:43 +0100 Subject: [PATCH 08/26] Change: Use Rect when drawing build engine list. --- src/autoreplace_gui.cpp | 6 ++---- src/build_vehicle_gui.cpp | 40 +++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 0e676c891d..186000ccd7 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -33,7 +33,7 @@ #include "safeguards.h" -void DrawEngineList(VehicleType type, int x, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group); +void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group); static bool EngineNumberSorter(const EngineID &a, const EngineID &b) { @@ -433,9 +433,7 @@ public: EngineID end = static_cast(std::min(this->vscroll[side]->GetCapacity() + start, this->engines[side].size())); /* Do the actual drawing */ - const Rect list = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM); - DrawEngineList((VehicleType)this->window_number, list.left, list.right, list.top, - &this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group); + DrawEngineList((VehicleType)this->window_number, r, &this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group); break; } } diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 5e808c0615..286a392ffa 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -33,6 +33,7 @@ #include "engine_cmd.h" #include "train_cmd.h" #include "vehicle_cmd.h" +#include "zoom_func.h" #include "widgets/build_vehicle_widget.h" @@ -953,9 +954,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, /** * Engine drawing loop * @param type Type of vehicle (VEH_*) - * @param l The left most location of the list - * @param r The right most location of the list - * @param y The top most location of the list + * @param r The Rect of the list * @param eng_list What engines to draw * @param min where to start in the list * @param max where in the list to end @@ -963,7 +962,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, * @param show_count Whether to show the amount of engines or not * @param selected_group the group to list the engines of */ -void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group) +void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group) { static const int sprite_y_offsets[] = { -1, -1, -2, -2 }; @@ -976,8 +975,9 @@ void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList * int sprite_right = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_right; int sprite_width = sprite_left + sprite_right; - int sprite_x = rtl ? r - sprite_right - 1 : l + sprite_left + 1; - int sprite_y_offset = sprite_y_offsets[type] + step_size / 2; + Rect ir = r.WithHeight(step_size).Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM); + int sprite_x = ir.WithWidth(sprite_width, rtl).left + sprite_left; + int sprite_y_offset = ScaleGUITrad(sprite_y_offsets[type]) + ir.Height() / 2; Dimension replace_icon = {0, 0}; int count_width = 0; @@ -987,16 +987,16 @@ void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList * count_width = GetStringBoundingBox(STR_TINY_BLACK_COMA).width; } - int text_left = l + (rtl ? WD_FRAMERECT_LEFT + replace_icon.width + 8 + count_width : sprite_width + WD_FRAMETEXT_LEFT); - int text_right = r - (rtl ? sprite_width + WD_FRAMETEXT_RIGHT : WD_FRAMERECT_RIGHT + replace_icon.width + 8 + count_width); - int replace_icon_left = rtl ? l + WD_FRAMERECT_LEFT : r - WD_FRAMERECT_RIGHT - replace_icon.width; - int count_left = l; - int count_right = rtl ? text_left : r - WD_FRAMERECT_RIGHT - replace_icon.width - 8; + Rect tr = ir.Indent(sprite_width + 6, rtl); // Name position + Rect cr = tr.Indent(replace_icon.width + 6, !rtl).WithWidth(count_width, !rtl); // Count position + Rect rr = tr.WithWidth(replace_icon.width, !rtl); // Replace icon position + if (show_count) tr = tr.Indent(count_width + 2 + replace_icon.width + 6, !rtl); - int normal_text_y_offset = (step_size - FONT_HEIGHT_NORMAL) / 2; - int small_text_y_offset = step_size - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1; - int replace_icon_y_offset = (step_size - replace_icon.height) / 2 - 1; + int normal_text_y_offset = (ir.Height() - FONT_HEIGHT_NORMAL) / 2; + int small_text_y_offset = ir.Height() - FONT_HEIGHT_SMALL; + int replace_icon_y_offset = (ir.Height() - replace_icon.height) / 2; + int y = ir.top; for (; min < max; min++, y += step_size) { const EngineID engine = (*eng_list)[min]; /* Note: num_engines is only used in the autoreplace GUI, so it is correct to use _local_company here. */ @@ -1008,12 +1008,12 @@ void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList * TextColour tc = (engine == selected_id) ? TC_WHITE : (TC_NO_SHADE | (hidden ? TC_GREY : TC_BLACK)); SetDParam(0, engine); - DrawString(text_left, text_right, y + normal_text_y_offset, str, tc); - DrawVehicleEngine(l, r, sprite_x, y + sprite_y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_company), EIT_PURCHASE); + DrawString(tr.left, tr.right, y + normal_text_y_offset, str, tc); + DrawVehicleEngine(r.left, r.right, sprite_x, y + sprite_y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_company), EIT_PURCHASE); if (show_count) { SetDParam(0, num_engines); - DrawString(count_left, count_right, y + small_text_y_offset, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); - if (EngineHasReplacementForCompany(Company::Get(_local_company), engine, selected_group)) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, num_engines == 0 ? PALETTE_CRASH : PAL_NONE, replace_icon_left, y + replace_icon_y_offset); + DrawString(cr.left, cr.right, y + small_text_y_offset, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); + if (EngineHasReplacementForCompany(Company::Get(_local_company), engine, selected_group)) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, num_engines == 0 ? PALETTE_CRASH : PAL_NONE, rr.left, y + replace_icon_y_offset); } } } @@ -1588,9 +1588,7 @@ struct BuildVehicleWindow : Window { case WID_BV_LIST: DrawEngineList( this->vehicle_type, - r.left + WD_FRAMERECT_LEFT, - r.right - WD_FRAMERECT_RIGHT, - r.top + WD_FRAMERECT_TOP, + r, &this->eng_list, this->vscroll->GetPosition(), static_cast(std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->eng_list.size())), From 75b222b0d95d0a4339046588d17508a64496eff8 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 28 Sep 2022 18:48:48 +0100 Subject: [PATCH 09/26] Add: RectPadding type. This is similar to Rect but specifies padding to apply to a Rect. --- src/core/geometry_func.cpp | 2 ++ src/core/geometry_type.hpp | 53 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/core/geometry_func.cpp b/src/core/geometry_func.cpp index dccef72ecc..3dd680347c 100644 --- a/src/core/geometry_func.cpp +++ b/src/core/geometry_func.cpp @@ -48,3 +48,5 @@ Rect BoundingRect(const Rect &r1, const Rect &r2) return r; } + +const RectPadding RectPadding::zero = {0, 0, 0, 0}; diff --git a/src/core/geometry_type.hpp b/src/core/geometry_type.hpp index d5fdd2a944..98a1f8f9d3 100644 --- a/src/core/geometry_type.hpp +++ b/src/core/geometry_type.hpp @@ -43,6 +43,28 @@ struct Dimension { } }; +/** Padding dimensions to apply to each side of a Rect. */ +struct RectPadding { + uint8 left; + uint8 top; + uint8 right; + uint8 bottom; + + static const RectPadding zero; + + /** + * Get total horizontal padding of RectPadding. + * @return total horizontal padding. + */ + inline uint Horizontal() const { return this->left + this->right; } + + /** + * Get total vertical padding of RectPadding. + * @return total vertical padding. + */ + inline uint Vertical() const { return this->top + this->bottom; } +}; + /** Specification of a rectangle with absolute coordinates of all edges */ struct Rect { int left; @@ -96,6 +118,27 @@ struct Rect { return {this->left + left, this->top + top, this->right - right, this->bottom - bottom}; } + /** + * Copy and shrink Rect by a RectPadding. + * @param other RectPadding to remove from each side of Rect. + * @return the new smaller Rect. + */ + [[nodiscard]] inline Rect Shrink(const RectPadding &other) const + { + return {this->left + other.left, this->top + other.top, this->right - other.right, this->bottom - other.bottom}; + } + + /** + * Copy and shrink Rect by a different horizontal and vertical RectPadding. + * @param horz RectPadding to remove from left and right of Rect. + * @param vert RectPadding to remove from top and bottom of Rect. + * @return the new smaller Rect. + */ + [[nodiscard]] inline Rect Shrink(const RectPadding &horz, const RectPadding &vert) const + { + return {this->left + horz.left, this->top + vert.top, this->right - horz.right, this->bottom - vert.bottom}; + } + /** * Copy and expand Rect by s pixels. * @param s number of pixels to add to each side of Rect. @@ -106,6 +149,16 @@ struct Rect { return this->Shrink(-s); } + /** + * Copy and expand Rect by a RectPadding. + * @param other RectPadding to add to each side of Rect. + * @return the new larger Rect. + */ + [[nodiscard]] inline Rect Expand(const RectPadding &other) const + { + return {this->left - other.left, this->top - other.top, this->right + other.right, this->bottom + other.bottom}; + } + /** * Copy and translate Rect by x,y pixels. * @param x number of pixels to move horizontally. From 04cbe57d2a35db22effc8118d28eebcf7a3132bb Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 28 Sep 2022 19:05:36 +0100 Subject: [PATCH 10/26] Change: Use RectPadding for widget padding/uz_padding. --- src/network/network_gui.cpp | 2 +- src/newgrf_gui.cpp | 76 ++++++++++++++--------------- src/toolbar_gui.cpp | 4 +- src/widget.cpp | 96 ++++++++++++++++++------------------- src/widget_type.h | 22 +++------ 5 files changed, 96 insertions(+), 104 deletions(-) diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 1d6e644b78..b618b763a3 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -126,7 +126,7 @@ public: /* First initialise some variables... */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom); } /* ... then in a second pass make sure the 'current' sizes are set. Won't change for most widgets. */ diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index cfd075282b..01de9fe583 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -1613,13 +1613,13 @@ public: this->acs->SetupSmallestSize(w, init_array); this->inf->SetupSmallestSize(w, init_array); - uint min_avs_width = this->avs->smallest_x + this->avs->padding_left + this->avs->padding_right; - uint min_acs_width = this->acs->smallest_x + this->acs->padding_left + this->acs->padding_right; - uint min_inf_width = this->inf->smallest_x + this->inf->padding_left + this->inf->padding_right; + uint min_avs_width = this->avs->smallest_x + this->avs->padding.left + this->avs->padding.right; + uint min_acs_width = this->acs->smallest_x + this->acs->padding.left + this->acs->padding.right; + uint min_inf_width = this->inf->smallest_x + this->inf->padding.left + this->inf->padding.right; - uint min_avs_height = this->avs->smallest_y + this->avs->padding_top + this->avs->padding_bottom; - uint min_acs_height = this->acs->smallest_y + this->acs->padding_top + this->acs->padding_bottom; - uint min_inf_height = this->inf->smallest_y + this->inf->padding_top + this->inf->padding_bottom; + uint min_avs_height = this->avs->smallest_y + this->avs->padding.top + this->avs->padding.bottom; + uint min_acs_height = this->acs->smallest_y + this->acs->padding.top + this->acs->padding.bottom; + uint min_inf_height = this->inf->smallest_y + this->inf->padding.top + this->inf->padding.bottom; /* Smallest window is in two column mode. */ this->smallest_x = std::max(min_avs_width, min_acs_width) + INTER_COLUMN_SPACING + min_inf_width; @@ -1649,9 +1649,9 @@ public: { this->StoreSizePosition(sizing, x, y, given_width, given_height); - uint min_avs_width = this->avs->smallest_x + this->avs->padding_left + this->avs->padding_right; - uint min_acs_width = this->acs->smallest_x + this->acs->padding_left + this->acs->padding_right; - uint min_inf_width = this->inf->smallest_x + this->inf->padding_left + this->inf->padding_right; + uint min_avs_width = this->avs->smallest_x + this->avs->padding.left + this->avs->padding.right; + uint min_acs_width = this->acs->smallest_x + this->acs->padding.left + this->acs->padding.right; + uint min_inf_width = this->inf->smallest_x + this->inf->padding.left + this->inf->padding.right; uint min_list_width = std::max(min_avs_width, min_acs_width); // Smallest width of the lists such that they have equal width (incl padding). uint avs_extra_width = min_list_width - min_avs_width; // Additional width needed for avs to reach min_list_width. @@ -1687,10 +1687,10 @@ public: avs_width = ComputeMaxSize(this->avs->smallest_x, this->avs->smallest_x + avs_width, this->avs->GetHorizontalStepSize(sizing)); uint acs_width = given_width - // Remaining space, including horizontal padding. - inf_width - this->inf->padding_left - this->inf->padding_right - - avs_width - this->avs->padding_left - this->avs->padding_right - 2 * INTER_COLUMN_SPACING; + inf_width - this->inf->padding.left - this->inf->padding.right - + avs_width - this->avs->padding.left - this->avs->padding.right - 2 * INTER_COLUMN_SPACING; acs_width = ComputeMaxSize(min_acs_width, acs_width, this->acs->GetHorizontalStepSize(sizing)) - - this->acs->padding_left - this->acs->padding_right; + this->acs->padding.left - this->acs->padding.right; /* Never use fill_y on these; the minimal size is chosen, so that the 3 column view looks nice */ uint avs_height = ComputeMaxSize(this->avs->smallest_y, given_height, this->avs->resize_y); @@ -1698,25 +1698,25 @@ public: /* Assign size and position to the children. */ if (rtl) { - x += this->inf->padding_left; - this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); - x += inf_width + this->inf->padding_right + INTER_COLUMN_SPACING; + x += this->inf->padding.left; + this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl); + x += inf_width + this->inf->padding.right + INTER_COLUMN_SPACING; } else { - x += this->avs->padding_left; - this->avs->AssignSizePosition(sizing, x, y + this->avs->padding_top, avs_width, avs_height, rtl); - x += avs_width + this->avs->padding_right + INTER_COLUMN_SPACING; + x += this->avs->padding.left; + this->avs->AssignSizePosition(sizing, x, y + this->avs->padding.top, avs_width, avs_height, rtl); + x += avs_width + this->avs->padding.right + INTER_COLUMN_SPACING; } - x += this->acs->padding_left; - this->acs->AssignSizePosition(sizing, x, y + this->acs->padding_top, acs_width, acs_height, rtl); - x += acs_width + this->acs->padding_right + INTER_COLUMN_SPACING; + x += this->acs->padding.left; + this->acs->AssignSizePosition(sizing, x, y + this->acs->padding.top, acs_width, acs_height, rtl); + x += acs_width + this->acs->padding.right + INTER_COLUMN_SPACING; if (rtl) { - x += this->avs->padding_left; - this->avs->AssignSizePosition(sizing, x, y + this->avs->padding_top, avs_width, avs_height, rtl); + x += this->avs->padding.left; + this->avs->AssignSizePosition(sizing, x, y + this->avs->padding.top, avs_width, avs_height, rtl); } else { - x += this->inf->padding_left; - this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); + x += this->inf->padding.left; + this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl); } } else { /* Two columns, all space in extra_width goes to both lists. Since the lists are underneath each other, @@ -1726,8 +1726,8 @@ public: uint acs_width = ComputeMaxSize(this->acs->smallest_x, this->acs->smallest_x + acs_extra_width + extra_width, this->acs->GetHorizontalStepSize(sizing)); - uint min_avs_height = (!this->editable) ? 0 : this->avs->smallest_y + this->avs->padding_top + this->avs->padding_bottom + INTER_LIST_SPACING; - uint min_acs_height = this->acs->smallest_y + this->acs->padding_top + this->acs->padding_bottom; + uint min_avs_height = (!this->editable) ? 0 : this->avs->smallest_y + this->avs->padding.top + this->avs->padding.bottom + INTER_LIST_SPACING; + uint min_acs_height = this->acs->smallest_y + this->acs->padding.top + this->acs->padding.bottom; uint extra_height = given_height - min_acs_height - min_avs_height; /* Never use fill_y on these; instead use the INTER_LIST_SPACING as filler */ @@ -1737,29 +1737,29 @@ public: /* Assign size and position to the children. */ if (rtl) { - x += this->inf->padding_left; - this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); - x += inf_width + this->inf->padding_right + INTER_COLUMN_SPACING; + x += this->inf->padding.left; + this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl); + x += inf_width + this->inf->padding.right + INTER_COLUMN_SPACING; - this->acs->AssignSizePosition(sizing, x + this->acs->padding_left, y + this->acs->padding_top, acs_width, acs_height, rtl); + this->acs->AssignSizePosition(sizing, x + this->acs->padding.left, y + this->acs->padding.top, acs_width, acs_height, rtl); if (this->editable) { - this->avs->AssignSizePosition(sizing, x + this->avs->padding_left, y + given_height - avs_height - this->avs->padding_bottom, avs_width, avs_height, rtl); + this->avs->AssignSizePosition(sizing, x + this->avs->padding.left, y + given_height - avs_height - this->avs->padding.bottom, avs_width, avs_height, rtl); } else { this->avs->AssignSizePosition(sizing, 0, 0, this->avs->smallest_x, this->avs->smallest_y, rtl); } } else { - this->acs->AssignSizePosition(sizing, x + this->acs->padding_left, y + this->acs->padding_top, acs_width, acs_height, rtl); + this->acs->AssignSizePosition(sizing, x + this->acs->padding.left, y + this->acs->padding.top, acs_width, acs_height, rtl); if (this->editable) { - this->avs->AssignSizePosition(sizing, x + this->avs->padding_left, y + given_height - avs_height - this->avs->padding_bottom, avs_width, avs_height, rtl); + this->avs->AssignSizePosition(sizing, x + this->avs->padding.left, y + given_height - avs_height - this->avs->padding.bottom, avs_width, avs_height, rtl); } else { this->avs->AssignSizePosition(sizing, 0, 0, this->avs->smallest_x, this->avs->smallest_y, rtl); } - uint dx = this->acs->current_x + this->acs->padding_left + this->acs->padding_right; + uint dx = this->acs->current_x + this->acs->padding.left + this->acs->padding.right; if (this->editable) { - dx = std::max(dx, this->avs->current_x + this->avs->padding_left + this->avs->padding_right); + dx = std::max(dx, this->avs->current_x + this->avs->padding.left + this->avs->padding.right); } - x += dx + INTER_COLUMN_SPACING + this->inf->padding_left; - this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); + x += dx + INTER_COLUMN_SPACING + this->inf->padding.left; + this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl); } } } diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index ea5bbb38b9..5d9af5a538 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -1354,10 +1354,10 @@ public: /* First initialise some variables... */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom); if (this->IsButton(child_wid->type)) { nbuttons++; - this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right); + this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.left + child_wid->padding.right); } else if (child_wid->type == NWID_SPACER) { this->spacers++; } diff --git a/src/widget.cpp b/src/widget.cpp index 10ae2f239c..eaffe1125f 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -831,10 +831,10 @@ NWidgetBase *NWidgetBase::GetWidgetOfType(WidgetType tp) void NWidgetBase::AdjustPaddingForZoom() { - this->padding_top = ScaleGUITrad(this->uz_padding_top); - this->padding_right = ScaleGUITrad(this->uz_padding_right); - this->padding_bottom = ScaleGUITrad(this->uz_padding_bottom); - this->padding_left = ScaleGUITrad(this->uz_padding_left); + this->padding.left = ScaleGUITrad(this->uz_padding.left); + this->padding.top = ScaleGUITrad(this->uz_padding.top); + this->padding.right = ScaleGUITrad(this->uz_padding.right); + this->padding.bottom = ScaleGUITrad(this->uz_padding.bottom); } /** @@ -1124,8 +1124,8 @@ void NWidgetStacked::SetupSmallestSize(Window *w, bool init_array) for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); - this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); + this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.left + child_wid->padding.right); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom); this->fill_x = LeastCommonMultiple(this->fill_x, child_wid->fill_x); this->fill_y = LeastCommonMultiple(this->fill_y, child_wid->fill_y); this->resize_x = LeastCommonMultiple(this->resize_x, child_wid->resize_x); @@ -1142,12 +1142,12 @@ void NWidgetStacked::AssignSizePosition(SizingType sizing, uint x, uint y, uint for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { uint hor_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetHorizontalStepSize(sizing); - uint child_width = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding_left - child_wid->padding_right, hor_step); - uint child_pos_x = (rtl ? child_wid->padding_right : child_wid->padding_left); + uint child_width = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding.left - child_wid->padding.right, hor_step); + uint child_pos_x = (rtl ? child_wid->padding.right : child_wid->padding.left); uint vert_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetVerticalStepSize(sizing); - uint child_height = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding_top - child_wid->padding_bottom, vert_step); - uint child_pos_y = child_wid->padding_top; + uint child_height = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding.top - child_wid->padding.bottom, vert_step); + uint child_pos_y = child_wid->padding.top; child_wid->AssignSizePosition(sizing, x + child_pos_x, y + child_pos_y, child_width, child_height, rtl); } @@ -1269,7 +1269,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) child_wid->SetupSmallestSize(w, init_array); longest = std::max(longest, child_wid->smallest_x); max_vert_fill = std::max(max_vert_fill, child_wid->GetVerticalStepSize(ST_SMALLEST)); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom); } /* 1b. Make the container higher if needed to accommodate all children nicely. */ [[maybe_unused]] uint max_smallest = this->smallest_y + 3 * max_vert_fill; // Upper limit to computing smallest height. @@ -1277,7 +1277,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) for (;;) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { uint step_size = child_wid->GetVerticalStepSize(ST_SMALLEST); - uint child_height = child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom; + uint child_height = child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom; if (step_size > 1 && child_height < cur_height) { // Small step sizes or already fitting children are not interesting. uint remainder = (cur_height - child_height) % step_size; if (remainder > 0) { // Child did not fit entirely, widen the container. @@ -1297,15 +1297,15 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) } } /* 3. Move PIP space to the children, compute smallest, fill, and resize values of the container. */ - if (this->head != nullptr) this->head->padding_left += this->pip_pre; + if (this->head != nullptr) this->head->padding.left += this->pip_pre; for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (child_wid->next != nullptr) { - child_wid->padding_right += this->pip_inter; + child_wid->padding.right += this->pip_inter; } else { - child_wid->padding_right += this->pip_post; + child_wid->padding.right += this->pip_post; } - this->smallest_x += child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right; + this->smallest_x += child_wid->smallest_x + child_wid->padding.left + child_wid->padding.right; if (child_wid->fill_x > 0) { if (this->fill_x == 0 || this->fill_x > child_wid->fill_x) this->fill_x = child_wid->fill_x; } @@ -1329,7 +1329,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) { /* For EQUALSIZE containers this does not sum to smallest_x during initialisation */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { - additional_length -= child_wid->smallest_x + child_wid->padding_right + child_wid->padding_left; + additional_length -= child_wid->smallest_x + child_wid->padding.right + child_wid->padding.left; } } else { additional_length -= this->smallest_x; @@ -1363,7 +1363,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui } uint vert_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetVerticalStepSize(sizing); - child_wid->current_y = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding_top - child_wid->padding_bottom, vert_step); + child_wid->current_y = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding.top - child_wid->padding.bottom, vert_step); } /* First.5 loop: count how many children are of the biggest step size. */ @@ -1411,11 +1411,11 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui NWidgetBase *child_wid = this->head; while (child_wid != nullptr) { uint child_width = child_wid->current_x; - uint child_x = x + (rtl ? position - child_width - child_wid->padding_left : position + child_wid->padding_left); - uint child_y = y + child_wid->padding_top; + uint child_x = x + (rtl ? position - child_width - child_wid->padding.left : position + child_wid->padding.left); + uint child_y = y + child_wid->padding.top; child_wid->AssignSizePosition(sizing, child_x, child_y, child_width, child_wid->current_y, rtl); - uint padded_child_width = child_width + child_wid->padding_right + child_wid->padding_left; + uint padded_child_width = child_width + child_wid->padding.right + child_wid->padding.left; position = rtl ? position - padded_child_width : position + padded_child_width; child_wid = child_wid->next; @@ -1454,7 +1454,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) child_wid->SetupSmallestSize(w, init_array); highest = std::max(highest, child_wid->smallest_y); max_hor_fill = std::max(max_hor_fill, child_wid->GetHorizontalStepSize(ST_SMALLEST)); - this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right); + this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.left + child_wid->padding.right); } /* 1b. Make the container wider if needed to accommodate all children nicely. */ [[maybe_unused]] uint max_smallest = this->smallest_x + 3 * max_hor_fill; // Upper limit to computing smallest height. @@ -1462,7 +1462,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) for (;;) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { uint step_size = child_wid->GetHorizontalStepSize(ST_SMALLEST); - uint child_width = child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right; + uint child_width = child_wid->smallest_x + child_wid->padding.left + child_wid->padding.right; if (step_size > 1 && child_width < cur_width) { // Small step sizes or already fitting children are not interesting. uint remainder = (cur_width - child_width) % step_size; if (remainder > 0) { // Child did not fit entirely, widen the container. @@ -1482,15 +1482,15 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) } } /* 3. Move PIP space to the child, compute smallest, fill, and resize values of the container. */ - if (this->head != nullptr) this->head->padding_top += this->pip_pre; + if (this->head != nullptr) this->head->padding.top += this->pip_pre; for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (child_wid->next != nullptr) { - child_wid->padding_bottom += this->pip_inter; + child_wid->padding.bottom += this->pip_inter; } else { - child_wid->padding_bottom += this->pip_post; + child_wid->padding.bottom += this->pip_post; } - this->smallest_y += child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom; + this->smallest_y += child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom; if (child_wid->fill_y > 0) { if (this->fill_y == 0 || this->fill_y > child_wid->fill_y) this->fill_y = child_wid->fill_y; } @@ -1514,7 +1514,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) { /* For EQUALSIZE containers this does not sum to smallest_y during initialisation */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { - additional_length -= child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom; + additional_length -= child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom; } } else { additional_length -= this->smallest_y; @@ -1539,7 +1539,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint } uint hor_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetHorizontalStepSize(sizing); - child_wid->current_x = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding_left - child_wid->padding_right, hor_step); + child_wid->current_x = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding.left - child_wid->padding.right, hor_step); } /* First.5 loop: count how many children are of the biggest step size. */ @@ -1585,11 +1585,11 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint /* Third loop: Compute position and call the child. */ uint position = 0; // Place to put next child relative to origin of the container. for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { - uint child_x = x + (rtl ? child_wid->padding_right : child_wid->padding_left); + uint child_x = x + (rtl ? child_wid->padding.right : child_wid->padding.left); uint child_height = child_wid->current_y; - child_wid->AssignSizePosition(sizing, child_x, y + position + child_wid->padding_top, child_wid->current_x, child_height, rtl); - position += child_height + child_wid->padding_top + child_wid->padding_bottom; + child_wid->AssignSizePosition(sizing, child_x, y + position + child_wid->padding.top, child_wid->current_x, child_height, rtl); + position += child_height + child_wid->padding.top + child_wid->padding.bottom; } } @@ -1945,25 +1945,25 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array) if (this->type == WWT_FRAME) { /* Account for the size of the frame's text if that exists */ - this->child->padding_left = WD_FRAMETEXT_LEFT; - this->child->padding_right = WD_FRAMETEXT_RIGHT; - this->child->padding_top = std::max((int)WD_FRAMETEXT_TOP, this->widget_data != STR_NULL ? FONT_HEIGHT_NORMAL + WD_FRAMETEXT_TOP / 2 : 0); - this->child->padding_bottom = WD_FRAMETEXT_BOTTOM; + this->child->padding.left = WD_FRAMETEXT_LEFT; + this->child->padding.right = WD_FRAMETEXT_RIGHT; + this->child->padding.top = std::max((int)WD_FRAMETEXT_TOP, this->widget_data != STR_NULL ? FONT_HEIGHT_NORMAL + WD_FRAMETEXT_TOP / 2 : 0); + this->child->padding.bottom = WD_FRAMETEXT_BOTTOM; - this->smallest_x += this->child->padding_left + this->child->padding_right; - this->smallest_y += this->child->padding_top + this->child->padding_bottom; + this->smallest_x += this->child->padding.left + this->child->padding.right; + this->smallest_y += this->child->padding.top + this->child->padding.bottom; if (this->index >= 0) w->SetStringParameters(this->index); this->smallest_x = std::max(this->smallest_x, GetStringBoundingBox(this->widget_data).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT); } else if (this->type == WWT_INSET) { /* Apply automatic padding for bevel thickness. */ - this->child->padding_left = WD_BEVEL_LEFT; - this->child->padding_right = WD_BEVEL_RIGHT; - this->child->padding_top = WD_BEVEL_TOP; - this->child->padding_bottom = WD_BEVEL_BOTTOM; + this->child->padding.left = WD_BEVEL_LEFT; + this->child->padding.right = WD_BEVEL_RIGHT; + this->child->padding.top = WD_BEVEL_TOP; + this->child->padding.bottom = WD_BEVEL_BOTTOM; - this->smallest_x += this->child->padding_left + this->child->padding_right; - this->smallest_y += this->child->padding_top + this->child->padding_bottom; + this->smallest_x += this->child->padding.left + this->child->padding.right; + this->smallest_y += this->child->padding.top + this->child->padding.bottom; } } else { Dimension d = {this->min_x, this->min_y}; @@ -1995,10 +1995,10 @@ void NWidgetBackground::AssignSizePosition(SizingType sizing, uint x, uint y, ui this->StoreSizePosition(sizing, x, y, given_width, given_height); if (this->child != nullptr) { - uint x_offset = (rtl ? this->child->padding_right : this->child->padding_left); - uint width = given_width - this->child->padding_right - this->child->padding_left; - uint height = given_height - this->child->padding_top - this->child->padding_bottom; - this->child->AssignSizePosition(sizing, x + x_offset, y + this->child->padding_top, width, height, rtl); + uint x_offset = (rtl ? this->child->padding.right : this->child->padding.left); + uint width = given_width - this->child->padding.right - this->child->padding.left; + uint height = given_height - this->child->padding.top - this->child->padding.bottom; + this->child->AssignSizePosition(sizing, x + x_offset, y + this->child->padding.top, width, height, rtl); } } diff --git a/src/widget_type.h b/src/widget_type.h index 4c812e42f1..d11dbc8796 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -149,10 +149,10 @@ public: */ inline void SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left) { - this->uz_padding_top = top; - this->uz_padding_right = right; - this->uz_padding_bottom = bottom; - this->uz_padding_left = left; + this->uz_padding.top = top; + this->uz_padding.right = right; + this->uz_padding.bottom = bottom; + this->uz_padding.left = left; this->AdjustPaddingForZoom(); } @@ -192,15 +192,8 @@ public: NWidgetBase *next; ///< Pointer to next widget in container. Managed by parent container widget. NWidgetBase *prev; ///< Pointer to previous widget in container. Managed by parent container widget. - uint8 padding_top; ///< Paddings added to the top of the widget. Managed by parent container widget. - uint8 padding_right; ///< Paddings added to the right of the widget. Managed by parent container widget. (parent container may swap this with padding_left for RTL) - uint8 padding_bottom; ///< Paddings added to the bottom of the widget. Managed by parent container widget. - uint8 padding_left; ///< Paddings added to the left of the widget. Managed by parent container widget. (parent container may swap this with padding_right for RTL) - - uint8 uz_padding_top; ///< Unscaled top padding, for resize calculation. - uint8 uz_padding_right; ///< Unscaled right padding, for resize calculation. - uint8 uz_padding_bottom; ///< Unscaled bottom padding, for resize calculation. - uint8 uz_padding_left; ///< Unscaled left padding, for resize calculation. + RectPadding padding; ///< Padding added to the widget. Managed by parent container widget. (parent container may swap left and right for RTL) + RectPadding uz_padding; ///< Unscaled padding, for resize calculation. protected: inline void StoreSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height); @@ -920,8 +913,7 @@ struct NWidgetPartWidget { * Widget part for storing padding. * @ingroup NestedWidgetParts */ -struct NWidgetPartPaddings { - uint8 top, right, bottom, left; ///< Paddings for all directions. +struct NWidgetPartPaddings : RectPadding { }; /** From dd9f6bc803588d93077510acfe3045fffb0c2473 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 28 Sep 2022 22:40:17 +0100 Subject: [PATCH 11/26] Change: Use RectPadding Horizontal()/Vertical() helpers. --- src/network/network_gui.cpp | 2 +- src/newgrf_gui.cpp | 32 +++++++++++++------------- src/toolbar_gui.cpp | 4 ++-- src/widget.cpp | 46 ++++++++++++++++++------------------- src/widget_type.h | 10 ++++++++ 5 files changed, 52 insertions(+), 42 deletions(-) diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index b618b763a3..8f1f82d551 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -126,7 +126,7 @@ public: /* First initialise some variables... */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical()); } /* ... then in a second pass make sure the 'current' sizes are set. Won't change for most widgets. */ diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 01de9fe583..73601502f1 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -1613,13 +1613,13 @@ public: this->acs->SetupSmallestSize(w, init_array); this->inf->SetupSmallestSize(w, init_array); - uint min_avs_width = this->avs->smallest_x + this->avs->padding.left + this->avs->padding.right; - uint min_acs_width = this->acs->smallest_x + this->acs->padding.left + this->acs->padding.right; - uint min_inf_width = this->inf->smallest_x + this->inf->padding.left + this->inf->padding.right; + uint min_avs_width = this->avs->smallest_x + this->avs->padding.Horizontal(); + uint min_acs_width = this->acs->smallest_x + this->acs->padding.Horizontal(); + uint min_inf_width = this->inf->smallest_x + this->inf->padding.Horizontal(); - uint min_avs_height = this->avs->smallest_y + this->avs->padding.top + this->avs->padding.bottom; - uint min_acs_height = this->acs->smallest_y + this->acs->padding.top + this->acs->padding.bottom; - uint min_inf_height = this->inf->smallest_y + this->inf->padding.top + this->inf->padding.bottom; + uint min_avs_height = this->avs->smallest_y + this->avs->padding.Vertical(); + uint min_acs_height = this->acs->smallest_y + this->acs->padding.Vertical(); + uint min_inf_height = this->inf->smallest_y + this->inf->padding.Vertical(); /* Smallest window is in two column mode. */ this->smallest_x = std::max(min_avs_width, min_acs_width) + INTER_COLUMN_SPACING + min_inf_width; @@ -1649,9 +1649,9 @@ public: { this->StoreSizePosition(sizing, x, y, given_width, given_height); - uint min_avs_width = this->avs->smallest_x + this->avs->padding.left + this->avs->padding.right; - uint min_acs_width = this->acs->smallest_x + this->acs->padding.left + this->acs->padding.right; - uint min_inf_width = this->inf->smallest_x + this->inf->padding.left + this->inf->padding.right; + uint min_avs_width = this->avs->smallest_x + this->avs->padding.Horizontal(); + uint min_acs_width = this->acs->smallest_x + this->acs->padding.Horizontal(); + uint min_inf_width = this->inf->smallest_x + this->inf->padding.Horizontal(); uint min_list_width = std::max(min_avs_width, min_acs_width); // Smallest width of the lists such that they have equal width (incl padding). uint avs_extra_width = min_list_width - min_avs_width; // Additional width needed for avs to reach min_list_width. @@ -1687,10 +1687,10 @@ public: avs_width = ComputeMaxSize(this->avs->smallest_x, this->avs->smallest_x + avs_width, this->avs->GetHorizontalStepSize(sizing)); uint acs_width = given_width - // Remaining space, including horizontal padding. - inf_width - this->inf->padding.left - this->inf->padding.right - - avs_width - this->avs->padding.left - this->avs->padding.right - 2 * INTER_COLUMN_SPACING; + inf_width - this->inf->padding.Horizontal() - + avs_width - this->avs->padding.Horizontal() - 2 * INTER_COLUMN_SPACING; acs_width = ComputeMaxSize(min_acs_width, acs_width, this->acs->GetHorizontalStepSize(sizing)) - - this->acs->padding.left - this->acs->padding.right; + this->acs->padding.Horizontal(); /* Never use fill_y on these; the minimal size is chosen, so that the 3 column view looks nice */ uint avs_height = ComputeMaxSize(this->avs->smallest_y, given_height, this->avs->resize_y); @@ -1726,8 +1726,8 @@ public: uint acs_width = ComputeMaxSize(this->acs->smallest_x, this->acs->smallest_x + acs_extra_width + extra_width, this->acs->GetHorizontalStepSize(sizing)); - uint min_avs_height = (!this->editable) ? 0 : this->avs->smallest_y + this->avs->padding.top + this->avs->padding.bottom + INTER_LIST_SPACING; - uint min_acs_height = this->acs->smallest_y + this->acs->padding.top + this->acs->padding.bottom; + uint min_avs_height = (!this->editable) ? 0 : this->avs->smallest_y + this->avs->padding.Vertical() + INTER_LIST_SPACING; + uint min_acs_height = this->acs->smallest_y + this->acs->padding.Vertical(); uint extra_height = given_height - min_acs_height - min_avs_height; /* Never use fill_y on these; instead use the INTER_LIST_SPACING as filler */ @@ -1754,9 +1754,9 @@ public: } else { this->avs->AssignSizePosition(sizing, 0, 0, this->avs->smallest_x, this->avs->smallest_y, rtl); } - uint dx = this->acs->current_x + this->acs->padding.left + this->acs->padding.right; + uint dx = this->acs->current_x + this->acs->padding.Horizontal(); if (this->editable) { - dx = std::max(dx, this->avs->current_x + this->avs->padding.left + this->avs->padding.right); + dx = std::max(dx, this->avs->current_x + this->avs->padding.Horizontal()); } x += dx + INTER_COLUMN_SPACING + this->inf->padding.left; this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl); diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 5d9af5a538..6fe6a82f94 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -1354,10 +1354,10 @@ public: /* First initialise some variables... */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical()); if (this->IsButton(child_wid->type)) { nbuttons++; - this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.left + child_wid->padding.right); + this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal()); } else if (child_wid->type == NWID_SPACER) { this->spacers++; } diff --git a/src/widget.cpp b/src/widget.cpp index eaffe1125f..22097daf44 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -1124,8 +1124,8 @@ void NWidgetStacked::SetupSmallestSize(Window *w, bool init_array) for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); - this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.left + child_wid->padding.right); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom); + this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal()); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical()); this->fill_x = LeastCommonMultiple(this->fill_x, child_wid->fill_x); this->fill_y = LeastCommonMultiple(this->fill_y, child_wid->fill_y); this->resize_x = LeastCommonMultiple(this->resize_x, child_wid->resize_x); @@ -1142,11 +1142,11 @@ void NWidgetStacked::AssignSizePosition(SizingType sizing, uint x, uint y, uint for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { uint hor_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetHorizontalStepSize(sizing); - uint child_width = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding.left - child_wid->padding.right, hor_step); + uint child_width = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding.Horizontal(), hor_step); uint child_pos_x = (rtl ? child_wid->padding.right : child_wid->padding.left); uint vert_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetVerticalStepSize(sizing); - uint child_height = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding.top - child_wid->padding.bottom, vert_step); + uint child_height = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding.Vertical(), vert_step); uint child_pos_y = child_wid->padding.top; child_wid->AssignSizePosition(sizing, x + child_pos_x, y + child_pos_y, child_width, child_height, rtl); @@ -1269,7 +1269,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) child_wid->SetupSmallestSize(w, init_array); longest = std::max(longest, child_wid->smallest_x); max_vert_fill = std::max(max_vert_fill, child_wid->GetVerticalStepSize(ST_SMALLEST)); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical()); } /* 1b. Make the container higher if needed to accommodate all children nicely. */ [[maybe_unused]] uint max_smallest = this->smallest_y + 3 * max_vert_fill; // Upper limit to computing smallest height. @@ -1277,7 +1277,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) for (;;) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { uint step_size = child_wid->GetVerticalStepSize(ST_SMALLEST); - uint child_height = child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom; + uint child_height = child_wid->smallest_y + child_wid->padding.Vertical(); if (step_size > 1 && child_height < cur_height) { // Small step sizes or already fitting children are not interesting. uint remainder = (cur_height - child_height) % step_size; if (remainder > 0) { // Child did not fit entirely, widen the container. @@ -1305,7 +1305,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) child_wid->padding.right += this->pip_post; } - this->smallest_x += child_wid->smallest_x + child_wid->padding.left + child_wid->padding.right; + this->smallest_x += child_wid->smallest_x + child_wid->padding.Horizontal(); if (child_wid->fill_x > 0) { if (this->fill_x == 0 || this->fill_x > child_wid->fill_x) this->fill_x = child_wid->fill_x; } @@ -1329,7 +1329,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) { /* For EQUALSIZE containers this does not sum to smallest_x during initialisation */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { - additional_length -= child_wid->smallest_x + child_wid->padding.right + child_wid->padding.left; + additional_length -= child_wid->smallest_x + child_wid->padding.Horizontal(); } } else { additional_length -= this->smallest_x; @@ -1363,7 +1363,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui } uint vert_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetVerticalStepSize(sizing); - child_wid->current_y = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding.top - child_wid->padding.bottom, vert_step); + child_wid->current_y = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding.Vertical(), vert_step); } /* First.5 loop: count how many children are of the biggest step size. */ @@ -1415,7 +1415,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui uint child_y = y + child_wid->padding.top; child_wid->AssignSizePosition(sizing, child_x, child_y, child_width, child_wid->current_y, rtl); - uint padded_child_width = child_width + child_wid->padding.right + child_wid->padding.left; + uint padded_child_width = child_width + child_wid->padding.Horizontal(); position = rtl ? position - padded_child_width : position + padded_child_width; child_wid = child_wid->next; @@ -1454,7 +1454,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) child_wid->SetupSmallestSize(w, init_array); highest = std::max(highest, child_wid->smallest_y); max_hor_fill = std::max(max_hor_fill, child_wid->GetHorizontalStepSize(ST_SMALLEST)); - this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.left + child_wid->padding.right); + this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal()); } /* 1b. Make the container wider if needed to accommodate all children nicely. */ [[maybe_unused]] uint max_smallest = this->smallest_x + 3 * max_hor_fill; // Upper limit to computing smallest height. @@ -1462,7 +1462,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) for (;;) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { uint step_size = child_wid->GetHorizontalStepSize(ST_SMALLEST); - uint child_width = child_wid->smallest_x + child_wid->padding.left + child_wid->padding.right; + uint child_width = child_wid->smallest_x + child_wid->padding.Horizontal(); if (step_size > 1 && child_width < cur_width) { // Small step sizes or already fitting children are not interesting. uint remainder = (cur_width - child_width) % step_size; if (remainder > 0) { // Child did not fit entirely, widen the container. @@ -1490,7 +1490,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) child_wid->padding.bottom += this->pip_post; } - this->smallest_y += child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom; + this->smallest_y += child_wid->smallest_y + child_wid->padding.Vertical(); if (child_wid->fill_y > 0) { if (this->fill_y == 0 || this->fill_y > child_wid->fill_y) this->fill_y = child_wid->fill_y; } @@ -1514,7 +1514,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) { /* For EQUALSIZE containers this does not sum to smallest_y during initialisation */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { - additional_length -= child_wid->smallest_y + child_wid->padding.top + child_wid->padding.bottom; + additional_length -= child_wid->smallest_y + child_wid->padding.Vertical(); } } else { additional_length -= this->smallest_y; @@ -1539,7 +1539,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint } uint hor_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetHorizontalStepSize(sizing); - child_wid->current_x = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding.left - child_wid->padding.right, hor_step); + child_wid->current_x = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding.Horizontal(), hor_step); } /* First.5 loop: count how many children are of the biggest step size. */ @@ -1589,7 +1589,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint uint child_height = child_wid->current_y; child_wid->AssignSizePosition(sizing, child_x, y + position + child_wid->padding.top, child_wid->current_x, child_height, rtl); - position += child_height + child_wid->padding.top + child_wid->padding.bottom; + position += child_height + child_wid->padding.Vertical(); } } @@ -1950,8 +1950,8 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array) this->child->padding.top = std::max((int)WD_FRAMETEXT_TOP, this->widget_data != STR_NULL ? FONT_HEIGHT_NORMAL + WD_FRAMETEXT_TOP / 2 : 0); this->child->padding.bottom = WD_FRAMETEXT_BOTTOM; - this->smallest_x += this->child->padding.left + this->child->padding.right; - this->smallest_y += this->child->padding.top + this->child->padding.bottom; + this->smallest_x += this->child->padding.Horizontal(); + this->smallest_y += this->child->padding.Vertical(); if (this->index >= 0) w->SetStringParameters(this->index); this->smallest_x = std::max(this->smallest_x, GetStringBoundingBox(this->widget_data).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT); @@ -1962,8 +1962,8 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array) this->child->padding.top = WD_BEVEL_TOP; this->child->padding.bottom = WD_BEVEL_BOTTOM; - this->smallest_x += this->child->padding.left + this->child->padding.right; - this->smallest_y += this->child->padding.top + this->child->padding.bottom; + this->smallest_x += this->child->padding.Horizontal(); + this->smallest_y += this->child->padding.Vertical(); } } else { Dimension d = {this->min_x, this->min_y}; @@ -1996,8 +1996,8 @@ void NWidgetBackground::AssignSizePosition(SizingType sizing, uint x, uint y, ui if (this->child != nullptr) { uint x_offset = (rtl ? this->child->padding.right : this->child->padding.left); - uint width = given_width - this->child->padding.right - this->child->padding.left; - uint height = given_height - this->child->padding.top - this->child->padding.bottom; + uint width = given_width - this->child->padding.Horizontal(); + uint height = given_height - this->child->padding.Vertical(); this->child->AssignSizePosition(sizing, x + x_offset, y + this->child->padding.top, width, height, rtl); } } @@ -2927,7 +2927,7 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, } case WPT_PADDING: - if (*dest != nullptr) (*dest)->SetPadding(parts->u.padding.top, parts->u.padding.right, parts->u.padding.bottom, parts->u.padding.left); + if (*dest != nullptr) (*dest)->SetPadding(parts->u.padding); break; case WPT_PIPSPACE: { diff --git a/src/widget_type.h b/src/widget_type.h index d11dbc8796..416ce35429 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -156,6 +156,16 @@ public: this->AdjustPaddingForZoom(); } + /** + * Set additional space (padding) around the widget. + * @param padding Amount of padding around the widget. + */ + inline void SetPadding(const RectPadding &padding) + { + this->uz_padding = padding; + this->AdjustPaddingForZoom(); + } + inline uint GetHorizontalStepSize(SizingType sizing) const; inline uint GetVerticalStepSize(SizingType sizing) const; From 47f4fc6a709e2883566b344882c655898a44a902 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 23 Sep 2022 19:50:25 +0100 Subject: [PATCH 12/26] Add: NWidgetPart SetPadding via RectPadding --- src/widget_type.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/widget_type.h b/src/widget_type.h index 416ce35429..1e6cdaf6b8 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -1153,6 +1153,24 @@ static inline NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 return part; } +/** + * Widget part function for setting additional space around a widget. + * @param r The padding around the widget. + * @ingroup NestedWidgetParts + */ +static inline NWidgetPart SetPadding(const RectPadding &padding) +{ + NWidgetPart part; + + part.type = WPT_PADDING; + part.u.padding.left = padding.left; + part.u.padding.top = padding.top; + part.u.padding.right = padding.right; + part.u.padding.bottom = padding.bottom; + + return part; +} + /** * Widget part function for setting a padding. * @param padding The padding to use for all directions. From 68423c40c52adbe6cf189003a6fe1fe7fab3f78d Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 1 Oct 2022 22:47:57 +0100 Subject: [PATCH 13/26] Fix: Off-by-one in GetAlignedPosition(). --- src/widget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widget.cpp b/src/widget.cpp index 22097daf44..d1ff668b96 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -39,13 +39,13 @@ static inline Point GetAlignedPosition(const Rect &r, const Dimension &d, String switch (align & SA_HOR_MASK) { case SA_LEFT: p.x = r.left; break; case SA_HOR_CENTER: p.x = CenterBounds(r.left, r.right, d.width); break; - case SA_RIGHT: p.x = r.right - d.width; break; + case SA_RIGHT: p.x = r.right + 1 - d.width; break; default: NOT_REACHED(); } switch (align & SA_VERT_MASK) { case SA_TOP: p.y = r.top; break; case SA_VERT_CENTER: p.y = CenterBounds(r.top, r.bottom, d.height); break; - case SA_BOTTOM: p.y = r.bottom - d.height; break; + case SA_BOTTOM: p.y = r.bottom + 1 - d.height; break; default: NOT_REACHED(); } return p; From 0108e9f3874d0ab670c6a14bc9f296a63d14c798 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 9 Sep 2022 17:40:35 +0100 Subject: [PATCH 14/26] Change: Set up suggested widget padding for panel, frame and inset. Window handlers are free to ignore the suggested padding, however some handlers have logic that assumes this information was already provided. --- src/widget.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/widget.cpp b/src/widget.cpp index d1ff668b96..f5e0cb9f69 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -1977,7 +1977,14 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array) d = maxdim(d, background); } if (this->index >= 0) { - static const Dimension padding = {0, 0}; + /* Setup suggested padding for widgets. */ + Dimension padding = {0, 0}; + switch (this->type) { + default: NOT_REACHED(); + case WWT_PANEL: padding = {WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM}; break; + case WWT_FRAME: padding = {WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM}; break; + case WWT_INSET: padding = {WD_INSET_LEFT + WD_INSET_RIGHT, WD_INSET_TOP + WD_BEVEL_BOTTOM}; break; + } w->UpdateWidgetSize(this->index, &d, padding, &fill, &resize); } } From b6ed5951769253aeeea174696f07e3b5d387484b Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 3 May 2021 16:56:02 +0100 Subject: [PATCH 15/26] Codechange: Prefer suggested widget padding. --- src/ai/ai_gui.cpp | 6 +++--- src/airport_gui.cpp | 8 +++++--- src/autoreplace_gui.cpp | 4 ++-- src/game/game_gui.cpp | 4 ++-- src/genworld_gui.cpp | 2 +- src/industry_gui.cpp | 6 +++--- src/linkgraph/linkgraph_gui.cpp | 8 ++++---- src/misc_gui.cpp | 4 ++-- src/music_gui.cpp | 8 ++++---- src/network/network_content_gui.cpp | 2 +- src/newgrf_debug_gui.cpp | 2 +- src/newgrf_gui.cpp | 4 ++-- src/object_gui.cpp | 2 +- src/order_gui.cpp | 2 +- src/rail_gui.cpp | 2 +- src/station_gui.cpp | 2 +- src/subsidy_gui.cpp | 4 ++-- src/tree_gui.cpp | 4 ++-- 18 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index cd442d9fd6..f15c265335 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -112,7 +112,7 @@ struct AIListWindow : public Window { void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_AIL_LIST) { - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = FONT_HEIGHT_NORMAL + padding.height; resize->width = 1; resize->height = this->line_height; @@ -342,7 +342,7 @@ struct AISettingsWindow : public Window { void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_AIS_BACKGROUND) { - this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + padding.height; resize->width = 1; resize->height = this->line_height; @@ -761,7 +761,7 @@ struct AIConfigWindow : public Window { break; case WID_AIC_LIST: - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = FONT_HEIGHT_NORMAL + padding.height; resize->height = this->line_height; size->height = 8 * this->line_height; break; diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 12eeb894e7..b182127353 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -343,7 +343,7 @@ public: size->width = std::max(size->width, GetStringBoundingBox(as->name).width); } - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = FONT_HEIGHT_NORMAL + padding.height; size->height = 5 * this->line_height; break; } @@ -356,8 +356,8 @@ public: SpriteID sprite = GetCustomAirportSprite(as, layout); if (sprite != 0) { Dimension d = GetSpriteSize(sprite); - d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += padding.width; + d.height += padding.height; *size = maxdim(d, *size); } } @@ -375,6 +375,8 @@ public: /* STR_BLACK_STRING is used to start the string with {BLACK} */ SetDParam(0, string); Dimension d = GetStringMultiLineBoundingBox(STR_BLACK_STRING, *size); + d.width += padding.width; + d.height += padding.height; *size = maxdim(d, *size); } } diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 186000ccd7..8ca396ca56 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -304,8 +304,8 @@ public: case WID_RV_INFO_TAB: { Dimension d = GetStringBoundingBox(STR_REPLACE_NOT_REPLACING); d = maxdim(d, GetStringBoundingBox(STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED)); - d.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; - d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += padding.width; + d.height += padding.height; *size = maxdim(*size, d); break; } diff --git a/src/game/game_gui.cpp b/src/game/game_gui.cpp index e6d482ced9..91cafc925a 100644 --- a/src/game/game_gui.cpp +++ b/src/game/game_gui.cpp @@ -152,14 +152,14 @@ struct GSConfigWindow : public Window { { switch (widget) { case WID_GSC_SETTINGS: - this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + padding.height; resize->width = 1; resize->height = this->line_height; size->height = 5 * this->line_height; break; case WID_GSC_GSLIST: - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = FONT_HEIGHT_NORMAL + padding.height; size->height = 1 * this->line_height; break; } diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index a33a7fa34b..7b0f07f16b 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -662,7 +662,7 @@ struct GenerateLandscapeWindow : public Window { } } size->width += padding.width; - size->height = std::max(size->height, (uint)(FONT_HEIGHT_NORMAL + WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM)); + size->height = std::max(size->height, (uint)(FONT_HEIGHT_NORMAL + padding.height)); } void OnClick(Point pt, int widget, int click_count) override diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 6e8205fd02..337776c3ad 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -422,7 +422,7 @@ public: if (this->index[i] == INVALID_INDUSTRYTYPE) continue; d = maxdim(d, GetStringBoundingBox(GetIndustrySpec(this->index[i])->name)); } - resize->height = std::max(this->legend.height, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + resize->height = std::max(this->legend.height, FONT_HEIGHT_NORMAL) + padding.height; d.width += this->legend.width + ScaleFontTrad(7) + padding.width; d.height = 5 * resize->height; *size = maxdim(*size, d); @@ -471,8 +471,8 @@ public: /* Set it to something more sane :) */ height += extra_lines_prd + extra_lines_req + extra_lines_newgrf; - size->height = height * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; - size->width = d.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + size->height = height * FONT_HEIGHT_NORMAL + padding.height; + size->width = d.width + padding.width; break; } diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index 84d5eaea5c..44c96aa531 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -592,8 +592,8 @@ void LinkGraphLegendWindow::UpdateWidgetSize(int widget, Dimension *size, const } if (str != STR_NULL) { Dimension dim = GetStringBoundingBox(str); - dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + dim.width += padding.width; + dim.height += padding.height; *size = maxdim(*size, dim); } } @@ -601,8 +601,8 @@ void LinkGraphLegendWindow::UpdateWidgetSize(int widget, Dimension *size, const CargoSpec *cargo = CargoSpec::Get(widget - WID_LGL_CARGO_FIRST); if (cargo->IsValid()) { Dimension dim = GetStringBoundingBox(cargo->abbrev); - dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + dim.width += padding.width; + dim.height += padding.height; *size = maxdim(*size, dim); } } diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 3c59414ae9..a7f7d79d8e 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -721,8 +721,8 @@ struct TooltipsWindow : public Window size->height = GetStringHeight(this->string_id, size->width); /* Increase slightly to have some space around the box. */ - size->width += 2 + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - size->height += 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + size->width += 2 + padding.width; + size->height += 2 + padding.height; } void DrawWidget(const Rect &r, int widget) const override diff --git a/src/music_gui.cpp b/src/music_gui.cpp index d7f6a41200..edfccf5766 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -682,8 +682,8 @@ struct MusicWindow : public Window { case WID_M_TRACK_NR: { Dimension d = GetStringBoundingBox(STR_MUSIC_TRACK_NONE); - d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += padding.width; + d.height += padding.height; *size = maxdim(*size, d); break; } @@ -694,8 +694,8 @@ struct MusicWindow : public Window { SetDParamStr(0, song->songname); d = maxdim(d, GetStringBoundingBox(STR_MUSIC_TITLE_NAME)); } - d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += padding.width; + d.height += padding.height; *size = maxdim(*size, d); break; } diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 255d1b8083..b1e022c8ed 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -573,7 +573,7 @@ public: } case WID_NCL_MATRIX: - resize->height = std::max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + resize->height = std::max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL) + padding.height; size->height = 10 * resize->height; break; } diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index da6ab7ba5f..ab8efcffb8 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -859,7 +859,7 @@ struct SpriteAlignerWindow : Window { size->height = ScaleGUITrad(200); break; case WID_SA_LIST: - resize->height = FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + resize->height = FONT_HEIGHT_NORMAL + padding.height; resize->width = 1; fill->height = resize->height; break; diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 73601502f1..2ff58e8077 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -732,13 +732,13 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { { Dimension d = maxdim(GetSpriteSize(SPR_SQUARE), GetSpriteSize(SPR_WARNING_SIGN)); resize->height = std::max(d.height + 2U, FONT_HEIGHT_NORMAL + 2U); - size->height = std::max(size->height, WD_FRAMERECT_TOP + 6 * resize->height + WD_FRAMERECT_BOTTOM); + size->height = std::max(size->height, padding.height + 6 * resize->height); break; } case WID_NS_AVAIL_LIST: resize->height = std::max(12, FONT_HEIGHT_NORMAL + 2); - size->height = std::max(size->height, WD_FRAMERECT_TOP + 8 * resize->height + WD_FRAMERECT_BOTTOM); + size->height = std::max(size->height, padding.height + 8 * resize->height); break; case WID_NS_NEWGRF_INFO_TITLE: { diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 083292a87f..98ece0e9d6 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -239,7 +239,7 @@ public: size->width = std::max(size->width, GetStringBoundingBox(objclass->name).width); } size->width += padding.width; - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = FONT_HEIGHT_NORMAL + padding.height; resize->height = this->line_height; size->height = 5 * this->line_height; break; diff --git a/src/order_gui.cpp b/src/order_gui.cpp index adc38625ea..2af9c14285 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -793,7 +793,7 @@ public: switch (widget) { case WID_O_ORDER_LIST: resize->height = FONT_HEIGHT_NORMAL; - size->height = 6 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + size->height = 6 * resize->height + padding.height; break; case WID_O_COND_VARIABLE: { diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index a41366fb09..e460672b1f 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1201,7 +1201,7 @@ public: d = maxdim(d, GetStringBoundingBox(StationClass::Get(station_class)->name)); } size->width = std::max(size->width, d.width + padding.width); - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = FONT_HEIGHT_NORMAL + padding.height; size->height = 5 * this->line_height; resize->height = this->line_height; break; diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 38a4c7a2ca..5e911c0fbd 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -392,7 +392,7 @@ public: case WID_STL_LIST: resize->height = std::max(FONT_HEIGHT_NORMAL, FONT_HEIGHT_SMALL + ScaleFontTrad(3)); - size->height = WD_FRAMERECT_TOP + 5 * resize->height + WD_FRAMERECT_BOTTOM; + size->height = padding.height + 5 * resize->height; /* Determine appropriate width for mini station rating graph */ this->rating_width = 0; diff --git a/src/subsidy_gui.cpp b/src/subsidy_gui.cpp index 90d78e4bed..8e3dd82dc7 100644 --- a/src/subsidy_gui.cpp +++ b/src/subsidy_gui.cpp @@ -133,8 +133,8 @@ struct SubsidyListWindow : Window { resize->height = d.height; d.height *= 5; - d.width += padding.width + WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT; - d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += padding.width; + d.height += padding.height; *size = maxdim(*size, d); } diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index 81c2d4e43a..e37da43114 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -159,8 +159,8 @@ public: if (widget >= WID_BT_TYPE_BUTTON_FIRST) { /* Ensure tree type buttons are sized after the largest tree type */ Dimension d = GetMaxTreeSpriteSize(); - size->width = d.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - size->height = d.height + WD_FRAMERECT_RIGHT + WD_FRAMERECT_BOTTOM + ScaleGUITrad(BUTTON_BOTTOM_OFFSET); // we need some more space + size->width = d.width + padding.width; + size->height = d.height + padding.height + ScaleGUITrad(BUTTON_BOTTOM_OFFSET); // we need some more space } } From b5693becdc342f09b16895fe7d4ac177bca26530 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 28 Sep 2022 18:02:14 +0100 Subject: [PATCH 16/26] Add: Define scaled WidgetDimensions. Includes RectPadding container. --- src/widget.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++--- src/widget_type.h | 2 ++ src/window.cpp | 1 + src/window_gui.h | 30 +++++++++++++++++ 4 files changed, 113 insertions(+), 4 deletions(-) diff --git a/src/widget.cpp b/src/widget.cpp index f5e0cb9f69..e864846ae8 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -24,6 +24,85 @@ #include "safeguards.h" +const WidgetDimensions WidgetDimensions::unscaled = { + {WD_IMGBTN_LEFT, WD_IMGBTN_TOP, WD_IMGBTN_RIGHT, WD_IMGBTN_BOTTOM}, ///< imgbtn + {WD_INSET_LEFT, WD_INSET_TOP, WD_INSET_RIGHT, WD_BEVEL_BOTTOM}, ///< inset + {WD_SCROLLBAR_LEFT, WD_SCROLLBAR_TOP, WD_SCROLLBAR_RIGHT, WD_SCROLLBAR_BOTTOM}, ///< scrollbar + {WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM}, ///< bevel + {WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM}, ///< fullbevel + {WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM}, ///< framerect + {WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM}, ///< frametext + {WD_FRAMETEXT_LEFT, WD_TEXTPANEL_TOP, WD_FRAMETEXT_RIGHT, WD_TEXTPANEL_BOTTOM}, ///< textpanel + {WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM}, ///< matrix + {WD_SHADEBOX_LEFT, WD_SHADEBOX_TOP, WD_SHADEBOX_RIGHT, WD_SHADEBOX_BOTTOM}, ///< shadebox + {WD_STICKYBOX_LEFT, WD_STICKYBOX_TOP, WD_STICKYBOX_RIGHT, WD_STICKYBOX_BOTTOM}, ///< stickybox + {WD_DEBUGBOX_LEFT, WD_DEBUGBOX_TOP, WD_DEBUGBOX_RIGHT, WD_DEBUGBOX_BOTTOM}, ///< debugbox + {WD_DEFSIZEBOX_LEFT, WD_DEFSIZEBOX_TOP, WD_DEFSIZEBOX_RIGHT, WD_DEFSIZEBOX_BOTTOM}, ///< defsizebox + {WD_RESIZEBOX_LEFT, WD_RESIZEBOX_TOP, WD_RESIZEBOX_RIGHT, WD_RESIZEBOX_BOTTOM}, ///< resizebox + {WD_CLOSEBOX_LEFT, WD_CLOSEBOX_TOP, WD_CLOSEBOX_RIGHT, WD_CLOSEBOX_BOTTOM}, ///< closebox + {WD_CAPTIONTEXT_LEFT, WD_CAPTIONTEXT_TOP, WD_CAPTIONTEXT_RIGHT, WD_CAPTIONTEXT_BOTTOM}, ///< captiontext + {WD_DROPDOWNTEXT_LEFT, WD_DROPDOWNTEXT_TOP, WD_DROPDOWNTEXT_RIGHT, WD_DROPDOWNTEXT_BOTTOM}, ///< dropdowntext + 1, ///< pressed + WD_PAR_VSEP_NORMAL, ///< vsep_normal + WD_PAR_VSEP_WIDE, ///< vsep_wide + 2, ///< hsep_normal + 6, ///< hsep_wide + 10, ///< hsep_indent +}; + +WidgetDimensions WidgetDimensions::scaled = {}; + +/** + * Scale a RectPadding to GUI zoom level. + * @param r RectPadding at ZOOM_LVL_BASE (traditional "normal" interface size). + * @return RectPadding at #ZOOM_LVL_GUI (current interface size). + */ +static inline RectPadding ScaleGUITrad(const RectPadding &r) +{ + return {(uint8)ScaleGUITrad(r.left), (uint8)ScaleGUITrad(r.top), (uint8)ScaleGUITrad(r.right), (uint8)ScaleGUITrad(r.bottom)}; +} + +/** + * Scale a Dimension to GUI zoom level. + * @param d Dimension at ZOOM_LVL_BASE (traditional "normal" interface size). + * @return Dimension at #ZOOM_LVL_GUI (current interface size). + */ +static inline Dimension ScaleGUITrad(const Dimension &dim) +{ + return {(uint)ScaleGUITrad(dim.width), (uint)ScaleGUITrad(dim.height)}; +} + +/** + * Set up pre-scaled versions of Widget Dimensions. + */ +void SetupWidgetDimensions() +{ + WidgetDimensions::scaled.imgbtn = ScaleGUITrad(WidgetDimensions::unscaled.imgbtn); + WidgetDimensions::scaled.inset = ScaleGUITrad(WidgetDimensions::unscaled.inset); + WidgetDimensions::scaled.scrollbar = ScaleGUITrad(WidgetDimensions::unscaled.scrollbar); + WidgetDimensions::scaled.bevel = WidgetDimensions::unscaled.bevel; + WidgetDimensions::scaled.fullbevel = ScaleGUITrad(WidgetDimensions::unscaled.fullbevel); + WidgetDimensions::scaled.framerect = ScaleGUITrad(WidgetDimensions::unscaled.framerect); + WidgetDimensions::scaled.frametext = ScaleGUITrad(WidgetDimensions::unscaled.frametext); + WidgetDimensions::scaled.textpanel = ScaleGUITrad(WidgetDimensions::unscaled.textpanel); + WidgetDimensions::scaled.matrix = ScaleGUITrad(WidgetDimensions::unscaled.matrix); + WidgetDimensions::scaled.shadebox = ScaleGUITrad(WidgetDimensions::unscaled.shadebox); + WidgetDimensions::scaled.stickybox = ScaleGUITrad(WidgetDimensions::unscaled.stickybox); + WidgetDimensions::scaled.debugbox = ScaleGUITrad(WidgetDimensions::unscaled.debugbox); + WidgetDimensions::scaled.defsizebox = ScaleGUITrad(WidgetDimensions::unscaled.defsizebox); + WidgetDimensions::scaled.resizebox = ScaleGUITrad(WidgetDimensions::unscaled.resizebox); + WidgetDimensions::scaled.closebox = ScaleGUITrad(WidgetDimensions::unscaled.closebox); + WidgetDimensions::scaled.captiontext = ScaleGUITrad(WidgetDimensions::unscaled.captiontext); + WidgetDimensions::scaled.dropdowntext = ScaleGUITrad(WidgetDimensions::unscaled.dropdowntext); + + WidgetDimensions::scaled.pressed = ScaleGUITrad(WidgetDimensions::unscaled.pressed); + WidgetDimensions::scaled.vsep_normal = ScaleGUITrad(WidgetDimensions::unscaled.vsep_normal); + WidgetDimensions::scaled.vsep_wide = ScaleGUITrad(WidgetDimensions::unscaled.vsep_wide); + WidgetDimensions::scaled.hsep_normal = ScaleGUITrad(WidgetDimensions::unscaled.hsep_normal); + WidgetDimensions::scaled.hsep_wide = ScaleGUITrad(WidgetDimensions::unscaled.hsep_wide); + WidgetDimensions::scaled.hsep_indent = ScaleGUITrad(WidgetDimensions::unscaled.hsep_indent); +} + /** * Calculate x and y coordinates for an aligned object within a window. * @param r Rectangle of the widget to be drawn in. @@ -831,10 +910,7 @@ NWidgetBase *NWidgetBase::GetWidgetOfType(WidgetType tp) void NWidgetBase::AdjustPaddingForZoom() { - this->padding.left = ScaleGUITrad(this->uz_padding.left); - this->padding.top = ScaleGUITrad(this->uz_padding.top); - this->padding.right = ScaleGUITrad(this->uz_padding.right); - this->padding.bottom = ScaleGUITrad(this->uz_padding.bottom); + this->padding = ScaleGUITrad(this->uz_padding); } /** diff --git a/src/widget_type.h b/src/widget_type.h index 1e6cdaf6b8..8c05a321f7 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -1273,4 +1273,6 @@ NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int widget_last, Colours button_colour, int max_length, StringID button_tooltip); +void SetupWidgetDimensions(); + #endif /* WIDGET_TYPE_H */ diff --git a/src/window.cpp b/src/window.cpp index 3cda423f37..7b121cca57 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -3356,6 +3356,7 @@ void ReInitWindow(Window *w, bool zoom_changed) /** Re-initialize all windows. */ void ReInitAllWindows(bool zoom_changed) { + SetupWidgetDimensions(); NWidgetLeaf::InvalidateDimensionCache(); // Reset cached sizes of several widgets. NWidgetScrollbar::InvalidateDimensionCache(); diff --git a/src/window_gui.h b/src/window_gui.h index 25b962f411..6dd1132932 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -34,6 +34,36 @@ enum FrameFlags { DECLARE_ENUM_AS_BIT_SET(FrameFlags) +struct WidgetDimensions { + RectPadding imgbtn; + RectPadding inset; + RectPadding scrollbar; + RectPadding bevel; ///< Widths of bevel border. + RectPadding fullbevel; ///< Always-scaled bevel border. + RectPadding framerect; ///< Offsets within frame area. + RectPadding frametext; ///< Offsets within a text frame area. + RectPadding textpanel; ///< Text panel? + RectPadding matrix; ///< Offsets within a matrix cell. + RectPadding shadebox; + RectPadding stickybox; + RectPadding debugbox; + RectPadding defsizebox; + RectPadding resizebox; + RectPadding closebox; + RectPadding captiontext; ///< Offsets of text within a caption. + RectPadding dropdowntext; ///< Offsets of text within a dropdown widget. + + int pressed; ///< Offset for contents of depressed widget. + int vsep_normal; ///< Normal vertical spacing. + int vsep_wide; ///< Wide vertical spacing. + int hsep_normal; ///< Normal horizontal spacing. + int hsep_wide; ///< Wide horizontal spacing. + int hsep_indent; ///< Width of identation for tree layouts. + + static const WidgetDimensions unscaled; ///< Unscaled widget dimensions. + static WidgetDimensions scaled; ///< Widget dimensions scaled for current zoom level. +}; + /** Distances used in drawing widgets. */ enum WidgetDrawDistances { /* WWT_IMGBTN(_2) */ From d0add1e07fee08c570f149f58fe9289e1327b7aa Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 23 Sep 2022 13:35:32 +0100 Subject: [PATCH 17/26] Change: Ignore offsets when drawing GUI sprite. --- src/gfx_func.h | 1 + src/widget.cpp | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/gfx_func.h b/src/gfx_func.h index c4e21792bd..f6018c8a59 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -90,6 +90,7 @@ void RedrawScreenRect(int left, int top, int right, int bottom); void GfxScroll(int left, int top, int width, int height, int xo, int yo); Dimension GetSpriteSize(SpriteID sprid, Point *offset = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI); +Dimension GetScaledSpriteSize(SpriteID sprid); /* widget.cpp */ void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr); void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI); std::unique_ptr DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zoom = ZOOM_LVL_GUI); diff --git a/src/widget.cpp b/src/widget.cpp index e864846ae8..5cee21f4d3 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -72,6 +72,19 @@ static inline Dimension ScaleGUITrad(const Dimension &dim) return {(uint)ScaleGUITrad(dim.width), (uint)ScaleGUITrad(dim.height)}; } +/** + * Scale sprite size for GUI. + * Offset is ignored. + */ +Dimension GetScaledSpriteSize(SpriteID sprid) +{ + Point offset; + Dimension d = GetSpriteSize(sprid, &offset, ZOOM_LVL_OUT_4X); + d.width -= offset.x; + d.height -= offset.y; + return ScaleGUITrad(d); +} + /** * Set up pre-scaled versions of Widget Dimensions. */ @@ -318,6 +331,17 @@ void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, Fra } } +void DrawSpriteIgnorePadding(const Rect &r, SpriteID img, int clicked, StringAlignment align) +{ + Point offset; + Dimension d = GetSpriteSize(img, &offset); + d.width -= offset.x; + d.height -= offset.y; + + Point p = GetAlignedPosition(r, d, align); + DrawSprite(img, PAL_NONE, p.x + clicked - offset.x, p.y + clicked - offset.y); +} + /** * Draw an image button. * @param r Rectangle of the button. @@ -333,9 +357,7 @@ static inline void DrawImageButtons(const Rect &r, WidgetType type, Colours colo DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE); if ((type & WWT_MASK) == WWT_IMGBTN_2 && clicked) img++; // Show different image when clicked for #WWT_IMGBTN_2. - Dimension d = GetSpriteSize(img); - Point p = GetAlignedPosition(r, d, align); - DrawSprite(img, PAL_NONE, p.x + clicked, p.y + clicked); + DrawSpriteIgnorePadding(r, img, clicked, align); } /** @@ -645,9 +667,12 @@ static inline void DrawResizeBox(const Rect &r, Colours colour, bool at_left, bo static inline void DrawCloseBox(const Rect &r, Colours colour) { if (colour != COLOUR_WHITE) DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_NONE); - Dimension d = GetSpriteSize(SPR_CLOSEBOX); - int s = UnScaleGUI(1); /* Offset to account for shadow of SPR_CLOSEBOX */ - DrawSprite(SPR_CLOSEBOX, (colour != COLOUR_WHITE ? TC_BLACK : TC_SILVER) | (1U << PALETTE_TEXT_RECOLOUR), CenterBounds(r.left, r.right, d.width - s), CenterBounds(r.top, r.bottom, d.height - s)); + Point offset; + Dimension d = GetSpriteSize(SPR_CLOSEBOX, &offset); + d.width -= offset.x; + d.height -= offset.y; + int s = ScaleGUITrad(1); /* Offset to account for shadow of SPR_CLOSEBOX */ + DrawSprite(SPR_CLOSEBOX, (colour != COLOUR_WHITE ? TC_BLACK : TC_SILVER) | (1U << PALETTE_TEXT_RECOLOUR), CenterBounds(r.left, r.right, d.width - s) - offset.x, CenterBounds(r.top, r.bottom, d.height - s) - offset.y); } /** From 0bb9a457855c2324ac07227be92a51cb21f96ebf Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 2 Oct 2022 15:16:45 +0100 Subject: [PATCH 18/26] Change: Simplify drawing widget image buttons. --- src/widget.cpp | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/src/widget.cpp b/src/widget.cpp index 5cee21f4d3..5a275d3e6e 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -481,11 +481,8 @@ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_ int height = NWidgetScrollbar::GetVerticalDimension().height; /* draw up/down buttons */ - DrawFrameRect(r.left, r.top, r.right, r.top + height - 1, colour, (up_clicked) ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_UP, PAL_NONE, r.left + 1 + up_clicked, r.top + 1 + up_clicked); - - DrawFrameRect(r.left, r.bottom - (height - 1), r.right, r.bottom, colour, (down_clicked) ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.left + 1 + down_clicked, r.bottom - (height - 2) + down_clicked); + DrawImageButtons(r.WithHeight(height, false), NWID_VSCROLLBAR, colour, up_clicked, SPR_ARROW_UP, SA_CENTER); + DrawImageButtons(r.WithHeight(height, true), NWID_VSCROLLBAR, colour, down_clicked, SPR_ARROW_DOWN, SA_CENTER); int c1 = _colour_gradient[colour & 0xF][3]; int c2 = _colour_gradient[colour & 0xF][7]; @@ -518,11 +515,8 @@ static inline void DrawHorizontalScrollbar(const Rect &r, Colours colour, bool l int centre = (r.bottom - r.top) / 2; int width = NWidgetScrollbar::GetHorizontalDimension().width; - DrawFrameRect(r.left, r.top, r.left + width - 1, r.bottom, colour, left_clicked ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_LEFT, PAL_NONE, r.left + 1 + left_clicked, r.top + 1 + left_clicked); - - DrawFrameRect(r.right - (width - 1), r.top, r.right, r.bottom, colour, right_clicked ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, r.right - (width - 2) + right_clicked, r.top + 1 + right_clicked); + DrawImageButtons(r.WithWidth(width, false), NWID_HSCROLLBAR, colour, left_clicked, SPR_ARROW_LEFT, SA_CENTER); + DrawImageButtons(r.WithWidth(width, true), NWID_HSCROLLBAR, colour, right_clicked, SPR_ARROW_RIGHT, SA_CENTER); int c1 = _colour_gradient[colour & 0xF][3]; int c2 = _colour_gradient[colour & 0xF][7]; @@ -648,15 +642,7 @@ static inline void DrawDebugBox(const Rect &r, Colours colour, bool clicked) static inline void DrawResizeBox(const Rect &r, Colours colour, bool at_left, bool clicked) { DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE); - if (at_left) { - Dimension d = GetSpriteSize(SPR_WINDOW_RESIZE_LEFT); - DrawSprite(SPR_WINDOW_RESIZE_LEFT, PAL_NONE, r.left + WD_RESIZEBOX_RIGHT + clicked, - r.bottom + 1 - WD_RESIZEBOX_BOTTOM - d.height + clicked); - } else { - Dimension d = GetSpriteSize(SPR_WINDOW_RESIZE_RIGHT); - DrawSprite(SPR_WINDOW_RESIZE_RIGHT, PAL_NONE, r.right + 1 - WD_RESIZEBOX_RIGHT - d.width + clicked, - r.bottom + 1 - WD_RESIZEBOX_BOTTOM - d.height + clicked); - } + DrawSpriteIgnorePadding(r.Shrink(ScaleGUITrad(2)), at_left ? SPR_WINDOW_RESIZE_LEFT : SPR_WINDOW_RESIZE_RIGHT, clicked, at_left ? (SA_LEFT | SA_BOTTOM | SA_FORCE) : (SA_RIGHT | SA_BOTTOM | SA_FORCE)); } /** @@ -718,18 +704,14 @@ static inline void DrawButtonDropdown(const Rect &r, Colours colour, bool clicke int text_offset = std::max(0, (r.Height() - FONT_HEIGHT_NORMAL) / 2); // Offset for rendering the text vertically centered int dd_width = NWidgetLeaf::dropdown_dimension.width; - int dd_height = NWidgetLeaf::dropdown_dimension.height; - int image_offset = std::max(0, (r.Height() - dd_height) / 2); if (_current_text_dir == TD_LTR) { DrawFrameRect(r.left, r.top, r.right - dd_width, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE); - DrawFrameRect(r.right + 1 - dd_width, r.top, r.right, r.bottom, colour, clicked_dropdown ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.right - (dd_width - 2) + clicked_dropdown, r.top + image_offset + clicked_dropdown); + DrawImageButtons(r.WithWidth(dd_width, true), WWT_DROPDOWN, colour, clicked_dropdown, SPR_ARROW_DOWN, SA_CENTER); if (str != STR_NULL) DrawString(r.left + WD_DROPDOWNTEXT_LEFT + clicked_button, r.right - dd_width - WD_DROPDOWNTEXT_RIGHT + clicked_button, r.top + text_offset + clicked_button, str, TC_BLACK, align); } else { DrawFrameRect(r.left + dd_width, r.top, r.right, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE); - DrawFrameRect(r.left, r.top, r.left + dd_width - 1, r.bottom, colour, clicked_dropdown ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.left + 1 + clicked_dropdown, r.top + image_offset + clicked_dropdown); + DrawImageButtons(r.WithWidth(dd_width, false), WWT_DROPDOWN, colour, clicked_dropdown, SPR_ARROW_DOWN, SA_CENTER); if (str != STR_NULL) DrawString(r.left + dd_width + WD_DROPDOWNTEXT_LEFT + clicked_button, r.right - WD_DROPDOWNTEXT_RIGHT + clicked_button, r.top + text_offset + clicked_button, str, TC_BLACK, align); } } @@ -776,15 +758,12 @@ void Window::DrawSortButtonState(int widget, SortButtonState state) const if (state == SBS_OFF) return; assert(this->nested_array != nullptr); - const NWidgetBase *nwid = this->GetWidget(widget); + Rect r = this->GetWidget(widget)->GetCurrentRect(); /* Sort button uses the same sprites as vertical scrollbar */ Dimension dim = NWidgetScrollbar::GetVerticalDimension(); - int offset = this->IsWidgetLowered(widget) ? 1 : 0; - int x = offset + nwid->pos_x + (_current_text_dir == TD_LTR ? nwid->current_x - dim.width : 0); - int y = offset + nwid->pos_y + (nwid->current_y - dim.height) / 2; - DrawSprite(state == SBS_DOWN ? SPR_ARROW_DOWN : SPR_ARROW_UP, PAL_NONE, x, y); + DrawSpriteIgnorePadding(r.WithWidth(dim.width, _current_text_dir == TD_LTR), state == SBS_DOWN ? SPR_ARROW_DOWN : SPR_ARROW_UP, this->IsWidgetLowered(widget), SA_CENTER); } /** From 90ce704366e8219cdbd2e9ba768c328e305b438a Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 2 Oct 2022 15:22:00 +0100 Subject: [PATCH 19/26] Change: Use scaled WidgetDimensions for core widgets. --- src/widget.cpp | 318 ++++++++++++++++++++++++------------------------- 1 file changed, 156 insertions(+), 162 deletions(-) diff --git a/src/widget.cpp b/src/widget.cpp index 5a275d3e6e..9acfef7710 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -312,26 +312,29 @@ void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, Fra } else { uint interior; + Rect outer = {left, top, right, bottom}; // Outside rectangle + Rect inner = outer.Shrink(WidgetDimensions::scaled.bevel); // Inside rectangle + if (flags & FR_LOWERED) { - GfxFillRect(left, top, left, bottom, dark); - GfxFillRect(left + WD_BEVEL_LEFT, top, right, top, dark); - GfxFillRect(right, top + WD_BEVEL_TOP, right, bottom - WD_BEVEL_BOTTOM, light); - GfxFillRect(left + WD_BEVEL_LEFT, bottom, right, bottom, light); + GfxFillRect(outer.left, outer.top, inner.left - 1, outer.bottom, dark); // Left + GfxFillRect(inner.left, outer.top, outer.right, inner.top - 1, dark); // Top + GfxFillRect(inner.right + 1, inner.top, outer.right, inner.bottom, light); // Right + GfxFillRect(inner.left, inner.bottom + 1, outer.right, outer.bottom, light); // Bottom interior = (flags & FR_DARKENED ? medium_dark : medium_light); } else { - GfxFillRect(left, top, left, bottom - WD_BEVEL_BOTTOM, light); - GfxFillRect(left + WD_BEVEL_LEFT, top, right - WD_BEVEL_RIGHT, top, light); - GfxFillRect(right, top, right, bottom - WD_BEVEL_BOTTOM, dark); - GfxFillRect(left, bottom, right, bottom, dark); + GfxFillRect(outer.left, outer.top, inner.left - 1, inner.bottom, light); // Left + GfxFillRect(inner.left, outer.top, inner.right, inner.top - 1, light); // Top + GfxFillRect(inner.right + 1, outer.top, outer.right, inner.bottom, dark); // Right + GfxFillRect(outer.left, inner.bottom + 1, outer.right, outer.bottom, dark); // Bottom interior = medium_dark; } if (!(flags & FR_BORDERONLY)) { - GfxFillRect(left + WD_BEVEL_LEFT, top + WD_BEVEL_TOP, right - WD_BEVEL_RIGHT, bottom - WD_BEVEL_BOTTOM, interior); + GfxFillRect(inner.left, inner.top, inner.right, inner.bottom, interior); // Inner } } } -void DrawSpriteIgnorePadding(const Rect &r, SpriteID img, int clicked, StringAlignment align) +void DrawSpriteIgnorePadding(const Rect &r, SpriteID img, bool clicked, StringAlignment align) { Point offset; Dimension d = GetSpriteSize(img, &offset); @@ -339,7 +342,8 @@ void DrawSpriteIgnorePadding(const Rect &r, SpriteID img, int clicked, StringAli d.height -= offset.y; Point p = GetAlignedPosition(r, d, align); - DrawSprite(img, PAL_NONE, p.x + clicked - offset.x, p.y + clicked - offset.y); + int o = clicked ? WidgetDimensions::scaled.pressed : 0; + DrawSprite(img, PAL_NONE, p.x + o - offset.x, p.y + o - offset.y); } /** @@ -375,7 +379,8 @@ static inline void DrawLabel(const Rect &r, WidgetType type, bool clicked, TextC if ((type & WWT_MASK) == WWT_TEXTBTN_2 && clicked) str++; Dimension d = GetStringBoundingBox(str); Point p = GetAlignedPosition(r, d, align); - DrawString(r.left + clicked, r.right + clicked, p.y + clicked, str, colour, align); + int o = clicked ? WidgetDimensions::scaled.pressed : 0; + DrawString(r.left + o, r.right + o, p.y + o, str, colour, align); } /** @@ -403,7 +408,7 @@ static inline void DrawText(const Rect &r, TextColour colour, StringID str, Stri static inline void DrawInset(const Rect &r, Colours colour, TextColour text_colour, StringID str, StringAlignment align) { DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_LOWERED | FR_DARKENED); - if (str != STR_NULL) DrawString(r.left + WD_INSET_LEFT, r.right - WD_INSET_RIGHT, r.top + WD_INSET_TOP, str, text_colour, align); + if (str != STR_NULL) DrawString(r.Shrink(WidgetDimensions::scaled.inset), str, text_colour, align); } /** @@ -442,13 +447,13 @@ static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint1 int x = r.left; for (int ctr = num_columns; ctr > 1; ctr--) { x += column_width; - GfxFillRect(x, r.top + 1, x, r.bottom - 1, col); + GfxFillRect(x, r.top + WidgetDimensions::scaled.bevel.top, x + WidgetDimensions::scaled.bevel.left - 1, r.bottom - WidgetDimensions::scaled.bevel.bottom, col); } x = r.top; for (int ctr = num_rows; ctr > 1; ctr--) { x += row_height; - GfxFillRect(r.left + 1, x, r.right - 1, x, col); + GfxFillRect(r.left + WidgetDimensions::scaled.bevel.left, x, r.right - WidgetDimensions::scaled.bevel.right, x + WidgetDimensions::scaled.bevel.top - 1, col); } col = _colour_gradient[colour & 0xF][4]; @@ -456,13 +461,13 @@ static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint1 x = r.left - 1; for (int ctr = num_columns; ctr > 1; ctr--) { x += column_width; - GfxFillRect(x, r.top + 1, x, r.bottom - 1, col); + GfxFillRect(x - WidgetDimensions::scaled.bevel.right + 1, r.top + WidgetDimensions::scaled.bevel.top, x, r.bottom - WidgetDimensions::scaled.bevel.bottom, col); } x = r.top - 1; for (int ctr = num_rows; ctr > 1; ctr--) { x += row_height; - GfxFillRect(r.left + 1, x, r.right - 1, x, col); + GfxFillRect(r.left + WidgetDimensions::scaled.bevel.left, x - WidgetDimensions::scaled.bevel.bottom + 1, r.right - WidgetDimensions::scaled.bevel.right, x, col); } } @@ -477,7 +482,6 @@ static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint1 */ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_clicked, bool bar_dragged, bool down_clicked, const Scrollbar *scrollbar) { - int centre = (r.right - r.left) / 2; int height = NWidgetScrollbar::GetVerticalDimension().height; /* draw up/down buttons */ @@ -491,11 +495,17 @@ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_ GfxFillRect(r.left, r.top + height, r.right, r.bottom - height, c2); GfxFillRect(r.left, r.top + height, r.right, r.bottom - height, c1, FILLRECT_CHECKER); + /* track positions. These fractions are based on original 1x dimensions, but scale better. */ + int left = r.left + r.Width() * 3 / 11; /* left track is positioned 3/11ths from the left */ + int right = r.left + r.Width() * 8 / 11; /* right track is positioned 8/11ths from the left */ + const uint8 bl = WidgetDimensions::scaled.bevel.left; + const uint8 br = WidgetDimensions::scaled.bevel.right; + /* draw shaded lines */ - GfxFillRect(r.left + centre - 3, r.top + height, r.left + centre - 3, r.bottom - height, c1); - GfxFillRect(r.left + centre - 2, r.top + height, r.left + centre - 2, r.bottom - height, c2); - GfxFillRect(r.left + centre + 2, r.top + height, r.left + centre + 2, r.bottom - height, c1); - GfxFillRect(r.left + centre + 3, r.top + height, r.left + centre + 3, r.bottom - height, c2); + GfxFillRect(left - bl, r.top + height, left - 1, r.bottom - height, c1); + GfxFillRect(left, r.top + height, left + br - 1, r.bottom - height, c2); + GfxFillRect(right - bl, r.top + height, right - 1, r.bottom - height, c1); + GfxFillRect(right, r.top + height, right + br - 1, r.bottom - height, c2); Point pt = HandleScrollbarHittest(scrollbar, r.top, r.bottom, false); DrawFrameRect(r.left, pt.x, r.right, pt.y, colour, bar_dragged ? FR_LOWERED : FR_NONE); @@ -512,7 +522,6 @@ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_ */ static inline void DrawHorizontalScrollbar(const Rect &r, Colours colour, bool left_clicked, bool bar_dragged, bool right_clicked, const Scrollbar *scrollbar) { - int centre = (r.bottom - r.top) / 2; int width = NWidgetScrollbar::GetHorizontalDimension().width; DrawImageButtons(r.WithWidth(width, false), NWID_HSCROLLBAR, colour, left_clicked, SPR_ARROW_LEFT, SA_CENTER); @@ -525,11 +534,17 @@ static inline void DrawHorizontalScrollbar(const Rect &r, Colours colour, bool l GfxFillRect(r.left + width, r.top, r.right - width, r.bottom, c2); GfxFillRect(r.left + width, r.top, r.right - width, r.bottom, c1, FILLRECT_CHECKER); + /* track positions. These fractions are based on original 1x dimensions, but scale better. */ + int top = r.top + r.Height() * 3 / 11; /* top track is positioned 3/11ths from the top */ + int bottom = r.top + r.Height() * 8 / 11; /* bottom track is positioned 8/11ths from the top */ + const uint8 bt = WidgetDimensions::scaled.bevel.top; + const uint8 bb = WidgetDimensions::scaled.bevel.bottom; + /* draw shaded lines */ - GfxFillRect(r.left + width, r.top + centre - 3, r.right - width, r.top + centre - 3, c1); - GfxFillRect(r.left + width, r.top + centre - 2, r.right - width, r.top + centre - 2, c2); - GfxFillRect(r.left + width, r.top + centre + 2, r.right - width, r.top + centre + 2, c1); - GfxFillRect(r.left + width, r.top + centre + 3, r.right - width, r.top + centre + 3, c2); + GfxFillRect(r.left + width, top - bt, r.right - width, top - 1, c1); + GfxFillRect(r.left + width, top, r.right - width, top + bb - 1, c2); + GfxFillRect(r.left + width, bottom - bt, r.right - width, bottom - 1, c1); + GfxFillRect(r.left + width, bottom, r.right - width, bottom + bb - 1, c2); /* draw actual scrollbar */ Point pt = HandleScrollbarHittest(scrollbar, r.left, r.right, true); @@ -548,44 +563,47 @@ static inline void DrawFrame(const Rect &r, Colours colour, TextColour text_colo { int x2 = r.left; // by default the left side is the left side of the widget - if (str != STR_NULL) x2 = DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top, str, text_colour, align); + if (str != STR_NULL) x2 = DrawString(r.left + WidgetDimensions::scaled.frametext.left, r.right - WidgetDimensions::scaled.frametext.right, r.top, str, text_colour, align); int c1 = _colour_gradient[colour][3]; int c2 = _colour_gradient[colour][7]; /* If the frame has text, adjust the top bar to fit half-way through */ - int dy1 = 4; - if (str != STR_NULL) dy1 = FONT_HEIGHT_NORMAL / 2 - 1; - int dy2 = dy1 + 1; + Rect inner = r.Shrink(ScaleGUITrad(1)); + if (str != STR_NULL) inner.top = r.top + FONT_HEIGHT_NORMAL / 2; + + Rect outer = inner.Expand(WidgetDimensions::scaled.bevel); + Rect inside = inner.Shrink(WidgetDimensions::scaled.bevel); if (_current_text_dir == TD_LTR) { /* Line from upper left corner to start of text */ - GfxFillRect(r.left, r.top + dy1, r.left + 4, r.top + dy1, c1); - GfxFillRect(r.left + 1, r.top + dy2, r.left + 4, r.top + dy2, c2); + GfxFillRect(outer.left, outer.top, r.left + WidgetDimensions::scaled.frametext.left - WidgetDimensions::scaled.bevel.left - 1, inner.top - 1, c1); + GfxFillRect(inner.left, inner.top, r.left + WidgetDimensions::scaled.frametext.left - WidgetDimensions::scaled.bevel.left - 1, inside.top - 1, c2); /* Line from end of text to upper right corner */ - GfxFillRect(x2, r.top + dy1, r.right - 1, r.top + dy1, c1); - GfxFillRect(x2, r.top + dy2, r.right - 2, r.top + dy2, c2); + GfxFillRect(x2 + WidgetDimensions::scaled.bevel.right, outer.top, inner.right, inner.top - 1, c1); + GfxFillRect(x2 + WidgetDimensions::scaled.bevel.right, inner.top, inside.right, inside.top - 1, c2); } else { /* Line from upper left corner to start of text */ - GfxFillRect(r.left, r.top + dy1, x2 - 2, r.top + dy1, c1); - GfxFillRect(r.left + 1, r.top + dy2, x2 - 2, r.top + dy2, c2); + GfxFillRect(outer.left, outer.top, x2 - WidgetDimensions::scaled.bevel.left - 1, inner.top - 1, c1); + GfxFillRect(inner.left, inner.top, x2 - WidgetDimensions::scaled.bevel.left - 1, inside.top - 1, c2); /* Line from end of text to upper right corner */ - GfxFillRect(r.right - 5, r.top + dy1, r.right - 1, r.top + dy1, c1); - GfxFillRect(r.right - 5, r.top + dy2, r.right - 2, r.top + dy2, c2); + GfxFillRect(r.right - WidgetDimensions::scaled.frametext.right + WidgetDimensions::scaled.bevel.right, outer.top, inner.right, inner.top - 1, c1); + GfxFillRect(r.right - WidgetDimensions::scaled.frametext.right + WidgetDimensions::scaled.bevel.right, inner.top, inside.right, inside.top - 1, c2); } /* Line from upper left corner to bottom left corner */ - GfxFillRect(r.left, r.top + dy2, r.left, r.bottom - 1, c1); - GfxFillRect(r.left + 1, r.top + dy2 + 1, r.left + 1, r.bottom - 2, c2); + GfxFillRect(outer.left, inner.top, inner.left - 1, inner.bottom, c1); + GfxFillRect(inner.left, inside.top, inside.left - 1, inside.bottom, c2); /* Line from upper right corner to bottom right corner */ - GfxFillRect(r.right - 1, r.top + dy2, r.right - 1, r.bottom - 2, c1); - GfxFillRect(r.right, r.top + dy1, r.right, r.bottom - 1, c2); + GfxFillRect(inside.right + 1, inner.top, inner.right, inside.bottom, c1); + GfxFillRect(inner.right + 1, outer.top, outer.right, inner.bottom, c2); - GfxFillRect(r.left + 1, r.bottom - 1, r.right - 1, r.bottom - 1, c1); - GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2); + /* Line from bottom left corner to bottom right corner */ + GfxFillRect(inner.left, inside.bottom + 1, inner.right, inner.bottom, c1); + GfxFillRect(outer.left, inner.bottom + 1, outer.right, outer.bottom, c2); } /** @@ -647,7 +665,7 @@ static inline void DrawResizeBox(const Rect &r, Colours colour, bool at_left, bo /** * Draw a close box. - * @param r Rectangle of the box. + * @param r Rectangle of the box.` * @param colour Colour of the close box. */ static inline void DrawCloseBox(const Rect &r, Colours colour) @@ -674,17 +692,18 @@ void DrawCaption(const Rect &r, Colours colour, Owner owner, TextColour text_col { bool company_owned = owner < MAX_COMPANIES; - DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_BORDERONLY); - DrawFrameRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, colour, company_owned ? FR_LOWERED | FR_DARKENED | FR_BORDERONLY : FR_LOWERED | FR_DARKENED); + DrawFrameRect(r, colour, FR_BORDERONLY); + Rect ir = r.Shrink(WidgetDimensions::scaled.bevel); + DrawFrameRect(ir, colour, company_owned ? FR_LOWERED | FR_DARKENED | FR_BORDERONLY : FR_LOWERED | FR_DARKENED); if (company_owned) { - GfxFillRect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2, _colour_gradient[_company_colours[owner]][4]); + GfxFillRect(ir.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[_company_colours[owner]][4]); } if (str != STR_NULL) { Dimension d = GetStringBoundingBox(str); Point p = GetAlignedPosition(r, d, align); - DrawString(r.left + WD_CAPTIONTEXT_LEFT, r.right - WD_CAPTIONTEXT_RIGHT, p.y, str, text_colour, align); + DrawString(r.left + WidgetDimensions::scaled.captiontext.left, r.right - WidgetDimensions::scaled.captiontext.left, p.y, str, text_colour, align); } } @@ -701,18 +720,22 @@ void DrawCaption(const Rect &r, Colours colour, Owner owner, TextColour text_col */ static inline void DrawButtonDropdown(const Rect &r, Colours colour, bool clicked_button, bool clicked_dropdown, StringID str, StringAlignment align) { - int text_offset = std::max(0, (r.Height() - FONT_HEIGHT_NORMAL) / 2); // Offset for rendering the text vertically centered - int dd_width = NWidgetLeaf::dropdown_dimension.width; if (_current_text_dir == TD_LTR) { DrawFrameRect(r.left, r.top, r.right - dd_width, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE); DrawImageButtons(r.WithWidth(dd_width, true), WWT_DROPDOWN, colour, clicked_dropdown, SPR_ARROW_DOWN, SA_CENTER); - if (str != STR_NULL) DrawString(r.left + WD_DROPDOWNTEXT_LEFT + clicked_button, r.right - dd_width - WD_DROPDOWNTEXT_RIGHT + clicked_button, r.top + text_offset + clicked_button, str, TC_BLACK, align); + if (str != STR_NULL) { + int o = clicked_button ? WidgetDimensions::scaled.pressed : 0; + DrawString(r.left + WidgetDimensions::scaled.dropdowntext.left + o, r.right - dd_width - WidgetDimensions::scaled.dropdowntext.right + o, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL) + o, str, TC_BLACK, align); + } } else { DrawFrameRect(r.left + dd_width, r.top, r.right, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE); DrawImageButtons(r.WithWidth(dd_width, false), WWT_DROPDOWN, colour, clicked_dropdown, SPR_ARROW_DOWN, SA_CENTER); - if (str != STR_NULL) DrawString(r.left + dd_width + WD_DROPDOWNTEXT_LEFT + clicked_button, r.right - WD_DROPDOWNTEXT_RIGHT + clicked_button, r.top + text_offset + clicked_button, str, TC_BLACK, align); + if (str != STR_NULL) { + int o = clicked_button ? WidgetDimensions::scaled.pressed : 0; + DrawString(r.left + dd_width + WidgetDimensions::scaled.dropdowntext.left + o, r.right - WidgetDimensions::scaled.dropdowntext.right + o, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL) + o, str, TC_BLACK, align); + } } } @@ -733,17 +756,15 @@ void Window::DrawWidgets() const const NWidgetBase *widget = this->GetWidget(i); if (widget == nullptr || !widget->IsHighlighted()) continue; - int left = widget->pos_x; - int top = widget->pos_y; - int right = left + widget->current_x - 1; - int bottom = top + widget->current_y - 1; + Rect outer = widget->GetCurrentRect(); + Rect inner = outer.Shrink(WidgetDimensions::scaled.bevel).Expand(1); int colour = _string_colourmap[_window_highlight_colour ? widget->GetHighlightColour() : TC_WHITE]; - GfxFillRect(left, top, left, bottom - WD_BEVEL_BOTTOM, colour); - GfxFillRect(left + WD_BEVEL_LEFT, top, right - WD_BEVEL_RIGHT, top, colour); - GfxFillRect(right, top, right, bottom - WD_BEVEL_BOTTOM, colour); - GfxFillRect(left, bottom, right, bottom, colour); + GfxFillRect(outer.left, outer.top, inner.left, inner.bottom, colour); + GfxFillRect(inner.left + 1, outer.top, inner.right - 1, inner.top, colour); + GfxFillRect(inner.right, outer.top, outer.right, inner.bottom, colour); + GfxFillRect(outer.left + 1, inner.bottom, outer.right - 1, outer.bottom, colour); } } } @@ -2025,22 +2046,17 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array) if (this->type == WWT_FRAME) { /* Account for the size of the frame's text if that exists */ - this->child->padding.left = WD_FRAMETEXT_LEFT; - this->child->padding.right = WD_FRAMETEXT_RIGHT; - this->child->padding.top = std::max((int)WD_FRAMETEXT_TOP, this->widget_data != STR_NULL ? FONT_HEIGHT_NORMAL + WD_FRAMETEXT_TOP / 2 : 0); - this->child->padding.bottom = WD_FRAMETEXT_BOTTOM; + this->child->padding = WidgetDimensions::scaled.frametext; + this->child->padding.top = std::max(WidgetDimensions::scaled.frametext.top, this->widget_data != STR_NULL ? FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.frametext.top / 2 : 0); this->smallest_x += this->child->padding.Horizontal(); this->smallest_y += this->child->padding.Vertical(); if (this->index >= 0) w->SetStringParameters(this->index); - this->smallest_x = std::max(this->smallest_x, GetStringBoundingBox(this->widget_data).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT); + this->smallest_x = std::max(this->smallest_x, GetStringBoundingBox(this->widget_data).width + WidgetDimensions::scaled.frametext.Horizontal()); } else if (this->type == WWT_INSET) { /* Apply automatic padding for bevel thickness. */ - this->child->padding.left = WD_BEVEL_LEFT; - this->child->padding.right = WD_BEVEL_RIGHT; - this->child->padding.top = WD_BEVEL_TOP; - this->child->padding.bottom = WD_BEVEL_BOTTOM; + this->child->padding = WidgetDimensions::scaled.bevel; this->smallest_x += this->child->padding.Horizontal(); this->smallest_y += this->child->padding.Vertical(); @@ -2053,17 +2069,16 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array) if (this->type == WWT_FRAME || this->type == WWT_INSET) { if (this->index >= 0) w->SetStringParameters(this->index); Dimension background = GetStringBoundingBox(this->widget_data); - background.width += (this->type == WWT_FRAME) ? (WD_FRAMETEXT_LEFT + WD_FRAMERECT_RIGHT) : (WD_INSET_LEFT + WD_INSET_RIGHT); + background.width += (this->type == WWT_FRAME) ? (WidgetDimensions::scaled.frametext.Horizontal()) : (WidgetDimensions::scaled.inset.Horizontal()); d = maxdim(d, background); } if (this->index >= 0) { - /* Setup suggested padding for widgets. */ - Dimension padding = {0, 0}; + Dimension padding; switch (this->type) { default: NOT_REACHED(); - case WWT_PANEL: padding = {WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM}; break; - case WWT_FRAME: padding = {WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM}; break; - case WWT_INSET: padding = {WD_INSET_LEFT + WD_INSET_RIGHT, WD_INSET_TOP + WD_BEVEL_BOTTOM}; break; + case WWT_PANEL: padding = {WidgetDimensions::scaled.framerect.Horizontal(), WidgetDimensions::scaled.framerect.Vertical()}; break; + case WWT_FRAME: padding = {WidgetDimensions::scaled.frametext.Horizontal(), WidgetDimensions::scaled.frametext.Vertical()}; break; + case WWT_INSET: padding = {WidgetDimensions::scaled.inset.Horizontal(), WidgetDimensions::scaled.inset.Vertical()}; break; } w->UpdateWidgetSize(this->index, &d, padding, &fill, &resize); } @@ -2128,7 +2143,7 @@ void NWidgetBackground::Draw(const Window *w) if (this->child != nullptr) this->child->Draw(w); if (this->IsDisabled()) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); } } @@ -2379,7 +2394,7 @@ void NWidgetScrollbar::Draw(const Window *w) } if (this->IsDisabled()) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); } } @@ -2391,22 +2406,20 @@ void NWidgetScrollbar::Draw(const Window *w) /* static */ Dimension NWidgetScrollbar::GetVerticalDimension() { - static const Dimension extra = {WD_SCROLLBAR_LEFT + WD_SCROLLBAR_RIGHT, WD_SCROLLBAR_TOP + WD_SCROLLBAR_BOTTOM}; if (vertical_dimension.width == 0) { - vertical_dimension = maxdim(GetSpriteSize(SPR_ARROW_UP), GetSpriteSize(SPR_ARROW_DOWN)); - vertical_dimension.width += extra.width; - vertical_dimension.height += extra.height; + vertical_dimension = maxdim(GetScaledSpriteSize(SPR_ARROW_UP), GetScaledSpriteSize(SPR_ARROW_DOWN)); + vertical_dimension.width += WidgetDimensions::scaled.scrollbar.Horizontal(); + vertical_dimension.height += WidgetDimensions::scaled.scrollbar.Vertical(); } return vertical_dimension; } /* static */ Dimension NWidgetScrollbar::GetHorizontalDimension() { - static const Dimension extra = {WD_SCROLLBAR_LEFT + WD_SCROLLBAR_RIGHT, WD_SCROLLBAR_TOP + WD_SCROLLBAR_BOTTOM}; if (horizontal_dimension.width == 0) { - horizontal_dimension = maxdim(GetSpriteSize(SPR_ARROW_LEFT), GetSpriteSize(SPR_ARROW_RIGHT)); - horizontal_dimension.width += extra.width; - horizontal_dimension.height += extra.height; + horizontal_dimension = maxdim(GetScaledSpriteSize(SPR_ARROW_LEFT), GetScaledSpriteSize(SPR_ARROW_RIGHT)); + horizontal_dimension.width += WidgetDimensions::scaled.scrollbar.Horizontal(); + horizontal_dimension.height += WidgetDimensions::scaled.scrollbar.Vertical(); } return horizontal_dimension; } @@ -2483,7 +2496,7 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint32 data, this->SetFill(1, 0); this->SetResize(1, 0); this->SetMinimalSize(0, WD_CAPTION_HEIGHT); - this->SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM, FS_NORMAL); + this->SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical(), FS_NORMAL); this->SetDataTip(data, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS); break; @@ -2541,41 +2554,35 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) w->nested_array[this->index] = this; } + Dimension padding = {0, 0}; Dimension size = {this->min_x, this->min_y}; Dimension fill = {this->fill_x, this->fill_y}; Dimension resize = {this->resize_x, this->resize_y}; - /* Get padding, and update size with the real content size if appropriate. */ - const Dimension *padding = nullptr; switch (this->type) { case WWT_EMPTY: { - static const Dimension extra = {0, 0}; - padding = &extra; break; } case WWT_MATRIX: { - static const Dimension extra = {WD_MATRIX_LEFT + WD_MATRIX_RIGHT, WD_MATRIX_TOP + WD_MATRIX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.matrix.Horizontal(), WidgetDimensions::scaled.matrix.Vertical()}; break; } case WWT_SHADEBOX: { - static const Dimension extra = {WD_SHADEBOX_LEFT + WD_SHADEBOX_RIGHT, WD_SHADEBOX_TOP + WD_SHADEBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.shadebox.Horizontal(), WidgetDimensions::scaled.shadebox.Vertical()}; if (NWidgetLeaf::shadebox_dimension.width == 0) { - NWidgetLeaf::shadebox_dimension = maxdim(GetSpriteSize(SPR_WINDOW_SHADE), GetSpriteSize(SPR_WINDOW_UNSHADE)); - NWidgetLeaf::shadebox_dimension.width += extra.width; - NWidgetLeaf::shadebox_dimension.height += extra.height; + NWidgetLeaf::shadebox_dimension = maxdim(GetScaledSpriteSize(SPR_WINDOW_SHADE), GetScaledSpriteSize(SPR_WINDOW_UNSHADE)); + NWidgetLeaf::shadebox_dimension.width += padding.width; + NWidgetLeaf::shadebox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::shadebox_dimension); break; } case WWT_DEBUGBOX: if (_settings_client.gui.newgrf_developer_tools && w->IsNewGRFInspectable()) { - static const Dimension extra = {WD_DEBUGBOX_LEFT + WD_DEBUGBOX_RIGHT, WD_DEBUGBOX_TOP + WD_DEBUGBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.debugbox.Horizontal(), WidgetDimensions::scaled.debugbox.Vertical()}; if (NWidgetLeaf::debugbox_dimension.width == 0) { - NWidgetLeaf::debugbox_dimension = GetSpriteSize(SPR_WINDOW_DEBUG); - NWidgetLeaf::debugbox_dimension.width += extra.width; - NWidgetLeaf::debugbox_dimension.height += extra.height; + NWidgetLeaf::debugbox_dimension = GetScaledSpriteSize(SPR_WINDOW_DEBUG); + NWidgetLeaf::debugbox_dimension.width += padding.width; + NWidgetLeaf::debugbox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::debugbox_dimension); } else { @@ -2587,81 +2594,74 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) break; case WWT_STICKYBOX: { - static const Dimension extra = {WD_STICKYBOX_LEFT + WD_STICKYBOX_RIGHT, WD_STICKYBOX_TOP + WD_STICKYBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.stickybox.Horizontal(), WidgetDimensions::scaled.stickybox.Vertical()}; if (NWidgetLeaf::stickybox_dimension.width == 0) { - NWidgetLeaf::stickybox_dimension = maxdim(GetSpriteSize(SPR_PIN_UP), GetSpriteSize(SPR_PIN_DOWN)); - NWidgetLeaf::stickybox_dimension.width += extra.width; - NWidgetLeaf::stickybox_dimension.height += extra.height; + NWidgetLeaf::stickybox_dimension = maxdim(GetScaledSpriteSize(SPR_PIN_UP), GetScaledSpriteSize(SPR_PIN_DOWN)); + NWidgetLeaf::stickybox_dimension.width += padding.width; + NWidgetLeaf::stickybox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::stickybox_dimension); break; } case WWT_DEFSIZEBOX: { - static const Dimension extra = {WD_DEFSIZEBOX_LEFT + WD_DEFSIZEBOX_RIGHT, WD_DEFSIZEBOX_TOP + WD_DEFSIZEBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.defsizebox.Horizontal(), WidgetDimensions::scaled.defsizebox.Vertical()}; if (NWidgetLeaf::defsizebox_dimension.width == 0) { - NWidgetLeaf::defsizebox_dimension = GetSpriteSize(SPR_WINDOW_DEFSIZE); - NWidgetLeaf::defsizebox_dimension.width += extra.width; - NWidgetLeaf::defsizebox_dimension.height += extra.height; + NWidgetLeaf::defsizebox_dimension = GetScaledSpriteSize(SPR_WINDOW_DEFSIZE); + NWidgetLeaf::defsizebox_dimension.width += padding.width; + NWidgetLeaf::defsizebox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::defsizebox_dimension); break; } case WWT_RESIZEBOX: { - static const Dimension extra = {WD_RESIZEBOX_LEFT + WD_RESIZEBOX_RIGHT, WD_RESIZEBOX_TOP + WD_RESIZEBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.resizebox.Horizontal(), WidgetDimensions::scaled.resizebox.Vertical()}; if (NWidgetLeaf::resizebox_dimension.width == 0) { - NWidgetLeaf::resizebox_dimension = maxdim(GetSpriteSize(SPR_WINDOW_RESIZE_LEFT), GetSpriteSize(SPR_WINDOW_RESIZE_RIGHT)); - NWidgetLeaf::resizebox_dimension.width += extra.width; - NWidgetLeaf::resizebox_dimension.height += extra.height; + NWidgetLeaf::resizebox_dimension = maxdim(GetScaledSpriteSize(SPR_WINDOW_RESIZE_LEFT), GetScaledSpriteSize(SPR_WINDOW_RESIZE_RIGHT)); + NWidgetLeaf::resizebox_dimension.width += padding.width; + NWidgetLeaf::resizebox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::resizebox_dimension); break; } case WWT_EDITBOX: { - Dimension sprite_size = GetSpriteSize(_current_text_dir == TD_RTL ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); - size.width = std::max(size.width, 30 + sprite_size.width); - size.height = std::max(sprite_size.height, GetStringBoundingBox("_").height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + Dimension sprite_size = GetScaledSpriteSize(_current_text_dir == TD_RTL ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); + size.width = std::max(size.width, ScaleGUITrad(30) + sprite_size.width); + size.height = std::max(sprite_size.height, GetStringBoundingBox("_").height + WidgetDimensions::scaled.framerect.Vertical()); } FALLTHROUGH; case WWT_PUSHBTN: { - static const Dimension extra = {WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.frametext.Horizontal(), WidgetDimensions::scaled.framerect.Vertical()}; break; } case WWT_IMGBTN: case WWT_IMGBTN_2: case WWT_PUSHIMGBTN: { - static const Dimension extra = {WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT, WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM}; - padding = &extra; - Dimension d2 = GetSpriteSize(this->widget_data); - if (this->type == WWT_IMGBTN_2) d2 = maxdim(d2, GetSpriteSize(this->widget_data + 1)); - d2.width += extra.width; - d2.height += extra.height; + padding = {WidgetDimensions::scaled.imgbtn.Horizontal(), WidgetDimensions::scaled.imgbtn.Vertical()}; + Dimension d2 = GetScaledSpriteSize(this->widget_data); + if (this->type == WWT_IMGBTN_2) d2 = maxdim(d2, GetScaledSpriteSize(this->widget_data + 1)); + d2.width += padding.width; + d2.height += padding.height; size = maxdim(size, d2); break; } case WWT_ARROWBTN: case WWT_PUSHARROWBTN: { - static const Dimension extra = {WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT, WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM}; - padding = &extra; - Dimension d2 = maxdim(GetSpriteSize(SPR_ARROW_LEFT), GetSpriteSize(SPR_ARROW_RIGHT)); - d2.width += extra.width; - d2.height += extra.height; + padding = {WidgetDimensions::scaled.imgbtn.Horizontal(), WidgetDimensions::scaled.imgbtn.Vertical()}; + Dimension d2 = maxdim(GetScaledSpriteSize(SPR_ARROW_LEFT), GetScaledSpriteSize(SPR_ARROW_RIGHT)); + d2.width += padding.width; + d2.height += padding.height; size = maxdim(size, d2); break; } case WWT_CLOSEBOX: { - static const Dimension extra = {WD_CLOSEBOX_LEFT + WD_CLOSEBOX_RIGHT, WD_CLOSEBOX_TOP + WD_CLOSEBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.closebox.Horizontal(), WidgetDimensions::scaled.closebox.Vertical()}; if (NWidgetLeaf::closebox_dimension.width == 0) { - NWidgetLeaf::closebox_dimension = GetSpriteSize(SPR_CLOSEBOX); - NWidgetLeaf::closebox_dimension.width += extra.width; - NWidgetLeaf::closebox_dimension.height += extra.height; + NWidgetLeaf::closebox_dimension = GetScaledSpriteSize(SPR_CLOSEBOX); + NWidgetLeaf::closebox_dimension.width += padding.width; + NWidgetLeaf::closebox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::closebox_dimension); break; @@ -2669,48 +2669,42 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) case WWT_TEXTBTN: case WWT_PUSHTXTBTN: case WWT_TEXTBTN_2: { - static const Dimension extra = {WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.framerect.Horizontal(), WidgetDimensions::scaled.framerect.Vertical()}; if (this->index >= 0) w->SetStringParameters(this->index); Dimension d2 = GetStringBoundingBox(this->widget_data); - d2.width += extra.width; - d2.height += extra.height; + d2.width += padding.width; + d2.height += padding.height; size = maxdim(size, d2); break; } case WWT_LABEL: case WWT_TEXT: { - static const Dimension extra = {0, 0}; - padding = &extra; if (this->index >= 0) w->SetStringParameters(this->index); size = maxdim(size, GetStringBoundingBox(this->widget_data)); break; } case WWT_CAPTION: { - static const Dimension extra = {WD_CAPTIONTEXT_LEFT + WD_CAPTIONTEXT_RIGHT, WD_CAPTIONTEXT_TOP + WD_CAPTIONTEXT_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.captiontext.Horizontal(), WidgetDimensions::scaled.captiontext.Vertical()}; if (this->index >= 0) w->SetStringParameters(this->index); Dimension d2 = GetStringBoundingBox(this->widget_data); - d2.width += extra.width; - d2.height += extra.height; + d2.width += padding.width; + d2.height += padding.height; size = maxdim(size, d2); break; } case WWT_DROPDOWN: case NWID_BUTTON_DROPDOWN: case NWID_PUSHBUTTON_DROPDOWN: { - static Dimension extra = {WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT, WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM}; - padding = &extra; if (NWidgetLeaf::dropdown_dimension.width == 0) { - NWidgetLeaf::dropdown_dimension = GetSpriteSize(SPR_ARROW_DOWN); - NWidgetLeaf::dropdown_dimension.width += WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT; - NWidgetLeaf::dropdown_dimension.height += WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM; - extra.width = WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT + NWidgetLeaf::dropdown_dimension.width; + NWidgetLeaf::dropdown_dimension = GetScaledSpriteSize(SPR_ARROW_DOWN); + NWidgetLeaf::dropdown_dimension.width += WidgetDimensions::scaled.vscrollbar.Horizontal(); + NWidgetLeaf::dropdown_dimension.height += WidgetDimensions::scaled.vscrollbar.Vertical(); } + padding = {WidgetDimensions::scaled.dropdowntext.Horizontal() + NWidgetLeaf::dropdown_dimension.width, WidgetDimensions::scaled.dropdowntext.Vertical()}; if (this->index >= 0) w->SetStringParameters(this->index); Dimension d2 = GetStringBoundingBox(this->widget_data); - d2.width += extra.width; - d2.height = std::max(d2.height, NWidgetLeaf::dropdown_dimension.height) + extra.height; + d2.width += padding.width; + d2.height = std::max(d2.height + padding.height, NWidgetLeaf::dropdown_dimension.height); size = maxdim(size, d2); break; } @@ -2718,7 +2712,7 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) NOT_REACHED(); } - if (this->index >= 0) w->UpdateWidgetSize(this->index, &size, *padding, &fill, &resize); + if (this->index >= 0) w->UpdateWidgetSize(this->index, &size, padding, &fill, &resize); this->smallest_x = size.width; this->smallest_y = size.height; @@ -2852,7 +2846,7 @@ void NWidgetLeaf::Draw(const Window *w) if (this->index >= 0) w->DrawWidget(r, this->index); if (this->IsDisabled()) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); } _cur_dpi = old_dpi; @@ -3220,8 +3214,8 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid int hor_length = 0; Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_OUT_4X); - sprite_size.width += WD_MATRIX_LEFT + WD_MATRIX_RIGHT; - sprite_size.height += WD_MATRIX_TOP + WD_MATRIX_BOTTOM + 1; // 1 for the 'offset' of being pressed + sprite_size.width += WidgetDimensions::unscaled.matrix.Horizontal(); + sprite_size.height += WidgetDimensions::unscaled.matrix.Vertical() + 1; // 1 for the 'offset' of being pressed for (int widnum = widget_first; widnum <= widget_last; widnum++) { /* Ensure there is room in 'hor' for another button. */ From 23a82222007a2ca7ab90dd180beb772f9611ae89 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 1 Oct 2022 16:49:37 +0100 Subject: [PATCH 20/26] Change: Split vscroll and hscroll padding. Vertical and horizontal scrollbars are different sizes, this allows different padding for each type. --- src/widget.cpp | 14 ++++++++------ src/window_gui.h | 16 +++++++++++----- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/widget.cpp b/src/widget.cpp index 9acfef7710..9d9ca94da4 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -27,7 +27,8 @@ const WidgetDimensions WidgetDimensions::unscaled = { {WD_IMGBTN_LEFT, WD_IMGBTN_TOP, WD_IMGBTN_RIGHT, WD_IMGBTN_BOTTOM}, ///< imgbtn {WD_INSET_LEFT, WD_INSET_TOP, WD_INSET_RIGHT, WD_BEVEL_BOTTOM}, ///< inset - {WD_SCROLLBAR_LEFT, WD_SCROLLBAR_TOP, WD_SCROLLBAR_RIGHT, WD_SCROLLBAR_BOTTOM}, ///< scrollbar + {WD_VSCROLLBAR_LEFT, WD_VSCROLLBAR_TOP, WD_VSCROLLBAR_RIGHT, WD_VSCROLLBAR_BOTTOM}, ///< vscrollbar + {WD_HSCROLLBAR_LEFT, WD_HSCROLLBAR_TOP, WD_HSCROLLBAR_RIGHT, WD_HSCROLLBAR_BOTTOM}, ///< hscrollbar {WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM}, ///< bevel {WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM}, ///< fullbevel {WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM}, ///< framerect @@ -92,7 +93,8 @@ void SetupWidgetDimensions() { WidgetDimensions::scaled.imgbtn = ScaleGUITrad(WidgetDimensions::unscaled.imgbtn); WidgetDimensions::scaled.inset = ScaleGUITrad(WidgetDimensions::unscaled.inset); - WidgetDimensions::scaled.scrollbar = ScaleGUITrad(WidgetDimensions::unscaled.scrollbar); + WidgetDimensions::scaled.vscrollbar = ScaleGUITrad(WidgetDimensions::unscaled.vscrollbar); + WidgetDimensions::scaled.hscrollbar = ScaleGUITrad(WidgetDimensions::unscaled.hscrollbar); WidgetDimensions::scaled.bevel = WidgetDimensions::unscaled.bevel; WidgetDimensions::scaled.fullbevel = ScaleGUITrad(WidgetDimensions::unscaled.fullbevel); WidgetDimensions::scaled.framerect = ScaleGUITrad(WidgetDimensions::unscaled.framerect); @@ -2408,8 +2410,8 @@ void NWidgetScrollbar::Draw(const Window *w) { if (vertical_dimension.width == 0) { vertical_dimension = maxdim(GetScaledSpriteSize(SPR_ARROW_UP), GetScaledSpriteSize(SPR_ARROW_DOWN)); - vertical_dimension.width += WidgetDimensions::scaled.scrollbar.Horizontal(); - vertical_dimension.height += WidgetDimensions::scaled.scrollbar.Vertical(); + vertical_dimension.width += WidgetDimensions::scaled.vscrollbar.Horizontal(); + vertical_dimension.height += WidgetDimensions::scaled.vscrollbar.Vertical(); } return vertical_dimension; } @@ -2418,8 +2420,8 @@ void NWidgetScrollbar::Draw(const Window *w) { if (horizontal_dimension.width == 0) { horizontal_dimension = maxdim(GetScaledSpriteSize(SPR_ARROW_LEFT), GetScaledSpriteSize(SPR_ARROW_RIGHT)); - horizontal_dimension.width += WidgetDimensions::scaled.scrollbar.Horizontal(); - horizontal_dimension.height += WidgetDimensions::scaled.scrollbar.Vertical(); + horizontal_dimension.width += WidgetDimensions::scaled.hscrollbar.Horizontal(); + horizontal_dimension.height += WidgetDimensions::scaled.hscrollbar.Vertical(); } return horizontal_dimension; } diff --git a/src/window_gui.h b/src/window_gui.h index 6dd1132932..6d7ef61118 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -37,7 +37,8 @@ DECLARE_ENUM_AS_BIT_SET(FrameFlags) struct WidgetDimensions { RectPadding imgbtn; RectPadding inset; - RectPadding scrollbar; + RectPadding vscrollbar; + RectPadding hscrollbar; RectPadding bevel; ///< Widths of bevel border. RectPadding fullbevel; ///< Always-scaled bevel border. RectPadding framerect; ///< Offsets within frame area. @@ -77,10 +78,15 @@ enum WidgetDrawDistances { WD_INSET_RIGHT = 2, ///< Right offset of string. WD_INSET_TOP = 1, ///< Top offset of string. - WD_SCROLLBAR_LEFT = 2, ///< Left offset of scrollbar. - WD_SCROLLBAR_RIGHT = 2, ///< Right offset of scrollbar. - WD_SCROLLBAR_TOP = 2, ///< Top offset of scrollbar. - WD_SCROLLBAR_BOTTOM = 2, ///< Bottom offset of scrollbar. + WD_VSCROLLBAR_LEFT = 2, ///< Left offset of vertical scrollbar. + WD_VSCROLLBAR_RIGHT = 2, ///< Right offset of vertical scrollbar. + WD_VSCROLLBAR_TOP = 3, ///< Top offset of vertical scrollbar. + WD_VSCROLLBAR_BOTTOM = 3, ///< Bottom offset of vertical scrollbar. + + WD_HSCROLLBAR_LEFT = 3, ///< Left offset of horizontal scrollbar. + WD_HSCROLLBAR_RIGHT = 3, ///< Right offset of horizontal scrollbar. + WD_HSCROLLBAR_TOP = 2, ///< Top offset of horizontal scrollbar. + WD_HSCROLLBAR_BOTTOM = 2, ///< Bottom offset of horizontal scrollbar. /* Size of the pure frame bevel without any padding. */ WD_BEVEL_LEFT = 1, ///< Width of left bevel border. From d35f1d3d06f270d607aafa39b0f25232b0964936 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 11 Sep 2022 21:21:59 +0100 Subject: [PATCH 21/26] Codechange: Rename slider widget functions to be less specific. --- src/music_gui.cpp | 6 +++--- src/settings_gui.cpp | 6 +++--- src/widgets/slider.cpp | 24 ++++++++++++------------ src/widgets/slider_func.h | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/music_gui.cpp b/src/music_gui.cpp index edfccf5766..72fec6f9c6 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -741,11 +741,11 @@ struct MusicWindow : public Window { } case WID_M_MUSIC_VOL: - DrawVolumeSliderWidget(r, _settings_client.music.music_vol); + DrawSliderWidget(r, _settings_client.music.music_vol); break; case WID_M_EFFECT_VOL: - DrawVolumeSliderWidget(r, _settings_client.music.effect_vol); + DrawSliderWidget(r, _settings_client.music.effect_vol); break; } } @@ -788,7 +788,7 @@ struct MusicWindow : public Window { case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: { // volume sliders byte &vol = (widget == WID_M_MUSIC_VOL) ? _settings_client.music.music_vol : _settings_client.music.effect_vol; - if (ClickVolumeSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, vol)) { + if (ClickSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, vol)) { if (widget == WID_M_MUSIC_VOL) { MusicDriver::GetInstance()->SetVolume(vol); } else { diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 035999e580..dc1f78e50f 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -347,11 +347,11 @@ struct GameOptionsWindow : Window { break; case WID_GO_BASE_SFX_VOLUME: - DrawVolumeSliderWidget(r, _settings_client.music.effect_vol); + DrawSliderWidget(r, _settings_client.music.effect_vol); break; case WID_GO_BASE_MUSIC_VOLUME: - DrawVolumeSliderWidget(r, _settings_client.music.music_vol); + DrawSliderWidget(r, _settings_client.music.music_vol); break; } } @@ -478,7 +478,7 @@ struct GameOptionsWindow : Window { case WID_GO_BASE_SFX_VOLUME: case WID_GO_BASE_MUSIC_VOLUME: { byte &vol = (widget == WID_GO_BASE_MUSIC_VOLUME) ? _settings_client.music.music_vol : _settings_client.music.effect_vol; - if (ClickVolumeSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, vol)) { + if (ClickSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, vol)) { if (widget == WID_GO_BASE_MUSIC_VOLUME) MusicDriver::GetInstance()->SetVolume(vol); this->SetWidgetDirty(widget); SetWindowClassesDirty(WC_MUSIC_WINDOW); diff --git a/src/widgets/slider.cpp b/src/widgets/slider.cpp index 67c4c372d2..253cd34c52 100644 --- a/src/widgets/slider.cpp +++ b/src/widgets/slider.cpp @@ -19,13 +19,13 @@ static const int SLIDER_WIDTH = 3; /** - * Draw a volume slider widget with know at given value + * Draw a slider widget with knob at given value * @param r Rectangle to draw the widget in * @param value Value to put the slider at */ -void DrawVolumeSliderWidget(Rect r, byte value) +void DrawSliderWidget(Rect r, byte value) { - /* Draw a wedge indicating low to high volume level. */ + /* Draw a wedge indicating low to high value. */ const int ha = (r.bottom - r.top) / 5; int wx1 = r.left, wx2 = r.right; if (_current_text_dir == TD_RTL) std::swap(wx1, wx2); @@ -38,7 +38,7 @@ void DrawVolumeSliderWidget(Rect r, byte value) GfxDrawLine(wedge[1].x, wedge[1].y, wedge[2].x, wedge[2].y, _current_text_dir == TD_RTL ? shadow : light); GfxDrawLine(wedge[0].x, wedge[0].y, wedge[1].x, wedge[1].y, shadow); - /* Draw a slider handle indicating current volume level. */ + /* Draw a slider handle indicating current value. */ const int sw = ScaleGUITrad(SLIDER_WIDTH); if (_current_text_dir == TD_RTL) value = 127 - value; const int x = r.left + (value * (r.right - r.left - sw) / 127); @@ -46,20 +46,20 @@ void DrawVolumeSliderWidget(Rect r, byte value) } /** - * Handle click on a volume slider widget to change the value + * Handle click on a slider widget to change the value * @param r Rectangle of the widget * @param pt Clicked point - * @param value[in,out] Volume value to modify - * @return True if the volume setting was modified + * @param value[in,out] Value to modify + * @return True if the value setting was modified */ -bool ClickVolumeSliderWidget(Rect r, Point pt, byte &value) +bool ClickSliderWidget(Rect r, Point pt, byte &value) { const int sw = ScaleGUITrad(SLIDER_WIDTH); - byte new_vol = Clamp((pt.x - r.left - sw / 2) * 127 / (r.right - r.left - sw), 0, 127); - if (_current_text_dir == TD_RTL) new_vol = 127 - new_vol; + byte new_value = Clamp((pt.x - r.left - sw / 2) * 127 / (r.right - r.left - sw), 0, 127); + if (_current_text_dir == TD_RTL) new_value = 127 - new_value; - if (new_vol != value) { - value = new_vol; + if (new_value != value) { + value = new_value; return true; } diff --git a/src/widgets/slider_func.h b/src/widgets/slider_func.h index 1aa1fa10c6..64f445da64 100644 --- a/src/widgets/slider_func.h +++ b/src/widgets/slider_func.h @@ -14,8 +14,8 @@ #include "../gfx_func.h" -void DrawVolumeSliderWidget(Rect r, byte value); -bool ClickVolumeSliderWidget(Rect r, Point pt, byte &value); +void DrawSliderWidget(Rect r, byte value); +bool ClickSliderWidget(Rect r, Point pt, byte &value); #endif /* WIDGETS_SLIDER_TYPE_H */ From 1180c95372f839f5f8ddd6dbab1b8a643ddf4328 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 23 Oct 2022 15:35:35 +0100 Subject: [PATCH 22/26] Codechange: Add parameters to change range of slider widget. --- src/music_gui.cpp | 6 +++--- src/settings_gui.cpp | 6 +++--- src/widgets/slider.cpp | 21 ++++++++++++++------- src/widgets/slider_func.h | 11 +++++++++-- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 72fec6f9c6..71068aeac8 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -741,11 +741,11 @@ struct MusicWindow : public Window { } case WID_M_MUSIC_VOL: - DrawSliderWidget(r, _settings_client.music.music_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol); break; case WID_M_EFFECT_VOL: - DrawSliderWidget(r, _settings_client.music.effect_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol); break; } } @@ -788,7 +788,7 @@ struct MusicWindow : public Window { case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: { // volume sliders byte &vol = (widget == WID_M_MUSIC_VOL) ? _settings_client.music.music_vol : _settings_client.music.effect_vol; - if (ClickSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, vol)) { + if (ClickSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, 0, INT8_MAX, vol)) { if (widget == WID_M_MUSIC_VOL) { MusicDriver::GetInstance()->SetVolume(vol); } else { diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index dc1f78e50f..8b9d8b3514 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -347,11 +347,11 @@ struct GameOptionsWindow : Window { break; case WID_GO_BASE_SFX_VOLUME: - DrawSliderWidget(r, _settings_client.music.effect_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol); break; case WID_GO_BASE_MUSIC_VOLUME: - DrawSliderWidget(r, _settings_client.music.music_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol); break; } } @@ -478,7 +478,7 @@ struct GameOptionsWindow : Window { case WID_GO_BASE_SFX_VOLUME: case WID_GO_BASE_MUSIC_VOLUME: { byte &vol = (widget == WID_GO_BASE_MUSIC_VOLUME) ? _settings_client.music.music_vol : _settings_client.music.effect_vol; - if (ClickSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, vol)) { + if (ClickSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, 0, INT8_MAX, vol)) { if (widget == WID_GO_BASE_MUSIC_VOLUME) MusicDriver::GetInstance()->SetVolume(vol); this->SetWidgetDirty(widget); SetWindowClassesDirty(WC_MUSIC_WINDOW); diff --git a/src/widgets/slider.cpp b/src/widgets/slider.cpp index 253cd34c52..5bad981936 100644 --- a/src/widgets/slider.cpp +++ b/src/widgets/slider.cpp @@ -20,11 +20,15 @@ static const int SLIDER_WIDTH = 3; /** * Draw a slider widget with knob at given value - * @param r Rectangle to draw the widget in + * @param r Rectangle to draw the widget in + * @param min_value Minimum value of slider + * @param max_value Maximum value of slider * @param value Value to put the slider at */ -void DrawSliderWidget(Rect r, byte value) +void DrawSliderWidget(Rect r, int min_value, int max_value, int value) { + max_value -= min_value; + /* Draw a wedge indicating low to high value. */ const int ha = (r.bottom - r.top) / 5; int wx1 = r.left, wx2 = r.right; @@ -40,8 +44,8 @@ void DrawSliderWidget(Rect r, byte value) /* Draw a slider handle indicating current value. */ const int sw = ScaleGUITrad(SLIDER_WIDTH); - if (_current_text_dir == TD_RTL) value = 127 - value; - const int x = r.left + (value * (r.right - r.left - sw) / 127); + if (_current_text_dir == TD_RTL) value = max_value - value; + const int x = r.left + ((value - min_value) * (r.right - r.left - sw) / max_value); DrawFrameRect(x, r.top, x + sw, r.bottom, COLOUR_GREY, FR_NONE); } @@ -52,11 +56,14 @@ void DrawSliderWidget(Rect r, byte value) * @param value[in,out] Value to modify * @return True if the value setting was modified */ -bool ClickSliderWidget(Rect r, Point pt, byte &value) +bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, int &value) { + max_value -= min_value; + const int sw = ScaleGUITrad(SLIDER_WIDTH); - byte new_value = Clamp((pt.x - r.left - sw / 2) * 127 / (r.right - r.left - sw), 0, 127); - if (_current_text_dir == TD_RTL) new_value = 127 - new_value; + int new_value = Clamp((pt.x - r.left - sw / 2) * max_value / (r.right - r.left - sw), 0, max_value); + if (_current_text_dir == TD_RTL) new_value = max_value - new_value; + new_value += min_value; if (new_value != value) { value = new_value; diff --git a/src/widgets/slider_func.h b/src/widgets/slider_func.h index 64f445da64..35b7737f3d 100644 --- a/src/widgets/slider_func.h +++ b/src/widgets/slider_func.h @@ -14,8 +14,15 @@ #include "../gfx_func.h" -void DrawSliderWidget(Rect r, byte value); -bool ClickSliderWidget(Rect r, Point pt, byte &value); +void DrawSliderWidget(Rect r, int min_value, int max_value, int value); +bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, int &value); +inline bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, byte &value) +{ + int tmp_value = value; + if (!ClickSliderWidget(r, pt, min_value, max_value, tmp_value)) return false; + value = tmp_value; + return true; +} #endif /* WIDGETS_SLIDER_TYPE_H */ From 64a1fc174ff668f3fd142104034bb47cd07689f0 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 23 Oct 2022 15:42:16 +0100 Subject: [PATCH 23/26] Change: Scale thickness of slider bevel. --- src/widgets/slider.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/widgets/slider.cpp b/src/widgets/slider.cpp index 5bad981936..5ed9ef3cbb 100644 --- a/src/widgets/slider.cpp +++ b/src/widgets/slider.cpp @@ -31,6 +31,7 @@ void DrawSliderWidget(Rect r, int min_value, int max_value, int value) /* Draw a wedge indicating low to high value. */ const int ha = (r.bottom - r.top) / 5; + const int t = WidgetDimensions::scaled.bevel.top; /* Thickness of lines */ int wx1 = r.left, wx2 = r.right; if (_current_text_dir == TD_RTL) std::swap(wx1, wx2); const uint shadow = _colour_gradient[COLOUR_GREY][3]; @@ -38,9 +39,9 @@ void DrawSliderWidget(Rect r, int min_value, int max_value, int value) const uint light = _colour_gradient[COLOUR_GREY][7]; const std::vector wedge{ Point{wx1, r.bottom - ha}, Point{wx2, r.top + ha}, Point{wx2, r.bottom - ha} }; GfxFillPolygon(wedge, fill); - GfxDrawLine(wedge[0].x, wedge[0].y, wedge[2].x, wedge[2].y, light); - GfxDrawLine(wedge[1].x, wedge[1].y, wedge[2].x, wedge[2].y, _current_text_dir == TD_RTL ? shadow : light); - GfxDrawLine(wedge[0].x, wedge[0].y, wedge[1].x, wedge[1].y, shadow); + GfxDrawLine(wedge[0].x, wedge[0].y, wedge[2].x, wedge[2].y, light, t); + GfxDrawLine(wedge[1].x, wedge[1].y, wedge[2].x, wedge[2].y, _current_text_dir == TD_RTL ? shadow : light, t); + GfxDrawLine(wedge[0].x, wedge[0].y, wedge[1].x, wedge[1].y, shadow, t); /* Draw a slider handle indicating current value. */ const int sw = ScaleGUITrad(SLIDER_WIDTH); From f0ae111c4a9b19d7bd965d95e0f50f7ca9489609 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 23 Oct 2022 15:44:23 +0100 Subject: [PATCH 24/26] Change: Put ends of slider under centre of control knob. --- src/widgets/slider.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/widgets/slider.cpp b/src/widgets/slider.cpp index 5ed9ef3cbb..b30aba848a 100644 --- a/src/widgets/slider.cpp +++ b/src/widgets/slider.cpp @@ -32,7 +32,8 @@ void DrawSliderWidget(Rect r, int min_value, int max_value, int value) /* Draw a wedge indicating low to high value. */ const int ha = (r.bottom - r.top) / 5; const int t = WidgetDimensions::scaled.bevel.top; /* Thickness of lines */ - int wx1 = r.left, wx2 = r.right; + int wx1 = r.left + sw / 2; + int wx2 = r.right - sw / 2; if (_current_text_dir == TD_RTL) std::swap(wx1, wx2); const uint shadow = _colour_gradient[COLOUR_GREY][3]; const uint fill = _colour_gradient[COLOUR_GREY][6]; From 123983743ff4a4f7da44c18b71fbd903eccd1b83 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 23 Oct 2022 15:45:47 +0100 Subject: [PATCH 25/26] Change: Add optional text labels to slider widget. --- src/gfx.cpp | 4 ++-- src/gfx_func.h | 2 +- src/music_gui.cpp | 4 ++-- src/settings_gui.cpp | 4 ++-- src/widgets/slider.cpp | 23 ++++++++++++++++++++--- src/widgets/slider_func.h | 3 ++- 6 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/gfx.cpp b/src/gfx.cpp index d96b2bdac4..67165fadc1 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -915,12 +915,12 @@ Dimension GetStringBoundingBox(const std::string &str, FontSize start_fontsize) * @param strid String to examine. * @return Width and height of the bounding box for the string in pixels. */ -Dimension GetStringBoundingBox(StringID strid) +Dimension GetStringBoundingBox(StringID strid, FontSize start_fontsize) { char buffer[DRAW_STRING_BUFFER]; GetString(buffer, strid, lastof(buffer)); - return GetStringBoundingBox(buffer); + return GetStringBoundingBox(buffer, start_fontsize); } /** diff --git a/src/gfx_func.h b/src/gfx_func.h index f6018c8a59..4ed6a81461 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -147,7 +147,7 @@ static inline void GfxFillRect(const Rect &r, int colour, FillRectMode mode = FI Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize = FS_NORMAL); Dimension GetStringBoundingBox(const std::string &str, FontSize start_fontsize = FS_NORMAL); -Dimension GetStringBoundingBox(StringID strid); +Dimension GetStringBoundingBox(StringID strid, FontSize start_fontsize = FS_NORMAL); int GetStringHeight(const char *str, int maxw, FontSize fontsize = FS_NORMAL); int GetStringHeight(StringID str, int maxw); int GetStringLineCount(StringID str, int maxw); diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 71068aeac8..8d4b9a019a 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -741,11 +741,11 @@ struct MusicWindow : public Window { } case WID_M_MUSIC_VOL: - DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol, {}); break; case WID_M_EFFECT_VOL: - DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol, {}); break; } } diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 8b9d8b3514..8e401edc22 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -347,11 +347,11 @@ struct GameOptionsWindow : Window { break; case WID_GO_BASE_SFX_VOLUME: - DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol, {}); break; case WID_GO_BASE_MUSIC_VOLUME: - DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol, {}); break; } } diff --git a/src/widgets/slider.cpp b/src/widgets/slider.cpp index b30aba848a..023101e73b 100644 --- a/src/widgets/slider.cpp +++ b/src/widgets/slider.cpp @@ -24,13 +24,18 @@ static const int SLIDER_WIDTH = 3; * @param min_value Minimum value of slider * @param max_value Maximum value of slider * @param value Value to put the slider at + * @param labels List of positions and labels to draw along the slider. */ -void DrawSliderWidget(Rect r, int min_value, int max_value, int value) +void DrawSliderWidget(Rect r, int min_value, int max_value, int value, const std::map &labels) { + /* Allow space for labels. We assume they are in the small font. */ + if (labels.size() > 0) r.bottom -= FONT_HEIGHT_SMALL + WidgetDimensions::scaled.hsep_normal; + max_value -= min_value; /* Draw a wedge indicating low to high value. */ const int ha = (r.bottom - r.top) / 5; + const int sw = ScaleGUITrad(SLIDER_WIDTH); const int t = WidgetDimensions::scaled.bevel.top; /* Thickness of lines */ int wx1 = r.left + sw / 2; int wx2 = r.right - sw / 2; @@ -44,10 +49,22 @@ void DrawSliderWidget(Rect r, int min_value, int max_value, int value) GfxDrawLine(wedge[1].x, wedge[1].y, wedge[2].x, wedge[2].y, _current_text_dir == TD_RTL ? shadow : light, t); GfxDrawLine(wedge[0].x, wedge[0].y, wedge[1].x, wedge[1].y, shadow, t); + int x; + for (auto label : labels) { + x = label.first - min_value; + if (_current_text_dir == TD_RTL) x = max_value - x; + x = r.left + (x * (r.right - r.left - sw) / max_value) + sw / 2; + GfxDrawLine(x, r.bottom - ha + 1, x, r.bottom + (label.second == STR_NULL ? 0 : WidgetDimensions::scaled.hsep_normal), shadow, t); + if (label.second != STR_NULL) { + Dimension d = GetStringBoundingBox(label.second, FS_SMALL); + x = Clamp(x - d.width / 2, r.left, r.right - d.width); + DrawString(x, x + d.width, r.bottom + 1 + WidgetDimensions::scaled.hsep_normal, label.second, TC_BLACK, SA_CENTER, false, FS_SMALL); + } + } + /* Draw a slider handle indicating current value. */ - const int sw = ScaleGUITrad(SLIDER_WIDTH); if (_current_text_dir == TD_RTL) value = max_value - value; - const int x = r.left + ((value - min_value) * (r.right - r.left - sw) / max_value); + x = r.left + ((value - min_value) * (r.right - r.left - sw) / max_value); DrawFrameRect(x, r.top, x + sw, r.bottom, COLOUR_GREY, FR_NONE); } diff --git a/src/widgets/slider_func.h b/src/widgets/slider_func.h index 35b7737f3d..7de929512c 100644 --- a/src/widgets/slider_func.h +++ b/src/widgets/slider_func.h @@ -13,8 +13,9 @@ #include "../window_type.h" #include "../gfx_func.h" +#include -void DrawSliderWidget(Rect r, int min_value, int max_value, int value); +void DrawSliderWidget(Rect r, int min_value, int max_value, int value, const std::map &labels); bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, int &value); inline bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, byte &value) From 61da064b82d89068da54f7d2aff0e22ad40df0da Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 27 Sep 2022 22:39:35 +0100 Subject: [PATCH 26/26] Fix: Settings GUI sprite size. --- src/settings_gui.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 8e401edc22..95be2ab869 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1933,7 +1933,6 @@ struct GameSettingsWindow : Window { this->filter.type_hides = false; this->settings_ptr = &GetGameSettings(); - _circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED)); GetSettingsTree().FoldAll(); // Close all sub-pages this->valuewindow_entry = nullptr; // No setting entry for which a entry window is opened @@ -1954,6 +1953,11 @@ struct GameSettingsWindow : Window { this->InvalidateData(); } + void OnInit() override + { + _circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED)); + } + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) {