summaryrefslogtreecommitdiff
path: root/src/newgrf_gui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/newgrf_gui.cpp')
-rw-r--r--src/newgrf_gui.cpp164
1 files changed, 161 insertions, 3 deletions
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<NWidgetBase>(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),