From 8755c26793e9ba8f49cef7303e7b7517c69231e9 Mon Sep 17 00:00:00 2001 From: alberth Date: Sat, 24 May 2014 19:11:20 +0000 Subject: (svn r26610) -Feature: Select an editable preset name for saving. --- src/lang/english.txt | 10 ++ src/newgrf_gui.cpp | 164 ++++++++++++++++++++++++- src/script/api/game/game_window.hpp.sq | 6 + src/script/api/script_window.hpp | 17 ++- src/script/api/template/template_window.hpp.sq | 2 + src/widgets/newgrf_widget.h | 9 ++ src/window.cpp | 1 + src/window_type.h | 8 +- 8 files changed, 212 insertions(+), 5 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 69c33bd3c..bd60237db 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2783,6 +2783,16 @@ STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}Matching f STR_NEWGRF_SETTINGS_DISABLED :{RED}Disabled STR_NEWGRF_SETTINGS_INCOMPATIBLE :{RED}Incompatible with this version of OpenTTD +# NewGRF save preset window +STR_SAVE_PRESET_CAPTION :{WHITE}Save preset +STR_SAVE_PRESET_LIST_TOOLTIP :{BLACK}List of available presets, select one to copy it to the save name below +STR_SAVE_PRESET_TITLE :{BLACK}Enter a name for the preset +STR_SAVE_PRESET_EDITBOX_TOOLTIP :{BLACK}Currently selected name for the preset to save +STR_SAVE_PRESET_CANCEL :{BLACK}Cancel +STR_SAVE_PRESET_CANCEL_TOOLTIP :{BLACK}Don't change the preset +STR_SAVE_PRESET_SAVE :{BLACK}Save +STR_SAVE_PRESET_SAVE_TOOLTIP :{BLACK}Save the preset to the current selected name + # NewGRF parameters window STR_NEWGRF_PARAMETERS_CAPTION :{WHITE}Change NewGRF parameters STR_NEWGRF_PARAMETERS_CLOSE :{BLACK}Close diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 462360d59..b919edfaa 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -567,7 +567,7 @@ void ShowNewGRFTextfileWindow(TextfileType file_type, const GRFConfig *c) new NewGRFTextfileWindow(file_type, c); } -static GRFPresetList _grf_preset_list; +static GRFPresetList _grf_preset_list; ///< List of known NewGRF presets. @see GetGRFPresetList class DropDownListPresetItem : public DropDownListItem { public: @@ -587,6 +587,7 @@ public: }; static void NewGRFConfirmationCallback(Window *w, bool confirmed); +static void ShowSavePresetWindow(const char *initial_text); /** * Window for showing NewGRF files @@ -614,7 +615,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { bool editable; ///< Is the window editable? bool show_params; ///< Are the grf-parameters shown in the info-panel? bool execute; ///< On pressing 'apply changes' are grf changes applied immediately, or only list is updated. - int preset; ///< Selected preset. + int preset; ///< Selected preset or \c -1 if none selected. int active_over; ///< Active GRF item over which another one is dragged, \c -1 if none. Scrollbar *vscroll; @@ -665,6 +666,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { { DeleteWindowByClass(WC_GRF_PARAMETERS); DeleteWindowByClass(WC_TEXTFILE); + DeleteWindowByClass(WC_SAVE_PRESET); if (this->editable && !this->execute) { CopyGRFConfigList(this->orig_list, this->actives, true); @@ -908,7 +910,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } case WID_NS_PRESET_SAVE: - ShowQueryString(STR_EMPTY, STR_NEWGRF_SETTINGS_PRESET_SAVE_QUERY, 32, this, CS_ALPHANUMERAL, QSF_NONE); + ShowSavePresetWindow((this->preset == -1) ? NULL : _grf_preset_list[this->preset]); break; case WID_NS_PRESET_DELETE: @@ -1940,6 +1942,162 @@ void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFC new NewGRFWindow(&_newgrf_desc, editable, show_params, exec_changes, config); } +/** Widget parts of the save preset window. */ +static const NWidgetPart _nested_save_preset_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_SAVE_PRESET_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_INSET, COLOUR_GREY, WID_SVP_PRESET_LIST), SetPadding(2, 1, 0, 2), + SetDataTip(0x0, STR_SAVE_PRESET_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SVP_SCROLLBAR), EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SVP_SCROLLBAR), + EndContainer(), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SVP_EDITBOX), SetPadding(3, 2, 2, 2), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_SAVE_PRESET_TITLE, STR_SAVE_PRESET_EDITBOX_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SVP_CANCEL), SetDataTip(STR_SAVE_PRESET_CANCEL, STR_SAVE_PRESET_CANCEL_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SVP_SAVE), SetDataTip(STR_SAVE_PRESET_SAVE, STR_SAVE_PRESET_SAVE_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_RESIZEBOX, COLOUR_GREY), + EndContainer(), +}; + +/** Window description of the preset save window. */ +static WindowDesc _save_preset_desc( + WDP_CENTER, "save_preset", 140, 110, + WC_SAVE_PRESET, WC_GAME_OPTIONS, + WDF_MODAL, + _nested_save_preset_widgets, lengthof(_nested_save_preset_widgets) +); + +/** Class for the save preset window. */ +struct SavePresetWindow : public Window { + QueryString presetname_editbox; ///< Edit box of the save preset. + GRFPresetList presets; ///< Available presets. + Scrollbar *vscroll; ///< Pointer to the scrollbar widget. + int selected; ///< Selected entry in the preset list, or \c -1 if none selected. + + /** + * Constructor of the save preset window. + * @param initial_text Initial text to display in the edit box, or \c NULL. + */ + SavePresetWindow(const char *initial_text) : Window(&_save_preset_desc), presetname_editbox(32) + { + GetGRFPresetList(&this->presets); + this->selected = -1; + if (initial_text != NULL) { + for (uint i = 0; i < this->presets.Length(); i++) { + if (!strcmp(initial_text, this->presets[i])) { + this->selected = i; + break; + } + } + } + + this->querystrings[WID_SVP_EDITBOX] = &this->presetname_editbox; + this->presetname_editbox.ok_button = WID_SVP_SAVE; + this->presetname_editbox.cancel_button = WID_SVP_CANCEL; + + this->CreateNestedTree(); + this->vscroll = this->GetScrollbar(WID_SVP_SCROLLBAR); + this->FinishInitNested(0); + + this->vscroll->SetCount(this->presets.Length()); + this->SetFocusedWidget(WID_SVP_EDITBOX); + if (initial_text != NULL) this->presetname_editbox.text.Assign(initial_text); + } + + ~SavePresetWindow() + { + } + + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + { + switch (widget) { + case WID_SVP_PRESET_LIST: { + resize->height = FONT_HEIGHT_NORMAL + 2U; + size->height = 0; + for (uint i = 0; i < this->presets.Length(); i++) { + Dimension d = GetStringBoundingBox(this->presets[i]); + size->width = max(size->width, d.width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT); + resize->height = max(resize->height, d.height); + } + size->height = ClampU(this->presets.Length(), 5, 20) * resize->height + 1; + break; + } + } + } + + virtual void DrawWidget(const Rect &r, int widget) const + { + switch (widget) { + case WID_SVP_PRESET_LIST: { + GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); + + uint step_height = this->GetWidget(WID_SVP_PRESET_LIST)->resize_y; + int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; + uint y = r.top + WD_FRAMERECT_TOP; + uint min_index = this->vscroll->GetPosition(); + uint max_index = min(min_index + this->vscroll->GetCapacity(), this->presets.Length()); + + for (uint i = min_index; i < max_index; i++) { + if ((int)i == this->selected) GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 2, PC_DARK_BLUE); + + const char *text = this->presets[i]; + DrawString(r.left + WD_FRAMERECT_LEFT, r.right, y + offset_y, text, ((int)i == this->selected) ? TC_WHITE : TC_SILVER); + y += step_height; + } + break; + } + } + } + + virtual void OnClick(Point pt, int widget, int click_count) + { + switch (widget) { + case WID_SVP_PRESET_LIST: { + uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SVP_PRESET_LIST); + if (row < this->presets.Length()) { + this->selected = row; + this->presetname_editbox.text.Assign(this->presets[row]); + this->SetWidgetDirty(WID_SVP_PRESET_LIST); + this->SetWidgetDirty(WID_SVP_EDITBOX); + } + break; + } + + case WID_SVP_CANCEL: + delete this; + break; + + case WID_SVP_SAVE: { + Window *w = FindWindowById(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE); + if (w != NULL && !StrEmpty(this->presetname_editbox.text.buf)) w->OnQueryTextFinished(this->presetname_editbox.text.buf); + delete this; + break; + } + } + } + + virtual void OnResize() + { + this->vscroll->SetCapacityFromWidget(this, WID_SVP_PRESET_LIST); + } +}; + +/** + * Open the window for saving a preset. + * @param initial_text Initial text to display in the edit box, or \c NULL. + */ +static void ShowSavePresetWindow(const char *initial_text) +{ + DeleteWindowByClass(WC_SAVE_PRESET); + new SavePresetWindow(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), diff --git a/src/script/api/game/game_window.hpp.sq b/src/script/api/game/game_window.hpp.sq index 52e570ef0..ef8f3da42 100644 --- a/src/script/api/game/game_window.hpp.sq +++ b/src/script/api/game/game_window.hpp.sq @@ -137,6 +137,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WC_NEWGRF_INSPECT, "WC_NEWGRF_INSPECT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WC_SPRITE_ALIGNER, "WC_SPRITE_ALIGNER"); SQGSWindow.DefSQConst(engine, ScriptWindow::WC_LINKGRAPH_LEGEND, "WC_LINKGRAPH_LEGEND"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WC_SAVE_PRESET, "WC_SAVE_PRESET"); SQGSWindow.DefSQConst(engine, ScriptWindow::WC_INVALID, "WC_INVALID"); SQGSWindow.DefSQConst(engine, ScriptWindow::TC_BLUE, "TC_BLUE"); SQGSWindow.DefSQConst(engine, ScriptWindow::TC_SILVER, "TC_SILVER"); @@ -806,6 +807,11 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_CONTENT_DOWNLOAD2, "WID_NS_CONTENT_DOWNLOAD2"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_SHOW_REMOVE, "WID_NS_SHOW_REMOVE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_SHOW_APPLY, "WID_NS_SHOW_APPLY"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SVP_PRESET_LIST, "WID_SVP_PRESET_LIST"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SVP_SCROLLBAR, "WID_SVP_SCROLLBAR"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SVP_EDITBOX, "WID_SVP_EDITBOX"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SVP_CANCEL, "WID_SVP_CANCEL"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SVP_SAVE, "WID_SVP_SAVE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SP_PROGRESS_BAR, "WID_SP_PROGRESS_BAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SP_PROGRESS_TEXT, "WID_SP_PROGRESS_TEXT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_N_PANEL, "WID_N_PANEL"); diff --git a/src/script/api/script_window.hpp b/src/script/api/script_window.hpp index 28db09859..21cf28f7a 100644 --- a/src/script/api/script_window.hpp +++ b/src/script/api/script_window.hpp @@ -753,11 +753,17 @@ public: WC_SPRITE_ALIGNER = ::WC_SPRITE_ALIGNER, /** - * Linkgraph legend; Window numbers: + * Linkgraph legend; %Window numbers: * - 0 = #LinkGraphWidgets */ WC_LINKGRAPH_LEGEND = ::WC_LINKGRAPH_LEGEND, + /** + * Save preset; %Window numbers: + * - 0 = #SavePresetWidgets + */ + WC_SAVE_PRESET = ::WC_SAVE_PRESET, + WC_INVALID = ::WC_INVALID, ///< Invalid window. }; @@ -1835,6 +1841,15 @@ public: WID_NS_SHOW_APPLY = ::WID_NS_SHOW_APPLY, ///< Select display of the buttons below the 'details'. }; + /** Widgets of the #SavePresetWindow class. */ + enum SavePresetWidgets { + WID_SVP_PRESET_LIST = ::WID_SVP_PRESET_LIST, ///< List with available preset names. + WID_SVP_SCROLLBAR = ::WID_SVP_SCROLLBAR, ///< Scrollbar for the list available preset names. + WID_SVP_EDITBOX = ::WID_SVP_EDITBOX, ///< Edit box for changing the preset name. + WID_SVP_CANCEL = ::WID_SVP_CANCEL, ///< Button to cancel saving the preset. + WID_SVP_SAVE = ::WID_SVP_SAVE, ///< Button to save the preset. + }; + /** Widgets of the #ScanProgressWindow class. */ enum ScanProgressWidgets { WID_SP_PROGRESS_BAR = ::WID_SP_PROGRESS_BAR, ///< Simple progress bar. diff --git a/src/script/api/template/template_window.hpp.sq b/src/script/api/template/template_window.hpp.sq index 9f01e42d5..a21a75ab8 100644 --- a/src/script/api/template/template_window.hpp.sq +++ b/src/script/api/template/template_window.hpp.sq @@ -161,6 +161,8 @@ namespace SQConvert { template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::NewGRFParametersWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptWindow::NewGRFStateWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::NewGRFStateWidgets)tmp; } template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::NewGRFStateWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } + template <> inline ScriptWindow::SavePresetWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::SavePresetWidgets)tmp; } + template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::SavePresetWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptWindow::ScanProgressWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::ScanProgressWidgets)tmp; } template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::ScanProgressWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptWindow::NewsWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::NewsWidgets)tmp; } diff --git a/src/widgets/newgrf_widget.h b/src/widgets/newgrf_widget.h index 878dcb891..c0c00ed8b 100644 --- a/src/widgets/newgrf_widget.h +++ b/src/widgets/newgrf_widget.h @@ -60,6 +60,15 @@ enum NewGRFStateWidgets { WID_NS_SHOW_APPLY, ///< Select display of the buttons below the 'details'. }; +/** Widgets of the #SavePresetWindow class. */ +enum SavePresetWidgets { + WID_SVP_PRESET_LIST, ///< List with available preset names. + WID_SVP_SCROLLBAR, ///< Scrollbar for the list available preset names. + WID_SVP_EDITBOX, ///< Edit box for changing the preset name. + WID_SVP_CANCEL, ///< Button to cancel saving the preset. + WID_SVP_SAVE, ///< Button to save the preset. +}; + /** Widgets of the #ScanProgressWindow class. */ enum ScanProgressWidgets { WID_SP_PROGRESS_BAR, ///< Simple progress bar. diff --git a/src/window.cpp b/src/window.cpp index 32b7ce4fe..5b3511573 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1267,6 +1267,7 @@ static uint GetWindowZPriority(const Window *w) case WC_CONFIRM_POPUP_QUERY: case WC_MODAL_PROGRESS: case WC_NETWORK_STATUS_WINDOW: + case WC_SAVE_PRESET: ++z_priority; case WC_GENERATE_LANDSCAPE: diff --git a/src/window_type.h b/src/window_type.h index 9727cf9f1..a8a8128f5 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -670,11 +670,17 @@ enum WindowClass { WC_SPRITE_ALIGNER, /** - * Linkgraph legend; Window numbers: + * Linkgraph legend; %Window numbers: * - 0 = #LinkGraphWidgets */ WC_LINKGRAPH_LEGEND, + /** + * Save preset; %Window numbers: + * - 0 = #SavePresetWidgets + */ + WC_SAVE_PRESET, + WC_INVALID = 0xFFFF, ///< Invalid window. }; -- cgit v1.2.3-54-g00ecf