diff --git a/.ottdrev b/.ottdrev
new file mode 100644
index 0000000000..89af2c77e7
--- /dev/null
+++ b/.ottdrev
@@ -0,0 +1 @@
+1.6.1 27609 0 1.6.1
diff --git a/android-extract-strings.sh b/android-extract-strings.sh
new file mode 100755
index 0000000000..f03e4bace8
--- /dev/null
+++ b/android-extract-strings.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+mkdir -p ../translations/lang
+git diff 1.6/master -- src/lang/english.txt | tail -n +5 | grep '^[+]' | cut -b 2- | \
+grep -v "^STR_TABLET_CLOSE\b" | \
+grep -v "^STR_TABLET_SHIFT\b" | \
+grep -v "^STR_TABLET_CTRL\b" | \
+cat > ../translations/lang/english.txt
+
+for f in src/lang/*.txt; do
+ [ "$f" = src/lang/english.txt ] && continue
+ rm -f ../translations/lang/`basename $f`
+ cat ../translations/lang/english.txt | grep '^STR' | while read name text; do
+ grep "^$name\b" $f >> ../translations/lang/`basename $f`
+ done
+done
diff --git a/android-store-strings.sh b/android-store-strings.sh
new file mode 100755
index 0000000000..70781d22b7
--- /dev/null
+++ b/android-store-strings.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+for f in ../translations/lang/*.txt; do
+ [ "$f" = ../translations/lang/english.txt ] && continue
+ out=src/lang/`basename $f`
+ grep "^# Android strings" $out > /dev/null || [ -z "`tail -c 2 $out`" ] || echo >> $out
+ { grep -v "^# Android strings" $out ; echo "# Android strings" ; } > $out.new
+ mv -f $out.new $out
+ cat $f | grep '^STR' | while read name text; do
+ { grep -v "^$name\b" $out ; printf "%-64s%s\n" "$name" "$text" ; } > $out.new
+ mv -f $out.new $out
+ done
+done
diff --git a/config.lib b/config.lib
index 3d10aaa3fd..df5a01adf2 100644
--- a/config.lib
+++ b/config.lib
@@ -1048,7 +1048,7 @@ check_params() {
# of the tags folder, the folder of the tag does not have a .svn folder
# anymore and this fails to detect the subversion repository checkout.
log 1 "checking revision... svn detection (tag)"
- elif [ -d "$ROOT_DIR/.git" ] && [ -n "`git help 2>/dev/null`" ]; then
+ elif [ -e "$ROOT_DIR/.git" ] && [ -n "`git help 2>/dev/null`" ]; then
log 1 "checking revision... git detection"
elif [ -d "$ROOT_DIR/.hg" ] && [ -n "`HGPLAIN= hg help 2>/dev/null`" ]; then
log 1 "checking revision... hg detection"
diff --git a/configure b/configure
index 5edbca1867..0510e4dd22 100755
--- a/configure
+++ b/configure
@@ -127,7 +127,7 @@ AWKCOMMAND='
if ($0 == "WINCE" && "'$os'" != "WINCE") { next; }
if ($0 == "MSVC" && "'$os'" != "MSVC") { next; }
if ($0 == "DIRECTMUSIC" && "'$with_direct_music'" == "0") { next; }
- if ($0 == "LIBTIMIDITY" && "'$libtimidity'" == "" ) { next; }
+ if ($0 == "LIBTIMIDITY" && "'$libtimidity_config'" == "" ) { next; }
if ($0 == "HAVE_THREAD" && "'$with_threads'" == "0") { next; }
if ($0 == "SSE" && "'$with_sse'" != "1") { next; }
diff --git a/findversion.sh b/findversion.sh
index 6be52b696f..bcae7b1989 100755
--- a/findversion.sh
+++ b/findversion.sh
@@ -70,7 +70,11 @@ ROOT_DIR=`pwd`
# Determine if we are using a modified version
# Assume the dir is not modified
MODIFIED="0"
-if [ -d "$ROOT_DIR/.svn" ] || [ -d "$ROOT_DIR/../.svn" ]; then
+if [ -f "$ROOT_DIR/.ottdrev" ]; then
+ # We are an exported source bundle
+ cat $ROOT_DIR/.ottdrev
+ exit
+elif [ -d "$ROOT_DIR/.svn" ] || [ -d "$ROOT_DIR/../.svn" ]; then
# We are an svn checkout
if [ -n "`svnversion | grep 'M'`" ]; then
MODIFIED="2"
@@ -84,7 +88,7 @@ if [ -d "$ROOT_DIR/.svn" ] || [ -d "$ROOT_DIR/../.svn" ]; then
else
REV="r$REV_NR"
fi
-elif [ -d "$ROOT_DIR/.git" ]; then
+elif [ -e "$ROOT_DIR/.git" ]; then
# We are a git checkout
# Refresh the index to make sure file stat info is in sync, then look for modifications
git update-index --refresh >/dev/null
@@ -122,10 +126,6 @@ elif [ -d "$ROOT_DIR/.hg" ]; then
# No rev? Maybe it is a custom hgsubversion clone
REV_NR=`LC_ALL=C HGPLAIN= hg parent --template="{svnrev}"`
fi
-elif [ -f "$ROOT_DIR/.ottdrev" ]; then
- # We are an exported source bundle
- cat $ROOT_DIR/.ottdrev
- exit
else
# We don't know
MODIFIED="1"
@@ -134,6 +134,7 @@ else
REV_NR=""
fi
+MODIFIED="0" # This prevents Andorid build from connecting to a public servers
if [ "$MODIFIED" -eq "2" ]; then
REV="${REV}M"
fi
diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj
index 59e087ee70..dc4ff018a7 100644
--- a/projects/openttd_vs100.vcxproj
+++ b/projects/openttd_vs100.vcxproj
@@ -626,6 +626,7 @@
+
diff --git a/projects/openttd_vs100.vcxproj.filters b/projects/openttd_vs100.vcxproj.filters
index 06800ffdaf..608345d9ed 100644
--- a/projects/openttd_vs100.vcxproj.filters
+++ b/projects/openttd_vs100.vcxproj.filters
@@ -1107,6 +1107,9 @@
Header Files
+
+ Header Files
+
Header Files
diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj
index 70dcab226a..624242d5bf 100644
--- a/projects/openttd_vs80.vcproj
+++ b/projects/openttd_vs80.vcproj
@@ -1778,6 +1778,10 @@
RelativePath=".\..\src\timetable.h"
>
+
+
diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj
index dd722d085d..1c9d3226db 100644
--- a/projects/openttd_vs90.vcproj
+++ b/projects/openttd_vs90.vcproj
@@ -1775,6 +1775,10 @@
RelativePath=".\..\src\timetable.h"
>
+
+
diff --git a/source.list b/source.list
index df35cdd26e..f7c8096d57 100644
--- a/source.list
+++ b/source.list
@@ -93,6 +93,7 @@ tgp.cpp
tile_map.cpp
tilearea.cpp
townname.cpp
+tutorial_gui.cpp
#if WIN32
#else
#if WINCE
@@ -143,6 +144,7 @@ base_media_func.h
base_station_base.h
bmp.h
bridge.h
+build_confirmation_func.h
cargo_type.h
cargoaction.h
cargomonitor.h
@@ -365,6 +367,7 @@ tilehighlight_func.h
tilehighlight_type.h
tilematrix_type.hpp
timetable.h
+toolbar_type.h
toolbar_gui.h
town.h
town_type.h
@@ -451,6 +454,7 @@ airport_gui.cpp
autoreplace_gui.cpp
bootstrap_gui.cpp
bridge_gui.cpp
+build_confirmation_gui.cpp
build_vehicle_gui.cpp
cheat_gui.cpp
company_gui.cpp
@@ -906,6 +910,12 @@ script/api/script_window.cpp
# Blitters
#if DEDICATED
#else
+blitter/16bpp_base.cpp
+blitter/16bpp_base.hpp
+blitter/16bpp_anim.cpp
+blitter/16bpp_anim.hpp
+blitter/16bpp_simple.cpp
+blitter/16bpp_simple.hpp
blitter/32bpp_anim.cpp
blitter/32bpp_anim.hpp
#if SSE
@@ -1113,7 +1123,10 @@ music/null_m.cpp
#else
#if MORPHOS
#else
- music/extmidi.cpp
+ #if LIBTIMIDITY
+ #else
+ music/extmidi.cpp
+ #end
#end
#end
#end
diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp
index a0720e2ea5..a49513009d 100644
--- a/src/ai/ai_gui.cpp
+++ b/src/ai/ai_gui.cpp
@@ -109,7 +109,7 @@ struct AIListWindow : public Window {
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
if (widget == WID_AIL_LIST) {
- this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
+ this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM);
resize->width = 1;
resize->height = this->line_height;
@@ -122,16 +122,16 @@ struct AIListWindow : public Window {
switch (widget) {
case WID_AIL_LIST: {
/* Draw a list of all available AIs. */
- int y = this->GetWidget(WID_AIL_LIST)->pos_y;
+ int y = Center(r.top, this->line_height);
/* First AI in the list is hardcoded to random */
if (this->vscroll->IsVisible(0)) {
- DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_LEFT, y + WD_MATRIX_TOP, this->slot == OWNER_DEITY ? STR_AI_CONFIG_NONE : STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_ORANGE);
+ DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_LEFT, y, this->slot == OWNER_DEITY ? STR_AI_CONFIG_NONE : STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_ORANGE);
y += this->line_height;
}
ScriptInfoList::const_iterator it = this->info_list->begin();
for (int i = 1; it != this->info_list->end(); i++, it++) {
if (this->vscroll->IsVisible(i)) {
- DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, (*it).second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE);
+ DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y, (*it).second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE);
y += this->line_height;
}
}
@@ -347,7 +347,7 @@ struct AISettingsWindow : public Window {
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
if (widget == WID_AIS_BACKGROUND) {
- this->line_height = max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
+ this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM);
resize->width = 1;
resize->height = this->line_height;
@@ -369,7 +369,6 @@ struct AISettingsWindow : public Window {
uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8);
uint text_right = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT);
-
int y = r.top;
int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2;
@@ -414,7 +413,7 @@ struct AISettingsWindow : public Window {
}
}
- DrawString(text_left, text_right, y + text_y_offset, str, colour);
+ DrawString(text_left, text_right, Center(y, this->line_height), str, colour);
y += this->line_height;
}
}
@@ -662,39 +661,41 @@ static const NWidgetPart _nested_ai_config_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_MAUVE, WID_AIC_BACKGROUND),
- NWidget(NWID_VERTICAL), SetPIP(4, 4, 4),
- NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7),
- NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_DECREASE), SetFill(0, 1), SetDataTip(AWV_DECREASE, STR_NULL),
- NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_INCREASE), SetFill(0, 1), SetDataTip(AWV_INCREASE, STR_NULL),
- NWidget(NWID_SPACER), SetMinimalSize(6, 0),
- NWidget(WWT_TEXT, COLOUR_MAUVE, WID_AIC_NUMBER), SetDataTip(STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS, STR_NULL), SetFill(1, 0), SetPadding(1, 0, 0, 0),
+ NWidget(NWID_HORIZONTAL), SetPIP(7, 7, 7),
+ NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_AI, STR_NULL), SetPadding(0, 5, 0, 5),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIC_LIST), SetMinimalSize(288, 112), SetFill(1, 0), SetMatrixDataTip(1, 8, STR_AI_CONFIG_AILIST_TOOLTIP), SetScrollbar(WID_AIC_SCROLLBAR),
+ NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_AIC_SCROLLBAR),
+ EndContainer(),
EndContainer(),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_UP), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_UP, STR_AI_CONFIG_MOVE_UP_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_DOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_DOWN, STR_AI_CONFIG_MOVE_DOWN_TOOLTIP),
+ NWidget(NWID_VERTICAL), SetPIP(4, 4, 4),
+ NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_DECREASE), SetFill(0, 1), SetDataTip(AWV_DECREASE, STR_NULL),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_INCREASE), SetFill(0, 1), SetDataTip(AWV_INCREASE, STR_NULL),
+ NWidget(NWID_SPACER), SetMinimalSize(6, 0),
+ NWidget(WWT_TEXT, COLOUR_MAUVE, WID_AIC_NUMBER), SetDataTip(STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS, STR_NULL), SetFill(1, 0), SetPadding(1, 0, 0, 0),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_UP), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_UP, STR_AI_CONFIG_MOVE_UP_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_DOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_DOWN, STR_AI_CONFIG_MOVE_DOWN_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 9),
+ NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_GAMESCRIPT, STR_NULL), SetPadding(0, 5, 4, 5),
+ NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIC_GAMELIST), SetSizingType(NWST_STEP), SetMinimalSize(288, 14), SetFill(1, 0), SetMatrixDataTip(1, 1, STR_AI_CONFIG_GAMELIST_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CHANGE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_CONFIG_CHANGE, STR_AI_CONFIG_CHANGE_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CONFIGURE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_CONFIG_CONFIGURE, STR_AI_CONFIG_CONFIGURE_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CLOSE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
+ EndContainer(),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CONTENT_DOWNLOAD), SetFill(1, 0), SetMinimalSize(279, 12), SetPadding(0, 7, 9, 7), SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
EndContainer(),
EndContainer(),
- NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_AI, STR_NULL), SetPadding(0, 5, 0, 5),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIC_LIST), SetMinimalSize(288, 112), SetFill(1, 0), SetMatrixDataTip(1, 8, STR_AI_CONFIG_AILIST_TOOLTIP), SetScrollbar(WID_AIC_SCROLLBAR),
- NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_AIC_SCROLLBAR),
- EndContainer(),
- EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 9),
- NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_GAMESCRIPT, STR_NULL), SetPadding(0, 5, 4, 5),
- NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIC_GAMELIST), SetMinimalSize(288, 14), SetFill(1, 0), SetMatrixDataTip(1, 1, STR_AI_CONFIG_GAMELIST_TOOLTIP),
- EndContainer(),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CHANGE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_CONFIG_CHANGE, STR_AI_CONFIG_CHANGE_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CONFIGURE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_CONFIG_CONFIGURE, STR_AI_CONFIG_CONFIGURE_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CLOSE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL),
- EndContainer(),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
- EndContainer(),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CONTENT_DOWNLOAD), SetFill(1, 0), SetMinimalSize(279, 12), SetPadding(0, 7, 9, 7), SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
EndContainer(),
};
@@ -759,12 +760,12 @@ struct AIConfigWindow : public Window {
{
switch (widget) {
case WID_AIC_GAMELIST:
- this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
- size->height = 1 * this->line_height;
+ this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM);
+ size->height = this->line_height;
break;
case WID_AIC_LIST:
- this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
+ this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM);
size->height = 8 * this->line_height;
break;
@@ -818,14 +819,14 @@ struct AIConfigWindow : public Window {
text = STR_JUST_RAW_STRING;
}
- DrawString(r.left + 10, r.right - 10, r.top + WD_MATRIX_TOP, text,
+ DrawString(r.left + 10, r.right - 10, Center(r.top, this->line_height), text,
(this->selected_slot == OWNER_DEITY) ? TC_WHITE : (IsEditable(OWNER_DEITY) ? TC_ORANGE : TC_SILVER));
break;
}
case WID_AIC_LIST: {
- int y = r.top;
+ int y = Center(r.top, this->line_height);
for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < MAX_COMPANIES; i++) {
StringID text;
@@ -837,7 +838,7 @@ struct AIConfigWindow : public Window {
} else {
text = STR_AI_CONFIG_RANDOM_AI;
}
- DrawString(r.left + 10, r.right - 10, y + WD_MATRIX_TOP, text,
+ DrawString(r.left + 10, r.right - 10, y, text,
(this->selected_slot == i) ? TC_WHITE : (IsEditable((CompanyID)i) ? TC_ORANGE : TC_SILVER));
y += this->line_height;
}
@@ -1090,7 +1091,7 @@ struct AIDebugWindow : public Window {
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
if (widget == WID_AID_LOG_PANEL) {
- resize->height = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
+ resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL);
size->height = 14 * resize->height + this->top_offset + this->bottom_offset;
}
}
@@ -1106,6 +1107,8 @@ struct AIDebugWindow : public Window {
bool dirty = false;
+ Dimension d = GetSpriteSize(SPR_COMPANY_ICON);
+ uint offset_y = Center(0, GetMinSizing(NWST_STEP, d.height + WD_MATRIX_TOP + WD_MATRIX_BOTTOM + 1), d.height);
/* Paint the company icons */
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
NWidgetCore *button = this->GetWidget(i + WID_AID_COMPANY_BUTTON_START);
@@ -1126,7 +1129,7 @@ struct AIDebugWindow : public Window {
if (!valid) continue;
byte offset = (i == ai_debug_company) ? 1 : 0;
- DrawCompanyIcon(i, button->pos_x + button->current_x / 2 - 7 + offset, this->GetWidget(WID_AID_COMPANY_BUTTON_START + i)->pos_y + 2 + offset);
+ DrawCompanyIcon(i, Center(button->pos_x + offset, button->current_x, d.width), button->pos_y + offset + offset_y);
}
/* Set button colour for Game Script. */
@@ -1205,7 +1208,7 @@ struct AIDebugWindow : public Window {
ScriptLog::LogData *log = this->GetLogPointer();
if (log == NULL) return;
- int y = this->top_offset;
+ int y = Center(this->top_offset, this->resize.step_height);
for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < log->used; i++) {
int pos = (i + log->pos + 1 - log->used + log->count) % log->count;
if (log->lines[pos] == NULL) break;
diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp
index 6437f236cd..14442408ce 100644
--- a/src/airport_gui.cpp
+++ b/src/airport_gui.cpp
@@ -28,6 +28,8 @@
#include "hotkeys.h"
#include "vehicle_func.h"
#include "gui.h"
+#include "command_func.h"
+#include "build_confirmation_func.h"
#include "widgets/airport_widget.h"
@@ -79,6 +81,7 @@ struct BuildAirToolbarWindow : Window {
~BuildAirToolbarWindow()
{
+ if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort();
if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
}
@@ -113,13 +116,13 @@ struct BuildAirToolbarWindow : Window {
}
}
-
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
switch (this->last_user_action) {
- case WID_AT_AIRPORT:
- PlaceAirport(tile);
+ case WID_AT_AIRPORT: {
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_STATION);
break;
+ }
case WID_AT_DEMOLISH:
PlaceProc_DemolishArea(tile);
@@ -127,6 +130,7 @@ struct BuildAirToolbarWindow : Window {
default: NOT_REACHED();
}
+ MoveAllWindowsOffScreen();
}
virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
@@ -136,17 +140,29 @@ struct BuildAirToolbarWindow : Window {
virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
{
- if (pt.x != -1 && select_proc == DDSP_DEMOLISH_AREA) {
- GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
+ if (pt.x == -1) return;
+ MoveAllHiddenWindowsBackToScreen();
+ switch (select_proc) {
+ case DDSP_BUILD_STATION:
+ assert(start_tile == end_tile);
+ PlaceAirport(end_tile);
+ break;
+ case DDSP_DEMOLISH_AREA:
+ GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
+ break;
+ default: NOT_REACHED();
}
}
virtual void OnPlaceObjectAbort()
{
+ MoveAllHiddenWindowsBackToScreen();
this->RaiseButtons();
-
- DeleteWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
- DeleteWindowById(WC_SELECT_STATION, 0);
+ if (!ConfirmationWindowShown()) {
+ DeleteWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
+ DeleteWindowById(WC_SELECT_STATION, 0);
+ }
+ ResetObjectToPlace();
}
static HotkeyList hotkeys;
@@ -204,7 +220,7 @@ Window *ShowBuildAirToolbar()
{
if (!Company::IsValidID(_local_company)) return NULL;
- DeleteWindowByClass(WC_BUILD_TOOLBAR);
+ DeleteToolbarLinkedWindows();
return AllocateWindowDescFront(&_air_toolbar_desc, TRANSPORT_AIR);
}
@@ -305,6 +321,7 @@ public:
d.width += padding.width;
d.height += padding.height;
*size = maxdim(*size, d);
+ size->height = GetMinSizing(NWST_STEP, size->height);
break;
}
@@ -316,7 +333,7 @@ public:
size->width = max(size->width, GetStringBoundingBox(as->name).width);
}
- this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
+ this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM);
size->height = 5 * this->line_height;
break;
}
@@ -368,7 +385,9 @@ public:
if (!as->IsAvailable()) {
GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->line_height - 2, 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(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, Center(y, this->line_height), as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK);
+
y += this->line_height;
}
break;
@@ -554,35 +573,41 @@ static const NWidgetPart _nested_build_airport_widgets[] = {
NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_AIRPORT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
EndContainer(),
- NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(1, 0), SetPIP(2, 0, 2),
- NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_AIRPORT_CLASS_LABEL, STR_NULL), SetFill(1, 0),
- NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_AP_CLASS_DROPDOWN), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_STATION_BUILD_AIRPORT_TOOLTIP),
- NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_AIRPORT_SPRITE), SetFill(1, 0),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_MATRIX, COLOUR_GREY, WID_AP_AIRPORT_LIST), SetFill(1, 0), SetMatrixDataTip(1, 5, STR_STATION_BUILD_AIRPORT_TOOLTIP), SetScrollbar(WID_AP_SCROLLBAR),
- NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_AP_SCROLLBAR),
+ NWidget(NWID_HORIZONTAL),
+ /* Airport dropdown selector and picture. */
+ NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(1, 0), SetPIP(2, 0, 2),
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetSizingType(NWST_STEP), SetDataTip(STR_STATION_BUILD_AIRPORT_CLASS_LABEL, STR_NULL), SetFill(1, 0),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_AP_CLASS_DROPDOWN), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_STATION_BUILD_AIRPORT_TOOLTIP),
+ NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_AIRPORT_SPRITE), SetFill(1, 0),
EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_AP_LAYOUT_DECREASE), SetMinimalSize(12, 0), SetDataTip(AWV_DECREASE, STR_NULL),
- NWidget(WWT_LABEL, COLOUR_GREY, WID_AP_LAYOUT_NUM), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NULL),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_AP_LAYOUT_INCREASE), SetMinimalSize(12, 0), SetDataTip(AWV_INCREASE, STR_NULL),
- EndContainer(),
- NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_EXTRA_TEXT), SetFill(1, 0), SetMinimalSize(150, 0),
- EndContainer(),
- /* Bottom panel. */
- NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_AP_BOTTOMPANEL), SetPIP(2, 2, 2),
- NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
- NWidget(NWID_HORIZONTAL),
- NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_AP_BTN_DONTHILIGHT), SetMinimalSize(60, 12), SetFill(1, 0),
- SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_AP_BTN_DOHILIGHT), SetMinimalSize(60, 12), SetFill(1, 0),
- SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
+ /* Airport parameters and info. */
+ NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(1, 0), SetPIP(2, 0, 2),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_MATRIX, COLOUR_GREY, WID_AP_AIRPORT_LIST), SetFill(1, 0), SetMatrixDataTip(1, 5, STR_STATION_BUILD_AIRPORT_TOOLTIP), SetScrollbar(WID_AP_SCROLLBAR),
+ NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_AP_SCROLLBAR),
EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_AP_LAYOUT_DECREASE), SetSizingType(NWST_STEP), SetMinimalSize(12, 0), SetDataTip(AWV_DECREASE, STR_NULL),
+ NWidget(WWT_LABEL, COLOUR_GREY, WID_AP_LAYOUT_NUM), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NULL),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_AP_LAYOUT_INCREASE), SetSizingType(NWST_STEP), SetMinimalSize(12, 0), SetDataTip(AWV_INCREASE, STR_NULL),
+ EndContainer(),
+ NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_EXTRA_TEXT), SetFill(1, 0), SetMinimalSize(150, 0),
+ EndContainer(),
+ /* Bottom panel. */
+ NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_AP_BOTTOMPANEL), SetPIP(2, 2, 2),
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_AP_BTN_DONTHILIGHT), SetMinimalSize(60, 12), SetFill(1, 0),
+ SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_AP_BTN_DOHILIGHT), SetMinimalSize(60, 12), SetFill(1, 0),
+ SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetResize(0, 1), SetFill(1, 0),
EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetResize(0, 1), SetFill(1, 0),
EndContainer(),
};
diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp
index 1074d1dd78..76fcf876ef 100644
--- a/src/autoreplace_gui.cpp
+++ b/src/autoreplace_gui.cpp
@@ -22,6 +22,7 @@
#include "window_gui.h"
#include "engine_gui.h"
#include "settings_func.h"
+#include "settings_gui.h"
#include "core/geometry_func.hpp"
#include "rail_gui.h"
#include "widgets/dropdown_func.h"
@@ -242,7 +243,7 @@ public:
switch (widget) {
case WID_RV_SORT_ASCENDING_DESCENDING: {
Dimension d = GetStringBoundingBox(this->GetWidget(widget)->widget_data);
- d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
+ d.width += padding.width + Window::SortButtonWidth();
d.height += padding.height;
*size = maxdim(*size, d);
break;
@@ -251,7 +252,7 @@ public:
case WID_RV_LEFT_MATRIX:
case WID_RV_RIGHT_MATRIX:
resize->height = GetEngineListHeight((VehicleType)this->window_number);
- size->height = (this->window_number <= VEH_ROAD ? 8 : 4) * resize->height;
+ size->height = (widget == WID_RV_RIGHT_MATRIX ? 3 : 4) * resize->height;
break;
case WID_RV_LEFT_DETAILS:
@@ -298,6 +299,7 @@ public:
d = maxdim(d, GetStringBoundingBox(rti->strings.replace_text));
}
d.width += padding.width;
+ d.width += SETTING_BUTTON_HEIGHT;
d.height += padding.height;
*size = maxdim(*size, d);
break;
@@ -309,6 +311,7 @@ public:
d = maxdim(d, GetStringBoundingBox(_start_replace_dropdown[i]));
}
d.width += padding.width;
+ d.width += SETTING_BUTTON_HEIGHT;
d.height += padding.height;
*size = maxdim(*size, d);
break;
@@ -376,7 +379,7 @@ public:
str = STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED;
}
- DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_BLACK, SA_HOR_CENTER);
+ DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, Center(r.top + WD_FRAMERECT_TOP, r.bottom - r.top - WD_FRAMERECT_TOP), str, TC_BLACK, SA_HOR_CENTER);
break;
}
@@ -598,33 +601,27 @@ static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_RAILTYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0),
- NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_REPLACE_ENGINE_WAGON_SELECT_HELP),
+ NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR),
+ NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_LEFT_SCROLLBAR),
EndContainer(),
- NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(),
EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), SetFill(1, 1),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetDataTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
EndContainer(),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetDataTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP),
- NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
+ NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR),
+ NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_RIGHT_SCROLLBAR),
+ EndContainer(),
+ NWidget(NWID_VERTICAL),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_TRAIN_WAGONREMOVE_TOGGLE), SetMinimalSize(138, 12), SetDataTip(STR_REPLACE_REMOVE_WAGON, STR_REPLACE_REMOVE_WAGON_HELP), SetFill(1, 0), SetResize(1, 0),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_RAILTYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_REPLACE_ENGINE_WAGON_SELECT_HELP),
EndContainer(),
- EndContainer(),
- EndContainer(),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
- NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR),
- NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_LEFT_SCROLLBAR),
- NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR),
- NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_RIGHT_SCROLLBAR),
- EndContainer(),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(),
- NWidget(NWID_VERTICAL),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_TRAIN_WAGONREMOVE_TOGGLE), SetMinimalSize(138, 12), SetDataTip(STR_REPLACE_REMOVE_WAGON, STR_REPLACE_REMOVE_WAGON_HELP), SetFill(1, 0), SetResize(1, 0),
EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL),
@@ -660,28 +657,26 @@ static const NWidgetPart _nested_replace_vehicle_widgets[] = {
EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
- NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
+ NWidget(NWID_VERTICAL),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR),
+ NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_LEFT_SCROLLBAR),
+ EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(228, 92), SetResize(1, 0), EndContainer(),
+ EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetDataTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
EndContainer(),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetDataTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP),
- NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
+ NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR),
+ NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_RIGHT_SCROLLBAR),
EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(228, 92), SetResize(1, 0), EndContainer(),
EndContainer(),
EndContainer(),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
- NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR),
- NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_LEFT_SCROLLBAR),
- NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR),
- NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_RIGHT_SCROLLBAR),
- EndContainer(),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(228, 92), SetResize(1, 0), EndContainer(),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(228, 92), SetResize(1, 0), EndContainer(),
- EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_PUSHBUTTON_DROPDOWN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetDataTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON),
NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_INFO_TAB), SetMinimalSize(167, 12), SetDataTip(0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB), SetResize(1, 0), EndContainer(),
diff --git a/src/blitter/16bpp_anim.cpp b/src/blitter/16bpp_anim.cpp
new file mode 100644
index 0000000000..115ffe9df5
--- /dev/null
+++ b/src/blitter/16bpp_anim.cpp
@@ -0,0 +1,386 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/** @file 16bpp_anim.cpp Implementation of the optimized 32 bpp blitter with animation support. */
+
+#include "../stdafx.h"
+#include "../video/video_driver.hpp"
+#include "../zoom_func.h"
+#include "16bpp_anim.hpp"
+
+#include "../table/sprites.h"
+
+/** Instantiation of the 16bpp with animation blitter factory. */
+static FBlitter_16bppAnim iFBlitter_16bppAnim;
+
+template
+void Blitter_16bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom)
+{
+ const Pixel *src, *src_line;
+ Colour16 *dst, *dst_line;
+ Anim *anim, *anim_line;
+
+ /* Find where to start reading in the source sprite */
+ src_line = (const Pixel *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
+ dst_line = (Colour16 *)bp->dst + bp->top * bp->pitch + bp->left;
+ anim_line = this->anim_buf + ((Colour16 *)bp->dst - (Colour16 *)_screen.dst_ptr) + bp->top * this->anim_buf_width + bp->left;
+
+ for (int y = 0; y < bp->height; y++) {
+ dst = dst_line;
+ dst_line += bp->pitch;
+
+ src = src_line;
+ src_line += bp->sprite_width * ScaleByZoom(1, zoom);
+
+ anim = anim_line;
+ anim_line += this->anim_buf_width;
+
+ for (int x = 0; x < bp->width; x++) {
+ switch (mode) {
+ case BM_COLOUR_REMAP:
+ /* In case the m-channel is zero, do not remap this pixel in any way */
+ anim->m = 0;
+ anim->v = 0;
+ if (src->m == 0) {
+ if (src->a != 0) *dst = ComposeColourPA(src->c, src->a, *dst);
+ } else {
+ uint8 r = bp->remap[src->m];
+ if (r != 0) {
+ *dst = ComposeColourPA(AdjustBrightness(LookupColourInPalette(r), src->v), src->a, *dst);
+ if (src->a == 15 && r >= PALETTE_ANIM_START) {
+ anim->m = r - PALETTE_ANIM_START + 1;
+ anim->v = src->v >> 1;
+ }
+ }
+ }
+ break;
+
+ case BM_TRANSPARENT:
+ /* TODO -- We make an assumption here that the remap in fact is transparency, not some colour.
+ * This is never a problem with the code we produce, but newgrfs can make it fail... or at least:
+ * we produce a result the newgrf maker didn't expect ;) */
+
+ /* Make the current colour a bit more black, so it looks like this image is transparent */
+ if (src->a != 0) *dst = MakeTransparent(*dst, 192);
+ anim->m = 0;
+ anim->v = 0;
+ break;
+
+ default:
+ if (src->a == 15 && src->m >= PALETTE_ANIM_START) {
+ *dst = AdjustBrightness(LookupColourInPalette(src->m), src->v);
+ anim->m = src->m - PALETTE_ANIM_START + 1;
+ anim->v = src->v >> 1;
+ } else {
+ if (src->a != 0) {
+ if (src->m >= PALETTE_ANIM_START) {
+ *dst = ComposeColourPANoCheck(AdjustBrightness(LookupColourInPalette(src->m), src->v), src->a, *dst);
+ } else {
+ *dst = ComposeColourPA(src->c, src->a, *dst);
+ }
+ }
+ anim->m = 0;
+ anim->v = 0;
+ }
+ break;
+ }
+ dst++;
+ src += ScaleByZoom(1, zoom);
+ }
+ }
+}
+
+void Blitter_16bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
+{
+ if (_screen_disable_anim) {
+ /* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent Draw() */
+ Blitter_16bppOptimized::Draw(bp, mode, zoom);
+ return;
+ }
+
+ switch (mode) {
+ default: NOT_REACHED();
+ case BM_NORMAL: Draw (bp, zoom); return;
+ case BM_COLOUR_REMAP: Draw(bp, zoom); return;
+ case BM_TRANSPARENT: Draw (bp, zoom); return;
+ }
+}
+
+void Blitter_16bppAnim::DrawColourMappingRect(void *dst, int width, int height, PaletteID pal)
+{
+ if (_screen_disable_anim) {
+ /* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent DrawColourMappingRect() */
+ Blitter_16bppOptimized::DrawColourMappingRect(dst, width, height, pal);
+ return;
+ }
+
+ Colour16 *udst = (Colour16 *)dst;
+ Anim *anim;
+
+ anim = this->anim_buf + ((Colour16 *)dst - (Colour16 *)_screen.dst_ptr);
+
+ if (pal == PALETTE_TO_TRANSPARENT) {
+ do {
+ for (int i = 0; i != width; i++) {
+ *udst = MakeTransparent(*udst, 154);
+ anim->m = 0;
+ anim->v = 0;
+ udst++;
+ anim++;
+ }
+ udst = udst - width + _screen.pitch;
+ anim = anim - width + this->anim_buf_width;
+ } while (--height);
+ return;
+ }
+ if (pal == PALETTE_NEWSPAPER) {
+ do {
+ for (int i = 0; i != width; i++) {
+ *udst = MakeGrey(*udst);
+ anim->m = 0;
+ anim->v = 0;
+ udst++;
+ anim++;
+ }
+ udst = udst - width + _screen.pitch;
+ anim = anim - width + this->anim_buf_width;
+ } while (--height);
+ return;
+ }
+
+ DEBUG(misc, 0, "16bpp blitter doesn't know how to draw this colour table ('%d')", pal);
+}
+
+void Blitter_16bppAnim::SetPixel(void *video, int x, int y, uint8 colour)
+{
+ *((Colour16 *)video + x + y * _screen.pitch) = LookupColourInPalette(colour);
+
+ /* Set the colour in the anim-buffer too, if we are rendering to the screen */
+ if (_screen_disable_anim) return;
+ Anim *anim = this->anim_buf + ((Colour16 *)video - (Colour16 *)_screen.dst_ptr) + x + y * this->anim_buf_width;
+ if (colour >= PALETTE_ANIM_START) {
+ anim->m = colour - PALETTE_ANIM_START + 1;
+ anim->v = DEFAULT_BRIGHTNESS >> 1;
+ } else {
+ anim->m = 0;
+ anim->v = 0;
+ }
+}
+
+void Blitter_16bppAnim::DrawRect(void *video, int width, int height, uint8 colour)
+{
+ if (_screen_disable_anim) {
+ /* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent DrawRect() */
+ Blitter_16bppOptimized::DrawRect(video, width, height, colour);
+ return;
+ }
+
+ Colour16 colour16 = LookupColourInPalette(colour);
+ Anim *anim_line = this->anim_buf + ((Colour16 *)video - (Colour16 *)_screen.dst_ptr);
+
+ do {
+ Colour16 *dst = (Colour16 *)video;
+ Anim *anim = anim_line;
+
+ for (int i = width; i > 0; i--) {
+ *dst = colour16;
+ /* Set the colour in the anim-buffer too */
+ if (colour >= PALETTE_ANIM_START) {
+ anim->m = colour - PALETTE_ANIM_START + 1;
+ anim->v = DEFAULT_BRIGHTNESS >> 1;
+ } else {
+ anim->m = 0;
+ anim->v = 0;
+ }
+ dst++;
+ anim++;
+ }
+ video = (Colour16 *)video + _screen.pitch;
+ anim_line += this->anim_buf_width;
+ } while (--height);
+}
+
+void Blitter_16bppAnim::CopyFromBuffer(void *video, const void *src, int width, int height)
+{
+ assert(!_screen_disable_anim);
+ assert(video >= _screen.dst_ptr && video <= (Colour16 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
+ Colour16 *dst = (Colour16 *)video;
+ const uint8 *usrc = (const uint8 *)src;
+ Anim *anim_line = this->anim_buf + ((Colour16 *)video - (Colour16 *)_screen.dst_ptr);
+
+ for (; height > 0; height--) {
+ /* We need to keep those for palette animation. */
+ Colour16 *dst_pal = dst;
+ Anim *anim_pal = anim_line;
+
+ memcpy(dst, usrc, width * sizeof(Colour16));
+ usrc += width * sizeof(Colour16);
+ dst += _screen.pitch;
+ /* Copy back the anim-buffer */
+ memcpy(anim_line, usrc, width * sizeof(Anim));
+ usrc += width * sizeof(Anim);
+ anim_line += this->anim_buf_width;
+
+ /* Okay, it is *very* likely that the image we stored is using
+ * the wrong palette animated colours. There are two things we
+ * can do to fix this. The first is simply reviewing the whole
+ * screen after we copied the buffer, i.e. run PaletteAnimate,
+ * however that forces a full screen redraw which is expensive
+ * for just the cursor. This just copies the implementation of
+ * palette animation, much cheaper though slightly nastier. */
+ for (int i = 0; i < width; i++) {
+ uint8 colour = anim_pal->m;
+ if (colour) {
+ /* Update this pixel */
+ *dst_pal = AdjustBrightness(LookupColourInPalette(colour + PALETTE_ANIM_START - 1), anim_pal->v << 1);
+ }
+ dst_pal++;
+ anim_pal++;
+ }
+ }
+}
+
+void Blitter_16bppAnim::CopyToBuffer(const void *video, void *dst, int width, int height)
+{
+ assert(!_screen_disable_anim);
+ assert(video >= _screen.dst_ptr && video <= (Colour16 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
+ uint8 *udst = (uint8 *)dst;
+ const Colour16 *src = (const Colour16 *)video;
+ const Anim *anim_line = this->anim_buf + ((const Colour16 *)video - (Colour16 *)_screen.dst_ptr);
+
+ for (; height > 0; height--) {
+ memcpy(udst, src, width * sizeof(Colour16));
+ src += _screen.pitch;
+ udst += width * sizeof(Colour16);
+ /* Copy the anim-buffer */
+ memcpy(udst, anim_line, width * sizeof(Anim));
+ udst += width * sizeof(Anim);
+ anim_line += this->anim_buf_width;
+ }
+}
+
+void Blitter_16bppAnim::ScrollBuffer(void *video, int &left_ref, int &top_ref, int &width_ref, int &height_ref, int scroll_x, int scroll_y)
+{
+ assert(!_screen_disable_anim);
+ assert(video >= _screen.dst_ptr && video <= (Colour16 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
+ const Anim *src;
+ Anim *dst;
+ int left = left_ref, top = top_ref, width = width_ref, height = height_ref;
+
+ /* We need to scroll the anim-buffer too */
+ if (scroll_y > 0) {
+ /* Calculate pointers */
+ dst = this->anim_buf + left + (top + height - 1) * this->anim_buf_width;
+ src = dst - scroll_y * this->anim_buf_width;
+
+ /* Decrease height and increase top */
+ top += scroll_y;
+ height -= scroll_y;
+ assert(height > 0);
+
+ /* Adjust left & width */
+ if (scroll_x >= 0) {
+ dst += scroll_x;
+ left += scroll_x;
+ width -= scroll_x;
+ } else {
+ src -= scroll_x;
+ width += scroll_x;
+ }
+
+ for (int h = height; h > 0; h--) {
+ memcpy(dst, src, width * sizeof(Anim));
+ src -= this->anim_buf_width;
+ dst -= this->anim_buf_width;
+ }
+ } else {
+ /* Calculate pointers */
+ dst = this->anim_buf + left + top * this->anim_buf_width;
+ src = dst - scroll_y * this->anim_buf_width;
+
+ /* Decrease height. (scroll_y is <=0). */
+ height += scroll_y;
+ assert(height > 0);
+
+ /* Adjust left & width */
+ if (scroll_x >= 0) {
+ dst += scroll_x;
+ left += scroll_x;
+ width -= scroll_x;
+ } else {
+ src -= scroll_x;
+ width += scroll_x;
+ }
+
+ /* the y-displacement may be 0 therefore we have to use memmove,
+ * because source and destination may overlap */
+ for (int h = height; h > 0; h--) {
+ memmove(dst, src, width * sizeof(Anim));
+ src += _screen.pitch;
+ dst += _screen.pitch;
+ }
+ }
+
+ Blitter_16bppOptimized::ScrollBuffer(video, left_ref, top_ref, width_ref, height_ref, scroll_x, scroll_y);
+}
+
+int Blitter_16bppAnim::BufferSize(int width, int height)
+{
+ return width * height * (sizeof(Anim) + sizeof(Colour16));
+}
+
+void Blitter_16bppAnim::PaletteAnimate(const Palette &palette)
+{
+ assert(!_screen_disable_anim);
+
+ /* If first_dirty is 0, it is for 8bpp indication to send the new
+ * palette. However, only the animation colours might possibly change.
+ * Especially when going between toyland and non-toyland. */
+ assert(palette.first_dirty == PALETTE_ANIM_START || palette.first_dirty == 0);
+
+ for (int i = 0; i < 256; i++) {
+ this->palette[i] = To16(palette.palette[i]);
+ }
+
+ const Anim *anim = this->anim_buf;
+ Colour16 *dst = (Colour16 *)_screen.dst_ptr;
+
+ /* Let's walk the anim buffer and try to find the pixels */
+ for (int y = this->anim_buf_height; y != 0 ; y--) {
+ for (int x = this->anim_buf_width; x != 0 ; x--) {
+ uint8 colour = anim->m;
+ if (colour) {
+ /* Update this pixel */
+ *dst = AdjustBrightness(LookupColourInPalette(colour + PALETTE_ANIM_START - 1), anim->v << 1);
+ }
+ dst++;
+ anim++;
+ }
+ dst += _screen.pitch - this->anim_buf_width;
+ }
+
+ /* Make sure the backend redraws the whole screen */
+ VideoDriver::GetInstance()->MakeDirty(0, 0, _screen.width, _screen.height);
+}
+
+Blitter::PaletteAnimation Blitter_16bppAnim::UsePaletteAnimation()
+{
+ return Blitter::PALETTE_ANIMATION_BLITTER;
+}
+
+void Blitter_16bppAnim::PostResize()
+{
+ if (_screen.width != this->anim_buf_width || _screen.height != this->anim_buf_height) {
+ /* The size of the screen changed; we can assume we can wipe all data from our buffer */
+ free(this->anim_buf);
+ this->anim_buf = CallocT(_screen.width * _screen.height);
+ this->anim_buf_width = _screen.width;
+ this->anim_buf_height = _screen.height;
+ }
+}
diff --git a/src/blitter/16bpp_anim.hpp b/src/blitter/16bpp_anim.hpp
new file mode 100644
index 0000000000..80bf6e5df5
--- /dev/null
+++ b/src/blitter/16bpp_anim.hpp
@@ -0,0 +1,75 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/** @file 16bpp_anim.hpp A 16 bpp blitter with animation support. */
+
+#ifndef BLITTER_16BPP_ANIM_HPP
+#define BLITTER_16BPP_ANIM_HPP
+
+#include "16bpp_simple.hpp"
+
+class Blitter_16bppOptimized: public Blitter_16bppSimple {
+ // TODO: implement that
+};
+
+/** The optimised 16 bpp blitter with palette animation. */
+class Blitter_16bppAnim : public Blitter_16bppOptimized {
+protected:
+ // PALETTE_ANIM_SIZE is less than 32, so we'll use 5 bits for color index, and 3 bits for brightness, losing 1 bit compared to struct Pixel
+ struct Anim {
+ unsigned m : 5 __attribute__((packed)); ///< Color index channel, packed 5 bits, 0 = no animation, 1 = PALETTE_ANIM_START
+ unsigned v : 3 __attribute__((packed)); ///< Brightness-channel, packed 3 bits
+ };
+
+ Anim *anim_buf; ///< In this buffer we keep track of the 8bpp indexes so we can do palette animation
+ int anim_buf_width; ///< The width of the animation buffer.
+ int anim_buf_height; ///< The height of the animation buffer.
+ Colour16 palette[256]; ///< The current palette.
+
+public:
+ Blitter_16bppAnim() :
+ anim_buf(NULL),
+ anim_buf_width(0),
+ anim_buf_height(0)
+ {}
+
+ /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
+ /* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal);
+ /* virtual */ void SetPixel(void *video, int x, int y, uint8 colour);
+ /* virtual */ void DrawRect(void *video, int width, int height, uint8 colour);
+ /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height);
+ /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height);
+ /* virtual */ void ScrollBuffer(void *video, int &left_ref, int &top_ref, int &width_ref, int &height_ref, int scroll_x, int scroll_y);
+ /* virtual */ int BufferSize(int width, int height);
+ /* virtual */ void PaletteAnimate(const Palette &palette);
+ /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation();
+ /* virtual */ int GetBytesPerPixel() { return 3; }
+
+ /* virtual */ const char *GetName() { return "16bpp-anim"; }
+ /* virtual */ void PostResize();
+
+ /**
+ * Look up the colour in the current palette.
+ */
+ inline Colour16 LookupColourInPalette(uint8 index)
+ {
+ return this->palette[index];
+ }
+
+ template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
+};
+
+/** Factory for the 16bpp blitter with animation. */
+class FBlitter_16bppAnim : public BlitterFactory {
+public:
+ FBlitter_16bppAnim() : BlitterFactory("16bpp-anim-broken", "16bpp Animation Blitter, currently broken (palette animation)") {}
+ /* virtual */ Blitter *CreateInstance() { return new Blitter_16bppAnim(); }
+};
+
+#endif /* BLITTER_16BPP_ANIM_HPP */
diff --git a/src/blitter/16bpp_base.cpp b/src/blitter/16bpp_base.cpp
new file mode 100644
index 0000000000..9161ce92c4
--- /dev/null
+++ b/src/blitter/16bpp_base.cpp
@@ -0,0 +1,147 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/** @file 16bpp_base.cpp Implementation of base for 32 bpp blitters. */
+
+#include "../stdafx.h"
+#include "16bpp_base.hpp"
+
+void *Blitter_16bppBase::MoveTo(void *video, int x, int y)
+{
+ return (uint16 *)video + x + y * _screen.pitch;
+}
+
+void Blitter_16bppBase::SetPixel(void *video, int x, int y, uint8 colour)
+{
+ *((Colour16 *)video + x + y * _screen.pitch) = LookupColourInPalette(colour);
+}
+
+void Blitter_16bppBase::DrawRect(void *video, int width, int height, uint8 colour)
+{
+ Colour16 target = LookupColourInPalette(colour);
+
+ do {
+ Colour16 *dst = (Colour16 *)video;
+ for (int i = width; i > 0; i--) {
+ *dst = target;
+ dst++;
+ }
+ video = (uint16 *)video + _screen.pitch;
+ } while (--height);
+}
+
+void Blitter_16bppBase::CopyFromBuffer(void *video, const void *src, int width, int height)
+{
+ uint16 *dst = (uint16 *)video;
+ const uint16 *usrc = (const uint16 *)src;
+
+ for (; height > 0; height--) {
+ memcpy(dst, usrc, width * sizeof(uint16));
+ usrc += width;
+ dst += _screen.pitch;
+ }
+}
+
+void Blitter_16bppBase::CopyToBuffer(const void *video, void *dst, int width, int height)
+{
+ uint16 *udst = (uint16 *)dst;
+ const uint16 *src = (const uint16 *)video;
+
+ for (; height > 0; height--) {
+ memcpy(udst, src, width * sizeof(uint16));
+ src += _screen.pitch;
+ udst += width;
+ }
+}
+
+void Blitter_16bppBase::CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch)
+{
+ uint16 *udst = (uint16 *)dst;
+ const uint16 *src = (const uint16 *)video;
+
+ for (; height > 0; height--) {
+ memcpy(udst, src, width * sizeof(uint16));
+ src += _screen.pitch;
+ udst += dst_pitch;
+ }
+}
+
+void Blitter_16bppBase::ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y)
+{
+ const Colour16 *src;
+ Colour16 *dst;
+
+ if (scroll_y > 0) {
+ /* Calculate pointers */
+ dst = (Colour16 *)video + left + (top + height - 1) * _screen.pitch;
+ src = dst - scroll_y * _screen.pitch;
+
+ /* Decrease height and increase top */
+ top += scroll_y;
+ height -= scroll_y;
+ assert(height > 0);
+
+ /* Adjust left & width */
+ if (scroll_x >= 0) {
+ dst += scroll_x;
+ left += scroll_x;
+ width -= scroll_x;
+ } else {
+ src -= scroll_x;
+ width += scroll_x;
+ }
+
+ for (int h = height; h > 0; h--) {
+ memcpy(dst, src, width * sizeof(Colour16));
+ src -= _screen.pitch;
+ dst -= _screen.pitch;
+ }
+ } else {
+ /* Calculate pointers */
+ dst = (Colour16 *)video + left + top * _screen.pitch;
+ src = dst - scroll_y * _screen.pitch;
+
+ /* Decrease height. (scroll_y is <=0). */
+ height += scroll_y;
+ assert(height > 0);
+
+ /* Adjust left & width */
+ if (scroll_x >= 0) {
+ dst += scroll_x;
+ left += scroll_x;
+ width -= scroll_x;
+ } else {
+ src -= scroll_x;
+ width += scroll_x;
+ }
+
+ /* the y-displacement may be 0 therefore we have to use memmove,
+ * because source and destination may overlap */
+ for (int h = height; h > 0; h--) {
+ memmove(dst, src, width * sizeof(Colour16));
+ src += _screen.pitch;
+ dst += _screen.pitch;
+ }
+ }
+}
+
+int Blitter_16bppBase::BufferSize(int width, int height)
+{
+ return width * height * sizeof(Colour16);
+}
+
+void Blitter_16bppBase::PaletteAnimate(const Palette &palette)
+{
+ /* By default, 16bpp doesn't have palette animation */
+}
+
+Blitter::PaletteAnimation Blitter_16bppBase::UsePaletteAnimation()
+{
+ return Blitter::PALETTE_ANIMATION_NONE;
+}
diff --git a/src/blitter/16bpp_base.hpp b/src/blitter/16bpp_base.hpp
new file mode 100644
index 0000000000..c4d63b0bd4
--- /dev/null
+++ b/src/blitter/16bpp_base.hpp
@@ -0,0 +1,225 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/** @file 16bpp_base.hpp Base for all 16 bits blitters. */
+
+#ifndef BLITTER_16BPP_BASE_HPP
+#define BLITTER_16BPP_BASE_HPP
+
+#include "base.hpp"
+#include "../core/bitmath_func.hpp"
+#include "../core/math_func.hpp"
+#include "../gfx_func.h"
+
+/** Base for all 16bpp blitters. */
+class Blitter_16bppBase : public Blitter {
+public:
+
+ // TODO: GCC-specific attributes
+ struct Colour16 {
+ unsigned b : 5 __attribute__((packed)); ///< Blue-channel, packed 5 bits
+ unsigned g : 6 __attribute__((packed)); ///< Green-channel, packed 6 bits
+ unsigned r : 5 __attribute__((packed)); ///< Red-channel, packed 5 bits
+ Colour16(uint8 r = 0, uint8 g = 0, uint8 b = 0):
+ b(b), g(g), r(r)
+ {
+ }
+ };
+
+ struct Pixel {
+ Colour16 c;
+ unsigned a : 4 __attribute__((packed)); ///< Alpha-channel, packed 4 bits
+ unsigned v : 4 __attribute__((packed)); ///< Brightness-channel, packed 4 bits
+ unsigned m : 8 __attribute__((packed)); ///< Remap-channel, cannot pack it, because it's palette lookup index, so it must be in range 0-255
+ };
+
+ /* virtual */ uint8 GetScreenDepth() { return 16; }
+ /* virtual */ void *MoveTo(void *video, int x, int y);
+ /* virtual */ void SetPixel(void *video, int x, int y, uint8 colour);
+ /* virtual */ void DrawRect(void *video, int width, int height, uint8 colour);
+ /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height);
+ /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height);
+ /* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch);
+ /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y);
+ /* virtual */ int BufferSize(int width, int height);
+ /* virtual */ void PaletteAnimate(const Palette &palette);
+ /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation();
+ /* virtual */ int GetBytesPerPixel() { return 2; }
+
+
+ /**
+ * Convert from rgb values to screen native 16bpp colour
+ */
+ static inline Colour16 To16(uint8 r, uint8 g, uint8 b)
+ {
+ return Colour16(r >> 3, g >> 2, b >> 3);
+ }
+
+ /**
+ * Convert from 32bpp colour to screen native 16bpp colour
+ */
+ static inline Colour16 To16(Colour c)
+ {
+ return To16(c.r, c.g, c.b);
+ }
+
+ /**
+ * Look up the colour in the current palette.
+ */
+ static inline Colour LookupColourInPalette32(uint index)
+ {
+ return _cur_palette.palette[index];
+ }
+
+ /**
+ * Look up the colour in the current palette.
+ */
+ static inline Colour16 LookupColourInPalette(uint index)
+ {
+ return To16(LookupColourInPalette32(index));
+ }
+
+ /**
+ * Compose a colour based on RGBA values and the current pixel value.
+ * @param r range is from 0 to 31.
+ * @param g range is from 0 to 63.
+ * @param b range is from 0 to 31.
+ * @param a range is from 0 to 15.
+ */
+ static inline Colour16 ComposeColourRGBANoCheck(uint8 r, uint8 g, uint8 b, uint8 a, Colour16 current)
+ {
+ /* The 16 is wrong, it should be 15, but 16 is much faster... */
+ return Colour16 ( ((int)(r - current.r) * a) / 16 + current.r,
+ ((int)(g - current.g) * a) / 16 + current.g,
+ ((int)(b - current.b) * a) / 16 + current.b );
+ }
+
+ /**
+ * Compose a colour based on RGBA values and the current pixel value.
+ * Handles fully transparent and solid pixels in a special (faster) way.
+ * @param r range is from 0 to 31.
+ * @param g range is from 0 to 63.
+ * @param b range is from 0 to 31.
+ * @param a range is from 0 to 15.
+ */
+ static inline Colour16 ComposeColourRGBA(uint8 r, uint8 g, uint8 b, uint8 a, Colour16 current)
+ {
+ if (a == 0) return current;
+ if (a >= 15) return Colour16(r, g, b);
+
+ return ComposeColourRGBANoCheck(r, g, b, a, current);
+ }
+
+ /**
+ * Compose a colour based on Pixel value, alpha value, and the current pixel value.
+ * @param a range is from 0 to 16.
+ */
+ static inline Colour16 ComposeColourPANoCheck(Colour16 colour, uint8 a, Colour16 current)
+ {
+ return ComposeColourRGBANoCheck(colour.r, colour.g, colour.b, a, current);
+ }
+
+ /**
+ * Compose a colour based on Pixel value, alpha value, and the current pixel value.
+ * Handles fully transparent and solid pixels in a special (faster) way.
+ * @param a range is from 0 to 15.
+ */
+ static inline Colour16 ComposeColourPA(Colour16 colour, uint8 a, Colour16 current)
+ {
+ if (a == 0) return current;
+ if (a >= 15) return colour;
+
+ return ComposeColourPANoCheck(colour, a, current);
+ }
+
+ /**
+ * Make a pixel looks like it is transparent.
+ * @param colour the colour already on the screen.
+ * @param nom the amount of transparency, nominator, makes colour lighter.
+ * @param denom denominator, makes colour darker.
+ * @return the new colour for the screen.
+ */
+ static inline Colour16 MakeTransparent(Colour16 colour, uint nom, uint denom = 256)
+ {
+ uint r = colour.r;
+ uint g = colour.g;
+ uint b = colour.b;
+
+ return Colour16( r * nom / denom,
+ g * nom / denom,
+ b * nom / denom );
+ }
+
+ /**
+ * Make a colour grey - based.
+ * @param colour the colour to make grey.
+ * @return the new colour, now grey.
+ */
+ static inline Colour16 MakeGrey(Colour16 colour)
+ {
+ uint8 r = colour.r;
+ uint8 g = colour.g;
+ uint8 b = colour.b;
+
+ /* To avoid doubles and stuff, multiple it with a total of 65536 (16bits), then
+ * divide by it to normalize the value to a byte again. See heightmap.cpp for
+ * information about the formula. */
+ uint grey = (((r << 3) * 19595) + ((g << 2) * 38470) + ((b << 3) * 7471)) / 65536;
+
+ return To16(grey, grey, grey);
+ }
+
+ /**
+ * Make a colour dark grey, for specialized 32bpp remapping.
+ * @param r red component
+ * @param g green component
+ * @param b blue component
+ * @return the brightness value of the new colour, now dark grey.
+ */
+ static inline uint8 MakeDark(Colour16 colour)
+ {
+ uint8 r = colour.r;
+ uint8 g = colour.g;
+ uint8 b = colour.b;
+
+ /* Magic-numbers are ~66% of those used in MakeGrey() */
+ return (((r << 3) * 13063) + ((g << 2) * 25647) + ((b << 3) * 4981)) / 65536;
+ }
+
+ enum { DEFAULT_BRIGHTNESS = 8 };
+
+ /**
+ * @param brightness range is from 0 to 15.
+ */
+ static inline Colour16 AdjustBrightness(Colour16 colour, uint8 brightness)
+ {
+ /* Shortcut for normal brightness */
+ if (brightness == DEFAULT_BRIGHTNESS) return colour;
+
+ uint16 ob = 0;
+ uint16 r = colour.r * brightness / DEFAULT_BRIGHTNESS;
+ uint16 g = colour.g * brightness / DEFAULT_BRIGHTNESS;
+ uint16 b = colour.b * brightness / DEFAULT_BRIGHTNESS;
+
+ /* Sum overbright */
+ if (r > 31) ob += r - 31;
+ if (g > 63) ob += g - 63;
+ if (b > 31) ob += b - 31;
+
+ if (ob == 0) return Colour16(r, g, b);
+
+ /* Reduce overbright strength */
+ ob /= 2;
+ return Colour16( r >= 31 ? 31 : min(r + ob * (31 - r) / 32, 31),
+ g >= 63 ? 63 : min(g + ob * (63 - g) / 64, 63),
+ b >= 31 ? 31 : min(b + ob * (31 - b) / 32, 31) );
+ }
+};
+
+#endif /* BLITTER_16BPP_BASE_HPP */
diff --git a/src/blitter/16bpp_simple.cpp b/src/blitter/16bpp_simple.cpp
new file mode 100644
index 0000000000..fc0e83fff3
--- /dev/null
+++ b/src/blitter/16bpp_simple.cpp
@@ -0,0 +1,173 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/** @file 32bpp_simple.cpp Implementation of the simple 32 bpp blitter. */
+
+#include "../stdafx.h"
+#include "../zoom_func.h"
+#include "16bpp_simple.hpp"
+
+#include "../table/sprites.h"
+
+/** Instantiation of the simple 16bpp blitter factory. */
+static FBlitter_16bppSimple iFBlitter_16bppSimple;
+
+template
+void Blitter_16bppSimple::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom)
+{
+ const Pixel *src, *src_line;
+ Colour16 *dst, *dst_line;
+
+ /* Find where to start reading in the source sprite */
+ src_line = (const Pixel *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
+ dst_line = (Colour16 *)bp->dst + bp->top * bp->pitch + bp->left;
+
+ for (int y = 0; y < bp->height; y++) {
+ dst = dst_line;
+ dst_line += bp->pitch;
+
+ src = src_line;
+ src_line += bp->sprite_width * ScaleByZoom(1, zoom);
+
+ for (int x = 0; x < bp->width; x++) {
+ switch (mode) {
+ case BM_COLOUR_REMAP:
+ /* In case the m-channel is zero, do not remap this pixel in any way */
+ if (src->m == 0) {
+ if (src->a != 0) *dst = ComposeColourPA(src->c, src->a, *dst);
+ } else {
+ if (bp->remap[src->m] != 0) *dst = ComposeColourPA(AdjustBrightness(LookupColourInPalette(bp->remap[src->m]), src->v), src->a, *dst);
+ }
+ break;
+
+ case BM_CRASH_REMAP:
+ if (src->m == 0) {
+ if (src->a != 0) {
+ uint8 g = MakeDark(src->c);
+ *dst = ComposeColourRGBA(g, g, g, src->a, *dst);
+ }
+ } else {
+ if (bp->remap[src->m] != 0) *dst = ComposeColourPA(AdjustBrightness(LookupColourInPalette(bp->remap[src->m]), src->v), src->a, *dst);
+ }
+ break;
+
+ case BM_TRANSPARENT:
+ /* TODO -- We make an assumption here that the remap in fact is transparency, not some colour.
+ * This is never a problem with the code we produce, but newgrfs can make it fail... or at least:
+ * we produce a result the newgrf maker didn't expect ;) */
+
+ /* Make the current colour a bit more black, so it looks like this image is transparent */
+ if (src->a != 0) *dst = MakeTransparent(*dst, 192);
+ break;
+
+ case BM_BLACK_REMAP:
+ if (src->a != 0) {
+ *dst = Colour16(0, 0, 0);
+ }
+ break;
+
+ default:
+ if (src->a != 0) *dst = ComposeColourPA(src->c, src->a, *dst);
+ break;
+ }
+ dst++;
+ src += ScaleByZoom(1, zoom);
+ }
+ }
+}
+
+void Blitter_16bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
+{
+ switch (mode) {
+ default: NOT_REACHED();
+ case BM_NORMAL: Draw (bp, zoom); return;
+ case BM_COLOUR_REMAP: Draw(bp, zoom); return;
+ case BM_TRANSPARENT: Draw (bp, zoom); return;
+ case BM_CRASH_REMAP: Draw (bp, zoom); return;
+ case BM_BLACK_REMAP: Draw (bp, zoom); return;
+ }
+}
+
+void Blitter_16bppSimple::DrawColourMappingRect(void *dst, int width, int height, PaletteID pal)
+{
+ Colour16 *udst = (Colour16 *)dst;
+
+ if (pal == PALETTE_TO_TRANSPARENT) {
+ do {
+ for (int i = 0; i != width; i++) {
+ *udst = MakeTransparent(*udst, 154);
+ udst++;
+ }
+ udst = udst - width + _screen.pitch;
+ } while (--height);
+ return;
+ }
+ if (pal == PALETTE_NEWSPAPER) {
+ do {
+ for (int i = 0; i != width; i++) {
+ *udst = MakeGrey(*udst);
+ udst++;
+ }
+ udst = udst - width + _screen.pitch;
+ } while (--height);
+ return;
+ }
+
+ DEBUG(misc, 0, "16bpp blitter doesn't know how to draw this colour table ('%d')", pal);
+}
+
+Sprite *Blitter_16bppSimple::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
+{
+ Pixel *dst;
+ Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite->height * (size_t)sprite->width * sizeof(Pixel));
+
+ dest_sprite->height = sprite->height;
+ dest_sprite->width = sprite->width;
+ dest_sprite->x_offs = sprite->x_offs;
+ dest_sprite->y_offs = sprite->y_offs;
+
+ dst = (Pixel *)dest_sprite->data;
+ SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite->data;
+
+ for (int i = 0; i < sprite->height * sprite->width; i++) {
+ if (src->m == 0) {
+ dst[i].c = To16(src->r, src->g, src->b);
+ dst[i].a = src->a / 16;
+ dst[i].m = 0;
+ dst[i].v = 0;
+ } else {
+ /* Get brightest value */
+ uint8 rgb_max = max(src->r, max(src->g, src->b));
+#if 0
+ /* Pre-convert the mapping channel to a RGB value,
+ use 32bpp AdjustBrightness() variant for better colors,
+ because this function is not called each frame */
+ if (rgb_max == 0) rgb_max = Blitter_32bppBase::DEFAULT_BRIGHTNESS;
+ dst[i].c = To16(Blitter_32bppBase::AdjustBrightness(LookupColourInPalette32(src->m), rgb_max));
+ dst[i].v = rgb_max / 16;
+#endif
+ rgb_max /= 16;
+
+ /* Black pixel (8bpp or old 32bpp image), so use default value */
+ if (rgb_max == 0) rgb_max = DEFAULT_BRIGHTNESS;
+
+ /* Pre-convert the mapping channel to a RGB value,
+ use 32bpp AdjustBrightness() variant for better colors,
+ because this function is not called each frame */
+ dst[i].c = AdjustBrightness(LookupColourInPalette(src->m), rgb_max);
+ dst[i].v = rgb_max;
+
+ dst[i].a = src->a / 16;
+ dst[i].m = src->m;
+ }
+ src++;
+ }
+
+ return dest_sprite;
+}
diff --git a/src/blitter/16bpp_simple.hpp b/src/blitter/16bpp_simple.hpp
new file mode 100644
index 0000000000..9feb934062
--- /dev/null
+++ b/src/blitter/16bpp_simple.hpp
@@ -0,0 +1,36 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/** @file 16bpp_simple.hpp Simple 16 bpp blitter. */
+
+#ifndef BLITTER_16BPP_SIMPLE_HPP
+#define BLITTER_16BPP_SIMPLE_HPP
+
+#include "16bpp_base.hpp"
+#include "factory.hpp"
+
+/** The most trivial 32 bpp blitter (without palette animation). */
+class Blitter_16bppSimple : public Blitter_16bppBase {
+public:
+ /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
+ /* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal);
+ /* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
+ template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
+
+ /* virtual */ const char *GetName() { return "16bpp-simple"; }
+};
+
+/** Factory for the simple 16 bpp blitter. */
+class FBlitter_16bppSimple : public BlitterFactory {
+public:
+ FBlitter_16bppSimple() : BlitterFactory("16bpp-simple", "16bpp Simple Blitter (no palette animation)") {}
+ /* virtual */ Blitter *CreateInstance() { return new Blitter_16bppSimple(); }
+};
+
+#endif /* BLITTER_16BPP_SIMPLE_HPP */
diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp
index 797ead1f51..ad00fba764 100644
--- a/src/bridge_gui.cpp
+++ b/src/bridge_gui.cpp
@@ -24,6 +24,7 @@
#include "cmd_helper.h"
#include "tunnelbridge_map.h"
#include "road_gui.h"
+#include "tilehighlight_func.h"
#include "widgets/bridge_widget.h"
@@ -198,6 +199,7 @@ public:
sprite_dim.height++; // Sprite is rendered one pixel down in the matrix field.
text_dim.height++; // Allowing the bottom row pixels to be rendered on the edge of the matrix field.
resize->height = max(sprite_dim.height, text_dim.height) + 2; // Max of both sizes + account for matrix edges.
+ resize->height = GetMinSizing(NWST_STEP, resize->height);
this->bridgetext_offset = WD_MATRIX_LEFT + sprite_dim.width + 1; // Left edge of text, 1 pixel distance from the sprite.
size->width = this->bridgetext_offset + text_dim.width + WD_MATRIX_RIGHT;
@@ -233,7 +235,8 @@ public:
SetDParam(1, b->speed);
SetDParam(0, b->material);
- DrawSprite(b->sprite, b->pal, r.left + WD_MATRIX_LEFT, y + this->resize.step_height - 1 - GetSpriteSize(b->sprite).height);
+ uint y_sprite = Center(y, this->resize.step_height, GetSpriteSize(b->sprite).height);
+ DrawSprite(b->sprite, b->pal, r.left + WD_MATRIX_LEFT, y_sprite);
DrawStringMultiLine(r.left + this->bridgetext_offset, r.right, y + 2, y + this->resize.step_height,
_game_mode == GM_EDITOR ? STR_SELECT_BRIDGE_SCENEDIT_INFO : STR_SELECT_BRIDGE_INFO);
y += this->resize.step_height;
@@ -430,6 +433,8 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
new BuildBridgeWindow(&_build_bridge_desc, start, end, type, bl);
} else {
delete bl;
+ SetSelectionTilesDirty();
+ _thd.Reset();
ShowErrorMessage(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, errmsg, WL_INFO, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE);
}
}
diff --git a/src/build_confirmation_func.h b/src/build_confirmation_func.h
new file mode 100644
index 0000000000..7bbbba24ef
--- /dev/null
+++ b/src/build_confirmation_func.h
@@ -0,0 +1,27 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/** @file build_confirmation_func.h Transparent confirmation dialog for building anything on the map. */
+
+#ifndef BUILD_CONFIRMATION_FUNC_H
+#define BUILD_CONFIRMATION_FUNC_H
+
+#include "stdafx.h"
+#include "window_func.h"
+#include "widget_type.h"
+
+
+void ShowBuildConfirmationWindow();
+void HideBuildConfirmationWindow();
+bool ConfirmationWindowShown();
+bool BuildConfirmationWindowProcessViewportClick();
+bool ConfirmationWindowEstimatingCost();
+void ConfirmationWindowSetEstimatedCost(Money cost);
+
+#endif /* BUILD_CONFIRMATION_FUNC_H */
diff --git a/src/build_confirmation_gui.cpp b/src/build_confirmation_gui.cpp
new file mode 100644
index 0000000000..c7d82bc2ca
--- /dev/null
+++ b/src/build_confirmation_gui.cpp
@@ -0,0 +1,304 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/** @file build_confirmation_gui.cpp Transparent confirmation dialog for building anything on the map. */
+
+#include "stdafx.h"
+#include "string_func.h"
+#include "strings_func.h"
+#include "window_func.h"
+#include "widget_type.h"
+#include "window_gui.h"
+#include "gfx_func.h"
+#include "tilehighlight_func.h"
+#include "viewport_func.h"
+#include "zoom_func.h"
+#include "settings_type.h"
+#include "station_gui.h"
+#include "build_confirmation_func.h"
+#include "widgets/build_confirmation_widget.h"
+#include "widgets/misc_widget.h"
+
+#include "table/strings.h"
+
+#include "safeguards.h"
+
+static const NWidgetPart _nested_build_info_widgets[] = {
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_TT_BACKGROUND), SetMinimalSize(200, 32), EndContainer(),
+};
+
+static WindowDesc _build_info_desc(
+ WDP_MANUAL, NULL, 0, 0, // Coordinates and sizes are not used,
+ WC_TOOLTIPS, WC_NONE,
+ WDF_NO_FOCUS,
+ _nested_build_info_widgets, lengthof(_nested_build_info_widgets)
+);
+
+/** Window for displaying accepted goods for a station. */
+struct BuildInfoWindow : public Window
+{
+ StationCoverageType sct;
+ bool station;
+ static Money cost;
+
+ static void show()
+ {
+ bool station = _settings_client.gui.station_show_coverage; // Station info is inaccurate when station coverage area option is disabled
+ StationCoverageType sct = SCT_ALL;
+ if (FindWindowByClass(WC_BUILD_STATION) != NULL) sct = SCT_ALL;
+ else if (FindWindowByClass(WC_BUS_STATION) != NULL) sct = SCT_PASSENGERS_ONLY;
+ else if (FindWindowByClass(WC_TRUCK_STATION) != NULL) sct = SCT_NON_PASSENGERS_ONLY;
+ else station = false;
+ new BuildInfoWindow(station, sct);
+ }
+
+ BuildInfoWindow(bool station, StationCoverageType sct) : Window(&_build_info_desc)
+ {
+ this->station = station;
+ this->sct = sct;
+ this->InitNested();
+
+ CLRBITS(this->flags, WF_WHITE_BORDER);
+ }
+
+ virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
+ {
+ Point pt;
+ pt.y = GetMainViewTop();
+ pt.x = _screen.width - sm_width - FindWindowById(WC_MAIN_TOOLBAR, 0)->width;
+ return pt;
+ }
+
+ virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
+ {
+ size->width = GetStringBoundingBox(STR_STATION_BUILD_COVERAGE_AREA_TITLE).width * 2.5;
+ size->height = GetStringHeight(STR_STATION_BUILD_COVERAGE_AREA_TITLE, size->width) * (this->station ? 3 : 1);
+
+ /* Increase slightly to have some space around the box. */
+ size->width += 2 + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
+ size->height += 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
+ }
+
+ virtual void DrawWidget(const Rect &r, int widget) const
+ {
+ /* There is only one widget. */
+ GfxFillRect(r.left, r.top, r.right, r.bottom, PC_BLACK);
+ GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_LIGHT_YELLOW);
+
+ int top = r.top + WD_FRAMERECT_TOP;
+ Money cost = BuildInfoWindow::cost;
+ StringID msg = STR_MESSAGE_ESTIMATED_COST;
+ SetDParam(0, cost);
+ if (cost < 0) {
+ msg = STR_MESSAGE_ESTIMATED_INCOME;
+ SetDParam(0, -cost);
+ }
+ top = DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, top, INT32_MAX, msg);
+
+ if (!this->station) return;
+
+ top = DrawStationCoverageAreaText(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, top, sct, _thd.outersize.x / TILE_SIZE / 2, false);
+ if (top - r.top <= GetStringHeight(STR_STATION_BUILD_COVERAGE_AREA_TITLE, r.right - r.left) * 1.5) {
+ DrawStationCoverageAreaText(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, top, sct, _thd.outersize.x / TILE_SIZE / 2, true);
+ }
+ }
+};
+
+Money BuildInfoWindow::cost = 0;
+
+/** GUI for confirming building actions. */
+struct BuildConfirmationWindow : Window {
+
+ // TODO: show estimated price
+ static bool shown; ///< Just to speed up window hiding, HideBuildConfirmationWindow() is called very often.
+ static bool estimating_cost; ///< Calculate action cost instead of executing action.
+ Point selstart; ///< The selection start on the viewport.
+ Point selend; ///< The selection end on the viewport.
+
+ BuildConfirmationWindow(WindowDesc *desc) : Window(desc)
+ {
+ // Save tile selection points, they will be reset by subsequent code, and we must keep them
+ selstart = _thd.selstart;
+ selend = _thd.selend;
+
+ this->InitNested(0);
+
+ Point pt;
+ const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
+ NWidgetViewport *nvp = this->GetWidget(WID_BC_OK);
+
+ pt.x = w->viewport->scrollpos_x + ScaleByZoom(_cursor.pos.x - nvp->current_x / 2, w->viewport->zoom);
+ pt.y = w->viewport->scrollpos_y + ScaleByZoom(_cursor.pos.y - nvp->current_y / 4, w->viewport->zoom);
+
+ nvp->InitializeViewport(this, 0, w->viewport->zoom);
+ nvp->disp_flags |= ND_SHADE_DIMMED;
+
+ this->viewport->scrollpos_x = pt.x;
+ this->viewport->scrollpos_y = pt.y;
+ this->viewport->dest_scrollpos_x = this->viewport->scrollpos_x;
+ this->viewport->dest_scrollpos_y = this->viewport->scrollpos_y;
+
+ BuildConfirmationWindow::shown = true;
+ BuildConfirmationWindow::estimating_cost = true;
+ ConfirmationWindowSetEstimatedCost(0); // Clear old value, just in case
+ // This is a hack - we invoke the build command with estimating_cost flag, which is equal to _shift_pressed,
+ // then we select last build tool, restore viewport selection, and hide all windows, which pop up when command is invoked,
+ // and all that just to get cost estimate value.
+ ConfirmPlacingObject();
+ ToolbarSelectLastTool();
+ _thd.selstart = selstart;
+ _thd.selend = selend;
+ BuildConfirmationWindow::estimating_cost = false;
+ MoveAllWindowsOffScreen();
+ }
+
+ ~BuildConfirmationWindow()
+ {
+ BuildConfirmationWindow::shown = false;
+ }
+
+ void OnClick(Point pt, int widget, int click_count)
+ {
+ switch (widget) {
+ case WID_BC_OK:
+ if (pt.y <= (int)GetWidget(WID_BC_OK)->current_y / 2) {
+ _thd.selstart = selstart;
+ _thd.selend = selend;
+ ConfirmPlacingObject();
+ ToolbarSelectLastTool();
+ } else {
+ ResetObjectToPlace();
+ }
+ break;
+ }
+ HideBuildConfirmationWindow(); // this == NULL after this call
+ }
+
+ virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
+ {
+ switch (widget) {
+ case WID_BC_OK:
+ size->width = GetMinSizing(NWST_BUTTON) * 2;
+ size->height = GetMinSizing(NWST_BUTTON) * 3;
+ break;
+ }
+ }
+
+ virtual void OnPaint()
+ {
+ this->DrawWidgets();
+
+ DrawButtonFrame(0, 0, this->width - 1, this->height / 2 - 2, STR_BUTTON_OK);
+ DrawButtonFrame(0, this->height / 2, this->width - 1, this->height / 2 - 1, STR_BUTTON_CANCEL);
+ }
+
+ void DrawButtonFrame(int x, int y, int w, int h, int str)
+ {
+ DrawFrameRect(x, y, x + w, y + h, COLOUR_GREY, FR_BORDERONLY);
+ Dimension d = GetStringBoundingBox(str);
+ DrawFrameRect(x + w / 2 - d.width / 2 - 1,
+ Center(y, h) - 2,
+ x + w / 2 + d.width / 2 + 1,
+ Center(y, h) + d.height,
+ COLOUR_GREY, FR_NONE);
+ DrawString(x, x + w, Center(y, h), str, TC_FROMSTRING, SA_HOR_CENTER);
+ }
+};
+
+bool BuildConfirmationWindow::shown = false;
+bool BuildConfirmationWindow::estimating_cost = false;
+
+static const NWidgetPart _nested_build_confirmation_widgets[] = {
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BC_PANEL),
+ NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_BC_OK), SetSizingType(NWST_VIEWPORT), SetResize(1, 1), SetFill(1, 1), //SetPadding(2, 2, 2, 2),
+ EndContainer(),
+};
+
+static WindowDesc _build_confirmation_desc(
+ WDP_MANUAL, "build_confirmation", 0, 0,
+ WC_BUILD_CONFIRMATION, WC_NONE,
+ 0,
+ _nested_build_confirmation_widgets, lengthof(_nested_build_confirmation_widgets)
+);
+
+/**
+ * Show build confirmation window under the mouse cursor
+*/
+void ShowBuildConfirmationWindow()
+{
+ if (ConfirmationWindowEstimatingCost()) return; // Special case, ignore recursive call
+
+ HideBuildConfirmationWindow();
+
+ if (!_settings_client.gui.build_confirmation || _shift_pressed) {
+ ConfirmPlacingObject();
+ return;
+ }
+
+ BuildConfirmationWindow *w = new BuildConfirmationWindow(&_build_confirmation_desc);
+
+ int old_left = w->left;
+ int old_top = w->top;
+ w->left = _cursor.pos.x - w->width / 2;
+ w->top = _cursor.pos.y - w->height / 4;
+ w->viewport->left += w->left - old_left;
+ w->viewport->top += w->top - old_top;
+ w->SetDirty();
+ SetDirtyBlocks(0, 0, _screen.width, _screen.height); // I don't know what does this do, but it looks important
+
+ BuildInfoWindow::show();
+}
+
+/**
+ * Destroy build confirmation window, this does not cancel current action
+*/
+void HideBuildConfirmationWindow()
+{
+ if (ConfirmationWindowEstimatingCost()) return; // Special case, ignore recursive call
+
+ if (!BuildConfirmationWindow::shown) return;
+
+ DeleteWindowById(WC_BUILD_CONFIRMATION, 0);
+ DeleteWindowById(WC_TOOLTIPS, 0);
+}
+
+bool ConfirmationWindowShown()
+{
+ return BuildConfirmationWindow::shown;
+}
+
+bool BuildConfirmationWindowProcessViewportClick()
+{
+ if (!BuildConfirmationWindow::shown) return false;
+
+ Window *w = FindWindowById(WC_BUILD_CONFIRMATION, 0);
+ if (w != NULL && IsInsideBS(_cursor.pos.x, w->left, w->width) && IsInsideBS(_cursor.pos.y, w->top, w->height)) {
+ Point pt;
+ pt.x = _cursor.pos.x - w->left;
+ pt.y = _cursor.pos.y - w->top;
+ w->OnClick(pt, WID_BC_OK, 1);
+ return true;
+ }
+
+ HideBuildConfirmationWindow();
+
+ _thd.new_outersize = _thd.outersize; // Revert station catchment area highlight, which is getting set to zero inside drawing funcs
+
+ return false;
+}
+
+bool ConfirmationWindowEstimatingCost()
+{
+ return BuildConfirmationWindow::estimating_cost;
+}
+
+void ConfirmationWindowSetEstimatedCost(Money cost)
+{
+ BuildInfoWindow::cost = cost;
+}
diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp
index bd4bf3b59b..8103623523 100644
--- a/src/build_vehicle_gui.cpp
+++ b/src/build_vehicle_gui.cpp
@@ -46,7 +46,8 @@
*/
uint GetEngineListHeight(VehicleType type)
{
- return max(FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM, GetVehicleImageCellSize(type, EIT_PURCHASE).height);
+ uint size = max(FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM, GetVehicleImageCellSize(type, EIT_PURCHASE).height);
+ return GetMinSizing(NWST_STEP, size);
}
static const NWidgetPart _nested_build_vehicle_widgets[] = {
@@ -57,25 +58,30 @@ static const NWidgetPart _nested_build_vehicle_widgets[] = {
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
- NWidget(WWT_PANEL, COLOUR_GREY),
+ NWidget(NWID_HORIZONTAL),
NWidget(NWID_VERTICAL),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
- NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_BV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
+ NWidget(WWT_PANEL, COLOUR_GREY),
+ NWidget(NWID_VERTICAL),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), SetSizingType(NWST_STEP),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_BV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), SetSizingType(NWST_STEP),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BV_SHOW_HIDDEN_ENGINES), SetSizingType(NWST_STEP),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_BV_CARGO_FILTER_DROPDOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_FILTER_CRITERIA), SetSizingType(NWST_STEP),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ EndContainer(),
EndContainer(),
+ /* Vehicle list. */
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BV_SHOW_HIDDEN_ENGINES),
- NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_BV_CARGO_FILTER_DROPDOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_FILTER_CRITERIA),
+ NWidget(WWT_MATRIX, COLOUR_GREY, WID_BV_LIST), SetResize(1, 1), SetFill(1, 0), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_BV_SCROLLBAR),
+ NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_BV_SCROLLBAR),
EndContainer(),
EndContainer(),
+ /* Panel with details. */
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BV_PANEL), SetMinimalSize(240, 122), SetResize(1, 1), EndContainer(),
EndContainer(),
- /* Vehicle list. */
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_MATRIX, COLOUR_GREY, WID_BV_LIST), SetResize(1, 1), SetFill(1, 0), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_BV_SCROLLBAR),
- NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_BV_SCROLLBAR),
- EndContainer(),
- /* Panel with details. */
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BV_PANEL), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(),
/* Build/rename buttons, resize button. */
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BV_BUILD_SEL),
@@ -1393,6 +1399,7 @@ struct BuildVehicleWindow : Window {
Dimension d = GetStringBoundingBox(this->GetWidget(widget)->widget_data);
d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
d.height += padding.height;
+ d.height = GetMinSizing(NWST_STEP, d.height);
*size = maxdim(*size, d);
break;
}
diff --git a/src/command.cpp b/src/command.cpp
index 959610cd28..79a93c20e8 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -26,6 +26,9 @@
#include "signal_func.h"
#include "core/backup_type.hpp"
#include "object_base.h"
+#include "string_func.h"
+#include "tilehighlight_func.h"
+#include "build_confirmation_func.h"
#include "table/strings.h"
@@ -551,11 +554,18 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac
* However, in case of incoming network commands,
* map generation or the pause button we do want
* to execute. */
- bool estimate_only = _shift_pressed && IsLocalCompany() &&
+ bool estimate_only = (_shift_pressed || ConfirmationWindowEstimatingCost()) &&
+ IsLocalCompany() &&
!_generating_world &&
!(cmd & CMD_NETWORK_COMMAND) &&
(cmd & CMD_ID_MASK) != CMD_PAUSE;
+ if (ConfirmationWindowEstimatingCost() && !estimate_only) {
+ // We cannot estimate cost, so abort the command - it will be repeated by confirmation dialog later
+ ShowEstimatedCostOrIncome(0, 0, 0);
+ return false;
+ }
+
/* We're only sending the command, so don't do
* fancy things for 'success'. */
bool only_sending = _networking && !(cmd & CMD_NETWORK_COMMAND);
diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp
index 577ea884d8..5d5156dc78 100644
--- a/src/company_cmd.cpp
+++ b/src/company_cmd.cpp
@@ -904,7 +904,10 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
Game::NewEvent(new ScriptEventCompanyBankrupt(c_index));
CompanyAdminRemove(c_index, (CompanyRemoveReason)reason);
- if (StoryPage::GetNumItems() == 0 || Goal::GetNumItems() == 0) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
+ if (StoryPage::GetNumItems() == 0 || Goal::GetNumItems() == 0) {
+ InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
+ InvalidateWindowData(WC_MAIN_TOOLBAR_RIGHT, 0);
+ }
break;
}
diff --git a/src/company_gui.cpp b/src/company_gui.cpp
index 0be6679583..8439cd6d13 100644
--- a/src/company_gui.cpp
+++ b/src/company_gui.cpp
@@ -35,6 +35,7 @@
#include "road_func.h"
#include "water.h"
#include "station_func.h"
+#include "widget_type.h"
#include "zoom_func.h"
#include "widgets/company_widget.h"
@@ -529,7 +530,7 @@ public:
uint Height(uint width) const
{
- return max(FONT_HEIGHT_NORMAL, ScaleGUITrad(12) + 2);
+ return GetMinSizing(NWST_STEP, max(FONT_HEIGHT_NORMAL, ScaleGUITrad(12) + 2));
}
bool Selectable() const
@@ -930,102 +931,112 @@ static const NWidgetPart _nested_select_company_manager_face_widgets[] = {
EndContainer(),
EndContainer(),
EndContainer(),
- NWidget(NWID_VERTICAL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TOGGLE_LARGE_SMALL_BUTTON), SetFill(1, 0), SetDataTip(STR_FACE_ADVANCED, STR_FACE_ADVANCED_TOOLTIP),
- NWidget(NWID_SPACER), SetMinimalSize(0, 2),
- NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SCMF_SEL_MALEFEMALE), // Simple male/female face setting.
- NWidget(NWID_VERTICAL),
- NWidget(NWID_SPACER), SetFill(0, 1),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_MALE), SetFill(1, 0), SetDataTip(STR_FACE_MALE_BUTTON, STR_FACE_MALE_TOOLTIP),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_FEMALE), SetFill(1, 0), SetDataTip(STR_FACE_FEMALE_BUTTON, STR_FACE_FEMALE_TOOLTIP),
- NWidget(NWID_SPACER), SetFill(0, 1),
+
+ NWidget(NWID_HORIZONTAL),
+ NWidget(NWID_SPACER), SetFill(1, 0),
+ NWidget(NWID_VERTICAL),
+ NWidget(NWID_SPACER), SetFill(0, 1),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TOGGLE_LARGE_SMALL_BUTTON), SetFill(1, 0), SetDataTip(STR_FACE_ADVANCED, STR_FACE_ADVANCED_TOOLTIP),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 2),
+ NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SCMF_SEL_MALEFEMALE), // Simple male/female face setting.
+ NWidget(NWID_VERTICAL),
+ NWidget(NWID_SPACER), SetFill(0, 1),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_MALE), SetFill(1, 0), SetDataTip(STR_FACE_MALE_BUTTON, STR_FACE_MALE_TOOLTIP),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_FEMALE), SetFill(1, 0), SetDataTip(STR_FACE_FEMALE_BUTTON, STR_FACE_FEMALE_TOOLTIP),
+ NWidget(NWID_SPACER), SetFill(0, 1),
+ EndContainer(),
EndContainer(),
- EndContainer(),
- NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SCMF_SEL_PARTS), // Advanced face parts setting.
- NWidget(NWID_VERTICAL),
- NWidget(NWID_SPACER), SetMinimalSize(0, 2),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_MALE2), SetFill(1, 0), SetDataTip(STR_FACE_MALE_BUTTON, STR_FACE_MALE_TOOLTIP),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_FEMALE2), SetFill(1, 0), SetDataTip(STR_FACE_FEMALE_BUTTON, STR_FACE_FEMALE_TOOLTIP),
- EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 2),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_ETHNICITY_EUR), SetFill(1, 0), SetDataTip(STR_FACE_EUROPEAN, STR_FACE_SELECT_EUROPEAN),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_ETHNICITY_AFR), SetFill(1, 0), SetDataTip(STR_FACE_AFRICAN, STR_FACE_SELECT_AFRICAN),
- EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 4),
+ NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SCMF_SEL_PARTS), // Advanced face parts setting.
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_MOUSTACHE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_MOUSTACHE_EARRING_TOOLTIP),
- EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAS_GLASSES_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP),
- EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAIR_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_L), SetDataTip(AWV_DECREASE, STR_FACE_HAIR_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAIR), SetDataTip(STR_EMPTY, STR_FACE_HAIR_TOOLTIP),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_R), SetDataTip(AWV_INCREASE, STR_FACE_HAIR_TOOLTIP),
- EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_EYEBROWS_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_L), SetDataTip(AWV_DECREASE, STR_FACE_EYEBROWS_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYEBROWS), SetDataTip(STR_EMPTY, STR_FACE_EYEBROWS_TOOLTIP),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_R), SetDataTip(AWV_INCREASE, STR_FACE_EYEBROWS_TOOLTIP),
- EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_EYECOLOUR_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_L), SetDataTip(AWV_DECREASE, STR_FACE_EYECOLOUR_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR), SetDataTip(STR_EMPTY, STR_FACE_EYECOLOUR_TOOLTIP),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_R), SetDataTip(AWV_INCREASE, STR_FACE_EYECOLOUR_TOOLTIP),
- EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_GLASSES_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_L), SetDataTip(AWV_DECREASE, STR_FACE_GLASSES_TOOLTIP_2),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP_2),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_R), SetDataTip(AWV_INCREASE, STR_FACE_GLASSES_TOOLTIP_2),
- EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_NOSE_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_L), SetDataTip(AWV_DECREASE, STR_FACE_NOSE_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_NOSE), SetDataTip(STR_EMPTY, STR_FACE_NOSE_TOOLTIP),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_R), SetDataTip(AWV_INCREASE, STR_FACE_NOSE_TOOLTIP),
- EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_LIPS_MOUSTACHE_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_L), SetDataTip(AWV_DECREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE), SetDataTip(STR_EMPTY, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_R), SetDataTip(AWV_INCREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
- EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_CHIN_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_L), SetDataTip(AWV_DECREASE, STR_FACE_CHIN_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_CHIN), SetDataTip(STR_EMPTY, STR_FACE_CHIN_TOOLTIP),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_R), SetDataTip(AWV_INCREASE, STR_FACE_CHIN_TOOLTIP),
- EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_JACKET_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_L), SetDataTip(AWV_DECREASE, STR_FACE_JACKET_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_JACKET), SetDataTip(STR_EMPTY, STR_FACE_JACKET_TOOLTIP),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_R), SetDataTip(AWV_INCREASE, STR_FACE_JACKET_TOOLTIP),
- EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_COLLAR_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_L), SetDataTip(AWV_DECREASE, STR_FACE_COLLAR_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_COLLAR), SetDataTip(STR_EMPTY, STR_FACE_COLLAR_TOOLTIP),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_R), SetDataTip(AWV_INCREASE, STR_FACE_COLLAR_TOOLTIP),
- EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_TIE_EARRING_TEXT), SetFill(1, 0),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_L), SetDataTip(AWV_DECREASE, STR_FACE_TIE_EARRING_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_TIE_EARRING_TOOLTIP),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_R), SetDataTip(AWV_INCREASE, STR_FACE_TIE_EARRING_TOOLTIP),
+ NWidget(NWID_VERTICAL),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 2),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_MALE2), SetFill(1, 0), SetDataTip(STR_FACE_MALE_BUTTON, STR_FACE_MALE_TOOLTIP),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_FEMALE2), SetFill(1, 0), SetDataTip(STR_FACE_FEMALE_BUTTON, STR_FACE_FEMALE_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 2),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_ETHNICITY_EUR), SetFill(1, 0), SetDataTip(STR_FACE_EUROPEAN, STR_FACE_SELECT_EUROPEAN),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_ETHNICITY_AFR), SetFill(1, 0), SetDataTip(STR_FACE_AFRICAN, STR_FACE_SELECT_AFRICAN),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 4),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_MOUSTACHE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_MOUSTACHE_EARRING_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAS_GLASSES_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAIR_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_HAIR_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAIR), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_HAIR_TOOLTIP),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_HAIR_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_EYEBROWS_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_EYEBROWS_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYEBROWS), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_EYEBROWS_TOOLTIP),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_EYEBROWS_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_EYECOLOUR_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_EYECOLOUR_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_EYECOLOUR_TOOLTIP),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_EYECOLOUR_TOOLTIP),
+ EndContainer(),
+ EndContainer(),
+ NWidget(NWID_VERTICAL),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_GLASSES_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_GLASSES_TOOLTIP_2),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_GLASSES), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP_2),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_GLASSES_TOOLTIP_2),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_NOSE_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_NOSE_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_NOSE), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_NOSE_TOOLTIP),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_NOSE_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_LIPS_MOUSTACHE_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_CHIN_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_CHIN_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_CHIN), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_CHIN_TOOLTIP),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_CHIN_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_JACKET_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_JACKET_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_JACKET), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_JACKET_TOOLTIP),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_JACKET_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_COLLAR_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_COLLAR_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_COLLAR), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_COLLAR_TOOLTIP),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_COLLAR_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_TIE_EARRING_TEXT), SetFill(1, 0),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_TIE_EARRING_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_TIE_EARRING_TOOLTIP),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_TIE_EARRING_TOOLTIP),
+ EndContainer(),
+ EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetFill(0, 1),
EndContainer(),
EndContainer(),
+ NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
@@ -1075,7 +1086,7 @@ class SelectCompanyManagerFaceWindow : public Window
/* Draw the value/bool in white (0xC). If the button clicked adds 1px to x and y text coordinates (IsWindowWidgetLowered()). */
DrawString(nwi_widget->pos_x + nwi_widget->IsLowered(), nwi_widget->pos_x + nwi_widget->current_x - 1 - nwi_widget->IsLowered(),
- nwi_widget->pos_y + 1 + nwi_widget->IsLowered(), str, TC_WHITE, SA_HOR_CENTER);
+ Center(nwi_widget->pos_y + nwi_widget->IsLowered(), nwi_widget->current_y), str, TC_WHITE, SA_HOR_CENTER);
}
}
@@ -1125,6 +1136,10 @@ public:
Dimension yesno_dim = maxdim(GetStringBoundingBox(STR_FACE_YES), GetStringBoundingBox(STR_FACE_NO));
yesno_dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
yesno_dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
+
+ yesno_dim.width = GetMinSizing(NWST_STEP, yesno_dim.width);
+ yesno_dim.height = GetMinSizing(NWST_STEP, yesno_dim.height);
+
/* Size of the number button + arrows. */
Dimension number_dim = {0, 0};
for (int val = 1; val <= 12; val++) {
@@ -1268,12 +1283,12 @@ public:
case WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT:
case WID_SCMF_TIE_EARRING_TEXT: {
StringID str = PART_TEXTS_IS_FEMALE[(widget - WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT) * 2 + this->is_female];
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_GOLD, SA_RIGHT);
+ DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top), str, TC_GOLD, SA_RIGHT);
break;
}
case WID_SCMF_LIPS_MOUSTACHE_TEXT:
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, (this->is_moust_male) ? STR_FACE_MOUSTACHE : STR_FACE_LIPS, TC_GOLD, SA_RIGHT);
+ DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top), (this->is_moust_male) ? STR_FACE_MOUSTACHE : STR_FACE_LIPS, TC_GOLD, SA_RIGHT);
break;
case WID_SCMF_HAS_GLASSES_TEXT:
@@ -1285,7 +1300,7 @@ public:
case WID_SCMF_CHIN_TEXT:
case WID_SCMF_JACKET_TEXT:
case WID_SCMF_COLLAR_TEXT:
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, PART_TEXTS[widget - WID_SCMF_HAS_GLASSES_TEXT], TC_GOLD, SA_RIGHT);
+ DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top), PART_TEXTS[widget - WID_SCMF_HAS_GLASSES_TEXT], TC_GOLD, SA_RIGHT);
break;
diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp
index 9cfc8e8f9d..72d9b81743 100644
--- a/src/console_cmds.cpp
+++ b/src/console_cmds.cpp
@@ -417,6 +417,20 @@ DEF_CONSOLE_CMD(ConListFiles)
return true;
}
+/* Open the cheat window. */
+DEF_CONSOLE_CMD(ConOpenCheats)
+{
+ if (argc == 0) {
+ IConsoleHelp("Open the cheat window. Usage: 'open_cheats'");
+ return true;
+ }
+
+ extern void ShowCheatWindow();
+ ShowCheatWindow();
+
+ return true;
+}
+
/* Change the dir via console */
DEF_CONSOLE_CMD(ConChangeDirectory)
{
@@ -1921,6 +1935,8 @@ void IConsoleStdLibRegister()
IConsoleCmdRegister("save", ConSave);
IConsoleCmdRegister("saveconfig", ConSaveConfig);
IConsoleCmdRegister("ls", ConListFiles);
+ IConsoleCmdRegister("open_cheats", ConOpenCheats);
+ IConsoleCmdRegister("cheats", ConOpenCheats);
IConsoleCmdRegister("cd", ConChangeDirectory);
IConsoleCmdRegister("pwd", ConPrintWorkingDirectory);
IConsoleCmdRegister("clear", ConClearBuffer);
diff --git a/src/console_gui.cpp b/src/console_gui.cpp
index ed46938cd5..ed84f6fe09 100644
--- a/src/console_gui.cpp
+++ b/src/console_gui.cpp
@@ -22,6 +22,7 @@
#include "console_func.h"
#include "rev.h"
#include "video/video_driver.hpp"
+#include "textbuf_gui.h"
#include "widgets/console_widget.h"
@@ -29,6 +30,10 @@
#include "safeguards.h"
+#ifdef __ANDROID__
+#include
+#endif
+
static const uint ICON_HISTORY_SIZE = 20;
static const uint ICON_LINE_SPACING = 2;
static const uint ICON_RIGHT_BORDERWIDTH = 10;
@@ -229,6 +234,16 @@ struct IConsoleWindow : Window
}
}
+ virtual void OnQueryTextFinished(char *str)
+ {
+ _focused_window = this;
+
+ if (str == NULL) return;
+
+ _iconsole_cmdline.Assign(str);
+ this->OnKeyPress(0, WKC_RETURN);
+ }
+
virtual void OnHundredthTick()
{
if (IConsoleLine::Truncate() &&
@@ -430,9 +445,25 @@ void IConsoleSwitch()
{
switch (_iconsole_mode) {
case ICONSOLE_CLOSED:
- new IConsoleWindow();
+#ifdef __ANDROID__
+ {
+ char buf[1024] = "";
+ for (const IConsoleLine *print = IConsoleLine::Get(0); print != NULL; print = print->previous) {
+ if (print->buffer && print->buffer[0]) {
+ strecat(buf, print->buffer, lastof(buf));
+ strecat(buf, "\n", lastof(buf));
+ }
+ }
+ strecat(buf, "\n\n\n\n\n\n\n\n", lastof(buf)); // Move all text to top
+ SDL_ANDROID_SetScreenKeyboardHintMesage(buf);
+ char text[512] = "";
+ SDL_ANDROID_GetScreenKeyboardTextInput(text, sizeof(text) - 1); /* Invoke Android built-in screen keyboard */
+ IConsoleCmdExec(text);
+ }
+#else
+ new IConsoleWindow();
+#endif
break;
-
case ICONSOLE_OPENED: case ICONSOLE_FULL:
DeleteWindowById(WC_CONSOLE, 0);
break;
diff --git a/src/debug.cpp b/src/debug.cpp
index 16eecadad0..f03e9490bd 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -16,6 +16,9 @@
#include "string_func.h"
#include "fileio_func.h"
#include "settings_type.h"
+#ifdef __ANDROID__
+#include
+#endif
#include
@@ -109,6 +112,9 @@ char *DumpDebugFacilityNames(char *buf, char *last)
*/
static void debug_print(const char *dbg, const char *buf)
{
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, "OpenTTD", "[%s] %s", dbg, buf);
+#endif
#if defined(ENABLE_NETWORK)
if (_debug_socket != INVALID_SOCKET) {
char buf2[1024 + 32];
diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp
index 47eefc65e9..5137777726 100644
--- a/src/depot_gui.cpp
+++ b/src/depot_gui.cpp
@@ -62,8 +62,8 @@ static const NWidgetPart _nested_train_depot_widgets[] = {
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_D_SHOW_SELL_CHAIN),
NWidget(WWT_IMGBTN, COLOUR_GREY, WID_D_SELL_CHAIN), SetDataTip(SPR_SELL_CHAIN_TRAIN, STR_DEPOT_DRAG_WHOLE_TRAIN_TO_SELL_TOOLTIP), SetResize(0, 1), SetFill(0, 1),
EndContainer(),
- NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_SELL_ALL), SetDataTip(0x0, STR_NULL),
- NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_AUTOREPLACE), SetDataTip(0x0, STR_NULL),
+ NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_SELL_ALL), SetResize(0, 1), SetFill(0, 1), SetDataTip(0x0, STR_NULL),
+ NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_AUTOREPLACE), SetResize(0, 1), SetFill(0, 1), SetDataTip(0x0, STR_NULL),
EndContainer(),
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_D_V_SCROLL),
EndContainer(),
@@ -299,7 +299,7 @@ struct DepotWindow : Window {
/* Length of consist in tiles with 1 fractional digit (rounded up) */
SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE));
SetDParam(1, 1);
- DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
+ DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, Center(y, this->resize.step_height, FONT_HEIGHT_SMALL), STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
break;
}
@@ -309,26 +309,28 @@ struct DepotWindow : Window {
default: NOT_REACHED();
}
- uint diff_x, diff_y;
+ uint diff_x, y_sprite, y_num;
if (v->IsGroundVehicle()) {
/* Arrange unitnumber and flag horizontally */
diff_x = this->flag_width + WD_FRAMERECT_LEFT;
- diff_y = (this->resize.step_height - this->flag_height) / 2 - 2;
+ y_sprite = Center(y, this->resize.step_height, this->flag_height);
+ y_num = Center(y, this->resize.step_height);
} else {
/* Arrange unitnumber and flag vertically */
diff_x = WD_FRAMERECT_LEFT;
- diff_y = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
+ y_num = Center(y, this->resize.step_height, FONT_HEIGHT_NORMAL + this->flag_height + 2);
+ y_sprite = y_num + FONT_HEIGHT_NORMAL;
}
int text_left = rtl ? right - this->header_width - 1 : left + diff_x;
int text_right = rtl ? right - diff_x : left + this->header_width - 1;
if (free_wagon) {
- DrawString(text_left, text_right, y + 2, STR_DEPOT_NO_ENGINE);
+ DrawString(text_left, text_right, Center(y, this->resize.step_height), STR_DEPOT_NO_ENGINE);
} else {
- DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, rtl ? right - this->flag_width : left + WD_FRAMERECT_LEFT, y + diff_y);
+ DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, rtl ? right - this->flag_width : left + WD_FRAMERECT_LEFT, y_sprite);
SetDParam(0, v->unitnumber);
- DrawString(text_left, text_right, y + 2, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA);
+ DrawString(text_left, text_right, y_num, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA);
}
}
@@ -345,7 +347,7 @@ struct DepotWindow : Window {
uint16 num = this->vscroll->GetPosition() * this->num_columns;
int maxval = min(this->vehicle_list.Length(), num + (rows_in_display * this->num_columns));
int y;
- for (y = r.top + 1; num < maxval; y += this->resize.step_height) { // Draw the rows
+ for (y = r.top; num < maxval; y += this->resize.step_height) { // Draw the rows
for (byte i = 0; i < this->num_columns && num < maxval; i++, num++) {
/* Draw all vehicles in the current row */
const Vehicle *v = this->vehicle_list[num];
@@ -624,6 +626,7 @@ struct DepotWindow : Window {
int base_width = this->count_width + this->header_width;
resize->height = max(GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).height, min_height);
+ resize->height = GetMinSizing(NWST_STEP, resize->height);
if (this->type == VEH_TRAIN) {
resize->width = 1;
size->width = base_width + 2 * ScaleGUITrad(29); // about 2 parts
diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp
index 79eaa89b14..b555daca1c 100644
--- a/src/dock_gui.cpp
+++ b/src/dock_gui.cpp
@@ -27,6 +27,7 @@
#include "hotkeys.h"
#include "gui.h"
#include "zoom_func.h"
+#include "build_confirmation_func.h"
#include "widgets/dock_widget.h"
@@ -105,6 +106,7 @@ struct BuildDocksToolbarWindow : Window {
~BuildDocksToolbarWindow()
{
+ if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort();
if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
}
@@ -146,7 +148,7 @@ struct BuildDocksToolbarWindow : Window {
case WID_DT_DEPOT: // Build depot button
if (!CanBuildVehicleInfrastructure(VEH_SHIP)) return;
- if (HandlePlacePushButton(this, WID_DT_DEPOT, SPR_CURSOR_SHIP_DEPOT, HT_RECT)) ShowBuildDocksDepotPicker(this);
+ if (HandlePlacePushButton(this, WID_DT_DEPOT, SPR_CURSOR_SHIP_DEPOT, HT_RECT | HT_SCROLL_VIEWPORT)) ShowBuildDocksDepotPicker(this);
break;
case WID_DT_STATION: // Build station button
@@ -156,7 +158,7 @@ struct BuildDocksToolbarWindow : Window {
case WID_DT_BUOY: // Build buoy button
if (!CanBuildVehicleInfrastructure(VEH_SHIP)) return;
- HandlePlacePushButton(this, WID_DT_BUOY, SPR_CURSOR_BUOY, HT_RECT);
+ HandlePlacePushButton(this, WID_DT_BUOY, SPR_CURSOR_BUOY, HT_RECT | HT_SCROLL_VIEWPORT);
break;
case WID_DT_RIVER: // Build river button (in scenario editor)
@@ -181,33 +183,21 @@ struct BuildDocksToolbarWindow : Window {
break;
case WID_DT_LOCK: // Build lock button
- DoCommandP(tile, 0, 0, CMD_BUILD_LOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_LOCKS), CcBuildDocks);
+ /* Reuse DDSP_REMOVE_TRUCKSTOP. */
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_REMOVE_TRUCKSTOP);
break;
case WID_DT_DEMOLISH: // Demolish aka dynamite button
PlaceProc_DemolishArea(tile);
break;
+ case WID_DT_STATION: // Build station button
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_STATION);
+ break;
+
case WID_DT_DEPOT: // Build depot button
- DoCommandP(tile, _ship_depot_direction, 0, CMD_BUILD_SHIP_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT), CcBuildDocks);
- break;
-
- case WID_DT_STATION: { // Build station button
- uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join
-
- /* tile is always the land tile, so need to evaluate _thd.pos */
- CommandContainer cmdcont = { tile, _ctrl_pressed, p2, CMD_BUILD_DOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_DOCK_HERE), CcBuildDocks, "" };
-
- /* Determine the watery part of the dock. */
- DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile));
- TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile);
-
- ShowSelectStationIfNeeded(cmdcont, TileArea(tile, tile_to));
- break;
- }
-
case WID_DT_BUOY: // Build buoy button
- DoCommandP(tile, 0, 0, CMD_BUILD_BUOY | CMD_MSG(STR_ERROR_CAN_T_POSITION_BUOY_HERE), CcBuildDocks);
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE);
break;
case WID_DT_RIVER: // Build river button (in scenario editor)
@@ -215,16 +205,26 @@ struct BuildDocksToolbarWindow : Window {
break;
case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button
- DoCommandP(tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15, CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE), CcBuildBridge);
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_BRIDGE);
break;
default: NOT_REACHED();
}
+ MoveAllWindowsOffScreen();
}
virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
{
- VpSelectTilesWithMethod(pt.x, pt.y, select_method);
+ switch (last_clicked_widget) {
+ case WID_DT_BUILD_AQUEDUCT:
+ case WID_DT_LOCK:
+ case WID_DT_STATION:
+ this->OnPlacePresize(pt, TileVirtXY(pt.x, pt.y));
+ break;
+ default:
+ VpSelectTilesWithMethod(pt.x, pt.y, select_method);
+ break;
+ }
}
virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
@@ -240,24 +240,73 @@ struct BuildDocksToolbarWindow : Window {
case DDSP_CREATE_RIVER:
DoCommandP(end_tile, start_tile, WATER_CLASS_RIVER, CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_PLACE_RIVERS), CcPlaySound_SPLAT_WATER);
break;
+ case DDSP_BUILD_STATION: {
+ uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join
+
+ /* Tile is always the land tile, so need to evaluate _thd.pos. */
+ CommandContainer cmdcont = { start_tile, _ctrl_pressed, p2, CMD_BUILD_DOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_DOCK_HERE), CcBuildDocks, "" };
+
+ //SetObjectToPlace(SPR_CURSOR_DOCK, PAL_NONE, HT_SPECIAL, this->window_class, this->window_number);
+ ShowSelectStationIfNeeded(cmdcont, TileArea(start_tile, end_tile));
+ VpStartPreSizing();
+ break;
+ }
+
+ case DDSP_BUILD_BRIDGE:
+ DoCommandP(start_tile, GetOtherAqueductEnd(start_tile), TRANSPORT_WATER << 15, CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE), CcBuildBridge);
+ VpStartPreSizing();
+ break;
+
+ case DDSP_REMOVE_TRUCKSTOP: { // Reusing for locks.
+ TileIndex middle_tile = start_tile;
+ if (start_tile != end_tile) middle_tile = TileAddByDiagDir(start_tile, DiagdirBetweenTiles(start_tile, end_tile));
+ DoCommandP(middle_tile, 0, 0, CMD_BUILD_LOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_LOCKS), CcBuildDocks);
+ VpStartPreSizing();
+ break;
+ }
+
+ case DDSP_SINGLE_TILE:
+ assert(start_tile == end_tile);
+ switch (last_clicked_widget) {
+ case WID_DT_BUOY:
+ DoCommandP(end_tile, 0, 0, CMD_BUILD_BUOY | CMD_MSG(STR_ERROR_CAN_T_POSITION_BUOY_HERE), CcBuildDocks);
+ break;
+ case WID_DT_DEPOT: // Build depot button
+ DoCommandP(end_tile, _ship_depot_direction, 0, CMD_BUILD_SHIP_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT), CcBuildDocks);
+ break;
+ default: NOT_REACHED();
+ }
default: break;
}
+ MoveAllHiddenWindowsBackToScreen();
}
}
virtual void OnPlaceObjectAbort()
{
+ MoveAllHiddenWindowsBackToScreen();
this->RaiseButtons();
+ if (ConfirmationWindowShown() && _ctrl_pressed) return;
DeleteWindowById(WC_BUILD_STATION, TRANSPORT_WATER);
DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_WATER);
DeleteWindowById(WC_SELECT_STATION, 0);
- DeleteWindowByClass(WC_BUILD_BRIDGE);
+ }
+
+ virtual void SelectLastTool()
+ {
+ // User misplaced something - activate last selected tool again
+ if (this->last_clicked_widget == WIDGET_LIST_END)
+ return;
+ Point dummy = {0, 0};
+ this->RaiseWidget(this->last_clicked_widget);
+ this->OnClick(dummy, this->last_clicked_widget, 0);
}
virtual void OnPlacePresize(Point pt, TileIndex tile_from)
{
+ if (!IsValidTile(tile_from)) return;
TileIndex tile_to = tile_from;
if (this->last_clicked_widget == WID_DT_BUILD_AQUEDUCT) {
@@ -347,7 +396,7 @@ Window *ShowBuildDocksToolbar()
{
if (!Company::IsValidID(_local_company)) return NULL;
- DeleteWindowByClass(WC_BUILD_TOOLBAR);
+ DeleteToolbarLinkedWindows();
return AllocateWindowDescFront(&_build_docks_toolbar_desc, TRANSPORT_WATER);
}
@@ -373,7 +422,7 @@ static const NWidgetPart _nested_build_docks_scen_toolbar_widgets[] = {
/** Window definition for the build docks in scenario editor window. */
static WindowDesc _build_docks_scen_toolbar_desc(
- WDP_AUTO, "toolbar_water_scen", 0, 0,
+ WDP_ALIGN_TOOLBAR, "toolbar_water_scen", 0, 0,
WC_SCEN_BUILD_TOOLBAR, WC_NONE,
WDF_CONSTRUCTION,
_nested_build_docks_scen_toolbar_widgets, lengthof(_nested_build_docks_scen_toolbar_widgets)
@@ -386,6 +435,7 @@ static WindowDesc _build_docks_scen_toolbar_desc(
*/
Window *ShowBuildDocksScenToolbar()
{
+ DeleteToolbarLinkedWindows();
return AllocateWindowDescFront(&_build_docks_scen_toolbar_desc, TRANSPORT_WATER);
}
@@ -556,10 +606,10 @@ static const NWidgetPart _nested_build_docks_depot_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(0, 3),
NWidget(NWID_HORIZONTAL_LTR),
NWidget(NWID_SPACER), SetMinimalSize(3, 0),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_X), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_X), SetSizingType(NWST_BUTTON), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_Y), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_Y), SetSizingType(NWST_BUTTON), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(3, 0),
EndContainer(),
diff --git a/src/economy.cpp b/src/economy.cpp
index cdfa059e86..92ce7bcbbe 100644
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -1692,7 +1692,9 @@ static void LoadUnloadVehicle(Vehicle *front)
}
}
- amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->cargo, payment);
+ if (payment != NULL) {
+ amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->cargo, payment);
+ }
remaining = v->cargo.UnloadCount() > 0;
if (amount_unloaded > 0) {
dirty_vehicle = true;
diff --git a/src/fileio.cpp b/src/fileio.cpp
index a72950bc73..467ea0fb92 100644
--- a/src/fileio.cpp
+++ b/src/fileio.cpp
@@ -292,7 +292,11 @@ static const char * const _subdirs[] = {
"ai" PATHSEP "library" PATHSEP,
"game" PATHSEP,
"game" PATHSEP "library" PATHSEP,
+#ifdef __ANDROID__
"screenshot" PATHSEP,
+#else
+ "screenshot" PATHSEP,
+#endif
};
assert_compile(lengthof(_subdirs) == NUM_SUBDIRS);
@@ -1315,6 +1319,21 @@ void DeterminePaths(const char *exe)
_searchpaths[SP_AUTODOWNLOAD_DIR] = NULL;
}
#endif /* ENABLE_NETWORK */
+
+#ifdef __ANDROID__
+ // Copy savegames from "full" OpenTTD to "lite" save directory
+ char curdir[PATH_MAX];
+ if (getcwd(curdir, sizeof(curdir)) && strstr(curdir, "org.openttd.sdl.lowmem")) {
+ // No, I won't implement file copying in C, shell script is just fine for this job
+ DEBUG(misc, 1, "Copying savegames from ../../org.openttd.sdl/files/.openttd/save to %s", curdir);
+ system("cd ../../org.openttd.sdl/files/.openttd/save && "
+ "for F in *.sav ; do "
+ "ls \"../../../../org.openttd.sdl.lowmem/files/.openttd/save/$F\" || "
+ "cat \"$F\" > \"../../../../org.openttd.sdl.lowmem/files/.openttd/save/$F\" ; "
+ "done");
+ chdir(curdir);
+ }
+#endif
}
/**
diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp
index e6cd9625cc..e8b403f542 100644
--- a/src/fios_gui.cpp
+++ b/src/fios_gui.cpp
@@ -35,11 +35,15 @@
#include "table/strings.h"
#include "safeguards.h"
+#ifdef __ANDROID__
+#include
+#endif
LoadCheckData _load_check_data; ///< Data loaded from save during SL_LOAD_CHECK.
static bool _fios_path_changed;
static bool _savegame_sort_dirty;
+static const char *NETWORK_SAVE_FILENAME = "network-save.sav";
/**
@@ -106,6 +110,9 @@ static const NWidgetPart _nested_load_dialog_widgets[] = {
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_NEWGRF_INFO), SetDataTip(STR_INTRO_NEWGRF_SETTINGS, STR_NULL), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_LOAD_BUTTON), SetDataTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
EndContainer(),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_LOAD_NETWORK_BUTTON), SetDataTip(STR_SAVELOAD_LOAD_NETWORK_BUTTON, STR_SAVELOAD_LOAD_NETWORK_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
EndContainer(),
EndContainer(),
@@ -179,7 +186,7 @@ static const NWidgetPart _nested_save_dialog_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1),
NWidget(NWID_HORIZONTAL),
- NWidget(NWID_SPACER), SetResize(1, 0), SetFill(1, 1),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SL_SAVE_NETWORK_BUTTON), SetDataTip(STR_SAVELOAD_SAVE_NETWORK_BUTTON, STR_SAVELOAD_SAVE_NETWORK_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
EndContainer(),
EndContainer(),
@@ -296,6 +303,7 @@ public:
this->FinishInitNested(0);
this->LowerWidget(WID_SL_DRIVES_DIRECTORIES_LIST);
+ if (mode == SLD_SAVE_GAME) this->SetWidgetLoweredState(WID_SL_SAVE_NETWORK_BUTTON, _settings_client.gui.save_to_network);
/* pause is only used in single-player, non-editor mode, non-menu mode. It
* will be unpaused in the WE_DESTROY event handler. */
@@ -375,7 +383,7 @@ public:
if (item == this->selected) {
GfxFillRect(r.left + 1, y, r.right, y + this->resize.step_height, PC_DARK_BLUE);
}
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, item->title, _fios_colours[GetDetailedFileType(item->type)]);
+ DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, this->resize.step_height), item->title, _fios_colours[GetDetailedFileType(item->type)]);
y += this->resize.step_height;
if (y >= this->vscroll->GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break;
}
@@ -486,8 +494,8 @@ public:
break;
case WID_SL_DRIVES_DIRECTORIES_LIST:
- resize->height = FONT_HEIGHT_NORMAL;
- size->height = resize->height * 10 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
+ resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
+ size->height = resize->height * 5 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
break;
case WID_SL_SORT_BYNAME:
case WID_SL_SORT_BYDATE: {
@@ -638,6 +646,32 @@ public:
/* Note, this is also called via the OSK; and we need to lower the button. */
this->HandleButtonClick(WID_SL_SAVE_GAME);
break;
+
+ case WID_SL_SAVE_NETWORK_BUTTON:
+ _settings_client.gui.save_to_network = !_settings_client.gui.save_to_network;
+ this->SetWidgetLoweredState(WID_SL_SAVE_NETWORK_BUTTON, _settings_client.gui.save_to_network);
+ this->SetDirty();
+ break;
+
+ case WID_SL_LOAD_NETWORK_BUTTON: {
+ char savePath[PATH_MAX];
+ FiosMakeSavegameName(savePath, NETWORK_SAVE_FILENAME, lastof(savePath));
+#ifdef __ANDROID__
+ if (!SDL_ANDROID_CloudLoad(savePath, NULL, "OpenTTD")) {
+ break;
+ }
+#endif
+ _load_check_data.Clear();
+ SaveOrLoadResult res = SaveOrLoad(savePath, SL_LOAD_CHECK, SAVE_DIR, false);
+ if (res == SL_OK && !_load_check_data.HasErrors()) {
+ strecpy(_file_to_saveload.name, savePath, lastof(_file_to_saveload.name));
+ strecpy(_file_to_saveload.title, "", lastof(_file_to_saveload.title));
+ if (!_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs()) {
+ _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD_GAME;
+ }
+ }
+ break;
+ }
}
}
diff --git a/src/fontcache.cpp b/src/fontcache.cpp
index 6bea59c103..a37ea0b6ec 100644
--- a/src/fontcache.cpp
+++ b/src/fontcache.cpp
@@ -383,7 +383,7 @@ static void LoadFreeTypeFont(FontSize fs)
return;
found_face:
- new FreeTypeFontCache(fs, face, settings->size);
+ new FreeTypeFontCache(fs, face, RescaleFrom854x480(settings->size));
}
@@ -460,7 +460,7 @@ static void *AllocateFont(size_t size)
static bool GetFontAAState(FontSize size)
{
/* AA is only supported for 32 bpp */
- if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32) return false;
+ if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32 && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 16) return false;
switch (size) {
default: NOT_REACHED();
diff --git a/src/fontdetection.cpp b/src/fontdetection.cpp
index 6df45cf6a1..c7412b7789 100644
--- a/src/fontdetection.cpp
+++ b/src/fontdetection.cpp
@@ -632,7 +632,8 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
if (split != NULL) *split = '\0';
/* First create a pattern to match the wanted language. */
- FcPattern *pat = FcNameParse((FcChar8*)lang);
+ //FcPattern *pat = FcNameParse((FcChar8*)lang);
+ FcPattern *pat = FcPatternCreate();
/* We only want to know the filename. */
FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT, NULL);
/* Get the list of filenames matching the wanted language. */
@@ -645,6 +646,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
if (fs != NULL) {
int best_weight = -1;
const char *best_font = NULL;
+ int best_missing_glypths = 65536;
for (int i = 0; i < fs->nfont; i++) {
FcPattern *font = fs->fonts[i];
@@ -654,28 +656,32 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
if (res != FcResultMatch || file == NULL) {
continue;
}
+ DEBUG(freetype, 1, "Got font %s", file);
+ int missing = 0;
/* Get a font with the right spacing .*/
int value = 0;
FcPatternGetInteger(font, FC_SPACING, 0, &value);
- if (callback->Monospace() != (value == FC_MONO) && value != FC_DUAL) continue;
+ if (callback->Monospace() != (value == FC_MONO) && value != FC_DUAL) missing += 1;
/* Do not use those that explicitly say they're slanted. */
FcPatternGetInteger(font, FC_SLANT, 0, &value);
- if (value != 0) continue;
+ if (value != 0) missing += 1;
/* We want the fatter font as they look better at small sizes. */
FcPatternGetInteger(font, FC_WEIGHT, 0, &value);
- if (value <= best_weight) continue;
+ if (value <= best_weight) missing += 1;
callback->SetFontNames(settings, (const char*)file);
- bool missing = callback->FindMissingGlyphs(NULL);
- DEBUG(freetype, 1, "Font \"%s\" misses%s glyphs", file, missing ? "" : " no");
+ missing = callback->FindMissingGlyphs(NULL);
+ DEBUG(freetype, 1, "Font \"%s\" misses %d glyphs for lang %s", file, missing, lang);
- if (!missing) {
+ if (missing < best_missing_glypths) {
best_weight = value;
best_font = (const char *)file;
+ best_missing_glypths = missing;
+ if (missing == 0) break;
}
}
@@ -683,6 +689,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
ret = true;
callback->SetFontNames(settings, best_font);
InitFreeType(callback->Monospace());
+ DEBUG(freetype, 1, "Selected font %s for lang %s", best_font, lang);
}
/* Clean up the list of filenames. */
diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp
index 359709e361..2e1bf0f9ed 100644
--- a/src/genworld_gui.cpp
+++ b/src/genworld_gui.cpp
@@ -29,6 +29,7 @@
#include "saveload/saveload.h"
#include "progress.h"
#include "error.h"
+#include "settings_gui.h"
#include "widgets/genworld_widget.h"
@@ -63,20 +64,20 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
EndContainer(),
NWidget(WWT_PANEL, COLOUR_BROWN),
NWidget(NWID_SPACER), SetMinimalSize(0, 10),
- /* Landscape selection. */
- NWidget(NWID_HORIZONTAL), SetPIP(10, 0, 10),
- NWidget(NWID_SPACER), SetFill(1, 0),
- NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
- NWidget(NWID_SPACER), SetFill(1, 0),
- NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
- NWidget(NWID_SPACER), SetFill(1, 0),
- NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
- NWidget(NWID_SPACER), SetFill(1, 0),
- NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
- NWidget(NWID_SPACER), SetFill(1, 0),
- EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 11),
NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
+ /* Landscape selection. */
+ NWidget(NWID_VERTICAL), SetPIP(10, 0, 10),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(20, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
/* Left column with labels. */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
@@ -169,7 +170,7 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
NWidget(NWID_SPACER), SetFill(1, 1),
EndContainer(),
EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 9), SetFill(1, 1),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 10),
EndContainer(),
};
@@ -458,6 +459,7 @@ struct GenerateLandscapeWindow : public Window {
case WID_GL_MAPSIZE_Y_PULLDOWN:
SetDParamMaxValue(0, MAX_MAP_SIZE);
*size = maxdim(*size, GetStringBoundingBox(STR_JUST_INT));
+ size->width = size->width + GetMinSizing(NWST_BUTTON);
break;
case WID_GL_SNOW_LEVEL_TEXT:
@@ -468,7 +470,8 @@ struct GenerateLandscapeWindow : public Window {
case WID_GL_HEIGHTMAP_SIZE_TEXT:
SetDParam(0, this->x);
SetDParam(1, this->y);
- *size = maxdim(*size, GetStringBoundingBox(STR_MAPGEN_HEIGHTMAP_SIZE));
+ //*size = maxdim(*size, GetStringBoundingBox(STR_MAPGEN_HEIGHTMAP_SIZE));
+ size->height = SETTING_BUTTON_HEIGHT;
break;
case WID_GL_TOWN_PULLDOWN:
@@ -492,18 +495,19 @@ struct GenerateLandscapeWindow : public Window {
case WID_GL_VARIETY_PULLDOWN: strs = _variety; break;
case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: strs = _rotation; break;
case WID_GL_BORDERS_RANDOM:
- *size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOMIZE), GetStringBoundingBox(STR_MAPGEN_BORDER_MANUAL));
+ //*size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOMIZE), GetStringBoundingBox(STR_MAPGEN_BORDER_MANUAL));
break;
case WID_GL_WATER_NE:
case WID_GL_WATER_NW:
case WID_GL_WATER_SE:
case WID_GL_WATER_SW:
- *size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOM), maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_WATER), GetStringBoundingBox(STR_MAPGEN_BORDER_FREEFORM)));
+ //*size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOM), maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_WATER), GetStringBoundingBox(STR_MAPGEN_BORDER_FREEFORM)));
break;
case WID_GL_HEIGHTMAP_NAME_TEXT:
size->width = 0;
+ size->height = SETTING_BUTTON_HEIGHT;
break;
default:
@@ -947,7 +951,9 @@ struct CreateScenarioWindow : public Window
}
*size = maxdim(*size, GetStringBoundingBox(str));
size->width += padding.width;
+ size->width = GetMinSizing(NWST_BUTTON, size->width);
size->height += padding.height;
+ size->height = GetMinSizing(NWST_BUTTON, size->height);
}
virtual void OnClick(Point pt, int widget, int click_count)
@@ -1066,11 +1072,16 @@ static const NWidgetPart _nested_create_scenario_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(0, 10),
/* Landscape style selection. */
NWidget(NWID_HORIZONTAL), SetPIP(10, 3, 10),
+ NWidget(NWID_SPACER), SetFill(1, 1),
NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
+ NWidget(NWID_SPACER), SetFill(1, 1),
NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
+ NWidget(NWID_SPACER), SetFill(1, 1),
NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
+ NWidget(NWID_SPACER), SetFill(1, 1),
NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
- EndContainer(),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(10, 8, 10),
/* Green generation type buttons: 'Flat land' and 'Random land'. */
NWidget(NWID_VERTICAL), SetPIP(10, 6, 10),
diff --git a/src/gfx.cpp b/src/gfx.cpp
index 7195051577..06123fd73e 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -35,11 +35,15 @@ byte _support8bpp;
CursorVars _cursor;
bool _ctrl_pressed; ///< Is Ctrl pressed?
bool _shift_pressed; ///< Is Shift pressed?
+bool _move_pressed;
+
byte _fast_forward;
bool _left_button_down; ///< Is left mouse button pressed?
bool _left_button_clicked; ///< Is left mouse button clicked?
bool _right_button_down; ///< Is right mouse button pressed?
bool _right_button_clicked; ///< Is right mouse button clicked?
+Point _right_button_down_pos; ///< Pos of right mouse button click, for drag and drop
+
DrawPixelInfo _screen;
bool _screen_disable_anim = false; ///< Disable palette animation (important for 32bpp-anim blitter during giant screenshot)
bool _exit_game;
@@ -848,6 +852,50 @@ void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub,
}
}
+/**
+ * Draw a sprite, centered at x:y, not in a viewport
+ * @param img Image number to draw
+ * @param pal Palette to use.
+ * @param x Left coordinate of image in pixels
+ * @param y Top coordinate of image in pixels
+ * @param sub If available, draw only specified part of the sprite
+ * @param zoom Zoom level of sprite
+ */
+void DrawSpriteCentered(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
+{
+ Dimension size = GetSpriteSize(img, NULL, zoom);
+ DrawSprite(img, pal, x - size.width / 2, y - size.height / 2, sub, zoom);
+}
+
+/**
+ * Draw a sprite, centered in rect, not in a viewport
+ * @param img Image number to draw
+ * @param pal Palette to use.
+ * @param left Left coordinate of image bounding box in pixels
+ * @param top Top coordinate of image bounding box in pixels
+ * @param right Right coordinate of image bounding box in pixels
+ * @param bottom Bottom coordinate of image bounding box in pixels
+ * @param sub If available, draw only specified part of the sprite
+ * @param zoom Zoom level of sprite
+ */
+void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, int left, int top, int right, int bottom, const SubSprite *sub, ZoomLevel zoom)
+{
+ DrawSpriteCentered(img, pal, (left + right) / 2, (top + bottom) / 2, sub, zoom);
+}
+
+/**
+ * Draw a sprite, centered in rect, not in a viewport
+ * @param img Image number to draw
+ * @param pal Palette to use.
+ * @param rect Image bounding box in pixels
+ * @param sub If available, draw only specified part of the sprite
+ * @param zoom Zoom level of sprite
+ */
+void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, const Rect &rect, const SubSprite *sub, ZoomLevel zoom)
+{
+ DrawSpriteCenteredRect(img, pal, rect.left, rect.top, rect.right, rect.bottom, sub, zoom);
+}
+
/**
* The code for setting up the blitter mode and sprite information before finally drawing the sprite.
* @param sprite The sprite to draw.
@@ -1197,6 +1245,8 @@ void ScreenSizeChanged()
/* screen size changed and the old bitmap is invalid now, so we don't want to undraw it */
_cursor.visible = false;
+
+ CheckWindowMinSizings();
}
void UndrawMouseCursor()
@@ -1214,11 +1264,6 @@ void UndrawMouseCursor()
void DrawMouseCursor()
{
-#if defined(WINCE)
- /* Don't ever draw the mouse for WinCE, as we work with a stylus */
- return;
-#endif
-
/* Don't draw the mouse cursor if the screen is not ready */
if (_screen.dst_ptr == NULL) return;
@@ -1710,3 +1755,104 @@ void SortResolutions(int count)
{
QSortT(_resolutions, count, &compare_res);
}
+
+
+/**
+ * Returns the initial value for a margin, after telling where are the left and right margins and where we want to draw/write (begining/end of line)
+ * @param left is the left margin of the horizontal space we want to draw to
+ * @param right: right margin
+ * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end
+ * @return the margin we asked
+ */
+int InitTempMargin(int left, int right, bool to_end_line)
+{
+ return to_end_line ^ (_current_text_dir == TD_RTL) ? right :left;
+}
+
+/**
+ * Consumes a space in an horizontal margin
+ * @param space: amount of space used
+ * @param here: the margin where to add the space
+ * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end
+ */
+void AddSpace(int space, int &here, bool to_end_line)
+{
+ here += to_end_line ^ (_current_text_dir == TD_RTL) ? -space : space;
+}
+
+/**
+ * After drawing something, update a margin
+ * @param end is where we ended drawing (usually the return value of a DrawString function)
+ * @param margin is the margin we want to update
+ * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end
+ */
+void UpdateMarginEnd(int end, int &margin, bool to_end_line)
+{
+ margin = to_end_line ^ (_current_text_dir == TD_RTL) ? min(end, margin) : max(end, margin);
+}
+
+/**
+ * After drawing something, horizontal margins are updated
+ * @param end: last position drawn
+ * @param left is the left margin of the horizontal space drawn
+ * @param right: right margin
+ * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end
+ */
+void UpdateMarginsEnd(int end, int &left, int &right, bool to_end_line)
+{
+ if (to_end_line ^ (_current_text_dir == TD_RTL)) {
+ right = end;
+ } else {
+ left = end;
+ }
+}
+
+/**
+ * After drawing something of a certain width, update margins
+ * @param width: used space
+ * @param initial left margin
+ * @param initial right margin
+ * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end
+ */
+void UpdateMarginsWidth(int width, int &left, int &right, bool to_end_line)
+{
+ if (to_end_line ^ (_current_text_dir == TD_RTL)) {
+ right -= width;
+ } else {
+ left += width;
+ }
+}
+
+/**
+ * Draws a string in a delimited space; temporal margin gets updated
+ * @param left is the left margin of the horizontal space we want to draw to
+ * @param right: right margin of the horizontal space we want to draw to
+ * @param top: vertical position
+ * @param margin keeps the most extreme limit used of the line (this should be previously initialized with InitTempLimit)
+ * @param string to draw
+ * @param colour for the string
+ * @param alignment of the string (only left or right alignment)
+ * @param underline
+ */
+void DrawString2(int left, int right, int top, int &margin, StringID str, TextColour colour, StringAlignment align, bool underline)
+{
+ int end = DrawString(left, right, top, str, colour, align, underline);
+ UpdateMarginEnd(end, margin, align == SA_RIGHT);
+}
+
+/**
+ * Draws a sprite in a delimited space; temporal margin gets updated
+ * @param width of the sprite
+ * @param left is the left margin of the horizontal space we want to draw to
+ * @param right: right margin of the horizontal space
+ * @param top: vertical position
+ * @param margin keeps the most extreme limit used of the line (this should be previously initialized with InitTempLimit)
+ * @param sprite
+ * @param palette
+ * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end
+ */
+void DrawSprite2(int width, int left, int right, int top, int &margin, SpriteID img, PaletteID pal, bool to_end_line, SubSprite *sub)
+{
+ DrawSprite(img, pal, to_end_line ^ (_current_text_dir == TD_RTL) ? right - width : left, top, sub);
+ margin = to_end_line ^ (_current_text_dir == TD_RTL) ? min(right - width, margin): max(margin, left + width);
+}
diff --git a/src/gfx_func.h b/src/gfx_func.h
index 566f91b2da..08acd08a85 100644
--- a/src/gfx_func.h
+++ b/src/gfx_func.h
@@ -45,6 +45,7 @@
#include "gfx_type.h"
#include "strings_type.h"
#include "string_type.h"
+#include "core/math_func.hpp"
void GameLoop();
@@ -56,12 +57,15 @@ extern byte _support8bpp;
extern CursorVars _cursor;
extern bool _ctrl_pressed; ///< Is Ctrl pressed?
extern bool _shift_pressed; ///< Is Shift pressed?
+extern bool _move_pressed;
+
extern byte _fast_forward;
extern bool _left_button_down;
extern bool _left_button_clicked;
extern bool _right_button_down;
extern bool _right_button_clicked;
+extern Point _right_button_down_pos;
extern DrawPixelInfo _screen;
extern bool _screen_disable_anim; ///< Disable palette animation (important for 32bpp-anim blitter during giant screenshot)
@@ -92,6 +96,9 @@ void GfxScroll(int left, int top, int width, int height, int xo, int yo);
Dimension GetSpriteSize(SpriteID sprid, Point *offset = NULL, ZoomLevel zoom = ZOOM_LVL_GUI);
void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL);
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI);
+void DrawSpriteCentered(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI);
+void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, int left, int top, int right, int bottom, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI);
+void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, const Rect &r, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI);
/** How to align the to-be drawn text. */
enum StringAlignment {
@@ -173,6 +180,39 @@ int GetCharacterHeight(FontSize size);
/** Height of characters in the large (#FS_MONO) font. @note Some characters may be oversized. */
#define FONT_HEIGHT_MONO (GetCharacterHeight(FS_MONO))
+int InitTempMargin(int left, int right, bool to_end_line);
+void AddSpace(int space, int &here, bool to_end_line);
+
+void UpdateMarginEnd(int end, int &margin, bool to_end_line);
+void UpdateMarginWidth(int adding, int &margin, bool to_end_line);
+void UpdateMarginsEnd(int end, int &left, int &right, bool to_end_line);
+void UpdateMarginsWidth(int width, int &left, int &right, bool to_end_line);
+
+void DrawString2(int left, int right, int top, int &margin, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false);
+void DrawSprite2(int width, int left, int right, int top, int &margin, SpriteID img, PaletteID pal, bool to_end_line = false, SubSprite *sub = NULL);
+
+/**
+ * Return where to start drawing a centered object inside a widget.
+ * @param top The top coordinate (or the left coordinate) of the widget.
+ * @param height The height (or width) of the widget.
+ * @param size The height (or width) of the object to draw.
+ * @return The coordinate where to start drawing the centered object.
+ */
+static inline int Center(int top, int height, uint size = FONT_HEIGHT_NORMAL)
+{
+ return top + (height - size) / 2;
+}
+
+/**
+ * Returns fint/button size, rescaled to current screen resolution from the base Android resolution, which is 854x480
+ * @param value The value to rescale
+ * @return Rescaled value, using lesser of the curret screen coordinates
+ */
+static inline int RescaleFrom854x480(int value)
+{
+ return min(value * _cur_resolution.width / 854, value * _cur_resolution.height / 480);
+}
+
extern DrawPixelInfo *_cur_dpi;
TextColour GetContrastColour(uint8 background);
diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp
index c12c6ace4d..019c4f039d 100644
--- a/src/graph_gui.cpp
+++ b/src/graph_gui.cpp
@@ -116,6 +116,7 @@ static NWidgetBase *MakeNWidgetCompanyLines(int *biggest_index)
for (int widnum = WID_GL_FIRST_COMPANY; widnum <= WID_GL_LAST_COMPANY; widnum++) {
NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, widnum);
+ panel->sizing_type = NWST_STEP;
panel->SetMinimalSize(246, line_height);
panel->SetFill(1, 0);
panel->SetDataTip(0x0, STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP);
@@ -1130,6 +1131,7 @@ private:
uint ordinal_width; ///< The width of the ordinal number
uint text_width; ///< The width of the actual text
uint icon_width; ///< The width of the company icon
+ uint icon_y_offset; ///< The vertical offset for drawing the company icon.
int line_height; ///< Height of the text lines
/**
@@ -1176,8 +1178,7 @@ public:
{
if (widget != WID_CL_BACKGROUND) return;
- int icon_y_offset = 1 + (FONT_HEIGHT_NORMAL - this->line_height) / 2;
- uint y = r.top + WD_FRAMERECT_TOP - icon_y_offset;
+ uint y = r.top + WD_FRAMERECT_TOP;
bool rtl = _current_text_dir == TD_RTL;
uint ordinal_left = rtl ? r.right - WD_FRAMERECT_LEFT - this->ordinal_width : r.left + WD_FRAMERECT_LEFT;
@@ -1190,7 +1191,7 @@ public:
const Company *c = this->companies[i];
DrawString(ordinal_left, ordinal_right, y, i + STR_ORDINAL_NUMBER_1ST, i == 0 ? TC_WHITE : TC_YELLOW);
- DrawCompanyIcon(c->index, icon_left, y + icon_y_offset);
+ DrawCompanyIcon(c->index, icon_left, y + this->icon_y_offset);
SetDParam(0, c->index);
SetDParam(1, c->index);
@@ -1223,6 +1224,7 @@ public:
Dimension d = GetSpriteSize(SPR_COMPANY_ICON);
this->icon_width = d.width + 2;
this->line_height = max(d.height + 2, FONT_HEIGHT_NORMAL);
+ this->icon_y_offset = Center(1, this->line_height, d.height);
const Company *c;
FOR_ALL_COMPANIES(c) {
diff --git a/src/group_gui.cpp b/src/group_gui.cpp
index 361ab53e56..9dd052179a 100644
--- a/src/group_gui.cpp
+++ b/src/group_gui.cpp
@@ -47,8 +47,7 @@ static const NWidgetPart _nested_group_widgets[] = {
NWidget(NWID_HORIZONTAL),
/* left part */
NWidget(NWID_VERTICAL),
- NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalTextLines(1, WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM), SetFill(1, 0), EndContainer(),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_ALL_VEHICLES), SetFill(1, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_ALL_VEHICLES), SetFill(1, 0), SetMinimalTextLines(1, WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_DEFAULT_VEHICLES), SetFill(1, 0), EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_MATRIX, COLOUR_GREY, WID_GL_LIST_GROUP), SetMatrixDataTip(1, 0, STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP),
@@ -70,7 +69,7 @@ static const NWidgetPart _nested_group_widgets[] = {
/* right part */
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_SORT_BY_ORDER), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_SORT_BY_ORDER), SetSizingType(NWST_STEP), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_SORT_BY_DROPDOWN), SetMinimalSize(167, 12), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA),
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetResize(1, 0), EndContainer(),
EndContainer(),
@@ -78,7 +77,7 @@ static const NWidgetPart _nested_group_widgets[] = {
NWidget(WWT_MATRIX, COLOUR_GREY, WID_GL_LIST_VEHICLE), SetMinimalSize(248, 0), SetMatrixDataTip(1, 0, STR_NULL), SetResize(1, 1), SetFill(1, 0), SetScrollbar(WID_GL_LIST_VEHICLE_SCROLLBAR),
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_GL_LIST_VEHICLE_SCROLLBAR),
EndContainer(),
- NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(1, 0), SetFill(1, 1), SetResize(1, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 0), EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_AVAILABLE_VEHICLES), SetMinimalSize(106, 12), SetFill(0, 1),
SetDataTip(STR_BLACK_STRING, STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP),
@@ -192,8 +191,9 @@ private:
uint ComputeGroupInfoSize()
{
this->column_size[VGC_NAME] = maxdim(GetStringBoundingBox(STR_GROUP_DEFAULT_TRAINS + this->vli.vtype), GetStringBoundingBox(STR_GROUP_ALL_TRAINS + this->vli.vtype));
- this->column_size[VGC_NAME].width = max(170u, this->column_size[VGC_NAME].width);
- this->tiny_step_height = this->column_size[VGC_NAME].height;
+/* We consider the max average length of characters to be the one of "a" */
+ this->column_size[VGC_NAME].width = max(GetCharacterWidth(FS_NORMAL, 97) * (MAX_LENGTH_GROUP_NAME_CHARS - 4), this->column_size[VGC_NAME].width);
+ this->tiny_step_height = max(11U, this->column_size[VGC_NAME].height);
this->column_size[VGC_PROTECT] = GetSpriteSize(SPR_GROUP_REPLACE_PROTECT);
this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_PROTECT].height);
@@ -215,9 +215,10 @@ private:
this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_NUMBER].height);
this->tiny_step_height += WD_MATRIX_TOP;
+ this->tiny_step_height = GetMinSizing(NWST_STEP, this->tiny_step_height);
return WD_FRAMERECT_LEFT + 8 +
- this->column_size[VGC_NAME].width + 8 +
+ this->column_size[VGC_NAME].width + 2 +
this->column_size[VGC_PROTECT].width + 2 +
this->column_size[VGC_AUTOREPLACE].width + 2 +
this->column_size[VGC_PROFIT].width + 2 +
@@ -238,7 +239,7 @@ private:
{
/* Highlight the group if a vehicle is dragged over it */
if (g_id == this->group_over) {
- GfxFillRect(left + WD_FRAMERECT_LEFT, y + WD_FRAMERECT_TOP, right - WD_FRAMERECT_RIGHT, y + this->tiny_step_height - WD_FRAMERECT_BOTTOM - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][7]);
+ GfxFillRect(left + WD_FRAMERECT_LEFT, y + WD_FRAMERECT_TOP + WD_MATRIX_TOP, right - WD_FRAMERECT_RIGHT, y + this->tiny_step_height - WD_FRAMERECT_BOTTOM - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][7]);
}
if (g_id == NEW_GROUP) return;
@@ -249,6 +250,7 @@ private:
bool rtl = _current_text_dir == TD_RTL;
/* draw group name */
+ int longer_name = 0;
StringID str;
if (IsAllGroupID(g_id)) {
str = STR_GROUP_ALL_TRAINS + this->vli.vtype;
@@ -257,12 +259,16 @@ private:
} else {
SetDParam(0, g_id);
str = STR_GROUP_NAME;
+ if (!protection) {
+ longer_name += this->column_size[VGC_PROTECT].width + 2;
+ if (!stats.autoreplace_defined) longer_name += this->column_size[VGC_AUTOREPLACE].width + 2;
+ }
}
- int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width + 1 : left + WD_FRAMERECT_LEFT + 8;
- DrawString(x + indent * LEVEL_WIDTH, x + this->column_size[VGC_NAME].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);
+ int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width - longer_name + 1 : left + WD_FRAMERECT_LEFT + 8;
+ DrawString(x + indent * LEVEL_WIDTH, x + this->column_size[VGC_NAME].width + longer_name - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);
/* draw autoreplace protection */
- x = rtl ? x - 8 - this->column_size[VGC_PROTECT].width : x + 8 + this->column_size[VGC_NAME].width;
+ x = rtl ? x - 2 - this->column_size[VGC_PROTECT].width : x + 2 + this->column_size[VGC_NAME].width;
if (protection) DrawSprite(SPR_GROUP_REPLACE_PROTECT, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROTECT].height) / 2);
/* draw autoreplace status */
@@ -363,16 +369,10 @@ public:
resize->height = this->tiny_step_height;
/* Minimum height is the height of the list widget minus all and default vehicles... */
- size->height = 4 * GetVehicleListHeight(this->vli.vtype, this->tiny_step_height) - 2 * this->tiny_step_height;
-
- /* ... minus the buttons at the bottom ... */
- uint max_icon_height = GetSpriteSize(this->GetWidget(WID_GL_CREATE_GROUP)->widget_data).height;
- max_icon_height = max(max_icon_height, GetSpriteSize(this->GetWidget(WID_GL_RENAME_GROUP)->widget_data).height);
- max_icon_height = max(max_icon_height, GetSpriteSize(this->GetWidget(WID_GL_DELETE_GROUP)->widget_data).height);
- max_icon_height = max(max_icon_height, GetSpriteSize(this->GetWidget(WID_GL_REPLACE_PROTECTION)->widget_data).height);
+ size->height = (this->vli.vtype >= VEH_SHIP ? 3.5 : 7) * GetVehicleListHeight(this->vli.vtype, this->tiny_step_height) - 2 * this->tiny_step_height;
/* Get a multiple of tiny_step_height of that amount */
- size->height = Ceil(size->height - max_icon_height, tiny_step_height);
+ size->height = Ceil(size->height, tiny_step_height);
break;
}
@@ -393,7 +393,7 @@ public:
case WID_GL_LIST_VEHICLE:
this->ComputeGroupInfoSize();
resize->height = GetVehicleListHeight(this->vli.vtype, this->tiny_step_height);
- size->height = 4 * resize->height;
+ size->height = (this->vli.vtype >= VEH_SHIP ? 3 : 6) * resize->height;
break;
case WID_GL_MANAGE_VEHICLES_DROPDOWN: {
@@ -520,15 +520,15 @@ public:
{
switch (widget) {
case WID_GL_ALL_VEHICLES:
- DrawGroupInfo(r.top + WD_FRAMERECT_TOP, r.left, r.right, ALL_GROUP);
+ DrawGroupInfo(r.top, r.left, r.right, ALL_GROUP);
break;
case WID_GL_DEFAULT_VEHICLES:
- DrawGroupInfo(r.top + WD_FRAMERECT_TOP, r.left, r.right, DEFAULT_GROUP);
+ DrawGroupInfo(r.top, r.left, r.right, DEFAULT_GROUP);
break;
case WID_GL_LIST_GROUP: {
- int y1 = r.top + WD_FRAMERECT_TOP;
+ int y1 = r.top;
int max = min(this->group_sb->GetPosition() + this->group_sb->GetCapacity(), this->groups.Length());
for (int i = this->group_sb->GetPosition(); i < max; ++i) {
const Group *g = this->groups[i];
diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp
index b9077b9d77..3ff55d3458 100644
--- a/src/industry_gui.cpp
+++ b/src/industry_gui.cpp
@@ -235,7 +235,7 @@ static const NWidgetPart _nested_build_industry_widgets[] = {
/** Window definition of the dynamic place industries gui */
static WindowDesc _build_industry_desc(
- WDP_AUTO, "build_industry", 170, 212,
+ WDP_ALIGN_TOOLBAR, "build_industry", 170, 212,
WC_BUILD_INDUSTRY, WC_NONE,
WDF_CONSTRUCTION,
_nested_build_industry_widgets, lengthof(_nested_build_industry_widgets)
@@ -252,9 +252,6 @@ class BuildIndustryWindow : public Window {
bool enabled[NUM_INDUSTRYTYPES + 1]; ///< availability state, coming from CBID_INDUSTRY_PROBABILITY (if ever)
Scrollbar *vscroll;
- /** The offset for the text in the matrix. */
- static const int MATRIX_TEXT_OFFSET = 17;
-
void SetupArrays()
{
this->count = 0;
@@ -328,6 +325,10 @@ public:
this->SetButtons();
}
+ ~BuildIndustryWindow() {
+ if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort();
+ }
+
virtual void OnInit()
{
this->SetupArrays();
@@ -342,8 +343,8 @@ public:
if (this->index[i] == INVALID_INDUSTRYTYPE) continue;
d = maxdim(d, GetStringBoundingBox(GetIndustrySpec(this->index[i])->name));
}
- resize->height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
- d.width += MATRIX_TEXT_OFFSET + padding.width;
+ resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM);
+ d.width += FONT_HEIGHT_NORMAL * 5 / 4 + padding.width;
d.height = 5 * resize->height;
*size = maxdim(*size, d);
break;
@@ -427,20 +428,22 @@ public:
switch (widget) {
case WID_DPI_MATRIX_WIDGET: {
uint text_left, text_right, icon_left, icon_right;
+ uint square_size = FONT_HEIGHT_NORMAL - 2;
+ uint text_offset = FONT_HEIGHT_NORMAL * 5 / 4;
if (_current_text_dir == TD_RTL) {
icon_right = r.right - WD_MATRIX_RIGHT;
- icon_left = icon_right - 10;
- text_right = icon_right - BuildIndustryWindow::MATRIX_TEXT_OFFSET;
+ icon_left = icon_right - square_size;
+ text_right = icon_right - text_offset;
text_left = r.left + WD_MATRIX_LEFT;
} else {
icon_left = r.left + WD_MATRIX_LEFT;
- icon_right = icon_left + 10;
- text_left = icon_left + BuildIndustryWindow::MATRIX_TEXT_OFFSET;
+ icon_right = icon_left + square_size;
+ text_left = icon_left + text_offset;
text_right = r.right - WD_MATRIX_RIGHT;
}
- for (byte i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->count; i++) {
- int y = r.top + WD_MATRIX_TOP + i * this->resize.step_height;
+ int y = Center(r.top, this->resize.step_height);
+ for (byte i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->count; i++, y += this->resize.step_height) {
bool selected = this->selected_index == i + this->vscroll->GetPosition();
if (this->index[i + this->vscroll->GetPosition()] == INVALID_INDUSTRYTYPE) {
@@ -451,8 +454,8 @@ public:
/* Draw the name of the industry in white is selected, otherwise, in orange */
DrawString(text_left, text_right, y, indsp->name, selected ? TC_WHITE : TC_ORANGE);
- GfxFillRect(icon_left, y + 1, icon_right, y + 7, selected ? PC_WHITE : PC_BLACK);
- GfxFillRect(icon_left + 1, y + 2, icon_right - 1, y + 6, indsp->map_colour);
+ GfxFillRect(icon_left, y + 1, icon_right, y + square_size, selected ? PC_WHITE : PC_BLACK);
+ GfxFillRect(icon_left + 1, y + 2, icon_right - 1, y + square_size - 1, indsp->map_colour);
}
break;
}
@@ -591,6 +594,21 @@ public:
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE);
+ MoveAllWindowsOffScreen();
+ }
+
+ virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
+ {
+ VpSelectTilesWithMethod(pt.x, pt.y, select_method);
+ }
+
+ virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
+ {
+ if (pt.x == -1) return;
+ assert(end_tile == start_tile);
+
+ MoveAllHiddenWindowsBackToScreen();
bool success = true;
/* We do not need to protect ourselves against "Random Many Industries" in this mode */
const IndustrySpec *indsp = GetIndustrySpec(this->selected_type);
@@ -608,14 +626,14 @@ public:
_generating_world = true;
_ignore_restrictions = true;
- DoCommandP(tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed,
+ DoCommandP(end_tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed,
CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), &CcBuildIndustry);
cur_company.Restore();
_ignore_restrictions = false;
_generating_world = false;
} else {
- success = DoCommandP(tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY));
+ success = DoCommandP(end_tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY));
}
/* If an industry has been built, just reset the cursor and the system */
@@ -653,6 +671,7 @@ public:
virtual void OnPlaceObjectAbort()
{
+ MoveAllHiddenWindowsBackToScreen();
this->RaiseButtons();
}
@@ -675,7 +694,7 @@ public:
void ShowBuildIndustryWindow()
{
if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return;
- if (BringWindowToFrontById(WC_BUILD_INDUSTRY, 0)) return;
+ DeleteToolbarLinkedWindows();
new BuildIndustryWindow();
}
@@ -818,7 +837,7 @@ public:
if (first) {
if (has_accept) y += WD_PAR_VSEP_WIDE;
DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE);
- y += FONT_HEIGHT_NORMAL;
+ y += this->editable == EA_RATE ? GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) : FONT_HEIGHT_NORMAL;
if (this->editable == EA_RATE) this->production_offset_y = y;
first = false;
}
@@ -833,8 +852,10 @@ public:
if (this->editable == EA_RATE) {
DrawArrowButtons(left + WD_FRAMETEXT_LEFT, y, COLOUR_YELLOW, (this->clicked_line == IL_RATE1 + j) ? this->clicked_button : 0,
i->production_rate[j] > 0, i->production_rate[j] < 255);
+ y += GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
+ } else {
+ y += FONT_HEIGHT_NORMAL;
}
- y += FONT_HEIGHT_NORMAL;
}
/* Display production multiplier if editable */
@@ -846,7 +867,7 @@ public:
DrawString(x, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LEVEL);
DrawArrowButtons(left + WD_FRAMETEXT_LEFT, y, COLOUR_YELLOW, (this->clicked_line == IL_MULTIPLIER) ? this->clicked_button : 0,
i->prod_level > PRODLEVEL_MINIMUM, i->prod_level < PRODLEVEL_MAXIMUM);
- y += FONT_HEIGHT_NORMAL;
+ y += GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
}
/* Get the extra message for the GUI */
@@ -894,12 +915,14 @@ public:
case EA_NONE: break;
case EA_MULTIPLIER:
- if (IsInsideBS(pt.y, this->production_offset_y, FONT_HEIGHT_NORMAL)) line = IL_MULTIPLIER;
+ if (IsInsideBS(pt.y, this->production_offset_y, SETTING_BUTTON_HEIGHT)) line = IL_MULTIPLIER;
break;
case EA_RATE:
if (pt.y >= this->production_offset_y) {
- int row = (pt.y - this->production_offset_y) / FONT_HEIGHT_NORMAL;
+ if ((pt.y - this->production_offset_y) % GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) > (uint)SETTING_BUTTON_HEIGHT) break;;
+
+ int row = (pt.y - this->production_offset_y) / GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
for (uint j = 0; j < lengthof(i->produced_cargo); j++) {
if (i->produced_cargo[j] == CT_INVALID) continue;
row--;
@@ -1115,7 +1138,7 @@ static const NWidgetPart _nested_industry_directory_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
+ NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetSizingType(NWST_STEP), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(),
EndContainer(),
@@ -1320,7 +1343,7 @@ public:
case WID_ID_INDUSTRY_LIST: {
int n = 0;
- int y = r.top + WD_FRAMERECT_TOP;
+ int y = Center(r.top, this->resize.step_height);
if (this->industries.Length() == 0) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_DIRECTORY_NONE);
break;
@@ -1363,7 +1386,7 @@ public:
for (uint i = 0; i < this->industries.Length(); i++) {
d = maxdim(d, GetStringBoundingBox(this->GetIndustryString(this->industries[i])));
}
- resize->height = d.height;
+ resize->height = d.height = GetMinSizing(NWST_STEP, d.height);
d.height *= 5;
d.width += padding.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
diff --git a/src/ini.cpp b/src/ini.cpp
index 905ebfacf8..c8ea89c1d2 100644
--- a/src/ini.cpp
+++ b/src/ini.cpp
@@ -15,7 +15,7 @@
#include "string_func.h"
#include "fileio_func.h"
-#if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500)
+#if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) || defined(__ANDROID__)
# include
#endif
diff --git a/src/intro_gui.cpp b/src/intro_gui.cpp
index 3659b033cf..e47ed730f5 100644
--- a/src/intro_gui.cpp
+++ b/src/intro_gui.cpp
@@ -27,6 +27,7 @@
#include "language.h"
#include "rev.h"
#include "highscore.h"
+#include "tutorial_gui.h"
#include "widgets/intro_widget.h"
@@ -158,13 +159,14 @@ struct SelectGameWindow : public Window {
}
break;
case WID_SGI_AI_SETTINGS: ShowAIConfigWindow(); break;
+ case WID_SGI_TUTORIAL: ShowTutorialWindow(); break;
case WID_SGI_EXIT: HandleExitGameRequest(); break;
}
}
};
static const NWidgetPart _nested_select_game_widgets[] = {
- NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_INTRO_CAPTION, STR_NULL),
+ NWidget(WWT_CAPTION, COLOUR_BROWN), SetSizingType(NWST_BUTTON), SetDataTip(STR_INTRO_CAPTION, STR_NULL),
NWidget(WWT_PANEL, COLOUR_BROWN),
NWidget(NWID_SPACER), SetMinimalSize(0, 8),
@@ -258,11 +260,11 @@ static const NWidgetPart _nested_select_game_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(0, 6),
/* 'exit program' button */
- NWidget(NWID_HORIZONTAL),
- NWidget(NWID_SPACER), SetFill(1, 0),
- NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_EXIT), SetMinimalSize(128, 12),
- SetDataTip(STR_INTRO_QUIT, STR_INTRO_TOOLTIP_QUIT),
- NWidget(NWID_SPACER), SetFill(1, 0),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_TUTORIAL), SetMinimalSize(158, 12),
+ SetDataTip(STR_ABOUT_MENU_TUTORIAL, STR_TUTORIAL_WINDOW_TOOLTIP), SetPadding(0, 0, 0, 10), SetFill(1, 0),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_EXIT), SetMinimalSize(158, 12),
+ SetDataTip(STR_INTRO_QUIT, STR_INTRO_TOOLTIP_QUIT), SetPadding(0, 10, 0, 0), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 8),
diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt
index 377c928460..1ef0469866 100644
--- a/src/lang/afrikaans.txt
+++ b/src/lang/afrikaans.txt
@@ -4965,3 +4965,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt
index 1cd5332615..f195723a87 100644
--- a/src/lang/arabic_egypt.txt
+++ b/src/lang/arabic_egypt.txt
@@ -4418,3 +4418,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/basque.txt b/src/lang/basque.txt
index 1db1ed48eb..437cfdc295 100644
--- a/src/lang/basque.txt
+++ b/src/lang/basque.txt
@@ -4828,3 +4828,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt
index 221f6f1573..1ae8bf5049 100644
--- a/src/lang/belarusian.txt
+++ b/src/lang/belarusian.txt
@@ -5437,3 +5437,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt
index fdc960e950..da8132cbd2 100644
--- a/src/lang/brazilian_portuguese.txt
+++ b/src/lang/brazilian_portuguese.txt
@@ -4965,3 +4965,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt
index 4adbc74de7..bfe620384c 100644
--- a/src/lang/bulgarian.txt
+++ b/src/lang/bulgarian.txt
@@ -4878,3 +4878,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt
index 7d407a0b68..e429a750b3 100644
--- a/src/lang/catalan.txt
+++ b/src/lang/catalan.txt
@@ -4973,3 +4973,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt
index cbb33f95e1..a6af03ac15 100644
--- a/src/lang/croatian.txt
+++ b/src/lang/croatian.txt
@@ -5105,3 +5105,35 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}Udžbenik
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Prikaži legendu mape / opis simbola na mapi
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Okomita alatna traka
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Glavna alatna traka je podijeljena na dvije okomite alatne trake na rubovima ekrana
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Veličina tipki
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Veličina svih elemenata korisničkog sučelja
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Veličina fonta
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Veličina svih fontova u igri
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Potvrdi akcije
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Prikaži dijalog potvrde pri gradnji cesta i stanica
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Postavi dubinu boja videa na 8 bitova po pikselu, ovaj način podržava animaciju vode
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Postavi dubinu boja videa na 16 bitova po pikselu, za ovo treba restart, ovaj način ne podržava animaciju vode
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Postavi dubinu boja videa na 24 bita po pikselu, ovaj način podržava animaciju vode
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}Zatvori sve otvorene prozore (osim zakačenih)
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}Pritisnuti za procjenu troškova izvođenja neke akcije
+STR_TABLET_CTRL_TOOLTIP :{BLACK}Koristiti za sve akcije za koje se koristi tipka "CTRL"
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}Videi za učenje
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Otvori prikazivač videa za gledanje videa za učenje
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Građenje cesta i stanica, kupnja vozila
+STR_TUTORIAL_RAILWAYS :{BLACK}Pruge i vlakovi
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Cestovna vozila
+STR_TUTORIAL_SHIPS :{BLACK}Brodovi i dokovi
+STR_TUTORIAL_CARGO :{BLACK}Vrste tereta
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Učitaj sa mreže
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Učitaj igru sa mrežne pohrane podataka
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Spremi na mrežu
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Spremi igru na mrežnu pohranu podataka
diff --git a/src/lang/czech.txt b/src/lang/czech.txt
index b053b507af..24dd66aeb1 100644
--- a/src/lang/czech.txt
+++ b/src/lang/czech.txt
@@ -5187,3 +5187,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/danish.txt b/src/lang/danish.txt
index 5fdc19c51c..6f4cc0dad5 100644
--- a/src/lang/danish.txt
+++ b/src/lang/danish.txt
@@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt
index 541d07b146..3d1c075c1e 100644
--- a/src/lang/dutch.txt
+++ b/src/lang/dutch.txt
@@ -4967,3 +4967,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/english.txt b/src/lang/english.txt
index 505356f08f..399c11cbf4 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -468,7 +468,7 @@ STR_NEWS_MENU_MESSAGE_HISTORY_MENU :Message history
############ range for about menu starts
STR_ABOUT_MENU_LAND_BLOCK_INFO :Land area information
-STR_ABOUT_MENU_SEPARATOR :
+STR_ABOUT_MENU_TUTORIAL :{BLACK}Tutorial
STR_ABOUT_MENU_TOGGLE_CONSOLE :Toggle console
STR_ABOUT_MENU_AI_DEBUG :AI/Game script debug
STR_ABOUT_MENU_SCREENSHOT :Screenshot
@@ -717,6 +717,7 @@ STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Show lan
STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Click on an industry type to toggle displaying it. Ctrl+Click disables all types except the selected one. Ctrl+Click on it again to enable all industry types
STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Click on a company to toggle displaying its property. Ctrl+Click disables all companies except the selected one. Ctrl+Click on it again to enable all companies
STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Click on a cargo to toggle displaying its property. Ctrl+Click disables all cargoes except the selected one. Ctrl+Click on it again to enable all cargoes
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Show map legend / description of map symbols
STR_SMALLMAP_LEGENDA_ROADS :{TINY_FONT}{BLACK}Roads
STR_SMALLMAP_LEGENDA_RAILROADS :{TINY_FONT}{BLACK}Railways
@@ -1211,6 +1212,20 @@ STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :Select on which
STR_CONFIG_SETTING_SIGNALSIDE_LEFT :On the left
STR_CONFIG_SETTING_SIGNALSIDE_DRIVING_SIDE :On the driving side
STR_CONFIG_SETTING_SIGNALSIDE_RIGHT :On the right
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Vertical toolbar
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Main toolbar is split into two vertical toolbars on the sides of the screen
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Button size
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Size of all user interface elements
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Font size
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Size of all game fonts
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Confirm actions
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Show confirmation dialog when building roads and stations
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Set video color depth to 8 bits per pixel, this video mode supports water animation
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Set video color depth to 16 bits per pixel, this requires restart, this video mode does not support water animation
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Set video color depth to 24 bits per pixel, this video mode supports water animation
STR_CONFIG_SETTING_SHOWFINANCES :Show finances window at the end of the year: {STRING2}
STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT :If enabled, the finances window pops up at the end of each year to allow easy inspection of the financial status of the company
STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT :New orders are 'non-stop' by default: {STRING2}
@@ -2477,6 +2492,13 @@ STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Raise a
STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Level an area of land to the height of the first selected corner. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate
STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Shift toggles building/showing cost estimate
+STR_TABLET_CLOSE :{BLACK}X
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}Close all opened windows (except pinned ones)
+STR_TABLET_SHIFT :{BLACK}{TINY_FONT}Shft
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}Press it for getting an estimated cost of executing an action
+STR_TABLET_CTRL :{BLACK}{TINY_FONT}Ctrl
+STR_TABLET_CTRL_TOOLTIP :{BLACK}Use it for actions that use the "CTRL" key
+
# Object construction window
STR_OBJECT_BUILD_CAPTION :{WHITE}Object Selection
STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Shift toggles building/showing cost estimate
@@ -2691,6 +2713,14 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original
STR_ABOUT_VERSION :{BLACK}OpenTTD version {REV}
STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2017 The OpenTTD team
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}Tutorial videos
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Open a video player to watch tutorial videos
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Building roads and stations, buying vehicles
+STR_TUTORIAL_RAILWAYS :{BLACK}Railways and trains
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Road vehicles
+STR_TUTORIAL_SHIPS :{BLACK}Ships and docks
+STR_TUTORIAL_CARGO :{BLACK}Cargo types
+
# Save/load game/scenario
STR_SAVELOAD_SAVE_CAPTION :{WHITE}Save Game
STR_SAVELOAD_LOAD_CAPTION :{WHITE}Load Game
@@ -2709,6 +2739,10 @@ STR_SAVELOAD_SAVE_TOOLTIP :{BLACK}Save the
STR_SAVELOAD_LOAD_BUTTON :{BLACK}Load
STR_SAVELOAD_LOAD_TOOLTIP :{BLACK}Load the selected game
STR_SAVELOAD_LOAD_HEIGHTMAP_TOOLTIP :{BLACK}Load the selected heightmap
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Load from network
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Load a game from the network storage
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Save to network
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Back up the game to the network storage
STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Game Details
STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No information available
STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING1}
diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt
index abdac23882..955949e744 100644
--- a/src/lang/english_AU.txt
+++ b/src/lang/english_AU.txt
@@ -4912,3 +4912,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt
index e67bb2c06b..1f8bbb9a4c 100644
--- a/src/lang/english_US.txt
+++ b/src/lang/english_US.txt
@@ -4970,3 +4970,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt
index 67abcfc9ed..f5f0859fab 100644
--- a/src/lang/esperanto.txt
+++ b/src/lang/esperanto.txt
@@ -4320,3 +4320,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt
index 4ce9d63471..e3e9ac6d88 100644
--- a/src/lang/estonian.txt
+++ b/src/lang/estonian.txt
@@ -5022,3 +5022,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt
index b121d9cb86..8fc695bf85 100644
--- a/src/lang/faroese.txt
+++ b/src/lang/faroese.txt
@@ -4468,3 +4468,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt
index 25bcabe338..0a9a2363af 100644
--- a/src/lang/finnish.txt
+++ b/src/lang/finnish.txt
@@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/french.txt b/src/lang/french.txt
index 33af65666f..e288eaa1b3 100644
--- a/src/lang/french.txt
+++ b/src/lang/french.txt
@@ -4973,3 +4973,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt
index 3722eb1634..34badf27cc 100644
--- a/src/lang/gaelic.txt
+++ b/src/lang/gaelic.txt
@@ -5350,3 +5350,35 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}Oideachadh
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Seall treòir a' mhapa / tuairisgeulan air samhlaidhean a' mhapa
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Bàr-inneal inghearach
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Thèid am prìomh bhàr-inneal a sgoltadh 'na bhàraichean-inneal inghearach ri dà thaobh an sgrìn
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Meud nam putan
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Meud aig a h-uile nì an eadar-aghaidh
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Meud a' chrutha-chlò
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Meud aig a h-uile cruth-clò a' gheama
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Dearbhaich na gnìomhan
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Seall còmhradh dearbhaidh le togail rathaidean is stèiseanan
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 biod
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Suidhich doimhneachd nan dath aig a' video gu 8 biod gach piogsail. Cuiridh am modh video sin taic ri beòthachadh uisge
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 biod
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Suidhich doimhneachd nan dath aig a' video gu 16 biod gach piogsail. Bidh feum air ath-thòiseachadh. Cha chuir am modh video sin taic ri beòthachadh uisge
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 biod
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Suidhich doimhneachd nan dath aig a' video gu 24 biod gach piogsail. Cuiridh am modh video sin taic ri beòthachadh uisge
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}Dùin a h-uile uinneag (seach an fheadhainn phrìnichte)
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}Brùth air gus tuairmse air cosgaisean gnìomha fhaighinn
+STR_TABLET_CTRL_TOOLTIP :{BLACK}Cleachd e airson gnìomhan a chleachdas an iuchair "CTRL"
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}Videothan oideachaidh
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Fosgail cluicheadair video gus coimhead air videothan oideachaidh
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Togail rathaidean is stèiseanan, ceannach charbadan
+STR_TUTORIAL_RAILWAYS :{BLACK}Slighean rèile is trèanaichean
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Carbadan-rathaid
+STR_TUTORIAL_SHIPS :{BLACK}Longan is puirt
+STR_TUTORIAL_CARGO :{BLACK}Seòrsaichean carago
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Luchdaich on lìonra
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Luchdaich geama o stòras an lìonraidh
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Sàbhail dhan lìonra
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Cuir lethbhreac-glèidhidh dhen gheama gu stòras an lìonraidh
diff --git a/src/lang/galician.txt b/src/lang/galician.txt
index b097f4daef..d38d58c894 100644
--- a/src/lang/galician.txt
+++ b/src/lang/galician.txt
@@ -4902,3 +4902,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/german.txt b/src/lang/german.txt
index 8a7bf51d33..2b70696012 100644
--- a/src/lang/german.txt
+++ b/src/lang/german.txt
@@ -4965,3 +4965,35 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}Tutorial
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Zeige Kartenlegende / Beschreibung der Kartensymbole
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Vertikale Werkzeugsleiste
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Hauptwerzeugleiste ist in zwei vertikale Leisten an den Bildschirmseiten aufgeteilt
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Schaltflächengröße
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Größe aller Elemente der Benutzeroberfläche
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Schriftartgröße
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Größe aller Schriftarten
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Aktionen bestätigen
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Zeige Bestätigungsdialog bei Straßen- und Haltenstellebau
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Setzt die Farbtiefe auf 8 Bits per Pixel. Dieser Modus unterstützt Wasseranimation
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Setzt die Farbtiefe auf 16 Bit per Pixel. Erfordert Neustart und dieser Modus unterstützt keine Wasseranimation
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Setzt die Farbtiefe auf 24 Bits per Pixel. Dieser Modus unterstützt Wasseranimation
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}Schließe alle offene Fenster (außer Festgepinnte)
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}Drücke hier, um eine Kostenabschätzung für die Durchführung einer Aktion zu erhalten
+STR_TABLET_CTRL_TOOLTIP :{BLACK}Für Aktionen benutzen, welche die "STRG" Taste benutzen
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}Tutorial Videos
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Öffne einen Videoplayer, um Tutorial videos anzuschauen
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Strassen und Haltestellen bauen, Fahrzeuge kaufen
+STR_TUTORIAL_RAILWAYS :{BLACK}Eisenbahnen und Züge
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Straßenfahrzeuge
+STR_TUTORIAL_SHIPS :{BLACK}Schiffe und Docks
+STR_TUTORIAL_CARGO :{BLACK}Warentypen
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Laden vom Netzwerk
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Öffne ein Spiel aus dem Netzwerkspeicher
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Speichern ins Netzwerk
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Spiel zurück in den Netzwerkspeicher backupen
diff --git a/src/lang/greek.txt b/src/lang/greek.txt
index 8659667126..a3204f0c66 100644
--- a/src/lang/greek.txt
+++ b/src/lang/greek.txt
@@ -5089,3 +5089,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt
index ef3bb5070a..9a77ac9853 100644
--- a/src/lang/hebrew.txt
+++ b/src/lang/hebrew.txt
@@ -4980,3 +4980,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt
index fd4f1338d7..875cd7b974 100644
--- a/src/lang/hungarian.txt
+++ b/src/lang/hungarian.txt
@@ -5069,3 +5069,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt
index 55a54c2d6c..5913d617f6 100644
--- a/src/lang/icelandic.txt
+++ b/src/lang/icelandic.txt
@@ -4721,3 +4721,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt
index 35b8db2522..9e9f563c52 100644
--- a/src/lang/indonesian.txt
+++ b/src/lang/indonesian.txt
@@ -4960,3 +4960,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/irish.txt b/src/lang/irish.txt
index b8a262e858..ac31316d4d 100644
--- a/src/lang/irish.txt
+++ b/src/lang/irish.txt
@@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/italian.txt b/src/lang/italian.txt
index cb75eaf927..6eb33e4d0b 100644
--- a/src/lang/italian.txt
+++ b/src/lang/italian.txt
@@ -5002,3 +5002,35 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}Istruzioni
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Mostra la legenda della mappa / descrizione dei simboli della mappa
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Barra degli strumenti verticale
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}La barra degli strumenti è divisa in due barre verticali sui lati dello schermo
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Dimensioni dei pulsanti
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Dimensioni degli elementi dell'interfaccia
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Dimensioni dei caratteri
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Dimensioni dei caratteri nel gioco
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Conferma
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Mostra il dialogo di conferma durante la costruzione di strade e stazioni
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Imposta i colori a 8 bit per pixel. Questa modalità video supporta l'animazione dell'acqua
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Imposta i colori a 16 bit per pixel (richiede il riavvio). Questa modalità video non supporta l'animazione dell'acqua
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Imposta i colori a 24 bit per pixel. Questa modalità video supporta l'animazione dell'acqua
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}Chiude tutte le schermate aperte (eccetto quelle permanenti)
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}Premi questo tasto per una stima dei costi dell'azione desiderata
+STR_TABLET_CTRL_TOOLTIP :{BLACK}Usa per le azioni che usano il tasto "CTRL"
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}Video di aiuto
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Apri un'applicazione video per guardare i video di aiuto
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Costruzione di strade e stazioni; acquisto di veicoli
+STR_TUTORIAL_RAILWAYS :{BLACK}Ferrovie e treni
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Veicoli stradali
+STR_TUTORIAL_SHIPS :{BLACK}Navi e attracchi
+STR_TUTORIAL_CARGO :{BLACK}Tipi di merce
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Carica dalla rete
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Carica il gioco dalla memoria di rete
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Salva sulla rete
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Salva il gioco nella memoria di rete
diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt
index 251c68b55f..0981bc21d1 100644
--- a/src/lang/japanese.txt
+++ b/src/lang/japanese.txt
@@ -4968,3 +4968,35 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}チュートリアル
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}マップシンボルについての説明の表示
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}垂直ツールバー
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}メインツールバーはスクリーンの両脇に垂直に2つに分割しています
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}ボタンサイズ
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}すべてのユーザーインターフェースの構成サイズ
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}フォントサイズ
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}全てのゲームのフォント
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}アクションの確認
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}道路とステーションの建設時に確認のダイアログの表示
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}色深度を8 bppに設定します 再起動が必要です このビデオモードは水のアニメーションに対応していません
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}色深度を16 bppに設定します 再起動が必要です このビデオモードは水のアニメーションに対応していません
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}色深度を24 bppに設定します 再起動が必要です このビデオモードは水のアニメーションに対応していません
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}全ての開いているウィンドウを閉じます (固定してあるものは除く)
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}押すことでアクションの決定時に費用の見積もりができます
+STR_TABLET_CTRL_TOOLTIP :{BLACK} "CTRL" キーを使うアクションのために使います
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}チュートリアル動画
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}チュートリアル動画を見るためにビデオプレイヤーを開きます
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}道路とステーションの建設と、車両の購入
+STR_TUTORIAL_RAILWAYS :{BLACK}鉄道と列車
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}道路車両
+STR_TUTORIAL_SHIPS :{BLACK}船とドック
+STR_TUTORIAL_CARGO :{BLACK}貨物のタイプ
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}ネットワークからロード
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}ネットワークストレージからゲームをロード
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}ネットワークにセーブ
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}ネットワークストレージにゲームをバックアップ
diff --git a/src/lang/korean.txt b/src/lang/korean.txt
index d05ab967eb..d2ffc5d7ce 100644
--- a/src/lang/korean.txt
+++ b/src/lang/korean.txt
@@ -4973,3 +4973,35 @@ STR_PLANE :{G=f}{BLACK}{PL
STR_SHIP :{G=f}{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}튜토리얼
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}지도 범례 / 기호 설명을 보여줌
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}수직 작업창
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}메인 작업창이 두 개의 화면 양쪽 두개의 수직 작업창으로 나뉨
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}버튼 크기
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}모든 사용자 인터페이스의 크기
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}폰트 크기
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}게임 내부 폰트의 크기
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}명령 확인
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}도로와 정류장을 건설시 확인 팝업을 보임
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8비트
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}그래픽 색상 깊이를 픽셀당 8비트로 설정합니다. 이 그래픽 모드는 물이 흐르는 애니메이션 효과를 표현할 수 있습니다.
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16비트
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}그래픽 색상 깊이를 픽셀당 16비트로 설정합니다. 이 그래픽 모드는 물이 흐르는 애니메이션 효과를 표현할 수 있습니다.
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24비트
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}그래픽 색상 깊이를 픽셀당 24비트로 설정합니다. 이 그래픽 모드는 물이 흐르는 애니메이션 효과를 표현할 수 있습니다.
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}열려있는 모든 창 닫기 (고정된 창 제외)
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}이 행동을 하기 위한 예상 비용을 알아보려면 누르세요.
+STR_TABLET_CTRL_TOOLTIP :{BLACK}"컨트롤"키를 이용하는 명령을 위해 사용
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}튜토리얼 영상
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}튜토리얼 영상을 보기 위해 비디오 플레이어를 열기
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}도로, 역 건설 및 차량 구입
+STR_TUTORIAL_RAILWAYS :{BLACK}선로 및 열차
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}차량
+STR_TUTORIAL_SHIPS :{BLACK}선박과 항구
+STR_TUTORIAL_CARGO :{BLACK}화물 종류
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}네트워크에서 불러오기
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}네트워크 저장소에서 불러오기
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}네트워크에 저장
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}네트워크 저장소로 게임을 백업
diff --git a/src/lang/latin.txt b/src/lang/latin.txt
index 380ac68537..dc352b4ba5 100644
--- a/src/lang/latin.txt
+++ b/src/lang/latin.txt
@@ -5289,3 +5289,35 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}Rudimentum
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Monstrare formulam graphicam / descriptionem tabulae
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Arca instrumentorum directa
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Si vis, arca instrumentorum prima dividitur in partes duas apud margines scrinii
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Magnitudo globulorum
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Magnitudo omnium elementorum interfaciei
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Magnitudo fontis typographici
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Magnitudo omnium fontium typographicorum in ludo
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Confirmare
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Monstrare confirmationem dum struuntur stationes viaeque
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8bpp
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Eligere modum coloris 8bpp; hic sinit colores aquae moventes
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16bpp
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Eligere modum coloris 16bpp (necesse erit programma exire et resumere); hic NON sinit colores aquae moventes
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24bpp
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Eligere modum coloris 24bpp; hic sinit colores aquae moventes
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}Claudere omnes fenestras (sed non glutinosas)
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}Preme ut aestimatio actionis monstretur
+STR_TABLET_CTRL_TOOLTIP :{BLACK}Utendum est ad actiones cum "CTRL"
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}Rudimenta visifica
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Aperire programma visificum ad rudimenta videnda
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Viae stationesque, emptio vehiculorum
+STR_TUTORIAL_RAILWAYS :{BLACK}Ferriviae traminaque
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Vehicula viaria
+STR_TUTORIAL_SHIPS :{BLACK}Naves navaliaque
+STR_TUTORIAL_CARGO :{BLACK}Genera onerum
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Legere e nebula
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Arcessere ludum "e nebula" (i.e. ex Interreti)
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Servare in nebula
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Conservare ludum "in nebula" (i.e. in Interreti)
diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt
index f75d381b39..ae7d7b2022 100644
--- a/src/lang/latvian.txt
+++ b/src/lang/latvian.txt
@@ -4880,3 +4880,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt
index f9067c5567..5801865906 100644
--- a/src/lang/lithuanian.txt
+++ b/src/lang/lithuanian.txt
@@ -5504,3 +5504,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt
index 37aec445da..b326e3876a 100644
--- a/src/lang/luxembourgish.txt
+++ b/src/lang/luxembourgish.txt
@@ -4967,3 +4967,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/malay.txt b/src/lang/malay.txt
index 7779ea9504..262ff6d81b 100644
--- a/src/lang/malay.txt
+++ b/src/lang/malay.txt
@@ -4588,3 +4588,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt
index e8bd624a0f..79d846a025 100644
--- a/src/lang/norwegian_bokmal.txt
+++ b/src/lang/norwegian_bokmal.txt
@@ -4969,3 +4969,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt
index aa455f5efe..93b02de68a 100644
--- a/src/lang/norwegian_nynorsk.txt
+++ b/src/lang/norwegian_nynorsk.txt
@@ -4878,3 +4878,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/polish.txt b/src/lang/polish.txt
index 206530f09f..167c332ea8 100644
--- a/src/lang/polish.txt
+++ b/src/lang/polish.txt
@@ -5390,3 +5390,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt
index 552456b081..eec05e2755 100644
--- a/src/lang/portuguese.txt
+++ b/src/lang/portuguese.txt
@@ -4965,3 +4965,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt
index 1a3e29f479..21fd638859 100644
--- a/src/lang/romanian.txt
+++ b/src/lang/romanian.txt
@@ -4918,3 +4918,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/russian.txt b/src/lang/russian.txt
index fc53374e3c..7c26137f5a 100644
--- a/src/lang/russian.txt
+++ b/src/lang/russian.txt
@@ -5199,3 +5199,35 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}Учебник
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Показывать миникарту / легенду
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Вертикальное меню
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Меню разделено на два вертикальных меню по краям экрата
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Размер кнопок
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Размер элементов интерфейса
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Размер шрифта
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Размер всех шрифтов в игре
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Подтверждать действия
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Показывать окно подтверждения при постройки дорог и станций
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 бит
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Установить глубину цвета в 16 бит на точку. Этот режим поддерживает анимацию воды
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 бит
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Установить глубину цвета в 16 бит на точку. Это потребует перезапуска программы. Этот режим не поддерживает анимацию воды
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 бит
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Установить глубину цвета в 24 бит на точку. Этот режим поддерживает анимацию воды
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}Закрыть все открытые окна (кроме закреплённых)
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}Использовать в качестве кнопки "SHIFT" (оценка стоимости)
+STR_TABLET_CTRL_TOOLTIP :{BLACK}Использовать в качестве кнопки "CTRL"
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}Учебные видео
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Открыть видеоплеер для просмотра учебного видео
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Постройка дорог и терминалов, покупка автомобилей
+STR_TUTORIAL_RAILWAYS :{BLACK}Железные дороги и поезда
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Автомобили
+STR_TUTORIAL_SHIPS :{BLACK}Корабли и пристани
+STR_TUTORIAL_CARGO :{BLACK}Грузы
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Загрузка из сети
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Загрузить игру из сетевого хранилища
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Сохранение в сети
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Сохранить игру в сетевое хранилище
diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt
index 61f848e8b3..1ba80e1d9e 100644
--- a/src/lang/serbian.txt
+++ b/src/lang/serbian.txt
@@ -5175,3 +5175,29 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}Priručnik
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Prikaži legendu mape / opis simbola na mapi
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Vertikalna alatna traka
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Glavna alatna traka je podeljena na dve okomite alatne trake na rubovima ekrana
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Veličina dugmeta
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Veličina svih elemenata korisničkog interfejsa
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Veličina slova
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Veličina svih slova u igri
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Potvrdi akcije
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Prikaži dijalog potvrde pri gradnji drumova i stanica
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}Zatvori sve otvorene prozore (osim zakačenih)
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}Pritisnite za dobivanje procene troškova odabrane akcije
+STR_TABLET_CTRL_TOOLTIP :{BLACK}Koristite za sve akcije za koje se koristi tipka "CTRL"
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}Video za učenje
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Otvori video plejer za gledanje videa za učenje
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Gradnja cesta i stanica, kupovina vozila
+STR_TUTORIAL_RAILWAYS :{BLACK}Šine i vozovi
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Drumska vozila
+STR_TUTORIAL_SHIPS :{BLACK}Brodovi i dokovi
+STR_TUTORIAL_CARGO :{BLACK}Tip tereta
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Učitaj igru sa mreže
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Učitaj igru sa mrežne pohrane podataka
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Spremi igru na mrežu
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Spremi igru na mrežu
diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt
index 6be975993f..028aa7cc68 100644
--- a/src/lang/simplified_chinese.txt
+++ b/src/lang/simplified_chinese.txt
@@ -4964,3 +4964,35 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}教程
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}在地图上显示图例/描述
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}垂直工具栏
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}将主工具栏分为屏幕两侧的两个垂直工具栏
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}按键大小
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}用户界面大小
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}字体大小
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}游戏字体大小
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}确认操作
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}建立道路和车站时显示确认对话框
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}将视频颜色深度设置为8位像素,此模式支持水面动态涟漪
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}将视频颜色深度设置为16位像素,这需要重新启动,此模式不支持水面动态涟漪
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}将视频颜色深度设置为24位像素,此模式支持水面动态涟漪
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}关闭所有打开的窗口(已固定的窗口除外)
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}按住显示预计费用
+STR_TABLET_CTRL_TOOLTIP :{BLACK}将其用于“CTRL”键的操作
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}教程视频
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}使用视频播放器观看教程视频
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}建设道路和车站,购买车辆
+STR_TUTORIAL_RAILWAYS :{BLACK}铁路和火车
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}公路车辆
+STR_TUTORIAL_SHIPS :{BLACK}船只和码头
+STR_TUTORIAL_CARGO :{BLACK}货物类型
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}读取云端存档
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}从云端储存读取游戏
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}保存到云端储存
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}备份游戏到云端储存
diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt
index 539b5379d7..506c5329f0 100644
--- a/src/lang/slovak.txt
+++ b/src/lang/slovak.txt
@@ -5033,3 +5033,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt
index 1cd9a11aa9..881e6a3a1c 100644
--- a/src/lang/slovenian.txt
+++ b/src/lang/slovenian.txt
@@ -5162,3 +5162,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt
index 37b033277d..f458bca1f5 100644
--- a/src/lang/spanish.txt
+++ b/src/lang/spanish.txt
@@ -4967,3 +4967,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt
index c2de0c7009..fbf6f84609 100644
--- a/src/lang/spanish_MX.txt
+++ b/src/lang/spanish_MX.txt
@@ -127,7 +127,11 @@ STR_QUANTITY_TOFFEE :{WEIGHT_LONG} d
STR_QUANTITY_BATTERIES :{COMMA} pila{P "" s}
STR_QUANTITY_PLASTIC :{VOLUME_LONG} de plásticos
STR_QUANTITY_FIZZY_DRINKS :{COMMA} refresco{P "" s}
+<<<<<<< HEAD
+STR_QUANTITY_N_A :Ninguna
+=======
STR_QUANTITY_N_A :N/A
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
# Two letter abbreviation of cargo name
STR_ABBREV_NOTHING :
@@ -301,7 +305,11 @@ STR_SORT_BY_WAITING_TOTAL :Cargamento tota
STR_SORT_BY_WAITING_AVAILABLE :Cargamento disponible en espera
STR_SORT_BY_RATING_MAX :Valoración más alta de cargamento
STR_SORT_BY_RATING_MIN :Valoración más baja de cargamento
+<<<<<<< HEAD
+STR_SORT_BY_ENGINE_ID :Id. de locomotora (orden clásico)
+=======
STR_SORT_BY_ENGINE_ID :EngineID (classic sort)Id. locomotora (orden clásico)
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_SORT_BY_COST :Costo
STR_SORT_BY_POWER :Potencia
STR_SORT_BY_TRACTIVE_EFFORT :Fuerza de tracción
@@ -379,7 +387,11 @@ STR_SETTINGS_MENU_NEWGRF_SETTINGS :Configuración
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opciones de transparencia
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Mostrar nombres de pueblos
STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :Mostrar nombres de estaciones
+<<<<<<< HEAD
+STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Mostrar puestos guías
+=======
STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Mostrar puntos guías
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_SETTINGS_MENU_SIGNS_DISPLAYED :Mostrar carteles propios
STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS :Mostrar carteles y nombres del competidor
STR_SETTINGS_MENU_FULL_ANIMATION :Animación completa
@@ -893,7 +905,11 @@ STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Selecci
############ start of currency region
STR_GAME_OPTIONS_CURRENCY_GBP :Libra británica (GBP)
+<<<<<<< HEAD
+STR_GAME_OPTIONS_CURRENCY_USD :Dólar americano (USD)
+=======
STR_GAME_OPTIONS_CURRENCY_USD :Dólar estadounidense (USD)
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_GAME_OPTIONS_CURRENCY_EUR :Euro (EUR)
STR_GAME_OPTIONS_CURRENCY_JPY :Yen japonés (¥)
STR_GAME_OPTIONS_CURRENCY_ATS :Chelín austríaco (ATS)
@@ -1008,7 +1024,11 @@ STR_ERROR_FULLSCREEN_FAILED :{WHITE}El modo
# Custom currency window
STR_CURRENCY_WINDOW :{WHITE}Moneda personalizada
+<<<<<<< HEAD
+STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Tasa de cambio: {ORANGE}{CURRENCY_LONG} = £ {COMMA}
+=======
STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Tasa de cambio: {ORANGE} {CURRENCY_LONG} = £ {COMMA}
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Reducir el valor de la moneda por una libra (£)
STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Incrementar el valor de la moneda por una libra (£)
STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP :{BLACK}Ajustar el valor de cambio de la moneda por una Libra (£)
@@ -1027,7 +1047,11 @@ STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Establec
STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Cambiar a euro antes
STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Cambiar a euro después
+<<<<<<< HEAD
+STR_CURRENCY_PREVIEW :{LTBLUE}Vista previa: {ORANGE}{CURRENCY_LONG}
+=======
STR_CURRENCY_PREVIEW :{LTBLUE}Vista previa: {ORANGE} {CURRENCY_LONG}
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 libras (£) en la moneda
STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Cambiar parámetro de moneda personalizada
@@ -1097,11 +1121,19 @@ STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Plegar t
STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(no hay explicación disponible)
STR_CONFIG_SETTING_DEFAULT_VALUE :{LTBLUE}Valor predeterminado: {ORANGE}{STRING}
STR_CONFIG_SETTING_TYPE :{LTBLUE}Tipo de opción: {ORANGE}{STRING}
+<<<<<<< HEAD
+STR_CONFIG_SETTING_TYPE_CLIENT :Opción de cliente (no se almacena en partidas guardadas, afecta a todas las partidas)
+STR_CONFIG_SETTING_TYPE_GAME_MENU :Opción de partida (se almacena en las partidas guardadas, afecta solamente a nuevas partidas)
+STR_CONFIG_SETTING_TYPE_GAME_INGAME :Opción de partida (almacenada en la partida guardada, afecta solamente a la partida actual)
+STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Opción de empresa (se almacena en las partidas guardadas, afecta solamente a las nuevas partidas)
+STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Opción de empresa (almacenada en la partida guardada, afecta solamente a la empresa actual)
+=======
STR_CONFIG_SETTING_TYPE_CLIENT :Opción de cliente (no se almacena en partidas guardadas, afecta todas las partidas)
STR_CONFIG_SETTING_TYPE_GAME_MENU :Opción de partida (se almacena en las partidas guardadas, afecta solamente partidas nuevas)
STR_CONFIG_SETTING_TYPE_GAME_INGAME :Opción de partida (almacenada en la partida guardada, afecta solamente la partida actual)
STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Opción de empresa (se almacena en las partidas guardadas, afecta solamente las partidas nuevas)
STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Opción de empresa (almacenada en la partida guardada, afecta solamente la empresa actual)
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}Categoría:
STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Tipo:
@@ -1114,11 +1146,19 @@ STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW :Opciones con un
STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT :{BLACK}Restringir la lista a ciertos tipos de opciones
STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL :Todos los tipos de opciones
+<<<<<<< HEAD
+STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT :Opciones de cliente (no se almacena en partidas guardadas, afecta a todas las partidas)
+STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :Opciones de juego (se almacena en las partidas guardadas, afecta solamente a partidas nuevas)
+STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Opciones de juego (se almacena en las partidas guardadas, afecta solamente a la partida actual)
+STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Opciones de empresa (se almacena en las partidas guardadas, afecta solamente a partidas nuevas)
+STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Opciones de empresa (se almacena en las partidas guardadas, afecta solamente a la empresa actual)
+=======
STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT :Opciones de cliente (no se almacena en partidas guardadas, afecta todas las partidas)
STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :Opciones de juego (se almacena en las partidas guardadas, afecta solamente partidas nuevas)
STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Opciones de juego (se almacena en las partidas guardadas, afecta solamente la partida actual)
STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Opciones de empresa (se almacena en las partidas guardadas, afecta solamente partidas nuevas)
STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Opciones de empresa (se almacena en las partidas guardadas, afecta solamente la empresa actual)
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CONFIG_SETTING_CATEGORY_HIDES :{BLACK}Mostrar todos los resultados por opción de configuración{}{SILVER}Categoría {BLACK}a {WHITE}{STRING}
STR_CONFIG_SETTING_TYPE_HIDES :{BLACK}Mostrar todos los resultados por opción de configuración{}{SILVER}Tipo {BLACK}a {WHITE}Todos los tipos de opción
STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}Mostrar todos los resultados por opción de configuración{}{SILVER}Categoría {BLACK}a {WHITE}{STRING} {BLACK}y {SILVER}Tipo {BLACK}a {WHITE}Todos los tipos de opción
@@ -1148,7 +1188,11 @@ STR_CONFIG_SETTING_RUNNING_COSTS :Costos de opera
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Nivel de los costos de mantenimiento y operación de vehículos e infraestructura
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Velocidad de construcción: {STRING}
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Restringir la velocidad de las acciones de construcción de jugadores no humanos
+<<<<<<< HEAD
+STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Descomposturas de vehículos: {STRING}
+=======
STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Averías de vehículos: {STRING}
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT :Controlar cada cuánto los vehículos con poco mantenimiento sufren fallas
STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER :Multiplicador de subsidio: {STRING}
STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :Establecer cuánto se paga por subsidios conectados
@@ -1161,7 +1205,11 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Si se activa, l
STR_CONFIG_SETTING_DISASTERS :Desastres: {STRING}
STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Desastres que ocasionalmente pueden bloquear o destruir vehículos o infraestructura
STR_CONFIG_SETTING_CITY_APPROVAL :Actitud de los ayuntamientos ante restructuraciones hechas en sus zonas: {STRING}
+<<<<<<< HEAD
+STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :En qué medida el ruido y el daño ambiental causado por las empresas afectan su evaluación y futuras acciones de construcción en las mismas zonas
+=======
STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Medida en que el ruido y el daño ambiental causado por las empresas afectan su evaluación y futuras acciones de construcción en las mismas zonas
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CONFIG_SETTING_MAX_HEIGHTLEVEL :Elevación máxima del mapa: {STRING}
STR_CONFIG_SETTING_MAX_HEIGHTLEVEL_HELPTEXT :Elevación máxima que las montañas pueden tener en el mapa
@@ -1230,7 +1278,11 @@ STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT :Todas las vista
STR_CONFIG_SETTING_BRIBE :Permitir sobornos al ayuntamiento: {STRING}
STR_CONFIG_SETTING_BRIBE_HELPTEXT :Las empresas pueden tratar de sobornar a los ayuntamientos. Si el soborno es descubierto por un inspector, la empresa no podrá realizar actividades en la localidad durante seis meses
STR_CONFIG_SETTING_ALLOW_EXCLUSIVE :Permitir adquirir los derechos de transporte exclusivos: {STRING}
+<<<<<<< HEAD
+STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Si una empresa adquiere los derechos de transporte exclusivos en un pueblo, las estaciones de la competencia (pasajeros o cargamento) no recibirán nada para transportar durante un año
+=======
STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Si una empresa adquiere los derechos de transporte exclusivos en un pueblo, las estaciones de la competencia (de pasajeros o carga) no recibirán nada que entregar durante un año
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS :Permitir la construcción de nuevos edificios: {STRING}
STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT :Las empresas aportan dinero a los ayuntamientos para que construyan nuevas casas y edificios
STR_CONFIG_SETTING_ALLOW_FUND_ROAD :Permitir el pago de la reconstrucción de las carreteras locales: {STRING}
@@ -1290,7 +1342,11 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Grosor de las l
STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Grosor de las líneas en las gráficas. Una línea fina es más precisa, una línea más gruesa es más fácil de distinguir
STR_CONFIG_SETTING_LANDSCAPE :Terreno: {STRING}
+<<<<<<< HEAD
+STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Los terrenos definen mapas con diferentes tipos de cargamentos y requisitos de crecimiento para los pueblos. Es posible modificarlos empleando NewGRF y scripts de juego
+=======
STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Los terrenos definen mapas con diferentes tipos de carga y requisitos de crecimiento para los pueblos. Es posible modificarlos empleando NewGRF y scripts de juego
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CONFIG_SETTING_LAND_GENERATOR :Generador de terreno: {STRING}
STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT :El generador 'Original' depende de los gráficos base y crea formas de terreno fijas. 'TerraGenesis' es un generador basado en Ruido Perlin que permite un mayor control de configuración
STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL :Original
@@ -1473,8 +1529,13 @@ STR_CONFIG_SETTING_SERVINT_AIRCRAFT :Intervalo de ma
STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT :Intervalo de mantenimiento predeterminado para nuevas aeronaves, en caso de no definirse otro explícitamente
STR_CONFIG_SETTING_SERVINT_SHIPS :Intervalo de mantenimiento predeterminado para barcos: {STRING}
STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT :Intervalo de mantenimiento predeterminado para nuevos barcos, en caso de no definirse otro explícitamente
+<<<<<<< HEAD
+STR_CONFIG_SETTING_NOSERVICE :Desactivar mantenimiento si las descomposturas están desactivadas: {STRING}
+STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Al activarse, los vehículos no recibirán mantenimiento si no pueden descomponerse
+=======
STR_CONFIG_SETTING_NOSERVICE :Desactivar mantenimiento si las averías están desactivadas: {STRING}
STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Al activarse, los vehículos no recibirán mantenimiento si no pueden averiarse
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Activar límites de velocidad para vagones: {STRING}
STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Al activarse, se tienen en cuenta los límites de velocidad de los vagones para decidir la máxima velocidad de un tren
STR_CONFIG_SETTING_DISABLE_ELRAILS :Desactivar ferrocarriles eléctricos: {STRING}
@@ -1522,8 +1583,13 @@ STR_CONFIG_SETTING_SMOOTH_ECONOMY :Activar econom
STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Al activarse, habrá cambios de producción en las industrias más frecuentemente y en escala menor. Si se usa un NewGRF con industrias adicionales esta opción generalmente no tiene efecto
STR_CONFIG_SETTING_ALLOW_SHARES :Permitir comprar acciones de otras empresas: {STRING}
STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Al activarse, se pueden comprar y vender acciones de otras empresas. Las acciones de una empresa solamente estarán disponibles cuando la empresa cumpla una edad determinada
+<<<<<<< HEAD
+STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Porcentaje de la utilidad total a pagar por transferencias de cargamento: {STRING}
+STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Porcentaje de utilidad cedida a los transportes intermedios en sistemas de transferencias de cargamento, dando un mayor control sobre la utilidad de cada vehículo
+=======
STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Porcentaje de la utilidad total a pagar por transferencias de carga: {STRING}
STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Porcentaje de utilidad cedida a los transportes intermedios en sistemas de transferencia de carga, dando un mayor control sobre la utilidad de cada vehículo
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Al arrastrar, colocar señales cada: {STRING}
STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT :Distancia de separación entre señales hasta topar con algún obstáculo (otra señal, un desvío, etc.) al instalarlas mediante arrastre con el ratón
STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE :{COMMA} casilla{P 0 "" s}
@@ -1564,7 +1630,11 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Permitido
STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Permitido, diseño urbano personalizado
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Crecimiento de árboles durante la partida: {STRING}
+<<<<<<< HEAD
+STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Controlar la aparición aleatoria de árboles durante la partida. Esto puede afectar a industrias que dependen del crecimiento de árboles, como los aserraderos
+=======
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Controlar la aparición aleatoria de árboles durante la partida. Esto puede afectar industrias que dependen del crecimiento de árboles, como los aserraderos
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NONE :Ninguno {RED}(inutiliza aserraderos)
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_RAINFOREST :Solo en selva
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_ALL :Cualquier parte
@@ -1623,7 +1693,11 @@ STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :'Asimétrica' s
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisión de la distribución: {STRING}
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Si el valor es alto, se requerirá mayor tiempo para calcular la gráfica de distribución (si se lleva demasiado tiempo, se notará desfase en el juego). Si es muy bajo, la distribución será imprecisa, pudiendo hacer que el cargamento no vaya al lugar indicado
STR_CONFIG_SETTING_DEMAND_DISTANCE :Efecto de la distancia en la demanda: {STRING}
+<<<<<<< HEAD
+STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Con un valor diferente a 0, la distancia entre la estación de origen de cierto cargamento y una posible estación de destino afectará a la cantidad de cargamento que se envíe entre ambas. Cuanto más lejos estén entre sí, menos cargamento se enviará. Cuanto mayor sea el valor de esta opción, menos cargamento se enviará a estaciones distantes en favor de estaciones cercanas
+=======
STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Con un valor diferente a 0, la distancia entre la estación de origen de cierta carga y una posible estación de destino afectará la cantidad de cargamento que se envíe entre ambas. Cuanto más lejos estén entre sí, menos cargamento se enviará. Cuanto mayor sea el valor de esta opción, menos cargamento se enviará a estaciones distantes en favor de estaciones cercanas
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CONFIG_SETTING_DEMAND_SIZE :Cantidad de cargamento a devolver en modo simétrico: {STRING}
STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Establecer un valor menor de 100% hará que la distribución simétrica de cargamento sea más asimétrica. Se enviará menos cargamento de regreso forzosamente si una cantidad determinada es enviada a una estación. Si se fija a 0%, la distribución simétrica será como una distribución asimétrica
STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Nivel de saturación de rutas cortas antes de cambiar a rutas de mayor capacidad: {STRING}
@@ -1685,7 +1759,11 @@ STR_CONFIG_SETTING_ENVIRONMENT :{ORANGE}Ambient
STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES :{ORANGE}Autoridades
STR_CONFIG_SETTING_ENVIRONMENT_TOWNS :{ORANGE}Pueblos
STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Industrias
+<<<<<<< HEAD
+STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distribución de cargamento
+=======
STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distribución de carga
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_CONFIG_SETTING_AI :{ORANGE}Competidores
STR_CONFIG_SETTING_AI_NPC :{ORANGE}Jugadores no humanos
@@ -1762,7 +1840,10 @@ STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Revisar
STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Mostrar configuración de scripts
STR_INTRO_TOOLTIP_QUIT :{BLACK}Salir de 'OpenTTD'
+<<<<<<< HEAD
+=======
STR_INTRO_BASESET :{BLACK}A los gráficos base elegidos les hace falta {NUM} spirte{P "" s}. Necesitan actualizarse.
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_INTRO_TRANSLATION :{BLACK}A esta traducción le falta{P 0 "" n} {NUM} cadena{P "" s}. Considera ayudar a mejorar OpenTTD convirtiéndote en traductor. Consulta el archivo readme.txt para más detalles.
# Quit window
@@ -2272,7 +2353,11 @@ STR_TRANSPARENT_SIGNS_TOOLTIP :{BLACK}Activar
STR_TRANSPARENT_TREES_TOOLTIP :{BLACK}Activar o desactivar transparencia para árboles. Ctrl+Clic para excluir de tecla rápida 'X'
STR_TRANSPARENT_HOUSES_TOOLTIP :{BLACK}Activar o desactivar transparencia para casas. Ctrl+Clic para excluir de tecla rápida 'X'
STR_TRANSPARENT_INDUSTRIES_TOOLTIP :{BLACK}Activar o desactivar transparencia para industrias. Ctrl+Clic para excluir de tecla rápida 'X'
+<<<<<<< HEAD
+STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Activar o desactivar transparencia para edificios como estaciones, depósitos o puestos guías. Ctrl+Clic para excluir de tecla rápida 'X'
+=======
STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Activar o desactivar transparencia para edificios como estaciones, depósitos o puntos guías. Ctrl+Clic para excluir de tecla rápida 'X'
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Activar o desactivar transparencia para puentes. Ctrl+Clic para excluir de tecla rápida 'X'
STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Activar o desactivar transparencia para estructuras como faros o antenas. Ctrl+Clic para excluir de tecla rápida 'X'
STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Activar o desactivar transparencia para catenaria. Ctrl+Clic para excluir de tecla rápida 'X'
@@ -2303,7 +2388,11 @@ STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Provee:
STR_JOIN_STATION_CAPTION :{WHITE}Ampliar estación
STR_JOIN_STATION_CREATE_SPLITTED_STATION :{YELLOW}Construir aparte
+<<<<<<< HEAD
+STR_JOIN_WAYPOINT_CAPTION :{WHITE}Unir puestos guías
+=======
STR_JOIN_WAYPOINT_CAPTION :{WHITE}Unir puntos guías
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT :{YELLOW}Construir aparte
# Rail construction toolbar
@@ -2333,8 +2422,13 @@ STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION :{WHITE}Orientac
STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP :{BLACK}Elegir la orientación del depósito de trenes
# Rail waypoint construction window
+<<<<<<< HEAD
+STR_WAYPOINT_CAPTION :{WHITE}Puesto guía
+STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Elegir el tipo de puesto guía
+=======
STR_WAYPOINT_CAPTION :{WHITE}Punto guía
STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Elegir el tipo de punto guía
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
# Rail station construction window
STR_STATION_BUILD_RAIL_CAPTION :{WHITE}Selección de estación
@@ -2351,7 +2445,11 @@ STR_STATION_BUILD_STATION_CLASS_TOOLTIP :{BLACK}Mostrar
STR_STATION_BUILD_STATION_TYPE_TOOLTIP :{BLACK}Construir el tipo de estación elegida
STR_STATION_CLASS_DFLT :Estación predeterminada
+<<<<<<< HEAD
+STR_STATION_CLASS_WAYP :Puestos guías
+=======
STR_STATION_CLASS_WAYP :Puntos guías
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
# Signal window
STR_BUILD_SIGNAL_CAPTION :{WHITE}Selección de señales
@@ -2432,7 +2530,11 @@ STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}Construi
STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP :{BLACK}Construir esclusa. Mayús muestra una estimación del precio
STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Construir astillero (para comprar y dar mantenimiento a barcos). Mayús muestra una estimación del precio
STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Construir muelles. Ctrl activa la ampliación de estaciones. Mayús muestra una estimación del precio
+<<<<<<< HEAD
+STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Colocar boya para utilizar como puesto guía marítimo. Mayús muestra una estimación del precio
+=======
STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Colocar boya para utilizar como punto guía marítimo. Mayús muestra una estimación del precio
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Construir acueducto. Mayús muestra una estimación del precio
STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Definir cuerpo de agua.{}Crea un canal, a menos que se pulse Ctrl en un área al nivel del mar, en cuyo caso se inundarán los alrededores
STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Colocar ríos
@@ -2591,7 +2693,10 @@ STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Nombre d
STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Cargamento recibido: {LTBLUE}
STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING})
+<<<<<<< HEAD
+=======
STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Tipo de vía: {LTBLUE}{STRING}
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Límite de velocidad de ferrocarril: {LTBLUE}{VELOCITY}
STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Límite de velocidad de carretera: {LTBLUE}{VELOCITY}
@@ -2604,6 +2709,31 @@ STR_LAI_CLEAR_DESCRIPTION_FIELDS :Campos
STR_LAI_CLEAR_DESCRIPTION_SNOW_COVERED_LAND :Terreno nevado
STR_LAI_CLEAR_DESCRIPTION_DESERT :Desierto
+<<<<<<< HEAD
+STR_LAI_RAIL_DESCRIPTION_TRACK :Vía de {STRING}
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Vía de {STRING} con señales de bloqueo
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Vía de {STRING} con señales de entrada
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXITSIGNALS :Vía de {STRING} con señales de salida
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBOSIGNALS :Vía de {STRING} con señales de combo
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS :Vía de {STRING} con señales de ruta
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS :Vía de {STRING} con señales de ruta de un solo sentido
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS :Vía de {STRING} con señales de bloqueo y señales de entrada
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS :Vía de {STRING} con señales de bloqueo y señales de salida
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS :Vía de {STRING} con señales de bloqueo y señales combo
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS :Vía de {STRING} con señales de bloqueo y señales de ruta
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS :Vía de {STRING} con señales de bloqueo y señales de ruta de un solo sentido
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS :Vía de {STRING} con señales de entrada y señales de salida
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS :Vía de {STRING} con señales de entrada y señales combo
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS :Vía de {STRING} con señales de entrada y señales de ruta
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS :Vía de {STRING} con señales de entrada y señales de ruta de un solo sentido
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS :Vía de {STRING} con señales de salida y señales de combo
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS :Vía de {STRING} con señales de salida y señales de ruta
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS :Vía de {STRING} con señales de salida y señales de ruta de un solo sentido
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Vía de {STRING} con señales de combo y señales de ruta
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Vía de {STRING} con señales de combo y señales de ruta de un solo sentido
+STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Vía de {STRING} con señales de ruta y señales de ruta de un solo sentido
+STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Depósito ({STRING})
+=======
STR_LAI_RAIL_DESCRIPTION_TRACK :Vías férreas
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Vías férreas con señales de bloqueo
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Vías férreas con señales de entrada
@@ -2627,6 +2757,7 @@ STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Vías férreas
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Vías férreas con señales combo y de ruta de un solo sentido
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Vías férreas con señales de ruta y de ruta de un solo sentido
STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Depósito (trenes)
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_LAI_ROAD_DESCRIPTION_ROAD :Carretera
STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Carretera con alumbrado
@@ -2649,7 +2780,11 @@ STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Estación de ca
STR_LAI_STATION_DESCRIPTION_BUS_STATION :Parada de autobús
STR_LAI_STATION_DESCRIPTION_SHIP_DOCK :Muelle
STR_LAI_STATION_DESCRIPTION_BUOY :Boya
+<<<<<<< HEAD
+STR_LAI_STATION_DESCRIPTION_WAYPOINT :puesto guía
+=======
STR_LAI_STATION_DESCRIPTION_WAYPOINT :Punto guía
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_LAI_WATER_DESCRIPTION_WATER :Agua
STR_LAI_WATER_DESCRIPTION_CANAL :Canal
@@ -2690,7 +2825,11 @@ STR_LAI_OBJECT_DESCRIPTION_COMPANY_OWNED_LAND :Terreno propied
STR_ABOUT_OPENTTD :{WHITE}Acerca de OpenTTD
STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Copyright original {COPYRIGHT} 1995 Chris Sawyer, Todos los derechos reservados
STR_ABOUT_VERSION :{BLACK}OpenTTD versión {REV}
+<<<<<<< HEAD
+STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2016, el equipo de OpenTTD
+=======
STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2017, el equipo de OpenTTD
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
# Save/load game/scenario
STR_SAVELOAD_SAVE_CAPTION :{WHITE}Guardar partida
@@ -2816,7 +2955,11 @@ STR_NEWGRF_SETTINGS_UPGRADE :{BLACK}Actualiz
STR_NEWGRF_SETTINGS_UPGRADE_TOOLTIP :{BLACK}Actualizar los archivos NewGRF que lo requieran a la versión más reciente
STR_NEWGRF_SETTINGS_FILE_TOOLTIP :{BLACK}Lista de archivos NewGRF instalados
+<<<<<<< HEAD
+STR_NEWGRF_SETTINGS_SET_PARAMETERS :{BLACK}Establecer parámetros
+=======
STR_NEWGRF_SETTINGS_SET_PARAMETERS :{BLACK}Parámetros
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_NEWGRF_SETTINGS_SHOW_PARAMETERS :{BLACK}Mostrar parámetros
STR_NEWGRF_SETTINGS_TOGGLE_PALETTE :{BLACK}Cambiar paleta
STR_NEWGRF_SETTINGS_TOGGLE_PALETTE_TOOLTIP :{BLACK}Cambia la paleta del NewGRF elegido.{}Esto es necesario cuando los gráficos de un NewGRF se ven de color rosa durante el juego
@@ -2909,6 +3052,11 @@ STR_NEWGRF_ERROR_INVALID_ID :Intento de usar
STR_NEWGRF_ERROR_CORRUPT_SPRITE :{YELLOW}{STRING} contiene un sprite con errores. Todos los sprites con errores se muestran como un símbolo de interrogación rojo (?)
STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Contiene múltiples entradas de Acción 8 (sprite {3:NUM})
STR_NEWGRF_ERROR_READ_BOUNDS :La lectura excedió el límite de pseudo-sprite (sprite {3:NUM})
+<<<<<<< HEAD
+STR_NEWGRF_ERROR_MISSING_SPRITES :{WHITE}A los gráficos base actualmente en uso les faltan algunos sprites.{}Los gráficos base deben ser actualizados
+STR_NEWGRF_ERROR_MISSING_SPRITES_UNSTABLE :{WHITE}A los gráficos base actualmente en uso les faltan algunos sprites.{}Los gráficos base deben ser actualizados.{}Dado que esta es una {YELLOW}versión de desarrollo de OpenTTD{WHITE}, es posible que también se requiera una {YELLOW}versión de desarrollo de los gráficos base{WHITE}
+=======
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_NEWGRF_ERROR_GRM_FAILED :Recursos GRF solicitados no disponibles (sprite {3:NUM})
STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} fue desactivado por {STRING}
STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Formato de colocación de sprites no válido o desconocido (sprite {3:NUM})
@@ -3172,12 +3320,21 @@ STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}No permi
# Waypoint/buoy view window
STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT}
+<<<<<<< HEAD
+STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Centrar vista en ubicación del puesto guía. Ctrl+Clic abre una ventana de vista en dicha ubicación
+STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}Cambiar nombre de puesto guía
+STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Centrar la vista en la ubicación de la boya. Ctrl+Clic abre una ventana de vista en dicha ubicación
+STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}Cambiar nombre de boya
+
+STR_EDIT_WAYPOINT_NAME :{WHITE}Cambiar nombre de puesto guía
+=======
STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Centrar vista en ubicación del punto guía. Ctrl+Clic abre una ventana de vista en dicha ubicación
STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}Cambiar nombre de punto guía
STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Centrar la vista en la ubicación de la boya. Ctrl+Clic abre una ventana de vista en dicha ubicación
STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}Cambiar nombre de boya
STR_EDIT_WAYPOINT_NAME :{WHITE}Cambiar nombre de punto guía
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
# Finances window
STR_FINANCES_CAPTION :{WHITE}Finanzas de {COMPANY} {BLACK}{COMPANY_NUM}
@@ -3295,8 +3452,14 @@ STR_INDUSTRY_VIEW_REQUIRES_CARGO_CARGO :{BLACK}Requiere
STR_INDUSTRY_VIEW_REQUIRES_CARGO_CARGO_CARGO :{BLACK}Requiere: {YELLOW}{STRING}{STRING}, {STRING}{STRING}, {STRING}{STRING}
############ range for requires ends
+<<<<<<< HEAD
+############ range for produces starts
+STR_INDUSTRY_VIEW_WAITING_FOR_PROCESSING :{BLACK}Cargamento esperando a ser procesado:
+STR_INDUSTRY_VIEW_WAITING_STOCKPILE_CARGO :{YELLOW}{CARGO_LONG}{STRING}{BLACK}
+=======
############ range for produces starts
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_INDUSTRY_VIEW_PRODUCES_CARGO :{BLACK}Produce: {YELLOW}{STRING}{STRING}
STR_INDUSTRY_VIEW_PRODUCES_CARGO_CARGO :{BLACK}Produce: {YELLOW}{STRING}{STRING}, {STRING}{STRING}
############ range for produces ends
@@ -3557,10 +3720,17 @@ STR_REPLACE_REPLACING_WHEN_OLD :{ENGINE} cuando
STR_REPLACE_VEHICLES_STOP :{BLACK}Dejar de reemplazar vehículos
STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Presionar este botón para detener el reemplazo del vehículo situado a la izquierda
+<<<<<<< HEAD
+STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Reemplazando: {ORANGE}{STRING}
+STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Cambiar entre reemplazo de vagón y locomotora
+STR_REPLACE_ENGINES :Locomotoras
+STR_REPLACE_WAGONS :Vagones
+=======
STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Cambiar entre reemplazo de vagón y locomotora
STR_REPLACE_ENGINES :Locomotoras
STR_REPLACE_WAGONS :Vagones
STR_REPLACE_ALL_RAILTYPE :Todos los vehículos ferroviarios
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_REPLACE_HELP_RAILTYPE :{BLACK}Elegir el tipo de vías férreas para las que se desea reemplazar locomotoras
STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Mostrar el vehículo que reemplazará al otro de la izquierda
@@ -3619,7 +3789,11 @@ STR_VEHICLE_VIEW_AIRCRAFT_STATE_START_STOP_TOOLTIP :{BLACK}Activida
STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}Cargando/Descargando
STR_VEHICLE_STATUS_LEAVING :{LTBLUE}Partiendo
STR_VEHICLE_STATUS_CRASHED :{RED}¡Accidentado!
+<<<<<<< HEAD
+STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}Descompuesto
+=======
STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}Averiado
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_VEHICLE_STATUS_STOPPED :{RED}Detenido
STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL :{RED}Deteniéndose, {VELOCITY}
STR_VEHICLE_STATUS_TRAIN_NO_POWER :{RED}Sin potencia
@@ -3658,7 +3832,11 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {L
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potencia: {LTBLUE}{POWER}{BLACK} Velocidad máx.: {LTBLUE}{VELOCITY} {BLACK}F.T. máx.: {LTBLUE}{FORCE}
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Utilidad este año: {LTBLUE}{CURRENCY_LONG} (año pasado: {CURRENCY_LONG})
+<<<<<<< HEAD
+STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidad: {LTBLUE}{COMMA}% {BLACK}Descomposturas desde el último mantenimiento: {LTBLUE}{COMMA}
+=======
STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidad: {LTBLUE}{COMMA}% {BLACK}Averías desde el último mantenimiento: {LTBLUE}{COMMA}
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Construido: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY_LONG}
STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacidad: {LTBLUE}Ninguna{STRING}
@@ -3773,7 +3951,11 @@ STR_ORDER_DROP_REFIT_AUTO_ANY :Cargamento disp
STR_ORDER_SERVICE :{BLACK}Mantenimiento
STR_ORDER_DROP_GO_ALWAYS_DEPOT :Ir siempre
+<<<<<<< HEAD
+STR_ORDER_DROP_SERVICE_DEPOT :Mantenimiento si es necesario
+=======
STR_ORDER_DROP_SERVICE_DEPOT :Mantto. si es necesario
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_ORDER_DROP_HALT_DEPOT :Detenerse
STR_ORDER_SERVICE_TOOLTIP :{BLACK}Ignorar esta orden a menos que el mantenimiento sea necesario
@@ -3815,7 +3997,11 @@ STR_ORDER_GO_TO_NEAREST_DEPOT :Ir al depósito
STR_ORDER_GO_TO_NEAREST_HANGAR :Ir al hangar más cercano
STR_ORDER_CONDITIONAL :Salto de orden condicional
STR_ORDER_SHARE :Compartir órdenes
+<<<<<<< HEAD
+STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Añadir nueva orden antes de la orden marcada o añadirla al final de la lista. Ctrl+Clic sobre una estación para establecer la orden a 'Cargar máx. cualquier carga', sobre un puesto guía para 'Sin paradas' y sobre un depósito para 'Mantenimiento' (esta última desactivará el mantenimiento automático). Ctrl+Clic sobre otro vehículo para hacer que ambos compartan siempre las mismas órdenes. Clic sobre un vehículo para copiar sus órdenes (sin compartirlas).
+=======
STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Añadir nueva orden antes de la orden marcada o añadirla al final de la lista. Ctrl+Clic sobre una estación para establecer la orden a 'Cargar máx. cualquier carga', sobre un punto guía para 'Sin paradas' y sobre un depósito para 'Mantenimiento' (esta última desactivará el mantenimiento automático). Ctrl+Clic sobre otro vehículo para hacer que ambos compartan siempre las mismas órdenes. Clic sobre un vehículo para copiar sus órdenes (sin compartirlas).
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Ver todos los vehículos que comparten el mismo itinerario
@@ -4240,6 +4426,17 @@ STR_ERROR_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Primero
STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Primero se debe demoler el aeropuerto
# Waypoint related errors
+<<<<<<< HEAD
+STR_ERROR_WAYPOINT_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Se amplía más de un puesto guía existente
+STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT :{WHITE}Demasiado cerca de otro puesto guía
+
+STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT :{WHITE}No se puede construir el puesto guía aquí...
+STR_ERROR_CAN_T_POSITION_BUOY_HERE :{WHITE}No se puede colocar la boya aquí...
+STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME :{WHITE}No se puede cambiar nombre del puesto guía...
+
+STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT :{WHITE}No se puede quitar el puesto guía de aquí...
+STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST :{WHITE}Primero se debe retirar el puesto guía
+=======
STR_ERROR_WAYPOINT_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Se amplía más de un punto guía existente
STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT :{WHITE}Demasiado cerca de otro punto guía
@@ -4249,6 +4446,7 @@ STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME :{WHITE}No se pu
STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT :{WHITE}No se puede quitar el punto guía de aquí...
STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST :{WHITE}Primero se debe retirar el punto guía
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_ERROR_BUOY_IN_THE_WAY :{WHITE}... una boya obstaculiza
STR_ERROR_BUOY_IS_IN_USE :{WHITE}... ¡boya en uso por otra empresa!
@@ -4860,7 +5058,11 @@ STR_FORMAT_BUOY_NAME_SERIAL :Boya {TOWN} #{C
STR_FORMAT_COMPANY_NUM :(Empresa {COMMA})
STR_FORMAT_GROUP_NAME :Grupo {COMMA}
STR_FORMAT_INDUSTRY_NAME :{1:STRING}, {0:TOWN}
+<<<<<<< HEAD
+STR_FORMAT_WAYPOINT_NAME :Puesto guía {TOWN}
+=======
STR_FORMAT_WAYPOINT_NAME :Punto guía, {TOWN}
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
STR_FORMAT_WAYPOINT_NAME_SERIAL :Puesto guía #{1:COMMA}, {0:TOWN}
STR_FORMAT_DEPOT_NAME_TRAIN :Depósito de trenes, {TOWN}
@@ -4968,3 +5170,38 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+<<<<<<< HEAD
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}Guía de cómo jugar
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Mostrar leyenda o descripción de símbolos del mapa
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Barra de herramientas vertical
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}La barra de herramientas principal se divide en dos barras verticales laterales
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Tamaño de botones
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Tamaño de elementos de la interfaz
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Tamaño de letra
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Tamaño de letra de los elementos del juego
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Confirmar acciones
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Mostrar diálogo de confirmación al construir carreteras y estaciones
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bits
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Establecer profundidad de color de video a 8 bits por pixel. Este modo de video soporta animación de agua
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bits
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Establecer profundidad de color de video a 16 bits por pixel. Requiere reinicio. Este modo de video no soporta animación de agua
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bits
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Establecer profundidad de color de video a 24 bits por pixel. Este modo de video soporta animación de agua
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}Cerrar todas las ventanas abiertas, salvo las que estén fijas
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}Pulsar para ver una estimación del precio al realizar una acción
+STR_TABLET_CTRL_TOOLTIP :{BLACK}Emplearlo para acciones que utilizan la tecla "Ctrl"
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}Videos de guías de juego
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Abrir reproductor de video para ver guías de juego
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Construir carrerteras y estaciones; comprar vehículos
+STR_TUTORIAL_RAILWAYS :{BLACK}Vías férreas y trenes
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Vehículos de carretera
+STR_TUTORIAL_SHIPS :{BLACK}Barcos y muelles
+STR_TUTORIAL_CARGO :{BLACK}Cargamentos
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Cargar desde red
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Cargar partida desde almacenamiento en red
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Guardar en red
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Realizar respaldo en almacenamiento de red
+=======
+>>>>>>> d3de08088326415d55ef052dc858053ab4932584
diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt
index 1abfef52a5..90a1ae9c9f 100644
--- a/src/lang/swedish.txt
+++ b/src/lang/swedish.txt
@@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt
index 32c647fac1..e58907d6a7 100644
--- a/src/lang/tamil.txt
+++ b/src/lang/tamil.txt
@@ -4514,3 +4514,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/thai.txt b/src/lang/thai.txt
index 96fa8775f8..e44775b62c 100644
--- a/src/lang/thai.txt
+++ b/src/lang/thai.txt
@@ -4874,3 +4874,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt
index b12a1b1df6..3c08b38a19 100644
--- a/src/lang/traditional_chinese.txt
+++ b/src/lang/traditional_chinese.txt
@@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt
index 5352546c22..0cf3ab389c 100644
--- a/src/lang/turkish.txt
+++ b/src/lang/turkish.txt
@@ -4977,3 +4977,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt
index ef7d9ad9e4..fef78cb160 100644
--- a/src/lang/ukrainian.txt
+++ b/src/lang/ukrainian.txt
@@ -5132,3 +5132,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt
index e78a0d4eaa..25f8ae4a00 100644
--- a/src/lang/vietnamese.txt
+++ b/src/lang/vietnamese.txt
@@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt
index 56dfccdfd6..8028171425 100644
--- a/src/lang/welsh.txt
+++ b/src/lang/welsh.txt
@@ -4966,3 +4966,5 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp
index 1fe34fe79c..ca81fa18d8 100644
--- a/src/linkgraph/linkgraph_gui.cpp
+++ b/src/linkgraph/linkgraph_gui.cpp
@@ -347,6 +347,7 @@ NWidgetBase *MakeCargoesLegendLinkGraphGUI(int *biggest_index)
row = new NWidgetHorizontal(NC_EQUALSIZE);
}
NWidgetBackground * wid = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, i + WID_LGL_CARGO_FIRST);
+ wid->sizing_type = NWST_STEP;
wid->SetMinimalSize(25, FONT_HEIGHT_SMALL);
wid->SetFill(1, 1);
wid->SetResize(0, 0);
diff --git a/src/main_gui.cpp b/src/main_gui.cpp
index b13920a648..713629a8bf 100644
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -32,6 +32,8 @@
#include "linkgraph/linkgraph_gui.h"
#include "tilehighlight_func.h"
#include "hotkeys.h"
+#include "tutorial_gui.h"
+#include "gui.h"
#include "saveload/saveload.h"
@@ -340,7 +342,7 @@ struct MainWindow : Window
break;
}
- case GHK_RESET_OBJECT_TO_PLACE: ResetObjectToPlace(); break;
+ case GHK_RESET_OBJECT_TO_PLACE: ResetObjectToPlace(); ToolbarSelectLastTool(); break;
case GHK_DELETE_WINDOWS: DeleteNonVitalWindows(); break;
case GHK_DELETE_NONVITAL_WINDOWS: DeleteAllNonVitalWindows(); break;
case GHK_REFRESH_SCREEN: MarkWholeScreenDirty(); break;
@@ -463,6 +465,7 @@ struct MainWindow : Window
if (!gui_scope) return;
/* Forward the message to the appropriate toolbar (ingame or scenario editor) */
InvalidateWindowData(WC_MAIN_TOOLBAR, 0, data, true);
+ InvalidateWindowData(WC_MAIN_TOOLBAR_RIGHT, 0, data, true);
}
static HotkeyList hotkeys;
@@ -562,6 +565,15 @@ void SetupColoursAndInitialWindow()
default: NOT_REACHED();
case GM_MENU:
ShowSelectGameWindow();
+ ShowTutorialWindowOnceAfterInstall();
+ if (getenv("SDL_RESTART_PARAMS") != NULL) {
+ static int counter = 5; // This part of code is called several times during startup, which closes all windows, so we need to put random hacks here
+ counter--;
+ ShowGameOptions();
+#ifndef WIN32
+ if (counter == 0) unsetenv("SDL_RESTART_PARAMS");
+#endif
+ }
break;
case GM_NORMAL:
diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp
index 2d3871ffbd..6072adb29d 100644
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -26,6 +26,7 @@
#include "core/geometry_func.hpp"
#include "newgrf_debug.h"
#include "zoom_func.h"
+#include "build_confirmation_func.h"
#include "widgets/misc_widget.h"
@@ -33,6 +34,10 @@
#include "safeguards.h"
+#ifdef __ANDROID__
+#include
+#endif
+
/** Method to open the OSK. */
enum OskActivation {
OSKA_DISABLED, ///< The OSK shall not be activated at all.
@@ -533,6 +538,10 @@ void ShowAboutWindow()
*/
void ShowEstimatedCostOrIncome(Money cost, int x, int y)
{
+ if (ConfirmationWindowEstimatingCost()) {
+ ConfirmationWindowSetEstimatedCost(cost);
+ return;
+ }
StringID msg = STR_MESSAGE_ESTIMATED_COST;
if (cost < 0) {
@@ -684,6 +693,12 @@ struct TooltipsWindow : public Window
if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.total_offs.y - 5, scr_bot) - sm_height;
pt.x = sm_width >= _screen.width ? 0 : Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width);
+ // Move it to the top of the screen, away from mouse cursor, so it won't steal screen taps on Android
+ pt.y = GetMainViewTop();
+ if (_cursor.pos.y < pt.y + GetMinSizing(NWST_STEP)) {
+ pt.x = _cursor.pos.x > _screen.width / 2 ? GetMinSizing(NWST_STEP) : _screen.width - sm_width - GetMinSizing(NWST_STEP);
+ }
+
return pt;
}
@@ -692,7 +707,7 @@ struct TooltipsWindow : public Window
/* There is only one widget. */
for (uint i = 0; i != this->paramcount; i++) SetDParam(i, this->params[i]);
- size->width = min(GetStringBoundingBox(this->string_id).width, ScaleGUITrad(194));
+ size->width = min(GetStringBoundingBox(this->string_id).width, ScaleGUITrad(250));
size->height = GetStringHeight(this->string_id, size->width);
/* Increase slightly to have some space around the box. */
@@ -765,7 +780,7 @@ void QueryString::DrawEditBox(const Window *w, int wid) const
bool rtl = _current_text_dir == TD_RTL;
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 = GetMinSizing(NWST_BUTTON, sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT);
int clearbtn_left = wi->pos_x + (rtl ? 0 : wi->current_x - clearbtn_width);
int clearbtn_right = wi->pos_x + (rtl ? clearbtn_width : wi->current_x) - 1;
@@ -776,7 +791,7 @@ void QueryString::DrawEditBox(const Window *w, int wid) const
int bottom = wi->pos_y + wi->current_y - 1;
DrawFrameRect(clearbtn_left, top, clearbtn_right, bottom, wi->colour, wi->IsLowered() ? FR_LOWERED : FR_NONE);
- DrawSprite(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT, PAL_NONE, clearbtn_left + WD_IMGBTN_LEFT + (wi->IsLowered() ? 1 : 0), (top + bottom - sprite_size.height) / 2 + (wi->IsLowered() ? 1 : 0));
+ DrawSprite(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT, PAL_NONE, Center(clearbtn_left + wi->IsLowered(), clearbtn_width, sprite_size.width), Center(top + wi->IsLowered(), bottom - top, sprite_size.height));
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);
@@ -799,11 +814,12 @@ void QueryString::DrawEditBox(const Window *w, int wid) const
/* 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);
- DrawString(delta, tb->pixels, 0, tb->buf, TC_YELLOW);
+ DrawString(delta, tb->pixels, Center(0, bottom - top), tb->buf, TC_YELLOW);
+
bool focussed = w->IsWidgetGloballyFocused(wid) || IsOSKOpenedFor(w, wid);
if (focussed && tb->caret) {
int caret_width = GetStringBoundingBox("_").width;
- DrawString(tb->caretxoffs + delta, tb->caretxoffs + delta + caret_width, 0, "_", TC_WHITE);
+ DrawString(tb->caretxoffs + delta, tb->caretxoffs + delta + caret_width, Center(0, bottom - top), "_", TC_WHITE);
}
_cur_dpi = old_dpi;
@@ -934,6 +950,17 @@ void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bo
/* Open the OSK window */
ShowOnScreenKeyboard(w, wid);
}
+#ifdef __ANDROID__
+ char text[512];
+ strecpy(text, this->text.buf, lastof(text));
+ this->text.DeleteAll();
+ SDL_ANDROID_ToggleScreenKeyboardTextInput(text); // Invoke Android built-in screen keyboard, this will not block
+ /*
+ SDL_ANDROID_GetScreenKeyboardTextInput(text, sizeof(text) - 1); // Invoke Android built-in screen keyboard, this will block
+ this->text.Assign(text);
+ w->OnEditboxChanged(wid);
+ */
+#endif
}
/** Class for the string query window. */
@@ -1113,6 +1140,7 @@ struct QueryWindow : public Window {
{
if (widget != WID_Q_TEXT) return;
+ size->width = GetMinSizing(NWST_WINDOW_LENGTH, size->width);
Dimension d = GetStringMultiLineBoundingBox(this->message, *size);
d.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
diff --git a/src/music/libtimidity.cpp b/src/music/libtimidity.cpp
index 1cb2adc0f9..02542fc9b9 100644
--- a/src/music/libtimidity.cpp
+++ b/src/music/libtimidity.cpp
@@ -13,6 +13,7 @@
#include "../openttd.h"
#include "../sound_type.h"
#include "../debug.h"
+#include "../core/math_func.hpp"
#include "libtimidity.h"
#include
#include
@@ -22,6 +23,7 @@
#include
#include
#include
+#include
#if defined(PSP)
#include
#endif /* PSP */
@@ -53,14 +55,34 @@ static void AudioOutCallback(void *buf, unsigned int _reqn, void *userdata)
}
}
#endif /* PSP */
+#ifdef __ANDROID__
+/* Android does not have Midi chip, we have to route the libtimidity output through SDL audio output */
+void Android_MidiMixMusic(Sint16 *stream, int len)
+{
+ if (_midi.status == MIDI_PLAYING) {
+ Sint16 buf[16384];
+ while( len > 0 )
+ {
+ int minlen = min(sizeof(buf), len);
+ mid_song_read_wave(_midi.song, buf, min(sizeof(buf), len*2));
+ for( Uint16 i = 0; i < minlen; i++ )
+ stream[i] += buf[i];
+ stream += minlen;
+ len -= minlen;
+ }
+ }
+}
+#endif /* __ANDROID__ */
/** Factory for the libtimidity driver. */
static FMusicDriver_LibTimidity iFMusicDriver_LibTimidity;
+enum { TIMIDITY_MAX_VOLUME = 50 };
const char *MusicDriver_LibTimidity::Start(const char * const *param)
{
_midi.status = MIDI_STOPPED;
_midi.song = NULL;
+ volume = TIMIDITY_MAX_VOLUME; // Avoid clipping
if (mid_init(param == NULL ? NULL : const_cast(param[0])) < 0) {
/* If init fails, it can be because no configuration was found.
@@ -115,6 +137,7 @@ void MusicDriver_LibTimidity::PlaySong(const char *filename)
return;
}
+ mid_song_set_volume(_midi.song, volume);
mid_song_start(_midi.song);
_midi.status = MIDI_PLAYING;
}
@@ -142,5 +165,6 @@ bool MusicDriver_LibTimidity::IsSongPlaying()
void MusicDriver_LibTimidity::SetVolume(byte vol)
{
+ volume = vol * TIMIDITY_MAX_VOLUME / 127; // I'm not sure about that value
if (_midi.song != NULL) mid_song_set_volume(_midi.song, vol);
}
diff --git a/src/music/libtimidity.h b/src/music/libtimidity.h
index abe17e7703..0a0686499f 100644
--- a/src/music/libtimidity.h
+++ b/src/music/libtimidity.h
@@ -16,6 +16,7 @@
/** Music driver making use of libtimidity. */
class MusicDriver_LibTimidity : public MusicDriver {
+ int volume;
public:
/* virtual */ const char *Start(const char * const *param);
diff --git a/src/music_gui.cpp b/src/music_gui.cpp
index 279f376525..508b06d2e5 100644
--- a/src/music_gui.cpp
+++ b/src/music_gui.cpp
@@ -297,13 +297,32 @@ static void SelectPlaylist(byte list)
}
struct MusicTrackSelectionWindow : public Window {
+ Scrollbar *left_sb;
+ Scrollbar *right_sb;
+
+ /** Count the number of tracks of current tracklist. */
+ uint GetNumberOfTracksOfTracklist() const
+ {
+ uint i = 0;
+ for (; _playlists[_settings_client.music.playlist][i] > 0; i++) {}
+ return i;
+ }
+
MusicTrackSelectionWindow(WindowDesc *desc, WindowNumber number) : Window(desc)
{
- this->InitNested(number);
+
+ this->CreateNestedTree();
+ this->left_sb = this->GetScrollbar(WID_MTS_LEFT_SCROLLBAR);
+ this->right_sb = this->GetScrollbar(WID_MTS_RIGHT_SCROLLBAR);
+
this->LowerWidget(WID_MTS_LIST_LEFT);
this->LowerWidget(WID_MTS_LIST_RIGHT);
this->SetWidgetDisabledState(WID_MTS_CLEAR, _settings_client.music.playlist <= 3);
this->LowerWidget(WID_MTS_ALL + _settings_client.music.playlist);
+ this->FinishInitNested(number);
+
+ this->left_sb->SetCount(NUM_SONGS_AVAILABLE);
+ this->right_sb->SetCount(GetNumberOfTracksOfTracklist());
}
virtual void SetStringParameters(int widget) const
@@ -327,6 +346,7 @@ struct MusicTrackSelectionWindow : public Window {
this->SetWidgetLoweredState(WID_MTS_ALL + i, i == _settings_client.music.playlist);
}
this->SetWidgetDisabledState(WID_MTS_CLEAR, _settings_client.music.playlist <= 3);
+ this->right_sb->SetCount(GetNumberOfTracksOfTracklist());
this->SetDirty();
}
@@ -346,7 +366,8 @@ struct MusicTrackSelectionWindow : public Window {
break;
}
- case WID_MTS_LIST_LEFT: case WID_MTS_LIST_RIGHT: {
+ case WID_MTS_LIST_LEFT:
+ case WID_MTS_LIST_RIGHT: {
Dimension d = {0, 0};
for (uint i = 0; i < NUM_SONGS_AVAILABLE; i++) {
@@ -356,12 +377,11 @@ struct MusicTrackSelectionWindow : public Window {
SetDParam(0, GetTrackNumber(i));
SetDParam(1, 2);
SetDParamStr(2, GetSongName(i));
- Dimension d2 = GetStringBoundingBox(STR_PLAYLIST_TRACK_NAME);
- d.width = max(d.width, d2.width);
- d.height += d2.height;
+ d = maxdim(d, GetStringBoundingBox(STR_PLAYLIST_TRACK_NAME));
}
- d.width += padding.width;
- d.height += padding.height;
+ resize->height = GetMinSizing(NWST_STEP, d.height);
+ d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
+ d.height = 7 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
*size = maxdim(*size, d);
break;
}
@@ -375,15 +395,17 @@ struct MusicTrackSelectionWindow : public Window {
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK);
int y = r.top + WD_FRAMERECT_TOP;
- for (uint i = 0; i < NUM_SONGS_AVAILABLE; i++) {
+ uint vscroll_max = min(this->left_sb->GetPosition() + this->left_sb->GetCapacity(), NUM_SONGS_AVAILABLE);
+
+ for (uint i = this->left_sb->GetPosition(); i < vscroll_max; i++) {
const char *song_name = GetSongName(i);
if (StrEmpty(song_name)) continue;
SetDParam(0, GetTrackNumber(i));
SetDParam(1, 2);
SetDParamStr(2, song_name);
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME);
- y += FONT_HEIGHT_SMALL;
+ DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, this->resize.step_height, FONT_HEIGHT_SMALL), STR_PLAYLIST_TRACK_NAME);
+ y += this->resize.step_height;
}
break;
}
@@ -392,13 +414,15 @@ struct MusicTrackSelectionWindow : public Window {
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK);
int y = r.top + WD_FRAMERECT_TOP;
- for (const byte *p = _playlists[_settings_client.music.playlist]; *p != 0; p++) {
- uint i = *p - 1;
- SetDParam(0, GetTrackNumber(i));
+ uint vscroll_max = min(this->right_sb->GetPosition() + this->right_sb->GetCapacity(), this->GetNumberOfTracksOfTracklist());
+
+ for (uint i = this->right_sb->GetPosition(); i < vscroll_max; i++) {
+ uint j = _playlists[_settings_client.music.playlist][i] - 1;
+ SetDParam(0, GetTrackNumber(j));
SetDParam(1, 2);
- SetDParamStr(2, GetSongName(i));
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME);
- y += FONT_HEIGHT_SMALL;
+ SetDParamStr(2, GetSongName(j));
+ DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, this->resize.step_height, FONT_HEIGHT_SMALL), STR_PLAYLIST_TRACK_NAME);
+ y += this->resize.step_height;
}
break;
}
@@ -409,22 +433,22 @@ struct MusicTrackSelectionWindow : public Window {
{
switch (widget) {
case WID_MTS_LIST_LEFT: { // add to playlist
- int y = this->GetRowFromWidget(pt.y, widget, 0, FONT_HEIGHT_SMALL);
-
if (_settings_client.music.playlist < 4) return;
- if (!IsInsideMM(y, 0, BaseMusic::GetUsedSet()->num_available)) return;
+ int id_m = this->left_sb->GetScrolledRowFromWidget(pt.y, this, WID_MTS_LIST_LEFT, WD_FRAMERECT_TOP, this->resize.step_height);
+ if (!IsInsideMM(id_m, 0, BaseMusic::GetUsedSet()->num_available)) return;
byte *p = _playlists[_settings_client.music.playlist];
for (uint i = 0; i != NUM_SONGS_PLAYLIST - 1; i++) {
if (p[i] == 0) {
/* Find the actual song number */
for (uint j = 0; j < NUM_SONGS_AVAILABLE; j++) {
- if (GetTrackNumber(j) == y + 1) {
+ if (GetTrackNumber(j) == id_m + 1) {
p[i] = j + 1;
break;
}
}
p[i + 1] = 0;
+ this->right_sb->SetCount(GetNumberOfTracksOfTracklist());
this->SetDirty();
SelectSongToPlay();
break;
@@ -434,16 +458,16 @@ struct MusicTrackSelectionWindow : public Window {
}
case WID_MTS_LIST_RIGHT: { // remove from playlist
- int y = this->GetRowFromWidget(pt.y, widget, 0, FONT_HEIGHT_SMALL);
-
if (_settings_client.music.playlist < 4) return;
- if (!IsInsideMM(y, 0, NUM_SONGS_PLAYLIST)) return;
+ int id_m = this->right_sb->GetScrolledRowFromWidget(pt.y, this, WID_MTS_LIST_RIGHT, WD_FRAMERECT_TOP, this->resize.step_height);
+ if (!IsInsideMM(id_m, 0, NUM_SONGS_PLAYLIST)) return;
byte *p = _playlists[_settings_client.music.playlist];
- for (uint i = y; i != NUM_SONGS_PLAYLIST - 1; i++) {
+ for (uint i = id_m; i != NUM_SONGS_PLAYLIST - 1; i++) {
p[i] = p[i + 1];
}
+ this->right_sb->SetCount(GetNumberOfTracksOfTracklist());
this->SetDirty();
SelectSongToPlay();
break;
@@ -451,55 +475,74 @@ struct MusicTrackSelectionWindow : public Window {
case WID_MTS_CLEAR: // clear
for (uint i = 0; _playlists[_settings_client.music.playlist][i] != 0; i++) _playlists[_settings_client.music.playlist][i] = 0;
+ this->right_sb->SetCount(GetNumberOfTracksOfTracklist());
this->SetDirty();
StopMusic();
SelectSongToPlay();
break;
- case WID_MTS_ALL: case WID_MTS_OLD: case WID_MTS_NEW:
- case WID_MTS_EZY: case WID_MTS_CUSTOM1: case WID_MTS_CUSTOM2: // set playlist
+ case WID_MTS_ALL:
+ case WID_MTS_OLD:
+ case WID_MTS_NEW:
+ case WID_MTS_EZY:
+ case WID_MTS_CUSTOM1:
+ case WID_MTS_CUSTOM2: // set playlist
SelectPlaylist(widget - WID_MTS_ALL);
+ this->right_sb->SetCount(GetNumberOfTracksOfTracklist());
+ this->SetDirty();
StopMusic();
SelectSongToPlay();
break;
}
}
+
+ virtual void OnResize()
+ {
+ this->left_sb->SetCapacityFromWidget(this, WID_MTS_LIST_LEFT);
+ this->right_sb->SetCapacityFromWidget(this, WID_MTS_LIST_RIGHT);
+ }
};
static const NWidgetPart _nested_music_track_selection_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_PLAYLIST_MUSIC_PROGRAM_SELECTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
+ NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
/* Left panel. */
NWidget(NWID_VERTICAL),
NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_PLAYLIST_TRACK_INDEX, STR_NULL),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_MTS_LIST_LEFT), SetMinimalSize(180, 194), SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK), EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_MATRIX, COLOUR_GREY, WID_MTS_LIST_LEFT), SetMinimalSize(180, 100), SetMatrixDataTip(1, 0, STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK),
+ SetFill(1, 0), SetResize(1, 1), SetScrollbar(WID_MTS_LEFT_SCROLLBAR),
+ NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_MTS_LEFT_SCROLLBAR),
+ EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
EndContainer(),
- /* Middle buttons. */
- NWidget(NWID_VERTICAL),
- NWidget(NWID_SPACER), SetMinimalSize(60, 30), // Space above the first button from the title bar.
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_ALL), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_ALL, STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_OLD), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_OLD_STYLE, STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_NEW), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_NEW_STYLE, STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_EZY), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_EZY_STREET, STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_CUSTOM1), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_1, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_CUSTOM2), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_2, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED),
- NWidget(NWID_SPACER), SetMinimalSize(0, 16), // Space above 'clear' button
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_MTS_CLEAR), SetFill(1, 0), SetDataTip(STR_PLAYLIST_CLEAR, STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1),
- NWidget(NWID_SPACER), SetFill(0, 1),
- EndContainer(),
/* Right panel. */
NWidget(NWID_VERTICAL),
NWidget(WWT_LABEL, COLOUR_GREY, WID_MTS_PLAYLIST), SetDataTip(STR_PLAYLIST_PROGRAM, STR_NULL),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_MTS_LIST_RIGHT), SetMinimalSize(180, 194), SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK), EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_MATRIX, COLOUR_GREY, WID_MTS_LIST_RIGHT), SetMinimalSize(180, 100), SetMatrixDataTip(1, 0, STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK),
+ SetFill(1, 0), SetResize(1, 1), SetScrollbar(WID_MTS_RIGHT_SCROLLBAR),
+ NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_MTS_RIGHT_SCROLLBAR),
+ EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
EndContainer(),
EndContainer(),
EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_ALL), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_ALL, STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_OLD), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_OLD_STYLE, STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_NEW), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_NEW_STYLE, STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_EZY), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_EZY_STREET, STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_CUSTOM1), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_1, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_CUSTOM2), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_2, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_MTS_CLEAR), SetFill(1, 0), SetDataTip(STR_PLAYLIST_CLEAR, STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1),
+ NWidget(WWT_RESIZEBOX, COLOUR_GREY),
+ EndContainer(),
};
static WindowDesc _music_track_selection_desc(
@@ -577,7 +620,7 @@ struct MusicWindow : public Window {
SetDParam(1, 2);
str = STR_MUSIC_TRACK_DIGIT;
}
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str);
+ DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top, FONT_HEIGHT_SMALL), str);
break;
}
@@ -588,7 +631,7 @@ struct MusicWindow : public Window {
str = STR_MUSIC_TITLE_NAME;
SetDParamStr(0, GetSongName(_music_wnd_cursong - 1));
}
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_HOR_CENTER);
+ DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top, FONT_HEIGHT_SMALL), str, TC_FROMSTRING, SA_HOR_CENTER);
break;
}
@@ -653,7 +696,7 @@ struct MusicWindow : public Window {
if (_current_text_dir == TD_RTL) new_vol = 127 - new_vol;
if (new_vol != *vol) {
*vol = new_vol;
- if (widget == WID_M_MUSIC_VOL) MusicVolumeChanged(new_vol);
+ if (widget == WID_M_MUSIC_VOL) MusicVolumeChanged((new_vol * new_vol) / 127); // Kinda logarithmic scale
this->SetDirty();
}
@@ -679,7 +722,6 @@ struct MusicWindow : public Window {
SelectPlaylist(widget - WID_M_ALL);
StopMusic();
SelectSongToPlay();
- this->SetDirty();
break;
}
}
@@ -744,11 +786,11 @@ static const NWidgetPart _nested_music_window_widgets[] = {
EndContainer(),
NWidget(NWID_VERTICAL), SetPadding(0, 0, 3, 3),
NWidget(WWT_LABEL, COLOUR_GREY, WID_M_TRACK), SetFill(0, 0), SetDataTip(STR_MUSIC_TRACK, STR_NULL),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_M_TRACK_NR), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_M_TRACK_NR), SetFill(0, 1), EndContainer(),
EndContainer(),
NWidget(NWID_VERTICAL), SetPadding(0, 3, 3, 0),
NWidget(WWT_LABEL, COLOUR_GREY, WID_M_TRACK_TITLE), SetFill(1, 0), SetDataTip(STR_MUSIC_XTITLE, STR_NULL),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_M_TRACK_NAME), SetFill(1, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_M_TRACK_NAME), SetFill(1, 1), EndContainer(),
EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetFill(0, 1),
diff --git a/src/network/core/os_abstraction.h b/src/network/core/os_abstraction.h
index 9608f08fa7..f358bf1c1c 100644
--- a/src/network/core/os_abstraction.h
+++ b/src/network/core/os_abstraction.h
@@ -161,7 +161,7 @@ static inline void OTTDfreeaddrinfo(struct addrinfo *ai)
# include
/* According to glibc/NEWS, appeared in glibc-2.3. */
# if !defined(__sgi__) && !defined(SUNOS) && !defined(__MORPHOS__) && !defined(__BEOS__) && !defined(__HAIKU__) && !defined(__INNOTEK_LIBC__) \
- && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) && !defined(HPUX)
+ && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) && !defined(HPUX) && !defined(__ANDROID__)
/* If for any reason ifaddrs.h does not exist on your system, comment out
* the following two lines and an alternative way will be used to fetch
* the list of IPs from the system. */
diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp
index 3416762d02..5b96b1a251 100644
--- a/src/network/network_chat_gui.cpp
+++ b/src/network/network_chat_gui.cpp
@@ -462,7 +462,7 @@ struct NetworkChatWindow : public Window {
virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
{
- Point pt = { 0, _screen.height - sm_height - FindWindowById(WC_STATUS_BAR, 0)->height };
+ Point pt = { GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) * 2, _screen.height - sm_height - FindWindowById(WC_STATUS_BAR, 0)->height };
return pt;
}
@@ -486,7 +486,7 @@ struct NetworkChatWindow : public Window {
if (this->dtype == DESTTYPE_CLIENT) {
SetDParamStr(0, NetworkClientInfo::GetByClientID((ClientID)this->dest)->client_name);
}
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, this->dest_string, TC_BLACK, SA_RIGHT);
+ DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top), this->dest_string, TC_BLACK, SA_RIGHT);
}
virtual void OnClick(Point pt, int widget, int click_count)
diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp
index 1227d43dbb..6b1b652ccc 100644
--- a/src/network/network_content_gui.cpp
+++ b/src/network/network_content_gui.cpp
@@ -23,6 +23,8 @@
#include "../querystring_gui.h"
#include "../core/geometry_func.hpp"
#include "../textfile_gui.h"
+#include "../settings_type.h"
+#include "../settings_gui.h"
#include "network_content_gui.h"
@@ -584,8 +586,8 @@ public:
}
case WID_NCL_MATRIX:
- resize->height = max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
- size->height = 10 * resize->height;
+ resize->height = SETTING_BUTTON_HEIGHT;
+ size->height = 6 * resize->height;
break;
}
}
@@ -595,7 +597,7 @@ public:
{
switch (widget) {
case WID_NCL_FILTER_CAPT:
- DrawString(r.left, r.right, r.top, STR_CONTENT_FILTER_TITLE, TC_FROMSTRING, SA_RIGHT);
+ DrawString(r.left, r.right, Center(r.top, r.bottom - r.top), STR_CONTENT_FILTER_TITLE, TC_FROMSTRING, SA_RIGHT);
break;
case WID_NCL_DETAILS:
@@ -638,14 +640,14 @@ public:
int line_height = max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL);
/* Fill the matrix with the information */
- int sprite_y_offset = WD_MATRIX_TOP + (line_height - this->checkbox_size.height) / 2 - 1;
- int text_y_offset = WD_MATRIX_TOP + (line_height - FONT_HEIGHT_NORMAL) / 2;
+ int sprite_y_offset = WD_MATRIX_TOP + (line_height - this->checkbox_size.height) / 2 - 1 + (this->resize.step_height - line_height) / 2;
+ int text_y_offset = WD_MATRIX_TOP + (line_height - FONT_HEIGHT_NORMAL) / 2 + (this->resize.step_height - line_height) / 2;
uint y = r.top;
int cnt = 0;
for (ConstContentIterator iter = this->content.Get(this->vscroll->GetPosition()); iter != this->content.End() && cnt < this->vscroll->GetCapacity(); iter++, cnt++) {
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(r.left + 1, y + WD_FRAMERECT_TOP, r.right - 1, y + this->resize.step_height - WD_FRAMERECT_BOTTOM, PC_GREY);
SpriteID sprite;
SpriteID pal = PAL_NONE;
@@ -1056,14 +1058,7 @@ static const NWidgetPart _nested_network_content_list_widgets[] = {
NWidget(WWT_DEFSIZEBOX, COLOUR_LIGHT_BLUE),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_NCL_BACKGROUND),
- NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetResize(1, 0),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8),
- /* Top */
- NWidget(WWT_EMPTY, COLOUR_LIGHT_BLUE, WID_NCL_FILTER_CAPT), SetFill(1, 0), SetResize(1, 0),
- NWidget(WWT_EDITBOX, COLOUR_LIGHT_BLUE, WID_NCL_FILTER), SetFill(1, 0), SetResize(1, 0),
- SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
- EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetResize(1, 0),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 3), SetResize(1, 0),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8),
/* Left side. */
NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
@@ -1093,6 +1088,13 @@ static const NWidgetPart _nested_network_content_list_widgets[] = {
EndContainer(),
/* Right side. */
NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8),
+ /* Top */
+ NWidget(WWT_EMPTY, COLOUR_LIGHT_BLUE, WID_NCL_FILTER_CAPT), SetFill(1, 0), SetResize(1, 0),
+ NWidget(WWT_EDITBOX, COLOUR_LIGHT_BLUE, WID_NCL_FILTER), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 3), SetResize(1, 0),
NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_NCL_DETAILS), SetResize(1, 1), SetFill(1, 1), EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, 8, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp
index 520c4f60a8..9e97035c84 100644
--- a/src/network/network_gui.cpp
+++ b/src/network/network_gui.cpp
@@ -31,6 +31,7 @@
#include "../core/geometry_func.hpp"
#include "../genworld.h"
#include "../map_type.h"
+#include "../settings_gui.h"
#include "../widgets/network_widget.h"
@@ -505,17 +506,17 @@ public:
switch (widget) {
case WID_NG_CONN_BTN:
*size = maxdim(*size, maxdim(GetStringBoundingBox(_lan_internet_types_dropdown[0]), GetStringBoundingBox(_lan_internet_types_dropdown[1])));
- size->width += padding.width;
+ size->width += padding.width + GetMinSizing(NWST_STEP, 11U);;
size->height += padding.height;
break;
case WID_NG_MATRIX:
- resize->height = WD_MATRIX_TOP + max(GetSpriteSize(SPR_BLOT).height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_BOTTOM;
- size->height = 10 * resize->height;
+ resize->height = SETTING_BUTTON_HEIGHT;
+ size->height = 5 * resize->height;
break;
case WID_NG_LASTJOINED:
- size->height = WD_MATRIX_TOP + max(GetSpriteSize(SPR_BLOT).height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_BOTTOM;
+ size->height = SETTING_BUTTON_HEIGHT;
break;
case WID_NG_LASTJOINED_SPACER:
@@ -550,7 +551,7 @@ public:
break;
case WID_NG_DETAILS_SPACER:
- size->height = 20 + 12 * FONT_HEIGHT_NORMAL;
+ size->height = 20 + 10 * FONT_HEIGHT_NORMAL;
break;
}
}
@@ -942,12 +943,9 @@ static const NWidgetPart _nested_network_game_widgets[] = {
/* LEFT SIDE */
NWidget(NWID_VERTICAL), SetPIP(0, 7, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 7, 0),
- NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NG_CONNECTION), SetDataTip(STR_NETWORK_SERVER_LIST_ADVERTISED, STR_NULL),
+ NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NG_CONNECTION), SetSizingType(NWST_STEP), SetDataTip(STR_NETWORK_SERVER_LIST_ADVERTISED, STR_NULL),
NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NG_CONN_BTN),
SetDataTip(STR_BLACK_STRING, STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP),
- NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
- EndContainer(),
- NWidget(NWID_HORIZONTAL), SetPIP(0, 7, 0),
NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NG_FILTER_LABEL), SetDataTip(STR_LIST_FILTER_TITLE, STR_NULL),
NWidget(WWT_EDITBOX, COLOUR_LIGHT_BLUE, WID_NG_FILTER), SetMinimalSize(251, 12), SetFill(1, 0), SetResize(1, 0),
SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
@@ -1091,8 +1089,8 @@ struct NetworkStartServerWindow : public Window {
switch (widget) {
case WID_NSS_CONNTYPE_BTN:
*size = maxdim(GetStringBoundingBox(_connection_types_dropdown[0]), GetStringBoundingBox(_connection_types_dropdown[1]));
- size->width += padding.width;
- size->height += padding.height;
+ size->width = GetMinSizing(NWST_BUTTON, size->width + padding.width);
+ size->height = GetMinSizing(NWST_BUTTON, size->height + padding.height);
break;
}
}
@@ -1275,15 +1273,15 @@ static const NWidgetPart _nested_network_start_server_window_widgets[] = {
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 6, 10),
NWidget(NWID_VERTICAL), SetPIP(0, 1, 0),
NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_LABEL), SetFill(1, 0), SetDataTip(STR_NETWORK_SERVER_LIST_ADVERTISED, STR_NULL),
- NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_BTN), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP),
+ NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_BTN), SetSizingType(NWST_BUTTON), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, 1, 0),
NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NSS_LANGUAGE_LABEL), SetFill(1, 0), SetDataTip(STR_NETWORK_START_SERVER_LANGUAGE_SPOKEN, STR_NULL),
- NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_LANGUAGE_BTN), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_START_SERVER_LANGUAGE_TOOLTIP),
+ NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_LANGUAGE_BTN), SetSizingType(NWST_BUTTON), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_START_SERVER_LANGUAGE_TOOLTIP),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, 1, 0),
NWidget(NWID_SPACER), SetFill(1, 1),
- NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NSS_SETPWD), SetFill(1, 0), SetDataTip(STR_NETWORK_START_SERVER_SET_PASSWORD, STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NSS_SETPWD), SetSizingType(NWST_BUTTON), SetFill(1, 0), SetDataTip(STR_NETWORK_START_SERVER_SET_PASSWORD, STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP),
EndContainer(),
EndContainer(),
@@ -1386,8 +1384,8 @@ struct NetworkLobbyWindow : public Window {
break;
case WID_NL_MATRIX:
- resize->height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM;
- size->height = 10 * resize->height;
+ resize->height = GetMinSizing(NWST_STEP, WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM);
+ size->height = 6 * resize->height;
break;
case WID_NL_DETAILS:
@@ -1454,7 +1452,7 @@ struct NetworkLobbyWindow : public Window {
uint profit_left = rtl ? left : right - profit_width;
uint lock_left = rtl ? left + profit_width + 2 : right - profit_width - lock_width - 2;
- int y = r.top + WD_MATRIX_TOP;
+ int y = r.top + WD_MATRIX_TOP + this->resize.step_height / 4;
/* Draw company list */
int pos = this->vscroll->GetPosition();
while (pos < this->server->info.companies_on) {
@@ -1719,7 +1717,7 @@ struct NetworkClientListPopupWindow : Window {
ClientList_Action_Proc *proc; ///< Action to execute
};
- uint sel_index;
+ int sel_index;
ClientID client_id;
Point desired_location;
SmallVector actions; ///< Actions to execute
@@ -1738,10 +1736,10 @@ struct NetworkClientListPopupWindow : Window {
NetworkClientListPopupWindow(WindowDesc *desc, int x, int y, ClientID client_id) :
Window(desc),
- sel_index(0), client_id(client_id)
+ sel_index(-1), client_id(client_id)
{
- this->desired_location.x = x;
- this->desired_location.y = y;
+ this->desired_location.x = x - GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
+ this->desired_location.y = y + GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) / 2;
const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
@@ -1783,6 +1781,7 @@ struct NetworkClientListPopupWindow : Window {
d = maxdim(GetStringBoundingBox(action->name), d);
}
+ d.height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
d.height *= this->actions.Length();
d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
@@ -1794,37 +1793,29 @@ struct NetworkClientListPopupWindow : Window {
/* Draw the actions */
int sel = this->sel_index;
int y = r.top + WD_FRAMERECT_TOP;
- for (const ClientListAction *action = this->actions.Begin(); action != this->actions.End(); action++, y += FONT_HEIGHT_NORMAL) {
+ for (const ClientListAction *action = this->actions.Begin(); action != this->actions.End(); action++, y += GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL)) {
TextColour colour;
if (sel-- == 0) { // Selected item, highlight it
- GfxFillRect(r.left + 1, y, r.right - 1, y + FONT_HEIGHT_NORMAL - 1, PC_BLACK);
+ GfxFillRect(r.left + 1, y, r.right - 1, y + GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) - 1, PC_BLACK);
colour = TC_WHITE;
} else {
colour = TC_BLACK;
}
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, action->name, colour);
+ DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL)), action->name, colour);
}
}
- virtual void OnMouseLoop()
+ virtual void OnClick(Point pt, int widget, int click_count)
{
- /* We selected an action */
- uint index = (_cursor.pos.y - this->top - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL;
+ int index = (pt.y - WD_FRAMERECT_TOP) / GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
- if (_left_button_down) {
- if (index == this->sel_index || index >= this->actions.Length()) return;
-
- this->sel_index = index;
- this->SetDirty();
- } else {
- if (index < this->actions.Length() && _cursor.pos.y >= this->top) {
- const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(this->client_id);
- if (ci != NULL) this->actions[index].proc(ci);
- }
-
- DeleteWindowByClass(WC_CLIENT_LIST_POPUP);
+ if (index >= 0 && index < (int)this->actions.Length()) {
+ const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(this->client_id);
+ if (ci != NULL) this->actions[index].proc(ci);
}
+
+ DeleteWindowByClass(WC_CLIENT_LIST_POPUP);
}
};
@@ -1846,7 +1837,7 @@ static const NWidgetPart _nested_client_list_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_CL_PANEL), SetMinimalSize(250, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM), SetResize(1, 1), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_CL_PANEL), SetMinimalSize(100, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM), SetResize(1, 1), EndContainer(),
};
static WindowDesc _client_list_desc(
@@ -1864,6 +1855,8 @@ struct NetworkClientListWindow : Window {
uint server_client_width;
uint line_height;
+ uint line_width;
+ enum { MAX_ROWS = 6 }; // Split the list in two if it does not fit the screen
Dimension icon_size;
@@ -1887,12 +1880,16 @@ struct NetworkClientListWindow : Window {
if (ci->client_playas != COMPANY_INACTIVE_CLIENT) num++;
}
+ int cols = 1 + (num - 1) / MAX_ROWS;
+ cols *= this->line_width;
+ num = min(num, MAX_ROWS);
num *= this->line_height;
- int diff = (num + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM) - (this->GetWidget(WID_CL_PANEL)->current_y);
+ int diffx = (cols + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT) - (this->GetWidget(WID_CL_PANEL)->current_x);
+ int diffy = (num + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM) - (this->GetWidget(WID_CL_PANEL)->current_y);
/* If height is changed */
- if (diff != 0) {
- ResizeWindow(this, 0, diff, false);
+ if (diffx > 0 || diffy != 0) { // Width can only grow, also title bar can be wider than content
+ ResizeWindow(this, diffx, diffy, false);
return false;
}
return true;
@@ -1905,6 +1902,7 @@ struct NetworkClientListWindow : Window {
this->server_client_width = max(GetStringBoundingBox(STR_NETWORK_SERVER).width, GetStringBoundingBox(STR_NETWORK_CLIENT).width) + WD_FRAMERECT_RIGHT;
this->icon_size = GetSpriteSize(SPR_COMPANY_ICON);
this->line_height = max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL);
+ this->line_height = GetMinSizing(NWST_STEP, this->line_height);
uint width = 100; // Default width
const NetworkClientInfo *ci;
@@ -1912,7 +1910,7 @@ struct NetworkClientListWindow : Window {
width = max(width, GetStringBoundingBox(ci->client_name).width);
}
- size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT + width + WD_FRAMERECT_RIGHT;
+ this->line_width = this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT + width + WD_FRAMERECT_RIGHT;
}
virtual void OnPaint()
@@ -1936,19 +1934,21 @@ struct NetworkClientListWindow : Window {
uint right = r.right - WD_FRAMERECT_RIGHT;
uint type_icon_width = this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT;
-
- uint type_left = rtl ? right - this->server_client_width : left;
- uint type_right = rtl ? right : left + this->server_client_width - 1;
- uint icon_left = rtl ? right - type_icon_width + WD_FRAMERECT_LEFT : left + this->server_client_width;
- uint name_left = rtl ? left : left + type_icon_width;
- uint name_right = rtl ? right - type_icon_width : right;
-
int i = 0;
const NetworkClientInfo *ci;
FOR_ALL_CLIENT_INFOS(ci) {
+ uint type_left = rtl ? right - this->server_client_width : left;
+ uint type_right = rtl ? right : left + this->server_client_width - 1;
+ uint icon_left = rtl ? right - type_icon_width + WD_FRAMERECT_LEFT : left + this->server_client_width;
+ uint name_left = rtl ? right - this->line_width : left + type_icon_width;
+ uint name_right = rtl ? right - type_icon_width : left + this->line_width;
TextColour colour;
if (this->selected_item == i++) { // Selected item, highlight it
- GfxFillRect(r.left + 1, y, r.right - 1, y + this->line_height - 1, PC_BLACK);
+ if (rtl) {
+ GfxFillRect(right - this->line_width, y, right + WD_FRAMERECT_RIGHT - 1, y + this->line_height - 1, PC_BLACK);
+ } else {
+ GfxFillRect(left - WD_FRAMERECT_LEFT + 1, y, left + this->line_width, y + this->line_height - 1, PC_BLACK);
+ }
colour = TC_WHITE;
} else {
colour = TC_BLACK;
@@ -1966,6 +1966,14 @@ struct NetworkClientListWindow : Window {
DrawString(name_left, name_right, y + text_offset, ci->client_name, colour);
y += line_height;
+ if (i % MAX_ROWS == 0 && i > 1) {
+ y = r.top + WD_FRAMERECT_TOP;
+ if (rtl) {
+ right -= this->line_width;
+ } else {
+ left += this->line_width;
+ }
+ }
}
}
@@ -1998,7 +2006,7 @@ struct NetworkClientListWindow : Window {
pt.y -= this->GetWidget(WID_CL_PANEL)->pos_y;
int item = -1;
if (IsInsideMM(pt.y, WD_FRAMERECT_TOP, this->GetWidget(WID_CL_PANEL)->current_y - WD_FRAMERECT_BOTTOM)) {
- item = (pt.y - WD_FRAMERECT_TOP) / this->line_height;
+ item = (pt.y - WD_FRAMERECT_TOP) / this->line_height + ((pt.x - WD_FRAMERECT_LEFT) / this->line_width) * MAX_ROWS;
}
/* It did not change.. no update! */
diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp
index 75b06967f7..295ad9ff52 100644
--- a/src/newgrf_debug_gui.cpp
+++ b/src/newgrf_debug_gui.cpp
@@ -437,7 +437,7 @@ struct NewGRFInspectWindow : Window {
GrfSpecFeature f = GetFeatureNum(this->window_number);
int h = GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height;
- int y = (r.top + r.bottom - h) / 2;
+ int y = Center(r.top, r.bottom - r.top, h);
DrawVehicleImage(v->First(), r.left + WD_BEVEL_LEFT, r.right - WD_BEVEL_RIGHT, y + 1, INVALID_VEHICLE, EIT_IN_DETAILS, skip);
/* Highlight the articulated part (this is different to the whole-vehicle highlighting of DrawVehicleImage */
@@ -860,7 +860,7 @@ struct SpriteAlignerWindow : Window {
{
if (widget != WID_SA_LIST) return;
- resize->height = max(11, FONT_HEIGHT_NORMAL + 1);
+ resize->height = GetMinSizing(NWST_STEP, max(11, FONT_HEIGHT_NORMAL + 1));
resize->width = 1;
/* Resize to about 200 pixels (for the preview) */
@@ -897,10 +897,10 @@ struct SpriteAlignerWindow : Window {
SmallVector &list = _newgrf_debug_sprite_picker.sprites;
int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), list.Length());
- int y = r.top + WD_FRAMERECT_TOP;
+ int y = Center(r.top + WD_FRAMERECT_TOP, step_size, FONT_HEIGHT_NORMAL);
for (int i = this->vscroll->GetPosition(); i < max; i++) {
SetDParam(0, list[i]);
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
+ DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_BLACK_COMMA, TC_FROMSTRING, SA_CENTER | SA_FORCE);
y += step_size;
}
break;
diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp
index c3007ac42d..0f347069db 100644
--- a/src/newgrf_gui.cpp
+++ b/src/newgrf_gui.cpp
@@ -654,10 +654,9 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_NS_SCROLLBAR);
- this->vscroll2 = this->GetScrollbar(WID_NS_SCROLL2BAR);
+ this->vscroll2 = this->editable ? this->GetScrollbar(WID_NS_SCROLL2BAR) : NULL;
this->GetWidget(WID_NS_SHOW_REMOVE)->SetDisplayedPlane(this->editable ? 0 : 1);
- this->GetWidget(WID_NS_SHOW_APPLY)->SetDisplayedPlane(this->editable ? 0 : this->show_params ? 1 : SZSP_HORIZONTAL);
this->FinishInitNested(WN_GAME_OPTIONS_NEWGRF_STATE);
this->querystrings[WID_NS_FILTER] = &this->filter_editbox;
@@ -738,14 +737,14 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
case WID_NS_FILE_LIST:
{
Dimension d = maxdim(GetSpriteSize(SPR_SQUARE), GetSpriteSize(SPR_WARNING_SIGN));
- resize->height = max(d.height + 2U, FONT_HEIGHT_NORMAL + 2U);
- size->height = max(size->height, WD_FRAMERECT_TOP + 6 * resize->height + WD_FRAMERECT_BOTTOM);
+ resize->height = GetMinSizing(NWST_STEP, max(d.height + 2U, FONT_HEIGHT_NORMAL + 2U));
+ size->height = max(size->height, WD_FRAMERECT_TOP + 4 * resize->height + WD_FRAMERECT_BOTTOM);
break;
}
case WID_NS_AVAIL_LIST:
- resize->height = max(12, FONT_HEIGHT_NORMAL + 2);
- size->height = max(size->height, WD_FRAMERECT_TOP + 8 * resize->height + WD_FRAMERECT_BOTTOM);
+ resize->height = GetMinSizing(NWST_STEP, max(12, FONT_HEIGHT_NORMAL + 2));
+ size->height = max(size->height, WD_FRAMERECT_TOP + 4 * resize->height + WD_FRAMERECT_BOTTOM);
break;
case WID_NS_NEWGRF_INFO_TITLE: {
@@ -768,6 +767,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
}
}
d.width += padding.width;
+ d.height = GetMinSizing(NWST_BUTTON, d.height);
*size = maxdim(d, *size);
break;
}
@@ -778,6 +778,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
*size = maxdim(d, GetStringBoundingBox(STR_INTRO_ONLINE_CONTENT));
size->width += padding.width;
size->height += padding.height;
+ size->height = GetMinSizing(NWST_BUTTON, size->height);
break;
}
}
@@ -786,7 +787,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
virtual void OnResize()
{
this->vscroll->SetCapacityFromWidget(this, WID_NS_FILE_LIST);
- this->vscroll2->SetCapacityFromWidget(this, WID_NS_AVAIL_LIST);
+ if (this->vscroll2) this->vscroll2->SetCapacityFromWidget(this, WID_NS_AVAIL_LIST);
}
virtual void SetStringParameters(int widget) const
@@ -1294,8 +1295,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
widget_data = STR_INTRO_ONLINE_CONTENT;
tool_tip = STR_INTRO_TOOLTIP_ONLINE_CONTENT;
}
- this->GetWidget(WID_NS_CONTENT_DOWNLOAD)->widget_data = widget_data;
- this->GetWidget(WID_NS_CONTENT_DOWNLOAD)->tool_tip = tool_tip;
+ if (this->editable) {
+ this->GetWidget(WID_NS_CONTENT_DOWNLOAD)->widget_data = widget_data;
+ this->GetWidget(WID_NS_CONTENT_DOWNLOAD)->tool_tip = tool_tip;
+ }
this->GetWidget(WID_NS_CONTENT_DOWNLOAD2)->widget_data = widget_data;
this->GetWidget(WID_NS_CONTENT_DOWNLOAD2)->tool_tip = tool_tip;
@@ -1493,7 +1496,7 @@ private:
if (this->avail_pos < 0) this->avail_sel = NULL;
}
- this->vscroll2->SetCount(this->avails.Length()); // Update the scrollbar
+ if (this->vscroll2) this->vscroll2->SetCount(this->avails.Length()); // Update the scrollbar
}
/**
@@ -1628,8 +1631,8 @@ public:
uint min_inf_height = this->inf->smallest_y + this->inf->padding_top + this->inf->padding_bottom;
/* Smallest window is in two column mode. */
- this->smallest_x = max(min_avs_width, min_acs_width) + INTER_COLUMN_SPACING + min_inf_width;
- this->smallest_y = max(min_inf_height, min_acs_height + INTER_LIST_SPACING + min_avs_height);
+ this->smallest_x = min_avs_width + min_acs_width + min_inf_width + INTER_COLUMN_SPACING * 2;
+ this->smallest_y = max(max(min_inf_height, min_acs_height), min_avs_height);
/* Filling. */
this->fill_x = LeastCommonMultiple(this->avs->fill_x, this->acs->fill_x);
@@ -1666,7 +1669,7 @@ public:
/* Use 2 or 3 columns? */
uint min_three_columns = min_avs_width + min_acs_width + min_inf_width + 2 * INTER_COLUMN_SPACING;
uint min_two_columns = min_list_width + min_inf_width + INTER_COLUMN_SPACING;
- bool use_three_columns = this->editable && (min_three_columns + MIN_EXTRA_FOR_3_COLUMNS <= given_width);
+ bool use_three_columns = true; // this->editable;
/* Info panel is a separate column in both modes. Compute its width first. */
uint extra_width, inf_width;
@@ -1774,7 +1777,7 @@ public:
{
if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
- NWidgetCore *nw = (this->editable) ? this->avs->GetWidgetFromPos(x, y) : NULL;
+ NWidgetCore *nw = this->avs->GetWidgetFromPos(x, y);
if (nw == NULL) nw = this->acs->GetWidgetFromPos(x, y);
if (nw == NULL) nw = this->inf->GetWidgetFromPos(x, y);
return nw;
@@ -1782,7 +1785,7 @@ public:
virtual void Draw(const Window *w)
{
- if (this->editable) this->avs->Draw(w);
+ this->avs->Draw(w);
this->acs->Draw(w);
this->inf->Draw(w);
}
@@ -1898,33 +1901,111 @@ static const NWidgetPart _nested_newgrf_infopanel_widgets[] = {
SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
EndContainer(),
EndContainer(),
- NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NS_SHOW_APPLY),
- /* Right side, buttons. */
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, WD_RESIZEBOX_WIDTH, 0),
- NWidget(NWID_VERTICAL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_SET_PARAMETERS), SetFill(1, 0), SetResize(1, 0),
- SetDataTip(STR_NEWGRF_SETTINGS_SET_PARAMETERS, STR_NULL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_TOGGLE_PALETTE), SetFill(1, 0), SetResize(1, 0),
- SetDataTip(STR_NEWGRF_SETTINGS_TOGGLE_PALETTE, STR_NEWGRF_SETTINGS_TOGGLE_PALETTE_TOOLTIP),
- EndContainer(),
- NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_APPLY_CHANGES), SetFill(1, 0), SetResize(1, 0),
- SetDataTip(STR_NEWGRF_SETTINGS_APPLY_CHANGES, STR_NULL),
+ /* Right side, buttons. */
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, WD_RESIZEBOX_WIDTH, 0),
+ NWidget(NWID_VERTICAL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_SET_PARAMETERS), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_NEWGRF_SETTINGS_SET_PARAMETERS, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_TOGGLE_PALETTE), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_NEWGRF_SETTINGS_TOGGLE_PALETTE, STR_NEWGRF_SETTINGS_TOGGLE_PALETTE_TOOLTIP),
EndContainer(),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_APPLY_CHANGES), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_NEWGRF_SETTINGS_APPLY_CHANGES, STR_NULL),
+ EndContainer(),
+};
+
+static const NWidgetPart _nested_newgrf_actives_wide_widgets[] = {
+ /* Left side, presets. */
+ NWidget(NWID_VERTICAL),
+ NWidget(WWT_LABEL, COLOUR_MAUVE), SetDataTip(STR_NEWGRF_SETTINGS_ACTIVE_LIST, STR_NULL),
+ SetFill(1, 0), SetResize(1, 0), SetPadding(3, WD_FRAMETEXT_RIGHT, 0, WD_FRAMETEXT_LEFT),
+ /* Left side, active grfs. */
+ NWidget(NWID_HORIZONTAL), SetPadding(0, 2, 0, 2),
+ NWidget(WWT_PANEL, COLOUR_MAUVE),
+ NWidget(WWT_INSET, COLOUR_MAUVE, WID_NS_FILE_LIST), SetMinimalSize(100, 1), SetPadding(2, 2, 2, 2),
+ SetFill(1, 1), SetResize(1, 1), SetScrollbar(WID_NS_SCROLLBAR), SetDataTip(STR_NULL, STR_NEWGRF_SETTINGS_FILE_TOOLTIP),
+ EndContainer(),
+ EndContainer(),
+ NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_NS_SCROLLBAR),
+ EndContainer(),
+ EndContainer(),
+};
+
+static const NWidgetPart _nested_newgrf_buttons_wide_widgets[] = {
+ NWidget(NWID_VERTICAL),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_TEXT, COLOUR_MAUVE), SetDataTip(STR_NEWGRF_SETTINGS_SELECT_PRESET, STR_NULL),
+ SetPadding(0, WD_FRAMETEXT_RIGHT, 0, 0),
+ NWidget(WWT_DROPDOWN, COLOUR_YELLOW, WID_NS_PRESET_LIST), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_JUST_STRING, STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_PRESET_SAVE), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_NEWGRF_SETTINGS_PRESET_SAVE, STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_PRESET_DELETE), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_NEWGRF_SETTINGS_PRESET_DELETE, STR_NEWGRF_SETTINGS_PRESET_DELETE_TOOLTIP),
+ EndContainer(),
+
+ NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NS_SHOW_REMOVE),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPadding(0, 2, 0, 2), SetPIP(0, WD_RESIZEBOX_WIDTH, 0),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_REMOVE), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_NEWGRF_SETTINGS_REMOVE, STR_NEWGRF_SETTINGS_REMOVE_TOOLTIP),
+ NWidget(NWID_VERTICAL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_MOVE_UP), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_NEWGRF_SETTINGS_MOVEUP, STR_NEWGRF_SETTINGS_MOVEUP_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_MOVE_DOWN), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_NEWGRF_SETTINGS_MOVEDOWN, STR_NEWGRF_SETTINGS_MOVEDOWN_TOOLTIP),
+ EndContainer(),
+ EndContainer(),
+ NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPadding(0, 0, 0, 0),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_RESCAN_FILES2), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_NEWGRF_SETTINGS_RESCAN_FILES, STR_NEWGRF_SETTINGS_RESCAN_FILES_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_CONTENT_DOWNLOAD2), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
+ EndContainer(),
+ EndContainer(),
+
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_OPEN_URL), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_NEWGRF_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_NEWGRF_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_NEWGRF_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0),
+ SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
+ EndContainer(),
+
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_VIEW_PARAMETERS), SetFill(1, 0), SetResize(1, 0),
SetDataTip(STR_NEWGRF_SETTINGS_SHOW_PARAMETERS, STR_NULL),
EndContainer(),
};
+static const NWidgetPart _nested_newgrf_infopanel_wide_widgets[] = {
+ /* Right side, info panel. */
+ NWidget(WWT_PANEL, COLOUR_MAUVE),
+ NWidget(WWT_EMPTY, COLOUR_MAUVE, WID_NS_NEWGRF_INFO_TITLE), SetFill(1, 0), SetResize(1, 0),
+ NWidget(WWT_EMPTY, COLOUR_MAUVE, WID_NS_NEWGRF_INFO), SetFill(1, 1), SetResize(1, 1), SetMinimalSize(100, 100),
+ EndContainer(),
+};
+
/** Construct nested container widget for managing the lists and the info panel of the NewGRF GUI. */
+static bool _newgrf_display_editable = false; // Quick hack
NWidgetBase* NewGRFDisplay(int *biggest_index)
{
- NWidgetBase *avs = MakeNWidgets(_nested_newgrf_availables_widgets, lengthof(_nested_newgrf_availables_widgets), biggest_index, NULL);
+ NWidgetBase *avs = _newgrf_display_editable ?
+ MakeNWidgets(_nested_newgrf_availables_widgets, lengthof(_nested_newgrf_availables_widgets), biggest_index, NULL) :
+ MakeNWidgets(_nested_newgrf_actives_wide_widgets, lengthof(_nested_newgrf_actives_wide_widgets), biggest_index, NULL);
int biggest2;
- NWidgetBase *acs = MakeNWidgets(_nested_newgrf_actives_widgets, lengthof(_nested_newgrf_actives_widgets), &biggest2, NULL);
+ NWidgetBase *acs = _newgrf_display_editable ?
+ MakeNWidgets(_nested_newgrf_actives_widgets, lengthof(_nested_newgrf_actives_widgets), &biggest2, NULL) :
+ MakeNWidgets(_nested_newgrf_buttons_wide_widgets, lengthof(_nested_newgrf_buttons_wide_widgets), &biggest2, NULL);
*biggest_index = max(*biggest_index, biggest2);
- NWidgetBase *inf = MakeNWidgets(_nested_newgrf_infopanel_widgets, lengthof(_nested_newgrf_infopanel_widgets), &biggest2, NULL);
+ NWidgetBase *inf = _newgrf_display_editable ?
+ MakeNWidgets(_nested_newgrf_infopanel_widgets, lengthof(_nested_newgrf_infopanel_widgets), &biggest2, NULL) :
+ MakeNWidgets(_nested_newgrf_infopanel_wide_widgets, lengthof(_nested_newgrf_infopanel_wide_widgets), &biggest2, NULL);
*biggest_index = max(*biggest_index, biggest2);
return new NWidgetNewGRFDisplay(avs, acs, inf);
@@ -2001,6 +2082,7 @@ static void NewGRFConfirmationCallback(Window *w, bool confirmed)
void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config)
{
DeleteWindowByClass(WC_GAME_OPTIONS);
+ _newgrf_display_editable = editable;
new NewGRFWindow(&_newgrf_desc, editable, show_params, exec_changes, config);
}
@@ -2163,6 +2245,7 @@ static void ShowSavePresetWindow(const char *initial_text)
/** Widgets for the progress window. */
static const NWidgetPart _nested_scan_progress_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_NEWGRF_SCAN_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
+ SetSizingType(NWST_BUTTON),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_HORIZONTAL), SetPIP(20, 0, 20),
NWidget(NWID_VERTICAL), SetPIP(11, 8, 11),
diff --git a/src/news_gui.cpp b/src/news_gui.cpp
index 3800af8b57..9f5eb6681e 100644
--- a/src/news_gui.cpp
+++ b/src/news_gui.cpp
@@ -165,7 +165,7 @@ static const NWidgetPart _nested_thin_news_widgets[] = {
EndContainer(),
EndContainer(),
NWidget(WWT_EMPTY, COLOUR_WHITE, WID_N_MESSAGE), SetMinimalSize(428, 48), SetFill(1, 0), SetPadding(0, 5, 0, 5),
- NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_N_VIEWPORT), SetMinimalSize(426, 70), SetPadding(1, 2, 2, 2),
+ NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_N_VIEWPORT), SetSizingType(NWST_VIEWPORT), SetMinimalSize(426, 70), SetPadding(1, 2, 2, 2),
EndContainer(),
};
@@ -187,7 +187,7 @@ static const NWidgetPart _nested_small_news_widgets[] = {
/* Main part */
NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_N_HEADLINE),
NWidget(WWT_INSET, COLOUR_LIGHT_BLUE, WID_N_INSET), SetPadding(2, 2, 2, 2),
- NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_N_VIEWPORT), SetPadding(1, 1, 1, 1), SetMinimalSize(274, 47), SetFill(1, 0),
+ NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_N_VIEWPORT), SetSizingType(NWST_VIEWPORT), SetPadding(1, 1, 1, 1), SetMinimalSize(274, 47), SetFill(1, 0),
EndContainer(),
NWidget(WWT_EMPTY, COLOUR_WHITE, WID_N_MESSAGE), SetMinimalSize(275, 20), SetFill(1, 0), SetPadding(0, 5, 0, 5),
EndContainer(),
@@ -318,6 +318,7 @@ struct NewsWindow : Window {
break;
case WID_N_MESSAGE:
+ size->width = GetMinSizing(NWST_WINDOW_LENGTH, size->width);
CopyInDParam(0, this->ni->params, lengthof(this->ni->params));
str = this->ni->string_id;
break;
@@ -1010,7 +1011,7 @@ struct MessageHistoryWindow : Window {
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
if (widget == WID_MH_BACKGROUND) {
- this->line_height = FONT_HEIGHT_NORMAL + 2;
+ this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + 2);
resize->height = this->line_height;
/* Months are off-by-one, so it's actually 8. Not using
@@ -1041,7 +1042,7 @@ struct MessageHistoryWindow : Window {
}
/* Fill the widget with news items. */
- int y = r.top + this->top_spacing;
+ int y = Center(r.top + this->top_spacing, this->line_height, FONT_HEIGHT_NORMAL);
bool rtl = _current_text_dir == TD_RTL;
uint date_left = rtl ? r.right - WD_FRAMERECT_RIGHT - this->date_width : r.left + WD_FRAMERECT_LEFT;
uint date_right = rtl ? r.right - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT + this->date_width;
diff --git a/src/openttd.cpp b/src/openttd.cpp
index 10c31e904e..3830c6d6c1 100644
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -69,6 +69,11 @@
#include
#include "safeguards.h"
+#ifdef __ANDROID__
+#include
+#endif
+#include
+#include
void CallLandscapeTick();
void IncreaseDate();
@@ -81,6 +86,8 @@ bool HandleBootstrap();
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY);
extern void ShowOSErrorBox(const char *buf, bool system);
extern char *_config_file;
+const char *NETWORK_SAVE_SCREENSHOT_FILE = "OpenTTD-network-save";
+const char *NETWORK_SAVE_SCREENSHOT_FILE_PNG = "OpenTTD-network-save.png";
/**
* Error handling for fatal user errors.
@@ -729,6 +736,16 @@ int openttd_main(int argc, char *argv[])
* just be out of the bounds of the window. */
_cursor.in_window = true;
+ {
+#ifndef WIN32
+ // Configure local font path on Android
+ //char curdir[PATH_MAX];
+ //getcwd(curdir, sizeof(curdir));
+ //setenv("FONTCONFIG_FONTS", (std::string(curdir) + "/fonts").c_str(), 1);
+ setenv("FONTCONFIG_FONTS", "fonts", 1);
+ DEBUG(misc, 1, "Set FONTCONFIG_FONTS to %s", getenv("FONTCONFIG_FONTS"));
+#endif
+ }
/* enumerate language files */
InitializeLanguagePacks();
@@ -755,7 +772,7 @@ int openttd_main(int argc, char *argv[])
GfxInitPalettes();
DEBUG(misc, 1, "Loading blitter...");
- if (blitter == NULL && _ini_blitter != NULL) blitter = stredup(_ini_blitter);
+ if (_ini_blitter != NULL) blitter = stredup(_ini_blitter);
_blitter_autodetected = StrEmpty(blitter);
/* Activate the initial blitter.
* This is only some initial guess, after NewGRFs have been loaded SwitchNewGRFBlitter may switch to a different one.
@@ -1162,6 +1179,24 @@ void SwitchToMode(SwitchMode new_mode)
ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
} else {
DeleteWindowById(WC_SAVELOAD, 0);
+#ifdef __ANDROID__
+ if (_settings_client.gui.save_to_network) {
+ char screenshotFile[PATH_MAX] = "";
+ const char* lastPart = strrchr(_file_to_saveload.name, PATHSEPCHAR);
+ if (!lastPart) {
+ lastPart = _file_to_saveload.name;
+ } else {
+ lastPart++;
+ }
+ MakeScreenshot(SC_VIEWPORT, NETWORK_SAVE_SCREENSHOT_FILE);
+ FioFindFullPath(screenshotFile, lastof(screenshotFile), SCREENSHOT_DIR, NETWORK_SAVE_SCREENSHOT_FILE_PNG);
+ uint64_t playedTime = abs(_date - DAYS_TILL(_settings_newgame.game_creation.starting_year)) * 1000;
+ int ret = SDL_ANDROID_CloudSave(_file_to_saveload.name, lastPart, "OpenTTD", lastPart, screenshotFile, playedTime);
+ if (_settings_client.gui.save_to_network == 2) {
+ _settings_client.gui.save_to_network = ret ? 1 : 0;
+ }
+ }
+#endif
}
break;
diff --git a/src/order_gui.cpp b/src/order_gui.cpp
index 3ca29e087a..edf5470e09 100644
--- a/src/order_gui.cpp
+++ b/src/order_gui.cpp
@@ -555,13 +555,16 @@ private:
assert(type > OPOS_NONE && type < OPOS_END);
static const HighLightStyle goto_place_style[OPOS_END - 1] = {
- HT_RECT | HT_VEHICLE, // OPOS_GOTO
+ HT_RECT | HT_VEHICLE | HT_SCROLL_VIEWPORT, // OPOS_GOTO
HT_NONE, // OPOS_CONDITIONAL
- HT_VEHICLE, // OPOS_SHARE
+ HT_VEHICLE | HT_SCROLL_VIEWPORT, // OPOS_SHARE
};
SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, goto_place_style[type - 1], this);
this->goto_type = type;
this->SetWidgetDirty(WID_O_GOTO);
+ if (type == OPOS_GOTO) {
+ MoveAllWindowsOffScreen();
+ }
}
/**
@@ -799,8 +802,8 @@ public:
{
switch (widget) {
case WID_O_ORDER_LIST:
- resize->height = FONT_HEIGHT_NORMAL;
- size->height = 6 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
+ resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
+ size->height = 4 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
break;
case WID_O_COND_VARIABLE: {
@@ -1086,8 +1089,8 @@ public:
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 y = r.top + WD_FRAMERECT_TOP;
int line_height = this->GetWidget(WID_O_ORDER_LIST)->resize_y;
+ int y = Center(r.top + WD_FRAMERECT_TOP, line_height);
int i = this->vscroll->GetPosition();
const Order *order = this->vehicle->GetOrder(i);
@@ -1112,7 +1115,7 @@ public:
}
/* Reset counters for drawing the orders. */
- y = r.top + WD_FRAMERECT_TOP;
+ y = Center(r.top + WD_FRAMERECT_TOP, line_height);
i = this->vscroll->GetPosition();
order = this->vehicle->GetOrder(i);
}
diff --git a/src/os/unix/crashlog_unix.cpp b/src/os/unix/crashlog_unix.cpp
index 47de057f7e..c0663a6b06 100644
--- a/src/os/unix/crashlog_unix.cpp
+++ b/src/os/unix/crashlog_unix.cpp
@@ -143,7 +143,11 @@ public:
};
/** The signals we want our crash handler to handle. */
+#ifdef __ANDROID__
+static const int _signals_to_handle[] = { }; // Default Android signal handler will give us stack trace
+#else
static const int _signals_to_handle[] = { SIGSEGV, SIGABRT, SIGFPE, SIGBUS, SIGILL };
+#endif
/**
* Entry point for the crash handler.
diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp
index d7c2304ce5..71c6d51f9d 100644
--- a/src/os/unix/unix.cpp
+++ b/src/os/unix/unix.cpp
@@ -27,7 +27,7 @@
#ifdef __APPLE__
#include
-#elif (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) || defined(__GLIBC__)
+#elif ((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) || defined(__GLIBC__)) && !defined(__ANDROID__)
#define HAS_STATVFS
#endif
@@ -65,6 +65,10 @@ ULONG __stack = (1024*1024)*2; // maybe not that much is needed actually ;)
#endif
#endif
+#ifdef __ANDROID__
+ #include "android/log.h"
+#endif
+
#include "../../safeguards.h"
bool FiosIsRoot(const char *path)
@@ -244,6 +248,9 @@ void ShowInfo(const char *str)
#if !defined(__APPLE__)
void ShowOSErrorBox(const char *buf, bool system)
{
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_FATAL, "OpenTTD", "[ERROR] %s", buf);
+#endif
/* All unix systems, except OSX. Only use escape codes on a TTY. */
if (isatty(fileno(stderr))) {
fprintf(stderr, "\033[1;31mError: %s\033[0;39m\n", buf);
@@ -258,6 +265,11 @@ void cocoaSetupAutoreleasePool();
void cocoaReleaseAutoreleasePool();
#endif
+#ifdef __ANDROID__
+#define main SDL_main
+extern "C" int CDECL main(int, char *[]);
+#endif
+
int CDECL main(int argc, char *argv[])
{
/* Make sure our arguments contain only valid UTF-8 characters. */
@@ -369,10 +381,23 @@ void OSOpenBrowser(const char *url)
pid_t child_pid = fork();
if (child_pid != 0) return;
+#ifdef __ANDROID__
+ const char *args[9];
+ args[0] = "/system/bin/am";
+ args[1] = "start";
+ args[2] = "-a";
+ args[3] = "android.intent.action.VIEW";
+ args[4] = "--user";
+ args[5] = "0";
+ args[6] = "-d";
+ args[7] = url;
+ args[8] = NULL;
+#else
const char *args[3];
args[0] = "xdg-open";
args[1] = url;
args[2] = NULL;
+#endif
execvp(args[0], const_cast(args));
DEBUG(misc, 0, "Failed to open url: %s", url);
exit(0);
diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp
index 974e465f43..71ae041b1d 100644
--- a/src/osk_gui.cpp
+++ b/src/osk_gui.cpp
@@ -105,7 +105,7 @@ struct OskWindow : public Window {
widget -= WID_OSK_LETTERS;
DrawCharCentered(_keyboard[this->shift][widget],
- r.left + 8,
+ (r.left + r.right) / 2,
r.top + 3,
TC_BLACK);
}
@@ -229,7 +229,8 @@ static const int INTER_KEY_SPACE = 2; // Number of pixels between two keys.
*/
static void AddKey(NWidgetHorizontal *hor, int height, int num_half, WidgetType widtype, int widnum, uint16 widdata, int *biggest_index)
{
- int key_width = HALF_KEY_WIDTH + (INTER_KEY_SPACE + HALF_KEY_WIDTH) * (num_half - 1);
+ int min_half_key = max(GetMinSizing(NWST_BUTTON), HALF_KEY_WIDTH);
+ int key_width = min_half_key + (INTER_KEY_SPACE + min_half_key) * (num_half - 1);
if (widtype == NWID_SPACER) {
if (!hor->IsEmpty()) key_width += INTER_KEY_SPACE;
@@ -252,7 +253,7 @@ static void AddKey(NWidgetHorizontal *hor, int height, int num_half, WidgetType
static NWidgetBase *MakeTopKeys(int *biggest_index)
{
NWidgetHorizontal *hor = new NWidgetHorizontal();
- int key_height = FONT_HEIGHT_NORMAL + 2;
+ int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 2);
AddKey(hor, key_height, 6 * 2, WWT_TEXTBTN, WID_OSK_CANCEL, STR_BUTTON_CANCEL, biggest_index);
AddKey(hor, key_height, 6 * 2, WWT_TEXTBTN, WID_OSK_OK, STR_BUTTON_OK, biggest_index);
@@ -264,7 +265,7 @@ static NWidgetBase *MakeTopKeys(int *biggest_index)
static NWidgetBase *MakeNumberKeys(int *biggest_index)
{
NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
- int key_height = FONT_HEIGHT_NORMAL + 6;
+ int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 6);
for (int widnum = WID_OSK_NUMBERS_FIRST; widnum <= WID_OSK_NUMBERS_LAST; widnum++) {
AddKey(hor, key_height, 2, WWT_PUSHBTN, widnum, 0x0, biggest_index);
@@ -276,7 +277,7 @@ static NWidgetBase *MakeNumberKeys(int *biggest_index)
static NWidgetBase *MakeQwertyKeys(int *biggest_index)
{
NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
- int key_height = FONT_HEIGHT_NORMAL + 6;
+ int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 6);
AddKey(hor, key_height, 3, WWT_PUSHIMGBTN, WID_OSK_SPECIAL, SPR_OSK_SPECIAL, biggest_index);
for (int widnum = WID_OSK_QWERTY_FIRST; widnum <= WID_OSK_QWERTY_LAST; widnum++) {
@@ -290,7 +291,7 @@ static NWidgetBase *MakeQwertyKeys(int *biggest_index)
static NWidgetBase *MakeAsdfgKeys(int *biggest_index)
{
NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
- int key_height = FONT_HEIGHT_NORMAL + 6;
+ int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 6);
AddKey(hor, key_height, 4, WWT_IMGBTN, WID_OSK_CAPS, SPR_OSK_CAPS, biggest_index);
for (int widnum = WID_OSK_ASDFG_FIRST; widnum <= WID_OSK_ASDFG_LAST; widnum++) {
@@ -303,7 +304,7 @@ static NWidgetBase *MakeAsdfgKeys(int *biggest_index)
static NWidgetBase *MakeZxcvbKeys(int *biggest_index)
{
NWidgetHorizontal *hor = new NWidgetHorizontalLTR();
- int key_height = FONT_HEIGHT_NORMAL + 6;
+ int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 6);
AddKey(hor, key_height, 3, WWT_IMGBTN, WID_OSK_SHIFT, SPR_OSK_SHIFT, biggest_index);
for (int widnum = WID_OSK_ZXCVB_FIRST; widnum <= WID_OSK_ZXCVB_LAST; widnum++) {
@@ -317,7 +318,7 @@ static NWidgetBase *MakeZxcvbKeys(int *biggest_index)
static NWidgetBase *MakeSpacebarKeys(int *biggest_index)
{
NWidgetHorizontal *hor = new NWidgetHorizontal();
- int key_height = FONT_HEIGHT_NORMAL + 6;
+ int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 6);
AddKey(hor, key_height, 8, NWID_SPACER, 0, 0, biggest_index);
AddKey(hor, key_height, 13, WWT_PUSHTXTBTN, WID_OSK_SPACE, STR_EMPTY, biggest_index);
@@ -329,7 +330,7 @@ static NWidgetBase *MakeSpacebarKeys(int *biggest_index)
static const NWidgetPart _nested_osk_widgets[] = {
- NWidget(WWT_CAPTION, COLOUR_GREY, WID_OSK_CAPTION), SetDataTip(STR_WHITE_STRING, STR_NULL),
+ NWidget(WWT_CAPTION, COLOUR_GREY, WID_OSK_CAPTION), SetSizingType(NWST_BUTTON), SetDataTip(STR_WHITE_STRING, STR_NULL),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(WWT_EDITBOX, COLOUR_GREY, WID_OSK_TEXT), SetMinimalSize(252, 12), SetPadding(2, 2, 2, 2),
EndContainer(),
diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp
index 73fe29da0d..2ff3a844a5 100644
--- a/src/rail_gui.cpp
+++ b/src/rail_gui.cpp
@@ -37,6 +37,7 @@
#include "station_map.h"
#include "tunnelbridge_map.h"
+#include "build_confirmation_func.h"
#include "widgets/rail_widget.h"
@@ -192,15 +193,7 @@ static void PlaceRail_Station(TileIndex tile)
VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION);
VpSetPlaceSizingLimit(_settings_game.station.station_spread);
} else {
- uint32 p1 = _cur_railtype | _railstation.orientation << 4 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24;
- uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
-
- int w = _settings_client.gui.station_numtracks;
- int h = _settings_client.gui.station_platlength;
- if (!_railstation.orientation) Swap(w, h);
-
- CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
- ShowSelectStationIfNeeded(cmdcont, TileArea(tile, w, h));
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_STATION);
}
}
@@ -255,22 +248,6 @@ static void GenericPlaceSignals(TileIndex tile)
}
}
-/**
- * Start placing a rail bridge.
- * @param tile Position of the first tile of the bridge.
- * @param w Rail toolbar window.
- */
-static void PlaceRail_Bridge(TileIndex tile, Window *w)
-{
- if (IsBridgeTile(tile)) {
- TileIndex other_tile = GetOtherTunnelBridgeEnd(tile);
- Point pt = {0, 0};
- w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, other_tile, tile);
- } else {
- VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE);
- }
-}
-
/** Command callback for building a tunnel */
void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
{
@@ -305,12 +282,15 @@ static bool RailToolbar_CtrlChanged(Window *w)
if (w->IsWidgetDisabled(WID_RAT_REMOVE)) return false;
/* allow ctrl to switch remove mode only for these widgets */
+ // This breaks joining rail stations functionality on Android
+ /*
for (uint i = WID_RAT_BUILD_NS; i <= WID_RAT_BUILD_STATION; i++) {
if ((i <= WID_RAT_AUTORAIL || i >= WID_RAT_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
ToggleRailButton_Remove(w);
return true;
}
}
+ */
return false;
}
@@ -419,6 +399,7 @@ static void HandleAutoSignalPlacement()
struct BuildRailToolbarWindow : Window {
RailType railtype; ///< Rail type to build.
int last_user_action; ///< Last started user action.
+ bool last_user_action_remove; ///< Use bulldozer button with last action
BuildRailToolbarWindow(WindowDesc *desc, RailType railtype) : Window(desc)
{
@@ -426,12 +407,14 @@ struct BuildRailToolbarWindow : Window {
this->SetupRailToolbar(railtype);
this->DisableWidget(WID_RAT_REMOVE);
this->last_user_action = WIDGET_LIST_END;
+ this->last_user_action_remove = false;
if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
}
~BuildRailToolbarWindow()
{
+ if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort();
if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
}
@@ -558,7 +541,7 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_BUILD_DEPOT:
- if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT)) {
+ if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT | HT_SCROLL_VIEWPORT)) {
ShowBuildTrainDepotPicker(this);
this->last_user_action = widget;
}
@@ -567,7 +550,7 @@ struct BuildRailToolbarWindow : Window {
case WID_RAT_BUILD_WAYPOINT:
this->last_user_action = widget;
_waypoint_count = StationClass::Get(STAT_CLASS_WAYP)->GetSpecCount();
- if (HandlePlacePushButton(this, WID_RAT_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, HT_RECT) && _waypoint_count > 1) {
+ if (HandlePlacePushButton(this, WID_RAT_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, HT_RECT | HT_SCROLL_VIEWPORT) && _waypoint_count > 1) {
ShowBuildWaypointPicker(this);
}
break;
@@ -647,9 +630,7 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_BUILD_DEPOT:
- DoCommandP(tile, _cur_railtype, _build_depot_direction,
- CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
- CcRailDepot);
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE);
break;
case WID_RAT_BUILD_WAYPOINT:
@@ -665,11 +646,11 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_BUILD_BRIDGE:
- PlaceRail_Bridge(tile, this);
+ VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE);
break;
case WID_RAT_BUILD_TUNNEL:
- DoCommandP(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel);
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_BRIDGE);
break;
case WID_RAT_CONVERT_RAIL:
@@ -678,6 +659,7 @@ struct BuildRailToolbarWindow : Window {
default: NOT_REACHED();
}
+ MoveAllWindowsOffScreen();
}
virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
@@ -685,17 +667,38 @@ struct BuildRailToolbarWindow : Window {
/* no dragging if you have pressed the convert button */
if (FindWindowById(WC_BUILD_SIGNAL, 0) != NULL && _convert_signal_button && this->IsWidgetLowered(WID_RAT_BUILD_SIGNALS)) return;
+ switch (this->last_user_action) {
+ case WID_RAT_BUILD_TUNNEL:
+ this->OnPlacePresize(pt, TileVirtXY(pt.x, pt.y));
+ return;
+ default:
+ break;
+ }
+
VpSelectTilesWithMethod(pt.x, pt.y, select_method);
}
virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
{
if (pt.x != -1) {
+ this->last_user_action_remove = _remove_button_clicked;
switch (select_proc) {
default: NOT_REACHED();
+ case DDSP_PLACE_AUTOROAD:
+ assert(this->last_user_action == WID_RAT_BUILD_BRIDGE);
case DDSP_BUILD_BRIDGE:
- if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
- ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype);
+ switch (this->last_user_action) {
+ case WID_RAT_BUILD_TUNNEL:
+ if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
+ else VpStartPreSizing();
+ DoCommandP(end_tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel);
+ break;
+ case WID_RAT_BUILD_BRIDGE:
+ if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
+ ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype);
+ break;
+ default: NOT_REACHED();
+ }
break;
case DDSP_PLACE_RAIL:
@@ -721,7 +724,19 @@ struct BuildRailToolbarWindow : Window {
if (_remove_button_clicked) {
DoCommandP(end_tile, start_tile, _ctrl_pressed ? 0 : 1, CMD_REMOVE_FROM_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION), CcPlaySound_SPLAT_RAIL);
} else {
- HandleStationPlacement(start_tile, end_tile);
+ if (!_settings_client.gui.station_dragdrop) {
+ uint32 p1 = _cur_railtype | _railstation.orientation << 4 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24;
+ uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
+
+ int w = _settings_client.gui.station_numtracks;
+ int h = _settings_client.gui.station_platlength;
+ if (!_railstation.orientation) Swap(w, h);
+
+ CommandContainer cmdcont = { end_tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
+ ShowSelectStationIfNeeded(cmdcont, TileArea(end_tile, w, h));
+ } else {
+ HandleStationPlacement(start_tile, end_tile);
+ }
}
} else {
/* Waypoint */
@@ -737,16 +752,27 @@ struct BuildRailToolbarWindow : Window {
}
}
break;
+
+ case DDSP_SINGLE_TILE:
+ assert(end_tile == start_tile);
+ assert(last_user_action == WID_RAT_BUILD_DEPOT);
+ DoCommandP(end_tile, _cur_railtype, _build_depot_direction,
+ CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
+ CcRailDepot);
+ break;
}
+ MoveAllHiddenWindowsBackToScreen();
}
}
virtual void OnPlaceObjectAbort()
{
+ MoveAllHiddenWindowsBackToScreen();
this->RaiseButtons();
this->DisableWidget(WID_RAT_REMOVE);
this->SetWidgetDirty(WID_RAT_REMOVE);
+ if (ConfirmationWindowShown() && (this->last_user_action == WID_RAT_BUILD_BRIDGE || _ctrl_pressed)) return;
DeleteWindowById(WC_BUILD_SIGNAL, TRANSPORT_RAIL);
DeleteWindowById(WC_BUILD_STATION, TRANSPORT_RAIL);
DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_RAIL);
@@ -755,10 +781,30 @@ struct BuildRailToolbarWindow : Window {
DeleteWindowByClass(WC_BUILD_BRIDGE);
}
- virtual void OnPlacePresize(Point pt, TileIndex tile)
+ virtual void SelectLastTool()
{
- DoCommand(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL);
- VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
+ // User misplaced something - activate last selected tool again
+ if (this->last_user_action == WIDGET_LIST_END)
+ return;
+ Point dummy = {0, 0};
+ this->RaiseWidget(this->last_user_action);
+ this->OnClick(dummy, this->last_user_action, 0);
+ if (this->last_user_action_remove) BuildRailClick_Remove(this);
+ }
+
+ virtual void OnPlacePresize(Point pt, TileIndex tile_from)
+ {
+ TileIndex tile_to = tile_from;
+
+ if (this->last_user_action == WID_RAT_BUILD_BRIDGE) {
+ tile_to = IsBridgeTile(tile_from) ? GetOtherBridgeEnd(tile_from) : TileVirtXY(pt.x, pt.y);
+ } else {
+ assert(this->last_user_action == WID_RAT_BUILD_TUNNEL);
+ DoCommand(tile_from, _cur_railtype | (TRANSPORT_RAIL << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL);
+ tile_to = _build_tunnel_endtile == 0 ? tile_from : _build_tunnel_endtile;
+ }
+
+ VpSetPresizeRange(tile_from, tile_to);
}
virtual EventState OnCTRLStateChange()
@@ -869,7 +915,7 @@ Window *ShowBuildRailToolbar(RailType railtype)
if (!Company::IsValidID(_local_company)) return NULL;
if (!ValParamRailtype(railtype)) return NULL;
- DeleteWindowByClass(WC_BUILD_TOOLBAR);
+ DeleteToolbarLinkedWindows();
_cur_railtype = railtype;
_remove_button_clicked = false;
return new BuildRailToolbarWindow(&_build_rail_desc, railtype);
@@ -1056,8 +1102,8 @@ public:
d = maxdim(d, GetStringBoundingBox(StationClass::Get((StationClassID)i)->name));
}
size->width = max(size->width, d.width + padding.width);
- this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
- size->height = 5 * this->line_height;
+ this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM);
+ size->height = 3 * this->line_height;
resize->height = this->line_height;
break;
}
@@ -1100,6 +1146,13 @@ public:
fill->height = 1;
resize->height = 1;
break;
+
+ case WID_BRAS_NEWST_SPACER:
+ size->height = 0;
+ if (_railstation.newstations) {
+ size->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
+ }
+ break;
}
}
@@ -1142,7 +1195,8 @@ public:
for (uint i = 0; i < StationClass::GetClassCount(); i++) {
if (i == STAT_CLASS_WAYP) continue;
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(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT,
+ Center(row * this->line_height + r.top, this->line_height),
StationClass::Get((StationClassID)i)->name,
(StationClassID)i == _railstation.station_class ? TC_WHITE : TC_BLACK);
row++;
@@ -1392,12 +1446,22 @@ static const NWidgetPart _nested_station_builder_widgets[] = {
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_BRAS_NEWST_SCROLL),
EndContainer(),
EndContainer(),
- NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(1, 2, 0, 2),
NWidget(NWID_HORIZONTAL),
+ NWidget(NWID_VERTICAL),
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(1, 2, 0, 2),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAS_PLATFORM_DIR_X), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 60), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAS_PLATFORM_DIR_Y), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 60), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
+ EndContainer(),
+ EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAS_PLATFORM_DIR_X), SetMinimalSize(66, 60), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAS_PLATFORM_DIR_Y), SetMinimalSize(66, 60), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(),
+ NWidget(NWID_VERTICAL),
+ NWidget(NWID_SPACER), SetMinimalSize(1, 0), SetFill(0, 1),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_DRAG_N_DROP), SetMinimalSize(75, 12), SetDataTip(STR_STATION_BUILD_DRAG_DROP, STR_STATION_BUILD_DRAG_DROP_TOOLTIP),
+ EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0),
EndContainer(),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BRAS_SHOW_NEWST_TYPE), SetMinimalSize(144, 11), SetDataTip(STR_ORANGE_STRING, STR_NULL), SetPadding(1, 2, 4, 2),
@@ -1427,31 +1491,36 @@ static const NWidgetPart _nested_station_builder_widgets[] = {
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
NWidget(NWID_HORIZONTAL),
- NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_DRAG_N_DROP), SetMinimalSize(75, 12), SetDataTip(STR_STATION_BUILD_DRAG_DROP, STR_STATION_BUILD_DRAG_DROP_TOOLTIP),
- NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
- EndContainer(),
- NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(3, 2, 0, 2),
- NWidget(NWID_HORIZONTAL),
- NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_HIGHLIGHT_OFF), SetMinimalSize(60, 12),
- SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_HIGHLIGHT_ON), SetMinimalSize(60, 12),
- SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
- NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
+ NWidget(NWID_VERTICAL),
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(3, 2, 0, 2),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_HIGHLIGHT_OFF), SetMinimalSize(60, 12),
+ SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_HIGHLIGHT_ON), SetMinimalSize(60, 12),
+ SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
+ NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0),
+ EndContainer(),
+ EndContainer(),
EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 2),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BRAS_SHOW_NEWST_MATRIX),
/* We need an additional background for the matrix, as the matrix cannot handle the scrollbar due to not being an NWidgetCore. */
- NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BRAS_MATRIX_SCROLL),
- NWidget(NWID_HORIZONTAL),
- NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BRAS_MATRIX), SetScrollbar(WID_BRAS_MATRIX_SCROLL), SetPIP(0, 2, 0), SetPadding(2, 0, 0, 0),
- NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BRAS_IMAGE), SetMinimalSize(66, 60),
- SetFill(0, 0), SetResize(0, 0), SetDataTip(0x0, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(WID_BRAS_MATRIX_SCROLL),
+ NWidget(NWID_VERTICAL),
+ NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BRAS_MATRIX_SCROLL),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BRAS_MATRIX), SetScrollbar(WID_BRAS_MATRIX_SCROLL), SetPIP(0, 2, 0), SetPadding(2, 0, 0, 0),
+ NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BRAS_IMAGE), SetMinimalSize(66, 60),
+ SetFill(0, 0), SetResize(0, 0), SetDataTip(0x0, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(WID_BRAS_MATRIX_SCROLL),
+ EndContainer(),
EndContainer(),
+ NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_BRAS_MATRIX_SCROLL),
EndContainer(),
- NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_BRAS_MATRIX_SCROLL),
EndContainer(),
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BRAS_NEWST_SPACER), SetDataTip(STR_EMPTY, STR_NULL),
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_EMPTY, STR_NULL),
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_EMPTY, STR_NULL),
EndContainer(),
EndContainer(),
EndContainer(),
@@ -1469,7 +1538,7 @@ static const NWidgetPart _nested_station_builder_widgets[] = {
/** High level window description of the station-build window (default & newGRF) */
static WindowDesc _station_builder_desc(
- WDP_AUTO, "build_station_rail", 350, 0,
+ WDP_AUTO, "build_station_rail", 0, 0,
WC_BUILD_STATION, WC_BUILD_TOOLBAR,
WDF_CONSTRUCTION,
_nested_station_builder_widgets, lengthof(_nested_station_builder_widgets)
@@ -1657,6 +1726,9 @@ static const NWidgetPart _nested_signal_builder_widgets[] = {
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_SEMAPHORE_PBS), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP), EndContainer(), SetFill(1, 1),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_SEMAPHORE_PBS_OWAY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP), EndContainer(), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_BS_CONVERT), SetDataTip(SPR_IMG_SIGNAL_CONVERT, STR_BUILD_SIGNAL_CONVERT_TOOLTIP), SetFill(1, 1),
+ NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1),
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BS_DRAG_SIGNALS_DENSITY_LABEL), SetDataTip(STR_ORANGE_INT, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1),
+ EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_NORM), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP), EndContainer(), SetFill(1, 1),
@@ -1666,14 +1738,10 @@ static const NWidgetPart _nested_signal_builder_widgets[] = {
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_PBS), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP), EndContainer(), SetFill(1, 1),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_PBS_OWAY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP), EndContainer(), SetFill(1, 1),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1),
- NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BS_DRAG_SIGNALS_DENSITY_LABEL), SetDataTip(STR_ORANGE_INT, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1),
- NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
- NWidget(NWID_SPACER), SetFill(1, 0),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_BS_DRAG_SIGNALS_DENSITY_DECREASE), SetMinimalSize(9, 12), SetDataTip(AWV_DECREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP),
- NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_BS_DRAG_SIGNALS_DENSITY_INCREASE), SetMinimalSize(9, 12), SetDataTip(AWV_INCREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP),
- NWidget(NWID_SPACER), SetFill(1, 0),
- EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_BS_DRAG_SIGNALS_DENSITY_DECREASE), SetSizingType(NWST_STEP), SetMinimalSize(9, 12), SetDataTip(AWV_DECREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP),
+ EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1),
+ NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_BS_DRAG_SIGNALS_DENSITY_INCREASE), SetSizingType(NWST_STEP), SetMinimalSize(9, 12), SetDataTip(AWV_INCREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP),
EndContainer(),
EndContainer(),
EndContainer(),
@@ -1745,18 +1813,18 @@ static const NWidgetPart _nested_build_depot_widgets[] = {
NWidget(NWID_HORIZONTAL_LTR),
NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
NWidget(NWID_VERTICAL),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_NW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_SW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(NWID_VERTICAL),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_NE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_SE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
diff --git a/src/rev.cpp.in b/src/rev.cpp.in
index 899a565bbe..a8e1f74a0b 100644
--- a/src/rev.cpp.in
+++ b/src/rev.cpp.in
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: rev.cpp.in 27518 2016-03-01 20:00:22Z frosch $ */
/*
* This file is part of OpenTTD.
diff --git a/src/road_gui.cpp b/src/road_gui.cpp
index 801d334351..4ab5091e21 100644
--- a/src/road_gui.cpp
+++ b/src/road_gui.cpp
@@ -29,6 +29,7 @@
#include "hotkeys.h"
#include "road_gui.h"
#include "zoom_func.h"
+#include "build_confirmation_func.h"
#include "widgets/road_widget.h"
@@ -69,21 +70,6 @@ void CcPlaySound_SPLAT_OTHER(const CommandCost &result, TileIndex tile, uint32 p
if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT_OTHER, tile);
}
-/**
- * Callback to start placing a bridge.
- * @param tile Start tile of the bridge.
- */
-static void PlaceRoad_Bridge(TileIndex tile, Window *w)
-{
- if (IsBridgeTile(tile)) {
- TileIndex other_tile = GetOtherTunnelBridgeEnd(tile);
- Point pt = {0, 0};
- w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, other_tile, tile);
- } else {
- VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE);
- }
-}
-
/**
* Callback executed after a build road tunnel command has been called.
*
@@ -297,12 +283,15 @@ static bool RoadToolbar_CtrlChanged(Window *w)
if (w->IsWidgetDisabled(WID_ROT_REMOVE)) return false;
/* allow ctrl to switch remove mode only for these widgets */
+ // This breaks joining stations functionality on Android
+ /*
for (uint i = WID_ROT_ROAD_X; i <= WID_ROT_AUTOROAD; i++) {
if (w->IsWidgetLowered(i)) {
ToggleRoadButton_Remove(w);
return true;
}
}
+ */
return false;
}
@@ -310,6 +299,8 @@ static bool RoadToolbar_CtrlChanged(Window *w)
/** Road toolbar window handler. */
struct BuildRoadToolbarWindow : Window {
int last_started_action; ///< Last started user action.
+ bool last_started_action_remove; ///< Use bulldozer button with last action
+ bool last_started_action_oneway; ///< Use 'one way road' button with last action
BuildRoadToolbarWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
{
@@ -321,12 +312,15 @@ struct BuildRoadToolbarWindow : Window {
this->OnInvalidateData();
this->last_started_action = WIDGET_LIST_END;
+ this->last_started_action_remove = false;
+ this->last_started_action_oneway = false;
if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
}
~BuildRoadToolbarWindow()
{
+ if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort();
if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
}
@@ -430,7 +424,7 @@ struct BuildRoadToolbarWindow : Window {
case WID_ROT_DEPOT:
if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD)) return;
- if (HandlePlacePushButton(this, WID_ROT_DEPOT, SPR_CURSOR_ROAD_DEPOT, HT_RECT)) {
+ if (HandlePlacePushButton(this, WID_ROT_DEPOT, SPR_CURSOR_ROAD_DEPOT, HT_RECT | HT_SCROLL_VIEWPORT)) {
ShowRoadDepotPicker(this);
this->last_started_action = widget;
}
@@ -518,8 +512,7 @@ struct BuildRoadToolbarWindow : Window {
break;
case WID_ROT_DEPOT:
- DoCommandP(tile, _cur_roadtype << 2 | _road_depot_orientation, 0,
- CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot);
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE);
break;
case WID_ROT_BUS_STATION:
@@ -531,20 +524,21 @@ struct BuildRoadToolbarWindow : Window {
break;
case WID_ROT_BUILD_BRIDGE:
- PlaceRoad_Bridge(tile, this);
+ VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE);
break;
case WID_ROT_BUILD_TUNNEL:
- DoCommandP(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0,
- CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel);
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_BRIDGE);
break;
default: NOT_REACHED();
}
+ MoveAllWindowsOffScreen();
}
virtual void OnPlaceObjectAbort()
{
+ MoveAllHiddenWindowsBackToScreen();
this->RaiseButtons();
this->SetWidgetsDisabledState(true,
WID_ROT_REMOVE,
@@ -553,6 +547,7 @@ struct BuildRoadToolbarWindow : Window {
this->SetWidgetDirty(WID_ROT_REMOVE);
this->SetWidgetDirty(WID_ROT_ONE_WAY);
+ if (ConfirmationWindowShown() && (this->last_started_action == WID_ROT_BUILD_BRIDGE || _ctrl_pressed)) return;
DeleteWindowById(WC_BUS_STATION, TRANSPORT_ROAD);
DeleteWindowById(WC_TRUCK_STATION, TRANSPORT_ROAD);
DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_ROAD);
@@ -560,8 +555,26 @@ struct BuildRoadToolbarWindow : Window {
DeleteWindowByClass(WC_BUILD_BRIDGE);
}
+ virtual void SelectLastTool()
+ {
+ // User misplaced something - activate last selected tool again
+ if (this->last_started_action == WIDGET_LIST_END)
+ return;
+ Point dummy = {0, 0};
+ this->RaiseWidget(this->last_started_action);
+ this->OnClick(dummy, this->last_started_action, 0);
+ if (this->last_started_action_remove) ToggleRoadButton_Remove(this);
+ if (this->last_started_action_oneway) this->LowerWidget(WID_ROT_ONE_WAY);
+ _one_way_button_clicked = this->last_started_action_oneway;
+ }
+
virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
{
+ if (this->last_started_action == WID_ROT_BUILD_TUNNEL) {
+ this->OnPlacePresize(pt, TileVirtXY(pt.x, pt.y));
+ return;
+ }
+
/* Here we update the end tile flags
* of the road placement actions.
* At first we reset the end halfroad
@@ -593,7 +606,6 @@ struct BuildRoadToolbarWindow : Window {
/* Set dir = Y */
_place_road_flag |= RF_DIR_Y;
}
-
break;
default:
@@ -606,11 +618,24 @@ struct BuildRoadToolbarWindow : Window {
virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
{
if (pt.x != -1) {
+ this->last_started_action_remove = _remove_button_clicked;
+ this->last_started_action_oneway = _one_way_button_clicked;
switch (select_proc) {
default: NOT_REACHED();
case DDSP_BUILD_BRIDGE:
- if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
- ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(_cur_roadtype));
+ switch (last_started_action) {
+ case WID_ROT_BUILD_TUNNEL:
+ if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
+ else VpStartPreSizing();
+ DoCommandP(end_tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0,
+ CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel);
+ break;
+ case WID_ROT_BUILD_BRIDGE:
+ if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
+ ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(_cur_roadtype));
+ break;
+ default: NOT_REACHED();
+ }
break;
case DDSP_DEMOLISH_AREA:
@@ -651,7 +676,16 @@ struct BuildRoadToolbarWindow : Window {
DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_TRUCK]), CcPlaySound_SPLAT_OTHER);
break;
}
+
+ case DDSP_SINGLE_TILE:
+ /* Build depot. */
+ assert(start_tile == end_tile);
+ assert(last_started_action == WID_ROT_DEPOT);
+ DoCommandP(start_tile, _cur_roadtype << 2 | _road_depot_orientation, 0,
+ CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot);
+ break;
}
+ MoveAllHiddenWindowsBackToScreen();
}
}
@@ -807,7 +841,7 @@ Window *ShowBuildRoadToolbar(RoadType roadtype)
if (!Company::IsValidID(_local_company)) return NULL;
_cur_roadtype = roadtype;
- DeleteWindowByClass(WC_BUILD_TOOLBAR);
+ DeleteToolbarLinkedWindows();
return AllocateWindowDescFront(roadtype == ROADTYPE_ROAD ? &_build_road_desc : &_build_tramway_desc, TRANSPORT_ROAD);
}
@@ -839,7 +873,7 @@ static const NWidgetPart _nested_build_road_scen_widgets[] = {
};
static WindowDesc _build_road_scen_desc(
- WDP_AUTO, "toolbar_road_scen", 0, 0,
+ WDP_ALIGN_TOOLBAR, "toolbar_road_scen", 0, 0,
WC_SCEN_BUILD_TOOLBAR, WC_NONE,
WDF_CONSTRUCTION,
_nested_build_road_scen_widgets, lengthof(_nested_build_road_scen_widgets),
@@ -852,6 +886,7 @@ static WindowDesc _build_road_scen_desc(
*/
Window *ShowBuildRoadScenToolbar()
{
+ DeleteToolbarLinkedWindows();
_cur_roadtype = ROADTYPE_ROAD;
return AllocateWindowDescFront(&_build_road_scen_desc, TRANSPORT_ROAD);
}
@@ -915,18 +950,18 @@ static const NWidgetPart _nested_build_road_depot_widgets[] = {
NWidget(NWID_HORIZONTAL_LTR),
NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
NWidget(NWID_VERTICAL),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(NWID_VERTICAL),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
@@ -1065,17 +1100,17 @@ static const NWidgetPart _nested_road_station_picker_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(0, 3),
NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
NWidget(NWID_SPACER), SetFill(1, 0),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
NWidget(NWID_SPACER), SetFill(1, 0),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 1),
@@ -1112,8 +1147,8 @@ static const NWidgetPart _nested_tram_station_picker_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(0, 3),
NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
NWidget(NWID_SPACER), SetFill(1, 0),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 1),
diff --git a/src/screenshot.cpp b/src/screenshot.cpp
index a24cc6b211..438b816502 100644
--- a/src/screenshot.cpp
+++ b/src/screenshot.cpp
@@ -25,6 +25,7 @@
#include "window_func.h"
#include "tile_map.h"
#include "landscape.h"
+#include "blitter/16bpp_base.hpp"
#include "table/strings.h"
@@ -36,7 +37,7 @@ static const char * const HEIGHTMAP_NAME = "heightmap"; ///< Default filename
char _screenshot_format_name[8]; ///< Extension of the current screenshot format (corresponds with #_cur_screenshot_format).
uint _num_screenshot_formats; ///< Number of available screenshot formats.
uint _cur_screenshot_format; ///< Index of the currently selected screenshot format in #_screenshot_formats.
-static char _screenshot_name[128]; ///< Filename of the screenshot file.
+static char _screenshot_name[256]; ///< Filename of the screenshot file.
char _full_screenshot_name[MAX_PATH]; ///< Pathname of the screenshot file.
/**
@@ -272,7 +273,8 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user
png_infop info_ptr;
/* only implemented for 8bit and 32bit images so far. */
- if (pixelformat != 8 && pixelformat != 32) return false;
+ if (pixelformat != 8 && pixelformat != 32 && pixelformat != 16) return false;
+ if (pixelformat == 16) bpp = 3;
f = fopen(name, "wb");
if (f == NULL) return false;
@@ -386,6 +388,17 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user
/* render the pixels into the buffer */
callb(userdata, buff, y, w, n);
y += n;
+ if (pixelformat == 16) {
+ // Convert to 24bpp
+ Blitter_16bppBase::Colour16 *inp = (Blitter_16bppBase::Colour16 *)buff;
+ uint8 *outp = (uint8 *)buff;
+ for (i = 1; i <= w * n; i++) {
+ outp[(w * n - i) * 3 ] = inp[w * n - i].r << 3;
+ outp[(w * n - i) * 3 + 1] = inp[w * n - i].g << 2;
+ outp[(w * n - i) * 3 + 2] = inp[w * n - i].b << 3;
+ //outp[(w * n - i) * 3] = 0xff;
+ }
+ }
/* write them to png */
for (i = 0; i != n; i++) {
@@ -858,7 +871,7 @@ bool MakeScreenshot(ScreenshotType t, const char *name)
if (ret) {
SetDParamStr(0, _screenshot_name);
- ShowErrorMessage(STR_MESSAGE_SCREENSHOT_SUCCESSFULLY, INVALID_STRING_ID, WL_WARNING);
+ //ShowErrorMessage(STR_MESSAGE_SCREENSHOT_SUCCESSFULLY, INVALID_STRING_ID, WL_WARNING); // No need for message when we're doing cloudsave
} else {
ShowErrorMessage(STR_ERROR_SCREENSHOT_FAILED, INVALID_STRING_ID, WL_ERROR);
}
diff --git a/src/script/api/game/game_window.hpp.sq b/src/script/api/game/game_window.hpp.sq
index f52de827d9..b4dfd1820c 100644
--- a/src/script/api/game/game_window.hpp.sq
+++ b/src/script/api/game/game_window.hpp.sq
@@ -627,8 +627,10 @@ void SQGSWindow_Register(Squirrel *engine)
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_VSCROLLBAR, "WID_TF_VSCROLLBAR");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_HSCROLLBAR, "WID_TF_HSCROLLBAR");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_LIST_LEFT, "WID_MTS_LIST_LEFT");
+ SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_LEFT_SCROLLBAR, "WID_MTS_LEFT_SCROLLBAR");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_PLAYLIST, "WID_MTS_PLAYLIST");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_LIST_RIGHT, "WID_MTS_LIST_RIGHT");
+ SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_RIGHT_SCROLLBAR, "WID_MTS_RIGHT_SCROLLBAR");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_ALL, "WID_MTS_ALL");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_OLD, "WID_MTS_OLD");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_NEW, "WID_MTS_NEW");
@@ -1193,6 +1195,9 @@ void SQGSWindow_Register(Squirrel *engine)
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_MESSAGES, "WID_TN_MESSAGES");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_HELP, "WID_TN_HELP");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_SWITCH_BAR, "WID_TN_SWITCH_BAR");
+ SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_CTRL, "WID_TN_CTRL");
+ SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_SHIFT, "WID_TN_SHIFT");
+ SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_DELETE, "WID_TN_DELETE");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_END, "WID_TN_END");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_PAUSE, "WID_TE_PAUSE");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_FAST_FORWARD, "WID_TE_FAST_FORWARD");
diff --git a/src/script/api/script_date.cpp b/src/script/api/script_date.cpp
index 2f5b399633..4290a4feb5 100644
--- a/src/script/api/script_date.cpp
+++ b/src/script/api/script_date.cpp
@@ -9,8 +9,8 @@
/** @file script_date.cpp Implementation of ScriptDate. */
+#include "../../stdafx.h" /* Have to be included before time.h, if we want UINT32_MAX macro defined on Android */
#include
-#include "../../stdafx.h"
#include "script_date.hpp"
#include "../../date_func.h"
diff --git a/src/script/api/script_window.hpp b/src/script/api/script_window.hpp
index fbdffb54b7..85f5514e94 100644
--- a/src/script/api/script_window.hpp
+++ b/src/script/api/script_window.hpp
@@ -135,6 +135,13 @@ public:
*/
WC_MAIN_TOOLBAR = ::WC_MAIN_TOOLBAR,
+ /**
+ * Main toolbar (the long bar at the top); %Window numbers:
+ * - 0 = #ToolbarNormalWidgets
+ * - 0 = #ToolbarEditorWidgets
+ */
+ WC_MAIN_TOOLBAR_RIGHT = ::WC_MAIN_TOOLBAR_RIGHT,
+
/**
* Statusbar (at the bottom of your screen); %Window numbers:
* - 0 = #StatusbarWidgets
@@ -1581,9 +1588,11 @@ public:
/* automatically generated from ../../widgets/music_widget.h */
/** Widgets of the #MusicTrackSelectionWindow class. */
enum MusicTrackSelectionWidgets {
- WID_MTS_LIST_LEFT = ::WID_MTS_LIST_LEFT, ///< Left button.
- WID_MTS_PLAYLIST = ::WID_MTS_PLAYLIST, ///< Playlist.
- WID_MTS_LIST_RIGHT = ::WID_MTS_LIST_RIGHT, ///< Right button.
+ WID_MTS_LIST_LEFT = ::WID_MTS_LIST_LEFT, ///< Left list.
+ WID_MTS_LEFT_SCROLLBAR = ::WID_MTS_LEFT_SCROLLBAR, ///< Scrollbar of left list.
+ WID_MTS_PLAYLIST = ::WID_MTS_PLAYLIST, ///< Playlist name.
+ WID_MTS_LIST_RIGHT = ::WID_MTS_LIST_RIGHT, ///< Right list.
+ WID_MTS_RIGHT_SCROLLBAR = ::WID_MTS_RIGHT_SCROLLBAR, ///< Scrollbar of right list.
WID_MTS_ALL = ::WID_MTS_ALL, ///< All button.
WID_MTS_OLD = ::WID_MTS_OLD, ///< Old button.
WID_MTS_NEW = ::WID_MTS_NEW, ///< New button.
@@ -2394,6 +2403,9 @@ public:
WID_TN_MESSAGES = ::WID_TN_MESSAGES, ///< Messages menu.
WID_TN_HELP = ::WID_TN_HELP, ///< Help menu.
WID_TN_SWITCH_BAR = ::WID_TN_SWITCH_BAR, ///< Only available when toolbar has been split to switch between different subsets.
+ WID_TN_CTRL = ::WID_TN_CTRL, ///< On-screen Ctrl key
+ WID_TN_SHIFT = ::WID_TN_SHIFT, ///< On-screen Sgift key
+ WID_TN_DELETE = ::WID_TN_DELETE, ///< Close all windows
WID_TN_END = ::WID_TN_END, ///< Helper for knowing the amount of widgets.
};
diff --git a/src/settings.cpp b/src/settings.cpp
index e6754bb905..a3276f83c1 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -54,6 +54,7 @@
#include "base_media_base.h"
#include "gamelog.h"
#include "settings_func.h"
+#include "settings_gui.h"
#include "ini_type.h"
#include "ai/ai_config.hpp"
#include "ai/ai.hpp"
@@ -64,6 +65,7 @@
#include "roadveh.h"
#include "fios.h"
#include "strings_func.h"
+#include "toolbar_gui.h"
#include "void_map.h"
#include "station_base.h"
@@ -1077,6 +1079,16 @@ static bool ZoomMinMaxChanged(int32 p1)
return true;
}
+static bool VerticalToolbarChanged(int32 p1)
+{
+ if (FindWindowByClass(WC_MAIN_TOOLBAR)) {
+ HideVitalWindows();
+ ShowVitalWindows();
+ ReInitAllWindows();
+ }
+ return true;
+}
+
/**
* Update any possible saveload window and delete any newgrf dialogue as
* its widget parts might change. Reinit all windows as it allows access to the
diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp
index 0652d1bd81..2b68f3093a 100644
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -36,11 +36,18 @@
#include "textfile_gui.h"
#include "stringfilter_type.h"
#include "querystring_gui.h"
+#include "fontcache.h"
+#include "settings_func.h"
#include
#include "safeguards.h"
+#ifdef __ANDROID__
+#include
+#endif
+
+enum { MIN_BUTTON_SIZE = 10, MAX_BUTTON_SIZE = 100 };
static const StringID _driveside_dropdown[] = {
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT,
@@ -113,6 +120,8 @@ static int GetCurRes()
static void ShowCustCurrency();
+static void ReconstructUserInterface();
+
template
static DropDownList *BuiltSetDropDownList(int *selected_index)
{
@@ -178,6 +187,7 @@ struct GameOptionsWindow : Window {
{
DeleteWindowById(WC_CUSTOM_CURRENCY, 0);
if (this->reload) _switch_mode = SM_MENU;
+ SaveToConfig(); // save all settins immediately on Android, because users tend to kill the app instead of pressing 'Quit' button
}
/**
@@ -286,6 +296,19 @@ struct GameOptionsWindow : Window {
}
break;
+ case WID_GO_BUTTON_SIZE_DROPDOWN: // Dropdowns for size of all GUI elements and fonts
+ case WID_GO_TEXT_SIZE_DROPDOWN:
+ list = new DropDownList();
+ *selected_index = (widget == WID_GO_BUTTON_SIZE_DROPDOWN) ?
+ _settings_client.gui.min_button :
+ _freetype.medium.size;
+ for (uint i = MIN_BUTTON_SIZE; i <= MAX_BUTTON_SIZE; i++) {
+ DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false);
+ item->SetParam(0, i);
+ *list->Append() = item;
+ }
+ break;
+
case WID_GO_GUI_ZOOM_DROPDOWN: {
list = new DropDownList();
*selected_index = ZOOM_LVL_OUT_4X - _gui_zoom;
@@ -324,6 +347,8 @@ struct GameOptionsWindow : Window {
case WID_GO_AUTOSAVE_DROPDOWN: SetDParam(0, _autosave_dropdown[_settings_client.gui.autosave]); break;
case WID_GO_LANG_DROPDOWN: SetDParamStr(0, _current_language->own_name); break;
case WID_GO_RESOLUTION_DROPDOWN: SetDParam(0, GetCurRes() == _num_resolutions ? STR_GAME_OPTIONS_RESOLUTION_OTHER : SPECSTR_RESOLUTION_START + GetCurRes()); break;
+ case WID_GO_BUTTON_SIZE_DROPDOWN:SetDParam(0, _settings_client.gui.min_button); break;
+ case WID_GO_TEXT_SIZE_DROPDOWN: SetDParam(0, _freetype.medium.size); break;
case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[ZOOM_LVL_OUT_4X - _gui_zoom]); break;
case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name); break;
case WID_GO_BASE_GRF_STATUS: SetDParam(0, BaseGraphics::GetUsedSet()->GetNumInvalid()); break;
@@ -338,17 +363,17 @@ struct GameOptionsWindow : Window {
switch (widget) {
case WID_GO_BASE_GRF_DESCRIPTION:
SetDParamStr(0, BaseGraphics::GetUsedSet()->GetDescription(GetCurrentLanguageIsoCode()));
- DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_BLACK_RAW_STRING);
+ DrawString(r.left, r.right, r.top, STR_BLACK_RAW_STRING);
break;
case WID_GO_BASE_SFX_DESCRIPTION:
SetDParamStr(0, BaseSounds::GetUsedSet()->GetDescription(GetCurrentLanguageIsoCode()));
- DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_BLACK_RAW_STRING);
+ DrawString(r.left, r.right, r.top, STR_BLACK_RAW_STRING);
break;
case WID_GO_BASE_MUSIC_DESCRIPTION:
SetDParamStr(0, BaseMusic::GetUsedSet()->GetDescription(GetCurrentLanguageIsoCode()));
- DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_BLACK_RAW_STRING);
+ DrawString(r.left, r.right, r.top, STR_BLACK_RAW_STRING);
break;
}
}
@@ -359,7 +384,7 @@ struct GameOptionsWindow : Window {
case WID_GO_BASE_GRF_DESCRIPTION:
/* Find the biggest description for the default size. */
for (int i = 0; i < BaseGraphics::GetNumSets(); i++) {
- SetDParamStr(0, BaseGraphics::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode()));
+ SetDParamStr(0, "123");
size->height = max(size->height, (uint)GetStringHeight(STR_BLACK_RAW_STRING, size->width));
}
break;
@@ -378,7 +403,7 @@ struct GameOptionsWindow : Window {
case WID_GO_BASE_SFX_DESCRIPTION:
/* Find the biggest description for the default size. */
for (int i = 0; i < BaseSounds::GetNumSets(); i++) {
- SetDParamStr(0, BaseSounds::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode()));
+ SetDParamStr(0, "123");
size->height = max(size->height, (uint)GetStringHeight(STR_BLACK_RAW_STRING, size->width));
}
break;
@@ -386,7 +411,7 @@ struct GameOptionsWindow : Window {
case WID_GO_BASE_MUSIC_DESCRIPTION:
/* Find the biggest description for the default size. */
for (int i = 0; i < BaseMusic::GetNumSets(); i++) {
- SetDParamStr(0, BaseMusic::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode()));
+ SetDParamStr(0, "123");
size->height = max(size->height, (uint)GetStringHeight(STR_BLACK_RAW_STRING, size->width));
}
break;
@@ -450,6 +475,52 @@ struct GameOptionsWindow : Window {
this->SetDirty();
break;
+ case WID_GO_VERTICAL_TOOLBAR:
+ _settings_client.gui.vertical_toolbar = !_settings_client.gui.vertical_toolbar;
+ this->SetWidgetLoweredState(WID_GO_VERTICAL_TOOLBAR, _settings_client.gui.vertical_toolbar);
+ this->SetDirty();
+ ReconstructUserInterface();
+ break;
+
+ case WID_GO_BUILD_CONFIRMATION:
+ _settings_client.gui.build_confirmation = !_settings_client.gui.build_confirmation;
+ this->SetWidgetLoweredState(WID_GO_BUILD_CONFIRMATION, _settings_client.gui.build_confirmation);
+ this->SetDirty();
+ break;
+
+ case WID_GO_8BPP_BUTTON:
+ if (this->IsWidgetLowered(WID_GO_8BPP_BUTTON)) break;
+ free(_ini_blitter);
+ _ini_blitter = stredup("8bpp-optimized");
+ SaveToConfig();
+ #ifdef __ANDROID__
+ SDL_ANDROID_SetConfigOption(SDL_ANDROID_CONFIG_VIDEO_DEPTH_BPP, 16);
+ SDL_ANDROID_RestartMyself("restart-settings"); // We terminate here, no need to update widget state
+ #endif
+ break;
+
+ case WID_GO_16BPP_BUTTON:
+ if (this->IsWidgetLowered(WID_GO_16BPP_BUTTON)) break;
+ free(_ini_blitter);
+ _ini_blitter = stredup("16bpp-simple");
+ SaveToConfig();
+ #ifdef __ANDROID__
+ SDL_ANDROID_SetConfigOption(SDL_ANDROID_CONFIG_VIDEO_DEPTH_BPP, 16);
+ SDL_ANDROID_RestartMyself("restart-settings"); // We terminate here, no need to update widget state
+ #endif
+ break;
+
+ case WID_GO_32BPP_BUTTON:
+ if (this->IsWidgetLowered(WID_GO_32BPP_BUTTON)) break;
+ free(_ini_blitter);
+ _ini_blitter = stredup("32bpp-anim");
+ SaveToConfig();
+ #ifdef __ANDROID__
+ SDL_ANDROID_SetConfigOption(SDL_ANDROID_CONFIG_VIDEO_DEPTH_BPP, 24);
+ SDL_ANDROID_RestartMyself("restart-settings"); // We terminate here, no need to update widget state
+ #endif
+ break;
+
default: {
int selected;
DropDownList *list = this->BuildDropDownList(widget, &selected);
@@ -523,15 +594,37 @@ struct GameOptionsWindow : Window {
case WID_GO_RESOLUTION_DROPDOWN: // Change resolution
if (index < _num_resolutions && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) {
+ ReconstructUserInterface();
this->SetDirty();
}
break;
+ case WID_GO_BUTTON_SIZE_DROPDOWN: // Setup screenshot format dropdown
+ _settings_client.gui.min_button = index;
+ _settings_client.gui.min_step = index;
+ ReconstructUserInterface();
+ break;
+
+ case WID_GO_TEXT_SIZE_DROPDOWN: // Setup screenshot format dropdown
+ _freetype.medium.size = index;
+ _freetype.small.size = _freetype.medium.size * 10 / 12;
+ _freetype.large.size = _freetype.medium.size * 16 / 12;
+ _freetype.mono.size = _freetype.medium.size;
+ ReconstructUserInterface();
+ break;
+
case WID_GO_GUI_ZOOM_DROPDOWN:
GfxClearSpriteCache();
_gui_zoom = (ZoomLevel)(ZOOM_LVL_OUT_4X - index);
+ switch (_gui_zoom) {
+ case ZOOM_LVL_OUT_4X - ZOOM_LVL_NORMAL: ChangeResInGame(854, 480); break;
+ case ZOOM_LVL_OUT_4X - ZOOM_LVL_OUT_2X: ChangeResInGame(1280, 720); break;
+ case ZOOM_LVL_OUT_4X - ZOOM_LVL_OUT_4X: ChangeResInGame(1920, 1080); break;
+ default: break;
+ }
UpdateCursorSize();
LoadStringWidthTable();
+ ReconstructUserInterface();
break;
case WID_GO_BASE_GRF_DROPDOWN:
@@ -556,7 +649,12 @@ struct GameOptionsWindow : Window {
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
{
if (!gui_scope) return;
- this->SetWidgetLoweredState(WID_GO_FULLSCREEN_BUTTON, _fullscreen);
+ //this->SetWidgetLoweredState(WID_GO_FULLSCREEN_BUTTON, _fullscreen);
+ //this->SetWidgetLoweredState(WID_GO_VERTICAL_TOOLBAR, _settings_client.gui.vertical_toolbar);
+ this->SetWidgetLoweredState(WID_GO_BUILD_CONFIRMATION, _settings_client.gui.build_confirmation);
+ this->SetWidgetLoweredState(WID_GO_8BPP_BUTTON, _ini_blitter != NULL && strcmp(_ini_blitter, "8bpp-optimized") == 0);
+ this->SetWidgetLoweredState(WID_GO_16BPP_BUTTON, _ini_blitter == NULL || strcmp(_ini_blitter, "16bpp-simple") == 0);
+ this->SetWidgetLoweredState(WID_GO_32BPP_BUTTON, _ini_blitter != NULL && strcmp(_ini_blitter, "32bpp-anim") == 0);
bool missing_files = BaseGraphics::GetUsedSet()->GetNumMissing() == 0;
this->GetWidget(WID_GO_BASE_GRF_STATUS)->SetDataTip(missing_files ? STR_EMPTY : STR_GAME_OPTIONS_BASE_GRF_STATUS, STR_NULL);
@@ -589,13 +687,22 @@ static const NWidgetPart _nested_game_options_widgets[] = {
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_RESOLUTION, STR_NULL),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_RESOLUTION_TOOLTIP), SetFill(1, 0), SetPadding(0, 0, 3, 0),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_FULLSCREEN, STR_NULL),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_FULLSCREEN_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_8BPP_BUTTON), SetMinimalSize(9, 9), SetDataTip(STR_CONFIG_SETTING_VIDEO_8BPP, STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_16BPP_BUTTON), SetMinimalSize(9, 9), SetDataTip(STR_CONFIG_SETTING_VIDEO_16BPP, STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_32BPP_BUTTON), SetMinimalSize(9, 9), SetDataTip(STR_CONFIG_SETTING_VIDEO_24BPP, STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT),
EndContainer(),
EndContainer(),
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GUI_ZOOM_FRAME, STR_NULL),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_GUI_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0),
EndContainer(),
+ NWidget(WWT_FRAME, COLOUR_GREY),
+ NWidget(NWID_HORIZONTAL),
+ //NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_CONFIG_SETTING_VERTICAL_TOOLBAR, STR_NULL),
+ //NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_VERTICAL_TOOLBAR), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT),
+ NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_CONFIG_SETTING_BUILD_CONFIRMATION, STR_NULL),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_BUILD_CONFIRMATION), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT),
+ EndContainer(),
+ EndContainer(),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, 6, 0),
@@ -608,46 +715,53 @@ static const NWidgetPart _nested_game_options_widgets[] = {
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME, STR_NULL),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0),
EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 0), SetFill(0, 1),
+ NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_CONFIG_SETTING_BUTTON_SIZE, STR_NULL),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BUTTON_SIZE_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_JUST_INT, STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP), SetFill(1, 0),
+ EndContainer(),
+ NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_CONFIG_SETTING_FONT_SIZE, STR_NULL),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_TEXT_SIZE_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_JUST_INT, STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP), SetFill(1, 0),
+ EndContainer(),
EndContainer(),
- EndContainer(),
- NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_GRF, STR_NULL), SetPadding(0, 10, 0, 10),
- NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0),
- NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_GRF_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_GRF_TOOLTIP),
- NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_GRF_STATUS), SetMinimalSize(150, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0),
- EndContainer(),
- NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_GRF_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
- EndContainer(),
- EndContainer(),
+ NWidget(NWID_VERTICAL), SetPIP(0, 6, 0),
+ NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_GRF, STR_NULL), SetPadding(0, 10, 0, 10),
+ NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_GRF_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_GRF_TOOLTIP),
+ NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_GRF_STATUS), SetMinimalSize(150, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0),
+ EndContainer(),
+ NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_GRF_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
+ EndContainer(),
+ EndContainer(),
- NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_SFX, STR_NULL), SetPadding(0, 10, 0, 10),
- NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0),
- NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_SFX_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_SFX_TOOLTIP),
- NWidget(NWID_SPACER), SetFill(1, 0),
- EndContainer(),
- NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_SFX_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
- EndContainer(),
- EndContainer(),
+ NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_SFX, STR_NULL), SetPadding(0, 10, 0, 10),
+ NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_SFX_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_SFX_TOOLTIP),
+ NWidget(NWID_SPACER), SetFill(1, 0),
+ EndContainer(),
+ NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_SFX_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
+ EndContainer(),
+ EndContainer(),
- NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_MUSIC, STR_NULL), SetPadding(0, 10, 0, 10),
- NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0),
- NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_MUSIC_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP),
- NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_STATUS), SetMinimalSize(150, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0),
- EndContainer(),
- NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
+ NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_MUSIC, STR_NULL), SetPadding(0, 10, 0, 10),
+ NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_MUSIC_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP),
+ NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_STATUS), SetMinimalSize(150, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0),
+ EndContainer(),
+ NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
+ EndContainer(),
+ EndContainer(),
EndContainer(),
EndContainer(),
EndContainer(),
@@ -1062,7 +1176,6 @@ bool SettingEntry::UpdateFilterState(SettingFilter &filter, bool force_visible)
return visible;
}
-
static const void *ResolveVariableAddress(const GameSettings *settings_ptr, const SettingDesc *sd)
{
if ((sd->desc.flags & SGF_PER_COMPANY) != 0) {
@@ -1537,6 +1650,7 @@ static SettingsContainer &GetSettingsTree()
}
interface->Add(new SettingEntry("gui.autosave"));
+ interface->Add(new SettingEntry("gui.vertical_toolbar"));
interface->Add(new SettingEntry("gui.toolbar_pos"));
interface->Add(new SettingEntry("gui.statusbar_pos"));
interface->Add(new SettingEntry("gui.prefer_teamchat"));
@@ -1818,11 +1932,16 @@ struct GameSettingsWindow : Window {
this->InvalidateData();
}
+ ~GameSettingsWindow()
+ {
+ SaveToConfig(); // save all settins immediately on Android, because users tend to kill the app instead of pressing 'Quit' button
+ }
+
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
switch (widget) {
case WID_GS_OPTIONSPANEL:
- resize->height = SETTING_HEIGHT = max(max(_circle_size.height, SETTING_BUTTON_HEIGHT), FONT_HEIGHT_NORMAL) + 1;
+ resize->height = SETTING_HEIGHT = GetMinSizing(NWST_STEP, max(max(_circle_size.height, SETTING_BUTTON_HEIGHT), FONT_HEIGHT_NORMAL) + 1);
resize->width = 1;
size->height = 5 * resize->height + SETTINGTREE_TOP_OFFSET + SETTINGTREE_BOTTOM_OFFSET;
@@ -2333,10 +2452,10 @@ static const NWidgetPart _nested_settings_selection_widgets[] = {
NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_CATEGORY), SetDataTip(STR_CONFIG_SETTING_RESTRICT_CATEGORY, STR_NULL),
NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_RESTRICT_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0),
EndContainer(),
- NWidget(NWID_HORIZONTAL), SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_RIGHT),
- NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_TYPE), SetDataTip(STR_CONFIG_SETTING_RESTRICT_TYPE, STR_NULL),
- NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_TYPE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0),
- EndContainer(),
+ //NWidget(NWID_HORIZONTAL), SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_RIGHT),
+ // NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_TYPE), SetDataTip(STR_CONFIG_SETTING_RESTRICT_TYPE, STR_NULL),
+ // NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_TYPE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0),
+ //EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPadding(0, 0, WD_TEXTPANEL_BOTTOM, 0),
SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_RIGHT),
@@ -2393,8 +2512,8 @@ void DrawArrowButtons(int x, int y, Colours button_colour, byte state, bool clic
DrawFrameRect(x, y, x + dim.width - 1, y + dim.height - 1, button_colour, (state == 1) ? FR_LOWERED : FR_NONE);
DrawFrameRect(x + dim.width, y, x + dim.width + dim.width - 1, y + dim.height - 1, button_colour, (state == 2) ? FR_LOWERED : FR_NONE);
- DrawSprite(SPR_ARROW_LEFT, PAL_NONE, x + WD_IMGBTN_LEFT, y + WD_IMGBTN_TOP);
- DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, x + WD_IMGBTN_LEFT + dim.width, y + WD_IMGBTN_TOP);
+ DrawSprite(SPR_ARROW_LEFT, PAL_NONE, Center(x + WD_IMGBTN_LEFT, dim.width - 1), Center(y + WD_IMGBTN_TOP, dim.height - 1));
+ DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, Center(x + WD_IMGBTN_LEFT + dim.width, dim.width - 1), Center(y + WD_IMGBTN_TOP, dim.height - 1));
/* Grey out the buttons that aren't clickable */
bool rtl = _current_text_dir == TD_RTL;
@@ -2419,7 +2538,7 @@ void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool cl
int colour = _colour_gradient[button_colour][2];
DrawFrameRect(x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1, button_colour, state ? FR_LOWERED : FR_NONE);
- DrawSprite(SPR_ARROW_DOWN, PAL_NONE, x + (SETTING_BUTTON_WIDTH - NWidgetScrollbar::GetVerticalDimension().width) / 2 + state, y + 2 + state);
+ DrawSpriteCentered(SPR_ARROW_DOWN, PAL_NONE, x + (SETTING_BUTTON_WIDTH - NWidgetScrollbar::GetVerticalDimension().width) + state, y + state + SETTING_BUTTON_HEIGHT / 2);
if (!clickable) {
GfxFillRect(x + 1, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 2, colour, FILLRECT_CHECKER);
@@ -2667,3 +2786,32 @@ static void ShowCustCurrency()
DeleteWindowById(WC_CUSTOM_CURRENCY, 0);
new CustomCurrencyWindow(&_cust_currency_desc);
}
+
+void ReconstructUserInterface()
+{
+ // Reinit all GUI elements and fonts, so they will rescale
+ InitFreeType(true);
+ CheckForMissingGlyphs();
+
+ DeleteAllNonVitalWindows();
+
+ switch (_game_mode) {
+ case GM_MENU:
+ DeleteWindowById(WC_SELECT_GAME, 0);
+ extern void ShowSelectGameWindow();
+ ShowSelectGameWindow();
+ break;
+
+ case GM_NORMAL:
+ case GM_EDITOR:
+ HideVitalWindows();
+ ShowVitalWindows();
+ break;
+
+ default:
+ break;
+ }
+
+ ReInitAllWindows();
+ ShowGameOptions();
+}
diff --git a/src/settings_gui.h b/src/settings_gui.h
index 05955aa557..bb2a1ecfe0 100644
--- a/src/settings_gui.h
+++ b/src/settings_gui.h
@@ -14,10 +14,8 @@
#include "gfx_type.h"
-/** Width of setting buttons */
-#define SETTING_BUTTON_WIDTH ((int)NWidgetScrollbar::GetHorizontalDimension().width * 2)
-/** Height of setting buttons */
-#define SETTING_BUTTON_HEIGHT ((int)NWidgetScrollbar::GetHorizontalDimension().height)
+extern int SETTING_BUTTON_WIDTH; ///< Width of setting buttons
+extern int SETTING_BUTTON_HEIGHT; ///< Height of setting buttons
void DrawArrowButtons(int x, int y, Colours button_colour, byte state, bool clickable_left, bool clickable_right);
void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable);
diff --git a/src/settings_type.h b/src/settings_type.h
index 41366a7719..be4adf58bb 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -77,6 +77,10 @@ struct GUISettings {
bool lost_vehicle_warn; ///< if a vehicle can't find its destination, show a warning
uint8 order_review_system; ///< perform order reviews on vehicles
bool vehicle_income_warn; ///< if a vehicle isn't generating income, show a warning
+ bool vertical_toolbar; ///< main toolbar is split into two vertical toolbars
+ bool build_confirmation; ///< show confirmation dialog when building roads and stations
+ uint min_button; ///< min size of most button widgets
+ uint min_step; ///< min size of scrollbar/dropdown elements
bool show_finances; ///< show finances at end of year
bool sg_new_nonstop; ///< ttdpatch compatible nonstop handling read from pre v93 savegames
bool new_nonstop; ///< ttdpatch compatible nonstop handling
@@ -102,6 +106,7 @@ struct GUISettings {
ZoomLevelByte zoom_max; ///< maximum zoom out level
bool disable_unsuitable_building; ///< disable infrastructure building when no suitable vehicles are available
byte autosave; ///< how often should we do autosaves?
+ byte save_to_network; ///< backup all savegames to network
bool threaded_saves; ///< should we do threaded saves?
bool keep_all_autosave; ///< name the autosave in a different way
bool autosave_on_exit; ///< save an autosave when you quit the game, but do not ask "Do you really want to quit?"
diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp
index 020ee1b6ea..1c4ad1dcc2 100644
--- a/src/signs_gui.cpp
+++ b/src/signs_gui.cpp
@@ -196,7 +196,7 @@ struct SignListWindow : Window, SignList {
{
switch (widget) {
case WID_SIL_LIST: {
- uint y = r.top + WD_FRAMERECT_TOP; // Offset from top of widget.
+ uint y = Center(r.top + WD_FRAMERECT_TOP, this->resize.step_height); // Offset from top of widget.
/* No signs? */
if (this->vscroll->GetCount() == 0) {
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_STATION_LIST_NONE);
@@ -267,7 +267,7 @@ struct SignListWindow : Window, SignList {
case WID_SIL_LIST: {
Dimension spr_dim = GetSpriteSize(SPR_COMPANY_ICON);
this->text_offset = WD_FRAMETEXT_LEFT + spr_dim.width + 2; // 2 pixels space between icon and the sign text.
- resize->height = max(FONT_HEIGHT_NORMAL, spr_dim.height);
+ resize->height = max(GetMinSizing(NWST_STEP), spr_dim.height);
Dimension d = {(uint)(this->text_offset + WD_FRAMETEXT_RIGHT), WD_FRAMERECT_TOP + 5 * resize->height + WD_FRAMERECT_BOTTOM};
*size = maxdim(*size, d);
break;
diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp
index f4bcdece18..bf4850da90 100644
--- a/src/smallmap_gui.cpp
+++ b/src/smallmap_gui.cpp
@@ -37,7 +37,7 @@ static int _smallmap_company_count; ///< Number of entries in the owner legend.
static int _smallmap_cargo_count; ///< Number of cargos in the link stats legend.
/** Link stat colours shown in legenda. */
-static uint8 _linkstat_colours_in_legenda[] = {0, 1, 3, 5, 7, 9, 11};
+static uint8 _linkstat_colours_in_legenda[] = {0, 1, 3, 5, 7};
static const int NUM_NO_COMPANY_ENTRIES = 4; ///< Number of entries in the owner legend that are not companies.
@@ -85,12 +85,12 @@ static LegendAndColour _legend_land_contours[] = {
MC(false),
MC(false),
MC(false),
- MC(false),
MC(true),
MC(false),
MC(false),
MC(false),
MC(false),
+ MC(true),
MC(false),
MKEND()
};
@@ -125,12 +125,13 @@ static const LegendAndColour _legend_vegetation[] = {
MK(PC_BARE_LAND, STR_SMALLMAP_LEGENDA_BARE_LAND),
MK(PC_FIELDS, STR_SMALLMAP_LEGENDA_FIELDS),
MK(PC_TREES, STR_SMALLMAP_LEGENDA_TREES),
- MK(PC_GREEN, STR_SMALLMAP_LEGENDA_FOREST),
- MS(PC_GREY, STR_SMALLMAP_LEGENDA_ROCKS),
+ MS(PC_GREEN, STR_SMALLMAP_LEGENDA_FOREST),
+ MK(PC_GREY, STR_SMALLMAP_LEGENDA_ROCKS),
MK(PC_ORANGE, STR_SMALLMAP_LEGENDA_DESERT),
MK(PC_LIGHT_BLUE, STR_SMALLMAP_LEGENDA_SNOW),
- MK(PC_BLACK, STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES),
+
+ MS(PC_BLACK, STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES),
MK(PC_DARK_RED, STR_SMALLMAP_LEGENDA_BUILDINGS_INDUSTRIES),
MKEND()
};
@@ -145,6 +146,7 @@ static LegendAndColour _legend_land_owners[NUM_NO_COMPANY_ENTRIES + MAX_COMPANIE
};
#undef MK
+#undef MKB
#undef MC
#undef MS
#undef MO
@@ -185,7 +187,7 @@ void BuildIndustriesLegend()
_legend_from_industries[j].colour = indsp->map_colour;
_legend_from_industries[j].type = ind;
_legend_from_industries[j].show_on_map = true;
- _legend_from_industries[j].col_break = false;
+ _legend_from_industries[j].col_break = j > 0 && j % lengthof(_linkstat_colours_in_legenda) == 0;
_legend_from_industries[j].end = false;
/* Store widget number for this industry type. */
@@ -216,6 +218,7 @@ void BuildLinkStatsLegend()
_legend_linkstats[i].colour = cs->legend_colour;
_legend_linkstats[i].type = cs->Index();
_legend_linkstats[i].show_on_map = true;
+ _legend_linkstats[i].col_break = i > 0 && i % lengthof(_linkstat_colours_in_legenda) == 0;
}
_legend_linkstats[i].col_break = true;
@@ -312,7 +315,7 @@ void BuildLandLegend()
uint delta = deltas[i][1];
int total_entries = (_settings_game.construction.max_heightlevel / delta) + 1;
- int rows = CeilDiv(total_entries, 2);
+ int rows = lengthof(_linkstat_colours_in_legenda);
int j = 0;
for (i = 0; i < lengthof(_legend_land_contours) - 1 && j < total_entries; i++) {
@@ -340,7 +343,7 @@ void BuildOwnerLegend()
_legend_land_owners[i].colour = _colour_gradient[c->colour][5];
_legend_land_owners[i].company = c->index;
_legend_land_owners[i].show_on_map = true;
- _legend_land_owners[i].col_break = false;
+ _legend_land_owners[i].col_break = i > 0 && i % lengthof(_linkstat_colours_in_legenda) == 0;
_legend_land_owners[i].end = false;
_company_to_list_pos[c->index] = i;
i++;
@@ -1044,12 +1047,18 @@ void SmallMapWindow::SetupWidgetData()
}
this->GetWidget(WID_SM_LEGEND)->SetDataTip(STR_NULL, legend_tooltip);
+/*
this->GetWidget(WID_SM_ENABLE_ALL)->SetDataTip(STR_SMALLMAP_ENABLE_ALL, enable_all_tooltip);
this->GetWidget(WID_SM_DISABLE_ALL)->SetDataTip(STR_SMALLMAP_DISABLE_ALL, disable_all_tooltip);
this->GetWidget(WID_SM_SELECT_BUTTONS)->SetDisplayedPlane(plane);
+*/
}
-SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) : Window(desc), refresh(FORCE_REFRESH_PERIOD)
+SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) :
+ Window(desc),
+ show_legend(true),
+ row_height(max(GetMinSizing(NWST_STEP, FONT_HEIGHT_SMALL) * 2 / 3, uint(FONT_HEIGHT_SMALL))), // Default spacing makes legend too tall - shrink it by 1/3
+ refresh(FORCE_REFRESH_PERIOD)
{
_smallmap_industry_highlight = INVALID_INDUSTRYTYPE;
this->overlay = new LinkGraphOverlay(this, WID_SM_MAP, 0, this->GetOverlayCompanyMask(), 1);
@@ -1058,9 +1067,10 @@ SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) : Window(des
this->RebuildColourIndexIfNecessary();
- this->SetWidgetLoweredState(WID_SM_SHOW_HEIGHT, _smallmap_show_heightmap);
+ //this->SetWidgetLoweredState(WID_SM_SHOW_HEIGHT, _smallmap_show_heightmap);
this->SetWidgetLoweredState(WID_SM_TOGGLETOWNNAME, this->show_towns);
+ //this->SetWidgetLoweredState(WID_SM_SHOW_LEGEND, this->show_legend);
this->SetupWidgetData();
@@ -1136,7 +1146,7 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
}
} else {
if (tbl->col_break) {
- this->min_number_of_fixed_rows = max(this->min_number_of_fixed_rows, height);
+ //this->min_number_of_fixed_rows = max(this->min_number_of_fixed_rows, height);
height = 0;
num_columns++;
}
@@ -1145,7 +1155,7 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
}
min_width = max(GetStringBoundingBox(str).width, min_width);
}
- this->min_number_of_fixed_rows = max(this->min_number_of_fixed_rows, height);
+ //this->min_number_of_fixed_rows = max(this->min_number_of_fixed_rows, height);
this->min_number_of_columns = max(this->min_number_of_columns, num_columns);
}
@@ -1185,9 +1195,8 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
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 y = Center(y_org, this->row_height, FONT_HEIGHT_SMALL);
uint i = 0; // Row counter for industry legend.
- uint row_height = FONT_HEIGHT_SMALL;
uint text_left = rtl ? 0 : LEGEND_BLOB_WIDTH + WD_FRAMERECT_LEFT;
uint text_right = this->column_width - 1 - (rtl ? LEGEND_BLOB_WIDTH + WD_FRAMERECT_RIGHT : 0);
@@ -1214,7 +1223,7 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
/* Column break needed, continue at top, COLUMN_WIDTH pixels
* (one "row") to the right. */
x += rtl ? -(int)this->column_width : this->column_width;
- y = y_org;
+ y = Center(y_org, this->row_height, FONT_HEIGHT_SMALL);
i = 1;
}
@@ -1242,7 +1251,7 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
DrawString(x + text_left, x + text_right, y, string, TC_GREY);
} else {
DrawString(x + text_left, x + text_right, y, string, TC_BLACK);
- GfxFillRect(x + blob_left, y + 1, x + blob_right, y + row_height - 1, PC_BLACK); // Outer border of the legend colour
+ GfxFillRect(x + blob_left, y + 1, x + blob_right, y + FONT_HEIGHT_SMALL - 1, PC_BLACK); // Outer border of the legend colour
}
break;
}
@@ -1250,13 +1259,13 @@ void SmallMapWindow::RebuildColourIndexIfNecessary()
default:
if (this->map_type == SMT_CONTOUR) SetDParam(0, tbl->height * TILE_HEIGHT_STEP);
/* Anything that is not an industry or a company is using normal process */
- GfxFillRect(x + blob_left, y + 1, x + blob_right, y + row_height - 1, PC_BLACK);
+ GfxFillRect(x + blob_left, y + 1, x + blob_right, y + FONT_HEIGHT_SMALL - 1, PC_BLACK);
DrawString(x + text_left, x + text_right, y, tbl->legend);
break;
}
- GfxFillRect(x + blob_left + 1, y + 2, x + blob_right - 1, y + row_height - 2, legend_colour); // Legend colour
+ GfxFillRect(x + blob_left + 1, y + 2, x + blob_right - 1, y + FONT_HEIGHT_SMALL - 2, legend_colour); // Legend colour
- y += row_height;
+ y += this->row_height;
}
}
}
@@ -1348,9 +1357,10 @@ void SmallMapWindow::SetOverlayCargoMask()
int SmallMapWindow::GetPositionOnLegend(Point pt)
{
const NWidgetBase *wi = this->GetWidget(WID_SM_LEGEND);
- uint line = (pt.y - wi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_SMALL;
+ uint line = (pt.y - wi->pos_y - WD_FRAMERECT_TOP) / this->row_height;
uint columns = this->GetNumberColumnsLegend(wi->current_x);
uint number_of_rows = this->GetNumberRowsLegend(columns);
+ number_of_rows = this->min_number_of_fixed_rows;
if (line >= number_of_rows) return -1;
bool rtl = _current_text_dir == TD_RTL;
@@ -1394,6 +1404,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
* actually being (virtually) clicked every inputloop.
*/
_left_button_clicked = false;
+ _scrolling_viewport = true;
const NWidgetBase *wid = this->GetWidget(WID_SM_MAP);
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
@@ -1439,6 +1450,14 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
break;
+ case WID_SM_SHOW_LEGEND: {
+ int oldHeight = this->GetLegendHeight(this->min_number_of_columns);
+ this->show_legend = !this->show_legend;
+ this->SetWidgetLoweredState(WID_SM_SHOW_LEGEND, this->show_legend);
+ this->ReInit(0, this->GetLegendHeight(this->min_number_of_columns) - oldHeight);
+ break;
+ }
+
case WID_SM_LEGEND: // Legend
if (this->map_type == SMT_INDUSTRY || this->map_type == SMT_LINKSTATS || this->map_type == SMT_OWNER) {
int click_pos = this->GetPositionOnLegend(pt);
@@ -1657,6 +1676,14 @@ Point SmallMapWindow::GetStationMiddle(const Station *st) const
return ret;
}
+/* virtual */ void SmallMapWindow::UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
+{
+ if (widget != WID_SM_LEGEND) return;
+
+ size->width = this->GetMinLegendWidth();
+ size->height = this->GetLegendHeight(this->min_number_of_columns);
+}
+
SmallMapWindow::SmallMapType SmallMapWindow::map_type = SMT_CONTOUR;
bool SmallMapWindow::show_towns = true;
int SmallMapWindow::max_heightlevel = -1;
@@ -1686,8 +1713,9 @@ public:
bar->SetupSmallestSize(w, init_array);
this->smallmap_window = dynamic_cast(w);
+
assert(this->smallmap_window != NULL);
- this->smallest_x = max(display->smallest_x, bar->smallest_x + smallmap_window->GetMinLegendWidth());
+ this->smallest_x = max(display->smallest_x, max(bar->smallest_x, smallmap_window->GetMinLegendWidth()));
this->smallest_y = display->smallest_y + max(bar->smallest_y, smallmap_window->GetLegendHeight(smallmap_window->min_number_of_columns));
this->fill_x = max(display->fill_x, bar->fill_x);
this->fill_y = (display->fill_y == 0 && bar->fill_y == 0) ? 0 : min(display->fill_y, bar->fill_y);
@@ -1738,7 +1766,7 @@ public:
/** Widget parts of the smallmap display. */
static const NWidgetPart _nested_smallmap_display[] = {
NWidget(WWT_PANEL, COLOUR_BROWN, WID_SM_MAP_BORDER),
- NWidget(WWT_INSET, COLOUR_BROWN, WID_SM_MAP), SetMinimalSize(346, 140), SetResize(1, 1), SetPadding(2, 2, 2, 2), EndContainer(),
+ NWidget(WWT_INSET, COLOUR_BROWN, WID_SM_MAP), SetMinimalSize(140, 140), SetResize(1, 1), SetPadding(2, 2, 2, 2), EndContainer(),
EndContainer(),
};
@@ -1746,27 +1774,23 @@ static const NWidgetPart _nested_smallmap_display[] = {
static const NWidgetPart _nested_smallmap_bar[] = {
NWidget(WWT_PANEL, COLOUR_BROWN),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SM_LEGEND), SetResize(1, 1),
- NWidget(NWID_VERTICAL),
+ NWidget(NWID_HORIZONTAL),
/* Top button row. */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
+ //NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_SHOW_LEGEND),
+ // SetDataTip(SPR_IMG_QUERY, STR_SMALLMAP_TOOLTIP_SHOW_LEGEND), SetFill(1, 1),
NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_ZOOM_IN),
SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN), SetFill(1, 1),
+ NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_ZOOM_OUT),
+ SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT), SetFill(1, 1),
NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_CENTERMAP),
SetDataTip(SPR_IMG_SMALLMAP, STR_SMALLMAP_CENTER), SetFill(1, 1),
- NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_BLANK),
- SetDataTip(SPR_DOT_SMALL, STR_NULL), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_CONTOUR),
SetDataTip(SPR_IMG_SHOW_COUNTOURS, STR_SMALLMAP_TOOLTIP_SHOW_LAND_CONTOURS_ON_MAP), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_VEHICLES),
SetDataTip(SPR_IMG_SHOW_VEHICLES, STR_SMALLMAP_TOOLTIP_SHOW_VEHICLES_ON_MAP), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_INDUSTRIES),
SetDataTip(SPR_IMG_INDUSTRY, STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP), SetFill(1, 1),
- EndContainer(),
- /* Bottom button row. */
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
- NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_ZOOM_OUT),
- SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_TOGGLETOWNNAME),
SetDataTip(SPR_IMG_TOWN, STR_SMALLMAP_TOOLTIP_TOGGLE_TOWN_NAMES_ON_OFF), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_LINKSTATS),
@@ -1777,10 +1801,12 @@ static const NWidgetPart _nested_smallmap_bar[] = {
SetDataTip(SPR_IMG_PLANTTREES, STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP), SetFill(1, 1),
NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_OWNERS),
SetDataTip(SPR_IMG_COMPANY_GENERAL, STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP), SetFill(1, 1),
+ NWidget(NWID_SPACER), SetResize(1, 0), SetMinimalSize(0, 1),
+ NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
EndContainer(),
- NWidget(NWID_SPACER), SetResize(0, 1),
EndContainer(),
EndContainer(),
+ NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SM_LEGEND), SetResize(1, 1),
EndContainer(),
};
@@ -1804,6 +1830,7 @@ static const NWidgetPart _nested_smallmap_widgets[] = {
EndContainer(),
NWidgetFunction(SmallMapDisplay), // Smallmap display and legend bar + image buttons.
/* Bottom button row and resize box. */
+/*
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SM_SELECT_BUTTONS),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
@@ -1818,10 +1845,11 @@ static const NWidgetPart _nested_smallmap_widgets[] = {
EndContainer(),
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
EndContainer(),
+*/
};
static WindowDesc _smallmap_desc(
- WDP_AUTO, "smallmap", 484, 314,
+ WDP_AUTO, "smallmap", 180, 180,
WC_SMALLMAP, WC_NONE,
0,
_nested_smallmap_widgets, lengthof(_nested_smallmap_widgets)
diff --git a/src/smallmap_gui.h b/src/smallmap_gui.h
index 2903544a69..c5eeeea21e 100644
--- a/src/smallmap_gui.h
+++ b/src/smallmap_gui.h
@@ -70,9 +70,11 @@ protected:
static const uint FORCE_REFRESH_PERIOD = 0x1F; ///< map is redrawn after that many ticks
static const uint BLINK_PERIOD = 0x0F; ///< highlight blinking interval
+ bool show_legend; ///< Display legend.
uint min_number_of_columns; ///< Minimal number of columns in legends.
uint min_number_of_fixed_rows; ///< Minimal number of rows in the legends for the fixed layouts only (all except #SMT_INDUSTRY).
uint column_width; ///< Width of a column in the #WID_SM_LEGEND widget.
+ const uint row_height; ///< Heigth of each row in the #WID_SM_LEGEND widget.
int32 scroll_x; ///< Horizontal world coordinate of the base tile left of the top-left corner of the smallmap display.
int32 scroll_y; ///< Vertical world coordinate of the base tile left of the top-left corner of the smallmap display.
@@ -114,7 +116,7 @@ protected:
*/
inline uint GetMinLegendWidth() const
{
- return WD_FRAMERECT_LEFT + this->min_number_of_columns * this->column_width;
+ return show_legend ? WD_FRAMERECT_LEFT + this->min_number_of_columns * this->column_width : 0;
}
/**
@@ -133,8 +135,8 @@ protected:
*/
inline uint GetLegendHeight(uint num_columns) const
{
- return WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM +
- this->GetNumberRowsLegend(num_columns) * FONT_HEIGHT_SMALL;
+ return show_legend ? WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM +
+ this->min_number_of_fixed_rows * this->row_height : 0;
}
/**
@@ -189,6 +191,7 @@ public:
virtual void OnTick();
virtual void OnScroll(Point delta);
virtual void OnMouseOver(Point pt, int widget);
+ virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize);
};
#endif /* SMALLMAP_GUI_H */
diff --git a/src/sound/sdl_s.cpp b/src/sound/sdl_s.cpp
index e3fb99eaa7..8c0849dfb2 100644
--- a/src/sound/sdl_s.cpp
+++ b/src/sound/sdl_s.cpp
@@ -23,6 +23,10 @@
/** Factory for the SDL sound driver. */
static FSoundDriver_SDL iFSoundDriver_SDL;
+#ifdef __ANDROID__
+extern void Android_MidiMixMusic(Sint16 *stream, int len);
+#endif
+
/**
* Callback that fills the sound buffer.
* @param userdata Ignored.
@@ -32,6 +36,9 @@ static FSoundDriver_SDL iFSoundDriver_SDL;
static void CDECL fill_sound_buffer(void *userdata, Uint8 *stream, int len)
{
MxMixSamples(stream, len / 4);
+#if defined(__ANDROID__) && defined(LIBTIMIDITY)
+ Android_MidiMixMusic((Sint16 *)stream, len / 2);
+#endif
}
const char *SoundDriver_SDL::Start(const char * const *parm)
diff --git a/src/spritecache.cpp b/src/spritecache.cpp
index 70a8834a91..16566863ca 100644
--- a/src/spritecache.cpp
+++ b/src/spritecache.cpp
@@ -419,6 +419,10 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty
/* Try for 32bpp sprites first. */
sprite_avail = sprite_loader.LoadSprite(sprite, file_slot, file_pos, sprite_type, true);
}
+ if (sprite_type != ST_MAPGEN && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 16) {
+ /* 32bpp sprites for 16bpp videomode. */
+ sprite_avail = sprite_loader.LoadSprite(sprite, file_slot, file_pos, sprite_type, true);
+ }
if (sprite_avail == 0) {
sprite_avail = sprite_loader.LoadSprite(sprite, file_slot, file_pos, sprite_type, false);
}
diff --git a/src/station_base.h b/src/station_base.h
index af4d206ba0..cf0ea6fc0a 100644
--- a/src/station_base.h
+++ b/src/station_base.h
@@ -299,6 +299,14 @@ struct GoodsEntry {
FlowStatMap::const_iterator flow_it(this->flows.find(source));
return flow_it != this->flows.end() ? flow_it->second.GetVia(excluded, excluded2) : INVALID_STATION;
}
+
+ /**
+ * Return true if a cargo type has a rating here or if there is cargo waiting for this type.
+ */
+ inline bool IsSourceStationForCargo() const
+ {
+ return this->HasRating() || this->cargo.TotalCount() > 0;
+ }
};
/** All airport-related information. Only valid if tile != INVALID_TILE. */
diff --git a/src/station_gui.cpp b/src/station_gui.cpp
index 7399fe0067..4b7d0ccafc 100644
--- a/src/station_gui.cpp
+++ b/src/station_gui.cpp
@@ -104,44 +104,44 @@ void CheckRedrawStationCoverage(const Window *w)
* @param type Cargo type
* @param amount Cargo amount
* @param rating ratings data for that particular cargo
- *
- * @note Each cargo-bar is 16 pixels wide and 6 pixels high
- * @note Each rating 14 pixels wide and 1 pixel high and is 1 pixel below the cargo-bar
*/
static void StationsWndShowStationRating(int left, int right, int y, CargoID type, uint amount, byte rating)
{
- static const uint units_full = 576; ///< number of units to show station as 'full'
- static const uint rating_full = 224; ///< rating needed so it is shown as 'full'
+ static const uint units_full = 1 << 9; ///< Number of units to show station as full.
+ static const uint rating_full = 224; ///< Rating needed so it is shown as full.
const CargoSpec *cs = CargoSpec::Get(type);
if (!cs->IsValid()) return;
+ y++; ///< Make boxes 1 pixel shorter.
+ int left_start = left;
+ int right_start = right;
+ int height = GetCharacterHeight(FS_SMALL) - 2;
int colour = cs->rating_colour;
- TextColour tc = GetContrastColour(colour);
- uint w = (minu(amount, units_full) + 5) / 36;
- int height = GetCharacterHeight(FS_SMALL);
+ /* Get width of the box to draw. */
+ uint width = minu(amount, units_full) * (right - left) / units_full;
- /* Draw total cargo (limited) on station (fits into 16 pixels) */
- if (w != 0) GfxFillRect(left, y, left + w - 1, y + height, colour);
+ /* Update the end margin, adding the width of the box not to be drawn... */
+ if (width != 0) UpdateMarginsWidth(right - left - width, left_start, right_start, true);
+ /* ... or prepare margins in case width == 0 and amount > 0 (just one pixel bar). */
+ else left_start = right_start = _current_text_dir ? right : left;
- /* Draw a one pixel-wide bar of additional cargo meter, useful
- * for stations with only a small amount (<=30) */
- if (w == 0) {
- uint rest = amount / 5;
- if (rest != 0) {
- w += left;
- GfxFillRect(w, y + height - rest, w, y + height, colour);
- }
- }
+ /* Draw total cargo (limited) on station */
+ if (amount > 0) GfxFillRect(left_start, y, right_start, y + height, colour);
- DrawString(left + 1, right, y, cs->abbrev, tc);
+ DrawString(left, right, y, cs->abbrev, GetContrastColour(colour), SA_CENTER);
- /* Draw green/red ratings bar (fits into 14 pixels) */
+ /* Draw green/red ratings bar*/
y += height + 2;
- GfxFillRect(left + 1, y, left + 14, y, PC_RED);
- rating = minu(rating, rating_full) / 16;
- if (rating != 0) GfxFillRect(left + 1, y, left + rating, y, PC_GREEN);
+ left_start = left + 1;
+ right_start = right - 1;
+ if (rating != 0) {
+ GfxFillRect(left_start, y, right_start, y, PC_GREEN);
+ width = minu(rating, rating_full) * (right_start - left_start) / rating_full;
+ UpdateMarginsWidth(width, left_start, right_start, false);
+ }
+ GfxFillRect(left_start, y, right_start, y, PC_RED);
}
typedef GUIList GUIStationList;
@@ -360,7 +360,7 @@ public:
}
case WID_STL_LIST:
- resize->height = FONT_HEIGHT_NORMAL;
+ resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
size->height = WD_FRAMERECT_TOP + 5 * resize->height + WD_FRAMERECT_BOTTOM;
break;
@@ -412,7 +412,8 @@ public:
case WID_STL_LIST: {
bool rtl = _current_text_dir == TD_RTL;
int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->stations.Length());
- int y = r.top + WD_FRAMERECT_TOP;
+ uint line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
+ int y = Center(r.top + WD_FRAMERECT_TOP, line_height);
for (int i = this->vscroll->GetPosition(); i < max; ++i) { // do until max number of stations of owner
const Station *st = this->stations[i];
assert(st->xy != INVALID_TILE);
@@ -424,6 +425,7 @@ public:
SetDParam(0, st->index);
SetDParam(1, st->facilities);
int x = DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_LIST_STATION);
+
x += rtl ? -5 : 5;
/* show cargo waiting and station ratings */
@@ -445,7 +447,8 @@ public:
}
}
}
- y += FONT_HEIGHT_NORMAL;
+
+ y += line_height;
}
if (this->vscroll->GetCount() == 0) { // company has no stations
@@ -497,7 +500,7 @@ public:
{
switch (widget) {
case WID_STL_LIST: {
- uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_STL_LIST, 0, FONT_HEIGHT_NORMAL);
+ uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_STL_LIST, 0, this->resize.step_height);
if (id_v >= this->stations.Length()) return; // click out of list bound
const Station *st = this->stations[id_v];
@@ -722,7 +725,7 @@ static const NWidgetPart _nested_company_stations_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY), SetDataTip(0x0, STR_NULL), SetResize(1, 0), SetFill(1, 1), EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_STL_SORTBY), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_STL_SORTBY), SetSizingType(NWST_STEP), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_STL_SORTDROPBTN), SetMinimalSize(163, 12), SetDataTip(STR_SORT_BY_NAME, STR_TOOLTIP_SORT_CRITERIA), // widget_data gets overwritten.
NWidget(WWT_PANEL, COLOUR_GREY), SetDataTip(0x0, STR_NULL), SetResize(1, 0), SetFill(1, 1), EndContainer(),
EndContainer(),
@@ -763,12 +766,12 @@ static const NWidgetPart _nested_station_view_widgets[] = {
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_SORT_ORDER), SetMinimalSize(81, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
- NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SV_SORT_BY), SetMinimalSize(168, 12), SetResize(1, 0), SetFill(0, 1), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_SORT_ORDER), SetMinimalSize(81, 12), SetFill(0, 1), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SV_SORT_BY), SetMinimalSize(168, 12), SetResize(1, 0), SetFill(1, 1), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA),
EndContainer(),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SV_GROUP), SetMinimalSize(81, 12), SetFill(1, 1), SetDataTip(STR_STATION_VIEW_GROUP, 0x0),
- NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SV_GROUP_BY), SetMinimalSize(168, 12), SetResize(1, 0), SetFill(0, 1), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SV_GROUP), SetMinimalSize(81, 12), SetFill(0, 1), SetDataTip(STR_STATION_VIEW_GROUP, 0x0),
+ NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SV_GROUP_BY), SetMinimalSize(168, 12), SetResize(1, 0), SetFill(1, 1), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_GREY, WID_SV_WAITING), SetMinimalSize(237, 44), SetResize(1, 10), SetScrollbar(WID_SV_SCROLLBAR), EndContainer(),
@@ -804,7 +807,7 @@ static const NWidgetPart _nested_station_view_widgets[] = {
* @param y y coordinate
* @param width the width of the view
*/
-static void DrawCargoIcons(CargoID i, uint waiting, int left, int right, int y)
+static void DrawCargoIcons(CargoID i, uint waiting, int left, int right, int top, int y)
{
int width = ScaleGUITrad(10);
uint num = min((waiting + (width / 2)) / width, (right - left) / width); // maximum is width / 10 icons so it won't overflow
@@ -1384,6 +1387,12 @@ struct StationViewWindow : public Window {
fill->width = 0;
}
break;
+
+ case WID_SV_SORT_ORDER:
+ case WID_SV_GROUP:
+ *size = maxdim(GetStringBoundingBox(STR_BUTTON_SORT_BY), GetStringBoundingBox(STR_STATION_VIEW_GROUP));
+ size->width += padding.width;
+ break;
}
}
@@ -1733,7 +1742,7 @@ struct StationViewWindow : public Window {
if (this->groupings[column] == GR_CARGO) {
str = STR_STATION_VIEW_WAITING_CARGO;
- DrawCargoIcons(cd->GetCargo(), cd->GetCount(), r.left + WD_FRAMERECT_LEFT + this->expand_shrink_width, r.right - WD_FRAMERECT_RIGHT - this->expand_shrink_width, y);
+ DrawCargoIcons(cd->GetCargo(), cd->GetCount(), r.left + WD_FRAMERECT_LEFT + this->expand_shrink_width, r.right - WD_FRAMERECT_RIGHT - this->expand_shrink_width, y, y + FONT_HEIGHT_NORMAL);
} else {
if (!auto_distributed) grouping = GR_SOURCE;
StationID station = cd->GetStation();
@@ -2264,8 +2273,8 @@ struct SelectStationWindow : Window {
d = maxdim(d, GetStringBoundingBox(T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_STATION_LIST_WAYPOINT : STR_STATION_LIST_STATION));
}
- resize->height = d.height;
- d.height *= 5;
+ resize->height = GetMinSizing(NWST_STEP, d.height);
+ d.height = 5 * resize->height;
d.width += WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT;
d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
*size = d;
@@ -2275,7 +2284,7 @@ struct SelectStationWindow : Window {
{
if (widget != WID_JS_PANEL) return;
- uint y = r.top + WD_FRAMERECT_TOP;
+ uint y = Center(r.top, this->resize.step_height);
if (this->vscroll->GetPosition() == 0) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT : STR_JOIN_STATION_CREATE_SPLITTED_STATION);
y += this->resize.step_height;
diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp
index 25efa6bb1c..a1a79d5bb4 100644
--- a/src/statusbar_gui.cpp
+++ b/src/statusbar_gui.cpp
@@ -26,6 +26,7 @@
#include "statusbar_gui.h"
#include "toolbar_gui.h"
#include "core/geometry_func.hpp"
+#include "settings_gui.h"
#include "widgets/statusbar_widget.h"
@@ -70,7 +71,7 @@ static bool DrawScrollingStatusText(const NewsItem *ni, int scroll_pos, int left
DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &tmp_dpi;
- DrawString(pos, INT16_MAX, 0, buffer, TC_LIGHT_BLUE, SA_LEFT | SA_FORCE);
+ DrawString(pos, INT16_MAX, Center(0, bottom - top), buffer, TC_LIGHT_BLUE, SA_LEFT | SA_FORCE);
_cur_dpi = old_dpi;
return (_current_text_dir == TD_RTL) ? (pos < right - left) : (pos + width > 0);
@@ -104,27 +105,37 @@ struct StatusBarWindow : Window {
virtual void FindWindowPlacementAndResize(int def_width, int def_height)
{
- Window::FindWindowPlacementAndResize(_toolbar_width, def_height);
+ Window::FindWindowPlacementAndResize(min(_toolbar_width, _screen.width - GetMinSizing(NWST_STEP) * 2), def_height);
}
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
Dimension d;
switch (widget) {
+ /* Left and right should have same sizing. */
case WID_S_LEFT:
+ case WID_S_RIGHT: {
SetDParamMaxValue(0, MAX_YEAR * DAYS_IN_YEAR);
d = GetStringBoundingBox(STR_WHITE_DATE_LONG);
- break;
- case WID_S_RIGHT: {
int64 max_money = UINT32_MAX;
const Company *c;
FOR_ALL_COMPANIES(c) max_money = max(c->money, max_money);
SetDParam(0, 100LL * max_money);
- d = GetStringBoundingBox(STR_COMPANY_MONEY);
+ d = maxdim(d, GetStringBoundingBox(STR_COMPANY_MONEY));
break;
}
+ case WID_S_MIDDLE:
+ d = GetStringBoundingBox(STR_STATUSBAR_AUTOSAVE);
+ d = maxdim(d, GetStringBoundingBox(STR_STATUSBAR_PAUSED));
+
+ if (Company::IsValidID(_local_company)) {
+ SetDParam(0, _local_company);
+ d = maxdim(d, GetStringBoundingBox(STR_STATUSBAR_COMPANY_NAME));
+ }
+ break;
+
default:
return;
}
@@ -136,11 +147,13 @@ struct StatusBarWindow : Window {
virtual void DrawWidget(const Rect &r, int widget) const
{
+ StringID str = INVALID_STRING_ID;
+
switch (widget) {
case WID_S_LEFT:
/* Draw the date */
SetDParam(0, _date);
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER);
+ str = STR_WHITE_DATE_LONG;
break;
case WID_S_RIGHT: {
@@ -148,7 +161,7 @@ struct StatusBarWindow : Window {
const Company *c = Company::GetIfValid(_local_company);
if (c != NULL) {
SetDParam(0, c->money);
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_COMPANY_MONEY, TC_FROMSTRING, SA_HOR_CENTER);
+ str = STR_COMPANY_MONEY;
}
break;
}
@@ -156,11 +169,11 @@ struct StatusBarWindow : Window {
case WID_S_MIDDLE:
/* Draw status bar */
if (this->saving) { // true when saving is active
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_SAVING_GAME, TC_FROMSTRING, SA_HOR_CENTER);
+ str = STR_STATUSBAR_SAVING_GAME;
} else if (_do_autosave) {
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_AUTOSAVE, TC_FROMSTRING, SA_HOR_CENTER);
+ str = STR_STATUSBAR_AUTOSAVE;
} else if (_pause_mode != PM_UNPAUSED) {
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_PAUSED, TC_FROMSTRING, SA_HOR_CENTER);
+ str = STR_STATUSBAR_PAUSED;
} else if (this->ticker_scroll < TICKER_STOP && FindWindowById(WC_NEWS_WINDOW, 0) == NULL && _statusbar_news_item != NULL && _statusbar_news_item->string_id != 0) {
/* Draw the scrolling news text */
if (!DrawScrollingStatusText(_statusbar_news_item, this->ticker_scroll, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom)) {
@@ -168,23 +181,27 @@ struct StatusBarWindow : Window {
if (Company::IsValidID(_local_company)) {
/* This is the default text */
SetDParam(0, _local_company);
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER);
+ str = STR_STATUSBAR_COMPANY_NAME;
}
}
} else {
if (Company::IsValidID(_local_company)) {
/* This is the default text */
SetDParam(0, _local_company);
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER);
+ str = STR_STATUSBAR_COMPANY_NAME;
}
}
-
- if (this->reminder_timeout > 0) {
- Dimension icon_size = GetSpriteSize(SPR_UNREAD_NEWS);
- DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, r.right - WD_FRAMERECT_RIGHT - icon_size.width, r.top + WD_FRAMERECT_TOP + (int)(FONT_HEIGHT_NORMAL - icon_size.height) / 2);
- }
break;
}
+
+ int center_top = Center(r.top + WD_FRAMERECT_TOP, r.bottom - r.top);
+ if (str != INVALID_STRING_ID) DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, center_top, str, TC_FROMSTRING, SA_HOR_CENTER);
+
+ if (widget == WID_S_MIDDLE && this->reminder_timeout > 0) {
+ Dimension icon_size = GetSpriteSize(SPR_UNREAD_NEWS);
+ center_top = Center(r.top + WD_FRAMERECT_TOP, r.bottom - r.top, icon_size.height);
+ DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, r.right - WD_FRAMERECT_RIGHT - icon_size.width, center_top);
+ }
}
/**
@@ -238,7 +255,7 @@ struct StatusBarWindow : Window {
static const NWidgetPart _nested_main_status_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_GREY, WID_S_LEFT), SetMinimalSize(140, 12), EndContainer(),
- NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_S_MIDDLE), SetMinimalSize(40, 12), SetDataTip(0x0, STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS), SetResize(1, 0),
+ NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_S_MIDDLE), SetMinimalSize(360, 12), SetDataTip(0x0, STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS), SetResize(1, 0),
NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_S_RIGHT), SetMinimalSize(140, 12),
EndContainer(),
};
diff --git a/src/strings.cpp b/src/strings.cpp
index 1c539d9343..7f1b60577d 100644
--- a/src/strings.cpp
+++ b/src/strings.cpp
@@ -2000,7 +2000,7 @@ const char *GetCurrentLanguageIsoCode()
* @return If glyphs are missing, return \c true, else return \c false.
* @post If \c true is returned and str is not NULL, *str points to a string that is found to contain at least one missing glyph.
*/
-bool MissingGlyphSearcher::FindMissingGlyphs(const char **str)
+int MissingGlyphSearcher::FindMissingGlyphs(const char **str)
{
InitFreeType(this->Monospace());
const Sprite *question_mark[FS_END];
@@ -2010,6 +2010,7 @@ bool MissingGlyphSearcher::FindMissingGlyphs(const char **str)
}
this->Reset();
+ int missing = 0;
for (const char *text = this->NextString(); text != NULL; text = this->NextString()) {
FontSize size = this->DefaultSize();
if (str != NULL) *str = text;
@@ -2020,11 +2021,11 @@ bool MissingGlyphSearcher::FindMissingGlyphs(const char **str)
size = FS_LARGE;
} else if (!IsInsideMM(c, SCC_SPRITE_START, SCC_SPRITE_END) && IsPrintable(c) && !IsTextDirectionChar(c) && c != '?' && GetGlyph(size, c) == question_mark[size]) {
/* The character is printable, but not in the normal font. This is the case we were testing for. */
- return true;
+ missing++;
}
}
}
- return false;
+ return missing;
}
/** Helper for searching through the language pack. */
diff --git a/src/strings_func.h b/src/strings_func.h
index 0da711bc4d..41ecc305eb 100644
--- a/src/strings_func.h
+++ b/src/strings_func.h
@@ -278,7 +278,7 @@ public:
*/
virtual void SetFontNames(struct FreeTypeSettings *settings, const char *font_name) = 0;
- bool FindMissingGlyphs(const char **str);
+ int FindMissingGlyphs(const char **str);
};
void CheckForMissingGlyphs(bool base_font = true, MissingGlyphSearcher *search = NULL);
diff --git a/src/subsidy_gui.cpp b/src/subsidy_gui.cpp
index 04e5ae262b..0e7c35d0e5 100644
--- a/src/subsidy_gui.cpp
+++ b/src/subsidy_gui.cpp
@@ -133,6 +133,7 @@ struct SubsidyListWindow : Window {
{
if (widget != WID_SUL_PANEL) return;
Dimension d = maxdim(GetStringBoundingBox(STR_SUBSIDIES_OFFERED_TITLE), GetStringBoundingBox(STR_SUBSIDIES_SUBSIDISED_TITLE));
+ d.height = GetMinSizing(NWST_STEP, d.height);
resize->height = d.height;
@@ -152,12 +153,13 @@ struct SubsidyListWindow : Window {
int right = r.right - WD_FRAMERECT_RIGHT;
int y = r.top + WD_FRAMERECT_TOP;
int x = r.left + WD_FRAMERECT_LEFT;
+ y = Center(y, GetMinSizing(NWST_STEP));
int pos = -this->vscroll->GetPosition();
const int cap = this->vscroll->GetCapacity();
/* Section for drawing the offered subsidies */
- if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_TITLE);
+ if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_OFFERED_TITLE);
pos++;
uint num = 0;
@@ -168,7 +170,7 @@ struct SubsidyListWindow : Window {
/* Displays the two offered towns */
SetupSubsidyDecodeParam(s, true);
SetDParam(7, _date - ymd.day + s->remaining * 32);
- DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_FROM_TO);
+ DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_OFFERED_FROM_TO);
}
pos++;
num++;
@@ -176,13 +178,13 @@ struct SubsidyListWindow : Window {
}
if (num == 0) {
- if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE);
+ if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_NONE);
pos++;
}
/* Section for drawing the already granted subsidies */
pos++;
- if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_TITLE);
+ if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_SUBSIDISED_TITLE);
pos++;
num = 0;
@@ -194,7 +196,7 @@ struct SubsidyListWindow : Window {
SetDParam(8, _date - ymd.day + s->remaining * 32);
/* Displays the two connected stations */
- DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_FROM_TO);
+ DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_SUBSIDISED_FROM_TO);
}
pos++;
num++;
@@ -202,7 +204,7 @@ struct SubsidyListWindow : Window {
}
if (num == 0) {
- if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE);
+ if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_NONE);
pos++;
}
}
diff --git a/src/table/gameopt_settings.ini b/src/table/gameopt_settings.ini
index 3a47c09e33..762ccaa3f2 100644
--- a/src/table/gameopt_settings.ini
+++ b/src/table/gameopt_settings.ini
@@ -19,6 +19,7 @@ static const char *_locale_units = "imperial|metric|si";
static const char *_town_names = "english|french|german|american|latin|silly|swedish|dutch|finnish|polish|slovak|norwegian|hungarian|austrian|romanian|czech|swiss|danish|turkish|italian|catalan";
static const char *_climates = "temperate|arctic|tropic|toyland";
static const char *_autosave_interval = "off|monthly|quarterly|half year|yearly";
+static const char *_save_to_network = "disabled|enabled|ask";
static const char *_roadsides = "left|right";
static const char *_savegame_date = "long|short|iso";
#ifdef ENABLE_NETWORK
@@ -173,6 +174,15 @@ max = 4
full = _autosave_interval
cat = SC_BASIC
+[SDTC_OMANY]
+var = gui.save_to_network
+type = SLE_UINT8
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = 2
+max = 2
+full = _save_to_network
+cat = SC_BASIC
+
[SDT_OMANY]
base = GameSettings
var = vehicle.road_side
diff --git a/src/table/misc_settings.ini b/src/table/misc_settings.ini
index 52ca2d16ef..15c6eb733f 100644
--- a/src/table/misc_settings.ini
+++ b/src/table/misc_settings.ini
@@ -121,7 +121,7 @@ name = ""resolution""
type = SLE_INT
length = 2
var = _cur_resolution
-def = ""640,480""
+def = ""854,480""
cat = SC_BASIC
[SDTG_STR]
@@ -231,6 +231,25 @@ name = ""mono_aa""
var = _freetype.mono.aa
def = false
+[SDTG_VAR]
+name = ""min_button_size""
+type = SLE_UINT
+var = _settings_client.gui.min_button
+def = 40
+min = 0
+max = 100
+cat = SC_EXPERT
+
+[SDTG_VAR]
+name = ""min_step_size""
+type = SLE_UINT
+var = _settings_client.gui.min_step
+def = 40
+min = 0
+max = 100
+cat = SC_EXPERT
+
+
[SDTG_VAR]
name = ""sprite_cache_size_px""
type = SLE_UINT
diff --git a/src/table/settings.ini b/src/table/settings.ini
index 8e2aecac15..cc4c8053a9 100644
--- a/src/table/settings.ini
+++ b/src/table/settings.ini
@@ -41,6 +41,7 @@ static bool RedrawTownAuthority(int32 p1);
static bool InvalidateCompanyInfrastructureWindow(int32 p1);
static bool InvalidateCompanyWindow(int32 p1);
static bool ZoomMinMaxChanged(int32 p1);
+static bool VerticalToolbarChanged(int32 p1);
static bool MaxVehiclesChanged(int32 p1);
#ifdef ENABLE_NETWORK
@@ -2521,6 +2522,15 @@ strhelp = STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT
strval = STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF
cat = SC_BASIC
+[SDTC_OMANY]
+var = gui.save_to_network
+type = SLE_UINT8
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = 2
+max = 2
+full = _save_to_network
+cat = SC_BASIC
+
[SDTC_BOOL]
var = gui.threaded_saves
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
@@ -2539,6 +2549,23 @@ str = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES
strhelp = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT
strval = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_LONG
+[SDTC_BOOL]
+var = gui.vertical_toolbar
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = true
+str = STR_CONFIG_SETTING_VERTICAL_TOOLBAR
+strhelp = STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT
+proc = VerticalToolbarChanged
+cat = SC_BASIC
+
+[SDTC_BOOL]
+var = gui.build_confirmation
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = true
+str = STR_CONFIG_SETTING_BUILD_CONFIRMATION
+strhelp = STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT
+cat = SC_BASIC
+
[SDTC_BOOL]
var = gui.show_finances
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
@@ -2563,7 +2590,7 @@ cat = SC_BASIC
[SDTC_BOOL]
var = gui.reverse_scroll
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
-def = false
+def = true
str = STR_CONFIG_SETTING_REVERSE_SCROLLING
strhelp = STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT
cat = SC_BASIC
@@ -2578,7 +2605,7 @@ strhelp = STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT
[SDTC_BOOL]
var = gui.left_mouse_btn_scrolling
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
-def = false
+def = true
str = STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING
strhelp = STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT
cat = SC_BASIC
diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp
index 6274de8cdd..a62d149153 100644
--- a/src/terraform_gui.cpp
+++ b/src/terraform_gui.cpp
@@ -222,18 +222,22 @@ struct TerraformToolbarWindow : Window {
switch (this->last_user_action) {
case WID_TT_LOWER_LAND: // Lower land button
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LOWER_AND_LEVEL_AREA);
+ MoveAllWindowsOffScreen();
break;
case WID_TT_RAISE_LAND: // Raise land button
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_RAISE_AND_LEVEL_AREA);
+ MoveAllWindowsOffScreen();
break;
case WID_TT_LEVEL_LAND: // Level land button
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LEVEL_AREA);
+ MoveAllWindowsOffScreen();
break;
case WID_TT_DEMOLISH: // Demolish aka dynamite button
PlaceProc_DemolishArea(tile);
+ MoveAllWindowsOffScreen();
break;
case WID_TT_BUY_LAND: // Buy land button
@@ -272,14 +276,26 @@ struct TerraformToolbarWindow : Window {
GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
break;
}
+ MoveAllHiddenWindowsBackToScreen();
}
}
virtual void OnPlaceObjectAbort()
{
+ MoveAllHiddenWindowsBackToScreen();
this->RaiseButtons();
}
+ virtual void SelectLastTool()
+ {
+ // User misplaced something - activate last selected tool again
+ if (this->last_user_action == WIDGET_LIST_END)
+ return;
+ Point dummy = {0, 0};
+ this->RaiseWidget(this->last_user_action);
+ this->OnClick(dummy, this->last_user_action, 0);
+ }
+
static HotkeyList hotkeys;
};
diff --git a/src/tilehighlight_func.h b/src/tilehighlight_func.h
index 3edef509a2..c9c7ea809f 100644
--- a/src/tilehighlight_func.h
+++ b/src/tilehighlight_func.h
@@ -22,13 +22,17 @@ bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyl
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w);
void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowClass window_class, WindowNumber window_num);
void ResetObjectToPlace();
+void ConfirmPlacingObject();
+
void VpSelectTilesWithMethod(int x, int y, ViewportPlaceMethod method);
void VpStartPlaceSizing(TileIndex tile, ViewportPlaceMethod method, ViewportDragDropSelectionProcess process);
+void VpStartPreSizing();
void VpSetPresizeRange(TileIndex from, TileIndex to);
void VpSetPlaceSizingLimit(int limit);
void UpdateTileSelection();
+void SetSelectionTilesDirty();
extern TileHighlightData _thd;
diff --git a/src/tilehighlight_type.h b/src/tilehighlight_type.h
index 3d64248dff..207f865a35 100644
--- a/src/tilehighlight_type.h
+++ b/src/tilehighlight_type.h
@@ -28,6 +28,7 @@ enum HighLightStyle {
HT_RAIL = 0x080, ///< autorail (one piece), lower bits: direction
HT_VEHICLE = 0x100, ///< vehicle is accepted as target as well (bitmask)
HT_DIAGONAL = 0x200, ///< Also allow 'diagonal rectangles'. Only usable in combination with #HT_RECT or #HT_POINT.
+ HT_SCROLL_VIEWPORT = 0x400, ///< Allow scrolling viewport with left mouse button, this disables drag&drop, use only when selection cannot grow.
HT_DRAG_MASK = 0x0F8, ///< Mask for the tile drag-type modes.
/* lower bits (used with HT_LINE and HT_RAIL):
diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp
index f253be8b3a..05e61160d5 100644
--- a/src/toolbar_gui.cpp
+++ b/src/toolbar_gui.cpp
@@ -46,6 +46,7 @@
#include "game/game.hpp"
#include "goal_base.h"
#include "story_base.h"
+#include "tutorial_gui.h"
#include "toolbar_gui.h"
#include "widgets/toolbar_widget.h"
@@ -64,6 +65,7 @@ RailType _last_built_railtype;
RoadType _last_built_roadtype;
static ScreenshotType _confirmed_screenshot_type; ///< Screenshot type the current query is about to confirm.
+int _last_clicked_toolbar_idx = 0;
/** Toobar modes */
enum ToolbarMode {
@@ -106,9 +108,9 @@ public:
{
bool rtl = _current_text_dir == TD_RTL;
if (this->checked) {
- DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK);
+ DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, Center(top, bottom - top), STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK);
}
- DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), top, this->String(), sel ? TC_WHITE : TC_BLACK);
+ DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), Center(top, bottom - top), this->String(), sel ? TC_WHITE : TC_BLACK);
}
};
@@ -142,7 +144,7 @@ public:
uint Height(uint width) const
{
- return max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL);
+ return GetMinSizing(NWST_STEP, max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL));
}
void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
@@ -179,7 +181,17 @@ public:
*/
static void PopupMainToolbMenu(Window *w, int widget, DropDownList *list, int def)
{
- ShowDropDownList(w, list, def, widget, 0, true, true);
+ if (!_settings_client.gui.vertical_toolbar) {
+ ShowDropDownList(w, list, def, widget, 0, true, list->Length() <= 1);
+ } else {
+ Rect wi_rect;
+ NWidgetCore *nwi = w->GetWidget(widget);
+ wi_rect.left = nwi->pos_x;
+ wi_rect.right = nwi->pos_x + nwi->current_x;
+ wi_rect.top = nwi->pos_y;
+ wi_rect.bottom = nwi->pos_y + nwi->current_y;
+ ShowDropDownListAt(w, list, def, widget, wi_rect, nwi->colour, true, list->Length() <= 1);
+ }
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
}
@@ -332,7 +344,7 @@ static CallBackFunction ToolbarOptionsClick(Window *w)
*list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES));
*list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS));
- ShowDropDownList(w, list, 0, WID_TN_SETTINGS, 140, true, true);
+ ShowDropDownList(w, list, 0, WID_TN_SETTINGS, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
return CBF_NONE;
}
@@ -868,7 +880,7 @@ static CallBackFunction ToolbarZoomOutClick(Window *w)
static CallBackFunction ToolbarBuildRailClick(Window *w)
{
- ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, true, true);
+ ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
return CBF_NONE;
}
@@ -905,7 +917,7 @@ static CallBackFunction ToolbarBuildRoadClick(Window *w)
*list->Append() = new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION, ROADTYPE_TRAM, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM));
break;
}
- ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, true);
+ ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, list->Length() <= 1);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
return CBF_NONE;
}
@@ -1038,7 +1050,7 @@ static CallBackFunction PlaceLandBlockInfo()
ResetObjectToPlace();
return CBF_NONE;
} else {
- SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
+ SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, HT_RECT, _settings_client.gui.vertical_toolbar ? WC_MAIN_TOOLBAR_RIGHT : WC_MAIN_TOOLBAR, 0);
return CBF_PLACE_LANDINFO;
}
}
@@ -1141,6 +1153,7 @@ static CallBackFunction MenuClickHelp(int index)
{
switch (index) {
case 0: return PlaceLandBlockInfo();
+ case 1: ShowTutorialWindow(); break;
case 2: IConsoleSwitch(); break;
case 3: ShowAIDebugWindow(); break;
case 4: MenuClickSmallScreenshot(); break;
@@ -1171,6 +1184,40 @@ static CallBackFunction ToolbarSwitchClick(Window *w)
return CBF_NONE;
}
+static CallBackFunction ToolbarCtrlClick(Window *w)
+{
+ _ctrl_pressed = !_ctrl_pressed;
+ //DEBUG(misc, 1, "ToolbarCtrlClick: pressed %d", _ctrl_pressed);
+ w->SetWidgetLoweredState(WID_TN_CTRL, _ctrl_pressed);
+ w->SetWidgetDirty(WID_TN_CTRL);
+ HandleCtrlChanged();
+ if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
+ return CBF_NONE;
+}
+
+static CallBackFunction ToolbarShiftClick(Window *w)
+{
+ _shift_pressed = !_shift_pressed;
+ //DEBUG(misc, 1, "ToolbarShiftClick: pressed %d", _shift_pressed);
+ w->SetWidgetLoweredState(WID_TN_SHIFT, _shift_pressed);
+ w->SetWidgetDirty(WID_TN_SHIFT);
+ if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
+ return CBF_NONE;
+}
+
+static CallBackFunction ToolbarDeleteClick(Window *w)
+{
+ DeleteNonVitalWindows();
+ _ctrl_pressed = false;
+ w->SetWidgetLoweredState(WID_TN_CTRL, _ctrl_pressed);
+ w->SetWidgetDirty(WID_TN_CTRL);
+ _shift_pressed = false;
+ w->SetWidgetLoweredState(WID_TN_SHIFT, _shift_pressed);
+ w->SetWidgetDirty(WID_TN_SHIFT);
+ if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
+ return CBF_NONE;
+}
+
/* --- Scenario editor specific handlers. */
/**
@@ -1313,7 +1360,7 @@ protected:
uint spacers; ///< Number of spacer widgets in this toolbar
public:
- NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL)
+ NWidgetToolbarContainer(WidgetType widgetType = NWID_HORIZONTAL) : NWidgetContainer(widgetType)
{
}
@@ -1324,27 +1371,35 @@ public:
*/
bool IsButton(WidgetType type) const
{
- return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN;
+ return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN || type == WWT_PUSHTXTBTN || type == WWT_TEXTBTN;
}
void SetupSmallestSize(Window *w, bool init_array)
{
this->smallest_x = 0; // Biggest child
this->smallest_y = 0; // Biggest child
- this->fill_x = 1;
- this->fill_y = 0;
- this->resize_x = 1; // We only resize in this direction
- this->resize_y = 0; // We never resize in this direction
+ this->fill_x = (type == NWID_HORIZONTAL);
+ this->fill_y = (type == NWID_VERTICAL);
+ this->resize_x = (type == NWID_HORIZONTAL); // We only resize in this direction
+ this->resize_y = (type == NWID_VERTICAL); // We never resize in this direction
this->spacers = 0;
uint nbuttons = 0;
/* First initialise some variables... */
for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
child_wid->SetupSmallestSize(w, init_array);
- this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
+ if (type == NWID_HORIZONTAL) {
+ this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
+ } else {
+ this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
+ }
if (this->IsButton(child_wid->type)) {
nbuttons++;
- this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
+ if (type == NWID_HORIZONTAL) {
+ this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
+ } else {
+ this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
+ }
} else if (child_wid->type == NWID_SPACER) {
this->spacers++;
}
@@ -1352,11 +1407,25 @@ public:
/* ... then in a second pass make sure the 'current' heights are set. Won't change ever. */
for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
- child_wid->current_y = this->smallest_y;
- if (!this->IsButton(child_wid->type)) {
- child_wid->current_x = child_wid->smallest_x;
+ if (type == NWID_HORIZONTAL) {
+ child_wid->current_y = this->smallest_y;
+ if (!this->IsButton(child_wid->type)) {
+ child_wid->current_x = child_wid->smallest_x;
+ }
+ } else {
+ child_wid->current_x = this->smallest_x;
+ if (!this->IsButton(child_wid->type)) {
+ child_wid->current_y = child_wid->smallest_y;
+ }
}
}
+ if (type == NWID_HORIZONTAL) {
+ //w->window_desc->default_width_trad = nbuttons * this->smallest_x;
+ w->window_desc->pref_width = nbuttons * this->smallest_x;
+ } else {
+ //w->window_desc->default_height_trad = nbuttons * this->smallest_y;
+ w->window_desc->pref_height = nbuttons * this->smallest_y;
+ }
_toolbar_width = nbuttons * this->smallest_x;
}
@@ -1388,6 +1457,10 @@ public:
uint position = 0; // Place to put next child relative to origin of the container.
uint spacer_space = max(0, (int)given_width - (int)(button_count * this->smallest_x)); // Remaining spacing for 'spacer' widgets
uint button_space = given_width - spacer_space; // Remaining spacing for the buttons
+ if (type == NWID_VERTICAL) {
+ spacer_space = max(0, (int)given_height - (int)(button_count * this->smallest_y));
+ button_space = given_height - spacer_space;
+ }
uint spacer_i = 0;
uint button_i = 0;
@@ -1408,12 +1481,22 @@ public:
/* Buttons can be scaled, the others not. */
if (this->IsButton(child_wid->type)) {
- child_wid->current_x = button_space / (button_count - button_i);
- button_space -= child_wid->current_x;
+ if (type == NWID_HORIZONTAL) {
+ child_wid->current_x = button_space / (button_count - button_i);
+ button_space -= child_wid->current_x;
+ } else {
+ child_wid->current_y = button_space / (button_count - button_i);
+ button_space -= child_wid->current_y;
+ }
button_i++;
}
- child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl);
- position += child_wid->current_x;
+ if (type == NWID_HORIZONTAL) {
+ child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl);
+ position += child_wid->current_x;
+ } else {
+ child_wid->AssignSizePosition(sizing, x, y + position, this->current_x, child_wid->current_y, rtl);
+ position += child_wid->current_y;
+ }
if (rtl) {
cur_wid--;
@@ -1784,6 +1867,54 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
}
};
+/** Container for the vertical main toolbar */
+class NWidgetVerticalToolbarContainer : public NWidgetToolbarContainer {
+ int side;
+
+ public:
+ NWidgetVerticalToolbarContainer(int side) : NWidgetToolbarContainer(NWID_VERTICAL), side(side)
+ {
+ }
+
+ /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
+ {
+ // TODO: replace with WID_TN_XXX
+ static const byte arrange_left[] = {
+ 32, 30, 31, 19, 20, 0, 1, 2, 3, 4, 5, 6,
+ };
+ // Some rather artistic button arrangement, I'm proud of myself
+ static const byte arrange_right[] = {
+ 29, 21, 22, 23, 24, 25, 7, 8, 9, 12, 14, 28,
+ 29, 15, 16, 17, 18, 13, 7, 10, 11, 26, 27, 28,
+ };
+ // Full-length toolbar without switch button, if enough space
+ static const byte arrange_left_all[] = {
+ 32, 30, 31, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13,
+ };
+ static const byte arrange_right_all[] = {
+ 10, 11, 12, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 27, 28,
+ };
+
+ spacer_count = 0;
+
+ if (_screen.height / this->smallest_y >= lengthof(arrange_left_all))
+ {
+ button_count = arrangable_count = lengthof(arrange_left_all);
+ if (side == 0) {
+ return arrange_left_all;
+ }
+ return arrange_right_all;
+ }
+
+ if (side == 0) {
+ button_count = arrangable_count = lengthof(arrange_left);
+ return arrange_left;
+ }
+ button_count = arrangable_count = lengthof(arrange_right) / 2;
+ return &arrange_right[((_toolbar_mode == TB_LOWER) ? button_count : 0)];
+ }
+};
+
/** Container for the scenario editor's toolbar */
class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
uint panel_widths[2]; ///< The width of the two panels (the text panel and date panel)
@@ -1931,6 +2062,9 @@ static ToolbarButtonProc * const _toolbar_button_procs[] = {
ToolbarNewspaperClick,
ToolbarHelpClick,
ToolbarSwitchClick,
+ ToolbarCtrlClick,
+ ToolbarShiftClick,
+ ToolbarDeleteClick,
};
enum MainToolbarHotkeys {
@@ -1976,7 +2110,10 @@ enum MainToolbarHotkeys {
/** Main toolbar. */
struct MainToolbarWindow : Window {
- MainToolbarWindow(WindowDesc *desc) : Window(desc)
+ int *clickedFlag;
+ int clickedValue;
+
+ MainToolbarWindow(WindowDesc *desc, int *clickedFlag = NULL, int clickedValue = 0) : Window(desc), clickedFlag(clickedFlag), clickedValue(clickedValue)
{
this->InitNested(0);
@@ -2013,11 +2150,15 @@ struct MainToolbarWindow : Window {
virtual void OnClick(Point pt, int widget, int click_count)
{
+ if (clickedFlag)
+ *clickedFlag = clickedValue;
if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
}
virtual void OnDropdownSelect(int widget, int index)
{
+ if (clickedFlag)
+ *clickedFlag = clickedValue;
CallBackFunction cbf = _menu_clicked_procs[widget](index);
if (cbf != CBF_NONE) _last_started_action = cbf;
}
@@ -2081,7 +2222,7 @@ struct MainToolbarWindow : Window {
ShowLandInfo(tile);
break;
- default: NOT_REACHED();
+ default: return; //NOT_REACHED();
}
}
@@ -2179,44 +2320,44 @@ static Hotkey maintoolbar_hotkeys[] = {
};
HotkeyList MainToolbarWindow::hotkeys("maintoolbar", maintoolbar_hotkeys);
+/** Sprites to use for the different toolbar buttons */
+static const SpriteID _toolbar_button_sprites[] = {
+ SPR_IMG_PAUSE, // WID_TN_PAUSE
+ SPR_IMG_FASTFORWARD, // WID_TN_FAST_FORWARD
+ SPR_IMG_SETTINGS, // WID_TN_SETTINGS
+ SPR_IMG_SAVE, // WID_TN_SAVE
+ SPR_IMG_SMALLMAP, // WID_TN_SMALL_MAP
+ SPR_IMG_TOWN, // WID_TN_TOWNS
+ SPR_IMG_SUBSIDIES, // WID_TN_SUBSIDIES
+ SPR_IMG_COMPANY_LIST, // WID_TN_STATIONS
+ SPR_IMG_COMPANY_FINANCE, // WID_TN_FINANCES
+ SPR_IMG_COMPANY_GENERAL, // WID_TN_COMPANIES
+ SPR_IMG_STORY_BOOK, // WID_TN_STORY
+ SPR_IMG_GOAL, // WID_TN_GOAL
+ SPR_IMG_GRAPHS, // WID_TN_GRAPHS
+ SPR_IMG_COMPANY_LEAGUE, // WID_TN_LEAGUE
+ SPR_IMG_INDUSTRY, // WID_TN_INDUSTRIES
+ SPR_IMG_TRAINLIST, // WID_TN_TRAINS
+ SPR_IMG_TRUCKLIST, // WID_TN_ROADVEHS
+ SPR_IMG_SHIPLIST, // WID_TN_SHIPS
+ SPR_IMG_AIRPLANESLIST, // WID_TN_AIRCRAFT
+ SPR_IMG_ZOOMIN, // WID_TN_ZOOMIN
+ SPR_IMG_ZOOMOUT, // WID_TN_ZOOMOUT
+ SPR_IMG_BUILDRAIL, // WID_TN_RAILS
+ SPR_IMG_BUILDROAD, // WID_TN_ROADS
+ SPR_IMG_BUILDWATER, // WID_TN_WATER
+ SPR_IMG_BUILDAIR, // WID_TN_AIR
+ SPR_IMG_LANDSCAPING, // WID_TN_LANDSCAPE
+ SPR_IMG_MUSIC, // WID_TN_MUSIC_SOUND
+ SPR_IMG_MESSAGES, // WID_TN_MESSAGES
+ SPR_IMG_QUERY, // WID_TN_HELP
+ SPR_IMG_SWITCH_TOOLBAR, // WID_TN_SWITCH_BAR
+};
+
static NWidgetBase *MakeMainToolbar(int *biggest_index)
{
- /** Sprites to use for the different toolbar buttons */
- static const SpriteID toolbar_button_sprites[] = {
- SPR_IMG_PAUSE, // WID_TN_PAUSE
- SPR_IMG_FASTFORWARD, // WID_TN_FAST_FORWARD
- SPR_IMG_SETTINGS, // WID_TN_SETTINGS
- SPR_IMG_SAVE, // WID_TN_SAVE
- SPR_IMG_SMALLMAP, // WID_TN_SMALL_MAP
- SPR_IMG_TOWN, // WID_TN_TOWNS
- SPR_IMG_SUBSIDIES, // WID_TN_SUBSIDIES
- SPR_IMG_COMPANY_LIST, // WID_TN_STATIONS
- SPR_IMG_COMPANY_FINANCE, // WID_TN_FINANCES
- SPR_IMG_COMPANY_GENERAL, // WID_TN_COMPANIES
- SPR_IMG_STORY_BOOK, // WID_TN_STORY
- SPR_IMG_GOAL, // WID_TN_GOAL
- SPR_IMG_GRAPHS, // WID_TN_GRAPHS
- SPR_IMG_COMPANY_LEAGUE, // WID_TN_LEAGUE
- SPR_IMG_INDUSTRY, // WID_TN_INDUSTRIES
- SPR_IMG_TRAINLIST, // WID_TN_TRAINS
- SPR_IMG_TRUCKLIST, // WID_TN_ROADVEHS
- SPR_IMG_SHIPLIST, // WID_TN_SHIPS
- SPR_IMG_AIRPLANESLIST, // WID_TN_AIRCRAFT
- SPR_IMG_ZOOMIN, // WID_TN_ZOOMIN
- SPR_IMG_ZOOMOUT, // WID_TN_ZOOMOUT
- SPR_IMG_BUILDRAIL, // WID_TN_RAILS
- SPR_IMG_BUILDROAD, // WID_TN_ROADS
- SPR_IMG_BUILDWATER, // WID_TN_WATER
- SPR_IMG_BUILDAIR, // WID_TN_AIR
- SPR_IMG_LANDSCAPING, // WID_TN_LANDSCAPE
- SPR_IMG_MUSIC, // WID_TN_MUSIC_SOUND
- SPR_IMG_MESSAGES, // WID_TN_MESSAGES
- SPR_IMG_QUERY, // WID_TN_HELP
- SPR_IMG_SWITCH_TOOLBAR, // WID_TN_SWITCH_BAR
- };
-
NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
- for (uint i = 0; i < WID_TN_END; i++) {
+ for (uint i = 0; i <= WID_TN_SWITCH_BAR; i++) {
switch (i) {
case WID_TN_SMALL_MAP:
case WID_TN_FINANCES:
@@ -2227,10 +2368,15 @@ static NWidgetBase *MakeMainToolbar(int *biggest_index)
hor->Add(new NWidgetSpacer(0, 0));
break;
}
- hor->Add(new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i));
+ hor->Add(new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, _toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i));
}
- *biggest_index = max(*biggest_index, WID_TN_SWITCH_BAR);
+ hor->Add(new NWidgetSpacer(0, 0));
+ hor->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_CTRL, STR_TABLET_CTRL, STR_TABLET_CTRL_TOOLTIP));
+ hor->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_SHIFT, STR_TABLET_SHIFT, STR_TABLET_SHIFT_TOOLTIP));
+ hor->Add(new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TN_DELETE, STR_TABLET_CLOSE, STR_TABLET_CLOSE_TOOLTIP));
+
+ *biggest_index = max(*biggest_index, WID_TN_DELETE);
return hor;
}
@@ -2246,6 +2392,59 @@ static WindowDesc _toolb_normal_desc(
&MainToolbarWindow::hotkeys
);
+static NWidgetBase *MakeVerticalLeftToolbar(int *biggest_index)
+{
+ NWidgetVerticalToolbarContainer *tb = new NWidgetVerticalToolbarContainer(0);
+ for (uint i = 0; i <= WID_TN_SWITCH_BAR; i++) {
+ tb->Add(new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, _toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i));
+ }
+
+ tb->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_CTRL, STR_TABLET_CTRL, STR_TABLET_CTRL_TOOLTIP));
+ tb->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_SHIFT, STR_TABLET_SHIFT, STR_TABLET_SHIFT_TOOLTIP));
+ tb->Add(new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TN_DELETE, STR_TABLET_CLOSE, STR_TABLET_CLOSE_TOOLTIP));
+
+ *biggest_index = max(*biggest_index, WID_TN_DELETE);
+ return tb;
+}
+
+static const NWidgetPart _nested_toolbar_vertical_left_widgets[] = {
+ NWidgetFunction(MakeVerticalLeftToolbar),
+};
+
+static WindowDesc _toolb_vertical_left_desc(
+ WDP_MANUAL, NULL, 22, 480,
+ WC_MAIN_TOOLBAR, WC_NONE,
+ WDF_NO_FOCUS,
+ _nested_toolbar_vertical_left_widgets, lengthof(_nested_toolbar_vertical_left_widgets),
+ &MainToolbarWindow::hotkeys
+);
+
+static NWidgetBase *MakeVerticalRightToolbar(int *biggest_index)
+{
+ NWidgetVerticalToolbarContainer *tb = new NWidgetVerticalToolbarContainer(1);
+ for (uint i = 0; i <= WID_TN_SWITCH_BAR; i++) {
+ tb->Add(new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, _toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i));
+ }
+
+ tb->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_CTRL, STR_TABLET_CTRL, STR_TABLET_CTRL_TOOLTIP));
+ tb->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_SHIFT, STR_TABLET_SHIFT, STR_TABLET_SHIFT_TOOLTIP));
+ tb->Add(new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TN_DELETE, STR_TABLET_CLOSE, STR_TABLET_CLOSE_TOOLTIP));
+
+ *biggest_index = max(*biggest_index, WID_TN_DELETE);
+ return tb;
+}
+
+static const NWidgetPart _nested_toolbar_vertical_right_widgets[] = {
+ NWidgetFunction(MakeVerticalRightToolbar),
+};
+
+static WindowDesc _toolb_vertical_right_desc(
+ WDP_MANUAL, NULL, 22, 480,
+ WC_MAIN_TOOLBAR_RIGHT, WC_NONE,
+ WDF_NO_FOCUS,
+ _nested_toolbar_vertical_right_widgets, lengthof(_nested_toolbar_vertical_right_widgets),
+ &MainToolbarWindow::hotkeys
+);
/* --- Toolbar handling for the scenario editor */
@@ -2574,6 +2773,14 @@ void AllocateToolbar()
if (_game_mode == GM_EDITOR) {
new ScenarioEditorToolbarWindow(&_toolb_scen_desc);
} else {
- new MainToolbarWindow(&_toolb_normal_desc);
+ if (_settings_client.gui.vertical_toolbar) {
+ MainToolbarWindow *w = new MainToolbarWindow(&_toolb_vertical_left_desc, &_last_clicked_toolbar_idx, 0);
+ w->left = 0;
+ w = new MainToolbarWindow(&_toolb_vertical_right_desc, &_last_clicked_toolbar_idx, 1);
+ w->left = _screen.width - w->width;
+ SetDirtyBlocks(0, w->top, _screen.width, w->top + w->height);
+ } else {
+ new MainToolbarWindow(&_toolb_normal_desc);
+ }
}
}
diff --git a/src/toolbar_gui.h b/src/toolbar_gui.h
index 37fc8f0e9f..69cb3bba6d 100644
--- a/src/toolbar_gui.h
+++ b/src/toolbar_gui.h
@@ -16,6 +16,7 @@ void AllocateToolbar();
void ToggleBoundingBoxes();
void ToggleDirtyBlocks();
+extern int _last_clicked_toolbar_idx;
extern uint _toolbar_width;
#endif /* TOOLBAR_GUI_H */
diff --git a/src/town_gui.cpp b/src/town_gui.cpp
index 142966b694..26107d76c9 100644
--- a/src/town_gui.cpp
+++ b/src/town_gui.cpp
@@ -49,12 +49,12 @@ static const NWidgetPart _nested_town_authority_widgets[] = {
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
EndContainer(),
- NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_RATING_INFO), SetMinimalSize(317, 92), SetResize(1, 1), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_RATING_INFO), SetMinimalSize(317, 92), SetResize(1, 1), SetFill(1, 1), EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_COMMAND_LIST), SetMinimalSize(305, 52), SetResize(1, 0), SetDataTip(0x0, STR_LOCAL_AUTHORITY_ACTIONS_TOOLTIP), SetScrollbar(WID_TA_SCROLLBAR), EndContainer(),
NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_TA_SCROLLBAR),
EndContainer(),
- NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_ACTION_INFO), SetMinimalSize(317, 52), SetResize(1, 0), EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_ACTION_INFO), SetMinimalSize(317, 52), SetResize(1, 1), SetFill(1, 1), EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TA_EXECUTE), SetMinimalSize(317, 12), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_LOCAL_AUTHORITY_DO_IT_BUTTON, STR_LOCAL_AUTHORITY_DO_IT_TOOLTIP),
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
@@ -67,6 +67,7 @@ private:
Town *town; ///< Town being displayed.
int sel_index; ///< Currently selected town action, \c 0 to \c TACT_COUNT-1, \c -1 means no action selected.
Scrollbar *vscroll;
+ uint actions_step;
uint displayed_actions_on_previous_painting; ///< Actions that were available on the previous call to OnPaint()
/**
@@ -96,7 +97,8 @@ public:
this->town = Town::Get(window_number);
this->InitNested(window_number);
this->vscroll = this->GetScrollbar(WID_TA_SCROLLBAR);
- this->vscroll->SetCapacity((this->GetWidget(WID_TA_COMMAND_LIST)->current_y - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM) / FONT_HEIGHT_NORMAL);
+ this->actions_step = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
+ this->vscroll->SetCapacity((this->GetWidget(WID_TA_COMMAND_LIST)->current_y - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM) / this->actions_step);
}
virtual void OnPaint()
@@ -199,12 +201,12 @@ public:
case WID_TA_COMMAND_LIST: {
int numact;
uint buttons = GetMaskOfTownActions(&numact, _local_company, this->town);
- int y = r.top + WD_FRAMERECT_TOP;
+ int y = Center(r.top, this->actions_step);
int pos = this->vscroll->GetPosition();
if (--pos < 0) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_LOCAL_AUTHORITY_ACTIONS_TITLE);
- y += FONT_HEIGHT_NORMAL;
+ y += this->actions_step;
}
for (int i = 0; buttons; i++, buttons >>= 1) {
@@ -213,7 +215,7 @@ public:
if ((buttons & 1) && --pos < 0) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y,
STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i, this->sel_index == i ? TC_WHITE : TC_ORANGE);
- y += FONT_HEIGHT_NORMAL;
+ y += this->actions_step;
}
}
break;
@@ -240,7 +242,8 @@ public:
}
case WID_TA_COMMAND_LIST:
- size->height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM;
+ resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
+ size->height = WD_FRAMERECT_TOP + 3 * resize->height + WD_FRAMERECT_BOTTOM;
size->width = GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTIONS_TITLE).width;
for (uint i = 0; i < TACT_COUNT; i++ ) {
size->width = max(size->width, GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i).width);
@@ -259,7 +262,7 @@ public:
{
switch (widget) {
case WID_TA_COMMAND_LIST: {
- int y = this->GetRowFromWidget(pt.y, WID_TA_COMMAND_LIST, 1, FONT_HEIGHT_NORMAL);
+ int y = this->GetRowFromWidget(pt.y, WID_TA_COMMAND_LIST, 1, this->actions_step);
if (!IsInsideMM(y, 0, 5)) return;
y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_company, this->town), y + this->vscroll->GetPosition() - 1);
@@ -613,7 +616,7 @@ static const NWidgetPart _nested_town_directory_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TD_SORT_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
+ NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TD_SORT_ORDER), SetSizingType(NWST_STEP), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_TD_SORT_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(),
EndContainer(),
@@ -825,7 +828,7 @@ public:
}
Dimension icon_size = GetSpriteSize(SPR_TOWN_RATING_GOOD);
d.width += icon_size.width + 2;
- d.height = max(d.height, icon_size.height);
+ d.height = GetMinSizing(NWST_STEP, max(d.height, icon_size.height));
resize->height = d.height;
d.height *= 5;
d.width += padding.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
@@ -977,61 +980,65 @@ static const NWidgetPart _nested_found_town_widgets[] = {
NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
EndContainer(),
/* Construct new town(s) buttons. */
- NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
- NWidget(NWID_SPACER), SetMinimalSize(0, 2),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_NEW_TOWN), SetMinimalSize(156, 12), SetFill(1, 0),
- SetDataTip(STR_FOUND_TOWN_NEW_TOWN_BUTTON, STR_FOUND_TOWN_NEW_TOWN_TOOLTIP), SetPadding(0, 2, 1, 2),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_RANDOM_TOWN), SetMinimalSize(156, 12), SetFill(1, 0),
- SetDataTip(STR_FOUND_TOWN_RANDOM_TOWN_BUTTON, STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP), SetPadding(0, 2, 1, 2),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_MANY_RANDOM_TOWNS), SetMinimalSize(156, 12), SetFill(1, 0),
- SetDataTip(STR_FOUND_TOWN_MANY_RANDOM_TOWNS, STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP), SetPadding(0, 2, 0, 2),
- /* Town name selection. */
- NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(156, 14), SetPadding(0, 2, 0, 2), SetDataTip(STR_FOUND_TOWN_NAME_TITLE, STR_NULL),
- NWidget(WWT_EDITBOX, COLOUR_GREY, WID_TF_TOWN_NAME_EDITBOX), SetMinimalSize(156, 12), SetPadding(0, 2, 3, 2),
- SetDataTip(STR_FOUND_TOWN_NAME_EDITOR_TITLE, STR_FOUND_TOWN_NAME_EDITOR_HELP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_TOWN_NAME_RANDOM), SetMinimalSize(78, 12), SetPadding(0, 2, 0, 2), SetFill(1, 0),
- SetDataTip(STR_FOUND_TOWN_NAME_RANDOM_BUTTON, STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP),
- /* Town size selection. */
- NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
- NWidget(NWID_SPACER), SetFill(1, 0),
- NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_TITLE, STR_NULL),
- NWidget(NWID_SPACER), SetFill(1, 0),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 2),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_NEW_TOWN), SetMinimalSize(156, 12), SetFill(1, 0),
+ SetDataTip(STR_FOUND_TOWN_NEW_TOWN_BUTTON, STR_FOUND_TOWN_NEW_TOWN_TOOLTIP), SetPadding(0, 2, 1, 2),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_RANDOM_TOWN), SetMinimalSize(156, 12), SetFill(1, 0),
+ SetDataTip(STR_FOUND_TOWN_RANDOM_TOWN_BUTTON, STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP), SetPadding(0, 2, 1, 2),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_MANY_RANDOM_TOWNS), SetMinimalSize(156, 12), SetFill(1, 0),
+ SetDataTip(STR_FOUND_TOWN_MANY_RANDOM_TOWNS, STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP), SetPadding(0, 2, 0, 2),
+ /* Town name selection. */
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(156, 14), SetPadding(0, 2, 0, 2), SetDataTip(STR_FOUND_TOWN_NAME_TITLE, STR_NULL),
+ NWidget(WWT_EDITBOX, COLOUR_GREY, WID_TF_TOWN_NAME_EDITBOX), SetMinimalSize(156, 12), SetPadding(0, 2, 3, 2),
+ SetDataTip(STR_FOUND_TOWN_NAME_EDITOR_TITLE, STR_FOUND_TOWN_NAME_EDITOR_HELP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_TOWN_NAME_RANDOM), SetMinimalSize(78, 12), SetPadding(0, 2, 0, 2), SetFill(1, 0),
+ SetDataTip(STR_FOUND_TOWN_NAME_RANDOM_BUTTON, STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP),
+ /* Town size selection. */
+ NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
+ NWidget(NWID_SPACER), SetFill(1, 0),
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_TITLE, STR_NULL),
+ NWidget(NWID_SPACER), SetFill(1, 0),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_SMALL), SetMinimalSize(78, 12), SetFill(1, 0),
+ SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_SMALL_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_MEDIUM), SetMinimalSize(78, 12), SetFill(1, 0),
+ SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_MEDIUM_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 1),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_LARGE), SetMinimalSize(78, 12), SetFill(1, 0),
+ SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_LARGE_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_RANDOM), SetMinimalSize(78, 12), SetFill(1, 0),
+ SetDataTip(STR_FOUND_TOWN_SIZE_RANDOM, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 3),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_CITY), SetPadding(0, 2, 0, 2), SetMinimalSize(156, 12), SetFill(1, 0),
+ SetDataTip(STR_FOUND_TOWN_CITY, STR_FOUND_TOWN_CITY_TOOLTIP), SetFill(1, 0),
EndContainer(),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_SMALL), SetMinimalSize(78, 12), SetFill(1, 0),
- SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_SMALL_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_MEDIUM), SetMinimalSize(78, 12), SetFill(1, 0),
- SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_MEDIUM_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
+ /* Town roads selection. */
+ NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
+ NWidget(NWID_SPACER), SetFill(1, 0),
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetDataTip(STR_FOUND_TOWN_ROAD_LAYOUT, STR_NULL),
+ NWidget(NWID_SPACER), SetFill(1, 0),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_ORIGINAL), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_ORIGINAL, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_BETTER), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_BETTER_ROADS, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 1),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_GRID2), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_2X2_GRID, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_GRID3), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_3X3_GRID, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 1),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_RANDOM), SetPadding(0, 2, 0, 2), SetMinimalSize(0, 12), SetFill(1, 0),
+ SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_RANDOM, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), SetFill(1, 0),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 2),
EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 1),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_LARGE), SetMinimalSize(78, 12), SetFill(1, 0),
- SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_LARGE_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_RANDOM), SetMinimalSize(78, 12), SetFill(1, 0),
- SetDataTip(STR_FOUND_TOWN_SIZE_RANDOM, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP),
- EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 3),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_CITY), SetPadding(0, 2, 0, 2), SetMinimalSize(156, 12), SetFill(1, 0),
- SetDataTip(STR_FOUND_TOWN_CITY, STR_FOUND_TOWN_CITY_TOOLTIP), SetFill(1, 0),
- /* Town roads selection. */
- NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
- NWidget(NWID_SPACER), SetFill(1, 0),
- NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetDataTip(STR_FOUND_TOWN_ROAD_LAYOUT, STR_NULL),
- NWidget(NWID_SPACER), SetFill(1, 0),
- EndContainer(),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_ORIGINAL), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_ORIGINAL, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_BETTER), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_BETTER_ROADS, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT),
- EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 1),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_GRID2), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_2X2_GRID, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_GRID3), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_3X3_GRID, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT),
- EndContainer(),
- NWidget(NWID_SPACER), SetMinimalSize(0, 1),
- NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_RANDOM), SetPadding(0, 2, 0, 2), SetMinimalSize(0, 12), SetFill(1, 0),
- SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_RANDOM, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), SetFill(1, 0),
- NWidget(NWID_SPACER), SetMinimalSize(0, 2),
EndContainer(),
};
@@ -1060,6 +1067,10 @@ public:
this->UpdateButtons(true);
}
+ ~FoundTownWindow() {
+ if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort();
+ }
+
void RandomTownName()
{
this->townnamevalid = GenerateTownName(&this->townnameparts);
@@ -1164,11 +1175,25 @@ public:
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
- this->ExecuteFoundTownCommand(tile, false, STR_ERROR_CAN_T_FOUND_TOWN_HERE, CcFoundTown);
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE);
+ MoveAllWindowsOffScreen();
+ }
+
+ virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
+ {
+ VpSelectTilesWithMethod(pt.x, pt.y, select_method);
+ }
+
+ virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
+ {
+ assert(start_tile == end_tile);
+ this->ExecuteFoundTownCommand(end_tile, false, STR_ERROR_CAN_T_FOUND_TOWN_HERE, CcFoundTown);
+ MoveAllHiddenWindowsBackToScreen();
}
virtual void OnPlaceObjectAbort()
{
+ MoveAllHiddenWindowsBackToScreen();
this->RaiseButtons();
this->UpdateButtons(false);
}
@@ -1186,7 +1211,7 @@ public:
};
static WindowDesc _found_town_desc(
- WDP_AUTO, "build_town", 160, 162,
+ WDP_ALIGN_TOOLBAR, "build_town", 160, 162,
WC_FOUND_TOWN, WC_NONE,
WDF_CONSTRUCTION,
_nested_found_town_widgets, lengthof(_nested_found_town_widgets)
@@ -1195,5 +1220,6 @@ static WindowDesc _found_town_desc(
void ShowFoundTownWindow()
{
if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return;
+ DeleteToolbarLinkedWindows();
AllocateWindowDescFront(&_found_town_desc, 0);
}
diff --git a/src/transparency_gui.cpp b/src/transparency_gui.cpp
index 4bad2b0561..af4c7d1d00 100644
--- a/src/transparency_gui.cpp
+++ b/src/transparency_gui.cpp
@@ -144,7 +144,7 @@ static const NWidgetPart _nested_transparency_widgets[] = {
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(1, 1), EndContainer(),
EndContainer(),
/* Panel with 'invisibility' buttons. */
- NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_TT_BUTTONS), SetMinimalSize(219, 13), SetDataTip(0x0, STR_TRANSPARENT_INVISIBLE_TOOLTIP),
+ NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_TT_BUTTONS), SetSizingType(NWST_STEP), SetMinimalSize(219, 13), SetDataTip(0x0, STR_TRANSPARENT_INVISIBLE_TOOLTIP),
EndContainer(),
};
diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp
index f21eeaef2e..e444745220 100644
--- a/src/tree_gui.cpp
+++ b/src/tree_gui.cpp
@@ -18,6 +18,7 @@
#include "command_func.h"
#include "sound_func.h"
#include "tree_map.h"
+#include "window_func.h"
#include "widgets/tree_widget.h"
@@ -60,6 +61,11 @@ public:
ResetObjectToPlace();
}
+ ~BuildTreesWindow()
+ {
+ if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort();
+ }
+
/**
* Calculate the maximum size of all tree sprites
* @return Dimension of the largest tree sprite
@@ -141,6 +147,7 @@ public:
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_PLANT_TREES);
+ MoveAllWindowsOffScreen();
}
virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
@@ -153,6 +160,7 @@ public:
if (pt.x != -1 && select_proc == DDSP_PLANT_TREES) {
DoCommandP(end_tile, this->tree_to_plant, start_tile,
CMD_PLANT_TREE | CMD_MSG(STR_ERROR_CAN_T_PLANT_TREE_HERE));
+ MoveAllHiddenWindowsBackToScreen();
}
}
@@ -167,7 +175,10 @@ public:
virtual void OnPlaceObjectAbort()
{
+ MoveAllHiddenWindowsBackToScreen();
this->RaiseButtons();
+
+ ResetObjectToPlace();
}
};
diff --git a/src/tutorial_gui.cpp b/src/tutorial_gui.cpp
new file mode 100644
index 0000000000..3cf107abce
--- /dev/null
+++ b/src/tutorial_gui.cpp
@@ -0,0 +1,224 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/**
+ * @file tutorial_gui.cpp
+ * Links to video tutorials on Youtube.
+ */
+
+#include "stdafx.h"
+
+#ifdef __ANDROID__
+#include
+#endif
+
+#include "tutorial_gui.h"
+#include "debug.h"
+#include "strings_func.h"
+#include "window_func.h"
+#include "fios.h"
+#include "string_func.h"
+#include "language.h"
+#include "widget_type.h"
+#include "window_type.h"
+#include "window_func.h"
+#include "window_gui.h"
+#include "widgets/station_widget.h"
+#include "table/strings.h"
+#include "table/sprites.h"
+
+
+static bool showTutorialMainMenu = false;
+
+static const char * ANY_LANG = "ANY_LANG";
+
+struct VideoLink_t {
+ const char *lang;
+ const char *video;
+};
+
+static VideoLink_t busTutorial[] = {
+ { "en", "https://www.youtube.com/watch?v=EULXRMR4PyE" },
+ { ANY_LANG, "https://www.youtube.com/watch?v=EULXRMR4PyE" },
+ { NULL, NULL }
+};
+
+static VideoLink_t trainTutorial[] = {
+ { "en", "https://www.youtube.com/watch?v=VdMdL2qyZ6s" },
+ { ANY_LANG, "https://www.youtube.com/watch?v=VdMdL2qyZ6s" },
+ { NULL, NULL }
+};
+
+static VideoLink_t truckTutorial[] = {
+ { "en", "https://www.youtube.com/watch?v=B-CL-XFGNtw" },
+ { ANY_LANG, "https://www.youtube.com/watch?v=B-CL-XFGNtw" },
+ { NULL, NULL }
+};
+
+static VideoLink_t shipTutorial[] = {
+ { "en", "https://www.youtube.com/watch?v=a5JHlWtIg3A" },
+ { ANY_LANG, "https://www.youtube.com/watch?v=a5JHlWtIg3A" },
+ { NULL, NULL }
+};
+
+static VideoLink_t cargoTutorial[] = {
+ { "en", "https://www.youtube.com/watch?v=GwjiQYsu3xg" },
+ { ANY_LANG, "https://www.youtube.com/watch?v=GwjiQYsu3xg" },
+ { NULL, NULL }
+};
+
+void OpenExternTutorialVideo(VideoLink_t *tutorial)
+{
+ const char *link = NULL;
+ for (; tutorial->lang != NULL; tutorial++) {
+ if (strcmp(tutorial->lang, _current_language->isocode) == 0) {
+ link = tutorial->video;
+ break;
+ }
+ if (strcmp(tutorial->lang, ANY_LANG) == 0) {
+ link = tutorial->video;
+ break;
+ }
+ }
+ if (!link) {
+ return;
+ }
+#ifdef __ANDROID__
+ SDL_ANDROID_OpenExternalWebBrowser(link);
+#else
+ char cmd[PATH_MAX] =
+#ifdef WIN32
+ "start ";
+#else
+ "xdg-open ";
+#endif
+ strcat(cmd, link);
+ system(cmd);
+#endif
+}
+
+static const NWidgetPart _nested_tutorial_widgets[] = {
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_CLOSEBOX, COLOUR_GREY),
+ NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_TUTORIAL_WINDOW_TITLE, STR_TUTORIAL_WINDOW_TOOLTIP),
+ EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0),
+ NWidget(NWID_VERTICAL), SetPIP(16, 2, 6),
+ // TODO: make different button IDs
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_BUS), SetMinimalSize(120, 20), SetDataTip(STR_TUTORIAL_ROADS_AND_STATIONS, STR_TUTORIAL_ROADS_AND_STATIONS), SetFill(1, 1),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetFill(1, 0),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_TRAIN), SetMinimalSize(120, 20), SetDataTip(STR_TUTORIAL_RAILWAYS, STR_TUTORIAL_RAILWAYS), SetFill(1, 1),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetFill(1, 0),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_TRUCK), SetMinimalSize(120, 20), SetDataTip(STR_TUTORIAL_ROAD_VEHICLES, STR_TUTORIAL_ROAD_VEHICLES), SetFill(1, 1),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetFill(1, 0),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_SHIP), SetMinimalSize(120, 20), SetDataTip(STR_TUTORIAL_SHIPS, STR_TUTORIAL_SHIPS), SetFill(1, 1),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetFill(1, 0),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_FACILALL), SetMinimalSize(120, 20), SetDataTip(STR_TUTORIAL_CARGO, STR_TUTORIAL_CARGO), SetFill(1, 1),
+ EndContainer(),
+ NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0),
+ EndContainer(),
+ EndContainer(),
+};
+
+static WindowDesc _tutorial_desc(
+ WDP_CENTER, NULL, 0, 0,
+ WC_GAME_OPTIONS, WC_NONE,
+ 0,
+ _nested_tutorial_widgets, lengthof(_nested_tutorial_widgets)
+);
+
+
+struct TutorialWindow : public Window {
+ VideoLink_t *video;
+ int counter;
+
+ TutorialWindow() : Window(&_tutorial_desc)
+ {
+ this->InitNested(WN_GAME_OPTIONS_ABOUT);
+ this->video = NULL;
+ this->counter = 0;
+ }
+
+ virtual void OnClick(Point pt, int widget, int click_count)
+ {
+ showTutorialMainMenu = false;
+ this->counter = 5;
+ this->LowerWidget(widget);
+ this->SetDirty();
+ switch (widget) {
+ case WID_STL_BUS:
+ this->video = busTutorial;
+ break;
+ case WID_STL_TRUCK:
+ this->video = truckTutorial;
+ break;
+ case WID_STL_TRAIN:
+ this->video = trainTutorial;
+ break;
+ case WID_STL_SHIP:
+ this->video = shipTutorial;
+ break;
+ //case WID_STL_AIRPLANE:
+ // this->video = planeTutorial;
+ // break;
+ case WID_STL_FACILALL:
+ this->video = cargoTutorial;
+ break;
+ }
+ }
+
+ virtual void OnTick()
+ {
+ // Open video with delay, to make visual feedback of button pressing,
+ // because youtube app freezes a screen for a second before launching.
+ if (this->counter > 0) {
+ this->counter--;
+ if (this->counter == 1) {
+ this->RaiseWidget(WID_STL_BUS);
+ this->RaiseWidget(WID_STL_TRUCK);
+ this->RaiseWidget(WID_STL_TRAIN);
+ this->RaiseWidget(WID_STL_SHIP);
+ //this->RaiseWidget(WID_STL_AIRPLANE);
+ this->RaiseWidget(WID_STL_FACILALL);
+ this->SetDirty();
+ }
+ if (this->counter == 0) {
+ if (this->video) {
+ OpenExternTutorialVideo(this->video);
+ this->video = NULL;
+ }
+ }
+ }
+ }
+};
+
+void ShowTutorialWindow()
+{
+ DeleteWindowByClass(WC_GAME_OPTIONS);
+ new TutorialWindow();
+}
+
+void ShowTutorialWindowOnceAfterInstall()
+{
+ static const char * TUTORIAL_SHOWN_FLAG = ".tutorial-shown-3.flag";
+
+ FILE *ff = fopen(TUTORIAL_SHOWN_FLAG, "r");
+ if (ff) {
+ fclose(ff);
+ if (!showTutorialMainMenu)
+ return;
+ }
+ showTutorialMainMenu = true;
+ ff = fopen(TUTORIAL_SHOWN_FLAG, "w");
+ fprintf(ff, "Tutorial shown");
+ fclose(ff);
+ ShowTutorialWindow();
+}
diff --git a/src/tutorial_gui.h b/src/tutorial_gui.h
new file mode 100644
index 0000000000..04840ee2c6
--- /dev/null
+++ b/src/tutorial_gui.h
@@ -0,0 +1,18 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/** @file tutorial_gui.h Links to video tutorials. */
+
+#ifndef TUTORIAL_GUI_H
+#define TUTORIAL_GUI_H
+
+void ShowTutorialWindow();
+void ShowTutorialWindowOnceAfterInstall();
+
+#endif /* TUTORIAL_GUI_H */
diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp
index 8ea8cda4c8..0d2ad5e8dc 100644
--- a/src/vehicle_gui.cpp
+++ b/src/vehicle_gui.cpp
@@ -330,7 +330,7 @@ typedef SmallVector SubtypeList; ///< List of refit subtypes as
*/
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;
+ uint y = Center(r.top, delta);
uint current = 0;
bool rtl = _current_text_dir == TD_RTL;
@@ -660,16 +660,17 @@ struct RefitWindow : public Window {
{
switch (widget) {
case WID_VR_MATRIX:
- resize->height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM;
- size->height = resize->height * 8;
+ resize->height = GetMinSizing(NWST_STEP, WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM);
+ size->height = resize->height * 5;
break;
case WID_VR_VEHICLE_PANEL_DISPLAY:
- size->height = ScaleGUITrad(GetVehicleHeight(Vehicle::Get(this->window_number)->type));
+ size->height = max((int)GetMinSizing(NWST_STEP), ScaleGUITrad(GetVehicleHeight(Vehicle::Get(this->window_number)->type)));
break;
case WID_VR_INFO:
size->width = WD_FRAMERECT_LEFT + this->information_width + WD_FRAMERECT_RIGHT;
+ size->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
break;
}
}
@@ -732,7 +733,7 @@ struct RefitWindow : public Window {
case WID_VR_VEHICLE_PANEL_DISPLAY: {
Vehicle *v = Vehicle::Get(this->window_number);
DrawVehicleImage(v, this->sprite_left + WD_FRAMERECT_LEFT, this->sprite_right - WD_FRAMERECT_RIGHT,
- r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, EIT_IN_DETAILS, this->hscroll != NULL ? this->hscroll->GetPosition() : 0);
+ r.top, INVALID_VEHICLE, EIT_IN_DETAILS, this->hscroll != NULL ? this->hscroll->GetPosition() : 0);
/* Highlight selected vehicles. */
if (this->order != INVALID_VEH_ORDER_ID) break;
diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp
index 3668f86020..e7770fb976 100644
--- a/src/video/sdl_v.cpp
+++ b/src/video/sdl_v.cpp
@@ -23,8 +23,14 @@
#include "../core/random_func.hpp"
#include "../core/math_func.hpp"
#include "../fileio_func.h"
+#include "../settings_type.h"
+#include "../tilehighlight_func.h"
+#include "../viewport_func.h"
#include "sdl_v.h"
#include
+#ifdef __ANDROID__
+#include
+#endif
#include "../safeguards.h"
@@ -150,6 +156,16 @@ static void DrawSurfaceToScreen()
{
int n = _num_dirty_rects;
if (n == 0) return;
+ static int frameskip = 0;
+
+#ifdef __ANDROID__
+ if (_fast_forward) {
+ frameskip++;
+ if (frameskip < 5)
+ return;
+ frameskip = 0;
+ }
+#endif
_num_dirty_rects = 0;
if (n > MAX_DIRTY_RECTS) {
@@ -510,6 +526,8 @@ static uint ConvertSdlKeyIntoMy(SDL_keysym *sym, WChar *character)
if (sym->scancode == 49) key = WKC_BACKSPACE;
#elif defined(__sgi__)
if (sym->scancode == 22) key = WKC_BACKQUOTE;
+#elif defined(__ANDROID__)
+ if (sym->scancode == SDLK_BACKQUOTE) key = WKC_BACKQUOTE;
#else
if (sym->scancode == 49) key = WKC_BACKQUOTE;
#endif
@@ -533,7 +551,9 @@ int VideoDriver_SDL::PollEvent()
switch (ev.type) {
case SDL_MOUSEMOTION:
if (_cursor.UpdateCursorPosition(ev.motion.x, ev.motion.y, true)) {
+#ifndef __ANDROID__ // No mouse warping on Android, mouse strictly follows finger
SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y);
+#endif
}
HandleMouseEvents();
break;
@@ -551,6 +571,13 @@ int VideoDriver_SDL::PollEvent()
case SDL_BUTTON_RIGHT:
_right_button_down = true;
_right_button_clicked = true;
+ _right_button_down_pos.x = ev.motion.x;
+ _right_button_down_pos.y = ev.motion.y;
+#ifdef __ANDROID__
+ // Right button click on Android - cancel whatever action we were doing
+ ResetObjectToPlace();
+ ToolbarSelectLastTool();
+#endif
break;
case SDL_BUTTON_WHEELUP: _cursor.wheel--; break;
@@ -569,12 +596,20 @@ int VideoDriver_SDL::PollEvent()
} else if (ev.button.button == SDL_BUTTON_LEFT) {
_left_button_down = false;
_left_button_clicked = false;
+#ifdef __ANDROID__
+ if (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_RMASK) {
+ // Two-finger click - hacky way to determine if the right mouse button is already pressed without processing the left button event
+ // Cancel whatever action we were doing, to allow two finger scrolling
+ ResetObjectToPlace();
+ ToolbarSelectLastTool();
+ }
+#endif
} else if (ev.button.button == SDL_BUTTON_RIGHT) {
_right_button_down = false;
}
HandleMouseEvents();
break;
-
+#ifndef __ANDROID__
case SDL_ACTIVEEVENT:
if (!(ev.active.state & SDL_APPMOUSEFOCUS)) break;
@@ -585,7 +620,7 @@ int VideoDriver_SDL::PollEvent()
_cursor.in_window = false;
}
break;
-
+#endif /* not __ANDROID__ */
case SDL_QUIT:
HandleExitGameRequest();
break;
@@ -598,15 +633,30 @@ int VideoDriver_SDL::PollEvent()
WChar character;
uint keycode = ConvertSdlKeyIntoMy(&ev.key.keysym, &character);
HandleKeypress(keycode, character);
+#ifdef __ANDROID__
+ if (ev.key.keysym.sym == SDLK_LCTRL || ev.key.keysym.sym == SDLK_RCTRL)
+ _ctrl_pressed = true;
+ if (ev.key.keysym.sym == SDLK_LSHIFT || ev.key.keysym.sym == SDLK_RSHIFT)
+ _shift_pressed = true;
+#endif
}
break;
-
+ case SDL_KEYUP:
+#ifdef __ANDROID__
+ if (ev.key.keysym.sym == SDLK_LCTRL || ev.key.keysym.sym == SDLK_RCTRL)
+ _ctrl_pressed = false;
+ if (ev.key.keysym.sym == SDLK_LSHIFT || ev.key.keysym.sym == SDLK_RSHIFT)
+ _shift_pressed = false;
+#endif
+ break;
+#ifndef __ANDROID__
case SDL_VIDEORESIZE: {
int w = max(ev.resize.w, 64);
int h = max(ev.resize.h, 64);
CreateMainSurface(w, h);
break;
}
+#endif /* not __ANDROID__ */
case SDL_VIDEOEXPOSE: {
/* Force a redraw of the entire screen. Note
* that SDL 1.2 seems to do this automatically
@@ -638,6 +688,9 @@ const char *VideoDriver_SDL::Start(const char * const *parm)
SetupKeyboard();
_draw_threaded = GetDriverParam(parm, "no_threads") == NULL && GetDriverParam(parm, "no_thread") == NULL;
+#ifdef __ANDROID__
+ _draw_threaded = false;
+#endif
return NULL;
}
@@ -728,8 +781,10 @@ void VideoDriver_SDL::MainLoop()
bool old_ctrl_pressed = _ctrl_pressed;
+#ifndef __ANDROID__
_ctrl_pressed = !!(mod & KMOD_CTRL);
_shift_pressed = !!(mod & KMOD_SHIFT);
+#endif
/* determine which directional keys are down */
_dirkeys =
diff --git a/src/viewport.cpp b/src/viewport.cpp
index a1bb2c81d1..e404b8db09 100644
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -84,6 +84,7 @@
#include "linkgraph/linkgraph_gui.h"
#include "viewport_sprite_sorter.h"
#include "bridge_map.h"
+#include "build_confirmation_func.h"
#include