Merge branch 'master' into jgrpp

# Conflicts:
#	src/build_vehicle_gui.cpp
#	src/cheat_gui.cpp
#	src/company_gui.cpp
#	src/error_gui.cpp
#	src/fios_gui.cpp
#	src/gfx_func.h
#	src/graph_gui.cpp
#	src/group_gui.cpp
#	src/misc_gui.cpp
#	src/newgrf_debug_gui.cpp
#	src/order_gui.cpp
#	src/road_gui.cpp
#	src/roadveh_gui.cpp
#	src/settings_gui.cpp
#	src/ship_gui.cpp
#	src/station_gui.cpp
#	src/statusbar_gui.cpp
#	src/subsidy_gui.cpp
#	src/timetable_gui.cpp
#	src/town_gui.cpp
#	src/train_gui.cpp
#	src/tree_gui.cpp
#	src/vehicle_gui.cpp
#	src/widget.cpp
#	src/widgets/dropdown.cpp
#	src/window_gui.h
This commit is contained in:
Jonathan G Rennison
2022-12-04 13:53:36 +00:00
53 changed files with 1478 additions and 1416 deletions

View File

@@ -110,7 +110,7 @@ struct AIListWindow : public Window {
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{ {
if (widget == WID_AIL_LIST) { 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->width = 1;
resize->height = this->line_height; resize->height = this->line_height;
@@ -123,18 +123,18 @@ struct AIListWindow : public Window {
switch (widget) { switch (widget) {
case WID_AIL_LIST: { case WID_AIL_LIST: {
/* Draw a list of all available AIs. */ /* Draw a list of all available AIs. */
int y = this->GetWidget<NWidgetBase>(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 */ /* First AI in the list is hardcoded to random */
if (this->vscroll->IsVisible(0)) { 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); DrawString(tr, this->slot == OWNER_DEITY ? STR_AI_CONFIG_NONE : STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_ORANGE);
y += this->line_height; tr.top += this->line_height;
} }
int i = 0; int i = 0;
for (const auto &item : *this->info_list) { for (const auto &item : *this->info_list) {
i++; i++;
if (this->vscroll->IsVisible(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); DrawString(tr, item.second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE);
y += this->line_height; tr.top += this->line_height;
} }
} }
break; break;
@@ -148,20 +148,20 @@ struct AIListWindow : public Window {
} }
/* Some info about the currently selected AI. */ /* Some info about the currently selected AI. */
if (selected_info != nullptr) { 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()); SetDParamStr(0, selected_info->GetAuthor());
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_AUTHOR); DrawString(tr, STR_AI_LIST_AUTHOR);
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; tr.top += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
SetDParam(0, selected_info->GetVersion()); SetDParam(0, selected_info->GetVersion());
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_VERSION); DrawString(tr, STR_AI_LIST_VERSION);
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; tr.top += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
if (selected_info->GetURL() != nullptr) { if (selected_info->GetURL() != nullptr) {
SetDParamStr(0, selected_info->GetURL()); SetDParamStr(0, selected_info->GetURL());
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_URL); DrawString(tr, STR_AI_LIST_URL);
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; tr.top += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
} }
SetDParamStr(0, selected_info->GetDescription()); 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; break;
} }
@@ -346,7 +346,7 @@ struct AISettingsWindow : public Window {
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{ {
if (widget == WID_AIS_BACKGROUND) { 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->width = 1;
resize->height = this->line_height; resize->height = this->line_height;
@@ -363,11 +363,10 @@ struct AISettingsWindow : public Window {
int i = 0; int i = 0;
for (; !this->vscroll->IsVisible(i); i++) it++; 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; bool rtl = _current_text_dir == TD_RTL;
uint buttons_left = rtl ? r.right - SETTING_BUTTON_WIDTH - 3 : r.left + 4; Rect br = ir.WithWidth(SETTING_BUTTON_WIDTH, rtl);
uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8); Rect tr = ir.Indent(SETTING_BUTTON_WIDTH + 8, rtl);
uint text_right = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT);
int y = r.top; int y = r.top;
int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
@@ -396,13 +395,13 @@ struct AISettingsWindow : public Window {
} }
if ((config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0) { 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); SetDParam(idx++, current_value == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON);
} else { } else {
if (config_item.complete_labels) { 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 { } 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)) { if (config_item.labels != nullptr && config_item.labels->Contains(current_value)) {
SetDParam(idx++, STR_JUST_RAW_STRING); SetDParam(idx++, STR_JUST_RAW_STRING);
@@ -413,7 +412,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; y += this->line_height;
} }
} }
@@ -431,8 +430,8 @@ struct AISettingsWindow : public Window {
{ {
switch (widget) { switch (widget) {
case WID_AIS_BACKGROUND: { case WID_AIS_BACKGROUND: {
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_AIS_BACKGROUND); Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WD_MATRIX_LEFT, 0, WD_MATRIX_RIGHT, 0);
int num = (pt.y - wid->pos_y) / this->line_height + this->vscroll->GetPosition(); int num = (pt.y - r.top) / this->line_height + this->vscroll->GetPosition();
if (num >= (int)this->visible_settings.size()) break; if (num >= (int)this->visible_settings.size()) break;
VisibleSettingsList::const_iterator it = this->visible_settings.begin(); VisibleSettingsList::const_iterator it = this->visible_settings.begin();
@@ -449,9 +448,8 @@ struct AISettingsWindow : public Window {
bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0; bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0;
int x = pt.x - wid->pos_x; int x = pt.x - r.left;
if (_current_text_dir == TD_RTL) x = wid->current_x - 1 - x; if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x;
x -= 4;
/* One of the arrows is clicked (or green/red rect in case of bool value) */ /* 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); int old_val = this->ai_config->GetSetting(config_item.name);
@@ -462,8 +460,7 @@ struct AISettingsWindow : public Window {
this->clicked_dropdown = false; this->clicked_dropdown = false;
this->closing_dropdown = false; this->closing_dropdown = false;
} else { } else {
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_AIS_BACKGROUND); int rel_y = (pt.y - r.top) % this->line_height;
int rel_y = (pt.y - (int)wid->pos_y) % this->line_height;
Rect wi_rect; Rect wi_rect;
wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x); wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);
@@ -767,7 +764,7 @@ struct AIConfigWindow : public Window {
break; break;
case WID_AIC_LIST: 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; resize->height = this->line_height;
size->height = 8 * this->line_height; size->height = 8 * this->line_height;
break; break;
@@ -797,7 +794,7 @@ struct AIConfigWindow : public Window {
{ {
switch (widget) { switch (widget) {
case WID_AIC_LIST: { 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++) { for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < MAX_COMPANIES; i++) {
StringID text; StringID text;
@@ -809,9 +806,9 @@ struct AIConfigWindow : public Window {
} else { } else {
text = STR_AI_CONFIG_RANDOM_AI; 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)); (this->selected_slot == i) ? TC_WHITE : (IsEditable((CompanyID)i) ? TC_ORANGE : TC_SILVER));
y += this->line_height; tr.top += this->line_height;
} }
break; break;
} }
@@ -945,9 +942,6 @@ static bool SetScriptButtonColour(NWidgetCore &button, bool dead, bool paused)
* Window with everything an AI prints via ScriptLog. * Window with everything an AI prints via ScriptLog.
*/ */
struct AIDebugWindow : public Window { 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 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. static CompanyID ai_debug_company; ///< The AI that is (was last) being debugged.
@@ -1052,7 +1046,7 @@ struct AIDebugWindow : public Window {
{ {
if (widget == WID_AID_LOG_PANEL) { if (widget == WID_AID_LOG_PANEL) {
resize->height = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; 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;
} }
} }
@@ -1166,7 +1160,8 @@ struct AIDebugWindow : public Window {
ScriptLog::LogData *log = this->GetLogPointer(); ScriptLog::LogData *log = this->GetLogPointer();
if (log == nullptr) return; 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++) { 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; int pos = (i + log->pos + 1 - log->used + log->count) % log->count;
if (log->lines[pos] == nullptr) break; if (log->lines[pos] == nullptr) break;
@@ -1183,12 +1178,12 @@ struct AIDebugWindow : public Window {
/* Check if the current line should be highlighted */ /* Check if the current line should be highlighted */
if (pos == this->highlight_row) { 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. 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); DrawString(tr, log->lines[pos], colour, SA_LEFT | SA_FORCE);
y += this->resize.step_height; tr.top += this->resize.step_height;
} }
break; break;
} }
@@ -1376,8 +1371,6 @@ struct AIDebugWindow : public Window {
static HotkeyList hotkeys; 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; CompanyID AIDebugWindow::ai_debug_company = INVALID_COMPANY;
char AIDebugWindow::break_string[MAX_BREAK_STR_STRING_LENGTH] = ""; char AIDebugWindow::break_string[MAX_BREAK_STR_STRING_LENGTH] = "";
bool AIDebugWindow::break_check_enabled = true; bool AIDebugWindow::break_check_enabled = true;

View File

@@ -25,47 +25,48 @@
* Draw the details for the given vehicle at the given position * Draw the details for the given vehicle at the given position
* *
* @param v current vehicle * @param v current vehicle
* @param left The left most coordinate to draw * @param r the Rect to draw within
* @param right The right most coordinate to draw
* @param y The y coordinate
*/ */
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; Money feeder_share = 0;
int y = r.top;
for (const Aircraft *u = v; u != nullptr; u = u->Next()) { for (const Aircraft *u = v; u != nullptr; u = u->Next()) {
if (u->IsNormalAircraft()) { if (u->IsNormalAircraft()) {
SetDParam(0, u->engine_type); SetDParam(0, u->engine_type);
SetDParam(1, u->build_year); SetDParam(1, u->build_year);
SetDParam(2, u->value); 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(0, u->cargo_type);
SetDParam(1, u->cargo_cap); SetDParam(1, u->cargo_cap);
SetDParam(2, u->Next()->cargo_type); SetDParam(2, u->Next()->cargo_type);
SetDParam(3, u->Next()->cargo_cap); SetDParam(3, u->Next()->cargo_cap);
SetDParam(4, GetCargoSubtypeText(u)); 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) { if (u->cargo_cap != 0) {
uint cargo_count = u->cargo.StoredCount(); uint cargo_count = u->cargo.StoredCount();
y_offset += FONT_HEIGHT_NORMAL + 1;
if (cargo_count != 0) { if (cargo_count != 0) {
/* Cargo names (fix pluralness) */ /* Cargo names (fix pluralness) */
SetDParam(0, u->cargo_type); SetDParam(0, u->cargo_type);
SetDParam(1, cargo_count); SetDParam(1, cargo_count);
SetDParam(2, u->cargo.Source()); 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(); feeder_share += u->cargo.FeederShare();
} }
} }
} }
y += WD_PAR_VSEP_NORMAL;
SetDParam(0, feeder_share); 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);
} }

View File

@@ -331,7 +331,7 @@ public:
size->width = std::max(size->width, GetStringBoundingBox(as->name).width); 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; size->height = 5 * this->line_height;
break; break;
} }
@@ -344,8 +344,8 @@ public:
SpriteID sprite = GetCustomAirportSprite(as, layout); SpriteID sprite = GetCustomAirportSprite(as, layout);
if (sprite != 0) { if (sprite != 0) {
Dimension d = GetSpriteSize(sprite); Dimension d = GetSpriteSize(sprite);
d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; d.width += padding.width;
d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; d.height += padding.height;
*size = maxdim(d, *size); *size = maxdim(d, *size);
} }
} }
@@ -363,6 +363,8 @@ public:
/* STR_BLACK_STRING is used to start the string with {BLACK} */ /* STR_BLACK_STRING is used to start the string with {BLACK} */
SetDParam(0, string); SetDParam(0, string);
Dimension d = GetStringMultiLineBoundingBox(STR_BLACK_STRING, *size); Dimension d = GetStringMultiLineBoundingBox(STR_BLACK_STRING, *size);
d.width += padding.width;
d.height += padding.height;
*size = maxdim(d, *size); *size = maxdim(d, *size);
} }
} }
@@ -376,15 +378,17 @@ public:
{ {
switch (widget) { switch (widget) {
case WID_AP_AIRPORT_LIST: { 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); AirportClass *apclass = AirportClass::Get(_selected_airport_class);
for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < apclass->GetSpecCount(); i++) { for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < apclass->GetSpecCount(); i++) {
const AirportSpec *as = apclass->GetSpec(i); const AirportSpec *as = apclass->GetSpec(i);
if (!as->IsAvailable()) { 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); DrawString(text, as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK);
y += this->line_height; row = row.Translate(0, this->line_height);
text = text.Translate(0, this->line_height);
} }
break; break;
} }

View File

@@ -30,7 +30,7 @@
#include "safeguards.h" #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) static bool EngineNumberSorter(const EngineID &a, const EngineID &b)
{ {
@@ -302,8 +302,8 @@ public:
case WID_RV_INFO_TAB: { case WID_RV_INFO_TAB: {
Dimension d = GetStringBoundingBox(STR_REPLACE_NOT_REPLACING); Dimension d = GetStringBoundingBox(STR_REPLACE_NOT_REPLACING);
d = maxdim(d, GetStringBoundingBox(STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED)); d = maxdim(d, GetStringBoundingBox(STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED));
d.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; d.width += padding.width;
d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; d.height += padding.height;
*size = maxdim(*size, d); *size = maxdim(*size, d);
break; break;
} }
@@ -420,7 +420,7 @@ public:
str = STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED; 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; break;
} }
@@ -431,8 +431,7 @@ public:
EngineID end = static_cast<EngineID>(std::min<size_t>(this->vscroll[side]->GetCapacity() + start, this->engines[side].size())); EngineID end = static_cast<EngineID>(std::min<size_t>(this->vscroll[side]->GetCapacity() + start, this->engines[side].size()));
/* Do the actual drawing */ /* Do the actual drawing */
DrawEngineList((VehicleType)this->window_number, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, DrawEngineList((VehicleType)this->window_number, r, &this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group);
&this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group);
break; break;
} }
} }
@@ -482,10 +481,10 @@ public:
ted.cost = 0; ted.cost = 0;
ted.FillDefaultCapacities(e); ted.FillDefaultCapacities(e);
NWidgetBase *nwi = this->GetWidget<NWidgetBase>(side == 0 ? WID_RV_LEFT_DETAILS : WID_RV_RIGHT_DETAILS); const Rect r = this->GetWidget<NWidgetBase>(side == 0 ? WID_RV_LEFT_DETAILS : WID_RV_RIGHT_DETAILS)->GetCurrentRect()
int text_end = DrawVehiclePurchaseInfo(nwi->pos_x + WD_FRAMETEXT_LEFT, nwi->pos_x + nwi->current_x - WD_FRAMETEXT_RIGHT, .Shrink(WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM);
nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine[side], ted); int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine[side], ted);
needed_height = std::max(needed_height, (text_end - (int)nwi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL); 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. if (needed_height != this->details_height) { // Details window are not high enough, enlarge them.

View File

@@ -107,7 +107,7 @@ public:
void DrawWidget(const Rect &r, int widget) const override void DrawWidget(const Rect &r, int widget) const override
{ {
if (widget == WID_BEM_MESSAGE) { 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);
} }
} }
@@ -233,7 +233,7 @@ public:
{ {
if (widget != 0) return; 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 void OnClick(Point pt, int widget, int click_count) override

View File

@@ -202,10 +202,10 @@ public:
} }
sprite_dim.height++; // Sprite is rendered one pixel down in the matrix field. 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. 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. this->bridgetext_offset = 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; 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. size->height = 4 * resize->height; // Smallest bridge gui is 4 entries high in the matrix.
break; break;
} }
@@ -230,7 +230,7 @@ public:
break; break;
case WID_BBS_BRIDGE_LIST: { 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++) { for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < (int)this->bridges->size(); i++) {
const BridgeSpec *b = this->bridges->at(i).spec; const BridgeSpec *b = this->bridges->at(i).spec;
@@ -238,10 +238,10 @@ public:
SetDParam(1, b->speed); SetDParam(1, b->speed);
SetDParam(0, b->material); SetDParam(0, b->material);
DrawSprite(b->sprite, b->pal, r.left + WD_MATRIX_LEFT, y + this->resize.step_height - 1 - GetSpriteSize(b->sprite).height); DrawSprite(b->sprite, b->pal, tr.left, tr.bottom - GetSpriteSize(b->sprite).height);
DrawStringMultiLine(r.left + this->bridgetext_offset, r.right, y + 2, y + this->resize.step_height, DrawStringMultiLine(tr.Indent(this->bridgetext_offset, false),
_game_mode == GM_EDITOR ? STR_SELECT_BRIDGE_SCENEDIT_INFO : STR_SELECT_BRIDGE_INFO); _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; break;
} }

View File

@@ -32,6 +32,7 @@
#include "autoreplace_func.h" #include "autoreplace_func.h"
#include "train.h" #include "train.h"
#include "error.h" #include "error.h"
#include "zoom_func.h"
#include "widgets/build_vehicle_widget.h" #include "widgets/build_vehicle_widget.h"
@@ -1176,9 +1177,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number,
/** /**
* Engine drawing loop * Engine drawing loop
* @param type Type of vehicle (VEH_*) * @param type Type of vehicle (VEH_*)
* @param l The left most location of the list * @param r The Rect of the list
* @param r The right most location of the list
* @param y The top most location of the list
* @param eng_list What engines to draw * @param eng_list What engines to draw
* @param min where to start in the list * @param min where to start in the list
* @param max where in the list to end * @param max where in the list to end
@@ -1186,7 +1185,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 show_count Whether to show the amount of engines or not
* @param selected_group the group to list the engines of * @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 }; static const int sprite_y_offsets[] = { -1, -1, -2, -2 };
@@ -1199,8 +1198,9 @@ void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList *
int sprite_right = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_right; int sprite_right = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_right;
int sprite_width = sprite_left + sprite_right; int sprite_width = sprite_left + sprite_right;
int sprite_x = rtl ? r - sprite_right - 1 : l + sprite_left + 1; Rect ir = r.WithHeight(step_size).Shrink(WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM);
int sprite_y_offset = sprite_y_offsets[type] + step_size / 2; 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}; Dimension replace_icon = {0, 0};
int count_width = 0; int count_width = 0;
@@ -1210,16 +1210,16 @@ void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList *
count_width = GetStringBoundingBox(STR_TINY_BLACK_COMA).width; 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); Rect tr = ir.Indent(sprite_width + 6, rtl); // Name position
int text_right = r - (rtl ? sprite_width + WD_FRAMETEXT_RIGHT : WD_FRAMERECT_RIGHT + replace_icon.width + 8 + count_width); Rect cr = tr.Indent(replace_icon.width + 6, !rtl).WithWidth(count_width, !rtl); // Count position
int replace_icon_left = rtl ? l + WD_FRAMERECT_LEFT : r - WD_FRAMERECT_RIGHT - replace_icon.width; Rect rr = tr.WithWidth(replace_icon.width, !rtl); // Replace icon position
int count_left = l; if (show_count) tr = tr.Indent(count_width + 2 + replace_icon.width + 6, !rtl);
int count_right = rtl ? text_left : r - WD_FRAMERECT_RIGHT - replace_icon.width - 8;
int normal_text_y_offset = (step_size - FONT_HEIGHT_NORMAL) / 2; int normal_text_y_offset = (ir.Height() - FONT_HEIGHT_NORMAL) / 2;
int small_text_y_offset = step_size - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1; int small_text_y_offset = ir.Height() - FONT_HEIGHT_SMALL;
int replace_icon_y_offset = (step_size - replace_icon.height) / 2 - 1; int replace_icon_y_offset = (ir.Height() - replace_icon.height) / 2;
int y = ir.top;
for (; min < max; min++, y += step_size) { for (; min < max; min++, y += step_size) {
const EngineID engine = (*eng_list)[min]; 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. */ /* Note: num_engines is only used in the autoreplace GUI, so it is correct to use _local_company here. */
@@ -1231,12 +1231,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)); TextColour tc = (engine == selected_id) ? TC_WHITE : (TC_NO_SHADE | (hidden ? TC_GREY : TC_BLACK));
SetDParam(0, engine); SetDParam(0, engine);
DrawString(text_left, text_right, y + normal_text_y_offset, str, tc); DrawString(tr.left, tr.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); 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) { if (show_count) {
SetDParam(0, num_engines); SetDParam(0, num_engines);
DrawString(count_left, count_right, y + small_text_y_offset, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); 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, replace_icon_left, y + replace_icon_y_offset); 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);
} }
} }
} }
@@ -1875,9 +1875,7 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
case WID_BV_LIST: case WID_BV_LIST:
DrawEngineList( DrawEngineList(
this->vehicle_type, this->vehicle_type,
r.left + WD_FRAMERECT_LEFT, r,
r.right - WD_FRAMERECT_RIGHT,
r.top + WD_FRAMERECT_TOP,
&this->eng_list, &this->eng_list,
this->vscroll->GetPosition(), this->vscroll->GetPosition(),
static_cast<uint16>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->eng_list.size())), static_cast<uint16>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->eng_list.size())),
@@ -1912,10 +1910,9 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
int needed_height = this->details_height; int needed_height = this->details_height;
/* Draw details panels. */ /* Draw details panels. */
if (this->sel_engine != INVALID_ENGINE) { if (this->sel_engine != INVALID_ENGINE) {
NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_BV_PANEL); const Rect r = this->GetWidget<NWidgetBase>(WID_BV_PANEL)->GetCurrentRect().Shrink(WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM);
int text_end = DrawVehiclePurchaseInfo(nwi->pos_x + WD_FRAMETEXT_LEFT, nwi->pos_x + nwi->current_x - WD_FRAMETEXT_RIGHT, int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine, this->te);
nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine, this->te); needed_height = std::max(needed_height, (text_end - r.top) / FONT_HEIGHT_NORMAL);
needed_height = std::max(needed_height, (text_end - (int)nwi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL);
} }
if (needed_height != this->details_height) { // Details window are not high enough, enlarge them. if (needed_height != this->details_height) { // Details window are not high enough, enlarge them.
int resize = needed_height - this->details_height; int resize = needed_height - this->details_height;
@@ -2743,8 +2740,8 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase {
{ {
switch (widget) { switch (widget) {
case WID_BV_LIST_LOCO: { case WID_BV_LIST_LOCO: {
DrawEngineList(this->vehicle_type, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, DrawEngineList(this->vehicle_type, r,
r.top + WD_FRAMERECT_TOP, &this->loco.eng_list, this->loco.vscroll->GetPosition(), &this->loco.eng_list, this->loco.vscroll->GetPosition(),
std::min<uint16>(this->loco.vscroll->GetPosition() + this->loco.vscroll->GetCapacity(), std::min<uint16>(this->loco.vscroll->GetPosition() + this->loco.vscroll->GetCapacity(),
static_cast<uint16>(this->loco.eng_list.size())), this->loco.sel_engine, false, static_cast<uint16>(this->loco.eng_list.size())), this->loco.sel_engine, false,
DEFAULT_GROUP); DEFAULT_GROUP);
@@ -2757,8 +2754,8 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase {
} }
case WID_BV_LIST_WAGON: { case WID_BV_LIST_WAGON: {
DrawEngineList(this->vehicle_type, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, DrawEngineList(this->vehicle_type, r,
r.top + WD_FRAMERECT_TOP, &this->wagon.eng_list, this->wagon.vscroll->GetPosition(), &this->wagon.eng_list, this->wagon.vscroll->GetPosition(),
std::min<uint16>(this->wagon.vscroll->GetPosition() + this->wagon.vscroll->GetCapacity(), std::min<uint16>(this->wagon.vscroll->GetPosition() + this->wagon.vscroll->GetCapacity(),
static_cast<uint16>(this->wagon.eng_list.size())), this->wagon.sel_engine, false, static_cast<uint16>(this->wagon.eng_list.size())), this->wagon.sel_engine, false,
DEFAULT_GROUP); DEFAULT_GROUP);

View File

@@ -31,6 +31,7 @@
#include "order_base.h" #include "order_base.h"
#include "vehicle_base.h" #include "vehicle_base.h"
#include "currency.h" #include "currency.h"
#include "core/geometry_func.hpp"
#include "widgets/cheat_widget.h" #include "widgets/cheat_widget.h"
@@ -232,34 +233,43 @@ struct CheatWindow : Window {
int clicked; int clicked;
int clicked_widget; int clicked_widget;
uint line_height; uint line_height;
int box_width; Dimension box; ///< Dimension of box sprite
Dimension icon; ///< Dimension of company icon sprite
CheatWindow(WindowDesc *desc) : Window(desc) CheatWindow(WindowDesc *desc) : Window(desc)
{ {
this->box_width = GetSpriteSize(SPR_BOX_EMPTY).width;
this->InitNested(); 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 void DrawWidget(const Rect &r, int widget) const override
{ {
if (widget != WID_C_PANEL) return; 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; bool rtl = _current_text_dir == TD_RTL;
uint box_left = rtl ? r.right - this->box_width - 5 : r.left + 5; uint box_left = rtl ? ir.right - this->box.width - 5 : ir.left + 5;
uint button_left = rtl ? r.right - this->box_width - 10 - SETTING_BUTTON_WIDTH : r.left + this->box_width + 10; uint button_left = rtl ? ir.right - this->box.width - 10 - SETTING_BUTTON_WIDTH : ir.left + this->box.width + 10;
uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : 20 + this->box_width + SETTING_BUTTON_WIDTH); uint text_left = ir.left + (rtl ? 0 : 20 + this->box.width + SETTING_BUTTON_WIDTH);
uint text_right = r.right - (rtl ? 20 + this->box_width + SETTING_BUTTON_WIDTH : WD_FRAMERECT_RIGHT); 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 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++) { for (int i = 0; i != lengthof(_cheats_ui); i++) {
const CheatEntry *ce = &_cheats_ui[i]; const CheatEntry *ce = &_cheats_ui[i];
if (!IsCheatAllowed(ce->mode)) continue; if (!IsCheatAllowed(ce->mode)) continue;
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) { switch (ce->type) {
case SLF_ALLOW_CONTROL: { case SLF_ALLOW_CONTROL: {
@@ -287,7 +297,7 @@ struct CheatWindow : Window {
char buf[512]; char buf[512];
/* Draw [<][>] boxes for settings of an integer-type */ /* 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) { switch (ce->str) {
/* Display date for change date cheat */ /* Display date for change date cheat */
@@ -298,7 +308,7 @@ struct CheatWindow : Window {
SetDParam(0, val + 1); SetDParam(0, val + 1);
GetString(buf, STR_CHEAT_CHANGE_COMPANY, lastof(buf)); GetString(buf, STR_CHEAT_CHANGE_COMPANY, lastof(buf));
uint offset = 10 + GetStringBoundingBox(buf).width; 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; break;
} }
@@ -363,15 +373,15 @@ struct CheatWindow : Window {
this->line_height = std::max<uint>(this->line_height, SETTING_BUTTON_HEIGHT); this->line_height = std::max<uint>(this->line_height, SETTING_BUTTON_HEIGHT);
this->line_height = std::max<uint>(this->line_height, FONT_HEIGHT_NORMAL) + WD_PAR_VSEP_NORMAL; this->line_height = std::max<uint>(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->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 * lines; size->height = WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + this->line_height * lines;
} }
void OnClick(Point pt, int widget, int click_count) override void OnClick(Point pt, int widget, int click_count) override
{ {
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_C_PANEL); const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_C_PANEL);
uint btn = (pt.y - wid->pos_y - WD_FRAMERECT_TOP - WD_PAR_VSEP_NORMAL) / this->line_height; uint btn = (pt.y - wid->pos_y - WD_FRAMERECT_TOP) / this->line_height;
int x = pt.x - wid->pos_x; uint x = pt.x - wid->pos_x;
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
if (rtl) x = wid->current_x - x; if (rtl) x = wid->current_x - x;
@@ -386,23 +396,23 @@ struct CheatWindow : Window {
int value = (int32)ReadValue(ce->variable, ce->type); int value = (int32)ReadValue(ce->variable, ce->type);
int oldvalue = value; 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. */ /* Click at the date text directly. */
clicked_widget = CHT_CHANGE_DATE; clicked_widget = CHT_CHANGE_DATE;
SetDParam(0, value); SetDParam(0, value);
ShowQueryString(STR_JUST_INT, STR_CHEAT_CHANGE_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED); ShowQueryString(STR_JUST_INT, STR_CHEAT_CHANGE_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED);
return; 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; clicked_widget = CHT_EDIT_MAX_HL;
SetDParam(0, value); SetDParam(0, value);
ShowQueryString(STR_JUST_INT, STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED); ShowQueryString(STR_JUST_INT, STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED);
return; return;
} else if (btn == CHT_MONEY && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) { } else if (btn == CHT_MONEY && x >= 20 + this->box.width + SETTING_BUTTON_WIDTH) {
clicked_widget = CHT_MONEY; clicked_widget = CHT_MONEY;
SetDParam(0, value); SetDParam(0, value);
ShowQueryString(STR_JUST_INT, STR_CHEAT_EDIT_MONEY_QUERY_CAPT, 20, this, CS_NUMERAL_SIGNED, QSF_ACCEPT_UNCHANGED); ShowQueryString(STR_JUST_INT, STR_CHEAT_EDIT_MONEY_QUERY_CAPT, 20, this, CS_NUMERAL_SIGNED, QSF_ACCEPT_UNCHANGED);
return; return;
} else if (ce->type == SLF_ALLOW_CONTROL && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) { } else if (ce->type == SLF_ALLOW_CONTROL && x >= 20 + this->box.width + SETTING_BUTTON_WIDTH) {
clicked_widget = btn; clicked_widget = btn;
uint64 val = (uint64)ReadValue(ce->variable, SLE_UINT64); uint64 val = (uint64)ReadValue(ce->variable, SLE_UINT64);
SetDParam(0, val * 1000 >> 16); SetDParam(0, val * 1000 >> 16);
@@ -416,14 +426,14 @@ struct CheatWindow : Window {
} }
/* Not clicking a button? */ /* 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;
if (!_networking) *ce->been_used = true; if (!_networking) *ce->been_used = true;
switch (ce->type) { switch (ce->type) {
case SLF_ALLOW_CONTROL: { case SLF_ALLOW_CONTROL: {
/* Change inflation factors */ /* Change inflation factors */
uint64 value = (uint64)ReadValue(ce->variable, SLE_UINT64) + (((x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1) << 16); uint64 value = (uint64)ReadValue(ce->variable, SLE_UINT64) + (((x >= 10 + this->box.width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1) << 16);
value = Clamp<uint64>(value, 1 << 16, MAX_INFLATION); value = Clamp<uint64>(value, 1 << 16, MAX_INFLATION);
DoCommandP(0, (uint32)btn, (uint32)value, CMD_CHEAT_SETTING); DoCommandP(0, (uint32)btn, (uint32)value, CMD_CHEAT_SETTING);
break; break;
@@ -436,10 +446,10 @@ struct CheatWindow : Window {
default: default:
/* Take whatever the function returns */ /* 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. */ /* 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; break;
} }

View File

@@ -157,16 +157,15 @@ static uint GetMaxCategoriesWidth()
*/ */
static void DrawCategory(const Rect &r, int start_y, ExpensesList list) static void DrawCategory(const Rect &r, int start_y, ExpensesList list)
{ {
int offs_left = _current_text_dir == TD_LTR ? EXP_INDENT : 0; Rect tr = r.Indent(EXP_INDENT, _current_text_dir == TD_RTL);
int offs_right = _current_text_dir == TD_LTR ? 0 : EXP_INDENT;
int y = start_y; tr.top = start_y;
ExpensesType et; ExpensesType et;
for (uint i = 0; i < list.length; i++) { for (uint i = 0; i < list.length; i++) {
et = list.et[i]; et = list.et[i];
DrawString(r.left + offs_left, r.right - offs_right, y, STR_FINANCES_SECTION_CONSTRUCTION + et); DrawString(tr, STR_FINANCES_SECTION_CONSTRUCTION + et);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
} }
} }
@@ -656,11 +655,12 @@ public:
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
int icon_y = CenterBounds(r.top, r.bottom, 0); int icon_y = CenterBounds(r.top, r.bottom, 0);
int text_y = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL); 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), DrawSprite(SPR_VEH_BUS_SIDE_VIEW, PALETTE_RECOLOUR_START + (this->result % COLOUR_END),
rtl ? r.right - 2 - ScaleGUITrad(14) : r.left + ScaleGUITrad(14) + 2, rtl ? tr.right - ScaleGUITrad(14) : tr.left + ScaleGUITrad(14),
icon_y); icon_y);
DrawString(rtl ? r.left + 2 : r.left + ScaleGUITrad(28) + 4, DrawString(rtl ? tr.left : tr.left + ScaleGUITrad(28) + 2,
rtl ? r.right - ScaleGUITrad(28) - 4 : r.right - 2, rtl ? tr.right - ScaleGUITrad(28) - 2 : tr.right,
text_y, this->String(), sel ? TC_WHITE : TC_BLACK); text_y, this->String(), sel ? TC_WHITE : TC_BLACK);
} }
}; };
@@ -973,40 +973,41 @@ public:
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
/* Horizontal coordinates of scheme name column. */ /* Coordinates of scheme name column. */
const NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_SCL_SPACER_DROPDOWN); const NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_SCL_SPACER_DROPDOWN);
int sch_left = nwi->pos_x; Rect sch = nwi->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM);
int sch_right = sch_left + nwi->current_x - 1; /* Coordinates of first dropdown. */
/* Horizontal coordinates of first dropdown. */
nwi = this->GetWidget<NWidgetBase>(WID_SCL_PRI_COL_DROPDOWN); nwi = this->GetWidget<NWidgetBase>(WID_SCL_PRI_COL_DROPDOWN);
int pri_left = nwi->pos_x; Rect pri = nwi->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM);
int pri_right = pri_left + nwi->current_x - 1; /* Coordinates of second dropdown. */
/* Horizontal coordinates of second dropdown. */
nwi = this->GetWidget<NWidgetBase>(WID_SCL_SEC_COL_DROPDOWN); nwi = this->GetWidget<NWidgetBase>(WID_SCL_SEC_COL_DROPDOWN);
int sec_left = nwi->pos_x; Rect sec = nwi->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM);
int sec_right = sec_left + nwi->current_x - 1;
int text_left = (rtl ? (uint)WD_FRAMERECT_LEFT : (this->square.width + 5)); Rect pri_squ = pri.WithWidth(this->square.width, rtl);
int text_right = (rtl ? (this->square.width + 5) : (uint)WD_FRAMERECT_RIGHT); Rect sec_squ = sec.WithWidth(this->square.width, rtl);
int square_offs = (this->line_height - this->square.height) / 2 + 1; pri = pri.Indent(this->square.width + ScaleGUITrad(2), rtl);
int text_offs = (this->line_height - FONT_HEIGHT_NORMAL) / 2 + 1; 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. */ /* Helper function to draw livery info. */
auto draw_livery = [&](StringID str, const Livery &liv, bool sel, bool def, int indent) { auto draw_livery = [&](StringID str, const Livery &liv, bool sel, bool def, int indent) {
/* Livery Label. */ /* 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. */ /* 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); DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour1), pri_squ.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); 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. */ /* Text below the second dropdown. */
if (sec_right > sec_left) { // Second dropdown has non-zero size. 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); DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour2), sec_squ.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); 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; y += this->line_height;

View File

@@ -528,25 +528,35 @@ public:
switch (widget) { switch (widget) {
case WID_BDD_X: case WID_BDD_X:
case WID_BDD_Y: case WID_BDD_Y:
size->width = ScaleGUITrad(96) + 2; size->width = ScaleGUITrad(96) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT;
size->height = ScaleGUITrad(64) + 2; size->height = ScaleGUITrad(64) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM;
break; break;
} }
} }
void OnPaint() override void DrawWidget(const Rect &r, int widget) const override
{ {
this->DrawWidgets(); DrawPixelInfo tmp_dpi;
int x1 = ScaleGUITrad(63) + 1; switch (widget) {
int x2 = ScaleGUITrad(31) + 1; case WID_BDD_X:
int y1 = ScaleGUITrad(17) + 1; case WID_BDD_Y: {
int y2 = ScaleGUITrad(33) + 1; Axis axis = widget == WID_BDD_X ? AXIS_X : AXIS_Y;
DrawShipDepotSprite(this->GetWidget<NWidgetBase>(WID_BDD_X)->pos_x + x1, this->GetWidget<NWidgetBase>(WID_BDD_X)->pos_y + y1, AXIS_X, DEPOT_PART_NORTH); if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) {
DrawShipDepotSprite(this->GetWidget<NWidgetBase>(WID_BDD_X)->pos_x + x2, this->GetWidget<NWidgetBase>(WID_BDD_X)->pos_y + y2, AXIS_X, DEPOT_PART_SOUTH); DrawPixelInfo *old_dpi = _cur_dpi;
DrawShipDepotSprite(this->GetWidget<NWidgetBase>(WID_BDD_Y)->pos_x + x2, this->GetWidget<NWidgetBase>(WID_BDD_Y)->pos_y + y1, AXIS_Y, DEPOT_PART_NORTH); _cur_dpi = &tmp_dpi;
DrawShipDepotSprite(this->GetWidget<NWidgetBase>(WID_BDD_Y)->pos_x + x1, this->GetWidget<NWidgetBase>(WID_BDD_Y)->pos_y + y2, AXIS_Y, DEPOT_PART_SOUTH); 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 void OnClick(Point pt, int widget, int click_count) override

View File

@@ -440,18 +440,21 @@ public:
_fios_path_changed = false; _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); 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(ir.left, ir.right, ir.top + FONT_HEIGHT_NORMAL, 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, path, TC_BLACK);
break; break;
} }
case WID_SL_DRIVES_DIRECTORIES_LIST: { 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(); 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]) { if (!this->fios_items_shown[row]) {
/* The current item is filtered out : we do not show it */ /* The current item is filtered out : we do not show it */
scroll_pos++; scroll_pos++;
@@ -461,118 +464,128 @@ public:
const FiosItem *item = &this->fios_items[row]; const FiosItem *item = &this->fios_items[row];
if (item == this->selected) { 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) { } 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)]); DrawString(tr, item->title, _fios_colours[GetDetailedFileType(item->type)]);
y += this->resize.step_height; tr = tr.Translate(0, this->resize.step_height);
if (y >= this->vscroll->GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break;
} }
break; break;
} }
case WID_SL_DETAILS: { 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); this->DrawDetails(r);
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 {
/* Warning if save unique id differ when saving */
if (this->fop == SLO_SAVE) {
if (_load_check_data.settings.game_creation.generation_unique_id == 0) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y_max, STR_SAVELOAD_UNKNOWN_ID);
y_max -= FONT_HEIGHT_NORMAL;
} else if (_load_check_data.settings.game_creation.generation_unique_id != _settings_game.game_creation.generation_unique_id) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y_max, STR_SAVELOAD_DIFFERENT_ID);
y_max -= FONT_HEIGHT_NORMAL;
}
}
/* 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;
}
}
}
break; 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 {
/* Warning if save unique id differ when saving */
if (this->fop == SLO_SAVE) {
if (_load_check_data.settings.game_creation.generation_unique_id == 0) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, tr.bottom - FONT_HEIGHT_NORMAL - WD_FRAMERECT_BOTTOM, STR_SAVELOAD_UNKNOWN_ID);
tr.bottom -= FONT_HEIGHT_NORMAL;
} else if (_load_check_data.settings.game_creation.generation_unique_id != _settings_game.game_creation.generation_unique_id) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, tr.bottom - FONT_HEIGHT_NORMAL - WD_FRAMERECT_BOTTOM, STR_SAVELOAD_DIFFERENT_ID);
tr.bottom -= FONT_HEIGHT_NORMAL;
}
}
/* 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;
}
} }
} }
} }

View File

@@ -154,14 +154,14 @@ struct GSConfigWindow : public Window {
{ {
switch (widget) { switch (widget) {
case WID_GSC_SETTINGS: 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->width = 1;
resize->height = this->line_height; resize->height = this->line_height;
size->height = 5 * this->line_height; size->height = 5 * this->line_height;
break; break;
case WID_GSC_GSLIST: 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; size->height = 1 * this->line_height;
break; break;
} }
@@ -188,7 +188,7 @@ struct GSConfigWindow : public Window {
} }
/* There is only one slot, unlike with the GS GUI, so it should never be white */ /* 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; break;
} }
case WID_GSC_SETTINGS: { case WID_GSC_SETTINGS: {
@@ -197,11 +197,10 @@ struct GSConfigWindow : public Window {
int i = 0; int i = 0;
for (; !this->vscroll->IsVisible(i); i++) it++; 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; bool rtl = _current_text_dir == TD_RTL;
uint buttons_left = rtl ? r.right - SETTING_BUTTON_WIDTH - 3 : r.left + 4; Rect br = ir.WithWidth(SETTING_BUTTON_WIDTH, rtl);
uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8); Rect tr = ir.Indent(SETTING_BUTTON_WIDTH + 8, rtl);
uint text_right = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT);
int y = r.top; int y = r.top;
int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
@@ -230,13 +229,13 @@ struct GSConfigWindow : public Window {
} }
if ((config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0) { 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); SetDParam(idx++, current_value == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON);
} else { } else {
if (config_item.complete_labels) { 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 { } 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)) { if (config_item.labels != nullptr && config_item.labels->Contains(current_value)) {
SetDParam(idx++, STR_JUST_RAW_STRING); SetDParam(idx++, STR_JUST_RAW_STRING);
@@ -247,7 +246,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; y += this->line_height;
} }
break; break;
@@ -291,9 +290,10 @@ struct GSConfigWindow : public Window {
ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_GAME); ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_GAME);
} }
break; break;
case WID_GSC_SETTINGS: { case WID_GSC_SETTINGS: {
const NWidgetBase* wid = this->GetWidget<NWidgetBase>(WID_GSC_SETTINGS); Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WD_MATRIX_LEFT, 0, WD_MATRIX_RIGHT, 0);
int num = (pt.y - wid->pos_y) / this->line_height + this->vscroll->GetPosition(); int num = (pt.y - r.top) / this->line_height + this->vscroll->GetPosition();
if (num >= (int)this->visible_settings.size()) break; if (num >= (int)this->visible_settings.size()) break;
VisibleSettingsList::const_iterator it = this->visible_settings.begin(); VisibleSettingsList::const_iterator it = this->visible_settings.begin();
@@ -310,9 +310,8 @@ struct GSConfigWindow : public Window {
bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0; bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0;
int x = pt.x - wid->pos_x; int x = pt.x - r.left;
if (_current_text_dir == TD_RTL) x = wid->current_x - 1 - x; if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x;
x -= 4;
/* One of the arrows is clicked (or green/red rect in case of bool value) */ /* 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); int old_val = this->gs_config->GetSetting(config_item.name);
@@ -323,8 +322,7 @@ struct GSConfigWindow : public Window {
this->clicked_dropdown = false; this->clicked_dropdown = false;
this->closing_dropdown = false; this->closing_dropdown = false;
} else { } else {
const NWidgetBase* wid = this->GetWidget<NWidgetBase>(WID_GSC_SETTINGS); int rel_y = (pt.y - r.top) % this->line_height;
int rel_y = (pt.y - (int)wid->pos_y) % this->line_height;
Rect wi_rect; Rect wi_rect;
wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x); wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);

View File

@@ -755,7 +755,7 @@ struct GenerateLandscapeWindow : public Window {
} }
} }
size->width += padding.width; 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 void OnClick(Point pt, int widget, int click_count) override
@@ -1597,13 +1597,15 @@ struct GenerateProgressWindow : public Window {
void DrawWidget(const Rect &r, int widget) const override void DrawWidget(const Rect &r, int widget) const override
{ {
switch (widget) { switch (widget) {
case WID_GP_PROGRESS_BAR: case WID_GP_PROGRESS_BAR: {
/* Draw the % complete with a bar and a text */ /* Draw the % complete with a bar and a text */
DrawFrameRect(r.left, r.top, r.right, r.bottom, COLOUR_GREY, FR_BORDERONLY); DrawFrameRect(r, 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); 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); 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; break;
}
case WID_GP_PROGRESS_TEXT: case WID_GP_PROGRESS_TEXT:
/* Tell which class we are generating */ /* Tell which class we are generating */

View File

@@ -93,6 +93,7 @@ static const int DRAW_STRING_BUFFER = 2048;
void RedrawScreenRect(int left, int top, int right, int bottom); void RedrawScreenRect(int left, int top, int right, int bottom);
Dimension GetSpriteSize(SpriteID sprid, Point *offset = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI); Dimension GetSpriteSize(SpriteID sprid, Point *offset = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI);
Dimension GetScaledSpriteSize(SpriteID sprid); /* widget.cpp */
struct SpritePointerHolder; struct SpritePointerHolder;
void DrawSpriteViewport(const SpritePointerHolder &sprite_store, const DrawPixelInfo *dpi, SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr); void DrawSpriteViewport(const SpritePointerHolder &sprite_store, const DrawPixelInfo *dpi, SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr);
void PrepareDrawSpriteViewportSpriteStore(SpritePointerHolder &sprite_store, SpriteID img, PaletteID pal); void PrepareDrawSpriteViewportSpriteStore(SpritePointerHolder &sprite_store, SpriteID img, PaletteID pal);

View File

@@ -191,9 +191,7 @@ struct GoalListWindow : public Window {
void DrawListColumn(GoalColumn column, NWidgetBase *wid, uint progress_col_width) const void DrawListColumn(GoalColumn column, NWidgetBase *wid, uint progress_col_width) const
{ {
/* Get column draw area. */ /* Get column draw area. */
int y = wid->pos_y + WD_FRAMERECT_TOP; Rect r = wid->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM);
int x = wid->pos_x + WD_FRAMERECT_LEFT;
int right = x + wid->current_x - WD_FRAMERECT_RIGHT;
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
int pos = -this->vscroll->GetPosition(); int pos = -this->vscroll->GetPosition();
@@ -208,7 +206,7 @@ struct GoalListWindow : public Window {
/* Display the goal. */ /* Display the goal. */
SetDParamStr(0, s->text); SetDParamStr(0, s->text);
uint width_reduction = progress_col_width > 0 ? progress_col_width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT : 0; 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; break;
} }
@@ -216,12 +214,11 @@ struct GoalListWindow : public Window {
if (s->progress != nullptr) { if (s->progress != nullptr) {
SetDParamStr(0, s->progress); SetDParamStr(0, s->progress);
StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS; StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS;
int progress_x = x; DrawString(r.WithWidth(progress_col_width, !rtl), str, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
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);
} }
break; break;
} }
r.top += FONT_HEIGHT_NORMAL;
} }
pos++; pos++;
num++; num++;
@@ -230,9 +227,8 @@ struct GoalListWindow : public Window {
if (num == 0) { if (num == 0) {
if (column == GC_GOAL && IsInsideMM(pos, 0, cap)) { 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++;
} }
} }
@@ -296,8 +292,7 @@ static const NWidgetPart _nested_goals_list_widgets[] = {
NWidget(WWT_STICKYBOX, COLOUR_BROWN), NWidget(WWT_STICKYBOX, COLOUR_BROWN),
EndContainer(), EndContainer(),
NWidget(NWID_HORIZONTAL), NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_BROWN), SetDataTip(0x0, STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER), SetScrollbar(WID_GOAL_SCROLLBAR), 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),
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),
EndContainer(), EndContainer(),
NWidget(NWID_VERTICAL), NWidget(NWID_VERTICAL),
NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_GOAL_SCROLLBAR), NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_GOAL_SCROLLBAR),
@@ -411,7 +406,7 @@ struct GoalQuestionWindow : public Window {
if (widget != WID_GQ_QUESTION) return; if (widget != WID_GQ_QUESTION) return;
SetDParamStr(0, this->question); 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);
} }
}; };

View File

@@ -69,12 +69,14 @@ struct GraphLegendWindow : Window {
bool rtl = _current_text_dir == TD_RTL; 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); 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(0, cid);
SetDParam(1, 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 void OnClick(Point pt, int widget, int click_count) override
@@ -968,32 +970,31 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
bool rtl = _current_text_dir == TD_RTL; 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 pos = this->vscroll->GetPosition();
int max = pos + this->vscroll->GetCapacity(); int max = pos + this->vscroll->GetCapacity();
Rect line = r.WithHeight(this->line_height);
for (const CargoSpec *cs : _sorted_standard_cargo_specs) { for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
if (pos-- > 0) continue; if (pos-- > 0) continue;
if (--max < 0) break; if (--max < 0) break;
bool lowered = !HasBit(_legend_excluded_cargo, cs->Index()); bool lowered = !HasBit(_legend_excluded_cargo, cs->Index());
/* Redraw box if lowered */ /* Redraw frame if lowered */
if (lowered) DrawFrameRect(r.left, y, r.right, y + this->line_height - 1, COLOUR_BROWN, FR_LOWERED); if (lowered) DrawFrameRect(line, COLOUR_BROWN, FR_LOWERED);
byte clk_dif = lowered ? 1 : 0; const Rect text = line.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM).Translate(lowered ? 1 : 0, lowered ? 1 : 0);
int rect_x = clk_dif + (rtl ? r.right - this->legend_width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT);
GfxFillRect(rect_x, y + padding + clk_dif, rect_x + this->legend_width, y + row_height - 1 + clk_dif, PC_BLACK); /* Cargo-colour box with outline */
GfxFillRect(rect_x + 1, y + padding + 1 + clk_dif, rect_x + this->legend_width - 1, y + row_height - 2 + clk_dif, cs->legend_colour); 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); 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);
} }
} }

View File

@@ -679,14 +679,14 @@ public:
case WID_GL_LIST_VEHICLE: case WID_GL_LIST_VEHICLE:
if (this->vli.index != ALL_GROUP && this->grouping == GB_NONE) { 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) */ /* 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<uint>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size())); uint max = static_cast<uint>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size()));
for (uint i = this->vscroll->GetPosition(); i < max; ++i) { for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
const Vehicle *v = this->vehgroups[i].GetSingleVehicle(); const Vehicle *v = this->vehgroups[i].GetSingleVehicle();
if (v->group_id != this->vli.index) { 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);
} }
} }

View File

@@ -444,7 +444,7 @@ public:
if (this->index[i] == INVALID_INDUSTRYTYPE) continue; if (this->index[i] == INVALID_INDUSTRYTYPE) continue;
d = maxdim(d, GetStringBoundingBox(GetIndustrySpec(this->index[i])->name)); d = maxdim(d, GetStringBoundingBox(GetIndustrySpec(this->index[i])->name));
} }
resize->height = std::max<uint>(this->legend.height, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; resize->height = std::max<uint>(this->legend.height, FONT_HEIGHT_NORMAL) + padding.height;
d.width += this->legend.width + ScaleFontTrad(7) + padding.width; d.width += this->legend.width + ScaleFontTrad(7) + padding.width;
d.height = 5 * resize->height; d.height = 5 * resize->height;
*size = maxdim(*size, d); *size = maxdim(*size, d);
@@ -493,8 +493,8 @@ public:
/* Set it to something more sane :) */ /* Set it to something more sane :) */
height += extra_lines_prd + extra_lines_req + extra_lines_newgrf; height += extra_lines_prd + extra_lines_req + extra_lines_newgrf;
size->height = height * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; size->height = height * FONT_HEIGHT_NORMAL + padding.height;
size->width = d.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; size->width = d.width + padding.width;
break; break;
} }
@@ -535,52 +535,40 @@ public:
{ {
switch (widget) { switch (widget) {
case WID_DPI_MATRIX_WIDGET: { case WID_DPI_MATRIX_WIDGET: {
uint text_left, text_right, icon_left, icon_right; bool rtl = _current_text_dir == TD_RTL;
if (_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);
icon_right = r.right - WD_MATRIX_RIGHT; Rect icon = text.WithWidth(this->legend.width, rtl);
icon_left = icon_right - this->legend.width; text = text.Indent(this->legend.width + ScaleFontTrad(7), rtl);
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;
}
/* Vertical offset for legend icon. */ /* Vertical offset for legend icon. */
int icon_top = (this->resize.step_height - this->legend.height + 1) / 2; icon.top = r.top + (this->resize.step_height - this->legend.height + 1) / 2;
int icon_bottom = icon_top + this->legend.height; 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++) { for (uint16 i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->count; i++) {
bool selected = this->selected_index == i + this->vscroll->GetPosition(); bool selected = this->selected_index == i + this->vscroll->GetPosition();
if (this->index[i + this->vscroll->GetPosition()] == INVALID_INDUSTRYTYPE) { 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); DrawString(text, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES, selected ? TC_WHITE : TC_ORANGE);
y += this->resize.step_height; } else {
continue; 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 */ text = text.Translate(0, this->resize.step_height);
DrawString(text_left, text_right, y + WD_MATRIX_TOP, indsp->name, selected ? TC_WHITE : TC_ORANGE); icon = icon.Translate(0, this->resize.step_height);
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;
} }
break; break;
} }
case WID_DPI_INFOPANEL: { case WID_DPI_INFOPANEL: {
int y = r.top + WD_FRAMERECT_TOP; Rect ir = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM);
int bottom = r.bottom - WD_FRAMERECT_BOTTOM;
int left = r.left + WD_FRAMERECT_LEFT;
int right = r.right - WD_FRAMERECT_RIGHT;
if (this->selected_type == INVALID_INDUSTRYTYPE) { 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; break;
} }
@@ -588,8 +576,8 @@ public:
if (_game_mode != GM_EDITOR) { if (_game_mode != GM_EDITOR) {
SetDParam(0, indsp->GetConstructionCost()); SetDParam(0, indsp->GetConstructionCost());
DrawString(left, right, y, STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST); DrawString(ir, STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST);
y += FONT_HEIGHT_NORMAL; ir.top += FONT_HEIGHT_NORMAL;
} }
CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)]; CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)];
@@ -597,12 +585,12 @@ public:
/* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */ /* 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); 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); 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". */ /* 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); 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); 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. */ /* Get the additional purchase info text, if it has not already been queried. */
if (HasBit(indsp->callback_mask, CBM_IND_FUND_MORE_TEXT)) { if (HasBit(indsp->callback_mask, CBM_IND_FUND_MORE_TEXT)) {
@@ -614,7 +602,7 @@ public:
StringID str = GetGRFStringID(indsp->grf_prop.grffile->grfid, 0xD000 + callback_res); // No. here's the new string StringID str = GetGRFStringID(indsp->grf_prop.grffile->grfid, 0xD000 + callback_res); // No. here's the new string
if (str != STR_UNDEFINED) { if (str != STR_UNDEFINED) {
StartTextRefStackUsage(indsp->grf_prop.grffile, 6); StartTextRefStackUsage(indsp->grf_prop.grffile, 6);
DrawStringMultiLine(left, right, y, bottom, str, TC_YELLOW); DrawStringMultiLine(ir, str, TC_YELLOW);
StopTextRefStackUsage(); StopTextRefStackUsage();
} }
} }
@@ -871,10 +859,10 @@ public:
if (this->IsShaded()) return; // Don't draw anything when the window is shaded. if (this->IsShaded()) return; // Don't draw anything when the window is shaded.
NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_IV_INFO); const Rect r = this->GetWidget<NWidgetBase>(WID_IV_INFO)->GetCurrentRect();
uint expected = this->DrawInfo(nwi->pos_x, nwi->pos_x + nwi->current_x - 1, nwi->pos_y) - nwi->pos_y; int expected = this->DrawInfo(r);
if (expected > nwi->current_y - 1) { if (expected > r.bottom) {
this->info_height = expected + 1; this->info_height = expected - r.top + 1;
this->ReInit(); this->ReInit();
return; return;
} }
@@ -887,30 +875,29 @@ public:
* @param top Top edge of the panel. * @param top Top edge of the panel.
* @return Expected position of the bottom 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); Industry *i = Industry::Get(this->window_number);
const IndustrySpec *ind = GetIndustrySpec(i->type); 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 first = true;
bool has_accept = false; bool has_accept = false;
if (i->prod_level == PRODLEVEL_CLOSURE) { if (i->prod_level == PRODLEVEL_CLOSURE) {
DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE); DrawString(ir, STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE);
y += 2 * FONT_HEIGHT_NORMAL; ir.top += 2 * FONT_HEIGHT_NORMAL;
} }
CargoSuffix cargo_suffix[lengthof(i->accepts_cargo)]; CargoSuffix cargo_suffix[lengthof(i->accepts_cargo)];
GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_VIEW, i, i->type, ind, i->accepts_cargo, cargo_suffix); 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); 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++) { for (byte j = 0; j < lengthof(i->accepts_cargo); j++) {
if (i->accepts_cargo[j] == CT_INVALID) continue; if (i->accepts_cargo[j] == CT_INVALID) continue;
has_accept = true; has_accept = true;
if (first) { if (first) {
DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_REQUIRES); DrawString(ir, STR_INDUSTRY_VIEW_REQUIRES);
y += FONT_HEIGHT_NORMAL; ir.top += FONT_HEIGHT_NORMAL;
first = false; first = false;
} }
SetDParam(0, CargoSpec::Get(i->accepts_cargo[j])->name); SetDParam(0, CargoSpec::Get(i->accepts_cargo[j])->name);
@@ -936,8 +923,8 @@ public:
default: default:
NOT_REACHED(); NOT_REACHED();
} }
DrawString(left_side, right - WD_FRAMERECT_RIGHT, y, str); DrawString(ir.Indent(10, _current_text_dir == TD_RTL), str);
y += FONT_HEIGHT_NORMAL; ir.top += FONT_HEIGHT_NORMAL;
} }
GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_VIEW, i, i->type, ind, i->produced_cargo, cargo_suffix); GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_VIEW, i, i->type, ind, i->produced_cargo, cargo_suffix);
@@ -945,10 +932,10 @@ public:
for (byte j = 0; j < lengthof(i->produced_cargo); j++) { for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
if (i->produced_cargo[j] == CT_INVALID) continue; if (i->produced_cargo[j] == CT_INVALID) continue;
if (first) { if (first) {
if (has_accept) y += WD_PAR_VSEP_WIDE; if (has_accept) ir.top += WD_PAR_VSEP_WIDE;
DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE); DrawString(ir, STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE);
y += FONT_HEIGHT_NORMAL; ir.top += FONT_HEIGHT_NORMAL;
if (this->editable == EA_RATE) this->production_offset_y = y; if (this->editable == EA_RATE) this->production_offset_y = ir.top;
first = false; first = false;
} }
@@ -956,26 +943,24 @@ public:
SetDParam(1, i->last_month_production[j]); SetDParam(1, i->last_month_production[j]);
SetDParamStr(2, cargo_suffix[j].text); SetDParamStr(2, cargo_suffix[j].text);
SetDParam(3, ToPercent8(i->last_month_pct_transported[j])); 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(ir.Indent(this->editable == EA_RATE ? SETTING_BUTTON_WIDTH + 10 : 0, false), STR_INDUSTRY_VIEW_TRANSPORTED);
DrawString(x, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_TRANSPORTED);
/* Let's put out those buttons.. */ /* Let's put out those buttons.. */
if (this->editable == EA_RATE) { 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); i->production_rate[j] > 0, i->production_rate[j] < 255);
} }
y += FONT_HEIGHT_NORMAL; ir.top += FONT_HEIGHT_NORMAL;
} }
/* Display production multiplier if editable */ /* Display production multiplier if editable */
if (this->editable == EA_MULTIPLIER) { if (this->editable == EA_MULTIPLIER) {
y += WD_PAR_VSEP_WIDE; ir.top += WD_PAR_VSEP_WIDE;
this->production_offset_y = y; this->production_offset_y = ir.top;
SetDParam(0, RoundDivSU(i->prod_level * 100, PRODLEVEL_DEFAULT)); SetDParam(0, RoundDivSU(i->prod_level * 100, PRODLEVEL_DEFAULT));
uint x = left + WD_FRAMETEXT_LEFT + SETTING_BUTTON_WIDTH + 10; DrawString(ir.Indent(SETTING_BUTTON_WIDTH + 10, false), STR_INDUSTRY_VIEW_PRODUCTION_LEVEL);
DrawString(x, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LEVEL); DrawArrowButtons(ir.left, ir.top, COLOUR_YELLOW, (this->clicked_line == IL_MULTIPLIER) ? this->clicked_button : 0,
DrawArrowButtons(left + WD_FRAMETEXT_LEFT, y, COLOUR_YELLOW, (this->clicked_line == IL_MULTIPLIER) ? this->clicked_button : 0,
i->prod_level > PRODLEVEL_MINIMUM, i->prod_level < PRODLEVEL_MAXIMUM); 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 */ /* Get the extra message for the GUI */
@@ -987,13 +972,13 @@ public:
} else { } else {
StringID message = GetGRFStringID(ind->grf_prop.grffile->grfid, 0xD000 + callback_res); StringID message = GetGRFStringID(ind->grf_prop.grffile->grfid, 0xD000 + callback_res);
if (message != STR_NULL && message != STR_UNDEFINED) { if (message != STR_NULL && message != STR_UNDEFINED) {
y += WD_PAR_VSEP_WIDE; ir.top += WD_PAR_VSEP_WIDE;
StartTextRefStackUsage(ind->grf_prop.grffile, 6); StartTextRefStackUsage(ind->grf_prop.grffile, 6);
/* Use all the available space left from where we stand up to the /* 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 * end of the window. We ALSO enlarge the window if needed, so we
* can 'go' wild with the bottom of the window. */ * 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(); StopTextRefStackUsage();
} }
} }
@@ -1002,11 +987,11 @@ public:
if (!i->text.empty()) { if (!i->text.empty()) {
SetDParamStr(0, i->text); SetDParamStr(0, i->text);
y += WD_PAR_VSEP_WIDE; ir.top += 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 = 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 void SetStringParameters(int widget) const override
@@ -1684,9 +1669,9 @@ public:
case WID_ID_INDUSTRY_LIST: { case WID_ID_INDUSTRY_LIST: {
int n = 0; 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) { 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; break;
} }
TextColour tc; TextColour tc;
@@ -1699,9 +1684,9 @@ public:
tc = TC_GREY | TC_FORCED; 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 if (++n == this->vscroll->GetCapacity()) break; // max number of industries in 1 window
} }
break; break;
@@ -2956,14 +2941,13 @@ struct IndustryCargoesWindow : public Window {
{ {
if (widget != WID_IC_PANEL) return; 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; DrawPixelInfo tmp_dpi, *old_dpi;
int width = r.Width(); if (!FillDrawPixelInfo(&tmp_dpi, ir.left, ir.top, ir.Width(), ir.Height())) return;
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;
old_dpi = _cur_dpi; old_dpi = _cur_dpi;
_cur_dpi = &tmp_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; 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; int last_column = (this->ind_cargo < NUM_INDUSTRYTYPES) ? 4 : 2;

View File

@@ -739,8 +739,8 @@ void LinkGraphLegendWindow::UpdateWidgetSize(int widget, Dimension *size, const
} }
if (str != STR_NULL) { if (str != STR_NULL) {
Dimension dim = GetStringBoundingBox(str); Dimension dim = GetStringBoundingBox(str);
dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; dim.width += padding.width;
dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; dim.height += padding.height;
*size = maxdim(*size, dim); *size = maxdim(*size, dim);
} }
} }
@@ -748,8 +748,8 @@ void LinkGraphLegendWindow::UpdateWidgetSize(int widget, Dimension *size, const
CargoSpec *cargo = CargoSpec::Get(widget - WID_LGL_CARGO_FIRST); CargoSpec *cargo = CargoSpec::Get(widget - WID_LGL_CARGO_FIRST);
if (cargo->IsValid()) { if (cargo->IsValid()) {
Dimension dim = GetStringBoundingBox(cargo->abbrev); Dimension dim = GetStringBoundingBox(cargo->abbrev);
dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; dim.width += padding.width;
dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; dim.height += padding.height;
*size = maxdim(*size, dim); *size = maxdim(*size, dim);
} }
} }
@@ -757,15 +757,17 @@ void LinkGraphLegendWindow::UpdateWidgetSize(int widget, Dimension *size, const
void LinkGraphLegendWindow::DrawWidget(const Rect &r, int widget) 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 (IsInsideMM(widget, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST + 1)) {
if (this->IsWidgetDisabled(widget)) return; if (this->IsWidgetDisabled(widget)) return;
CompanyID cid = (CompanyID)(widget - WID_LGL_COMPANY_FIRST); CompanyID cid = (CompanyID)(widget - WID_LGL_COMPANY_FIRST);
Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON); 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)) { 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]; 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; StringID str = STR_NULL;
if (widget == WID_LGL_SATURATION_FIRST) { if (widget == WID_LGL_SATURATION_FIRST) {
str = STR_LINKGRAPH_LEGEND_UNUSED; str = STR_LINKGRAPH_LEGEND_UNUSED;
@@ -775,14 +777,14 @@ void LinkGraphLegendWindow::DrawWidget(const Rect &r, int widget) const
str = STR_LINKGRAPH_LEGEND_SATURATED; str = STR_LINKGRAPH_LEGEND_SATURATED;
} }
if (str != STR_NULL) { 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 (IsInsideMM(widget, WID_LGL_CARGO_FIRST, WID_LGL_CARGO_LAST + 1)) {
if (this->IsWidgetDisabled(widget)) return; if (this->IsWidgetDisabled(widget)) return;
CargoSpec *cargo = CargoSpec::Get(widget - WID_LGL_CARGO_FIRST); 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); GfxFillRect(br, 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); DrawString(br.left, br.right, CenterBounds(br.top, br.bottom, FONT_HEIGHT_SMALL), cargo->abbrev, GetContrastColour(cargo->legend_colour, 73), SA_HOR_CENTER);
} }
} }

View File

@@ -76,16 +76,15 @@ public:
{ {
if (widget != WID_LI_BACKGROUND) return; 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++) { 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); DrawString(ir, this->landinfo_data[i], i == 0 ? TC_LIGHT_BLUE : TC_FROMSTRING, SA_HOR_CENTER);
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; ir.top += FONT_HEIGHT_NORMAL + (i == 0 ? WD_PAR_VSEP_WIDE : WD_PAR_VSEP_NORMAL);
if (i == 0) y += 4;
} }
if (!this->cargo_acceptance.empty()) { if (!this->cargo_acceptance.empty()) {
SetDParamStr(0, this->cargo_acceptance); 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);
} }
} }
@@ -98,8 +97,7 @@ public:
uint width = GetStringBoundingBox(this->landinfo_data[i]).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; uint width = GetStringBoundingBox(this->landinfo_data[i]).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
size->width = std::max(size->width, width); size->width = std::max(size->width, width);
size->height += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; size->height += FONT_HEIGHT_NORMAL + (i == 0 ? WD_PAR_VSEP_WIDE : WD_PAR_VSEP_NORMAL);
if (i == 0) size->height += 4;
} }
if (!this->cargo_acceptance.empty()) { if (!this->cargo_acceptance.empty()) {
@@ -778,15 +776,15 @@ struct TooltipsWindow : public Window
} }
/* Increase slightly to have some space around the box. */ /* Increase slightly to have some space around the box. */
size->width += 2 + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; size->width += 2 + padding.width;
size->height += 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; size->height += 2 + padding.height;
} }
void DrawWidget(const Rect &r, int widget) const override void DrawWidget(const Rect &r, int widget) const override
{ {
/* There is only one widget. */ /* There is only one widget. */
GfxFillRect(r.left, r.top, r.right, r.bottom, PC_BLACK); GfxFillRect(r, PC_BLACK);
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_LIGHT_YELLOW); GfxFillRect(r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_LIGHT_YELLOW);
if (this->paramcount == 0) { if (this->paramcount == 0) {
DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, this->buffer, TC_FROMSTRING, SA_CENTER); DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, this->buffer, TC_FROMSTRING, SA_CENTER);
@@ -873,24 +871,21 @@ void QueryString::DrawEditBox(const Window *w, int wid) const
Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); 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_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT;
int clearbtn_left = wi->pos_x + (rtl ? 0 : wi->current_x - clearbtn_width); Rect r = wi->GetCurrentRect();
int clearbtn_right = wi->pos_x + (rtl ? clearbtn_width : wi->current_x) - 1; Rect cr = r.WithWidth(clearbtn_width, !rtl);
int left = wi->pos_x + (rtl ? clearbtn_width : 0); Rect fr = r.Indent(clearbtn_width, !rtl);
int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1;
int top = wi->pos_y; DrawFrameRect(cr, wi->colour, wi->IsLowered() ? FR_LOWERED : FR_NONE);
int bottom = wi->pos_y + wi->current_y - 1; 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); DrawFrameRect(fr, wi->colour, FR_LOWERED | FR_DARKENED);
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)); GfxFillRect(fr.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM), PC_BLACK);
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);
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 */ /* Limit the drawing of the string inside the widget boundaries */
DrawPixelInfo dpi; 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; DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &dpi; _cur_dpi = &dpi;
@@ -898,12 +893,12 @@ void QueryString::DrawEditBox(const Window *w, int wid) const
/* We will take the current widget length as maximum width, with a small /* We will take the current widget length as maximum width, with a small
* space reserved at the end for the caret to show */ * space reserved at the end for the caret to show */
const Textbuf *tb = &this->text; 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 (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs;
/* If we have a marked area, draw a background highlight. */ /* 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); DrawString(delta, tb->pixels, 0, tb->buf, TC_YELLOW);
bool focussed = w->IsWidgetGloballyFocused(wid) || IsOSKOpenedFor(w, wid); bool focussed = w->IsWidgetGloballyFocused(wid) || IsOSKOpenedFor(w, wid);
@@ -931,15 +926,14 @@ Point QueryString::GetCaretPosition(const Window *w, int wid) const
Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); 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_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT;
int left = wi->pos_x + (rtl ? clearbtn_width : 0); Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM);
int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1;
/* Clamp caret position to be inside out current width. */ /* Clamp caret position to be inside out current width. */
const Textbuf *tb = &this->text; 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; 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; return pt;
} }
@@ -961,24 +955,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); 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_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT;
int left = wi->pos_x + (rtl ? clearbtn_width : 0); Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM);
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;
/* Clamp caret position to be inside our current width. */ /* Clamp caret position to be inside our current width. */
const Textbuf *tb = &this->text; 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; if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs;
/* Get location of first and last character. */ /* Get location of first and last character. */
Point p1 = GetCharPosInString(tb->buf, from, FS_NORMAL); Point p1 = GetCharPosInString(tb->buf, from, FS_NORMAL);
Point p2 = from != to ? GetCharPosInString(tb->buf, to, FS_NORMAL) : p1; 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 { Clamp(r.left + p1.x + delta, r.left, r.right), r.top, Clamp(r.left + p2.x + delta, r.left, r.right), r.bottom };
return r;
} }
/** /**
@@ -998,20 +986,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); 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_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT;
int left = wi->pos_x + (rtl ? clearbtn_width : 0); Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM);
int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1;
int top = wi->pos_y + WD_FRAMERECT_TOP; if (!IsInsideMM(pt.y, r.top, r.bottom)) return nullptr;
int bottom = wi->pos_y + wi->current_y - 1 - WD_FRAMERECT_BOTTOM;
if (!IsInsideMM(pt.y, top, bottom)) return nullptr;
/* Clamp caret position to be inside our current width. */ /* Clamp caret position to be inside our current width. */
const Textbuf *tb = &this->text; 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; 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) void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bool focus_changed)
@@ -1023,9 +1007,9 @@ void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bo
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
int clearbtn_width = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT).width; 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) { if (this->text.bytes > 1) {
this->text.DeleteAll(); this->text.DeleteAll();
w->HandleButtonClick(wid); w->HandleButtonClick(wid);
@@ -1116,8 +1100,7 @@ struct QueryStringWindow : public Window
if (widget != WID_QS_WARNING) return; if (widget != WID_QS_WARNING) return;
if (this->flags & QSF_PASSWORD) { if (this->flags & QSF_PASSWORD) {
DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT - WD_FRAMERECT_RIGHT, 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),
r.top + WD_FRAMERECT_TOP + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMERECT_BOTTOM - WD_FRAMETEXT_BOTTOM,
STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER); STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER);
} }
} }
@@ -1270,7 +1253,7 @@ struct QueryWindow : public Window {
{ {
if (widget != WID_Q_TEXT) return; 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); this->message, TC_FROMSTRING, SA_CENTER);
} }

View File

@@ -522,29 +522,29 @@ struct MusicTrackSelectionWindow : public Window {
{ {
switch (widget) { switch (widget) {
case WID_MTS_LIST_LEFT: { 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) { for (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) {
SetDParam(0, song->tracknr); SetDParam(0, song->tracknr);
SetDParam(1, 2); SetDParam(1, 2);
SetDParamStr(2, song->songname); SetDParamStr(2, song->songname);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME); DrawString(tr, STR_PLAYLIST_TRACK_NAME);
y += FONT_HEIGHT_SMALL; tr.top += FONT_HEIGHT_SMALL;
} }
break; break;
} }
case WID_MTS_LIST_RIGHT: { 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) { for (MusicSystem::Playlist::const_iterator song = _music.active_playlist.begin(); song != _music.active_playlist.end(); ++song) {
SetDParam(0, song->tracknr); SetDParam(0, song->tracknr);
SetDParam(1, 2); SetDParam(1, 2);
SetDParamStr(2, song->songname); SetDParamStr(2, song->songname);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME); DrawString(tr, STR_PLAYLIST_TRACK_NAME);
y += FONT_HEIGHT_SMALL; tr.top += FONT_HEIGHT_SMALL;
} }
break; break;
} }
@@ -682,8 +682,8 @@ struct MusicWindow : public Window {
case WID_M_TRACK_NR: { case WID_M_TRACK_NR: {
Dimension d = GetStringBoundingBox(STR_MUSIC_TRACK_NONE); Dimension d = GetStringBoundingBox(STR_MUSIC_TRACK_NONE);
d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; d.width += padding.width;
d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; d.height += padding.height;
*size = maxdim(*size, d); *size = maxdim(*size, d);
break; break;
} }
@@ -694,8 +694,8 @@ struct MusicWindow : public Window {
SetDParamStr(0, song->songname); SetDParamStr(0, song->songname);
d = maxdim(d, GetStringBoundingBox(STR_MUSIC_TITLE_NAME)); d = maxdim(d, GetStringBoundingBox(STR_MUSIC_TITLE_NAME));
} }
d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; d.width += padding.width;
d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; d.height += padding.height;
*size = maxdim(*size, d); *size = maxdim(*size, d);
break; break;
} }
@@ -712,7 +712,7 @@ struct MusicWindow : public Window {
{ {
switch (widget) { switch (widget) {
case WID_M_TRACK_NR: { 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) { if (BaseMusic::GetUsedSet()->num_available == 0) {
break; break;
} }
@@ -722,12 +722,12 @@ struct MusicWindow : public Window {
SetDParam(1, 2); SetDParam(1, 2);
str = STR_MUSIC_TRACK_DIGIT; 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; break;
} }
case WID_M_TRACK_NAME: { 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; StringID str = STR_MUSIC_TITLE_NONE;
MusicSystem::PlaylistEntry entry(_music.GetCurrentSong()); MusicSystem::PlaylistEntry entry(_music.GetCurrentSong());
if (BaseMusic::GetUsedSet()->num_available == 0) { if (BaseMusic::GetUsedSet()->num_available == 0) {
@@ -736,16 +736,16 @@ struct MusicWindow : public Window {
str = STR_MUSIC_TITLE_NAME; str = STR_MUSIC_TITLE_NAME;
SetDParamStr(0, entry.songname); 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; break;
} }
case WID_M_MUSIC_VOL: case WID_M_MUSIC_VOL:
DrawVolumeSliderWidget(r, _settings_client.music.music_vol); DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol, {});
break; break;
case WID_M_EFFECT_VOL: case WID_M_EFFECT_VOL:
DrawVolumeSliderWidget(r, _settings_client.music.effect_vol); DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol, {});
break; break;
} }
} }
@@ -788,7 +788,7 @@ struct MusicWindow : public Window {
case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: { // volume sliders 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; byte &vol = (widget == WID_M_MUSIC_VOL) ? _settings_client.music.music_vol : _settings_client.music.effect_vol;
if (ClickVolumeSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, vol)) { if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, 0, INT8_MAX, vol)) {
if (widget == WID_M_MUSIC_VOL) { if (widget == WID_M_MUSIC_VOL) {
MusicDriver::GetInstance()->SetVolume(vol); MusicDriver::GetInstance()->SetVolume(vol);
} else { } else {

View File

@@ -571,7 +571,7 @@ public:
} }
case WID_NCL_MATRIX: 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; size->height = 10 * resize->height;
break; break;
} }
@@ -614,17 +614,15 @@ public:
*/ */
void DrawMatrix(const Rect &r) const void DrawMatrix(const Rect &r) const
{ {
const NWidgetBase *nwi_checkbox = this->GetWidget<NWidgetBase>(WID_NCL_CHECKBOX); Rect checkbox = this->GetWidget<NWidgetBase>(WID_NCL_CHECKBOX)->GetCurrentRect();
const NWidgetBase *nwi_name = this->GetWidget<NWidgetBase>(WID_NCL_NAME); Rect name = this->GetWidget<NWidgetBase>(WID_NCL_NAME)->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, 0, WD_FRAMERECT_RIGHT, 0);
const NWidgetBase *nwi_type = this->GetWidget<NWidgetBase>(WID_NCL_TYPE); Rect type = this->GetWidget<NWidgetBase>(WID_NCL_TYPE)->GetCurrentRect();
int line_height = std::max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL);
/* Fill the matrix with the information */ /* Fill the matrix with the information */
int sprite_y_offset = WD_MATRIX_TOP + (line_height - this->checkbox_size.height) / 2 - 1; int sprite_y_offset = (this->resize.step_height - this->checkbox_size.height) / 2;
int text_y_offset = WD_MATRIX_TOP + (line_height - FONT_HEIGHT_NORMAL) / 2; int text_y_offset = (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2;
uint y = r.top;
Rect mr = r.WithHeight(this->resize.step_height);
auto iter = this->content.begin() + this->vscroll->GetPosition(); auto iter = this->content.begin() + this->vscroll->GetPosition();
size_t last = this->vscroll->GetPosition() + this->vscroll->GetCapacity(); size_t last = this->vscroll->GetPosition() + this->vscroll->GetCapacity();
auto end = (last < this->content.size()) ? this->content.begin() + last : this->content.end(); auto end = (last < this->content.size()) ? this->content.begin() + last : this->content.end();
@@ -632,7 +630,7 @@ public:
for (/**/; iter != end; iter++) { for (/**/; iter != end; iter++) {
const ContentInfo *ci = *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 sprite;
SpriteID pal = PAL_NONE; SpriteID pal = PAL_NONE;
@@ -644,13 +642,13 @@ public:
case ContentInfo::DOES_NOT_EXIST: sprite = SPR_BLOT; pal = PALETTE_TO_RED; break; case ContentInfo::DOES_NOT_EXIST: sprite = SPR_BLOT; pal = PALETTE_TO_RED; break;
default: NOT_REACHED(); 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; 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); DrawString(name.left, name.right, mr.top + text_y_offset, ci->name, TC_BLACK);
y += this->resize.step_height; mr = mr.Translate(0, this->resize.step_height);
} }
} }
@@ -660,60 +658,59 @@ public:
*/ */
void DrawDetails(const Rect &r) const 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 */ /* 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 */ /* 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); GfxFillRect(r.WithHeight(HEADER_HEIGHT).Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, 0), 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); DrawString(hr.left, hr.right, hr.top, STR_CONTENT_DETAIL_TITLE, TC_FROMSTRING, SA_HOR_CENTER);
/* Draw the total download size */ /* Draw the total download size */
SetDParam(0, this->filesize_sum); 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; if (this->selected == nullptr) return;
/* And fill the rest of the details when there's information to place there */ /* 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 */ /* 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; tr.bottom -= FONT_HEIGHT_NORMAL + WD_PAR_VSEP_WIDE;
int y = r.top + DETAIL_TITLE_HEIGHT + DETAIL_TOP;
if (this->selected->upgrade) { if (this->selected->upgrade) {
SetDParam(0, STR_CONTENT_TYPE_BASE_GRAPHICS + this->selected->type - CONTENT_TYPE_BASE_GRAPHICS); 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); tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_UPDATE);
y += WD_PAR_VSEP_WIDE; tr.top += WD_PAR_VSEP_WIDE;
} }
SetDParamStr(0, this->selected->name); 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()) { if (!this->selected->version.empty()) {
SetDParamStr(0, this->selected->version); 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()) { if (!this->selected->description.empty()) {
SetDParamStr(0, this->selected->description); 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()) { if (!this->selected->url.empty()) {
SetDParamStr(0, this->selected->url); 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); 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); 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()) { if (!this->selected->dependencies.empty()) {
/* List dependencies */ /* List dependencies */
@@ -731,7 +728,7 @@ public:
} }
} }
SetDParamStr(0, buf); 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()) { if (!this->selected->tags.empty()) {
@@ -742,7 +739,7 @@ public:
p += seprintf(p, lastof(buf), p == buf ? "%s" : ", %s", tag.c_str()); p += seprintf(p, lastof(buf), p == buf ? "%s" : ", %s", tag.c_str());
} }
SetDParamStr(0, buf); 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()) { if (this->selected->IsSelected()) {
@@ -759,7 +756,7 @@ public:
} }
if (p != buf) { if (p != buf) {
SetDParamStr(0, 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);
} }
} }
} }

View File

@@ -127,7 +127,7 @@ public:
/* First initialise some variables... */ /* First initialise some variables... */
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
child_wid->SetupSmallestSize(w, init_array); 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. */ /* ... then in a second pass make sure the 'current' sizes are set. Won't change for most widgets. */
@@ -647,15 +647,19 @@ public:
{ {
NetworkGameList *sel = this->server; 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 */ /* 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) { 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) { } 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; StringID message = INVALID_STRING_ID;
switch (sel->status) { switch (sel->status) {
case NGLS_OFFLINE: message = STR_NETWORK_SERVER_LIST_SERVER_OFFLINE; break; case NGLS_OFFLINE: message = STR_NETWORK_SERVER_LIST_SERVER_OFFLINE; break;
@@ -666,63 +670,63 @@ public:
/* Handled by the if-case above. */ /* Handled by the if-case above. */
case NGLS_ONLINE: NOT_REACHED(); 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 } 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(hr.left, hr.right, hr.top, 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 DrawStringMultiLine(hr.left, hr.right, hr.top + FONT_HEIGHT_NORMAL, hr.bottom, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name
uint16 y = r.top + detail_height + 4;
SetDParam(0, sel->info.clients_on); SetDParam(0, sel->info.clients_on);
SetDParam(1, sel->info.clients_max); SetDParam(1, sel->info.clients_max);
SetDParam(2, sel->info.companies_on); SetDParam(2, sel->info.companies_on);
SetDParam(3, sel->info.companies_max); SetDParam(3, sel->info.companies_max);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CLIENTS); DrawString(tr, STR_NETWORK_SERVER_LIST_CLIENTS);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
SetDParam(0, STR_CLIMATE_TEMPERATE_LANDSCAPE + sel->info.landscape); 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 DrawString(tr, STR_NETWORK_SERVER_LIST_LANDSCAPE); // landscape
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
SetDParam(0, sel->info.map_width); SetDParam(0, sel->info.map_width);
SetDParam(1, sel->info.map_height); 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 DrawString(tr, STR_NETWORK_SERVER_LIST_MAP_SIZE); // map size
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
SetDParamStr(0, sel->info.server_revision); 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 DrawString(tr, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
SetDParamStr(0, sel->connection_string); 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; 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 DrawString(tr, invite_or_address); // server address / invite code
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
SetDParam(0, sel->info.start_date); 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 DrawString(tr, STR_NETWORK_SERVER_LIST_START_DATE); // start date
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
SetDParam(0, sel->info.game_date); 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 DrawString(tr, STR_NETWORK_SERVER_LIST_CURRENT_DATE); // current date
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
if (sel->info.gamescript_version != -1) { if (sel->info.gamescript_version != -1) {
SetDParamStr(0, sel->info.gamescript_name); SetDParamStr(0, sel->info.gamescript_name);
SetDParam(1, sel->info.gamescript_version); 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 tr.top = DrawStringMultiLine(tr, STR_NETWORK_SERVER_LIST_GAMESCRIPT); // gamescript name and version
y += FONT_HEIGHT_NORMAL;
} }
y += WD_PAR_VSEP_NORMAL; tr.top += WD_PAR_VSEP_WIDE;
if (!sel->info.compatible) { 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) { } else if (sel->info.clients_on == sel->info.clients_max) {
/* Show: server full, when clients_on == max_clients */ /* 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) { } 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
} }
} }
} }
@@ -2102,8 +2106,8 @@ public:
uint line = 0; uint line = 0;
if (this->hover_index >= 0) { if (this->hover_index >= 0) {
uint offset = this->hover_index * this->line_height; Rect br = r.WithHeight(this->line_height).Translate(0, 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)); 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); NetworkClientInfo *own_ci = NetworkClientInfo::GetByClientID(_network_own_client_id);
@@ -2328,8 +2332,7 @@ struct NetworkCompanyPasswordWindow : public Window {
{ {
if (widget != WID_NCP_WARNING) return; if (widget != WID_NCP_WARNING) return;
DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, DrawStringMultiLine(r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM),
r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM,
STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER); STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER);
} }
@@ -2429,7 +2432,7 @@ struct NetworkAskRelayWindow : public Window {
void DrawWidget(const Rect &r, int widget) const override void DrawWidget(const Rect &r, int widget) const override
{ {
if (widget == WID_NAR_TEXT) { 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);
} }
} }

View File

@@ -293,11 +293,6 @@ static inline const NIHelper *GetFeatureHelper(uint window_number)
/** Window used for inspecting NewGRFs. */ /** Window used for inspecting NewGRFs. */
struct NewGRFInspectWindow : Window { 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. */ /** The value for the variable 60 parameters. */
static uint32 var60params[GSF_FAKE_END][0x20]; static uint32 var60params[GSF_FAKE_END][0x20];
@@ -428,7 +423,7 @@ struct NewGRFInspectWindow : Window {
resize->height = std::max(11, FONT_HEIGHT_NORMAL + 1); resize->height = std::max(11, FONT_HEIGHT_NORMAL + 1);
resize->width = 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; break;
} }
} }
@@ -453,7 +448,7 @@ struct NewGRFInspectWindow : Window {
offset -= this->vscroll->GetPosition(); offset -= this->vscroll->GetPosition();
if (offset < 0 || offset >= this->vscroll->GetCapacity()) return; 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 void DrawWidget(const Rect &r, int widget) const override
@@ -474,7 +469,8 @@ struct NewGRFInspectWindow : Window {
if (u == v) sel_end = total_width; 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; int skip = 0;
if (total_width > width) { if (total_width > width) {
int sel_center = (sel_start + sel_end) / 2; int sel_center = (sel_start + sel_end) / 2;
@@ -483,8 +479,8 @@ struct NewGRFInspectWindow : Window {
GrfSpecFeature f = GetFeatureNum(this->window_number); GrfSpecFeature f = GetFeatureNum(this->window_number);
int h = GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height; int h = GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height;
int y = CenterBounds(r.top, r.bottom, h); int y = CenterBounds(br.top, br.bottom, h);
DrawVehicleImage(v->First(), r.left + WD_BEVEL_LEFT, r.right - WD_BEVEL_RIGHT, y + 1, INVALID_VEHICLE, EIT_IN_DETAILS, skip); 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 */ /* Highlight the articulated part (this is different to the whole-vehicle highlighting of DrawVehicleImage */
if (_current_text_dir == TD_RTL) { if (_current_text_dir == TD_RTL) {
@@ -540,7 +536,7 @@ struct NewGRFInspectWindow : Window {
offset -= this->vscroll->GetPosition(); offset -= this->vscroll->GetPosition();
if (offset < 0 || offset >= this->vscroll->GetCapacity()) return; 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.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP + (offset * this->resize.step_height), buf, TC_BLACK);
}; };
const_cast<NewGRFInspectWindow *>(this)->sprite_group_lines.clear(); const_cast<NewGRFInspectWindow *>(this)->sprite_group_lines.clear();
const_cast<NewGRFInspectWindow *>(this)->highlight_tag_lines.clear(); const_cast<NewGRFInspectWindow *>(this)->highlight_tag_lines.clear();
@@ -601,7 +597,7 @@ struct NewGRFInspectWindow : Window {
} }
} }
} }
::DrawString(r.left + LEFT_OFFSET, r.right - RIGHT_OFFSET, r.top + TOP_OFFSET + (scroll_offset * this->resize.step_height), buf, colour); ::DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP + (scroll_offset * this->resize.step_height), buf, colour);
}); });
SpriteGroupDumper::use_shadows = false; SpriteGroupDumper::use_shadows = false;
return; return;
@@ -671,9 +667,9 @@ struct NewGRFInspectWindow : Window {
if (offset >= 0 && offset < this->vscroll->GetCapacity()) { if (offset >= 0 && offset < this->vscroll->GetCapacity()) {
char buf[512]; char buf[512];
seprintf(buf, lastof(buf), " %s: ", info->name); seprintf(buf, lastof(buf), " %s: ", info->name);
::DrawString(r.left + LEFT_OFFSET, r.right - RIGHT_OFFSET, r.top + TOP_OFFSET + (offset * this->resize.step_height), buf, TC_BLACK); ::DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP + (offset * this->resize.step_height), buf, TC_BLACK);
seprintf(buf, lastof(buf), "%08x (%s)", value, niv->name); seprintf(buf, lastof(buf), "%08x (%s)", value, niv->name);
::DrawString(r.left + LEFT_OFFSET + prefix_width, r.right - RIGHT_OFFSET, r.top + TOP_OFFSET + (offset * this->resize.step_height), buf, TC_BLACK); ::DrawString(r.left + WD_FRAMETEXT_LEFT + prefix_width, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP + (offset * this->resize.step_height), buf, TC_BLACK);
} }
} }
break; break;
@@ -826,7 +822,7 @@ struct NewGRFInspectWindow : Window {
case WID_NGRFI_MAINPANEL: { case WID_NGRFI_MAINPANEL: {
/* Get the line, make sure it's within the boundaries. */ /* 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; if (line == INT_MAX) return;
if (this->sprite_dump) { if (this->sprite_dump) {
@@ -974,7 +970,7 @@ struct NewGRFInspectWindow : Window {
void OnResize() override 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);
} }
/** /**
@@ -1286,7 +1282,7 @@ struct SpriteAlignerWindow : Window {
size->height = ScaleGUITrad(200); size->height = ScaleGUITrad(200);
break; break;
case WID_SA_LIST: 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; resize->width = 1;
fill->height = resize->height; fill->height = resize->height;
break; break;
@@ -1301,13 +1297,12 @@ struct SpriteAlignerWindow : Window {
case WID_SA_SPRITE: { case WID_SA_SPRITE: {
/* Center the sprite ourselves */ /* Center the sprite ourselves */
const Sprite *spr = GetSprite(this->current_sprite, ST_NORMAL); const Sprite *spr = GetSprite(this->current_sprite, ST_NORMAL);
int width = r.Width() - WD_BEVEL_LEFT - WD_BEVEL_RIGHT; Rect ir = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM);
int height = r.Height() - WD_BEVEL_TOP - WD_BEVEL_BOTTOM; int x = -UnScaleGUI(spr->x_offs) + (ir.Width() - UnScaleGUI(spr->width) ) / 2;
int x = -UnScaleGUI(spr->x_offs) + (width - UnScaleGUI(spr->width) ) / 2; int y = -UnScaleGUI(spr->y_offs) + (ir.Height() - UnScaleGUI(spr->height)) / 2;
int y = -UnScaleGUI(spr->y_offs) + (height - UnScaleGUI(spr->height)) / 2;
DrawPixelInfo new_dpi; 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; DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &new_dpi; _cur_dpi = &new_dpi;
@@ -1325,11 +1320,11 @@ struct SpriteAlignerWindow : Window {
std::vector<SpriteID> &list = _newgrf_debug_sprite_picker.sprites; std::vector<SpriteID> &list = _newgrf_debug_sprite_picker.sprites;
int max = std::min<int>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)list.size()); int max = std::min<int>(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++) { for (int i = this->vscroll->GetPosition(); i < max; i++) {
SetDParam(0, list[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); DrawString(ir, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
y += step_size; ir.top += step_size;
} }
break; break;
} }

View File

@@ -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) { if (c->error != nullptr) {
char message[512]; char message[512];
SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages 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)); GetString(message, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message));
SetDParamStr(0, 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) */ /* Draw filename or not if it is not known (GRF sent over internet) */
if (c->filename != nullptr) { if (c->filename != nullptr) {
SetDParamStr(0, c->filename); 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 */ /* Prepare and draw GRF ID */
char buff[256]; char buff[256];
seprintf(buff, lastof(buff), "%08X", BSWAP32(c->ident.grfid)); seprintf(buff, lastof(buff), "%08X", BSWAP32(c->ident.grfid));
SetDParamStr(0, buff); 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) { if ((_settings_client.gui.newgrf_developer_tools || _settings_client.gui.newgrf_show_old_versions) && c->version != 0) {
SetDParam(0, c->version); 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) { 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); 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 */ /* Prepare and draw MD5 sum */
md5sumToString(buff, lastof(buff), c->ident.md5sum); md5sumToString(buff, lastof(buff), c->ident.md5sum);
SetDParamStr(0, buff); 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 */ /* Show GRF parameter list */
if (show_params) { if (show_params) {
@@ -117,7 +118,7 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint
} else { } else {
SetDParam(0, STR_NEWGRF_SETTINGS_PARAMETER_NONE); 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 */ /* Draw the palette of the NewGRF */
if (c->palette & GRFP_BLT_32BPP) { if (c->palette & GRFP_BLT_32BPP) {
@@ -125,21 +126,21 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint
} else { } else {
SetDParam(0, (c->palette & GRFP_USE_WINDOWS) ? STR_NEWGRF_SETTINGS_PALETTE_LEGACY : STR_NEWGRF_SETTINGS_PALETTE_DEFAULT); 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 */ /* Show flags */
if (c->status == GCS_NOT_FOUND) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_NOT_FOUND); if (c->status == GCS_NOT_FOUND) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_NOT_FOUND);
if (c->status == GCS_DISABLED) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_DISABLED); if (c->status == GCS_DISABLED) tr.top = DrawStringMultiLine(tr, 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_INVALID)) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_INCOMPATIBLE);
if (HasBit(c->flags, GCF_COMPATIBLE)) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_COMPATIBLE_LOADED); if (HasBit(c->flags, GCF_COMPATIBLE)) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_COMPATIBLE_LOADED);
/* Draw GRF info if it exists */ /* Draw GRF info if it exists */
if (!StrEmpty(c->GetDescription())) { if (!StrEmpty(c->GetDescription())) {
SetDParamStr(0, 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 { } 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; if (par_info == nullptr) return;
const char *desc = GetGRFStringFromGRFText(par_info->desc); const char *desc = GetGRFStringFromGRFText(par_info->desc);
if (desc == nullptr) return; 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; return;
} else if (widget != WID_NP_BACKGROUND) { } else if (widget != WID_NP_BACKGROUND) {
return; return;
} }
Rect ir = r.Shrink(WD_FRAMERECT_LEFT, 0, WD_FRAMERECT_RIGHT, 0);
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
uint buttons_left = rtl ? r.right - SETTING_BUTTON_WIDTH - 3 : r.left + 4; uint buttons_left = rtl ? ir.right - SETTING_BUTTON_WIDTH - 3 : ir.left + 4;
uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8); Rect tr = r.Indent(SETTING_BUTTON_WIDTH + 8, rtl);
uint text_right = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT);
int y = r.top;
int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 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++) { 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); bool selected = (i == this->clicked_row);
if (par_info->type == PTYPE_BOOL) { 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); 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) { } else if (par_info->type == PTYPE_UINT_ENUM) {
if (par_info->complete_labels) { 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 { } 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(2, STR_JUST_INT);
SetDParam(3, current_value); SetDParam(3, current_value);
@@ -301,8 +301,8 @@ struct NewGRFParametersWindow : public Window {
SetDParam(1, i + 1); SetDParam(1, i + 1);
} }
DrawString(text_left, text_right, y + text_y_offset, STR_NEWGRF_PARAMETERS_SETTING, selected ? TC_WHITE : TC_LIGHT_BLUE); DrawString(tr.left, tr.right, ir.top + text_y_offset, STR_NEWGRF_PARAMETERS_SETTING, selected ? TC_WHITE : TC_LIGHT_BLUE);
y += this->line_height; ir.top += this->line_height;
} }
} }
@@ -729,13 +729,13 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
{ {
Dimension d = maxdim(GetSpriteSize(SPR_SQUARE), GetSpriteSize(SPR_WARNING_SIGN)); Dimension d = maxdim(GetSpriteSize(SPR_SQUARE), GetSpriteSize(SPR_WARNING_SIGN));
resize->height = std::max(d.height + 2U, FONT_HEIGHT_NORMAL + 2U); 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; break;
} }
case WID_NS_AVAIL_LIST: case WID_NS_AVAIL_LIST:
resize->height = std::max(12, FONT_HEIGHT_NORMAL + 2); 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; break;
case WID_NS_NEWGRF_INFO_TITLE: { case WID_NS_NEWGRF_INFO_TITLE: {
@@ -830,10 +830,11 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
{ {
switch (widget) { switch (widget) {
case WID_NS_FILE_LIST: { 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<NWidgetBase>(WID_NS_FILE_LIST)->resize_y; uint step_height = this->GetWidget<NWidgetBase>(WID_NS_FILE_LIST)->resize_y;
uint y = r.top + WD_FRAMERECT_TOP;
Dimension square = GetSpriteSize(SPR_SQUARE); Dimension square = GetSpriteSize(SPR_SQUARE);
Dimension warning = GetSpriteSize(SPR_WARNING_SIGN); Dimension warning = GetSpriteSize(SPR_WARNING_SIGN);
int square_offset_y = (step_height - square.height) / 2; int square_offset_y = (step_height - square.height) / 2;
@@ -841,10 +842,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2;
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
uint text_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.left + square.width + 15; uint text_left = rtl ? tr.left : tr.left + square.width + 13;
uint text_right = rtl ? r.right - square.width - 15 : r.right - WD_FRAMERECT_RIGHT; uint text_right = rtl ? tr.right - square.width - 13 : tr.right;
uint square_left = rtl ? r.right - square.width - 5 : r.left + 5; uint square_left = rtl ? tr.right - square.width - 3 : tr.left + 3;
uint warning_left = rtl ? r.right - square.width - warning.width - 10 : r.left + square.width + 10; uint warning_left = rtl ? tr.right - square.width - warning.width - 8 : tr.left + square.width + 8;
int i = 0; int i = 0;
for (const GRFConfig *c = this->actives; c != nullptr; c = c->next, i++) { for (const GRFConfig *c = this->actives; c != nullptr; c = c->next, i++) {
@@ -854,35 +855,36 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
PaletteID pal = this->GetPalette(c); PaletteID pal = this->GetPalette(c);
if (h) { 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) { } else if (i == this->active_over) {
/* Get index of current selection. */ /* Get index of current selection. */
int active_sel_pos = 0; int active_sel_pos = 0;
for (GRFConfig *c = this->actives; c != nullptr && c != this->active_sel; c = c->next, active_sel_pos++) {} for (GRFConfig *c = this->actives; c != nullptr && c != this->active_sel; c = c->next, active_sel_pos++) {}
if (active_sel_pos != this->active_over) { if (active_sel_pos != this->active_over) {
uint top = this->active_over < active_sel_pos ? y + 1 : y + step_height - 2; uint top = this->active_over < active_sel_pos ? tr.top + 1 : tr.top + step_height - 2;
GfxFillRect(r.left + WD_FRAMERECT_LEFT, top - 1, r.right - WD_FRAMERECT_RIGHT, top + 1, PC_GREY); GfxFillRect(tr.left, top - 1, tr.right, top + 1, PC_GREY);
} }
} }
DrawSprite(SPR_SQUARE, pal, square_left, y + square_offset_y); DrawSprite(SPR_SQUARE, pal, square_left, tr.top + square_offset_y);
if (c->error != nullptr) DrawSprite(SPR_WARNING_SIGN, 0, warning_left, y + warning_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; 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); DrawString(text_left + (rtl ? 0 : txtoffset), text_right - (rtl ? txtoffset : 0), tr.top + offset_y, text, h ? TC_WHITE : TC_ORANGE);
y += step_height; tr.top += step_height;
} }
} }
if (i == this->active_over && this->vscroll->IsVisible(i)) { // Highlight is after the last GRF entry. 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; break;
} }
case WID_NS_AVAIL_LIST: { 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<NWidgetBase>(WID_NS_AVAIL_LIST)->resize_y; uint step_height = this->GetWidget<NWidgetBase>(WID_NS_AVAIL_LIST)->resize_y;
int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2;
uint y = r.top + WD_FRAMERECT_TOP;
uint min_index = this->vscroll2->GetPosition(); uint min_index = this->vscroll2->GetPosition();
uint max_index = std::min(min_index + this->vscroll2->GetCapacity(), (uint)this->avails.size()); uint max_index = std::min(min_index + this->vscroll2->GetCapacity(), (uint)this->avails.size());
@@ -891,16 +893,16 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
bool h = (c == this->avail_sel); bool h = (c == this->avail_sel);
const char *text = c->GetName(); const char *text = c->GetName();
if (h) GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 1, PC_DARK_BLUE); if (h) GfxFillRect(br.left, tr.top, br.right, tr.top + 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); DrawString(tr.left, tr.right, tr.top + offset_y, text, h ? TC_WHITE : TC_SILVER);
y += step_height; tr.top += step_height;
} }
break; break;
} }
case WID_NS_NEWGRF_INFO_TITLE: case WID_NS_NEWGRF_INFO_TITLE:
/* Create the nice grayish rectangle at the details top. */ /* 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); DrawString(r.left, r.right, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), STR_NEWGRF_SETTINGS_INFO_TITLE, TC_FROMSTRING, SA_HOR_CENTER);
break; break;
@@ -908,7 +910,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
const GRFConfig *selected = this->active_sel; const GRFConfig *selected = this->active_sel;
if (selected == nullptr) selected = this->avail_sel; if (selected == nullptr) selected = this->avail_sel;
if (selected != nullptr) { 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; break;
} }
@@ -1615,13 +1617,13 @@ public:
this->acs->SetupSmallestSize(w, init_array); this->acs->SetupSmallestSize(w, init_array);
this->inf->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_avs_width = this->avs->smallest_x + this->avs->padding.Horizontal();
uint min_acs_width = this->acs->smallest_x + this->acs->padding_left + this->acs->padding_right; uint min_acs_width = this->acs->smallest_x + this->acs->padding.Horizontal();
uint min_inf_width = this->inf->smallest_x + this->inf->padding_left + this->inf->padding_right; 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_avs_height = this->avs->smallest_y + this->avs->padding.Vertical();
uint min_acs_height = this->acs->smallest_y + this->acs->padding_top + this->acs->padding_bottom; uint min_acs_height = this->acs->smallest_y + this->acs->padding.Vertical();
uint min_inf_height = this->inf->smallest_y + this->inf->padding_top + this->inf->padding_bottom; uint min_inf_height = this->inf->smallest_y + this->inf->padding.Vertical();
/* Smallest window is in two column mode. */ /* Smallest window is in two column mode. */
this->smallest_x = std::max(min_avs_width, min_acs_width) + INTER_COLUMN_SPACING + min_inf_width; this->smallest_x = std::max(min_avs_width, min_acs_width) + INTER_COLUMN_SPACING + min_inf_width;
@@ -1651,9 +1653,9 @@ public:
{ {
this->StoreSizePosition(sizing, x, y, given_width, given_height); 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_avs_width = this->avs->smallest_x + this->avs->padding.Horizontal();
uint min_acs_width = this->acs->smallest_x + this->acs->padding_left + this->acs->padding_right; uint min_acs_width = this->acs->smallest_x + this->acs->padding.Horizontal();
uint min_inf_width = this->inf->smallest_x + this->inf->padding_left + this->inf->padding_right; 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 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. uint avs_extra_width = min_list_width - min_avs_width; // Additional width needed for avs to reach min_list_width.
@@ -1689,10 +1691,10 @@ public:
avs_width = ComputeMaxSize(this->avs->smallest_x, this->avs->smallest_x + avs_width, this->avs->GetHorizontalStepSize(sizing)); 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. uint acs_width = given_width - // Remaining space, including horizontal padding.
inf_width - this->inf->padding_left - this->inf->padding_right - inf_width - this->inf->padding.Horizontal() -
avs_width - this->avs->padding_left - this->avs->padding_right - 2 * INTER_COLUMN_SPACING; avs_width - this->avs->padding.Horizontal() - 2 * INTER_COLUMN_SPACING;
acs_width = ComputeMaxSize(min_acs_width, acs_width, this->acs->GetHorizontalStepSize(sizing)) - 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 */ /* 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); uint avs_height = ComputeMaxSize(this->avs->smallest_y, given_height, this->avs->resize_y);
@@ -1700,25 +1702,25 @@ public:
/* Assign size and position to the children. */ /* Assign size and position to the children. */
if (rtl) { if (rtl) {
x += this->inf->padding_left; x += this->inf->padding.left;
this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); 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 += inf_width + this->inf->padding.right + INTER_COLUMN_SPACING;
} else { } else {
x += this->avs->padding_left; x += this->avs->padding.left;
this->avs->AssignSizePosition(sizing, x, y + this->avs->padding_top, avs_width, avs_height, rtl); 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 += avs_width + this->avs->padding.right + INTER_COLUMN_SPACING;
} }
x += this->acs->padding_left; x += this->acs->padding.left;
this->acs->AssignSizePosition(sizing, x, y + this->acs->padding_top, acs_width, acs_height, rtl); 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 += acs_width + this->acs->padding.right + INTER_COLUMN_SPACING;
if (rtl) { if (rtl) {
x += this->avs->padding_left; x += this->avs->padding.left;
this->avs->AssignSizePosition(sizing, x, y + this->avs->padding_top, avs_width, avs_height, rtl); this->avs->AssignSizePosition(sizing, x, y + this->avs->padding.top, avs_width, avs_height, rtl);
} else { } else {
x += this->inf->padding_left; x += this->inf->padding.left;
this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl);
} }
} else { } else {
/* Two columns, all space in extra_width goes to both lists. Since the lists are underneath each other, /* Two columns, all space in extra_width goes to both lists. Since the lists are underneath each other,
@@ -1728,8 +1730,8 @@ public:
uint acs_width = ComputeMaxSize(this->acs->smallest_x, this->acs->smallest_x + acs_extra_width + extra_width, uint acs_width = ComputeMaxSize(this->acs->smallest_x, this->acs->smallest_x + acs_extra_width + extra_width,
this->acs->GetHorizontalStepSize(sizing)); 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_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_top + this->acs->padding_bottom; uint min_acs_height = this->acs->smallest_y + this->acs->padding.Vertical();
uint extra_height = given_height - min_acs_height - min_avs_height; 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 */ /* Never use fill_y on these; instead use the INTER_LIST_SPACING as filler */
@@ -1739,29 +1741,29 @@ public:
/* Assign size and position to the children. */ /* Assign size and position to the children. */
if (rtl) { if (rtl) {
x += this->inf->padding_left; x += this->inf->padding.left;
this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); 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 += 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) { 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 { } else {
this->avs->AssignSizePosition(sizing, 0, 0, this->avs->smallest_x, this->avs->smallest_y, rtl); this->avs->AssignSizePosition(sizing, 0, 0, this->avs->smallest_x, this->avs->smallest_y, rtl);
} }
} else { } 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) { 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 { } else {
this->avs->AssignSizePosition(sizing, 0, 0, this->avs->smallest_x, this->avs->smallest_y, rtl); 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) { 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; x += dx + INTER_COLUMN_SPACING + this->inf->padding.left;
this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl);
} }
} }
} }
@@ -2113,20 +2115,21 @@ struct SavePresetWindow : public Window {
{ {
switch (widget) { switch (widget) {
case WID_SVP_PRESET_LIST: { 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<NWidgetBase>(WID_SVP_PRESET_LIST)->resize_y; uint step_height = this->GetWidget<NWidgetBase>(WID_SVP_PRESET_LIST)->resize_y;
int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; 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 min_index = this->vscroll->GetPosition();
uint max_index = std::min(min_index + this->vscroll->GetCapacity(), (uint)this->presets.size()); uint max_index = std::min(min_index + this->vscroll->GetCapacity(), (uint)this->presets.size());
for (uint i = min_index; i < max_index; i++) { 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(); 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); DrawString(tr.left, tr.right, tr.top + offset_y, text, ((int)i == this->selected) ? TC_WHITE : TC_SILVER);
y += step_height; tr.top += step_height;
} }
break; break;
} }

View File

@@ -1143,9 +1143,6 @@ static void DrawNewsString(uint left, uint right, int y, TextColour colour, cons
} }
struct MessageHistoryWindow : Window { 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 line_height; /// < Height of a single line in the news history window including spacing.
int date_width; /// < Width needed for the date part. int date_width; /// < Width needed for the date part.
@@ -1162,7 +1159,7 @@ struct MessageHistoryWindow : Window {
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{ {
if (widget == WID_MH_BACKGROUND) { 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; resize->height = this->line_height;
/* Months are off-by-one, so it's actually 8. Not using /* Months are off-by-one, so it's actually 8. Not using
@@ -1170,7 +1167,7 @@ struct MessageHistoryWindow : Window {
SetDParam(0, ConvertYMDToDate(ORIGINAL_MAX_YEAR, 7, 30)); SetDParam(0, ConvertYMDToDate(ORIGINAL_MAX_YEAR, 7, 30));
this->date_width = GetStringBoundingBox(STR_SHORT_DATE).width; 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. size->width = std::max(200u, size->width); // At least 200 pixels wide.
} }
} }
@@ -1193,17 +1190,15 @@ struct MessageHistoryWindow : Window {
} }
/* Fill the widget with news items. */ /* Fill the widget with news items. */
int y = r.top + this->top_spacing;
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
uint date_left = rtl ? r.right - WD_FRAMERECT_RIGHT - this->date_width : r.left + WD_FRAMERECT_LEFT; Rect news = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM).Indent(this->date_width + ScaleFontTrad(5), rtl);
uint date_right = rtl ? r.right - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT + this->date_width; Rect date = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM).WithWidth(this->date_width, rtl);
uint news_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.left + WD_FRAMERECT_LEFT + this->date_width + WD_FRAMERECT_RIGHT + ScaleFontTrad(5); int y = news.top;
uint news_right = rtl ? r.right - WD_FRAMERECT_RIGHT - this->date_width - WD_FRAMERECT_RIGHT - ScaleFontTrad(5) : r.right - WD_FRAMERECT_RIGHT;
for (int n = this->vscroll->GetCapacity(); n > 0; n--) { for (int n = this->vscroll->GetCapacity(); n > 0; n--) {
SetDParam(0, ni->date); 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; y += this->line_height;
ni = ni->prev; ni = ni->prev;
@@ -1243,9 +1238,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[] = { static const NWidgetPart _nested_message_history[] = {
NWidget(NWID_HORIZONTAL), NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CLOSEBOX, COLOUR_BROWN),

View File

@@ -236,7 +236,7 @@ public:
size->width = std::max(size->width, GetStringBoundingBox(objclass->name).width); size->width = std::max(size->width, GetStringBoundingBox(objclass->name).width);
} }
size->width += padding.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; resize->height = this->line_height;
size->height = 5 * this->line_height; size->height = 5 * this->line_height;
break; break;
@@ -310,8 +310,8 @@ public:
break; break;
case WID_BO_SELECT_IMAGE: case WID_BO_SELECT_IMAGE:
size->width = ScaleGUITrad(64) + 2; size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT;
size->height = ScaleGUITrad(58) + 2; size->height = ScaleGUITrad(58) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM;
break; break;
default: break; default: break;
@@ -322,15 +322,15 @@ public:
{ {
switch (GB(widget, 0, 16)) { switch (GB(widget, 0, 16)) {
case WID_BO_CLASS_LIST: { 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; uint pos = 0;
for (auto object_class_id : this->object_classes) { for (auto object_class_id : this->object_classes) {
ObjectClass *objclass = ObjectClass::Get(object_class_id); ObjectClass *objclass = ObjectClass::Get(object_class_id);
if (objclass->GetUISpecCount() == 0) continue; if (objclass->GetUISpecCount() == 0) continue;
if (!this->vscroll->IsVisible(pos++)) 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); (object_class_id == _selected_object_class) ? TC_WHITE : TC_BLACK);
y += this->line_height; mr.top += this->line_height;
} }
break; break;
} }
@@ -357,9 +357,9 @@ public:
if (spec->grf_prop.grffile == nullptr) { if (spec->grf_prop.grffile == nullptr) {
extern const DrawTileSprites _objects[]; extern const DrawTileSprites _objects[];
const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; 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 { } 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; _cur_dpi = old_dpi;
} }
@@ -374,19 +374,19 @@ public:
if (spec == nullptr) break; if (spec == nullptr) break;
if (!spec->IsAvailable()) { 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; DrawPixelInfo tmp_dpi;
/* Set up a clipping area for the preview. */ /* 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; DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &tmp_dpi; _cur_dpi = &tmp_dpi;
if (spec->grf_prop.grffile == nullptr) { if (spec->grf_prop.grffile == nullptr) {
extern const DrawTileSprites _objects[]; extern const DrawTileSprites _objects[];
const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; 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 { } 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<int>(_selected_object_view, spec->views - 1)); std::min<int>(_selected_object_view, spec->views - 1));
} }
_cur_dpi = old_dpi; _cur_dpi = old_dpi;

View File

@@ -1795,7 +1795,7 @@ public:
case WID_O_SEL_OCCUPANCY: case WID_O_SEL_OCCUPANCY:
case WID_O_ORDER_LIST: case WID_O_ORDER_LIST:
resize->height = FONT_HEIGHT_NORMAL; resize->height = FONT_HEIGHT_NORMAL;
size->height = 6 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; size->height = 6 * resize->height + padding.height;
break; break;
case WID_O_COND_VARIABLE: { case WID_O_COND_VARIABLE: {
@@ -2246,12 +2246,13 @@ public:
void DrawOrderListWidget(const Rect &r) const void DrawOrderListWidget(const Rect &r) const
{ {
Rect ir = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMERECT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMERECT_BOTTOM);
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
SetDParamMaxValue(0, this->vehicle->GetNumOrders(), 2); 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 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<NWidgetBase>(WID_O_ORDER_LIST)->resize_y; int line_height = this->GetWidget<NWidgetBase>(WID_O_ORDER_LIST)->resize_y;
int i = this->vscroll->GetPosition(); int i = this->vscroll->GetPosition();
@@ -2265,9 +2266,9 @@ public:
if (i != this->selected_order && i == this->order_over) { if (i != this->selected_order && i == this->order_over) {
/* Highlight dragged order destination. */ /* Highlight dragged order destination. */
int top = (this->order_over < this->selected_order ? y : y + line_height) - WD_FRAMERECT_TOP; 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); int bottom = std::min(top + 2, ir.bottom);
top = std::max(top - 3, r.top + WD_FRAMERECT_TOP); top = std::max(top - 3, ir.top);
GfxFillRect(r.left + WD_FRAMETEXT_LEFT, top, r.right - WD_FRAMETEXT_RIGHT, bottom, _colour_gradient[COLOUR_GREY][7]); GfxFillRect(ir.left, top, ir.right, bottom, _colour_gradient[COLOUR_GREY][7]);
break; break;
} }
y += line_height; y += line_height;

View File

@@ -1344,7 +1344,7 @@ public:
d = maxdim(d, GetStringBoundingBox(StationClass::Get(station_class)->name)); d = maxdim(d, GetStringBoundingBox(StationClass::Get(station_class)->name));
} }
size->width = std::max(size->width, d.width + padding.width); 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; size->height = 5 * this->line_height;
resize->height = this->line_height; resize->height = this->line_height;
break; break;
@@ -1376,8 +1376,8 @@ public:
case WID_BRAS_PLATFORM_DIR_X: case WID_BRAS_PLATFORM_DIR_X:
case WID_BRAS_PLATFORM_DIR_Y: case WID_BRAS_PLATFORM_DIR_Y:
case WID_BRAS_IMAGE: case WID_BRAS_IMAGE:
size->width = ScaleGUITrad(64) + 2; size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT;
size->height = ScaleGUITrad(58) + 2; size->height = ScaleGUITrad(58) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM;
break; break;
case WID_BRAS_COVERAGE_TEXTS: case WID_BRAS_COVERAGE_TEXTS:
@@ -1401,8 +1401,8 @@ public:
if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) {
DrawPixelInfo *old_dpi = _cur_dpi; DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &tmp_dpi; _cur_dpi = &tmp_dpi;
int x = ScaleGUITrad(31) + 1; int x = (r.Width() - ScaleGUITrad(64)) / 2 + ScaleGUITrad(31);
int y = r.bottom - r.top - 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)) { if (!DrawStationTile(x, y, _cur_railtype, AXIS_X, _railstation.station_class, _railstation.station_type)) {
StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2); StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2);
} }
@@ -1415,8 +1415,8 @@ public:
if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) {
DrawPixelInfo *old_dpi = _cur_dpi; DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &tmp_dpi; _cur_dpi = &tmp_dpi;
int x = ScaleGUITrad(31) + 1; int x = (r.Width() - ScaleGUITrad(64)) / 2 + ScaleGUITrad(31);
int y = r.bottom - r.top - 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)) { if (!DrawStationTile(x, y, _cur_railtype, AXIS_Y, _railstation.station_class, _railstation.station_type)) {
StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 3); StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 3);
} }
@@ -1425,14 +1425,14 @@ public:
break; break;
case WID_BRAS_NEWST_LIST: { 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 statclass = 0;
uint row = 0;
for (auto station_class : this->station_classes) { for (auto station_class : this->station_classes) {
if (this->vscroll->IsVisible(statclass)) { 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, StationClass::Get(station_class)->name,
station_class == _railstation.station_class ? TC_WHITE : TC_BLACK); station_class == _railstation.station_class ? TC_WHITE : TC_BLACK);
row++; ir.top += this->line_height;
} }
statclass++; statclass++;
} }
@@ -1445,15 +1445,15 @@ public:
/* Check station availability callback */ /* Check station availability callback */
const StationSpec *statspec = StationClass::Get(_railstation.station_class)->GetSpec(type); const StationSpec *statspec = StationClass::Get(_railstation.station_class)->GetSpec(type);
if (!IsStationAvailable(statspec)) { 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. */ /* Set up a clipping area for the station preview. */
if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) {
DrawPixelInfo *old_dpi = _cur_dpi; DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &tmp_dpi; _cur_dpi = &tmp_dpi;
int x = ScaleGUITrad(31) + 1; int x = (r.Width() - ScaleGUITrad(64)) / 2 + ScaleGUITrad(31);
int y = r.bottom - r.top - ScaleGUITrad(31); int y = (r.Height() + ScaleGUITrad(58)) / 2 - ScaleGUITrad(31);
if (!DrawStationTile(x, y, _cur_railtype, _railstation.orientation, _railstation.station_class, type)) { if (!DrawStationTile(x, y, _cur_railtype, _railstation.orientation, _railstation.station_class, type)) {
StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2 + _railstation.orientation); StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2 + _railstation.orientation);
} }
@@ -2291,15 +2291,23 @@ struct BuildRailDepotWindow : public PickerWindowBase {
{ {
if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return; if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return;
size->width = ScaleGUITrad(64) + 2; size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT;
size->height = ScaleGUITrad(48) + 2; size->height = ScaleGUITrad(48) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM;
} }
void DrawWidget(const Rect &r, int widget) const override void DrawWidget(const Rect &r, int widget) const override
{ {
if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return; 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 void OnClick(Point pt, int widget, int click_count) override
@@ -2390,8 +2398,8 @@ struct BuildRailWaypointWindow : PickerWindowBase {
break; break;
case WID_BRW_WAYPOINT: case WID_BRW_WAYPOINT:
size->width = ScaleGUITrad(64) + 2; size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT;
size->height = ScaleGUITrad(58) + 2; size->height = ScaleGUITrad(58) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM;
break; break;
} }
} }
@@ -2402,10 +2410,19 @@ struct BuildRailWaypointWindow : PickerWindowBase {
case WID_BRW_WAYPOINT: { case WID_BRW_WAYPOINT: {
uint type = GB(widget, 16, 16); uint type = GB(widget, 16, 16);
const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP)->GetSpec(type); 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)) { 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);
} }
} }
} }

View File

@@ -1129,15 +1129,23 @@ struct BuildRoadDepotWindow : public PickerWindowBase {
{ {
if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return; if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return;
size->width = ScaleGUITrad(64) + 2; size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT;
size->height = ScaleGUITrad(48) + 2; size->height = ScaleGUITrad(48) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM;
} }
void DrawWidget(const Rect &r, int widget) const override void DrawWidget(const Rect &r, int widget) const override
{ {
if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return; 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 void OnClick(Point pt, int widget, int click_count) override
@@ -1493,8 +1501,8 @@ public:
} }
case WID_BROS_IMAGE: case WID_BROS_IMAGE:
size->width = ScaleGUITrad(64) + 2; size->width = ScaleGUITrad(64) + WD_BEVEL_LEFT + WD_BEVEL_RIGHT;
size->height = ScaleGUITrad(58) + 2; size->height = ScaleGUITrad(48) + WD_BEVEL_TOP + WD_BEVEL_BOTTOM;
break; break;
case WID_BROS_STATION_NE: case WID_BROS_STATION_NE:
@@ -1540,8 +1548,16 @@ public:
const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(_roadstop_gui_settings.roadstop_type); const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(_roadstop_gui_settings.roadstop_type);
bool disabled = (spec != nullptr && widget < WID_BROS_STATION_X && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)); bool disabled = (spec != nullptr && widget < WID_BROS_STATION_X && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY));
if (spec == nullptr || disabled) { if (spec == nullptr || disabled) {
StationPickerDrawSprite(r.left + WD_MATRIX_LEFT + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE); DrawPixelInfo tmp_dpi;
if (disabled) GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER); 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);
if (disabled) GfxFillRect(1, 1, r.Width() - 1, r.Height() - 1, PC_BLACK, FILLRECT_CHECKER);
_cur_dpi = old_dpi;
}
} else { } else {
DrawRoadStopTile(r.left + WD_MATRIX_LEFT + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), _cur_roadtype, spec, st, (int)widget - WID_BROS_STATION_NE); DrawRoadStopTile(r.left + WD_MATRIX_LEFT + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), _cur_roadtype, spec, st, (int)widget - WID_BROS_STATION_NE);
} }

View File

@@ -23,20 +23,19 @@
* Draw the details for the given vehicle at the given position * Draw the details for the given vehicle at the given position
* *
* @param v current vehicle * @param v current vehicle
* @param left The left most coordinate to draw * @param r the Rect to draw within
* @param right The right most coordinate to draw
* @param y The y coordinate
*/ */
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; StringID str;
Money feeder_share = 0; Money feeder_share = 0;
SetDParam(0, v->engine_type); SetDParam(0, v->engine_type);
SetDParam(1, v->build_year); SetDParam(1, v->build_year);
SetDParam(2, v->value); 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()) { if (v->HasArticulatedPart()) {
CargoArray max_cargo; 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()) { for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
if (u->cargo_cap == 0) continue; 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; str = STR_VEHICLE_DETAILS_CARGO_FROM;
feeder_share += u->cargo.FeederShare(); feeder_share += u->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;
y_offset += FONT_HEIGHT_NORMAL + 1;
} }
y += WD_PAR_VSEP_NORMAL;
y_offset -= FONT_HEIGHT_NORMAL + 1;
} else { } else {
SetDParam(0, v->cargo_type); SetDParam(0, v->cargo_type);
SetDParam(1, v->cargo_cap); SetDParam(1, v->cargo_cap);
SetDParam(4, GetCargoSubtypeText(v)); 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; str = STR_VEHICLE_DETAILS_CARGO_EMPTY;
if (v->cargo.StoredCount() > 0) { if (v->cargo.StoredCount() > 0) {
@@ -109,16 +108,18 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y)
str = STR_VEHICLE_DETAILS_CARGO_FROM; str = STR_VEHICLE_DETAILS_CARGO_FROM;
feeder_share += v->cargo.FeederShare(); 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 */ /* Draw Transfer credits text */
SetDParam(0, feeder_share); 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);
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
if (RoadVehicle::From(v)->critical_breakdown_count > 0) { if (RoadVehicle::From(v)->critical_breakdown_count > 0) {
SetDParam(0, RoadVehicle::From(v)->GetDisplayEffectiveMaxSpeed()); SetDParam(0, RoadVehicle::From(v)->GetDisplayEffectiveMaxSpeed());
DrawString(left, right, y + 4 * FONT_HEIGHT_NORMAL + 4 + y_offset, STR_NEED_REPAIR); DrawString(r.left, r.right, y, STR_NEED_REPAIR);
} }
} }

View File

@@ -374,11 +374,11 @@ struct GameOptionsWindow : Window {
break; break;
case WID_GO_BASE_SFX_VOLUME: case WID_GO_BASE_SFX_VOLUME:
DrawVolumeSliderWidget(r, _settings_client.music.effect_vol); DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol, {});
break; break;
case WID_GO_BASE_MUSIC_VOLUME: case WID_GO_BASE_MUSIC_VOLUME:
DrawVolumeSliderWidget(r, _settings_client.music.music_vol); DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol, {});
break; break;
} }
} }
@@ -505,7 +505,7 @@ struct GameOptionsWindow : Window {
case WID_GO_BASE_SFX_VOLUME: case WID_GO_BASE_SFX_VOLUME:
case WID_GO_BASE_MUSIC_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; byte &vol = (widget == WID_GO_BASE_MUSIC_VOLUME) ? _settings_client.music.music_vol : _settings_client.music.effect_vol;
if (ClickVolumeSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, vol)) { if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, 0, INT8_MAX, vol)) {
if (widget == WID_GO_BASE_MUSIC_VOLUME) MusicDriver::GetInstance()->SetVolume(vol); if (widget == WID_GO_BASE_MUSIC_VOLUME) MusicDriver::GetInstance()->SetVolume(vol);
this->SetWidgetDirty(widget); this->SetWidgetDirty(widget);
SetWindowClassesDirty(WC_MUSIC_WINDOW); SetWindowClassesDirty(WC_MUSIC_WINDOW);
@@ -2359,11 +2359,6 @@ static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed)
/** Window to edit settings of the game. */ /** Window to edit settings of the game. */
struct GameSettingsWindow : Window { 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. 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. SettingEntry *valuewindow_entry; ///< If non-nullptr, pointer to setting for which a value-entering window has been opened.
@@ -2390,7 +2385,6 @@ struct GameSettingsWindow : Window {
this->filter.type_hides = false; this->filter.type_hides = false;
this->settings_ptr = &GetGameSettings(); this->settings_ptr = &GetGameSettings();
_circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED));
GetSettingsTree().FoldAll(); // Close all sub-pages GetSettingsTree().FoldAll(); // Close all sub-pages
this->valuewindow_entry = nullptr; // No setting entry for which a entry window is opened this->valuewindow_entry = nullptr; // No setting entry for which a entry window is opened
@@ -2411,6 +2405,11 @@ struct GameSettingsWindow : Window {
this->InvalidateData(); 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 void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{ {
switch (widget) { switch (widget) {
@@ -2418,7 +2417,7 @@ struct GameSettingsWindow : Window {
resize->height = SETTING_HEIGHT = std::max({(int)_circle_size.height, SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL}) + 1; resize->height = SETTING_HEIGHT = std::max({(int)_circle_size.height, SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL}) + 1;
resize->width = 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; break;
case WID_GS_HELP_TEXT: { case WID_GS_HELP_TEXT: {
@@ -2456,14 +2455,14 @@ struct GameSettingsWindow : Window {
} }
/* Reserve the correct number of lines for the 'some search results are hidden' notice in the central settings display panel. */ /* 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<NWidgetBase>(WID_GS_OPTIONSPANEL); const Rect panel = this->GetWidget<NWidgetBase>(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; StringID warn_str = STR_CONFIG_SETTING_CATEGORY_HIDES - 1 + this->warn_missing;
int new_warn_lines; int new_warn_lines;
if (this->warn_missing == WHR_NONE) { if (this->warn_missing == WHR_NONE) {
new_warn_lines = 0; new_warn_lines = 0;
} else { } else {
SetDParam(0, _game_settings_restrict_dropdown[this->filter.min_cat]); 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) { if (this->warn_lines != new_warn_lines) {
this->vscroll->SetCount(this->vscroll->GetCount() - this->warn_lines + new_warn_lines); this->vscroll->SetCount(this->vscroll->GetCount() - this->warn_lines + new_warn_lines);
@@ -2474,16 +2473,8 @@ struct GameSettingsWindow : Window {
/* Draw the 'some search results are hidden' notice. */ /* Draw the 'some search results are hidden' notice. */
if (this->warn_missing != WHR_NONE) { 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]); SetDParam(0, _game_settings_restrict_dropdown[this->filter.min_cat]);
if (this->warn_lines == 1) { DrawStringMultiLine(panel.WithHeight(this->warn_lines * FONT_HEIGHT_NORMAL), warn_str, TC_FROMSTRING, SA_CENTER);
/* 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);
}
} }
} }
@@ -2533,11 +2524,12 @@ struct GameSettingsWindow : Window {
{ {
switch (widget) { switch (widget) {
case WID_GS_OPTIONSPANEL: { 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; 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); 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; break;
} }
@@ -2545,20 +2537,20 @@ struct GameSettingsWindow : Window {
if (this->last_clicked != nullptr) { if (this->last_clicked != nullptr) {
const IntSettingDesc *sd = this->last_clicked->setting; const IntSettingDesc *sd = this->last_clicked->setting;
int y = r.top; Rect tr = r;
switch (sd->GetType()) { 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_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_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; 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(); default: NOT_REACHED();
} }
DrawString(r.left, r.right, y, STR_CONFIG_SETTING_TYPE); DrawString(tr, STR_CONFIG_SETTING_TYPE);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
std::unique_ptr<SettingEntry::SetValueDParamsTempData> tempdata; std::unique_ptr<SettingEntry::SetValueDParamsTempData> tempdata;
this->last_clicked->SetValueDParams(0, sd->def, tempdata); this->last_clicked->SetValueDParams(0, sd->def, tempdata);
DrawString(r.left, r.right, y, STR_CONFIG_SETTING_DEFAULT_VALUE); DrawString(tr, STR_CONFIG_SETTING_DEFAULT_VALUE);
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; tr.top += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
if (sd->flags & SF_GUI_ADVISE_DEFAULT) { if (sd->flags & SF_GUI_ADVISE_DEFAULT) {
const Dimension warning_dimensions = GetSpriteSize(SPR_WARNING_SIGN); const Dimension warning_dimensions = GetSpriteSize(SPR_WARNING_SIGN);
@@ -2567,20 +2559,20 @@ struct GameSettingsWindow : Window {
const int warning_offset_y = (step_height - warning_dimensions.height) / 2; const int warning_offset_y = (step_height - warning_dimensions.height) / 2;
const bool rtl = _current_text_dir == TD_RTL; const bool rtl = _current_text_dir == TD_RTL;
int left = r.left; int left = tr.left;
int right = r.right; int right = tr.right;
DrawSprite(SPR_WARNING_SIGN, 0, rtl ? right - warning_dimensions.width - 5 : left + 5, y + warning_offset_y); DrawSprite(SPR_WARNING_SIGN, 0, rtl ? right - warning_dimensions.width - 5 : left + 5, tr.top + warning_offset_y);
if (rtl) { if (rtl) {
right -= (warning_dimensions.width + 10); right -= (warning_dimensions.width + 10);
} else { } else {
left += (warning_dimensions.width + 10); left += (warning_dimensions.width + 10);
} }
DrawString(left, right, y + text_offset_y, STR_CONFIG_SETTING_ADVISED_LEAVE_DEFAULT, TC_RED); DrawString(left, right, tr.top + text_offset_y, STR_CONFIG_SETTING_ADVISED_LEAVE_DEFAULT, TC_RED);
y += step_height + WD_PAR_VSEP_NORMAL; tr.top += step_height + 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; break;
@@ -2642,7 +2634,7 @@ struct GameSettingsWindow : Window {
if (widget != WID_GS_OPTIONSPANEL) return; 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; if (btn == INT_MAX || (int)btn < this->warn_lines) return;
btn -= this->warn_lines; btn -= this->warn_lines;
@@ -2651,7 +2643,7 @@ struct GameSettingsWindow : Window {
if (clicked_entry == nullptr) return; // Clicked below the last setting of the page 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 if (x < 0) return; // Clicked left of the entry
SettingsPage *clicked_page = dynamic_cast<SettingsPage*>(clicked_entry); SettingsPage *clicked_page = dynamic_cast<SettingsPage*>(clicked_entry);
@@ -2692,7 +2684,7 @@ struct GameSettingsWindow : Window {
this->closing_dropdown = false; this->closing_dropdown = false;
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_GS_OPTIONSPANEL); const NWidgetBase *wid = this->GetWidget<NWidgetBase>(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; Rect wi_rect;
wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x); wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);
@@ -2950,7 +2942,7 @@ struct GameSettingsWindow : Window {
void OnResize() override 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);
} }
}; };

View File

@@ -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 * Draw the details for the given vehicle at the given position
* *
* @param v current vehicle * @param v current vehicle
* @param left The left most coordinate to draw * @param r the Rect to draw within
* @param right The right most coordinate to draw
* @param y The y coordinate
*/ */
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(0, v->engine_type);
SetDParam(1, v->build_year); SetDParam(1, v->build_year);
SetDParam(2, v->value); 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(0, v->cargo_type);
SetDParam(1, v->cargo_cap); SetDParam(1, v->cargo_cap);
SetDParam(4, GetCargoSubtypeText(v)); 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; StringID str = STR_VEHICLE_DETAILS_CARGO_EMPTY;
if (v->cargo.StoredCount() > 0) { if (v->cargo.StoredCount() > 0) {
@@ -80,14 +82,16 @@ void DrawShipDetails(const Vehicle *v, int left, int right, int y)
SetDParam(2, v->cargo.Source()); SetDParam(2, v->cargo.Source());
str = STR_VEHICLE_DETAILS_CARGO_FROM; 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 */ /* Draw Transfer credits text */
SetDParam(0, v->cargo.FeederShare()); 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);
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
if (Ship::From(v)->critical_breakdown_count > 0) { if (Ship::From(v)->critical_breakdown_count > 0) {
SetDParam(0, Ship::From(v)->GetDisplayEffectiveMaxSpeed()); SetDParam(0, Ship::From(v)->GetDisplayEffectiveMaxSpeed());
DrawString(left, right, y + 4 * FONT_HEIGHT_NORMAL + 4, STR_NEED_REPAIR); DrawString(r.left, r.right, y, STR_NEED_REPAIR);
} }
} }

View File

@@ -193,30 +193,29 @@ struct SignListWindow : Window, SignList {
{ {
switch (widget) { switch (widget) {
case WID_SIL_LIST: { 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; uint text_offset_y = (this->resize.step_height - FONT_HEIGHT_NORMAL + 1) / 2;
/* No signs? */ /* No signs? */
if (this->vscroll->GetCount() == 0) { 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; return;
} }
Dimension d = GetSpriteSize(SPR_COMPANY_ICON); Dimension d = GetSpriteSize(SPR_COMPANY_ICON);
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
int sprite_offset_y = (this->resize.step_height - d.height + 1) / 2; 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 icon_left = rtl ? tr.right - this->text_offset : tr.left;
uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : this->text_offset); tr = tr.Indent(this->text_offset, rtl);
uint text_right = r.right - (rtl ? this->text_offset : WD_FRAMERECT_RIGHT);
/* At least one sign available. */ /* At least one sign available. */
for (uint16 i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) { for (uint16 i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) {
const Sign *si = this->signs[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); SetDParam(0, si->index);
DrawString(text_left, text_right, y + text_offset_y, STR_SIGN_NAME, TC_YELLOW); DrawString(tr.left, tr.right, tr.top + text_offset_y, STR_SIGN_NAME, TC_YELLOW);
y += this->resize.step_height; tr.top += this->resize.step_height;
} }
break; break;
} }

View File

@@ -1241,8 +1241,9 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
{ {
switch (widget) { switch (widget) {
case WID_SM_MAP: { case WID_SM_MAP: {
Rect ir = r.Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM);
DrawPixelInfo new_dpi; 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); this->DrawSmallMap(&new_dpi);
break; break;
} }
@@ -1251,17 +1252,13 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
uint columns = this->GetNumberColumnsLegend(r.Width()); uint columns = this->GetNumberColumnsLegend(r.Width());
uint number_of_rows = this->GetNumberRowsLegend(columns); uint number_of_rows = this->GetNumberRowsLegend(columns);
bool rtl = _current_text_dir == TD_RTL; 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 i = 0; // Row counter for industry legend.
uint row_height = FONT_HEIGHT_SMALL; uint row_height = FONT_HEIGHT_SMALL;
int padding = ScaleFontTrad(1); int padding = ScaleFontTrad(1);
uint text_left = rtl ? 0 : this->legend_width + WD_FRAMERECT_LEFT; Rect origin = r.WithWidth(this->column_width, rtl).Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM).WithHeight(row_height);
uint text_right = this->column_width - padding - (rtl ? this->legend_width + WD_FRAMERECT_RIGHT : 0); Rect text = origin.Indent(this->legend_width + padding, rtl);
uint blob_left = rtl ? this->column_width - padding - this->legend_width : 0; Rect icon = origin.WithWidth(this->legend_width, rtl).Shrink(0, padding, 0, 0);
uint blob_right = rtl ? this->column_width - padding : this->legend_width;
StringID string = STR_NULL; StringID string = STR_NULL;
switch (this->map_type) { switch (this->map_type) {
@@ -1282,8 +1279,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)) { 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 /* Column break needed, continue at top, COLUMN_WIDTH pixels
* (one "row") to the right. */ * (one "row") to the right. */
x += rtl ? -(int)this->column_width : this->column_width; int x = rtl ? -(int)this->column_width : this->column_width;
y = y_org; int y = origin.top - text.top;
text = text.Translate(x, y);
icon = icon.Translate(x, y);
i = 1; i = 1;
} }
@@ -1310,10 +1309,10 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
if (!tbl->show_on_map) { if (!tbl->show_on_map) {
/* Simply draw the string, not the black border of the legend colour. /* Simply draw the string, not the black border of the legend colour.
* This will enforce the idea of the disabled item */ * 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 { } else {
DrawString(x + text_left, x + text_right, y, string, TC_BLACK); DrawString(text, string, TC_BLACK);
GfxFillRect(x + blob_left, y + padding, x + blob_right, y + row_height - 1, PC_BLACK); // Outer border of the legend colour GfxFillRect(icon, PC_BLACK); // Outer border of the legend colour
} }
break; break;
} }
@@ -1322,13 +1321,14 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
default: default:
if (this->map_type == SMT_CONTOUR) SetDParam(0, tbl->height * TILE_HEIGHT_STEP); 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 */ /* 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); GfxFillRect(icon, PC_BLACK);
DrawString(x + text_left, x + text_right, y, tbl->legend); DrawString(text, tbl->legend);
break; 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);
} }
} }
} }

View File

@@ -466,7 +466,7 @@ public:
case WID_STL_LIST: case WID_STL_LIST:
resize->height = std::max(FONT_HEIGHT_NORMAL, FONT_HEIGHT_SMALL + ScaleFontTrad(3)); 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 */ /* Determine appropriate width for mini station rating graph */
this->rating_width = 0; this->rating_width = 0;
@@ -507,7 +507,7 @@ public:
case WID_STL_LIST: { case WID_STL_LIST: {
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
int max = std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->stations.size()); int max = std::min<size_t>(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<NWidgetBase>(widget)->resize_y; uint line_height = this->GetWidget<NWidgetBase>(widget)->resize_y;
/* Spacing between station name and first rating graph. */ /* Spacing between station name and first rating graph. */
int text_spacing = ScaleFontTrad(5); int text_spacing = ScaleFontTrad(5);
@@ -524,7 +524,7 @@ public:
SetDParam(0, st->index); SetDParam(0, st->index);
SetDParam(1, st->facilities); 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; x += rtl ? -text_spacing : text_spacing;
/* show cargo waiting and station ratings */ /* show cargo waiting and station ratings */
@@ -537,20 +537,20 @@ public:
* the space. */ * the space. */
if (rtl) { if (rtl) {
x -= rating_width + rating_spacing; 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) { if (!rtl) {
x += rating_width + rating_spacing; 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 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; return;
} }
break; break;
@@ -558,11 +558,13 @@ public:
default: default:
if (widget >= WID_STL_CARGOSTART) { 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]; const CargoSpec *cs = _sorted_cargo_specs[widget - WID_STL_CARGOSTART];
int cg_ofst = HasBit(this->cargo_filter, cs->Index()) ? 1 : 0; 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); 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; break;
} }
@@ -1457,7 +1459,7 @@ struct StationViewWindow : public Window {
case WID_SV_WAITING: case WID_SV_WAITING:
resize->height = FONT_HEIGHT_NORMAL; resize->height = FONT_HEIGHT_NORMAL;
size->height = WD_FRAMERECT_TOP + 4 * resize->height + WD_FRAMERECT_BOTTOM; 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; break;
case WID_SV_ACCEPT_RATING_LIST: case WID_SV_ACCEPT_RATING_LIST:
@@ -1572,7 +1574,7 @@ struct StationViewWindow : public Window {
/* Draw waiting cargo. */ /* Draw waiting cargo. */
NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_SV_WAITING); NWidgetBase *nwi = this->GetWidget<NWidgetBase>(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); this->DrawEntries(&cargo, waiting_rect, pos, maxrows, 0);
scroll_to_row = INT_MAX; scroll_to_row = INT_MAX;
} }
@@ -1842,7 +1844,7 @@ struct StationViewWindow : public Window {
* @param cargo Current cargo being drawn (if cargo column has been passed). * @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. * @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->sortings[column] == ST_AS_GROUPING) {
if (this->groupings[column] != GR_CARGO) { if (this->groupings[column] != GR_CARGO) {
@@ -1860,13 +1862,13 @@ struct StationViewWindow : public Window {
if (pos > -maxrows && pos <= 0) { if (pos > -maxrows && pos <= 0) {
StringID str = STR_EMPTY; 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(0, cargo);
SetDParam(1, cd->GetCount()); SetDParam(1, cd->GetCount());
if (this->groupings[column] == GR_CARGO) { if (this->groupings[column] == GR_CARGO) {
str = STR_STATION_VIEW_WAITING_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 { } else {
if (!auto_distributed) grouping = GR_SOURCE; if (!auto_distributed) grouping = GR_SOURCE;
StationID station = cd->GetStation(); StationID station = cd->GetStation();
@@ -1891,12 +1893,10 @@ struct StationViewWindow : public Window {
} }
bool rtl = _current_text_dir == TD_RTL; 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; Rect text = r.Indent(column * this->expand_shrink_width, rtl).Indent(this->expand_shrink_width, !rtl);
int text_right = rtl ? r.right - WD_FRAMERECT_LEFT - column * this->expand_shrink_width : r.right - this->expand_shrink_width; Rect shrink = r.WithWidth(this->expand_shrink_width, !rtl);
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;
DrawString(text_left, text_right, y, str); DrawString(text.left, text.right, y, str);
if (column < NUM_COLUMNS - 1) { if (column < NUM_COLUMNS - 1) {
const char *sym = nullptr; const char *sym = nullptr;
@@ -1911,7 +1911,7 @@ struct StationViewWindow : public Window {
sym = "+"; 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); this->SetDisplayedRow(cd);
} }
@@ -1931,13 +1931,14 @@ struct StationViewWindow : public Window {
int DrawAcceptedCargo(const Rect &r) const int DrawAcceptedCargo(const Rect &r) const
{ {
const Station *st = Station::Get(this->window_number); 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; CargoTypes cargo_mask = 0;
for (CargoID i = 0; i < NUM_CARGO; i++) { for (CargoID i = 0; i < NUM_CARGO; i++) {
if (HasBit(st->goods[i].status, GoodsEntry::GES_ACCEPTANCE)) SetBit(cargo_mask, i); if (HasBit(st->goods[i].status, GoodsEntry::GES_ACCEPTANCE)) SetBit(cargo_mask, i);
} }
SetDParam(0, cargo_mask); 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); return CeilDiv(bottom - r.top - WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL);
} }
@@ -1949,18 +1950,19 @@ struct StationViewWindow : public Window {
int DrawCargoRatings(const Rect &r) int DrawCargoRatings(const Rect &r)
{ {
const Station *st = Station::Get(this->window_number); 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) { if (st->town->exclusive_counter > 0) {
SetDParam(0, st->town->exclusivity); 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); tr.top = DrawStringMultiLine(tr, st->town->exclusivity == st->owner ? STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF : STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY);
y += WD_PAR_VSEP_WIDE; tr.top += WD_PAR_VSEP_WIDE;
} }
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_VIEW_SUPPLY_RATINGS_TITLE); DrawString(tr, STR_STATION_VIEW_SUPPLY_RATINGS_TITLE);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
this->ratings_list_y = y; this->ratings_list_y = tr.top;
for (const CargoSpec *cs : _sorted_standard_cargo_specs) { for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
const GoodsEntry *ge = &st->goods[cs->Index()]; const GoodsEntry *ge = &st->goods[cs->Index()];
@@ -1971,14 +1973,16 @@ struct StationViewWindow : public Window {
SetDParam(1, lg != nullptr ? lg->Monthly((*lg)[ge->node].Supply()) : 0); SetDParam(1, lg != nullptr ? lg->Monthly((*lg)[ge->node].Supply()) : 0);
SetDParam(2, STR_CARGO_RATING_APPALLING + (ge->rating >> 5)); SetDParam(2, STR_CARGO_RATING_APPALLING + (ge->rating >> 5));
SetDParam(3, ToPercent8(ge->rating)); SetDParam(3, ToPercent8(ge->rating));
int x = DrawString(r.left + WD_FRAMERECT_LEFT + 6, r.right - WD_FRAMERECT_RIGHT - 6, y, STR_STATION_VIEW_CARGO_SUPPLY_RATING);
Rect rating_rect = tr.Indent(6, rtl);
int x = DrawString(rating_rect, STR_STATION_VIEW_CARGO_SUPPLY_RATING);
if (!ge->IsSupplyAllowed() && x != 0) { if (!ge->IsSupplyAllowed() && x != 0) {
int line_y = y + (FONT_HEIGHT_NORMAL / 2) - 1; int line_y = tr.top + (FONT_HEIGHT_NORMAL / 2) - 1;
GfxDrawLine(r.left + WD_FRAMERECT_LEFT + 6, line_y, x, line_y, PC_WHITE, 1); GfxDrawLine(rating_rect.left, line_y, x, line_y, PC_WHITE, 1);
} }
y += FONT_HEIGHT_NORMAL; 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);
} }
/** /**
@@ -2463,20 +2467,20 @@ struct SelectStationWindow : Window {
{ {
if (widget != WID_JS_PANEL) return; 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) { 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); DrawString(tr, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT : STR_JOIN_STATION_CREATE_SPLITTED_STATION);
y += this->resize.step_height; tr.top += this->resize.step_height;
} }
for (uint i = std::max<uint>(1, this->vscroll->GetPosition()); i <= _stations_nearby_list.size(); ++i, y += this->resize.step_height) { for (uint i = std::max<uint>(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. */ /* Don't draw anything if it extends past the end of the window. */
if (i - this->vscroll->GetPosition() >= this->vscroll->GetCapacity()) break; if (i - this->vscroll->GetPosition() >= this->vscroll->GetCapacity()) break;
const T *st = T::Get(_stations_nearby_list[i - 1]); const T *st = T::Get(_stations_nearby_list[i - 1]);
SetDParam(0, st->index); SetDParam(0, st->index);
SetDParam(1, st->facilities); 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);
} }
} }

View File

@@ -138,24 +138,24 @@ struct StatusBarWindow : Window {
void DrawWidget(const Rect &r, int widget) const override 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 Rect tr = r.Shrink(WD_FRAMERECT_LEFT, 0, WD_FRAMERECT_RIGHT, 0);
int text_top = r.top + text_offset; tr.top = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL);
switch (widget) { switch (widget) {
case WID_S_LEFT: case WID_S_LEFT:
/* Draw the date */ /* Draw the date */
SetDParam(0, _scaled_date_ticks); SetDParam(0, _scaled_date_ticks);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_WHITE_DATE_WALLCLOCK_LONG, TC_FROMSTRING, SA_HOR_CENTER); DrawString(tr, STR_WHITE_DATE_WALLCLOCK_LONG, TC_FROMSTRING, SA_HOR_CENTER);
break; break;
case WID_S_RIGHT: { case WID_S_RIGHT: {
if (_local_company == COMPANY_SPECTATOR) { 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 { } else {
/* Draw company money, if any */ /* Draw company money, if any */
const Company *c = Company::GetIfValid(_local_company); const Company *c = Company::GetIfValid(_local_company);
if (c != nullptr) { if (c != nullptr) {
SetDParam(0, c->money); 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; break;
@@ -164,12 +164,12 @@ struct StatusBarWindow : Window {
case WID_S_MIDDLE: case WID_S_MIDDLE:
/* Draw status bar */ /* Draw status bar */
if (this->saving) { // true when saving is active 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) { } 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) { } else if (_pause_mode != PM_UNPAUSED) {
StringID msg = (_pause_mode & PM_PAUSED_LINK_GRAPH) ? STR_STATUSBAR_PAUSED_LINK_GRAPH : STR_STATUSBAR_PAUSED; 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) { } else if (this->ticker_scroll < TICKER_STOP && _statusbar_news_item != nullptr && _statusbar_news_item->string_id != 0) {
/* Draw the scrolling news text */ /* 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)) { 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)) {
@@ -177,20 +177,20 @@ struct StatusBarWindow : Window {
if (Company::IsValidID(_local_company)) { if (Company::IsValidID(_local_company)) {
/* This is the default text */ /* This is the default text */
SetDParam(0, _local_company); 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 { } else {
if (Company::IsValidID(_local_company)) { if (Company::IsValidID(_local_company)) {
/* This is the default text */ /* This is the default text */
SetDParam(0, _local_company); 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()) { if (!this->reminder_timeout.HasElapsed()) {
Dimension icon_size = GetSpriteSize(SPR_UNREAD_NEWS); 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; break;
} }

View File

@@ -691,19 +691,17 @@ public:
StoryPage *page = this->GetSelPage(); StoryPage *page = this->GetSelPage();
if (page == nullptr) return; if (page == nullptr) return;
const int x = r.left + WD_FRAMETEXT_LEFT; Rect fr = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM);
const int y = r.top + WD_FRAMETEXT_TOP;
const int right = r.right - WD_FRAMETEXT_RIGHT;
const int bottom = r.bottom - WD_FRAMETEXT_BOTTOM;
/* Set up a clipping region for the panel. */ /* Set up a clipping region for the panel. */
DrawPixelInfo tmp_dpi; 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; DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &tmp_dpi; _cur_dpi = &tmp_dpi;
/* Draw content (now coordinates given to Draw** are local to the new clipping region). */ /* 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; int line_height = FONT_HEIGHT_NORMAL;
const int scrollpos = this->vscroll->GetPosition(); const int scrollpos = this->vscroll->GetPosition();
int y_offset = -scrollpos; int y_offset = -scrollpos;
@@ -711,13 +709,13 @@ public:
/* Date */ /* Date */
if (page->date != INVALID_DATE) { if (page->date != INVALID_DATE) {
SetDParam(0, page->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; y_offset += line_height;
/* Title */ /* Title */
SetDParamStr(0, page->title != nullptr ? page->title : this->selected_generic_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 */ /* Page elements */
this->EnsureStoryPageElementLayout(); this->EnsureStoryPageElementLayout();

View File

@@ -133,8 +133,8 @@ struct SubsidyListWindow : Window {
resize->height = d.height; resize->height = d.height;
d.height *= 5; d.height *= 5;
d.width += padding.width + WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT; d.width += padding.width;
d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; d.height += padding.height;
*size = maxdim(*size, d); *size = maxdim(*size, d);
} }
@@ -142,15 +142,13 @@ struct SubsidyListWindow : Window {
{ {
if (widget != WID_SUL_PANEL) return; if (widget != WID_SUL_PANEL) return;
int right = r.right - WD_FRAMERECT_RIGHT; Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM);
int y = r.top + WD_FRAMERECT_TOP;
int x = r.left + WD_FRAMERECT_LEFT;
int pos = -this->vscroll->GetPosition(); int pos = -this->vscroll->GetPosition();
const int cap = this->vscroll->GetCapacity(); const int cap = this->vscroll->GetCapacity();
/* Section for drawing the offered subsidies */ /* 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++; pos++;
uint num = 0; uint num = 0;
@@ -160,7 +158,7 @@ struct SubsidyListWindow : Window {
/* Displays the two offered towns */ /* Displays the two offered towns */
SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::Gui); SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::Gui);
SetDParam(7, _date - _cur_date_ymd.day + s->remaining * 32); SetDParam(7, _date - _cur_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++; pos++;
num++; num++;
@@ -168,13 +166,13 @@ struct SubsidyListWindow : Window {
} }
if (num == 0) { 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++; pos++;
} }
/* Section for drawing the already granted subsidies */ /* Section for drawing the already granted subsidies */
pos++; 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++; pos++;
num = 0; num = 0;
@@ -186,7 +184,7 @@ struct SubsidyListWindow : Window {
SetDParam(8, _date - _cur_date_ymd.day + s->remaining * 32); SetDParam(8, _date - _cur_date_ymd.day + s->remaining * 32);
/* Displays the two connected stations */ /* 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++; pos++;
num++; num++;
@@ -194,7 +192,7 @@ struct SubsidyListWindow : Window {
} }
if (num == 0) { 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++; pos++;
} }
} }

View File

@@ -148,17 +148,15 @@ void TextfileWindow::SetupScrollbars(bool force_reflow)
{ {
if (widget != WID_TF_BACKGROUND) return; if (widget != WID_TF_BACKGROUND) return;
const int x = r.left + WD_FRAMETEXT_LEFT; Rect fr = r.Shrink(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM);
const int y = r.top + WD_FRAMETEXT_TOP;
const int right = r.right - WD_FRAMETEXT_RIGHT;
const int bottom = r.bottom - WD_FRAMETEXT_BOTTOM;
DrawPixelInfo new_dpi; 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; DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &new_dpi; _cur_dpi = &new_dpi;
/* Draw content (now coordinates given to DrawString* are local to the new clipping region). */ /* 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 line_height = FONT_HEIGHT_MONO;
int pos = this->vscroll->GetPosition(); int pos = this->vscroll->GetPosition();
int cap = this->vscroll->GetCapacity(); int cap = this->vscroll->GetCapacity();
@@ -169,9 +167,9 @@ void TextfileWindow::SetupScrollbars(bool force_reflow)
int y_offset = (line.top - pos) * line_height; int y_offset = (line.top - pos) * line_height;
if (IsWidgetLowered(WID_TF_WRAPTEXT)) { 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 { } 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);
} }
} }

View File

@@ -670,7 +670,7 @@ struct TimetableWindow : GeneralVehicleWindow {
switch (widget) { switch (widget) {
case WID_VT_TIMETABLE_PANEL: { 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(); int i = this->vscroll->GetPosition();
Dimension lock_d = GetSpriteSize(SPR_LOCK); Dimension lock_d = GetSpriteSize(SPR_LOCK);
int line_height = std::max<int>(FONT_HEIGHT_NORMAL, lock_d.height); int line_height = std::max<int>(FONT_HEIGHT_NORMAL, lock_d.height);
@@ -680,7 +680,7 @@ struct TimetableWindow : GeneralVehicleWindow {
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
SetDParamMaxValue(0, v->GetNumOrders(), 2); 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 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); const Order *order = v->GetOrder(order_id);
while (order != nullptr) { while (order != nullptr) {
@@ -688,7 +688,7 @@ struct TimetableWindow : GeneralVehicleWindow {
if (!this->vscroll->IsVisible(i)) break; if (!this->vscroll->IsVisible(i)) break;
if (i % 2 == 0) { 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++; order_id++;
@@ -724,16 +724,16 @@ struct TimetableWindow : GeneralVehicleWindow {
} }
SetDParam(string == STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED ? 2 : 4, order->GetMaxSpeed()); SetDParam(string == STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED ? 2 : 4, order->GetMaxSpeed());
int edge = DrawString(rtl ? r.left + WD_FRAMERECT_LEFT : middle, rtl ? middle : r.right - WD_FRAMERECT_LEFT, y, string, colour); int edge = DrawString(rtl ? tr.left : middle, rtl ? middle : tr.right, tr.top, string, colour);
if (order->IsTravelFixed()) { if (order->IsTravelFixed()) {
Dimension lock_d = GetSpriteSize(SPR_LOCK); Dimension lock_d = GetSpriteSize(SPR_LOCK);
DrawPixelInfo tmp_dpi; DrawPixelInfo tmp_dpi;
if (FillDrawPixelInfo(&tmp_dpi, rtl ? r.left + WD_FRAMERECT_LEFT : middle, y, rtl ? middle : r.right - WD_FRAMERECT_LEFT, lock_d.height)) { if (FillDrawPixelInfo(&tmp_dpi, rtl ? tr.left : middle, tr.top, rtl ? middle : tr.right, lock_d.height)) {
DrawPixelInfo *old_dpi = _cur_dpi; DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &tmp_dpi; _cur_dpi = &tmp_dpi;
DrawSprite(SPR_LOCK, PAL_NONE, rtl ? edge - 3 - lock_d.width - (r.left + WD_FRAMERECT_LEFT) : edge + 3 - middle, 0); DrawSprite(SPR_LOCK, PAL_NONE, rtl ? edge - 3 - lock_d.width - tr.left : edge + 3 - middle, 0);
_cur_dpi = old_dpi; _cur_dpi = old_dpi;
} }
@@ -743,7 +743,7 @@ struct TimetableWindow : GeneralVehicleWindow {
} }
i++; i++;
y += line_height; tr.top += line_height;
} }
break; break;
} }
@@ -761,7 +761,7 @@ struct TimetableWindow : GeneralVehicleWindow {
VehicleOrderID earlyID = BuildArrivalDepartureList(v, arr_dep) ? cur_order : (VehicleOrderID)INVALID_VEH_ORDER_ID; 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);
Dimension lock_d = GetSpriteSize(SPR_LOCK); Dimension lock_d = GetSpriteSize(SPR_LOCK);
int line_height = std::max<int>(FONT_HEIGHT_NORMAL, lock_d.height); int line_height = std::max<int>(FONT_HEIGHT_NORMAL, lock_d.height);
@@ -769,10 +769,8 @@ struct TimetableWindow : GeneralVehicleWindow {
Ticks offset = show_late ? 0 : -v->lateness_counter; Ticks offset = show_late ? 0 : -v->lateness_counter;
bool rtl = _current_text_dir == TD_RTL; 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; Rect abbr = tr.WithWidth(this->deparr_abbr_width, rtl);
int abbr_right = rtl ? r.right - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT + this->deparr_abbr_width; Rect time = tr.WithWidth(this->deparr_time_width, !rtl);
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;
for (int i = this->vscroll->GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop 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. */ /* Don't draw anything if it extends past the end of the window. */
@@ -780,56 +778,56 @@ struct TimetableWindow : GeneralVehicleWindow {
if (i % 2 == 0) { if (i % 2 == 0) {
if (arr_dep[i / 2].arrival != INVALID_TICKS) { 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) { if (this->show_expected && i / 2 == earlyID) {
SetDParam(0, _scaled_date_ticks + arr_dep[i / 2].arrival); SetDParam(0, _scaled_date_ticks + arr_dep[i / 2].arrival);
DrawString(time_left, time_right, y, STR_JUST_DATE_WALLCLOCK_TINY, TC_GREEN); DrawString(time.left, time.right, tr.top, STR_JUST_DATE_WALLCLOCK_TINY, TC_GREEN);
} else { } else {
SetDParam(0, _scaled_date_ticks + arr_dep[i / 2].arrival + (HasBit(arr_dep[i / 2].flags, TADF_ARRIVAL_NO_OFFSET) ? 0 : offset)); SetDParam(0, _scaled_date_ticks + arr_dep[i / 2].arrival + (HasBit(arr_dep[i / 2].flags, TADF_ARRIVAL_NO_OFFSET) ? 0 : offset));
DrawString(time_left, time_right, y, STR_JUST_DATE_WALLCLOCK_TINY, DrawString(time.left, time.right, tr.top, STR_JUST_DATE_WALLCLOCK_TINY,
HasBit(arr_dep[i / 2].flags, TADF_ARRIVAL_PREDICTED) ? (TextColour)(TC_IS_PALETTE_COLOUR | TC_NO_SHADE | 4) : (show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK)); HasBit(arr_dep[i / 2].flags, TADF_ARRIVAL_PREDICTED) ? (TextColour)(TC_IS_PALETTE_COLOUR | TC_NO_SHADE | 4) : (show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK));
} }
} }
} else { } else {
if (arr_dep[i / 2].departure != INVALID_TICKS) { 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, _scaled_date_ticks + arr_dep[i/2].departure + (HasBit(arr_dep[i / 2].flags, TADF_DEPARTURE_NO_OFFSET) ? 0 : offset)); SetDParam(0, _scaled_date_ticks + arr_dep[i/2].departure + (HasBit(arr_dep[i / 2].flags, TADF_DEPARTURE_NO_OFFSET) ? 0 : offset));
DrawString(time_left, time_right, y, STR_JUST_DATE_WALLCLOCK_TINY, DrawString(time.left, time.right, tr.top, STR_JUST_DATE_WALLCLOCK_TINY,
HasBit(arr_dep[i / 2].flags, TADF_DEPARTURE_PREDICTED) ? (TextColour)(TC_IS_PALETTE_COLOUR | TC_NO_SHADE | 4) : (show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK)); HasBit(arr_dep[i / 2].flags, TADF_DEPARTURE_PREDICTED) ? (TextColour)(TC_IS_PALETTE_COLOUR | TC_NO_SHADE | 4) : (show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK));
} }
} }
y += line_height; tr.top += line_height;
} }
break; break;
} }
case WID_VT_SUMMARY_PANEL: { 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; Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0;
if (total_time != 0) { if (total_time != 0) {
SetTimetableParams(0, total_time); SetTimetableParams(0, 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) { if (v->timetable_start != 0) {
/* We are running towards the first station so we can start the /* We are running towards the first station so we can start the
* timetable at the given time. */ * timetable at the given time. */
SetDParam(0, STR_JUST_DATE_WALLCLOCK_TINY); SetDParam(0, STR_JUST_DATE_WALLCLOCK_TINY);
SetDParam(1, (((DateTicksScaled) v->timetable_start) * _settings_game.economy.day_length_factor) + v->timetable_start_subticks); SetDParam(1, (((DateTicksScaled) v->timetable_start) * _settings_game.economy.day_length_factor) + v->timetable_start_subticks);
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)) { } else if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) {
/* We aren't running on a timetable yet, so how can we be "on time" /* We aren't running on a timetable yet, so how can we be "on time"
* when we aren't even "on service"/"on duty"? */ * 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 / DATE_UNIT_SIZE == 0)) { } else if (v->lateness_counter == 0 || (!_settings_client.gui.timetable_in_ticks && v->lateness_counter / DATE_UNIT_SIZE == 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 { } else {
SetTimetableParams(0, abs(v->lateness_counter)); SetTimetableParams(0, 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);
} }
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
{ {
const Dimension warning_dimensions = GetSpriteSize(SPR_WARNING_SIGN); const Dimension warning_dimensions = GetSpriteSize(SPR_WARNING_SIGN);
@@ -839,18 +837,18 @@ struct TimetableWindow : GeneralVehicleWindow {
const bool rtl = _current_text_dir == TD_RTL; const bool rtl = _current_text_dir == TD_RTL;
auto draw_warning = [&](StringID text, bool warning) { auto draw_warning = [&](StringID text, bool warning) {
int left = r.left + WD_FRAMERECT_LEFT; int left = tr.left;
int right = r.right - WD_FRAMERECT_RIGHT; int right = tr.right;
if (warning) { if (warning) {
DrawSprite(SPR_WARNING_SIGN, 0, rtl ? right - warning_dimensions.width - 5 : left + 5, y + warning_offset_y); DrawSprite(SPR_WARNING_SIGN, 0, rtl ? right - warning_dimensions.width - 5 : left + 5, tr.top + warning_offset_y);
if (rtl) { if (rtl) {
right -= (warning_dimensions.width + 10); right -= (warning_dimensions.width + 10);
} else { } else {
left += (warning_dimensions.width + 10); left += (warning_dimensions.width + 10);
} }
} }
DrawString(left, right, y + text_offset_y, text); DrawString(left, right, tr.top + text_offset_y, text);
y += step_height; tr.top += step_height;
}; };
int warning_count = 0; int warning_count = 0;

View File

@@ -109,10 +109,11 @@ public:
void Draw(const Rect &r, bool sel, Colours bg_colour) const override void Draw(const Rect &r, bool sel, Colours bg_colour) const override
{ {
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
Rect tr = r.Shrink(WD_DROPDOWNTEXT_LEFT, 0, WD_DROPDOWNTEXT_RIGHT, 0);
if (this->checked) { 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);
} }
}; };
@@ -141,12 +142,12 @@ public:
CompanyID company = (CompanyID)this->result; CompanyID company = (CompanyID)this->result;
SetDParam(0, company); SetDParam(0, company);
SetDParam(1, 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 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 void Draw(const Rect &r, bool sel, Colours bg_colour) const override
@@ -157,13 +158,14 @@ public:
/* It's possible the company is deleted while the dropdown is open */ /* It's possible the company is deleted while the dropdown is open */
if (!Company::IsValidID(company)) return; 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 icon_y = CenterBounds(r.top, r.bottom, icon_size.height);
int text_y = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL); int text_y = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL);
int lock_y = CenterBounds(r.top, r.bottom, lock_size.height); 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)) { 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); SetDParam(0, company);
@@ -174,7 +176,8 @@ public:
} else { } else {
col = sel ? TC_WHITE : TC_BLACK; 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);
} }
}; };
@@ -1411,10 +1414,10 @@ public:
/* First initialise some variables... */ /* First initialise some variables... */
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
child_wid->SetupSmallestSize(w, init_array); 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)) { if (this->IsButton(child_wid->type)) {
nbuttons++; 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) { } else if (child_wid->type == NWID_SPACER) {
this->spacers++; this->spacers++;
} }
@@ -2449,10 +2452,10 @@ struct ScenarioEditorToolbarWindow : Window {
{ {
switch (widget) { switch (widget) {
case WID_TE_SPACER: { case WID_TE_SPACER: {
int height = r.bottom - r.top; int height = r.Height();
if (height > 2 * FONT_HEIGHT_NORMAL) { 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 / 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, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
} else { } else {
DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER); DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
} }

View File

@@ -147,14 +147,10 @@ public:
/** Draw the contents of the ratings panel. May request a resize of the window if the contents does not fit. */ /** Draw the contents of the ratings panel. May request a resize of the window if the contents does not fit. */
void DrawRatings() void DrawRatings()
{ {
NWidgetBase *nwid = this->GetWidget<NWidgetBase>(WID_TA_RATING_INFO); Rect r = this->GetWidget<NWidgetBase>(WID_TA_RATING_INFO)->GetCurrentRect().Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM);
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; DrawString(r, STR_LOCAL_AUTHORITY_COMPANY_RATINGS);
r.top += FONT_HEIGHT_NORMAL;
DrawString(left, right, y, STR_LOCAL_AUTHORITY_COMPANY_RATINGS);
y += FONT_HEIGHT_NORMAL;
Dimension icon_size = GetSpriteSize(SPR_COMPANY_ICON); Dimension icon_size = GetSpriteSize(SPR_COMPANY_ICON);
int icon_width = icon_size.width; int icon_width = icon_size.width;
@@ -165,43 +161,42 @@ public:
int exclusive_y_offset = (FONT_HEIGHT_NORMAL - exclusive_size.height) / 2; int exclusive_y_offset = (FONT_HEIGHT_NORMAL - exclusive_size.height) / 2;
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
uint text_left = left + (rtl ? 0 : icon_width + exclusive_width + 4); Rect text = r.Indent(icon_width + exclusive_width + 4, rtl);
uint text_right = right - (rtl ? icon_width + exclusive_width + 4 : 0); uint icon_left = r.WithWidth(icon_width, rtl).left;
uint icon_left = rtl ? right - icon_width : left; uint exclusive_left = r.Indent(icon_width + 2, rtl).WithWidth(exclusive_width, rtl).left;
uint exclusive_left = rtl ? right - icon_width - exclusive_width - 2 : left + icon_width + 2;
/* Draw list of companies */ /* Draw list of companies */
for (const Company *c : Company::Iterate()) { for (const Company *c : Company::Iterate()) {
if ((HasBit(this->town->have_ratings, c->index) || this->town->exclusivity == c->index)) { 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(0, c->index);
SetDParam(1, 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; StringID str = STR_CARGO_RATING_APPALLING;
if (r > RATING_APPALLING) str++; if (rating > RATING_APPALLING) str++;
if (r > RATING_VERYPOOR) str++; if (rating > RATING_VERYPOOR) str++;
if (r > RATING_POOR) str++; if (rating > RATING_POOR) str++;
if (r > RATING_MEDIOCRE) str++; if (rating > RATING_MEDIOCRE) str++;
if (r > RATING_GOOD) str++; if (rating > RATING_GOOD) str++;
if (r > RATING_VERYGOOD) str++; if (rating > RATING_VERYGOOD) str++;
if (r > RATING_EXCELLENT) str++; if (rating > RATING_EXCELLENT) str++;
SetDParam(2, str); SetDParam(2, str);
if (this->town->exclusivity == c->index) { 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); DrawString(text, STR_LOCAL_AUTHORITY_COMPANY_RATING);
y += FONT_HEIGHT_NORMAL; text.top += FONT_HEIGHT_NORMAL;
} }
} }
y = y + WD_FRAMERECT_BOTTOM - nwid->pos_y; // Compute needed size of the widget. text.bottom = text.top - 1;
if (y > nwid->current_y) { if (text.bottom > r.bottom) {
/* If the company list is too big to fit, mark ourself dirty and draw again. */ /* 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);
} }
} }
@@ -528,21 +523,24 @@ public:
{ {
if (widget != WID_TV_INFO) return; 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(0, this->town->cache.population);
SetDParam(1, this->town->cache.num_houses); 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(0, 1 << CT_PASSENGERS);
SetDParam(1, this->town->supplied[CT_PASSENGERS].old_act); SetDParam(1, this->town->supplied[CT_PASSENGERS].old_act);
SetDParam(2, this->town->supplied[CT_PASSENGERS].old_max); 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(0, 1 << CT_MAIL);
SetDParam(1, this->town->supplied[CT_MAIL].old_act); SetDParam(1, this->town->supplied[CT_MAIL].old_act);
SetDParam(2, this->town->supplied[CT_MAIL].old_max); 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; bool first = true;
for (int i = TE_BEGIN; i < TE_END; i++) { for (int i = TE_BEGIN; i < TE_END; i++) {
@@ -551,13 +549,12 @@ public:
if (this->town->goal[i] == TOWN_GROWTH_DESERT && (GetTropicZone(this->town->xy) != TROPICZONE_DESERT || this->town->cache.population <= 60)) continue; if (this->town->goal[i] == TOWN_GROWTH_DESERT && (GetTropicZone(this->town->xy) != TROPICZONE_DESERT || this->town->cache.population <= 60)) continue;
if (first) { 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; first = false;
} }
bool rtl = _current_text_dir == TD_RTL; 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); const CargoSpec *cargo = FindFirstCargoWithTownEffect((TownEffect)i);
assert(cargo != nullptr); assert(cargo != nullptr);
@@ -587,14 +584,17 @@ public:
SetDParam(2, cargo->Index()); SetDParam(2, cargo->Index());
SetDParam(3, this->town->goal[i]); 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)) { if (HasBit(this->town->flags, TOWN_IS_GROWING)) {
SetDParam(0, RoundDivSU(this->town->growth_rate + 1, DAY_TICKS)); 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 { } 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. */ /* only show the town noise, if the noise option is activated. */
@@ -602,12 +602,13 @@ public:
uint16 max_noise = this->town->MaxTownNoise(); uint16 max_noise = this->town->MaxTownNoise();
SetDParam(0, this->town->noise_reached); SetDParam(0, this->town->noise_reached);
SetDParam(1, max_noise); SetDParam(1, max_noise);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, max_noise == UINT16_MAX ? STR_TOWN_VIEW_NOISE_IN_TOWN_NO_LIMIT : STR_TOWN_VIEW_NOISE_IN_TOWN); DrawString(tr, max_noise == UINT16_MAX ? STR_TOWN_VIEW_NOISE_IN_TOWN_NO_LIMIT : STR_TOWN_VIEW_NOISE_IN_TOWN);
tr.top += FONT_HEIGHT_NORMAL;
} }
if (!this->town->text.empty()) { if (!this->town->text.empty()) {
SetDParamStr(0, this->town->text); 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);
} }
} }
@@ -973,18 +974,17 @@ public:
case WID_TD_LIST: { case WID_TD_LIST: {
int n = 0; 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. 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; break;
} }
/* At least one town available. */ /* At least one town available. */
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
Dimension icon_size = GetSpriteSize(SPR_TOWN_RATING_GOOD); Dimension icon_size = GetSpriteSize(SPR_TOWN_RATING_GOOD);
int text_left = r.left + WD_FRAMERECT_LEFT + (rtl ? 0 : icon_size.width + 2); int icon_x = tr.WithWidth(icon_size.width, rtl).left;
int text_right = r.right - WD_FRAMERECT_RIGHT - (rtl ? icon_size.width + 2 : 0); tr = tr.Indent(icon_size.width + 2, rtl);
int icon_x = rtl ? r.right - WD_FRAMERECT_RIGHT - icon_size.width : r.left + WD_FRAMERECT_LEFT;
for (uint i = this->vscroll->GetPosition(); i < this->towns.size(); i++) { for (uint i = this->vscroll->GetPosition(); i < this->towns.size(); i++) {
const Town *t = this->towns[i]; const Town *t = this->towns[i];
@@ -992,19 +992,19 @@ public:
/* Draw rating icon. */ /* Draw rating icon. */
if (_game_mode == GM_EDITOR || !HasBit(t->have_ratings, _local_company)) { 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 { } else {
SpriteID icon = SPR_TOWN_RATING_APALLING; SpriteID icon = SPR_TOWN_RATING_APALLING;
if (t->ratings[_local_company] > RATING_VERYPOOR) icon = SPR_TOWN_RATING_MEDIOCRE; if (t->ratings[_local_company] > RATING_VERYPOOR) icon = SPR_TOWN_RATING_MEDIOCRE;
if (t->ratings[_local_company] > RATING_GOOD) icon = SPR_TOWN_RATING_GOOD; 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(0, t->index);
SetDParam(1, t->cache.population); 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 if (++n == this->vscroll->GetCapacity()) break; // max number of towns in 1 window
} }
break; break;

View File

@@ -415,32 +415,22 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab)
* Draw the details for the given vehicle at the given position * Draw the details for the given vehicle at the given position
* *
* @param v current vehicle * @param v current vehicle
* @param left The left most coordinate to draw * @param r the Rect to draw within
* @param right The right most coordinate to draw
* @param y The y coordinate
* @param vscroll_pos Position of scrollbar * @param vscroll_pos Position of scrollbar
* @param vscroll_cap Number of lines currently displayed * @param vscroll_cap Number of lines currently displayed
* @param det_tab Selected details tab * @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 */ bool rtl = _current_text_dir == TD_RTL;
y -= WD_MATRIX_TOP; int line_height = r.Height();
/* 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);
int sprite_y_offset = line_height / 2; int sprite_y_offset = line_height / 2;
int text_y_offset = (line_height - FONT_HEIGHT_NORMAL) / 2; int text_y_offset = (line_height - FONT_HEIGHT_NORMAL) / 2;
/* draw the first 3 details tabs */ /* draw the first 3 details tabs */
if (det_tab != TDW_TAB_TOTALS) { if (det_tab != TDW_TAB_TOTALS) {
bool rtl = _current_text_dir == TD_RTL;
Direction dir = rtl ? DIR_E : DIR_W; Direction dir = rtl ? DIR_E : DIR_W;
int x = rtl ? right : left; int x = rtl ? r.right : r.left;
byte line_number = 0; byte line_number = 0;
for (; v != nullptr && vscroll_pos > -vscroll_cap; v = v->GetNextVehicle()) { for (; v != nullptr && vscroll_pos > -vscroll_cap; v = v->GetNextVehicle()) {
GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary); GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary);
@@ -461,7 +451,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); PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
u->GetImage(dir, EIT_IN_DETAILS, &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; px += rtl ? -width : width;
dx += width; dx += width;
@@ -474,35 +464,34 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
dx = 0; dx = 0;
} }
int sprite_width = std::max<int>(dx, ScaleGUITrad(TRAIN_DETAILS_MIN_INDENT)) + 3;
Rect dr = r.Indent(sprite_width, rtl);
uint num_lines = std::max(1u, (unsigned)_cargo_summary.size()); uint num_lines = std::max(1u, (unsigned)_cargo_summary.size());
for (uint i = 0; i < num_lines;) { for (uint i = 0; i < num_lines;) {
int sprite_width = std::max<int>(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) { 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 (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) { switch (det_tab) {
case TDW_TAB_CARGO: case TDW_TAB_CARGO:
if (i < _cargo_summary.size()) { if (i < _cargo_summary.size()) {
TrainDetailsCargoTab(&_cargo_summary[i], data_left, data_right, py); TrainDetailsCargoTab(&_cargo_summary[i], dr.left, dr.right, py);
} else { } 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; break;
case TDW_TAB_INFO: case TDW_TAB_INFO:
if (i == 0) TrainDetailsInfoTab(v, data_left, data_right, py, line_number); if (i == 0) TrainDetailsInfoTab(v, dr.left, dr.right, py, line_number);
break; break;
case TDW_TAB_CAPACITY: case TDW_TAB_CAPACITY:
if (i < _cargo_summary.size()) { if (i < _cargo_summary.size()) {
TrainDetailsCapacityTab(&_cargo_summary[i], data_left, data_right, py); TrainDetailsCapacityTab(&_cargo_summary[i], dr.left, dr.right, py);
} else { } else {
SetDParam(0, STR_EMPTY); 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; break;
@@ -519,6 +508,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
} }
} }
} else { } else {
int y = r.top;
CargoArray act_cargo; CargoArray act_cargo;
CargoArray max_cargo; CargoArray max_cargo;
Money feeder_share = 0; Money feeder_share = 0;
@@ -542,14 +532,14 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) { if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
SetDParam(0, empty_weight); SetDParam(0, empty_weight);
SetDParam(1, loaded_weight); SetDParam(1, loaded_weight);
DrawString(left, right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_TOTAL_WEIGHT); DrawString(r.left, r.right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_TOTAL_WEIGHT);
y += line_height; y += line_height;
} }
if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) { if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
SetDParam(0, empty_max_speed); SetDParam(0, empty_max_speed);
SetDParam(1, loaded_max_speed); SetDParam(1, loaded_max_speed);
DrawString(left, right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_MAX_SPEED); DrawString(r.left, r.right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_MAX_SPEED);
y += line_height; y += line_height;
} }
@@ -559,10 +549,12 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
} }
if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) { if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
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; 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++) { for (CargoID i = 0; i < NUM_CARGO; i++) {
if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) { if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
SetDParam(0, i); // {CARGO} #1 SetDParam(0, i); // {CARGO} #1
@@ -570,7 +562,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
SetDParam(2, i); // {SHORTCARGO} #1 SetDParam(2, i); // {SHORTCARGO} #1
SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2 SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2
SetDParam(4, _settings_game.vehicle.freight_trains); 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; y += line_height;
} }
} }
@@ -583,7 +575,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) { if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
SetDParam(0, feeder_share); 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);
} }
} }
} }

View File

@@ -77,18 +77,20 @@ public:
case WID_TT_LOADING: case WID_TT_LOADING:
case WIT_TT_TUNNELS: { case WIT_TT_TUNNELS: {
uint i = widget - WID_TT_BEGIN; 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; 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++) { for (uint i = WID_TT_BEGIN; i < WID_TT_END; i++) {
if (i == WID_TT_LOADING || i == WIT_TT_TUNNELS) continue; // Do not draw button for invisible loading indicators. if (i == WID_TT_LOADING || i == WIT_TT_TUNNELS) continue; // Do not draw button for invisible loading indicators.
const NWidgetBase *wi = this->GetWidget<NWidgetBase>(i); const Rect wr = this->GetWidget<NWidgetBase>(i)->GetCurrentRect().Shrink(WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM);
DrawFrameRect(wi->pos_x + 1, r.top + 2, wi->pos_x + wi->current_x - 2, r.bottom - 2, COLOUR_PALE_GREEN, DrawFrameRect(wr.left, fr.top, wr.right, fr.bottom, COLOUR_PALE_GREEN,
HasBit(_invisibility_opt, i - WID_TT_BEGIN) ? FR_LOWERED : FR_NONE); HasBit(_invisibility_opt, i - WID_TT_BEGIN) ? FR_LOWERED : FR_NONE);
} }
break; break;
}
} }
} }

View File

@@ -146,8 +146,8 @@ public:
if (widget >= WID_BT_TYPE_BUTTON_FIRST) { if (widget >= WID_BT_TYPE_BUTTON_FIRST) {
/* Ensure tree type buttons are sized after the largest tree type */ /* Ensure tree type buttons are sized after the largest tree type */
Dimension d = GetMaxTreeSpriteSize(); Dimension d = GetMaxTreeSpriteSize();
size->width = d.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; size->width = d.width + padding.width;
size->height = d.height + WD_FRAMERECT_RIGHT + WD_FRAMERECT_BOTTOM + ScaleGUITrad(BUTTON_BOTTOM_OFFSET); // we need some more space size->height = d.height + padding.height + ScaleGUITrad(BUTTON_BOTTOM_OFFSET); // we need some more space
} }
} }
@@ -156,7 +156,7 @@ public:
if (widget >= WID_BT_TYPE_BUTTON_FIRST) { if (widget >= WID_BT_TYPE_BUTTON_FIRST) {
const int index = 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 */ /* 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));
} }
} }

View File

@@ -622,7 +622,7 @@ typedef std::vector<RefitOption> 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) 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; uint current = 0;
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
@@ -630,12 +630,11 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int
uint iconheight = GetSpriteSize(SPR_CIRCLE_FOLDED).height; uint iconheight = GetSpriteSize(SPR_CIRCLE_FOLDED).height;
int linecolour = _colour_gradient[COLOUR_ORANGE][4]; int linecolour = _colour_gradient[COLOUR_ORANGE][4];
int iconleft = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth : r.left + WD_MATRIX_LEFT; int iconleft = rtl ? ir.right - iconwidth : ir.left;
int iconcenter = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth / 2 : r.left + WD_MATRIX_LEFT + iconwidth / 2; int iconcenter = rtl ? ir.right - iconwidth / 2 : ir.left + iconwidth / 2;
int iconinner = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth : r.left + WD_MATRIX_LEFT + iconwidth; int iconinner = rtl ? ir.right - iconwidth : ir.left + iconwidth;
int textleft = r.left + WD_MATRIX_LEFT + (rtl ? 0 : iconwidth + 4); Rect tr = ir.Indent(iconwidth + 4, rtl);
int textright = r.right - WD_MATRIX_RIGHT - (rtl ? iconwidth + 4 : 0);
/* Draw the list of subtypes for each cargo, and find the selected refit option (by its position). */ /* 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++) { for (uint i = 0; current < pos + rows && i < NUM_CARGO; i++) {
@@ -654,12 +653,12 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int
if (list[i].size() > 1) { if (list[i].size() > 1) {
if (refit.subtype != 0xFF) { if (refit.subtype != 0xFF) {
/* Draw tree lines */ /* Draw tree lines */
int ycenter = y + FONT_HEIGHT_NORMAL / 2; int ycenter = tr.top + FONT_HEIGHT_NORMAL / 2;
GfxDrawLine(iconcenter, y - WD_MATRIX_TOP, iconcenter, j == list[i].size() - 1 ? ycenter : y - WD_MATRIX_TOP + delta - 1, linecolour); 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); GfxDrawLine(iconcenter, ycenter, iconinner, ycenter, linecolour);
} else { } else {
/* Draw expand/collapse icon */ /* 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);
} }
} }
@@ -667,9 +666,9 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int
/* Get the cargo name. */ /* Get the cargo name. */
SetDParam(0, CargoSpec::Get(refit.cargo)->name); SetDParam(0, CargoSpec::Get(refit.cargo)->name);
SetDParam(1, refit.string); 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++; current++;
} }
} }
@@ -1121,8 +1120,7 @@ struct RefitWindow : public Window {
if (this->cargo != nullptr) { if (this->cargo != nullptr) {
StringID string = this->GetCapacityString(this->cargo); StringID string = this->GetCapacityString(this->cargo);
if (string != INVALID_STRING_ID) { if (string != INVALID_STRING_ID) {
DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, DrawStringMultiLine(r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM), string);
r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, string);
} }
} }
break; break;
@@ -1799,25 +1797,22 @@ uint GetVehicleListHeight(VehicleType type, uint divisor)
*/ */
void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int line_height, const Rect &r) const void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int line_height, const Rect &r) const
{ {
int left = r.left + WD_MATRIX_LEFT; Rect ir = r.WithHeight(line_height).Shrink(WD_MATRIX_LEFT, 0, WD_MATRIX_RIGHT, 0);
int right = r.right - WD_MATRIX_RIGHT;
int width = right - left;
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
int text_offset = std::max<int>(GetSpriteSize(SPR_PROFIT_LOT).width, GetDigitWidth() * this->unitnumber_digits) + WD_FRAMERECT_RIGHT; Dimension profit = GetSpriteSize(SPR_PROFIT_LOT);
int text_left = left + (rtl ? 0 : text_offset); int text_offset = std::max<int>(profit.width, GetDigitWidth() * this->unitnumber_digits) + WD_FRAMERECT_RIGHT;
int text_right = right - (rtl ? text_offset : 0); Rect tr = ir.Indent(text_offset, rtl);
bool show_orderlist = this->vli.vtype >= VEH_SHIP; bool show_orderlist = this->vli.vtype >= VEH_SHIP;
int orderlist_left = left + (rtl ? 0 : std::max(ScaleGUITrad(100) + text_offset, width / 2)); Rect olr = ir.Indent(std::max(ScaleGUITrad(100) + text_offset, ir.Width() / 2), rtl);
int orderlist_right = right - (rtl ? std::max(ScaleGUITrad(100) + text_offset, width / 2) : 0);
int image_left = (rtl && show_orderlist) ? orderlist_right : text_left; int image_left = (rtl && show_orderlist) ? olr.right : tr.left;
int image_right = (!rtl && show_orderlist) ? orderlist_left : text_right; 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<uint>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size())); uint max = static_cast<uint>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size()));
for (uint i = this->vscroll->GetPosition(); i < max; ++i) { for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
const GUIVehicleGroup &vehgroup = this->vehgroups[i]; const GUIVehicleGroup &vehgroup = this->vehgroups[i];
@@ -1925,8 +1920,8 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
} }
} }
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);
DrawString(text_left, text_right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1, str); DrawString(tr.left, tr.right, ir.top + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1, str);
/* company colour stripe along vehicle description row */ /* company colour stripe along vehicle description row */
if (_settings_client.gui.show_vehicle_list_company_colour && v->owner != this->vli.company) { if (_settings_client.gui.show_vehicle_list_company_colour && v->owner != this->vli.company) {
@@ -1935,37 +1930,37 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
if (c != nullptr) { if (c != nullptr) {
ccolour = _colour_gradient[c->colour][6]; ccolour = _colour_gradient[c->colour][6];
} }
GfxFillRect((text_right - 1) - (FONT_HEIGHT_SMALL - 2), y + 1, text_right - 1, (y + 1) + (FONT_HEIGHT_SMALL - 2), ccolour, FILLRECT_OPAQUE); GfxFillRect((tr.right - 1) - (FONT_HEIGHT_SMALL - 2), ir.top + 1, tr.right - 1, (ir.top + 1) + (FONT_HEIGHT_SMALL - 2), ccolour, FILLRECT_OPAQUE);
} }
} else { } else {
SetDParam(0, vehgroup.GetDisplayProfitThisYear()); SetDParam(0, vehgroup.GetDisplayProfitThisYear());
SetDParam(1, vehgroup.GetDisplayProfitLastYear()); 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) { switch (this->grouping) {
case GB_NONE: { case GB_NONE: {
const Vehicle *v = vehgroup.GetSingleVehicle(); const Vehicle *v = vehgroup.GetSingleVehicle();
if (HasBit(v->vehicle_flags, VF_PATHFINDER_LOST)) { 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()) { if (!v->name.empty()) {
/* The vehicle got a name so we will print it */ /* The vehicle got a name so we will print it */
SetDParam(0, v->index); 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) { } else if (v->group_id != DEFAULT_GROUP) {
/* The vehicle has no name, but is member of a group, so print group name */ /* The vehicle has no name, but is member of a group, so print group name */
SetDParam(0, v->group_id | GROUP_NAME_HIERARCHY); SetDParam(0, v->group_id | GROUP_NAME_HIERARCHY);
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; StringID str;
if (v->IsChainInDepot()) { if (v->IsChainInDepot()) {
@@ -1975,7 +1970,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
} }
SetDParam(0, v->unitnumber); SetDParam(0, v->unitnumber);
DrawString(left, right, y + 2, str); DrawString(ir.left, ir.right, ir.top + WD_FRAMERECT_TOP, str);
break; break;
} }
@@ -1984,7 +1979,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
for (int i = 0; i < static_cast<int>(vehgroup.NumVehicles()); ++i) { for (int i = 0; i < static_cast<int>(vehgroup.NumVehicles()); ++i) {
if (image_left + 8 * i >= image_right) break; // Break if there is no more space to draw any more vehicles anyway. 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 (vehgroup.vehicles_begin[0]->group_id != DEFAULT_GROUP) { if (vehgroup.vehicles_begin[0]->group_id != DEFAULT_GROUP) {
@@ -1999,21 +1994,21 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
} }
if (show_group) { if (show_group) {
SetDParam(0, gid | GROUP_NAME_HIERARCHY); SetDParam(0, gid | GROUP_NAME_HIERARCHY);
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((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()); 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; break;
default: default:
NOT_REACHED(); NOT_REACHED();
} }
y += line_height; ir = ir.Translate(0, line_height);
} }
} }
@@ -2714,10 +2709,10 @@ static const NWidgetPart _nested_train_vehicle_details_widgets[] = {
extern int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab); 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 DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab);
extern void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y); extern void DrawRoadVehDetails(const Vehicle *v, const Rect &r);
extern void DrawShipDetails(const Vehicle *v, int left, int right, int y); extern void DrawShipDetails(const Vehicle *v, const Rect &r);
extern void DrawAircraftDetails(const Aircraft *v, int left, int right, int y); extern void DrawAircraftDetails(const Aircraft *v, const Rect &r);
static StringID _service_interval_dropdown[] = { static StringID _service_interval_dropdown[] = {
STR_VEHICLE_DETAILS_DEFAULT, STR_VEHICLE_DETAILS_DEFAULT,
@@ -2802,13 +2797,13 @@ struct VehicleDetailsWindow : Window {
uint desired_height; uint desired_height;
if (v->HasArticulatedPart()) { if (v->HasArticulatedPart()) {
/* An articulated RV has its text drawn under the sprite instead of after it, hence 15 pixels extra. */ /* 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) + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM; desired_height = WD_FRAMERECT_TOP + ScaleGUITrad(15) + 4 * FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL * 2 + WD_FRAMERECT_BOTTOM;
/* Add space for the cargo amount for each part. */ /* Add space for the cargo amount for each part. */
for (const Vehicle *u = v; u != nullptr; u = u->Next()) { 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 { } else {
desired_height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + 4 + WD_FRAMERECT_BOTTOM; desired_height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL * 2 + WD_FRAMERECT_BOTTOM;
} }
return desired_height; return desired_height;
} }
@@ -2906,11 +2901,11 @@ struct VehicleDetailsWindow : Window {
break; break;
case VEH_SHIP: case VEH_SHIP:
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; break;
case VEH_AIRCRAFT: 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; break;
default: default:
@@ -2963,20 +2958,18 @@ struct VehicleDetailsWindow : Window {
* Draw the details for the given vehicle at the position of the Details windows * Draw the details for the given vehicle at the position of the Details windows
* *
* @param v current vehicle * @param v current vehicle
* @param left The left most coordinate to draw * @param r the Rect to draw within
* @param right The right most coordinate to draw
* @param y The y coordinate
* @param vscroll_pos Position of scrollbar (train only) * @param vscroll_pos Position of scrollbar (train only)
* @param vscroll_cap Number of lines currently displayed (train only) * @param vscroll_cap Number of lines currently displayed (train only)
* @param det_tab Selected details tab (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) { switch (v->type) {
case VEH_TRAIN: DrawTrainDetails(Train::From(v), left, right, y, vscroll_pos, vscroll_cap, det_tab); break; case VEH_TRAIN: DrawTrainDetails(Train::From(v), r, vscroll_pos, vscroll_cap, det_tab); break;
case VEH_ROAD: DrawRoadVehDetails(v, left, right, y); break; case VEH_ROAD: DrawRoadVehDetails(v, r); break;
case VEH_SHIP: DrawShipDetails(v, left, right, y); break; case VEH_SHIP: DrawShipDetails(v, r); break;
case VEH_AIRCRAFT: DrawAircraftDetails(Aircraft::From(v), left, right, y); break; case VEH_AIRCRAFT: DrawAircraftDetails(Aircraft::From(v), r); break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
} }
@@ -2992,15 +2985,15 @@ struct VehicleDetailsWindow : Window {
switch (widget) { switch (widget) {
case WID_VD_TOP_DETAILS: { 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 */ /* Draw running cost */
SetDParam(1, v->age / DAYS_IN_LEAP_YEAR); 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(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(2, v->max_age / DAYS_IN_LEAP_YEAR);
SetDParam(3, v->GetDisplayRunningCost()); SetDParam(3, v->GetDisplayRunningCost());
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_AGE_RUNNING_COST_YR); DrawString(tr, STR_VEHICLE_INFO_AGE_RUNNING_COST_YR);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
/* Draw max speed */ /* Draw max speed */
StringID string; StringID string;
@@ -3031,8 +3024,8 @@ struct VehicleDetailsWindow : Window {
string = STR_VEHICLE_INFO_MAX_SPEED; string = STR_VEHICLE_INFO_MAX_SPEED;
} }
} }
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, string); DrawString(tr, string);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
bool should_show_weight_ratio = this->ShouldShowWeightRatioLine(v); bool should_show_weight_ratio = this->ShouldShowWeightRatioLine(v);
if (should_show_weight_ratio) { if (should_show_weight_ratio) {
@@ -3040,8 +3033,8 @@ struct VehicleDetailsWindow : Window {
SetDParam(1, (100 * Train::From(v)->gcache.cached_power) / std::max<uint>(1, Train::From(v)->gcache.cached_weight)); SetDParam(1, (100 * Train::From(v)->gcache.cached_power) / std::max<uint>(1, Train::From(v)->gcache.cached_weight));
SetDParam(2, Train::From(v)->GetAccelerationType() == 2 ? STR_EMPTY : STR_VEHICLE_INFO_TE_WEIGHT_RATIO); SetDParam(2, Train::From(v)->GetAccelerationType() == 2 ? STR_EMPTY : STR_VEHICLE_INFO_TE_WEIGHT_RATIO);
SetDParam(3, (Train::From(v)->gcache.cached_max_te / 10) / std::max<uint>(1, Train::From(v)->gcache.cached_weight)); SetDParam(3, (Train::From(v)->gcache.cached_max_te / 10) / std::max<uint>(1, Train::From(v)->gcache.cached_weight));
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_WEIGHT_RATIOS); DrawString(tr, STR_VEHICLE_INFO_WEIGHT_RATIOS);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
} }
/* Draw profit */ /* Draw profit */
@@ -3054,15 +3047,15 @@ struct VehicleDetailsWindow : Window {
SetDParam(4, v->GetDisplayProfitThisYear()); SetDParam(4, v->GetDisplayProfitThisYear());
SetDParam(5, v->GetDisplayProfitLastYear()); SetDParam(5, v->GetDisplayProfitLastYear());
SetDParam(6, v->GetDisplayProfitLifetime()); SetDParam(6, v->GetDisplayProfitLifetime());
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_TRAIN_LENGTH); DrawString(tr, STR_VEHICLE_INFO_TRAIN_LENGTH);
} else { } else {
SetDParam(0, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); SetDParam(0, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR);
SetDParam(1, v->GetDisplayProfitThisYear()); SetDParam(1, v->GetDisplayProfitThisYear());
SetDParam(2, v->GetDisplayProfitLastYear()); SetDParam(2, v->GetDisplayProfitLastYear());
SetDParam(3, v->GetDisplayProfitLifetime()); SetDParam(3, v->GetDisplayProfitLifetime());
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_LIFETIME); DrawString(tr, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_LIFETIME);
} }
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
/* Draw breakdown & reliability */ /* Draw breakdown & reliability */
byte total_engines = 0; byte total_engines = 0;
@@ -3084,14 +3077,14 @@ struct VehicleDetailsWindow : Window {
SetDParam(0, ToPercent16(v->reliability)); SetDParam(0, ToPercent16(v->reliability));
SetDParam(1, v->breakdowns_since_last_service); 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);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
bool should_show_group = this->ShouldShowGroupLine(v); bool should_show_group = this->ShouldShowGroupLine(v);
if (should_show_group) { if (should_show_group) {
SetDParam(0, v->group_id | GROUP_NAME_HIERARCHY); SetDParam(0, v->group_id | GROUP_NAME_HIERARCHY);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_GROUP); DrawString(tr, STR_VEHICLE_INFO_GROUP);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
} }
bool should_show_slots = this->ShouldShowSlotsLine(v); bool should_show_slots = this->ShouldShowSlotsLine(v);
@@ -3110,21 +3103,21 @@ struct VehicleDetailsWindow : Window {
buffer = strecpy(buffer, TraceRestrictSlot::Get(slots[i])->name.c_str(), last); buffer = strecpy(buffer, TraceRestrictSlot::Get(slots[i])->name.c_str(), last);
} }
SetDParamStr(0, text_buffer); SetDParamStr(0, text_buffer);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_JUST_RAW_STRING); DrawString(tr, STR_JUST_RAW_STRING);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
} }
bool should_show_speed_restriction = this->ShouldShowSpeedRestrictionLine(v); bool should_show_speed_restriction = this->ShouldShowSpeedRestrictionLine(v);
if (should_show_speed_restriction) { if (should_show_speed_restriction) {
SetDParam(0, Train::From(v)->speed_restriction); SetDParam(0, Train::From(v)->speed_restriction);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_SPEED_RESTRICTION); DrawString(tr, STR_VEHICLE_INFO_SPEED_RESTRICTION);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
} }
bool should_show_speed_adaptation_exempt = this->ShouldShowSpeedAdaptationExemptLine(v); bool should_show_speed_adaptation_exempt = this->ShouldShowSpeedAdaptationExemptLine(v);
if (should_show_speed_adaptation_exempt) { if (should_show_speed_adaptation_exempt) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_SPEED_ADAPTATION_EXEMPT); DrawString(tr, STR_VEHICLE_INFO_SPEED_ADAPTATION_EXEMPT);
y += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
} }
if (this->vehicle_weight_ratio_line_shown != should_show_weight_ratio || if (this->vehicle_weight_ratio_line_shown != should_show_weight_ratio ||
@@ -3139,37 +3132,36 @@ struct VehicleDetailsWindow : Window {
case WID_VD_MATRIX: case WID_VD_MATRIX:
/* For trains only. */ /* 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; break;
case WID_VD_MIDDLE_DETAILS: { case WID_VD_MIDDLE_DETAILS: {
/* For other vehicles, at the place of the matrix. */ /* For other vehicles, at the place of the matrix. */
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
uint sprite_width = GetSingleVehicleWidth(v, EIT_IN_DETAILS) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; uint sprite_width = GetSingleVehicleWidth(v, EIT_IN_DETAILS) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM);
uint text_left = r.left + (rtl ? 0 : sprite_width);
uint text_right = r.right - (rtl ? sprite_width : 0);
/* Articulated road vehicles use a complete line. */ /* Articulated road vehicles use a complete line. */
if (v->type == VEH_ROAD && v->HasArticulatedPart()) { 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 { } else {
uint sprite_left = rtl ? text_right : r.left; Rect sr = tr.WithWidth(sprite_width, rtl);
uint sprite_right = rtl ? r.right : text_left; DrawVehicleImage(v, sr.left, sr.right, sr.top, INVALID_VEHICLE, EIT_IN_DETAILS, 0);
DrawVehicleImage(v, sprite_left + WD_FRAMERECT_LEFT, sprite_right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_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; break;
} }
case WID_VD_SERVICING_INTERVAL: case WID_VD_SERVICING_INTERVAL: {
/* Draw service interval text */ /* 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(0, v->GetServiceInterval());
SetDParam(1, v->date_of_last_service); 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); v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS);
break; break;
}
} }
} }
@@ -3792,16 +3784,13 @@ public:
/* Draw the flag plus orders. */ /* Draw the flag plus orders. */
bool rtl = (_current_text_dir == TD_RTL); 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; uint icon_width = std::max({GetSpriteSize(SPR_WARNING_SIGN).width, GetSpriteSize(SPR_FLAG_VEH_STOPPED).width, GetSpriteSize(SPR_FLAG_VEH_RUNNING).width});
int text_left = r.left + (rtl ? (uint)WD_FRAMERECT_LEFT : text_offset); int lowered = this->IsWidgetLowered(widget) ? 1 : 0;
int text_right = r.right - (rtl ? text_offset : (uint)WD_FRAMERECT_RIGHT); Rect tr = r.Shrink(WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM).Translate(lowered, lowered);
int text_top = CenterBounds(r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, FONT_HEIGHT_NORMAL); 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;
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; DrawSprite(image, PAL_NONE, tr.WithWidth(icon_width, rtl).left, CenterBounds(tr.top, tr.bottom, GetSpriteSize(image).height));
int image_left = (rtl ? text_right + 1 : r.left) + WD_IMGBTN_LEFT; tr = tr.Indent(icon_width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT, rtl);
int image_top = CenterBounds(r.top + WD_IMGBTN_TOP, r.bottom - WD_IMGBTN_BOTTOM, GetSpriteSize(image).height); DrawString(tr.left, tr.right, CenterBounds(tr.top, tr.bottom, FONT_HEIGHT_NORMAL), str, text_colour, SA_HOR_CENTER);
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);
} }
void OnClick(Point pt, int widget, int click_count) override void OnClick(Point pt, int widget, int click_count) override

View File

@@ -27,7 +27,8 @@
const WidgetDimensions WidgetDimensions::unscaled = { const WidgetDimensions WidgetDimensions::unscaled = {
{WD_IMGBTN_LEFT, WD_IMGBTN_TOP, WD_IMGBTN_RIGHT, WD_IMGBTN_BOTTOM}, ///< imgbtn {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_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}, ///< bevel
{WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM}, ///< fullbevel {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_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM}, ///< framerect
@@ -72,6 +73,19 @@ static inline Dimension ScaleGUITrad(const Dimension &dim)
return {(uint)ScaleGUITrad(dim.width), (uint)ScaleGUITrad(dim.height)}; 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. * Set up pre-scaled versions of Widget Dimensions.
*/ */
@@ -79,7 +93,8 @@ void SetupWidgetDimensions()
{ {
WidgetDimensions::scaled.imgbtn = ScaleGUITrad(WidgetDimensions::unscaled.imgbtn); WidgetDimensions::scaled.imgbtn = ScaleGUITrad(WidgetDimensions::unscaled.imgbtn);
WidgetDimensions::scaled.inset = ScaleGUITrad(WidgetDimensions::unscaled.inset); 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.bevel = WidgetDimensions::unscaled.bevel;
WidgetDimensions::scaled.fullbevel = ScaleGUITrad(WidgetDimensions::unscaled.fullbevel); WidgetDimensions::scaled.fullbevel = ScaleGUITrad(WidgetDimensions::unscaled.fullbevel);
WidgetDimensions::scaled.framerect = ScaleGUITrad(WidgetDimensions::unscaled.framerect); WidgetDimensions::scaled.framerect = ScaleGUITrad(WidgetDimensions::unscaled.framerect);
@@ -118,13 +133,13 @@ static inline Point GetAlignedPosition(const Rect &r, const Dimension &d, String
switch (align & SA_HOR_MASK) { switch (align & SA_HOR_MASK) {
case SA_LEFT: p.x = r.left; break; case SA_LEFT: p.x = r.left; break;
case SA_HOR_CENTER: p.x = CenterBounds(r.left, r.right, d.width); 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(); default: NOT_REACHED();
} }
switch (align & SA_VERT_MASK) { switch (align & SA_VERT_MASK) {
case SA_TOP: p.y = r.top; break; case SA_TOP: p.y = r.top; break;
case SA_VERT_CENTER: p.y = CenterBounds(r.top, r.bottom, d.height); 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(); default: NOT_REACHED();
} }
return p; return p;
@@ -299,25 +314,40 @@ void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, Fra
} else { } else {
uint interior; uint interior;
Rect outer = {left, top, right, bottom}; // Outside rectangle
Rect inner = outer.Shrink(WidgetDimensions::scaled.bevel); // Inside rectangle
if (flags & FR_LOWERED) { if (flags & FR_LOWERED) {
GfxFillRect(left, top, left, bottom, dark); GfxFillRect(outer.left, outer.top, inner.left - 1, outer.bottom, dark); // Left
GfxFillRect(left + WD_BEVEL_LEFT, top, right, top, dark); GfxFillRect(inner.left, outer.top, outer.right, inner.top - 1, dark); // Top
GfxFillRect(right, top + WD_BEVEL_TOP, right, bottom - WD_BEVEL_BOTTOM, light); GfxFillRect(inner.right + 1, inner.top, outer.right, inner.bottom, light); // Right
GfxFillRect(left + WD_BEVEL_LEFT, bottom, right, bottom, light); GfxFillRect(inner.left, inner.bottom + 1, outer.right, outer.bottom, light); // Bottom
interior = (flags & FR_DARKENED ? medium_dark : medium_light); interior = (flags & FR_DARKENED ? medium_dark : medium_light);
} else { } else {
GfxFillRect(left, top, left, bottom - WD_BEVEL_BOTTOM, light); GfxFillRect(outer.left, outer.top, inner.left - 1, inner.bottom, light); // Left
GfxFillRect(left + WD_BEVEL_LEFT, top, right - WD_BEVEL_RIGHT, top, light); GfxFillRect(inner.left, outer.top, inner.right, inner.top - 1, light); // Top
GfxFillRect(right, top, right, bottom - WD_BEVEL_BOTTOM, dark); GfxFillRect(inner.right + 1, outer.top, outer.right, inner.bottom, dark); // Right
GfxFillRect(left, bottom, right, bottom, dark); GfxFillRect(outer.left, inner.bottom + 1, outer.right, outer.bottom, dark); // Bottom
interior = medium_dark; interior = medium_dark;
} }
if (!(flags & FR_BORDERONLY)) { 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, bool clicked, StringAlignment align)
{
Point offset;
Dimension d = GetSpriteSize(img, &offset);
d.width -= offset.x;
d.height -= offset.y;
Point p = GetAlignedPosition(r, d, align);
int o = clicked ? WidgetDimensions::scaled.pressed : 0;
DrawSprite(img, PAL_NONE, p.x + o - offset.x, p.y + o - offset.y);
}
/** /**
* Draw an image button. * Draw an image button.
* @param r Rectangle of the button. * @param r Rectangle of the button.
@@ -333,9 +363,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); 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. if ((type & WWT_MASK) == WWT_IMGBTN_2 && clicked) img++; // Show different image when clicked for #WWT_IMGBTN_2.
Dimension d = GetSpriteSize(img); DrawSpriteIgnorePadding(r, img, clicked, align);
Point p = GetAlignedPosition(r, d, align);
DrawSprite(img, PAL_NONE, p.x + clicked, p.y + clicked);
} }
/** /**
@@ -353,7 +381,8 @@ static inline void DrawLabel(const Rect &r, WidgetType type, bool clicked, TextC
if ((type & WWT_MASK) == WWT_TEXTBTN_2 && clicked) str++; if ((type & WWT_MASK) == WWT_TEXTBTN_2 && clicked) str++;
Dimension d = GetStringBoundingBox(str); Dimension d = GetStringBoundingBox(str);
Point p = GetAlignedPosition(r, d, align); 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);
} }
/** /**
@@ -381,7 +410,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) 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); 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);
} }
/** /**
@@ -420,13 +449,13 @@ static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint1
int x = r.left; int x = r.left;
for (int ctr = num_columns; ctr > 1; ctr--) { for (int ctr = num_columns; ctr > 1; ctr--) {
x += column_width; 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; x = r.top;
for (int ctr = num_rows; ctr > 1; ctr--) { for (int ctr = num_rows; ctr > 1; ctr--) {
x += row_height; 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]; col = _colour_gradient[colour & 0xF][4];
@@ -434,13 +463,13 @@ static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint1
x = r.left - 1; x = r.left - 1;
for (int ctr = num_columns; ctr > 1; ctr--) { for (int ctr = num_columns; ctr > 1; ctr--) {
x += column_width; 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; x = r.top - 1;
for (int ctr = num_rows; ctr > 1; ctr--) { for (int ctr = num_rows; ctr > 1; ctr--) {
x += row_height; 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);
} }
} }
@@ -455,15 +484,11 @@ 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) 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; int height = NWidgetScrollbar::GetVerticalDimension().height;
/* draw up/down buttons */ /* draw up/down buttons */
DrawFrameRect(r.left, r.top, r.right, r.top + height - 1, colour, (up_clicked) ? FR_LOWERED : FR_NONE); DrawImageButtons(r.WithHeight(height, false), NWID_VSCROLLBAR, colour, up_clicked, SPR_ARROW_UP, SA_CENTER);
DrawSprite(SPR_ARROW_UP, PAL_NONE, r.left + 1 + up_clicked, r.top + 1 + up_clicked); DrawImageButtons(r.WithHeight(height, true), NWID_VSCROLLBAR, colour, down_clicked, SPR_ARROW_DOWN, SA_CENTER);
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);
int c1 = _colour_gradient[colour & 0xF][3]; int c1 = _colour_gradient[colour & 0xF][3];
int c2 = _colour_gradient[colour & 0xF][7]; int c2 = _colour_gradient[colour & 0xF][7];
@@ -472,11 +497,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, c2);
GfxFillRect(r.left, r.top + height, r.right, r.bottom - height, c1, FILLRECT_CHECKER); 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 */ /* draw shaded lines */
GfxFillRect(r.left + centre - 3, r.top + height, r.left + centre - 3, r.bottom - height, c1); GfxFillRect(left - bl, r.top + height, left - 1, r.bottom - height, c1);
GfxFillRect(r.left + centre - 2, r.top + height, r.left + centre - 2, r.bottom - height, c2); GfxFillRect(left, r.top + height, left + br - 1, r.bottom - height, c2);
GfxFillRect(r.left + centre + 2, r.top + height, r.left + centre + 2, r.bottom - height, c1); GfxFillRect(right - bl, r.top + height, right - 1, r.bottom - height, c1);
GfxFillRect(r.left + centre + 3, r.top + height, r.left + centre + 3, r.bottom - height, c2); GfxFillRect(right, r.top + height, right + br - 1, r.bottom - height, c2);
Point pt = HandleScrollbarHittest(scrollbar, r.top, r.bottom, false); 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); DrawFrameRect(r.left, pt.x, r.right, pt.y, colour, bar_dragged ? FR_LOWERED : FR_NONE);
@@ -493,14 +524,10 @@ 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) 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; int width = NWidgetScrollbar::GetHorizontalDimension().width;
DrawFrameRect(r.left, r.top, r.left + width - 1, r.bottom, colour, left_clicked ? FR_LOWERED : FR_NONE); DrawImageButtons(r.WithWidth(width, false), NWID_HSCROLLBAR, colour, left_clicked, SPR_ARROW_LEFT, SA_CENTER);
DrawSprite(SPR_ARROW_LEFT, PAL_NONE, r.left + 1 + left_clicked, r.top + 1 + left_clicked); DrawImageButtons(r.WithWidth(width, true), NWID_HSCROLLBAR, colour, right_clicked, SPR_ARROW_RIGHT, SA_CENTER);
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);
int c1 = _colour_gradient[colour & 0xF][3]; int c1 = _colour_gradient[colour & 0xF][3];
int c2 = _colour_gradient[colour & 0xF][7]; int c2 = _colour_gradient[colour & 0xF][7];
@@ -509,11 +536,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, c2);
GfxFillRect(r.left + width, r.top, r.right - width, r.bottom, c1, FILLRECT_CHECKER); 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 */ /* draw shaded lines */
GfxFillRect(r.left + width, r.top + centre - 3, r.right - width, r.top + centre - 3, c1); GfxFillRect(r.left + width, top - bt, r.right - width, top - 1, c1);
GfxFillRect(r.left + width, r.top + centre - 2, r.right - width, r.top + centre - 2, c2); GfxFillRect(r.left + width, top, r.right - width, top + bb - 1, c2);
GfxFillRect(r.left + width, r.top + centre + 2, r.right - width, r.top + centre + 2, c1); GfxFillRect(r.left + width, bottom - bt, r.right - width, bottom - 1, c1);
GfxFillRect(r.left + width, r.top + centre + 3, r.right - width, r.top + centre + 3, c2); GfxFillRect(r.left + width, bottom, r.right - width, bottom + bb - 1, c2);
/* draw actual scrollbar */ /* draw actual scrollbar */
Point pt = HandleScrollbarHittest(scrollbar, r.left, r.right, true); Point pt = HandleScrollbarHittest(scrollbar, r.left, r.right, true);
@@ -532,44 +565,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 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 c1 = _colour_gradient[colour][3];
int c2 = _colour_gradient[colour][7]; int c2 = _colour_gradient[colour][7];
/* If the frame has text, adjust the top bar to fit half-way through */ /* If the frame has text, adjust the top bar to fit half-way through */
int dy1 = 4; Rect inner = r.Shrink(ScaleGUITrad(1));
if (str != STR_NULL) dy1 = FONT_HEIGHT_NORMAL / 2 - 1; if (str != STR_NULL) inner.top = r.top + FONT_HEIGHT_NORMAL / 2;
int dy2 = dy1 + 1;
Rect outer = inner.Expand(WidgetDimensions::scaled.bevel);
Rect inside = inner.Shrink(WidgetDimensions::scaled.bevel);
if (_current_text_dir == TD_LTR) { if (_current_text_dir == TD_LTR) {
/* Line from upper left corner to start of text */ /* Line from upper left corner to start of text */
GfxFillRect(r.left, r.top + dy1, r.left + 4, r.top + dy1, c1); GfxFillRect(outer.left, outer.top, r.left + WidgetDimensions::scaled.frametext.left - WidgetDimensions::scaled.bevel.left - 1, inner.top - 1, c1);
GfxFillRect(r.left + 1, r.top + dy2, r.left + 4, r.top + dy2, c2); 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 */ /* Line from end of text to upper right corner */
GfxFillRect(x2, r.top + dy1, r.right - 1, r.top + dy1, c1); GfxFillRect(x2 + WidgetDimensions::scaled.bevel.right, outer.top, inner.right, inner.top - 1, c1);
GfxFillRect(x2, r.top + dy2, r.right - 2, r.top + dy2, c2); GfxFillRect(x2 + WidgetDimensions::scaled.bevel.right, inner.top, inside.right, inside.top - 1, c2);
} else { } else {
/* Line from upper left corner to start of text */ /* Line from upper left corner to start of text */
GfxFillRect(r.left, r.top + dy1, x2 - 2, r.top + dy1, c1); GfxFillRect(outer.left, outer.top, x2 - WidgetDimensions::scaled.bevel.left - 1, inner.top - 1, c1);
GfxFillRect(r.left + 1, r.top + dy2, x2 - 2, r.top + dy2, c2); GfxFillRect(inner.left, inner.top, x2 - WidgetDimensions::scaled.bevel.left - 1, inside.top - 1, c2);
/* Line from end of text to upper right corner */ /* 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 - WidgetDimensions::scaled.frametext.right + WidgetDimensions::scaled.bevel.right, outer.top, inner.right, inner.top - 1, 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, inner.top, inside.right, inside.top - 1, c2);
} }
/* Line from upper left corner to bottom left corner */ /* Line from upper left corner to bottom left corner */
GfxFillRect(r.left, r.top + dy2, r.left, r.bottom - 1, c1); GfxFillRect(outer.left, inner.top, inner.left - 1, inner.bottom, c1);
GfxFillRect(r.left + 1, r.top + dy2 + 1, r.left + 1, r.bottom - 2, c2); GfxFillRect(inner.left, inside.top, inside.left - 1, inside.bottom, c2);
/* Line from upper right corner to bottom right corner */ /* Line from upper right corner to bottom right corner */
GfxFillRect(r.right - 1, r.top + dy2, r.right - 1, r.bottom - 2, c1); GfxFillRect(inside.right + 1, inner.top, inner.right, inside.bottom, c1);
GfxFillRect(r.right, r.top + dy1, r.right, r.bottom - 1, c2); 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); /* Line from bottom left corner to bottom right corner */
GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2); GfxFillRect(inner.left, inside.bottom + 1, inner.right, inner.bottom, c1);
GfxFillRect(outer.left, inner.bottom + 1, outer.right, outer.bottom, c2);
} }
/** /**
@@ -626,28 +662,23 @@ 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) 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); DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE);
if (at_left) { 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));
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);
}
} }
/** /**
* Draw a close box. * Draw a close box.
* @param r Rectangle of the box. * @param r Rectangle of the box.`
* @param colour Colour of the close box. * @param colour Colour of the close box.
*/ */
static inline void DrawCloseBox(const Rect &r, Colours colour) 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); if (colour != COLOUR_WHITE) DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_NONE);
Dimension d = GetSpriteSize(SPR_CLOSEBOX); Point offset;
int s = UnScaleGUI(1); /* Offset to account for shadow of SPR_CLOSEBOX */ Dimension d = GetSpriteSize(SPR_CLOSEBOX, &offset);
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)); 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);
} }
/** /**
@@ -663,17 +694,18 @@ void DrawCaption(const Rect &r, Colours colour, Owner owner, TextColour text_col
{ {
bool company_owned = owner < MAX_COMPANIES; bool company_owned = owner < MAX_COMPANIES;
DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_BORDERONLY); DrawFrameRect(r, 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); 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) { 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) { if (str != STR_NULL) {
Dimension d = GetStringBoundingBox(str); Dimension d = GetStringBoundingBox(str);
Point p = GetAlignedPosition(r, d, align); 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);
} }
} }
@@ -690,22 +722,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) 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; 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) { 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.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); DrawImageButtons(r.WithWidth(dd_width, true), WWT_DROPDOWN, colour, clicked_dropdown, SPR_ARROW_DOWN, SA_CENTER);
DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.right - (dd_width - 2) + clicked_dropdown, r.top + image_offset + clicked_dropdown); if (str != STR_NULL) {
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); 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 { } else {
DrawFrameRect(r.left + dd_width, r.top, r.right, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE); 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); DrawImageButtons(r.WithWidth(dd_width, false), WWT_DROPDOWN, colour, clicked_dropdown, SPR_ARROW_DOWN, SA_CENTER);
DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.left + 1 + clicked_dropdown, r.top + image_offset + clicked_dropdown); if (str != STR_NULL) {
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); 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);
}
} }
} }
@@ -726,17 +758,15 @@ void Window::DrawWidgets() const
const NWidgetBase *widget = this->GetWidget<NWidgetBase>(i); const NWidgetBase *widget = this->GetWidget<NWidgetBase>(i);
if (widget == nullptr || !widget->IsHighlighted()) continue; if (widget == nullptr || !widget->IsHighlighted()) continue;
int left = widget->pos_x; Rect outer = widget->GetCurrentRect();
int top = widget->pos_y; Rect inner = outer.Shrink(WidgetDimensions::scaled.bevel).Expand(1);
int right = left + widget->current_x - 1;
int bottom = top + widget->current_y - 1;
int colour = _string_colourmap[_window_highlight_colour ? widget->GetHighlightColour() : TC_WHITE]; int colour = _string_colourmap[_window_highlight_colour ? widget->GetHighlightColour() : TC_WHITE];
GfxFillRect(left, top, left, bottom - WD_BEVEL_BOTTOM, colour); GfxFillRect(outer.left, outer.top, inner.left, inner.bottom, colour);
GfxFillRect(left + WD_BEVEL_LEFT, top, right - WD_BEVEL_RIGHT, top, colour); GfxFillRect(inner.left + 1, outer.top, inner.right - 1, inner.top, colour);
GfxFillRect(right, top, right, bottom - WD_BEVEL_BOTTOM, colour); GfxFillRect(inner.right, outer.top, outer.right, inner.bottom, colour);
GfxFillRect(left, bottom, right, bottom, colour); GfxFillRect(outer.left + 1, inner.bottom, outer.right - 1, outer.bottom, colour);
} }
} }
} }
@@ -751,15 +781,12 @@ void Window::DrawSortButtonState(int widget, SortButtonState state) const
if (state == SBS_OFF) return; if (state == SBS_OFF) return;
assert(this->nested_array != nullptr); assert(this->nested_array != nullptr);
const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget); Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect();
/* Sort button uses the same sprites as vertical scrollbar */ /* Sort button uses the same sprites as vertical scrollbar */
Dimension dim = NWidgetScrollbar::GetVerticalDimension(); 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);
} }
/** /**
@@ -909,10 +936,7 @@ NWidgetBase *NWidgetBase::GetWidgetOfType(WidgetType tp)
void NWidgetBase::AdjustPaddingForZoom() void NWidgetBase::AdjustPaddingForZoom()
{ {
this->padding_top = ScaleGUITrad(this->uz_padding_top); this->padding = ScaleGUITrad(this->uz_padding);
this->padding_right = ScaleGUITrad(this->uz_padding_right);
this->padding_bottom = ScaleGUITrad(this->uz_padding_bottom);
this->padding_left = ScaleGUITrad(this->uz_padding_left);
} }
/** /**
@@ -1207,8 +1231,8 @@ void NWidgetStacked::SetupSmallestSize(Window *w, bool init_array)
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
child_wid->SetupSmallestSize(w, init_array); 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_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_top + child_wid->padding_bottom); 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_x = LeastCommonMultiple(this->fill_x, child_wid->fill_x);
this->fill_y = LeastCommonMultiple(this->fill_y, child_wid->fill_y); this->fill_y = LeastCommonMultiple(this->fill_y, child_wid->fill_y);
this->resize_x = LeastCommonMultiple(this->resize_x, child_wid->resize_x); this->resize_x = LeastCommonMultiple(this->resize_x, child_wid->resize_x);
@@ -1225,12 +1249,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) { 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 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 child_pos_x = (rtl ? child_wid->padding.right : child_wid->padding.left);
uint vert_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetVerticalStepSize(sizing); 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; 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); child_wid->AssignSizePosition(sizing, x + child_pos_x, y + child_pos_y, child_width, child_height, rtl);
} }
@@ -1382,7 +1406,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array)
child_wid->SetupSmallestSize(w, init_array); child_wid->SetupSmallestSize(w, init_array);
longest = std::max(longest, child_wid->smallest_x); longest = std::max(longest, child_wid->smallest_x);
max_vert_fill = std::max(max_vert_fill, child_wid->GetVerticalStepSize(ST_SMALLEST)); 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. */ /* 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. [[maybe_unused]] uint max_smallest = this->smallest_y + 3 * max_vert_fill; // Upper limit to computing smallest height.
@@ -1390,7 +1414,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array)
for (;;) { for (;;) {
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
uint step_size = child_wid->GetVerticalStepSize(ST_SMALLEST); 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. 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; uint remainder = (cur_height - child_height) % step_size;
if (remainder > 0) { // Child did not fit entirely, widen the container. if (remainder > 0) { // Child did not fit entirely, widen the container.
@@ -1410,15 +1434,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. */ /* 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) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
if (child_wid->next != nullptr) { if (child_wid->next != nullptr) {
child_wid->padding_right += this->pip_inter; child_wid->padding.right += this->pip_inter;
} else { } 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.Horizontal();
if (child_wid->fill_x > 0) { 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; if (this->fill_x == 0 || this->fill_x > child_wid->fill_x) this->fill_x = child_wid->fill_x;
} }
@@ -1442,7 +1466,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui
if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) { if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) {
/* For EQUALSIZE containers this does not sum to smallest_x during initialisation */ /* 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) { 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 { } else {
additional_length -= this->smallest_x; additional_length -= this->smallest_x;
@@ -1476,7 +1500,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui
} }
uint vert_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetVerticalStepSize(sizing); 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. */ /* First.5 loop: count how many children are of the biggest step size. */
@@ -1524,11 +1548,11 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui
NWidgetBase *child_wid = this->head; NWidgetBase *child_wid = this->head;
while (child_wid != nullptr) { while (child_wid != nullptr) {
uint child_width = child_wid->current_x; 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_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_y = y + child_wid->padding.top;
child_wid->AssignSizePosition(sizing, child_x, child_y, child_width, child_wid->current_y, rtl); 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; position = rtl ? position - padded_child_width : position + padded_child_width;
child_wid = child_wid->next; child_wid = child_wid->next;
@@ -1567,7 +1591,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array)
child_wid->SetupSmallestSize(w, init_array); child_wid->SetupSmallestSize(w, init_array);
highest = std::max(highest, child_wid->smallest_y); highest = std::max(highest, child_wid->smallest_y);
max_hor_fill = std::max(max_hor_fill, child_wid->GetHorizontalStepSize(ST_SMALLEST)); 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. */ /* 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. [[maybe_unused]] uint max_smallest = this->smallest_x + 3 * max_hor_fill; // Upper limit to computing smallest height.
@@ -1575,7 +1599,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array)
for (;;) { for (;;) {
for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
uint step_size = child_wid->GetHorizontalStepSize(ST_SMALLEST); 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. 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; uint remainder = (cur_width - child_width) % step_size;
if (remainder > 0) { // Child did not fit entirely, widen the container. if (remainder > 0) { // Child did not fit entirely, widen the container.
@@ -1595,15 +1619,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. */ /* 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) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) {
if (child_wid->next != nullptr) { if (child_wid->next != nullptr) {
child_wid->padding_bottom += this->pip_inter; child_wid->padding.bottom += this->pip_inter;
} else { } 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.Vertical();
if (child_wid->fill_y > 0) { 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; if (this->fill_y == 0 || this->fill_y > child_wid->fill_y) this->fill_y = child_wid->fill_y;
} }
@@ -1627,7 +1651,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint
if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) { if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) {
/* For EQUALSIZE containers this does not sum to smallest_y during initialisation */ /* 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) { 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 { } else {
additional_length -= this->smallest_y; additional_length -= this->smallest_y;
@@ -1652,7 +1676,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint
} }
uint hor_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetHorizontalStepSize(sizing); 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. */ /* First.5 loop: count how many children are of the biggest step size. */
@@ -1698,11 +1722,11 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint
/* Third loop: Compute position and call the child. */ /* Third loop: Compute position and call the child. */
uint position = 0; // Place to put next child relative to origin of the container. 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) { 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; 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); 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();
} }
} }
@@ -2073,25 +2097,20 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array)
if (this->type == WWT_FRAME) { if (this->type == WWT_FRAME) {
/* Account for the size of the frame's text if that exists */ /* Account for the size of the frame's text if that exists */
this->child->padding_left = WD_FRAMETEXT_LEFT; this->child->padding = WidgetDimensions::scaled.frametext;
this->child->padding_right = WD_FRAMETEXT_RIGHT; this->child->padding.top = std::max<uint8>(WidgetDimensions::scaled.frametext.top, this->widget_data != STR_NULL ? FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.frametext.top / 2 : 0);
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_x += this->child->padding.Horizontal();
this->smallest_y += this->child->padding_top + this->child->padding_bottom; this->smallest_y += this->child->padding.Vertical();
if (this->index >= 0) w->SetStringParameters(this->index); 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) { } else if (this->type == WWT_INSET) {
/* Apply automatic padding for bevel thickness. */ /* Apply automatic padding for bevel thickness. */
this->child->padding_left = WD_BEVEL_LEFT; this->child->padding = WidgetDimensions::scaled.bevel;
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_x += this->child->padding.Horizontal();
this->smallest_y += this->child->padding_top + this->child->padding_bottom; this->smallest_y += this->child->padding.Vertical();
} }
} else { } else {
Dimension d = {this->min_x, this->min_y}; Dimension d = {this->min_x, this->min_y};
@@ -2101,11 +2120,17 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array)
if (this->type == WWT_FRAME || this->type == WWT_INSET) { if (this->type == WWT_FRAME || this->type == WWT_INSET) {
if (this->index >= 0) w->SetStringParameters(this->index); if (this->index >= 0) w->SetStringParameters(this->index);
Dimension background = GetStringBoundingBox(this->widget_data); 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); d = maxdim(d, background);
} }
if (this->index >= 0) { if (this->index >= 0) {
static const Dimension padding = {0, 0}; Dimension padding;
switch (this->type) {
default: NOT_REACHED();
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); w->UpdateWidgetSize(this->index, &d, padding, &fill, &resize);
} }
} }
@@ -2123,10 +2148,10 @@ void NWidgetBackground::AssignSizePosition(SizingType sizing, uint x, uint y, ui
this->StoreSizePosition(sizing, x, y, given_width, given_height); this->StoreSizePosition(sizing, x, y, given_width, given_height);
if (this->child != nullptr) { if (this->child != nullptr) {
uint x_offset = (rtl ? this->child->padding_right : this->child->padding_left); 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 width = given_width - this->child->padding.Horizontal();
uint height = given_height - this->child->padding_top - this->child->padding_bottom; uint height = given_height - this->child->padding.Vertical();
this->child->AssignSizePosition(sizing, x + x_offset, y + this->child->padding_top, width, height, rtl); this->child->AssignSizePosition(sizing, x + x_offset, y + this->child->padding.top, width, height, rtl);
} }
} }
@@ -2172,7 +2197,7 @@ void NWidgetBackground::Draw(const Window *w)
if (this->child != nullptr) this->child->Draw(w); if (this->child != nullptr) this->child->Draw(w);
if (this->IsDisabled()) { 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);
} }
} }
@@ -2432,7 +2457,7 @@ void NWidgetScrollbar::Draw(const Window *w)
} }
if (this->IsDisabled()) { 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);
} }
} }
@@ -2444,22 +2469,20 @@ void NWidgetScrollbar::Draw(const Window *w)
/* static */ Dimension NWidgetScrollbar::GetVerticalDimension() /* 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) { if (vertical_dimension.width == 0) {
vertical_dimension = maxdim(GetSpriteSize(SPR_ARROW_UP), GetSpriteSize(SPR_ARROW_DOWN)); vertical_dimension = maxdim(GetScaledSpriteSize(SPR_ARROW_UP), GetScaledSpriteSize(SPR_ARROW_DOWN));
vertical_dimension.width += extra.width; vertical_dimension.width += WidgetDimensions::scaled.vscrollbar.Horizontal();
vertical_dimension.height += extra.height; vertical_dimension.height += WidgetDimensions::scaled.vscrollbar.Vertical();
} }
return vertical_dimension; return vertical_dimension;
} }
/* static */ Dimension NWidgetScrollbar::GetHorizontalDimension() /* 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) { if (horizontal_dimension.width == 0) {
horizontal_dimension = maxdim(GetSpriteSize(SPR_ARROW_LEFT), GetSpriteSize(SPR_ARROW_RIGHT)); horizontal_dimension = maxdim(GetScaledSpriteSize(SPR_ARROW_LEFT), GetScaledSpriteSize(SPR_ARROW_RIGHT));
horizontal_dimension.width += extra.width; horizontal_dimension.width += WidgetDimensions::scaled.hscrollbar.Horizontal();
horizontal_dimension.height += extra.height; horizontal_dimension.height += WidgetDimensions::scaled.hscrollbar.Vertical();
} }
return horizontal_dimension; return horizontal_dimension;
} }
@@ -2536,7 +2559,7 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint32 data,
this->SetFill(1, 0); this->SetFill(1, 0);
this->SetResize(1, 0); this->SetResize(1, 0);
this->SetMinimalSize(0, WD_CAPTION_HEIGHT); 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); this->SetDataTip(data, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
break; break;
@@ -2594,41 +2617,35 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array)
w->nested_array[this->index] = this; w->nested_array[this->index] = this;
} }
Dimension padding = {0, 0};
Dimension size = {this->min_x, this->min_y}; Dimension size = {this->min_x, this->min_y};
Dimension fill = {this->fill_x, this->fill_y}; Dimension fill = {this->fill_x, this->fill_y};
Dimension resize = {this->resize_x, this->resize_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) { switch (this->type) {
case WWT_EMPTY: { case WWT_EMPTY: {
static const Dimension extra = {0, 0};
padding = &extra;
break; break;
} }
case WWT_MATRIX: { case WWT_MATRIX: {
static const Dimension extra = {WD_MATRIX_LEFT + WD_MATRIX_RIGHT, WD_MATRIX_TOP + WD_MATRIX_BOTTOM}; padding = {WidgetDimensions::scaled.matrix.Horizontal(), WidgetDimensions::scaled.matrix.Vertical()};
padding = &extra;
break; break;
} }
case WWT_SHADEBOX: { case WWT_SHADEBOX: {
static const Dimension extra = {WD_SHADEBOX_LEFT + WD_SHADEBOX_RIGHT, WD_SHADEBOX_TOP + WD_SHADEBOX_BOTTOM}; padding = {WidgetDimensions::scaled.shadebox.Horizontal(), WidgetDimensions::scaled.shadebox.Vertical()};
padding = &extra;
if (NWidgetLeaf::shadebox_dimension.width == 0) { if (NWidgetLeaf::shadebox_dimension.width == 0) {
NWidgetLeaf::shadebox_dimension = maxdim(GetSpriteSize(SPR_WINDOW_SHADE), GetSpriteSize(SPR_WINDOW_UNSHADE)); NWidgetLeaf::shadebox_dimension = maxdim(GetScaledSpriteSize(SPR_WINDOW_SHADE), GetScaledSpriteSize(SPR_WINDOW_UNSHADE));
NWidgetLeaf::shadebox_dimension.width += extra.width; NWidgetLeaf::shadebox_dimension.width += padding.width;
NWidgetLeaf::shadebox_dimension.height += extra.height; NWidgetLeaf::shadebox_dimension.height += padding.height;
} }
size = maxdim(size, NWidgetLeaf::shadebox_dimension); size = maxdim(size, NWidgetLeaf::shadebox_dimension);
break; break;
} }
case WWT_DEBUGBOX: case WWT_DEBUGBOX:
if (_settings_client.gui.newgrf_developer_tools && w->IsNewGRFInspectable()) { 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 = {WidgetDimensions::scaled.debugbox.Horizontal(), WidgetDimensions::scaled.debugbox.Vertical()};
padding = &extra;
if (NWidgetLeaf::debugbox_dimension.width == 0) { if (NWidgetLeaf::debugbox_dimension.width == 0) {
NWidgetLeaf::debugbox_dimension = GetSpriteSize(SPR_WINDOW_DEBUG); NWidgetLeaf::debugbox_dimension = GetScaledSpriteSize(SPR_WINDOW_DEBUG);
NWidgetLeaf::debugbox_dimension.width += extra.width; NWidgetLeaf::debugbox_dimension.width += padding.width;
NWidgetLeaf::debugbox_dimension.height += extra.height; NWidgetLeaf::debugbox_dimension.height += padding.height;
} }
size = maxdim(size, NWidgetLeaf::debugbox_dimension); size = maxdim(size, NWidgetLeaf::debugbox_dimension);
} else { } else {
@@ -2640,81 +2657,74 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array)
break; break;
case WWT_STICKYBOX: { case WWT_STICKYBOX: {
static const Dimension extra = {WD_STICKYBOX_LEFT + WD_STICKYBOX_RIGHT, WD_STICKYBOX_TOP + WD_STICKYBOX_BOTTOM}; padding = {WidgetDimensions::scaled.stickybox.Horizontal(), WidgetDimensions::scaled.stickybox.Vertical()};
padding = &extra;
if (NWidgetLeaf::stickybox_dimension.width == 0) { if (NWidgetLeaf::stickybox_dimension.width == 0) {
NWidgetLeaf::stickybox_dimension = maxdim(GetSpriteSize(SPR_PIN_UP), GetSpriteSize(SPR_PIN_DOWN)); NWidgetLeaf::stickybox_dimension = maxdim(GetScaledSpriteSize(SPR_PIN_UP), GetScaledSpriteSize(SPR_PIN_DOWN));
NWidgetLeaf::stickybox_dimension.width += extra.width; NWidgetLeaf::stickybox_dimension.width += padding.width;
NWidgetLeaf::stickybox_dimension.height += extra.height; NWidgetLeaf::stickybox_dimension.height += padding.height;
} }
size = maxdim(size, NWidgetLeaf::stickybox_dimension); size = maxdim(size, NWidgetLeaf::stickybox_dimension);
break; break;
} }
case WWT_DEFSIZEBOX: { case WWT_DEFSIZEBOX: {
static const Dimension extra = {WD_DEFSIZEBOX_LEFT + WD_DEFSIZEBOX_RIGHT, WD_DEFSIZEBOX_TOP + WD_DEFSIZEBOX_BOTTOM}; padding = {WidgetDimensions::scaled.defsizebox.Horizontal(), WidgetDimensions::scaled.defsizebox.Vertical()};
padding = &extra;
if (NWidgetLeaf::defsizebox_dimension.width == 0) { if (NWidgetLeaf::defsizebox_dimension.width == 0) {
NWidgetLeaf::defsizebox_dimension = GetSpriteSize(SPR_WINDOW_DEFSIZE); NWidgetLeaf::defsizebox_dimension = GetScaledSpriteSize(SPR_WINDOW_DEFSIZE);
NWidgetLeaf::defsizebox_dimension.width += extra.width; NWidgetLeaf::defsizebox_dimension.width += padding.width;
NWidgetLeaf::defsizebox_dimension.height += extra.height; NWidgetLeaf::defsizebox_dimension.height += padding.height;
} }
size = maxdim(size, NWidgetLeaf::defsizebox_dimension); size = maxdim(size, NWidgetLeaf::defsizebox_dimension);
break; break;
} }
case WWT_RESIZEBOX: { case WWT_RESIZEBOX: {
static const Dimension extra = {WD_RESIZEBOX_LEFT + WD_RESIZEBOX_RIGHT, WD_RESIZEBOX_TOP + WD_RESIZEBOX_BOTTOM}; padding = {WidgetDimensions::scaled.resizebox.Horizontal(), WidgetDimensions::scaled.resizebox.Vertical()};
padding = &extra;
if (NWidgetLeaf::resizebox_dimension.width == 0) { if (NWidgetLeaf::resizebox_dimension.width == 0) {
NWidgetLeaf::resizebox_dimension = maxdim(GetSpriteSize(SPR_WINDOW_RESIZE_LEFT), GetSpriteSize(SPR_WINDOW_RESIZE_RIGHT)); NWidgetLeaf::resizebox_dimension = maxdim(GetScaledSpriteSize(SPR_WINDOW_RESIZE_LEFT), GetScaledSpriteSize(SPR_WINDOW_RESIZE_RIGHT));
NWidgetLeaf::resizebox_dimension.width += extra.width; NWidgetLeaf::resizebox_dimension.width += padding.width;
NWidgetLeaf::resizebox_dimension.height += extra.height; NWidgetLeaf::resizebox_dimension.height += padding.height;
} }
size = maxdim(size, NWidgetLeaf::resizebox_dimension); size = maxdim(size, NWidgetLeaf::resizebox_dimension);
break; break;
} }
case WWT_EDITBOX: { case WWT_EDITBOX: {
Dimension sprite_size = GetSpriteSize(_current_text_dir == TD_RTL ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); Dimension sprite_size = GetScaledSpriteSize(_current_text_dir == TD_RTL ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT);
size.width = std::max(size.width, 30 + sprite_size.width); size.width = std::max(size.width, ScaleGUITrad(30) + sprite_size.width);
size.height = std::max(sprite_size.height, GetStringBoundingBox("_").height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); size.height = std::max(sprite_size.height, GetStringBoundingBox("_").height + WidgetDimensions::scaled.framerect.Vertical());
} }
FALLTHROUGH; FALLTHROUGH;
case WWT_PUSHBTN: { case WWT_PUSHBTN: {
static const Dimension extra = {WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM}; padding = {WidgetDimensions::scaled.frametext.Horizontal(), WidgetDimensions::scaled.framerect.Vertical()};
padding = &extra;
break; break;
} }
case WWT_IMGBTN: case WWT_IMGBTN:
case WWT_IMGBTN_2: case WWT_IMGBTN_2:
case WWT_PUSHIMGBTN: { case WWT_PUSHIMGBTN: {
static const Dimension extra = {WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT, WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM}; padding = {WidgetDimensions::scaled.imgbtn.Horizontal(), WidgetDimensions::scaled.imgbtn.Vertical()};
padding = &extra; Dimension d2 = GetScaledSpriteSize(this->widget_data);
Dimension d2 = GetSpriteSize(this->widget_data); if (this->type == WWT_IMGBTN_2) d2 = maxdim(d2, GetScaledSpriteSize(this->widget_data + 1));
if (this->type == WWT_IMGBTN_2) d2 = maxdim(d2, GetSpriteSize(this->widget_data + 1)); d2.width += padding.width;
d2.width += extra.width; d2.height += padding.height;
d2.height += extra.height;
size = maxdim(size, d2); size = maxdim(size, d2);
break; break;
} }
case WWT_ARROWBTN: case WWT_ARROWBTN:
case WWT_PUSHARROWBTN: { case WWT_PUSHARROWBTN: {
static const Dimension extra = {WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT, WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM}; padding = {WidgetDimensions::scaled.imgbtn.Horizontal(), WidgetDimensions::scaled.imgbtn.Vertical()};
padding = &extra; Dimension d2 = maxdim(GetScaledSpriteSize(SPR_ARROW_LEFT), GetScaledSpriteSize(SPR_ARROW_RIGHT));
Dimension d2 = maxdim(GetSpriteSize(SPR_ARROW_LEFT), GetSpriteSize(SPR_ARROW_RIGHT)); d2.width += padding.width;
d2.width += extra.width; d2.height += padding.height;
d2.height += extra.height;
size = maxdim(size, d2); size = maxdim(size, d2);
break; break;
} }
case WWT_CLOSEBOX: { case WWT_CLOSEBOX: {
static const Dimension extra = {WD_CLOSEBOX_LEFT + WD_CLOSEBOX_RIGHT, WD_CLOSEBOX_TOP + WD_CLOSEBOX_BOTTOM}; padding = {WidgetDimensions::scaled.closebox.Horizontal(), WidgetDimensions::scaled.closebox.Vertical()};
padding = &extra;
if (NWidgetLeaf::closebox_dimension.width == 0) { if (NWidgetLeaf::closebox_dimension.width == 0) {
NWidgetLeaf::closebox_dimension = GetSpriteSize(SPR_CLOSEBOX); NWidgetLeaf::closebox_dimension = GetScaledSpriteSize(SPR_CLOSEBOX);
NWidgetLeaf::closebox_dimension.width += extra.width; NWidgetLeaf::closebox_dimension.width += padding.width;
NWidgetLeaf::closebox_dimension.height += extra.height; NWidgetLeaf::closebox_dimension.height += padding.height;
} }
size = maxdim(size, NWidgetLeaf::closebox_dimension); size = maxdim(size, NWidgetLeaf::closebox_dimension);
break; break;
@@ -2722,48 +2732,42 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array)
case WWT_TEXTBTN: case WWT_TEXTBTN:
case WWT_PUSHTXTBTN: case WWT_PUSHTXTBTN:
case WWT_TEXTBTN_2: { case WWT_TEXTBTN_2: {
static const Dimension extra = {WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM}; padding = {WidgetDimensions::scaled.framerect.Horizontal(), WidgetDimensions::scaled.framerect.Vertical()};
padding = &extra;
if (this->index >= 0) w->SetStringParameters(this->index); if (this->index >= 0) w->SetStringParameters(this->index);
Dimension d2 = GetStringBoundingBox(this->widget_data); Dimension d2 = GetStringBoundingBox(this->widget_data);
d2.width += extra.width; d2.width += padding.width;
d2.height += extra.height; d2.height += padding.height;
size = maxdim(size, d2); size = maxdim(size, d2);
break; break;
} }
case WWT_LABEL: case WWT_LABEL:
case WWT_TEXT: { case WWT_TEXT: {
static const Dimension extra = {0, 0};
padding = &extra;
if (this->index >= 0) w->SetStringParameters(this->index); if (this->index >= 0) w->SetStringParameters(this->index);
size = maxdim(size, GetStringBoundingBox(this->widget_data)); size = maxdim(size, GetStringBoundingBox(this->widget_data));
break; break;
} }
case WWT_CAPTION: { case WWT_CAPTION: {
static const Dimension extra = {WD_CAPTIONTEXT_LEFT + WD_CAPTIONTEXT_RIGHT, WD_CAPTIONTEXT_TOP + WD_CAPTIONTEXT_BOTTOM}; padding = {WidgetDimensions::scaled.captiontext.Horizontal(), WidgetDimensions::scaled.captiontext.Vertical()};
padding = &extra;
if (this->index >= 0) w->SetStringParameters(this->index); if (this->index >= 0) w->SetStringParameters(this->index);
Dimension d2 = GetStringBoundingBox(this->widget_data); Dimension d2 = GetStringBoundingBox(this->widget_data);
d2.width += extra.width; d2.width += padding.width;
d2.height += extra.height; d2.height += padding.height;
size = maxdim(size, d2); size = maxdim(size, d2);
break; break;
} }
case WWT_DROPDOWN: case WWT_DROPDOWN:
case NWID_BUTTON_DROPDOWN: case NWID_BUTTON_DROPDOWN:
case NWID_PUSHBUTTON_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) { if (NWidgetLeaf::dropdown_dimension.width == 0) {
NWidgetLeaf::dropdown_dimension = GetSpriteSize(SPR_ARROW_DOWN); NWidgetLeaf::dropdown_dimension = GetScaledSpriteSize(SPR_ARROW_DOWN);
NWidgetLeaf::dropdown_dimension.width += WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT; NWidgetLeaf::dropdown_dimension.width += WidgetDimensions::scaled.vscrollbar.Horizontal();
NWidgetLeaf::dropdown_dimension.height += WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM; NWidgetLeaf::dropdown_dimension.height += WidgetDimensions::scaled.vscrollbar.Vertical();
extra.width = WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT + NWidgetLeaf::dropdown_dimension.width;
} }
padding = {WidgetDimensions::scaled.dropdowntext.Horizontal() + NWidgetLeaf::dropdown_dimension.width, WidgetDimensions::scaled.dropdowntext.Vertical()};
if (this->index >= 0) w->SetStringParameters(this->index); if (this->index >= 0) w->SetStringParameters(this->index);
Dimension d2 = GetStringBoundingBox(this->widget_data); Dimension d2 = GetStringBoundingBox(this->widget_data);
d2.width += extra.width; d2.width += padding.width;
d2.height = std::max(d2.height, NWidgetLeaf::dropdown_dimension.height) + extra.height; d2.height = std::max(d2.height + padding.height, NWidgetLeaf::dropdown_dimension.height);
size = maxdim(size, d2); size = maxdim(size, d2);
break; break;
} }
@@ -2771,7 +2775,7 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array)
NOT_REACHED(); 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_x = size.width;
this->smallest_y = size.height; this->smallest_y = size.height;
@@ -2908,7 +2912,7 @@ void NWidgetLeaf::Draw(const Window *w)
if (this->index >= 0) w->DrawWidget(r, this->index); if (this->index >= 0) w->DrawWidget(r, this->index);
if (this->IsDisabled()) { 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; _cur_dpi = old_dpi;
@@ -3070,7 +3074,7 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest,
} }
case WPT_PADDING: 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; break;
case WPT_PIPSPACE: { case WPT_PIPSPACE: {
@@ -3276,8 +3280,8 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid
int hor_length = 0; int hor_length = 0;
Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_OUT_4X); Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_OUT_4X);
sprite_size.width += WD_MATRIX_LEFT + WD_MATRIX_RIGHT; sprite_size.width += WidgetDimensions::unscaled.matrix.Horizontal();
sprite_size.height += WD_MATRIX_TOP + WD_MATRIX_BOTTOM + 1; // 1 for the 'offset' of being pressed sprite_size.height += WidgetDimensions::unscaled.matrix.Vertical() + 1; // 1 for the 'offset' of being pressed
for (int widnum = widget_first; widnum <= widget_last; widnum++) { for (int widnum = widget_first; widnum <= widget_last; widnum++) {
/* Ensure there is room in 'hor' for another button. */ /* Ensure there is room in 'hor' for another button. */

View File

@@ -160,10 +160,20 @@ public:
*/ */
inline void SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left) inline void SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
{ {
this->uz_padding_top = top; this->uz_padding.top = top;
this->uz_padding_right = right; this->uz_padding.right = right;
this->uz_padding_bottom = bottom; this->uz_padding.bottom = bottom;
this->uz_padding_left = left; this->uz_padding.left = left;
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(); this->AdjustPaddingForZoom();
} }
@@ -205,15 +215,8 @@ public:
NWidgetBase *next; ///< Pointer to next widget in container. Managed by parent container widget. 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. 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. RectPadding padding; ///< Padding added to the widget. Managed by parent container widget. (parent container may swap left and right for RTL)
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) RectPadding uz_padding; ///< Unscaled padding, for resize calculation.
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.
inline bool IsOutsideDrawArea() const inline bool IsOutsideDrawArea() const
{ {
@@ -946,8 +949,7 @@ struct NWidgetPartWidget {
* Widget part for storing padding. * Widget part for storing padding.
* @ingroup NestedWidgetParts * @ingroup NestedWidgetParts
*/ */
struct NWidgetPartPaddings { struct NWidgetPartPaddings : RectPadding {
uint8 top, right, bottom, left; ///< Paddings for all directions.
}; };
/** /**
@@ -1177,6 +1179,24 @@ static inline NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8
return part; 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. * Widget part function for setting a padding.
* @param padding The padding to use for all directions. * @param padding The padding to use for all directions.

View File

@@ -88,8 +88,10 @@ uint DropDownListIconItem::Width() const
void DropDownListIconItem::Draw(const Rect &r, bool sel, Colours bg_colour) const void DropDownListIconItem::Draw(const Rect &r, bool sel, Colours bg_colour) const
{ {
bool rtl = _current_text_dir == TD_RTL; 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)); Rect ir = r.Shrink(WD_DROPDOWNTEXT_LEFT, WD_DROPDOWNTEXT_TOP, WD_DROPDOWNTEXT_RIGHT, WD_DROPDOWNTEXT_LEFT);
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) | this->colour_flags); 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) | this->colour_flags);
} }
void DropDownListIconItem::SetDimension(Dimension d) void DropDownListIconItem::SetDimension(Dimension d)

View File

@@ -19,47 +19,73 @@
static const int SLIDER_WIDTH = 3; 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 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 * @param value Value to put the slider at
* @param labels List of positions and labels to draw along the slider.
*/ */
void DrawVolumeSliderWidget(Rect r, byte value) void DrawSliderWidget(Rect r, int min_value, int max_value, int value, const std::map<int, StringID> &labels)
{ {
/* Draw a wedge indicating low to high volume level. */ /* 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 ha = (r.bottom - r.top) / 5;
int wx1 = r.left, wx2 = r.right; 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;
if (_current_text_dir == TD_RTL) std::swap(wx1, wx2); if (_current_text_dir == TD_RTL) std::swap(wx1, wx2);
const uint shadow = _colour_gradient[COLOUR_GREY][3]; const uint shadow = _colour_gradient[COLOUR_GREY][3];
const uint fill = _colour_gradient[COLOUR_GREY][6]; const uint fill = _colour_gradient[COLOUR_GREY][6];
const uint light = _colour_gradient[COLOUR_GREY][7]; const uint light = _colour_gradient[COLOUR_GREY][7];
const std::vector<Point> wedge{ Point{wx1, r.bottom - ha}, Point{wx2, r.top + ha}, Point{wx2, r.bottom - ha} }; const std::vector<Point> wedge{ Point{wx1, r.bottom - ha}, Point{wx2, r.top + ha}, Point{wx2, r.bottom - ha} };
GfxFillPolygon(wedge, fill); GfxFillPolygon(wedge, fill);
GfxDrawLine(wedge[0].x, wedge[0].y, wedge[2].x, wedge[2].y, light); 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); 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); GfxDrawLine(wedge[0].x, wedge[0].y, wedge[1].x, wedge[1].y, shadow, t);
/* Draw a slider handle indicating current volume level. */ int x;
const int sw = ScaleGUITrad(SLIDER_WIDTH); for (auto label : labels) {
if (_current_text_dir == TD_RTL) value = 127 - value; x = label.first - min_value;
const int x = r.left + (value * (r.right - r.left - sw) / 127); 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. */
if (_current_text_dir == TD_RTL) value = max_value - 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); DrawFrameRect(x, r.top, x + sw, r.bottom, COLOUR_GREY, FR_NONE);
} }
/** /**
* 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 r Rectangle of the widget
* @param pt Clicked point * @param pt Clicked point
* @param value[in,out] Volume value to modify * @param value[in,out] Value to modify
* @return True if the volume setting was modified * @return True if the value setting was modified
*/ */
bool ClickVolumeSliderWidget(Rect r, Point pt, byte &value) bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, int &value)
{ {
const int sw = ScaleGUITrad(SLIDER_WIDTH); max_value -= min_value;
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;
if (new_vol != value) { const int sw = ScaleGUITrad(SLIDER_WIDTH);
value = new_vol; 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;
return true; return true;
} }

View File

@@ -13,9 +13,17 @@
#include "../window_type.h" #include "../window_type.h"
#include "../gfx_func.h" #include "../gfx_func.h"
#include <map>
void DrawVolumeSliderWidget(Rect r, byte value); void DrawSliderWidget(Rect r, int min_value, int max_value, int value, const std::map<int, StringID> &labels);
bool ClickVolumeSliderWidget(Rect r, Point pt, byte &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 */ #endif /* WIDGETS_SLIDER_TYPE_H */

View File

@@ -35,7 +35,8 @@ DECLARE_ENUM_AS_BIT_SET(FrameFlags)
struct WidgetDimensions { struct WidgetDimensions {
RectPadding imgbtn; RectPadding imgbtn;
RectPadding inset; RectPadding inset;
RectPadding scrollbar; RectPadding vscrollbar;
RectPadding hscrollbar;
RectPadding bevel; ///< Widths of bevel border. RectPadding bevel; ///< Widths of bevel border.
RectPadding fullbevel; ///< Always-scaled bevel border. RectPadding fullbevel; ///< Always-scaled bevel border.
RectPadding framerect; ///< Offsets within frame area. RectPadding framerect; ///< Offsets within frame area.
@@ -75,10 +76,15 @@ enum WidgetDrawDistances {
WD_INSET_RIGHT = 2, ///< Right offset of string. WD_INSET_RIGHT = 2, ///< Right offset of string.
WD_INSET_TOP = 1, ///< Top offset of string. WD_INSET_TOP = 1, ///< Top offset of string.
WD_SCROLLBAR_LEFT = 2, ///< Left offset of scrollbar. WD_VSCROLLBAR_LEFT = 2, ///< Left offset of vertical scrollbar.
WD_SCROLLBAR_RIGHT = 2, ///< Right offset of scrollbar. WD_VSCROLLBAR_RIGHT = 2, ///< Right offset of vertical scrollbar.
WD_SCROLLBAR_TOP = 2, ///< Top offset of scrollbar. WD_VSCROLLBAR_TOP = 3, ///< Top offset of vertical scrollbar.
WD_SCROLLBAR_BOTTOM = 2, ///< Bottom offset of 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. */ /* Size of the pure frame bevel without any padding. */
WD_BEVEL_LEFT = 1, ///< Width of left bevel border. WD_BEVEL_LEFT = 1, ///< Width of left bevel border.