# HG changeset patch # User rubidium # Date 2011-08-21 12:53:13 # Node ID c07585e51a286cc511f5c0f9d4a13f24db7e9c13 # Parent 5601372941d21a3203d45c2573faa1f3c55ca902 (svn r22797) -Add: progress bar for scanning NewGRFs diff --git a/src/lang/english.txt b/src/lang/english.txt --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2521,6 +2521,11 @@ STR_NEWGRF_INVALID_CARGO_QUANTITY STR_NEWGRF_INVALID_ENGINE : STR_NEWGRF_INVALID_INDUSTRYTYPE : +# NewGRF scanning window +STR_NEWGRF_SCAN_CAPTION :{WHITE}Scanning NewGRFs +STR_NEWGRF_SCAN_MESSAGE :{BLACK}Scanning NewGRFs. Depending on the amount this can take a while... +STR_NEWGRF_SCAN_STATUS :{BLACK}{NUM} NewGRF{P "" s} scanned out of an estimated {NUM} NewGRF{P "" s} + # Sign list window STR_SIGN_LIST_CAPTION :{WHITE}Sign List - {COMMA} Sign{P "" s} STR_SIGN_LIST_MATCH_CASE :{BLACK}Match case diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -543,7 +543,11 @@ public: static uint DoScan() { GRFFileScanner fs; - return fs.Scan(".grf", DATA_DIR); + int ret = fs.Scan(".grf", DATA_DIR); + /* The number scanned and the number returned may not be the same; + * duplicate NewGRFs and base sets are ignored in the return value. */ + _settings_client.gui.last_newgrf_count = fs.num_scanned; + return ret; } }; @@ -588,7 +592,7 @@ bool GRFFileScanner::AddFile(const char const char *name = NULL; if (c->name != NULL) name = GetGRFStringFromGRFText(c->name->text); if (name == NULL) name = c->filename; - DEBUG(grf, 0, "Scanning %i: %s", this->num_scanned, name); + UpdateNewGRFScanStatus(this->num_scanned, name); _modal_progress_work_mutex->BeginCritical(); _modal_progress_paint_mutex->EndCritical(); diff --git a/src/newgrf_config.h b/src/newgrf_config.h --- a/src/newgrf_config.h +++ b/src/newgrf_config.h @@ -218,4 +218,6 @@ void ShowNewGRFSettings(bool editable, b GRFTextWrapper *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create); #endif /* ENABLE_NETWORK */ +void UpdateNewGRFScanStatus(uint num, const char *name); + #endif /* NEWGRF_CONFIG_H */ diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -1687,3 +1687,122 @@ void ShowNewGRFSettings(bool editable, b DeleteWindowByClass(WC_GAME_OPTIONS); new NewGRFWindow(&_newgrf_desc, editable, show_params, exec_changes, config); } + +/** The widgets for the scan progress. */ +enum ScanProgressWindowWidgets { + SPWW_PROGRESS_BAR, ///< Simple progress bar. + GPWW_PROGRESS_TEXT, ///< Text explaining what is happening. +}; + +/** 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), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_HORIZONTAL), SetPIP(20, 0, 20), + NWidget(NWID_VERTICAL), SetPIP(11, 8, 11), + NWidget(WWT_LABEL, INVALID_COLOUR), SetDataTip(STR_NEWGRF_SCAN_MESSAGE, STR_NULL), SetFill(1, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, SPWW_PROGRESS_BAR), SetFill(1, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, GPWW_PROGRESS_TEXT), SetFill(1, 0), + EndContainer(), + EndContainer(), + EndContainer(), +}; + +/** Description of the widgets and other settings of the window. */ +static const WindowDesc _scan_progress_desc( + WDP_CENTER, 0, 0, + WC_MODAL_PROGRESS, WC_NONE, + WDF_UNCLICK_BUTTONS, + _nested_scan_progress_widgets, lengthof(_nested_scan_progress_widgets) +); + +/** Window for showing the progress of NewGRF scanning. */ +struct ScanProgressWindow : public Window { + char *last_name; ///< The name of the last 'seen' NewGRF. + int scanned; ///< The number of NewGRFs that we have seen. + + /** Create the window. */ + ScanProgressWindow() : Window(), last_name(NULL), scanned(0) + { + this->InitNested(&_scan_progress_desc); + } + + /** Free the last name buffer. */ + ~ScanProgressWindow() + { + free(last_name); + } + + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + { + switch (widget) { + case SPWW_PROGRESS_BAR: { + SetDParam(0, 100); + *size = GetStringBoundingBox(STR_GENERATION_PROGRESS); + /* We need some spacing for the 'border' */ + size->height += 8; + size->width += 8; + break; + } + + case GPWW_PROGRESS_TEXT: + SetDParam(0, 9999); + SetDParam(1, 9999); + /* We really don't know the width. We could determine it by scanning the NewGRFs, + * but this is the status window for scanning them... */ + size->width = max(400U, GetStringBoundingBox(STR_NEWGRF_SCAN_STATUS).width); + size->height = FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL; + break; + } + } + + virtual void DrawWidget(const Rect &r, int widget) const + { + switch (widget) { + case SPWW_PROGRESS_BAR: { + /* Draw the % complete with a bar and a text */ + DrawFrameRect(r.left, r.top, r.right, r.bottom, COLOUR_GREY, FR_BORDERONLY); + uint percent = scanned * 100 / max(1U, _settings_client.gui.last_newgrf_count); + DrawFrameRect(r.left + 1, r.top + 1, (int)((r.right - r.left - 2) * percent / 100) + r.left + 1, r.bottom - 1, COLOUR_MAUVE, FR_NONE); + SetDParam(0, percent); + DrawString(r.left, r.right, r.top + 5, STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER); + break; + } + + case GPWW_PROGRESS_TEXT: + SetDParam(0, this->scanned); + SetDParam(1, _settings_client.gui.last_newgrf_count); + DrawString(r.left, r.right, r.top, STR_NEWGRF_SCAN_STATUS, TC_FROMSTRING, SA_HOR_CENTER); + + DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL, this->last_name == NULL ? "" : this->last_name, TC_BLACK, SA_HOR_CENTER); + break; + } + } + + /** + * Update the NewGRF scan status. + * @param num The number of NewGRFs scanned so far. + * @param name The name of the last scanned NewGRF. + */ + void UpdateNewGRFScanStatus(uint num, const char *name) + { + free(this->last_name); + this->last_name = strdup(name); + this->scanned = num; + if (num > _settings_client.gui.last_newgrf_count) _settings_client.gui.last_newgrf_count = num; + + this->SetDirty(); + } +}; + +/** + * Update the NewGRF scan status. + * @param num The number of NewGRFs scanned so far. + * @param name The name of the last scanned NewGRF. + */ +void UpdateNewGRFScanStatus(uint num, const char *name) +{ + ScanProgressWindow *w = dynamic_cast(FindWindowByClass(WC_MODAL_PROGRESS)); + if (w == NULL) w = new ScanProgressWindow(); + w->UpdateNewGRFScanStatus(num, name); +} diff --git a/src/settings_type.h b/src/settings_type.h --- a/src/settings_type.h +++ b/src/settings_type.h @@ -110,6 +110,7 @@ struct GUISettings { bool station_show_coverage; ///< whether to highlight coverage area bool persistent_buildingtools; ///< keep the building tools active after usage bool expenses_layout; ///< layout of expenses window + uint32 last_newgrf_count; ///< the numbers of NewGRFs we found during the last scan uint16 console_backlog_timeout; ///< the minimum amount of time items should be in the console backlog before they will be removed in ~3 seconds granularity. uint16 console_backlog_length; ///< the minimum amount of items in the console backlog before items will be removed. diff --git a/src/table/settings.ini b/src/table/settings.ini --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -2379,6 +2379,14 @@ def = false str = STR_CONFIG_SETTING_EXPENSES_LAYOUT proc = RedrawScreen +[SDTC_VAR] +var = gui.last_newgrf_count +type = SLE_UINT32 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = 100 +min = 0 +max = UINT32_MAX + ; For the dedicated build we'll enable dates in logs by default. [SDTC_BOOL]