TBTR: Fix layout of middle panel in RTL languages
This commit is contained in:
@@ -37,6 +37,7 @@
|
|||||||
#include "game/game_text.hpp"
|
#include "game/game_text.hpp"
|
||||||
#include "network/network_content_gui.h"
|
#include "network/network_content_gui.h"
|
||||||
#include "newgrf_engine.h"
|
#include "newgrf_engine.h"
|
||||||
|
#include "tbtr_template_vehicle_func.h"
|
||||||
#include "core/backup_type.hpp"
|
#include "core/backup_type.hpp"
|
||||||
#include "core/y_combinator.hpp"
|
#include "core/y_combinator.hpp"
|
||||||
#include <stack>
|
#include <stack>
|
||||||
@@ -52,7 +53,7 @@ std::string _config_language_file; ///< The file (name) stored in
|
|||||||
LanguageList _languages; ///< The actual list of language meta data.
|
LanguageList _languages; ///< The actual list of language meta data.
|
||||||
const LanguageMetadata *_current_language = nullptr; ///< The currently loaded language.
|
const LanguageMetadata *_current_language = nullptr; ///< The currently loaded language.
|
||||||
|
|
||||||
TextDirection _current_text_dir; ///< Text direction of the currently selected language.
|
TextDirection _current_text_dir = TD_LTR; ///< Text direction of the currently selected language.
|
||||||
|
|
||||||
#ifdef WITH_ICU_I18N
|
#ifdef WITH_ICU_I18N
|
||||||
std::unique_ptr<icu::Collator> _current_collator; ///< Collator for the language currently in use.
|
std::unique_ptr<icu::Collator> _current_collator; ///< Collator for the language currently in use.
|
||||||
@@ -2307,6 +2308,7 @@ bool ReadLanguagePack(const LanguageMetadata *lang)
|
|||||||
_langpack.langtab_start = tab_start;
|
_langpack.langtab_start = tab_start;
|
||||||
|
|
||||||
_current_language = lang;
|
_current_language = lang;
|
||||||
|
const TextDirection old_text_dir = _current_text_dir;
|
||||||
_current_text_dir = (TextDirection)_current_language->text_dir;
|
_current_text_dir = (TextDirection)_current_language->text_dir;
|
||||||
const char *c_file = strrchr(_current_language->file, PATHSEPCHAR) + 1;
|
const char *c_file = strrchr(_current_language->file, PATHSEPCHAR) + 1;
|
||||||
_config_language_file = c_file;
|
_config_language_file = c_file;
|
||||||
@@ -2350,6 +2352,10 @@ bool ReadLanguagePack(const LanguageMetadata *lang)
|
|||||||
InvalidateWindowClassesData(WC_INDUSTRY_DIRECTORY); // Industry directory window.
|
InvalidateWindowClassesData(WC_INDUSTRY_DIRECTORY); // Industry directory window.
|
||||||
InvalidateWindowClassesData(WC_STATION_LIST); // Station list window.
|
InvalidateWindowClassesData(WC_STATION_LIST); // Station list window.
|
||||||
|
|
||||||
|
if (old_text_dir != _current_text_dir) {
|
||||||
|
InvalidateTemplateReplacementImages();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -187,6 +187,12 @@ static WindowDesc _replace_rail_vehicle_desc(
|
|||||||
_widgets, lengthof(_widgets)
|
_widgets, lengthof(_widgets)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TRW_LEFT_OFFSET = 36,
|
||||||
|
TRW_RIGHT_OFFSET = 30,
|
||||||
|
TRW_GAP = 10,
|
||||||
|
};
|
||||||
|
|
||||||
class TemplateReplaceWindow : public Window {
|
class TemplateReplaceWindow : public Window {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -208,6 +214,13 @@ private:
|
|||||||
|
|
||||||
bool editInProgress;
|
bool editInProgress;
|
||||||
|
|
||||||
|
uint buy_cost_width = 0;
|
||||||
|
uint refit_text_width = 0;
|
||||||
|
uint depot_text_width = 0;
|
||||||
|
uint remainder_text_width = 0;
|
||||||
|
uint old_text_width = 0;
|
||||||
|
uint toggle_text_width = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TemplateReplaceWindow(WindowDesc *wdesc) : Window(wdesc)
|
TemplateReplaceWindow(WindowDesc *wdesc) : Window(wdesc)
|
||||||
{
|
{
|
||||||
@@ -259,6 +272,21 @@ public:
|
|||||||
int target_resize = WidgetDimensions::scaled.matrix.top + FONT_HEIGHT_NORMAL + ScaleGUITrad(GetVehicleHeight(VEH_TRAIN));
|
int target_resize = WidgetDimensions::scaled.matrix.top + FONT_HEIGHT_NORMAL + ScaleGUITrad(GetVehicleHeight(VEH_TRAIN));
|
||||||
this->bottom_matrix_item_size = resize->height = CeilT<int>(target_resize, base_resize);
|
this->bottom_matrix_item_size = resize->height = CeilT<int>(target_resize, base_resize);
|
||||||
size->height = 4 * resize->height;
|
size->height = 4 * resize->height;
|
||||||
|
|
||||||
|
int gap = ScaleGUITrad(TRW_GAP);
|
||||||
|
|
||||||
|
SetDParamMaxDigits(0, 8);
|
||||||
|
this->buy_cost_width = GetStringBoundingBox(STR_TMPL_TEMPLATE_OVR_VALUE).width + gap;
|
||||||
|
|
||||||
|
this->refit_text_width = maxdim(GetStringBoundingBox(STR_TMPL_CONFIG_REFIT_AS_TEMPLATE), GetStringBoundingBox(STR_TMPL_CONFIG_REFIT_AS_INCOMING)).width;
|
||||||
|
this->depot_text_width = GetStringBoundingBox(STR_TMPL_CONFIG_USEDEPOT).width + gap;
|
||||||
|
this->remainder_text_width = GetStringBoundingBox(STR_TMPL_CONFIG_KEEPREMAINDERS).width + gap;
|
||||||
|
this->old_text_width = GetStringBoundingBox(STR_TMPL_CONFIG_OLD_ONLY).width + gap;
|
||||||
|
|
||||||
|
/* use buy cost width as nominal width for name field */
|
||||||
|
uint left_side = ScaleGUITrad(TRW_LEFT_OFFSET) + this->buy_cost_width * 2;
|
||||||
|
uint right_side = this->refit_text_width + this->depot_text_width + this->remainder_text_width + this->old_text_width + ScaleGUITrad(TRW_RIGHT_OFFSET);
|
||||||
|
size->width = std::max(size->width, left_side + gap + right_side);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TRW_WIDGET_TRAIN_RAILTYPE_DROPDOWN: {
|
case TRW_WIDGET_TRAIN_RAILTYPE_DROPDOWN: {
|
||||||
@@ -708,28 +736,42 @@ public:
|
|||||||
|
|
||||||
const_cast<TemplateReplaceWindow *>(this)->BuildTemplateGuiList();
|
const_cast<TemplateReplaceWindow *>(this)->BuildTemplateGuiList();
|
||||||
|
|
||||||
int left = r.left;
|
|
||||||
int right = r.right;
|
|
||||||
int y = r.top;
|
int y = r.top;
|
||||||
|
|
||||||
Scrollbar *draw_vscroll = vscroll[1];
|
Scrollbar *draw_vscroll = vscroll[1];
|
||||||
uint max = std::min<uint>(draw_vscroll->GetPosition() + draw_vscroll->GetCapacity(), (uint)this->templates.size());
|
uint max = std::min<uint>(draw_vscroll->GetPosition() + draw_vscroll->GetCapacity(), (uint)this->templates.size());
|
||||||
|
|
||||||
|
bool rtl = _current_text_dir == TD_RTL;
|
||||||
|
|
||||||
const TemplateVehicle *v;
|
const TemplateVehicle *v;
|
||||||
for (uint i = draw_vscroll->GetPosition(); i < max; ++i) {
|
for (uint i = draw_vscroll->GetPosition(); i < max; ++i) {
|
||||||
v = (this->templates)[i];
|
v = (this->templates)[i];
|
||||||
|
|
||||||
/* Fill the background of the current cell in a darker tone for the currently selected template */
|
/* Fill the background of the current cell in a darker tone for the currently selected template */
|
||||||
if (this->selected_template_index == (int32) i) {
|
if (this->selected_template_index == (int32) i) {
|
||||||
GfxFillRect(left + 1, y, right, y + this->bottom_matrix_item_size, _colour_gradient[COLOUR_GREY][3]);
|
GfxFillRect(r.left + 1, y, r.right, y + this->bottom_matrix_item_size, _colour_gradient[COLOUR_GREY][3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw the template */
|
/* Draw the template */
|
||||||
DrawTemplate(v, left + ScaleGUITrad(36), right - ScaleGUITrad(24), y, ScaleGUITrad(15));
|
DrawTemplate(v, r.left + ScaleGUITrad(rtl ? TRW_RIGHT_OFFSET : TRW_LEFT_OFFSET), r.right - ScaleGUITrad(rtl ? TRW_LEFT_OFFSET : TRW_RIGHT_OFFSET), y, ScaleGUITrad(15));
|
||||||
|
|
||||||
|
auto draw_text_across = [&](int left_offset, int right_offset, int y_offset, StringID str, TextColour colour, StringAlignment align, FontSize fontsize = FS_NORMAL) {
|
||||||
|
DrawString(r.left + (rtl ? right_offset : left_offset), r.right - (rtl ? left_offset : right_offset), y + y_offset, str, colour, align, false, fontsize);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto draw_text_left = [&](int left_offset, int left_offset_end, int y_offset, StringID str, TextColour colour, StringAlignment align, FontSize fontsize = FS_NORMAL) {
|
||||||
|
int left = (rtl ? (r.right - left_offset_end) : (r.left + left_offset));
|
||||||
|
DrawString(left, left + (left_offset_end - left_offset), y + y_offset, str, colour, align, false, fontsize);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto draw_text_right = [&](int right_offset, int right_offset_end, int y_offset, StringID str, TextColour colour, StringAlignment align, FontSize fontsize = FS_NORMAL) {
|
||||||
|
int left = (rtl ? (r.left + right_offset_end) : (r.right - right_offset));
|
||||||
|
DrawString(left, left + (right_offset - right_offset_end), y + y_offset, str, colour, align, false, fontsize);
|
||||||
|
};
|
||||||
|
|
||||||
/* Draw a notification string for chains that are not runnable */
|
/* Draw a notification string for chains that are not runnable */
|
||||||
if (v->IsFreeWagonChain()) {
|
if (v->IsFreeWagonChain()) {
|
||||||
DrawString(left, right - ScaleGUITrad(24), y + ScaleGUITrad(2), STR_TMPL_WARNING_FREE_WAGON, TC_RED, SA_RIGHT);
|
draw_text_across(0, ScaleGUITrad(TRW_RIGHT_OFFSET), ScaleGUITrad(2), STR_TMPL_WARNING_FREE_WAGON, TC_RED, SA_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool buildable = true;
|
bool buildable = true;
|
||||||
@@ -744,52 +786,55 @@ public:
|
|||||||
}
|
}
|
||||||
/* Draw a notification string for chains that are not buildable */
|
/* Draw a notification string for chains that are not buildable */
|
||||||
if (!buildable) {
|
if (!buildable) {
|
||||||
DrawString(left, right - ScaleGUITrad(24), y + ScaleGUITrad(2), STR_TMPL_WARNING_VEH_UNAVAILABLE, TC_RED, SA_CENTER);
|
draw_text_across(0, ScaleGUITrad(TRW_RIGHT_OFFSET), ScaleGUITrad(2), STR_TMPL_WARNING_VEH_UNAVAILABLE, TC_RED, SA_CENTER);
|
||||||
} else if (types == RAILTYPES_NONE) {
|
} else if (types == RAILTYPES_NONE) {
|
||||||
DrawString(left, right - ScaleGUITrad(24), y + ScaleGUITrad(2), STR_TMPL_WARNING_VEH_NO_COMPATIBLE_RAIL_TYPE, TC_RED, SA_CENTER);
|
draw_text_across(0, ScaleGUITrad(TRW_RIGHT_OFFSET), ScaleGUITrad(2), STR_TMPL_WARNING_VEH_NO_COMPATIBLE_RAIL_TYPE, TC_RED, SA_CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw the template's length in tile-units */
|
/* Draw the template's length in tile-units */
|
||||||
SetDParam(0, v->GetRealLength());
|
SetDParam(0, v->GetRealLength());
|
||||||
SetDParam(1, 1);
|
SetDParam(1, 1);
|
||||||
DrawString(left, right - ScaleGUITrad(4), y + ScaleGUITrad(2), STR_JUST_DECIMAL, TC_BLACK, SA_RIGHT, false, FS_SMALL);
|
draw_text_across(0, ScaleGUITrad(4), ScaleGUITrad(2), STR_JUST_DECIMAL, TC_BLACK, SA_RIGHT, FS_SMALL);
|
||||||
|
|
||||||
int bottom_edge = y + this->bottom_matrix_item_size - FONT_HEIGHT_NORMAL - WidgetDimensions::scaled.framerect.bottom;
|
int bottom_edge = this->bottom_matrix_item_size - FONT_HEIGHT_NORMAL - WidgetDimensions::scaled.framerect.bottom;
|
||||||
|
|
||||||
bool have_name = !v->name.empty();
|
|
||||||
|
|
||||||
/* Buying cost */
|
/* Buying cost */
|
||||||
SetDParam(0, CalculateOverallTemplateCost(v));
|
SetDParam(0, CalculateOverallTemplateCost(v));
|
||||||
DrawString(left + ScaleGUITrad(35), have_name ? left + ScaleGUITrad(195) : right - ScaleGUITrad(310), bottom_edge, STR_TMPL_TEMPLATE_OVR_VALUE, TC_BLUE, SA_LEFT);
|
draw_text_left(ScaleGUITrad(TRW_LEFT_OFFSET), ScaleGUITrad(TRW_LEFT_OFFSET) + this->buy_cost_width, bottom_edge, STR_TMPL_TEMPLATE_OVR_VALUE, TC_BLUE, SA_LEFT);
|
||||||
|
|
||||||
if (have_name) {
|
|
||||||
SetDParamStr(0, v->name);
|
|
||||||
DrawString(left + ScaleGUITrad(200), right - ScaleGUITrad(310), bottom_edge, STR_JUST_RAW_STRING, TC_BLACK, SA_LEFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Index of current template vehicle in the list of all templates for its company */
|
/* Index of current template vehicle in the list of all templates for its company */
|
||||||
SetDParam(0, i);
|
SetDParam(0, i);
|
||||||
DrawString(left + ScaleGUITrad(5), left + ScaleGUITrad(25), y + ScaleGUITrad(2), STR_JUST_INT, TC_BLACK, SA_RIGHT);
|
draw_text_left(ScaleGUITrad(5), ScaleGUITrad(25), ScaleGUITrad(2), STR_JUST_INT, TC_BLACK, SA_RIGHT);
|
||||||
|
|
||||||
/* Draw whether the current template is in use by any group */
|
/* Draw whether the current template is in use by any group */
|
||||||
if (v->NumGroupsUsingTemplate() > 0) {
|
if (v->NumGroupsUsingTemplate() > 0) {
|
||||||
DrawString(left + ScaleGUITrad(35), right, bottom_edge - FONT_HEIGHT_NORMAL - WidgetDimensions::scaled.framerect.bottom,
|
draw_text_across(ScaleGUITrad(TRW_LEFT_OFFSET), 0, ScaleGUITrad(2), STR_TMP_TEMPLATE_IN_USE, TC_GREEN, SA_LEFT);
|
||||||
STR_TMP_TEMPLATE_IN_USE, TC_GREEN, SA_LEFT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw information about template configuration settings */
|
/* Draw information about template configuration settings */
|
||||||
|
|
||||||
DrawString(right - ScaleGUITrad(300), right, bottom_edge, v->IsSetRefitAsTemplate() ? STR_TMPL_CONFIG_REFIT_AS_TEMPLATE : STR_TMPL_CONFIG_REFIT_AS_INCOMING, TC_FROMSTRING, SA_LEFT);
|
int r_offset = ScaleGUITrad(TRW_LEFT_OFFSET);
|
||||||
|
|
||||||
TextColour color;
|
TextColour color;
|
||||||
color = v->IsSetReuseDepotVehicles() ? TC_LIGHT_BLUE : TC_GREY;
|
color = v->IsReplaceOldOnly() ? TC_LIGHT_BLUE : TC_GREY;
|
||||||
DrawString(right - ScaleGUITrad(210), right, bottom_edge, STR_TMPL_CONFIG_USEDEPOT, color, SA_LEFT);
|
draw_text_right(r_offset + this->old_text_width, r_offset, bottom_edge, STR_TMPL_CONFIG_OLD_ONLY, color, SA_RIGHT);
|
||||||
|
r_offset += this->old_text_width;
|
||||||
|
|
||||||
color = v->IsSetKeepRemainingVehicles() ? TC_LIGHT_BLUE : TC_GREY;
|
color = v->IsSetKeepRemainingVehicles() ? TC_LIGHT_BLUE : TC_GREY;
|
||||||
DrawString(right - ScaleGUITrad(140), right, bottom_edge, STR_TMPL_CONFIG_KEEPREMAINDERS, color, SA_LEFT);
|
draw_text_right(r_offset + this->remainder_text_width, r_offset, bottom_edge, STR_TMPL_CONFIG_KEEPREMAINDERS, color, SA_RIGHT);
|
||||||
|
r_offset += this->remainder_text_width;
|
||||||
|
|
||||||
color = v->IsReplaceOldOnly() ? TC_LIGHT_BLUE : TC_GREY;
|
color = v->IsSetReuseDepotVehicles() ? TC_LIGHT_BLUE : TC_GREY;
|
||||||
DrawString(right - ScaleGUITrad(70), right, bottom_edge, STR_TMPL_CONFIG_OLD_ONLY, color, SA_LEFT);
|
draw_text_right(r_offset + this->depot_text_width, r_offset, bottom_edge, STR_TMPL_CONFIG_USEDEPOT, color, SA_RIGHT);
|
||||||
|
r_offset += this->depot_text_width;
|
||||||
|
|
||||||
|
draw_text_right(r_offset + this->refit_text_width, r_offset, bottom_edge, v->IsSetRefitAsTemplate() ? STR_TMPL_CONFIG_REFIT_AS_TEMPLATE : STR_TMPL_CONFIG_REFIT_AS_INCOMING, TC_FROMSTRING, SA_LEFT);
|
||||||
|
r_offset += this->refit_text_width;
|
||||||
|
|
||||||
|
if (!v->name.empty()) {
|
||||||
|
SetDParamStr(0, v->name);
|
||||||
|
draw_text_across(ScaleGUITrad(TRW_LEFT_OFFSET) + this->buy_cost_width, r_offset + ScaleGUITrad(TRW_GAP), bottom_edge, STR_JUST_RAW_STRING, TC_BLACK, SA_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
y += this->bottom_matrix_item_size;
|
y += this->bottom_matrix_item_size;
|
||||||
}
|
}
|
||||||
|
@@ -78,6 +78,8 @@ void DrawTemplate(const TemplateVehicle *tv, int left, int right, int y, int hei
|
|||||||
{
|
{
|
||||||
if (!tv) return;
|
if (!tv) return;
|
||||||
|
|
||||||
|
bool rtl = _current_text_dir == TD_RTL;
|
||||||
|
|
||||||
DrawPixelInfo tmp_dpi;
|
DrawPixelInfo tmp_dpi;
|
||||||
int max_width = right - left + 1;
|
int max_width = right - left + 1;
|
||||||
int veh_height = ScaleSpriteTrad(14);
|
int veh_height = ScaleSpriteTrad(14);
|
||||||
@@ -87,12 +89,12 @@ void DrawTemplate(const TemplateVehicle *tv, int left, int right, int y, int hei
|
|||||||
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
|
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
|
||||||
|
|
||||||
const TemplateVehicle *t = tv;
|
const TemplateVehicle *t = tv;
|
||||||
int offset = 0;
|
int offset = rtl ? max_width : 0;
|
||||||
|
|
||||||
while (t) {
|
while (t) {
|
||||||
t->sprite_seq.Draw(offset + t->image_dimensions.GetOffsetX(), t->image_dimensions.GetOffsetY() + ScaleSpriteTrad(10), t->colourmap, false);
|
t->sprite_seq.Draw(offset + ((rtl ? -1 : 1) * t->image_dimensions.GetOffsetX()), t->image_dimensions.GetOffsetY() + ScaleSpriteTrad(10), t->colourmap, false);
|
||||||
|
|
||||||
offset += t->image_dimensions.GetDisplayImageWidth();
|
offset += (rtl ? -1 : 1) * t->image_dimensions.GetDisplayImageWidth();
|
||||||
t = t->Next();
|
t = t->Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +135,7 @@ void SetupTemplateVehicleFromVirtual(TemplateVehicle *tmp, TemplateVehicle *prev
|
|||||||
tmp->air_drag = gcache->cached_air_drag;
|
tmp->air_drag = gcache->cached_air_drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
virt->GetImage(DIR_W, EIT_IN_DEPOT, &tmp->sprite_seq);
|
virt->GetImage(_current_text_dir == TD_RTL ? DIR_E : DIR_W, EIT_IN_DEPOT, &tmp->sprite_seq);
|
||||||
tmp->image_dimensions.SetFromTrain(virt);
|
tmp->image_dimensions.SetFromTrain(virt);
|
||||||
tmp->colourmap = GetUncachedTrainPaletteIgnoringGroup(virt);
|
tmp->colourmap = GetUncachedTrainPaletteIgnoringGroup(virt);
|
||||||
}
|
}
|
||||||
@@ -441,7 +443,7 @@ void UpdateAllTemplateVehicleImages()
|
|||||||
if (t_len == tv_len) {
|
if (t_len == tv_len) {
|
||||||
Train *v = t;
|
Train *v = t;
|
||||||
for (TemplateVehicle *u = tv; u != nullptr; u = u->Next(), v = v->Next()) {
|
for (TemplateVehicle *u = tv; u != nullptr; u = u->Next(), v = v->Next()) {
|
||||||
v->GetImage(DIR_W, EIT_IN_DEPOT, &u->sprite_seq);
|
v->GetImage(_current_text_dir == TD_RTL ? DIR_E : DIR_W, EIT_IN_DEPOT, &u->sprite_seq);
|
||||||
u->image_dimensions.SetFromTrain(v);
|
u->image_dimensions.SetFromTrain(v);
|
||||||
u->colourmap = GetVehiclePalette(v);
|
u->colourmap = GetVehiclePalette(v);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user