Update: Translations from eints

english (au): 3 changes by krysclarke
swedish: 3 changes by robert-i
korean: 3 changes by telk5093
greek: 3 changes by gh658804
russian: 3 changes by Ln-Wolf
finnish: 3 changes by hpiirai
catalan: 3 changes by J0anJosep
portuguese: 3 changes by jcteotonio
portuguese (brazilian): 3 changes by pasantoro
polish: 3 changes by pAter-exe
This commit is contained in:
translators
2025-09-28 04:37:53 +00:00
committed by dP
parent 32b92a6594
commit ed856a8eb9
11 changed files with 217 additions and 248 deletions

View File

@@ -3431,8 +3431,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Água
STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatório
###length 3
STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatório
STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual
STR_MAPGEN_BORDER_RANDOMIZE :Aleatório
STR_MAPGEN_BORDER_MANUAL :Manual
STR_MAPGEN_BORDER_INFINITE_WATER :Água Infinita
STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Rotação do mapa de altitudes:
STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Nome do mapa de altitudes:

View File

@@ -3431,8 +3431,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Aigua
STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatori
###length 3
STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatori
STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual
STR_MAPGEN_BORDER_RANDOMIZE :Aleatori
STR_MAPGEN_BORDER_MANUAL :Manual
STR_MAPGEN_BORDER_INFINITE_WATER :Aigua infinita
STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Rotació del mapa d'alçades:
STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Nom del mapa d'alçades:

View File

@@ -3430,8 +3430,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Water
STR_MAPGEN_BORDER_RANDOM :{BLACK}Random
###length 3
STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Random
STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual
STR_MAPGEN_BORDER_RANDOMIZE :Random
STR_MAPGEN_BORDER_MANUAL :Manual
STR_MAPGEN_BORDER_INFINITE_WATER :Infinite Water
STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Heightmap rotation:
STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Heightmap name:

View File

@@ -3430,8 +3430,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Vesi
STR_MAPGEN_BORDER_RANDOM :{BLACK}Sattumanvarainen
###length 3
STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Sattumanvarainen
STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuaalinen
STR_MAPGEN_BORDER_RANDOMIZE :Satunnaiset
STR_MAPGEN_BORDER_MANUAL :Aseta käsin
STR_MAPGEN_BORDER_INFINITE_WATER :Ääretön vesi
STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Korkeuskartan kierto:
STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Korkeuskartan nimi:

View File

@@ -3523,8 +3523,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Νερό
STR_MAPGEN_BORDER_RANDOM :{BLACK}Τυχαία
###length 3
STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Τυχαία
STR_MAPGEN_BORDER_MANUAL :{BLACK}Χειροκίνητος
STR_MAPGEN_BORDER_RANDOMIZE :Τυχαία
STR_MAPGEN_BORDER_MANUAL :Χειροκίνητος
STR_MAPGEN_BORDER_INFINITE_WATER :Απεριόριστo Νερό
STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Περιστροφή χάρτη υψομετρίας:
STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Όνομα χάρτη υψομετρίας:

View File

@@ -3431,8 +3431,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}물
STR_MAPGEN_BORDER_RANDOM :{BLACK}임의
###length 3
STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}임의
STR_MAPGEN_BORDER_MANUAL :{BLACK}사용자 정의
STR_MAPGEN_BORDER_RANDOMIZE :임의
STR_MAPGEN_BORDER_MANUAL :사용자 정의
STR_MAPGEN_BORDER_INFINITE_WATER :물 (지도 밖까지 모두)
STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}높이맵 방향:
STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}높이맵 이름:

View File

@@ -3810,8 +3810,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Woda
STR_MAPGEN_BORDER_RANDOM :{BLACK}Losowe
###length 3
STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Losowo
STR_MAPGEN_BORDER_MANUAL :{BLACK}Użytkownika
STR_MAPGEN_BORDER_RANDOMIZE :Losowe
STR_MAPGEN_BORDER_MANUAL :Ustalone
STR_MAPGEN_BORDER_INFINITE_WATER :Bezkres Wód
STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Obrót mapy wysokości:
STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Nazwa mapy wysokosci:

View File

@@ -3431,8 +3431,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Água
STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatório
###length 3
STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatório
STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual
STR_MAPGEN_BORDER_RANDOMIZE :Aleatório
STR_MAPGEN_BORDER_MANUAL :Manual
STR_MAPGEN_BORDER_INFINITE_WATER :Água Infinita
STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Rotação mapa de alt.:
STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Nome mapa de alt.:

View File

@@ -3608,8 +3608,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Водн
STR_MAPGEN_BORDER_RANDOM :{BLACK}Случайно
###length 3
STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Случайно
STR_MAPGEN_BORDER_MANUAL :{BLACK}Вручную
STR_MAPGEN_BORDER_RANDOMIZE :Случайно
STR_MAPGEN_BORDER_MANUAL :Вручную
STR_MAPGEN_BORDER_INFINITE_WATER :Бескрайний океан
STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Поворот карты:
STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Название карты:

View File

@@ -3430,8 +3430,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Vatten
STR_MAPGEN_BORDER_RANDOM :{BLACK}På måfå
###length 3
STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}På måfå
STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuella
STR_MAPGEN_BORDER_RANDOMIZE :Slumpmässig
STR_MAPGEN_BORDER_MANUAL :Manuellt
STR_MAPGEN_BORDER_INFINITE_WATER :Obegränsat vatten
STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Höjdkartans rotation:
STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Namn på höjdkarta:

View File

@@ -1425,6 +1425,159 @@ public:
using CompanyButton = Button<CompanyID>;
using ClientButton = Button<ClientID>;
/**
* Base interface for a network client list line.
*/
class ButtonLine {
public:
std::vector<std::unique_ptr<ButtonCommon>> buttons{}; ///< Buttons for this line.
virtual ~ButtonLine() = default;
/**
* Draw the button line.
* @param r Rect to draw within.
*/
virtual void Draw(Rect r) const = 0;
template <typename T, typename...TArgs>
T &AddButton(TArgs &&... args)
{
auto &button = this->buttons.emplace_back(std::make_unique<T>(std::forward<TArgs &&>(args)...));
return static_cast<T &>(*button);
}
/**
* Get the button at a given point on the line.
* @param r Rect of line.
* @param pt Point of interest.
* @return Button at point, or \c nullptr if button isn't pressed.
*/
ButtonCommon *GetButton(Rect r, const Point &pt) const
{
bool rtl = _current_text_dir == TD_RTL;
for (auto &button : this->buttons) {
if (r.WithWidth(button->width, !rtl).Contains(pt)) return button.get();
r = r.Indent(button->width + WidgetDimensions::scaled.hsep_normal, !rtl);
}
return nullptr;
}
/**
* Get tooptip for a given point on the line.
* @param r Rect of line.
* @param pt Point of interest.
* @return EncodedString of tooltip, or \c std::nullopt if none.
*/
virtual std::optional<EncodedString> GetTooltip(Rect r, const Point &pt) const
{
ButtonCommon *button = this->GetButton(r, pt);
if (button == nullptr) return {};
return GetEncodedString(button->tooltip);
}
protected:
/**
* Draw the buttons for this line.
* @param r Rect to draw within.
* @return Rect of remaining space.
*/
Rect DrawButtons(Rect r) const
{
bool rtl = _current_text_dir == TD_RTL;
for (auto &button : buttons) {
Rect br = r.CentreTo(r.Width(), button->height).WithWidth(button->width, !rtl);
DrawFrameRect(br, button->colour, {});
DrawSpriteIgnorePadding(button->sprite, PAL_NONE, br, SA_CENTER);
if (button->disabled) {
GfxFillRect(br.Shrink(WidgetDimensions::scaled.bevel), GetColourGradient(button->colour, SHADE_DARKER), FILLRECT_CHECKER);
}
r = r.Indent(button->width + WidgetDimensions::scaled.hsep_normal, !rtl);
}
return r;
}
};
class CompanyButtonLine : public ButtonLine {
public:
CompanyButtonLine(CompanyID company_id) : company_id(company_id) {}
void Draw(Rect r) const override
{
bool rtl = _current_text_dir == TD_RTL;
r = this->DrawButtons(r);
Dimension d = GetSpriteSize(CM_SPR_COMPANY_ICON);
PaletteID pal = Company::IsValidID(this->company_id) ? GetCompanyPalette(this->company_id) : PALETTE_TO_GREY;
DrawSpriteIgnorePadding(CM_SPR_COMPANY_ICON, pal, r.WithWidth(d.width, rtl), SA_CENTER);
Rect tr = r.CentreTo(r.Width(), GetCharacterHeight(FS_NORMAL)).Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl);
if (this->company_id == COMPANY_SPECTATOR) {
DrawString(tr, STR_NETWORK_CLIENT_LIST_SPECTATORS, TC_SILVER);
} else if (this->company_id == COMPANY_NEW_COMPANY) {
DrawString(tr, STR_NETWORK_CLIENT_LIST_NEW_COMPANY, TC_WHITE);
} else {
DrawString(tr, GetString(STR_COMPANY_NAME, this->company_id, this->company_id), TC_SILVER);
}
};
private:
CompanyID company_id;
};
class ClientButtonLine : public ButtonLine {
public:
ClientButtonLine(ClientPoolID client_pool_id) : client_pool_id(client_pool_id) {}
void Draw(Rect r) const override
{
const NetworkClientInfo *ci = NetworkClientInfo::GetIfValid(this->client_pool_id);
if (ci == nullptr) return;
bool rtl = _current_text_dir == TD_RTL;
r = this->DrawButtons(r);
Rect tr = r.CentreTo(r.Width(), GetCharacterHeight(FS_NORMAL));
SpriteID player_icon = 0;
if (ci->client_id == _network_own_client_id) {
player_icon = CM_SPR_PLAYER; /* SPR_PLAYER_SELF */
} else if (ci->client_id == CLIENT_ID_SERVER) {
player_icon = CM_SPR_HOST; /* SPR_PLAYER_HOST */
}
if (player_icon != 0) {
Dimension d = GetSpriteSize(player_icon);
DrawSpriteIgnorePadding(player_icon, PALETTE_TO_GREY, r.WithWidth(d.width, rtl), SA_CENTER);
tr = tr.Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl);
}
DrawString(tr, GetString(STR_JUST_RAW_STRING, ci->client_name), TC_BLACK);
}
std::optional<EncodedString> GetTooltip(Rect r, const Point &pt) const override
{
bool rtl = _current_text_dir == TD_RTL;
Dimension d = GetSpriteSize(SPR_PLAYER_SELF);
if (r.WithWidth(d.width, rtl).Contains(pt)) {
const NetworkClientInfo *ci = NetworkClientInfo::GetIfValid(this->client_pool_id);
if (ci != nullptr) {
if (ci->client_id == _network_own_client_id) {
return GetEncodedString(STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP);
} else if (ci->client_id == CLIENT_ID_SERVER) {
return GetEncodedString(STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP);
}
}
}
return this->ButtonLine::GetTooltip(r, pt);
}
private:
ClientPoolID client_pool_id;
};
/**
* Main handle for clientlist
*/
@@ -1437,12 +1590,9 @@ private:
Scrollbar *vscroll = nullptr; ///< Vertical scrollbar of this window.
uint line_height = 0; ///< Current lineheight of each entry in the matrix.
uint line_count = 0; ///< Amount of lines in the matrix.
int hover_index = -1; ///< Index of the current line we are hovering over, or -1 if none.
int player_self_index = -1; ///< The line the current player is on.
int player_host_index = -1; ///< The line the host is on.
std::map<uint, std::vector<std::unique_ptr<ButtonCommon>>> buttons{}; ///< Per line which buttons are available.
std::vector<std::unique_ptr<ButtonLine>> buttons{}; ///< Per line which buttons are available.
/**
* Chat button on a Company is clicked.
@@ -1561,44 +1711,34 @@ private:
*/
void RebuildListCompany(CompanyID company_id, CompanyID client_playas, bool can_join_company)
{
ButtonCommon *chat_button = new CompanyButton(SPR_CHAT, company_id == COMPANY_SPECTATOR ? STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP : STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyChat);
ButtonLine &company_line = *this->buttons.emplace_back(std::make_unique<CompanyButtonLine>(company_id));
if (_network_server) company_line.AddButton<CompanyButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP, COLOUR_RED, company_id, &NetworkClientListWindow::OnClickCompanyAdmin, company_id == COMPANY_SPECTATOR);
if (_network_server) this->buttons[line_count].push_back(std::make_unique<CompanyButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP, COLOUR_RED, company_id, &NetworkClientListWindow::OnClickCompanyAdmin, company_id == COMPANY_SPECTATOR));
/* CityMania code start */
auto company = Company::GetIfValid(company_id);
if (company != nullptr) {
ButtonCommon *hq_button = new CompanyButton(CM_SPR_HQ, CM_STR_NETWORK_CLIENT_LIST_HQ_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::CMOnClickCompanyHQ);
if (company->location_of_HQ == INVALID_TILE) hq_button->disabled = true;
this->buttons[line_count].emplace_back(hq_button);
// TODO push_back(make_unique?
this->buttons[line_count].emplace_back(new CompanyButton(CM_SPR_WATCH, CM_STR_NETWORK_CLIENT_LIST_WATCH_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::CMOnClickCompanyWatch));
ButtonCommon &hq_button = company_line.AddButton<CompanyButton>(CM_SPR_HQ, CM_STR_NETWORK_CLIENT_LIST_HQ_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::CMOnClickCompanyHQ);
if (company->location_of_HQ == INVALID_TILE) hq_button.disabled = true;
company_line.AddButton<CompanyButton>(CM_SPR_WATCH, CM_STR_NETWORK_CLIENT_LIST_WATCH_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::CMOnClickCompanyWatch);
}
/* CityMania code end */
this->buttons[line_count].emplace_back(chat_button);
if (can_join_company) this->buttons[line_count].push_back(std::make_unique<CompanyButton>(SPR_JOIN, STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyJoin, company_id != COMPANY_SPECTATOR && Company::Get(company_id)->is_ai));
this->line_count += 1;
ButtonCommon &chat_button = company_line.AddButton<CompanyButton>(SPR_CHAT, company_id == COMPANY_SPECTATOR ? STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP : STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyChat);
if (can_join_company) company_line.AddButton<CompanyButton>(SPR_JOIN, STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyJoin, company_id != COMPANY_SPECTATOR && Company::Get(company_id)->is_ai);
bool has_players = false;
for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
if (ci->client_playas != company_id) continue;
has_players = true;
if (_network_server) this->buttons[line_count].push_back(std::make_unique<ClientButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP, COLOUR_RED, ci->client_id, &NetworkClientListWindow::OnClickClientAdmin, _network_own_client_id == ci->client_id));
if (_network_own_client_id != ci->client_id) this->buttons[line_count].push_back(std::make_unique<ClientButton>(SPR_CHAT, STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP, COLOUR_ORANGE, ci->client_id, &NetworkClientListWindow::OnClickClientChat));
if (_network_own_client_id != ci->client_id && client_playas != COMPANY_SPECTATOR && !ci->CanJoinCompany(client_playas)) this->buttons[line_count].push_back(std::make_unique<ClientButton>(SPR_JOIN, STR_NETWORK_CLIENT_LIST_COMPANY_AUTHORIZE_TOOLTIP, COLOUR_GREEN, ci->client_id, &NetworkClientListWindow::OnClickClientAuthorize));
if (ci->client_id == _network_own_client_id) {
this->player_self_index = this->line_count;
} else if (ci->client_id == CLIENT_ID_SERVER) {
this->player_host_index = this->line_count;
}
this->line_count += 1;
ButtonLine &line = *this->buttons.emplace_back(std::make_unique<ClientButtonLine>(ci->index));
if (_network_server) line.AddButton<ClientButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP, COLOUR_RED, ci->client_id, &NetworkClientListWindow::OnClickClientAdmin, _network_own_client_id == ci->client_id);
if (_network_own_client_id != ci->client_id) line.AddButton<ClientButton>(SPR_CHAT, STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP, COLOUR_ORANGE, ci->client_id, &NetworkClientListWindow::OnClickClientChat);
if (_network_own_client_id != ci->client_id && client_playas != COMPANY_SPECTATOR && !ci->CanJoinCompany(client_playas)) line.AddButton<ClientButton>(SPR_JOIN, STR_NETWORK_CLIENT_LIST_COMPANY_AUTHORIZE_TOOLTIP, COLOUR_GREEN, ci->client_id, &NetworkClientListWindow::OnClickClientAuthorize);
}
/* Disable the chat button when there are players in this company. */
chat_button->disabled = !has_players;
chat_button.disabled = !has_players;
}
/**
@@ -1610,14 +1750,11 @@ private:
CompanyID client_playas = own_ci == nullptr ? COMPANY_SPECTATOR : own_ci->client_playas;
this->buttons.clear();
this->line_count = 0;
this->player_host_index = -1;
this->player_self_index = -1;
/* As spectator, show a line to create a new company. */
if (client_playas == COMPANY_SPECTATOR && !NetworkMaxCompaniesReached()) {
this->buttons[line_count].push_back(std::make_unique<CompanyButton>(SPR_JOIN, STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP, COLOUR_ORANGE, COMPANY_SPECTATOR, &NetworkClientListWindow::OnClickCompanyNew));
this->line_count += 1;
ButtonLine &line = *this->buttons.emplace_back(std::make_unique<CompanyButtonLine>(COMPANY_NEW_COMPANY));
line.AddButton<CompanyButton>(SPR_JOIN, STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP, COLOUR_ORANGE, COMPANY_SPECTATOR, &NetworkClientListWindow::OnClickCompanyNew);
}
if (client_playas != COMPANY_SPECTATOR) {
@@ -1634,40 +1771,7 @@ private:
/* Spectators */
this->RebuildListCompany(COMPANY_SPECTATOR, client_playas, client_playas != COMPANY_SPECTATOR);
this->vscroll->SetCount(this->line_count);
}
/**
* Get the button at a specific point on the WID_CL_MATRIX.
* @param pt The point to look for a button.
* @return The button or a nullptr if there was none.
*/
ButtonCommon *GetButtonAtPoint(Point pt)
{
uint index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_CL_MATRIX);
Rect matrix = this->GetWidget<NWidgetBase>(WID_CL_MATRIX)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
bool rtl = _current_text_dir == TD_RTL;
uint x = rtl ? matrix.left : matrix.right;
/* Find the buttons for this row. */
auto button_find = this->buttons.find(index);
if (button_find == this->buttons.end()) return nullptr;
/* Check if we want to display a tooltip for any of the buttons. */
for (auto &button : button_find->second) {
uint left = rtl ? x : x - button->width;
uint right = rtl ? x + button->width : x;
if (IsInsideMM(pt.x, left, right)) {
return button.get();
}
int width = button->width + WidgetDimensions::scaled.framerect.Horizontal();
x += rtl ? width : -width;
}
return nullptr;
this->vscroll->SetCount(this->buttons.size());
}
public:
@@ -1682,7 +1786,7 @@ public:
void OnInit() override
{
RebuildList();
this->RebuildList();
}
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
@@ -1786,7 +1890,12 @@ public:
break;
case WID_CL_MATRIX: {
ButtonCommon *button = this->GetButtonAtPoint(pt);
auto it = this->vscroll->GetScrolledItemFromWidget(this->buttons, pt.y, this, WID_CL_MATRIX);
if (it == std::end(this->buttons)) break;
Rect r = this->GetWidget<NWidgetBase>(WID_CL_MATRIX)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
ButtonCommon *button = (*it)->GetButton(r, pt);
/* CityMania code start */
// NOTE: needs to match company order in DrawWidget
if (button == nullptr) {
@@ -1835,34 +1944,14 @@ public:
{
switch (widget) {
case WID_CL_MATRIX: {
int index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_CL_MATRIX);
auto it = this->vscroll->GetScrolledItemFromWidget(this->buttons, pt.y, this, WID_CL_MATRIX);
if (it == std::end(this->buttons)) break;
bool rtl = _current_text_dir == TD_RTL;
Rect matrix = this->GetWidget<NWidgetBase>(WID_CL_MATRIX)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
Rect r = this->GetWidget<NWidgetBase>(WID_CL_MATRIX)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
auto tooltip = (*it)->GetTooltip(r, pt);
if (!tooltip.has_value()) break;
Dimension d = GetSpriteSize(SPR_COMPANY_ICON);
uint text_left = matrix.left + (rtl ? 0 : d.width + WidgetDimensions::scaled.hsep_wide);
uint text_right = matrix.right - (rtl ? d.width + WidgetDimensions::scaled.hsep_wide : 0);
Dimension d2 = GetSpriteSize(SPR_PLAYER_SELF);
uint offset_x = WidgetDimensions::scaled.hsep_indent - d2.width - ScaleGUITrad(3);
uint player_icon_x = rtl ? text_right - offset_x - d2.width : text_left + offset_x;
if (IsInsideMM(pt.x, player_icon_x, player_icon_x + d2.width)) {
if (index == this->player_self_index) {
GuiShowTooltips(this, GetEncodedString(STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP), close_cond);
return true;
} else if (index == this->player_host_index) {
GuiShowTooltips(this, GetEncodedString(STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP), close_cond);
return true;
}
}
ButtonCommon *button = this->GetButtonAtPoint(pt);
if (button == nullptr) return false;
GuiShowTooltips(this, GetEncodedString(button->tooltip), close_cond);
GuiShowTooltips(this, std::move(*tooltip), close_cond);
return true;
};
}
@@ -1956,153 +2045,23 @@ public:
}
}
/**
* Draw the buttons for a single line in the matrix.
*
* The x-position in RTL is the most left or otherwise the most right pixel
* we can draw the buttons from.
*
* @param x The x-position to start with the buttons. Updated during this function.
* @param y The y-position to start with the buttons.
* @param buttons The buttons to draw.
*/
void DrawButtons(int &x, uint y, const std::vector<std::unique_ptr<ButtonCommon>> &buttons) const
{
Rect r;
for (auto &button : buttons) {
bool rtl = _current_text_dir == TD_RTL;
int offset = (this->line_height - button->height) / 2;
r.left = rtl ? x : x - button->width + 1;
r.right = rtl ? x + button->width - 1 : x;
r.top = y + offset;
r.bottom = r.top + button->height - 1;
DrawFrameRect(r, button->colour, {});
DrawSprite(button->sprite, PAL_NONE, r.left + WidgetDimensions::scaled.framerect.left, r.top + WidgetDimensions::scaled.framerect.top);
if (button->disabled) {
GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), GetColourGradient(button->colour, SHADE_DARKER), FILLRECT_CHECKER);
}
int width = button->width + WidgetDimensions::scaled.hsep_normal;
x += rtl ? width : -width;
}
}
/**
* Draw a company and its clients on the matrix.
* @param company_id The company to draw.
* @param r The rect to draw within.
* @param line The Nth line we are drawing. Updated during this function.
*/
void DrawCompany(CompanyID company_id, const Rect &r, uint &line) const
{
bool rtl = _current_text_dir == TD_RTL;
int text_y_offset = CentreBounds(0, this->line_height, GetCharacterHeight(FS_NORMAL));
Dimension d = GetSpriteSize(CM_SPR_COMPANY_ICON);
int offset = CentreBounds(0, this->line_height, d.height);
uint line_start = this->vscroll->GetPosition();
uint line_end = line_start + this->vscroll->GetCapacity();
uint y = r.top + (this->line_height * (line - line_start));
/* Draw the company line (if in range of scrollbar). */
if (IsInsideMM(line, line_start, line_end)) {
int icon_left = r.WithWidth(d.width, rtl).left;
Rect tr = r.Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl);
int &x = rtl ? tr.left : tr.right;
/* If there are buttons for this company, draw them. */
auto button_find = this->buttons.find(line);
if (button_find != this->buttons.end()) {
this->DrawButtons(x, y, button_find->second);
}
if (company_id == COMPANY_SPECTATOR) {
DrawSprite(CM_SPR_COMPANY_ICON, PALETTE_TO_GREY, icon_left, y + offset);
DrawString(tr.left, tr.right, y + text_y_offset, STR_NETWORK_CLIENT_LIST_SPECTATORS, TC_SILVER);
} else if (company_id == COMPANY_NEW_COMPANY) {
DrawSprite(CM_SPR_COMPANY_ICON, PALETTE_TO_GREY, icon_left, y + offset);
DrawString(tr.left, tr.right, y + text_y_offset, STR_NETWORK_CLIENT_LIST_NEW_COMPANY, TC_WHITE);
} else {
DrawSprite(CM_SPR_COMPANY_ICON, GetCompanyPalette(company_id), icon_left, y + offset);
DrawString(tr.left, tr.right, y + text_y_offset, GetString(STR_COMPANY_NAME, company_id, company_id), TC_SILVER);
}
}
y += this->line_height;
line++;
for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
if (ci->client_playas != company_id) continue;
/* Draw the player line (if in range of scrollbar). */
if (IsInsideMM(line, line_start, line_end)) {
Rect tr = r.Indent(WidgetDimensions::scaled.hsep_indent, rtl);
/* If there are buttons for this client, draw them. */
auto button_find = this->buttons.find(line);
if (button_find != this->buttons.end()) {
int &x = rtl ? tr.left : tr.right;
this->DrawButtons(x, y, button_find->second);
}
SpriteID player_icon = 0;
if (ci->client_id == _network_own_client_id) {
player_icon = CM_SPR_PLAYER /* SPR_PLAYER_SELF */;
} else if (ci->client_id == CLIENT_ID_SERVER) {
player_icon = CM_SPR_HOST /* SPR_PLAYER_HOST */;
}
if (player_icon != 0) {
Dimension d2 = GetSpriteSize(player_icon);
int offset_y = CentreBounds(0, this->line_height, d2.height);
DrawSprite(player_icon, PALETTE_TO_GREY, rtl ? tr.right - d2.width : tr.left, y + offset_y);
tr = tr.Indent(d2.width + WidgetDimensions::scaled.hsep_normal, rtl);
}
DrawString(tr.left, tr.right, y + text_y_offset, GetString(STR_JUST_RAW_STRING, ci->client_name), TC_BLACK);
}
y += this->line_height;
line++;
}
}
void DrawWidget(const Rect &r, WidgetID widget) const override
{
switch (widget) {
case WID_CL_MATRIX: {
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero);
uint line = 0;
Rect ir = r.WithHeight(this->line_height).Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero);
if (this->hover_index >= 0) {
Rect br = r.WithHeight(this->line_height).Translate(0, this->hover_index * this->line_height);
GfxFillRect(br.Shrink(WidgetDimensions::scaled.bevel), GREY_SCALE(9));
}
NetworkClientInfo *own_ci = NetworkClientInfo::GetByClientID(_network_own_client_id);
CompanyID client_playas = own_ci == nullptr ? COMPANY_SPECTATOR : own_ci->client_playas;
if (client_playas == COMPANY_SPECTATOR && !NetworkMaxCompaniesReached()) {
this->DrawCompany(COMPANY_NEW_COMPANY, ir, line);
auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->buttons);
for (auto it = first; it != last; ++it) {
(*it)->Draw(ir);
ir = ir.Translate(0, this->line_height);
}
if (client_playas != COMPANY_SPECTATOR) {
this->DrawCompany(client_playas, ir, line);
}
for (const Company *c : Company::Iterate()) {
if (client_playas == c->index) continue;
this->DrawCompany(c->index, ir, line);
}
/* Spectators */
this->DrawCompany(COMPANY_SPECTATOR, ir, line);
break;
}
}