mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-04 06:00:15 +00:00
(svn r19837) -Change: Display list of available (non-active) grfs in the NewGRF window.
This commit is contained in:
parent
5e24305e0d
commit
47360b029e
@ -2323,6 +2323,7 @@ STR_GENERATION_PREPARING_GAME :{BLACK}Preparin
|
||||
STR_NEWGRF_SETTINGS_CAPTION :{WHITE}NewGRF Settings
|
||||
STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Detailed NewGRF information
|
||||
STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Active NewGRF files
|
||||
STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Inactive NewGRF files
|
||||
STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Select preset:
|
||||
STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Load the selected preset
|
||||
STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Save preset
|
||||
|
@ -350,7 +350,7 @@ public:
|
||||
*list = c;
|
||||
|
||||
DeleteWindowByClass(WC_SAVELOAD);
|
||||
InvalidateWindowData(WC_GAME_OPTIONS, 0, 2);
|
||||
InvalidateWindowData(WC_GAME_OPTIONS, 0, 4);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -506,6 +506,8 @@ enum ShowNewGRFStateWidgets {
|
||||
SNGRFS_MOVE_DOWN,
|
||||
SNGRFS_FILE_LIST,
|
||||
SNGRFS_SCROLLBAR,
|
||||
SNGRFS_AVAIL_LIST,
|
||||
SNGRFS_SCROLL2BAR,
|
||||
SNGRFS_NEWGRF_INFO_TITLE,
|
||||
SNGRFS_NEWGRF_INFO,
|
||||
SNGRFS_SET_PARAMETERS,
|
||||
@ -518,17 +520,31 @@ enum ShowNewGRFStateWidgets {
|
||||
* Window for showing NewGRF files
|
||||
*/
|
||||
struct NewGRFWindow : public Window {
|
||||
GRFConfig **orig_list; ///< grf list the window is shown with
|
||||
GRFConfig *actives; ///< Temporary active grf list to which changes are made.
|
||||
GRFConfig *active_sel; ///< Selected active grf item.
|
||||
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 query_widget; ///< widget that opened a query
|
||||
int preset; ///< selected preset
|
||||
typedef GUIList<const GRFConfig *> GUIGRFConfigList;
|
||||
|
||||
static Listing last_sorting; ///< Default sorting of #GUIGRFConfigList.
|
||||
static Filtering last_filtering; ///< Default filtering of #GUIGRFConfigList.
|
||||
static GUIGRFConfigList::SortFunction * const sorter_funcs[]; ///< Sort functions of the #GUIGRFConfigList.
|
||||
static GUIGRFConfigList::FilterFunction * const filter_funcs[]; ///< Filter functions of the #GUIGRFConfigList.
|
||||
|
||||
GUIGRFConfigList avails; ///< Available (non-active) grfs.
|
||||
const GRFConfig *avail_sel; ///< Currently selected available grf. \c NULL is none is selected.
|
||||
int avail_pos; ///< Index of #avail_sel if existing, else \c -1.
|
||||
|
||||
GRFConfig *actives; ///< Temporary active grf list to which changes are made.
|
||||
GRFConfig *active_sel; ///< Selected active grf item.
|
||||
|
||||
GRFConfig **orig_list; ///< List active grfs in the game. Used as initial value, may be updated by the window.
|
||||
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 query_widget; ///< Widget that opened the last query.
|
||||
int preset; ///< Selected preset.
|
||||
|
||||
NewGRFWindow(const WindowDesc *desc, bool editable, bool show_params, bool execute, GRFConfig **orig_list) : Window()
|
||||
{
|
||||
this->avail_sel = NULL;
|
||||
this->avail_pos = -1;
|
||||
this->active_sel = NULL;
|
||||
this->actives = NULL;
|
||||
this->orig_list = orig_list;
|
||||
@ -541,6 +557,12 @@ struct NewGRFWindow : public Window {
|
||||
GetGRFPresetList(&_grf_preset_list);
|
||||
|
||||
this->InitNested(desc);
|
||||
this->avails.SetListing(this->last_sorting);
|
||||
this->avails.SetFiltering(this->last_filtering);
|
||||
this->avails.SetSortFuncs(this->sorter_funcs);
|
||||
this->avails.SetFilterFuncs(this->filter_funcs);
|
||||
this->avails.ForceRebuild();
|
||||
|
||||
this->OnInvalidateData(2);
|
||||
}
|
||||
|
||||
@ -561,6 +583,11 @@ struct NewGRFWindow : public Window {
|
||||
{
|
||||
switch (widget) {
|
||||
case SNGRFS_FILE_LIST:
|
||||
resize->height = max(12, FONT_HEIGHT_NORMAL + 2);
|
||||
size->height = max(size->height, WD_FRAMERECT_TOP + 6 * resize->height + WD_FRAMERECT_BOTTOM);
|
||||
break;
|
||||
|
||||
case SNGRFS_AVAIL_LIST:
|
||||
resize->height = max(12, FONT_HEIGHT_NORMAL + 2);
|
||||
size->height = max(size->height, WD_FRAMERECT_TOP + 8 * resize->height + WD_FRAMERECT_BOTTOM);
|
||||
break;
|
||||
@ -602,6 +629,7 @@ struct NewGRFWindow : public Window {
|
||||
virtual void OnResize()
|
||||
{
|
||||
this->vscroll.SetCapacityFromWidget(this, SNGRFS_FILE_LIST);
|
||||
this->vscroll2.SetCapacityFromWidget(this, SNGRFS_AVAIL_LIST);
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
@ -690,17 +718,41 @@ struct NewGRFWindow : public Window {
|
||||
}
|
||||
} break;
|
||||
|
||||
case SNGRFS_AVAIL_LIST: {
|
||||
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 0xD7);
|
||||
|
||||
uint step_height = this->GetWidget<NWidgetBase>(SNGRFS_AVAIL_LIST)->resize_y;
|
||||
uint y = r.top + WD_FRAMERECT_TOP;
|
||||
uint min_index = this->vscroll2.GetPosition();
|
||||
uint max_index = min(min_index + this->vscroll2.GetCapacity(), this->avails.Length());
|
||||
|
||||
for (uint i = min_index; i < max_index; i++)
|
||||
{
|
||||
const GRFConfig *c = this->avails[i];
|
||||
bool h = (c == this->avail_sel);
|
||||
const char *text = c->GetName();
|
||||
|
||||
if (h) GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 1, 156);
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, text, h ? TC_WHITE : TC_SILVER);
|
||||
y += step_height;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SNGRFS_NEWGRF_INFO_TITLE:
|
||||
/* Create the nice grayish rectangle at the details top. */
|
||||
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 157);
|
||||
DrawString(r.left, r.right, (r.top + r.bottom - FONT_HEIGHT_NORMAL) / 2, STR_NEWGRF_SETTINGS_INFO_TITLE, TC_FROMSTRING, SA_CENTER);
|
||||
break;
|
||||
|
||||
case SNGRFS_NEWGRF_INFO:
|
||||
if (this->active_sel != NULL) {
|
||||
ShowNewGRFInfo(this->active_sel, r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, r.right - WD_FRAMERECT_RIGHT, r.bottom - WD_FRAMERECT_BOTTOM, this->show_params);
|
||||
case SNGRFS_NEWGRF_INFO: {
|
||||
const GRFConfig *selected = this->active_sel;
|
||||
if (selected == NULL) selected = this->avail_sel;
|
||||
if (selected != NULL) {
|
||||
ShowNewGRFInfo(selected, r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, r.right - WD_FRAMERECT_RIGHT, r.bottom - WD_FRAMERECT_BOTTOM, this->show_params);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -761,6 +813,9 @@ struct NewGRFWindow : public Window {
|
||||
|
||||
this->active_sel = newsel;
|
||||
this->preset = -1;
|
||||
this->avail_pos = -1;
|
||||
this->avail_sel = NULL;
|
||||
this->avails.ForceRebuild();
|
||||
this->InvalidateData(3);
|
||||
this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window
|
||||
break;
|
||||
@ -804,7 +859,7 @@ struct NewGRFWindow : public Window {
|
||||
break;
|
||||
}
|
||||
|
||||
case SNGRFS_FILE_LIST: { // Select a GRF
|
||||
case SNGRFS_FILE_LIST: { // Select an active GRF.
|
||||
NWidgetBase *nw = this->GetWidget<NWidgetBase>(SNGRFS_FILE_LIST);
|
||||
uint i = (pt.y - nw->pos_y) / nw->resize_y + this->vscroll.GetPosition();
|
||||
|
||||
@ -813,12 +868,27 @@ struct NewGRFWindow : public Window {
|
||||
|
||||
if (this->active_sel != c) this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window
|
||||
this->active_sel = c;
|
||||
this->avail_sel = NULL;
|
||||
this->avail_pos = -1;
|
||||
|
||||
this->InvalidateData();
|
||||
if (click_count > 1) this->OnClick(pt, SNGRFS_SET_PARAMETERS, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case SNGRFS_AVAIL_LIST: { // Select a non-active GRF.
|
||||
NWidgetBase *nw = this->GetWidget<NWidgetBase>(SNGRFS_AVAIL_LIST);
|
||||
uint i = (pt.y - nw->pos_y) / nw->resize_y + this->vscroll2.GetPosition();
|
||||
this->active_sel = NULL;
|
||||
if (i < this->avails.Length()) {
|
||||
this->avail_sel = this->avails[i];
|
||||
this->avail_pos = i;
|
||||
}
|
||||
this->InvalidateData();
|
||||
this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window
|
||||
break;
|
||||
}
|
||||
|
||||
case SNGRFS_APPLY_CHANGES: // Apply changes made to GRF list
|
||||
if (this->execute) {
|
||||
ShowQuery(
|
||||
@ -891,6 +961,7 @@ struct NewGRFWindow : public Window {
|
||||
ClearGRFConfigList(&this->actives);
|
||||
this->actives = c;
|
||||
this->preset = index;
|
||||
this->avails.ForceRebuild();
|
||||
}
|
||||
}
|
||||
|
||||
@ -919,6 +990,8 @@ struct NewGRFWindow : public Window {
|
||||
break;
|
||||
|
||||
case SNGRFS_SET_PARAMETERS: {
|
||||
if (this->active_sel == NULL) return;
|
||||
|
||||
/* Parse our new "int list" */
|
||||
GRFConfig *c = this->active_sel;
|
||||
c->num_params = ParseIntList(str, (int*)c->param, lengthof(c->param));
|
||||
@ -934,6 +1007,13 @@ struct NewGRFWindow : public Window {
|
||||
this->InvalidateData();
|
||||
}
|
||||
|
||||
/** Calback to update internal data.
|
||||
* - 0: (optionally) build availables, update button status.
|
||||
* - 1: build availables, Add newly found grfs, update button status.
|
||||
* - 2: (optionally) build availables, Reset preset, + 3
|
||||
* - 3: (optionally) build availables, Update active scrollbar, update button status.
|
||||
* - 4: Force a rebuild of the availables, + 2
|
||||
*/
|
||||
virtual void OnInvalidateData(int data = 0)
|
||||
{
|
||||
switch (data) {
|
||||
@ -959,8 +1039,10 @@ struct NewGRFWindow : public Window {
|
||||
c->info = f->info == NULL ? NULL : strdup(f->info);
|
||||
c->status = GCS_UNKNOWN;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Fall through. */
|
||||
case 4:
|
||||
this->avails.ForceRebuild();
|
||||
/* Fall through. */
|
||||
case 2:
|
||||
this->preset = -1;
|
||||
/* Fall through */
|
||||
@ -970,10 +1052,15 @@ struct NewGRFWindow : public Window {
|
||||
|
||||
this->vscroll.SetCapacityFromWidget(this, SNGRFS_FILE_LIST);
|
||||
this->vscroll.SetCount(i);
|
||||
|
||||
this->vscroll2.SetCapacityFromWidget(this, SNGRFS_AVAIL_LIST);
|
||||
if (this->avail_pos >= 0) this->vscroll2.ScrollTowards(this->avail_pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->BuildAvailables();
|
||||
|
||||
this->SetWidgetsDisabledState(!this->editable,
|
||||
SNGRFS_PRESET_LIST,
|
||||
SNGRFS_ADD,
|
||||
@ -1016,8 +1103,55 @@ struct NewGRFWindow : public Window {
|
||||
}
|
||||
this->SetWidgetDisabledState(SNGRFS_PRESET_SAVE, has_missing);
|
||||
}
|
||||
|
||||
private:
|
||||
/** Sort grfs by name. */
|
||||
static int CDECL NameSorter(const GRFConfig * const *a, const GRFConfig * const *b)
|
||||
{
|
||||
return strcasecmp((*a)->GetName(), (*b)->GetName());
|
||||
}
|
||||
|
||||
/** Filter grfs by tags/name */
|
||||
static bool CDECL TagNameFilter(const GRFConfig * const *a, const char *filter_string)
|
||||
{
|
||||
if (strcasestr((*a)->GetName(), filter_string) != NULL) return true;
|
||||
if ((*a)->filename != NULL && strcasestr((*a)->filename, filter_string) != NULL) return true;
|
||||
if ((*a)->GetDescription() != NULL && strcasestr((*a)->GetDescription(), filter_string) != NULL) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void BuildAvailables()
|
||||
{
|
||||
if (!this->avails.NeedRebuild()) return;
|
||||
|
||||
this->avails.Clear();
|
||||
|
||||
for (const GRFConfig *c = _all_grfs; c != NULL; c = c->next) {
|
||||
bool found = false;
|
||||
for (const GRFConfig *grf = this->actives; grf != NULL && !found; grf = grf->next) found = grf->ident.HasGrfIdentifier(c->ident.grfid, c->ident.md5sum);
|
||||
if (!found) *this->avails.Append() = c;
|
||||
}
|
||||
|
||||
this->avails.Compact();
|
||||
this->avails.RebuildDone();
|
||||
this->avails.Sort();
|
||||
|
||||
this->vscroll2.SetCount(this->avails.Length()); // Update the scrollbar
|
||||
}
|
||||
};
|
||||
|
||||
Listing NewGRFWindow::last_sorting = {false, 0};
|
||||
Filtering NewGRFWindow::last_filtering = {false, 0};
|
||||
|
||||
NewGRFWindow::GUIGRFConfigList::SortFunction * const NewGRFWindow::sorter_funcs[] = {
|
||||
&NameSorter,
|
||||
};
|
||||
|
||||
NewGRFWindow::GUIGRFConfigList::FilterFunction * const NewGRFWindow::filter_funcs[] = {
|
||||
&TagNameFilter,
|
||||
};
|
||||
|
||||
|
||||
/* Widget definition of the manage newgrfs window */
|
||||
static const NWidgetPart _nested_newgrf_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
@ -1069,6 +1203,21 @@ static const NWidgetPart _nested_newgrf_widgets[] = {
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
|
||||
NWidget(NWID_SPACER), SetMinimalSize(0, WD_RESIZEBOX_WIDTH), SetResize(1, 0),
|
||||
NWidget(WWT_PANEL, COLOUR_MAUVE),
|
||||
NWidget(WWT_LABEL, COLOUR_MAUVE), SetDataTip(STR_NEWGRF_SETTINGS_INACTIVE_LIST, STR_NULL),
|
||||
SetFill(1, 0), SetResize(1, 0), SetPadding(3, WD_FRAMETEXT_RIGHT, 0, WD_FRAMETEXT_LEFT),
|
||||
/* Left side, available grfs. */
|
||||
NWidget(NWID_HORIZONTAL), SetPadding(0, 2, 0, 2),
|
||||
NWidget(WWT_PANEL, COLOUR_MAUVE),
|
||||
NWidget(WWT_INSET, COLOUR_MAUVE, SNGRFS_AVAIL_LIST), SetMinimalSize(100, 1), SetPadding(2, 2, 2, 2),
|
||||
SetFill(1, 1), SetResize(1, 1),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(WWT_SCROLL2BAR, COLOUR_MAUVE, SNGRFS_SCROLL2BAR),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
|
||||
NWidget(NWID_VERTICAL),
|
||||
@ -1130,8 +1279,9 @@ static void NewGRFConfirmationCallback(Window *w, bool confirmed)
|
||||
CopyGRFConfigList(&nw->actives, *nw->orig_list, false);
|
||||
for (c = nw->actives; c != NULL && i > 0; c = c->next, i--) {}
|
||||
nw->active_sel = c;
|
||||
nw->avails.ForceRebuild();
|
||||
|
||||
w->SetDirty();
|
||||
w->InvalidateData();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user