diff --git a/.ottdrev b/.ottdrev
new file mode 100644
index 0000000000..fdb7582eca
--- /dev/null
+++ b/.ottdrev
@@ -0,0 +1 @@
+1.8.0 28002 0 1.8.0
diff --git a/android-extract-strings.sh b/android-extract-strings.sh
new file mode 100755
index 0000000000..6f0d4a8edb
--- /dev/null
+++ b/android-extract-strings.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+mkdir -p ../translations/lang
+git diff 1.7/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..7a9d540c25
--- /dev/null
+++ b/android-store-strings.sh
@@ -0,0 +1,14 @@
+#!/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
+ [ "$name" = "STR_ABOUT_MENU_SEPARATOR" ] && continue
+ { 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 2bcc643fba..11896f31b3 100644
--- a/config.lib
+++ b/config.lib
@@ -1099,7 +1099,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"
@@ -1823,14 +1823,14 @@ make_cflags_and_ldflags() {
CFLAGS="$CFLAGS -DWITH_XAUDIO2"
fi
- if [ -n "$libtimidity_config" ]; then
+ if [ -n "$libtimidity" ]; then
CFLAGS="$CFLAGS -DLIBTIMIDITY"
- CFLAGS="$CFLAGS `$libtimidity_config --cflags | tr '\n\r' ' '`"
+ CFLAGS="$CFLAGS `$libtimidity --cflags | tr '\n\r' ' '`"
if [ "$enable_static" != "0" ]; then
- LIBS="$LIBS `$libtimidity_config --libs --static | tr '\n\r' ' '`"
+ LIBS="$LIBS `$libtimidity --libs --static | tr '\n\r' ' '`"
else
- LIBS="$LIBS `$libtimidity_config --libs | tr '\n\r' ' '`"
+ LIBS="$LIBS `$libtimidity --libs | tr '\n\r' ' '`"
fi
fi
@@ -2772,7 +2772,7 @@ detect_lzo2() {
}
detect_libtimidity() {
- detect_pkg_config "$with_libtimidity" "libtimidity" "libtimidity_config" "0.1" "1"
+ detect_pkg_config "$with_libtimidity" "libtimidity" "libtimidity" "0.1" "1"
}
detect_fluidsynth() {
diff --git a/findversion.sh b/findversion.sh
index 95a041bac0..a744c6fba8 100755
--- a/findversion.sh
+++ b/findversion.sh
@@ -59,7 +59,11 @@ ROOT_DIR=`pwd`
# Determine if we are using a modified version
# Assume the dir is not modified
MODIFIED="0"
-if [ -d "$ROOT_DIR/.git" ]; then
+if [ -f "$ROOT_DIR/.ottdrev" ]; then
+ # We are an exported source bundle
+ cat $ROOT_DIR/.ottdrev
+ exit
+elif [ -d "$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
@@ -93,11 +97,6 @@ if [ -d "$ROOT_DIR/.git" ]; then
ISTAG="0"
ISSTABLETAG="0"
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"
diff --git a/projects/openttd_vs142.vcxproj b/projects/openttd_vs142.vcxproj
index 5999d00d6c..997ec829b5 100644
--- a/projects/openttd_vs142.vcxproj
+++ b/projects/openttd_vs142.vcxproj
@@ -676,6 +676,7 @@
+
diff --git a/projects/openttd_vs142.vcxproj.filters b/projects/openttd_vs142.vcxproj.filters
index 751e54887c..a301b9ddcc 100644
--- a/projects/openttd_vs142.vcxproj.filters
+++ b/projects/openttd_vs142.vcxproj.filters
@@ -1116,6 +1116,9 @@
Header Files
+
+ Header Files
+
Header Files
diff --git a/source.list b/source.list
index ce6c4cf150..c9ba04c0ee 100644
--- a/source.list
+++ b/source.list
@@ -90,6 +90,7 @@ tgp.cpp
tile_map.cpp
tilearea.cpp
townname.cpp
+tutorial_gui.cpp
#if WIN32
#else
#if OS2
@@ -137,6 +138,7 @@ base_media_func.h
base_station_base.h
bmp.h
bridge.h
+build_confirmation_func.h
cargo_type.h
cargoaction.h
cargomonitor.h
@@ -363,6 +365,7 @@ tilehighlight_func.h
tilehighlight_type.h
tilematrix_type.hpp
timetable.h
+toolbar_type.h
toolbar_gui.h
town.h
town_type.h
@@ -452,6 +455,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
@@ -913,6 +917,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
diff --git a/src/3rdparty/squirrel/squirrel/sqobject.h b/src/3rdparty/squirrel/squirrel/sqobject.h
index d71e515a8d..0b4576f3d4 100644
--- a/src/3rdparty/squirrel/squirrel/sqobject.h
+++ b/src/3rdparty/squirrel/squirrel/sqobject.h
@@ -2,6 +2,7 @@
#ifndef _SQOBJECT_H_
#define _SQOBJECT_H_
+#include
#include "squtils.h"
#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp
index 73806da15e..4a949267fd 100644
--- a/src/ai/ai_gui.cpp
+++ b/src/ai/ai_gui.cpp
@@ -110,7 +110,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;
@@ -123,16 +123,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;
}
}
@@ -349,7 +349,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;
@@ -371,7 +371,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;
@@ -416,7 +415,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;
}
}
@@ -674,39 +673,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(),
};
@@ -771,12 +772,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;
@@ -830,14 +831,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;
@@ -849,7 +850,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;
}
@@ -1101,7 +1102,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;
}
}
@@ -1117,6 +1118,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);
@@ -1137,7 +1140,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. */
@@ -1216,7 +1219,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 243f91b247..efd9d1b97a 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"
@@ -73,12 +75,13 @@ struct BuildAirToolbarWindow : Window {
BuildAirToolbarWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
{
this->InitNested(window_number);
- if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
+ if (_settings_client.gui.link_terraform_toolbar || _settings_client.gui.compact_vertical_toolbar) ShowTerraformToolbar();
this->last_user_action = WIDGET_LIST_END;
}
~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 eae0a378eb..7f18efc862 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_LEFT_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;
}
@@ -601,30 +604,26 @@ static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
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(),
- NWidget(WWT_PANEL, COLOUR_GREY), 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(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(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(),
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 +659,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 768691f080..b9122fafad 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..7d9d044af5
--- /dev/null
+++ b/src/build_confirmation_gui.cpp
@@ -0,0 +1,310 @@
+/* $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 "error.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();
+ DeleteWindowByClass(WC_BUILD_BRIDGE);
+ //ClearErrorMessages();
+ Window *w = FindWindowById(WC_ERRMSG, 0);
+ if (w != NULL) delete w;
+ }
+ 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)) {
+ if (_settings_client.gui.windows_titlebars || !_left_button_down) {
+ 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 0ac23cfde6..631dff67ce 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),
@@ -1407,6 +1413,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 70258aaa1d..904353175d 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"
@@ -555,11 +558,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 651b216a56..3426451f58 100644
--- a/src/company_cmd.cpp
+++ b/src/company_cmd.cpp
@@ -911,7 +911,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 a3885ec960..e526acb3e7 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 "sortlist_type.h"
@@ -219,7 +220,7 @@ static const NWidgetPart _nested_company_finances_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_CF_CAPTION), SetDataTip(STR_FINANCES_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_IMGBTN, COLOUR_GREY, WID_CF_TOGGLE_SIZE), SetDataTip(SPR_LARGE_SMALL_WINDOW, STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW),
+ //NWidget(WWT_IMGBTN, COLOUR_GREY, WID_CF_TOGGLE_SIZE), SetDataTip(SPR_LARGE_SMALL_WINDOW, STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
@@ -528,7 +529,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
@@ -1158,7 +1159,7 @@ static const NWidgetPart _nested_select_company_manager_face_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_SCMF_CAPTION), SetDataTip(STR_FACE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_IMGBTN, COLOUR_GREY, WID_SCMF_TOGGLE_LARGE_SMALL), SetDataTip(SPR_LARGE_SMALL_WINDOW, STR_FACE_ADVANCED_TOOLTIP),
+ //NWidget(WWT_IMGBTN, COLOUR_GREY, WID_SCMF_TOGGLE_LARGE_SMALL), SetDataTip(SPR_LARGE_SMALL_WINDOW, STR_FACE_ADVANCED_TOOLTIP),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_SCMF_SELECT_FACE),
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
@@ -1181,102 +1182,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),
@@ -1326,7 +1337,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);
}
}
@@ -1376,6 +1387,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++) {
@@ -1519,12 +1534,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:
@@ -1536,7 +1551,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 732ace6a2b..3edf53b433 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)
{
@@ -1959,6 +1973,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 13df98db34..5c140122a6 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
#if defined(_WIN32)
#include "os/windows/win32.h"
@@ -111,6 +114,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 39accd65f1..22e14c7ad6 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(),
@@ -331,7 +331,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;
}
@@ -341,26 +341,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);
}
}
@@ -400,7 +402,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];
@@ -680,6 +682,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 e2224dfa28..87a0342efb 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"
@@ -100,11 +101,12 @@ struct BuildDocksToolbarWindow : Window {
this->last_clicked_widget = WID_DT_INVALID;
this->InitNested(window_number);
this->OnInvalidateData();
- if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
+ if (_settings_client.gui.link_terraform_toolbar || _settings_client.gui.compact_vertical_toolbar) ShowTerraformToolbar();
}
~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,22 @@ 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_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));
+ VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_STATION);
break;
}
+ case WID_DT_DEPOT: // Build depot button
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 +206,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 +241,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 +397,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 +423,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 +436,7 @@ static WindowDesc _build_docks_scen_toolbar_desc(
*/
Window *ShowBuildDocksScenToolbar()
{
+ DeleteToolbarLinkedWindows();
return AllocateWindowDescFront(&_build_docks_scen_toolbar_desc, TRANSPORT_WATER);
}
@@ -556,10 +607,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 32c6b85862..fc2759bd2c 100644
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -1705,7 +1705,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/error_gui.cpp b/src/error_gui.cpp
index 1c59b7e8d0..90f1698f1b 100644
--- a/src/error_gui.cpp
+++ b/src/error_gui.cpp
@@ -37,7 +37,10 @@ static const NWidgetPart _nested_errmsg_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_RED, WID_EM_CAPTION), SetDataTip(STR_ERROR_MESSAGE_CAPTION, STR_NULL),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_RED),
- NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetPadding(0, 2, 0, 2), SetMinimalSize(236, 32),
+ NWidget(WWT_TEXT, COLOUR_RED), SetDataTip(STR_EMPTY, STR_NULL), // Add some borders
+ NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetPadding(4, 4, 4, 4), SetMinimalSize(236, 32),
+ NWidget(WWT_TEXT, COLOUR_RED), SetDataTip(STR_EMPTY, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_RED, WID_EM_CLOSE), SetPadding(4, 4, 4, 4), SetDataTip(STR_BUTTON_OK, STR_NULL),
EndContainer(),
};
@@ -54,10 +57,13 @@ static const NWidgetPart _nested_errmsg_face_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_RED, WID_EM_CAPTION), SetDataTip(STR_ERROR_MESSAGE_CAPTION_OTHER_COMPANY, STR_NULL),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_RED),
+ NWidget(WWT_TEXT, COLOUR_RED), SetDataTip(STR_EMPTY, STR_NULL), // Add some borders
NWidget(NWID_HORIZONTAL), SetPIP(2, 1, 2),
- NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_FACE), SetMinimalSize(92, 119), SetFill(0, 1), SetPadding(2, 0, 1, 0),
- NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetFill(0, 1), SetMinimalSize(238, 123),
+ NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_FACE), SetMinimalSize(92, 119), SetFill(0, 1), SetPadding(4, 4, 4, 4),
+ NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetFill(0, 1), SetMinimalSize(238, 123), SetPadding(4, 4, 4, 4),
EndContainer(),
+ NWidget(WWT_TEXT, COLOUR_RED), SetDataTip(STR_EMPTY, STR_NULL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_RED, WID_EM_CLOSE), SetPadding(4, 4, 4, 4), SetDataTip(STR_BUTTON_OK, STR_NULL),
EndContainer(),
};
@@ -320,6 +326,18 @@ public:
return ES_HANDLED;
}
+ virtual void OnClick(Point pt, int widget, int click_count)
+ {
+ switch (widget) {
+ case WID_EM_CLOSE:
+ delete this;
+ break;
+
+ default:
+ break;
+ }
+ }
+
/**
* Check whether the currently shown error message was critical or not.
* @return True iff the message was critical.
diff --git a/src/fileio.cpp b/src/fileio.cpp
index 0e6d86e3c7..e5e2875b87 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);
@@ -1279,6 +1283,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 58242e71e2..55ff76e6bd 100644
--- a/src/fios_gui.cpp
+++ b/src/fios_gui.cpp
@@ -36,11 +36,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";
/**
@@ -121,6 +125,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(),
@@ -219,7 +226,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(),
@@ -357,6 +364,7 @@ public:
this->LowerWidget(WID_SL_DRIVES_DIRECTORIES_LIST);
this->querystrings[WID_SL_FILTER] = &this->filter_editbox;
this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
+ if (this->fop == SLO_SAVE) 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. */
@@ -450,7 +458,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;
}
@@ -561,8 +569,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: {
@@ -719,6 +727,27 @@ 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
+ _file_to_saveload.SetMode(FIOS_TYPE_FILE);
+ _file_to_saveload.SetName(savePath);
+ _file_to_saveload.SetTitle("Network Save");
+ _switch_mode = SM_LOAD_GAME;
+ break;
+ }
}
}
diff --git a/src/fontcache.cpp b/src/fontcache.cpp
index 2811f17989..3677441a2b 100644
--- a/src/fontcache.cpp
+++ b/src/fontcache.cpp
@@ -398,7 +398,7 @@ static void LoadFreeTypeFont(FontSize fs)
return;
found_face:
- new FreeTypeFontCache(fs, face, settings->size);
+ new FreeTypeFontCache(fs, face, RescaleFrom854x480(settings->size));
}
@@ -479,7 +479,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 4279d60f3b..39e7b2eca9 100644
--- a/src/fontdetection.cpp
+++ b/src/fontdetection.cpp
@@ -663,7 +663,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. */
@@ -676,6 +677,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];
@@ -685,28 +687,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;
}
}
@@ -714,6 +720,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 b22ba5287e..76aa7a5452 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,47 +64,43 @@ 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),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
+ NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_LAND_GENERATOR, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TERRAIN_TYPE, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_VARIETY, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_SEA_LAKES, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TREE_PLACER, STR_NULL), SetFill(1, 1),
- NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BORDER_TYPE, STR_NULL), SetFill(1, 1),
EndContainer(),
/* Widgets at the right of the labels. */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
/* Mapsize X * Y. */
- NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0),
- NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
- NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(1, 1),
- NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
- EndContainer(),
+ NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
+ NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_LANDSCAPE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TERRAIN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_VARIETY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_WATER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TREE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
- NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_BORDERS_RANDOM), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
EndContainer(),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
@@ -115,6 +112,7 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SMOOTHNESS, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1),
+ NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BORDER_TYPE, STR_NULL), SetFill(1, 1),
EndContainer(),
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
/* Max. heightlevel. */
@@ -138,6 +136,7 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_SMOOTHNESS_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
+ NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_BORDERS_RANDOM), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
EndContainer(),
EndContainer(),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 0), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetFill(1, 1),
@@ -146,30 +145,12 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(0, 4),
/* Map borders buttons for each edge. */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 0, 10),
- NWidget(NWID_HORIZONTAL), SetPIP(0, 0, 3),
- NWidget(NWID_SPACER), SetFill(1, 1),
- NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NORTHWEST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
- EndContainer(),
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NW), SetDataTip(STR_JUST_STRING, STR_MAPGEN_NORTHWEST), SetFill(1, 1),
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NE), SetDataTip(STR_JUST_STRING, STR_MAPGEN_NORTHEAST), SetFill(1, 1),
- NWidget(NWID_HORIZONTAL), SetPIP(3, 0, 0),
- NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NORTHEAST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
- NWidget(NWID_SPACER), SetFill(1, 1),
- EndContainer(),
- EndContainer(),
- NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 0, 10),
- NWidget(NWID_HORIZONTAL), SetPIP(0, 0, 3),
- NWidget(NWID_SPACER), SetFill(1, 1),
- NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SOUTHWEST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
- EndContainer(),
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SW), SetDataTip(STR_JUST_STRING, STR_MAPGEN_SOUTHWEST), SetFill(1, 1),
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SE), SetDataTip(STR_JUST_STRING, STR_MAPGEN_SOUTHEAST), SetFill(1, 1),
- NWidget(NWID_HORIZONTAL), SetPIP(3, 0, 0),
- NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SOUTHEAST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
- 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 +439,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 +450,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 +475,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 +931,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 +1052,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 7a6b827b7a..5ba8f0dc62 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -35,14 +35,19 @@ 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;
+bool _restart_game;
GameMode _game_mode;
SwitchMode _switch_mode; ///< The next mainloop command.
PauseModeByte _pause_mode;
@@ -849,6 +854,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.
@@ -1200,6 +1249,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()
@@ -1712,3 +1763,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 9f7cb9153d..4486874462 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 {
@@ -185,6 +192,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, uint8 threshold = 128);
diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp
index 39df8ab6e2..e36f64e760 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);
@@ -472,7 +473,7 @@ protected:
format_str_y_axis(format_str_y_axis)
{
SetWindowDirty(WC_GRAPH_LEGEND, 0);
- this->num_vert_lines = 24;
+ this->num_vert_lines = 12;
this->graph_widget = widget;
}
@@ -631,7 +632,6 @@ static const NWidgetPart _nested_operating_profit_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GRAPH_OPERATING_PROFIT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -641,6 +641,7 @@ static const NWidgetPart _nested_operating_profit_widgets[] = {
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CV_GRAPH), SetMinimalSize(576, 160), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), SetSizingType(NWST_STEP),
NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CV_RESIZE),
EndContainer(),
EndContainer(),
@@ -682,7 +683,6 @@ static const NWidgetPart _nested_income_graph_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GRAPH_INCOME_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -692,6 +692,7 @@ static const NWidgetPart _nested_income_graph_widgets[] = {
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), SetSizingType(NWST_STEP),
NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CV_RESIZE),
EndContainer(),
EndContainer(),
@@ -731,7 +732,6 @@ static const NWidgetPart _nested_delivered_cargo_graph_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GRAPH_CARGO_DELIVERED_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -741,6 +741,7 @@ static const NWidgetPart _nested_delivered_cargo_graph_widgets[] = {
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), SetSizingType(NWST_STEP),
NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CV_RESIZE),
EndContainer(),
EndContainer(),
@@ -786,8 +787,6 @@ static const NWidgetPart _nested_performance_history_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_PHG_DETAILED_PERFORMANCE), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_PERFORMANCE_DETAIL_KEY, STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_PHG_KEY), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -797,6 +796,8 @@ static const NWidgetPart _nested_performance_history_widgets[] = {
NWidget(WWT_EMPTY, COLOUR_GREY, WID_PHG_GRAPH), SetMinimalSize(576, 224), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_PHG_DETAILED_PERFORMANCE), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_PERFORMANCE_DETAIL_KEY, STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP), SetSizingType(NWST_STEP),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_PHG_KEY), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), SetSizingType(NWST_STEP),
NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_PHG_RESIZE),
EndContainer(),
EndContainer(),
@@ -836,7 +837,6 @@ static const NWidgetPart _nested_company_value_graph_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GRAPH_COMPANY_VALUES_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -846,6 +846,7 @@ static const NWidgetPart _nested_company_value_graph_widgets[] = {
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CV_GRAPH), SetMinimalSize(576, 224), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), SetSizingType(NWST_STEP),
NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CV_RESIZE),
EndContainer(),
EndContainer(),
@@ -1127,6 +1128,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
/**
@@ -1173,8 +1175,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;
@@ -1187,7 +1188,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);
@@ -1220,6 +1221,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 b5f33ff52a..b9a5eabedc 100644
--- a/src/group_gui.cpp
+++ b/src/group_gui.cpp
@@ -48,8 +48,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),
@@ -74,7 +73,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(),
@@ -82,7 +81,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),
@@ -195,8 +194,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);
@@ -218,6 +218,7 @@ 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 +
@@ -241,7 +242,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;
@@ -367,7 +368,7 @@ 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;
+ size->height = (this->vli.vtype >= VEH_SHIP ? 3.5 : 7) * 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;
@@ -379,7 +380,7 @@ public:
max_icon_height += (FONT_HEIGHT_NORMAL * 3) + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
/* 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;
}
@@ -400,7 +401,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: {
diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp
index 78bf3f4a01..483094344e 100644
--- a/src/industry_gui.cpp
+++ b/src/industry_gui.cpp
@@ -261,7 +261,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)
@@ -278,8 +278,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;
/** The largest allowed minimum-width of the window, given in line heights */
static const int MAX_MINWIDTH_LINEHEIGHTS = 20;
@@ -403,6 +401,10 @@ public:
this->SetButtons();
}
+ ~BuildIndustryWindow() {
+ if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort();
+ }
+
virtual void OnInit()
{
this->SetupArrays();
@@ -417,8 +419,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;
@@ -499,20 +501,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) {
@@ -523,8 +527,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;
}
@@ -643,6 +647,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);
@@ -660,14 +679,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 */
@@ -704,6 +723,7 @@ public:
virtual void OnPlaceObjectAbort()
{
+ MoveAllHiddenWindowsBackToScreen();
this->RaiseButtons();
}
@@ -726,7 +746,7 @@ public:
void ShowBuildIndustryWindow()
{
if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return;
- if (BringWindowToFrontById(WC_BUILD_INDUSTRY, 0)) return;
+ DeleteToolbarLinkedWindows();
new BuildIndustryWindow();
}
@@ -869,7 +889,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;
}
@@ -884,8 +904,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 */
@@ -897,7 +919,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 */
@@ -945,12 +967,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--;
@@ -1166,7 +1190,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(),
@@ -1371,7 +1395,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;
@@ -1414,7 +1438,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 6767d8525d..ae0750ffd1 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..d0ac774027 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"
@@ -61,9 +62,13 @@ struct SelectGameWindow : public Window {
virtual void OnInit()
{
bool missing_sprites = _missing_extra_graphics > 0 && !IsReleasedVersion();
+ missing_sprites = false;
this->GetWidget(WID_SGI_BASESET_SELECTION)->SetDisplayedPlane(missing_sprites ? 0 : SZSP_NONE);
bool missing_lang = _current_language->missing >= _settings_client.gui.missing_strings_threshold && !IsReleasedVersion();
+#ifdef __ANDROID__
+ missing_lang = false;
+#endif
this->GetWidget(WID_SGI_TRANSLATION_SELECTION)->SetDisplayedPlane(missing_lang ? 0 : SZSP_NONE);
}
@@ -158,13 +163,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 +264,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 3fd6ff7dae..1a7376de1f 100644
--- a/src/lang/afrikaans.txt
+++ b/src/lang/afrikaans.txt
@@ -4950,3 +4950,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 2f658115c7..c95ca0aa87 100644
--- a/src/lang/arabic_egypt.txt
+++ b/src/lang/arabic_egypt.txt
@@ -4409,3 +4409,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 e5ea6a873b..d22da6cdec 100644
--- a/src/lang/basque.txt
+++ b/src/lang/basque.txt
@@ -4816,3 +4816,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 5560ef785b..9928e3254b 100644
--- a/src/lang/belarusian.txt
+++ b/src/lang/belarusian.txt
@@ -5457,3 +5457,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 660e9caa7c..7abcb2bf9e 100644
--- a/src/lang/brazilian_portuguese.txt
+++ b/src/lang/brazilian_portuguese.txt
@@ -5027,3 +5027,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 50229f6d0a..b6a787df7e 100644
--- a/src/lang/bulgarian.txt
+++ b/src/lang/bulgarian.txt
@@ -4879,3 +4879,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 fa6b17868e..d915b8a058 100644
--- a/src/lang/catalan.txt
+++ b/src/lang/catalan.txt
@@ -5068,3 +5068,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 f8d00dc199..5b434d912e 100644
--- a/src/lang/croatian.txt
+++ b/src/lang/croatian.txt
@@ -5201,3 +5201,41 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}Uputstva
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Prikaži legendu mape / opis simbola na mapi
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :Okomita alatna traka: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :Glavna alatna traka je podijeljena na dvije okomite alatne trake na rubovima ekrana
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR :Kompaktna okomita alatna traka: {STRING}
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR_HELPTEXT :Ne postoji dugme 'Izmijeni alatnu traku' u okomitoj alatnoj traci ali postoje pod-meniji
+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 :Potvrdi akcije: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :Prikaži dijalog potvrde pri gradnji cesta i stanica
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS :{BLACK}Naslovne trake
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT :{BLACK}Prikaži naslovne trake za sve prozore ili ih sakrij za uštedu prostora na ekranu
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS :Ukrasi prozora: {STRING}
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS_HELPTEXT :Ukrasi na rubovima prozora
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bita
+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 bita
+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 bita
+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 2e622b1422..ebb716e0f8 100644
--- a/src/lang/czech.txt
+++ b/src/lang/czech.txt
@@ -5214,3 +5214,41 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :{BLACK}Tutoriál
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Zobrazit legendu mapy / popis symbolů na mapě
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :Svislý panel nástrojů: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :Hlavní panel nástrojů je rozdělen ma dva svislé panely nástrojů na krajích obrazovky
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR :Kompaktní svislý panel nástrojů: {STRING}
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR_HELPTEXT :Žádné 'Přepnout panely nástrojů' tlačítko ve svislém panelu nástrojů, avšak více podmenu
+STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Velikost tlačítka
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Velikost všech prvků uživatelského rozhraní
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Veliksot fontu
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Velikost všech fontů ve hře
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :Potvrdit akce: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :Zobrazitr potvrzující okno při stavbě silnic a stanic
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS :{BLACK}Titulní pruhy
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT :{BLACK}Zobrazit titulní pruhy u všech oken, nebo je schovat pro ušetření místa na displeji
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS :Ozdoby oken: {STRING}
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS_HELPTEXT :Ozdoby na hranách oken
+STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bitů
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Nastavit hloubku videa na 8 bitů / pixel, tento mód podporuje animaci vody.
+STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bitů
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Nastavit hloubku videa na 16 bitů / pixel, vyžaduje restart, tento mód nepodporuje animaci vody.
+STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bitů
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Nastavit hloubku videa na 24 bitů / pixel, tento mód podporuje animaci vody.
+STR_TABLET_CLOSE_TOOLTIP :{BLACK}Zavřít všechna otevřená okna (vyjma připnutých)
+STR_TABLET_SHIFT_TOOLTIP :{BLACK}Podrž pro zobrazení odhadované ceny akce
+STR_TABLET_CTRL_TOOLTIP :{BLACK}Použij pro akce, které užívají klávesu"CTRL"
+STR_TUTORIAL_WINDOW_TITLE :{BLACK}Tutoriálová videa
+STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Otevřít video přehrávač ke shlédnutí tutoriálových videí
+STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Stavba silnic a stanic, koupě vozidel
+STR_TUTORIAL_RAILWAYS :{BLACK}Železnice a vlaky
+STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Silniční vozidla
+STR_TUTORIAL_SHIPS :{BLACK}Lodě a doky
+STR_TUTORIAL_CARGO :{BLACK}Typy nákladů
+STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Nahrát ze sítě
+STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Nahrát hru ze síťového uložiště
+STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Uložit na síť
+STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Zálohovat hru na síťové uložiště
diff --git a/src/lang/danish.txt b/src/lang/danish.txt
index 28b0778a00..99fe68921d 100644
--- a/src/lang/danish.txt
+++ b/src/lang/danish.txt
@@ -5068,3 +5068,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 b837036998..ea507ae5fc 100644
--- a/src/lang/dutch.txt
+++ b/src/lang/dutch.txt
@@ -5068,3 +5068,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 b4688d5e27..5cf249d458 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -405,11 +405,11 @@ STR_MAP_MENU_SIGN_LIST :Sign list
############ range for town menu starts
STR_TOWN_MENU_TOWN_DIRECTORY :Town directory
-STR_TOWN_MENU_FOUND_TOWN :Found town
-############ range ends here
-
-############ range for subsidies menu starts
STR_SUBSIDIES_MENU_SUBSIDIES :Subsidies
+STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY :Industry directory
+STR_INDUSTRY_MENU_INDUSTRY_CHAIN :Industry chains
+STR_INDUSTRY_MENU_FUND_NEW_INDUSTRY :Fund new industry
+STR_TOWN_MENU_FOUND_TOWN :Found town
############ range ends here
############ range for graph menu starts
@@ -427,12 +427,6 @@ STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING :Detailed perfor
STR_GRAPH_MENU_HIGHSCORE :Highscore table
############ range ends here
-############ range for industry menu starts
-STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY :Industry directory
-STR_INDUSTRY_MENU_INDUSTRY_CHAIN :Industry chains
-STR_INDUSTRY_MENU_FUND_NEW_INDUSTRY :Fund new industry
-############ range ends here
-
############ range for railway construction menu starts
STR_RAIL_MENU_RAILROAD_CONSTRUCTION :Railway construction
STR_RAIL_MENU_ELRAIL_CONSTRUCTION :Electrified railway construction
@@ -472,6 +466,7 @@ STR_NEWS_MENU_DELETE_ALL_MESSAGES :Delete all mess
############ 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
@@ -722,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
@@ -1226,6 +1222,26 @@ 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 :Vertical toolbar: {STRING2}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :Main toolbar is split into two vertical toolbars on the sides of the screen
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR :Compact vertical toolbar: {STRING2}
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR_HELPTEXT :No 'Switch toolbars' button in the vertical toolbar, but more sub-menus
+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 :Confirm actions: {STRING2}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :Show confirmation dialog when building roads and stations
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS :{BLACK}Title bars
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT :{BLACK}Show title bars for all windows, or hide them to save screen space
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS :Window decorations: {STRING2}
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS_HELPTEXT :Ornaments on window edges
+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}
@@ -2500,6 +2516,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
@@ -2770,6 +2793,14 @@ STR_FRAMETIME_CAPTION_AI :AI {NUM} {RAW_S
############ End of leave-in-this-order
+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
@@ -2788,6 +2819,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 4ca2bf1b59..d63f021e1d 100644
--- a/src/lang/english_AU.txt
+++ b/src/lang/english_AU.txt
@@ -4897,3 +4897,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 f2c0c8d321..9161686d9a 100644
--- a/src/lang/english_US.txt
+++ b/src/lang/english_US.txt
@@ -5068,3 +5068,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 c82ca05527..e367b6682c 100644
--- a/src/lang/esperanto.txt
+++ b/src/lang/esperanto.txt
@@ -4311,3 +4311,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 458c9e9e15..38c8b62600 100644
--- a/src/lang/estonian.txt
+++ b/src/lang/estonian.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/faroese.txt b/src/lang/faroese.txt
index b738ba9bbe..1b7b1a062c 100644
--- a/src/lang/faroese.txt
+++ b/src/lang/faroese.txt
@@ -4455,3 +4455,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 d8574e05e9..f6dc2c7054 100644
--- a/src/lang/finnish.txt
+++ b/src/lang/finnish.txt
@@ -5068,3 +5068,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 41755d2b40..adb212fc83 100644
--- a/src/lang/french.txt
+++ b/src/lang/french.txt
@@ -5068,3 +5068,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 f2096687f1..013a1f808f 100644
--- a/src/lang/gaelic.txt
+++ b/src/lang/gaelic.txt
@@ -5404,3 +5404,41 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :Oideachadh
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Seall treòir a' mhapa / tuairisgeulan air samhlaidhean a' mhapa
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :Bàr-inneal inghearach: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :Thèid am prìomh bhàr-inneal a sgoltadh 'na bhàraichean-inneal inghearach ri dà thaobh an sgrìn
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR :Bàr-inneal inghearach dùmhlaichte: {STRING}
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR_HELPTEXT :Cha bhi putan air a' bhàr-inneal inghearach gus leum a ghearradh gu bàr-inneal eile ach bidh barrachd fo-chlàran-taice aige
+STR_CONFIG_SETTING_BUTTON_SIZE :Meud nam putan
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :Meud aig a h-uile nì an eadar-aghaidh
+STR_CONFIG_SETTING_FONT_SIZE :Meud a' chrutha-chlò
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Am meud air gach cruth-clò a' gheama
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :Dearbhaich na gnìomhan: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :Seall còmhradh dearbhaidh le togail rathaidean is stèiseanan
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS :{BLACK}Bàraichean-tiotail
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT :{BLACK}Seall bàr-tiotail air gach uinneag no falaich iad gus rum a shàbhaladh air an sgrìn
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS :Sgeadachadh nan uinneagan: {STRING}
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS_HELPTEXT :Sgeadachadh air oirean nan uinneagan
+STR_CONFIG_SETTING_VIDEO_8BPP :8 biod
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :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 :16 biod
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :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 :24 biod
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :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 f301e71f1f..6c8e3bf181 100644
--- a/src/lang/galician.txt
+++ b/src/lang/galician.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/german.txt b/src/lang/german.txt
index 42490b2a39..1d7e4d8abb 100644
--- a/src/lang/german.txt
+++ b/src/lang/german.txt
@@ -5053,3 +5053,38 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :Tutorial
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Zeige Kartenlegende / Beschreibung der Kartensymbole
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :Vertikale Werkzeugsleiste: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :Hauptwerzeugleiste ist in zwei vertikale Leisten an den Bildschirmseiten aufgeteilt
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR :Kompakte vertikale Werkzeugleiste: {STRING}
+STR_CONFIG_SETTING_BUTTON_SIZE :Schaltflächengröße
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :Größe aller Elemente der Benutzeroberfläche
+STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Schriftgröße
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :Größe aller Schriftarten
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :Aktionen bestätigen: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :Zeige Bestätigungsdialog bei Straßen- und Haltenstellebau
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS :{BLACK}Titelleisten
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT :{BLACK}Zeige in allen Fenstern die Titelleiste an oder verbirg sie, um Platz zu sparen.
+STR_CONFIG_SETTING_VIDEO_8BPP :8 bit
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :Setzt die Farbtiefe auf 8 Bits per Pixel. Dieser Modus unterstützt Wasseranimation
+STR_CONFIG_SETTING_VIDEO_16BPP :16 bit
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Setzt die Farbtiefe auf 16 Bit per Pixel. Erfordert einen Neustart. Dieser Modus unterstützt keine Wasseranimation
+STR_CONFIG_SETTING_VIDEO_24BPP :24 bit
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :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 7ea02340e4..d12be9ad74 100644
--- a/src/lang/greek.txt
+++ b/src/lang/greek.txt
@@ -5185,3 +5185,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 05fb5fe1d7..f6d9a5eb82 100644
--- a/src/lang/hebrew.txt
+++ b/src/lang/hebrew.txt
@@ -5028,3 +5028,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 c66e0fdf4f..8ce4f446fb 100644
--- a/src/lang/hungarian.txt
+++ b/src/lang/hungarian.txt
@@ -5173,3 +5173,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 44f3b40598..bcb6dabb4c 100644
--- a/src/lang/icelandic.txt
+++ b/src/lang/icelandic.txt
@@ -4706,3 +4706,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 fe1991d835..214c0d1de4 100644
--- a/src/lang/indonesian.txt
+++ b/src/lang/indonesian.txt
@@ -5000,3 +5000,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 73a86c940b..112e9322da 100644
--- a/src/lang/irish.txt
+++ b/src/lang/irish.txt
@@ -4949,3 +4949,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 3f1014cbf8..c0c5a57871 100644
--- a/src/lang/italian.txt
+++ b/src/lang/italian.txt
@@ -5098,3 +5098,35 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :Istruzioni
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Mostra la legenda della mappa / descrizione dei simboli della mappa
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :Barra degli strumenti verticale: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :La barra degli strumenti è divisa in due barre verticali sui lati dello schermo
+STR_CONFIG_SETTING_BUTTON_SIZE :Dimensioni dei pulsanti
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :Dimensioni degli elementi dell'interfaccia
+STR_CONFIG_SETTING_FONT_SIZE :Dimensioni dei caratteri
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :Dimensioni dei caratteri nel gioco
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :Conferma: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :Mostra il dialogo di conferma durante la costruzione di strade e stazioni
+STR_CONFIG_SETTING_VIDEO_8BPP :8 bit
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :Imposta i colori a 8 bit per pixel. Questa modalità video supporta l'animazione dell'acqua
+STR_CONFIG_SETTING_VIDEO_16BPP :16 bit
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :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 :24 bit
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :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 d9291ebcd2..7ffe70b4c8 100644
--- a/src/lang/japanese.txt
+++ b/src/lang/japanese.txt
@@ -4952,3 +4952,41 @@ 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 :垂直ツールバー: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :メインツールバーをスクリーンの両脇に垂直に2つに分割します
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR :コンパクト垂直ツールバー: {STRING}
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR_HELPTEXT :ツールバー切り替えボタンを垂直ツールバーから無くすかわりに、サブメニューを増やします
+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 :アクションの確認: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :道路とステーションの建設時に確認のダイアログの表示
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS :{BLACK}タイトルバー
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT :{BLACK}ウィンドウのタイトルバーを表示するか、隠して画面のスペースを確保するか選べます
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS :ウィンドウの装飾: {STRING}
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS_HELPTEXT :ウィンドウの縁を装飾します
+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 755e3a8500..dea5b0600b 100644
--- a/src/lang/korean.txt
+++ b/src/lang/korean.txt
@@ -5069,3 +5069,41 @@ 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 :수직 작업창: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :메인 작업창이 두 개의 화면 양쪽 두개의 수직 작업창으로 나뉨
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR :소형 수직 작업창: {STRING}
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR_HELPTEXT :수직 작업창에 '작업창 바꾸기'메뉴가 없지만, 부 메뉴가 추가로 있음
+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 :명령 확인: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :도로와 정류장을 건설시 확인 팝업을 보임
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS :이름 창
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT :모든 창에 대해 이름을 보여주거나, 화면 공간 절약을 위해 이름을 가리기
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS :창 꾸미기: {STRING}
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS_HELPTEXT :창 모서리에 꾸밈 효과
+STR_CONFIG_SETTING_VIDEO_8BPP : {BLACK}8비트
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :그래픽 색상 심도를 픽셀당 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 :그래픽 색상 심도를 픽셀당 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 77ff4614cc..6c082af525 100644
--- a/src/lang/latin.txt
+++ b/src/lang/latin.txt
@@ -5345,3 +5345,35 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :Rudimentum
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Monstrare formulam graphicam / descriptionem tabulae
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :Arca instrumentorum directa: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :Si vis, arca instrumentorum prima dividitur in partes duas apud margines scrinii
+STR_CONFIG_SETTING_BUTTON_SIZE :Magnitudo globulorum
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :Magnitudo omnium elementorum interfaciei
+STR_CONFIG_SETTING_FONT_SIZE :Magnitudo fontis typographici
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :Magnitudo omnium fontium typographicorum in ludo
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :Confirmare: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :Monstrare confirmationem dum struuntur stationes viaeque
+STR_CONFIG_SETTING_VIDEO_8BPP :8bpp
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :Eligere modum coloris 8bpp; hic sinit colores aquae moventes
+STR_CONFIG_SETTING_VIDEO_16BPP :16bpp
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :Eligere modum coloris 16bpp (necesse erit programma exire et resumere); hic NON sinit colores aquae moventes
+STR_CONFIG_SETTING_VIDEO_24BPP :24bpp
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :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 9ab4dd48cc..56839cf783 100644
--- a/src/lang/latvian.txt
+++ b/src/lang/latvian.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/lithuanian.txt b/src/lang/lithuanian.txt
index f030ba2b4f..b04f991d6f 100644
--- a/src/lang/lithuanian.txt
+++ b/src/lang/lithuanian.txt
@@ -5489,3 +5489,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 b52b60dde5..58fb597536 100644
--- a/src/lang/luxembourgish.txt
+++ b/src/lang/luxembourgish.txt
@@ -5027,3 +5027,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 0a0c8eb026..1e0f962f3a 100644
--- a/src/lang/malay.txt
+++ b/src/lang/malay.txt
@@ -4620,3 +4620,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 1d63e6fb0e..6abb6441db 100644
--- a/src/lang/norwegian_bokmal.txt
+++ b/src/lang/norwegian_bokmal.txt
@@ -5073,3 +5073,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 757ffe25ee..937b4923e0 100644
--- a/src/lang/norwegian_nynorsk.txt
+++ b/src/lang/norwegian_nynorsk.txt
@@ -4865,3 +4865,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 637b5ab6ea..7d61bb7a44 100644
--- a/src/lang/polish.txt
+++ b/src/lang/polish.txt
@@ -5454,3 +5454,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 74b40844d9..91b0ff2f3f 100644
--- a/src/lang/portuguese.txt
+++ b/src/lang/portuguese.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/romanian.txt b/src/lang/romanian.txt
index 4c67771203..0852d415e6 100644
--- a/src/lang/romanian.txt
+++ b/src/lang/romanian.txt
@@ -4935,3 +4935,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 21542eb5f5..65f0cf92c1 100644
--- a/src/lang/russian.txt
+++ b/src/lang/russian.txt
@@ -5295,3 +5295,35 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :Учебник
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Показывать миникарту / легенду
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :Вертикальное меню: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :Меню разделено на два вертикальных меню по краям экрата
+STR_CONFIG_SETTING_BUTTON_SIZE :Размер кнопок
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :Размер элементов интерфейса
+STR_CONFIG_SETTING_FONT_SIZE :Размер шрифта
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :Размер всех шрифтов в игре
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :Подтверждать действия: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :Показывать окно подтверждения при постройки дорог и станций
+STR_CONFIG_SETTING_VIDEO_8BPP :8 бит
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :Установить глубину цвета в 16 бит на точку. Этот режим поддерживает анимацию воды
+STR_CONFIG_SETTING_VIDEO_16BPP :16 бит
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :Установить глубину цвета в 16 бит на точку. Это потребует перезапуска программы. Этот режим не поддерживает анимацию воды
+STR_CONFIG_SETTING_VIDEO_24BPP :24 бит
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :Установить глубину цвета в 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 20a813b38a..be40e5b828 100644
--- a/src/lang/serbian.txt
+++ b/src/lang/serbian.txt
@@ -5194,3 +5194,29 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :Priručnik
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Prikaži legendu mape / opis simbola na mapi
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :Vertikalna alatna traka: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :Glavna alatna traka je podeljena na dve okomite alatne trake na rubovima ekrana
+STR_CONFIG_SETTING_BUTTON_SIZE :Veličina dugmeta
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :Veličina svih elemenata korisničkog interfejsa
+STR_CONFIG_SETTING_FONT_SIZE :Veličina slova
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :Veličina svih slova u igri
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :Potvrdi akcije: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :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 27c35cdabd..0aaf8f824a 100644
--- a/src/lang/simplified_chinese.txt
+++ b/src/lang/simplified_chinese.txt
@@ -4989,3 +4989,41 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# Android strings
+STR_ABOUT_MENU_TUTORIAL :教程
+STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}在地图上显示图例/描述
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR :垂直工具栏: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :将主工具栏分为屏幕两侧的两个垂直工具栏
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR :紧凑型垂直工具栏: {STRING}
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR_HELPTEXT :隐藏垂直工具栏中的“切换工具栏”按钮,以显示更多子菜单
+STR_CONFIG_SETTING_BUTTON_SIZE :按键大小
+STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :用户界面大小
+STR_CONFIG_SETTING_FONT_SIZE :字体大小
+STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :游戏字体大小
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :确认操作: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :建立道路和车站时显示确认对话框
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS :{BLACK}标题栏
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT :{BLACK}显示所有窗口的标题栏,或者隐藏它们以节省屏幕空间
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS :窗口装饰: {STRING}
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS_HELPTEXT :窗口边缘装饰
+STR_CONFIG_SETTING_VIDEO_8BPP :8 bit
+STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :将视频颜色深度设置为8位像素,此模式支持水面动态涟漪
+STR_CONFIG_SETTING_VIDEO_16BPP :16 bit
+STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :将视频颜色深度设置为16位像素,这需要重新启动,此模式不支持水面动态涟漪
+STR_CONFIG_SETTING_VIDEO_24BPP :24 bit
+STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :将视频颜色深度设置为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 4ba647de92..6135aa084c 100644
--- a/src/lang/slovak.txt
+++ b/src/lang/slovak.txt
@@ -5018,3 +5018,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 4de468b497..bb4f651db5 100644
--- a/src/lang/slovenian.txt
+++ b/src/lang/slovenian.txt
@@ -5149,3 +5149,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 79a0dfac19..a2ad54b6af 100644
--- a/src/lang/spanish.txt
+++ b/src/lang/spanish.txt
@@ -5019,3 +5019,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 7ce9fb2d2f..e39254134e 100644
--- a/src/lang/spanish_MX.txt
+++ b/src/lang/spanish_MX.txt
@@ -5069,3 +5069,41 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
+
+# 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 :Barra de herramientas vertical: {STRING}
+STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :La barra de herramientas principal se divide en dos barras verticales laterales
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR :Compactar barra vertical: {STRING}
+STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR_HELPTEXT :Más submenúes en la barra vertical en lugar de botón de "Cambiar barras"
+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 general
+STR_CONFIG_SETTING_BUILD_CONFIRMATION :Confirmar acciones: {STRING}
+STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :Mostrar diálogo de confirmación al construir carreteras y estaciones
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS :{BLACK}Barras de título
+STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT :{BLACK}Mostrar títulos en todas las ventas u ocultarlos para reducir espacio
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS :Decoraciones de ventana: {STRING}
+STR_CONFIG_SETTING_WINDOWS_DECORATIONS_HELPTEXT :Adornos en bordes de ventana
+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 reiniciar. 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
diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt
index 03df018123..5abaecf730 100644
--- a/src/lang/swedish.txt
+++ b/src/lang/swedish.txt
@@ -5052,3 +5052,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 13e4772d5c..b429be2b85 100644
--- a/src/lang/tamil.txt
+++ b/src/lang/tamil.txt
@@ -4502,3 +4502,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 1c5d4400d3..fb8f1126ce 100644
--- a/src/lang/thai.txt
+++ b/src/lang/thai.txt
@@ -4859,3 +4859,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 7ddf4fbd3e..2bef0de060 100644
--- a/src/lang/traditional_chinese.txt
+++ b/src/lang/traditional_chinese.txt
@@ -4949,3 +4949,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 c9e17a9cce..a93c8ff15f 100644
--- a/src/lang/turkish.txt
+++ b/src/lang/turkish.txt
@@ -5071,3 +5071,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 ffd1d135c8..2a91c56fa9 100644
--- a/src/lang/ukrainian.txt
+++ b/src/lang/ukrainian.txt
@@ -5234,3 +5234,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 6b3c288342..75808fb5e3 100644
--- a/src/lang/vietnamese.txt
+++ b/src/lang/vietnamese.txt
@@ -5030,3 +5030,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 4e8e0b14fb..6f16e5b3d7 100644
--- a/src/lang/welsh.txt
+++ b/src/lang/welsh.txt
@@ -4968,3 +4968,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 6844092c2e..dbf134ce28 100644
--- a/src/linkgraph/linkgraph_gui.cpp
+++ b/src/linkgraph/linkgraph_gui.cpp
@@ -406,6 +406,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 cdd3831576..8b02a55775 100644
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -33,6 +33,8 @@
#include "tilehighlight_func.h"
#include "hotkeys.h"
#include "guitimer_func.h"
+#include "tutorial_gui.h"
+#include "gui.h"
#include "saveload/saveload.h"
@@ -343,7 +345,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_DELETE_ALL_MESSAGES: DeleteAllMessages(); break;
@@ -467,6 +469,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;
@@ -567,6 +570,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 061070a2b5..9a055c2de2 100644
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -27,6 +27,7 @@
#include "newgrf_debug.h"
#include "zoom_func.h"
#include "guitimer_func.h"
+#include "build_confirmation_func.h"
#include "widgets/misc_widget.h"
@@ -34,6 +35,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.
@@ -42,6 +47,8 @@ enum OskActivation {
OSKA_IMMEDIATELY, ///< Focusing click already opens OSK.
};
+static char _android_text_input[512];
+
static const NWidgetPart _nested_land_info_widgets[] = {
NWidget(NWID_HORIZONTAL),
@@ -533,6 +540,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) {
@@ -680,10 +691,18 @@ struct TooltipsWindow : public Window
/* Correctly position the tooltip position, watch out for window and cursor size
* Clamp value to below main toolbar and above statusbar. If tooltip would
* go below window, flip it so it is shown above the cursor */
- pt.y = Clamp(_cursor.pos.y + _cursor.total_size.y + _cursor.total_offs.y + 5, scr_top, scr_bot);
- if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.total_offs.y - 5, scr_bot) - sm_height;
+ pt.y = min(_cursor.pos.y + _cursor.total_offs.y - 5, scr_bot) - sm_height - GetMinSizing(NWST_STEP);
+ if (pt.y < scr_top) pt.y = Clamp(_cursor.pos.y + _cursor.total_size.y + _cursor.total_offs.y + 5, scr_top, scr_bot) + GetMinSizing(NWST_STEP);
pt.x = sm_width >= _screen.width ? 0 : Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width);
+ if (_settings_client.gui.windows_titlebars) {
+ // 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 +711,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. */
@@ -755,6 +774,14 @@ void QueryString::HandleEditBox(Window *w, int wid)
/* For the OSK also invalidate the parent window */
if (w->window_class == WC_OSK) w->InvalidateData();
}
+#ifdef __ANDROID__
+ if (SDL_IsScreenKeyboardShown(NULL)) {
+ if (SDL_ANDROID_GetScreenKeyboardTextInputAsync(_android_text_input, sizeof(_android_text_input)) == SDL_ANDROID_TEXTINPUT_ASYNC_FINISHED) {
+ this->text.Assign(_android_text_input);
+ w->OnEditboxChanged(wid);
+ }
+ }
+#endif
}
void QueryString::DrawEditBox(const Window *w, int wid) const
@@ -765,7 +792,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 +803,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 +826,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 +962,11 @@ void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bo
/* Open the OSK window */
ShowOnScreenKeyboard(w, wid);
}
+#ifdef __ANDROID__
+ strecpy(_android_text_input, this->text.buf, lastof(_android_text_input));
+ this->text.DeleteAll();
+ SDL_ANDROID_GetScreenKeyboardTextInputAsync(_android_text_input, sizeof(_android_text_input));
+#endif
}
/** Class for the string query window. */
@@ -1115,6 +1148,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 42c1e3c155..b32850b33f 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 "midifile.hpp"
#include "../base_media_base.h"
@@ -24,6 +25,7 @@
#include
#include
#include
+#include
#include "../safeguards.h"
@@ -43,13 +45,34 @@ static struct {
uint32 song_position;
} _midi; ///< Metadata about the midi we're playing.
+#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.
@@ -97,6 +120,7 @@ void MusicDriver_LibTimidity::PlaySong(const MusicSongInfo &song)
return;
}
+ mid_song_set_volume(_midi.song, volume);
mid_song_start(_midi.song);
_midi.status = MIDI_PLAYING;
}
@@ -124,5 +148,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 badb05bab2..34dcc887da 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 885647427f..b0f88a3f8a 100644
--- a/src/music_gui.cpp
+++ b/src/music_gui.cpp
@@ -450,13 +450,32 @@ void InitializeMusic()
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
@@ -483,6 +502,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();
}
@@ -502,19 +522,19 @@ 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 (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) {
SetDParam(0, song->tracknr);
SetDParam(1, 2);
SetDParamStr(2, song->songname);
- 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;
}
@@ -528,12 +548,14 @@ 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 (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) {
+ 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++) {
SetDParam(0, song->tracknr);
SetDParam(1, 2);
SetDParamStr(2, song->songname);
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME);
- y += FONT_HEIGHT_SMALL;
+ DrawString(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;
}
@@ -542,12 +564,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 (MusicSystem::Playlist::const_iterator song = _music.active_playlist.begin(); song != _music.active_playlist.end(); ++song) {
+ 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, song->tracknr);
SetDParam(1, 2);
SetDParamStr(2, song->songname);
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME);
- y += FONT_HEIGHT_SMALL;
+ DrawString(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;
}
@@ -558,13 +583,13 @@ 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);
+ int y = this->left_sb->GetScrolledRowFromWidget(pt.y, this, WID_MTS_LIST_LEFT, WD_FRAMERECT_TOP, this->resize.step_height);
_music.PlaylistAdd(y);
break;
}
case WID_MTS_LIST_RIGHT: { // remove from playlist
- int y = this->GetRowFromWidget(pt.y, widget, 0, FONT_HEIGHT_SMALL);
+ int y = this->right_sb->GetScrolledRowFromWidget(pt.y, this, WID_MTS_LIST_RIGHT, WD_FRAMERECT_TOP, this->resize.step_height);
_music.PlaylistRemove(y);
break;
}
@@ -597,6 +622,12 @@ struct MusicTrackSelectionWindow : public Window {
NOT_REACHED();
}
}
+
+ 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[] = {
@@ -604,36 +635,42 @@ static const NWidgetPart _nested_music_track_selection_widgets[] = {
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_MTS_CAPTION), SetDataTip(STR_PLAYLIST_MUSIC_SELECTION_SETNAME, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_MTS_MUSICSET), SetDataTip(STR_PLAYLIST_CHANGE_SET, STR_PLAYLIST_TOOLTIP_CHANGE_SET),
+ 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(
@@ -728,7 +765,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;
}
@@ -741,7 +778,7 @@ struct MusicWindow : public Window {
str = STR_MUSIC_TITLE_NAME;
SetDParamStr(0, _music.GetCurrentSong().songname);
}
- DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_HOR_CENTER);
+ DrawString(r.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;
}
@@ -806,7 +843,11 @@ struct MusicWindow : public Window {
if (new_vol < 3) new_vol = 0;
if (new_vol != *vol) {
*vol = new_vol;
+<<<<<<< HEAD
if (widget == WID_M_MUSIC_VOL) MusicDriver::GetInstance()->SetVolume(new_vol);
+=======
+ if (widget == WID_M_MUSIC_VOL) MusicVolumeChanged((new_vol * new_vol) / 127); // Kinda logarithmic scale
+>>>>>>> origin/master
this->SetDirty();
}
@@ -895,11 +936,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 32c6cffff2..f9e66e6637 100644
--- a/src/network/core/os_abstraction.h
+++ b/src/network/core/os_abstraction.h
@@ -75,7 +75,7 @@ typedef unsigned long in_addr_t;
# 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 68e1489874..45c2aa90b3 100644
--- a/src/network/network_chat_gui.cpp
+++ b/src/network/network_chat_gui.cpp
@@ -109,7 +109,7 @@ void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const char *m
/** Initialize all font-dependent chat box sizes. */
void NetworkReInitChatBoxSize()
{
- _chatmsg_box.y = 3 * FONT_HEIGHT_NORMAL;
+ _chatmsg_box.y = GetMinSizing(NWST_STEP, 10) + 5;
_chatmsg_box.height = MAX_CHAT_MESSAGES * (FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING) + 4;
_chatmessage_backup = ReallocT(_chatmessage_backup, _chatmsg_box.width * _chatmsg_box.height * BlitterFactory::GetCurrentBlitter()->GetBytesPerPixel());
}
@@ -120,7 +120,7 @@ void NetworkInitChatMessage()
MAX_CHAT_MESSAGES = _settings_client.gui.network_chat_box_height;
_chatmsg_list = ReallocT(_chatmsg_list, _settings_client.gui.network_chat_box_height);
- _chatmsg_box.x = 10;
+ _chatmsg_box.x = GetMinSizing(NWST_STEP, 10) + 5;
_chatmsg_box.width = _settings_client.gui.network_chat_box_width_pct * _screen.width / 100;
NetworkReInitChatBoxSize();
_chatmessage_visible = false;
@@ -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 = { (int)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 877dea9786..306bf9e39f 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;
@@ -1057,14 +1059,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),
@@ -1094,6 +1089,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 93cd3d9733..ce41e187da 100644
--- a/src/network/network_gui.cpp
+++ b/src/network/network_gui.cpp
@@ -32,6 +32,7 @@
#include "../genworld.h"
#include "../map_type.h"
#include "../guitimer_func.h"
+#include "../settings_gui.h"
#include "../widgets/network_widget.h"
@@ -509,17 +510,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:
@@ -554,7 +555,7 @@ public:
break;
case WID_NG_DETAILS_SPACER:
- size->height = 20 + 12 * FONT_HEIGHT_NORMAL;
+ size->height = 20 + 10 * FONT_HEIGHT_NORMAL;
break;
}
}
@@ -949,12 +950,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),
@@ -1098,8 +1096,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;
}
}
@@ -1282,15 +1280,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(),
@@ -1393,8 +1391,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:
@@ -1461,7 +1459,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) {
@@ -1726,7 +1724,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
@@ -1745,10 +1743,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);
@@ -1790,6 +1788,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;
@@ -1801,37 +1800,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);
}
};
@@ -1853,7 +1844,7 @@ static const NWidgetPart _nested_client_list_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_NETWORK_COMPANY_LIST_CLIENT_LIST_CAPTION, 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(
@@ -1871,6 +1862,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;
@@ -1894,12 +1887,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;
@@ -1912,6 +1909,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;
@@ -1919,7 +1917,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()
@@ -1943,19 +1941,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;
@@ -1973,6 +1973,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;
+ }
+ }
}
}
@@ -2005,7 +2013,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.cpp b/src/newgrf.cpp
index 2fc546d4eb..1741b73295 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -204,7 +204,7 @@ static inline bool IsValidNewGRFImageIndex(uint8 image_index)
return image_index == 0xFD || IsValidImageIndex(image_index);
}
-class OTTDByteReaderSignal { };
+class OTTDByteReaderSignal: public std::runtime_error { public: OTTDByteReaderSignal():std::runtime_error("OTTDByteReaderSignal: NewGRF byte data invalid") {} };
/** Class to read from a NewGRF file */
class ByteReader {
diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp
index 75b06967f7..faa9b1f62b 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 */
@@ -660,13 +660,13 @@ static const NWidgetPart _nested_newgrf_inspect_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_NGRFI_CAPTION), SetDataTip(STR_NEWGRF_INSPECT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NGRFI_PARENT), SetDataTip(STR_NEWGRF_INSPECT_PARENT_BUTTON, STR_NEWGRF_INSPECT_PARENT_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_GREY, WID_NGRFI_MAINPANEL), SetMinimalSize(300, 0), SetScrollbar(WID_NGRFI_SCROLLBAR), EndContainer(),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NGRFI_PARENT), SetDataTip(STR_NEWGRF_INSPECT_PARENT_BUTTON, STR_NEWGRF_INSPECT_PARENT_TOOLTIP),
NWidget(NWID_VERTICAL),
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_NGRFI_SCROLLBAR),
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
@@ -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 5f32b5bad5..400b2332b6 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;
@@ -742,14 +741,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: {
@@ -772,6 +771,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
}
}
d.width += padding.width;
+ d.height = GetMinSizing(NWST_BUTTON, d.height);
*size = maxdim(d, *size);
break;
}
@@ -782,6 +782,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;
}
}
@@ -790,7 +791,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
@@ -1308,8 +1309,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;
@@ -1510,7 +1513,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
}
/**
@@ -1647,8 +1650,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);
@@ -1685,7 +1688,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;
@@ -1793,7 +1796,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;
@@ -1801,7 +1804,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);
}
@@ -1917,33 +1920,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);
@@ -2021,6 +2102,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);
}
@@ -2183,6 +2265,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 b79418c899..47922d8fc3 100644
--- a/src/news_gui.cpp
+++ b/src/news_gui.cpp
@@ -166,7 +166,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(),
};
@@ -188,7 +188,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(),
@@ -332,6 +332,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;
@@ -374,7 +375,7 @@ struct NewsWindow : Window {
{
switch (widget) {
case WID_N_CAPTION:
- DrawCaption(r, COLOUR_LIGHT_BLUE, this->owner, STR_NEWS_MESSAGE_CAPTION);
+ DrawCaption(r, COLOUR_LIGHT_BLUE, this->owner, STR_NEWS_MESSAGE_CAPTION, this->GetWidget(WID_N_CAPTION), this);
break;
case WID_N_PANEL:
@@ -1027,7 +1028,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
@@ -1058,7 +1059,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 6265b96849..cf2172c464 100644
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -70,6 +70,12 @@
#include
#include "safeguards.h"
+#ifdef __ANDROID__
+#include
+#include
+#endif
+#include
+#include
void CallLandscapeTick();
void IncreaseDate();
@@ -82,6 +88,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.
@@ -492,6 +500,24 @@ struct AfterNewGRFScan : NewGRFScanCallback {
}
#endif /* ENABLE_NETWORK */
+ // TODO: remove this hack in one year
+ // Check if OpenTTD config is broken by blitter changing code
+ static bool checked = false;
+ DEBUG(misc, 0, "========= Limits for vehicles: %d %d %d %d", _settings_newgame.vehicle.max_trains, _settings_newgame.vehicle.max_roadveh, _settings_newgame.vehicle.max_aircraft, _settings_newgame.vehicle.max_ships);
+ if (!checked &&
+ _settings_newgame.vehicle.max_trains == 0 && _settings_newgame.vehicle.max_roadveh == 0 &&
+ _settings_newgame.vehicle.max_aircraft == 0 && _settings_newgame.vehicle.max_ships == 0) {
+ if (access(".openttd/openttd-backup.cfg", F_OK) == 0) {
+ system("mv -f .openttd/openttd-backup.cfg .openttd/openttd.cfg");
+ } else {
+ unlink("libsdl-DownloadFinished-1.flag");
+ }
+ //_exit_game = true;
+ //_restart_game = true;
+ _exit(0); // kill(getpid(), SIG_KILL); //abort(); // Kill myself with contempt, user will restart the app, because otherwise we enter infinite restart loop
+ }
+ checked = true;
+
/* After the scan we're not used anymore. */
delete this;
}
@@ -732,6 +758,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();
@@ -758,7 +794,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.
@@ -863,7 +899,15 @@ int openttd_main(int argc, char *argv[])
ScanNewGRFFiles(scanner);
scanner = NULL;
- VideoDriver::GetInstance()->MainLoop();
+ try {
+ VideoDriver::GetInstance()->MainLoop();
+ } catch (const std::exception & e) {
+ DEBUG(misc, 0, "Main thread got exception: %s", e.what());
+ throw;
+ } catch (...) {
+ DEBUG(misc, 0, "Main thread got unknown exception");
+ throw;
+ }
WaitTillSaved();
@@ -893,6 +937,14 @@ exit_bootstrap:
free(sounddriver);
exit_normal:
+
+ if (_restart_game) {
+#ifdef __ANDROID__
+ // This makes OpenTTD reset all it's settings for some reason, because the process is not killed and shared libraries are not unloaded.
+ exit(0);
+#endif
+ }
+
free(BaseGraphics::ini_set);
free(BaseSounds::ini_set);
free(BaseMusic::ini_set);
@@ -1173,6 +1225,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/openttd.h b/src/openttd.h
index 5e360d6fcd..0a92475f51 100644
--- a/src/openttd.h
+++ b/src/openttd.h
@@ -52,6 +52,7 @@ enum DisplayOptions {
extern GameMode _game_mode;
extern SwitchMode _switch_mode;
extern bool _exit_game;
+extern bool _restart_game;
/** Modes of pausing we've got */
enum PauseMode {
diff --git a/src/order_gui.cpp b/src/order_gui.cpp
index 81350deb74..91ca244d4d 100644
--- a/src/order_gui.cpp
+++ b/src/order_gui.cpp
@@ -556,13 +556,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();
+ }
}
/**
@@ -800,8 +803,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: {
@@ -1087,8 +1090,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);
@@ -1113,7 +1116,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);
}
@@ -1535,7 +1538,6 @@ static const NWidgetPart _nested_orders_train_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION), SetDataTip(STR_ORDERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetDataTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -1585,6 +1587,7 @@ static const NWidgetPart _nested_orders_train_widgets[] = {
/* Second button row. */
NWidget(NWID_HORIZONTAL),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetDataTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_SKIP), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_ORDERS_SKIP_BUTTON, STR_ORDERS_SKIP_TOOLTIP), SetResize(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_BOTTOM_MIDDLE),
@@ -1613,7 +1616,6 @@ static const NWidgetPart _nested_orders_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION), SetDataTip(STR_ORDERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetDataTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -1659,6 +1661,7 @@ static const NWidgetPart _nested_orders_widgets[] = {
/* Second button row. */
NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetDataTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_SKIP), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_ORDERS_SKIP_BUTTON, STR_ORDERS_SKIP_TOOLTIP), SetResize(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_BOTTOM_MIDDLE),
@@ -1686,13 +1689,15 @@ static const NWidgetPart _nested_other_orders_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION), SetDataTip(STR_ORDERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetDataTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
NWidget(NWID_HORIZONTAL),
- NWidget(WWT_PANEL, COLOUR_GREY, WID_O_ORDER_LIST), SetMinimalSize(372, 72), SetDataTip(0x0, STR_ORDERS_LIST_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_O_SCROLLBAR), EndContainer(),
+ NWidget(NWID_VERTICAL),
+ NWidget(WWT_PANEL, COLOUR_GREY, WID_O_ORDER_LIST), SetMinimalSize(372, 72), SetDataTip(0x0, STR_ORDERS_LIST_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_O_SCROLLBAR), EndContainer(),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_TIMETABLE_VIEW), SetMinimalSize(61, 14), SetDataTip(STR_ORDERS_TIMETABLE_VIEW, STR_ORDERS_TIMETABLE_VIEW_TOOLTIP),
+ EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_O_SCROLLBAR),
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
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 bea69ec931..6a25d9444e 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. */
@@ -367,10 +379,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 dc069d1686..4ef27f7561 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 234edbf22f..ae07245e8c 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 << 6 | _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);
+ if (_settings_client.gui.link_terraform_toolbar || _settings_client.gui.compact_vertical_toolbar) ShowTerraformToolbar();
}
~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 << 6 | _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/road_gui.cpp b/src/road_gui.cpp
index e3091ec8af..b11bb8e871 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);
+ if (_settings_client.gui.link_terraform_toolbar || _settings_client.gui.compact_vertical_toolbar) ShowTerraformToolbar();
}
~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:
@@ -655,7 +680,16 @@ struct BuildRoadToolbarWindow : Window {
}
}
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();
}
}
@@ -811,7 +845,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);
}
@@ -843,7 +877,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),
@@ -856,6 +890,7 @@ static WindowDesc _build_road_scen_desc(
*/
Window *ShowBuildRoadScenToolbar()
{
+ DeleteToolbarLinkedWindows();
_cur_roadtype = ROADTYPE_ROAD;
return AllocateWindowDescFront(&_build_road_scen_desc, TRANSPORT_ROAD);
}
@@ -919,18 +954,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),
@@ -1069,17 +1104,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),
@@ -1116,8 +1151,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 700a065669..f413ec149c 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.
/**
@@ -265,7 +266,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;
@@ -379,6 +381,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++) {
@@ -851,7 +864,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 ce2b37bb53..6d03b460ad 100644
--- a/src/script/api/game/game_window.hpp.sq
+++ b/src/script/api/game/game_window.hpp.sq
@@ -650,9 +650,11 @@ void SQGSWindow_Register(Squirrel *engine)
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_HSCROLLBAR, "WID_TF_HSCROLLBAR");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_CAPTION, "WID_MTS_CAPTION");
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_MUSICSET, "WID_MTS_MUSICSET");
+ 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");
@@ -1218,6 +1220,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 fa584693af..ad34ccd471 100644
--- a/src/script/api/script_window.hpp
+++ b/src/script/api/script_window.hpp
@@ -136,6 +136,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
@@ -1625,8 +1632,10 @@ public:
enum MusicTrackSelectionWidgets {
WID_MTS_CAPTION = ::WID_MTS_CAPTION, ///< Window caption.
WID_MTS_LIST_LEFT = ::WID_MTS_LIST_LEFT, ///< Left button.
+ WID_MTS_LEFT_SCROLLBAR = ::WID_MTS_LEFT_SCROLLBAR, ///< Scrollbar of left list.
WID_MTS_PLAYLIST = ::WID_MTS_PLAYLIST, ///< Playlist.
WID_MTS_LIST_RIGHT = ::WID_MTS_LIST_RIGHT, ///< Right button.
+ WID_MTS_RIGHT_SCROLLBAR = ::WID_MTS_RIGHT_SCROLLBAR, ///< Scrollbar of right list.
WID_MTS_MUSICSET = ::WID_MTS_MUSICSET, ///< Music set selection.
WID_MTS_ALL = ::WID_MTS_ALL, ///< All button.
WID_MTS_OLD = ::WID_MTS_OLD, ///< Old button.
@@ -2439,6 +2448,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 b93f4d7066..dc11a37635 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"
@@ -1078,6 +1080,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 c3a38b4081..ea6842b609 100644
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -37,11 +37,17 @@
#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,
@@ -121,6 +127,8 @@ static int GetCurRes()
static void ShowCustCurrency();
+static void ReconstructUserInterface();
+
template
static DropDownList *BuildSetDropDownList(int *selected_index, bool allow_selection)
{
@@ -192,6 +200,7 @@ struct GameOptionsWindow : Window {
DeleteWindowById(WC_CUSTOM_CURRENCY, 0);
DeleteWindowByClass(WC_TEXTFILE);
if (this->reload) _switch_mode = SM_MENU;
+ if (!_exit_game) SaveToConfig(); // Save all settings immediately on Android, because users tend to kill the app instead of pressing 'Quit' button
}
/**
@@ -300,6 +309,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;
@@ -348,6 +370,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_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[ZOOM_LVL_OUT_4X - _font_zoom]); break;
case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name); break;
@@ -363,17 +387,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;
}
}
@@ -384,7 +408,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;
@@ -403,7 +427,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;
@@ -411,7 +435,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;
@@ -475,6 +499,54 @@ struct GameOptionsWindow : Window {
this->SetDirty();
break;
+ case WID_GO_WINDOWS_TITLEBARS:
+ _settings_client.gui.windows_titlebars = !_settings_client.gui.windows_titlebars;
+ this->SetWidgetLoweredState(WID_GO_WINDOWS_TITLEBARS, _settings_client.gui.windows_titlebars);
+ this->SetDirty();
+ if (_settings_client.gui.min_button == 48 && _settings_client.gui.windows_titlebars) {
+ _settings_client.gui.min_button = 40;
+ _settings_client.gui.min_step = 40;
+ }
+ if (_settings_client.gui.min_button == 40 && !_settings_client.gui.windows_titlebars) {
+ _settings_client.gui.min_button = 48;
+ _settings_client.gui.min_step = 48;
+ }
+ ReconstructUserInterface();
+ break;
+
+ case WID_GO_8BPP_BUTTON:
+ if (this->IsWidgetLowered(WID_GO_8BPP_BUTTON)) break;
+ free(_ini_blitter);
+ _ini_blitter = stredup("8bpp-optimized");
+ _exit_game = true;
+ _restart_game = true;
+ #ifdef __ANDROID__
+ SDL_ANDROID_SetConfigOption(SDL_ANDROID_CONFIG_VIDEO_DEPTH_BPP, 16);
+ #endif
+ break;
+
+ case WID_GO_16BPP_BUTTON:
+ if (this->IsWidgetLowered(WID_GO_16BPP_BUTTON)) break;
+ free(_ini_blitter);
+ _ini_blitter = stredup("16bpp-simple");
+ _exit_game = true;
+ _restart_game = true;
+ #ifdef __ANDROID__
+ SDL_ANDROID_SetConfigOption(SDL_ANDROID_CONFIG_VIDEO_DEPTH_BPP, 16);
+ #endif
+ break;
+
+ case WID_GO_32BPP_BUTTON:
+ if (this->IsWidgetLowered(WID_GO_32BPP_BUTTON)) break;
+ free(_ini_blitter);
+ _ini_blitter = stredup("32bpp-anim");
+ _exit_game = true;
+ _restart_game = true;
+ #ifdef __ANDROID__
+ SDL_ANDROID_SetConfigOption(SDL_ANDROID_CONFIG_VIDEO_DEPTH_BPP, 24);
+ #endif
+ break;
+
default: {
int selected;
DropDownList *list = this->BuildDropDownList(widget, &selected);
@@ -548,13 +620,34 @@ 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();
UpdateAllVirtCoords();
ReInitAllWindows();
@@ -565,6 +658,7 @@ struct GameOptionsWindow : Window {
_font_zoom = (ZoomLevel)(ZOOM_LVL_OUT_4X - index);
ClearFontCache();
LoadStringWidthTable();
+ ReconstructUserInterface();
UpdateAllVirtCoords();
break;
@@ -590,7 +684,14 @@ struct GameOptionsWindow : Window {
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
{
if (!gui_scope) return;
+ this->SetWidgetLoweredState(WID_GO_WINDOWS_TITLEBARS, _settings_client.gui.windows_titlebars);
+#ifdef WIN32
this->SetWidgetLoweredState(WID_GO_FULLSCREEN_BUTTON, _fullscreen);
+#else
+ 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);
+#endif
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);
@@ -623,13 +724,24 @@ 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),
+#ifdef WIN32
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),
+#else
+ 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),
+#endif
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_TEXTBTN, COLOUR_GREY, WID_GO_WINDOWS_TITLEBARS), SetMinimalSize(21, 9), SetDataTip(STR_CONFIG_SETTING_WINDOWS_TITLEBARS, STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT), SetFill(1, 0),
+ EndContainer(),
+ EndContainer(),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, 6, 0),
@@ -642,49 +754,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_GAME_OPTIONS_FONT_ZOOM, STR_NULL),
- NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_FONT_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0),
+ 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(),
@@ -1099,7 +1215,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) {
@@ -1574,6 +1689,11 @@ static SettingsContainer &GetSettingsTree()
}
interface->Add(new SettingEntry("gui.autosave"));
+ interface->Add(new SettingEntry("gui.vertical_toolbar"));
+ interface->Add(new SettingEntry("gui.compact_vertical_toolbar"));
+ interface->Add(new SettingEntry("gui.build_confirmation"));
+ interface->Add(new SettingEntry("gui.windows_titlebars"));
+ interface->Add(new SettingEntry("gui.windows_decorations"));
interface->Add(new SettingEntry("gui.toolbar_pos"));
interface->Add(new SettingEntry("gui.statusbar_pos"));
interface->Add(new SettingEntry("gui.prefer_teamchat"));
@@ -1856,11 +1976,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;
@@ -2371,10 +2496,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),
@@ -2431,8 +2556,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;
@@ -2457,7 +2582,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);
@@ -2705,3 +2830,35 @@ 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();
+ if (_settings_client.gui.windows_titlebars) {
+ // Hack to prevent second click on the same button via button-up event
+ ShowGameOptions();
+ }
+}
diff --git a/src/settings_gui.h b/src/settings_gui.h
index 23a343219f..8cc507ddd1 100644
--- a/src/settings_gui.h
+++ b/src/settings_gui.h
@@ -15,10 +15,8 @@
#include "gfx_type.h"
#include "widgets/dropdown_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 8f03b1dc15..5756c6e4e9 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -86,6 +86,13 @@ 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 compact_vertical_toolbar; ///< compact mode for vertical toolbars, with more sub-menus
+ bool build_confirmation; ///< show confirmation dialog when building roads and stations
+ bool windows_titlebars; ///< show or hide titlebars for all windows to increase scrren space
+ bool windows_decorations; ///< draw ornament on all window edges
+ 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
@@ -111,6 +118,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 56af6e6655..7d64c33589 100644
--- a/src/signs_gui.cpp
+++ b/src/signs_gui.cpp
@@ -24,6 +24,7 @@
#include "sortlist_type.h"
#include "stringfilter_type.h"
#include "string_func.h"
+#include "settings_type.h"
#include "core/geometry_func.hpp"
#include "hotkeys.h"
#include "transparency.h"
@@ -200,7 +201,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);
@@ -271,13 +272,14 @@ 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;
}
case WID_SIL_CAPTION:
+ if (!_settings_client.gui.windows_titlebars) break;
SetDParamMaxValue(0, Sign::GetPoolSize(), 3);
*size = GetStringBoundingBox(STR_SIGN_LIST_CAPTION);
size->height += padding.height;
diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp
index 97d01325a0..3d1604385a 100644
--- a/src/smallmap_gui.cpp
+++ b/src/smallmap_gui.cpp
@@ -38,7 +38,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.
@@ -86,12 +86,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()
};
@@ -126,12 +126,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()
};
@@ -146,6 +147,7 @@ static LegendAndColour _legend_land_owners[NUM_NO_COMPANY_ENTRIES + MAX_COMPANIE
};
#undef MK
+#undef MKB
#undef MC
#undef MS
#undef MO
@@ -186,7 +188,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. */
@@ -217,6 +219,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;
@@ -313,7 +316,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++) {
@@ -341,7 +344,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++;
@@ -1051,12 +1054,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(GUITimer(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(GUITimer(FORCE_REFRESH_PERIOD))
{
_smallmap_industry_highlight = INVALID_INDUSTRYTYPE;
this->overlay = new LinkGraphOverlay(this, WID_SM_MAP, 0, this->GetOverlayCompanyMask(), 1);
@@ -1065,9 +1074,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();
@@ -1149,7 +1159,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++;
}
@@ -1158,7 +1168,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);
}
@@ -1198,9 +1208,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);
@@ -1227,7 +1236,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;
}
@@ -1257,7 +1266,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;
}
@@ -1266,13 +1275,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;
}
}
}
@@ -1367,9 +1376,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;
@@ -1402,6 +1412,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
switch (widget) {
case WID_SM_MAP: { // Map window
if (click_count > 0) this->mouse_capture_widget = widget;
+ _scrolling_viewport = true;
const NWidgetBase *wid = this->GetWidget(WID_SM_MAP);
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
@@ -1447,6 +1458,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);
@@ -1665,6 +1684,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;
@@ -1694,8 +1721,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);
@@ -1746,7 +1774,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(),
};
@@ -1754,27 +1782,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),
@@ -1785,10 +1809,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(),
};
@@ -1812,6 +1838,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),
@@ -1826,10 +1853,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 486f2a6524..b0e1a83249 100644
--- a/src/smallmap_gui.h
+++ b/src/smallmap_gui.h
@@ -71,9 +71,11 @@ protected:
static const uint FORCE_REFRESH_PERIOD = 930; ///< map is redrawn after that many milliseconds.
static const uint BLINK_PERIOD = 450; ///< highlight blinking interval in milliseconds.
+ 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.
@@ -116,7 +118,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;
}
/**
@@ -135,8 +137,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;
}
/**
@@ -191,6 +193,7 @@ public:
virtual void OnRealtimeTick(uint delta_ms);
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 b37016c24e..e4c89b0f20 100644
--- a/src/sound/sdl_s.cpp
+++ b/src/sound/sdl_s.cpp
@@ -22,6 +22,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.
@@ -31,6 +35,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 8a5a25ac00..2f9e243d46 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 bf860538d1..7b349a39e7 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 5c2e06070b..b64942d479 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];
@@ -721,7 +724,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(),
@@ -762,12 +765,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(),
@@ -802,7 +805,7 @@ static const NWidgetPart _nested_station_view_widgets[] = {
* @param right right most coordinate to draw on
* @param y y coordinate
*/
-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
@@ -1382,6 +1385,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;
}
}
@@ -1731,7 +1740,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();
@@ -2262,8 +2271,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;
@@ -2273,7 +2282,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 88ba495f34..278f85d8b3 100644
--- a/src/statusbar_gui.cpp
+++ b/src/statusbar_gui.cpp
@@ -27,6 +27,7 @@
#include "toolbar_gui.h"
#include "core/geometry_func.hpp"
#include "guitimer_func.h"
+#include "settings_gui.h"
#include "widgets/statusbar_widget.h"
@@ -71,7 +72,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);
@@ -107,27 +108,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;
}
@@ -139,11 +150,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: {
@@ -151,7 +164,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;
}
@@ -159,11 +172,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)) {
@@ -171,23 +184,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.HasElapsed()) {
- 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.HasElapsed()) {
+ 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);
+ }
}
/**
diff --git a/src/strings.cpp b/src/strings.cpp
index a3ece9830e..34b923830b 100644
--- a/src/strings.cpp
+++ b/src/strings.cpp
@@ -2010,7 +2010,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];
@@ -2020,6 +2020,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;
@@ -2028,11 +2029,11 @@ bool MissingGlyphSearcher::FindMissingGlyphs(const char **str)
size = (FontSize)(c - SCC_FIRST_FONT);
} 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 624d475c31..6152dfb2f6 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 787a82dd86..1ee03faf00 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 5bb2c73aad..3493097551 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);
static bool InvalidateShipPathCache(int32 p1);
@@ -2524,6 +2525,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
@@ -2542,6 +2552,47 @@ 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.compact_vertical_toolbar
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = true
+str = STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR
+strhelp = STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR_HELPTEXT
+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.windows_titlebars
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = true
+str = STR_CONFIG_SETTING_WINDOWS_TITLEBARS
+strhelp = STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT
+cat = SC_BASIC
+
+[SDTC_BOOL]
+var = gui.windows_decorations
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = true
+str = STR_CONFIG_SETTING_WINDOWS_DECORATIONS
+strhelp = STR_CONFIG_SETTING_WINDOWS_DECORATIONS_HELPTEXT
+cat = SC_BASIC
+
[SDTC_BOOL]
var = gui.show_finances
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
@@ -2568,7 +2619,7 @@ var = gui.scroll_mode
type = SLE_UINT8
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SGF_MULTISTRING
-def = 0
+def = 3
min = 0
max = 3
str = STR_CONFIG_SETTING_SCROLLMODE
@@ -3722,7 +3773,7 @@ ifdef = ENABLE_NETWORK
var = network.server_advertise
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SGF_NETWORK_ONLY
-def = false
+def = true
[SDTC_VAR]
ifdef = ENABLE_NETWORK
diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp
index 97749a8dcc..122096ec05 100644
--- a/src/terraform_gui.cpp
+++ b/src/terraform_gui.cpp
@@ -224,18 +224,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
@@ -274,14 +278,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/textfile_gui.cpp b/src/textfile_gui.cpp
index ff5226c2b5..6a1d975c66 100644
--- a/src/textfile_gui.cpp
+++ b/src/textfile_gui.cpp
@@ -36,7 +36,6 @@ static const NWidgetPart _nested_textfile_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_TF_CAPTION), SetDataTip(STR_NULL, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_TEXTBTN, COLOUR_MAUVE, WID_TF_WRAPTEXT), SetDataTip(STR_TEXTFILE_WRAP_TEXT, STR_TEXTFILE_WRAP_TEXT_TOOLTIP),
NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE),
EndContainer(),
NWidget(NWID_HORIZONTAL),
@@ -47,6 +46,7 @@ static const NWidgetPart _nested_textfile_widgets[] = {
EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_TEXTBTN, COLOUR_MAUVE, WID_TF_WRAPTEXT), SetDataTip(STR_TEXTFILE_WRAP_TEXT, STR_TEXTFILE_WRAP_TEXT_TOOLTIP),
NWidget(NWID_HSCROLLBAR, COLOUR_MAUVE, WID_TF_HSCROLLBAR),
NWidget(WWT_RESIZEBOX, COLOUR_MAUVE),
EndContainer(),
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/timetable_gui.cpp b/src/timetable_gui.cpp
index 5dd45561f3..e3e9660d19 100644
--- a/src/timetable_gui.cpp
+++ b/src/timetable_gui.cpp
@@ -201,8 +201,8 @@ struct TimetableWindow : Window {
case WID_VT_ARRIVAL_DEPARTURE_SELECTION:
case WID_VT_TIMETABLE_PANEL:
- resize->height = FONT_HEIGHT_NORMAL;
- size->height = WD_FRAMERECT_TOP + 8 * resize->height + WD_FRAMERECT_BOTTOM;
+ resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL);
+ size->height = WD_FRAMERECT_TOP + 4 * resize->height + WD_FRAMERECT_BOTTOM;
break;
case WID_VT_SUMMARY_PANEL:
@@ -213,7 +213,8 @@ struct TimetableWindow : Window {
int GetOrderFromTimetableWndPt(int y, const Vehicle *v)
{
- int sel = (y - this->GetWidget(WID_VT_TIMETABLE_PANEL)->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL;
+ int line_height = this->GetWidget(WID_VT_TIMETABLE_PANEL)->resize_y;
+ int sel = (y - this->GetWidget(WID_VT_TIMETABLE_PANEL)->pos_y - WD_FRAMERECT_TOP) / line_height;
if ((uint)sel >= this->vscroll->GetCapacity()) return INVALID_ORDER;
@@ -356,7 +357,8 @@ struct TimetableWindow : Window {
switch (widget) {
case WID_VT_TIMETABLE_PANEL: {
- int y = r.top + WD_FRAMERECT_TOP;
+ int line_height = this->GetWidget(WID_VT_TIMETABLE_PANEL)->resize_y;
+ int y = Center(r.top + WD_FRAMERECT_TOP, line_height);
int i = this->vscroll->GetPosition();
VehicleOrderID order_id = (i + 1) / 2;
bool final_order = false;
@@ -414,7 +416,7 @@ struct TimetableWindow : Window {
}
i++;
- y += FONT_HEIGHT_NORMAL;
+ y += line_height;
}
break;
}
@@ -432,7 +434,8 @@ struct TimetableWindow : Window {
VehicleOrderID earlyID = BuildArrivalDepartureList(v, arr_dep) ? cur_order : (VehicleOrderID)INVALID_VEH_ORDER_ID;
- int y = r.top + WD_FRAMERECT_TOP;
+ int line_height = this->GetWidget(WID_VT_TIMETABLE_PANEL)->resize_y;
+ int y = Center(r.top + WD_FRAMERECT_TOP, line_height);
bool show_late = this->show_expected && v->lateness_counter > DAY_TICKS;
Ticks offset = show_late ? 0 : -v->lateness_counter;
@@ -467,7 +470,7 @@ struct TimetableWindow : Window {
show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK);
}
}
- y += FONT_HEIGHT_NORMAL;
+ y += line_height;
}
break;
}
@@ -654,7 +657,6 @@ static const NWidgetPart _nested_timetable_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_VT_CAPTION), SetDataTip(STR_TIMETABLE_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_ORDER_VIEW), SetMinimalSize(61, 14), SetDataTip( STR_TIMETABLE_ORDER_VIEW, STR_TIMETABLE_ORDER_VIEW_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -669,6 +671,7 @@ static const NWidgetPart _nested_timetable_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY, WID_VT_SUMMARY_PANEL), SetMinimalSize(400, 22), SetResize(1, 0), EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_ORDER_VIEW), SetMinimalSize(61, 14), SetDataTip(STR_TIMETABLE_ORDER_VIEW, STR_TIMETABLE_ORDER_VIEW_TOOLTIP),
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_CHANGE_TIME), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_CHANGE_TIME, STR_TIMETABLE_WAIT_TIME_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_CLEAR_TIME), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_CLEAR_TIME, STR_TIMETABLE_CLEAR_TIME_TOOLTIP),
diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp
index 5567c55800..5b68d67fbb 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 "framerate_type.h"
#include "guitimer_func.h"
@@ -66,6 +67,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 {
@@ -108,9 +110,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);
}
};
@@ -146,7 +148,7 @@ public:
uint Height(uint width) const
{
- return max(max(this->icon_size.height, this->lock_size.height) + 2U, (uint)FONT_HEIGHT_NORMAL);
+ return GetMinSizing(NWST_STEP, max(max(this->icon_size.height, this->lock_size.height) + 2U, (uint)FONT_HEIGHT_NORMAL));
}
void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
@@ -189,7 +191,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);
}
@@ -214,6 +226,7 @@ static const int CTMN_CLIENT_LIST = -1; ///< Show the client list
static const int CTMN_NEW_COMPANY = -2; ///< Create a new company
static const int CTMN_SPECTATE = -3; ///< Become spectator
static const int CTMN_SPECTATOR = -4; ///< Show a company window as spectator
+static const int CTMN_SPEAK_ALL = -5; ///< Send message to public chat
/**
* Pop up a generic company list menu.
@@ -232,6 +245,7 @@ static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0)
/* Add the client list button for the companies menu */
*list->Append() = new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false);
+ *list->Append() = new DropDownListStringItem(STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, CTMN_SPEAK_ALL, false);
if (_local_company == COMPANY_SPECTATOR) {
*list->Append() = new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_NEW_COMPANY, CTMN_NEW_COMPANY, NetworkMaxCompaniesReached());
@@ -345,7 +359,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;
}
@@ -515,7 +529,7 @@ static CallBackFunction MenuClickMap(int index)
static CallBackFunction ToolbarTownClick(Window *w)
{
- PopupMainToolbMenu(w, WID_TN_TOWNS, STR_TOWN_MENU_TOWN_DIRECTORY, (_settings_game.economy.found_town == TF_FORBIDDEN) ? 1 : 2);
+ PopupMainToolbMenu(w, WID_TN_TOWNS, STR_TOWN_MENU_TOWN_DIRECTORY, (_settings_game.economy.found_town == TF_FORBIDDEN) ? 5 : 6);
return CBF_NONE;
}
@@ -529,7 +543,11 @@ static CallBackFunction MenuClickTown(int index)
{
switch (index) {
case 0: ShowTownDirectory(); break;
- case 1: // setting could be changed when the dropdown was open
+ case 1: ShowSubsidiesList(); break;
+ case 2: ShowIndustryDirectory(); break;
+ case 3: ShowIndustryCargoesWindow(); break;
+ case 4: if (_local_company != COMPANY_SPECTATOR) ShowBuildIndustryWindow(); break;
+ case 5: // setting could be changed when the dropdown was open
if (_settings_game.economy.found_town != TF_FORBIDDEN) ShowFoundTownWindow();
break;
}
@@ -637,6 +655,10 @@ static CallBackFunction MenuClickCompany(int index)
NetworkClientRequestMove(COMPANY_SPECTATOR);
}
return CBF_NONE;
+
+ case CTMN_SPEAK_ALL:
+ ShowNetworkChatQueryWindow(DESTTYPE_BROADCAST, 0);
+ return CBF_NONE;
}
}
#endif /* ENABLE_NETWORK */
@@ -688,7 +710,8 @@ static CallBackFunction MenuClickGoal(int index)
static CallBackFunction ToolbarGraphsClick(Window *w)
{
- PopupMainToolbMenu(w, WID_TN_GRAPHS, STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8);
+ PopupMainToolbMenu(w, WID_TN_GRAPHS, STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH,
+ (_toolbar_mode == TB_NORMAL && !_settings_client.gui.compact_vertical_toolbar) ? 6 : (_networking ? 8 : 9));
return CBF_NONE;
}
@@ -710,6 +733,7 @@ static CallBackFunction MenuClickGraphs(int index)
/* functions for combined graphs/league button */
case 6: ShowCompanyLeagueTable(); break;
case 7: ShowPerformanceRatingDetail(); break;
+ case 8: ShowHighscoreTable(); break;
}
return CBF_NONE;
}
@@ -881,11 +905,23 @@ static CallBackFunction ToolbarZoomOutClick(Window *w)
static CallBackFunction ToolbarBuildRailClick(Window *w)
{
- ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, true, true);
+ DropDownList *list = GetRailTypeDropDownList();
+ if (_settings_client.gui.compact_vertical_toolbar) {
+ const Company *c = Company::Get(_local_company);
+ *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION, RAILTYPE_END + ROADTYPE_ROAD, false);
+ *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION, RAILTYPE_END + ROADTYPE_TRAM, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM));
+ *list->Append() = new DropDownListStringItem(STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, RAILTYPE_END + WID_TN_WATER, false);
+ *list->Append() = new DropDownListStringItem(STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, RAILTYPE_END + WID_TN_AIR, false);
+ }
+ ShowDropDownList(w, list, _last_built_railtype, WID_TN_RAILS, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
return CBF_NONE;
}
+static CallBackFunction MenuClickBuildRoad(int index);
+static CallBackFunction MenuClickBuildWater(int index);
+static CallBackFunction MenuClickBuildAir(int index);
+
/**
* Handle click on the entry in the Build Rail menu.
*
@@ -894,6 +930,16 @@ static CallBackFunction ToolbarBuildRailClick(Window *w)
*/
static CallBackFunction MenuClickBuildRail(int index)
{
+ switch (index) {
+ case RAILTYPE_END + ROADTYPE_ROAD:
+ return MenuClickBuildRoad(ROADTYPE_ROAD);
+ case RAILTYPE_END + ROADTYPE_TRAM:
+ return MenuClickBuildRoad(ROADTYPE_TRAM);
+ case RAILTYPE_END + WID_TN_WATER:
+ return MenuClickBuildWater(0);
+ case RAILTYPE_END + WID_TN_AIR:
+ return MenuClickBuildAir(0);
+ }
_last_built_railtype = (RailType)index;
ShowBuildRailToolbar(_last_built_railtype);
return CBF_NONE;
@@ -918,7 +964,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;
}
@@ -1052,14 +1098,34 @@ 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;
}
}
static CallBackFunction ToolbarHelpClick(Window *w)
{
- PopupMainToolbMenu(w, WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 13 : 10);
+ DropDownList *list = new DropDownList();
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_LAND_BLOCK_INFO, 0, false);
+ *list->Append() = new DropDownListStringItem(STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT, 1, false);
+ *list->Append() = new DropDownListStringItem(STR_NEWS_MENU_MESSAGE_HISTORY_MENU, 2, false);
+ *list->Append() = new DropDownListStringItem(STR_TOOLBAR_SOUND_MUSIC, 3, false);
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_TUTORIAL, 4, false);
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_TOGGLE_CONSOLE, 5, false);
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_AI_DEBUG, 6, false);
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_SCREENSHOT, 7, false);
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_ZOOMIN_SCREENSHOT, 8, false);
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT, 9, false);
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_GIANT_SCREENSHOT, 10, false);
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_SHOW_FRAMERATE, 11, false);
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_ABOUT_OPENTTD, 12, false);
+ if (_settings_client.gui.newgrf_developer_tools) {
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_SPRITE_ALIGNER, 13, false);
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES, 14, false);
+ *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS, 15, false);
+ }
+ ShowDropDownList(w, list, 0, WID_TN_HELP, 140, true);
+ if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
return CBF_NONE;
}
@@ -1155,17 +1221,21 @@ static CallBackFunction MenuClickHelp(int index)
{
switch (index) {
case 0: return PlaceLandBlockInfo();
- case 2: IConsoleSwitch(); break;
- case 3: ShowAIDebugWindow(); break;
- case 4: MenuClickSmallScreenshot(); break;
- case 5: MenuClickLargeWorldScreenshot(SC_ZOOMEDIN); break;
- case 6: MenuClickLargeWorldScreenshot(SC_DEFAULTZOOM); break;
- case 7: MenuClickLargeWorldScreenshot(SC_WORLD); break;
- case 8: ShowFramerateWindow(); break;
- case 9: ShowAboutWindow(); break;
- case 10: ShowSpriteAlignerWindow(); break;
- case 11: ToggleBoundingBoxes(); break;
- case 12: ToggleDirtyBlocks(); break;
+ case 1: ShowLastNewsMessage(); break;
+ case 2: ShowMessageHistory(); break;
+ case 3: ShowMusicWindow(); break;
+ case 4: ShowTutorialWindow(); break;
+ case 5: IConsoleSwitch(); break;
+ case 6: ShowAIDebugWindow(); break;
+ case 7: MenuClickSmallScreenshot(); break;
+ case 8: MenuClickLargeWorldScreenshot(SC_ZOOMEDIN); break;
+ case 9: MenuClickLargeWorldScreenshot(SC_DEFAULTZOOM); break;
+ case 10: MenuClickLargeWorldScreenshot(SC_WORLD); break;
+ case 11: ShowFramerateWindow(); break;
+ case 12: ShowAboutWindow(); break;
+ case 13: ShowSpriteAlignerWindow(); break;
+ case 14: ToggleBoundingBoxes(); break;
+ case 15: ToggleDirtyBlocks(); break;
}
return CBF_NONE;
}
@@ -1186,6 +1256,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. */
/**
@@ -1328,7 +1432,7 @@ protected:
uint spacers; ///< Number of spacer widgets in this toolbar
public:
- NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL)
+ NWidgetToolbarContainer(WidgetType widgetType = NWID_HORIZONTAL) : NWidgetContainer(widgetType)
{
}
@@ -1339,27 +1443,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++;
}
@@ -1367,11 +1479,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;
}
@@ -1403,6 +1529,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;
@@ -1423,12 +1553,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--;
@@ -1482,8 +1622,8 @@ public:
class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
/* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
{
- static const uint SMALLEST_ARRANGEMENT = 14;
- static const uint BIGGEST_ARRANGEMENT = 20;
+ uint SMALLEST_ARRANGEMENT = 14 + (_settings_client.gui.build_confirmation ? 1 : 2);
+ uint BIGGEST_ARRANGEMENT = 20 + (_settings_client.gui.build_confirmation ? 1 : 2);
/* The number of buttons of each row of the toolbar should match the number of items which we want to be visible.
* The total number of buttons should be equal to arrangable_count * 2.
@@ -1505,6 +1645,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_WATER,
WID_TN_AIR,
WID_TN_LANDSCAPE,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
// lower toolbar
WID_TN_SETTINGS,
@@ -1520,6 +1661,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_MUSIC_SOUND,
WID_TN_MESSAGES,
WID_TN_HELP,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
};
static const byte arrange15[] = {
@@ -1537,6 +1679,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_LANDSCAPE,
WID_TN_ZOOM_IN,
WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
// lower toolbar
WID_TN_PAUSE,
@@ -1553,6 +1696,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_MUSIC_SOUND,
WID_TN_MESSAGES,
WID_TN_HELP,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
};
static const byte arrange16[] = {
@@ -1571,6 +1715,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_LANDSCAPE,
WID_TN_ZOOM_IN,
WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
// lower toolbar
WID_TN_PAUSE,
@@ -1588,6 +1733,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_HELP,
WID_TN_ZOOM_IN,
WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
};
static const byte arrange17[] = {
@@ -1607,6 +1753,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_LANDSCAPE,
WID_TN_ZOOM_IN,
WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
// lower toolbar
WID_TN_PAUSE,
@@ -1625,6 +1772,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_HELP,
WID_TN_ZOOM_IN,
WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
};
static const byte arrange18[] = {
@@ -1645,6 +1793,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_LANDSCAPE,
WID_TN_ZOOM_IN,
WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
// lower toolbar
WID_TN_PAUSE,
@@ -1664,6 +1813,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_HELP,
WID_TN_ZOOM_IN,
WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
};
static const byte arrange19[] = {
@@ -1685,6 +1835,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_MUSIC_SOUND,
WID_TN_ZOOM_IN,
WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
// lower toolbar
WID_TN_PAUSE,
@@ -1705,6 +1856,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_HELP,
WID_TN_ZOOM_IN,
WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
};
static const byte arrange20[] = {
@@ -1727,6 +1879,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_GOAL,
WID_TN_ZOOM_IN,
WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
// lower toolbar
WID_TN_PAUSE,
@@ -1748,6 +1901,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_HELP,
WID_TN_ZOOM_IN,
WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
WID_TN_SWITCH_BAR,
};
static const byte arrange_all[] = {
@@ -1779,19 +1933,345 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
WID_TN_LANDSCAPE,
WID_TN_MUSIC_SOUND,
WID_TN_MESSAGES,
+ WID_TN_CTRL,
WID_TN_HELP
};
+ /* With 'Shift' button included */
+ static const byte arrange14shift[] = {
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ // lower toolbar
+ WID_TN_SETTINGS,
+ WID_TN_SAVE,
+ WID_TN_SMALL_MAP,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_GRAPHS,
+ WID_TN_INDUSTRIES,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_MESSAGES,
+ WID_TN_HELP,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ };
+ static const byte arrange15shift[] = {
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SMALL_MAP,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ // lower toolbar
+ WID_TN_PAUSE,
+ WID_TN_SETTINGS,
+ WID_TN_SMALL_MAP,
+ WID_TN_SAVE,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_GRAPHS,
+ WID_TN_INDUSTRIES,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_MESSAGES,
+ WID_TN_HELP,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ };
+ static const byte arrange16shift[] = {
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SETTINGS,
+ WID_TN_SMALL_MAP,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ // lower toolbar
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SAVE,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_GRAPHS,
+ WID_TN_INDUSTRIES,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_MESSAGES,
+ WID_TN_HELP,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ };
+ static const byte arrange17shift[] = {
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SETTINGS,
+ WID_TN_SMALL_MAP,
+ WID_TN_SUBSIDIES,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ // lower toolbar
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SAVE,
+ WID_TN_SMALL_MAP,
+ WID_TN_SUBSIDIES,
+ WID_TN_TOWNS,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_GRAPHS,
+ WID_TN_INDUSTRIES,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_MESSAGES,
+ WID_TN_HELP,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ };
+ static const byte arrange18shift[] = {
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SETTINGS,
+ WID_TN_SMALL_MAP,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_INDUSTRIES,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ // lower toolbar
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SAVE,
+ WID_TN_SMALL_MAP,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ WID_TN_STATIONS,
+ WID_TN_GRAPHS,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_MESSAGES,
+ WID_TN_HELP,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ };
+ static const byte arrange19shift[] = {
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SETTINGS,
+ WID_TN_SMALL_MAP,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ // lower toolbar
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SAVE,
+ WID_TN_SMALL_MAP,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_GRAPHS,
+ WID_TN_INDUSTRIES,
+ WID_TN_MESSAGES,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_HELP,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ };
+ static const byte arrange20shift[] = {
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SETTINGS,
+ WID_TN_SMALL_MAP,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_GOAL,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ // lower toolbar
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SAVE,
+ WID_TN_SMALL_MAP,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_GRAPHS,
+ WID_TN_INDUSTRIES,
+ WID_TN_MESSAGES,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_STORY,
+ WID_TN_HELP,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_SWITCH_BAR,
+ };
+ static const byte arrange_all_shift[] = {
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SETTINGS,
+ WID_TN_SAVE,
+ WID_TN_SMALL_MAP,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_STORY,
+ WID_TN_GOAL,
+ WID_TN_GRAPHS,
+ WID_TN_LEAGUE,
+ WID_TN_INDUSTRIES,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_MESSAGES,
+ WID_TN_HELP,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ };
/* If at least BIGGEST_ARRANGEMENT fit, just spread all the buttons nicely */
uint full_buttons = max(CeilDiv(width, this->smallest_x), SMALLEST_ARRANGEMENT);
if (full_buttons > BIGGEST_ARRANGEMENT) {
- button_count = arrangable_count = lengthof(arrange_all);
+ button_count = arrangable_count = _settings_client.gui.build_confirmation ? lengthof(arrange_all) : lengthof(arrange_all_shift);
spacer_count = this->spacers;
- return arrange_all;
+ return _settings_client.gui.build_confirmation ? arrange_all : arrange_all_shift;
}
/* Introduce the split toolbar */
- static const byte * const arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19, arrange20 };
+ static const byte * const arrangements_noshift[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19, arrange20 };
+
+ static const byte * const arrangements_shift[] = { arrange14shift, arrange15shift, arrange16shift, arrange17shift, arrange18shift, arrange19shift, arrange20shift };
+
+ const byte * const * arrangements = _settings_client.gui.build_confirmation ? arrangements_noshift : arrangements_shift;
button_count = arrangable_count = full_buttons;
spacer_count = this->spacers;
@@ -1799,6 +2279,228 @@ 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
+ {
+ // Ultra-compact arrangement, ultra-huge buttons.
+ // No WID_TN_SHIFT, WID_TN_STORY, WID_TN_GOAL, and WID_TN_LEAGUE buttons.
+ static const byte arrange_left_compact[] = {
+ WID_TN_DELETE,
+ WID_TN_CTRL,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SETTINGS,
+ WID_TN_SAVE,
+ WID_TN_SMALL_MAP,
+ WID_TN_STATIONS,
+ };
+ static const byte arrange_right_compact[] = {
+ WID_TN_SWITCH_BAR,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+
+ WID_TN_SWITCH_BAR,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_GRAPHS,
+ WID_TN_INDUSTRIES,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_MESSAGES,
+ WID_TN_HELP,
+ };
+ static const byte arrange_right_compact_noswitch[] = {
+ WID_TN_RAILS,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_TOWNS,
+ WID_TN_GRAPHS,
+ WID_TN_HELP,
+ };
+
+ // Some rather artistic button arrangement, I'm proud of myself
+ static const byte arrange_left_classic[] = {
+ WID_TN_DELETE,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SETTINGS,
+ WID_TN_SAVE,
+ WID_TN_SMALL_MAP,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ };
+ static const byte arrange_right_classic[] = {
+ WID_TN_SWITCH_BAR,
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_LANDSCAPE,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_GRAPHS,
+ WID_TN_INDUSTRIES,
+ WID_TN_HELP,
+
+ WID_TN_SWITCH_BAR,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_LEAGUE,
+ WID_TN_STATIONS,
+ WID_TN_STORY,
+ WID_TN_GOAL,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_MESSAGES,
+ WID_TN_HELP,
+ };
+ static const byte arrange_right_classic_noswitch[] = {
+ WID_TN_RAILS,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_GRAPHS,
+ WID_TN_LEAGUE,
+ WID_TN_GOAL,
+ WID_TN_HELP,
+ };
+
+ // Full-length toolbar without switch button.
+ // No WID_TN_SHIFT, WID_TN_STORY, WID_TN_GOAL, and WID_TN_LEAGUE buttons.
+ static const byte arrange_left_almost_all[] = {
+ WID_TN_DELETE,
+ WID_TN_CTRL,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SETTINGS,
+ WID_TN_SAVE,
+ WID_TN_SMALL_MAP,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ };
+ static const byte arrange_right_almost_all[] = {
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_LANDSCAPE,
+ WID_TN_GRAPHS,
+ WID_TN_INDUSTRIES,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_MESSAGES,
+ WID_TN_HELP
+ };
+
+ // Full-length toolbar without switch button, all buttons are included.
+ static const byte arrange_left_all[] = {
+ WID_TN_DELETE,
+ WID_TN_CTRL,
+ WID_TN_SHIFT,
+ WID_TN_ZOOM_IN,
+ WID_TN_ZOOM_OUT,
+ WID_TN_PAUSE,
+ WID_TN_FAST_FORWARD,
+ WID_TN_SETTINGS,
+ WID_TN_SAVE,
+ WID_TN_SMALL_MAP,
+ WID_TN_TOWNS,
+ WID_TN_SUBSIDIES,
+ WID_TN_STATIONS,
+ WID_TN_FINANCES,
+ WID_TN_COMPANIES,
+ WID_TN_STORY,
+ };
+ static const byte arrange_right_all[] = {
+ WID_TN_RAILS,
+ WID_TN_ROADS,
+ WID_TN_WATER,
+ WID_TN_AIR,
+ WID_TN_TRAINS,
+ WID_TN_ROADVEHS,
+ WID_TN_SHIPS,
+ WID_TN_AIRCRAFTS,
+ WID_TN_LANDSCAPE,
+ WID_TN_GOAL,
+ WID_TN_GRAPHS,
+ WID_TN_LEAGUE,
+ WID_TN_INDUSTRIES,
+ WID_TN_MUSIC_SOUND,
+ WID_TN_MESSAGES,
+ WID_TN_HELP
+ };
+
+ 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 (_screen.height / this->smallest_y >= lengthof(arrange_left_almost_all))
+ {
+ button_count = arrangable_count = lengthof(arrange_left_almost_all);
+ if (side == 0) return arrange_left_almost_all;
+ return arrange_right_almost_all;
+ }
+
+ if (_screen.height / this->smallest_y >= lengthof(arrange_left_classic))
+ {
+ button_count = arrangable_count = lengthof(arrange_left_classic);
+ if (side == 0) return arrange_left_classic;
+ if (_settings_client.gui.compact_vertical_toolbar) return arrange_right_classic_noswitch;
+ return &arrange_right_classic[((_toolbar_mode == TB_LOWER) ? button_count : 0)];
+ }
+
+ button_count = arrangable_count = lengthof(arrange_left_compact);
+ if (side == 0) return arrange_left_compact;
+ if (_settings_client.gui.compact_vertical_toolbar) return arrange_right_compact_noswitch;
+ return &arrange_right_compact[((_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)
@@ -1946,6 +2648,9 @@ static ToolbarButtonProc * const _toolbar_button_procs[] = {
ToolbarNewspaperClick,
ToolbarHelpClick,
ToolbarSwitchClick,
+ ToolbarCtrlClick,
+ ToolbarShiftClick,
+ ToolbarDeleteClick,
};
enum MainToolbarHotkeys {
@@ -1992,8 +2697,10 @@ enum MainToolbarHotkeys {
/** Main toolbar. */
struct MainToolbarWindow : Window {
GUITimer timer;
+ int *clickedFlag;
+ int clickedValue;
- MainToolbarWindow(WindowDesc *desc) : Window(desc)
+ MainToolbarWindow(WindowDesc *desc, int *clickedFlag = NULL, int clickedValue = 0) : Window(desc), clickedFlag(clickedFlag), clickedValue(clickedValue)
{
this->InitNested(0);
@@ -2032,11 +2739,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;
}
@@ -2100,7 +2811,7 @@ struct MainToolbarWindow : Window {
ShowLandInfo(tile);
break;
- default: NOT_REACHED();
+ default: return; //NOT_REACHED();
}
}
@@ -2201,44 +2912,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:
@@ -2249,10 +2960,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;
}
@@ -2268,6 +2984,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 */
@@ -2603,6 +3372,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 17449854d6..dae8696a72 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);
@@ -568,7 +571,6 @@ static const NWidgetPart _nested_town_editor_view_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
NWidget(WWT_CAPTION, COLOUR_BROWN, WID_TV_CAPTION), SetDataTip(STR_TOWN_VIEW_TOWN_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CHANGE_NAME), SetMinimalSize(76, 14), SetDataTip(STR_BUTTON_RENAME, STR_TOWN_VIEW_RENAME_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
@@ -581,6 +583,7 @@ static const NWidgetPart _nested_town_editor_view_widgets[] = {
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TV_INFO), SetMinimalSize(260, 32), SetResize(1, 0), SetFill(1, 0), EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CHANGE_NAME), SetMinimalSize(76, 14), SetDataTip(STR_BUTTON_RENAME, STR_TOWN_VIEW_RENAME_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CENTER_VIEW), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_BUTTON_LOCATION, STR_TOWN_VIEW_CENTER_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_EXPAND), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_TOWN_VIEW_EXPAND_BUTTON, STR_TOWN_VIEW_EXPAND_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_DELETE), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_TOWN_VIEW_DELETE_BUTTON, STR_TOWN_VIEW_DELETE_TOOLTIP),
@@ -616,7 +619,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(),
@@ -838,7 +841,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;
@@ -990,61 +993,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(),
};
@@ -1073,6 +1080,10 @@ public:
this->UpdateButtons(true);
}
+ ~FoundTownWindow() {
+ if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort();
+ }
+
void RandomTownName()
{
this->townnamevalid = GenerateTownName(&this->townnameparts);
@@ -1177,11 +1188,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);
}
@@ -1199,7 +1224,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)
@@ -1208,5 +1233,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..575d63514e
--- /dev/null
+++ b/src/tutorial_gui.cpp
@@ -0,0 +1,227 @@
+/* $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()
+{
+ // Close button on tutorial window is gone, so don't show that windows on first run, it's confusing
+#if 0
+ 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();
+#endif
+}
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 777716c646..4036744599 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;
@@ -1791,7 +1792,6 @@ static const NWidgetPart _nested_nontrain_vehicle_details_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_VD_CAPTION), SetDataTip(STR_VEHICLE_DETAILS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_RENAME_VEHICLE), SetMinimalSize(40, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_VEHICLE_NAME_BUTTON, STR_NULL /* filled in later */),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -1799,6 +1799,7 @@ static const NWidgetPart _nested_nontrain_vehicle_details_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_TOP_DETAILS), SetMinimalSize(405, 42), SetResize(1, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_MIDDLE_DETAILS), SetMinimalSize(405, 45), SetResize(1, 0), EndContainer(),
NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_RENAME_VEHICLE), SetMinimalSize(40, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_VEHICLE_NAME_BUTTON, STR_NULL /* filled in later */),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_VD_DECREASE_SERVICING_INTERVAL), SetFill(0, 1),
SetDataTip(AWV_DECREASE, STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_VD_INCREASE_SERVICING_INTERVAL), SetFill(0, 1),
@@ -1815,7 +1816,6 @@ static const NWidgetPart _nested_train_vehicle_details_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_VD_CAPTION), SetDataTip(STR_VEHICLE_DETAILS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_RENAME_VEHICLE), SetMinimalSize(40, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_VEHICLE_NAME_BUTTON, STR_NULL /* filled in later */),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
@@ -1835,6 +1835,7 @@ static const NWidgetPart _nested_train_vehicle_details_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_SERVICING_INTERVAL), SetFill(1, 1), SetResize(1, 0), EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_RENAME_VEHICLE), SetMinimalSize(40, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_VEHICLE_NAME_BUTTON, STR_NULL /* filled in later */),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_DETAILS_CARGO_CARRIED), SetMinimalSize(96, 12),
SetDataTip(STR_VEHICLE_DETAIL_TAB_CARGO, STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_DETAILS_TRAIN_VEHICLES), SetMinimalSize(99, 12),
@@ -2659,8 +2660,8 @@ public:
int image_left = (rtl ? text_right + 1 : r.left) + WD_IMGBTN_LEFT;
int image = ((v->vehstatus & VS_STOPPED) != 0) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING;
int lowered = this->IsWidgetLowered(WID_VV_START_STOP) ? 1 : 0;
- DrawSprite(image, PAL_NONE, image_left + lowered, r.top + WD_IMGBTN_TOP + lowered);
- DrawString(text_left + lowered, text_right + lowered, r.top + WD_FRAMERECT_TOP + lowered, str, TC_FROMSTRING, SA_HOR_CENTER);
+ DrawSprite(image, PAL_NONE, image_left + lowered, Center(r.top, r.bottom - r.top) + WD_IMGBTN_TOP + lowered);
+ DrawString(text_left + lowered, text_right + lowered, Center(r.top, r.bottom - r.top) + lowered, str, TC_FROMSTRING, SA_HOR_CENTER);
}
virtual void OnClick(Point pt, int widget, int click_count)
diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp
index 8493ae89fc..eb35240364 100644
--- a/src/video/sdl_v.cpp
+++ b/src/video/sdl_v.cpp
@@ -23,8 +23,15 @@
#include "../core/math_func.hpp"
#include "../fileio_func.h"
#include "../framerate_type.h"
+#include "../settings_type.h"
+#include "../tilehighlight_func.h"
+#include "../viewport_func.h"
#include "sdl_v.h"
#include
+#ifdef __ANDROID__
+#include
+#include
+#endif
#include "../safeguards.h"
@@ -50,6 +57,9 @@ static int _num_dirty_rects;
static int _use_hwpalette;
static int _requested_hwpalette; /* Did we request a HWPALETTE for the current video mode? */
+static SDL_Joystick * _multitouch_device = NULL;
+static Point _multitouch_second_point;
+
void VideoDriver_SDL::MakeDirty(int left, int top, int width, int height)
{
if (_num_dirty_rects < MAX_DIRTY_RECTS) {
@@ -151,7 +161,11 @@ static void DrawSurfaceToScreen()
PerformanceMeasurer framerate(PFE_VIDEO);
int n = _num_dirty_rects;
+#ifdef __ANDROID__
+ if (n == 0 && !_left_button_down) return; // We have to update the screen regularly to receive mouse_up event on Android
+#else
if (n == 0) return;
+#endif
_num_dirty_rects = 0;
if (n > MAX_DIRTY_RECTS) {
@@ -165,7 +179,9 @@ static void DrawSurfaceToScreen()
SDL_BlitSurface(_sdl_screen, &_dirty_rects[i], _sdl_realscreen, &_dirty_rects[i]);
}
}
- SDL_UpdateRects(_sdl_realscreen, n, _dirty_rects);
+ static SDL_Rect dummy_rect = { 0, 0, 8, 8 };
+ if (n > 0) SDL_UpdateRects(_sdl_realscreen, n, _dirty_rects);
+ else SDL_UpdateRects(_sdl_realscreen, 1, &dummy_rect);
}
}
@@ -405,6 +421,14 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h)
GameSizeChanged();
+#ifdef __ANDROID__
+ if (!_multitouch_device) {
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+ _multitouch_device = SDL_JoystickOpen(0);
+ }
+ SDL_ANDROID_SetSystemMousePointerVisible(0); // We have our own cursor, only works on Android N
+#endif
+
return true;
}
@@ -505,6 +529,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
@@ -528,7 +554,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_WarpMouse(_cursor.pos.x, _cursor.pos.y);
+#endif
}
HandleMouseEvents();
break;
@@ -546,10 +574,30 @@ 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;
+#ifdef __ANDROID__
+ case SDL_BUTTON_WHEELUP:
+ case SDL_BUTTON_WHEELDOWN:
+ _cursor.wheel += (ev.button.button == SDL_BUTTON_WHEELDOWN) ? 1 : -1;
+ _right_button_down = false;
+ // Center the mouse cursor between touch points
+ SDL_GetMouseState(&_cursor.pos.x, &_cursor.pos.y);
+ _cursor.pos.x = (_cursor.pos.x + _multitouch_second_point.x) / 2;
+ _cursor.pos.y = (_cursor.pos.y + _multitouch_second_point.y) / 2;
+ //_cursor.UpdateCursorPosition(_cursor.pos.x, _cursor.pos.y, false);
+ break;
+#else
case SDL_BUTTON_WHEELUP: _cursor.wheel--; break;
case SDL_BUTTON_WHEELDOWN: _cursor.wheel++; break;
+#endif
default: break;
}
@@ -564,12 +612,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;
@@ -580,7 +636,7 @@ int VideoDriver_SDL::PollEvent()
_cursor.in_window = false;
}
break;
-
+#endif /* not __ANDROID__ */
case SDL_QUIT:
HandleExitGameRequest();
break;
@@ -593,15 +649,42 @@ 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;
+#ifdef __ANDROID__
+ case SDL_JOYBALLMOTION:
+ if (ev.jball.which == 0 && ev.jball.ball == 1) {
+ _multitouch_second_point.x = ev.jball.xrel;
+ _multitouch_second_point.y = ev.jball.yrel;
+ }
+ break;
+#endif /* not __ANDROID__ */
+#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
@@ -641,6 +724,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;
}
@@ -734,8 +820,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 =
@@ -756,7 +844,9 @@ void VideoDriver_SDL::MainLoop()
* except sleeping can't. */
if (_draw_mutex != NULL) _draw_mutex->EndCritical();
- GameLoop();
+ for (int i = (_fast_forward ? 5 : 1); i > 0; i--) {
+ GameLoop();
+ }
if (_draw_mutex != NULL) _draw_mutex->BeginCritical();
diff --git a/src/viewport.cpp b/src/viewport.cpp
index 07cecb556e..3f6619490e 100644
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -88,6 +88,7 @@
#include "command_func.h"
#include "network/network_func.h"
#include "framerate_type.h"
+#include "build_confirmation_func.h"
#include