diff --git a/.ottdrev b/.ottdrev new file mode 100644 index 0000000000..89af2c77e7 --- /dev/null +++ b/.ottdrev @@ -0,0 +1 @@ +1.6.1 27609 0 1.6.1 diff --git a/android-extract-strings.sh b/android-extract-strings.sh new file mode 100755 index 0000000000..f03e4bace8 --- /dev/null +++ b/android-extract-strings.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +mkdir -p ../translations/lang +git diff 1.6/master -- src/lang/english.txt | tail -n +5 | grep '^[+]' | cut -b 2- | \ +grep -v "^STR_TABLET_CLOSE\b" | \ +grep -v "^STR_TABLET_SHIFT\b" | \ +grep -v "^STR_TABLET_CTRL\b" | \ +cat > ../translations/lang/english.txt + +for f in src/lang/*.txt; do + [ "$f" = src/lang/english.txt ] && continue + rm -f ../translations/lang/`basename $f` + cat ../translations/lang/english.txt | grep '^STR' | while read name text; do + grep "^$name\b" $f >> ../translations/lang/`basename $f` + done +done diff --git a/android-store-strings.sh b/android-store-strings.sh new file mode 100755 index 0000000000..70781d22b7 --- /dev/null +++ b/android-store-strings.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +for f in ../translations/lang/*.txt; do + [ "$f" = ../translations/lang/english.txt ] && continue + out=src/lang/`basename $f` + grep "^# Android strings" $out > /dev/null || [ -z "`tail -c 2 $out`" ] || echo >> $out + { grep -v "^# Android strings" $out ; echo "# Android strings" ; } > $out.new + mv -f $out.new $out + cat $f | grep '^STR' | while read name text; do + { grep -v "^$name\b" $out ; printf "%-64s%s\n" "$name" "$text" ; } > $out.new + mv -f $out.new $out + done +done diff --git a/config.lib b/config.lib index 3d10aaa3fd..df5a01adf2 100644 --- a/config.lib +++ b/config.lib @@ -1048,7 +1048,7 @@ check_params() { # of the tags folder, the folder of the tag does not have a .svn folder # anymore and this fails to detect the subversion repository checkout. log 1 "checking revision... svn detection (tag)" - elif [ -d "$ROOT_DIR/.git" ] && [ -n "`git help 2>/dev/null`" ]; then + elif [ -e "$ROOT_DIR/.git" ] && [ -n "`git help 2>/dev/null`" ]; then log 1 "checking revision... git detection" elif [ -d "$ROOT_DIR/.hg" ] && [ -n "`HGPLAIN= hg help 2>/dev/null`" ]; then log 1 "checking revision... hg detection" diff --git a/configure b/configure index 5edbca1867..0510e4dd22 100755 --- a/configure +++ b/configure @@ -127,7 +127,7 @@ AWKCOMMAND=' if ($0 == "WINCE" && "'$os'" != "WINCE") { next; } if ($0 == "MSVC" && "'$os'" != "MSVC") { next; } if ($0 == "DIRECTMUSIC" && "'$with_direct_music'" == "0") { next; } - if ($0 == "LIBTIMIDITY" && "'$libtimidity'" == "" ) { next; } + if ($0 == "LIBTIMIDITY" && "'$libtimidity_config'" == "" ) { next; } if ($0 == "HAVE_THREAD" && "'$with_threads'" == "0") { next; } if ($0 == "SSE" && "'$with_sse'" != "1") { next; } diff --git a/findversion.sh b/findversion.sh index 6be52b696f..bcae7b1989 100755 --- a/findversion.sh +++ b/findversion.sh @@ -70,7 +70,11 @@ ROOT_DIR=`pwd` # Determine if we are using a modified version # Assume the dir is not modified MODIFIED="0" -if [ -d "$ROOT_DIR/.svn" ] || [ -d "$ROOT_DIR/../.svn" ]; then +if [ -f "$ROOT_DIR/.ottdrev" ]; then + # We are an exported source bundle + cat $ROOT_DIR/.ottdrev + exit +elif [ -d "$ROOT_DIR/.svn" ] || [ -d "$ROOT_DIR/../.svn" ]; then # We are an svn checkout if [ -n "`svnversion | grep 'M'`" ]; then MODIFIED="2" @@ -84,7 +88,7 @@ if [ -d "$ROOT_DIR/.svn" ] || [ -d "$ROOT_DIR/../.svn" ]; then else REV="r$REV_NR" fi -elif [ -d "$ROOT_DIR/.git" ]; then +elif [ -e "$ROOT_DIR/.git" ]; then # We are a git checkout # Refresh the index to make sure file stat info is in sync, then look for modifications git update-index --refresh >/dev/null @@ -122,10 +126,6 @@ elif [ -d "$ROOT_DIR/.hg" ]; then # No rev? Maybe it is a custom hgsubversion clone REV_NR=`LC_ALL=C HGPLAIN= hg parent --template="{svnrev}"` fi -elif [ -f "$ROOT_DIR/.ottdrev" ]; then - # We are an exported source bundle - cat $ROOT_DIR/.ottdrev - exit else # We don't know MODIFIED="1" @@ -134,6 +134,7 @@ else REV_NR="" fi +MODIFIED="0" # This prevents Andorid build from connecting to a public servers if [ "$MODIFIED" -eq "2" ]; then REV="${REV}M" fi diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj index 59e087ee70..dc4ff018a7 100644 --- a/projects/openttd_vs100.vcxproj +++ b/projects/openttd_vs100.vcxproj @@ -626,6 +626,7 @@ + diff --git a/projects/openttd_vs100.vcxproj.filters b/projects/openttd_vs100.vcxproj.filters index 06800ffdaf..608345d9ed 100644 --- a/projects/openttd_vs100.vcxproj.filters +++ b/projects/openttd_vs100.vcxproj.filters @@ -1107,6 +1107,9 @@ Header Files + + Header Files + Header Files diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj index 70dcab226a..624242d5bf 100644 --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -1778,6 +1778,10 @@ RelativePath=".\..\src\timetable.h" > + + diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj index dd722d085d..1c9d3226db 100644 --- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -1775,6 +1775,10 @@ RelativePath=".\..\src\timetable.h" > + + diff --git a/source.list b/source.list index df35cdd26e..f7c8096d57 100644 --- a/source.list +++ b/source.list @@ -93,6 +93,7 @@ tgp.cpp tile_map.cpp tilearea.cpp townname.cpp +tutorial_gui.cpp #if WIN32 #else #if WINCE @@ -143,6 +144,7 @@ base_media_func.h base_station_base.h bmp.h bridge.h +build_confirmation_func.h cargo_type.h cargoaction.h cargomonitor.h @@ -365,6 +367,7 @@ tilehighlight_func.h tilehighlight_type.h tilematrix_type.hpp timetable.h +toolbar_type.h toolbar_gui.h town.h town_type.h @@ -451,6 +454,7 @@ airport_gui.cpp autoreplace_gui.cpp bootstrap_gui.cpp bridge_gui.cpp +build_confirmation_gui.cpp build_vehicle_gui.cpp cheat_gui.cpp company_gui.cpp @@ -906,6 +910,12 @@ script/api/script_window.cpp # Blitters #if DEDICATED #else +blitter/16bpp_base.cpp +blitter/16bpp_base.hpp +blitter/16bpp_anim.cpp +blitter/16bpp_anim.hpp +blitter/16bpp_simple.cpp +blitter/16bpp_simple.hpp blitter/32bpp_anim.cpp blitter/32bpp_anim.hpp #if SSE @@ -1113,7 +1123,10 @@ music/null_m.cpp #else #if MORPHOS #else - music/extmidi.cpp + #if LIBTIMIDITY + #else + music/extmidi.cpp + #end #end #end #end diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index a0720e2ea5..a49513009d 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -109,7 +109,7 @@ struct AIListWindow : public Window { virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { if (widget == WID_AIL_LIST) { - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM); resize->width = 1; resize->height = this->line_height; @@ -122,16 +122,16 @@ struct AIListWindow : public Window { switch (widget) { case WID_AIL_LIST: { /* Draw a list of all available AIs. */ - int y = this->GetWidget(WID_AIL_LIST)->pos_y; + int y = Center(r.top, this->line_height); /* First AI in the list is hardcoded to random */ if (this->vscroll->IsVisible(0)) { - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_LEFT, y + WD_MATRIX_TOP, this->slot == OWNER_DEITY ? STR_AI_CONFIG_NONE : STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_ORANGE); + DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_LEFT, y, this->slot == OWNER_DEITY ? STR_AI_CONFIG_NONE : STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_ORANGE); y += this->line_height; } ScriptInfoList::const_iterator it = this->info_list->begin(); for (int i = 1; it != this->info_list->end(); i++, it++) { if (this->vscroll->IsVisible(i)) { - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, (*it).second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE); + DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y, (*it).second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE); y += this->line_height; } } @@ -347,7 +347,7 @@ struct AISettingsWindow : public Window { virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { if (widget == WID_AIS_BACKGROUND) { - this->line_height = max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM); resize->width = 1; resize->height = this->line_height; @@ -369,7 +369,6 @@ struct AISettingsWindow : public Window { uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8); uint text_right = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT); - int y = r.top; int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; @@ -414,7 +413,7 @@ struct AISettingsWindow : public Window { } } - DrawString(text_left, text_right, y + text_y_offset, str, colour); + DrawString(text_left, text_right, Center(y, this->line_height), str, colour); y += this->line_height; } } @@ -662,39 +661,41 @@ static const NWidgetPart _nested_ai_config_widgets[] = { NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), EndContainer(), NWidget(WWT_PANEL, COLOUR_MAUVE, WID_AIC_BACKGROUND), - NWidget(NWID_VERTICAL), SetPIP(4, 4, 4), - NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7), - NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_DECREASE), SetFill(0, 1), SetDataTip(AWV_DECREASE, STR_NULL), - NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_INCREASE), SetFill(0, 1), SetDataTip(AWV_INCREASE, STR_NULL), - NWidget(NWID_SPACER), SetMinimalSize(6, 0), - NWidget(WWT_TEXT, COLOUR_MAUVE, WID_AIC_NUMBER), SetDataTip(STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS, STR_NULL), SetFill(1, 0), SetPadding(1, 0, 0, 0), + NWidget(NWID_HORIZONTAL), SetPIP(7, 7, 7), + NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_AI, STR_NULL), SetPadding(0, 5, 0, 5), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIC_LIST), SetMinimalSize(288, 112), SetFill(1, 0), SetMatrixDataTip(1, 8, STR_AI_CONFIG_AILIST_TOOLTIP), SetScrollbar(WID_AIC_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_AIC_SCROLLBAR), + EndContainer(), EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_UP), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_UP, STR_AI_CONFIG_MOVE_UP_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_DOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_DOWN, STR_AI_CONFIG_MOVE_DOWN_TOOLTIP), + NWidget(NWID_VERTICAL), SetPIP(4, 4, 4), + NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7), + NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_DECREASE), SetFill(0, 1), SetDataTip(AWV_DECREASE, STR_NULL), + NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_INCREASE), SetFill(0, 1), SetDataTip(AWV_INCREASE, STR_NULL), + NWidget(NWID_SPACER), SetMinimalSize(6, 0), + NWidget(WWT_TEXT, COLOUR_MAUVE, WID_AIC_NUMBER), SetDataTip(STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS, STR_NULL), SetFill(1, 0), SetPadding(1, 0, 0, 0), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_UP), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_UP, STR_AI_CONFIG_MOVE_UP_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_DOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_DOWN, STR_AI_CONFIG_MOVE_DOWN_TOOLTIP), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 9), + NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_GAMESCRIPT, STR_NULL), SetPadding(0, 5, 4, 5), + NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIC_GAMELIST), SetSizingType(NWST_STEP), SetMinimalSize(288, 14), SetFill(1, 0), SetMatrixDataTip(1, 1, STR_AI_CONFIG_GAMELIST_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CHANGE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_CONFIG_CHANGE, STR_AI_CONFIG_CHANGE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CONFIGURE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_CONFIG_CONFIGURE, STR_AI_CONFIG_CONFIGURE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CLOSE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), + EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CONTENT_DOWNLOAD), SetFill(1, 0), SetMinimalSize(279, 12), SetPadding(0, 7, 9, 7), SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), EndContainer(), EndContainer(), - NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_AI, STR_NULL), SetPadding(0, 5, 0, 5), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIC_LIST), SetMinimalSize(288, 112), SetFill(1, 0), SetMatrixDataTip(1, 8, STR_AI_CONFIG_AILIST_TOOLTIP), SetScrollbar(WID_AIC_SCROLLBAR), - NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_AIC_SCROLLBAR), - EndContainer(), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 9), - NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_GAMESCRIPT, STR_NULL), SetPadding(0, 5, 4, 5), - NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIC_GAMELIST), SetMinimalSize(288, 14), SetFill(1, 0), SetMatrixDataTip(1, 1, STR_AI_CONFIG_GAMELIST_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CHANGE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_CONFIG_CHANGE, STR_AI_CONFIG_CHANGE_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CONFIGURE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_CONFIG_CONFIGURE, STR_AI_CONFIG_CONFIGURE_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CLOSE), SetFill(1, 0), SetMinimalSize(93, 12), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), - EndContainer(), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CONTENT_DOWNLOAD), SetFill(1, 0), SetMinimalSize(279, 12), SetPadding(0, 7, 9, 7), SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), EndContainer(), }; @@ -759,12 +760,12 @@ struct AIConfigWindow : public Window { { switch (widget) { case WID_AIC_GAMELIST: - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; - size->height = 1 * this->line_height; + this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM); + size->height = this->line_height; break; case WID_AIC_LIST: - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM); size->height = 8 * this->line_height; break; @@ -818,14 +819,14 @@ struct AIConfigWindow : public Window { text = STR_JUST_RAW_STRING; } - DrawString(r.left + 10, r.right - 10, r.top + WD_MATRIX_TOP, text, + DrawString(r.left + 10, r.right - 10, Center(r.top, this->line_height), text, (this->selected_slot == OWNER_DEITY) ? TC_WHITE : (IsEditable(OWNER_DEITY) ? TC_ORANGE : TC_SILVER)); break; } case WID_AIC_LIST: { - int y = r.top; + int y = Center(r.top, this->line_height); for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < MAX_COMPANIES; i++) { StringID text; @@ -837,7 +838,7 @@ struct AIConfigWindow : public Window { } else { text = STR_AI_CONFIG_RANDOM_AI; } - DrawString(r.left + 10, r.right - 10, y + WD_MATRIX_TOP, text, + DrawString(r.left + 10, r.right - 10, y, text, (this->selected_slot == i) ? TC_WHITE : (IsEditable((CompanyID)i) ? TC_ORANGE : TC_SILVER)); y += this->line_height; } @@ -1090,7 +1091,7 @@ struct AIDebugWindow : public Window { virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { if (widget == WID_AID_LOG_PANEL) { - resize->height = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; + resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL); size->height = 14 * resize->height + this->top_offset + this->bottom_offset; } } @@ -1106,6 +1107,8 @@ struct AIDebugWindow : public Window { bool dirty = false; + Dimension d = GetSpriteSize(SPR_COMPANY_ICON); + uint offset_y = Center(0, GetMinSizing(NWST_STEP, d.height + WD_MATRIX_TOP + WD_MATRIX_BOTTOM + 1), d.height); /* Paint the company icons */ for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) { NWidgetCore *button = this->GetWidget(i + WID_AID_COMPANY_BUTTON_START); @@ -1126,7 +1129,7 @@ struct AIDebugWindow : public Window { if (!valid) continue; byte offset = (i == ai_debug_company) ? 1 : 0; - DrawCompanyIcon(i, button->pos_x + button->current_x / 2 - 7 + offset, this->GetWidget(WID_AID_COMPANY_BUTTON_START + i)->pos_y + 2 + offset); + DrawCompanyIcon(i, Center(button->pos_x + offset, button->current_x, d.width), button->pos_y + offset + offset_y); } /* Set button colour for Game Script. */ @@ -1205,7 +1208,7 @@ struct AIDebugWindow : public Window { ScriptLog::LogData *log = this->GetLogPointer(); if (log == NULL) return; - int y = this->top_offset; + int y = Center(this->top_offset, this->resize.step_height); for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < log->used; i++) { int pos = (i + log->pos + 1 - log->used + log->count) % log->count; if (log->lines[pos] == NULL) break; diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 6437f236cd..14442408ce 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -28,6 +28,8 @@ #include "hotkeys.h" #include "vehicle_func.h" #include "gui.h" +#include "command_func.h" +#include "build_confirmation_func.h" #include "widgets/airport_widget.h" @@ -79,6 +81,7 @@ struct BuildAirToolbarWindow : Window { ~BuildAirToolbarWindow() { + if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false); } @@ -113,13 +116,13 @@ struct BuildAirToolbarWindow : Window { } } - virtual void OnPlaceObject(Point pt, TileIndex tile) { switch (this->last_user_action) { - case WID_AT_AIRPORT: - PlaceAirport(tile); + case WID_AT_AIRPORT: { + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_STATION); break; + } case WID_AT_DEMOLISH: PlaceProc_DemolishArea(tile); @@ -127,6 +130,7 @@ struct BuildAirToolbarWindow : Window { default: NOT_REACHED(); } + MoveAllWindowsOffScreen(); } virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) @@ -136,17 +140,29 @@ struct BuildAirToolbarWindow : Window { virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) { - if (pt.x != -1 && select_proc == DDSP_DEMOLISH_AREA) { - GUIPlaceProcDragXY(select_proc, start_tile, end_tile); + if (pt.x == -1) return; + MoveAllHiddenWindowsBackToScreen(); + switch (select_proc) { + case DDSP_BUILD_STATION: + assert(start_tile == end_tile); + PlaceAirport(end_tile); + break; + case DDSP_DEMOLISH_AREA: + GUIPlaceProcDragXY(select_proc, start_tile, end_tile); + break; + default: NOT_REACHED(); } } virtual void OnPlaceObjectAbort() { + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); - - DeleteWindowById(WC_BUILD_STATION, TRANSPORT_AIR); - DeleteWindowById(WC_SELECT_STATION, 0); + if (!ConfirmationWindowShown()) { + DeleteWindowById(WC_BUILD_STATION, TRANSPORT_AIR); + DeleteWindowById(WC_SELECT_STATION, 0); + } + ResetObjectToPlace(); } static HotkeyList hotkeys; @@ -204,7 +220,7 @@ Window *ShowBuildAirToolbar() { if (!Company::IsValidID(_local_company)) return NULL; - DeleteWindowByClass(WC_BUILD_TOOLBAR); + DeleteToolbarLinkedWindows(); return AllocateWindowDescFront(&_air_toolbar_desc, TRANSPORT_AIR); } @@ -305,6 +321,7 @@ public: d.width += padding.width; d.height += padding.height; *size = maxdim(*size, d); + size->height = GetMinSizing(NWST_STEP, size->height); break; } @@ -316,7 +333,7 @@ public: size->width = max(size->width, GetStringBoundingBox(as->name).width); } - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM); size->height = 5 * this->line_height; break; } @@ -368,7 +385,9 @@ public: if (!as->IsAvailable()) { GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->line_height - 2, PC_BLACK, FILLRECT_CHECKER); } - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK); + + DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, Center(y, this->line_height), as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK); + y += this->line_height; } break; @@ -554,35 +573,41 @@ static const NWidgetPart _nested_build_airport_widgets[] = { NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_AIRPORT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), EndContainer(), - NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(1, 0), SetPIP(2, 0, 2), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_AIRPORT_CLASS_LABEL, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_AP_CLASS_DROPDOWN), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_STATION_BUILD_AIRPORT_TOOLTIP), - NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_AIRPORT_SPRITE), SetFill(1, 0), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_MATRIX, COLOUR_GREY, WID_AP_AIRPORT_LIST), SetFill(1, 0), SetMatrixDataTip(1, 5, STR_STATION_BUILD_AIRPORT_TOOLTIP), SetScrollbar(WID_AP_SCROLLBAR), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_AP_SCROLLBAR), + NWidget(NWID_HORIZONTAL), + /* Airport dropdown selector and picture. */ + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(1, 0), SetPIP(2, 0, 2), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetSizingType(NWST_STEP), SetDataTip(STR_STATION_BUILD_AIRPORT_CLASS_LABEL, STR_NULL), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_AP_CLASS_DROPDOWN), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_STATION_BUILD_AIRPORT_TOOLTIP), + NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_AIRPORT_SPRITE), SetFill(1, 0), EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_AP_LAYOUT_DECREASE), SetMinimalSize(12, 0), SetDataTip(AWV_DECREASE, STR_NULL), - NWidget(WWT_LABEL, COLOUR_GREY, WID_AP_LAYOUT_NUM), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NULL), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_AP_LAYOUT_INCREASE), SetMinimalSize(12, 0), SetDataTip(AWV_INCREASE, STR_NULL), - EndContainer(), - NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_EXTRA_TEXT), SetFill(1, 0), SetMinimalSize(150, 0), - EndContainer(), - /* Bottom panel. */ - NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_AP_BOTTOMPANEL), SetPIP(2, 2, 2), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0), - NWidget(NWID_HORIZONTAL), - NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_AP_BTN_DONTHILIGHT), SetMinimalSize(60, 12), SetFill(1, 0), - SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_AP_BTN_DOHILIGHT), SetMinimalSize(60, 12), SetFill(1, 0), - SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), + /* Airport parameters and info. */ + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(1, 0), SetPIP(2, 0, 2), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_AP_AIRPORT_LIST), SetFill(1, 0), SetMatrixDataTip(1, 5, STR_STATION_BUILD_AIRPORT_TOOLTIP), SetScrollbar(WID_AP_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_AP_SCROLLBAR), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_AP_LAYOUT_DECREASE), SetSizingType(NWST_STEP), SetMinimalSize(12, 0), SetDataTip(AWV_DECREASE, STR_NULL), + NWidget(WWT_LABEL, COLOUR_GREY, WID_AP_LAYOUT_NUM), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NULL), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_AP_LAYOUT_INCREASE), SetSizingType(NWST_STEP), SetMinimalSize(12, 0), SetDataTip(AWV_INCREASE, STR_NULL), + EndContainer(), + NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_EXTRA_TEXT), SetFill(1, 0), SetMinimalSize(150, 0), + EndContainer(), + /* Bottom panel. */ + NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_AP_BOTTOMPANEL), SetPIP(2, 2, 2), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_AP_BTN_DONTHILIGHT), SetMinimalSize(60, 12), SetFill(1, 0), + SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_AP_BTN_DOHILIGHT), SetMinimalSize(60, 12), SetFill(1, 0), + SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetResize(0, 1), SetFill(1, 0), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetResize(0, 1), SetFill(1, 0), EndContainer(), }; diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 1074d1dd78..76fcf876ef 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -22,6 +22,7 @@ #include "window_gui.h" #include "engine_gui.h" #include "settings_func.h" +#include "settings_gui.h" #include "core/geometry_func.hpp" #include "rail_gui.h" #include "widgets/dropdown_func.h" @@ -242,7 +243,7 @@ public: switch (widget) { case WID_RV_SORT_ASCENDING_DESCENDING: { Dimension d = GetStringBoundingBox(this->GetWidget(widget)->widget_data); - d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better. + d.width += padding.width + Window::SortButtonWidth(); d.height += padding.height; *size = maxdim(*size, d); break; @@ -251,7 +252,7 @@ public: case WID_RV_LEFT_MATRIX: case WID_RV_RIGHT_MATRIX: resize->height = GetEngineListHeight((VehicleType)this->window_number); - size->height = (this->window_number <= VEH_ROAD ? 8 : 4) * resize->height; + size->height = (widget == WID_RV_RIGHT_MATRIX ? 3 : 4) * resize->height; break; case WID_RV_LEFT_DETAILS: @@ -298,6 +299,7 @@ public: d = maxdim(d, GetStringBoundingBox(rti->strings.replace_text)); } d.width += padding.width; + d.width += SETTING_BUTTON_HEIGHT; d.height += padding.height; *size = maxdim(*size, d); break; @@ -309,6 +311,7 @@ public: d = maxdim(d, GetStringBoundingBox(_start_replace_dropdown[i])); } d.width += padding.width; + d.width += SETTING_BUTTON_HEIGHT; d.height += padding.height; *size = maxdim(*size, d); break; @@ -376,7 +379,7 @@ public: str = STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED; } - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_BLACK, SA_HOR_CENTER); + DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, Center(r.top + WD_FRAMERECT_TOP, r.bottom - r.top - WD_FRAMERECT_TOP), str, TC_BLACK, SA_HOR_CENTER); break; } @@ -598,33 +601,27 @@ static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = { NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_RAILTYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_REPLACE_ENGINE_WAGON_SELECT_HELP), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_LEFT_SCROLLBAR), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(), EndContainer(), NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), SetFill(1, 1), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetDataTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetDataTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP), - NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_RIGHT_SCROLLBAR), + EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_TRAIN_WAGONREMOVE_TOGGLE), SetMinimalSize(138, 12), SetDataTip(STR_REPLACE_REMOVE_WAGON, STR_REPLACE_REMOVE_WAGON_HELP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_RAILTYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_REPLACE_ENGINE_WAGON_SELECT_HELP), EndContainer(), - EndContainer(), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_LEFT_SCROLLBAR), - NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_RIGHT_SCROLLBAR), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(), - NWidget(NWID_VERTICAL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_TRAIN_WAGONREMOVE_TOGGLE), SetMinimalSize(138, 12), SetDataTip(STR_REPLACE_REMOVE_WAGON, STR_REPLACE_REMOVE_WAGON_HELP), SetFill(1, 0), SetResize(1, 0), EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -660,28 +657,26 @@ static const NWidgetPart _nested_replace_vehicle_widgets[] = { EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_LEFT_SCROLLBAR), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(228, 92), SetResize(1, 0), EndContainer(), + EndContainer(), NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetDataTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetDataTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP), - NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_RIGHT_SCROLLBAR), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(228, 92), SetResize(1, 0), EndContainer(), EndContainer(), EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_LEFT_SCROLLBAR), - NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_RIGHT_SCROLLBAR), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(228, 92), SetResize(1, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(228, 92), SetResize(1, 0), EndContainer(), - EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(NWID_PUSHBUTTON_DROPDOWN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetDataTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON), NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_INFO_TAB), SetMinimalSize(167, 12), SetDataTip(0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB), SetResize(1, 0), EndContainer(), diff --git a/src/blitter/16bpp_anim.cpp b/src/blitter/16bpp_anim.cpp new file mode 100644 index 0000000000..115ffe9df5 --- /dev/null +++ b/src/blitter/16bpp_anim.cpp @@ -0,0 +1,386 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file 16bpp_anim.cpp Implementation of the optimized 32 bpp blitter with animation support. */ + +#include "../stdafx.h" +#include "../video/video_driver.hpp" +#include "../zoom_func.h" +#include "16bpp_anim.hpp" + +#include "../table/sprites.h" + +/** Instantiation of the 16bpp with animation blitter factory. */ +static FBlitter_16bppAnim iFBlitter_16bppAnim; + +template +void Blitter_16bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom) +{ + const Pixel *src, *src_line; + Colour16 *dst, *dst_line; + Anim *anim, *anim_line; + + /* Find where to start reading in the source sprite */ + src_line = (const Pixel *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom); + dst_line = (Colour16 *)bp->dst + bp->top * bp->pitch + bp->left; + anim_line = this->anim_buf + ((Colour16 *)bp->dst - (Colour16 *)_screen.dst_ptr) + bp->top * this->anim_buf_width + bp->left; + + for (int y = 0; y < bp->height; y++) { + dst = dst_line; + dst_line += bp->pitch; + + src = src_line; + src_line += bp->sprite_width * ScaleByZoom(1, zoom); + + anim = anim_line; + anim_line += this->anim_buf_width; + + for (int x = 0; x < bp->width; x++) { + switch (mode) { + case BM_COLOUR_REMAP: + /* In case the m-channel is zero, do not remap this pixel in any way */ + anim->m = 0; + anim->v = 0; + if (src->m == 0) { + if (src->a != 0) *dst = ComposeColourPA(src->c, src->a, *dst); + } else { + uint8 r = bp->remap[src->m]; + if (r != 0) { + *dst = ComposeColourPA(AdjustBrightness(LookupColourInPalette(r), src->v), src->a, *dst); + if (src->a == 15 && r >= PALETTE_ANIM_START) { + anim->m = r - PALETTE_ANIM_START + 1; + anim->v = src->v >> 1; + } + } + } + break; + + case BM_TRANSPARENT: + /* TODO -- We make an assumption here that the remap in fact is transparency, not some colour. + * This is never a problem with the code we produce, but newgrfs can make it fail... or at least: + * we produce a result the newgrf maker didn't expect ;) */ + + /* Make the current colour a bit more black, so it looks like this image is transparent */ + if (src->a != 0) *dst = MakeTransparent(*dst, 192); + anim->m = 0; + anim->v = 0; + break; + + default: + if (src->a == 15 && src->m >= PALETTE_ANIM_START) { + *dst = AdjustBrightness(LookupColourInPalette(src->m), src->v); + anim->m = src->m - PALETTE_ANIM_START + 1; + anim->v = src->v >> 1; + } else { + if (src->a != 0) { + if (src->m >= PALETTE_ANIM_START) { + *dst = ComposeColourPANoCheck(AdjustBrightness(LookupColourInPalette(src->m), src->v), src->a, *dst); + } else { + *dst = ComposeColourPA(src->c, src->a, *dst); + } + } + anim->m = 0; + anim->v = 0; + } + break; + } + dst++; + src += ScaleByZoom(1, zoom); + } + } +} + +void Blitter_16bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) +{ + if (_screen_disable_anim) { + /* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent Draw() */ + Blitter_16bppOptimized::Draw(bp, mode, zoom); + return; + } + + switch (mode) { + default: NOT_REACHED(); + case BM_NORMAL: Draw (bp, zoom); return; + case BM_COLOUR_REMAP: Draw(bp, zoom); return; + case BM_TRANSPARENT: Draw (bp, zoom); return; + } +} + +void Blitter_16bppAnim::DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) +{ + if (_screen_disable_anim) { + /* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent DrawColourMappingRect() */ + Blitter_16bppOptimized::DrawColourMappingRect(dst, width, height, pal); + return; + } + + Colour16 *udst = (Colour16 *)dst; + Anim *anim; + + anim = this->anim_buf + ((Colour16 *)dst - (Colour16 *)_screen.dst_ptr); + + if (pal == PALETTE_TO_TRANSPARENT) { + do { + for (int i = 0; i != width; i++) { + *udst = MakeTransparent(*udst, 154); + anim->m = 0; + anim->v = 0; + udst++; + anim++; + } + udst = udst - width + _screen.pitch; + anim = anim - width + this->anim_buf_width; + } while (--height); + return; + } + if (pal == PALETTE_NEWSPAPER) { + do { + for (int i = 0; i != width; i++) { + *udst = MakeGrey(*udst); + anim->m = 0; + anim->v = 0; + udst++; + anim++; + } + udst = udst - width + _screen.pitch; + anim = anim - width + this->anim_buf_width; + } while (--height); + return; + } + + DEBUG(misc, 0, "16bpp blitter doesn't know how to draw this colour table ('%d')", pal); +} + +void Blitter_16bppAnim::SetPixel(void *video, int x, int y, uint8 colour) +{ + *((Colour16 *)video + x + y * _screen.pitch) = LookupColourInPalette(colour); + + /* Set the colour in the anim-buffer too, if we are rendering to the screen */ + if (_screen_disable_anim) return; + Anim *anim = this->anim_buf + ((Colour16 *)video - (Colour16 *)_screen.dst_ptr) + x + y * this->anim_buf_width; + if (colour >= PALETTE_ANIM_START) { + anim->m = colour - PALETTE_ANIM_START + 1; + anim->v = DEFAULT_BRIGHTNESS >> 1; + } else { + anim->m = 0; + anim->v = 0; + } +} + +void Blitter_16bppAnim::DrawRect(void *video, int width, int height, uint8 colour) +{ + if (_screen_disable_anim) { + /* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent DrawRect() */ + Blitter_16bppOptimized::DrawRect(video, width, height, colour); + return; + } + + Colour16 colour16 = LookupColourInPalette(colour); + Anim *anim_line = this->anim_buf + ((Colour16 *)video - (Colour16 *)_screen.dst_ptr); + + do { + Colour16 *dst = (Colour16 *)video; + Anim *anim = anim_line; + + for (int i = width; i > 0; i--) { + *dst = colour16; + /* Set the colour in the anim-buffer too */ + if (colour >= PALETTE_ANIM_START) { + anim->m = colour - PALETTE_ANIM_START + 1; + anim->v = DEFAULT_BRIGHTNESS >> 1; + } else { + anim->m = 0; + anim->v = 0; + } + dst++; + anim++; + } + video = (Colour16 *)video + _screen.pitch; + anim_line += this->anim_buf_width; + } while (--height); +} + +void Blitter_16bppAnim::CopyFromBuffer(void *video, const void *src, int width, int height) +{ + assert(!_screen_disable_anim); + assert(video >= _screen.dst_ptr && video <= (Colour16 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch); + Colour16 *dst = (Colour16 *)video; + const uint8 *usrc = (const uint8 *)src; + Anim *anim_line = this->anim_buf + ((Colour16 *)video - (Colour16 *)_screen.dst_ptr); + + for (; height > 0; height--) { + /* We need to keep those for palette animation. */ + Colour16 *dst_pal = dst; + Anim *anim_pal = anim_line; + + memcpy(dst, usrc, width * sizeof(Colour16)); + usrc += width * sizeof(Colour16); + dst += _screen.pitch; + /* Copy back the anim-buffer */ + memcpy(anim_line, usrc, width * sizeof(Anim)); + usrc += width * sizeof(Anim); + anim_line += this->anim_buf_width; + + /* Okay, it is *very* likely that the image we stored is using + * the wrong palette animated colours. There are two things we + * can do to fix this. The first is simply reviewing the whole + * screen after we copied the buffer, i.e. run PaletteAnimate, + * however that forces a full screen redraw which is expensive + * for just the cursor. This just copies the implementation of + * palette animation, much cheaper though slightly nastier. */ + for (int i = 0; i < width; i++) { + uint8 colour = anim_pal->m; + if (colour) { + /* Update this pixel */ + *dst_pal = AdjustBrightness(LookupColourInPalette(colour + PALETTE_ANIM_START - 1), anim_pal->v << 1); + } + dst_pal++; + anim_pal++; + } + } +} + +void Blitter_16bppAnim::CopyToBuffer(const void *video, void *dst, int width, int height) +{ + assert(!_screen_disable_anim); + assert(video >= _screen.dst_ptr && video <= (Colour16 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch); + uint8 *udst = (uint8 *)dst; + const Colour16 *src = (const Colour16 *)video; + const Anim *anim_line = this->anim_buf + ((const Colour16 *)video - (Colour16 *)_screen.dst_ptr); + + for (; height > 0; height--) { + memcpy(udst, src, width * sizeof(Colour16)); + src += _screen.pitch; + udst += width * sizeof(Colour16); + /* Copy the anim-buffer */ + memcpy(udst, anim_line, width * sizeof(Anim)); + udst += width * sizeof(Anim); + anim_line += this->anim_buf_width; + } +} + +void Blitter_16bppAnim::ScrollBuffer(void *video, int &left_ref, int &top_ref, int &width_ref, int &height_ref, int scroll_x, int scroll_y) +{ + assert(!_screen_disable_anim); + assert(video >= _screen.dst_ptr && video <= (Colour16 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch); + const Anim *src; + Anim *dst; + int left = left_ref, top = top_ref, width = width_ref, height = height_ref; + + /* We need to scroll the anim-buffer too */ + if (scroll_y > 0) { + /* Calculate pointers */ + dst = this->anim_buf + left + (top + height - 1) * this->anim_buf_width; + src = dst - scroll_y * this->anim_buf_width; + + /* Decrease height and increase top */ + top += scroll_y; + height -= scroll_y; + assert(height > 0); + + /* Adjust left & width */ + if (scroll_x >= 0) { + dst += scroll_x; + left += scroll_x; + width -= scroll_x; + } else { + src -= scroll_x; + width += scroll_x; + } + + for (int h = height; h > 0; h--) { + memcpy(dst, src, width * sizeof(Anim)); + src -= this->anim_buf_width; + dst -= this->anim_buf_width; + } + } else { + /* Calculate pointers */ + dst = this->anim_buf + left + top * this->anim_buf_width; + src = dst - scroll_y * this->anim_buf_width; + + /* Decrease height. (scroll_y is <=0). */ + height += scroll_y; + assert(height > 0); + + /* Adjust left & width */ + if (scroll_x >= 0) { + dst += scroll_x; + left += scroll_x; + width -= scroll_x; + } else { + src -= scroll_x; + width += scroll_x; + } + + /* the y-displacement may be 0 therefore we have to use memmove, + * because source and destination may overlap */ + for (int h = height; h > 0; h--) { + memmove(dst, src, width * sizeof(Anim)); + src += _screen.pitch; + dst += _screen.pitch; + } + } + + Blitter_16bppOptimized::ScrollBuffer(video, left_ref, top_ref, width_ref, height_ref, scroll_x, scroll_y); +} + +int Blitter_16bppAnim::BufferSize(int width, int height) +{ + return width * height * (sizeof(Anim) + sizeof(Colour16)); +} + +void Blitter_16bppAnim::PaletteAnimate(const Palette &palette) +{ + assert(!_screen_disable_anim); + + /* If first_dirty is 0, it is for 8bpp indication to send the new + * palette. However, only the animation colours might possibly change. + * Especially when going between toyland and non-toyland. */ + assert(palette.first_dirty == PALETTE_ANIM_START || palette.first_dirty == 0); + + for (int i = 0; i < 256; i++) { + this->palette[i] = To16(palette.palette[i]); + } + + const Anim *anim = this->anim_buf; + Colour16 *dst = (Colour16 *)_screen.dst_ptr; + + /* Let's walk the anim buffer and try to find the pixels */ + for (int y = this->anim_buf_height; y != 0 ; y--) { + for (int x = this->anim_buf_width; x != 0 ; x--) { + uint8 colour = anim->m; + if (colour) { + /* Update this pixel */ + *dst = AdjustBrightness(LookupColourInPalette(colour + PALETTE_ANIM_START - 1), anim->v << 1); + } + dst++; + anim++; + } + dst += _screen.pitch - this->anim_buf_width; + } + + /* Make sure the backend redraws the whole screen */ + VideoDriver::GetInstance()->MakeDirty(0, 0, _screen.width, _screen.height); +} + +Blitter::PaletteAnimation Blitter_16bppAnim::UsePaletteAnimation() +{ + return Blitter::PALETTE_ANIMATION_BLITTER; +} + +void Blitter_16bppAnim::PostResize() +{ + if (_screen.width != this->anim_buf_width || _screen.height != this->anim_buf_height) { + /* The size of the screen changed; we can assume we can wipe all data from our buffer */ + free(this->anim_buf); + this->anim_buf = CallocT(_screen.width * _screen.height); + this->anim_buf_width = _screen.width; + this->anim_buf_height = _screen.height; + } +} diff --git a/src/blitter/16bpp_anim.hpp b/src/blitter/16bpp_anim.hpp new file mode 100644 index 0000000000..80bf6e5df5 --- /dev/null +++ b/src/blitter/16bpp_anim.hpp @@ -0,0 +1,75 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file 16bpp_anim.hpp A 16 bpp blitter with animation support. */ + +#ifndef BLITTER_16BPP_ANIM_HPP +#define BLITTER_16BPP_ANIM_HPP + +#include "16bpp_simple.hpp" + +class Blitter_16bppOptimized: public Blitter_16bppSimple { + // TODO: implement that +}; + +/** The optimised 16 bpp blitter with palette animation. */ +class Blitter_16bppAnim : public Blitter_16bppOptimized { +protected: + // PALETTE_ANIM_SIZE is less than 32, so we'll use 5 bits for color index, and 3 bits for brightness, losing 1 bit compared to struct Pixel + struct Anim { + unsigned m : 5 __attribute__((packed)); ///< Color index channel, packed 5 bits, 0 = no animation, 1 = PALETTE_ANIM_START + unsigned v : 3 __attribute__((packed)); ///< Brightness-channel, packed 3 bits + }; + + Anim *anim_buf; ///< In this buffer we keep track of the 8bpp indexes so we can do palette animation + int anim_buf_width; ///< The width of the animation buffer. + int anim_buf_height; ///< The height of the animation buffer. + Colour16 palette[256]; ///< The current palette. + +public: + Blitter_16bppAnim() : + anim_buf(NULL), + anim_buf_width(0), + anim_buf_height(0) + {} + + /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); + /* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal); + /* virtual */ void SetPixel(void *video, int x, int y, uint8 colour); + /* virtual */ void DrawRect(void *video, int width, int height, uint8 colour); + /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height); + /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height); + /* virtual */ void ScrollBuffer(void *video, int &left_ref, int &top_ref, int &width_ref, int &height_ref, int scroll_x, int scroll_y); + /* virtual */ int BufferSize(int width, int height); + /* virtual */ void PaletteAnimate(const Palette &palette); + /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation(); + /* virtual */ int GetBytesPerPixel() { return 3; } + + /* virtual */ const char *GetName() { return "16bpp-anim"; } + /* virtual */ void PostResize(); + + /** + * Look up the colour in the current palette. + */ + inline Colour16 LookupColourInPalette(uint8 index) + { + return this->palette[index]; + } + + template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); +}; + +/** Factory for the 16bpp blitter with animation. */ +class FBlitter_16bppAnim : public BlitterFactory { +public: + FBlitter_16bppAnim() : BlitterFactory("16bpp-anim-broken", "16bpp Animation Blitter, currently broken (palette animation)") {} + /* virtual */ Blitter *CreateInstance() { return new Blitter_16bppAnim(); } +}; + +#endif /* BLITTER_16BPP_ANIM_HPP */ diff --git a/src/blitter/16bpp_base.cpp b/src/blitter/16bpp_base.cpp new file mode 100644 index 0000000000..9161ce92c4 --- /dev/null +++ b/src/blitter/16bpp_base.cpp @@ -0,0 +1,147 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file 16bpp_base.cpp Implementation of base for 32 bpp blitters. */ + +#include "../stdafx.h" +#include "16bpp_base.hpp" + +void *Blitter_16bppBase::MoveTo(void *video, int x, int y) +{ + return (uint16 *)video + x + y * _screen.pitch; +} + +void Blitter_16bppBase::SetPixel(void *video, int x, int y, uint8 colour) +{ + *((Colour16 *)video + x + y * _screen.pitch) = LookupColourInPalette(colour); +} + +void Blitter_16bppBase::DrawRect(void *video, int width, int height, uint8 colour) +{ + Colour16 target = LookupColourInPalette(colour); + + do { + Colour16 *dst = (Colour16 *)video; + for (int i = width; i > 0; i--) { + *dst = target; + dst++; + } + video = (uint16 *)video + _screen.pitch; + } while (--height); +} + +void Blitter_16bppBase::CopyFromBuffer(void *video, const void *src, int width, int height) +{ + uint16 *dst = (uint16 *)video; + const uint16 *usrc = (const uint16 *)src; + + for (; height > 0; height--) { + memcpy(dst, usrc, width * sizeof(uint16)); + usrc += width; + dst += _screen.pitch; + } +} + +void Blitter_16bppBase::CopyToBuffer(const void *video, void *dst, int width, int height) +{ + uint16 *udst = (uint16 *)dst; + const uint16 *src = (const uint16 *)video; + + for (; height > 0; height--) { + memcpy(udst, src, width * sizeof(uint16)); + src += _screen.pitch; + udst += width; + } +} + +void Blitter_16bppBase::CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) +{ + uint16 *udst = (uint16 *)dst; + const uint16 *src = (const uint16 *)video; + + for (; height > 0; height--) { + memcpy(udst, src, width * sizeof(uint16)); + src += _screen.pitch; + udst += dst_pitch; + } +} + +void Blitter_16bppBase::ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) +{ + const Colour16 *src; + Colour16 *dst; + + if (scroll_y > 0) { + /* Calculate pointers */ + dst = (Colour16 *)video + left + (top + height - 1) * _screen.pitch; + src = dst - scroll_y * _screen.pitch; + + /* Decrease height and increase top */ + top += scroll_y; + height -= scroll_y; + assert(height > 0); + + /* Adjust left & width */ + if (scroll_x >= 0) { + dst += scroll_x; + left += scroll_x; + width -= scroll_x; + } else { + src -= scroll_x; + width += scroll_x; + } + + for (int h = height; h > 0; h--) { + memcpy(dst, src, width * sizeof(Colour16)); + src -= _screen.pitch; + dst -= _screen.pitch; + } + } else { + /* Calculate pointers */ + dst = (Colour16 *)video + left + top * _screen.pitch; + src = dst - scroll_y * _screen.pitch; + + /* Decrease height. (scroll_y is <=0). */ + height += scroll_y; + assert(height > 0); + + /* Adjust left & width */ + if (scroll_x >= 0) { + dst += scroll_x; + left += scroll_x; + width -= scroll_x; + } else { + src -= scroll_x; + width += scroll_x; + } + + /* the y-displacement may be 0 therefore we have to use memmove, + * because source and destination may overlap */ + for (int h = height; h > 0; h--) { + memmove(dst, src, width * sizeof(Colour16)); + src += _screen.pitch; + dst += _screen.pitch; + } + } +} + +int Blitter_16bppBase::BufferSize(int width, int height) +{ + return width * height * sizeof(Colour16); +} + +void Blitter_16bppBase::PaletteAnimate(const Palette &palette) +{ + /* By default, 16bpp doesn't have palette animation */ +} + +Blitter::PaletteAnimation Blitter_16bppBase::UsePaletteAnimation() +{ + return Blitter::PALETTE_ANIMATION_NONE; +} diff --git a/src/blitter/16bpp_base.hpp b/src/blitter/16bpp_base.hpp new file mode 100644 index 0000000000..c4d63b0bd4 --- /dev/null +++ b/src/blitter/16bpp_base.hpp @@ -0,0 +1,225 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file 16bpp_base.hpp Base for all 16 bits blitters. */ + +#ifndef BLITTER_16BPP_BASE_HPP +#define BLITTER_16BPP_BASE_HPP + +#include "base.hpp" +#include "../core/bitmath_func.hpp" +#include "../core/math_func.hpp" +#include "../gfx_func.h" + +/** Base for all 16bpp blitters. */ +class Blitter_16bppBase : public Blitter { +public: + + // TODO: GCC-specific attributes + struct Colour16 { + unsigned b : 5 __attribute__((packed)); ///< Blue-channel, packed 5 bits + unsigned g : 6 __attribute__((packed)); ///< Green-channel, packed 6 bits + unsigned r : 5 __attribute__((packed)); ///< Red-channel, packed 5 bits + Colour16(uint8 r = 0, uint8 g = 0, uint8 b = 0): + b(b), g(g), r(r) + { + } + }; + + struct Pixel { + Colour16 c; + unsigned a : 4 __attribute__((packed)); ///< Alpha-channel, packed 4 bits + unsigned v : 4 __attribute__((packed)); ///< Brightness-channel, packed 4 bits + unsigned m : 8 __attribute__((packed)); ///< Remap-channel, cannot pack it, because it's palette lookup index, so it must be in range 0-255 + }; + + /* virtual */ uint8 GetScreenDepth() { return 16; } + /* virtual */ void *MoveTo(void *video, int x, int y); + /* virtual */ void SetPixel(void *video, int x, int y, uint8 colour); + /* virtual */ void DrawRect(void *video, int width, int height, uint8 colour); + /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height); + /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height); + /* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch); + /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y); + /* virtual */ int BufferSize(int width, int height); + /* virtual */ void PaletteAnimate(const Palette &palette); + /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation(); + /* virtual */ int GetBytesPerPixel() { return 2; } + + + /** + * Convert from rgb values to screen native 16bpp colour + */ + static inline Colour16 To16(uint8 r, uint8 g, uint8 b) + { + return Colour16(r >> 3, g >> 2, b >> 3); + } + + /** + * Convert from 32bpp colour to screen native 16bpp colour + */ + static inline Colour16 To16(Colour c) + { + return To16(c.r, c.g, c.b); + } + + /** + * Look up the colour in the current palette. + */ + static inline Colour LookupColourInPalette32(uint index) + { + return _cur_palette.palette[index]; + } + + /** + * Look up the colour in the current palette. + */ + static inline Colour16 LookupColourInPalette(uint index) + { + return To16(LookupColourInPalette32(index)); + } + + /** + * Compose a colour based on RGBA values and the current pixel value. + * @param r range is from 0 to 31. + * @param g range is from 0 to 63. + * @param b range is from 0 to 31. + * @param a range is from 0 to 15. + */ + static inline Colour16 ComposeColourRGBANoCheck(uint8 r, uint8 g, uint8 b, uint8 a, Colour16 current) + { + /* The 16 is wrong, it should be 15, but 16 is much faster... */ + return Colour16 ( ((int)(r - current.r) * a) / 16 + current.r, + ((int)(g - current.g) * a) / 16 + current.g, + ((int)(b - current.b) * a) / 16 + current.b ); + } + + /** + * Compose a colour based on RGBA values and the current pixel value. + * Handles fully transparent and solid pixels in a special (faster) way. + * @param r range is from 0 to 31. + * @param g range is from 0 to 63. + * @param b range is from 0 to 31. + * @param a range is from 0 to 15. + */ + static inline Colour16 ComposeColourRGBA(uint8 r, uint8 g, uint8 b, uint8 a, Colour16 current) + { + if (a == 0) return current; + if (a >= 15) return Colour16(r, g, b); + + return ComposeColourRGBANoCheck(r, g, b, a, current); + } + + /** + * Compose a colour based on Pixel value, alpha value, and the current pixel value. + * @param a range is from 0 to 16. + */ + static inline Colour16 ComposeColourPANoCheck(Colour16 colour, uint8 a, Colour16 current) + { + return ComposeColourRGBANoCheck(colour.r, colour.g, colour.b, a, current); + } + + /** + * Compose a colour based on Pixel value, alpha value, and the current pixel value. + * Handles fully transparent and solid pixels in a special (faster) way. + * @param a range is from 0 to 15. + */ + static inline Colour16 ComposeColourPA(Colour16 colour, uint8 a, Colour16 current) + { + if (a == 0) return current; + if (a >= 15) return colour; + + return ComposeColourPANoCheck(colour, a, current); + } + + /** + * Make a pixel looks like it is transparent. + * @param colour the colour already on the screen. + * @param nom the amount of transparency, nominator, makes colour lighter. + * @param denom denominator, makes colour darker. + * @return the new colour for the screen. + */ + static inline Colour16 MakeTransparent(Colour16 colour, uint nom, uint denom = 256) + { + uint r = colour.r; + uint g = colour.g; + uint b = colour.b; + + return Colour16( r * nom / denom, + g * nom / denom, + b * nom / denom ); + } + + /** + * Make a colour grey - based. + * @param colour the colour to make grey. + * @return the new colour, now grey. + */ + static inline Colour16 MakeGrey(Colour16 colour) + { + uint8 r = colour.r; + uint8 g = colour.g; + uint8 b = colour.b; + + /* To avoid doubles and stuff, multiple it with a total of 65536 (16bits), then + * divide by it to normalize the value to a byte again. See heightmap.cpp for + * information about the formula. */ + uint grey = (((r << 3) * 19595) + ((g << 2) * 38470) + ((b << 3) * 7471)) / 65536; + + return To16(grey, grey, grey); + } + + /** + * Make a colour dark grey, for specialized 32bpp remapping. + * @param r red component + * @param g green component + * @param b blue component + * @return the brightness value of the new colour, now dark grey. + */ + static inline uint8 MakeDark(Colour16 colour) + { + uint8 r = colour.r; + uint8 g = colour.g; + uint8 b = colour.b; + + /* Magic-numbers are ~66% of those used in MakeGrey() */ + return (((r << 3) * 13063) + ((g << 2) * 25647) + ((b << 3) * 4981)) / 65536; + } + + enum { DEFAULT_BRIGHTNESS = 8 }; + + /** + * @param brightness range is from 0 to 15. + */ + static inline Colour16 AdjustBrightness(Colour16 colour, uint8 brightness) + { + /* Shortcut for normal brightness */ + if (brightness == DEFAULT_BRIGHTNESS) return colour; + + uint16 ob = 0; + uint16 r = colour.r * brightness / DEFAULT_BRIGHTNESS; + uint16 g = colour.g * brightness / DEFAULT_BRIGHTNESS; + uint16 b = colour.b * brightness / DEFAULT_BRIGHTNESS; + + /* Sum overbright */ + if (r > 31) ob += r - 31; + if (g > 63) ob += g - 63; + if (b > 31) ob += b - 31; + + if (ob == 0) return Colour16(r, g, b); + + /* Reduce overbright strength */ + ob /= 2; + return Colour16( r >= 31 ? 31 : min(r + ob * (31 - r) / 32, 31), + g >= 63 ? 63 : min(g + ob * (63 - g) / 64, 63), + b >= 31 ? 31 : min(b + ob * (31 - b) / 32, 31) ); + } +}; + +#endif /* BLITTER_16BPP_BASE_HPP */ diff --git a/src/blitter/16bpp_simple.cpp b/src/blitter/16bpp_simple.cpp new file mode 100644 index 0000000000..fc0e83fff3 --- /dev/null +++ b/src/blitter/16bpp_simple.cpp @@ -0,0 +1,173 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file 32bpp_simple.cpp Implementation of the simple 32 bpp blitter. */ + +#include "../stdafx.h" +#include "../zoom_func.h" +#include "16bpp_simple.hpp" + +#include "../table/sprites.h" + +/** Instantiation of the simple 16bpp blitter factory. */ +static FBlitter_16bppSimple iFBlitter_16bppSimple; + +template +void Blitter_16bppSimple::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom) +{ + const Pixel *src, *src_line; + Colour16 *dst, *dst_line; + + /* Find where to start reading in the source sprite */ + src_line = (const Pixel *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom); + dst_line = (Colour16 *)bp->dst + bp->top * bp->pitch + bp->left; + + for (int y = 0; y < bp->height; y++) { + dst = dst_line; + dst_line += bp->pitch; + + src = src_line; + src_line += bp->sprite_width * ScaleByZoom(1, zoom); + + for (int x = 0; x < bp->width; x++) { + switch (mode) { + case BM_COLOUR_REMAP: + /* In case the m-channel is zero, do not remap this pixel in any way */ + if (src->m == 0) { + if (src->a != 0) *dst = ComposeColourPA(src->c, src->a, *dst); + } else { + if (bp->remap[src->m] != 0) *dst = ComposeColourPA(AdjustBrightness(LookupColourInPalette(bp->remap[src->m]), src->v), src->a, *dst); + } + break; + + case BM_CRASH_REMAP: + if (src->m == 0) { + if (src->a != 0) { + uint8 g = MakeDark(src->c); + *dst = ComposeColourRGBA(g, g, g, src->a, *dst); + } + } else { + if (bp->remap[src->m] != 0) *dst = ComposeColourPA(AdjustBrightness(LookupColourInPalette(bp->remap[src->m]), src->v), src->a, *dst); + } + break; + + case BM_TRANSPARENT: + /* TODO -- We make an assumption here that the remap in fact is transparency, not some colour. + * This is never a problem with the code we produce, but newgrfs can make it fail... or at least: + * we produce a result the newgrf maker didn't expect ;) */ + + /* Make the current colour a bit more black, so it looks like this image is transparent */ + if (src->a != 0) *dst = MakeTransparent(*dst, 192); + break; + + case BM_BLACK_REMAP: + if (src->a != 0) { + *dst = Colour16(0, 0, 0); + } + break; + + default: + if (src->a != 0) *dst = ComposeColourPA(src->c, src->a, *dst); + break; + } + dst++; + src += ScaleByZoom(1, zoom); + } + } +} + +void Blitter_16bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) +{ + switch (mode) { + default: NOT_REACHED(); + case BM_NORMAL: Draw (bp, zoom); return; + case BM_COLOUR_REMAP: Draw(bp, zoom); return; + case BM_TRANSPARENT: Draw (bp, zoom); return; + case BM_CRASH_REMAP: Draw (bp, zoom); return; + case BM_BLACK_REMAP: Draw (bp, zoom); return; + } +} + +void Blitter_16bppSimple::DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) +{ + Colour16 *udst = (Colour16 *)dst; + + if (pal == PALETTE_TO_TRANSPARENT) { + do { + for (int i = 0; i != width; i++) { + *udst = MakeTransparent(*udst, 154); + udst++; + } + udst = udst - width + _screen.pitch; + } while (--height); + return; + } + if (pal == PALETTE_NEWSPAPER) { + do { + for (int i = 0; i != width; i++) { + *udst = MakeGrey(*udst); + udst++; + } + udst = udst - width + _screen.pitch; + } while (--height); + return; + } + + DEBUG(misc, 0, "16bpp blitter doesn't know how to draw this colour table ('%d')", pal); +} + +Sprite *Blitter_16bppSimple::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) +{ + Pixel *dst; + Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite->height * (size_t)sprite->width * sizeof(Pixel)); + + dest_sprite->height = sprite->height; + dest_sprite->width = sprite->width; + dest_sprite->x_offs = sprite->x_offs; + dest_sprite->y_offs = sprite->y_offs; + + dst = (Pixel *)dest_sprite->data; + SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite->data; + + for (int i = 0; i < sprite->height * sprite->width; i++) { + if (src->m == 0) { + dst[i].c = To16(src->r, src->g, src->b); + dst[i].a = src->a / 16; + dst[i].m = 0; + dst[i].v = 0; + } else { + /* Get brightest value */ + uint8 rgb_max = max(src->r, max(src->g, src->b)); +#if 0 + /* Pre-convert the mapping channel to a RGB value, + use 32bpp AdjustBrightness() variant for better colors, + because this function is not called each frame */ + if (rgb_max == 0) rgb_max = Blitter_32bppBase::DEFAULT_BRIGHTNESS; + dst[i].c = To16(Blitter_32bppBase::AdjustBrightness(LookupColourInPalette32(src->m), rgb_max)); + dst[i].v = rgb_max / 16; +#endif + rgb_max /= 16; + + /* Black pixel (8bpp or old 32bpp image), so use default value */ + if (rgb_max == 0) rgb_max = DEFAULT_BRIGHTNESS; + + /* Pre-convert the mapping channel to a RGB value, + use 32bpp AdjustBrightness() variant for better colors, + because this function is not called each frame */ + dst[i].c = AdjustBrightness(LookupColourInPalette(src->m), rgb_max); + dst[i].v = rgb_max; + + dst[i].a = src->a / 16; + dst[i].m = src->m; + } + src++; + } + + return dest_sprite; +} diff --git a/src/blitter/16bpp_simple.hpp b/src/blitter/16bpp_simple.hpp new file mode 100644 index 0000000000..9feb934062 --- /dev/null +++ b/src/blitter/16bpp_simple.hpp @@ -0,0 +1,36 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file 16bpp_simple.hpp Simple 16 bpp blitter. */ + +#ifndef BLITTER_16BPP_SIMPLE_HPP +#define BLITTER_16BPP_SIMPLE_HPP + +#include "16bpp_base.hpp" +#include "factory.hpp" + +/** The most trivial 32 bpp blitter (without palette animation). */ +class Blitter_16bppSimple : public Blitter_16bppBase { +public: + /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); + /* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal); + /* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator); + template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); + + /* virtual */ const char *GetName() { return "16bpp-simple"; } +}; + +/** Factory for the simple 16 bpp blitter. */ +class FBlitter_16bppSimple : public BlitterFactory { +public: + FBlitter_16bppSimple() : BlitterFactory("16bpp-simple", "16bpp Simple Blitter (no palette animation)") {} + /* virtual */ Blitter *CreateInstance() { return new Blitter_16bppSimple(); } +}; + +#endif /* BLITTER_16BPP_SIMPLE_HPP */ diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index 797ead1f51..ad00fba764 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -24,6 +24,7 @@ #include "cmd_helper.h" #include "tunnelbridge_map.h" #include "road_gui.h" +#include "tilehighlight_func.h" #include "widgets/bridge_widget.h" @@ -198,6 +199,7 @@ public: sprite_dim.height++; // Sprite is rendered one pixel down in the matrix field. text_dim.height++; // Allowing the bottom row pixels to be rendered on the edge of the matrix field. resize->height = max(sprite_dim.height, text_dim.height) + 2; // Max of both sizes + account for matrix edges. + resize->height = GetMinSizing(NWST_STEP, resize->height); this->bridgetext_offset = WD_MATRIX_LEFT + sprite_dim.width + 1; // Left edge of text, 1 pixel distance from the sprite. size->width = this->bridgetext_offset + text_dim.width + WD_MATRIX_RIGHT; @@ -233,7 +235,8 @@ public: SetDParam(1, b->speed); SetDParam(0, b->material); - DrawSprite(b->sprite, b->pal, r.left + WD_MATRIX_LEFT, y + this->resize.step_height - 1 - GetSpriteSize(b->sprite).height); + uint y_sprite = Center(y, this->resize.step_height, GetSpriteSize(b->sprite).height); + DrawSprite(b->sprite, b->pal, r.left + WD_MATRIX_LEFT, y_sprite); DrawStringMultiLine(r.left + this->bridgetext_offset, r.right, y + 2, y + this->resize.step_height, _game_mode == GM_EDITOR ? STR_SELECT_BRIDGE_SCENEDIT_INFO : STR_SELECT_BRIDGE_INFO); y += this->resize.step_height; @@ -430,6 +433,8 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo new BuildBridgeWindow(&_build_bridge_desc, start, end, type, bl); } else { delete bl; + SetSelectionTilesDirty(); + _thd.Reset(); ShowErrorMessage(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, errmsg, WL_INFO, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE); } } diff --git a/src/build_confirmation_func.h b/src/build_confirmation_func.h new file mode 100644 index 0000000000..7bbbba24ef --- /dev/null +++ b/src/build_confirmation_func.h @@ -0,0 +1,27 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file build_confirmation_func.h Transparent confirmation dialog for building anything on the map. */ + +#ifndef BUILD_CONFIRMATION_FUNC_H +#define BUILD_CONFIRMATION_FUNC_H + +#include "stdafx.h" +#include "window_func.h" +#include "widget_type.h" + + +void ShowBuildConfirmationWindow(); +void HideBuildConfirmationWindow(); +bool ConfirmationWindowShown(); +bool BuildConfirmationWindowProcessViewportClick(); +bool ConfirmationWindowEstimatingCost(); +void ConfirmationWindowSetEstimatedCost(Money cost); + +#endif /* BUILD_CONFIRMATION_FUNC_H */ diff --git a/src/build_confirmation_gui.cpp b/src/build_confirmation_gui.cpp new file mode 100644 index 0000000000..c7d82bc2ca --- /dev/null +++ b/src/build_confirmation_gui.cpp @@ -0,0 +1,304 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file build_confirmation_gui.cpp Transparent confirmation dialog for building anything on the map. */ + +#include "stdafx.h" +#include "string_func.h" +#include "strings_func.h" +#include "window_func.h" +#include "widget_type.h" +#include "window_gui.h" +#include "gfx_func.h" +#include "tilehighlight_func.h" +#include "viewport_func.h" +#include "zoom_func.h" +#include "settings_type.h" +#include "station_gui.h" +#include "build_confirmation_func.h" +#include "widgets/build_confirmation_widget.h" +#include "widgets/misc_widget.h" + +#include "table/strings.h" + +#include "safeguards.h" + +static const NWidgetPart _nested_build_info_widgets[] = { + NWidget(WWT_PANEL, COLOUR_GREY, WID_TT_BACKGROUND), SetMinimalSize(200, 32), EndContainer(), +}; + +static WindowDesc _build_info_desc( + WDP_MANUAL, NULL, 0, 0, // Coordinates and sizes are not used, + WC_TOOLTIPS, WC_NONE, + WDF_NO_FOCUS, + _nested_build_info_widgets, lengthof(_nested_build_info_widgets) +); + +/** Window for displaying accepted goods for a station. */ +struct BuildInfoWindow : public Window +{ + StationCoverageType sct; + bool station; + static Money cost; + + static void show() + { + bool station = _settings_client.gui.station_show_coverage; // Station info is inaccurate when station coverage area option is disabled + StationCoverageType sct = SCT_ALL; + if (FindWindowByClass(WC_BUILD_STATION) != NULL) sct = SCT_ALL; + else if (FindWindowByClass(WC_BUS_STATION) != NULL) sct = SCT_PASSENGERS_ONLY; + else if (FindWindowByClass(WC_TRUCK_STATION) != NULL) sct = SCT_NON_PASSENGERS_ONLY; + else station = false; + new BuildInfoWindow(station, sct); + } + + BuildInfoWindow(bool station, StationCoverageType sct) : Window(&_build_info_desc) + { + this->station = station; + this->sct = sct; + this->InitNested(); + + CLRBITS(this->flags, WF_WHITE_BORDER); + } + + virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) + { + Point pt; + pt.y = GetMainViewTop(); + pt.x = _screen.width - sm_width - FindWindowById(WC_MAIN_TOOLBAR, 0)->width; + return pt; + } + + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + { + size->width = GetStringBoundingBox(STR_STATION_BUILD_COVERAGE_AREA_TITLE).width * 2.5; + size->height = GetStringHeight(STR_STATION_BUILD_COVERAGE_AREA_TITLE, size->width) * (this->station ? 3 : 1); + + /* Increase slightly to have some space around the box. */ + size->width += 2 + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + size->height += 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + } + + virtual void DrawWidget(const Rect &r, int widget) const + { + /* There is only one widget. */ + GfxFillRect(r.left, r.top, r.right, r.bottom, PC_BLACK); + GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_LIGHT_YELLOW); + + int top = r.top + WD_FRAMERECT_TOP; + Money cost = BuildInfoWindow::cost; + StringID msg = STR_MESSAGE_ESTIMATED_COST; + SetDParam(0, cost); + if (cost < 0) { + msg = STR_MESSAGE_ESTIMATED_INCOME; + SetDParam(0, -cost); + } + top = DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, top, INT32_MAX, msg); + + if (!this->station) return; + + top = DrawStationCoverageAreaText(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, top, sct, _thd.outersize.x / TILE_SIZE / 2, false); + if (top - r.top <= GetStringHeight(STR_STATION_BUILD_COVERAGE_AREA_TITLE, r.right - r.left) * 1.5) { + DrawStationCoverageAreaText(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, top, sct, _thd.outersize.x / TILE_SIZE / 2, true); + } + } +}; + +Money BuildInfoWindow::cost = 0; + +/** GUI for confirming building actions. */ +struct BuildConfirmationWindow : Window { + + // TODO: show estimated price + static bool shown; ///< Just to speed up window hiding, HideBuildConfirmationWindow() is called very often. + static bool estimating_cost; ///< Calculate action cost instead of executing action. + Point selstart; ///< The selection start on the viewport. + Point selend; ///< The selection end on the viewport. + + BuildConfirmationWindow(WindowDesc *desc) : Window(desc) + { + // Save tile selection points, they will be reset by subsequent code, and we must keep them + selstart = _thd.selstart; + selend = _thd.selend; + + this->InitNested(0); + + Point pt; + const Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + NWidgetViewport *nvp = this->GetWidget(WID_BC_OK); + + pt.x = w->viewport->scrollpos_x + ScaleByZoom(_cursor.pos.x - nvp->current_x / 2, w->viewport->zoom); + pt.y = w->viewport->scrollpos_y + ScaleByZoom(_cursor.pos.y - nvp->current_y / 4, w->viewport->zoom); + + nvp->InitializeViewport(this, 0, w->viewport->zoom); + nvp->disp_flags |= ND_SHADE_DIMMED; + + this->viewport->scrollpos_x = pt.x; + this->viewport->scrollpos_y = pt.y; + this->viewport->dest_scrollpos_x = this->viewport->scrollpos_x; + this->viewport->dest_scrollpos_y = this->viewport->scrollpos_y; + + BuildConfirmationWindow::shown = true; + BuildConfirmationWindow::estimating_cost = true; + ConfirmationWindowSetEstimatedCost(0); // Clear old value, just in case + // This is a hack - we invoke the build command with estimating_cost flag, which is equal to _shift_pressed, + // then we select last build tool, restore viewport selection, and hide all windows, which pop up when command is invoked, + // and all that just to get cost estimate value. + ConfirmPlacingObject(); + ToolbarSelectLastTool(); + _thd.selstart = selstart; + _thd.selend = selend; + BuildConfirmationWindow::estimating_cost = false; + MoveAllWindowsOffScreen(); + } + + ~BuildConfirmationWindow() + { + BuildConfirmationWindow::shown = false; + } + + void OnClick(Point pt, int widget, int click_count) + { + switch (widget) { + case WID_BC_OK: + if (pt.y <= (int)GetWidget(WID_BC_OK)->current_y / 2) { + _thd.selstart = selstart; + _thd.selend = selend; + ConfirmPlacingObject(); + ToolbarSelectLastTool(); + } else { + ResetObjectToPlace(); + } + break; + } + HideBuildConfirmationWindow(); // this == NULL after this call + } + + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + { + switch (widget) { + case WID_BC_OK: + size->width = GetMinSizing(NWST_BUTTON) * 2; + size->height = GetMinSizing(NWST_BUTTON) * 3; + break; + } + } + + virtual void OnPaint() + { + this->DrawWidgets(); + + DrawButtonFrame(0, 0, this->width - 1, this->height / 2 - 2, STR_BUTTON_OK); + DrawButtonFrame(0, this->height / 2, this->width - 1, this->height / 2 - 1, STR_BUTTON_CANCEL); + } + + void DrawButtonFrame(int x, int y, int w, int h, int str) + { + DrawFrameRect(x, y, x + w, y + h, COLOUR_GREY, FR_BORDERONLY); + Dimension d = GetStringBoundingBox(str); + DrawFrameRect(x + w / 2 - d.width / 2 - 1, + Center(y, h) - 2, + x + w / 2 + d.width / 2 + 1, + Center(y, h) + d.height, + COLOUR_GREY, FR_NONE); + DrawString(x, x + w, Center(y, h), str, TC_FROMSTRING, SA_HOR_CENTER); + } +}; + +bool BuildConfirmationWindow::shown = false; +bool BuildConfirmationWindow::estimating_cost = false; + +static const NWidgetPart _nested_build_confirmation_widgets[] = { + NWidget(WWT_PANEL, COLOUR_GREY, WID_BC_PANEL), + NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_BC_OK), SetSizingType(NWST_VIEWPORT), SetResize(1, 1), SetFill(1, 1), //SetPadding(2, 2, 2, 2), + EndContainer(), +}; + +static WindowDesc _build_confirmation_desc( + WDP_MANUAL, "build_confirmation", 0, 0, + WC_BUILD_CONFIRMATION, WC_NONE, + 0, + _nested_build_confirmation_widgets, lengthof(_nested_build_confirmation_widgets) +); + +/** + * Show build confirmation window under the mouse cursor +*/ +void ShowBuildConfirmationWindow() +{ + if (ConfirmationWindowEstimatingCost()) return; // Special case, ignore recursive call + + HideBuildConfirmationWindow(); + + if (!_settings_client.gui.build_confirmation || _shift_pressed) { + ConfirmPlacingObject(); + return; + } + + BuildConfirmationWindow *w = new BuildConfirmationWindow(&_build_confirmation_desc); + + int old_left = w->left; + int old_top = w->top; + w->left = _cursor.pos.x - w->width / 2; + w->top = _cursor.pos.y - w->height / 4; + w->viewport->left += w->left - old_left; + w->viewport->top += w->top - old_top; + w->SetDirty(); + SetDirtyBlocks(0, 0, _screen.width, _screen.height); // I don't know what does this do, but it looks important + + BuildInfoWindow::show(); +} + +/** + * Destroy build confirmation window, this does not cancel current action +*/ +void HideBuildConfirmationWindow() +{ + if (ConfirmationWindowEstimatingCost()) return; // Special case, ignore recursive call + + if (!BuildConfirmationWindow::shown) return; + + DeleteWindowById(WC_BUILD_CONFIRMATION, 0); + DeleteWindowById(WC_TOOLTIPS, 0); +} + +bool ConfirmationWindowShown() +{ + return BuildConfirmationWindow::shown; +} + +bool BuildConfirmationWindowProcessViewportClick() +{ + if (!BuildConfirmationWindow::shown) return false; + + Window *w = FindWindowById(WC_BUILD_CONFIRMATION, 0); + if (w != NULL && IsInsideBS(_cursor.pos.x, w->left, w->width) && IsInsideBS(_cursor.pos.y, w->top, w->height)) { + Point pt; + pt.x = _cursor.pos.x - w->left; + pt.y = _cursor.pos.y - w->top; + w->OnClick(pt, WID_BC_OK, 1); + return true; + } + + HideBuildConfirmationWindow(); + + _thd.new_outersize = _thd.outersize; // Revert station catchment area highlight, which is getting set to zero inside drawing funcs + + return false; +} + +bool ConfirmationWindowEstimatingCost() +{ + return BuildConfirmationWindow::estimating_cost; +} + +void ConfirmationWindowSetEstimatedCost(Money cost) +{ + BuildInfoWindow::cost = cost; +} diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index bd4bf3b59b..8103623523 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -46,7 +46,8 @@ */ uint GetEngineListHeight(VehicleType type) { - return max(FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM, GetVehicleImageCellSize(type, EIT_PURCHASE).height); + uint size = max(FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM, GetVehicleImageCellSize(type, EIT_PURCHASE).height); + return GetMinSizing(NWST_STEP, size); } static const NWidgetPart _nested_build_vehicle_widgets[] = { @@ -57,25 +58,30 @@ static const NWidgetPart _nested_build_vehicle_widgets[] = { NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), NWidget(WWT_STICKYBOX, COLOUR_GREY), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_HORIZONTAL), NWidget(NWID_VERTICAL), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_BV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), SetSizingType(NWST_STEP), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_BV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), SetSizingType(NWST_STEP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BV_SHOW_HIDDEN_ENGINES), SetSizingType(NWST_STEP), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_BV_CARGO_FILTER_DROPDOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_FILTER_CRITERIA), SetSizingType(NWST_STEP), + EndContainer(), + NWidget(NWID_SPACER), SetFill(1, 1), + EndContainer(), EndContainer(), + /* Vehicle list. */ NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BV_SHOW_HIDDEN_ENGINES), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_BV_CARGO_FILTER_DROPDOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_FILTER_CRITERIA), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_BV_LIST), SetResize(1, 1), SetFill(1, 0), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_BV_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_BV_SCROLLBAR), EndContainer(), EndContainer(), + /* Panel with details. */ + NWidget(WWT_PANEL, COLOUR_GREY, WID_BV_PANEL), SetMinimalSize(240, 122), SetResize(1, 1), EndContainer(), EndContainer(), - /* Vehicle list. */ - NWidget(NWID_HORIZONTAL), - NWidget(WWT_MATRIX, COLOUR_GREY, WID_BV_LIST), SetResize(1, 1), SetFill(1, 0), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_BV_SCROLLBAR), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_BV_SCROLLBAR), - EndContainer(), - /* Panel with details. */ - NWidget(WWT_PANEL, COLOUR_GREY, WID_BV_PANEL), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(), /* Build/rename buttons, resize button. */ NWidget(NWID_HORIZONTAL), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BV_BUILD_SEL), @@ -1393,6 +1399,7 @@ struct BuildVehicleWindow : Window { Dimension d = GetStringBoundingBox(this->GetWidget(widget)->widget_data); d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better. d.height += padding.height; + d.height = GetMinSizing(NWST_STEP, d.height); *size = maxdim(*size, d); break; } diff --git a/src/command.cpp b/src/command.cpp index 959610cd28..79a93c20e8 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -26,6 +26,9 @@ #include "signal_func.h" #include "core/backup_type.hpp" #include "object_base.h" +#include "string_func.h" +#include "tilehighlight_func.h" +#include "build_confirmation_func.h" #include "table/strings.h" @@ -551,11 +554,18 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac * However, in case of incoming network commands, * map generation or the pause button we do want * to execute. */ - bool estimate_only = _shift_pressed && IsLocalCompany() && + bool estimate_only = (_shift_pressed || ConfirmationWindowEstimatingCost()) && + IsLocalCompany() && !_generating_world && !(cmd & CMD_NETWORK_COMMAND) && (cmd & CMD_ID_MASK) != CMD_PAUSE; + if (ConfirmationWindowEstimatingCost() && !estimate_only) { + // We cannot estimate cost, so abort the command - it will be repeated by confirmation dialog later + ShowEstimatedCostOrIncome(0, 0, 0); + return false; + } + /* We're only sending the command, so don't do * fancy things for 'success'. */ bool only_sending = _networking && !(cmd & CMD_NETWORK_COMMAND); diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 577ea884d8..5d5156dc78 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -904,7 +904,10 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 Game::NewEvent(new ScriptEventCompanyBankrupt(c_index)); CompanyAdminRemove(c_index, (CompanyRemoveReason)reason); - if (StoryPage::GetNumItems() == 0 || Goal::GetNumItems() == 0) InvalidateWindowData(WC_MAIN_TOOLBAR, 0); + if (StoryPage::GetNumItems() == 0 || Goal::GetNumItems() == 0) { + InvalidateWindowData(WC_MAIN_TOOLBAR, 0); + InvalidateWindowData(WC_MAIN_TOOLBAR_RIGHT, 0); + } break; } diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 0be6679583..8439cd6d13 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -35,6 +35,7 @@ #include "road_func.h" #include "water.h" #include "station_func.h" +#include "widget_type.h" #include "zoom_func.h" #include "widgets/company_widget.h" @@ -529,7 +530,7 @@ public: uint Height(uint width) const { - return max(FONT_HEIGHT_NORMAL, ScaleGUITrad(12) + 2); + return GetMinSizing(NWST_STEP, max(FONT_HEIGHT_NORMAL, ScaleGUITrad(12) + 2)); } bool Selectable() const @@ -930,102 +931,112 @@ static const NWidgetPart _nested_select_company_manager_face_widgets[] = { EndContainer(), EndContainer(), EndContainer(), - NWidget(NWID_VERTICAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TOGGLE_LARGE_SMALL_BUTTON), SetFill(1, 0), SetDataTip(STR_FACE_ADVANCED, STR_FACE_ADVANCED_TOOLTIP), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SCMF_SEL_MALEFEMALE), // Simple male/female face setting. - NWidget(NWID_VERTICAL), - NWidget(NWID_SPACER), SetFill(0, 1), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_MALE), SetFill(1, 0), SetDataTip(STR_FACE_MALE_BUTTON, STR_FACE_MALE_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_FEMALE), SetFill(1, 0), SetDataTip(STR_FACE_FEMALE_BUTTON, STR_FACE_FEMALE_TOOLTIP), - NWidget(NWID_SPACER), SetFill(0, 1), + + NWidget(NWID_HORIZONTAL), + NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(NWID_VERTICAL), + NWidget(NWID_SPACER), SetFill(0, 1), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TOGGLE_LARGE_SMALL_BUTTON), SetFill(1, 0), SetDataTip(STR_FACE_ADVANCED, STR_FACE_ADVANCED_TOOLTIP), + NWidget(NWID_SPACER), SetMinimalSize(0, 2), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SCMF_SEL_MALEFEMALE), // Simple male/female face setting. + NWidget(NWID_VERTICAL), + NWidget(NWID_SPACER), SetFill(0, 1), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_MALE), SetFill(1, 0), SetDataTip(STR_FACE_MALE_BUTTON, STR_FACE_MALE_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_FEMALE), SetFill(1, 0), SetDataTip(STR_FACE_FEMALE_BUTTON, STR_FACE_FEMALE_TOOLTIP), + NWidget(NWID_SPACER), SetFill(0, 1), + EndContainer(), EndContainer(), - EndContainer(), - NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SCMF_SEL_PARTS), // Advanced face parts setting. - NWidget(NWID_VERTICAL), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_MALE2), SetFill(1, 0), SetDataTip(STR_FACE_MALE_BUTTON, STR_FACE_MALE_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_FEMALE2), SetFill(1, 0), SetDataTip(STR_FACE_FEMALE_BUTTON, STR_FACE_FEMALE_TOOLTIP), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_ETHNICITY_EUR), SetFill(1, 0), SetDataTip(STR_FACE_EUROPEAN, STR_FACE_SELECT_EUROPEAN), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_ETHNICITY_AFR), SetFill(1, 0), SetDataTip(STR_FACE_AFRICAN, STR_FACE_SELECT_AFRICAN), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 4), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SCMF_SEL_PARTS), // Advanced face parts setting. NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_MOUSTACHE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_MOUSTACHE_EARRING_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAS_GLASSES_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAIR_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_L), SetDataTip(AWV_DECREASE, STR_FACE_HAIR_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAIR), SetDataTip(STR_EMPTY, STR_FACE_HAIR_TOOLTIP), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_R), SetDataTip(AWV_INCREASE, STR_FACE_HAIR_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_EYEBROWS_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_L), SetDataTip(AWV_DECREASE, STR_FACE_EYEBROWS_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYEBROWS), SetDataTip(STR_EMPTY, STR_FACE_EYEBROWS_TOOLTIP), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_R), SetDataTip(AWV_INCREASE, STR_FACE_EYEBROWS_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_EYECOLOUR_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_L), SetDataTip(AWV_DECREASE, STR_FACE_EYECOLOUR_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR), SetDataTip(STR_EMPTY, STR_FACE_EYECOLOUR_TOOLTIP), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_R), SetDataTip(AWV_INCREASE, STR_FACE_EYECOLOUR_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_GLASSES_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_L), SetDataTip(AWV_DECREASE, STR_FACE_GLASSES_TOOLTIP_2), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP_2), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_R), SetDataTip(AWV_INCREASE, STR_FACE_GLASSES_TOOLTIP_2), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_NOSE_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_L), SetDataTip(AWV_DECREASE, STR_FACE_NOSE_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_NOSE), SetDataTip(STR_EMPTY, STR_FACE_NOSE_TOOLTIP), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_R), SetDataTip(AWV_INCREASE, STR_FACE_NOSE_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_LIPS_MOUSTACHE_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_L), SetDataTip(AWV_DECREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE), SetDataTip(STR_EMPTY, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_R), SetDataTip(AWV_INCREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_CHIN_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_L), SetDataTip(AWV_DECREASE, STR_FACE_CHIN_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_CHIN), SetDataTip(STR_EMPTY, STR_FACE_CHIN_TOOLTIP), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_R), SetDataTip(AWV_INCREASE, STR_FACE_CHIN_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_JACKET_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_L), SetDataTip(AWV_DECREASE, STR_FACE_JACKET_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_JACKET), SetDataTip(STR_EMPTY, STR_FACE_JACKET_TOOLTIP), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_R), SetDataTip(AWV_INCREASE, STR_FACE_JACKET_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_COLLAR_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_L), SetDataTip(AWV_DECREASE, STR_FACE_COLLAR_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_COLLAR), SetDataTip(STR_EMPTY, STR_FACE_COLLAR_TOOLTIP), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_R), SetDataTip(AWV_INCREASE, STR_FACE_COLLAR_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_TIE_EARRING_TEXT), SetFill(1, 0), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_L), SetDataTip(AWV_DECREASE, STR_FACE_TIE_EARRING_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_TIE_EARRING_TOOLTIP), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_R), SetDataTip(AWV_INCREASE, STR_FACE_TIE_EARRING_TOOLTIP), + NWidget(NWID_VERTICAL), + NWidget(NWID_SPACER), SetMinimalSize(0, 2), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_MALE2), SetFill(1, 0), SetDataTip(STR_FACE_MALE_BUTTON, STR_FACE_MALE_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_FEMALE2), SetFill(1, 0), SetDataTip(STR_FACE_FEMALE_BUTTON, STR_FACE_FEMALE_TOOLTIP), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 2), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_ETHNICITY_EUR), SetFill(1, 0), SetDataTip(STR_FACE_EUROPEAN, STR_FACE_SELECT_EUROPEAN), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCMF_ETHNICITY_AFR), SetFill(1, 0), SetDataTip(STR_FACE_AFRICAN, STR_FACE_SELECT_AFRICAN), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 4), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_MOUSTACHE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_MOUSTACHE_EARRING_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAS_GLASSES_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAIR_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_HAIR_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAIR), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_HAIR_TOOLTIP), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_HAIR_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_EYEBROWS_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_EYEBROWS_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYEBROWS), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_EYEBROWS_TOOLTIP), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_EYEBROWS_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_EYECOLOUR_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_EYECOLOUR_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_EYECOLOUR_TOOLTIP), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_EYECOLOUR_TOOLTIP), + EndContainer(), + EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_GLASSES_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_GLASSES_TOOLTIP_2), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_GLASSES), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP_2), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_GLASSES_TOOLTIP_2), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_NOSE_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_NOSE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_NOSE), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_NOSE_TOOLTIP), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_NOSE_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_LIPS_MOUSTACHE_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_CHIN_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_CHIN_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_CHIN), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_CHIN_TOOLTIP), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_CHIN_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_JACKET_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_JACKET_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_JACKET), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_JACKET_TOOLTIP), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_JACKET_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_COLLAR_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_COLLAR_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_COLLAR), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_COLLAR_TOOLTIP), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_COLLAR_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_TIE_EARRING_TEXT), SetFill(1, 0), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_L), SetSizingType(NWST_STEP), SetDataTip(AWV_DECREASE, STR_FACE_TIE_EARRING_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING), SetSizingType(NWST_STEP), SetDataTip(STR_EMPTY, STR_FACE_TIE_EARRING_TOOLTIP), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_R), SetSizingType(NWST_STEP), SetDataTip(AWV_INCREASE, STR_FACE_TIE_EARRING_TOOLTIP), + EndContainer(), + EndContainer(), EndContainer(), NWidget(NWID_SPACER), SetFill(0, 1), EndContainer(), EndContainer(), + NWidget(NWID_SPACER), SetFill(1, 0), EndContainer(), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 2), @@ -1075,7 +1086,7 @@ class SelectCompanyManagerFaceWindow : public Window /* Draw the value/bool in white (0xC). If the button clicked adds 1px to x and y text coordinates (IsWindowWidgetLowered()). */ DrawString(nwi_widget->pos_x + nwi_widget->IsLowered(), nwi_widget->pos_x + nwi_widget->current_x - 1 - nwi_widget->IsLowered(), - nwi_widget->pos_y + 1 + nwi_widget->IsLowered(), str, TC_WHITE, SA_HOR_CENTER); + Center(nwi_widget->pos_y + nwi_widget->IsLowered(), nwi_widget->current_y), str, TC_WHITE, SA_HOR_CENTER); } } @@ -1125,6 +1136,10 @@ public: Dimension yesno_dim = maxdim(GetStringBoundingBox(STR_FACE_YES), GetStringBoundingBox(STR_FACE_NO)); yesno_dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; yesno_dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + + yesno_dim.width = GetMinSizing(NWST_STEP, yesno_dim.width); + yesno_dim.height = GetMinSizing(NWST_STEP, yesno_dim.height); + /* Size of the number button + arrows. */ Dimension number_dim = {0, 0}; for (int val = 1; val <= 12; val++) { @@ -1268,12 +1283,12 @@ public: case WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT: case WID_SCMF_TIE_EARRING_TEXT: { StringID str = PART_TEXTS_IS_FEMALE[(widget - WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT) * 2 + this->is_female]; - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_GOLD, SA_RIGHT); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top), str, TC_GOLD, SA_RIGHT); break; } case WID_SCMF_LIPS_MOUSTACHE_TEXT: - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, (this->is_moust_male) ? STR_FACE_MOUSTACHE : STR_FACE_LIPS, TC_GOLD, SA_RIGHT); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top), (this->is_moust_male) ? STR_FACE_MOUSTACHE : STR_FACE_LIPS, TC_GOLD, SA_RIGHT); break; case WID_SCMF_HAS_GLASSES_TEXT: @@ -1285,7 +1300,7 @@ public: case WID_SCMF_CHIN_TEXT: case WID_SCMF_JACKET_TEXT: case WID_SCMF_COLLAR_TEXT: - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, PART_TEXTS[widget - WID_SCMF_HAS_GLASSES_TEXT], TC_GOLD, SA_RIGHT); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top), PART_TEXTS[widget - WID_SCMF_HAS_GLASSES_TEXT], TC_GOLD, SA_RIGHT); break; diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 9cfc8e8f9d..72d9b81743 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -417,6 +417,20 @@ DEF_CONSOLE_CMD(ConListFiles) return true; } +/* Open the cheat window. */ +DEF_CONSOLE_CMD(ConOpenCheats) +{ + if (argc == 0) { + IConsoleHelp("Open the cheat window. Usage: 'open_cheats'"); + return true; + } + + extern void ShowCheatWindow(); + ShowCheatWindow(); + + return true; +} + /* Change the dir via console */ DEF_CONSOLE_CMD(ConChangeDirectory) { @@ -1921,6 +1935,8 @@ void IConsoleStdLibRegister() IConsoleCmdRegister("save", ConSave); IConsoleCmdRegister("saveconfig", ConSaveConfig); IConsoleCmdRegister("ls", ConListFiles); + IConsoleCmdRegister("open_cheats", ConOpenCheats); + IConsoleCmdRegister("cheats", ConOpenCheats); IConsoleCmdRegister("cd", ConChangeDirectory); IConsoleCmdRegister("pwd", ConPrintWorkingDirectory); IConsoleCmdRegister("clear", ConClearBuffer); diff --git a/src/console_gui.cpp b/src/console_gui.cpp index ed46938cd5..ed84f6fe09 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -22,6 +22,7 @@ #include "console_func.h" #include "rev.h" #include "video/video_driver.hpp" +#include "textbuf_gui.h" #include "widgets/console_widget.h" @@ -29,6 +30,10 @@ #include "safeguards.h" +#ifdef __ANDROID__ +#include +#endif + static const uint ICON_HISTORY_SIZE = 20; static const uint ICON_LINE_SPACING = 2; static const uint ICON_RIGHT_BORDERWIDTH = 10; @@ -229,6 +234,16 @@ struct IConsoleWindow : Window } } + virtual void OnQueryTextFinished(char *str) + { + _focused_window = this; + + if (str == NULL) return; + + _iconsole_cmdline.Assign(str); + this->OnKeyPress(0, WKC_RETURN); + } + virtual void OnHundredthTick() { if (IConsoleLine::Truncate() && @@ -430,9 +445,25 @@ void IConsoleSwitch() { switch (_iconsole_mode) { case ICONSOLE_CLOSED: - new IConsoleWindow(); +#ifdef __ANDROID__ + { + char buf[1024] = ""; + for (const IConsoleLine *print = IConsoleLine::Get(0); print != NULL; print = print->previous) { + if (print->buffer && print->buffer[0]) { + strecat(buf, print->buffer, lastof(buf)); + strecat(buf, "\n", lastof(buf)); + } + } + strecat(buf, "\n\n\n\n\n\n\n\n", lastof(buf)); // Move all text to top + SDL_ANDROID_SetScreenKeyboardHintMesage(buf); + char text[512] = ""; + SDL_ANDROID_GetScreenKeyboardTextInput(text, sizeof(text) - 1); /* Invoke Android built-in screen keyboard */ + IConsoleCmdExec(text); + } +#else + new IConsoleWindow(); +#endif break; - case ICONSOLE_OPENED: case ICONSOLE_FULL: DeleteWindowById(WC_CONSOLE, 0); break; diff --git a/src/debug.cpp b/src/debug.cpp index 16eecadad0..f03e9490bd 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -16,6 +16,9 @@ #include "string_func.h" #include "fileio_func.h" #include "settings_type.h" +#ifdef __ANDROID__ +#include +#endif #include @@ -109,6 +112,9 @@ char *DumpDebugFacilityNames(char *buf, char *last) */ static void debug_print(const char *dbg, const char *buf) { +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, "OpenTTD", "[%s] %s", dbg, buf); +#endif #if defined(ENABLE_NETWORK) if (_debug_socket != INVALID_SOCKET) { char buf2[1024 + 32]; diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 47eefc65e9..5137777726 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -62,8 +62,8 @@ static const NWidgetPart _nested_train_depot_widgets[] = { NWidget(NWID_SELECTION, INVALID_COLOUR, WID_D_SHOW_SELL_CHAIN), NWidget(WWT_IMGBTN, COLOUR_GREY, WID_D_SELL_CHAIN), SetDataTip(SPR_SELL_CHAIN_TRAIN, STR_DEPOT_DRAG_WHOLE_TRAIN_TO_SELL_TOOLTIP), SetResize(0, 1), SetFill(0, 1), EndContainer(), - NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_SELL_ALL), SetDataTip(0x0, STR_NULL), - NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_AUTOREPLACE), SetDataTip(0x0, STR_NULL), + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_SELL_ALL), SetResize(0, 1), SetFill(0, 1), SetDataTip(0x0, STR_NULL), + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_D_AUTOREPLACE), SetResize(0, 1), SetFill(0, 1), SetDataTip(0x0, STR_NULL), EndContainer(), NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_D_V_SCROLL), EndContainer(), @@ -299,7 +299,7 @@ struct DepotWindow : Window { /* Length of consist in tiles with 1 fractional digit (rounded up) */ SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE)); SetDParam(1, 1); - DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter + DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, Center(y, this->resize.step_height, FONT_HEIGHT_SMALL), STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter break; } @@ -309,26 +309,28 @@ struct DepotWindow : Window { default: NOT_REACHED(); } - uint diff_x, diff_y; + uint diff_x, y_sprite, y_num; if (v->IsGroundVehicle()) { /* Arrange unitnumber and flag horizontally */ diff_x = this->flag_width + WD_FRAMERECT_LEFT; - diff_y = (this->resize.step_height - this->flag_height) / 2 - 2; + y_sprite = Center(y, this->resize.step_height, this->flag_height); + y_num = Center(y, this->resize.step_height); } else { /* Arrange unitnumber and flag vertically */ diff_x = WD_FRAMERECT_LEFT; - diff_y = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; + y_num = Center(y, this->resize.step_height, FONT_HEIGHT_NORMAL + this->flag_height + 2); + y_sprite = y_num + FONT_HEIGHT_NORMAL; } int text_left = rtl ? right - this->header_width - 1 : left + diff_x; int text_right = rtl ? right - diff_x : left + this->header_width - 1; if (free_wagon) { - DrawString(text_left, text_right, y + 2, STR_DEPOT_NO_ENGINE); + DrawString(text_left, text_right, Center(y, this->resize.step_height), STR_DEPOT_NO_ENGINE); } else { - DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, rtl ? right - this->flag_width : left + WD_FRAMERECT_LEFT, y + diff_y); + DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, rtl ? right - this->flag_width : left + WD_FRAMERECT_LEFT, y_sprite); SetDParam(0, v->unitnumber); - DrawString(text_left, text_right, y + 2, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA); + DrawString(text_left, text_right, y_num, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA); } } @@ -345,7 +347,7 @@ struct DepotWindow : Window { uint16 num = this->vscroll->GetPosition() * this->num_columns; int maxval = min(this->vehicle_list.Length(), num + (rows_in_display * this->num_columns)); int y; - for (y = r.top + 1; num < maxval; y += this->resize.step_height) { // Draw the rows + for (y = r.top; num < maxval; y += this->resize.step_height) { // Draw the rows for (byte i = 0; i < this->num_columns && num < maxval; i++, num++) { /* Draw all vehicles in the current row */ const Vehicle *v = this->vehicle_list[num]; @@ -624,6 +626,7 @@ struct DepotWindow : Window { int base_width = this->count_width + this->header_width; resize->height = max(GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).height, min_height); + resize->height = GetMinSizing(NWST_STEP, resize->height); if (this->type == VEH_TRAIN) { resize->width = 1; size->width = base_width + 2 * ScaleGUITrad(29); // about 2 parts diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 79eaa89b14..b555daca1c 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -27,6 +27,7 @@ #include "hotkeys.h" #include "gui.h" #include "zoom_func.h" +#include "build_confirmation_func.h" #include "widgets/dock_widget.h" @@ -105,6 +106,7 @@ struct BuildDocksToolbarWindow : Window { ~BuildDocksToolbarWindow() { + if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false); } @@ -146,7 +148,7 @@ struct BuildDocksToolbarWindow : Window { case WID_DT_DEPOT: // Build depot button if (!CanBuildVehicleInfrastructure(VEH_SHIP)) return; - if (HandlePlacePushButton(this, WID_DT_DEPOT, SPR_CURSOR_SHIP_DEPOT, HT_RECT)) ShowBuildDocksDepotPicker(this); + if (HandlePlacePushButton(this, WID_DT_DEPOT, SPR_CURSOR_SHIP_DEPOT, HT_RECT | HT_SCROLL_VIEWPORT)) ShowBuildDocksDepotPicker(this); break; case WID_DT_STATION: // Build station button @@ -156,7 +158,7 @@ struct BuildDocksToolbarWindow : Window { case WID_DT_BUOY: // Build buoy button if (!CanBuildVehicleInfrastructure(VEH_SHIP)) return; - HandlePlacePushButton(this, WID_DT_BUOY, SPR_CURSOR_BUOY, HT_RECT); + HandlePlacePushButton(this, WID_DT_BUOY, SPR_CURSOR_BUOY, HT_RECT | HT_SCROLL_VIEWPORT); break; case WID_DT_RIVER: // Build river button (in scenario editor) @@ -181,33 +183,21 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_LOCK: // Build lock button - DoCommandP(tile, 0, 0, CMD_BUILD_LOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_LOCKS), CcBuildDocks); + /* Reuse DDSP_REMOVE_TRUCKSTOP. */ + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_REMOVE_TRUCKSTOP); break; case WID_DT_DEMOLISH: // Demolish aka dynamite button PlaceProc_DemolishArea(tile); break; + case WID_DT_STATION: // Build station button + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_STATION); + break; + case WID_DT_DEPOT: // Build depot button - DoCommandP(tile, _ship_depot_direction, 0, CMD_BUILD_SHIP_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT), CcBuildDocks); - break; - - case WID_DT_STATION: { // Build station button - uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join - - /* tile is always the land tile, so need to evaluate _thd.pos */ - CommandContainer cmdcont = { tile, _ctrl_pressed, p2, CMD_BUILD_DOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_DOCK_HERE), CcBuildDocks, "" }; - - /* Determine the watery part of the dock. */ - DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile)); - TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile); - - ShowSelectStationIfNeeded(cmdcont, TileArea(tile, tile_to)); - break; - } - case WID_DT_BUOY: // Build buoy button - DoCommandP(tile, 0, 0, CMD_BUILD_BUOY | CMD_MSG(STR_ERROR_CAN_T_POSITION_BUOY_HERE), CcBuildDocks); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); break; case WID_DT_RIVER: // Build river button (in scenario editor) @@ -215,16 +205,26 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button - DoCommandP(tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15, CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE), CcBuildBridge); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_BRIDGE); break; default: NOT_REACHED(); } + MoveAllWindowsOffScreen(); } virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) { - VpSelectTilesWithMethod(pt.x, pt.y, select_method); + switch (last_clicked_widget) { + case WID_DT_BUILD_AQUEDUCT: + case WID_DT_LOCK: + case WID_DT_STATION: + this->OnPlacePresize(pt, TileVirtXY(pt.x, pt.y)); + break; + default: + VpSelectTilesWithMethod(pt.x, pt.y, select_method); + break; + } } virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) @@ -240,24 +240,73 @@ struct BuildDocksToolbarWindow : Window { case DDSP_CREATE_RIVER: DoCommandP(end_tile, start_tile, WATER_CLASS_RIVER, CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_PLACE_RIVERS), CcPlaySound_SPLAT_WATER); break; + case DDSP_BUILD_STATION: { + uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join + + /* Tile is always the land tile, so need to evaluate _thd.pos. */ + CommandContainer cmdcont = { start_tile, _ctrl_pressed, p2, CMD_BUILD_DOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_DOCK_HERE), CcBuildDocks, "" }; + + //SetObjectToPlace(SPR_CURSOR_DOCK, PAL_NONE, HT_SPECIAL, this->window_class, this->window_number); + ShowSelectStationIfNeeded(cmdcont, TileArea(start_tile, end_tile)); + VpStartPreSizing(); + break; + } + + case DDSP_BUILD_BRIDGE: + DoCommandP(start_tile, GetOtherAqueductEnd(start_tile), TRANSPORT_WATER << 15, CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE), CcBuildBridge); + VpStartPreSizing(); + break; + + case DDSP_REMOVE_TRUCKSTOP: { // Reusing for locks. + TileIndex middle_tile = start_tile; + if (start_tile != end_tile) middle_tile = TileAddByDiagDir(start_tile, DiagdirBetweenTiles(start_tile, end_tile)); + DoCommandP(middle_tile, 0, 0, CMD_BUILD_LOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_LOCKS), CcBuildDocks); + VpStartPreSizing(); + break; + } + + case DDSP_SINGLE_TILE: + assert(start_tile == end_tile); + switch (last_clicked_widget) { + case WID_DT_BUOY: + DoCommandP(end_tile, 0, 0, CMD_BUILD_BUOY | CMD_MSG(STR_ERROR_CAN_T_POSITION_BUOY_HERE), CcBuildDocks); + break; + case WID_DT_DEPOT: // Build depot button + DoCommandP(end_tile, _ship_depot_direction, 0, CMD_BUILD_SHIP_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT), CcBuildDocks); + break; + default: NOT_REACHED(); + } default: break; } + MoveAllHiddenWindowsBackToScreen(); } } virtual void OnPlaceObjectAbort() { + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); + if (ConfirmationWindowShown() && _ctrl_pressed) return; DeleteWindowById(WC_BUILD_STATION, TRANSPORT_WATER); DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_WATER); DeleteWindowById(WC_SELECT_STATION, 0); - DeleteWindowByClass(WC_BUILD_BRIDGE); + } + + virtual void SelectLastTool() + { + // User misplaced something - activate last selected tool again + if (this->last_clicked_widget == WIDGET_LIST_END) + return; + Point dummy = {0, 0}; + this->RaiseWidget(this->last_clicked_widget); + this->OnClick(dummy, this->last_clicked_widget, 0); } virtual void OnPlacePresize(Point pt, TileIndex tile_from) { + if (!IsValidTile(tile_from)) return; TileIndex tile_to = tile_from; if (this->last_clicked_widget == WID_DT_BUILD_AQUEDUCT) { @@ -347,7 +396,7 @@ Window *ShowBuildDocksToolbar() { if (!Company::IsValidID(_local_company)) return NULL; - DeleteWindowByClass(WC_BUILD_TOOLBAR); + DeleteToolbarLinkedWindows(); return AllocateWindowDescFront(&_build_docks_toolbar_desc, TRANSPORT_WATER); } @@ -373,7 +422,7 @@ static const NWidgetPart _nested_build_docks_scen_toolbar_widgets[] = { /** Window definition for the build docks in scenario editor window. */ static WindowDesc _build_docks_scen_toolbar_desc( - WDP_AUTO, "toolbar_water_scen", 0, 0, + WDP_ALIGN_TOOLBAR, "toolbar_water_scen", 0, 0, WC_SCEN_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, _nested_build_docks_scen_toolbar_widgets, lengthof(_nested_build_docks_scen_toolbar_widgets) @@ -386,6 +435,7 @@ static WindowDesc _build_docks_scen_toolbar_desc( */ Window *ShowBuildDocksScenToolbar() { + DeleteToolbarLinkedWindows(); return AllocateWindowDescFront(&_build_docks_scen_toolbar_desc, TRANSPORT_WATER); } @@ -556,10 +606,10 @@ static const NWidgetPart _nested_build_docks_depot_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 3), NWidget(NWID_HORIZONTAL_LTR), NWidget(NWID_SPACER), SetMinimalSize(3, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_X), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_X), SetSizingType(NWST_BUTTON), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(2, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_Y), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_Y), SetSizingType(NWST_BUTTON), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(3, 0), EndContainer(), diff --git a/src/economy.cpp b/src/economy.cpp index cdfa059e86..92ce7bcbbe 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1692,7 +1692,9 @@ static void LoadUnloadVehicle(Vehicle *front) } } - amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->cargo, payment); + if (payment != NULL) { + amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->cargo, payment); + } remaining = v->cargo.UnloadCount() > 0; if (amount_unloaded > 0) { dirty_vehicle = true; diff --git a/src/fileio.cpp b/src/fileio.cpp index a72950bc73..467ea0fb92 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -292,7 +292,11 @@ static const char * const _subdirs[] = { "ai" PATHSEP "library" PATHSEP, "game" PATHSEP, "game" PATHSEP "library" PATHSEP, +#ifdef __ANDROID__ "screenshot" PATHSEP, +#else + "screenshot" PATHSEP, +#endif }; assert_compile(lengthof(_subdirs) == NUM_SUBDIRS); @@ -1315,6 +1319,21 @@ void DeterminePaths(const char *exe) _searchpaths[SP_AUTODOWNLOAD_DIR] = NULL; } #endif /* ENABLE_NETWORK */ + +#ifdef __ANDROID__ + // Copy savegames from "full" OpenTTD to "lite" save directory + char curdir[PATH_MAX]; + if (getcwd(curdir, sizeof(curdir)) && strstr(curdir, "org.openttd.sdl.lowmem")) { + // No, I won't implement file copying in C, shell script is just fine for this job + DEBUG(misc, 1, "Copying savegames from ../../org.openttd.sdl/files/.openttd/save to %s", curdir); + system("cd ../../org.openttd.sdl/files/.openttd/save && " + "for F in *.sav ; do " + "ls \"../../../../org.openttd.sdl.lowmem/files/.openttd/save/$F\" || " + "cat \"$F\" > \"../../../../org.openttd.sdl.lowmem/files/.openttd/save/$F\" ; " + "done"); + chdir(curdir); + } +#endif } /** diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index e6cd9625cc..e8b403f542 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -35,11 +35,15 @@ #include "table/strings.h" #include "safeguards.h" +#ifdef __ANDROID__ +#include +#endif LoadCheckData _load_check_data; ///< Data loaded from save during SL_LOAD_CHECK. static bool _fios_path_changed; static bool _savegame_sort_dirty; +static const char *NETWORK_SAVE_FILENAME = "network-save.sav"; /** @@ -106,6 +110,9 @@ static const NWidgetPart _nested_load_dialog_widgets[] = { NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_NEWGRF_INFO), SetDataTip(STR_INTRO_NEWGRF_SETTINGS, STR_NULL), SetFill(1, 0), SetResize(1, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_LOAD_BUTTON), SetDataTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_TOOLTIP), SetFill(1, 0), SetResize(1, 0), EndContainer(), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_LOAD_NETWORK_BUTTON), SetDataTip(STR_SAVELOAD_LOAD_NETWORK_BUTTON, STR_SAVELOAD_LOAD_NETWORK_TOOLTIP), SetFill(1, 0), SetResize(1, 0), NWidget(WWT_RESIZEBOX, COLOUR_GREY), EndContainer(), EndContainer(), @@ -179,7 +186,7 @@ static const NWidgetPart _nested_save_dialog_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY), NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1), NWidget(NWID_HORIZONTAL), - NWidget(NWID_SPACER), SetResize(1, 0), SetFill(1, 1), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SL_SAVE_NETWORK_BUTTON), SetDataTip(STR_SAVELOAD_SAVE_NETWORK_BUTTON, STR_SAVELOAD_SAVE_NETWORK_TOOLTIP), SetFill(1, 1), SetResize(1, 0), NWidget(WWT_RESIZEBOX, COLOUR_GREY), EndContainer(), EndContainer(), @@ -296,6 +303,7 @@ public: this->FinishInitNested(0); this->LowerWidget(WID_SL_DRIVES_DIRECTORIES_LIST); + if (mode == SLD_SAVE_GAME) this->SetWidgetLoweredState(WID_SL_SAVE_NETWORK_BUTTON, _settings_client.gui.save_to_network); /* pause is only used in single-player, non-editor mode, non-menu mode. It * will be unpaused in the WE_DESTROY event handler. */ @@ -375,7 +383,7 @@ public: if (item == this->selected) { GfxFillRect(r.left + 1, y, r.right, y + this->resize.step_height, PC_DARK_BLUE); } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, item->title, _fios_colours[GetDetailedFileType(item->type)]); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, this->resize.step_height), item->title, _fios_colours[GetDetailedFileType(item->type)]); y += this->resize.step_height; if (y >= this->vscroll->GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break; } @@ -486,8 +494,8 @@ public: break; case WID_SL_DRIVES_DIRECTORIES_LIST: - resize->height = FONT_HEIGHT_NORMAL; - size->height = resize->height * 10 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); + size->height = resize->height * 5 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; break; case WID_SL_SORT_BYNAME: case WID_SL_SORT_BYDATE: { @@ -638,6 +646,32 @@ public: /* Note, this is also called via the OSK; and we need to lower the button. */ this->HandleButtonClick(WID_SL_SAVE_GAME); break; + + case WID_SL_SAVE_NETWORK_BUTTON: + _settings_client.gui.save_to_network = !_settings_client.gui.save_to_network; + this->SetWidgetLoweredState(WID_SL_SAVE_NETWORK_BUTTON, _settings_client.gui.save_to_network); + this->SetDirty(); + break; + + case WID_SL_LOAD_NETWORK_BUTTON: { + char savePath[PATH_MAX]; + FiosMakeSavegameName(savePath, NETWORK_SAVE_FILENAME, lastof(savePath)); +#ifdef __ANDROID__ + if (!SDL_ANDROID_CloudLoad(savePath, NULL, "OpenTTD")) { + break; + } +#endif + _load_check_data.Clear(); + SaveOrLoadResult res = SaveOrLoad(savePath, SL_LOAD_CHECK, SAVE_DIR, false); + if (res == SL_OK && !_load_check_data.HasErrors()) { + strecpy(_file_to_saveload.name, savePath, lastof(_file_to_saveload.name)); + strecpy(_file_to_saveload.title, "", lastof(_file_to_saveload.title)); + if (!_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs()) { + _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD_GAME; + } + } + break; + } } } diff --git a/src/fontcache.cpp b/src/fontcache.cpp index 6bea59c103..a37ea0b6ec 100644 --- a/src/fontcache.cpp +++ b/src/fontcache.cpp @@ -383,7 +383,7 @@ static void LoadFreeTypeFont(FontSize fs) return; found_face: - new FreeTypeFontCache(fs, face, settings->size); + new FreeTypeFontCache(fs, face, RescaleFrom854x480(settings->size)); } @@ -460,7 +460,7 @@ static void *AllocateFont(size_t size) static bool GetFontAAState(FontSize size) { /* AA is only supported for 32 bpp */ - if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32) return false; + if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32 && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 16) return false; switch (size) { default: NOT_REACHED(); diff --git a/src/fontdetection.cpp b/src/fontdetection.cpp index 6df45cf6a1..c7412b7789 100644 --- a/src/fontdetection.cpp +++ b/src/fontdetection.cpp @@ -632,7 +632,8 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i if (split != NULL) *split = '\0'; /* First create a pattern to match the wanted language. */ - FcPattern *pat = FcNameParse((FcChar8*)lang); + //FcPattern *pat = FcNameParse((FcChar8*)lang); + FcPattern *pat = FcPatternCreate(); /* We only want to know the filename. */ FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT, NULL); /* Get the list of filenames matching the wanted language. */ @@ -645,6 +646,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i if (fs != NULL) { int best_weight = -1; const char *best_font = NULL; + int best_missing_glypths = 65536; for (int i = 0; i < fs->nfont; i++) { FcPattern *font = fs->fonts[i]; @@ -654,28 +656,32 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i if (res != FcResultMatch || file == NULL) { continue; } + DEBUG(freetype, 1, "Got font %s", file); + int missing = 0; /* Get a font with the right spacing .*/ int value = 0; FcPatternGetInteger(font, FC_SPACING, 0, &value); - if (callback->Monospace() != (value == FC_MONO) && value != FC_DUAL) continue; + if (callback->Monospace() != (value == FC_MONO) && value != FC_DUAL) missing += 1; /* Do not use those that explicitly say they're slanted. */ FcPatternGetInteger(font, FC_SLANT, 0, &value); - if (value != 0) continue; + if (value != 0) missing += 1; /* We want the fatter font as they look better at small sizes. */ FcPatternGetInteger(font, FC_WEIGHT, 0, &value); - if (value <= best_weight) continue; + if (value <= best_weight) missing += 1; callback->SetFontNames(settings, (const char*)file); - bool missing = callback->FindMissingGlyphs(NULL); - DEBUG(freetype, 1, "Font \"%s\" misses%s glyphs", file, missing ? "" : " no"); + missing = callback->FindMissingGlyphs(NULL); + DEBUG(freetype, 1, "Font \"%s\" misses %d glyphs for lang %s", file, missing, lang); - if (!missing) { + if (missing < best_missing_glypths) { best_weight = value; best_font = (const char *)file; + best_missing_glypths = missing; + if (missing == 0) break; } } @@ -683,6 +689,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i ret = true; callback->SetFontNames(settings, best_font); InitFreeType(callback->Monospace()); + DEBUG(freetype, 1, "Selected font %s for lang %s", best_font, lang); } /* Clean up the list of filenames. */ diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 359709e361..2e1bf0f9ed 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -29,6 +29,7 @@ #include "saveload/saveload.h" #include "progress.h" #include "error.h" +#include "settings_gui.h" #include "widgets/genworld_widget.h" @@ -63,20 +64,20 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = { EndContainer(), NWidget(WWT_PANEL, COLOUR_BROWN), NWidget(NWID_SPACER), SetMinimalSize(0, 10), - /* Landscape selection. */ - NWidget(NWID_HORIZONTAL), SetPIP(10, 0, 10), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE), - NWidget(NWID_SPACER), SetFill(1, 0), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 11), NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10), + /* Landscape selection. */ + NWidget(NWID_VERTICAL), SetPIP(10, 0, 10), + NWidget(NWID_SPACER), SetFill(1, 1), + NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE), + NWidget(NWID_SPACER), SetFill(1, 1), + NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE), + NWidget(NWID_SPACER), SetFill(1, 1), + NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE), + NWidget(NWID_SPACER), SetFill(1, 1), + NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE), + NWidget(NWID_SPACER), SetFill(1, 1), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(20, 0), NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), /* Left column with labels. */ NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), @@ -169,7 +170,7 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = { NWidget(NWID_SPACER), SetFill(1, 1), EndContainer(), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 9), SetFill(1, 1), + NWidget(NWID_SPACER), SetMinimalSize(0, 10), EndContainer(), }; @@ -458,6 +459,7 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_MAPSIZE_Y_PULLDOWN: SetDParamMaxValue(0, MAX_MAP_SIZE); *size = maxdim(*size, GetStringBoundingBox(STR_JUST_INT)); + size->width = size->width + GetMinSizing(NWST_BUTTON); break; case WID_GL_SNOW_LEVEL_TEXT: @@ -468,7 +470,8 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_HEIGHTMAP_SIZE_TEXT: SetDParam(0, this->x); SetDParam(1, this->y); - *size = maxdim(*size, GetStringBoundingBox(STR_MAPGEN_HEIGHTMAP_SIZE)); + //*size = maxdim(*size, GetStringBoundingBox(STR_MAPGEN_HEIGHTMAP_SIZE)); + size->height = SETTING_BUTTON_HEIGHT; break; case WID_GL_TOWN_PULLDOWN: @@ -492,18 +495,19 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_VARIETY_PULLDOWN: strs = _variety; break; case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: strs = _rotation; break; case WID_GL_BORDERS_RANDOM: - *size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOMIZE), GetStringBoundingBox(STR_MAPGEN_BORDER_MANUAL)); + //*size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOMIZE), GetStringBoundingBox(STR_MAPGEN_BORDER_MANUAL)); break; case WID_GL_WATER_NE: case WID_GL_WATER_NW: case WID_GL_WATER_SE: case WID_GL_WATER_SW: - *size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOM), maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_WATER), GetStringBoundingBox(STR_MAPGEN_BORDER_FREEFORM))); + //*size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOM), maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_WATER), GetStringBoundingBox(STR_MAPGEN_BORDER_FREEFORM))); break; case WID_GL_HEIGHTMAP_NAME_TEXT: size->width = 0; + size->height = SETTING_BUTTON_HEIGHT; break; default: @@ -947,7 +951,9 @@ struct CreateScenarioWindow : public Window } *size = maxdim(*size, GetStringBoundingBox(str)); size->width += padding.width; + size->width = GetMinSizing(NWST_BUTTON, size->width); size->height += padding.height; + size->height = GetMinSizing(NWST_BUTTON, size->height); } virtual void OnClick(Point pt, int widget, int click_count) @@ -1066,11 +1072,16 @@ static const NWidgetPart _nested_create_scenario_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 10), /* Landscape style selection. */ NWidget(NWID_HORIZONTAL), SetPIP(10, 3, 10), + NWidget(NWID_SPACER), SetFill(1, 1), NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE), + NWidget(NWID_SPACER), SetFill(1, 1), NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE), + NWidget(NWID_SPACER), SetFill(1, 1), NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE), + NWidget(NWID_SPACER), SetFill(1, 1), NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE), - EndContainer(), + NWidget(NWID_SPACER), SetFill(1, 1), + EndContainer(), NWidget(NWID_HORIZONTAL), SetPIP(10, 8, 10), /* Green generation type buttons: 'Flat land' and 'Random land'. */ NWidget(NWID_VERTICAL), SetPIP(10, 6, 10), diff --git a/src/gfx.cpp b/src/gfx.cpp index 7195051577..06123fd73e 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -35,11 +35,15 @@ byte _support8bpp; CursorVars _cursor; bool _ctrl_pressed; ///< Is Ctrl pressed? bool _shift_pressed; ///< Is Shift pressed? +bool _move_pressed; + byte _fast_forward; bool _left_button_down; ///< Is left mouse button pressed? bool _left_button_clicked; ///< Is left mouse button clicked? bool _right_button_down; ///< Is right mouse button pressed? bool _right_button_clicked; ///< Is right mouse button clicked? +Point _right_button_down_pos; ///< Pos of right mouse button click, for drag and drop + DrawPixelInfo _screen; bool _screen_disable_anim = false; ///< Disable palette animation (important for 32bpp-anim blitter during giant screenshot) bool _exit_game; @@ -848,6 +852,50 @@ void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, } } +/** + * Draw a sprite, centered at x:y, not in a viewport + * @param img Image number to draw + * @param pal Palette to use. + * @param x Left coordinate of image in pixels + * @param y Top coordinate of image in pixels + * @param sub If available, draw only specified part of the sprite + * @param zoom Zoom level of sprite + */ +void DrawSpriteCentered(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom) +{ + Dimension size = GetSpriteSize(img, NULL, zoom); + DrawSprite(img, pal, x - size.width / 2, y - size.height / 2, sub, zoom); +} + +/** + * Draw a sprite, centered in rect, not in a viewport + * @param img Image number to draw + * @param pal Palette to use. + * @param left Left coordinate of image bounding box in pixels + * @param top Top coordinate of image bounding box in pixels + * @param right Right coordinate of image bounding box in pixels + * @param bottom Bottom coordinate of image bounding box in pixels + * @param sub If available, draw only specified part of the sprite + * @param zoom Zoom level of sprite + */ +void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, int left, int top, int right, int bottom, const SubSprite *sub, ZoomLevel zoom) +{ + DrawSpriteCentered(img, pal, (left + right) / 2, (top + bottom) / 2, sub, zoom); +} + +/** + * Draw a sprite, centered in rect, not in a viewport + * @param img Image number to draw + * @param pal Palette to use. + * @param rect Image bounding box in pixels + * @param sub If available, draw only specified part of the sprite + * @param zoom Zoom level of sprite + */ +void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, const Rect &rect, const SubSprite *sub, ZoomLevel zoom) +{ + DrawSpriteCenteredRect(img, pal, rect.left, rect.top, rect.right, rect.bottom, sub, zoom); +} + /** * The code for setting up the blitter mode and sprite information before finally drawing the sprite. * @param sprite The sprite to draw. @@ -1197,6 +1245,8 @@ void ScreenSizeChanged() /* screen size changed and the old bitmap is invalid now, so we don't want to undraw it */ _cursor.visible = false; + + CheckWindowMinSizings(); } void UndrawMouseCursor() @@ -1214,11 +1264,6 @@ void UndrawMouseCursor() void DrawMouseCursor() { -#if defined(WINCE) - /* Don't ever draw the mouse for WinCE, as we work with a stylus */ - return; -#endif - /* Don't draw the mouse cursor if the screen is not ready */ if (_screen.dst_ptr == NULL) return; @@ -1710,3 +1755,104 @@ void SortResolutions(int count) { QSortT(_resolutions, count, &compare_res); } + + +/** + * Returns the initial value for a margin, after telling where are the left and right margins and where we want to draw/write (begining/end of line) + * @param left is the left margin of the horizontal space we want to draw to + * @param right: right margin + * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end + * @return the margin we asked + */ +int InitTempMargin(int left, int right, bool to_end_line) +{ + return to_end_line ^ (_current_text_dir == TD_RTL) ? right :left; +} + +/** + * Consumes a space in an horizontal margin + * @param space: amount of space used + * @param here: the margin where to add the space + * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end + */ +void AddSpace(int space, int &here, bool to_end_line) +{ + here += to_end_line ^ (_current_text_dir == TD_RTL) ? -space : space; +} + +/** + * After drawing something, update a margin + * @param end is where we ended drawing (usually the return value of a DrawString function) + * @param margin is the margin we want to update + * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end + */ +void UpdateMarginEnd(int end, int &margin, bool to_end_line) +{ + margin = to_end_line ^ (_current_text_dir == TD_RTL) ? min(end, margin) : max(end, margin); +} + +/** + * After drawing something, horizontal margins are updated + * @param end: last position drawn + * @param left is the left margin of the horizontal space drawn + * @param right: right margin + * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end + */ +void UpdateMarginsEnd(int end, int &left, int &right, bool to_end_line) +{ + if (to_end_line ^ (_current_text_dir == TD_RTL)) { + right = end; + } else { + left = end; + } +} + +/** + * After drawing something of a certain width, update margins + * @param width: used space + * @param initial left margin + * @param initial right margin + * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end + */ +void UpdateMarginsWidth(int width, int &left, int &right, bool to_end_line) +{ + if (to_end_line ^ (_current_text_dir == TD_RTL)) { + right -= width; + } else { + left += width; + } +} + +/** + * Draws a string in a delimited space; temporal margin gets updated + * @param left is the left margin of the horizontal space we want to draw to + * @param right: right margin of the horizontal space we want to draw to + * @param top: vertical position + * @param margin keeps the most extreme limit used of the line (this should be previously initialized with InitTempLimit) + * @param string to draw + * @param colour for the string + * @param alignment of the string (only left or right alignment) + * @param underline + */ +void DrawString2(int left, int right, int top, int &margin, StringID str, TextColour colour, StringAlignment align, bool underline) +{ + int end = DrawString(left, right, top, str, colour, align, underline); + UpdateMarginEnd(end, margin, align == SA_RIGHT); +} + +/** + * Draws a sprite in a delimited space; temporal margin gets updated + * @param width of the sprite + * @param left is the left margin of the horizontal space we want to draw to + * @param right: right margin of the horizontal space + * @param top: vertical position + * @param margin keeps the most extreme limit used of the line (this should be previously initialized with InitTempLimit) + * @param sprite + * @param palette + * @param to_end_line: 0 if working at the begining of the line, 1 if working at the end + */ +void DrawSprite2(int width, int left, int right, int top, int &margin, SpriteID img, PaletteID pal, bool to_end_line, SubSprite *sub) +{ + DrawSprite(img, pal, to_end_line ^ (_current_text_dir == TD_RTL) ? right - width : left, top, sub); + margin = to_end_line ^ (_current_text_dir == TD_RTL) ? min(right - width, margin): max(margin, left + width); +} diff --git a/src/gfx_func.h b/src/gfx_func.h index 566f91b2da..08acd08a85 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -45,6 +45,7 @@ #include "gfx_type.h" #include "strings_type.h" #include "string_type.h" +#include "core/math_func.hpp" void GameLoop(); @@ -56,12 +57,15 @@ extern byte _support8bpp; extern CursorVars _cursor; extern bool _ctrl_pressed; ///< Is Ctrl pressed? extern bool _shift_pressed; ///< Is Shift pressed? +extern bool _move_pressed; + extern byte _fast_forward; extern bool _left_button_down; extern bool _left_button_clicked; extern bool _right_button_down; extern bool _right_button_clicked; +extern Point _right_button_down_pos; extern DrawPixelInfo _screen; extern bool _screen_disable_anim; ///< Disable palette animation (important for 32bpp-anim blitter during giant screenshot) @@ -92,6 +96,9 @@ void GfxScroll(int left, int top, int width, int height, int xo, int yo); Dimension GetSpriteSize(SpriteID sprid, Point *offset = NULL, ZoomLevel zoom = ZOOM_LVL_GUI); void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL); void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI); +void DrawSpriteCentered(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI); +void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, int left, int top, int right, int bottom, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI); +void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, const Rect &r, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI); /** How to align the to-be drawn text. */ enum StringAlignment { @@ -173,6 +180,39 @@ int GetCharacterHeight(FontSize size); /** Height of characters in the large (#FS_MONO) font. @note Some characters may be oversized. */ #define FONT_HEIGHT_MONO (GetCharacterHeight(FS_MONO)) +int InitTempMargin(int left, int right, bool to_end_line); +void AddSpace(int space, int &here, bool to_end_line); + +void UpdateMarginEnd(int end, int &margin, bool to_end_line); +void UpdateMarginWidth(int adding, int &margin, bool to_end_line); +void UpdateMarginsEnd(int end, int &left, int &right, bool to_end_line); +void UpdateMarginsWidth(int width, int &left, int &right, bool to_end_line); + +void DrawString2(int left, int right, int top, int &margin, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false); +void DrawSprite2(int width, int left, int right, int top, int &margin, SpriteID img, PaletteID pal, bool to_end_line = false, SubSprite *sub = NULL); + +/** + * Return where to start drawing a centered object inside a widget. + * @param top The top coordinate (or the left coordinate) of the widget. + * @param height The height (or width) of the widget. + * @param size The height (or width) of the object to draw. + * @return The coordinate where to start drawing the centered object. + */ +static inline int Center(int top, int height, uint size = FONT_HEIGHT_NORMAL) +{ + return top + (height - size) / 2; +} + +/** + * Returns fint/button size, rescaled to current screen resolution from the base Android resolution, which is 854x480 + * @param value The value to rescale + * @return Rescaled value, using lesser of the curret screen coordinates + */ +static inline int RescaleFrom854x480(int value) +{ + return min(value * _cur_resolution.width / 854, value * _cur_resolution.height / 480); +} + extern DrawPixelInfo *_cur_dpi; TextColour GetContrastColour(uint8 background); diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index c12c6ace4d..019c4f039d 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -116,6 +116,7 @@ static NWidgetBase *MakeNWidgetCompanyLines(int *biggest_index) for (int widnum = WID_GL_FIRST_COMPANY; widnum <= WID_GL_LAST_COMPANY; widnum++) { NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, widnum); + panel->sizing_type = NWST_STEP; panel->SetMinimalSize(246, line_height); panel->SetFill(1, 0); panel->SetDataTip(0x0, STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP); @@ -1130,6 +1131,7 @@ private: uint ordinal_width; ///< The width of the ordinal number uint text_width; ///< The width of the actual text uint icon_width; ///< The width of the company icon + uint icon_y_offset; ///< The vertical offset for drawing the company icon. int line_height; ///< Height of the text lines /** @@ -1176,8 +1178,7 @@ public: { if (widget != WID_CL_BACKGROUND) return; - int icon_y_offset = 1 + (FONT_HEIGHT_NORMAL - this->line_height) / 2; - uint y = r.top + WD_FRAMERECT_TOP - icon_y_offset; + uint y = r.top + WD_FRAMERECT_TOP; bool rtl = _current_text_dir == TD_RTL; uint ordinal_left = rtl ? r.right - WD_FRAMERECT_LEFT - this->ordinal_width : r.left + WD_FRAMERECT_LEFT; @@ -1190,7 +1191,7 @@ public: const Company *c = this->companies[i]; DrawString(ordinal_left, ordinal_right, y, i + STR_ORDINAL_NUMBER_1ST, i == 0 ? TC_WHITE : TC_YELLOW); - DrawCompanyIcon(c->index, icon_left, y + icon_y_offset); + DrawCompanyIcon(c->index, icon_left, y + this->icon_y_offset); SetDParam(0, c->index); SetDParam(1, c->index); @@ -1223,6 +1224,7 @@ public: Dimension d = GetSpriteSize(SPR_COMPANY_ICON); this->icon_width = d.width + 2; this->line_height = max(d.height + 2, FONT_HEIGHT_NORMAL); + this->icon_y_offset = Center(1, this->line_height, d.height); const Company *c; FOR_ALL_COMPANIES(c) { diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 361ab53e56..9dd052179a 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -47,8 +47,7 @@ static const NWidgetPart _nested_group_widgets[] = { NWidget(NWID_HORIZONTAL), /* left part */ NWidget(NWID_VERTICAL), - NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalTextLines(1, WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM), SetFill(1, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_ALL_VEHICLES), SetFill(1, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_ALL_VEHICLES), SetFill(1, 0), SetMinimalTextLines(1, WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_DEFAULT_VEHICLES), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_MATRIX, COLOUR_GREY, WID_GL_LIST_GROUP), SetMatrixDataTip(1, 0, STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP), @@ -70,7 +69,7 @@ static const NWidgetPart _nested_group_widgets[] = { /* right part */ NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_SORT_BY_ORDER), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_SORT_BY_ORDER), SetSizingType(NWST_STEP), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_SORT_BY_DROPDOWN), SetMinimalSize(167, 12), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA), NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetResize(1, 0), EndContainer(), EndContainer(), @@ -78,7 +77,7 @@ static const NWidgetPart _nested_group_widgets[] = { NWidget(WWT_MATRIX, COLOUR_GREY, WID_GL_LIST_VEHICLE), SetMinimalSize(248, 0), SetMatrixDataTip(1, 0, STR_NULL), SetResize(1, 1), SetFill(1, 0), SetScrollbar(WID_GL_LIST_VEHICLE_SCROLLBAR), NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_GL_LIST_VEHICLE_SCROLLBAR), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(1, 0), SetFill(1, 1), SetResize(1, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_AVAILABLE_VEHICLES), SetMinimalSize(106, 12), SetFill(0, 1), SetDataTip(STR_BLACK_STRING, STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP), @@ -192,8 +191,9 @@ private: uint ComputeGroupInfoSize() { this->column_size[VGC_NAME] = maxdim(GetStringBoundingBox(STR_GROUP_DEFAULT_TRAINS + this->vli.vtype), GetStringBoundingBox(STR_GROUP_ALL_TRAINS + this->vli.vtype)); - this->column_size[VGC_NAME].width = max(170u, this->column_size[VGC_NAME].width); - this->tiny_step_height = this->column_size[VGC_NAME].height; +/* We consider the max average length of characters to be the one of "a" */ + this->column_size[VGC_NAME].width = max(GetCharacterWidth(FS_NORMAL, 97) * (MAX_LENGTH_GROUP_NAME_CHARS - 4), this->column_size[VGC_NAME].width); + this->tiny_step_height = max(11U, this->column_size[VGC_NAME].height); this->column_size[VGC_PROTECT] = GetSpriteSize(SPR_GROUP_REPLACE_PROTECT); this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_PROTECT].height); @@ -215,9 +215,10 @@ private: this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_NUMBER].height); this->tiny_step_height += WD_MATRIX_TOP; + this->tiny_step_height = GetMinSizing(NWST_STEP, this->tiny_step_height); return WD_FRAMERECT_LEFT + 8 + - this->column_size[VGC_NAME].width + 8 + + this->column_size[VGC_NAME].width + 2 + this->column_size[VGC_PROTECT].width + 2 + this->column_size[VGC_AUTOREPLACE].width + 2 + this->column_size[VGC_PROFIT].width + 2 + @@ -238,7 +239,7 @@ private: { /* Highlight the group if a vehicle is dragged over it */ if (g_id == this->group_over) { - GfxFillRect(left + WD_FRAMERECT_LEFT, y + WD_FRAMERECT_TOP, right - WD_FRAMERECT_RIGHT, y + this->tiny_step_height - WD_FRAMERECT_BOTTOM - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][7]); + GfxFillRect(left + WD_FRAMERECT_LEFT, y + WD_FRAMERECT_TOP + WD_MATRIX_TOP, right - WD_FRAMERECT_RIGHT, y + this->tiny_step_height - WD_FRAMERECT_BOTTOM - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][7]); } if (g_id == NEW_GROUP) return; @@ -249,6 +250,7 @@ private: bool rtl = _current_text_dir == TD_RTL; /* draw group name */ + int longer_name = 0; StringID str; if (IsAllGroupID(g_id)) { str = STR_GROUP_ALL_TRAINS + this->vli.vtype; @@ -257,12 +259,16 @@ private: } else { SetDParam(0, g_id); str = STR_GROUP_NAME; + if (!protection) { + longer_name += this->column_size[VGC_PROTECT].width + 2; + if (!stats.autoreplace_defined) longer_name += this->column_size[VGC_AUTOREPLACE].width + 2; + } } - int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width + 1 : left + WD_FRAMERECT_LEFT + 8; - DrawString(x + indent * LEVEL_WIDTH, x + this->column_size[VGC_NAME].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour); + int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width - longer_name + 1 : left + WD_FRAMERECT_LEFT + 8; + DrawString(x + indent * LEVEL_WIDTH, x + this->column_size[VGC_NAME].width + longer_name - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour); /* draw autoreplace protection */ - x = rtl ? x - 8 - this->column_size[VGC_PROTECT].width : x + 8 + this->column_size[VGC_NAME].width; + x = rtl ? x - 2 - this->column_size[VGC_PROTECT].width : x + 2 + this->column_size[VGC_NAME].width; if (protection) DrawSprite(SPR_GROUP_REPLACE_PROTECT, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROTECT].height) / 2); /* draw autoreplace status */ @@ -363,16 +369,10 @@ public: resize->height = this->tiny_step_height; /* Minimum height is the height of the list widget minus all and default vehicles... */ - size->height = 4 * GetVehicleListHeight(this->vli.vtype, this->tiny_step_height) - 2 * this->tiny_step_height; - - /* ... minus the buttons at the bottom ... */ - uint max_icon_height = GetSpriteSize(this->GetWidget(WID_GL_CREATE_GROUP)->widget_data).height; - max_icon_height = max(max_icon_height, GetSpriteSize(this->GetWidget(WID_GL_RENAME_GROUP)->widget_data).height); - max_icon_height = max(max_icon_height, GetSpriteSize(this->GetWidget(WID_GL_DELETE_GROUP)->widget_data).height); - max_icon_height = max(max_icon_height, GetSpriteSize(this->GetWidget(WID_GL_REPLACE_PROTECTION)->widget_data).height); + size->height = (this->vli.vtype >= VEH_SHIP ? 3.5 : 7) * GetVehicleListHeight(this->vli.vtype, this->tiny_step_height) - 2 * this->tiny_step_height; /* Get a multiple of tiny_step_height of that amount */ - size->height = Ceil(size->height - max_icon_height, tiny_step_height); + size->height = Ceil(size->height, tiny_step_height); break; } @@ -393,7 +393,7 @@ public: case WID_GL_LIST_VEHICLE: this->ComputeGroupInfoSize(); resize->height = GetVehicleListHeight(this->vli.vtype, this->tiny_step_height); - size->height = 4 * resize->height; + size->height = (this->vli.vtype >= VEH_SHIP ? 3 : 6) * resize->height; break; case WID_GL_MANAGE_VEHICLES_DROPDOWN: { @@ -520,15 +520,15 @@ public: { switch (widget) { case WID_GL_ALL_VEHICLES: - DrawGroupInfo(r.top + WD_FRAMERECT_TOP, r.left, r.right, ALL_GROUP); + DrawGroupInfo(r.top, r.left, r.right, ALL_GROUP); break; case WID_GL_DEFAULT_VEHICLES: - DrawGroupInfo(r.top + WD_FRAMERECT_TOP, r.left, r.right, DEFAULT_GROUP); + DrawGroupInfo(r.top, r.left, r.right, DEFAULT_GROUP); break; case WID_GL_LIST_GROUP: { - int y1 = r.top + WD_FRAMERECT_TOP; + int y1 = r.top; int max = min(this->group_sb->GetPosition() + this->group_sb->GetCapacity(), this->groups.Length()); for (int i = this->group_sb->GetPosition(); i < max; ++i) { const Group *g = this->groups[i]; diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index b9077b9d77..3ff55d3458 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -235,7 +235,7 @@ static const NWidgetPart _nested_build_industry_widgets[] = { /** Window definition of the dynamic place industries gui */ static WindowDesc _build_industry_desc( - WDP_AUTO, "build_industry", 170, 212, + WDP_ALIGN_TOOLBAR, "build_industry", 170, 212, WC_BUILD_INDUSTRY, WC_NONE, WDF_CONSTRUCTION, _nested_build_industry_widgets, lengthof(_nested_build_industry_widgets) @@ -252,9 +252,6 @@ class BuildIndustryWindow : public Window { bool enabled[NUM_INDUSTRYTYPES + 1]; ///< availability state, coming from CBID_INDUSTRY_PROBABILITY (if ever) Scrollbar *vscroll; - /** The offset for the text in the matrix. */ - static const int MATRIX_TEXT_OFFSET = 17; - void SetupArrays() { this->count = 0; @@ -328,6 +325,10 @@ public: this->SetButtons(); } + ~BuildIndustryWindow() { + if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); + } + virtual void OnInit() { this->SetupArrays(); @@ -342,8 +343,8 @@ public: if (this->index[i] == INVALID_INDUSTRYTYPE) continue; d = maxdim(d, GetStringBoundingBox(GetIndustrySpec(this->index[i])->name)); } - resize->height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; - d.width += MATRIX_TEXT_OFFSET + padding.width; + resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM); + d.width += FONT_HEIGHT_NORMAL * 5 / 4 + padding.width; d.height = 5 * resize->height; *size = maxdim(*size, d); break; @@ -427,20 +428,22 @@ public: switch (widget) { case WID_DPI_MATRIX_WIDGET: { uint text_left, text_right, icon_left, icon_right; + uint square_size = FONT_HEIGHT_NORMAL - 2; + uint text_offset = FONT_HEIGHT_NORMAL * 5 / 4; if (_current_text_dir == TD_RTL) { icon_right = r.right - WD_MATRIX_RIGHT; - icon_left = icon_right - 10; - text_right = icon_right - BuildIndustryWindow::MATRIX_TEXT_OFFSET; + icon_left = icon_right - square_size; + text_right = icon_right - text_offset; text_left = r.left + WD_MATRIX_LEFT; } else { icon_left = r.left + WD_MATRIX_LEFT; - icon_right = icon_left + 10; - text_left = icon_left + BuildIndustryWindow::MATRIX_TEXT_OFFSET; + icon_right = icon_left + square_size; + text_left = icon_left + text_offset; text_right = r.right - WD_MATRIX_RIGHT; } - for (byte i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->count; i++) { - int y = r.top + WD_MATRIX_TOP + i * this->resize.step_height; + int y = Center(r.top, this->resize.step_height); + for (byte i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->count; i++, y += this->resize.step_height) { bool selected = this->selected_index == i + this->vscroll->GetPosition(); if (this->index[i + this->vscroll->GetPosition()] == INVALID_INDUSTRYTYPE) { @@ -451,8 +454,8 @@ public: /* Draw the name of the industry in white is selected, otherwise, in orange */ DrawString(text_left, text_right, y, indsp->name, selected ? TC_WHITE : TC_ORANGE); - GfxFillRect(icon_left, y + 1, icon_right, y + 7, selected ? PC_WHITE : PC_BLACK); - GfxFillRect(icon_left + 1, y + 2, icon_right - 1, y + 6, indsp->map_colour); + GfxFillRect(icon_left, y + 1, icon_right, y + square_size, selected ? PC_WHITE : PC_BLACK); + GfxFillRect(icon_left + 1, y + 2, icon_right - 1, y + square_size - 1, indsp->map_colour); } break; } @@ -591,6 +594,21 @@ public: virtual void OnPlaceObject(Point pt, TileIndex tile) { + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); + MoveAllWindowsOffScreen(); + } + + virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + { + VpSelectTilesWithMethod(pt.x, pt.y, select_method); + } + + virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + { + if (pt.x == -1) return; + assert(end_tile == start_tile); + + MoveAllHiddenWindowsBackToScreen(); bool success = true; /* We do not need to protect ourselves against "Random Many Industries" in this mode */ const IndustrySpec *indsp = GetIndustrySpec(this->selected_type); @@ -608,14 +626,14 @@ public: _generating_world = true; _ignore_restrictions = true; - DoCommandP(tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, + DoCommandP(end_tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), &CcBuildIndustry); cur_company.Restore(); _ignore_restrictions = false; _generating_world = false; } else { - success = DoCommandP(tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY)); + success = DoCommandP(end_tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY)); } /* If an industry has been built, just reset the cursor and the system */ @@ -653,6 +671,7 @@ public: virtual void OnPlaceObjectAbort() { + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); } @@ -675,7 +694,7 @@ public: void ShowBuildIndustryWindow() { if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return; - if (BringWindowToFrontById(WC_BUILD_INDUSTRY, 0)) return; + DeleteToolbarLinkedWindows(); new BuildIndustryWindow(); } @@ -818,7 +837,7 @@ public: if (first) { if (has_accept) y += WD_PAR_VSEP_WIDE; DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE); - y += FONT_HEIGHT_NORMAL; + y += this->editable == EA_RATE ? GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) : FONT_HEIGHT_NORMAL; if (this->editable == EA_RATE) this->production_offset_y = y; first = false; } @@ -833,8 +852,10 @@ public: if (this->editable == EA_RATE) { DrawArrowButtons(left + WD_FRAMETEXT_LEFT, y, COLOUR_YELLOW, (this->clicked_line == IL_RATE1 + j) ? this->clicked_button : 0, i->production_rate[j] > 0, i->production_rate[j] < 255); + y += GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); + } else { + y += FONT_HEIGHT_NORMAL; } - y += FONT_HEIGHT_NORMAL; } /* Display production multiplier if editable */ @@ -846,7 +867,7 @@ public: DrawString(x, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LEVEL); DrawArrowButtons(left + WD_FRAMETEXT_LEFT, y, COLOUR_YELLOW, (this->clicked_line == IL_MULTIPLIER) ? this->clicked_button : 0, i->prod_level > PRODLEVEL_MINIMUM, i->prod_level < PRODLEVEL_MAXIMUM); - y += FONT_HEIGHT_NORMAL; + y += GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); } /* Get the extra message for the GUI */ @@ -894,12 +915,14 @@ public: case EA_NONE: break; case EA_MULTIPLIER: - if (IsInsideBS(pt.y, this->production_offset_y, FONT_HEIGHT_NORMAL)) line = IL_MULTIPLIER; + if (IsInsideBS(pt.y, this->production_offset_y, SETTING_BUTTON_HEIGHT)) line = IL_MULTIPLIER; break; case EA_RATE: if (pt.y >= this->production_offset_y) { - int row = (pt.y - this->production_offset_y) / FONT_HEIGHT_NORMAL; + if ((pt.y - this->production_offset_y) % GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) > (uint)SETTING_BUTTON_HEIGHT) break;; + + int row = (pt.y - this->production_offset_y) / GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); for (uint j = 0; j < lengthof(i->produced_cargo); j++) { if (i->produced_cargo[j] == CT_INVALID) continue; row--; @@ -1115,7 +1138,7 @@ static const NWidgetPart _nested_industry_directory_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), + NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetSizingType(NWST_STEP), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(), EndContainer(), @@ -1320,7 +1343,7 @@ public: case WID_ID_INDUSTRY_LIST: { int n = 0; - int y = r.top + WD_FRAMERECT_TOP; + int y = Center(r.top, this->resize.step_height); if (this->industries.Length() == 0) { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_DIRECTORY_NONE); break; @@ -1363,7 +1386,7 @@ public: for (uint i = 0; i < this->industries.Length(); i++) { d = maxdim(d, GetStringBoundingBox(this->GetIndustryString(this->industries[i]))); } - resize->height = d.height; + resize->height = d.height = GetMinSizing(NWST_STEP, d.height); d.height *= 5; d.width += padding.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; diff --git a/src/ini.cpp b/src/ini.cpp index 905ebfacf8..c8ea89c1d2 100644 --- a/src/ini.cpp +++ b/src/ini.cpp @@ -15,7 +15,7 @@ #include "string_func.h" #include "fileio_func.h" -#if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) +#if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) || defined(__ANDROID__) # include #endif diff --git a/src/intro_gui.cpp b/src/intro_gui.cpp index 3659b033cf..e47ed730f5 100644 --- a/src/intro_gui.cpp +++ b/src/intro_gui.cpp @@ -27,6 +27,7 @@ #include "language.h" #include "rev.h" #include "highscore.h" +#include "tutorial_gui.h" #include "widgets/intro_widget.h" @@ -158,13 +159,14 @@ struct SelectGameWindow : public Window { } break; case WID_SGI_AI_SETTINGS: ShowAIConfigWindow(); break; + case WID_SGI_TUTORIAL: ShowTutorialWindow(); break; case WID_SGI_EXIT: HandleExitGameRequest(); break; } } }; static const NWidgetPart _nested_select_game_widgets[] = { - NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_INTRO_CAPTION, STR_NULL), + NWidget(WWT_CAPTION, COLOUR_BROWN), SetSizingType(NWST_BUTTON), SetDataTip(STR_INTRO_CAPTION, STR_NULL), NWidget(WWT_PANEL, COLOUR_BROWN), NWidget(NWID_SPACER), SetMinimalSize(0, 8), @@ -258,11 +260,11 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 6), /* 'exit program' button */ - NWidget(NWID_HORIZONTAL), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_EXIT), SetMinimalSize(128, 12), - SetDataTip(STR_INTRO_QUIT, STR_INTRO_TOOLTIP_QUIT), - NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_TUTORIAL), SetMinimalSize(158, 12), + SetDataTip(STR_ABOUT_MENU_TUTORIAL, STR_TUTORIAL_WINDOW_TOOLTIP), SetPadding(0, 0, 0, 10), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_EXIT), SetMinimalSize(158, 12), + SetDataTip(STR_INTRO_QUIT, STR_INTRO_TOOLTIP_QUIT), SetPadding(0, 10, 0, 0), SetFill(1, 0), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 8), diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index 377c928460..1ef0469866 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -4965,3 +4965,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 1cd5332615..f195723a87 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -4418,3 +4418,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/basque.txt b/src/lang/basque.txt index 1db1ed48eb..437cfdc295 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -4828,3 +4828,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 221f6f1573..1ae8bf5049 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -5437,3 +5437,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index fdc960e950..da8132cbd2 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -4965,3 +4965,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index 4adbc74de7..bfe620384c 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -4878,3 +4878,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 7d407a0b68..e429a750b3 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -4973,3 +4973,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index cbb33f95e1..a6af03ac15 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -5105,3 +5105,35 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings +STR_ABOUT_MENU_TUTORIAL :{BLACK}Udžbenik +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Prikaži legendu mape / opis simbola na mapi +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Okomita alatna traka +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Glavna alatna traka je podijeljena na dvije okomite alatne trake na rubovima ekrana +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Veličina tipki +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Veličina svih elemenata korisničkog sučelja +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Veličina fonta +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Veličina svih fontova u igri +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Potvrdi akcije +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Prikaži dijalog potvrde pri gradnji cesta i stanica +STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit +STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Postavi dubinu boja videa na 8 bitova po pikselu, ovaj način podržava animaciju vode +STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit +STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Postavi dubinu boja videa na 16 bitova po pikselu, za ovo treba restart, ovaj način ne podržava animaciju vode +STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit +STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Postavi dubinu boja videa na 24 bita po pikselu, ovaj način podržava animaciju vode +STR_TABLET_CLOSE_TOOLTIP :{BLACK}Zatvori sve otvorene prozore (osim zakačenih) +STR_TABLET_SHIFT_TOOLTIP :{BLACK}Pritisnuti za procjenu troškova izvođenja neke akcije +STR_TABLET_CTRL_TOOLTIP :{BLACK}Koristiti za sve akcije za koje se koristi tipka "CTRL" +STR_TUTORIAL_WINDOW_TITLE :{BLACK}Videi za učenje +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Otvori prikazivač videa za gledanje videa za učenje +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Građenje cesta i stanica, kupnja vozila +STR_TUTORIAL_RAILWAYS :{BLACK}Pruge i vlakovi +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Cestovna vozila +STR_TUTORIAL_SHIPS :{BLACK}Brodovi i dokovi +STR_TUTORIAL_CARGO :{BLACK}Vrste tereta +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Učitaj sa mreže +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Učitaj igru sa mrežne pohrane podataka +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Spremi na mrežu +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Spremi igru na mrežnu pohranu podataka diff --git a/src/lang/czech.txt b/src/lang/czech.txt index b053b507af..24dd66aeb1 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -5187,3 +5187,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 5fdc19c51c..6f4cc0dad5 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 541d07b146..3d1c075c1e 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -4967,3 +4967,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/english.txt b/src/lang/english.txt index 505356f08f..399c11cbf4 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -468,7 +468,7 @@ STR_NEWS_MENU_MESSAGE_HISTORY_MENU :Message history ############ range for about menu starts STR_ABOUT_MENU_LAND_BLOCK_INFO :Land area information -STR_ABOUT_MENU_SEPARATOR : +STR_ABOUT_MENU_TUTORIAL :{BLACK}Tutorial STR_ABOUT_MENU_TOGGLE_CONSOLE :Toggle console STR_ABOUT_MENU_AI_DEBUG :AI/Game script debug STR_ABOUT_MENU_SCREENSHOT :Screenshot @@ -717,6 +717,7 @@ STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Show lan STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Click on an industry type to toggle displaying it. Ctrl+Click disables all types except the selected one. Ctrl+Click on it again to enable all industry types STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Click on a company to toggle displaying its property. Ctrl+Click disables all companies except the selected one. Ctrl+Click on it again to enable all companies STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Click on a cargo to toggle displaying its property. Ctrl+Click disables all cargoes except the selected one. Ctrl+Click on it again to enable all cargoes +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Show map legend / description of map symbols STR_SMALLMAP_LEGENDA_ROADS :{TINY_FONT}{BLACK}Roads STR_SMALLMAP_LEGENDA_RAILROADS :{TINY_FONT}{BLACK}Railways @@ -1211,6 +1212,20 @@ STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :Select on which STR_CONFIG_SETTING_SIGNALSIDE_LEFT :On the left STR_CONFIG_SETTING_SIGNALSIDE_DRIVING_SIDE :On the driving side STR_CONFIG_SETTING_SIGNALSIDE_RIGHT :On the right +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Vertical toolbar +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Main toolbar is split into two vertical toolbars on the sides of the screen +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Button size +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Size of all user interface elements +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Font size +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Size of all game fonts +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Confirm actions +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Show confirmation dialog when building roads and stations +STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit +STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Set video color depth to 8 bits per pixel, this video mode supports water animation +STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit +STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Set video color depth to 16 bits per pixel, this requires restart, this video mode does not support water animation +STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit +STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Set video color depth to 24 bits per pixel, this video mode supports water animation STR_CONFIG_SETTING_SHOWFINANCES :Show finances window at the end of the year: {STRING2} STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT :If enabled, the finances window pops up at the end of each year to allow easy inspection of the financial status of the company STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT :New orders are 'non-stop' by default: {STRING2} @@ -2477,6 +2492,13 @@ STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Raise a STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Level an area of land to the height of the first selected corner. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Shift toggles building/showing cost estimate +STR_TABLET_CLOSE :{BLACK}X +STR_TABLET_CLOSE_TOOLTIP :{BLACK}Close all opened windows (except pinned ones) +STR_TABLET_SHIFT :{BLACK}{TINY_FONT}Shft +STR_TABLET_SHIFT_TOOLTIP :{BLACK}Press it for getting an estimated cost of executing an action +STR_TABLET_CTRL :{BLACK}{TINY_FONT}Ctrl +STR_TABLET_CTRL_TOOLTIP :{BLACK}Use it for actions that use the "CTRL" key + # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Object Selection STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Shift toggles building/showing cost estimate @@ -2691,6 +2713,14 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original STR_ABOUT_VERSION :{BLACK}OpenTTD version {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2017 The OpenTTD team +STR_TUTORIAL_WINDOW_TITLE :{BLACK}Tutorial videos +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Open a video player to watch tutorial videos +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Building roads and stations, buying vehicles +STR_TUTORIAL_RAILWAYS :{BLACK}Railways and trains +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Road vehicles +STR_TUTORIAL_SHIPS :{BLACK}Ships and docks +STR_TUTORIAL_CARGO :{BLACK}Cargo types + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Save Game STR_SAVELOAD_LOAD_CAPTION :{WHITE}Load Game @@ -2709,6 +2739,10 @@ STR_SAVELOAD_SAVE_TOOLTIP :{BLACK}Save the STR_SAVELOAD_LOAD_BUTTON :{BLACK}Load STR_SAVELOAD_LOAD_TOOLTIP :{BLACK}Load the selected game STR_SAVELOAD_LOAD_HEIGHTMAP_TOOLTIP :{BLACK}Load the selected heightmap +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Load from network +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Load a game from the network storage +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Save to network +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Back up the game to the network storage STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Game Details STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No information available STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING1} diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index abdac23882..955949e744 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -4912,3 +4912,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index e67bb2c06b..1f8bbb9a4c 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -4970,3 +4970,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index 67abcfc9ed..f5f0859fab 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -4320,3 +4320,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index 4ce9d63471..e3e9ac6d88 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -5022,3 +5022,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index b121d9cb86..8fc695bf85 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -4468,3 +4468,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index 25bcabe338..0a9a2363af 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/french.txt b/src/lang/french.txt index 33af65666f..e288eaa1b3 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -4973,3 +4973,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index 3722eb1634..34badf27cc 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -5350,3 +5350,35 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings +STR_ABOUT_MENU_TUTORIAL :{BLACK}Oideachadh +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Seall treòir a' mhapa / tuairisgeulan air samhlaidhean a' mhapa +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Bàr-inneal inghearach +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Thèid am prìomh bhàr-inneal a sgoltadh 'na bhàraichean-inneal inghearach ri dà thaobh an sgrìn +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Meud nam putan +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Meud aig a h-uile nì an eadar-aghaidh +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Meud a' chrutha-chlò +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Meud aig a h-uile cruth-clò a' gheama +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Dearbhaich na gnìomhan +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Seall còmhradh dearbhaidh le togail rathaidean is stèiseanan +STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 biod +STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Suidhich doimhneachd nan dath aig a' video gu 8 biod gach piogsail. Cuiridh am modh video sin taic ri beòthachadh uisge +STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 biod +STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Suidhich doimhneachd nan dath aig a' video gu 16 biod gach piogsail. Bidh feum air ath-thòiseachadh. Cha chuir am modh video sin taic ri beòthachadh uisge +STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 biod +STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Suidhich doimhneachd nan dath aig a' video gu 24 biod gach piogsail. Cuiridh am modh video sin taic ri beòthachadh uisge +STR_TABLET_CLOSE_TOOLTIP :{BLACK}Dùin a h-uile uinneag (seach an fheadhainn phrìnichte) +STR_TABLET_SHIFT_TOOLTIP :{BLACK}Brùth air gus tuairmse air cosgaisean gnìomha fhaighinn +STR_TABLET_CTRL_TOOLTIP :{BLACK}Cleachd e airson gnìomhan a chleachdas an iuchair "CTRL" +STR_TUTORIAL_WINDOW_TITLE :{BLACK}Videothan oideachaidh +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Fosgail cluicheadair video gus coimhead air videothan oideachaidh +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Togail rathaidean is stèiseanan, ceannach charbadan +STR_TUTORIAL_RAILWAYS :{BLACK}Slighean rèile is trèanaichean +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Carbadan-rathaid +STR_TUTORIAL_SHIPS :{BLACK}Longan is puirt +STR_TUTORIAL_CARGO :{BLACK}Seòrsaichean carago +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Luchdaich on lìonra +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Luchdaich geama o stòras an lìonraidh +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Sàbhail dhan lìonra +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Cuir lethbhreac-glèidhidh dhen gheama gu stòras an lìonraidh diff --git a/src/lang/galician.txt b/src/lang/galician.txt index b097f4daef..d38d58c894 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -4902,3 +4902,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/german.txt b/src/lang/german.txt index 8a7bf51d33..2b70696012 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -4965,3 +4965,35 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings +STR_ABOUT_MENU_TUTORIAL :{BLACK}Tutorial +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Zeige Kartenlegende / Beschreibung der Kartensymbole +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Vertikale Werkzeugsleiste +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Hauptwerzeugleiste ist in zwei vertikale Leisten an den Bildschirmseiten aufgeteilt +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Schaltflächengröße +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Größe aller Elemente der Benutzeroberfläche +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Schriftartgröße +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Größe aller Schriftarten +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Aktionen bestätigen +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Zeige Bestätigungsdialog bei Straßen- und Haltenstellebau +STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit +STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Setzt die Farbtiefe auf 8 Bits per Pixel. Dieser Modus unterstützt Wasseranimation +STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit +STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Setzt die Farbtiefe auf 16 Bit per Pixel. Erfordert Neustart und dieser Modus unterstützt keine Wasseranimation +STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit +STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Setzt die Farbtiefe auf 24 Bits per Pixel. Dieser Modus unterstützt Wasseranimation +STR_TABLET_CLOSE_TOOLTIP :{BLACK}Schließe alle offene Fenster (außer Festgepinnte) +STR_TABLET_SHIFT_TOOLTIP :{BLACK}Drücke hier, um eine Kostenabschätzung für die Durchführung einer Aktion zu erhalten +STR_TABLET_CTRL_TOOLTIP :{BLACK}Für Aktionen benutzen, welche die "STRG" Taste benutzen +STR_TUTORIAL_WINDOW_TITLE :{BLACK}Tutorial Videos +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Öffne einen Videoplayer, um Tutorial videos anzuschauen +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Strassen und Haltestellen bauen, Fahrzeuge kaufen +STR_TUTORIAL_RAILWAYS :{BLACK}Eisenbahnen und Züge +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Straßenfahrzeuge +STR_TUTORIAL_SHIPS :{BLACK}Schiffe und Docks +STR_TUTORIAL_CARGO :{BLACK}Warentypen +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Laden vom Netzwerk +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Öffne ein Spiel aus dem Netzwerkspeicher +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Speichern ins Netzwerk +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Spiel zurück in den Netzwerkspeicher backupen diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 8659667126..a3204f0c66 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -5089,3 +5089,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index ef3bb5070a..9a77ac9853 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -4980,3 +4980,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index fd4f1338d7..875cd7b974 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -5069,3 +5069,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index 55a54c2d6c..5913d617f6 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -4721,3 +4721,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index 35b8db2522..9e9f563c52 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -4960,3 +4960,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/irish.txt b/src/lang/irish.txt index b8a262e858..ac31316d4d 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/italian.txt b/src/lang/italian.txt index cb75eaf927..6eb33e4d0b 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -5002,3 +5002,35 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings +STR_ABOUT_MENU_TUTORIAL :{BLACK}Istruzioni +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Mostra la legenda della mappa / descrizione dei simboli della mappa +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Barra degli strumenti verticale +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}La barra degli strumenti è divisa in due barre verticali sui lati dello schermo +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Dimensioni dei pulsanti +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Dimensioni degli elementi dell'interfaccia +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Dimensioni dei caratteri +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Dimensioni dei caratteri nel gioco +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Conferma +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Mostra il dialogo di conferma durante la costruzione di strade e stazioni +STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit +STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Imposta i colori a 8 bit per pixel. Questa modalità video supporta l'animazione dell'acqua +STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit +STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Imposta i colori a 16 bit per pixel (richiede il riavvio). Questa modalità video non supporta l'animazione dell'acqua +STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit +STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Imposta i colori a 24 bit per pixel. Questa modalità video supporta l'animazione dell'acqua +STR_TABLET_CLOSE_TOOLTIP :{BLACK}Chiude tutte le schermate aperte (eccetto quelle permanenti) +STR_TABLET_SHIFT_TOOLTIP :{BLACK}Premi questo tasto per una stima dei costi dell'azione desiderata +STR_TABLET_CTRL_TOOLTIP :{BLACK}Usa per le azioni che usano il tasto "CTRL" +STR_TUTORIAL_WINDOW_TITLE :{BLACK}Video di aiuto +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Apri un'applicazione video per guardare i video di aiuto +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Costruzione di strade e stazioni; acquisto di veicoli +STR_TUTORIAL_RAILWAYS :{BLACK}Ferrovie e treni +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Veicoli stradali +STR_TUTORIAL_SHIPS :{BLACK}Navi e attracchi +STR_TUTORIAL_CARGO :{BLACK}Tipi di merce +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Carica dalla rete +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Carica il gioco dalla memoria di rete +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Salva sulla rete +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Salva il gioco nella memoria di rete diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index 251c68b55f..0981bc21d1 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -4968,3 +4968,35 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings +STR_ABOUT_MENU_TUTORIAL :{BLACK}チュートリアル +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}マップシンボルについての説明の表示 +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}垂直ツールバー +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}メインツールバーはスクリーンの両脇に垂直に2つに分割しています +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}ボタンサイズ +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}すべてのユーザーインターフェースの構成サイズ +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}フォントサイズ +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}全てのゲームのフォント +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}アクションの確認 +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}道路とステーションの建設時に確認のダイアログの表示 +STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit +STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}色深度を8 bppに設定します 再起動が必要です このビデオモードは水のアニメーションに対応していません +STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit +STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}色深度を16 bppに設定します 再起動が必要です このビデオモードは水のアニメーションに対応していません +STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit +STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}色深度を24 bppに設定します 再起動が必要です このビデオモードは水のアニメーションに対応していません +STR_TABLET_CLOSE_TOOLTIP :{BLACK}全ての開いているウィンドウを閉じます (固定してあるものは除く) +STR_TABLET_SHIFT_TOOLTIP :{BLACK}押すことでアクションの決定時に費用の見積もりができます +STR_TABLET_CTRL_TOOLTIP :{BLACK} "CTRL" キーを使うアクションのために使います +STR_TUTORIAL_WINDOW_TITLE :{BLACK}チュートリアル動画 +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}チュートリアル動画を見るためにビデオプレイヤーを開きます +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}道路とステーションの建設と、車両の購入 +STR_TUTORIAL_RAILWAYS :{BLACK}鉄道と列車 +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}道路車両 +STR_TUTORIAL_SHIPS :{BLACK}船とドック +STR_TUTORIAL_CARGO :{BLACK}貨物のタイプ +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}ネットワークからロード +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}ネットワークストレージからゲームをロード +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}ネットワークにセーブ +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}ネットワークストレージにゲームをバックアップ diff --git a/src/lang/korean.txt b/src/lang/korean.txt index d05ab967eb..d2ffc5d7ce 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -4973,3 +4973,35 @@ STR_PLANE :{G=f}{BLACK}{PL STR_SHIP :{G=f}{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings +STR_ABOUT_MENU_TUTORIAL :{BLACK}튜토리얼 +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}지도 범례 / 기호 설명을 보여줌 +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}수직 작업창 +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}메인 작업창이 두 개의 화면 양쪽 두개의 수직 작업창으로 나뉨 +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}버튼 크기 +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}모든 사용자 인터페이스의 크기 +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}폰트 크기 +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}게임 내부 폰트의 크기 +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}명령 확인 +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}도로와 정류장을 건설시 확인 팝업을 보임 +STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8비트 +STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}그래픽 색상 깊이를 픽셀당 8비트로 설정합니다. 이 그래픽 모드는 물이 흐르는 애니메이션 효과를 표현할 수 있습니다. +STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16비트 +STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}그래픽 색상 깊이를 픽셀당 16비트로 설정합니다. 이 그래픽 모드는 물이 흐르는 애니메이션 효과를 표현할 수 있습니다. +STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24비트 +STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}그래픽 색상 깊이를 픽셀당 24비트로 설정합니다. 이 그래픽 모드는 물이 흐르는 애니메이션 효과를 표현할 수 있습니다. +STR_TABLET_CLOSE_TOOLTIP :{BLACK}열려있는 모든 창 닫기 (고정된 창 제외) +STR_TABLET_SHIFT_TOOLTIP :{BLACK}이 행동을 하기 위한 예상 비용을 알아보려면 누르세요. +STR_TABLET_CTRL_TOOLTIP :{BLACK}"컨트롤"키를 이용하는 명령을 위해 사용 +STR_TUTORIAL_WINDOW_TITLE :{BLACK}튜토리얼 영상 +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}튜토리얼 영상을 보기 위해 비디오 플레이어를 열기 +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}도로, 역 건설 및 차량 구입 +STR_TUTORIAL_RAILWAYS :{BLACK}선로 및 열차 +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}차량 +STR_TUTORIAL_SHIPS :{BLACK}선박과 항구 +STR_TUTORIAL_CARGO :{BLACK}화물 종류 +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}네트워크에서 불러오기 +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}네트워크 저장소에서 불러오기 +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}네트워크에 저장 +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}네트워크 저장소로 게임을 백업 diff --git a/src/lang/latin.txt b/src/lang/latin.txt index 380ac68537..dc352b4ba5 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -5289,3 +5289,35 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings +STR_ABOUT_MENU_TUTORIAL :{BLACK}Rudimentum +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Monstrare formulam graphicam / descriptionem tabulae +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Arca instrumentorum directa +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Si vis, arca instrumentorum prima dividitur in partes duas apud margines scrinii +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Magnitudo globulorum +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Magnitudo omnium elementorum interfaciei +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Magnitudo fontis typographici +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Magnitudo omnium fontium typographicorum in ludo +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Confirmare +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Monstrare confirmationem dum struuntur stationes viaeque +STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8bpp +STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Eligere modum coloris 8bpp; hic sinit colores aquae moventes +STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16bpp +STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Eligere modum coloris 16bpp (necesse erit programma exire et resumere); hic NON sinit colores aquae moventes +STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24bpp +STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Eligere modum coloris 24bpp; hic sinit colores aquae moventes +STR_TABLET_CLOSE_TOOLTIP :{BLACK}Claudere omnes fenestras (sed non glutinosas) +STR_TABLET_SHIFT_TOOLTIP :{BLACK}Preme ut aestimatio actionis monstretur +STR_TABLET_CTRL_TOOLTIP :{BLACK}Utendum est ad actiones cum "CTRL" +STR_TUTORIAL_WINDOW_TITLE :{BLACK}Rudimenta visifica +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Aperire programma visificum ad rudimenta videnda +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Viae stationesque, emptio vehiculorum +STR_TUTORIAL_RAILWAYS :{BLACK}Ferriviae traminaque +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Vehicula viaria +STR_TUTORIAL_SHIPS :{BLACK}Naves navaliaque +STR_TUTORIAL_CARGO :{BLACK}Genera onerum +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Legere e nebula +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Arcessere ludum "e nebula" (i.e. ex Interreti) +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Servare in nebula +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Conservare ludum "in nebula" (i.e. in Interreti) diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index f75d381b39..ae7d7b2022 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -4880,3 +4880,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index f9067c5567..5801865906 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -5504,3 +5504,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index 37aec445da..b326e3876a 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -4967,3 +4967,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/malay.txt b/src/lang/malay.txt index 7779ea9504..262ff6d81b 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -4588,3 +4588,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index e8bd624a0f..79d846a025 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -4969,3 +4969,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index aa455f5efe..93b02de68a 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -4878,3 +4878,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 206530f09f..167c332ea8 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -5390,3 +5390,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 552456b081..eec05e2755 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -4965,3 +4965,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index 1a3e29f479..21fd638859 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -4918,3 +4918,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/russian.txt b/src/lang/russian.txt index fc53374e3c..7c26137f5a 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -5199,3 +5199,35 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings +STR_ABOUT_MENU_TUTORIAL :{BLACK}Учебник +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Показывать миникарту / легенду +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Вертикальное меню +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Меню разделено на два вертикальных меню по краям экрата +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Размер кнопок +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Размер элементов интерфейса +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Размер шрифта +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Размер всех шрифтов в игре +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Подтверждать действия +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Показывать окно подтверждения при постройки дорог и станций +STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 бит +STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Установить глубину цвета в 16 бит на точку. Этот режим поддерживает анимацию воды +STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 бит +STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Установить глубину цвета в 16 бит на точку. Это потребует перезапуска программы. Этот режим не поддерживает анимацию воды +STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 бит +STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Установить глубину цвета в 24 бит на точку. Этот режим поддерживает анимацию воды +STR_TABLET_CLOSE_TOOLTIP :{BLACK}Закрыть все открытые окна (кроме закреплённых) +STR_TABLET_SHIFT_TOOLTIP :{BLACK}Использовать в качестве кнопки "SHIFT" (оценка стоимости) +STR_TABLET_CTRL_TOOLTIP :{BLACK}Использовать в качестве кнопки "CTRL" +STR_TUTORIAL_WINDOW_TITLE :{BLACK}Учебные видео +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Открыть видеоплеер для просмотра учебного видео +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Постройка дорог и терминалов, покупка автомобилей +STR_TUTORIAL_RAILWAYS :{BLACK}Железные дороги и поезда +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Автомобили +STR_TUTORIAL_SHIPS :{BLACK}Корабли и пристани +STR_TUTORIAL_CARGO :{BLACK}Грузы +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Загрузка из сети +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Загрузить игру из сетевого хранилища +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Сохранение в сети +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Сохранить игру в сетевое хранилище diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index 61f848e8b3..1ba80e1d9e 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -5175,3 +5175,29 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings +STR_ABOUT_MENU_TUTORIAL :{BLACK}Priručnik +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Prikaži legendu mape / opis simbola na mapi +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Vertikalna alatna traka +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}Glavna alatna traka je podeljena na dve okomite alatne trake na rubovima ekrana +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Veličina dugmeta +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Veličina svih elemenata korisničkog interfejsa +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Veličina slova +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Veličina svih slova u igri +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Potvrdi akcije +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Prikaži dijalog potvrde pri gradnji drumova i stanica +STR_TABLET_CLOSE_TOOLTIP :{BLACK}Zatvori sve otvorene prozore (osim zakačenih) +STR_TABLET_SHIFT_TOOLTIP :{BLACK}Pritisnite za dobivanje procene troškova odabrane akcije +STR_TABLET_CTRL_TOOLTIP :{BLACK}Koristite za sve akcije za koje se koristi tipka "CTRL" +STR_TUTORIAL_WINDOW_TITLE :{BLACK}Video za učenje +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Otvori video plejer za gledanje videa za učenje +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Gradnja cesta i stanica, kupovina vozila +STR_TUTORIAL_RAILWAYS :{BLACK}Šine i vozovi +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Drumska vozila +STR_TUTORIAL_SHIPS :{BLACK}Brodovi i dokovi +STR_TUTORIAL_CARGO :{BLACK}Tip tereta +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Učitaj igru sa mreže +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Učitaj igru sa mrežne pohrane podataka +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Spremi igru na mrežu +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Spremi igru na mrežu diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 6be975993f..028aa7cc68 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -4964,3 +4964,35 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings +STR_ABOUT_MENU_TUTORIAL :{BLACK}教程 +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}在地图上显示图例/描述 +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}垂直工具栏 +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}将主工具栏分为屏幕两侧的两个垂直工具栏 +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}按键大小 +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}用户界面大小 +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}字体大小 +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}游戏字体大小 +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}确认操作 +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}建立道路和车站时显示确认对话框 +STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bit +STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}将视频颜色深度设置为8位像素,此模式支持水面动态涟漪 +STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bit +STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}将视频颜色深度设置为16位像素,这需要重新启动,此模式不支持水面动态涟漪 +STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bit +STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}将视频颜色深度设置为24位像素,此模式支持水面动态涟漪 +STR_TABLET_CLOSE_TOOLTIP :{BLACK}关闭所有打开的窗口(已固定的窗口除外) +STR_TABLET_SHIFT_TOOLTIP :{BLACK}按住显示预计费用 +STR_TABLET_CTRL_TOOLTIP :{BLACK}将其用于“CTRL”键的操作 +STR_TUTORIAL_WINDOW_TITLE :{BLACK}教程视频 +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}使用视频播放器观看教程视频 +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}建设道路和车站,购买车辆 +STR_TUTORIAL_RAILWAYS :{BLACK}铁路和火车 +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}公路车辆 +STR_TUTORIAL_SHIPS :{BLACK}船只和码头 +STR_TUTORIAL_CARGO :{BLACK}货物类型 +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}读取云端存档 +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}从云端储存读取游戏 +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}保存到云端储存 +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}备份游戏到云端储存 diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 539b5379d7..506c5329f0 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -5033,3 +5033,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index 1cd9a11aa9..881e6a3a1c 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -5162,3 +5162,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 37b033277d..f458bca1f5 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -4967,3 +4967,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index c2de0c7009..fbf6f84609 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -127,7 +127,11 @@ STR_QUANTITY_TOFFEE :{WEIGHT_LONG} d STR_QUANTITY_BATTERIES :{COMMA} pila{P "" s} STR_QUANTITY_PLASTIC :{VOLUME_LONG} de plásticos STR_QUANTITY_FIZZY_DRINKS :{COMMA} refresco{P "" s} +<<<<<<< HEAD +STR_QUANTITY_N_A :Ninguna +======= STR_QUANTITY_N_A :N/A +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 # Two letter abbreviation of cargo name STR_ABBREV_NOTHING : @@ -301,7 +305,11 @@ STR_SORT_BY_WAITING_TOTAL :Cargamento tota STR_SORT_BY_WAITING_AVAILABLE :Cargamento disponible en espera STR_SORT_BY_RATING_MAX :Valoración más alta de cargamento STR_SORT_BY_RATING_MIN :Valoración más baja de cargamento +<<<<<<< HEAD +STR_SORT_BY_ENGINE_ID :Id. de locomotora (orden clásico) +======= STR_SORT_BY_ENGINE_ID :EngineID (classic sort)Id. locomotora (orden clásico) +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_SORT_BY_COST :Costo STR_SORT_BY_POWER :Potencia STR_SORT_BY_TRACTIVE_EFFORT :Fuerza de tracción @@ -379,7 +387,11 @@ STR_SETTINGS_MENU_NEWGRF_SETTINGS :Configuración STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opciones de transparencia STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Mostrar nombres de pueblos STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :Mostrar nombres de estaciones +<<<<<<< HEAD +STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Mostrar puestos guías +======= STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Mostrar puntos guías +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_SETTINGS_MENU_SIGNS_DISPLAYED :Mostrar carteles propios STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS :Mostrar carteles y nombres del competidor STR_SETTINGS_MENU_FULL_ANIMATION :Animación completa @@ -893,7 +905,11 @@ STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Selecci ############ start of currency region STR_GAME_OPTIONS_CURRENCY_GBP :Libra británica (GBP) +<<<<<<< HEAD +STR_GAME_OPTIONS_CURRENCY_USD :Dólar americano (USD) +======= STR_GAME_OPTIONS_CURRENCY_USD :Dólar estadounidense (USD) +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_GAME_OPTIONS_CURRENCY_EUR :Euro (EUR) STR_GAME_OPTIONS_CURRENCY_JPY :Yen japonés (¥) STR_GAME_OPTIONS_CURRENCY_ATS :Chelín austríaco (ATS) @@ -1008,7 +1024,11 @@ STR_ERROR_FULLSCREEN_FAILED :{WHITE}El modo # Custom currency window STR_CURRENCY_WINDOW :{WHITE}Moneda personalizada +<<<<<<< HEAD +STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Tasa de cambio: {ORANGE}{CURRENCY_LONG} = £ {COMMA} +======= STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Tasa de cambio: {ORANGE} {CURRENCY_LONG} = £ {COMMA} +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Reducir el valor de la moneda por una libra (£) STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Incrementar el valor de la moneda por una libra (£) STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP :{BLACK}Ajustar el valor de cambio de la moneda por una Libra (£) @@ -1027,7 +1047,11 @@ STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Establec STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Cambiar a euro antes STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Cambiar a euro después +<<<<<<< HEAD +STR_CURRENCY_PREVIEW :{LTBLUE}Vista previa: {ORANGE}{CURRENCY_LONG} +======= STR_CURRENCY_PREVIEW :{LTBLUE}Vista previa: {ORANGE} {CURRENCY_LONG} +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 libras (£) en la moneda STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Cambiar parámetro de moneda personalizada @@ -1097,11 +1121,19 @@ STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Plegar t STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(no hay explicación disponible) STR_CONFIG_SETTING_DEFAULT_VALUE :{LTBLUE}Valor predeterminado: {ORANGE}{STRING} STR_CONFIG_SETTING_TYPE :{LTBLUE}Tipo de opción: {ORANGE}{STRING} +<<<<<<< HEAD +STR_CONFIG_SETTING_TYPE_CLIENT :Opción de cliente (no se almacena en partidas guardadas, afecta a todas las partidas) +STR_CONFIG_SETTING_TYPE_GAME_MENU :Opción de partida (se almacena en las partidas guardadas, afecta solamente a nuevas partidas) +STR_CONFIG_SETTING_TYPE_GAME_INGAME :Opción de partida (almacenada en la partida guardada, afecta solamente a la partida actual) +STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Opción de empresa (se almacena en las partidas guardadas, afecta solamente a las nuevas partidas) +STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Opción de empresa (almacenada en la partida guardada, afecta solamente a la empresa actual) +======= STR_CONFIG_SETTING_TYPE_CLIENT :Opción de cliente (no se almacena en partidas guardadas, afecta todas las partidas) STR_CONFIG_SETTING_TYPE_GAME_MENU :Opción de partida (se almacena en las partidas guardadas, afecta solamente partidas nuevas) STR_CONFIG_SETTING_TYPE_GAME_INGAME :Opción de partida (almacenada en la partida guardada, afecta solamente la partida actual) STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Opción de empresa (se almacena en las partidas guardadas, afecta solamente las partidas nuevas) STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Opción de empresa (almacenada en la partida guardada, afecta solamente la empresa actual) +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}Categoría: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Tipo: @@ -1114,11 +1146,19 @@ STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW :Opciones con un STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT :{BLACK}Restringir la lista a ciertos tipos de opciones STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL :Todos los tipos de opciones +<<<<<<< HEAD +STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT :Opciones de cliente (no se almacena en partidas guardadas, afecta a todas las partidas) +STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :Opciones de juego (se almacena en las partidas guardadas, afecta solamente a partidas nuevas) +STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Opciones de juego (se almacena en las partidas guardadas, afecta solamente a la partida actual) +STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Opciones de empresa (se almacena en las partidas guardadas, afecta solamente a partidas nuevas) +STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Opciones de empresa (se almacena en las partidas guardadas, afecta solamente a la empresa actual) +======= STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT :Opciones de cliente (no se almacena en partidas guardadas, afecta todas las partidas) STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :Opciones de juego (se almacena en las partidas guardadas, afecta solamente partidas nuevas) STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Opciones de juego (se almacena en las partidas guardadas, afecta solamente la partida actual) STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Opciones de empresa (se almacena en las partidas guardadas, afecta solamente partidas nuevas) STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Opciones de empresa (se almacena en las partidas guardadas, afecta solamente la empresa actual) +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CONFIG_SETTING_CATEGORY_HIDES :{BLACK}Mostrar todos los resultados por opción de configuración{}{SILVER}Categoría {BLACK}a {WHITE}{STRING} STR_CONFIG_SETTING_TYPE_HIDES :{BLACK}Mostrar todos los resultados por opción de configuración{}{SILVER}Tipo {BLACK}a {WHITE}Todos los tipos de opción STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}Mostrar todos los resultados por opción de configuración{}{SILVER}Categoría {BLACK}a {WHITE}{STRING} {BLACK}y {SILVER}Tipo {BLACK}a {WHITE}Todos los tipos de opción @@ -1148,7 +1188,11 @@ STR_CONFIG_SETTING_RUNNING_COSTS :Costos de opera STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Nivel de los costos de mantenimiento y operación de vehículos e infraestructura STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Velocidad de construcción: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Restringir la velocidad de las acciones de construcción de jugadores no humanos +<<<<<<< HEAD +STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Descomposturas de vehículos: {STRING} +======= STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Averías de vehículos: {STRING} +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT :Controlar cada cuánto los vehículos con poco mantenimiento sufren fallas STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER :Multiplicador de subsidio: {STRING} STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :Establecer cuánto se paga por subsidios conectados @@ -1161,7 +1205,11 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Si se activa, l STR_CONFIG_SETTING_DISASTERS :Desastres: {STRING} STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Desastres que ocasionalmente pueden bloquear o destruir vehículos o infraestructura STR_CONFIG_SETTING_CITY_APPROVAL :Actitud de los ayuntamientos ante restructuraciones hechas en sus zonas: {STRING} +<<<<<<< HEAD +STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :En qué medida el ruido y el daño ambiental causado por las empresas afectan su evaluación y futuras acciones de construcción en las mismas zonas +======= STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Medida en que el ruido y el daño ambiental causado por las empresas afectan su evaluación y futuras acciones de construcción en las mismas zonas +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CONFIG_SETTING_MAX_HEIGHTLEVEL :Elevación máxima del mapa: {STRING} STR_CONFIG_SETTING_MAX_HEIGHTLEVEL_HELPTEXT :Elevación máxima que las montañas pueden tener en el mapa @@ -1230,7 +1278,11 @@ STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT :Todas las vista STR_CONFIG_SETTING_BRIBE :Permitir sobornos al ayuntamiento: {STRING} STR_CONFIG_SETTING_BRIBE_HELPTEXT :Las empresas pueden tratar de sobornar a los ayuntamientos. Si el soborno es descubierto por un inspector, la empresa no podrá realizar actividades en la localidad durante seis meses STR_CONFIG_SETTING_ALLOW_EXCLUSIVE :Permitir adquirir los derechos de transporte exclusivos: {STRING} +<<<<<<< HEAD +STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Si una empresa adquiere los derechos de transporte exclusivos en un pueblo, las estaciones de la competencia (pasajeros o cargamento) no recibirán nada para transportar durante un año +======= STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Si una empresa adquiere los derechos de transporte exclusivos en un pueblo, las estaciones de la competencia (de pasajeros o carga) no recibirán nada que entregar durante un año +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS :Permitir la construcción de nuevos edificios: {STRING} STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT :Las empresas aportan dinero a los ayuntamientos para que construyan nuevas casas y edificios STR_CONFIG_SETTING_ALLOW_FUND_ROAD :Permitir el pago de la reconstrucción de las carreteras locales: {STRING} @@ -1290,7 +1342,11 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Grosor de las l STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Grosor de las líneas en las gráficas. Una línea fina es más precisa, una línea más gruesa es más fácil de distinguir STR_CONFIG_SETTING_LANDSCAPE :Terreno: {STRING} +<<<<<<< HEAD +STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Los terrenos definen mapas con diferentes tipos de cargamentos y requisitos de crecimiento para los pueblos. Es posible modificarlos empleando NewGRF y scripts de juego +======= STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Los terrenos definen mapas con diferentes tipos de carga y requisitos de crecimiento para los pueblos. Es posible modificarlos empleando NewGRF y scripts de juego +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CONFIG_SETTING_LAND_GENERATOR :Generador de terreno: {STRING} STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT :El generador 'Original' depende de los gráficos base y crea formas de terreno fijas. 'TerraGenesis' es un generador basado en Ruido Perlin que permite un mayor control de configuración STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL :Original @@ -1473,8 +1529,13 @@ STR_CONFIG_SETTING_SERVINT_AIRCRAFT :Intervalo de ma STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT :Intervalo de mantenimiento predeterminado para nuevas aeronaves, en caso de no definirse otro explícitamente STR_CONFIG_SETTING_SERVINT_SHIPS :Intervalo de mantenimiento predeterminado para barcos: {STRING} STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT :Intervalo de mantenimiento predeterminado para nuevos barcos, en caso de no definirse otro explícitamente +<<<<<<< HEAD +STR_CONFIG_SETTING_NOSERVICE :Desactivar mantenimiento si las descomposturas están desactivadas: {STRING} +STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Al activarse, los vehículos no recibirán mantenimiento si no pueden descomponerse +======= STR_CONFIG_SETTING_NOSERVICE :Desactivar mantenimiento si las averías están desactivadas: {STRING} STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Al activarse, los vehículos no recibirán mantenimiento si no pueden averiarse +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Activar límites de velocidad para vagones: {STRING} STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Al activarse, se tienen en cuenta los límites de velocidad de los vagones para decidir la máxima velocidad de un tren STR_CONFIG_SETTING_DISABLE_ELRAILS :Desactivar ferrocarriles eléctricos: {STRING} @@ -1522,8 +1583,13 @@ STR_CONFIG_SETTING_SMOOTH_ECONOMY :Activar econom STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Al activarse, habrá cambios de producción en las industrias más frecuentemente y en escala menor. Si se usa un NewGRF con industrias adicionales esta opción generalmente no tiene efecto STR_CONFIG_SETTING_ALLOW_SHARES :Permitir comprar acciones de otras empresas: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Al activarse, se pueden comprar y vender acciones de otras empresas. Las acciones de una empresa solamente estarán disponibles cuando la empresa cumpla una edad determinada +<<<<<<< HEAD +STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Porcentaje de la utilidad total a pagar por transferencias de cargamento: {STRING} +STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Porcentaje de utilidad cedida a los transportes intermedios en sistemas de transferencias de cargamento, dando un mayor control sobre la utilidad de cada vehículo +======= STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Porcentaje de la utilidad total a pagar por transferencias de carga: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Porcentaje de utilidad cedida a los transportes intermedios en sistemas de transferencia de carga, dando un mayor control sobre la utilidad de cada vehículo +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Al arrastrar, colocar señales cada: {STRING} STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT :Distancia de separación entre señales hasta topar con algún obstáculo (otra señal, un desvío, etc.) al instalarlas mediante arrastre con el ratón STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE :{COMMA} casilla{P 0 "" s} @@ -1564,7 +1630,11 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Permitido STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Permitido, diseño urbano personalizado STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Crecimiento de árboles durante la partida: {STRING} +<<<<<<< HEAD +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Controlar la aparición aleatoria de árboles durante la partida. Esto puede afectar a industrias que dependen del crecimiento de árboles, como los aserraderos +======= STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Controlar la aparición aleatoria de árboles durante la partida. Esto puede afectar industrias que dependen del crecimiento de árboles, como los aserraderos +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NONE :Ninguno {RED}(inutiliza aserraderos) STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_RAINFOREST :Solo en selva STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_ALL :Cualquier parte @@ -1623,7 +1693,11 @@ STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :'Asimétrica' s STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisión de la distribución: {STRING} STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Si el valor es alto, se requerirá mayor tiempo para calcular la gráfica de distribución (si se lleva demasiado tiempo, se notará desfase en el juego). Si es muy bajo, la distribución será imprecisa, pudiendo hacer que el cargamento no vaya al lugar indicado STR_CONFIG_SETTING_DEMAND_DISTANCE :Efecto de la distancia en la demanda: {STRING} +<<<<<<< HEAD +STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Con un valor diferente a 0, la distancia entre la estación de origen de cierto cargamento y una posible estación de destino afectará a la cantidad de cargamento que se envíe entre ambas. Cuanto más lejos estén entre sí, menos cargamento se enviará. Cuanto mayor sea el valor de esta opción, menos cargamento se enviará a estaciones distantes en favor de estaciones cercanas +======= STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Con un valor diferente a 0, la distancia entre la estación de origen de cierta carga y una posible estación de destino afectará la cantidad de cargamento que se envíe entre ambas. Cuanto más lejos estén entre sí, menos cargamento se enviará. Cuanto mayor sea el valor de esta opción, menos cargamento se enviará a estaciones distantes en favor de estaciones cercanas +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CONFIG_SETTING_DEMAND_SIZE :Cantidad de cargamento a devolver en modo simétrico: {STRING} STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Establecer un valor menor de 100% hará que la distribución simétrica de cargamento sea más asimétrica. Se enviará menos cargamento de regreso forzosamente si una cantidad determinada es enviada a una estación. Si se fija a 0%, la distribución simétrica será como una distribución asimétrica STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Nivel de saturación de rutas cortas antes de cambiar a rutas de mayor capacidad: {STRING} @@ -1685,7 +1759,11 @@ STR_CONFIG_SETTING_ENVIRONMENT :{ORANGE}Ambient STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES :{ORANGE}Autoridades STR_CONFIG_SETTING_ENVIRONMENT_TOWNS :{ORANGE}Pueblos STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Industrias +<<<<<<< HEAD +STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distribución de cargamento +======= STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distribución de carga +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_CONFIG_SETTING_AI :{ORANGE}Competidores STR_CONFIG_SETTING_AI_NPC :{ORANGE}Jugadores no humanos @@ -1762,7 +1840,10 @@ STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Revisar STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Mostrar configuración de scripts STR_INTRO_TOOLTIP_QUIT :{BLACK}Salir de 'OpenTTD' +<<<<<<< HEAD +======= STR_INTRO_BASESET :{BLACK}A los gráficos base elegidos les hace falta {NUM} spirte{P "" s}. Necesitan actualizarse. +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_INTRO_TRANSLATION :{BLACK}A esta traducción le falta{P 0 "" n} {NUM} cadena{P "" s}. Considera ayudar a mejorar OpenTTD convirtiéndote en traductor. Consulta el archivo readme.txt para más detalles. # Quit window @@ -2272,7 +2353,11 @@ STR_TRANSPARENT_SIGNS_TOOLTIP :{BLACK}Activar STR_TRANSPARENT_TREES_TOOLTIP :{BLACK}Activar o desactivar transparencia para árboles. Ctrl+Clic para excluir de tecla rápida 'X' STR_TRANSPARENT_HOUSES_TOOLTIP :{BLACK}Activar o desactivar transparencia para casas. Ctrl+Clic para excluir de tecla rápida 'X' STR_TRANSPARENT_INDUSTRIES_TOOLTIP :{BLACK}Activar o desactivar transparencia para industrias. Ctrl+Clic para excluir de tecla rápida 'X' +<<<<<<< HEAD +STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Activar o desactivar transparencia para edificios como estaciones, depósitos o puestos guías. Ctrl+Clic para excluir de tecla rápida 'X' +======= STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Activar o desactivar transparencia para edificios como estaciones, depósitos o puntos guías. Ctrl+Clic para excluir de tecla rápida 'X' +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Activar o desactivar transparencia para puentes. Ctrl+Clic para excluir de tecla rápida 'X' STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Activar o desactivar transparencia para estructuras como faros o antenas. Ctrl+Clic para excluir de tecla rápida 'X' STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Activar o desactivar transparencia para catenaria. Ctrl+Clic para excluir de tecla rápida 'X' @@ -2303,7 +2388,11 @@ STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Provee: STR_JOIN_STATION_CAPTION :{WHITE}Ampliar estación STR_JOIN_STATION_CREATE_SPLITTED_STATION :{YELLOW}Construir aparte +<<<<<<< HEAD +STR_JOIN_WAYPOINT_CAPTION :{WHITE}Unir puestos guías +======= STR_JOIN_WAYPOINT_CAPTION :{WHITE}Unir puntos guías +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT :{YELLOW}Construir aparte # Rail construction toolbar @@ -2333,8 +2422,13 @@ STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION :{WHITE}Orientac STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP :{BLACK}Elegir la orientación del depósito de trenes # Rail waypoint construction window +<<<<<<< HEAD +STR_WAYPOINT_CAPTION :{WHITE}Puesto guía +STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Elegir el tipo de puesto guía +======= STR_WAYPOINT_CAPTION :{WHITE}Punto guía STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Elegir el tipo de punto guía +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 # Rail station construction window STR_STATION_BUILD_RAIL_CAPTION :{WHITE}Selección de estación @@ -2351,7 +2445,11 @@ STR_STATION_BUILD_STATION_CLASS_TOOLTIP :{BLACK}Mostrar STR_STATION_BUILD_STATION_TYPE_TOOLTIP :{BLACK}Construir el tipo de estación elegida STR_STATION_CLASS_DFLT :Estación predeterminada +<<<<<<< HEAD +STR_STATION_CLASS_WAYP :Puestos guías +======= STR_STATION_CLASS_WAYP :Puntos guías +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 # Signal window STR_BUILD_SIGNAL_CAPTION :{WHITE}Selección de señales @@ -2432,7 +2530,11 @@ STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}Construi STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP :{BLACK}Construir esclusa. Mayús muestra una estimación del precio STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Construir astillero (para comprar y dar mantenimiento a barcos). Mayús muestra una estimación del precio STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Construir muelles. Ctrl activa la ampliación de estaciones. Mayús muestra una estimación del precio +<<<<<<< HEAD +STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Colocar boya para utilizar como puesto guía marítimo. Mayús muestra una estimación del precio +======= STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Colocar boya para utilizar como punto guía marítimo. Mayús muestra una estimación del precio +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Construir acueducto. Mayús muestra una estimación del precio STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Definir cuerpo de agua.{}Crea un canal, a menos que se pulse Ctrl en un área al nivel del mar, en cuyo caso se inundarán los alrededores STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Colocar ríos @@ -2591,7 +2693,10 @@ STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Nombre d STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Cargamento recibido: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) +<<<<<<< HEAD +======= STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Tipo de vía: {LTBLUE}{STRING} +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Límite de velocidad de ferrocarril: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Límite de velocidad de carretera: {LTBLUE}{VELOCITY} @@ -2604,6 +2709,31 @@ STR_LAI_CLEAR_DESCRIPTION_FIELDS :Campos STR_LAI_CLEAR_DESCRIPTION_SNOW_COVERED_LAND :Terreno nevado STR_LAI_CLEAR_DESCRIPTION_DESERT :Desierto +<<<<<<< HEAD +STR_LAI_RAIL_DESCRIPTION_TRACK :Vía de {STRING} +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Vía de {STRING} con señales de bloqueo +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Vía de {STRING} con señales de entrada +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXITSIGNALS :Vía de {STRING} con señales de salida +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBOSIGNALS :Vía de {STRING} con señales de combo +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS :Vía de {STRING} con señales de ruta +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS :Vía de {STRING} con señales de ruta de un solo sentido +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS :Vía de {STRING} con señales de bloqueo y señales de entrada +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS :Vía de {STRING} con señales de bloqueo y señales de salida +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS :Vía de {STRING} con señales de bloqueo y señales combo +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS :Vía de {STRING} con señales de bloqueo y señales de ruta +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS :Vía de {STRING} con señales de bloqueo y señales de ruta de un solo sentido +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS :Vía de {STRING} con señales de entrada y señales de salida +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS :Vía de {STRING} con señales de entrada y señales combo +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS :Vía de {STRING} con señales de entrada y señales de ruta +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS :Vía de {STRING} con señales de entrada y señales de ruta de un solo sentido +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS :Vía de {STRING} con señales de salida y señales de combo +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS :Vía de {STRING} con señales de salida y señales de ruta +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS :Vía de {STRING} con señales de salida y señales de ruta de un solo sentido +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Vía de {STRING} con señales de combo y señales de ruta +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Vía de {STRING} con señales de combo y señales de ruta de un solo sentido +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Vía de {STRING} con señales de ruta y señales de ruta de un solo sentido +STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Depósito ({STRING}) +======= STR_LAI_RAIL_DESCRIPTION_TRACK :Vías férreas STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Vías férreas con señales de bloqueo STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Vías férreas con señales de entrada @@ -2627,6 +2757,7 @@ STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Vías férreas STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Vías férreas con señales combo y de ruta de un solo sentido STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Vías férreas con señales de ruta y de ruta de un solo sentido STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Depósito (trenes) +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_LAI_ROAD_DESCRIPTION_ROAD :Carretera STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Carretera con alumbrado @@ -2649,7 +2780,11 @@ STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Estación de ca STR_LAI_STATION_DESCRIPTION_BUS_STATION :Parada de autobús STR_LAI_STATION_DESCRIPTION_SHIP_DOCK :Muelle STR_LAI_STATION_DESCRIPTION_BUOY :Boya +<<<<<<< HEAD +STR_LAI_STATION_DESCRIPTION_WAYPOINT :puesto guía +======= STR_LAI_STATION_DESCRIPTION_WAYPOINT :Punto guía +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_LAI_WATER_DESCRIPTION_WATER :Agua STR_LAI_WATER_DESCRIPTION_CANAL :Canal @@ -2690,7 +2825,11 @@ STR_LAI_OBJECT_DESCRIPTION_COMPANY_OWNED_LAND :Terreno propied STR_ABOUT_OPENTTD :{WHITE}Acerca de OpenTTD STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Copyright original {COPYRIGHT} 1995 Chris Sawyer, Todos los derechos reservados STR_ABOUT_VERSION :{BLACK}OpenTTD versión {REV} +<<<<<<< HEAD +STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2016, el equipo de OpenTTD +======= STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2017, el equipo de OpenTTD +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Guardar partida @@ -2816,7 +2955,11 @@ STR_NEWGRF_SETTINGS_UPGRADE :{BLACK}Actualiz STR_NEWGRF_SETTINGS_UPGRADE_TOOLTIP :{BLACK}Actualizar los archivos NewGRF que lo requieran a la versión más reciente STR_NEWGRF_SETTINGS_FILE_TOOLTIP :{BLACK}Lista de archivos NewGRF instalados +<<<<<<< HEAD +STR_NEWGRF_SETTINGS_SET_PARAMETERS :{BLACK}Establecer parámetros +======= STR_NEWGRF_SETTINGS_SET_PARAMETERS :{BLACK}Parámetros +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_NEWGRF_SETTINGS_SHOW_PARAMETERS :{BLACK}Mostrar parámetros STR_NEWGRF_SETTINGS_TOGGLE_PALETTE :{BLACK}Cambiar paleta STR_NEWGRF_SETTINGS_TOGGLE_PALETTE_TOOLTIP :{BLACK}Cambia la paleta del NewGRF elegido.{}Esto es necesario cuando los gráficos de un NewGRF se ven de color rosa durante el juego @@ -2909,6 +3052,11 @@ STR_NEWGRF_ERROR_INVALID_ID :Intento de usar STR_NEWGRF_ERROR_CORRUPT_SPRITE :{YELLOW}{STRING} contiene un sprite con errores. Todos los sprites con errores se muestran como un símbolo de interrogación rojo (?) STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Contiene múltiples entradas de Acción 8 (sprite {3:NUM}) STR_NEWGRF_ERROR_READ_BOUNDS :La lectura excedió el límite de pseudo-sprite (sprite {3:NUM}) +<<<<<<< HEAD +STR_NEWGRF_ERROR_MISSING_SPRITES :{WHITE}A los gráficos base actualmente en uso les faltan algunos sprites.{}Los gráficos base deben ser actualizados +STR_NEWGRF_ERROR_MISSING_SPRITES_UNSTABLE :{WHITE}A los gráficos base actualmente en uso les faltan algunos sprites.{}Los gráficos base deben ser actualizados.{}Dado que esta es una {YELLOW}versión de desarrollo de OpenTTD{WHITE}, es posible que también se requiera una {YELLOW}versión de desarrollo de los gráficos base{WHITE} +======= +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_NEWGRF_ERROR_GRM_FAILED :Recursos GRF solicitados no disponibles (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} fue desactivado por {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Formato de colocación de sprites no válido o desconocido (sprite {3:NUM}) @@ -3172,12 +3320,21 @@ STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}No permi # Waypoint/buoy view window STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT} +<<<<<<< HEAD +STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Centrar vista en ubicación del puesto guía. Ctrl+Clic abre una ventana de vista en dicha ubicación +STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}Cambiar nombre de puesto guía +STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Centrar la vista en la ubicación de la boya. Ctrl+Clic abre una ventana de vista en dicha ubicación +STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}Cambiar nombre de boya + +STR_EDIT_WAYPOINT_NAME :{WHITE}Cambiar nombre de puesto guía +======= STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Centrar vista en ubicación del punto guía. Ctrl+Clic abre una ventana de vista en dicha ubicación STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}Cambiar nombre de punto guía STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Centrar la vista en la ubicación de la boya. Ctrl+Clic abre una ventana de vista en dicha ubicación STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}Cambiar nombre de boya STR_EDIT_WAYPOINT_NAME :{WHITE}Cambiar nombre de punto guía +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 # Finances window STR_FINANCES_CAPTION :{WHITE}Finanzas de {COMPANY} {BLACK}{COMPANY_NUM} @@ -3295,8 +3452,14 @@ STR_INDUSTRY_VIEW_REQUIRES_CARGO_CARGO :{BLACK}Requiere STR_INDUSTRY_VIEW_REQUIRES_CARGO_CARGO_CARGO :{BLACK}Requiere: {YELLOW}{STRING}{STRING}, {STRING}{STRING}, {STRING}{STRING} ############ range for requires ends +<<<<<<< HEAD +############ range for produces starts +STR_INDUSTRY_VIEW_WAITING_FOR_PROCESSING :{BLACK}Cargamento esperando a ser procesado: +STR_INDUSTRY_VIEW_WAITING_STOCKPILE_CARGO :{YELLOW}{CARGO_LONG}{STRING}{BLACK} +======= ############ range for produces starts +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_INDUSTRY_VIEW_PRODUCES_CARGO :{BLACK}Produce: {YELLOW}{STRING}{STRING} STR_INDUSTRY_VIEW_PRODUCES_CARGO_CARGO :{BLACK}Produce: {YELLOW}{STRING}{STRING}, {STRING}{STRING} ############ range for produces ends @@ -3557,10 +3720,17 @@ STR_REPLACE_REPLACING_WHEN_OLD :{ENGINE} cuando STR_REPLACE_VEHICLES_STOP :{BLACK}Dejar de reemplazar vehículos STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Presionar este botón para detener el reemplazo del vehículo situado a la izquierda +<<<<<<< HEAD +STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Reemplazando: {ORANGE}{STRING} +STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Cambiar entre reemplazo de vagón y locomotora +STR_REPLACE_ENGINES :Locomotoras +STR_REPLACE_WAGONS :Vagones +======= STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Cambiar entre reemplazo de vagón y locomotora STR_REPLACE_ENGINES :Locomotoras STR_REPLACE_WAGONS :Vagones STR_REPLACE_ALL_RAILTYPE :Todos los vehículos ferroviarios +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_REPLACE_HELP_RAILTYPE :{BLACK}Elegir el tipo de vías férreas para las que se desea reemplazar locomotoras STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Mostrar el vehículo que reemplazará al otro de la izquierda @@ -3619,7 +3789,11 @@ STR_VEHICLE_VIEW_AIRCRAFT_STATE_START_STOP_TOOLTIP :{BLACK}Activida STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}Cargando/Descargando STR_VEHICLE_STATUS_LEAVING :{LTBLUE}Partiendo STR_VEHICLE_STATUS_CRASHED :{RED}¡Accidentado! +<<<<<<< HEAD +STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}Descompuesto +======= STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}Averiado +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_VEHICLE_STATUS_STOPPED :{RED}Detenido STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL :{RED}Deteniéndose, {VELOCITY} STR_VEHICLE_STATUS_TRAIN_NO_POWER :{RED}Sin potencia @@ -3658,7 +3832,11 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {L STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potencia: {LTBLUE}{POWER}{BLACK} Velocidad máx.: {LTBLUE}{VELOCITY} {BLACK}F.T. máx.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Utilidad este año: {LTBLUE}{CURRENCY_LONG} (año pasado: {CURRENCY_LONG}) +<<<<<<< HEAD +STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidad: {LTBLUE}{COMMA}% {BLACK}Descomposturas desde el último mantenimiento: {LTBLUE}{COMMA} +======= STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidad: {LTBLUE}{COMMA}% {BLACK}Averías desde el último mantenimiento: {LTBLUE}{COMMA} +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Construido: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacidad: {LTBLUE}Ninguna{STRING} @@ -3773,7 +3951,11 @@ STR_ORDER_DROP_REFIT_AUTO_ANY :Cargamento disp STR_ORDER_SERVICE :{BLACK}Mantenimiento STR_ORDER_DROP_GO_ALWAYS_DEPOT :Ir siempre +<<<<<<< HEAD +STR_ORDER_DROP_SERVICE_DEPOT :Mantenimiento si es necesario +======= STR_ORDER_DROP_SERVICE_DEPOT :Mantto. si es necesario +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_ORDER_DROP_HALT_DEPOT :Detenerse STR_ORDER_SERVICE_TOOLTIP :{BLACK}Ignorar esta orden a menos que el mantenimiento sea necesario @@ -3815,7 +3997,11 @@ STR_ORDER_GO_TO_NEAREST_DEPOT :Ir al depósito STR_ORDER_GO_TO_NEAREST_HANGAR :Ir al hangar más cercano STR_ORDER_CONDITIONAL :Salto de orden condicional STR_ORDER_SHARE :Compartir órdenes +<<<<<<< HEAD +STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Añadir nueva orden antes de la orden marcada o añadirla al final de la lista. Ctrl+Clic sobre una estación para establecer la orden a 'Cargar máx. cualquier carga', sobre un puesto guía para 'Sin paradas' y sobre un depósito para 'Mantenimiento' (esta última desactivará el mantenimiento automático). Ctrl+Clic sobre otro vehículo para hacer que ambos compartan siempre las mismas órdenes. Clic sobre un vehículo para copiar sus órdenes (sin compartirlas). +======= STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Añadir nueva orden antes de la orden marcada o añadirla al final de la lista. Ctrl+Clic sobre una estación para establecer la orden a 'Cargar máx. cualquier carga', sobre un punto guía para 'Sin paradas' y sobre un depósito para 'Mantenimiento' (esta última desactivará el mantenimiento automático). Ctrl+Clic sobre otro vehículo para hacer que ambos compartan siempre las mismas órdenes. Clic sobre un vehículo para copiar sus órdenes (sin compartirlas). +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Ver todos los vehículos que comparten el mismo itinerario @@ -4240,6 +4426,17 @@ STR_ERROR_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Primero STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Primero se debe demoler el aeropuerto # Waypoint related errors +<<<<<<< HEAD +STR_ERROR_WAYPOINT_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Se amplía más de un puesto guía existente +STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT :{WHITE}Demasiado cerca de otro puesto guía + +STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT :{WHITE}No se puede construir el puesto guía aquí... +STR_ERROR_CAN_T_POSITION_BUOY_HERE :{WHITE}No se puede colocar la boya aquí... +STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME :{WHITE}No se puede cambiar nombre del puesto guía... + +STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT :{WHITE}No se puede quitar el puesto guía de aquí... +STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST :{WHITE}Primero se debe retirar el puesto guía +======= STR_ERROR_WAYPOINT_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Se amplía más de un punto guía existente STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT :{WHITE}Demasiado cerca de otro punto guía @@ -4249,6 +4446,7 @@ STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME :{WHITE}No se pu STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT :{WHITE}No se puede quitar el punto guía de aquí... STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST :{WHITE}Primero se debe retirar el punto guía +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_ERROR_BUOY_IN_THE_WAY :{WHITE}... una boya obstaculiza STR_ERROR_BUOY_IS_IN_USE :{WHITE}... ¡boya en uso por otra empresa! @@ -4860,7 +5058,11 @@ STR_FORMAT_BUOY_NAME_SERIAL :Boya {TOWN} #{C STR_FORMAT_COMPANY_NUM :(Empresa {COMMA}) STR_FORMAT_GROUP_NAME :Grupo {COMMA} STR_FORMAT_INDUSTRY_NAME :{1:STRING}, {0:TOWN} +<<<<<<< HEAD +STR_FORMAT_WAYPOINT_NAME :Puesto guía {TOWN} +======= STR_FORMAT_WAYPOINT_NAME :Punto guía, {TOWN} +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 STR_FORMAT_WAYPOINT_NAME_SERIAL :Puesto guía #{1:COMMA}, {0:TOWN} STR_FORMAT_DEPOT_NAME_TRAIN :Depósito de trenes, {TOWN} @@ -4968,3 +5170,38 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) +<<<<<<< HEAD + +# Android strings +STR_ABOUT_MENU_TUTORIAL :{BLACK}Guía de cómo jugar +STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Mostrar leyenda o descripción de símbolos del mapa +STR_CONFIG_SETTING_VERTICAL_TOOLBAR :{BLACK}Barra de herramientas vertical +STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :{BLACK}La barra de herramientas principal se divide en dos barras verticales laterales +STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Tamaño de botones +STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Tamaño de elementos de la interfaz +STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Tamaño de letra +STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Tamaño de letra de los elementos del juego +STR_CONFIG_SETTING_BUILD_CONFIRMATION :{BLACK}Confirmar acciones +STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :{BLACK}Mostrar diálogo de confirmación al construir carreteras y estaciones +STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bits +STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Establecer profundidad de color de video a 8 bits por pixel. Este modo de video soporta animación de agua +STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bits +STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Establecer profundidad de color de video a 16 bits por pixel. Requiere reinicio. Este modo de video no soporta animación de agua +STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bits +STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Establecer profundidad de color de video a 24 bits por pixel. Este modo de video soporta animación de agua +STR_TABLET_CLOSE_TOOLTIP :{BLACK}Cerrar todas las ventanas abiertas, salvo las que estén fijas +STR_TABLET_SHIFT_TOOLTIP :{BLACK}Pulsar para ver una estimación del precio al realizar una acción +STR_TABLET_CTRL_TOOLTIP :{BLACK}Emplearlo para acciones que utilizan la tecla "Ctrl" +STR_TUTORIAL_WINDOW_TITLE :{BLACK}Videos de guías de juego +STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Abrir reproductor de video para ver guías de juego +STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Construir carrerteras y estaciones; comprar vehículos +STR_TUTORIAL_RAILWAYS :{BLACK}Vías férreas y trenes +STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Vehículos de carretera +STR_TUTORIAL_SHIPS :{BLACK}Barcos y muelles +STR_TUTORIAL_CARGO :{BLACK}Cargamentos +STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Cargar desde red +STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Cargar partida desde almacenamiento en red +STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Guardar en red +STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Realizar respaldo en almacenamiento de red +======= +>>>>>>> d3de08088326415d55ef052dc858053ab4932584 diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 1abfef52a5..90a1ae9c9f 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index 32c647fac1..e58907d6a7 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -4514,3 +4514,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/thai.txt b/src/lang/thai.txt index 96fa8775f8..e44775b62c 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -4874,3 +4874,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index b12a1b1df6..3c08b38a19 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index 5352546c22..0cf3ab389c 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -4977,3 +4977,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index ef7d9ad9e4..fef78cb160 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -5132,3 +5132,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index e78a0d4eaa..25f8ae4a00 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -4964,3 +4964,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 56dfccdfd6..8028171425 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -4966,3 +4966,5 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# Android strings diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index 1fe34fe79c..ca81fa18d8 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -347,6 +347,7 @@ NWidgetBase *MakeCargoesLegendLinkGraphGUI(int *biggest_index) row = new NWidgetHorizontal(NC_EQUALSIZE); } NWidgetBackground * wid = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, i + WID_LGL_CARGO_FIRST); + wid->sizing_type = NWST_STEP; wid->SetMinimalSize(25, FONT_HEIGHT_SMALL); wid->SetFill(1, 1); wid->SetResize(0, 0); diff --git a/src/main_gui.cpp b/src/main_gui.cpp index b13920a648..713629a8bf 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -32,6 +32,8 @@ #include "linkgraph/linkgraph_gui.h" #include "tilehighlight_func.h" #include "hotkeys.h" +#include "tutorial_gui.h" +#include "gui.h" #include "saveload/saveload.h" @@ -340,7 +342,7 @@ struct MainWindow : Window break; } - case GHK_RESET_OBJECT_TO_PLACE: ResetObjectToPlace(); break; + case GHK_RESET_OBJECT_TO_PLACE: ResetObjectToPlace(); ToolbarSelectLastTool(); break; case GHK_DELETE_WINDOWS: DeleteNonVitalWindows(); break; case GHK_DELETE_NONVITAL_WINDOWS: DeleteAllNonVitalWindows(); break; case GHK_REFRESH_SCREEN: MarkWholeScreenDirty(); break; @@ -463,6 +465,7 @@ struct MainWindow : Window if (!gui_scope) return; /* Forward the message to the appropriate toolbar (ingame or scenario editor) */ InvalidateWindowData(WC_MAIN_TOOLBAR, 0, data, true); + InvalidateWindowData(WC_MAIN_TOOLBAR_RIGHT, 0, data, true); } static HotkeyList hotkeys; @@ -562,6 +565,15 @@ void SetupColoursAndInitialWindow() default: NOT_REACHED(); case GM_MENU: ShowSelectGameWindow(); + ShowTutorialWindowOnceAfterInstall(); + if (getenv("SDL_RESTART_PARAMS") != NULL) { + static int counter = 5; // This part of code is called several times during startup, which closes all windows, so we need to put random hacks here + counter--; + ShowGameOptions(); +#ifndef WIN32 + if (counter == 0) unsetenv("SDL_RESTART_PARAMS"); +#endif + } break; case GM_NORMAL: diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 2d3871ffbd..6072adb29d 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -26,6 +26,7 @@ #include "core/geometry_func.hpp" #include "newgrf_debug.h" #include "zoom_func.h" +#include "build_confirmation_func.h" #include "widgets/misc_widget.h" @@ -33,6 +34,10 @@ #include "safeguards.h" +#ifdef __ANDROID__ +#include +#endif + /** Method to open the OSK. */ enum OskActivation { OSKA_DISABLED, ///< The OSK shall not be activated at all. @@ -533,6 +538,10 @@ void ShowAboutWindow() */ void ShowEstimatedCostOrIncome(Money cost, int x, int y) { + if (ConfirmationWindowEstimatingCost()) { + ConfirmationWindowSetEstimatedCost(cost); + return; + } StringID msg = STR_MESSAGE_ESTIMATED_COST; if (cost < 0) { @@ -684,6 +693,12 @@ struct TooltipsWindow : public Window if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.total_offs.y - 5, scr_bot) - sm_height; pt.x = sm_width >= _screen.width ? 0 : Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width); + // Move it to the top of the screen, away from mouse cursor, so it won't steal screen taps on Android + pt.y = GetMainViewTop(); + if (_cursor.pos.y < pt.y + GetMinSizing(NWST_STEP)) { + pt.x = _cursor.pos.x > _screen.width / 2 ? GetMinSizing(NWST_STEP) : _screen.width - sm_width - GetMinSizing(NWST_STEP); + } + return pt; } @@ -692,7 +707,7 @@ struct TooltipsWindow : public Window /* There is only one widget. */ for (uint i = 0; i != this->paramcount; i++) SetDParam(i, this->params[i]); - size->width = min(GetStringBoundingBox(this->string_id).width, ScaleGUITrad(194)); + size->width = min(GetStringBoundingBox(this->string_id).width, ScaleGUITrad(250)); size->height = GetStringHeight(this->string_id, size->width); /* Increase slightly to have some space around the box. */ @@ -765,7 +780,7 @@ void QueryString::DrawEditBox(const Window *w, int wid) const bool rtl = _current_text_dir == TD_RTL; Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); - int clearbtn_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; + int clearbtn_width = GetMinSizing(NWST_BUTTON, sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT); int clearbtn_left = wi->pos_x + (rtl ? 0 : wi->current_x - clearbtn_width); int clearbtn_right = wi->pos_x + (rtl ? clearbtn_width : wi->current_x) - 1; @@ -776,7 +791,7 @@ void QueryString::DrawEditBox(const Window *w, int wid) const int bottom = wi->pos_y + wi->current_y - 1; DrawFrameRect(clearbtn_left, top, clearbtn_right, bottom, wi->colour, wi->IsLowered() ? FR_LOWERED : FR_NONE); - DrawSprite(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT, PAL_NONE, clearbtn_left + WD_IMGBTN_LEFT + (wi->IsLowered() ? 1 : 0), (top + bottom - sprite_size.height) / 2 + (wi->IsLowered() ? 1 : 0)); + DrawSprite(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT, PAL_NONE, Center(clearbtn_left + wi->IsLowered(), clearbtn_width, sprite_size.width), Center(top + wi->IsLowered(), bottom - top, sprite_size.height)); if (this->text.bytes == 1) GfxFillRect(clearbtn_left + 1, top + 1, clearbtn_right - 1, bottom - 1, _colour_gradient[wi->colour & 0xF][2], FILLRECT_CHECKER); DrawFrameRect(left, top, right, bottom, wi->colour, FR_LOWERED | FR_DARKENED); @@ -799,11 +814,12 @@ void QueryString::DrawEditBox(const Window *w, int wid) const /* If we have a marked area, draw a background highlight. */ if (tb->marklength != 0) GfxFillRect(delta + tb->markxoffs, 0, delta + tb->markxoffs + tb->marklength - 1, bottom - top, PC_GREY); - DrawString(delta, tb->pixels, 0, tb->buf, TC_YELLOW); + DrawString(delta, tb->pixels, Center(0, bottom - top), tb->buf, TC_YELLOW); + bool focussed = w->IsWidgetGloballyFocused(wid) || IsOSKOpenedFor(w, wid); if (focussed && tb->caret) { int caret_width = GetStringBoundingBox("_").width; - DrawString(tb->caretxoffs + delta, tb->caretxoffs + delta + caret_width, 0, "_", TC_WHITE); + DrawString(tb->caretxoffs + delta, tb->caretxoffs + delta + caret_width, Center(0, bottom - top), "_", TC_WHITE); } _cur_dpi = old_dpi; @@ -934,6 +950,17 @@ void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bo /* Open the OSK window */ ShowOnScreenKeyboard(w, wid); } +#ifdef __ANDROID__ + char text[512]; + strecpy(text, this->text.buf, lastof(text)); + this->text.DeleteAll(); + SDL_ANDROID_ToggleScreenKeyboardTextInput(text); // Invoke Android built-in screen keyboard, this will not block + /* + SDL_ANDROID_GetScreenKeyboardTextInput(text, sizeof(text) - 1); // Invoke Android built-in screen keyboard, this will block + this->text.Assign(text); + w->OnEditboxChanged(wid); + */ +#endif } /** Class for the string query window. */ @@ -1113,6 +1140,7 @@ struct QueryWindow : public Window { { if (widget != WID_Q_TEXT) return; + size->width = GetMinSizing(NWST_WINDOW_LENGTH, size->width); Dimension d = GetStringMultiLineBoundingBox(this->message, *size); d.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; diff --git a/src/music/libtimidity.cpp b/src/music/libtimidity.cpp index 1cb2adc0f9..02542fc9b9 100644 --- a/src/music/libtimidity.cpp +++ b/src/music/libtimidity.cpp @@ -13,6 +13,7 @@ #include "../openttd.h" #include "../sound_type.h" #include "../debug.h" +#include "../core/math_func.hpp" #include "libtimidity.h" #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #if defined(PSP) #include #endif /* PSP */ @@ -53,14 +55,34 @@ static void AudioOutCallback(void *buf, unsigned int _reqn, void *userdata) } } #endif /* PSP */ +#ifdef __ANDROID__ +/* Android does not have Midi chip, we have to route the libtimidity output through SDL audio output */ +void Android_MidiMixMusic(Sint16 *stream, int len) +{ + if (_midi.status == MIDI_PLAYING) { + Sint16 buf[16384]; + while( len > 0 ) + { + int minlen = min(sizeof(buf), len); + mid_song_read_wave(_midi.song, buf, min(sizeof(buf), len*2)); + for( Uint16 i = 0; i < minlen; i++ ) + stream[i] += buf[i]; + stream += minlen; + len -= minlen; + } + } +} +#endif /* __ANDROID__ */ /** Factory for the libtimidity driver. */ static FMusicDriver_LibTimidity iFMusicDriver_LibTimidity; +enum { TIMIDITY_MAX_VOLUME = 50 }; const char *MusicDriver_LibTimidity::Start(const char * const *param) { _midi.status = MIDI_STOPPED; _midi.song = NULL; + volume = TIMIDITY_MAX_VOLUME; // Avoid clipping if (mid_init(param == NULL ? NULL : const_cast(param[0])) < 0) { /* If init fails, it can be because no configuration was found. @@ -115,6 +137,7 @@ void MusicDriver_LibTimidity::PlaySong(const char *filename) return; } + mid_song_set_volume(_midi.song, volume); mid_song_start(_midi.song); _midi.status = MIDI_PLAYING; } @@ -142,5 +165,6 @@ bool MusicDriver_LibTimidity::IsSongPlaying() void MusicDriver_LibTimidity::SetVolume(byte vol) { + volume = vol * TIMIDITY_MAX_VOLUME / 127; // I'm not sure about that value if (_midi.song != NULL) mid_song_set_volume(_midi.song, vol); } diff --git a/src/music/libtimidity.h b/src/music/libtimidity.h index abe17e7703..0a0686499f 100644 --- a/src/music/libtimidity.h +++ b/src/music/libtimidity.h @@ -16,6 +16,7 @@ /** Music driver making use of libtimidity. */ class MusicDriver_LibTimidity : public MusicDriver { + int volume; public: /* virtual */ const char *Start(const char * const *param); diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 279f376525..508b06d2e5 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -297,13 +297,32 @@ static void SelectPlaylist(byte list) } struct MusicTrackSelectionWindow : public Window { + Scrollbar *left_sb; + Scrollbar *right_sb; + + /** Count the number of tracks of current tracklist. */ + uint GetNumberOfTracksOfTracklist() const + { + uint i = 0; + for (; _playlists[_settings_client.music.playlist][i] > 0; i++) {} + return i; + } + MusicTrackSelectionWindow(WindowDesc *desc, WindowNumber number) : Window(desc) { - this->InitNested(number); + + this->CreateNestedTree(); + this->left_sb = this->GetScrollbar(WID_MTS_LEFT_SCROLLBAR); + this->right_sb = this->GetScrollbar(WID_MTS_RIGHT_SCROLLBAR); + this->LowerWidget(WID_MTS_LIST_LEFT); this->LowerWidget(WID_MTS_LIST_RIGHT); this->SetWidgetDisabledState(WID_MTS_CLEAR, _settings_client.music.playlist <= 3); this->LowerWidget(WID_MTS_ALL + _settings_client.music.playlist); + this->FinishInitNested(number); + + this->left_sb->SetCount(NUM_SONGS_AVAILABLE); + this->right_sb->SetCount(GetNumberOfTracksOfTracklist()); } virtual void SetStringParameters(int widget) const @@ -327,6 +346,7 @@ struct MusicTrackSelectionWindow : public Window { this->SetWidgetLoweredState(WID_MTS_ALL + i, i == _settings_client.music.playlist); } this->SetWidgetDisabledState(WID_MTS_CLEAR, _settings_client.music.playlist <= 3); + this->right_sb->SetCount(GetNumberOfTracksOfTracklist()); this->SetDirty(); } @@ -346,7 +366,8 @@ struct MusicTrackSelectionWindow : public Window { break; } - case WID_MTS_LIST_LEFT: case WID_MTS_LIST_RIGHT: { + case WID_MTS_LIST_LEFT: + case WID_MTS_LIST_RIGHT: { Dimension d = {0, 0}; for (uint i = 0; i < NUM_SONGS_AVAILABLE; i++) { @@ -356,12 +377,11 @@ struct MusicTrackSelectionWindow : public Window { SetDParam(0, GetTrackNumber(i)); SetDParam(1, 2); SetDParamStr(2, GetSongName(i)); - Dimension d2 = GetStringBoundingBox(STR_PLAYLIST_TRACK_NAME); - d.width = max(d.width, d2.width); - d.height += d2.height; + d = maxdim(d, GetStringBoundingBox(STR_PLAYLIST_TRACK_NAME)); } - d.width += padding.width; - d.height += padding.height; + resize->height = GetMinSizing(NWST_STEP, d.height); + d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + d.height = 7 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; *size = maxdim(*size, d); break; } @@ -375,15 +395,17 @@ struct MusicTrackSelectionWindow : public Window { GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); int y = r.top + WD_FRAMERECT_TOP; - for (uint i = 0; i < NUM_SONGS_AVAILABLE; i++) { + uint vscroll_max = min(this->left_sb->GetPosition() + this->left_sb->GetCapacity(), NUM_SONGS_AVAILABLE); + + for (uint i = this->left_sb->GetPosition(); i < vscroll_max; i++) { const char *song_name = GetSongName(i); if (StrEmpty(song_name)) continue; SetDParam(0, GetTrackNumber(i)); SetDParam(1, 2); SetDParamStr(2, song_name); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME); - y += FONT_HEIGHT_SMALL; + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, this->resize.step_height, FONT_HEIGHT_SMALL), STR_PLAYLIST_TRACK_NAME); + y += this->resize.step_height; } break; } @@ -392,13 +414,15 @@ struct MusicTrackSelectionWindow : public Window { GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); int y = r.top + WD_FRAMERECT_TOP; - for (const byte *p = _playlists[_settings_client.music.playlist]; *p != 0; p++) { - uint i = *p - 1; - SetDParam(0, GetTrackNumber(i)); + uint vscroll_max = min(this->right_sb->GetPosition() + this->right_sb->GetCapacity(), this->GetNumberOfTracksOfTracklist()); + + for (uint i = this->right_sb->GetPosition(); i < vscroll_max; i++) { + uint j = _playlists[_settings_client.music.playlist][i] - 1; + SetDParam(0, GetTrackNumber(j)); SetDParam(1, 2); - SetDParamStr(2, GetSongName(i)); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME); - y += FONT_HEIGHT_SMALL; + SetDParamStr(2, GetSongName(j)); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, this->resize.step_height, FONT_HEIGHT_SMALL), STR_PLAYLIST_TRACK_NAME); + y += this->resize.step_height; } break; } @@ -409,22 +433,22 @@ struct MusicTrackSelectionWindow : public Window { { switch (widget) { case WID_MTS_LIST_LEFT: { // add to playlist - int y = this->GetRowFromWidget(pt.y, widget, 0, FONT_HEIGHT_SMALL); - if (_settings_client.music.playlist < 4) return; - if (!IsInsideMM(y, 0, BaseMusic::GetUsedSet()->num_available)) return; + int id_m = this->left_sb->GetScrolledRowFromWidget(pt.y, this, WID_MTS_LIST_LEFT, WD_FRAMERECT_TOP, this->resize.step_height); + if (!IsInsideMM(id_m, 0, BaseMusic::GetUsedSet()->num_available)) return; byte *p = _playlists[_settings_client.music.playlist]; for (uint i = 0; i != NUM_SONGS_PLAYLIST - 1; i++) { if (p[i] == 0) { /* Find the actual song number */ for (uint j = 0; j < NUM_SONGS_AVAILABLE; j++) { - if (GetTrackNumber(j) == y + 1) { + if (GetTrackNumber(j) == id_m + 1) { p[i] = j + 1; break; } } p[i + 1] = 0; + this->right_sb->SetCount(GetNumberOfTracksOfTracklist()); this->SetDirty(); SelectSongToPlay(); break; @@ -434,16 +458,16 @@ struct MusicTrackSelectionWindow : public Window { } case WID_MTS_LIST_RIGHT: { // remove from playlist - int y = this->GetRowFromWidget(pt.y, widget, 0, FONT_HEIGHT_SMALL); - if (_settings_client.music.playlist < 4) return; - if (!IsInsideMM(y, 0, NUM_SONGS_PLAYLIST)) return; + int id_m = this->right_sb->GetScrolledRowFromWidget(pt.y, this, WID_MTS_LIST_RIGHT, WD_FRAMERECT_TOP, this->resize.step_height); + if (!IsInsideMM(id_m, 0, NUM_SONGS_PLAYLIST)) return; byte *p = _playlists[_settings_client.music.playlist]; - for (uint i = y; i != NUM_SONGS_PLAYLIST - 1; i++) { + for (uint i = id_m; i != NUM_SONGS_PLAYLIST - 1; i++) { p[i] = p[i + 1]; } + this->right_sb->SetCount(GetNumberOfTracksOfTracklist()); this->SetDirty(); SelectSongToPlay(); break; @@ -451,55 +475,74 @@ struct MusicTrackSelectionWindow : public Window { case WID_MTS_CLEAR: // clear for (uint i = 0; _playlists[_settings_client.music.playlist][i] != 0; i++) _playlists[_settings_client.music.playlist][i] = 0; + this->right_sb->SetCount(GetNumberOfTracksOfTracklist()); this->SetDirty(); StopMusic(); SelectSongToPlay(); break; - case WID_MTS_ALL: case WID_MTS_OLD: case WID_MTS_NEW: - case WID_MTS_EZY: case WID_MTS_CUSTOM1: case WID_MTS_CUSTOM2: // set playlist + case WID_MTS_ALL: + case WID_MTS_OLD: + case WID_MTS_NEW: + case WID_MTS_EZY: + case WID_MTS_CUSTOM1: + case WID_MTS_CUSTOM2: // set playlist SelectPlaylist(widget - WID_MTS_ALL); + this->right_sb->SetCount(GetNumberOfTracksOfTracklist()); + this->SetDirty(); StopMusic(); SelectSongToPlay(); break; } } + + virtual void OnResize() + { + this->left_sb->SetCapacityFromWidget(this, WID_MTS_LIST_LEFT); + this->right_sb->SetCapacityFromWidget(this, WID_MTS_LIST_RIGHT); + } }; static const NWidgetPart _nested_music_track_selection_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_PLAYLIST_MUSIC_PROGRAM_SELECTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2), /* Left panel. */ NWidget(NWID_VERTICAL), NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_PLAYLIST_TRACK_INDEX, STR_NULL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_MTS_LIST_LEFT), SetMinimalSize(180, 194), SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK), EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_MTS_LIST_LEFT), SetMinimalSize(180, 100), SetMatrixDataTip(1, 0, STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK), + SetFill(1, 0), SetResize(1, 1), SetScrollbar(WID_MTS_LEFT_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_MTS_LEFT_SCROLLBAR), + EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 2), EndContainer(), - /* Middle buttons. */ - NWidget(NWID_VERTICAL), - NWidget(NWID_SPACER), SetMinimalSize(60, 30), // Space above the first button from the title bar. - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_ALL), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_ALL, STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_OLD), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_OLD_STYLE, STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_NEW), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_NEW_STYLE, STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_EZY), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_EZY_STREET, STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_CUSTOM1), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_1, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_CUSTOM2), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_2, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED), - NWidget(NWID_SPACER), SetMinimalSize(0, 16), // Space above 'clear' button - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_MTS_CLEAR), SetFill(1, 0), SetDataTip(STR_PLAYLIST_CLEAR, STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1), - NWidget(NWID_SPACER), SetFill(0, 1), - EndContainer(), /* Right panel. */ NWidget(NWID_VERTICAL), NWidget(WWT_LABEL, COLOUR_GREY, WID_MTS_PLAYLIST), SetDataTip(STR_PLAYLIST_PROGRAM, STR_NULL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_MTS_LIST_RIGHT), SetMinimalSize(180, 194), SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK), EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_MTS_LIST_RIGHT), SetMinimalSize(180, 100), SetMatrixDataTip(1, 0, STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK), + SetFill(1, 0), SetResize(1, 1), SetScrollbar(WID_MTS_RIGHT_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_MTS_RIGHT_SCROLLBAR), + EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 2), EndContainer(), EndContainer(), EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_ALL), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_ALL, STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_OLD), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_OLD_STYLE, STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_NEW), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_NEW_STYLE, STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_EZY), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_EZY_STREET, STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_CUSTOM1), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_1, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_CUSTOM2), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_2, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_MTS_CLEAR), SetFill(1, 0), SetDataTip(STR_PLAYLIST_CLEAR, STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1), + NWidget(WWT_RESIZEBOX, COLOUR_GREY), + EndContainer(), }; static WindowDesc _music_track_selection_desc( @@ -577,7 +620,7 @@ struct MusicWindow : public Window { SetDParam(1, 2); str = STR_MUSIC_TRACK_DIGIT; } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top, FONT_HEIGHT_SMALL), str); break; } @@ -588,7 +631,7 @@ struct MusicWindow : public Window { str = STR_MUSIC_TITLE_NAME; SetDParamStr(0, GetSongName(_music_wnd_cursong - 1)); } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top, FONT_HEIGHT_SMALL), str, TC_FROMSTRING, SA_HOR_CENTER); break; } @@ -653,7 +696,7 @@ struct MusicWindow : public Window { if (_current_text_dir == TD_RTL) new_vol = 127 - new_vol; if (new_vol != *vol) { *vol = new_vol; - if (widget == WID_M_MUSIC_VOL) MusicVolumeChanged(new_vol); + if (widget == WID_M_MUSIC_VOL) MusicVolumeChanged((new_vol * new_vol) / 127); // Kinda logarithmic scale this->SetDirty(); } @@ -679,7 +722,6 @@ struct MusicWindow : public Window { SelectPlaylist(widget - WID_M_ALL); StopMusic(); SelectSongToPlay(); - this->SetDirty(); break; } } @@ -744,11 +786,11 @@ static const NWidgetPart _nested_music_window_widgets[] = { EndContainer(), NWidget(NWID_VERTICAL), SetPadding(0, 0, 3, 3), NWidget(WWT_LABEL, COLOUR_GREY, WID_M_TRACK), SetFill(0, 0), SetDataTip(STR_MUSIC_TRACK, STR_NULL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_M_TRACK_NR), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_M_TRACK_NR), SetFill(0, 1), EndContainer(), EndContainer(), NWidget(NWID_VERTICAL), SetPadding(0, 3, 3, 0), NWidget(WWT_LABEL, COLOUR_GREY, WID_M_TRACK_TITLE), SetFill(1, 0), SetDataTip(STR_MUSIC_XTITLE, STR_NULL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_M_TRACK_NAME), SetFill(1, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_M_TRACK_NAME), SetFill(1, 1), EndContainer(), EndContainer(), NWidget(NWID_VERTICAL), NWidget(NWID_SPACER), SetFill(0, 1), diff --git a/src/network/core/os_abstraction.h b/src/network/core/os_abstraction.h index 9608f08fa7..f358bf1c1c 100644 --- a/src/network/core/os_abstraction.h +++ b/src/network/core/os_abstraction.h @@ -161,7 +161,7 @@ static inline void OTTDfreeaddrinfo(struct addrinfo *ai) # include /* According to glibc/NEWS, appeared in glibc-2.3. */ # if !defined(__sgi__) && !defined(SUNOS) && !defined(__MORPHOS__) && !defined(__BEOS__) && !defined(__HAIKU__) && !defined(__INNOTEK_LIBC__) \ - && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) && !defined(HPUX) + && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) && !defined(HPUX) && !defined(__ANDROID__) /* If for any reason ifaddrs.h does not exist on your system, comment out * the following two lines and an alternative way will be used to fetch * the list of IPs from the system. */ diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp index 3416762d02..5b96b1a251 100644 --- a/src/network/network_chat_gui.cpp +++ b/src/network/network_chat_gui.cpp @@ -462,7 +462,7 @@ struct NetworkChatWindow : public Window { virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) { - Point pt = { 0, _screen.height - sm_height - FindWindowById(WC_STATUS_BAR, 0)->height }; + Point pt = { GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) * 2, _screen.height - sm_height - FindWindowById(WC_STATUS_BAR, 0)->height }; return pt; } @@ -486,7 +486,7 @@ struct NetworkChatWindow : public Window { if (this->dtype == DESTTYPE_CLIENT) { SetDParamStr(0, NetworkClientInfo::GetByClientID((ClientID)this->dest)->client_name); } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, this->dest_string, TC_BLACK, SA_RIGHT); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top), this->dest_string, TC_BLACK, SA_RIGHT); } virtual void OnClick(Point pt, int widget, int click_count) diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 1227d43dbb..6b1b652ccc 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -23,6 +23,8 @@ #include "../querystring_gui.h" #include "../core/geometry_func.hpp" #include "../textfile_gui.h" +#include "../settings_type.h" +#include "../settings_gui.h" #include "network_content_gui.h" @@ -584,8 +586,8 @@ public: } case WID_NCL_MATRIX: - resize->height = max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; - size->height = 10 * resize->height; + resize->height = SETTING_BUTTON_HEIGHT; + size->height = 6 * resize->height; break; } } @@ -595,7 +597,7 @@ public: { switch (widget) { case WID_NCL_FILTER_CAPT: - DrawString(r.left, r.right, r.top, STR_CONTENT_FILTER_TITLE, TC_FROMSTRING, SA_RIGHT); + DrawString(r.left, r.right, Center(r.top, r.bottom - r.top), STR_CONTENT_FILTER_TITLE, TC_FROMSTRING, SA_RIGHT); break; case WID_NCL_DETAILS: @@ -638,14 +640,14 @@ public: int line_height = max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL); /* Fill the matrix with the information */ - int sprite_y_offset = WD_MATRIX_TOP + (line_height - this->checkbox_size.height) / 2 - 1; - int text_y_offset = WD_MATRIX_TOP + (line_height - FONT_HEIGHT_NORMAL) / 2; + int sprite_y_offset = WD_MATRIX_TOP + (line_height - this->checkbox_size.height) / 2 - 1 + (this->resize.step_height - line_height) / 2; + int text_y_offset = WD_MATRIX_TOP + (line_height - FONT_HEIGHT_NORMAL) / 2 + (this->resize.step_height - line_height) / 2; uint y = r.top; int cnt = 0; for (ConstContentIterator iter = this->content.Get(this->vscroll->GetPosition()); iter != this->content.End() && cnt < this->vscroll->GetCapacity(); iter++, cnt++) { const ContentInfo *ci = *iter; - if (ci == this->selected) GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 1, PC_GREY); + if (ci == this->selected) GfxFillRect(r.left + 1, y + WD_FRAMERECT_TOP, r.right - 1, y + this->resize.step_height - WD_FRAMERECT_BOTTOM, PC_GREY); SpriteID sprite; SpriteID pal = PAL_NONE; @@ -1056,14 +1058,7 @@ static const NWidgetPart _nested_network_content_list_widgets[] = { NWidget(WWT_DEFSIZEBOX, COLOUR_LIGHT_BLUE), EndContainer(), NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_NCL_BACKGROUND), - NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetResize(1, 0), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8), - /* Top */ - NWidget(WWT_EMPTY, COLOUR_LIGHT_BLUE, WID_NCL_FILTER_CAPT), SetFill(1, 0), SetResize(1, 0), - NWidget(WWT_EDITBOX, COLOUR_LIGHT_BLUE, WID_NCL_FILTER), SetFill(1, 0), SetResize(1, 0), - SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetResize(1, 0), + NWidget(NWID_SPACER), SetMinimalSize(0, 3), SetResize(1, 0), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8), /* Left side. */ NWidget(NWID_VERTICAL), SetPIP(0, 4, 0), @@ -1093,6 +1088,13 @@ static const NWidgetPart _nested_network_content_list_widgets[] = { EndContainer(), /* Right side. */ NWidget(NWID_VERTICAL), SetPIP(0, 4, 0), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8), + /* Top */ + NWidget(WWT_EMPTY, COLOUR_LIGHT_BLUE, WID_NCL_FILTER_CAPT), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_EDITBOX, COLOUR_LIGHT_BLUE, WID_NCL_FILTER), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 3), SetResize(1, 0), NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_NCL_DETAILS), SetResize(1, 1), SetFill(1, 1), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, 8, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 520c4f60a8..9e97035c84 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -31,6 +31,7 @@ #include "../core/geometry_func.hpp" #include "../genworld.h" #include "../map_type.h" +#include "../settings_gui.h" #include "../widgets/network_widget.h" @@ -505,17 +506,17 @@ public: switch (widget) { case WID_NG_CONN_BTN: *size = maxdim(*size, maxdim(GetStringBoundingBox(_lan_internet_types_dropdown[0]), GetStringBoundingBox(_lan_internet_types_dropdown[1]))); - size->width += padding.width; + size->width += padding.width + GetMinSizing(NWST_STEP, 11U);; size->height += padding.height; break; case WID_NG_MATRIX: - resize->height = WD_MATRIX_TOP + max(GetSpriteSize(SPR_BLOT).height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_BOTTOM; - size->height = 10 * resize->height; + resize->height = SETTING_BUTTON_HEIGHT; + size->height = 5 * resize->height; break; case WID_NG_LASTJOINED: - size->height = WD_MATRIX_TOP + max(GetSpriteSize(SPR_BLOT).height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_BOTTOM; + size->height = SETTING_BUTTON_HEIGHT; break; case WID_NG_LASTJOINED_SPACER: @@ -550,7 +551,7 @@ public: break; case WID_NG_DETAILS_SPACER: - size->height = 20 + 12 * FONT_HEIGHT_NORMAL; + size->height = 20 + 10 * FONT_HEIGHT_NORMAL; break; } } @@ -942,12 +943,9 @@ static const NWidgetPart _nested_network_game_widgets[] = { /* LEFT SIDE */ NWidget(NWID_VERTICAL), SetPIP(0, 7, 0), NWidget(NWID_HORIZONTAL), SetPIP(0, 7, 0), - NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NG_CONNECTION), SetDataTip(STR_NETWORK_SERVER_LIST_ADVERTISED, STR_NULL), + NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NG_CONNECTION), SetSizingType(NWST_STEP), SetDataTip(STR_NETWORK_SERVER_LIST_ADVERTISED, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NG_CONN_BTN), SetDataTip(STR_BLACK_STRING, STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP), - NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0), - EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(0, 7, 0), NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NG_FILTER_LABEL), SetDataTip(STR_LIST_FILTER_TITLE, STR_NULL), NWidget(WWT_EDITBOX, COLOUR_LIGHT_BLUE, WID_NG_FILTER), SetMinimalSize(251, 12), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), @@ -1091,8 +1089,8 @@ struct NetworkStartServerWindow : public Window { switch (widget) { case WID_NSS_CONNTYPE_BTN: *size = maxdim(GetStringBoundingBox(_connection_types_dropdown[0]), GetStringBoundingBox(_connection_types_dropdown[1])); - size->width += padding.width; - size->height += padding.height; + size->width = GetMinSizing(NWST_BUTTON, size->width + padding.width); + size->height = GetMinSizing(NWST_BUTTON, size->height + padding.height); break; } } @@ -1275,15 +1273,15 @@ static const NWidgetPart _nested_network_start_server_window_widgets[] = { NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 6, 10), NWidget(NWID_VERTICAL), SetPIP(0, 1, 0), NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_LABEL), SetFill(1, 0), SetDataTip(STR_NETWORK_SERVER_LIST_ADVERTISED, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_BTN), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP), + NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_BTN), SetSizingType(NWST_BUTTON), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP), EndContainer(), NWidget(NWID_VERTICAL), SetPIP(0, 1, 0), NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NSS_LANGUAGE_LABEL), SetFill(1, 0), SetDataTip(STR_NETWORK_START_SERVER_LANGUAGE_SPOKEN, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_LANGUAGE_BTN), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_START_SERVER_LANGUAGE_TOOLTIP), + NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_LANGUAGE_BTN), SetSizingType(NWST_BUTTON), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_START_SERVER_LANGUAGE_TOOLTIP), EndContainer(), NWidget(NWID_VERTICAL), SetPIP(0, 1, 0), NWidget(NWID_SPACER), SetFill(1, 1), - NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NSS_SETPWD), SetFill(1, 0), SetDataTip(STR_NETWORK_START_SERVER_SET_PASSWORD, STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NSS_SETPWD), SetSizingType(NWST_BUTTON), SetFill(1, 0), SetDataTip(STR_NETWORK_START_SERVER_SET_PASSWORD, STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP), EndContainer(), EndContainer(), @@ -1386,8 +1384,8 @@ struct NetworkLobbyWindow : public Window { break; case WID_NL_MATRIX: - resize->height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM; - size->height = 10 * resize->height; + resize->height = GetMinSizing(NWST_STEP, WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM); + size->height = 6 * resize->height; break; case WID_NL_DETAILS: @@ -1454,7 +1452,7 @@ struct NetworkLobbyWindow : public Window { uint profit_left = rtl ? left : right - profit_width; uint lock_left = rtl ? left + profit_width + 2 : right - profit_width - lock_width - 2; - int y = r.top + WD_MATRIX_TOP; + int y = r.top + WD_MATRIX_TOP + this->resize.step_height / 4; /* Draw company list */ int pos = this->vscroll->GetPosition(); while (pos < this->server->info.companies_on) { @@ -1719,7 +1717,7 @@ struct NetworkClientListPopupWindow : Window { ClientList_Action_Proc *proc; ///< Action to execute }; - uint sel_index; + int sel_index; ClientID client_id; Point desired_location; SmallVector actions; ///< Actions to execute @@ -1738,10 +1736,10 @@ struct NetworkClientListPopupWindow : Window { NetworkClientListPopupWindow(WindowDesc *desc, int x, int y, ClientID client_id) : Window(desc), - sel_index(0), client_id(client_id) + sel_index(-1), client_id(client_id) { - this->desired_location.x = x; - this->desired_location.y = y; + this->desired_location.x = x - GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); + this->desired_location.y = y + GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) / 2; const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); @@ -1783,6 +1781,7 @@ struct NetworkClientListPopupWindow : Window { d = maxdim(GetStringBoundingBox(action->name), d); } + d.height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); d.height *= this->actions.Length(); d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; @@ -1794,37 +1793,29 @@ struct NetworkClientListPopupWindow : Window { /* Draw the actions */ int sel = this->sel_index; int y = r.top + WD_FRAMERECT_TOP; - for (const ClientListAction *action = this->actions.Begin(); action != this->actions.End(); action++, y += FONT_HEIGHT_NORMAL) { + for (const ClientListAction *action = this->actions.Begin(); action != this->actions.End(); action++, y += GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL)) { TextColour colour; if (sel-- == 0) { // Selected item, highlight it - GfxFillRect(r.left + 1, y, r.right - 1, y + FONT_HEIGHT_NORMAL - 1, PC_BLACK); + GfxFillRect(r.left + 1, y, r.right - 1, y + GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) - 1, PC_BLACK); colour = TC_WHITE; } else { colour = TC_BLACK; } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, action->name, colour); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL)), action->name, colour); } } - virtual void OnMouseLoop() + virtual void OnClick(Point pt, int widget, int click_count) { - /* We selected an action */ - uint index = (_cursor.pos.y - this->top - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL; + int index = (pt.y - WD_FRAMERECT_TOP) / GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); - if (_left_button_down) { - if (index == this->sel_index || index >= this->actions.Length()) return; - - this->sel_index = index; - this->SetDirty(); - } else { - if (index < this->actions.Length() && _cursor.pos.y >= this->top) { - const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(this->client_id); - if (ci != NULL) this->actions[index].proc(ci); - } - - DeleteWindowByClass(WC_CLIENT_LIST_POPUP); + if (index >= 0 && index < (int)this->actions.Length()) { + const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(this->client_id); + if (ci != NULL) this->actions[index].proc(ci); } + + DeleteWindowByClass(WC_CLIENT_LIST_POPUP); } }; @@ -1846,7 +1837,7 @@ static const NWidgetPart _nested_client_list_widgets[] = { NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_STICKYBOX, COLOUR_GREY), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_CL_PANEL), SetMinimalSize(250, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM), SetResize(1, 1), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_CL_PANEL), SetMinimalSize(100, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM), SetResize(1, 1), EndContainer(), }; static WindowDesc _client_list_desc( @@ -1864,6 +1855,8 @@ struct NetworkClientListWindow : Window { uint server_client_width; uint line_height; + uint line_width; + enum { MAX_ROWS = 6 }; // Split the list in two if it does not fit the screen Dimension icon_size; @@ -1887,12 +1880,16 @@ struct NetworkClientListWindow : Window { if (ci->client_playas != COMPANY_INACTIVE_CLIENT) num++; } + int cols = 1 + (num - 1) / MAX_ROWS; + cols *= this->line_width; + num = min(num, MAX_ROWS); num *= this->line_height; - int diff = (num + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM) - (this->GetWidget(WID_CL_PANEL)->current_y); + int diffx = (cols + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT) - (this->GetWidget(WID_CL_PANEL)->current_x); + int diffy = (num + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM) - (this->GetWidget(WID_CL_PANEL)->current_y); /* If height is changed */ - if (diff != 0) { - ResizeWindow(this, 0, diff, false); + if (diffx > 0 || diffy != 0) { // Width can only grow, also title bar can be wider than content + ResizeWindow(this, diffx, diffy, false); return false; } return true; @@ -1905,6 +1902,7 @@ struct NetworkClientListWindow : Window { this->server_client_width = max(GetStringBoundingBox(STR_NETWORK_SERVER).width, GetStringBoundingBox(STR_NETWORK_CLIENT).width) + WD_FRAMERECT_RIGHT; this->icon_size = GetSpriteSize(SPR_COMPANY_ICON); this->line_height = max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL); + this->line_height = GetMinSizing(NWST_STEP, this->line_height); uint width = 100; // Default width const NetworkClientInfo *ci; @@ -1912,7 +1910,7 @@ struct NetworkClientListWindow : Window { width = max(width, GetStringBoundingBox(ci->client_name).width); } - size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT + width + WD_FRAMERECT_RIGHT; + this->line_width = this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT + width + WD_FRAMERECT_RIGHT; } virtual void OnPaint() @@ -1936,19 +1934,21 @@ struct NetworkClientListWindow : Window { uint right = r.right - WD_FRAMERECT_RIGHT; uint type_icon_width = this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT; - - uint type_left = rtl ? right - this->server_client_width : left; - uint type_right = rtl ? right : left + this->server_client_width - 1; - uint icon_left = rtl ? right - type_icon_width + WD_FRAMERECT_LEFT : left + this->server_client_width; - uint name_left = rtl ? left : left + type_icon_width; - uint name_right = rtl ? right - type_icon_width : right; - int i = 0; const NetworkClientInfo *ci; FOR_ALL_CLIENT_INFOS(ci) { + uint type_left = rtl ? right - this->server_client_width : left; + uint type_right = rtl ? right : left + this->server_client_width - 1; + uint icon_left = rtl ? right - type_icon_width + WD_FRAMERECT_LEFT : left + this->server_client_width; + uint name_left = rtl ? right - this->line_width : left + type_icon_width; + uint name_right = rtl ? right - type_icon_width : left + this->line_width; TextColour colour; if (this->selected_item == i++) { // Selected item, highlight it - GfxFillRect(r.left + 1, y, r.right - 1, y + this->line_height - 1, PC_BLACK); + if (rtl) { + GfxFillRect(right - this->line_width, y, right + WD_FRAMERECT_RIGHT - 1, y + this->line_height - 1, PC_BLACK); + } else { + GfxFillRect(left - WD_FRAMERECT_LEFT + 1, y, left + this->line_width, y + this->line_height - 1, PC_BLACK); + } colour = TC_WHITE; } else { colour = TC_BLACK; @@ -1966,6 +1966,14 @@ struct NetworkClientListWindow : Window { DrawString(name_left, name_right, y + text_offset, ci->client_name, colour); y += line_height; + if (i % MAX_ROWS == 0 && i > 1) { + y = r.top + WD_FRAMERECT_TOP; + if (rtl) { + right -= this->line_width; + } else { + left += this->line_width; + } + } } } @@ -1998,7 +2006,7 @@ struct NetworkClientListWindow : Window { pt.y -= this->GetWidget(WID_CL_PANEL)->pos_y; int item = -1; if (IsInsideMM(pt.y, WD_FRAMERECT_TOP, this->GetWidget(WID_CL_PANEL)->current_y - WD_FRAMERECT_BOTTOM)) { - item = (pt.y - WD_FRAMERECT_TOP) / this->line_height; + item = (pt.y - WD_FRAMERECT_TOP) / this->line_height + ((pt.x - WD_FRAMERECT_LEFT) / this->line_width) * MAX_ROWS; } /* It did not change.. no update! */ diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index 75b06967f7..295ad9ff52 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -437,7 +437,7 @@ struct NewGRFInspectWindow : Window { GrfSpecFeature f = GetFeatureNum(this->window_number); int h = GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height; - int y = (r.top + r.bottom - h) / 2; + int y = Center(r.top, r.bottom - r.top, h); DrawVehicleImage(v->First(), r.left + WD_BEVEL_LEFT, r.right - WD_BEVEL_RIGHT, y + 1, INVALID_VEHICLE, EIT_IN_DETAILS, skip); /* Highlight the articulated part (this is different to the whole-vehicle highlighting of DrawVehicleImage */ @@ -860,7 +860,7 @@ struct SpriteAlignerWindow : Window { { if (widget != WID_SA_LIST) return; - resize->height = max(11, FONT_HEIGHT_NORMAL + 1); + resize->height = GetMinSizing(NWST_STEP, max(11, FONT_HEIGHT_NORMAL + 1)); resize->width = 1; /* Resize to about 200 pixels (for the preview) */ @@ -897,10 +897,10 @@ struct SpriteAlignerWindow : Window { SmallVector &list = _newgrf_debug_sprite_picker.sprites; int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), list.Length()); - int y = r.top + WD_FRAMERECT_TOP; + int y = Center(r.top + WD_FRAMERECT_TOP, step_size, FONT_HEIGHT_NORMAL); for (int i = this->vscroll->GetPosition(); i < max; i++) { SetDParam(0, list[i]); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_BLACK_COMMA, TC_FROMSTRING, SA_CENTER | SA_FORCE); y += step_size; } break; diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index c3007ac42d..0f347069db 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -654,10 +654,9 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_NS_SCROLLBAR); - this->vscroll2 = this->GetScrollbar(WID_NS_SCROLL2BAR); + this->vscroll2 = this->editable ? this->GetScrollbar(WID_NS_SCROLL2BAR) : NULL; this->GetWidget(WID_NS_SHOW_REMOVE)->SetDisplayedPlane(this->editable ? 0 : 1); - this->GetWidget(WID_NS_SHOW_APPLY)->SetDisplayedPlane(this->editable ? 0 : this->show_params ? 1 : SZSP_HORIZONTAL); this->FinishInitNested(WN_GAME_OPTIONS_NEWGRF_STATE); this->querystrings[WID_NS_FILTER] = &this->filter_editbox; @@ -738,14 +737,14 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case WID_NS_FILE_LIST: { Dimension d = maxdim(GetSpriteSize(SPR_SQUARE), GetSpriteSize(SPR_WARNING_SIGN)); - resize->height = max(d.height + 2U, FONT_HEIGHT_NORMAL + 2U); - size->height = max(size->height, WD_FRAMERECT_TOP + 6 * resize->height + WD_FRAMERECT_BOTTOM); + resize->height = GetMinSizing(NWST_STEP, max(d.height + 2U, FONT_HEIGHT_NORMAL + 2U)); + size->height = max(size->height, WD_FRAMERECT_TOP + 4 * resize->height + WD_FRAMERECT_BOTTOM); break; } case WID_NS_AVAIL_LIST: - resize->height = max(12, FONT_HEIGHT_NORMAL + 2); - size->height = max(size->height, WD_FRAMERECT_TOP + 8 * resize->height + WD_FRAMERECT_BOTTOM); + resize->height = GetMinSizing(NWST_STEP, max(12, FONT_HEIGHT_NORMAL + 2)); + size->height = max(size->height, WD_FRAMERECT_TOP + 4 * resize->height + WD_FRAMERECT_BOTTOM); break; case WID_NS_NEWGRF_INFO_TITLE: { @@ -768,6 +767,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } } d.width += padding.width; + d.height = GetMinSizing(NWST_BUTTON, d.height); *size = maxdim(d, *size); break; } @@ -778,6 +778,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { *size = maxdim(d, GetStringBoundingBox(STR_INTRO_ONLINE_CONTENT)); size->width += padding.width; size->height += padding.height; + size->height = GetMinSizing(NWST_BUTTON, size->height); break; } } @@ -786,7 +787,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { virtual void OnResize() { this->vscroll->SetCapacityFromWidget(this, WID_NS_FILE_LIST); - this->vscroll2->SetCapacityFromWidget(this, WID_NS_AVAIL_LIST); + if (this->vscroll2) this->vscroll2->SetCapacityFromWidget(this, WID_NS_AVAIL_LIST); } virtual void SetStringParameters(int widget) const @@ -1294,8 +1295,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { widget_data = STR_INTRO_ONLINE_CONTENT; tool_tip = STR_INTRO_TOOLTIP_ONLINE_CONTENT; } - this->GetWidget(WID_NS_CONTENT_DOWNLOAD)->widget_data = widget_data; - this->GetWidget(WID_NS_CONTENT_DOWNLOAD)->tool_tip = tool_tip; + if (this->editable) { + this->GetWidget(WID_NS_CONTENT_DOWNLOAD)->widget_data = widget_data; + this->GetWidget(WID_NS_CONTENT_DOWNLOAD)->tool_tip = tool_tip; + } this->GetWidget(WID_NS_CONTENT_DOWNLOAD2)->widget_data = widget_data; this->GetWidget(WID_NS_CONTENT_DOWNLOAD2)->tool_tip = tool_tip; @@ -1493,7 +1496,7 @@ private: if (this->avail_pos < 0) this->avail_sel = NULL; } - this->vscroll2->SetCount(this->avails.Length()); // Update the scrollbar + if (this->vscroll2) this->vscroll2->SetCount(this->avails.Length()); // Update the scrollbar } /** @@ -1628,8 +1631,8 @@ public: uint min_inf_height = this->inf->smallest_y + this->inf->padding_top + this->inf->padding_bottom; /* Smallest window is in two column mode. */ - this->smallest_x = max(min_avs_width, min_acs_width) + INTER_COLUMN_SPACING + min_inf_width; - this->smallest_y = max(min_inf_height, min_acs_height + INTER_LIST_SPACING + min_avs_height); + this->smallest_x = min_avs_width + min_acs_width + min_inf_width + INTER_COLUMN_SPACING * 2; + this->smallest_y = max(max(min_inf_height, min_acs_height), min_avs_height); /* Filling. */ this->fill_x = LeastCommonMultiple(this->avs->fill_x, this->acs->fill_x); @@ -1666,7 +1669,7 @@ public: /* Use 2 or 3 columns? */ uint min_three_columns = min_avs_width + min_acs_width + min_inf_width + 2 * INTER_COLUMN_SPACING; uint min_two_columns = min_list_width + min_inf_width + INTER_COLUMN_SPACING; - bool use_three_columns = this->editable && (min_three_columns + MIN_EXTRA_FOR_3_COLUMNS <= given_width); + bool use_three_columns = true; // this->editable; /* Info panel is a separate column in both modes. Compute its width first. */ uint extra_width, inf_width; @@ -1774,7 +1777,7 @@ public: { if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL; - NWidgetCore *nw = (this->editable) ? this->avs->GetWidgetFromPos(x, y) : NULL; + NWidgetCore *nw = this->avs->GetWidgetFromPos(x, y); if (nw == NULL) nw = this->acs->GetWidgetFromPos(x, y); if (nw == NULL) nw = this->inf->GetWidgetFromPos(x, y); return nw; @@ -1782,7 +1785,7 @@ public: virtual void Draw(const Window *w) { - if (this->editable) this->avs->Draw(w); + this->avs->Draw(w); this->acs->Draw(w); this->inf->Draw(w); } @@ -1898,33 +1901,111 @@ static const NWidgetPart _nested_newgrf_infopanel_widgets[] = { SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), EndContainer(), EndContainer(), - NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NS_SHOW_APPLY), - /* Right side, buttons. */ - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, WD_RESIZEBOX_WIDTH, 0), - NWidget(NWID_VERTICAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_SET_PARAMETERS), SetFill(1, 0), SetResize(1, 0), - SetDataTip(STR_NEWGRF_SETTINGS_SET_PARAMETERS, STR_NULL), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_TOGGLE_PALETTE), SetFill(1, 0), SetResize(1, 0), - SetDataTip(STR_NEWGRF_SETTINGS_TOGGLE_PALETTE, STR_NEWGRF_SETTINGS_TOGGLE_PALETTE_TOOLTIP), - EndContainer(), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_APPLY_CHANGES), SetFill(1, 0), SetResize(1, 0), - SetDataTip(STR_NEWGRF_SETTINGS_APPLY_CHANGES, STR_NULL), + /* Right side, buttons. */ + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, WD_RESIZEBOX_WIDTH, 0), + NWidget(NWID_VERTICAL), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_SET_PARAMETERS), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_NEWGRF_SETTINGS_SET_PARAMETERS, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_TOGGLE_PALETTE), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_NEWGRF_SETTINGS_TOGGLE_PALETTE, STR_NEWGRF_SETTINGS_TOGGLE_PALETTE_TOOLTIP), EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_APPLY_CHANGES), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_NEWGRF_SETTINGS_APPLY_CHANGES, STR_NULL), + EndContainer(), +}; + +static const NWidgetPart _nested_newgrf_actives_wide_widgets[] = { + /* Left side, presets. */ + NWidget(NWID_VERTICAL), + NWidget(WWT_LABEL, COLOUR_MAUVE), SetDataTip(STR_NEWGRF_SETTINGS_ACTIVE_LIST, STR_NULL), + SetFill(1, 0), SetResize(1, 0), SetPadding(3, WD_FRAMETEXT_RIGHT, 0, WD_FRAMETEXT_LEFT), + /* Left side, active grfs. */ + NWidget(NWID_HORIZONTAL), SetPadding(0, 2, 0, 2), + NWidget(WWT_PANEL, COLOUR_MAUVE), + NWidget(WWT_INSET, COLOUR_MAUVE, WID_NS_FILE_LIST), SetMinimalSize(100, 1), SetPadding(2, 2, 2, 2), + SetFill(1, 1), SetResize(1, 1), SetScrollbar(WID_NS_SCROLLBAR), SetDataTip(STR_NULL, STR_NEWGRF_SETTINGS_FILE_TOOLTIP), + EndContainer(), + EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_NS_SCROLLBAR), + EndContainer(), + EndContainer(), +}; + +static const NWidgetPart _nested_newgrf_buttons_wide_widgets[] = { + NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_TEXT, COLOUR_MAUVE), SetDataTip(STR_NEWGRF_SETTINGS_SELECT_PRESET, STR_NULL), + SetPadding(0, WD_FRAMETEXT_RIGHT, 0, 0), + NWidget(WWT_DROPDOWN, COLOUR_YELLOW, WID_NS_PRESET_LIST), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_JUST_STRING, STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_PRESET_SAVE), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_NEWGRF_SETTINGS_PRESET_SAVE, STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_PRESET_DELETE), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_NEWGRF_SETTINGS_PRESET_DELETE, STR_NEWGRF_SETTINGS_PRESET_DELETE_TOOLTIP), + EndContainer(), + + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NS_SHOW_REMOVE), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPadding(0, 2, 0, 2), SetPIP(0, WD_RESIZEBOX_WIDTH, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_REMOVE), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_NEWGRF_SETTINGS_REMOVE, STR_NEWGRF_SETTINGS_REMOVE_TOOLTIP), + NWidget(NWID_VERTICAL), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_MOVE_UP), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_NEWGRF_SETTINGS_MOVEUP, STR_NEWGRF_SETTINGS_MOVEUP_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_MOVE_DOWN), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_NEWGRF_SETTINGS_MOVEDOWN, STR_NEWGRF_SETTINGS_MOVEDOWN_TOOLTIP), + EndContainer(), + EndContainer(), + NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPadding(0, 0, 0, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_RESCAN_FILES2), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_NEWGRF_SETTINGS_RESCAN_FILES, STR_NEWGRF_SETTINGS_RESCAN_FILES_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_CONTENT_DOWNLOAD2), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), + EndContainer(), + EndContainer(), + + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_OPEN_URL), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_NEWGRF_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_NEWGRF_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_NEWGRF_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), + EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_VIEW_PARAMETERS), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_NEWGRF_SETTINGS_SHOW_PARAMETERS, STR_NULL), EndContainer(), }; +static const NWidgetPart _nested_newgrf_infopanel_wide_widgets[] = { + /* Right side, info panel. */ + NWidget(WWT_PANEL, COLOUR_MAUVE), + NWidget(WWT_EMPTY, COLOUR_MAUVE, WID_NS_NEWGRF_INFO_TITLE), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_EMPTY, COLOUR_MAUVE, WID_NS_NEWGRF_INFO), SetFill(1, 1), SetResize(1, 1), SetMinimalSize(100, 100), + EndContainer(), +}; + /** Construct nested container widget for managing the lists and the info panel of the NewGRF GUI. */ +static bool _newgrf_display_editable = false; // Quick hack NWidgetBase* NewGRFDisplay(int *biggest_index) { - NWidgetBase *avs = MakeNWidgets(_nested_newgrf_availables_widgets, lengthof(_nested_newgrf_availables_widgets), biggest_index, NULL); + NWidgetBase *avs = _newgrf_display_editable ? + MakeNWidgets(_nested_newgrf_availables_widgets, lengthof(_nested_newgrf_availables_widgets), biggest_index, NULL) : + MakeNWidgets(_nested_newgrf_actives_wide_widgets, lengthof(_nested_newgrf_actives_wide_widgets), biggest_index, NULL); int biggest2; - NWidgetBase *acs = MakeNWidgets(_nested_newgrf_actives_widgets, lengthof(_nested_newgrf_actives_widgets), &biggest2, NULL); + NWidgetBase *acs = _newgrf_display_editable ? + MakeNWidgets(_nested_newgrf_actives_widgets, lengthof(_nested_newgrf_actives_widgets), &biggest2, NULL) : + MakeNWidgets(_nested_newgrf_buttons_wide_widgets, lengthof(_nested_newgrf_buttons_wide_widgets), &biggest2, NULL); *biggest_index = max(*biggest_index, biggest2); - NWidgetBase *inf = MakeNWidgets(_nested_newgrf_infopanel_widgets, lengthof(_nested_newgrf_infopanel_widgets), &biggest2, NULL); + NWidgetBase *inf = _newgrf_display_editable ? + MakeNWidgets(_nested_newgrf_infopanel_widgets, lengthof(_nested_newgrf_infopanel_widgets), &biggest2, NULL) : + MakeNWidgets(_nested_newgrf_infopanel_wide_widgets, lengthof(_nested_newgrf_infopanel_wide_widgets), &biggest2, NULL); *biggest_index = max(*biggest_index, biggest2); return new NWidgetNewGRFDisplay(avs, acs, inf); @@ -2001,6 +2082,7 @@ static void NewGRFConfirmationCallback(Window *w, bool confirmed) void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config) { DeleteWindowByClass(WC_GAME_OPTIONS); + _newgrf_display_editable = editable; new NewGRFWindow(&_newgrf_desc, editable, show_params, exec_changes, config); } @@ -2163,6 +2245,7 @@ static void ShowSavePresetWindow(const char *initial_text) /** Widgets for the progress window. */ static const NWidgetPart _nested_scan_progress_widgets[] = { NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_NEWGRF_SCAN_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + SetSizingType(NWST_BUTTON), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(NWID_HORIZONTAL), SetPIP(20, 0, 20), NWidget(NWID_VERTICAL), SetPIP(11, 8, 11), diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 3800af8b57..9f5eb6681e 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -165,7 +165,7 @@ static const NWidgetPart _nested_thin_news_widgets[] = { EndContainer(), EndContainer(), NWidget(WWT_EMPTY, COLOUR_WHITE, WID_N_MESSAGE), SetMinimalSize(428, 48), SetFill(1, 0), SetPadding(0, 5, 0, 5), - NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_N_VIEWPORT), SetMinimalSize(426, 70), SetPadding(1, 2, 2, 2), + NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_N_VIEWPORT), SetSizingType(NWST_VIEWPORT), SetMinimalSize(426, 70), SetPadding(1, 2, 2, 2), EndContainer(), }; @@ -187,7 +187,7 @@ static const NWidgetPart _nested_small_news_widgets[] = { /* Main part */ NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_N_HEADLINE), NWidget(WWT_INSET, COLOUR_LIGHT_BLUE, WID_N_INSET), SetPadding(2, 2, 2, 2), - NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_N_VIEWPORT), SetPadding(1, 1, 1, 1), SetMinimalSize(274, 47), SetFill(1, 0), + NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_N_VIEWPORT), SetSizingType(NWST_VIEWPORT), SetPadding(1, 1, 1, 1), SetMinimalSize(274, 47), SetFill(1, 0), EndContainer(), NWidget(WWT_EMPTY, COLOUR_WHITE, WID_N_MESSAGE), SetMinimalSize(275, 20), SetFill(1, 0), SetPadding(0, 5, 0, 5), EndContainer(), @@ -318,6 +318,7 @@ struct NewsWindow : Window { break; case WID_N_MESSAGE: + size->width = GetMinSizing(NWST_WINDOW_LENGTH, size->width); CopyInDParam(0, this->ni->params, lengthof(this->ni->params)); str = this->ni->string_id; break; @@ -1010,7 +1011,7 @@ struct MessageHistoryWindow : Window { virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { if (widget == WID_MH_BACKGROUND) { - this->line_height = FONT_HEIGHT_NORMAL + 2; + this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + 2); resize->height = this->line_height; /* Months are off-by-one, so it's actually 8. Not using @@ -1041,7 +1042,7 @@ struct MessageHistoryWindow : Window { } /* Fill the widget with news items. */ - int y = r.top + this->top_spacing; + int y = Center(r.top + this->top_spacing, this->line_height, FONT_HEIGHT_NORMAL); bool rtl = _current_text_dir == TD_RTL; uint date_left = rtl ? r.right - WD_FRAMERECT_RIGHT - this->date_width : r.left + WD_FRAMERECT_LEFT; uint date_right = rtl ? r.right - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT + this->date_width; diff --git a/src/openttd.cpp b/src/openttd.cpp index 10c31e904e..3830c6d6c1 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -69,6 +69,11 @@ #include #include "safeguards.h" +#ifdef __ANDROID__ +#include +#endif +#include +#include void CallLandscapeTick(); void IncreaseDate(); @@ -81,6 +86,8 @@ bool HandleBootstrap(); extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY); extern void ShowOSErrorBox(const char *buf, bool system); extern char *_config_file; +const char *NETWORK_SAVE_SCREENSHOT_FILE = "OpenTTD-network-save"; +const char *NETWORK_SAVE_SCREENSHOT_FILE_PNG = "OpenTTD-network-save.png"; /** * Error handling for fatal user errors. @@ -729,6 +736,16 @@ int openttd_main(int argc, char *argv[]) * just be out of the bounds of the window. */ _cursor.in_window = true; + { +#ifndef WIN32 + // Configure local font path on Android + //char curdir[PATH_MAX]; + //getcwd(curdir, sizeof(curdir)); + //setenv("FONTCONFIG_FONTS", (std::string(curdir) + "/fonts").c_str(), 1); + setenv("FONTCONFIG_FONTS", "fonts", 1); + DEBUG(misc, 1, "Set FONTCONFIG_FONTS to %s", getenv("FONTCONFIG_FONTS")); +#endif + } /* enumerate language files */ InitializeLanguagePacks(); @@ -755,7 +772,7 @@ int openttd_main(int argc, char *argv[]) GfxInitPalettes(); DEBUG(misc, 1, "Loading blitter..."); - if (blitter == NULL && _ini_blitter != NULL) blitter = stredup(_ini_blitter); + if (_ini_blitter != NULL) blitter = stredup(_ini_blitter); _blitter_autodetected = StrEmpty(blitter); /* Activate the initial blitter. * This is only some initial guess, after NewGRFs have been loaded SwitchNewGRFBlitter may switch to a different one. @@ -1162,6 +1179,24 @@ void SwitchToMode(SwitchMode new_mode) ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR); } else { DeleteWindowById(WC_SAVELOAD, 0); +#ifdef __ANDROID__ + if (_settings_client.gui.save_to_network) { + char screenshotFile[PATH_MAX] = ""; + const char* lastPart = strrchr(_file_to_saveload.name, PATHSEPCHAR); + if (!lastPart) { + lastPart = _file_to_saveload.name; + } else { + lastPart++; + } + MakeScreenshot(SC_VIEWPORT, NETWORK_SAVE_SCREENSHOT_FILE); + FioFindFullPath(screenshotFile, lastof(screenshotFile), SCREENSHOT_DIR, NETWORK_SAVE_SCREENSHOT_FILE_PNG); + uint64_t playedTime = abs(_date - DAYS_TILL(_settings_newgame.game_creation.starting_year)) * 1000; + int ret = SDL_ANDROID_CloudSave(_file_to_saveload.name, lastPart, "OpenTTD", lastPart, screenshotFile, playedTime); + if (_settings_client.gui.save_to_network == 2) { + _settings_client.gui.save_to_network = ret ? 1 : 0; + } + } +#endif } break; diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 3ca29e087a..edf5470e09 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -555,13 +555,16 @@ private: assert(type > OPOS_NONE && type < OPOS_END); static const HighLightStyle goto_place_style[OPOS_END - 1] = { - HT_RECT | HT_VEHICLE, // OPOS_GOTO + HT_RECT | HT_VEHICLE | HT_SCROLL_VIEWPORT, // OPOS_GOTO HT_NONE, // OPOS_CONDITIONAL - HT_VEHICLE, // OPOS_SHARE + HT_VEHICLE | HT_SCROLL_VIEWPORT, // OPOS_SHARE }; SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, goto_place_style[type - 1], this); this->goto_type = type; this->SetWidgetDirty(WID_O_GOTO); + if (type == OPOS_GOTO) { + MoveAllWindowsOffScreen(); + } } /** @@ -799,8 +802,8 @@ public: { switch (widget) { case WID_O_ORDER_LIST: - resize->height = FONT_HEIGHT_NORMAL; - size->height = 6 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); + size->height = 4 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; break; case WID_O_COND_VARIABLE: { @@ -1086,8 +1089,8 @@ public: int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + 3; int middle = rtl ? r.right - WD_FRAMETEXT_RIGHT - index_column_width : r.left + WD_FRAMETEXT_LEFT + index_column_width; - int y = r.top + WD_FRAMERECT_TOP; int line_height = this->GetWidget(WID_O_ORDER_LIST)->resize_y; + int y = Center(r.top + WD_FRAMERECT_TOP, line_height); int i = this->vscroll->GetPosition(); const Order *order = this->vehicle->GetOrder(i); @@ -1112,7 +1115,7 @@ public: } /* Reset counters for drawing the orders. */ - y = r.top + WD_FRAMERECT_TOP; + y = Center(r.top + WD_FRAMERECT_TOP, line_height); i = this->vscroll->GetPosition(); order = this->vehicle->GetOrder(i); } diff --git a/src/os/unix/crashlog_unix.cpp b/src/os/unix/crashlog_unix.cpp index 47de057f7e..c0663a6b06 100644 --- a/src/os/unix/crashlog_unix.cpp +++ b/src/os/unix/crashlog_unix.cpp @@ -143,7 +143,11 @@ public: }; /** The signals we want our crash handler to handle. */ +#ifdef __ANDROID__ +static const int _signals_to_handle[] = { }; // Default Android signal handler will give us stack trace +#else static const int _signals_to_handle[] = { SIGSEGV, SIGABRT, SIGFPE, SIGBUS, SIGILL }; +#endif /** * Entry point for the crash handler. diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index d7c2304ce5..71c6d51f9d 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -27,7 +27,7 @@ #ifdef __APPLE__ #include -#elif (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) || defined(__GLIBC__) +#elif ((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) || defined(__GLIBC__)) && !defined(__ANDROID__) #define HAS_STATVFS #endif @@ -65,6 +65,10 @@ ULONG __stack = (1024*1024)*2; // maybe not that much is needed actually ;) #endif #endif +#ifdef __ANDROID__ + #include "android/log.h" +#endif + #include "../../safeguards.h" bool FiosIsRoot(const char *path) @@ -244,6 +248,9 @@ void ShowInfo(const char *str) #if !defined(__APPLE__) void ShowOSErrorBox(const char *buf, bool system) { +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_FATAL, "OpenTTD", "[ERROR] %s", buf); +#endif /* All unix systems, except OSX. Only use escape codes on a TTY. */ if (isatty(fileno(stderr))) { fprintf(stderr, "\033[1;31mError: %s\033[0;39m\n", buf); @@ -258,6 +265,11 @@ void cocoaSetupAutoreleasePool(); void cocoaReleaseAutoreleasePool(); #endif +#ifdef __ANDROID__ +#define main SDL_main +extern "C" int CDECL main(int, char *[]); +#endif + int CDECL main(int argc, char *argv[]) { /* Make sure our arguments contain only valid UTF-8 characters. */ @@ -369,10 +381,23 @@ void OSOpenBrowser(const char *url) pid_t child_pid = fork(); if (child_pid != 0) return; +#ifdef __ANDROID__ + const char *args[9]; + args[0] = "/system/bin/am"; + args[1] = "start"; + args[2] = "-a"; + args[3] = "android.intent.action.VIEW"; + args[4] = "--user"; + args[5] = "0"; + args[6] = "-d"; + args[7] = url; + args[8] = NULL; +#else const char *args[3]; args[0] = "xdg-open"; args[1] = url; args[2] = NULL; +#endif execvp(args[0], const_cast(args)); DEBUG(misc, 0, "Failed to open url: %s", url); exit(0); diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp index 974e465f43..71ae041b1d 100644 --- a/src/osk_gui.cpp +++ b/src/osk_gui.cpp @@ -105,7 +105,7 @@ struct OskWindow : public Window { widget -= WID_OSK_LETTERS; DrawCharCentered(_keyboard[this->shift][widget], - r.left + 8, + (r.left + r.right) / 2, r.top + 3, TC_BLACK); } @@ -229,7 +229,8 @@ static const int INTER_KEY_SPACE = 2; // Number of pixels between two keys. */ static void AddKey(NWidgetHorizontal *hor, int height, int num_half, WidgetType widtype, int widnum, uint16 widdata, int *biggest_index) { - int key_width = HALF_KEY_WIDTH + (INTER_KEY_SPACE + HALF_KEY_WIDTH) * (num_half - 1); + int min_half_key = max(GetMinSizing(NWST_BUTTON), HALF_KEY_WIDTH); + int key_width = min_half_key + (INTER_KEY_SPACE + min_half_key) * (num_half - 1); if (widtype == NWID_SPACER) { if (!hor->IsEmpty()) key_width += INTER_KEY_SPACE; @@ -252,7 +253,7 @@ static void AddKey(NWidgetHorizontal *hor, int height, int num_half, WidgetType static NWidgetBase *MakeTopKeys(int *biggest_index) { NWidgetHorizontal *hor = new NWidgetHorizontal(); - int key_height = FONT_HEIGHT_NORMAL + 2; + int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 2); AddKey(hor, key_height, 6 * 2, WWT_TEXTBTN, WID_OSK_CANCEL, STR_BUTTON_CANCEL, biggest_index); AddKey(hor, key_height, 6 * 2, WWT_TEXTBTN, WID_OSK_OK, STR_BUTTON_OK, biggest_index); @@ -264,7 +265,7 @@ static NWidgetBase *MakeTopKeys(int *biggest_index) static NWidgetBase *MakeNumberKeys(int *biggest_index) { NWidgetHorizontal *hor = new NWidgetHorizontalLTR(); - int key_height = FONT_HEIGHT_NORMAL + 6; + int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 6); for (int widnum = WID_OSK_NUMBERS_FIRST; widnum <= WID_OSK_NUMBERS_LAST; widnum++) { AddKey(hor, key_height, 2, WWT_PUSHBTN, widnum, 0x0, biggest_index); @@ -276,7 +277,7 @@ static NWidgetBase *MakeNumberKeys(int *biggest_index) static NWidgetBase *MakeQwertyKeys(int *biggest_index) { NWidgetHorizontal *hor = new NWidgetHorizontalLTR(); - int key_height = FONT_HEIGHT_NORMAL + 6; + int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 6); AddKey(hor, key_height, 3, WWT_PUSHIMGBTN, WID_OSK_SPECIAL, SPR_OSK_SPECIAL, biggest_index); for (int widnum = WID_OSK_QWERTY_FIRST; widnum <= WID_OSK_QWERTY_LAST; widnum++) { @@ -290,7 +291,7 @@ static NWidgetBase *MakeQwertyKeys(int *biggest_index) static NWidgetBase *MakeAsdfgKeys(int *biggest_index) { NWidgetHorizontal *hor = new NWidgetHorizontalLTR(); - int key_height = FONT_HEIGHT_NORMAL + 6; + int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 6); AddKey(hor, key_height, 4, WWT_IMGBTN, WID_OSK_CAPS, SPR_OSK_CAPS, biggest_index); for (int widnum = WID_OSK_ASDFG_FIRST; widnum <= WID_OSK_ASDFG_LAST; widnum++) { @@ -303,7 +304,7 @@ static NWidgetBase *MakeAsdfgKeys(int *biggest_index) static NWidgetBase *MakeZxcvbKeys(int *biggest_index) { NWidgetHorizontal *hor = new NWidgetHorizontalLTR(); - int key_height = FONT_HEIGHT_NORMAL + 6; + int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 6); AddKey(hor, key_height, 3, WWT_IMGBTN, WID_OSK_SHIFT, SPR_OSK_SHIFT, biggest_index); for (int widnum = WID_OSK_ZXCVB_FIRST; widnum <= WID_OSK_ZXCVB_LAST; widnum++) { @@ -317,7 +318,7 @@ static NWidgetBase *MakeZxcvbKeys(int *biggest_index) static NWidgetBase *MakeSpacebarKeys(int *biggest_index) { NWidgetHorizontal *hor = new NWidgetHorizontal(); - int key_height = FONT_HEIGHT_NORMAL + 6; + int key_height = GetMinSizing(NWST_KEYBOARD, FONT_HEIGHT_NORMAL + 6); AddKey(hor, key_height, 8, NWID_SPACER, 0, 0, biggest_index); AddKey(hor, key_height, 13, WWT_PUSHTXTBTN, WID_OSK_SPACE, STR_EMPTY, biggest_index); @@ -329,7 +330,7 @@ static NWidgetBase *MakeSpacebarKeys(int *biggest_index) static const NWidgetPart _nested_osk_widgets[] = { - NWidget(WWT_CAPTION, COLOUR_GREY, WID_OSK_CAPTION), SetDataTip(STR_WHITE_STRING, STR_NULL), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_OSK_CAPTION), SetSizingType(NWST_BUTTON), SetDataTip(STR_WHITE_STRING, STR_NULL), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(WWT_EDITBOX, COLOUR_GREY, WID_OSK_TEXT), SetMinimalSize(252, 12), SetPadding(2, 2, 2, 2), EndContainer(), diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 73fe29da0d..2ff3a844a5 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -37,6 +37,7 @@ #include "station_map.h" #include "tunnelbridge_map.h" +#include "build_confirmation_func.h" #include "widgets/rail_widget.h" @@ -192,15 +193,7 @@ static void PlaceRail_Station(TileIndex tile) VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION); VpSetPlaceSizingLimit(_settings_game.station.station_spread); } else { - uint32 p1 = _cur_railtype | _railstation.orientation << 4 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24; - uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16; - - int w = _settings_client.gui.station_numtracks; - int h = _settings_client.gui.station_platlength; - if (!_railstation.orientation) Swap(w, h); - - CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" }; - ShowSelectStationIfNeeded(cmdcont, TileArea(tile, w, h)); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_STATION); } } @@ -255,22 +248,6 @@ static void GenericPlaceSignals(TileIndex tile) } } -/** - * Start placing a rail bridge. - * @param tile Position of the first tile of the bridge. - * @param w Rail toolbar window. - */ -static void PlaceRail_Bridge(TileIndex tile, Window *w) -{ - if (IsBridgeTile(tile)) { - TileIndex other_tile = GetOtherTunnelBridgeEnd(tile); - Point pt = {0, 0}; - w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, other_tile, tile); - } else { - VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE); - } -} - /** Command callback for building a tunnel */ void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) { @@ -305,12 +282,15 @@ static bool RailToolbar_CtrlChanged(Window *w) if (w->IsWidgetDisabled(WID_RAT_REMOVE)) return false; /* allow ctrl to switch remove mode only for these widgets */ + // This breaks joining rail stations functionality on Android + /* for (uint i = WID_RAT_BUILD_NS; i <= WID_RAT_BUILD_STATION; i++) { if ((i <= WID_RAT_AUTORAIL || i >= WID_RAT_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) { ToggleRailButton_Remove(w); return true; } } + */ return false; } @@ -419,6 +399,7 @@ static void HandleAutoSignalPlacement() struct BuildRailToolbarWindow : Window { RailType railtype; ///< Rail type to build. int last_user_action; ///< Last started user action. + bool last_user_action_remove; ///< Use bulldozer button with last action BuildRailToolbarWindow(WindowDesc *desc, RailType railtype) : Window(desc) { @@ -426,12 +407,14 @@ struct BuildRailToolbarWindow : Window { this->SetupRailToolbar(railtype); this->DisableWidget(WID_RAT_REMOVE); this->last_user_action = WIDGET_LIST_END; + this->last_user_action_remove = false; if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this); } ~BuildRailToolbarWindow() { + if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false); } @@ -558,7 +541,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_DEPOT: - if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT)) { + if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT | HT_SCROLL_VIEWPORT)) { ShowBuildTrainDepotPicker(this); this->last_user_action = widget; } @@ -567,7 +550,7 @@ struct BuildRailToolbarWindow : Window { case WID_RAT_BUILD_WAYPOINT: this->last_user_action = widget; _waypoint_count = StationClass::Get(STAT_CLASS_WAYP)->GetSpecCount(); - if (HandlePlacePushButton(this, WID_RAT_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, HT_RECT) && _waypoint_count > 1) { + if (HandlePlacePushButton(this, WID_RAT_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, HT_RECT | HT_SCROLL_VIEWPORT) && _waypoint_count > 1) { ShowBuildWaypointPicker(this); } break; @@ -647,9 +630,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_DEPOT: - DoCommandP(tile, _cur_railtype, _build_depot_direction, - CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT), - CcRailDepot); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); break; case WID_RAT_BUILD_WAYPOINT: @@ -665,11 +646,11 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_BRIDGE: - PlaceRail_Bridge(tile, this); + VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE); break; case WID_RAT_BUILD_TUNNEL: - DoCommandP(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_BRIDGE); break; case WID_RAT_CONVERT_RAIL: @@ -678,6 +659,7 @@ struct BuildRailToolbarWindow : Window { default: NOT_REACHED(); } + MoveAllWindowsOffScreen(); } virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) @@ -685,17 +667,38 @@ struct BuildRailToolbarWindow : Window { /* no dragging if you have pressed the convert button */ if (FindWindowById(WC_BUILD_SIGNAL, 0) != NULL && _convert_signal_button && this->IsWidgetLowered(WID_RAT_BUILD_SIGNALS)) return; + switch (this->last_user_action) { + case WID_RAT_BUILD_TUNNEL: + this->OnPlacePresize(pt, TileVirtXY(pt.x, pt.y)); + return; + default: + break; + } + VpSelectTilesWithMethod(pt.x, pt.y, select_method); } virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) { if (pt.x != -1) { + this->last_user_action_remove = _remove_button_clicked; switch (select_proc) { default: NOT_REACHED(); + case DDSP_PLACE_AUTOROAD: + assert(this->last_user_action == WID_RAT_BUILD_BRIDGE); case DDSP_BUILD_BRIDGE: - if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); - ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype); + switch (this->last_user_action) { + case WID_RAT_BUILD_TUNNEL: + if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); + else VpStartPreSizing(); + DoCommandP(end_tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel); + break; + case WID_RAT_BUILD_BRIDGE: + if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); + ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype); + break; + default: NOT_REACHED(); + } break; case DDSP_PLACE_RAIL: @@ -721,7 +724,19 @@ struct BuildRailToolbarWindow : Window { if (_remove_button_clicked) { DoCommandP(end_tile, start_tile, _ctrl_pressed ? 0 : 1, CMD_REMOVE_FROM_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION), CcPlaySound_SPLAT_RAIL); } else { - HandleStationPlacement(start_tile, end_tile); + if (!_settings_client.gui.station_dragdrop) { + uint32 p1 = _cur_railtype | _railstation.orientation << 4 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24; + uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16; + + int w = _settings_client.gui.station_numtracks; + int h = _settings_client.gui.station_platlength; + if (!_railstation.orientation) Swap(w, h); + + CommandContainer cmdcont = { end_tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" }; + ShowSelectStationIfNeeded(cmdcont, TileArea(end_tile, w, h)); + } else { + HandleStationPlacement(start_tile, end_tile); + } } } else { /* Waypoint */ @@ -737,16 +752,27 @@ struct BuildRailToolbarWindow : Window { } } break; + + case DDSP_SINGLE_TILE: + assert(end_tile == start_tile); + assert(last_user_action == WID_RAT_BUILD_DEPOT); + DoCommandP(end_tile, _cur_railtype, _build_depot_direction, + CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT), + CcRailDepot); + break; } + MoveAllHiddenWindowsBackToScreen(); } } virtual void OnPlaceObjectAbort() { + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); this->DisableWidget(WID_RAT_REMOVE); this->SetWidgetDirty(WID_RAT_REMOVE); + if (ConfirmationWindowShown() && (this->last_user_action == WID_RAT_BUILD_BRIDGE || _ctrl_pressed)) return; DeleteWindowById(WC_BUILD_SIGNAL, TRANSPORT_RAIL); DeleteWindowById(WC_BUILD_STATION, TRANSPORT_RAIL); DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_RAIL); @@ -755,10 +781,30 @@ struct BuildRailToolbarWindow : Window { DeleteWindowByClass(WC_BUILD_BRIDGE); } - virtual void OnPlacePresize(Point pt, TileIndex tile) + virtual void SelectLastTool() { - DoCommand(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL); - VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); + // User misplaced something - activate last selected tool again + if (this->last_user_action == WIDGET_LIST_END) + return; + Point dummy = {0, 0}; + this->RaiseWidget(this->last_user_action); + this->OnClick(dummy, this->last_user_action, 0); + if (this->last_user_action_remove) BuildRailClick_Remove(this); + } + + virtual void OnPlacePresize(Point pt, TileIndex tile_from) + { + TileIndex tile_to = tile_from; + + if (this->last_user_action == WID_RAT_BUILD_BRIDGE) { + tile_to = IsBridgeTile(tile_from) ? GetOtherBridgeEnd(tile_from) : TileVirtXY(pt.x, pt.y); + } else { + assert(this->last_user_action == WID_RAT_BUILD_TUNNEL); + DoCommand(tile_from, _cur_railtype | (TRANSPORT_RAIL << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL); + tile_to = _build_tunnel_endtile == 0 ? tile_from : _build_tunnel_endtile; + } + + VpSetPresizeRange(tile_from, tile_to); } virtual EventState OnCTRLStateChange() @@ -869,7 +915,7 @@ Window *ShowBuildRailToolbar(RailType railtype) if (!Company::IsValidID(_local_company)) return NULL; if (!ValParamRailtype(railtype)) return NULL; - DeleteWindowByClass(WC_BUILD_TOOLBAR); + DeleteToolbarLinkedWindows(); _cur_railtype = railtype; _remove_button_clicked = false; return new BuildRailToolbarWindow(&_build_rail_desc, railtype); @@ -1056,8 +1102,8 @@ public: d = maxdim(d, GetStringBoundingBox(StationClass::Get((StationClassID)i)->name)); } size->width = max(size->width, d.width + padding.width); - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; - size->height = 5 * this->line_height; + this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM); + size->height = 3 * this->line_height; resize->height = this->line_height; break; } @@ -1100,6 +1146,13 @@ public: fill->height = 1; resize->height = 1; break; + + case WID_BRAS_NEWST_SPACER: + size->height = 0; + if (_railstation.newstations) { + size->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); + } + break; } } @@ -1142,7 +1195,8 @@ public: for (uint i = 0; i < StationClass::GetClassCount(); i++) { if (i == STAT_CLASS_WAYP) continue; if (this->vscroll->IsVisible(statclass)) { - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, row * this->line_height + r.top + WD_MATRIX_TOP, + DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, + Center(row * this->line_height + r.top, this->line_height), StationClass::Get((StationClassID)i)->name, (StationClassID)i == _railstation.station_class ? TC_WHITE : TC_BLACK); row++; @@ -1392,12 +1446,22 @@ static const NWidgetPart _nested_station_builder_widgets[] = { NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_BRAS_NEWST_SCROLL), EndContainer(), EndContainer(), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(1, 2, 0, 2), NWidget(NWID_HORIZONTAL), + NWidget(NWID_VERTICAL), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(1, 2, 0, 2), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAS_PLATFORM_DIR_X), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 60), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAS_PLATFORM_DIR_Y), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 60), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0), + EndContainer(), + EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAS_PLATFORM_DIR_X), SetMinimalSize(66, 60), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAS_PLATFORM_DIR_Y), SetMinimalSize(66, 60), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(NWID_SPACER), SetMinimalSize(1, 0), SetFill(0, 1), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_DRAG_N_DROP), SetMinimalSize(75, 12), SetDataTip(STR_STATION_BUILD_DRAG_DROP, STR_STATION_BUILD_DRAG_DROP_TOOLTIP), + EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0), EndContainer(), NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BRAS_SHOW_NEWST_TYPE), SetMinimalSize(144, 11), SetDataTip(STR_ORANGE_STRING, STR_NULL), SetPadding(1, 2, 4, 2), @@ -1427,31 +1491,36 @@ static const NWidgetPart _nested_station_builder_widgets[] = { EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 2), NWidget(NWID_HORIZONTAL), - NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_DRAG_N_DROP), SetMinimalSize(75, 12), SetDataTip(STR_STATION_BUILD_DRAG_DROP, STR_STATION_BUILD_DRAG_DROP_TOOLTIP), - NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), - EndContainer(), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(3, 2, 0, 2), - NWidget(NWID_HORIZONTAL), - NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_HIGHLIGHT_OFF), SetMinimalSize(60, 12), - SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_HIGHLIGHT_ON), SetMinimalSize(60, 12), - SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), - NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), + NWidget(NWID_VERTICAL), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(3, 2, 0, 2), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_HIGHLIGHT_OFF), SetMinimalSize(60, 12), + SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_HIGHLIGHT_ON), SetMinimalSize(60, 12), + SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), + NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), + EndContainer(), + EndContainer(), EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 2), EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BRAS_SHOW_NEWST_MATRIX), /* We need an additional background for the matrix, as the matrix cannot handle the scrollbar due to not being an NWidgetCore. */ - NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BRAS_MATRIX_SCROLL), - NWidget(NWID_HORIZONTAL), - NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BRAS_MATRIX), SetScrollbar(WID_BRAS_MATRIX_SCROLL), SetPIP(0, 2, 0), SetPadding(2, 0, 0, 0), - NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BRAS_IMAGE), SetMinimalSize(66, 60), - SetFill(0, 0), SetResize(0, 0), SetDataTip(0x0, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(WID_BRAS_MATRIX_SCROLL), + NWidget(NWID_VERTICAL), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BRAS_MATRIX_SCROLL), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BRAS_MATRIX), SetScrollbar(WID_BRAS_MATRIX_SCROLL), SetPIP(0, 2, 0), SetPadding(2, 0, 0, 0), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BRAS_IMAGE), SetMinimalSize(66, 60), + SetFill(0, 0), SetResize(0, 0), SetDataTip(0x0, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(WID_BRAS_MATRIX_SCROLL), + EndContainer(), EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_BRAS_MATRIX_SCROLL), EndContainer(), - NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_BRAS_MATRIX_SCROLL), EndContainer(), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BRAS_NEWST_SPACER), SetDataTip(STR_EMPTY, STR_NULL), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_EMPTY, STR_NULL), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_EMPTY, STR_NULL), EndContainer(), EndContainer(), EndContainer(), @@ -1469,7 +1538,7 @@ static const NWidgetPart _nested_station_builder_widgets[] = { /** High level window description of the station-build window (default & newGRF) */ static WindowDesc _station_builder_desc( - WDP_AUTO, "build_station_rail", 350, 0, + WDP_AUTO, "build_station_rail", 0, 0, WC_BUILD_STATION, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, _nested_station_builder_widgets, lengthof(_nested_station_builder_widgets) @@ -1657,6 +1726,9 @@ static const NWidgetPart _nested_signal_builder_widgets[] = { NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_SEMAPHORE_PBS), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP), EndContainer(), SetFill(1, 1), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_SEMAPHORE_PBS_OWAY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP), EndContainer(), SetFill(1, 1), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_BS_CONVERT), SetDataTip(SPR_IMG_SIGNAL_CONVERT, STR_BUILD_SIGNAL_CONVERT_TOOLTIP), SetFill(1, 1), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BS_DRAG_SIGNALS_DENSITY_LABEL), SetDataTip(STR_ORANGE_INT, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1), + EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_NORM), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP), EndContainer(), SetFill(1, 1), @@ -1666,14 +1738,10 @@ static const NWidgetPart _nested_signal_builder_widgets[] = { NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_PBS), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP), EndContainer(), SetFill(1, 1), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_PBS_OWAY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP), EndContainer(), SetFill(1, 1), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BS_DRAG_SIGNALS_DENSITY_LABEL), SetDataTip(STR_ORANGE_INT, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1), - NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_BS_DRAG_SIGNALS_DENSITY_DECREASE), SetMinimalSize(9, 12), SetDataTip(AWV_DECREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP), - NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_BS_DRAG_SIGNALS_DENSITY_INCREASE), SetMinimalSize(9, 12), SetDataTip(AWV_INCREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP), - NWidget(NWID_SPACER), SetFill(1, 0), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_BS_DRAG_SIGNALS_DENSITY_DECREASE), SetSizingType(NWST_STEP), SetMinimalSize(9, 12), SetDataTip(AWV_DECREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_BS_DRAG_SIGNALS_DENSITY_INCREASE), SetSizingType(NWST_STEP), SetMinimalSize(9, 12), SetDataTip(AWV_INCREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP), EndContainer(), EndContainer(), EndContainer(), @@ -1745,18 +1813,18 @@ static const NWidgetPart _nested_build_depot_widgets[] = { NWidget(NWID_HORIZONTAL_LTR), NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0), NWidget(NWID_VERTICAL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_NW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_SW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP), EndContainer(), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(2, 0), NWidget(NWID_VERTICAL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_NE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAD_DEPOT_SE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP), EndContainer(), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0), diff --git a/src/rev.cpp.in b/src/rev.cpp.in index 899a565bbe..a8e1f74a0b 100644 --- a/src/rev.cpp.in +++ b/src/rev.cpp.in @@ -1,4 +1,4 @@ -/* $Id$ */ +/* $Id: rev.cpp.in 27518 2016-03-01 20:00:22Z frosch $ */ /* * This file is part of OpenTTD. diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 801d334351..4ab5091e21 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -29,6 +29,7 @@ #include "hotkeys.h" #include "road_gui.h" #include "zoom_func.h" +#include "build_confirmation_func.h" #include "widgets/road_widget.h" @@ -69,21 +70,6 @@ void CcPlaySound_SPLAT_OTHER(const CommandCost &result, TileIndex tile, uint32 p if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT_OTHER, tile); } -/** - * Callback to start placing a bridge. - * @param tile Start tile of the bridge. - */ -static void PlaceRoad_Bridge(TileIndex tile, Window *w) -{ - if (IsBridgeTile(tile)) { - TileIndex other_tile = GetOtherTunnelBridgeEnd(tile); - Point pt = {0, 0}; - w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, other_tile, tile); - } else { - VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE); - } -} - /** * Callback executed after a build road tunnel command has been called. * @@ -297,12 +283,15 @@ static bool RoadToolbar_CtrlChanged(Window *w) if (w->IsWidgetDisabled(WID_ROT_REMOVE)) return false; /* allow ctrl to switch remove mode only for these widgets */ + // This breaks joining stations functionality on Android + /* for (uint i = WID_ROT_ROAD_X; i <= WID_ROT_AUTOROAD; i++) { if (w->IsWidgetLowered(i)) { ToggleRoadButton_Remove(w); return true; } } + */ return false; } @@ -310,6 +299,8 @@ static bool RoadToolbar_CtrlChanged(Window *w) /** Road toolbar window handler. */ struct BuildRoadToolbarWindow : Window { int last_started_action; ///< Last started user action. + bool last_started_action_remove; ///< Use bulldozer button with last action + bool last_started_action_oneway; ///< Use 'one way road' button with last action BuildRoadToolbarWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc) { @@ -321,12 +312,15 @@ struct BuildRoadToolbarWindow : Window { this->OnInvalidateData(); this->last_started_action = WIDGET_LIST_END; + this->last_started_action_remove = false; + this->last_started_action_oneway = false; if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this); } ~BuildRoadToolbarWindow() { + if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false); } @@ -430,7 +424,7 @@ struct BuildRoadToolbarWindow : Window { case WID_ROT_DEPOT: if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD)) return; - if (HandlePlacePushButton(this, WID_ROT_DEPOT, SPR_CURSOR_ROAD_DEPOT, HT_RECT)) { + if (HandlePlacePushButton(this, WID_ROT_DEPOT, SPR_CURSOR_ROAD_DEPOT, HT_RECT | HT_SCROLL_VIEWPORT)) { ShowRoadDepotPicker(this); this->last_started_action = widget; } @@ -518,8 +512,7 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_DEPOT: - DoCommandP(tile, _cur_roadtype << 2 | _road_depot_orientation, 0, - CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); break; case WID_ROT_BUS_STATION: @@ -531,20 +524,21 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_BUILD_BRIDGE: - PlaceRoad_Bridge(tile, this); + VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE); break; case WID_ROT_BUILD_TUNNEL: - DoCommandP(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0, - CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_BRIDGE); break; default: NOT_REACHED(); } + MoveAllWindowsOffScreen(); } virtual void OnPlaceObjectAbort() { + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); this->SetWidgetsDisabledState(true, WID_ROT_REMOVE, @@ -553,6 +547,7 @@ struct BuildRoadToolbarWindow : Window { this->SetWidgetDirty(WID_ROT_REMOVE); this->SetWidgetDirty(WID_ROT_ONE_WAY); + if (ConfirmationWindowShown() && (this->last_started_action == WID_ROT_BUILD_BRIDGE || _ctrl_pressed)) return; DeleteWindowById(WC_BUS_STATION, TRANSPORT_ROAD); DeleteWindowById(WC_TRUCK_STATION, TRANSPORT_ROAD); DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_ROAD); @@ -560,8 +555,26 @@ struct BuildRoadToolbarWindow : Window { DeleteWindowByClass(WC_BUILD_BRIDGE); } + virtual void SelectLastTool() + { + // User misplaced something - activate last selected tool again + if (this->last_started_action == WIDGET_LIST_END) + return; + Point dummy = {0, 0}; + this->RaiseWidget(this->last_started_action); + this->OnClick(dummy, this->last_started_action, 0); + if (this->last_started_action_remove) ToggleRoadButton_Remove(this); + if (this->last_started_action_oneway) this->LowerWidget(WID_ROT_ONE_WAY); + _one_way_button_clicked = this->last_started_action_oneway; + } + virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) { + if (this->last_started_action == WID_ROT_BUILD_TUNNEL) { + this->OnPlacePresize(pt, TileVirtXY(pt.x, pt.y)); + return; + } + /* Here we update the end tile flags * of the road placement actions. * At first we reset the end halfroad @@ -593,7 +606,6 @@ struct BuildRoadToolbarWindow : Window { /* Set dir = Y */ _place_road_flag |= RF_DIR_Y; } - break; default: @@ -606,11 +618,24 @@ struct BuildRoadToolbarWindow : Window { virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) { if (pt.x != -1) { + this->last_started_action_remove = _remove_button_clicked; + this->last_started_action_oneway = _one_way_button_clicked; switch (select_proc) { default: NOT_REACHED(); case DDSP_BUILD_BRIDGE: - if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); - ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(_cur_roadtype)); + switch (last_started_action) { + case WID_ROT_BUILD_TUNNEL: + if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); + else VpStartPreSizing(); + DoCommandP(end_tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0, + CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel); + break; + case WID_ROT_BUILD_BRIDGE: + if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); + ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(_cur_roadtype)); + break; + default: NOT_REACHED(); + } break; case DDSP_DEMOLISH_AREA: @@ -651,7 +676,16 @@ struct BuildRoadToolbarWindow : Window { DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_TRUCK]), CcPlaySound_SPLAT_OTHER); break; } + + case DDSP_SINGLE_TILE: + /* Build depot. */ + assert(start_tile == end_tile); + assert(last_started_action == WID_ROT_DEPOT); + DoCommandP(start_tile, _cur_roadtype << 2 | _road_depot_orientation, 0, + CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot); + break; } + MoveAllHiddenWindowsBackToScreen(); } } @@ -807,7 +841,7 @@ Window *ShowBuildRoadToolbar(RoadType roadtype) if (!Company::IsValidID(_local_company)) return NULL; _cur_roadtype = roadtype; - DeleteWindowByClass(WC_BUILD_TOOLBAR); + DeleteToolbarLinkedWindows(); return AllocateWindowDescFront(roadtype == ROADTYPE_ROAD ? &_build_road_desc : &_build_tramway_desc, TRANSPORT_ROAD); } @@ -839,7 +873,7 @@ static const NWidgetPart _nested_build_road_scen_widgets[] = { }; static WindowDesc _build_road_scen_desc( - WDP_AUTO, "toolbar_road_scen", 0, 0, + WDP_ALIGN_TOOLBAR, "toolbar_road_scen", 0, 0, WC_SCEN_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, _nested_build_road_scen_widgets, lengthof(_nested_build_road_scen_widgets), @@ -852,6 +886,7 @@ static WindowDesc _build_road_scen_desc( */ Window *ShowBuildRoadScenToolbar() { + DeleteToolbarLinkedWindows(); _cur_roadtype = ROADTYPE_ROAD; return AllocateWindowDescFront(&_build_road_scen_desc, TRANSPORT_ROAD); } @@ -915,18 +950,18 @@ static const NWidgetPart _nested_build_road_depot_widgets[] = { NWidget(NWID_HORIZONTAL_LTR), NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0), NWidget(NWID_VERTICAL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(2, 0), NWidget(NWID_VERTICAL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0), @@ -1065,17 +1100,17 @@ static const NWidgetPart _nested_road_station_picker_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 3), NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0), NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), NWidget(NWID_SPACER), SetFill(1, 0), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 2), NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0), NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), NWidget(NWID_SPACER), SetFill(1, 0), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 1), @@ -1112,8 +1147,8 @@ static const NWidgetPart _nested_tram_station_picker_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 3), NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0), NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetSizingType(NWST_BUTTON), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), NWidget(NWID_SPACER), SetFill(1, 0), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 1), diff --git a/src/screenshot.cpp b/src/screenshot.cpp index a24cc6b211..438b816502 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -25,6 +25,7 @@ #include "window_func.h" #include "tile_map.h" #include "landscape.h" +#include "blitter/16bpp_base.hpp" #include "table/strings.h" @@ -36,7 +37,7 @@ static const char * const HEIGHTMAP_NAME = "heightmap"; ///< Default filename char _screenshot_format_name[8]; ///< Extension of the current screenshot format (corresponds with #_cur_screenshot_format). uint _num_screenshot_formats; ///< Number of available screenshot formats. uint _cur_screenshot_format; ///< Index of the currently selected screenshot format in #_screenshot_formats. -static char _screenshot_name[128]; ///< Filename of the screenshot file. +static char _screenshot_name[256]; ///< Filename of the screenshot file. char _full_screenshot_name[MAX_PATH]; ///< Pathname of the screenshot file. /** @@ -272,7 +273,8 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user png_infop info_ptr; /* only implemented for 8bit and 32bit images so far. */ - if (pixelformat != 8 && pixelformat != 32) return false; + if (pixelformat != 8 && pixelformat != 32 && pixelformat != 16) return false; + if (pixelformat == 16) bpp = 3; f = fopen(name, "wb"); if (f == NULL) return false; @@ -386,6 +388,17 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user /* render the pixels into the buffer */ callb(userdata, buff, y, w, n); y += n; + if (pixelformat == 16) { + // Convert to 24bpp + Blitter_16bppBase::Colour16 *inp = (Blitter_16bppBase::Colour16 *)buff; + uint8 *outp = (uint8 *)buff; + for (i = 1; i <= w * n; i++) { + outp[(w * n - i) * 3 ] = inp[w * n - i].r << 3; + outp[(w * n - i) * 3 + 1] = inp[w * n - i].g << 2; + outp[(w * n - i) * 3 + 2] = inp[w * n - i].b << 3; + //outp[(w * n - i) * 3] = 0xff; + } + } /* write them to png */ for (i = 0; i != n; i++) { @@ -858,7 +871,7 @@ bool MakeScreenshot(ScreenshotType t, const char *name) if (ret) { SetDParamStr(0, _screenshot_name); - ShowErrorMessage(STR_MESSAGE_SCREENSHOT_SUCCESSFULLY, INVALID_STRING_ID, WL_WARNING); + //ShowErrorMessage(STR_MESSAGE_SCREENSHOT_SUCCESSFULLY, INVALID_STRING_ID, WL_WARNING); // No need for message when we're doing cloudsave } else { ShowErrorMessage(STR_ERROR_SCREENSHOT_FAILED, INVALID_STRING_ID, WL_ERROR); } diff --git a/src/script/api/game/game_window.hpp.sq b/src/script/api/game/game_window.hpp.sq index f52de827d9..b4dfd1820c 100644 --- a/src/script/api/game/game_window.hpp.sq +++ b/src/script/api/game/game_window.hpp.sq @@ -627,8 +627,10 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_VSCROLLBAR, "WID_TF_VSCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_HSCROLLBAR, "WID_TF_HSCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_LIST_LEFT, "WID_MTS_LIST_LEFT"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_LEFT_SCROLLBAR, "WID_MTS_LEFT_SCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_PLAYLIST, "WID_MTS_PLAYLIST"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_LIST_RIGHT, "WID_MTS_LIST_RIGHT"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_RIGHT_SCROLLBAR, "WID_MTS_RIGHT_SCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_ALL, "WID_MTS_ALL"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_OLD, "WID_MTS_OLD"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_NEW, "WID_MTS_NEW"); @@ -1193,6 +1195,9 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_MESSAGES, "WID_TN_MESSAGES"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_HELP, "WID_TN_HELP"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_SWITCH_BAR, "WID_TN_SWITCH_BAR"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_CTRL, "WID_TN_CTRL"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_SHIFT, "WID_TN_SHIFT"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_DELETE, "WID_TN_DELETE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_END, "WID_TN_END"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_PAUSE, "WID_TE_PAUSE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_FAST_FORWARD, "WID_TE_FAST_FORWARD"); diff --git a/src/script/api/script_date.cpp b/src/script/api/script_date.cpp index 2f5b399633..4290a4feb5 100644 --- a/src/script/api/script_date.cpp +++ b/src/script/api/script_date.cpp @@ -9,8 +9,8 @@ /** @file script_date.cpp Implementation of ScriptDate. */ +#include "../../stdafx.h" /* Have to be included before time.h, if we want UINT32_MAX macro defined on Android */ #include -#include "../../stdafx.h" #include "script_date.hpp" #include "../../date_func.h" diff --git a/src/script/api/script_window.hpp b/src/script/api/script_window.hpp index fbdffb54b7..85f5514e94 100644 --- a/src/script/api/script_window.hpp +++ b/src/script/api/script_window.hpp @@ -135,6 +135,13 @@ public: */ WC_MAIN_TOOLBAR = ::WC_MAIN_TOOLBAR, + /** + * Main toolbar (the long bar at the top); %Window numbers: + * - 0 = #ToolbarNormalWidgets + * - 0 = #ToolbarEditorWidgets + */ + WC_MAIN_TOOLBAR_RIGHT = ::WC_MAIN_TOOLBAR_RIGHT, + /** * Statusbar (at the bottom of your screen); %Window numbers: * - 0 = #StatusbarWidgets @@ -1581,9 +1588,11 @@ public: /* automatically generated from ../../widgets/music_widget.h */ /** Widgets of the #MusicTrackSelectionWindow class. */ enum MusicTrackSelectionWidgets { - WID_MTS_LIST_LEFT = ::WID_MTS_LIST_LEFT, ///< Left button. - WID_MTS_PLAYLIST = ::WID_MTS_PLAYLIST, ///< Playlist. - WID_MTS_LIST_RIGHT = ::WID_MTS_LIST_RIGHT, ///< Right button. + WID_MTS_LIST_LEFT = ::WID_MTS_LIST_LEFT, ///< Left list. + WID_MTS_LEFT_SCROLLBAR = ::WID_MTS_LEFT_SCROLLBAR, ///< Scrollbar of left list. + WID_MTS_PLAYLIST = ::WID_MTS_PLAYLIST, ///< Playlist name. + WID_MTS_LIST_RIGHT = ::WID_MTS_LIST_RIGHT, ///< Right list. + WID_MTS_RIGHT_SCROLLBAR = ::WID_MTS_RIGHT_SCROLLBAR, ///< Scrollbar of right list. WID_MTS_ALL = ::WID_MTS_ALL, ///< All button. WID_MTS_OLD = ::WID_MTS_OLD, ///< Old button. WID_MTS_NEW = ::WID_MTS_NEW, ///< New button. @@ -2394,6 +2403,9 @@ public: WID_TN_MESSAGES = ::WID_TN_MESSAGES, ///< Messages menu. WID_TN_HELP = ::WID_TN_HELP, ///< Help menu. WID_TN_SWITCH_BAR = ::WID_TN_SWITCH_BAR, ///< Only available when toolbar has been split to switch between different subsets. + WID_TN_CTRL = ::WID_TN_CTRL, ///< On-screen Ctrl key + WID_TN_SHIFT = ::WID_TN_SHIFT, ///< On-screen Sgift key + WID_TN_DELETE = ::WID_TN_DELETE, ///< Close all windows WID_TN_END = ::WID_TN_END, ///< Helper for knowing the amount of widgets. }; diff --git a/src/settings.cpp b/src/settings.cpp index e6754bb905..a3276f83c1 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -54,6 +54,7 @@ #include "base_media_base.h" #include "gamelog.h" #include "settings_func.h" +#include "settings_gui.h" #include "ini_type.h" #include "ai/ai_config.hpp" #include "ai/ai.hpp" @@ -64,6 +65,7 @@ #include "roadveh.h" #include "fios.h" #include "strings_func.h" +#include "toolbar_gui.h" #include "void_map.h" #include "station_base.h" @@ -1077,6 +1079,16 @@ static bool ZoomMinMaxChanged(int32 p1) return true; } +static bool VerticalToolbarChanged(int32 p1) +{ + if (FindWindowByClass(WC_MAIN_TOOLBAR)) { + HideVitalWindows(); + ShowVitalWindows(); + ReInitAllWindows(); + } + return true; +} + /** * Update any possible saveload window and delete any newgrf dialogue as * its widget parts might change. Reinit all windows as it allows access to the diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 0652d1bd81..2b68f3093a 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -36,11 +36,18 @@ #include "textfile_gui.h" #include "stringfilter_type.h" #include "querystring_gui.h" +#include "fontcache.h" +#include "settings_func.h" #include #include "safeguards.h" +#ifdef __ANDROID__ +#include +#endif + +enum { MIN_BUTTON_SIZE = 10, MAX_BUTTON_SIZE = 100 }; static const StringID _driveside_dropdown[] = { STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT, @@ -113,6 +120,8 @@ static int GetCurRes() static void ShowCustCurrency(); +static void ReconstructUserInterface(); + template static DropDownList *BuiltSetDropDownList(int *selected_index) { @@ -178,6 +187,7 @@ struct GameOptionsWindow : Window { { DeleteWindowById(WC_CUSTOM_CURRENCY, 0); if (this->reload) _switch_mode = SM_MENU; + SaveToConfig(); // save all settins immediately on Android, because users tend to kill the app instead of pressing 'Quit' button } /** @@ -286,6 +296,19 @@ struct GameOptionsWindow : Window { } break; + case WID_GO_BUTTON_SIZE_DROPDOWN: // Dropdowns for size of all GUI elements and fonts + case WID_GO_TEXT_SIZE_DROPDOWN: + list = new DropDownList(); + *selected_index = (widget == WID_GO_BUTTON_SIZE_DROPDOWN) ? + _settings_client.gui.min_button : + _freetype.medium.size; + for (uint i = MIN_BUTTON_SIZE; i <= MAX_BUTTON_SIZE; i++) { + DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false); + item->SetParam(0, i); + *list->Append() = item; + } + break; + case WID_GO_GUI_ZOOM_DROPDOWN: { list = new DropDownList(); *selected_index = ZOOM_LVL_OUT_4X - _gui_zoom; @@ -324,6 +347,8 @@ struct GameOptionsWindow : Window { case WID_GO_AUTOSAVE_DROPDOWN: SetDParam(0, _autosave_dropdown[_settings_client.gui.autosave]); break; case WID_GO_LANG_DROPDOWN: SetDParamStr(0, _current_language->own_name); break; case WID_GO_RESOLUTION_DROPDOWN: SetDParam(0, GetCurRes() == _num_resolutions ? STR_GAME_OPTIONS_RESOLUTION_OTHER : SPECSTR_RESOLUTION_START + GetCurRes()); break; + case WID_GO_BUTTON_SIZE_DROPDOWN:SetDParam(0, _settings_client.gui.min_button); break; + case WID_GO_TEXT_SIZE_DROPDOWN: SetDParam(0, _freetype.medium.size); break; case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[ZOOM_LVL_OUT_4X - _gui_zoom]); break; case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name); break; case WID_GO_BASE_GRF_STATUS: SetDParam(0, BaseGraphics::GetUsedSet()->GetNumInvalid()); break; @@ -338,17 +363,17 @@ struct GameOptionsWindow : Window { switch (widget) { case WID_GO_BASE_GRF_DESCRIPTION: SetDParamStr(0, BaseGraphics::GetUsedSet()->GetDescription(GetCurrentLanguageIsoCode())); - DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_BLACK_RAW_STRING); + DrawString(r.left, r.right, r.top, STR_BLACK_RAW_STRING); break; case WID_GO_BASE_SFX_DESCRIPTION: SetDParamStr(0, BaseSounds::GetUsedSet()->GetDescription(GetCurrentLanguageIsoCode())); - DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_BLACK_RAW_STRING); + DrawString(r.left, r.right, r.top, STR_BLACK_RAW_STRING); break; case WID_GO_BASE_MUSIC_DESCRIPTION: SetDParamStr(0, BaseMusic::GetUsedSet()->GetDescription(GetCurrentLanguageIsoCode())); - DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_BLACK_RAW_STRING); + DrawString(r.left, r.right, r.top, STR_BLACK_RAW_STRING); break; } } @@ -359,7 +384,7 @@ struct GameOptionsWindow : Window { case WID_GO_BASE_GRF_DESCRIPTION: /* Find the biggest description for the default size. */ for (int i = 0; i < BaseGraphics::GetNumSets(); i++) { - SetDParamStr(0, BaseGraphics::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode())); + SetDParamStr(0, "123"); size->height = max(size->height, (uint)GetStringHeight(STR_BLACK_RAW_STRING, size->width)); } break; @@ -378,7 +403,7 @@ struct GameOptionsWindow : Window { case WID_GO_BASE_SFX_DESCRIPTION: /* Find the biggest description for the default size. */ for (int i = 0; i < BaseSounds::GetNumSets(); i++) { - SetDParamStr(0, BaseSounds::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode())); + SetDParamStr(0, "123"); size->height = max(size->height, (uint)GetStringHeight(STR_BLACK_RAW_STRING, size->width)); } break; @@ -386,7 +411,7 @@ struct GameOptionsWindow : Window { case WID_GO_BASE_MUSIC_DESCRIPTION: /* Find the biggest description for the default size. */ for (int i = 0; i < BaseMusic::GetNumSets(); i++) { - SetDParamStr(0, BaseMusic::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode())); + SetDParamStr(0, "123"); size->height = max(size->height, (uint)GetStringHeight(STR_BLACK_RAW_STRING, size->width)); } break; @@ -450,6 +475,52 @@ struct GameOptionsWindow : Window { this->SetDirty(); break; + case WID_GO_VERTICAL_TOOLBAR: + _settings_client.gui.vertical_toolbar = !_settings_client.gui.vertical_toolbar; + this->SetWidgetLoweredState(WID_GO_VERTICAL_TOOLBAR, _settings_client.gui.vertical_toolbar); + this->SetDirty(); + ReconstructUserInterface(); + break; + + case WID_GO_BUILD_CONFIRMATION: + _settings_client.gui.build_confirmation = !_settings_client.gui.build_confirmation; + this->SetWidgetLoweredState(WID_GO_BUILD_CONFIRMATION, _settings_client.gui.build_confirmation); + this->SetDirty(); + break; + + case WID_GO_8BPP_BUTTON: + if (this->IsWidgetLowered(WID_GO_8BPP_BUTTON)) break; + free(_ini_blitter); + _ini_blitter = stredup("8bpp-optimized"); + SaveToConfig(); + #ifdef __ANDROID__ + SDL_ANDROID_SetConfigOption(SDL_ANDROID_CONFIG_VIDEO_DEPTH_BPP, 16); + SDL_ANDROID_RestartMyself("restart-settings"); // We terminate here, no need to update widget state + #endif + break; + + case WID_GO_16BPP_BUTTON: + if (this->IsWidgetLowered(WID_GO_16BPP_BUTTON)) break; + free(_ini_blitter); + _ini_blitter = stredup("16bpp-simple"); + SaveToConfig(); + #ifdef __ANDROID__ + SDL_ANDROID_SetConfigOption(SDL_ANDROID_CONFIG_VIDEO_DEPTH_BPP, 16); + SDL_ANDROID_RestartMyself("restart-settings"); // We terminate here, no need to update widget state + #endif + break; + + case WID_GO_32BPP_BUTTON: + if (this->IsWidgetLowered(WID_GO_32BPP_BUTTON)) break; + free(_ini_blitter); + _ini_blitter = stredup("32bpp-anim"); + SaveToConfig(); + #ifdef __ANDROID__ + SDL_ANDROID_SetConfigOption(SDL_ANDROID_CONFIG_VIDEO_DEPTH_BPP, 24); + SDL_ANDROID_RestartMyself("restart-settings"); // We terminate here, no need to update widget state + #endif + break; + default: { int selected; DropDownList *list = this->BuildDropDownList(widget, &selected); @@ -523,15 +594,37 @@ struct GameOptionsWindow : Window { case WID_GO_RESOLUTION_DROPDOWN: // Change resolution if (index < _num_resolutions && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) { + ReconstructUserInterface(); this->SetDirty(); } break; + case WID_GO_BUTTON_SIZE_DROPDOWN: // Setup screenshot format dropdown + _settings_client.gui.min_button = index; + _settings_client.gui.min_step = index; + ReconstructUserInterface(); + break; + + case WID_GO_TEXT_SIZE_DROPDOWN: // Setup screenshot format dropdown + _freetype.medium.size = index; + _freetype.small.size = _freetype.medium.size * 10 / 12; + _freetype.large.size = _freetype.medium.size * 16 / 12; + _freetype.mono.size = _freetype.medium.size; + ReconstructUserInterface(); + break; + case WID_GO_GUI_ZOOM_DROPDOWN: GfxClearSpriteCache(); _gui_zoom = (ZoomLevel)(ZOOM_LVL_OUT_4X - index); + switch (_gui_zoom) { + case ZOOM_LVL_OUT_4X - ZOOM_LVL_NORMAL: ChangeResInGame(854, 480); break; + case ZOOM_LVL_OUT_4X - ZOOM_LVL_OUT_2X: ChangeResInGame(1280, 720); break; + case ZOOM_LVL_OUT_4X - ZOOM_LVL_OUT_4X: ChangeResInGame(1920, 1080); break; + default: break; + } UpdateCursorSize(); LoadStringWidthTable(); + ReconstructUserInterface(); break; case WID_GO_BASE_GRF_DROPDOWN: @@ -556,7 +649,12 @@ struct GameOptionsWindow : Window { virtual void OnInvalidateData(int data = 0, bool gui_scope = true) { if (!gui_scope) return; - this->SetWidgetLoweredState(WID_GO_FULLSCREEN_BUTTON, _fullscreen); + //this->SetWidgetLoweredState(WID_GO_FULLSCREEN_BUTTON, _fullscreen); + //this->SetWidgetLoweredState(WID_GO_VERTICAL_TOOLBAR, _settings_client.gui.vertical_toolbar); + this->SetWidgetLoweredState(WID_GO_BUILD_CONFIRMATION, _settings_client.gui.build_confirmation); + this->SetWidgetLoweredState(WID_GO_8BPP_BUTTON, _ini_blitter != NULL && strcmp(_ini_blitter, "8bpp-optimized") == 0); + this->SetWidgetLoweredState(WID_GO_16BPP_BUTTON, _ini_blitter == NULL || strcmp(_ini_blitter, "16bpp-simple") == 0); + this->SetWidgetLoweredState(WID_GO_32BPP_BUTTON, _ini_blitter != NULL && strcmp(_ini_blitter, "32bpp-anim") == 0); bool missing_files = BaseGraphics::GetUsedSet()->GetNumMissing() == 0; this->GetWidget(WID_GO_BASE_GRF_STATUS)->SetDataTip(missing_files ? STR_EMPTY : STR_GAME_OPTIONS_BASE_GRF_STATUS, STR_NULL); @@ -589,13 +687,22 @@ static const NWidgetPart _nested_game_options_widgets[] = { NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_RESOLUTION, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_RESOLUTION_TOOLTIP), SetFill(1, 0), SetPadding(0, 0, 3, 0), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_FULLSCREEN, STR_NULL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_FULLSCREEN_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_8BPP_BUTTON), SetMinimalSize(9, 9), SetDataTip(STR_CONFIG_SETTING_VIDEO_8BPP, STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_16BPP_BUTTON), SetMinimalSize(9, 9), SetDataTip(STR_CONFIG_SETTING_VIDEO_16BPP, STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_32BPP_BUTTON), SetMinimalSize(9, 9), SetDataTip(STR_CONFIG_SETTING_VIDEO_24BPP, STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT), EndContainer(), EndContainer(), NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GUI_ZOOM_FRAME, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_GUI_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0), EndContainer(), + NWidget(WWT_FRAME, COLOUR_GREY), + NWidget(NWID_HORIZONTAL), + //NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_CONFIG_SETTING_VERTICAL_TOOLBAR, STR_NULL), + //NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_VERTICAL_TOOLBAR), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT), + NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_CONFIG_SETTING_BUILD_CONFIRMATION, STR_NULL), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_BUILD_CONFIRMATION), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT), + EndContainer(), + EndContainer(), EndContainer(), NWidget(NWID_VERTICAL), SetPIP(0, 6, 0), @@ -608,46 +715,53 @@ static const NWidgetPart _nested_game_options_widgets[] = { NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 0), SetFill(0, 1), + NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_CONFIG_SETTING_BUTTON_SIZE, STR_NULL), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BUTTON_SIZE_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_JUST_INT, STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP), SetFill(1, 0), + EndContainer(), + NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_CONFIG_SETTING_FONT_SIZE, STR_NULL), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_TEXT_SIZE_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_JUST_INT, STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP), SetFill(1, 0), + EndContainer(), EndContainer(), - EndContainer(), - NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_GRF, STR_NULL), SetPadding(0, 10, 0, 10), - NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_GRF_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_GRF_TOOLTIP), - NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_GRF_STATUS), SetMinimalSize(150, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0), - EndContainer(), - NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_GRF_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), - EndContainer(), - EndContainer(), + NWidget(NWID_VERTICAL), SetPIP(0, 6, 0), + NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_GRF, STR_NULL), SetPadding(0, 10, 0, 10), + NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_GRF_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_GRF_TOOLTIP), + NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_GRF_STATUS), SetMinimalSize(150, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0), + EndContainer(), + NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_GRF_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), + EndContainer(), + EndContainer(), - NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_SFX, STR_NULL), SetPadding(0, 10, 0, 10), - NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_SFX_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_SFX_TOOLTIP), - NWidget(NWID_SPACER), SetFill(1, 0), - EndContainer(), - NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_SFX_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), - EndContainer(), - EndContainer(), + NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_SFX, STR_NULL), SetPadding(0, 10, 0, 10), + NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_SFX_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_SFX_TOOLTIP), + NWidget(NWID_SPACER), SetFill(1, 0), + EndContainer(), + NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_SFX_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), + EndContainer(), + EndContainer(), - NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_MUSIC, STR_NULL), SetPadding(0, 10, 0, 10), - NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_MUSIC_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP), - NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_STATUS), SetMinimalSize(150, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0), - EndContainer(), - NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), + NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_MUSIC, STR_NULL), SetPadding(0, 10, 0, 10), + NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_MUSIC_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP), + NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_STATUS), SetMinimalSize(150, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0), + EndContainer(), + NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), + EndContainer(), + EndContainer(), EndContainer(), EndContainer(), EndContainer(), @@ -1062,7 +1176,6 @@ bool SettingEntry::UpdateFilterState(SettingFilter &filter, bool force_visible) return visible; } - static const void *ResolveVariableAddress(const GameSettings *settings_ptr, const SettingDesc *sd) { if ((sd->desc.flags & SGF_PER_COMPANY) != 0) { @@ -1537,6 +1650,7 @@ static SettingsContainer &GetSettingsTree() } interface->Add(new SettingEntry("gui.autosave")); + interface->Add(new SettingEntry("gui.vertical_toolbar")); interface->Add(new SettingEntry("gui.toolbar_pos")); interface->Add(new SettingEntry("gui.statusbar_pos")); interface->Add(new SettingEntry("gui.prefer_teamchat")); @@ -1818,11 +1932,16 @@ struct GameSettingsWindow : Window { this->InvalidateData(); } + ~GameSettingsWindow() + { + SaveToConfig(); // save all settins immediately on Android, because users tend to kill the app instead of pressing 'Quit' button + } + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { switch (widget) { case WID_GS_OPTIONSPANEL: - resize->height = SETTING_HEIGHT = max(max(_circle_size.height, SETTING_BUTTON_HEIGHT), FONT_HEIGHT_NORMAL) + 1; + resize->height = SETTING_HEIGHT = GetMinSizing(NWST_STEP, max(max(_circle_size.height, SETTING_BUTTON_HEIGHT), FONT_HEIGHT_NORMAL) + 1); resize->width = 1; size->height = 5 * resize->height + SETTINGTREE_TOP_OFFSET + SETTINGTREE_BOTTOM_OFFSET; @@ -2333,10 +2452,10 @@ static const NWidgetPart _nested_settings_selection_widgets[] = { NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_CATEGORY), SetDataTip(STR_CONFIG_SETTING_RESTRICT_CATEGORY, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_RESTRICT_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_RIGHT), - NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_TYPE), SetDataTip(STR_CONFIG_SETTING_RESTRICT_TYPE, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_TYPE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), - EndContainer(), + //NWidget(NWID_HORIZONTAL), SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_RIGHT), + // NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_TYPE), SetDataTip(STR_CONFIG_SETTING_RESTRICT_TYPE, STR_NULL), + // NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_TYPE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), + //EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), SetPadding(0, 0, WD_TEXTPANEL_BOTTOM, 0), SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_RIGHT), @@ -2393,8 +2512,8 @@ void DrawArrowButtons(int x, int y, Colours button_colour, byte state, bool clic DrawFrameRect(x, y, x + dim.width - 1, y + dim.height - 1, button_colour, (state == 1) ? FR_LOWERED : FR_NONE); DrawFrameRect(x + dim.width, y, x + dim.width + dim.width - 1, y + dim.height - 1, button_colour, (state == 2) ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_LEFT, PAL_NONE, x + WD_IMGBTN_LEFT, y + WD_IMGBTN_TOP); - DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, x + WD_IMGBTN_LEFT + dim.width, y + WD_IMGBTN_TOP); + DrawSprite(SPR_ARROW_LEFT, PAL_NONE, Center(x + WD_IMGBTN_LEFT, dim.width - 1), Center(y + WD_IMGBTN_TOP, dim.height - 1)); + DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, Center(x + WD_IMGBTN_LEFT + dim.width, dim.width - 1), Center(y + WD_IMGBTN_TOP, dim.height - 1)); /* Grey out the buttons that aren't clickable */ bool rtl = _current_text_dir == TD_RTL; @@ -2419,7 +2538,7 @@ void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool cl int colour = _colour_gradient[button_colour][2]; DrawFrameRect(x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1, button_colour, state ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_DOWN, PAL_NONE, x + (SETTING_BUTTON_WIDTH - NWidgetScrollbar::GetVerticalDimension().width) / 2 + state, y + 2 + state); + DrawSpriteCentered(SPR_ARROW_DOWN, PAL_NONE, x + (SETTING_BUTTON_WIDTH - NWidgetScrollbar::GetVerticalDimension().width) + state, y + state + SETTING_BUTTON_HEIGHT / 2); if (!clickable) { GfxFillRect(x + 1, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 2, colour, FILLRECT_CHECKER); @@ -2667,3 +2786,32 @@ static void ShowCustCurrency() DeleteWindowById(WC_CUSTOM_CURRENCY, 0); new CustomCurrencyWindow(&_cust_currency_desc); } + +void ReconstructUserInterface() +{ + // Reinit all GUI elements and fonts, so they will rescale + InitFreeType(true); + CheckForMissingGlyphs(); + + DeleteAllNonVitalWindows(); + + switch (_game_mode) { + case GM_MENU: + DeleteWindowById(WC_SELECT_GAME, 0); + extern void ShowSelectGameWindow(); + ShowSelectGameWindow(); + break; + + case GM_NORMAL: + case GM_EDITOR: + HideVitalWindows(); + ShowVitalWindows(); + break; + + default: + break; + } + + ReInitAllWindows(); + ShowGameOptions(); +} diff --git a/src/settings_gui.h b/src/settings_gui.h index 05955aa557..bb2a1ecfe0 100644 --- a/src/settings_gui.h +++ b/src/settings_gui.h @@ -14,10 +14,8 @@ #include "gfx_type.h" -/** Width of setting buttons */ -#define SETTING_BUTTON_WIDTH ((int)NWidgetScrollbar::GetHorizontalDimension().width * 2) -/** Height of setting buttons */ -#define SETTING_BUTTON_HEIGHT ((int)NWidgetScrollbar::GetHorizontalDimension().height) +extern int SETTING_BUTTON_WIDTH; ///< Width of setting buttons +extern int SETTING_BUTTON_HEIGHT; ///< Height of setting buttons void DrawArrowButtons(int x, int y, Colours button_colour, byte state, bool clickable_left, bool clickable_right); void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable); diff --git a/src/settings_type.h b/src/settings_type.h index 41366a7719..be4adf58bb 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -77,6 +77,10 @@ struct GUISettings { bool lost_vehicle_warn; ///< if a vehicle can't find its destination, show a warning uint8 order_review_system; ///< perform order reviews on vehicles bool vehicle_income_warn; ///< if a vehicle isn't generating income, show a warning + bool vertical_toolbar; ///< main toolbar is split into two vertical toolbars + bool build_confirmation; ///< show confirmation dialog when building roads and stations + uint min_button; ///< min size of most button widgets + uint min_step; ///< min size of scrollbar/dropdown elements bool show_finances; ///< show finances at end of year bool sg_new_nonstop; ///< ttdpatch compatible nonstop handling read from pre v93 savegames bool new_nonstop; ///< ttdpatch compatible nonstop handling @@ -102,6 +106,7 @@ struct GUISettings { ZoomLevelByte zoom_max; ///< maximum zoom out level bool disable_unsuitable_building; ///< disable infrastructure building when no suitable vehicles are available byte autosave; ///< how often should we do autosaves? + byte save_to_network; ///< backup all savegames to network bool threaded_saves; ///< should we do threaded saves? bool keep_all_autosave; ///< name the autosave in a different way bool autosave_on_exit; ///< save an autosave when you quit the game, but do not ask "Do you really want to quit?" diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index 020ee1b6ea..1c4ad1dcc2 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -196,7 +196,7 @@ struct SignListWindow : Window, SignList { { switch (widget) { case WID_SIL_LIST: { - uint y = r.top + WD_FRAMERECT_TOP; // Offset from top of widget. + uint y = Center(r.top + WD_FRAMERECT_TOP, this->resize.step_height); // Offset from top of widget. /* No signs? */ if (this->vscroll->GetCount() == 0) { DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_STATION_LIST_NONE); @@ -267,7 +267,7 @@ struct SignListWindow : Window, SignList { case WID_SIL_LIST: { Dimension spr_dim = GetSpriteSize(SPR_COMPANY_ICON); this->text_offset = WD_FRAMETEXT_LEFT + spr_dim.width + 2; // 2 pixels space between icon and the sign text. - resize->height = max(FONT_HEIGHT_NORMAL, spr_dim.height); + resize->height = max(GetMinSizing(NWST_STEP), spr_dim.height); Dimension d = {(uint)(this->text_offset + WD_FRAMETEXT_RIGHT), WD_FRAMERECT_TOP + 5 * resize->height + WD_FRAMERECT_BOTTOM}; *size = maxdim(*size, d); break; diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index f4bcdece18..bf4850da90 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -37,7 +37,7 @@ static int _smallmap_company_count; ///< Number of entries in the owner legend. static int _smallmap_cargo_count; ///< Number of cargos in the link stats legend. /** Link stat colours shown in legenda. */ -static uint8 _linkstat_colours_in_legenda[] = {0, 1, 3, 5, 7, 9, 11}; +static uint8 _linkstat_colours_in_legenda[] = {0, 1, 3, 5, 7}; static const int NUM_NO_COMPANY_ENTRIES = 4; ///< Number of entries in the owner legend that are not companies. @@ -85,12 +85,12 @@ static LegendAndColour _legend_land_contours[] = { MC(false), MC(false), MC(false), - MC(false), MC(true), MC(false), MC(false), MC(false), MC(false), + MC(true), MC(false), MKEND() }; @@ -125,12 +125,13 @@ static const LegendAndColour _legend_vegetation[] = { MK(PC_BARE_LAND, STR_SMALLMAP_LEGENDA_BARE_LAND), MK(PC_FIELDS, STR_SMALLMAP_LEGENDA_FIELDS), MK(PC_TREES, STR_SMALLMAP_LEGENDA_TREES), - MK(PC_GREEN, STR_SMALLMAP_LEGENDA_FOREST), - MS(PC_GREY, STR_SMALLMAP_LEGENDA_ROCKS), + MS(PC_GREEN, STR_SMALLMAP_LEGENDA_FOREST), + MK(PC_GREY, STR_SMALLMAP_LEGENDA_ROCKS), MK(PC_ORANGE, STR_SMALLMAP_LEGENDA_DESERT), MK(PC_LIGHT_BLUE, STR_SMALLMAP_LEGENDA_SNOW), - MK(PC_BLACK, STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES), + + MS(PC_BLACK, STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES), MK(PC_DARK_RED, STR_SMALLMAP_LEGENDA_BUILDINGS_INDUSTRIES), MKEND() }; @@ -145,6 +146,7 @@ static LegendAndColour _legend_land_owners[NUM_NO_COMPANY_ENTRIES + MAX_COMPANIE }; #undef MK +#undef MKB #undef MC #undef MS #undef MO @@ -185,7 +187,7 @@ void BuildIndustriesLegend() _legend_from_industries[j].colour = indsp->map_colour; _legend_from_industries[j].type = ind; _legend_from_industries[j].show_on_map = true; - _legend_from_industries[j].col_break = false; + _legend_from_industries[j].col_break = j > 0 && j % lengthof(_linkstat_colours_in_legenda) == 0; _legend_from_industries[j].end = false; /* Store widget number for this industry type. */ @@ -216,6 +218,7 @@ void BuildLinkStatsLegend() _legend_linkstats[i].colour = cs->legend_colour; _legend_linkstats[i].type = cs->Index(); _legend_linkstats[i].show_on_map = true; + _legend_linkstats[i].col_break = i > 0 && i % lengthof(_linkstat_colours_in_legenda) == 0; } _legend_linkstats[i].col_break = true; @@ -312,7 +315,7 @@ void BuildLandLegend() uint delta = deltas[i][1]; int total_entries = (_settings_game.construction.max_heightlevel / delta) + 1; - int rows = CeilDiv(total_entries, 2); + int rows = lengthof(_linkstat_colours_in_legenda); int j = 0; for (i = 0; i < lengthof(_legend_land_contours) - 1 && j < total_entries; i++) { @@ -340,7 +343,7 @@ void BuildOwnerLegend() _legend_land_owners[i].colour = _colour_gradient[c->colour][5]; _legend_land_owners[i].company = c->index; _legend_land_owners[i].show_on_map = true; - _legend_land_owners[i].col_break = false; + _legend_land_owners[i].col_break = i > 0 && i % lengthof(_linkstat_colours_in_legenda) == 0; _legend_land_owners[i].end = false; _company_to_list_pos[c->index] = i; i++; @@ -1044,12 +1047,18 @@ void SmallMapWindow::SetupWidgetData() } this->GetWidget(WID_SM_LEGEND)->SetDataTip(STR_NULL, legend_tooltip); +/* this->GetWidget(WID_SM_ENABLE_ALL)->SetDataTip(STR_SMALLMAP_ENABLE_ALL, enable_all_tooltip); this->GetWidget(WID_SM_DISABLE_ALL)->SetDataTip(STR_SMALLMAP_DISABLE_ALL, disable_all_tooltip); this->GetWidget(WID_SM_SELECT_BUTTONS)->SetDisplayedPlane(plane); +*/ } -SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) : Window(desc), refresh(FORCE_REFRESH_PERIOD) +SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) : + Window(desc), + show_legend(true), + row_height(max(GetMinSizing(NWST_STEP, FONT_HEIGHT_SMALL) * 2 / 3, uint(FONT_HEIGHT_SMALL))), // Default spacing makes legend too tall - shrink it by 1/3 + refresh(FORCE_REFRESH_PERIOD) { _smallmap_industry_highlight = INVALID_INDUSTRYTYPE; this->overlay = new LinkGraphOverlay(this, WID_SM_MAP, 0, this->GetOverlayCompanyMask(), 1); @@ -1058,9 +1067,10 @@ SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) : Window(des this->RebuildColourIndexIfNecessary(); - this->SetWidgetLoweredState(WID_SM_SHOW_HEIGHT, _smallmap_show_heightmap); + //this->SetWidgetLoweredState(WID_SM_SHOW_HEIGHT, _smallmap_show_heightmap); this->SetWidgetLoweredState(WID_SM_TOGGLETOWNNAME, this->show_towns); + //this->SetWidgetLoweredState(WID_SM_SHOW_LEGEND, this->show_legend); this->SetupWidgetData(); @@ -1136,7 +1146,7 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() } } else { if (tbl->col_break) { - this->min_number_of_fixed_rows = max(this->min_number_of_fixed_rows, height); + //this->min_number_of_fixed_rows = max(this->min_number_of_fixed_rows, height); height = 0; num_columns++; } @@ -1145,7 +1155,7 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() } min_width = max(GetStringBoundingBox(str).width, min_width); } - this->min_number_of_fixed_rows = max(this->min_number_of_fixed_rows, height); + //this->min_number_of_fixed_rows = max(this->min_number_of_fixed_rows, height); this->min_number_of_columns = max(this->min_number_of_columns, num_columns); } @@ -1185,9 +1195,8 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() bool rtl = _current_text_dir == TD_RTL; uint y_org = r.top + WD_FRAMERECT_TOP; uint x = rtl ? r.right - this->column_width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT; - uint y = y_org; + uint y = Center(y_org, this->row_height, FONT_HEIGHT_SMALL); uint i = 0; // Row counter for industry legend. - uint row_height = FONT_HEIGHT_SMALL; uint text_left = rtl ? 0 : LEGEND_BLOB_WIDTH + WD_FRAMERECT_LEFT; uint text_right = this->column_width - 1 - (rtl ? LEGEND_BLOB_WIDTH + WD_FRAMERECT_RIGHT : 0); @@ -1214,7 +1223,7 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() /* Column break needed, continue at top, COLUMN_WIDTH pixels * (one "row") to the right. */ x += rtl ? -(int)this->column_width : this->column_width; - y = y_org; + y = Center(y_org, this->row_height, FONT_HEIGHT_SMALL); i = 1; } @@ -1242,7 +1251,7 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() DrawString(x + text_left, x + text_right, y, string, TC_GREY); } else { DrawString(x + text_left, x + text_right, y, string, TC_BLACK); - GfxFillRect(x + blob_left, y + 1, x + blob_right, y + row_height - 1, PC_BLACK); // Outer border of the legend colour + GfxFillRect(x + blob_left, y + 1, x + blob_right, y + FONT_HEIGHT_SMALL - 1, PC_BLACK); // Outer border of the legend colour } break; } @@ -1250,13 +1259,13 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() default: if (this->map_type == SMT_CONTOUR) SetDParam(0, tbl->height * TILE_HEIGHT_STEP); /* Anything that is not an industry or a company is using normal process */ - GfxFillRect(x + blob_left, y + 1, x + blob_right, y + row_height - 1, PC_BLACK); + GfxFillRect(x + blob_left, y + 1, x + blob_right, y + FONT_HEIGHT_SMALL - 1, PC_BLACK); DrawString(x + text_left, x + text_right, y, tbl->legend); break; } - GfxFillRect(x + blob_left + 1, y + 2, x + blob_right - 1, y + row_height - 2, legend_colour); // Legend colour + GfxFillRect(x + blob_left + 1, y + 2, x + blob_right - 1, y + FONT_HEIGHT_SMALL - 2, legend_colour); // Legend colour - y += row_height; + y += this->row_height; } } } @@ -1348,9 +1357,10 @@ void SmallMapWindow::SetOverlayCargoMask() int SmallMapWindow::GetPositionOnLegend(Point pt) { const NWidgetBase *wi = this->GetWidget(WID_SM_LEGEND); - uint line = (pt.y - wi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_SMALL; + uint line = (pt.y - wi->pos_y - WD_FRAMERECT_TOP) / this->row_height; uint columns = this->GetNumberColumnsLegend(wi->current_x); uint number_of_rows = this->GetNumberRowsLegend(columns); + number_of_rows = this->min_number_of_fixed_rows; if (line >= number_of_rows) return -1; bool rtl = _current_text_dir == TD_RTL; @@ -1394,6 +1404,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) * actually being (virtually) clicked every inputloop. */ _left_button_clicked = false; + _scrolling_viewport = true; const NWidgetBase *wid = this->GetWidget(WID_SM_MAP); Window *w = FindWindowById(WC_MAIN_WINDOW, 0); @@ -1439,6 +1450,14 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); break; + case WID_SM_SHOW_LEGEND: { + int oldHeight = this->GetLegendHeight(this->min_number_of_columns); + this->show_legend = !this->show_legend; + this->SetWidgetLoweredState(WID_SM_SHOW_LEGEND, this->show_legend); + this->ReInit(0, this->GetLegendHeight(this->min_number_of_columns) - oldHeight); + break; + } + case WID_SM_LEGEND: // Legend if (this->map_type == SMT_INDUSTRY || this->map_type == SMT_LINKSTATS || this->map_type == SMT_OWNER) { int click_pos = this->GetPositionOnLegend(pt); @@ -1657,6 +1676,14 @@ Point SmallMapWindow::GetStationMiddle(const Station *st) const return ret; } +/* virtual */ void SmallMapWindow::UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) +{ + if (widget != WID_SM_LEGEND) return; + + size->width = this->GetMinLegendWidth(); + size->height = this->GetLegendHeight(this->min_number_of_columns); +} + SmallMapWindow::SmallMapType SmallMapWindow::map_type = SMT_CONTOUR; bool SmallMapWindow::show_towns = true; int SmallMapWindow::max_heightlevel = -1; @@ -1686,8 +1713,9 @@ public: bar->SetupSmallestSize(w, init_array); this->smallmap_window = dynamic_cast(w); + assert(this->smallmap_window != NULL); - this->smallest_x = max(display->smallest_x, bar->smallest_x + smallmap_window->GetMinLegendWidth()); + this->smallest_x = max(display->smallest_x, max(bar->smallest_x, smallmap_window->GetMinLegendWidth())); this->smallest_y = display->smallest_y + max(bar->smallest_y, smallmap_window->GetLegendHeight(smallmap_window->min_number_of_columns)); this->fill_x = max(display->fill_x, bar->fill_x); this->fill_y = (display->fill_y == 0 && bar->fill_y == 0) ? 0 : min(display->fill_y, bar->fill_y); @@ -1738,7 +1766,7 @@ public: /** Widget parts of the smallmap display. */ static const NWidgetPart _nested_smallmap_display[] = { NWidget(WWT_PANEL, COLOUR_BROWN, WID_SM_MAP_BORDER), - NWidget(WWT_INSET, COLOUR_BROWN, WID_SM_MAP), SetMinimalSize(346, 140), SetResize(1, 1), SetPadding(2, 2, 2, 2), EndContainer(), + NWidget(WWT_INSET, COLOUR_BROWN, WID_SM_MAP), SetMinimalSize(140, 140), SetResize(1, 1), SetPadding(2, 2, 2, 2), EndContainer(), EndContainer(), }; @@ -1746,27 +1774,23 @@ static const NWidgetPart _nested_smallmap_display[] = { static const NWidgetPart _nested_smallmap_bar[] = { NWidget(WWT_PANEL, COLOUR_BROWN), NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SM_LEGEND), SetResize(1, 1), - NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL), /* Top button row. */ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + //NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_SHOW_LEGEND), + // SetDataTip(SPR_IMG_QUERY, STR_SMALLMAP_TOOLTIP_SHOW_LEGEND), SetFill(1, 1), NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_ZOOM_IN), SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN), SetFill(1, 1), + NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_ZOOM_OUT), + SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT), SetFill(1, 1), NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_CENTERMAP), SetDataTip(SPR_IMG_SMALLMAP, STR_SMALLMAP_CENTER), SetFill(1, 1), - NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_BLANK), - SetDataTip(SPR_DOT_SMALL, STR_NULL), SetFill(1, 1), NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_CONTOUR), SetDataTip(SPR_IMG_SHOW_COUNTOURS, STR_SMALLMAP_TOOLTIP_SHOW_LAND_CONTOURS_ON_MAP), SetFill(1, 1), NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_VEHICLES), SetDataTip(SPR_IMG_SHOW_VEHICLES, STR_SMALLMAP_TOOLTIP_SHOW_VEHICLES_ON_MAP), SetFill(1, 1), NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_INDUSTRIES), SetDataTip(SPR_IMG_INDUSTRY, STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP), SetFill(1, 1), - EndContainer(), - /* Bottom button row. */ - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_ZOOM_OUT), - SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT), SetFill(1, 1), NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_TOGGLETOWNNAME), SetDataTip(SPR_IMG_TOWN, STR_SMALLMAP_TOOLTIP_TOGGLE_TOWN_NAMES_ON_OFF), SetFill(1, 1), NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_LINKSTATS), @@ -1777,10 +1801,12 @@ static const NWidgetPart _nested_smallmap_bar[] = { SetDataTip(SPR_IMG_PLANTTREES, STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP), SetFill(1, 1), NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_OWNERS), SetDataTip(SPR_IMG_COMPANY_GENERAL, STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP), SetFill(1, 1), + NWidget(NWID_SPACER), SetResize(1, 0), SetMinimalSize(0, 1), + NWidget(WWT_RESIZEBOX, COLOUR_BROWN), EndContainer(), - NWidget(NWID_SPACER), SetResize(0, 1), EndContainer(), EndContainer(), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SM_LEGEND), SetResize(1, 1), EndContainer(), }; @@ -1804,6 +1830,7 @@ static const NWidgetPart _nested_smallmap_widgets[] = { EndContainer(), NWidgetFunction(SmallMapDisplay), // Smallmap display and legend bar + image buttons. /* Bottom button row and resize box. */ +/* NWidget(NWID_HORIZONTAL), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SM_SELECT_BUTTONS), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), @@ -1818,10 +1845,11 @@ static const NWidgetPart _nested_smallmap_widgets[] = { EndContainer(), NWidget(WWT_RESIZEBOX, COLOUR_BROWN), EndContainer(), +*/ }; static WindowDesc _smallmap_desc( - WDP_AUTO, "smallmap", 484, 314, + WDP_AUTO, "smallmap", 180, 180, WC_SMALLMAP, WC_NONE, 0, _nested_smallmap_widgets, lengthof(_nested_smallmap_widgets) diff --git a/src/smallmap_gui.h b/src/smallmap_gui.h index 2903544a69..c5eeeea21e 100644 --- a/src/smallmap_gui.h +++ b/src/smallmap_gui.h @@ -70,9 +70,11 @@ protected: static const uint FORCE_REFRESH_PERIOD = 0x1F; ///< map is redrawn after that many ticks static const uint BLINK_PERIOD = 0x0F; ///< highlight blinking interval + bool show_legend; ///< Display legend. uint min_number_of_columns; ///< Minimal number of columns in legends. uint min_number_of_fixed_rows; ///< Minimal number of rows in the legends for the fixed layouts only (all except #SMT_INDUSTRY). uint column_width; ///< Width of a column in the #WID_SM_LEGEND widget. + const uint row_height; ///< Heigth of each row in the #WID_SM_LEGEND widget. int32 scroll_x; ///< Horizontal world coordinate of the base tile left of the top-left corner of the smallmap display. int32 scroll_y; ///< Vertical world coordinate of the base tile left of the top-left corner of the smallmap display. @@ -114,7 +116,7 @@ protected: */ inline uint GetMinLegendWidth() const { - return WD_FRAMERECT_LEFT + this->min_number_of_columns * this->column_width; + return show_legend ? WD_FRAMERECT_LEFT + this->min_number_of_columns * this->column_width : 0; } /** @@ -133,8 +135,8 @@ protected: */ inline uint GetLegendHeight(uint num_columns) const { - return WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + - this->GetNumberRowsLegend(num_columns) * FONT_HEIGHT_SMALL; + return show_legend ? WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + + this->min_number_of_fixed_rows * this->row_height : 0; } /** @@ -189,6 +191,7 @@ public: virtual void OnTick(); virtual void OnScroll(Point delta); virtual void OnMouseOver(Point pt, int widget); + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize); }; #endif /* SMALLMAP_GUI_H */ diff --git a/src/sound/sdl_s.cpp b/src/sound/sdl_s.cpp index e3fb99eaa7..8c0849dfb2 100644 --- a/src/sound/sdl_s.cpp +++ b/src/sound/sdl_s.cpp @@ -23,6 +23,10 @@ /** Factory for the SDL sound driver. */ static FSoundDriver_SDL iFSoundDriver_SDL; +#ifdef __ANDROID__ +extern void Android_MidiMixMusic(Sint16 *stream, int len); +#endif + /** * Callback that fills the sound buffer. * @param userdata Ignored. @@ -32,6 +36,9 @@ static FSoundDriver_SDL iFSoundDriver_SDL; static void CDECL fill_sound_buffer(void *userdata, Uint8 *stream, int len) { MxMixSamples(stream, len / 4); +#if defined(__ANDROID__) && defined(LIBTIMIDITY) + Android_MidiMixMusic((Sint16 *)stream, len / 2); +#endif } const char *SoundDriver_SDL::Start(const char * const *parm) diff --git a/src/spritecache.cpp b/src/spritecache.cpp index 70a8834a91..16566863ca 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -419,6 +419,10 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty /* Try for 32bpp sprites first. */ sprite_avail = sprite_loader.LoadSprite(sprite, file_slot, file_pos, sprite_type, true); } + if (sprite_type != ST_MAPGEN && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 16) { + /* 32bpp sprites for 16bpp videomode. */ + sprite_avail = sprite_loader.LoadSprite(sprite, file_slot, file_pos, sprite_type, true); + } if (sprite_avail == 0) { sprite_avail = sprite_loader.LoadSprite(sprite, file_slot, file_pos, sprite_type, false); } diff --git a/src/station_base.h b/src/station_base.h index af4d206ba0..cf0ea6fc0a 100644 --- a/src/station_base.h +++ b/src/station_base.h @@ -299,6 +299,14 @@ struct GoodsEntry { FlowStatMap::const_iterator flow_it(this->flows.find(source)); return flow_it != this->flows.end() ? flow_it->second.GetVia(excluded, excluded2) : INVALID_STATION; } + + /** + * Return true if a cargo type has a rating here or if there is cargo waiting for this type. + */ + inline bool IsSourceStationForCargo() const + { + return this->HasRating() || this->cargo.TotalCount() > 0; + } }; /** All airport-related information. Only valid if tile != INVALID_TILE. */ diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 7399fe0067..4b7d0ccafc 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -104,44 +104,44 @@ void CheckRedrawStationCoverage(const Window *w) * @param type Cargo type * @param amount Cargo amount * @param rating ratings data for that particular cargo - * - * @note Each cargo-bar is 16 pixels wide and 6 pixels high - * @note Each rating 14 pixels wide and 1 pixel high and is 1 pixel below the cargo-bar */ static void StationsWndShowStationRating(int left, int right, int y, CargoID type, uint amount, byte rating) { - static const uint units_full = 576; ///< number of units to show station as 'full' - static const uint rating_full = 224; ///< rating needed so it is shown as 'full' + static const uint units_full = 1 << 9; ///< Number of units to show station as full. + static const uint rating_full = 224; ///< Rating needed so it is shown as full. const CargoSpec *cs = CargoSpec::Get(type); if (!cs->IsValid()) return; + y++; ///< Make boxes 1 pixel shorter. + int left_start = left; + int right_start = right; + int height = GetCharacterHeight(FS_SMALL) - 2; int colour = cs->rating_colour; - TextColour tc = GetContrastColour(colour); - uint w = (minu(amount, units_full) + 5) / 36; - int height = GetCharacterHeight(FS_SMALL); + /* Get width of the box to draw. */ + uint width = minu(amount, units_full) * (right - left) / units_full; - /* Draw total cargo (limited) on station (fits into 16 pixels) */ - if (w != 0) GfxFillRect(left, y, left + w - 1, y + height, colour); + /* Update the end margin, adding the width of the box not to be drawn... */ + if (width != 0) UpdateMarginsWidth(right - left - width, left_start, right_start, true); + /* ... or prepare margins in case width == 0 and amount > 0 (just one pixel bar). */ + else left_start = right_start = _current_text_dir ? right : left; - /* Draw a one pixel-wide bar of additional cargo meter, useful - * for stations with only a small amount (<=30) */ - if (w == 0) { - uint rest = amount / 5; - if (rest != 0) { - w += left; - GfxFillRect(w, y + height - rest, w, y + height, colour); - } - } + /* Draw total cargo (limited) on station */ + if (amount > 0) GfxFillRect(left_start, y, right_start, y + height, colour); - DrawString(left + 1, right, y, cs->abbrev, tc); + DrawString(left, right, y, cs->abbrev, GetContrastColour(colour), SA_CENTER); - /* Draw green/red ratings bar (fits into 14 pixels) */ + /* Draw green/red ratings bar*/ y += height + 2; - GfxFillRect(left + 1, y, left + 14, y, PC_RED); - rating = minu(rating, rating_full) / 16; - if (rating != 0) GfxFillRect(left + 1, y, left + rating, y, PC_GREEN); + left_start = left + 1; + right_start = right - 1; + if (rating != 0) { + GfxFillRect(left_start, y, right_start, y, PC_GREEN); + width = minu(rating, rating_full) * (right_start - left_start) / rating_full; + UpdateMarginsWidth(width, left_start, right_start, false); + } + GfxFillRect(left_start, y, right_start, y, PC_RED); } typedef GUIList GUIStationList; @@ -360,7 +360,7 @@ public: } case WID_STL_LIST: - resize->height = FONT_HEIGHT_NORMAL; + resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); size->height = WD_FRAMERECT_TOP + 5 * resize->height + WD_FRAMERECT_BOTTOM; break; @@ -412,7 +412,8 @@ public: case WID_STL_LIST: { bool rtl = _current_text_dir == TD_RTL; int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->stations.Length()); - int y = r.top + WD_FRAMERECT_TOP; + uint line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); + int y = Center(r.top + WD_FRAMERECT_TOP, line_height); for (int i = this->vscroll->GetPosition(); i < max; ++i) { // do until max number of stations of owner const Station *st = this->stations[i]; assert(st->xy != INVALID_TILE); @@ -424,6 +425,7 @@ public: SetDParam(0, st->index); SetDParam(1, st->facilities); int x = DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_LIST_STATION); + x += rtl ? -5 : 5; /* show cargo waiting and station ratings */ @@ -445,7 +447,8 @@ public: } } } - y += FONT_HEIGHT_NORMAL; + + y += line_height; } if (this->vscroll->GetCount() == 0) { // company has no stations @@ -497,7 +500,7 @@ public: { switch (widget) { case WID_STL_LIST: { - uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_STL_LIST, 0, FONT_HEIGHT_NORMAL); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_STL_LIST, 0, this->resize.step_height); if (id_v >= this->stations.Length()) return; // click out of list bound const Station *st = this->stations[id_v]; @@ -722,7 +725,7 @@ static const NWidgetPart _nested_company_stations_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY), SetDataTip(0x0, STR_NULL), SetResize(1, 0), SetFill(1, 1), EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_STL_SORTBY), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_STL_SORTBY), SetSizingType(NWST_STEP), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_STL_SORTDROPBTN), SetMinimalSize(163, 12), SetDataTip(STR_SORT_BY_NAME, STR_TOOLTIP_SORT_CRITERIA), // widget_data gets overwritten. NWidget(WWT_PANEL, COLOUR_GREY), SetDataTip(0x0, STR_NULL), SetResize(1, 0), SetFill(1, 1), EndContainer(), EndContainer(), @@ -763,12 +766,12 @@ static const NWidgetPart _nested_station_view_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_GREY), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_SORT_ORDER), SetMinimalSize(81, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SV_SORT_BY), SetMinimalSize(168, 12), SetResize(1, 0), SetFill(0, 1), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_SORT_ORDER), SetMinimalSize(81, 12), SetFill(0, 1), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SV_SORT_BY), SetMinimalSize(168, 12), SetResize(1, 0), SetFill(1, 1), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SV_GROUP), SetMinimalSize(81, 12), SetFill(1, 1), SetDataTip(STR_STATION_VIEW_GROUP, 0x0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SV_GROUP_BY), SetMinimalSize(168, 12), SetResize(1, 0), SetFill(0, 1), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SV_GROUP), SetMinimalSize(81, 12), SetFill(0, 1), SetDataTip(STR_STATION_VIEW_GROUP, 0x0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SV_GROUP_BY), SetMinimalSize(168, 12), SetResize(1, 0), SetFill(1, 1), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_GREY, WID_SV_WAITING), SetMinimalSize(237, 44), SetResize(1, 10), SetScrollbar(WID_SV_SCROLLBAR), EndContainer(), @@ -804,7 +807,7 @@ static const NWidgetPart _nested_station_view_widgets[] = { * @param y y coordinate * @param width the width of the view */ -static void DrawCargoIcons(CargoID i, uint waiting, int left, int right, int y) +static void DrawCargoIcons(CargoID i, uint waiting, int left, int right, int top, int y) { int width = ScaleGUITrad(10); uint num = min((waiting + (width / 2)) / width, (right - left) / width); // maximum is width / 10 icons so it won't overflow @@ -1384,6 +1387,12 @@ struct StationViewWindow : public Window { fill->width = 0; } break; + + case WID_SV_SORT_ORDER: + case WID_SV_GROUP: + *size = maxdim(GetStringBoundingBox(STR_BUTTON_SORT_BY), GetStringBoundingBox(STR_STATION_VIEW_GROUP)); + size->width += padding.width; + break; } } @@ -1733,7 +1742,7 @@ struct StationViewWindow : public Window { if (this->groupings[column] == GR_CARGO) { str = STR_STATION_VIEW_WAITING_CARGO; - DrawCargoIcons(cd->GetCargo(), cd->GetCount(), r.left + WD_FRAMERECT_LEFT + this->expand_shrink_width, r.right - WD_FRAMERECT_RIGHT - this->expand_shrink_width, y); + DrawCargoIcons(cd->GetCargo(), cd->GetCount(), r.left + WD_FRAMERECT_LEFT + this->expand_shrink_width, r.right - WD_FRAMERECT_RIGHT - this->expand_shrink_width, y, y + FONT_HEIGHT_NORMAL); } else { if (!auto_distributed) grouping = GR_SOURCE; StationID station = cd->GetStation(); @@ -2264,8 +2273,8 @@ struct SelectStationWindow : Window { d = maxdim(d, GetStringBoundingBox(T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_STATION_LIST_WAYPOINT : STR_STATION_LIST_STATION)); } - resize->height = d.height; - d.height *= 5; + resize->height = GetMinSizing(NWST_STEP, d.height); + d.height = 5 * resize->height; d.width += WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT; d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; *size = d; @@ -2275,7 +2284,7 @@ struct SelectStationWindow : Window { { if (widget != WID_JS_PANEL) return; - uint y = r.top + WD_FRAMERECT_TOP; + uint y = Center(r.top, this->resize.step_height); if (this->vscroll->GetPosition() == 0) { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT : STR_JOIN_STATION_CREATE_SPLITTED_STATION); y += this->resize.step_height; diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 25efa6bb1c..a1a79d5bb4 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -26,6 +26,7 @@ #include "statusbar_gui.h" #include "toolbar_gui.h" #include "core/geometry_func.hpp" +#include "settings_gui.h" #include "widgets/statusbar_widget.h" @@ -70,7 +71,7 @@ static bool DrawScrollingStatusText(const NewsItem *ni, int scroll_pos, int left DrawPixelInfo *old_dpi = _cur_dpi; _cur_dpi = &tmp_dpi; - DrawString(pos, INT16_MAX, 0, buffer, TC_LIGHT_BLUE, SA_LEFT | SA_FORCE); + DrawString(pos, INT16_MAX, Center(0, bottom - top), buffer, TC_LIGHT_BLUE, SA_LEFT | SA_FORCE); _cur_dpi = old_dpi; return (_current_text_dir == TD_RTL) ? (pos < right - left) : (pos + width > 0); @@ -104,27 +105,37 @@ struct StatusBarWindow : Window { virtual void FindWindowPlacementAndResize(int def_width, int def_height) { - Window::FindWindowPlacementAndResize(_toolbar_width, def_height); + Window::FindWindowPlacementAndResize(min(_toolbar_width, _screen.width - GetMinSizing(NWST_STEP) * 2), def_height); } virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { Dimension d; switch (widget) { + /* Left and right should have same sizing. */ case WID_S_LEFT: + case WID_S_RIGHT: { SetDParamMaxValue(0, MAX_YEAR * DAYS_IN_YEAR); d = GetStringBoundingBox(STR_WHITE_DATE_LONG); - break; - case WID_S_RIGHT: { int64 max_money = UINT32_MAX; const Company *c; FOR_ALL_COMPANIES(c) max_money = max(c->money, max_money); SetDParam(0, 100LL * max_money); - d = GetStringBoundingBox(STR_COMPANY_MONEY); + d = maxdim(d, GetStringBoundingBox(STR_COMPANY_MONEY)); break; } + case WID_S_MIDDLE: + d = GetStringBoundingBox(STR_STATUSBAR_AUTOSAVE); + d = maxdim(d, GetStringBoundingBox(STR_STATUSBAR_PAUSED)); + + if (Company::IsValidID(_local_company)) { + SetDParam(0, _local_company); + d = maxdim(d, GetStringBoundingBox(STR_STATUSBAR_COMPANY_NAME)); + } + break; + default: return; } @@ -136,11 +147,13 @@ struct StatusBarWindow : Window { virtual void DrawWidget(const Rect &r, int widget) const { + StringID str = INVALID_STRING_ID; + switch (widget) { case WID_S_LEFT: /* Draw the date */ SetDParam(0, _date); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER); + str = STR_WHITE_DATE_LONG; break; case WID_S_RIGHT: { @@ -148,7 +161,7 @@ struct StatusBarWindow : Window { const Company *c = Company::GetIfValid(_local_company); if (c != NULL) { SetDParam(0, c->money); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_COMPANY_MONEY, TC_FROMSTRING, SA_HOR_CENTER); + str = STR_COMPANY_MONEY; } break; } @@ -156,11 +169,11 @@ struct StatusBarWindow : Window { case WID_S_MIDDLE: /* Draw status bar */ if (this->saving) { // true when saving is active - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_SAVING_GAME, TC_FROMSTRING, SA_HOR_CENTER); + str = STR_STATUSBAR_SAVING_GAME; } else if (_do_autosave) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_AUTOSAVE, TC_FROMSTRING, SA_HOR_CENTER); + str = STR_STATUSBAR_AUTOSAVE; } else if (_pause_mode != PM_UNPAUSED) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_PAUSED, TC_FROMSTRING, SA_HOR_CENTER); + str = STR_STATUSBAR_PAUSED; } else if (this->ticker_scroll < TICKER_STOP && FindWindowById(WC_NEWS_WINDOW, 0) == NULL && _statusbar_news_item != NULL && _statusbar_news_item->string_id != 0) { /* Draw the scrolling news text */ if (!DrawScrollingStatusText(_statusbar_news_item, this->ticker_scroll, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom)) { @@ -168,23 +181,27 @@ struct StatusBarWindow : Window { if (Company::IsValidID(_local_company)) { /* This is the default text */ SetDParam(0, _local_company); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER); + str = STR_STATUSBAR_COMPANY_NAME; } } } else { if (Company::IsValidID(_local_company)) { /* This is the default text */ SetDParam(0, _local_company); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER); + str = STR_STATUSBAR_COMPANY_NAME; } } - - if (this->reminder_timeout > 0) { - Dimension icon_size = GetSpriteSize(SPR_UNREAD_NEWS); - DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, r.right - WD_FRAMERECT_RIGHT - icon_size.width, r.top + WD_FRAMERECT_TOP + (int)(FONT_HEIGHT_NORMAL - icon_size.height) / 2); - } break; } + + int center_top = Center(r.top + WD_FRAMERECT_TOP, r.bottom - r.top); + if (str != INVALID_STRING_ID) DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, center_top, str, TC_FROMSTRING, SA_HOR_CENTER); + + if (widget == WID_S_MIDDLE && this->reminder_timeout > 0) { + Dimension icon_size = GetSpriteSize(SPR_UNREAD_NEWS); + center_top = Center(r.top + WD_FRAMERECT_TOP, r.bottom - r.top, icon_size.height); + DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, r.right - WD_FRAMERECT_RIGHT - icon_size.width, center_top); + } } /** @@ -238,7 +255,7 @@ struct StatusBarWindow : Window { static const NWidgetPart _nested_main_status_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_GREY, WID_S_LEFT), SetMinimalSize(140, 12), EndContainer(), - NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_S_MIDDLE), SetMinimalSize(40, 12), SetDataTip(0x0, STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS), SetResize(1, 0), + NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_S_MIDDLE), SetMinimalSize(360, 12), SetDataTip(0x0, STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS), SetResize(1, 0), NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_S_RIGHT), SetMinimalSize(140, 12), EndContainer(), }; diff --git a/src/strings.cpp b/src/strings.cpp index 1c539d9343..7f1b60577d 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -2000,7 +2000,7 @@ const char *GetCurrentLanguageIsoCode() * @return If glyphs are missing, return \c true, else return \c false. * @post If \c true is returned and str is not NULL, *str points to a string that is found to contain at least one missing glyph. */ -bool MissingGlyphSearcher::FindMissingGlyphs(const char **str) +int MissingGlyphSearcher::FindMissingGlyphs(const char **str) { InitFreeType(this->Monospace()); const Sprite *question_mark[FS_END]; @@ -2010,6 +2010,7 @@ bool MissingGlyphSearcher::FindMissingGlyphs(const char **str) } this->Reset(); + int missing = 0; for (const char *text = this->NextString(); text != NULL; text = this->NextString()) { FontSize size = this->DefaultSize(); if (str != NULL) *str = text; @@ -2020,11 +2021,11 @@ bool MissingGlyphSearcher::FindMissingGlyphs(const char **str) size = FS_LARGE; } else if (!IsInsideMM(c, SCC_SPRITE_START, SCC_SPRITE_END) && IsPrintable(c) && !IsTextDirectionChar(c) && c != '?' && GetGlyph(size, c) == question_mark[size]) { /* The character is printable, but not in the normal font. This is the case we were testing for. */ - return true; + missing++; } } } - return false; + return missing; } /** Helper for searching through the language pack. */ diff --git a/src/strings_func.h b/src/strings_func.h index 0da711bc4d..41ecc305eb 100644 --- a/src/strings_func.h +++ b/src/strings_func.h @@ -278,7 +278,7 @@ public: */ virtual void SetFontNames(struct FreeTypeSettings *settings, const char *font_name) = 0; - bool FindMissingGlyphs(const char **str); + int FindMissingGlyphs(const char **str); }; void CheckForMissingGlyphs(bool base_font = true, MissingGlyphSearcher *search = NULL); diff --git a/src/subsidy_gui.cpp b/src/subsidy_gui.cpp index 04e5ae262b..0e7c35d0e5 100644 --- a/src/subsidy_gui.cpp +++ b/src/subsidy_gui.cpp @@ -133,6 +133,7 @@ struct SubsidyListWindow : Window { { if (widget != WID_SUL_PANEL) return; Dimension d = maxdim(GetStringBoundingBox(STR_SUBSIDIES_OFFERED_TITLE), GetStringBoundingBox(STR_SUBSIDIES_SUBSIDISED_TITLE)); + d.height = GetMinSizing(NWST_STEP, d.height); resize->height = d.height; @@ -152,12 +153,13 @@ struct SubsidyListWindow : Window { int right = r.right - WD_FRAMERECT_RIGHT; int y = r.top + WD_FRAMERECT_TOP; int x = r.left + WD_FRAMERECT_LEFT; + y = Center(y, GetMinSizing(NWST_STEP)); int pos = -this->vscroll->GetPosition(); const int cap = this->vscroll->GetCapacity(); /* Section for drawing the offered subsidies */ - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_TITLE); + if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_OFFERED_TITLE); pos++; uint num = 0; @@ -168,7 +170,7 @@ struct SubsidyListWindow : Window { /* Displays the two offered towns */ SetupSubsidyDecodeParam(s, true); SetDParam(7, _date - ymd.day + s->remaining * 32); - DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_FROM_TO); + DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_OFFERED_FROM_TO); } pos++; num++; @@ -176,13 +178,13 @@ struct SubsidyListWindow : Window { } if (num == 0) { - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE); + if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_NONE); pos++; } /* Section for drawing the already granted subsidies */ pos++; - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_TITLE); + if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_SUBSIDISED_TITLE); pos++; num = 0; @@ -194,7 +196,7 @@ struct SubsidyListWindow : Window { SetDParam(8, _date - ymd.day + s->remaining * 32); /* Displays the two connected stations */ - DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_FROM_TO); + DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_SUBSIDISED_FROM_TO); } pos++; num++; @@ -202,7 +204,7 @@ struct SubsidyListWindow : Window { } if (num == 0) { - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE); + if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * GetMinSizing(NWST_STEP), STR_SUBSIDIES_NONE); pos++; } } diff --git a/src/table/gameopt_settings.ini b/src/table/gameopt_settings.ini index 3a47c09e33..762ccaa3f2 100644 --- a/src/table/gameopt_settings.ini +++ b/src/table/gameopt_settings.ini @@ -19,6 +19,7 @@ static const char *_locale_units = "imperial|metric|si"; static const char *_town_names = "english|french|german|american|latin|silly|swedish|dutch|finnish|polish|slovak|norwegian|hungarian|austrian|romanian|czech|swiss|danish|turkish|italian|catalan"; static const char *_climates = "temperate|arctic|tropic|toyland"; static const char *_autosave_interval = "off|monthly|quarterly|half year|yearly"; +static const char *_save_to_network = "disabled|enabled|ask"; static const char *_roadsides = "left|right"; static const char *_savegame_date = "long|short|iso"; #ifdef ENABLE_NETWORK @@ -173,6 +174,15 @@ max = 4 full = _autosave_interval cat = SC_BASIC +[SDTC_OMANY] +var = gui.save_to_network +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = 2 +max = 2 +full = _save_to_network +cat = SC_BASIC + [SDT_OMANY] base = GameSettings var = vehicle.road_side diff --git a/src/table/misc_settings.ini b/src/table/misc_settings.ini index 52ca2d16ef..15c6eb733f 100644 --- a/src/table/misc_settings.ini +++ b/src/table/misc_settings.ini @@ -121,7 +121,7 @@ name = ""resolution"" type = SLE_INT length = 2 var = _cur_resolution -def = ""640,480"" +def = ""854,480"" cat = SC_BASIC [SDTG_STR] @@ -231,6 +231,25 @@ name = ""mono_aa"" var = _freetype.mono.aa def = false +[SDTG_VAR] +name = ""min_button_size"" +type = SLE_UINT +var = _settings_client.gui.min_button +def = 40 +min = 0 +max = 100 +cat = SC_EXPERT + +[SDTG_VAR] +name = ""min_step_size"" +type = SLE_UINT +var = _settings_client.gui.min_step +def = 40 +min = 0 +max = 100 +cat = SC_EXPERT + + [SDTG_VAR] name = ""sprite_cache_size_px"" type = SLE_UINT diff --git a/src/table/settings.ini b/src/table/settings.ini index 8e2aecac15..cc4c8053a9 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -41,6 +41,7 @@ static bool RedrawTownAuthority(int32 p1); static bool InvalidateCompanyInfrastructureWindow(int32 p1); static bool InvalidateCompanyWindow(int32 p1); static bool ZoomMinMaxChanged(int32 p1); +static bool VerticalToolbarChanged(int32 p1); static bool MaxVehiclesChanged(int32 p1); #ifdef ENABLE_NETWORK @@ -2521,6 +2522,15 @@ strhelp = STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT strval = STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF cat = SC_BASIC +[SDTC_OMANY] +var = gui.save_to_network +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = 2 +max = 2 +full = _save_to_network +cat = SC_BASIC + [SDTC_BOOL] var = gui.threaded_saves flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -2539,6 +2549,23 @@ str = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES strhelp = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT strval = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_LONG +[SDTC_BOOL] +var = gui.vertical_toolbar +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_VERTICAL_TOOLBAR +strhelp = STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT +proc = VerticalToolbarChanged +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.build_confirmation +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_BUILD_CONFIRMATION +strhelp = STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT +cat = SC_BASIC + [SDTC_BOOL] var = gui.show_finances flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -2563,7 +2590,7 @@ cat = SC_BASIC [SDTC_BOOL] var = gui.reverse_scroll flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -def = false +def = true str = STR_CONFIG_SETTING_REVERSE_SCROLLING strhelp = STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT cat = SC_BASIC @@ -2578,7 +2605,7 @@ strhelp = STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT [SDTC_BOOL] var = gui.left_mouse_btn_scrolling flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -def = false +def = true str = STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING strhelp = STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT cat = SC_BASIC diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 6274de8cdd..a62d149153 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -222,18 +222,22 @@ struct TerraformToolbarWindow : Window { switch (this->last_user_action) { case WID_TT_LOWER_LAND: // Lower land button VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LOWER_AND_LEVEL_AREA); + MoveAllWindowsOffScreen(); break; case WID_TT_RAISE_LAND: // Raise land button VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_RAISE_AND_LEVEL_AREA); + MoveAllWindowsOffScreen(); break; case WID_TT_LEVEL_LAND: // Level land button VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LEVEL_AREA); + MoveAllWindowsOffScreen(); break; case WID_TT_DEMOLISH: // Demolish aka dynamite button PlaceProc_DemolishArea(tile); + MoveAllWindowsOffScreen(); break; case WID_TT_BUY_LAND: // Buy land button @@ -272,14 +276,26 @@ struct TerraformToolbarWindow : Window { GUIPlaceProcDragXY(select_proc, start_tile, end_tile); break; } + MoveAllHiddenWindowsBackToScreen(); } } virtual void OnPlaceObjectAbort() { + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); } + virtual void SelectLastTool() + { + // User misplaced something - activate last selected tool again + if (this->last_user_action == WIDGET_LIST_END) + return; + Point dummy = {0, 0}; + this->RaiseWidget(this->last_user_action); + this->OnClick(dummy, this->last_user_action, 0); + } + static HotkeyList hotkeys; }; diff --git a/src/tilehighlight_func.h b/src/tilehighlight_func.h index 3edef509a2..c9c7ea809f 100644 --- a/src/tilehighlight_func.h +++ b/src/tilehighlight_func.h @@ -22,13 +22,17 @@ bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyl void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w); void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowClass window_class, WindowNumber window_num); void ResetObjectToPlace(); +void ConfirmPlacingObject(); + void VpSelectTilesWithMethod(int x, int y, ViewportPlaceMethod method); void VpStartPlaceSizing(TileIndex tile, ViewportPlaceMethod method, ViewportDragDropSelectionProcess process); +void VpStartPreSizing(); void VpSetPresizeRange(TileIndex from, TileIndex to); void VpSetPlaceSizingLimit(int limit); void UpdateTileSelection(); +void SetSelectionTilesDirty(); extern TileHighlightData _thd; diff --git a/src/tilehighlight_type.h b/src/tilehighlight_type.h index 3d64248dff..207f865a35 100644 --- a/src/tilehighlight_type.h +++ b/src/tilehighlight_type.h @@ -28,6 +28,7 @@ enum HighLightStyle { HT_RAIL = 0x080, ///< autorail (one piece), lower bits: direction HT_VEHICLE = 0x100, ///< vehicle is accepted as target as well (bitmask) HT_DIAGONAL = 0x200, ///< Also allow 'diagonal rectangles'. Only usable in combination with #HT_RECT or #HT_POINT. + HT_SCROLL_VIEWPORT = 0x400, ///< Allow scrolling viewport with left mouse button, this disables drag&drop, use only when selection cannot grow. HT_DRAG_MASK = 0x0F8, ///< Mask for the tile drag-type modes. /* lower bits (used with HT_LINE and HT_RAIL): diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index f253be8b3a..05e61160d5 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -46,6 +46,7 @@ #include "game/game.hpp" #include "goal_base.h" #include "story_base.h" +#include "tutorial_gui.h" #include "toolbar_gui.h" #include "widgets/toolbar_widget.h" @@ -64,6 +65,7 @@ RailType _last_built_railtype; RoadType _last_built_roadtype; static ScreenshotType _confirmed_screenshot_type; ///< Screenshot type the current query is about to confirm. +int _last_clicked_toolbar_idx = 0; /** Toobar modes */ enum ToolbarMode { @@ -106,9 +108,9 @@ public: { bool rtl = _current_text_dir == TD_RTL; if (this->checked) { - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK); + DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, Center(top, bottom - top), STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK); } - DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), top, this->String(), sel ? TC_WHITE : TC_BLACK); + DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), Center(top, bottom - top), this->String(), sel ? TC_WHITE : TC_BLACK); } }; @@ -142,7 +144,7 @@ public: uint Height(uint width) const { - return max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL); + return GetMinSizing(NWST_STEP, max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL)); } void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const @@ -179,7 +181,17 @@ public: */ static void PopupMainToolbMenu(Window *w, int widget, DropDownList *list, int def) { - ShowDropDownList(w, list, def, widget, 0, true, true); + if (!_settings_client.gui.vertical_toolbar) { + ShowDropDownList(w, list, def, widget, 0, true, list->Length() <= 1); + } else { + Rect wi_rect; + NWidgetCore *nwi = w->GetWidget(widget); + wi_rect.left = nwi->pos_x; + wi_rect.right = nwi->pos_x + nwi->current_x; + wi_rect.top = nwi->pos_y; + wi_rect.bottom = nwi->pos_y + nwi->current_y; + ShowDropDownListAt(w, list, def, widget, wi_rect, nwi->colour, true, list->Length() <= 1); + } if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); } @@ -332,7 +344,7 @@ static CallBackFunction ToolbarOptionsClick(Window *w) *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES)); *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS)); - ShowDropDownList(w, list, 0, WID_TN_SETTINGS, 140, true, true); + ShowDropDownList(w, list, 0, WID_TN_SETTINGS, 140, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; } @@ -868,7 +880,7 @@ static CallBackFunction ToolbarZoomOutClick(Window *w) static CallBackFunction ToolbarBuildRailClick(Window *w) { - ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, true, true); + ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; } @@ -905,7 +917,7 @@ static CallBackFunction ToolbarBuildRoadClick(Window *w) *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION, ROADTYPE_TRAM, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM)); break; } - ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, true); + ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, list->Length() <= 1); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; } @@ -1038,7 +1050,7 @@ static CallBackFunction PlaceLandBlockInfo() ResetObjectToPlace(); return CBF_NONE; } else { - SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0); + SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, HT_RECT, _settings_client.gui.vertical_toolbar ? WC_MAIN_TOOLBAR_RIGHT : WC_MAIN_TOOLBAR, 0); return CBF_PLACE_LANDINFO; } } @@ -1141,6 +1153,7 @@ static CallBackFunction MenuClickHelp(int index) { switch (index) { case 0: return PlaceLandBlockInfo(); + case 1: ShowTutorialWindow(); break; case 2: IConsoleSwitch(); break; case 3: ShowAIDebugWindow(); break; case 4: MenuClickSmallScreenshot(); break; @@ -1171,6 +1184,40 @@ static CallBackFunction ToolbarSwitchClick(Window *w) return CBF_NONE; } +static CallBackFunction ToolbarCtrlClick(Window *w) +{ + _ctrl_pressed = !_ctrl_pressed; + //DEBUG(misc, 1, "ToolbarCtrlClick: pressed %d", _ctrl_pressed); + w->SetWidgetLoweredState(WID_TN_CTRL, _ctrl_pressed); + w->SetWidgetDirty(WID_TN_CTRL); + HandleCtrlChanged(); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + return CBF_NONE; +} + +static CallBackFunction ToolbarShiftClick(Window *w) +{ + _shift_pressed = !_shift_pressed; + //DEBUG(misc, 1, "ToolbarShiftClick: pressed %d", _shift_pressed); + w->SetWidgetLoweredState(WID_TN_SHIFT, _shift_pressed); + w->SetWidgetDirty(WID_TN_SHIFT); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + return CBF_NONE; +} + +static CallBackFunction ToolbarDeleteClick(Window *w) +{ + DeleteNonVitalWindows(); + _ctrl_pressed = false; + w->SetWidgetLoweredState(WID_TN_CTRL, _ctrl_pressed); + w->SetWidgetDirty(WID_TN_CTRL); + _shift_pressed = false; + w->SetWidgetLoweredState(WID_TN_SHIFT, _shift_pressed); + w->SetWidgetDirty(WID_TN_SHIFT); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + return CBF_NONE; +} + /* --- Scenario editor specific handlers. */ /** @@ -1313,7 +1360,7 @@ protected: uint spacers; ///< Number of spacer widgets in this toolbar public: - NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL) + NWidgetToolbarContainer(WidgetType widgetType = NWID_HORIZONTAL) : NWidgetContainer(widgetType) { } @@ -1324,27 +1371,35 @@ public: */ bool IsButton(WidgetType type) const { - return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN; + return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN || type == WWT_PUSHTXTBTN || type == WWT_TEXTBTN; } void SetupSmallestSize(Window *w, bool init_array) { this->smallest_x = 0; // Biggest child this->smallest_y = 0; // Biggest child - this->fill_x = 1; - this->fill_y = 0; - this->resize_x = 1; // We only resize in this direction - this->resize_y = 0; // We never resize in this direction + this->fill_x = (type == NWID_HORIZONTAL); + this->fill_y = (type == NWID_VERTICAL); + this->resize_x = (type == NWID_HORIZONTAL); // We only resize in this direction + this->resize_y = (type == NWID_VERTICAL); // We never resize in this direction this->spacers = 0; uint nbuttons = 0; /* First initialise some variables... */ for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); - this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); + if (type == NWID_HORIZONTAL) { + this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); + } else { + this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right); + } if (this->IsButton(child_wid->type)) { nbuttons++; - this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right); + if (type == NWID_HORIZONTAL) { + this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right); + } else { + this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); + } } else if (child_wid->type == NWID_SPACER) { this->spacers++; } @@ -1352,11 +1407,25 @@ public: /* ... then in a second pass make sure the 'current' heights are set. Won't change ever. */ for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { - child_wid->current_y = this->smallest_y; - if (!this->IsButton(child_wid->type)) { - child_wid->current_x = child_wid->smallest_x; + if (type == NWID_HORIZONTAL) { + child_wid->current_y = this->smallest_y; + if (!this->IsButton(child_wid->type)) { + child_wid->current_x = child_wid->smallest_x; + } + } else { + child_wid->current_x = this->smallest_x; + if (!this->IsButton(child_wid->type)) { + child_wid->current_y = child_wid->smallest_y; + } } } + if (type == NWID_HORIZONTAL) { + //w->window_desc->default_width_trad = nbuttons * this->smallest_x; + w->window_desc->pref_width = nbuttons * this->smallest_x; + } else { + //w->window_desc->default_height_trad = nbuttons * this->smallest_y; + w->window_desc->pref_height = nbuttons * this->smallest_y; + } _toolbar_width = nbuttons * this->smallest_x; } @@ -1388,6 +1457,10 @@ public: uint position = 0; // Place to put next child relative to origin of the container. uint spacer_space = max(0, (int)given_width - (int)(button_count * this->smallest_x)); // Remaining spacing for 'spacer' widgets uint button_space = given_width - spacer_space; // Remaining spacing for the buttons + if (type == NWID_VERTICAL) { + spacer_space = max(0, (int)given_height - (int)(button_count * this->smallest_y)); + button_space = given_height - spacer_space; + } uint spacer_i = 0; uint button_i = 0; @@ -1408,12 +1481,22 @@ public: /* Buttons can be scaled, the others not. */ if (this->IsButton(child_wid->type)) { - child_wid->current_x = button_space / (button_count - button_i); - button_space -= child_wid->current_x; + if (type == NWID_HORIZONTAL) { + child_wid->current_x = button_space / (button_count - button_i); + button_space -= child_wid->current_x; + } else { + child_wid->current_y = button_space / (button_count - button_i); + button_space -= child_wid->current_y; + } button_i++; } - child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl); - position += child_wid->current_x; + if (type == NWID_HORIZONTAL) { + child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl); + position += child_wid->current_x; + } else { + child_wid->AssignSizePosition(sizing, x, y + position, this->current_x, child_wid->current_y, rtl); + position += child_wid->current_y; + } if (rtl) { cur_wid--; @@ -1784,6 +1867,54 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { } }; +/** Container for the vertical main toolbar */ +class NWidgetVerticalToolbarContainer : public NWidgetToolbarContainer { + int side; + + public: + NWidgetVerticalToolbarContainer(int side) : NWidgetToolbarContainer(NWID_VERTICAL), side(side) + { + } + + /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const + { + // TODO: replace with WID_TN_XXX + static const byte arrange_left[] = { + 32, 30, 31, 19, 20, 0, 1, 2, 3, 4, 5, 6, + }; + // Some rather artistic button arrangement, I'm proud of myself + static const byte arrange_right[] = { + 29, 21, 22, 23, 24, 25, 7, 8, 9, 12, 14, 28, + 29, 15, 16, 17, 18, 13, 7, 10, 11, 26, 27, 28, + }; + // Full-length toolbar without switch button, if enough space + static const byte arrange_left_all[] = { + 32, 30, 31, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13, + }; + static const byte arrange_right_all[] = { + 10, 11, 12, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 27, 28, + }; + + spacer_count = 0; + + if (_screen.height / this->smallest_y >= lengthof(arrange_left_all)) + { + button_count = arrangable_count = lengthof(arrange_left_all); + if (side == 0) { + return arrange_left_all; + } + return arrange_right_all; + } + + if (side == 0) { + button_count = arrangable_count = lengthof(arrange_left); + return arrange_left; + } + button_count = arrangable_count = lengthof(arrange_right) / 2; + return &arrange_right[((_toolbar_mode == TB_LOWER) ? button_count : 0)]; + } +}; + /** Container for the scenario editor's toolbar */ class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer { uint panel_widths[2]; ///< The width of the two panels (the text panel and date panel) @@ -1931,6 +2062,9 @@ static ToolbarButtonProc * const _toolbar_button_procs[] = { ToolbarNewspaperClick, ToolbarHelpClick, ToolbarSwitchClick, + ToolbarCtrlClick, + ToolbarShiftClick, + ToolbarDeleteClick, }; enum MainToolbarHotkeys { @@ -1976,7 +2110,10 @@ enum MainToolbarHotkeys { /** Main toolbar. */ struct MainToolbarWindow : Window { - MainToolbarWindow(WindowDesc *desc) : Window(desc) + int *clickedFlag; + int clickedValue; + + MainToolbarWindow(WindowDesc *desc, int *clickedFlag = NULL, int clickedValue = 0) : Window(desc), clickedFlag(clickedFlag), clickedValue(clickedValue) { this->InitNested(0); @@ -2013,11 +2150,15 @@ struct MainToolbarWindow : Window { virtual void OnClick(Point pt, int widget, int click_count) { + if (clickedFlag) + *clickedFlag = clickedValue; if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this); } virtual void OnDropdownSelect(int widget, int index) { + if (clickedFlag) + *clickedFlag = clickedValue; CallBackFunction cbf = _menu_clicked_procs[widget](index); if (cbf != CBF_NONE) _last_started_action = cbf; } @@ -2081,7 +2222,7 @@ struct MainToolbarWindow : Window { ShowLandInfo(tile); break; - default: NOT_REACHED(); + default: return; //NOT_REACHED(); } } @@ -2179,44 +2320,44 @@ static Hotkey maintoolbar_hotkeys[] = { }; HotkeyList MainToolbarWindow::hotkeys("maintoolbar", maintoolbar_hotkeys); +/** Sprites to use for the different toolbar buttons */ +static const SpriteID _toolbar_button_sprites[] = { + SPR_IMG_PAUSE, // WID_TN_PAUSE + SPR_IMG_FASTFORWARD, // WID_TN_FAST_FORWARD + SPR_IMG_SETTINGS, // WID_TN_SETTINGS + SPR_IMG_SAVE, // WID_TN_SAVE + SPR_IMG_SMALLMAP, // WID_TN_SMALL_MAP + SPR_IMG_TOWN, // WID_TN_TOWNS + SPR_IMG_SUBSIDIES, // WID_TN_SUBSIDIES + SPR_IMG_COMPANY_LIST, // WID_TN_STATIONS + SPR_IMG_COMPANY_FINANCE, // WID_TN_FINANCES + SPR_IMG_COMPANY_GENERAL, // WID_TN_COMPANIES + SPR_IMG_STORY_BOOK, // WID_TN_STORY + SPR_IMG_GOAL, // WID_TN_GOAL + SPR_IMG_GRAPHS, // WID_TN_GRAPHS + SPR_IMG_COMPANY_LEAGUE, // WID_TN_LEAGUE + SPR_IMG_INDUSTRY, // WID_TN_INDUSTRIES + SPR_IMG_TRAINLIST, // WID_TN_TRAINS + SPR_IMG_TRUCKLIST, // WID_TN_ROADVEHS + SPR_IMG_SHIPLIST, // WID_TN_SHIPS + SPR_IMG_AIRPLANESLIST, // WID_TN_AIRCRAFT + SPR_IMG_ZOOMIN, // WID_TN_ZOOMIN + SPR_IMG_ZOOMOUT, // WID_TN_ZOOMOUT + SPR_IMG_BUILDRAIL, // WID_TN_RAILS + SPR_IMG_BUILDROAD, // WID_TN_ROADS + SPR_IMG_BUILDWATER, // WID_TN_WATER + SPR_IMG_BUILDAIR, // WID_TN_AIR + SPR_IMG_LANDSCAPING, // WID_TN_LANDSCAPE + SPR_IMG_MUSIC, // WID_TN_MUSIC_SOUND + SPR_IMG_MESSAGES, // WID_TN_MESSAGES + SPR_IMG_QUERY, // WID_TN_HELP + SPR_IMG_SWITCH_TOOLBAR, // WID_TN_SWITCH_BAR +}; + static NWidgetBase *MakeMainToolbar(int *biggest_index) { - /** Sprites to use for the different toolbar buttons */ - static const SpriteID toolbar_button_sprites[] = { - SPR_IMG_PAUSE, // WID_TN_PAUSE - SPR_IMG_FASTFORWARD, // WID_TN_FAST_FORWARD - SPR_IMG_SETTINGS, // WID_TN_SETTINGS - SPR_IMG_SAVE, // WID_TN_SAVE - SPR_IMG_SMALLMAP, // WID_TN_SMALL_MAP - SPR_IMG_TOWN, // WID_TN_TOWNS - SPR_IMG_SUBSIDIES, // WID_TN_SUBSIDIES - SPR_IMG_COMPANY_LIST, // WID_TN_STATIONS - SPR_IMG_COMPANY_FINANCE, // WID_TN_FINANCES - SPR_IMG_COMPANY_GENERAL, // WID_TN_COMPANIES - SPR_IMG_STORY_BOOK, // WID_TN_STORY - SPR_IMG_GOAL, // WID_TN_GOAL - SPR_IMG_GRAPHS, // WID_TN_GRAPHS - SPR_IMG_COMPANY_LEAGUE, // WID_TN_LEAGUE - SPR_IMG_INDUSTRY, // WID_TN_INDUSTRIES - SPR_IMG_TRAINLIST, // WID_TN_TRAINS - SPR_IMG_TRUCKLIST, // WID_TN_ROADVEHS - SPR_IMG_SHIPLIST, // WID_TN_SHIPS - SPR_IMG_AIRPLANESLIST, // WID_TN_AIRCRAFT - SPR_IMG_ZOOMIN, // WID_TN_ZOOMIN - SPR_IMG_ZOOMOUT, // WID_TN_ZOOMOUT - SPR_IMG_BUILDRAIL, // WID_TN_RAILS - SPR_IMG_BUILDROAD, // WID_TN_ROADS - SPR_IMG_BUILDWATER, // WID_TN_WATER - SPR_IMG_BUILDAIR, // WID_TN_AIR - SPR_IMG_LANDSCAPING, // WID_TN_LANDSCAPE - SPR_IMG_MUSIC, // WID_TN_MUSIC_SOUND - SPR_IMG_MESSAGES, // WID_TN_MESSAGES - SPR_IMG_QUERY, // WID_TN_HELP - SPR_IMG_SWITCH_TOOLBAR, // WID_TN_SWITCH_BAR - }; - NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer(); - for (uint i = 0; i < WID_TN_END; i++) { + for (uint i = 0; i <= WID_TN_SWITCH_BAR; i++) { switch (i) { case WID_TN_SMALL_MAP: case WID_TN_FINANCES: @@ -2227,10 +2368,15 @@ static NWidgetBase *MakeMainToolbar(int *biggest_index) hor->Add(new NWidgetSpacer(0, 0)); break; } - hor->Add(new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i)); + hor->Add(new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, _toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i)); } - *biggest_index = max(*biggest_index, WID_TN_SWITCH_BAR); + hor->Add(new NWidgetSpacer(0, 0)); + hor->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_CTRL, STR_TABLET_CTRL, STR_TABLET_CTRL_TOOLTIP)); + hor->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_SHIFT, STR_TABLET_SHIFT, STR_TABLET_SHIFT_TOOLTIP)); + hor->Add(new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TN_DELETE, STR_TABLET_CLOSE, STR_TABLET_CLOSE_TOOLTIP)); + + *biggest_index = max(*biggest_index, WID_TN_DELETE); return hor; } @@ -2246,6 +2392,59 @@ static WindowDesc _toolb_normal_desc( &MainToolbarWindow::hotkeys ); +static NWidgetBase *MakeVerticalLeftToolbar(int *biggest_index) +{ + NWidgetVerticalToolbarContainer *tb = new NWidgetVerticalToolbarContainer(0); + for (uint i = 0; i <= WID_TN_SWITCH_BAR; i++) { + tb->Add(new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, _toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i)); + } + + tb->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_CTRL, STR_TABLET_CTRL, STR_TABLET_CTRL_TOOLTIP)); + tb->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_SHIFT, STR_TABLET_SHIFT, STR_TABLET_SHIFT_TOOLTIP)); + tb->Add(new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TN_DELETE, STR_TABLET_CLOSE, STR_TABLET_CLOSE_TOOLTIP)); + + *biggest_index = max(*biggest_index, WID_TN_DELETE); + return tb; +} + +static const NWidgetPart _nested_toolbar_vertical_left_widgets[] = { + NWidgetFunction(MakeVerticalLeftToolbar), +}; + +static WindowDesc _toolb_vertical_left_desc( + WDP_MANUAL, NULL, 22, 480, + WC_MAIN_TOOLBAR, WC_NONE, + WDF_NO_FOCUS, + _nested_toolbar_vertical_left_widgets, lengthof(_nested_toolbar_vertical_left_widgets), + &MainToolbarWindow::hotkeys +); + +static NWidgetBase *MakeVerticalRightToolbar(int *biggest_index) +{ + NWidgetVerticalToolbarContainer *tb = new NWidgetVerticalToolbarContainer(1); + for (uint i = 0; i <= WID_TN_SWITCH_BAR; i++) { + tb->Add(new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, _toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i)); + } + + tb->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_CTRL, STR_TABLET_CTRL, STR_TABLET_CTRL_TOOLTIP)); + tb->Add(new NWidgetLeaf(WWT_TEXTBTN, COLOUR_GREY, WID_TN_SHIFT, STR_TABLET_SHIFT, STR_TABLET_SHIFT_TOOLTIP)); + tb->Add(new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TN_DELETE, STR_TABLET_CLOSE, STR_TABLET_CLOSE_TOOLTIP)); + + *biggest_index = max(*biggest_index, WID_TN_DELETE); + return tb; +} + +static const NWidgetPart _nested_toolbar_vertical_right_widgets[] = { + NWidgetFunction(MakeVerticalRightToolbar), +}; + +static WindowDesc _toolb_vertical_right_desc( + WDP_MANUAL, NULL, 22, 480, + WC_MAIN_TOOLBAR_RIGHT, WC_NONE, + WDF_NO_FOCUS, + _nested_toolbar_vertical_right_widgets, lengthof(_nested_toolbar_vertical_right_widgets), + &MainToolbarWindow::hotkeys +); /* --- Toolbar handling for the scenario editor */ @@ -2574,6 +2773,14 @@ void AllocateToolbar() if (_game_mode == GM_EDITOR) { new ScenarioEditorToolbarWindow(&_toolb_scen_desc); } else { - new MainToolbarWindow(&_toolb_normal_desc); + if (_settings_client.gui.vertical_toolbar) { + MainToolbarWindow *w = new MainToolbarWindow(&_toolb_vertical_left_desc, &_last_clicked_toolbar_idx, 0); + w->left = 0; + w = new MainToolbarWindow(&_toolb_vertical_right_desc, &_last_clicked_toolbar_idx, 1); + w->left = _screen.width - w->width; + SetDirtyBlocks(0, w->top, _screen.width, w->top + w->height); + } else { + new MainToolbarWindow(&_toolb_normal_desc); + } } } diff --git a/src/toolbar_gui.h b/src/toolbar_gui.h index 37fc8f0e9f..69cb3bba6d 100644 --- a/src/toolbar_gui.h +++ b/src/toolbar_gui.h @@ -16,6 +16,7 @@ void AllocateToolbar(); void ToggleBoundingBoxes(); void ToggleDirtyBlocks(); +extern int _last_clicked_toolbar_idx; extern uint _toolbar_width; #endif /* TOOLBAR_GUI_H */ diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 142966b694..26107d76c9 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -49,12 +49,12 @@ static const NWidgetPart _nested_town_authority_widgets[] = { NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN), NWidget(WWT_STICKYBOX, COLOUR_BROWN), EndContainer(), - NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_RATING_INFO), SetMinimalSize(317, 92), SetResize(1, 1), EndContainer(), + NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_RATING_INFO), SetMinimalSize(317, 92), SetResize(1, 1), SetFill(1, 1), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_COMMAND_LIST), SetMinimalSize(305, 52), SetResize(1, 0), SetDataTip(0x0, STR_LOCAL_AUTHORITY_ACTIONS_TOOLTIP), SetScrollbar(WID_TA_SCROLLBAR), EndContainer(), NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_TA_SCROLLBAR), EndContainer(), - NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_ACTION_INFO), SetMinimalSize(317, 52), SetResize(1, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_ACTION_INFO), SetMinimalSize(317, 52), SetResize(1, 1), SetFill(1, 1), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TA_EXECUTE), SetMinimalSize(317, 12), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_LOCAL_AUTHORITY_DO_IT_BUTTON, STR_LOCAL_AUTHORITY_DO_IT_TOOLTIP), NWidget(WWT_RESIZEBOX, COLOUR_BROWN), @@ -67,6 +67,7 @@ private: Town *town; ///< Town being displayed. int sel_index; ///< Currently selected town action, \c 0 to \c TACT_COUNT-1, \c -1 means no action selected. Scrollbar *vscroll; + uint actions_step; uint displayed_actions_on_previous_painting; ///< Actions that were available on the previous call to OnPaint() /** @@ -96,7 +97,8 @@ public: this->town = Town::Get(window_number); this->InitNested(window_number); this->vscroll = this->GetScrollbar(WID_TA_SCROLLBAR); - this->vscroll->SetCapacity((this->GetWidget(WID_TA_COMMAND_LIST)->current_y - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM) / FONT_HEIGHT_NORMAL); + this->actions_step = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); + this->vscroll->SetCapacity((this->GetWidget(WID_TA_COMMAND_LIST)->current_y - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM) / this->actions_step); } virtual void OnPaint() @@ -199,12 +201,12 @@ public: case WID_TA_COMMAND_LIST: { int numact; uint buttons = GetMaskOfTownActions(&numact, _local_company, this->town); - int y = r.top + WD_FRAMERECT_TOP; + int y = Center(r.top, this->actions_step); int pos = this->vscroll->GetPosition(); if (--pos < 0) { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_LOCAL_AUTHORITY_ACTIONS_TITLE); - y += FONT_HEIGHT_NORMAL; + y += this->actions_step; } for (int i = 0; buttons; i++, buttons >>= 1) { @@ -213,7 +215,7 @@ public: if ((buttons & 1) && --pos < 0) { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i, this->sel_index == i ? TC_WHITE : TC_ORANGE); - y += FONT_HEIGHT_NORMAL; + y += this->actions_step; } } break; @@ -240,7 +242,8 @@ public: } case WID_TA_COMMAND_LIST: - size->height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM; + resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); + size->height = WD_FRAMERECT_TOP + 3 * resize->height + WD_FRAMERECT_BOTTOM; size->width = GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTIONS_TITLE).width; for (uint i = 0; i < TACT_COUNT; i++ ) { size->width = max(size->width, GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i).width); @@ -259,7 +262,7 @@ public: { switch (widget) { case WID_TA_COMMAND_LIST: { - int y = this->GetRowFromWidget(pt.y, WID_TA_COMMAND_LIST, 1, FONT_HEIGHT_NORMAL); + int y = this->GetRowFromWidget(pt.y, WID_TA_COMMAND_LIST, 1, this->actions_step); if (!IsInsideMM(y, 0, 5)) return; y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_company, this->town), y + this->vscroll->GetPosition() - 1); @@ -613,7 +616,7 @@ static const NWidgetPart _nested_town_directory_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TD_SORT_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), + NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TD_SORT_ORDER), SetSizingType(NWST_STEP), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_TD_SORT_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(), EndContainer(), @@ -825,7 +828,7 @@ public: } Dimension icon_size = GetSpriteSize(SPR_TOWN_RATING_GOOD); d.width += icon_size.width + 2; - d.height = max(d.height, icon_size.height); + d.height = GetMinSizing(NWST_STEP, max(d.height, icon_size.height)); resize->height = d.height; d.height *= 5; d.width += padding.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; @@ -977,61 +980,65 @@ static const NWidgetPart _nested_found_town_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), EndContainer(), /* Construct new town(s) buttons. */ - NWidget(WWT_PANEL, COLOUR_DARK_GREEN), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_NEW_TOWN), SetMinimalSize(156, 12), SetFill(1, 0), - SetDataTip(STR_FOUND_TOWN_NEW_TOWN_BUTTON, STR_FOUND_TOWN_NEW_TOWN_TOOLTIP), SetPadding(0, 2, 1, 2), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_RANDOM_TOWN), SetMinimalSize(156, 12), SetFill(1, 0), - SetDataTip(STR_FOUND_TOWN_RANDOM_TOWN_BUTTON, STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP), SetPadding(0, 2, 1, 2), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_MANY_RANDOM_TOWNS), SetMinimalSize(156, 12), SetFill(1, 0), - SetDataTip(STR_FOUND_TOWN_MANY_RANDOM_TOWNS, STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP), SetPadding(0, 2, 0, 2), - /* Town name selection. */ - NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(156, 14), SetPadding(0, 2, 0, 2), SetDataTip(STR_FOUND_TOWN_NAME_TITLE, STR_NULL), - NWidget(WWT_EDITBOX, COLOUR_GREY, WID_TF_TOWN_NAME_EDITBOX), SetMinimalSize(156, 12), SetPadding(0, 2, 3, 2), - SetDataTip(STR_FOUND_TOWN_NAME_EDITOR_TITLE, STR_FOUND_TOWN_NAME_EDITOR_HELP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_TOWN_NAME_RANDOM), SetMinimalSize(78, 12), SetPadding(0, 2, 0, 2), SetFill(1, 0), - SetDataTip(STR_FOUND_TOWN_NAME_RANDOM_BUTTON, STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP), - /* Town size selection. */ - NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_TITLE, STR_NULL), - NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), + NWidget(NWID_SPACER), SetMinimalSize(0, 2), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_NEW_TOWN), SetMinimalSize(156, 12), SetFill(1, 0), + SetDataTip(STR_FOUND_TOWN_NEW_TOWN_BUTTON, STR_FOUND_TOWN_NEW_TOWN_TOOLTIP), SetPadding(0, 2, 1, 2), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_RANDOM_TOWN), SetMinimalSize(156, 12), SetFill(1, 0), + SetDataTip(STR_FOUND_TOWN_RANDOM_TOWN_BUTTON, STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP), SetPadding(0, 2, 1, 2), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_MANY_RANDOM_TOWNS), SetMinimalSize(156, 12), SetFill(1, 0), + SetDataTip(STR_FOUND_TOWN_MANY_RANDOM_TOWNS, STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP), SetPadding(0, 2, 0, 2), + /* Town name selection. */ + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(156, 14), SetPadding(0, 2, 0, 2), SetDataTip(STR_FOUND_TOWN_NAME_TITLE, STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_TF_TOWN_NAME_EDITBOX), SetMinimalSize(156, 12), SetPadding(0, 2, 3, 2), + SetDataTip(STR_FOUND_TOWN_NAME_EDITOR_TITLE, STR_FOUND_TOWN_NAME_EDITOR_HELP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_TOWN_NAME_RANDOM), SetMinimalSize(78, 12), SetPadding(0, 2, 0, 2), SetFill(1, 0), + SetDataTip(STR_FOUND_TOWN_NAME_RANDOM_BUTTON, STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP), + /* Town size selection. */ + NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), + NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_TITLE, STR_NULL), + NWidget(NWID_SPACER), SetFill(1, 0), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_SMALL), SetMinimalSize(78, 12), SetFill(1, 0), + SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_SMALL_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_MEDIUM), SetMinimalSize(78, 12), SetFill(1, 0), + SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_MEDIUM_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 1), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_LARGE), SetMinimalSize(78, 12), SetFill(1, 0), + SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_LARGE_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_RANDOM), SetMinimalSize(78, 12), SetFill(1, 0), + SetDataTip(STR_FOUND_TOWN_SIZE_RANDOM, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 3), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_CITY), SetPadding(0, 2, 0, 2), SetMinimalSize(156, 12), SetFill(1, 0), + SetDataTip(STR_FOUND_TOWN_CITY, STR_FOUND_TOWN_CITY_TOOLTIP), SetFill(1, 0), EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_SMALL), SetMinimalSize(78, 12), SetFill(1, 0), - SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_SMALL_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_MEDIUM), SetMinimalSize(78, 12), SetFill(1, 0), - SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_MEDIUM_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), + /* Town roads selection. */ + NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), + NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetDataTip(STR_FOUND_TOWN_ROAD_LAYOUT, STR_NULL), + NWidget(NWID_SPACER), SetFill(1, 0), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_ORIGINAL), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_ORIGINAL, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_BETTER), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_BETTER_ROADS, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 1), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_GRID2), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_2X2_GRID, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_GRID3), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_3X3_GRID, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 1), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_RANDOM), SetPadding(0, 2, 0, 2), SetMinimalSize(0, 12), SetFill(1, 0), + SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_RANDOM, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), SetFill(1, 0), + NWidget(NWID_SPACER), SetMinimalSize(0, 2), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 1), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_LARGE), SetMinimalSize(78, 12), SetFill(1, 0), - SetDataTip(STR_FOUND_TOWN_INITIAL_SIZE_LARGE_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_RANDOM), SetMinimalSize(78, 12), SetFill(1, 0), - SetDataTip(STR_FOUND_TOWN_SIZE_RANDOM, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 3), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_CITY), SetPadding(0, 2, 0, 2), SetMinimalSize(156, 12), SetFill(1, 0), - SetDataTip(STR_FOUND_TOWN_CITY, STR_FOUND_TOWN_CITY_TOOLTIP), SetFill(1, 0), - /* Town roads selection. */ - NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(148, 14), SetDataTip(STR_FOUND_TOWN_ROAD_LAYOUT, STR_NULL), - NWidget(NWID_SPACER), SetFill(1, 0), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_ORIGINAL), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_ORIGINAL, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_BETTER), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_BETTER_ROADS, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 1), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_GRID2), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_2X2_GRID, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_GRID3), SetMinimalSize(78, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_3X3_GRID, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 1), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_RANDOM), SetPadding(0, 2, 0, 2), SetMinimalSize(0, 12), SetFill(1, 0), - SetDataTip(STR_FOUND_TOWN_SELECT_LAYOUT_RANDOM, STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT), SetFill(1, 0), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), EndContainer(), }; @@ -1060,6 +1067,10 @@ public: this->UpdateButtons(true); } + ~FoundTownWindow() { + if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); + } + void RandomTownName() { this->townnamevalid = GenerateTownName(&this->townnameparts); @@ -1164,11 +1175,25 @@ public: virtual void OnPlaceObject(Point pt, TileIndex tile) { - this->ExecuteFoundTownCommand(tile, false, STR_ERROR_CAN_T_FOUND_TOWN_HERE, CcFoundTown); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); + MoveAllWindowsOffScreen(); + } + + virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + { + VpSelectTilesWithMethod(pt.x, pt.y, select_method); + } + + virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + { + assert(start_tile == end_tile); + this->ExecuteFoundTownCommand(end_tile, false, STR_ERROR_CAN_T_FOUND_TOWN_HERE, CcFoundTown); + MoveAllHiddenWindowsBackToScreen(); } virtual void OnPlaceObjectAbort() { + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); this->UpdateButtons(false); } @@ -1186,7 +1211,7 @@ public: }; static WindowDesc _found_town_desc( - WDP_AUTO, "build_town", 160, 162, + WDP_ALIGN_TOOLBAR, "build_town", 160, 162, WC_FOUND_TOWN, WC_NONE, WDF_CONSTRUCTION, _nested_found_town_widgets, lengthof(_nested_found_town_widgets) @@ -1195,5 +1220,6 @@ static WindowDesc _found_town_desc( void ShowFoundTownWindow() { if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return; + DeleteToolbarLinkedWindows(); AllocateWindowDescFront(&_found_town_desc, 0); } diff --git a/src/transparency_gui.cpp b/src/transparency_gui.cpp index 4bad2b0561..af4c7d1d00 100644 --- a/src/transparency_gui.cpp +++ b/src/transparency_gui.cpp @@ -144,7 +144,7 @@ static const NWidgetPart _nested_transparency_widgets[] = { NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(1, 1), EndContainer(), EndContainer(), /* Panel with 'invisibility' buttons. */ - NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_TT_BUTTONS), SetMinimalSize(219, 13), SetDataTip(0x0, STR_TRANSPARENT_INVISIBLE_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_TT_BUTTONS), SetSizingType(NWST_STEP), SetMinimalSize(219, 13), SetDataTip(0x0, STR_TRANSPARENT_INVISIBLE_TOOLTIP), EndContainer(), }; diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index f21eeaef2e..e444745220 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -18,6 +18,7 @@ #include "command_func.h" #include "sound_func.h" #include "tree_map.h" +#include "window_func.h" #include "widgets/tree_widget.h" @@ -60,6 +61,11 @@ public: ResetObjectToPlace(); } + ~BuildTreesWindow() + { + if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); + } + /** * Calculate the maximum size of all tree sprites * @return Dimension of the largest tree sprite @@ -141,6 +147,7 @@ public: virtual void OnPlaceObject(Point pt, TileIndex tile) { VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_PLANT_TREES); + MoveAllWindowsOffScreen(); } virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) @@ -153,6 +160,7 @@ public: if (pt.x != -1 && select_proc == DDSP_PLANT_TREES) { DoCommandP(end_tile, this->tree_to_plant, start_tile, CMD_PLANT_TREE | CMD_MSG(STR_ERROR_CAN_T_PLANT_TREE_HERE)); + MoveAllHiddenWindowsBackToScreen(); } } @@ -167,7 +175,10 @@ public: virtual void OnPlaceObjectAbort() { + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); + + ResetObjectToPlace(); } }; diff --git a/src/tutorial_gui.cpp b/src/tutorial_gui.cpp new file mode 100644 index 0000000000..3cf107abce --- /dev/null +++ b/src/tutorial_gui.cpp @@ -0,0 +1,224 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** + * @file tutorial_gui.cpp + * Links to video tutorials on Youtube. + */ + +#include "stdafx.h" + +#ifdef __ANDROID__ +#include +#endif + +#include "tutorial_gui.h" +#include "debug.h" +#include "strings_func.h" +#include "window_func.h" +#include "fios.h" +#include "string_func.h" +#include "language.h" +#include "widget_type.h" +#include "window_type.h" +#include "window_func.h" +#include "window_gui.h" +#include "widgets/station_widget.h" +#include "table/strings.h" +#include "table/sprites.h" + + +static bool showTutorialMainMenu = false; + +static const char * ANY_LANG = "ANY_LANG"; + +struct VideoLink_t { + const char *lang; + const char *video; +}; + +static VideoLink_t busTutorial[] = { + { "en", "https://www.youtube.com/watch?v=EULXRMR4PyE" }, + { ANY_LANG, "https://www.youtube.com/watch?v=EULXRMR4PyE" }, + { NULL, NULL } +}; + +static VideoLink_t trainTutorial[] = { + { "en", "https://www.youtube.com/watch?v=VdMdL2qyZ6s" }, + { ANY_LANG, "https://www.youtube.com/watch?v=VdMdL2qyZ6s" }, + { NULL, NULL } +}; + +static VideoLink_t truckTutorial[] = { + { "en", "https://www.youtube.com/watch?v=B-CL-XFGNtw" }, + { ANY_LANG, "https://www.youtube.com/watch?v=B-CL-XFGNtw" }, + { NULL, NULL } +}; + +static VideoLink_t shipTutorial[] = { + { "en", "https://www.youtube.com/watch?v=a5JHlWtIg3A" }, + { ANY_LANG, "https://www.youtube.com/watch?v=a5JHlWtIg3A" }, + { NULL, NULL } +}; + +static VideoLink_t cargoTutorial[] = { + { "en", "https://www.youtube.com/watch?v=GwjiQYsu3xg" }, + { ANY_LANG, "https://www.youtube.com/watch?v=GwjiQYsu3xg" }, + { NULL, NULL } +}; + +void OpenExternTutorialVideo(VideoLink_t *tutorial) +{ + const char *link = NULL; + for (; tutorial->lang != NULL; tutorial++) { + if (strcmp(tutorial->lang, _current_language->isocode) == 0) { + link = tutorial->video; + break; + } + if (strcmp(tutorial->lang, ANY_LANG) == 0) { + link = tutorial->video; + break; + } + } + if (!link) { + return; + } +#ifdef __ANDROID__ + SDL_ANDROID_OpenExternalWebBrowser(link); +#else + char cmd[PATH_MAX] = +#ifdef WIN32 + "start "; +#else + "xdg-open "; +#endif + strcat(cmd, link); + system(cmd); +#endif +} + +static const NWidgetPart _nested_tutorial_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_TUTORIAL_WINDOW_TITLE, STR_TUTORIAL_WINDOW_TOOLTIP), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0), + NWidget(NWID_VERTICAL), SetPIP(16, 2, 6), + // TODO: make different button IDs + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_BUS), SetMinimalSize(120, 20), SetDataTip(STR_TUTORIAL_ROADS_AND_STATIONS, STR_TUTORIAL_ROADS_AND_STATIONS), SetFill(1, 1), + NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_TRAIN), SetMinimalSize(120, 20), SetDataTip(STR_TUTORIAL_RAILWAYS, STR_TUTORIAL_RAILWAYS), SetFill(1, 1), + NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_TRUCK), SetMinimalSize(120, 20), SetDataTip(STR_TUTORIAL_ROAD_VEHICLES, STR_TUTORIAL_ROAD_VEHICLES), SetFill(1, 1), + NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_SHIP), SetMinimalSize(120, 20), SetDataTip(STR_TUTORIAL_SHIPS, STR_TUTORIAL_SHIPS), SetFill(1, 1), + NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_FACILALL), SetMinimalSize(120, 20), SetDataTip(STR_TUTORIAL_CARGO, STR_TUTORIAL_CARGO), SetFill(1, 1), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0), + EndContainer(), + EndContainer(), +}; + +static WindowDesc _tutorial_desc( + WDP_CENTER, NULL, 0, 0, + WC_GAME_OPTIONS, WC_NONE, + 0, + _nested_tutorial_widgets, lengthof(_nested_tutorial_widgets) +); + + +struct TutorialWindow : public Window { + VideoLink_t *video; + int counter; + + TutorialWindow() : Window(&_tutorial_desc) + { + this->InitNested(WN_GAME_OPTIONS_ABOUT); + this->video = NULL; + this->counter = 0; + } + + virtual void OnClick(Point pt, int widget, int click_count) + { + showTutorialMainMenu = false; + this->counter = 5; + this->LowerWidget(widget); + this->SetDirty(); + switch (widget) { + case WID_STL_BUS: + this->video = busTutorial; + break; + case WID_STL_TRUCK: + this->video = truckTutorial; + break; + case WID_STL_TRAIN: + this->video = trainTutorial; + break; + case WID_STL_SHIP: + this->video = shipTutorial; + break; + //case WID_STL_AIRPLANE: + // this->video = planeTutorial; + // break; + case WID_STL_FACILALL: + this->video = cargoTutorial; + break; + } + } + + virtual void OnTick() + { + // Open video with delay, to make visual feedback of button pressing, + // because youtube app freezes a screen for a second before launching. + if (this->counter > 0) { + this->counter--; + if (this->counter == 1) { + this->RaiseWidget(WID_STL_BUS); + this->RaiseWidget(WID_STL_TRUCK); + this->RaiseWidget(WID_STL_TRAIN); + this->RaiseWidget(WID_STL_SHIP); + //this->RaiseWidget(WID_STL_AIRPLANE); + this->RaiseWidget(WID_STL_FACILALL); + this->SetDirty(); + } + if (this->counter == 0) { + if (this->video) { + OpenExternTutorialVideo(this->video); + this->video = NULL; + } + } + } + } +}; + +void ShowTutorialWindow() +{ + DeleteWindowByClass(WC_GAME_OPTIONS); + new TutorialWindow(); +} + +void ShowTutorialWindowOnceAfterInstall() +{ + static const char * TUTORIAL_SHOWN_FLAG = ".tutorial-shown-3.flag"; + + FILE *ff = fopen(TUTORIAL_SHOWN_FLAG, "r"); + if (ff) { + fclose(ff); + if (!showTutorialMainMenu) + return; + } + showTutorialMainMenu = true; + ff = fopen(TUTORIAL_SHOWN_FLAG, "w"); + fprintf(ff, "Tutorial shown"); + fclose(ff); + ShowTutorialWindow(); +} diff --git a/src/tutorial_gui.h b/src/tutorial_gui.h new file mode 100644 index 0000000000..04840ee2c6 --- /dev/null +++ b/src/tutorial_gui.h @@ -0,0 +1,18 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file tutorial_gui.h Links to video tutorials. */ + +#ifndef TUTORIAL_GUI_H +#define TUTORIAL_GUI_H + +void ShowTutorialWindow(); +void ShowTutorialWindowOnceAfterInstall(); + +#endif /* TUTORIAL_GUI_H */ diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 8ea8cda4c8..0d2ad5e8dc 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -330,7 +330,7 @@ typedef SmallVector SubtypeList; ///< List of refit subtypes as */ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int sel[2], uint pos, uint rows, uint delta, const Rect &r) { - uint y = r.top + WD_MATRIX_TOP; + uint y = Center(r.top, delta); uint current = 0; bool rtl = _current_text_dir == TD_RTL; @@ -660,16 +660,17 @@ struct RefitWindow : public Window { { switch (widget) { case WID_VR_MATRIX: - resize->height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM; - size->height = resize->height * 8; + resize->height = GetMinSizing(NWST_STEP, WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM); + size->height = resize->height * 5; break; case WID_VR_VEHICLE_PANEL_DISPLAY: - size->height = ScaleGUITrad(GetVehicleHeight(Vehicle::Get(this->window_number)->type)); + size->height = max((int)GetMinSizing(NWST_STEP), ScaleGUITrad(GetVehicleHeight(Vehicle::Get(this->window_number)->type))); break; case WID_VR_INFO: size->width = WD_FRAMERECT_LEFT + this->information_width + WD_FRAMERECT_RIGHT; + size->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); break; } } @@ -732,7 +733,7 @@ struct RefitWindow : public Window { case WID_VR_VEHICLE_PANEL_DISPLAY: { Vehicle *v = Vehicle::Get(this->window_number); DrawVehicleImage(v, this->sprite_left + WD_FRAMERECT_LEFT, this->sprite_right - WD_FRAMERECT_RIGHT, - r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, EIT_IN_DETAILS, this->hscroll != NULL ? this->hscroll->GetPosition() : 0); + r.top, INVALID_VEHICLE, EIT_IN_DETAILS, this->hscroll != NULL ? this->hscroll->GetPosition() : 0); /* Highlight selected vehicles. */ if (this->order != INVALID_VEH_ORDER_ID) break; diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp index 3668f86020..e7770fb976 100644 --- a/src/video/sdl_v.cpp +++ b/src/video/sdl_v.cpp @@ -23,8 +23,14 @@ #include "../core/random_func.hpp" #include "../core/math_func.hpp" #include "../fileio_func.h" +#include "../settings_type.h" +#include "../tilehighlight_func.h" +#include "../viewport_func.h" #include "sdl_v.h" #include +#ifdef __ANDROID__ +#include +#endif #include "../safeguards.h" @@ -150,6 +156,16 @@ static void DrawSurfaceToScreen() { int n = _num_dirty_rects; if (n == 0) return; + static int frameskip = 0; + +#ifdef __ANDROID__ + if (_fast_forward) { + frameskip++; + if (frameskip < 5) + return; + frameskip = 0; + } +#endif _num_dirty_rects = 0; if (n > MAX_DIRTY_RECTS) { @@ -510,6 +526,8 @@ static uint ConvertSdlKeyIntoMy(SDL_keysym *sym, WChar *character) if (sym->scancode == 49) key = WKC_BACKSPACE; #elif defined(__sgi__) if (sym->scancode == 22) key = WKC_BACKQUOTE; +#elif defined(__ANDROID__) + if (sym->scancode == SDLK_BACKQUOTE) key = WKC_BACKQUOTE; #else if (sym->scancode == 49) key = WKC_BACKQUOTE; #endif @@ -533,7 +551,9 @@ int VideoDriver_SDL::PollEvent() switch (ev.type) { case SDL_MOUSEMOTION: if (_cursor.UpdateCursorPosition(ev.motion.x, ev.motion.y, true)) { +#ifndef __ANDROID__ // No mouse warping on Android, mouse strictly follows finger SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y); +#endif } HandleMouseEvents(); break; @@ -551,6 +571,13 @@ int VideoDriver_SDL::PollEvent() case SDL_BUTTON_RIGHT: _right_button_down = true; _right_button_clicked = true; + _right_button_down_pos.x = ev.motion.x; + _right_button_down_pos.y = ev.motion.y; +#ifdef __ANDROID__ + // Right button click on Android - cancel whatever action we were doing + ResetObjectToPlace(); + ToolbarSelectLastTool(); +#endif break; case SDL_BUTTON_WHEELUP: _cursor.wheel--; break; @@ -569,12 +596,20 @@ int VideoDriver_SDL::PollEvent() } else if (ev.button.button == SDL_BUTTON_LEFT) { _left_button_down = false; _left_button_clicked = false; +#ifdef __ANDROID__ + if (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_RMASK) { + // Two-finger click - hacky way to determine if the right mouse button is already pressed without processing the left button event + // Cancel whatever action we were doing, to allow two finger scrolling + ResetObjectToPlace(); + ToolbarSelectLastTool(); + } +#endif } else if (ev.button.button == SDL_BUTTON_RIGHT) { _right_button_down = false; } HandleMouseEvents(); break; - +#ifndef __ANDROID__ case SDL_ACTIVEEVENT: if (!(ev.active.state & SDL_APPMOUSEFOCUS)) break; @@ -585,7 +620,7 @@ int VideoDriver_SDL::PollEvent() _cursor.in_window = false; } break; - +#endif /* not __ANDROID__ */ case SDL_QUIT: HandleExitGameRequest(); break; @@ -598,15 +633,30 @@ int VideoDriver_SDL::PollEvent() WChar character; uint keycode = ConvertSdlKeyIntoMy(&ev.key.keysym, &character); HandleKeypress(keycode, character); +#ifdef __ANDROID__ + if (ev.key.keysym.sym == SDLK_LCTRL || ev.key.keysym.sym == SDLK_RCTRL) + _ctrl_pressed = true; + if (ev.key.keysym.sym == SDLK_LSHIFT || ev.key.keysym.sym == SDLK_RSHIFT) + _shift_pressed = true; +#endif } break; - + case SDL_KEYUP: +#ifdef __ANDROID__ + if (ev.key.keysym.sym == SDLK_LCTRL || ev.key.keysym.sym == SDLK_RCTRL) + _ctrl_pressed = false; + if (ev.key.keysym.sym == SDLK_LSHIFT || ev.key.keysym.sym == SDLK_RSHIFT) + _shift_pressed = false; +#endif + break; +#ifndef __ANDROID__ case SDL_VIDEORESIZE: { int w = max(ev.resize.w, 64); int h = max(ev.resize.h, 64); CreateMainSurface(w, h); break; } +#endif /* not __ANDROID__ */ case SDL_VIDEOEXPOSE: { /* Force a redraw of the entire screen. Note * that SDL 1.2 seems to do this automatically @@ -638,6 +688,9 @@ const char *VideoDriver_SDL::Start(const char * const *parm) SetupKeyboard(); _draw_threaded = GetDriverParam(parm, "no_threads") == NULL && GetDriverParam(parm, "no_thread") == NULL; +#ifdef __ANDROID__ + _draw_threaded = false; +#endif return NULL; } @@ -728,8 +781,10 @@ void VideoDriver_SDL::MainLoop() bool old_ctrl_pressed = _ctrl_pressed; +#ifndef __ANDROID__ _ctrl_pressed = !!(mod & KMOD_CTRL); _shift_pressed = !!(mod & KMOD_SHIFT); +#endif /* determine which directional keys are down */ _dirkeys = diff --git a/src/viewport.cpp b/src/viewport.cpp index a1bb2c81d1..e404b8db09 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -84,6 +84,7 @@ #include "linkgraph/linkgraph_gui.h" #include "viewport_sprite_sorter.h" #include "bridge_map.h" +#include "build_confirmation_func.h" #include @@ -1934,7 +1935,7 @@ void MarkTileDirtyByTileOutsideMap(int x, int y) * * @ingroup dirty */ -static void SetSelectionTilesDirty() +void SetSelectionTilesDirty() { int x_size = _thd.size.x; int y_size = _thd.size.y; @@ -2150,6 +2151,8 @@ static void PlaceObject() Point pt; Window *w; + if (BuildConfirmationWindowProcessViewportClick()) return; + pt = GetTileBelowCursor(); if (pt.x == -1) return; @@ -2168,13 +2171,28 @@ static void PlaceObject() bool HandleViewportClicked(const ViewPort *vp, int x, int y) { + if (_move_pressed) return false; + + // Allow scrolling viewport with mouse even in selection mode, + // unless we select line or area, or perform drag&drop + if ((_thd.place_mode & HT_DRAG_MASK) != HT_NONE && !(_thd.place_mode & HT_SCROLL_VIEWPORT)) { + PlaceObject(); + return true; + } + + return false; +} + +bool HandleViewportMouseUp(const ViewPort *vp, int x, int y) +{ + if (_move_pressed) return false; + const Vehicle *v = CheckClickOnVehicle(vp, x, y); if (_thd.place_mode & HT_VEHICLE) { if (v != NULL && VehicleClicked(v)) return true; } - /* Vehicle placement mode already handled above. */ if ((_thd.place_mode & HT_DRAG_MASK) != HT_NONE) { PlaceObject(); return true; @@ -2420,8 +2438,10 @@ void UpdateTileSelection() default: NOT_REACHED(); } - _thd.selstart.x = x1 & ~TILE_UNIT_MASK; - _thd.selstart.y = y1 & ~TILE_UNIT_MASK; + if (!ConfirmationWindowShown()) { + _thd.selstart.x = x1 & ~TILE_UNIT_MASK; + _thd.selstart.y = y1 & ~TILE_UNIT_MASK; + } break; default: NOT_REACHED(); @@ -2432,6 +2452,8 @@ void UpdateTileSelection() } } + if (ConfirmationWindowShown()) return; + /* redraw selection */ if (_thd.drawstyle != new_drawstyle || _thd.pos.x != _thd.new_pos.x || _thd.pos.y != _thd.new_pos.y || @@ -2488,7 +2510,9 @@ void VpStartPlaceSizing(TileIndex tile, ViewportPlaceMethod method, ViewportDrag } HighLightStyle others = _thd.place_mode & ~(HT_DRAG_MASK | HT_DIR_MASK); - if ((_thd.place_mode & HT_DRAG_MASK) == HT_RECT) { + if (method == VPM_SINGLE_TILE) { + /* Nothing to do. */ + } else if ((_thd.place_mode & HT_DRAG_MASK) == HT_RECT) { _thd.place_mode = HT_SPECIAL | others; _thd.next_drawstyle = HT_RECT | others; } else if (_thd.place_mode & (HT_RAIL | HT_LINE)) { @@ -2525,7 +2549,7 @@ void VpSetPresizeRange(TileIndex from, TileIndex to) if (distance > 1) ShowMeasurementTooltips(STR_MEASURE_LENGTH, 1, &distance, TCC_HOVER); } -static void VpStartPreSizing() +void VpStartPreSizing() { _thd.selend.x = -1; _special_mouse_mode = WSM_PRESIZE; @@ -2967,6 +2991,11 @@ void VpSelectTilesWithMethod(int x, int y, ViewportPlaceMethod method) int limit = 0; switch (method) { + case VPM_SINGLE_TILE: + _thd.selstart.x = x; + _thd.selstart.y = y; + break; + case VPM_X_OR_Y: // drag in X or Y direction if (abs(sy - y) < abs(sx - x)) { y = sy; @@ -3117,15 +3146,20 @@ EventState VpHandlePlaceSizingDrag() /* while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() ) */ if (_left_button_down) { + HideBuildConfirmationWindow(); w->OnPlaceDrag(_thd.select_method, _thd.select_proc, GetTileBelowCursor()); return ES_HANDLED; } + ShowBuildConfirmationWindow(); // This will also remember tile selection, so it's okay for the code below to change selection + /* mouse button released.. * keep the selected tool, but reset it to the original mode. */ _special_mouse_mode = WSM_NONE; HighLightStyle others = _thd.place_mode & ~(HT_DRAG_MASK | HT_DIR_MASK); - if ((_thd.next_drawstyle & HT_DRAG_MASK) == HT_RECT) { + if (_thd.select_method == VPM_SINGLE_TILE) { + goto place_mouseup; + } else if ((_thd.next_drawstyle & HT_DRAG_MASK) == HT_RECT) { _thd.place_mode = HT_RECT | others; } else if (_thd.select_method & VPM_SIGNALDIRS) { _thd.place_mode = HT_RECT | others; @@ -3136,8 +3170,7 @@ EventState VpHandlePlaceSizingDrag() } SetTileSelectSize(1, 1); - w->OnPlaceMouseUp(_thd.select_method, _thd.select_proc, _thd.selend, TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y)); - +place_mouseup: return ES_HANDLED; } @@ -3155,6 +3188,23 @@ void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Wind #include "table/animcursors.h" +static WindowClass _last_selected_window_class; +static WindowNumber _last_selected_window_number; + +/** Place object from the build confirmation dialog */ +void ConfirmPlacingObject() +{ + Window *w = _thd.GetCallbackWnd(); + if (w == NULL) { + ResetObjectToPlace(); + return; + } + + _last_selected_window_class = _thd.window_class; + _last_selected_window_number = _thd.window_number; + w->OnPlaceMouseUp(_thd.select_method, _thd.select_proc, _thd.selend, TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y)); +} + /** * Change the cursor and mouse click/drag handling to a mode for performing special operations like tile area selection, object placement, etc. * @param icon New shape of the mouse cursor. @@ -3210,7 +3260,20 @@ void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowC /** Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows). */ void ResetObjectToPlace() { + if (_thd.window_class != WC_INVALID) { + _last_selected_window_class = _thd.window_class; + _last_selected_window_number = _thd.window_number; + } SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0); + HideBuildConfirmationWindow(); + MoveAllHiddenWindowsBackToScreen(); +} + +void ToolbarSelectLastTool() +{ + Window *w = FindWindowById(_last_selected_window_class, _last_selected_window_number); + if (w != NULL) w->SelectLastTool(); + _last_selected_window_class = WC_INVALID; } Point GetViewportStationMiddle(const ViewPort *vp, const Station *st) diff --git a/src/viewport_func.h b/src/viewport_func.h index cbdcc5019a..a52cccc2e1 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.h @@ -60,6 +60,7 @@ void StartSpriteCombine(); void EndSpriteCombine(); bool HandleViewportClicked(const ViewPort *vp, int x, int y); +bool HandleViewportMouseUp(const ViewPort *vp, int x, int y); void SetRedErrorSquare(TileIndex tile); void SetTileSelectSize(int w, int h); void SetTileSelectBigSize(int ox, int oy, int sx, int sy); @@ -84,4 +85,6 @@ void MarkTileDirtyByTileOutsideMap(int x, int y); Point GetViewportStationMiddle(const ViewPort *vp, const Station *st); +void ToolbarSelectLastTool(); + #endif /* VIEWPORT_FUNC_H */ diff --git a/src/viewport_gui.cpp b/src/viewport_gui.cpp index cbd300dec7..7bf07257f3 100644 --- a/src/viewport_gui.cpp +++ b/src/viewport_gui.cpp @@ -34,7 +34,7 @@ static const NWidgetPart _nested_extra_view_port_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_GREY), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_EV_VIEWPORT), SetPadding(2, 2, 2, 2), SetResize(1, 1), SetFill(1, 1), + NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_EV_VIEWPORT), SetSizingType(NWST_VIEWPORT), SetPadding(2, 2, 2, 2), SetResize(1, 1), SetFill(1, 1), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_EV_ZOOM_IN), SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN), @@ -45,9 +45,6 @@ static const NWidgetPart _nested_extra_view_port_widgets[] = { NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_EV_VIEW_TO_MAIN), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN, STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT), EndContainer(), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 0), EndContainer(), NWidget(WWT_RESIZEBOX, COLOUR_GREY), EndContainer(), }; diff --git a/src/viewport_type.h b/src/viewport_type.h index 07485c3243..173471ab42 100644 --- a/src/viewport_type.h +++ b/src/viewport_type.h @@ -85,6 +85,7 @@ enum ViewportPlaceMethod { VPM_FIX_VERTICAL = 6, ///< drag only in vertical direction VPM_X_LIMITED = 7, ///< Drag only in X axis with limited size VPM_Y_LIMITED = 8, ///< Drag only in Y axis with limited size + VPM_SINGLE_TILE = 9, ///< Drag around the screen, selecting only the end tile VPM_RAILDIRS = 0x40, ///< all rail directions VPM_SIGNALDIRS = 0x80, ///< similar to VMP_RAILDIRS, but with different cursor }; @@ -121,6 +122,9 @@ enum ViewportDragDropSelectionProcess { DDSP_BUILD_TRUCKSTOP, ///< Road stop placement (trucks) DDSP_REMOVE_BUSSTOP, ///< Road stop removal (buses) DDSP_REMOVE_TRUCKSTOP, ///< Road stop removal (trucks) + + /* Single tile dragging */ + DDSP_SINGLE_TILE, ///< Single tile actions (build industry, town, etc.) }; #endif /* VIEWPORT_TYPE_H */ diff --git a/src/widget.cpp b/src/widget.cpp index 2c06cfe29b..a15c7e5b1d 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -18,6 +18,7 @@ #include "transparency.h" #include "core/geometry_func.hpp" #include "settings_type.h" +#include "settings_gui.h" #include "querystring_gui.h" #include "table/sprites.h" @@ -47,6 +48,11 @@ static Point HandleScrollbarHittest(const Scrollbar *sb, int top, int bottom, bo } top += button_size; // top points to just below the up-button bottom -= button_size; // bottom points to top of the down-button + bool wide_enough = false; + if (bottom > top + button_size * 2) { + bottom -= button_size; // Slider should be no smaller than a regular button, reserve some size from bottom + wide_enough = true; + } int height = (bottom - top); int pos = sb->GetPosition(); @@ -57,10 +63,11 @@ static Point HandleScrollbarHittest(const Scrollbar *sb, int top, int bottom, bo if (cap > count) cap = count; if (count != 0) bottom -= (count - pos - cap) * height / count; + if (wide_enough) bottom += button_size; Point pt; if (horizontal && _current_text_dir == TD_RTL) { - pt.x = rev_base - bottom; + pt.x = rev_base - bottom - button_size; pt.y = rev_base - top; } else { pt.x = top; @@ -96,7 +103,7 @@ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, in /* Pressing the upper button? */ SetBit(sb->disp_flags, NDB_SCROLLBAR_UP); if (_scroller_click_timeout <= 1) { - _scroller_click_timeout = 3; + _scroller_click_timeout = SCROLLER_CLICK_DELAY; sb->UpdatePosition(rtl ? 1 : -1); } w->scrolling_scrollbar = sb->index; @@ -105,7 +112,7 @@ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, in SetBit(sb->disp_flags, NDB_SCROLLBAR_DOWN); if (_scroller_click_timeout <= 1) { - _scroller_click_timeout = 3; + _scroller_click_timeout = SCROLLER_CLICK_DELAY; sb->UpdatePosition(rtl ? -1 : 1); } w->scrolling_scrollbar = sb->index; @@ -119,6 +126,8 @@ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, in } else { _scrollbar_start_pos = pt.x - mi - button_size; _scrollbar_size = ma - mi - button_size * 2; + if (_scrollbar_size > button_size * 2) + _scrollbar_size -= button_size; w->scrolling_scrollbar = sb->index; _cursorpos_drag_start = _cursor.pos; } @@ -221,7 +230,8 @@ static inline void DrawImageButtons(const Rect &r, WidgetType type, Colours colo DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE); if ((type & WWT_MASK) == WWT_IMGBTN_2 && clicked) img++; // Show different image when clicked for #WWT_IMGBTN_2. - DrawSprite(img, PAL_NONE, r.left + WD_IMGBTN_LEFT + clicked, r.top + WD_IMGBTN_TOP + clicked); + Dimension d2 = GetSpriteSize(img); + DrawSprite(img, PAL_NONE, Center(r.left + clicked, r.right - r.left, d2.width), Center(r.top + clicked, r.bottom - r.top, d2.height)); } /** @@ -341,10 +351,10 @@ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_ /* draw up/down buttons */ DrawFrameRect(r.left, r.top, r.right, r.top + height - 1, colour, (up_clicked) ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_UP, PAL_NONE, r.left + 1 + up_clicked, r.top + 1 + up_clicked); + DrawSpriteCenteredRect(SPR_ARROW_UP, PAL_NONE, r.left + 2 + up_clicked * 2, r.top + 2 + up_clicked * 2, r.right, r.top + height); DrawFrameRect(r.left, r.bottom - (height - 1), r.right, r.bottom, colour, (down_clicked) ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.left + 1 + down_clicked, r.bottom - (height - 2) + down_clicked); + DrawSpriteCenteredRect(SPR_ARROW_DOWN, PAL_NONE, r.left + 2 + down_clicked * 2, r.bottom - height + 2 + down_clicked, r.right, r.bottom); int c1 = _colour_gradient[colour & 0xF][3]; int c2 = _colour_gradient[colour & 0xF][7]; @@ -376,12 +386,13 @@ static inline void DrawHorizontalScrollbar(const Rect &r, Colours colour, bool l { int centre = (r.bottom - r.top) / 2; int width = NWidgetScrollbar::GetHorizontalDimension().width; + int height = NWidgetScrollbar::GetVerticalDimension().height; DrawFrameRect(r.left, r.top, r.left + width - 1, r.bottom, colour, left_clicked ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_LEFT, PAL_NONE, r.left + 1 + left_clicked, r.top + 1 + left_clicked); + DrawSpriteCenteredRect(SPR_ARROW_LEFT, PAL_NONE, r.left + left_clicked * 2, r.top + 2 + left_clicked * 2, r.left + height, r.bottom); DrawFrameRect(r.right - (width - 1), r.top, r.right, r.bottom, colour, right_clicked ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, r.right - (width - 2) + right_clicked, r.top + 1 + right_clicked); + DrawSpriteCenteredRect(SPR_ARROW_RIGHT, PAL_NONE, r.right - width + right_clicked * 2, r.top + 2 + right_clicked * 2, r.right, r.bottom); int c1 = _colour_gradient[colour & 0xF][3]; int c2 = _colour_gradient[colour & 0xF][7]; @@ -451,54 +462,6 @@ static inline void DrawFrame(const Rect &r, Colours colour, StringID str) GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2); } -/** - * Draw a shade box. - * @param r Rectangle of the box. - * @param colour Colour of the shade box. - * @param clicked Box is lowered. - */ -static inline void DrawShadeBox(const Rect &r, Colours colour, bool clicked) -{ - DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE); - DrawSprite((clicked) ? SPR_WINDOW_SHADE : SPR_WINDOW_UNSHADE, PAL_NONE, r.left + WD_SHADEBOX_LEFT + clicked, r.top + WD_SHADEBOX_TOP + clicked); -} - -/** - * Draw a sticky box. - * @param r Rectangle of the box. - * @param colour Colour of the sticky box. - * @param clicked Box is lowered. - */ -static inline void DrawStickyBox(const Rect &r, Colours colour, bool clicked) -{ - DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE); - DrawSprite((clicked) ? SPR_PIN_UP : SPR_PIN_DOWN, PAL_NONE, r.left + WD_STICKYBOX_LEFT + clicked, r.top + WD_STICKYBOX_TOP + clicked); -} - -/** - * Draw a defsize box. - * @param r Rectangle of the box. - * @param colour Colour of the defsize box. - * @param clicked Box is lowered. - */ -static inline void DrawDefSizeBox(const Rect &r, Colours colour, bool clicked) -{ - DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_WINDOW_DEFSIZE, PAL_NONE, r.left + WD_DEFSIZEBOX_LEFT + clicked, r.top + WD_DEFSIZEBOX_TOP + clicked); -} - -/** - * Draw a NewGRF debug box. - * @param r Rectangle of the box. - * @param colour Colour of the debug box. - * @param clicked Box is lowered. - */ -static inline void DrawDebugBox(const Rect &r, Colours colour, bool clicked) -{ - DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_WINDOW_DEBUG, PAL_NONE, r.left + WD_DEBUGBOX_LEFT + clicked, r.top + WD_DEBUGBOX_TOP + clicked); -} - /** * Draw a resize box. * @param r Rectangle of the box. @@ -509,12 +472,13 @@ static inline void DrawDebugBox(const Rect &r, Colours colour, bool clicked) static inline void DrawResizeBox(const Rect &r, Colours colour, bool at_left, bool clicked) { DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE); + Dimension d = GetSpriteSize(at_left ? SPR_WINDOW_RESIZE_LEFT : SPR_WINDOW_RESIZE_RIGHT); if (at_left) { - DrawSprite(SPR_WINDOW_RESIZE_LEFT, PAL_NONE, r.left + WD_RESIZEBOX_RIGHT + clicked, - r.bottom - WD_RESIZEBOX_BOTTOM - GetSpriteSize(SPR_WINDOW_RESIZE_LEFT).height + clicked); + DrawSprite(SPR_WINDOW_RESIZE_LEFT, PAL_NONE, r.left + WD_RESIZEBOX_LEFT + clicked, + r.bottom - WD_RESIZEBOX_BOTTOM - d.height + clicked); } else { - DrawSprite(SPR_WINDOW_RESIZE_RIGHT, PAL_NONE, r.left + WD_RESIZEBOX_LEFT + clicked, - r.bottom - WD_RESIZEBOX_BOTTOM - GetSpriteSize(SPR_WINDOW_RESIZE_RIGHT).height + clicked); + DrawSprite(SPR_WINDOW_RESIZE_RIGHT, PAL_NONE, r.right - WD_RESIZEBOX_RIGHT - d.width + clicked, + r.bottom - WD_RESIZEBOX_BOTTOM - d.height + clicked); } } @@ -526,7 +490,8 @@ static inline void DrawResizeBox(const Rect &r, Colours colour, bool at_left, bo static inline void DrawCloseBox(const Rect &r, Colours colour) { if (colour != COLOUR_WHITE) DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_NONE); - DrawSprite(SPR_CLOSEBOX, (colour != COLOUR_WHITE ? TC_BLACK : TC_SILVER) | (1 << PALETTE_TEXT_RECOLOUR), r.left + WD_CLOSEBOX_LEFT, r.top + WD_CLOSEBOX_TOP); + DrawSpriteCenteredRect(SPR_CLOSEBOX, (colour != COLOUR_WHITE ? TC_BLACK : TC_SILVER) | (1 << PALETTE_TEXT_RECOLOUR), + r.left + WD_CLOSEBOX_LEFT * 2, r.top + WD_CLOSEBOX_TOP * 2, r.right, r.bottom); } /** @@ -568,19 +533,19 @@ static inline void DrawButtonDropdown(const Rect &r, Colours colour, bool clicke { int text_offset = max(0, ((int)(r.bottom - r.top + 1) - FONT_HEIGHT_NORMAL) / 2); // Offset for rendering the text vertically centered - int dd_width = NWidgetLeaf::dropdown_dimension.width; - int dd_height = NWidgetLeaf::dropdown_dimension.height; + int dd_width = GetMinSizing(NWST_STEP, NWidgetLeaf::dropdown_dimension.width); + int dd_height = GetMinSizing(NWST_STEP, NWidgetLeaf::dropdown_dimension.height); int image_offset = max(0, ((int)(r.bottom - r.top + 1) - dd_height) / 2); if (_current_text_dir == TD_LTR) { DrawFrameRect(r.left, r.top, r.right - dd_width, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE); DrawFrameRect(r.right + 1 - dd_width, r.top, r.right, r.bottom, colour, clicked_dropdown ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.right - (dd_width - 2) + clicked_dropdown, r.top + image_offset + clicked_dropdown); + DrawSpriteCenteredRect(SPR_ARROW_DOWN, PAL_NONE, r.right - (dd_width - 2) + clicked_dropdown * 2, r.top + image_offset + clicked_dropdown * 2, r.right, r.bottom); if (str != STR_NULL) DrawString(r.left + WD_DROPDOWNTEXT_LEFT + clicked_button, r.right - dd_width - WD_DROPDOWNTEXT_RIGHT + clicked_button, r.top + text_offset + clicked_button, str, TC_BLACK); } else { DrawFrameRect(r.left + dd_width, r.top, r.right, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE); DrawFrameRect(r.left, r.top, r.left + dd_width - 1, r.bottom, colour, clicked_dropdown ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.left + 1 + clicked_dropdown, r.top + image_offset + clicked_dropdown); + DrawSpriteCenteredRect(SPR_ARROW_DOWN, PAL_NONE, r.left + 1 + clicked_dropdown * 2, r.top + image_offset + clicked_dropdown * 2, r.left + dd_width, r.bottom); if (str != STR_NULL) DrawString(r.left + dd_width + WD_DROPDOWNTEXT_LEFT + clicked_button, r.right - WD_DROPDOWNTEXT_RIGHT + clicked_button, r.top + text_offset + clicked_button, str, TC_BLACK); } } @@ -642,12 +607,11 @@ void Window::DrawSortButtonState(int widget, SortButtonState state) const const NWidgetBase *nwid = this->GetWidget(widget); /* Sort button uses the same sprites as vertical scrollbar */ - Dimension dim = NWidgetScrollbar::GetVerticalDimension(); int offset = this->IsWidgetLowered(widget) ? 1 : 0; - int x = offset + nwid->pos_x + (_current_text_dir == TD_LTR ? nwid->current_x - dim.width : 0); - int y = offset + nwid->pos_y + (nwid->current_y - dim.height) / 2; + int x = offset + nwid->pos_x + (_current_text_dir == TD_LTR ? nwid->current_x - SETTING_BUTTON_HEIGHT / 2 : SETTING_BUTTON_HEIGHT / 2); + int y = offset + Center(nwid->pos_y, nwid->current_y, FONT_HEIGHT_NORMAL / 4); - DrawSprite(state == SBS_DOWN ? SPR_ARROW_DOWN : SPR_ARROW_UP, PAL_NONE, x, y); + DrawSpriteCentered(state == SBS_DOWN ? SPR_ARROW_DOWN : SPR_ARROW_UP, PAL_NONE, x, y); } /** @@ -804,6 +768,7 @@ NWidgetBase *NWidgetBase::GetWidgetOfType(WidgetType tp) */ NWidgetResizeBase::NWidgetResizeBase(WidgetType tp, uint fill_x, uint fill_y) : NWidgetBase(tp) { + this->sizing_type = NWST_NONE; this->fill_x = fill_x; this->fill_y = fill_y; } @@ -817,6 +782,27 @@ void NWidgetResizeBase::SetMinimalSize(uint min_x, uint min_y) { this->min_x = max(this->min_x, min_x); this->min_y = max(this->min_y, min_y); + uint min_size = 0; + switch (this->sizing_type) { + case NWST_NONE: + case NWST_OVERRIDE: + min_size = 0; + break; + case NWST_BUTTON: + min_size = _settings_client.gui.min_button; + break; + case NWST_STEP: + min_size = _settings_client.gui.min_step; + break; + case NWST_VIEWPORT: + min_size = 3 * _settings_client.gui.min_button; + break; + default: NOT_REACHED(); + } + min_size = RescaleFrom854x480(min_size); + + this->min_x = max(min_x, min_size); + this->min_y = max(min_y, min_size); } /** @@ -868,6 +854,7 @@ void NWidgetResizeBase::AssignSizePosition(SizingType sizing, uint x, uint y, ui */ NWidgetCore::NWidgetCore(WidgetType tp, Colours colour, uint fill_x, uint fill_y, uint32 widget_data, StringID tool_tip) : NWidgetResizeBase(tp, fill_x, fill_y) { + this->sizing_type = NWST_NONE; this->colour = colour; this->index = -1; this->widget_data = widget_data; @@ -1988,6 +1975,7 @@ void Scrollbar::SetCapacityFromWidget(Window *w, int widget, int padding) NWidgetScrollbar::NWidgetScrollbar(WidgetType tp, Colours colour, int index) : NWidgetCore(tp, colour, 1, 1, 0x0, STR_NULL), Scrollbar(tp != NWID_HSCROLLBAR) { assert(tp == NWID_HSCROLLBAR || tp == NWID_VSCROLLBAR); + this->sizing_type = NWST_STEP; this->SetIndex(index); } @@ -2062,7 +2050,9 @@ void NWidgetScrollbar::Draw(const Window *w) if (vertical_dimension.width == 0) { vertical_dimension = maxdim(GetSpriteSize(SPR_ARROW_UP), GetSpriteSize(SPR_ARROW_DOWN)); vertical_dimension.width += extra.width; + vertical_dimension.width = GetMinSizing(NWST_STEP, vertical_dimension.width); vertical_dimension.height += extra.height; + vertical_dimension.height = GetMinSizing(NWST_STEP, vertical_dimension.height); } return vertical_dimension; } @@ -2073,7 +2063,9 @@ void NWidgetScrollbar::Draw(const Window *w) if (horizontal_dimension.width == 0) { horizontal_dimension = maxdim(GetSpriteSize(SPR_ARROW_LEFT), GetSpriteSize(SPR_ARROW_RIGHT)); horizontal_dimension.width += extra.width; + horizontal_dimension.width = GetMinSizing(NWST_STEP, horizontal_dimension.width); horizontal_dimension.height += extra.height; + horizontal_dimension.height = GetMinSizing(NWST_STEP, horizontal_dimension.height); } return horizontal_dimension; } @@ -2111,12 +2103,46 @@ Dimension NWidgetLeaf::dropdown_dimension = {0, 0}; */ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint32 data, StringID tip) : NWidgetCore(tp, colour, 1, 1, data, tip) { + assert(this->sizing_type < NWST_END); assert(index >= 0 || tp == WWT_LABEL || tp == WWT_TEXT || tp == WWT_CAPTION || tp == WWT_RESIZEBOX || tp == WWT_SHADEBOX || tp == WWT_DEFSIZEBOX || tp == WWT_DEBUGBOX || tp == WWT_STICKYBOX || tp == WWT_CLOSEBOX); if (index >= 0) this->SetIndex(index); this->min_x = 0; this->min_y = 0; this->SetResize(0, 0); + if (this->sizing_type == NWST_NONE) { + switch (tp) { + case WWT_PUSHBTN: + case WWT_IMGBTN: + case WWT_PUSHIMGBTN: + case WWT_IMGBTN_2: + case WWT_TEXTBTN: + case WWT_PUSHTXTBTN: + case WWT_TEXTBTN_2: + case WWT_PUSHARROWBTN: + case WWT_EDITBOX: + case WWT_CAPTION: + case WWT_STICKYBOX: + case WWT_SHADEBOX: + case WWT_DEBUGBOX: + case WWT_DEFSIZEBOX: + case WWT_RESIZEBOX: + case WWT_CLOSEBOX: + this->sizing_type = NWST_BUTTON; + this->SetMinimalSize(8, 8); + break; + case NWID_PUSHBUTTON_DROPDOWN: + case NWID_BUTTON_DROPDOWN: + case WWT_DROPDOWN: + case WWT_ARROWBTN: + this->sizing_type = NWST_STEP; + this->SetMinimalSize(8, 8); + break; + default: + this->sizing_type = NWST_OVERRIDE; + } + } + switch (tp) { case WWT_EMPTY: break; @@ -2145,7 +2171,7 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint32 data, case WWT_CAPTION: this->SetFill(1, 0); this->SetResize(1, 0); - this->min_y = WD_CAPTION_HEIGHT; + //this->min_y = WD_CAPTION_HEIGHT; this->SetDataTip(data, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS); break; @@ -2187,7 +2213,7 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint32 data, case WWT_DROPDOWN: this->SetFill(0, 0); - this->min_y = WD_DROPDOWN_HEIGHT; + //this->min_y = WD_DROPDOWN_HEIGHT; break; default: @@ -2286,6 +2312,7 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) Dimension sprite_size = GetSpriteSize(_current_text_dir == TD_RTL ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); size.width = max(size.width, 30 + sprite_size.width); size.height = max(sprite_size.height, GetStringBoundingBox("_").height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + size.height = GetMinSizing(NWST_BUTTON, size.height); /* FALL THROUGH */ } case WWT_PUSHBTN: { @@ -2352,7 +2379,7 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) padding = &extra; if (this->index >= 0) w->SetStringParameters(this->index); Dimension d2 = GetStringBoundingBox(this->widget_data); - d2.width += extra.width; + d2.width += extra.width + GetMinSizing(NWST_STEP, 11U); d2.height += extra.height; size = maxdim(size, d2); break; @@ -2364,7 +2391,8 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) padding = &extra; if (NWidgetLeaf::dropdown_dimension.width == 0) { NWidgetLeaf::dropdown_dimension = GetSpriteSize(SPR_ARROW_DOWN); - NWidgetLeaf::dropdown_dimension.width += WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT; + NWidgetLeaf::dropdown_dimension.width = SETTING_BUTTON_HEIGHT; + //NWidgetLeaf::dropdown_dimension.width += WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT; NWidgetLeaf::dropdown_dimension.height += WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM; extra.width = WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT + NWidgetLeaf::dropdown_dimension.width; } @@ -2474,21 +2502,23 @@ void NWidgetLeaf::Draw(const Window *w) case WWT_SHADEBOX: assert(this->widget_data == 0); - DrawShadeBox(r, this->colour, w->IsShaded()); + DrawImageButtons(r, WWT_SHADEBOX, this->colour, w->IsShaded(), w->IsShaded() ? SPR_WINDOW_SHADE : SPR_WINDOW_UNSHADE); break; case WWT_DEBUGBOX: - DrawDebugBox(r, this->colour, clicked); + DrawImageButtons(r, WWT_DEBUGBOX, this->colour, clicked, SPR_WINDOW_DEBUG); break; - case WWT_STICKYBOX: + case WWT_STICKYBOX: { assert(this->widget_data == 0); - DrawStickyBox(r, this->colour, !!(w->flags & WF_STICKY)); + bool clicked = !!(w->flags & WF_STICKY); + DrawImageButtons(r, WWT_STICKYBOX, this->colour, clicked, clicked ? SPR_PIN_DOWN : SPR_PIN_UP); break; + } case WWT_DEFSIZEBOX: assert(this->widget_data == 0); - DrawDefSizeBox(r, this->colour, clicked); + DrawImageButtons(r, WWT_DEFSIZEBOX, this->colour, clicked, SPR_WINDOW_DEFSIZE); break; case WWT_RESIZEBOX: @@ -2532,11 +2562,12 @@ void NWidgetLeaf::Draw(const Window *w) */ bool NWidgetLeaf::ButtonHit(const Point &pt) { + uint button_size = GetMinSizing(NWST_STEP, 12); if (_current_text_dir == TD_LTR) { - int button_width = this->pos_x + this->current_x - NWidgetLeaf::dropdown_dimension.width; + int button_width = this->pos_x + this->current_x - button_size; return pt.x < button_width; } else { - int button_left = this->pos_x + NWidgetLeaf::dropdown_dimension.width; + int button_left = this->pos_x + button_size; return pt.x >= button_left; } } @@ -2629,6 +2660,16 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, break; } + case WPT_SIZINGTYPE: { + NWidgetResizeBase *nwrb = dynamic_cast(*dest); + if (nwrb != NULL) { + assert(parts->u.sizing_type < NWST_END); + nwrb->sizing_type = parts->u.sizing_type; + nwrb->SetMinimalSize(0, 0); + } + break; + } + case WPT_MINSIZE: { NWidgetResizeBase *nwrb = dynamic_cast(*dest); if (nwrb != NULL) { @@ -2885,6 +2926,7 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid } NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, widnum); + panel->sizing_type = NWST_STEP; panel->SetMinimalSize(sprite_size.width, sprite_size.height); panel->SetFill(1, 1); panel->SetResize(1, 0); @@ -2905,3 +2947,35 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid if (hor != NULL) vert->Add(hor); return vert; } + +/** + * Return the minimal automatic size for a widget. + * @param type The automatic sizing type to use. + * @param min_1 Minimal passed value. + * @return At least the passed value, or the minimal size for the associated sizing type. + */ +uint GetMinSizing(NWidSizingType type, uint min_1) +{ + uint min_sizing; + switch (type) { + case NWST_NONE: + case NWST_OVERRIDE: + return min_1; + case NWST_BUTTON: + min_sizing = _settings_client.gui.min_button; + break; + case NWST_STEP: + min_sizing = _settings_client.gui.min_step; + break; + case NWST_KEYBOARD: + min_sizing = 2 * _settings_client.gui.min_button; + break; + case NWST_WINDOW_LENGTH: + min_sizing = 8 * _settings_client.gui.min_button; + break; + default: NOT_REACHED(); + } + min_sizing = RescaleFrom854x480(min_sizing); + + return max(min_sizing, min_1); +} diff --git a/src/widget_type.h b/src/widget_type.h index 39efbb4637..e7940da178 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -40,6 +40,20 @@ enum ArrowWidgetValues { AWV_RIGHT, ///< Force the arrow to the right }; +/** Values for different minimal sizing of widgets. */ +enum NWidSizingType { + NWST_NONE, ///< No sizing type is yet defined. + ///< Most buttons and scrollbars are initialized with this value. + ///< Later, they are automatically set to NWST_BUTTON or NWST_STEP. + NWST_BUTTON, ///< Size will be set at least _settings_client.gui.min_button. + NWST_STEP, ///< Size will be set at least _settings_client.gui.min_step (scrollbars and dropdowns). + NWST_KEYBOARD, ///< Size for keyboard keys. + NWST_WINDOW_LENGTH, ///< Width for command errors, message windows and statusbar middle part. + NWST_VIEWPORT, ///< Sizing type for viewports. + NWST_OVERRIDE, ///< Avoid widgets to use automatic minimal sizing. + NWST_END +}; + /** * Window widget types, nested widget types, and nested widget part types. */ @@ -85,6 +99,7 @@ enum WidgetType { /* Nested widget part types. */ WPT_RESIZE, ///< Widget part for specifying resizing. + WPT_SIZINGTYPE, ///< Widget part for specifying sizing mode. WPT_MINSIZE, ///< Widget part for specifying minimal size. WPT_MINTEXTLINES, ///< Widget part for specifying minimal number of lines of text. WPT_FILL, ///< Widget part for specifying fill. @@ -160,11 +175,12 @@ public: virtual void Draw(const Window *w) = 0; virtual void SetDirty(const Window *w) const; - WidgetType type; ///< Type of the widget / nested widget. - uint fill_x; ///< Horizontal fill stepsize (from initial size, \c 0 means not resizable). - uint fill_y; ///< Vertical fill stepsize (from initial size, \c 0 means not resizable). - uint resize_x; ///< Horizontal resize step (\c 0 means not resizable). - uint resize_y; ///< Vertical resize step (\c 0 means not resizable). + WidgetType type; ///< Type of the widget / nested widget. + NWidSizingType sizing_type; ///< Type for deciding minimal sizes of the widget. + uint fill_x; ///< Horizontal fill stepsize (from initial size, \c 0 means not resizable). + uint fill_y; ///< Vertical fill stepsize (from initial size, \c 0 means not resizable). + uint resize_x; ///< Horizontal resize step (\c 0 means not resizable). + uint resize_y; ///< Vertical resize step (\c 0 means not resizable). /* Size of the widget in the smallest window possible. * Computed by #SetupSmallestSize() followed by #AssignSizePosition(). */ @@ -918,6 +934,7 @@ struct NWidgetPart { NWidgetPartTextLines text_lines; ///< Part with text line data. NWidgetFunctionType *func_ptr; ///< Part with a function call. NWidContainerFlags cont_flags; ///< Part with container flags. + NWidSizingType sizing_type; ///< Part with sizing type. } u; }; @@ -938,6 +955,23 @@ static inline NWidgetPart SetResize(int16 dx, int16 dy) return part; } +/** + * Widget part function for setting the automatic minimal size. + * @param type How to decide the minimal size of the widget. + * @ingroup NestedWidgetParts + */ +static inline NWidgetPart SetSizingType(NWidSizingType type) +{ + NWidgetPart part; + + part.type = WPT_SIZINGTYPE; + part.u.sizing_type = type; + + return part; +} + +uint GetMinSizing(NWidSizingType type, uint min_1 = 0); + /** * Widget part function for setting the minimal size. * @param x Horizontal minimal size. diff --git a/src/widgets/build_confirmation_widget.h b/src/widgets/build_confirmation_widget.h new file mode 100644 index 0000000000..9244ef204e --- /dev/null +++ b/src/widgets/build_confirmation_widget.h @@ -0,0 +1,23 @@ +/* $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_widget.h Types related to the build_confirmation widgets. */ + +#ifndef WIDGETS_BUILD_CONFIRMATION_WIDGET_H +#define WIDGETS_BUILD_CONFIRMATION_WIDGET_H + +/** Widgets of the #BuildVehicleWindow class. */ +enum BuildConfirmationWidgets { + WID_BC_PRICE, ///< Estimated price. + WID_BC_OK, ///< Confirm action. + WID_BC_CANCEL, ///< Cancel action. + WID_BC_PANEL, ///< Cancel action. +}; + +#endif /* WIDGETS_BUILD_CONFIRMATION_WIDGET_H */ diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index e0ad96a87a..4da3c3d69d 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -40,7 +40,7 @@ uint DropDownListStringItem::Width() const void DropDownListStringItem::Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const { - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, this->String(), sel ? TC_WHITE : TC_BLACK); + DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, Center(top, bottom - top), this->String(), sel ? TC_WHITE : TC_BLACK); } /** @@ -96,6 +96,7 @@ struct DropdownWindow : Window { byte click_delay; ///< Timer to delay selection. bool drag_mode; bool instant_close; ///< Close the window when the mouse button is raised. + bool left_button_state; ///< Close the window when the mouse button is clicked outside the window. int scrolling; ///< If non-zero, auto-scroll the item list (one time). Point position; ///< Position of the topleft corner of the window. Scrollbar *vscroll; @@ -154,8 +155,9 @@ struct DropdownWindow : Window { this->list = list; this->selected_index = selected; this->click_delay = 0; - this->drag_mode = true; + this->drag_mode = instant_close; this->instant_close = instant_close; + this->left_button_state = _left_button_down; } ~DropdownWindow() @@ -260,8 +262,11 @@ struct DropdownWindow : Window { if (this->scrolling != 0) { int pos = this->vscroll->GetPosition(); - this->vscroll->UpdatePosition(this->scrolling); - this->scrolling = 0; + if (_scroller_click_timeout <= 1) { + _scroller_click_timeout = SCROLLER_CLICK_DELAY; + this->vscroll->UpdatePosition(this->scrolling); + this->scrolling = 0; + } if (pos != this->vscroll->GetPosition()) { this->SetDirty(); @@ -317,6 +322,16 @@ struct DropdownWindow : Window { this->SetDirty(); } } + + // Close dropdown if user clicks outside of it + if (_left_button_down && !this->left_button_state && ( + _cursor.pos.x < this->left || _cursor.pos.x > this->left + this->width || + _cursor.pos.y < this->top || _cursor.pos.y > this->top + this->height)) { + delete this; + return; + } else { + this->left_button_state = _left_button_down; + } } }; @@ -360,21 +375,45 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b int screen_bottom = GetMainViewBottom(); bool scroll = false; + enum { DISPLAY_BORDER = 20, TOP_BORDER = 4 }; + /* Check if the dropdown will fully fit below the widget */ - if (top + height + 4 >= screen_bottom) { + if (top + height + DISPLAY_BORDER >= screen_bottom) { /* If not, check if it will fit above the widget */ - if (w->top + wi_rect.top - height > GetMainViewTop()) { - top = w->top + wi_rect.top - height - 4; + int screen_top = GetMainViewTop(); + if (w->top + wi_rect.top - TOP_BORDER > screen_top + height) { + top = w->top + wi_rect.top - height - TOP_BORDER; } else { + /* If it doesn't fit above the widget, we need to enable a scrollbar... */ + int avg_height = height / (int)list->Length(); + scroll = true; + + /* ... and choose whether to put the list above or below the widget. */ + bool put_above = false; + int available_height = screen_bottom - w->top - wi_rect.bottom; + if (w->top + wi_rect.top - screen_top > available_height) { + // Put it above. + available_height = w->top + wi_rect.top - screen_top - DISPLAY_BORDER - TOP_BORDER; + put_above = true; + } + + /* Check at least there is space for one item. */ + assert(available_height >= avg_height); + /* ... and lastly if it won't, enable the scroll bar and fit the * list in below the widget */ - int avg_height = height / (int)list->Length(); - int rows = (screen_bottom - 4 - top) / avg_height; + int rows = available_height / avg_height; height = rows * avg_height; + scroll = true; /* Add space for the scroll bar if we automatically determined * the width of the list. */ max_item_width += NWidgetScrollbar::GetVerticalDimension().width; + + /* ... and set the top position if needed. */ + if (put_above) { + top = w->top + wi_rect.top - height - TOP_BORDER; + } } } diff --git a/src/widgets/dropdown_type.h b/src/widgets/dropdown_type.h index b65d4557bd..4c330117e7 100644 --- a/src/widgets/dropdown_type.h +++ b/src/widgets/dropdown_type.h @@ -13,6 +13,7 @@ #define WIDGETS_DROPDOWN_TYPE_H #include "../window_type.h" +#include "../widget_type.h" #include "../gfx_func.h" #include "../core/smallvec_type.hpp" #include "table/strings.h" @@ -30,7 +31,7 @@ public: virtual ~DropDownListItem() {} virtual bool Selectable() const { return false; } - virtual uint Height(uint width) const { return FONT_HEIGHT_NORMAL; } + virtual uint Height(uint width) const { return GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); } virtual uint Width() const { return 0; } virtual void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const; }; diff --git a/src/widgets/fios_widget.h b/src/widgets/fios_widget.h index c94655d767..3f4b49fbee 100644 --- a/src/widgets/fios_widget.h +++ b/src/widgets/fios_widget.h @@ -31,6 +31,8 @@ enum SaveLoadWidgets { WID_SL_NEWGRF_INFO, ///< Button to open NewGgrf configuration. WID_SL_LOAD_BUTTON, ///< Button to load game/scenario. WID_SL_MISSING_NEWGRFS, ///< Button to find missing NewGRFs online. + WID_SL_SAVE_NETWORK_BUTTON, ///< Toggle button to back up savegame to the network storage. + WID_SL_LOAD_NETWORK_BUTTON, ///< Button to load game from the network storage. }; #endif /* WIDGETS_FIOS_WIDGET_H */ diff --git a/src/widgets/intro_widget.h b/src/widgets/intro_widget.h index ae48827ed1..4b772852e5 100644 --- a/src/widgets/intro_widget.h +++ b/src/widgets/intro_widget.h @@ -34,6 +34,7 @@ enum SelectGameIntroWidgets { WID_SGI_GRF_SETTINGS, ///< NewGRF button. WID_SGI_CONTENT_DOWNLOAD, ///< Content Download button. WID_SGI_AI_SETTINGS, ///< AI button. + WID_SGI_TUTORIAL, ///< Tutorial button. WID_SGI_EXIT, ///< Exit button. }; diff --git a/src/widgets/music_widget.h b/src/widgets/music_widget.h index 3a99bc6150..ebd7ea057d 100644 --- a/src/widgets/music_widget.h +++ b/src/widgets/music_widget.h @@ -14,16 +14,18 @@ /** Widgets of the #MusicTrackSelectionWindow class. */ enum MusicTrackSelectionWidgets { - WID_MTS_LIST_LEFT, ///< Left button. - WID_MTS_PLAYLIST, ///< Playlist. - WID_MTS_LIST_RIGHT, ///< Right button. - WID_MTS_ALL, ///< All button. - WID_MTS_OLD, ///< Old button. - WID_MTS_NEW, ///< New button. - WID_MTS_EZY, ///< Ezy button. - WID_MTS_CUSTOM1, ///< Custom1 button. - WID_MTS_CUSTOM2, ///< Custom2 button. - WID_MTS_CLEAR, ///< Clear button. + WID_MTS_LIST_LEFT, ///< Left list. + WID_MTS_LEFT_SCROLLBAR, ///< Scrollbar of left list. + WID_MTS_PLAYLIST, ///< Playlist name. + WID_MTS_LIST_RIGHT, ///< Right list. + WID_MTS_RIGHT_SCROLLBAR, ///< Scrollbar of right list. + WID_MTS_ALL, ///< All button. + WID_MTS_OLD, ///< Old button. + WID_MTS_NEW, ///< New button. + WID_MTS_EZY, ///< Ezy button. + WID_MTS_CUSTOM1, ///< Custom1 button. + WID_MTS_CUSTOM2, ///< Custom2 button. + WID_MTS_CLEAR, ///< Clear button. }; /** Widgets of the #MusicWindow class. */ diff --git a/src/widgets/rail_widget.h b/src/widgets/rail_widget.h index f977f44803..d334f02c5a 100644 --- a/src/widgets/rail_widget.h +++ b/src/widgets/rail_widget.h @@ -71,6 +71,7 @@ enum BuildRailStationWidgets { WID_BRAS_SHOW_NEWST_TYPE, ///< Display of selected station type. WID_BRAS_NEWST_LIST, ///< List with available newstation classes. WID_BRAS_NEWST_SCROLL, ///< Scrollbar of the #WID_BRAS_NEWST_LIST. + WID_BRAS_NEWST_SPACER, ///< Spacer to make newst list fit the screen WID_BRAS_PLATFORM_NUM_BEGIN = WID_BRAS_PLATFORM_NUM_1 - 1, ///< Helper for determining the chosen platform width. WID_BRAS_PLATFORM_LEN_BEGIN = WID_BRAS_PLATFORM_LEN_1 - 1, ///< Helper for determining the chosen platform length. diff --git a/src/widgets/settings_widget.h b/src/widgets/settings_widget.h index 661f788cd7..292c50bafd 100644 --- a/src/widgets/settings_widget.h +++ b/src/widgets/settings_widget.h @@ -23,6 +23,13 @@ enum GameOptionsWidgets { WID_GO_LANG_DROPDOWN, ///< Language dropdown. WID_GO_RESOLUTION_DROPDOWN, ///< Dropdown for the resolution. WID_GO_FULLSCREEN_BUTTON, ///< Toggle fullscreen. + WID_GO_8BPP_BUTTON, ///< 8 bits per pixel video mode + WID_GO_16BPP_BUTTON, ///< 16 bits per pixel video mode + WID_GO_32BPP_BUTTON, ///< 32 bits per pixel video mode + WID_GO_BUTTON_SIZE_DROPDOWN, ///< Size of in-game UI elements, such as buttons. + WID_GO_TEXT_SIZE_DROPDOWN, ///< Size of medium font, sizes of other fonts are derived from it. + WID_GO_VERTICAL_TOOLBAR, ///< Enable vertical toolbar. + WID_GO_BUILD_CONFIRMATION, ///< Enable build confirmation dialog. WID_GO_GUI_ZOOM_DROPDOWN, ///< Dropdown for the GUI zoom level. WID_GO_BASE_GRF_DROPDOWN, ///< Use to select a base GRF. WID_GO_BASE_GRF_STATUS, ///< Info about missing files etc. diff --git a/src/widgets/smallmap_widget.h b/src/widgets/smallmap_widget.h index 0b1daea03f..753dcb74e3 100644 --- a/src/widgets/smallmap_widget.h +++ b/src/widgets/smallmap_widget.h @@ -34,6 +34,7 @@ enum SmallMapWidgets { WID_SM_ENABLE_ALL, ///< Button to enable display of all legend entries. WID_SM_DISABLE_ALL, ///< Button to disable display of all legend entries. WID_SM_SHOW_HEIGHT, ///< Show heightmap toggle button. + WID_SM_SHOW_LEGEND, ///< Show/hide legend area. }; #endif /* WIDGETS_SMALLMAP_WIDGET_H */ diff --git a/src/widgets/toolbar_widget.h b/src/widgets/toolbar_widget.h index 434a238acc..dc205838a3 100644 --- a/src/widgets/toolbar_widget.h +++ b/src/widgets/toolbar_widget.h @@ -46,6 +46,9 @@ enum ToolbarNormalWidgets { WID_TN_MESSAGES, ///< Messages menu. WID_TN_HELP, ///< Help menu. WID_TN_SWITCH_BAR, ///< Only available when toolbar has been split to switch between different subsets. + WID_TN_CTRL, ///< Press CTRL. + WID_TN_SHIFT, ///< Press SHIFT. + WID_TN_DELETE, ///< Press DELETE. WID_TN_END, ///< Helper for knowing the amount of widgets. }; diff --git a/src/window.cpp b/src/window.cpp index 0ffbf8bf1b..233e758ef0 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -36,6 +36,15 @@ #include "error.h" #include "game/game.hpp" #include "video/video_driver.hpp" +#include "settings_gui.h" +#include "fontcache.h" +#include "error.h" +#include "station_base.h" +#include "waypoint_base.h" +#include "command_func.h" +#include "build_confirmation_func.h" + +#include "table/strings.h" #include "safeguards.h" @@ -74,6 +83,7 @@ byte _scroller_click_timeout = 0; bool _scrolling_viewport; ///< A viewport is being scrolled with the mouse. bool _mouse_hovering; ///< The mouse is hovering over the same point. +static bool _left_button_dragged; SpecialMouseMode _special_mouse_mode; ///< Mode of the mouse. @@ -1245,6 +1255,7 @@ static inline bool IsVitalWindow(const Window *w) { switch (w->window_class) { case WC_MAIN_TOOLBAR: + case WC_MAIN_TOOLBAR_RIGHT: case WC_STATUS_BAR: case WC_NEWS_WINDOW: case WC_SEND_NETWORK_MSG: @@ -1283,6 +1294,7 @@ static uint GetWindowZPriority(const Window *w) ++z_priority; case WC_MAIN_TOOLBAR: + case WC_MAIN_TOOLBAR_RIGHT: case WC_STATUS_BAR: ++z_priority; @@ -1428,6 +1440,14 @@ void Window::InitializeData(WindowNumber window_number) this->nested_focus = NULL; this->window_number = window_number; + if (this->window_class != WC_BUILD_CONFIRMATION && + this->window_class != WC_TOOLTIPS && + this->window_class != WC_NEWS_WINDOW && + this->window_class != WC_BUILD_BRIDGE && + this->window_class != WC_SELECT_STATION) { + HideBuildConfirmationWindow(); + } + this->OnInit(); /* Initialize nested widget tree. */ if (this->nested_array == NULL) { @@ -1482,6 +1502,7 @@ void Window::FindWindowPlacementAndResize(int def_width, int def_height) { def_width = max(def_width, this->width); // Don't allow default size to be smaller than smallest size def_height = max(def_height, this->height); + bool vertical_toolbar = _settings_client.gui.vertical_toolbar && _game_mode != GM_EDITOR; /* Try to make windows smaller when our window is too small. * w->(width|height) is normally the same as min_(width|height), * but this way the GUIs can be made a little more dynamic; @@ -1493,10 +1514,13 @@ void Window::FindWindowPlacementAndResize(int def_width, int def_height) const Window *wt = FindWindowById(WC_STATUS_BAR, 0); if (wt != NULL) free_height -= wt->height; wt = FindWindowById(WC_MAIN_TOOLBAR, 0); - if (wt != NULL) free_height -= wt->height; + if (wt != NULL && !vertical_toolbar) free_height -= wt->height; int enlarge_x = max(min(def_width - this->width, _screen.width - this->width), 0); int enlarge_y = max(min(def_height - this->height, free_height - this->height), 0); + if (wt && vertical_toolbar && enlarge_x > _screen.width - wt->width * 2) { + enlarge_x = _screen.width - wt->width * 2; + } /* X and Y has to go by step.. calculate it. * The cast to int is necessary else x/y are implicitly casted to @@ -1517,8 +1541,13 @@ void Window::FindWindowPlacementAndResize(int def_width, int def_height) if (nx + this->width > _screen.width) nx -= (nx + this->width - _screen.width); const Window *wt = FindWindowById(WC_MAIN_TOOLBAR, 0); - ny = max(ny, (wt == NULL || this == wt || this->top == 0) ? 0 : wt->height); - nx = max(nx, 0); + if (!vertical_toolbar) { + ny = max(ny, (wt == NULL || this == wt || this->top == 0) ? 0 : wt->height); + nx = max(nx, 0); + } else { + nx = max(nx, (wt == NULL || this == wt || this == FindWindowById(WC_MAIN_TOOLBAR_RIGHT, 0) || this->left == 0) ? 0 : wt->width); + ny = max(ny, 0); + } if (this->viewport != NULL) { this->viewport->left += nx - this->left; @@ -1547,7 +1576,12 @@ static bool IsGoodAutoPlace1(int left, int top, int width, int height, Point &po int bottom = height + top; const Window *main_toolbar = FindWindowByClass(WC_MAIN_TOOLBAR); - if (left < 0 || (main_toolbar != NULL && top < main_toolbar->height) || right > _screen.width || bottom > _screen.height) return false; + bool vertical_toolbar = _settings_client.gui.vertical_toolbar && _game_mode != GM_EDITOR; + if (!vertical_toolbar || !main_toolbar) { + if (left < 0 || (main_toolbar != NULL && top < main_toolbar->height) || right > _screen.width || bottom > _screen.height) return false; + } else { + if (left < main_toolbar->width || top < 0 || right > _screen.width - main_toolbar->width * 2 || bottom > _screen.height) return false; + } /* Make sure it is not obscured by any window. */ const Window *w; @@ -1614,10 +1648,15 @@ static bool IsGoodAutoPlace2(int left, int top, int width, int height, Point &po static Point GetAutoPlacePosition(int width, int height) { Point pt; + bool vertical_toolbar = _settings_client.gui.vertical_toolbar && _game_mode != GM_EDITOR; /* First attempt, try top-left of the screen */ const Window *main_toolbar = FindWindowByClass(WC_MAIN_TOOLBAR); - if (IsGoodAutoPlace1(0, main_toolbar != NULL ? main_toolbar->height + 2 : 2, width, height, pt)) return pt; + if (vertical_toolbar) { + if (IsGoodAutoPlace1(main_toolbar != NULL ? main_toolbar->width : 0, 0, width, height, pt)) return pt; + } else { + if (IsGoodAutoPlace1(0, main_toolbar != NULL ? main_toolbar->height : 0, width, height, pt)) return pt; + } /* Second attempt, try around all existing windows with a distance of 2 pixels. * The new window must be entirely on-screen, and not overlap with an existing window. @@ -1654,6 +1693,10 @@ static Point GetAutoPlacePosition(int width, int height) * of (+5, +5) */ int left = 0, top = 24; + if (vertical_toolbar) { + left = main_toolbar != NULL ? main_toolbar->width : 0; + top = 0; + } restart: FOR_ALL_WINDOWS_FROM_BACK(w) { @@ -1679,7 +1722,15 @@ Point GetToolbarAlignedWindowPosition(int window_width) { const Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0); assert(w != NULL); - Point pt = { _current_text_dir == TD_RTL ? w->left : (w->left + w->width) - window_width, w->top + w->height }; + Point pt; + if (_settings_client.gui.vertical_toolbar && _game_mode != GM_EDITOR) { + // Retermine if the window was opened from the left or the right toolbar + pt.x = (_last_clicked_toolbar_idx == 0) ? w->left + w->width : _screen.width - w->width - window_width; + pt.y = w->top; + } else { + pt.x = _current_text_dir == TD_RTL ? w->left : (w->left + w->width) - window_width; + pt.y = w->top + w->height; + } return pt; } @@ -1708,7 +1759,7 @@ static Point LocalGetWindowPlacement(const WindowDesc *desc, int16 sm_width, int int16 default_width = max(desc->GetDefaultWidth(), sm_width); int16 default_height = max(desc->GetDefaultHeight(), sm_height); - if (desc->parent_cls != 0 /* WC_MAIN_WINDOW */ && + if (desc->parent_cls != WC_NONE && (w = FindWindowById(desc->parent_cls, window_number)) != NULL && w->left < _screen.width - 20 && w->left > -60 && w->top < _screen.height - 20) { @@ -1716,6 +1767,13 @@ static Point LocalGetWindowPlacement(const WindowDesc *desc, int16 sm_width, int if (pt.x > _screen.width + 10 - default_width) { pt.x = (_screen.width + 10 - default_width) - 20; } + const Window *wt = FindWindowById(WC_MAIN_TOOLBAR_RIGHT, 0); + if (wt && (pt.x + default_width > _screen.width - wt->width || + desc->parent_cls == WC_BUILD_TOOLBAR || desc->parent_cls == WC_SCEN_LAND_GEN)) { + // Move all build toolbar windows to the right, because all build toolbars are always at the right part of the screen + pt.x = _screen.width - wt->width - default_width; + } + pt.y = w->top + ((desc->parent_cls == WC_BUILD_TOOLBAR || desc->parent_cls == WC_SCEN_LAND_GEN) ? w->height : 10); return pt; } @@ -1741,6 +1799,8 @@ static Point LocalGetWindowPlacement(const WindowDesc *desc, int16 sm_width, int NOT_REACHED(); } + // try to put it to + return pt; } @@ -1818,6 +1878,21 @@ Window *FindWindowFromPt(int x, int y) return NULL; } +int SETTING_BUTTON_WIDTH = 20; +int SETTING_BUTTON_HEIGHT = 10; + +/** + * Set button size of settings. If automatic sizing is also enabled, it also sets + * the sizing of buttons, scrollbars and font size (recommend restart). + * @todo Check if it can be moved to another file, so we do not need to include error, string and fontcache headers. + * @todo Fix magic numbers 16/18/20/30/32 + */ +void CheckWindowMinSizings() +{ + SETTING_BUTTON_HEIGHT = GetMinSizing(NWST_STEP); + SETTING_BUTTON_WIDTH = 2 * SETTING_BUTTON_HEIGHT; +} + /** * (re)initialize the windowing system */ @@ -2045,7 +2120,10 @@ static void EnsureVisibleCaption(Window *w, int nx, int ny) ny = Clamp(ny, 0, _screen.height - MIN_VISIBLE_TITLE_BAR); /* Make sure the title bar isn't hidden behind the main tool bar or the status bar. */ - PreventHiding(&nx, &ny, caption_rect, FindWindowById(WC_MAIN_TOOLBAR, 0), w->left, PHD_DOWN); + if (!_settings_client.gui.vertical_toolbar || _game_mode == GM_EDITOR) { + // This call hides the window totally with vertical toolbar if you move it slightly off-screen to the left + PreventHiding(&nx, &ny, caption_rect, FindWindowById(WC_MAIN_TOOLBAR, 0), w->left, PHD_DOWN); + } PreventHiding(&nx, &ny, caption_rect, FindWindowById(WC_STATUS_BAR, 0), w->left, PHD_UP); } @@ -2106,6 +2184,7 @@ void ResizeWindow(Window *w, int delta_x, int delta_y, bool clamp_to_screen) */ int GetMainViewTop() { + if (_settings_client.gui.vertical_toolbar && _game_mode != GM_EDITOR) return 0; Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0); return (w == NULL) ? 0 : w->top + w->height; } @@ -2361,7 +2440,7 @@ static EventState HandleScrollbarScrolling() if (sb->disp_flags & ND_SCROLLBAR_BTN) { if (_scroller_click_timeout == 1) { - _scroller_click_timeout = 3; + _scroller_click_timeout = SCROLLER_CLICK_DELAY; sb->UpdatePosition(rtl == HasBit(sb->disp_flags, NDB_SCROLLBAR_UP) ? 1 : -1); w->SetDirty(); } @@ -2390,6 +2469,21 @@ static EventState HandleViewportScroll() { bool scrollwheel_scrolling = _settings_client.gui.scrollwheel_scrolling == 1 && (_cursor.v_wheel != 0 || _cursor.h_wheel != 0); + if (_settings_client.gui.left_mouse_btn_scrolling) { + // Do not open vehicle/town info window while scrolling with left mouse button + static int oldDx = 0, oldDy = 0; + if (_left_button_down) { + oldDx += _cursor.delta.x; + oldDy += _cursor.delta.y; + if (!_left_button_dragged && abs(oldDx) + abs(oldDy) > 20) { + _left_button_dragged = true; + } + } else { + oldDx = 0; + oldDy = 0; + } + } + if (!_scrolling_viewport) return ES_NOT_HANDLED; /* When we don't have a last scroll window we are starting to scroll. @@ -2397,7 +2491,9 @@ static EventState HandleViewportScroll() * outside of the window and should not left-mouse scroll anymore. */ if (_last_scroll_window == NULL) _last_scroll_window = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); - if (_last_scroll_window == NULL || !(_right_button_down || scrollwheel_scrolling || (_settings_client.gui.left_mouse_btn_scrolling && _left_button_down))) { + + if (_last_scroll_window == NULL || !(_right_button_down || scrollwheel_scrolling || + (_left_button_down && (_move_pressed || _settings_client.gui.left_mouse_btn_scrolling)))) { _cursor.fix_at = false; _scrolling_viewport = false; _last_scroll_window = NULL; @@ -2686,12 +2782,14 @@ static int _input_events_this_tick = 0; */ static void HandleAutoscroll() { + _move_pressed = false; if (_game_mode == GM_MENU || HasModalProgress()) return; if (_settings_client.gui.auto_scrolling == VA_DISABLED) return; if (_settings_client.gui.auto_scrolling == VA_MAIN_VIEWPORT_FULLSCREEN && !_fullscreen) return; int x = _cursor.pos.x; int y = _cursor.pos.y; + int border = RescaleFrom854x480(_settings_client.gui.min_button); Window *w = FindWindowFromPt(x, y); if (w == NULL || w->flags & WF_DISABLE_VP_SCROLL) return; if (_settings_client.gui.auto_scrolling != VA_EVERY_VIEWPORT && w->window_class != WC_MAIN_WINDOW) return; @@ -2703,16 +2801,38 @@ static void HandleAutoscroll() y -= vp->top; /* here allows scrolling in both x and y axis */ -#define scrollspeed 3 - if (x - 15 < 0) { - w->viewport->dest_scrollpos_x += ScaleByZoom((x - 15) * scrollspeed, vp->zoom); - } else if (15 - (vp->width - x) > 0) { - w->viewport->dest_scrollpos_x += ScaleByZoom((15 - (vp->width - x)) * scrollspeed, vp->zoom); +#define scrollspeed 15 + if (x - border < 0) { + _move_pressed = true; + w->viewport->dest_scrollpos_x += ScaleByZoom(-scrollspeed, vp->zoom); + } else if (border - (vp->width - x) > 0) { + _move_pressed = true; + w->viewport->dest_scrollpos_x += ScaleByZoom(scrollspeed, vp->zoom); } - if (y - 15 < 0) { - w->viewport->dest_scrollpos_y += ScaleByZoom((y - 15) * scrollspeed, vp->zoom); - } else if (15 - (vp->height - y) > 0) { - w->viewport->dest_scrollpos_y += ScaleByZoom((15 - (vp->height - y)) * scrollspeed, vp->zoom); + if (y - border * 2 < 0) { // Border twice thicker, to accomodate top toolbar + _move_pressed = true; + w->viewport->dest_scrollpos_y += ScaleByZoom(-scrollspeed, vp->zoom); + } else if (border - (vp->height - y) > 0) { // Same thickness, because bottom toolbar does not cover whole screen width + _move_pressed = true; + w->viewport->dest_scrollpos_y += ScaleByZoom(scrollspeed, vp->zoom); + } +#undef scrollspeed +} + +/** + * Perform small continuous scrolling with right button press and drag. + */ +static void HandleContinuousScroll() +{ +#define scrollspeed 0.05f + if (_scrolling_viewport && _right_button_down) { + Window *w = FindWindowFromPt(_right_button_down_pos.x, _right_button_down_pos.y); + if (w == NULL || w->flags & WF_DISABLE_VP_SCROLL) return; + ViewPort *vp = IsPtInWindowViewport(w, _right_button_down_pos.x, _right_button_down_pos.y); + if (vp == NULL) return; + + w->viewport->dest_scrollpos_x += ScaleByZoom(scrollspeed * (_right_button_down_pos.x - _cursor.pos.x), vp->zoom); + w->viewport->dest_scrollpos_y += ScaleByZoom(scrollspeed * (_right_button_down_pos.y - _cursor.pos.y), vp->zoom); } #undef scrollspeed } @@ -2720,6 +2840,7 @@ static void HandleAutoscroll() enum MouseClick { MC_NONE = 0, MC_LEFT, + MC_LEFT_UP, MC_RIGHT, MC_DOUBLE_LEFT, MC_HOVER, @@ -2787,6 +2908,16 @@ static void MouseLoop(MouseClick click, int mousewheel) * But there is no company related window open anyway, so _current_company is not used. */ assert(HasModalProgress() || IsLocalCompany()); + static bool mouse_down_on_viewport = false; + int x = _cursor.pos.x; + int y = _cursor.pos.y; + Window *w = FindWindowFromPt(x, y); + if (w == NULL) return; + ViewPort *vp = IsPtInWindowViewport(w, x, y); + + /* Don't allow any action in a viewport if either in menu or when having a modal progress window */ + if (vp != NULL && (_game_mode == GM_MENU || HasModalProgress())) return; + HandlePlacePresize(); UpdateTileSelection(); @@ -2801,16 +2932,9 @@ static void MouseLoop(MouseClick click, int mousewheel) bool scrollwheel_scrolling = _settings_client.gui.scrollwheel_scrolling == 1 && (_cursor.v_wheel != 0 || _cursor.h_wheel != 0); if (click == MC_NONE && mousewheel == 0 && !scrollwheel_scrolling) return; - int x = _cursor.pos.x; - int y = _cursor.pos.y; - Window *w = FindWindowFromPt(x, y); if (w == NULL) return; - if (click != MC_HOVER && !MaybeBringWindowToFront(w)) return; - ViewPort *vp = IsPtInWindowViewport(w, x, y); - - /* Don't allow any action in a viewport if either in menu or when having a modal progress window */ - if (vp != NULL && (_game_mode == GM_MENU || HasModalProgress())) return; + if (click != MC_NONE && click != MC_HOVER && click != MC_LEFT_UP && !MaybeBringWindowToFront(w)) return; if (mousewheel != 0) { /* Send mousewheel event to window */ @@ -2827,10 +2951,23 @@ static void MouseLoop(MouseClick click, int mousewheel) case MC_LEFT: if (!HandleViewportClicked(vp, x, y) && !(w->flags & WF_DISABLE_VP_SCROLL) && - _settings_client.gui.left_mouse_btn_scrolling) { + (_settings_client.gui.left_mouse_btn_scrolling || _move_pressed)) { _scrolling_viewport = true; _cursor.fix_at = false; + } else { + // Viewport already clicked, prevent sending same event on mouse-up + _left_button_dragged = true; } + mouse_down_on_viewport = true; + break; + + case MC_LEFT_UP: + if (!_left_button_dragged && mouse_down_on_viewport) { + HandleViewportMouseUp(vp, x, y); + MoveAllHiddenWindowsBackToScreen(); + } + _left_button_dragged = false; + mouse_down_on_viewport = false; break; case MC_RIGHT: @@ -2849,6 +2986,9 @@ static void MouseLoop(MouseClick click, int mousewheel) } } else { switch (click) { + case MC_LEFT_UP: + break; + case MC_LEFT: case MC_DOUBLE_LEFT: DispatchLeftClickEvent(w, x - w->left, y - w->top, click == MC_DOUBLE_LEFT ? 2 : 1); @@ -2878,6 +3018,7 @@ void HandleMouseEvents() static int double_click_time = 0; static Point double_click_pos = {0, 0}; + static bool left_button_released = false; /* Mouse event? */ MouseClick click = MC_NONE; @@ -2891,11 +3032,17 @@ void HandleMouseEvents() double_click_time = _realtime_tick; double_click_pos = _cursor.pos; _left_button_clicked = true; + left_button_released = false; _input_events_this_tick++; } else if (_right_button_clicked) { _right_button_clicked = false; click = MC_RIGHT; _input_events_this_tick++; + } else if(!_left_button_down && !left_button_released) { + click = MC_LEFT_UP; + left_button_released = true; + _left_button_clicked = false; + _input_events_this_tick++; } int mousewheel = 0; @@ -3010,6 +3157,7 @@ void InputLoop() /* HandleMouseEvents was already called for this tick */ HandleMouseEvents(); HandleAutoscroll(); + HandleContinuousScroll(); } /** @@ -3226,6 +3374,7 @@ restart_search: if (w->window_class != WC_MAIN_WINDOW && w->window_class != WC_SELECT_GAME && w->window_class != WC_MAIN_TOOLBAR && + w->window_class != WC_MAIN_TOOLBAR_RIGHT && w->window_class != WC_STATUS_BAR && w->window_class != WC_TOOLTIPS && (w->flags & WF_STICKY) == 0) { // do not delete windows which are 'pinned' @@ -3284,10 +3433,33 @@ restart_search: FOR_ALL_WINDOWS_FROM_BACK(w) w->SetDirty(); } +/** + * Delete all windows that are linked to the main toolbar. + * Once done with that, refresh other windows too. + */ +void DeleteToolbarLinkedWindows() +{ + Window *w; + +restart_search: + /* When we find the window to delete, we need to restart the search + * as deleting this window could cascade in deleting (many) others + * anywhere in the z-array */ + FOR_ALL_WINDOWS_FROM_BACK(w) { + if (w->window_desc->default_pos == WDP_ALIGN_TOOLBAR) { + delete w; + goto restart_search; + } + } + + FOR_ALL_WINDOWS_FROM_BACK(w) w->SetDirty(); +} + /** Delete all always on-top windows to get an empty screen */ void HideVitalWindows() { DeleteWindowById(WC_MAIN_TOOLBAR, 0); + DeleteWindowById(WC_MAIN_TOOLBAR_RIGHT, 0); DeleteWindowById(WC_STATUS_BAR, 0); } @@ -3346,6 +3518,7 @@ static int PositionWindow(Window *w, WindowClass clss, int setting) */ int PositionMainToolbar(Window *w) { + if (_settings_client.gui.vertical_toolbar && _game_mode != GM_EDITOR) return 0; /* Always at the left */ DEBUG(misc, 5, "Repositioning Main Toolbar..."); return PositionWindow(w, WC_MAIN_TOOLBAR, _settings_client.gui.toolbar_pos); } @@ -3427,13 +3600,20 @@ void RelocateAllWindows(int neww, int newh) left = PositionMainToolbar(w); // changes toolbar orientation break; + case WC_MAIN_TOOLBAR_RIGHT: + ResizeWindow(w, min(neww, _toolbar_width) - w->width, 0, false); + + top = w->top; + left = neww - w->width; + break; + case WC_NEWS_WINDOW: top = newh - w->height; left = PositionNewsMessage(w); break; case WC_STATUS_BAR: - ResizeWindow(w, min(neww, _toolbar_width) - w->width, 0, false); + ResizeWindow(w, min(neww, min(_toolbar_width, _screen.width - SETTING_BUTTON_HEIGHT * 2)) - w->width, 0, false); top = newh - w->height; left = PositionStatusbar(w); @@ -3471,6 +3651,65 @@ void RelocateAllWindows(int neww, int newh) } } +static void MoveAllWindowsOffScreen(bool moveOffScreen) +{ + Window *w; + bool updateScreen = false; + + FOR_ALL_WINDOWS_FROM_BACK(w) { + switch (w->window_class) { + case WC_MAIN_WINDOW: + case WC_BUILD_CONFIRMATION: + case WC_BOOTSTRAP: + case WC_MAIN_TOOLBAR: + case WC_MAIN_TOOLBAR_RIGHT: + case WC_NEWS_WINDOW: + case WC_STATUS_BAR: + case WC_SEND_NETWORK_MSG: + case WC_CONSOLE: + continue; + + default: + if (moveOffScreen) { + if (w->left < _screen.width) { + w->left += _screen.width; + if (w->viewport != NULL) { + w->viewport->left += _screen.width; + } + //w->SetDirty(); + updateScreen = true; + } + } else { + if (w->left >= _screen.width) { + w->left -= _screen.width; + if (w->viewport != NULL) { + w->viewport->left -= _screen.width; + } + w->SetDirty(); + //updateScreen = true; + } + } + break; + } + } + if (updateScreen) { + w = FindWindowById(WC_MAIN_WINDOW, 0); + if (w) { + w->SetDirty(); + } + } +} + +void MoveAllWindowsOffScreen() +{ + MoveAllWindowsOffScreen(true); +} + +void MoveAllHiddenWindowsBackToScreen() +{ + MoveAllWindowsOffScreen(false); +} + /** * Destructor of the base class PickerWindowBase * Main utility is to stop the base Window destructor from triggering diff --git a/src/window_func.h b/src/window_func.h index 453b889789..335ab9eae3 100644 --- a/src/window_func.h +++ b/src/window_func.h @@ -29,6 +29,7 @@ int PositionNetworkChatWindow(Window *w); int GetMainViewTop(); int GetMainViewBottom(); +void CheckWindowMinSizings(); void InitWindowSystem(); void UnInitWindowSystem(); void ResetWindowSystem(); @@ -41,6 +42,7 @@ void InvalidateWindowClassesData(WindowClass cls, int data = 0, bool gui_scope = void DeleteNonVitalWindows(); void DeleteAllNonVitalWindows(); void DeleteConstructionWindows(); +void DeleteToolbarLinkedWindows(); void HideVitalWindows(); void ShowVitalWindows(); diff --git a/src/window_gui.h b/src/window_gui.h index b81b06e391..1a02df14bf 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -747,6 +747,10 @@ public: */ virtual void OnPlaceObjectAbort() {} + /** + * Select the cancelled tool again, this is called after OnPlaceObjectAbort() + */ + virtual void SelectLastTool() {} /** * The user is dragging over the map when the tile highlight mode @@ -864,6 +868,8 @@ Wcls *AllocateWindowDescFront(WindowDesc *desc, int window_number, bool return_e } void RelocateAllWindows(int neww, int newh); +void MoveAllWindowsOffScreen(); +void MoveAllHiddenWindowsBackToScreen(); /* misc_gui.cpp */ enum TooltipCloseCondition { @@ -888,6 +894,9 @@ extern Point _cursorpos_drag_start; extern int _scrollbar_start_pos; extern int _scrollbar_size; extern byte _scroller_click_timeout; +enum { + SCROLLER_CLICK_DELAY = 6 ///< Delay in video frames between scrollbar doing scroll, we don't want to get to the bottom of the list in an instant +}; extern bool _scrolling_viewport; extern bool _mouse_hovering; diff --git a/src/window_type.h b/src/window_type.h index 809e81d485..91c0f25c82 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -52,6 +52,19 @@ enum WindowClass { */ WC_MAIN_TOOLBAR, + /** + * Right part of split main toolbar; %Window numbers: + * - 0 = #ToolbarNormalWidgets + * - 0 = #ToolbarEditorWidgets + */ + WC_MAIN_TOOLBAR_RIGHT, + + /** + * Confirmation window for building anything; %Window numbers: + * - 0 = #BuildConfirmationWidgets + */ + WC_BUILD_CONFIRMATION, + /** * Statusbar (at the bottom of your screen); %Window numbers: * - 0 = #StatusbarWidgets diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000000..4f807fab64 --- /dev/null +++ b/todo.txt @@ -0,0 +1,21 @@ + +- 'Place Sign' does not work. Landscaping - Place Sign works. + +- Smallmap UI won't fit all FIRS industries. + +- Fix text input - it should use SDL_ANDROID_GetScreenKeyboardTextInputAsync(), and fix double-backspace bug in SDL. + +- Put mouse cursor in the middle between touch points when zooming in and out. + +- Option to remove all window titles. + +- Move and resize all windows with two-finger gestures. + +- Windows can cover status bar. + +- Close news window by flicking it sideways. + +- Default button size set to 48, update vertical toolbar buttons. + +- Remove Shift key from toolbar, it's not needed anymore. +