mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-08-22 14:09:10 +00:00
Compare commits
6 Commits
9122b4eb47
...
07a8bd21e4
Author | SHA1 | Date | |
---|---|---|---|
07a8bd21e4 | |||
dcf730f1f6 | |||
4d9f335f36 | |||
f7380a4d2d | |||
0434c1b474 | |||
4e5700939d |
@@ -28,7 +28,7 @@ struct GUIEngineListItem {
|
||||
bool operator == (const EngineID &other) const { return this->engine_id == other; }
|
||||
};
|
||||
|
||||
typedef GUIList<GUIEngineListItem, CargoID> GUIEngineList;
|
||||
typedef GUIList<GUIEngineListItem, std::nullptr_t, CargoID> GUIEngineList;
|
||||
|
||||
typedef bool EngList_SortTypeFunction(const GUIEngineListItem&, const GUIEngineListItem&); ///< argument type for #EngList_Sort.
|
||||
void EngList_Sort(GUIEngineList &el, EngList_SortTypeFunction compare);
|
||||
|
@@ -1245,7 +1245,7 @@ static const NWidgetPart _nested_industry_directory_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
typedef GUIList<const Industry *, const std::pair<CargoID, CargoID> &> GUIIndustryList;
|
||||
typedef GUIList<const Industry *, const CargoID &, const std::pair<CargoID, CargoID> &> GUIIndustryList;
|
||||
|
||||
/** Special cargo filter criteria */
|
||||
enum CargoFilterSpecialType {
|
||||
@@ -1315,7 +1315,7 @@ protected:
|
||||
static const StringID sorter_names[];
|
||||
static GUIIndustryList::SortFunction * const sorter_funcs[];
|
||||
|
||||
GUIIndustryList industries;
|
||||
GUIIndustryList industries{IndustryDirectoryWindow::produced_cargo_filter};
|
||||
Scrollbar *vscroll;
|
||||
Scrollbar *hscroll;
|
||||
|
||||
@@ -1484,7 +1484,7 @@ protected:
|
||||
}
|
||||
|
||||
/** Sort industries by name */
|
||||
static bool IndustryNameSorter(const Industry * const &a, const Industry * const &b)
|
||||
static bool IndustryNameSorter(const Industry * const &a, const Industry * const &b, const CargoID &)
|
||||
{
|
||||
int r = StrNaturalCompare(a->GetCachedName(), b->GetCachedName()); // Sort by name (natural sorting).
|
||||
if (r == 0) return a->index < b->index;
|
||||
@@ -1492,21 +1492,20 @@ protected:
|
||||
}
|
||||
|
||||
/** Sort industries by type and name */
|
||||
static bool IndustryTypeSorter(const Industry * const &a, const Industry * const &b)
|
||||
static bool IndustryTypeSorter(const Industry * const &a, const Industry * const &b, const CargoID &filter)
|
||||
{
|
||||
int it_a = 0;
|
||||
while (it_a != NUM_INDUSTRYTYPES && a->type != _sorted_industry_types[it_a]) it_a++;
|
||||
int it_b = 0;
|
||||
while (it_b != NUM_INDUSTRYTYPES && b->type != _sorted_industry_types[it_b]) it_b++;
|
||||
int r = it_a - it_b;
|
||||
return (r == 0) ? IndustryNameSorter(a, b) : r < 0;
|
||||
return (r == 0) ? IndustryNameSorter(a, b, filter) : r < 0;
|
||||
}
|
||||
|
||||
/** Sort industries by production and name */
|
||||
static bool IndustryProductionSorter(const Industry * const &a, const Industry * const &b)
|
||||
static bool IndustryProductionSorter(const Industry * const &a, const Industry * const &b, const CargoID &filter)
|
||||
{
|
||||
CargoID filter = IndustryDirectoryWindow::produced_cargo_filter;
|
||||
if (filter == CF_NONE) return IndustryTypeSorter(a, b);
|
||||
if (filter == CF_NONE) return IndustryTypeSorter(a, b, filter);
|
||||
|
||||
uint prod_a = 0, prod_b = 0;
|
||||
if (filter == CF_ANY) {
|
||||
@@ -1522,14 +1521,14 @@ protected:
|
||||
}
|
||||
int r = prod_a - prod_b;
|
||||
|
||||
return (r == 0) ? IndustryTypeSorter(a, b) : r < 0;
|
||||
return (r == 0) ? IndustryTypeSorter(a, b, filter) : r < 0;
|
||||
}
|
||||
|
||||
/** Sort industries by transported cargo and name */
|
||||
static bool IndustryTransportedCargoSorter(const Industry * const &a, const Industry * const &b)
|
||||
static bool IndustryTransportedCargoSorter(const Industry * const &a, const Industry * const &b, const CargoID &filter)
|
||||
{
|
||||
int r = GetCargoTransportedSortValue(a) - GetCargoTransportedSortValue(b);
|
||||
return (r == 0) ? IndustryNameSorter(a, b) : r < 0;
|
||||
return (r == 0) ? IndustryNameSorter(a, b, filter) : r < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -326,7 +326,7 @@ enum ContentListFilterCriteria {
|
||||
/** Window that lists the content that's at the content server */
|
||||
class NetworkContentListWindow : public Window, ContentCallback {
|
||||
/** List with content infos. */
|
||||
typedef GUIList<const ContentInfo *, ContentListFilterData &> GUIContentList;
|
||||
typedef GUIList<const ContentInfo *, std::nullptr_t, ContentListFilterData &> GUIContentList;
|
||||
|
||||
static const uint EDITBOX_MAX_SIZE = 50; ///< Maximum size of the editbox in characters.
|
||||
|
||||
|
@@ -79,7 +79,7 @@ static DropDownList BuildVisibilityDropDownList()
|
||||
return list;
|
||||
}
|
||||
|
||||
typedef GUIList<NetworkGameList*, StringFilter&> GUIGameServerList;
|
||||
typedef GUIList<NetworkGameList*, std::nullptr_t, StringFilter&> GUIGameServerList;
|
||||
typedef int ServerListPosition;
|
||||
static const ServerListPosition SLP_INVALID = -1;
|
||||
|
||||
|
@@ -819,11 +819,15 @@ struct SpriteAlignerWindow : Window {
|
||||
Scrollbar *vscroll;
|
||||
std::map<SpriteID, XyOffs> offs_start_map; ///< Mapping of starting offsets for the sprites which have been aligned in the sprite aligner window.
|
||||
|
||||
static inline ZoomLevel zoom = ZOOM_LVL_END;
|
||||
static bool centre;
|
||||
static bool crosshair;
|
||||
|
||||
SpriteAlignerWindow(WindowDesc *desc, WindowNumber wno) : Window(desc)
|
||||
{
|
||||
/* On first opening, set initial zoom to current zoom level. */
|
||||
if (SpriteAlignerWindow::zoom == ZOOM_LVL_END) SpriteAlignerWindow::zoom = _gui_zoom;
|
||||
|
||||
this->CreateNestedTree();
|
||||
this->vscroll = this->GetScrollbar(WID_SA_SCROLLBAR);
|
||||
this->vscroll->SetCount(_newgrf_debug_sprite_picker.sprites.size());
|
||||
@@ -834,6 +838,8 @@ struct SpriteAlignerWindow : Window {
|
||||
|
||||
/* Oh yes, we assume there is at least one normal sprite! */
|
||||
while (GetSpriteType(this->current_sprite) != SpriteType::Normal) this->current_sprite++;
|
||||
|
||||
this->InvalidateData(0, true);
|
||||
}
|
||||
|
||||
void SetStringParameters(int widget) const override
|
||||
@@ -846,8 +852,8 @@ struct SpriteAlignerWindow : Window {
|
||||
break;
|
||||
|
||||
case WID_SA_OFFSETS_ABS:
|
||||
SetDParam(0, spr->x_offs);
|
||||
SetDParam(1, spr->y_offs);
|
||||
SetDParam(0, UnScaleByZoom(spr->x_offs, SpriteAlignerWindow::zoom));
|
||||
SetDParam(1, UnScaleByZoom(spr->y_offs, SpriteAlignerWindow::zoom));
|
||||
break;
|
||||
|
||||
case WID_SA_OFFSETS_REL: {
|
||||
@@ -856,8 +862,8 @@ struct SpriteAlignerWindow : Window {
|
||||
*/
|
||||
const auto key_offs_pair = this->offs_start_map.find(this->current_sprite);
|
||||
if (key_offs_pair != this->offs_start_map.end()) {
|
||||
SetDParam(0, spr->x_offs - key_offs_pair->second.first);
|
||||
SetDParam(1, spr->y_offs - key_offs_pair->second.second);
|
||||
SetDParam(0, UnScaleByZoom(spr->x_offs - key_offs_pair->second.first, SpriteAlignerWindow::zoom));
|
||||
SetDParam(1, UnScaleByZoom(spr->y_offs - key_offs_pair->second.second, SpriteAlignerWindow::zoom));
|
||||
} else {
|
||||
SetDParam(0, 0);
|
||||
SetDParam(1, 0);
|
||||
@@ -898,8 +904,8 @@ struct SpriteAlignerWindow : Window {
|
||||
int x;
|
||||
int y;
|
||||
if (SpriteAlignerWindow::centre) {
|
||||
x = -UnScaleGUI(spr->x_offs) + (ir.Width() - UnScaleGUI(spr->width)) / 2;
|
||||
y = -UnScaleGUI(spr->y_offs) + (ir.Height() - UnScaleGUI(spr->height)) / 2;
|
||||
x = -UnScaleByZoom(spr->x_offs, SpriteAlignerWindow::zoom) + (ir.Width() - UnScaleByZoom(spr->width, SpriteAlignerWindow::zoom)) / 2;
|
||||
y = -UnScaleByZoom(spr->y_offs, SpriteAlignerWindow::zoom) + (ir.Height() - UnScaleByZoom(spr->height, SpriteAlignerWindow::zoom)) / 2;
|
||||
} else {
|
||||
x = ir.Width() / 2;
|
||||
y = ir.Height() / 2;
|
||||
@@ -909,8 +915,13 @@ struct SpriteAlignerWindow : Window {
|
||||
if (!FillDrawPixelInfo(&new_dpi, ir.left, ir.top, ir.Width(), ir.Height())) break;
|
||||
AutoRestoreBackup dpi_backup(_cur_dpi, &new_dpi);
|
||||
|
||||
DrawSprite(this->current_sprite, PAL_NONE, x, y, nullptr, ZOOM_LVL_GUI);
|
||||
if (this->crosshair) {
|
||||
DrawSprite(this->current_sprite, PAL_NONE, x, y, nullptr, SpriteAlignerWindow::zoom);
|
||||
|
||||
Rect outline = {0, 0, UnScaleByZoom(spr->width, SpriteAlignerWindow::zoom) - 1, UnScaleByZoom(spr->height, SpriteAlignerWindow::zoom) - 1};
|
||||
outline = outline.Translate(x + UnScaleByZoom(spr->x_offs, SpriteAlignerWindow::zoom),y + UnScaleByZoom(spr->y_offs, SpriteAlignerWindow::zoom));
|
||||
DrawRectOutline(outline.Expand(1), PC_LIGHT_BLUE, 1, 1);
|
||||
|
||||
if (SpriteAlignerWindow::crosshair) {
|
||||
GfxDrawLine(x, 0, x, ir.Height() - 1, PC_WHITE, 1, 1);
|
||||
GfxDrawLine(0, y, ir.Width() - 1, y, PC_WHITE, 1, 1);
|
||||
}
|
||||
@@ -927,7 +938,7 @@ struct SpriteAlignerWindow : Window {
|
||||
Rect ir = r.Shrink(WidgetDimensions::scaled.matrix);
|
||||
for (int i = this->vscroll->GetPosition(); i < max; i++) {
|
||||
SetDParam(0, list[i]);
|
||||
DrawString(ir, STR_JUST_COMMA, TC_BLACK, SA_RIGHT | SA_FORCE);
|
||||
DrawString(ir, STR_JUST_COMMA, list[i] == this->current_sprite ? TC_WHITE : TC_BLACK, SA_RIGHT | SA_FORCE);
|
||||
ir.top += step_size;
|
||||
}
|
||||
break;
|
||||
@@ -995,12 +1006,13 @@ struct SpriteAlignerWindow : Window {
|
||||
if (this->offs_start_map.count(this->current_sprite) == 0) {
|
||||
this->offs_start_map[this->current_sprite] = XyOffs(spr->x_offs, spr->y_offs);
|
||||
}
|
||||
int amt = ScaleByZoom(_ctrl_pressed ? 8 : 1, SpriteAlignerWindow::zoom);
|
||||
switch (widget) {
|
||||
/* Move eight units at a time if ctrl is pressed. */
|
||||
case WID_SA_UP: spr->y_offs -= _ctrl_pressed ? 8 : 1; break;
|
||||
case WID_SA_DOWN: spr->y_offs += _ctrl_pressed ? 8 : 1; break;
|
||||
case WID_SA_LEFT: spr->x_offs -= _ctrl_pressed ? 8 : 1; break;
|
||||
case WID_SA_RIGHT: spr->x_offs += _ctrl_pressed ? 8 : 1; break;
|
||||
case WID_SA_UP: spr->y_offs -= amt; break;
|
||||
case WID_SA_DOWN: spr->y_offs += amt; break;
|
||||
case WID_SA_LEFT: spr->x_offs -= amt; break;
|
||||
case WID_SA_RIGHT: spr->x_offs += amt; break;
|
||||
}
|
||||
/* Of course, we need to redraw the sprite, but where is it used?
|
||||
* Everywhere is a safe bet. */
|
||||
@@ -1025,6 +1037,13 @@ struct SpriteAlignerWindow : Window {
|
||||
this->SetWidgetLoweredState(widget, SpriteAlignerWindow::crosshair);
|
||||
this->SetDirty();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (IsInsideBS(widget, WID_SA_ZOOM, ZOOM_LVL_END)) {
|
||||
SpriteAlignerWindow::zoom = ZoomLevel(widget - WID_SA_ZOOM);
|
||||
this->InvalidateData(0, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1053,6 +1072,10 @@ struct SpriteAlignerWindow : Window {
|
||||
this->RaiseWidget(WID_SA_PICKER);
|
||||
this->vscroll->SetCount(_newgrf_debug_sprite_picker.sprites.size());
|
||||
}
|
||||
|
||||
for (ZoomLevel z = ZOOM_LVL_NORMAL; z < ZOOM_LVL_END; z++) {
|
||||
this->SetWidgetsLoweredState(SpriteAlignerWindow::zoom == z, WID_SA_ZOOM + z);
|
||||
}
|
||||
}
|
||||
|
||||
void OnResize() override
|
||||
@@ -1072,53 +1095,65 @@ static const NWidgetPart _nested_sprite_aligner_widgets[] = {
|
||||
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, 0, 10),
|
||||
NWidget(NWID_VERTICAL), SetPIP(10, 5, 10),
|
||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 5, 10),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_PREVIOUS), SetDataTip(STR_SPRITE_ALIGNER_PREVIOUS_BUTTON, STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP), SetFill(1, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_GOTO), SetDataTip(STR_SPRITE_ALIGNER_GOTO_BUTTON, STR_SPRITE_ALIGNER_GOTO_TOOLTIP), SetFill(1, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_NEXT), SetDataTip(STR_SPRITE_ALIGNER_NEXT_BUTTON, STR_SPRITE_ALIGNER_NEXT_TOOLTIP), SetFill(1, 0),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), SetPadding(WidgetDimensions::unscaled.sparse_resize),
|
||||
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
|
||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_PREVIOUS), SetDataTip(STR_SPRITE_ALIGNER_PREVIOUS_BUTTON, STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_GOTO), SetDataTip(STR_SPRITE_ALIGNER_GOTO_BUTTON, STR_SPRITE_ALIGNER_GOTO_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_NEXT), SetDataTip(STR_SPRITE_ALIGNER_NEXT_BUTTON, STR_SPRITE_ALIGNER_NEXT_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 0),
|
||||
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_UP), SetDataTip(SPR_ARROW_UP, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), SetMinimalSize(11, 11),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 0),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL_LTR), SetPIP(10, 5, 10),
|
||||
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
|
||||
NWidget(NWID_VERTICAL),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1), SetResize(0, 1),
|
||||
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_LEFT), SetDataTip(SPR_ARROW_LEFT, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), SetMinimalSize(11, 11),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1), SetResize(0, 1),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_DARK_BLUE, WID_SA_SPRITE), SetDataTip(STR_NULL, STR_SPRITE_ALIGNER_SPRITE_TOOLTIP),
|
||||
NWidget(WWT_PANEL, COLOUR_DARK_BLUE, WID_SA_SPRITE), SetDataTip(STR_NULL, STR_SPRITE_ALIGNER_SPRITE_TOOLTIP), SetResize(1, 1), SetFill(1, 1),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VERTICAL),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1), SetResize(0, 1),
|
||||
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_RIGHT), SetDataTip(SPR_ARROW_RIGHT, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), SetMinimalSize(11, 11),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1), SetResize(0, 1),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 0),
|
||||
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), SetMinimalSize(11, 11),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1),
|
||||
NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 0),
|
||||
EndContainer(),
|
||||
NWidget(WWT_LABEL, COLOUR_GREY, WID_SA_OFFSETS_ABS), SetDataTip(STR_SPRITE_ALIGNER_OFFSETS_ABS, STR_NULL), SetFill(1, 0), SetPadding(0, 10, 0, 10),
|
||||
NWidget(WWT_LABEL, COLOUR_GREY, WID_SA_OFFSETS_REL), SetDataTip(STR_SPRITE_ALIGNER_OFFSETS_REL, STR_NULL), SetFill(1, 0), SetPadding(0, 10, 0, 10),
|
||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 5, 10),
|
||||
NWidget(WWT_TEXTBTN_2, COLOUR_GREY, WID_SA_CENTRE), SetDataTip(STR_SPRITE_ALIGNER_CENTRE_OFFSET, STR_NULL), SetFill(1, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_RESET_REL), SetDataTip(STR_SPRITE_ALIGNER_RESET_BUTTON, STR_SPRITE_ALIGNER_RESET_TOOLTIP), SetFill(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_CROSSHAIR), SetDataTip(STR_SPRITE_ALIGNER_CROSSHAIR, STR_NULL), SetFill(1, 0),
|
||||
NWidget(WWT_LABEL, COLOUR_GREY, WID_SA_OFFSETS_ABS), SetDataTip(STR_SPRITE_ALIGNER_OFFSETS_ABS, STR_NULL), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_LABEL, COLOUR_GREY, WID_SA_OFFSETS_REL), SetDataTip(STR_SPRITE_ALIGNER_OFFSETS_REL, STR_NULL), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0),
|
||||
NWidget(WWT_TEXTBTN_2, COLOUR_GREY, WID_SA_CENTRE), SetDataTip(STR_SPRITE_ALIGNER_CENTRE_OFFSET, STR_NULL), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_RESET_REL), SetDataTip(STR_SPRITE_ALIGNER_RESET_BUTTON, STR_SPRITE_ALIGNER_RESET_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_CROSSHAIR), SetDataTip(STR_SPRITE_ALIGNER_CROSSHAIR, STR_NULL), SetFill(1, 0), SetResize(1, 0),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VERTICAL), SetPIP(10, 5, 10),
|
||||
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_PICKER), SetDataTip(STR_SPRITE_ALIGNER_PICKER_BUTTON, STR_SPRITE_ALIGNER_PICKER_TOOLTIP), SetFill(1, 0),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_MATRIX, COLOUR_GREY, WID_SA_LIST), SetResize(1, 1), SetMatrixDataTip(1, 0, STR_NULL), SetFill(1, 1), SetScrollbar(WID_SA_SCROLLBAR),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SA_SCROLLBAR),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VERTICAL),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_NORMAL), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_MIN, STR_NULL), SetFill(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_2X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_IN_2X, STR_NULL), SetFill(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_4X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_NORMAL, STR_NULL), SetFill(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_8X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X, STR_NULL), SetFill(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_16X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X, STR_NULL), SetFill(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_32X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X, STR_NULL), SetFill(1, 0),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
|
@@ -602,7 +602,7 @@ static void ShowSavePresetWindow(const char *initial_text);
|
||||
* Window for showing NewGRF files
|
||||
*/
|
||||
struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
typedef GUIList<const GRFConfig *, StringFilter &> GUIGRFConfigList;
|
||||
typedef GUIList<const GRFConfig *, std::nullptr_t, StringFilter &> GUIGRFConfigList;
|
||||
|
||||
static const uint EDITBOX_MAX_SIZE = 50;
|
||||
|
||||
|
@@ -45,7 +45,7 @@ enum BuildObjectHotkeys {
|
||||
|
||||
/** The window used for building objects. */
|
||||
class BuildObjectWindow : public Window {
|
||||
typedef GUIList<ObjectClassID, StringFilter &> GUIObjectClassList; ///< Type definition for the list to hold available object classes.
|
||||
typedef GUIList<ObjectClassID, std::nullptr_t, StringFilter &> GUIObjectClassList; ///< Type definition for the list to hold available object classes.
|
||||
|
||||
static const uint EDITBOX_MAX_SIZE = 16; ///< The maximum number of characters for the filter edit box.
|
||||
|
||||
|
@@ -903,7 +903,7 @@ private:
|
||||
Scrollbar *vscroll; ///< Vertical scrollbar of the new station list.
|
||||
Scrollbar *vscroll2; ///< Vertical scrollbar of the matrix with new stations.
|
||||
|
||||
typedef GUIList<StationClassID, StringFilter &> GUIStationClassList; ///< Type definition for the list to hold available station classes.
|
||||
typedef GUIList<StationClassID, std::nullptr_t, StringFilter &> GUIStationClassList; ///< Type definition for the list to hold available station classes.
|
||||
|
||||
static const uint EDITBOX_MAX_SIZE = 16; ///< The maximum number of characters for the filter edit box.
|
||||
|
||||
|
@@ -1101,7 +1101,7 @@ private:
|
||||
Scrollbar *vscrollList; ///< Vertical scrollbar of the new station list.
|
||||
Scrollbar *vscrollMatrix; ///< Vertical scrollbar of the station picker matrix.
|
||||
|
||||
typedef GUIList<RoadStopClassID, StringFilter &> GUIRoadStopClassList; ///< Type definition for the list to hold available road stop classes.
|
||||
typedef GUIList<RoadStopClassID, std::nullptr_t, StringFilter &> GUIRoadStopClassList; ///< Type definition for the list to hold available road stop classes.
|
||||
|
||||
static const uint EDITBOX_MAX_SIZE = 16; ///< The maximum number of characters for the filter edit box.
|
||||
|
||||
|
@@ -41,7 +41,7 @@ struct SignList {
|
||||
/**
|
||||
* A GUIList contains signs and uses a StringFilter for filtering.
|
||||
*/
|
||||
typedef GUIList<const Sign *, StringFilter &> GUISignList;
|
||||
typedef GUIList<const Sign *, std::nullptr_t, StringFilter &> GUISignList;
|
||||
|
||||
GUISignList signs;
|
||||
|
||||
|
@@ -40,12 +40,13 @@ struct Filtering {
|
||||
/**
|
||||
* List template of 'things' \p T to sort in a GUI.
|
||||
* @tparam T Type of data stored in the list to represent each item.
|
||||
* @tparam P Tyoe of data passed as additional parameter to the sort function.
|
||||
* @tparam F Type of data fed as additional value to the filter function. @see FilterFunction
|
||||
*/
|
||||
template <typename T, typename F = const char*>
|
||||
template <typename T, typename P = std::nullptr_t, typename F = const char*>
|
||||
class GUIList : public std::vector<T> {
|
||||
public:
|
||||
typedef bool SortFunction(const T&, const T&); ///< Signature of sort function.
|
||||
using SortFunction = std::conditional_t<std::is_same_v<P, std::nullptr_t>, bool (const T&, const T&), bool (const T&, const T&, const P)>; ///< Signature of sort function.
|
||||
typedef bool CDECL FilterFunction(const T*, F); ///< Signature of filter function.
|
||||
|
||||
protected:
|
||||
@@ -56,6 +57,11 @@ protected:
|
||||
uint8_t filter_type; ///< what criteria to filter on
|
||||
uint16_t resort_timer; ///< resort list after a given amount of ticks if set
|
||||
|
||||
/* If sort parameters are used then params must be a reference, however if not then params cannot be a reference as
|
||||
* it will not be able to reference anything. */
|
||||
using SortParameterReference = std::conditional_t<std::is_same_v<P, std::nullptr_t>, P, P&>;
|
||||
const SortParameterReference params;
|
||||
|
||||
/**
|
||||
* Check if the list is sortable
|
||||
*
|
||||
@@ -76,13 +82,28 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
/* If sort parameters are not used then we don't require a reference to the params. */
|
||||
template <typename T_ = T, typename P_ = P, typename _F = F, std::enable_if_t<std::is_same_v<P_, std::nullptr_t>>* = nullptr>
|
||||
GUIList() :
|
||||
sort_func_list(nullptr),
|
||||
filter_func_list(nullptr),
|
||||
flags(VL_NONE),
|
||||
sort_type(0),
|
||||
filter_type(0),
|
||||
resort_timer(1)
|
||||
resort_timer(1),
|
||||
params(nullptr)
|
||||
{};
|
||||
|
||||
/* If sort parameters are used then we require a reference to the params. */
|
||||
template <typename T_ = T, typename P_ = P, typename _F = F, std::enable_if_t<!std::is_same_v<P_, std::nullptr_t>>* = nullptr>
|
||||
GUIList(const P& params) :
|
||||
sort_func_list(nullptr),
|
||||
filter_func_list(nullptr),
|
||||
flags(VL_NONE),
|
||||
sort_type(0),
|
||||
filter_type(0),
|
||||
resort_timer(1),
|
||||
params(params)
|
||||
{};
|
||||
|
||||
/**
|
||||
@@ -258,7 +279,11 @@ public:
|
||||
|
||||
const bool desc = (this->flags & VL_DESC) != 0;
|
||||
|
||||
std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
|
||||
if constexpr (std::is_same_v<P, std::nullptr_t>) {
|
||||
std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); });
|
||||
} else {
|
||||
std::sort(std::vector<T>::begin(), std::vector<T>::end(), [&](const T &a, const T &b) { return desc ? compare(b, a, params) : compare(a, b, params); });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -209,7 +209,7 @@ static void StationsWndShowStationRating(int left, int right, int y, CargoID typ
|
||||
if (w != 0) GfxFillRect(left + padding, y, left + w - 1, y + padding - 1, PC_GREEN);
|
||||
}
|
||||
|
||||
typedef GUIList<const Station*> GUIStationList;
|
||||
typedef GUIList<const Station*, const CargoTypes &> GUIStationList;
|
||||
|
||||
/**
|
||||
* The list of stations per company.
|
||||
@@ -218,17 +218,26 @@ class CompanyStationsWindow : public Window
|
||||
{
|
||||
protected:
|
||||
/* Runtime saved values */
|
||||
static Listing last_sorting;
|
||||
static byte facilities; // types of stations of interest
|
||||
static bool include_empty; // whether we should include stations without waiting cargo
|
||||
static const CargoTypes cargo_filter_max;
|
||||
static CargoTypes cargo_filter; // bitmap of cargo types to include
|
||||
struct FilterState {
|
||||
Listing last_sorting;
|
||||
byte facilities; ///< types of stations of interest
|
||||
bool include_empty; ///< whether we should include stations without waiting cargo
|
||||
CargoTypes cargoes; ///< bitmap of cargo types to include
|
||||
};
|
||||
|
||||
static inline FilterState initial_state = {
|
||||
{false, 0},
|
||||
FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK,
|
||||
true,
|
||||
ALL_CARGOTYPES,
|
||||
};
|
||||
|
||||
/* Constants for sorting stations */
|
||||
static const StringID sorter_names[];
|
||||
static GUIStationList::SortFunction * const sorter_funcs[];
|
||||
|
||||
GUIStationList stations;
|
||||
FilterState filter;
|
||||
GUIStationList stations{filter.cargoes};
|
||||
Scrollbar *vscroll;
|
||||
uint rating_width;
|
||||
|
||||
@@ -247,19 +256,19 @@ protected:
|
||||
|
||||
for (const Station *st : Station::Iterate()) {
|
||||
if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) {
|
||||
if (this->facilities & st->facilities) { // only stations with selected facilities
|
||||
if (this->filter.facilities & st->facilities) { // only stations with selected facilities
|
||||
int num_waiting_cargo = 0;
|
||||
for (CargoID j = 0; j < NUM_CARGO; j++) {
|
||||
if (st->goods[j].HasRating()) {
|
||||
num_waiting_cargo++; // count number of waiting cargo
|
||||
if (HasBit(this->cargo_filter, j)) {
|
||||
if (HasBit(this->filter.cargoes, j)) {
|
||||
this->stations.push_back(st);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* stations without waiting cargo */
|
||||
if (num_waiting_cargo == 0 && this->include_empty) {
|
||||
if (num_waiting_cargo == 0 && this->filter.include_empty) {
|
||||
this->stations.push_back(st);
|
||||
}
|
||||
}
|
||||
@@ -273,7 +282,7 @@ protected:
|
||||
}
|
||||
|
||||
/** Sort stations by their name */
|
||||
static bool StationNameSorter(const Station * const &a, const Station * const &b)
|
||||
static bool StationNameSorter(const Station * const &a, const Station * const &b, const CargoTypes &)
|
||||
{
|
||||
int r = StrNaturalCompare(a->GetCachedName(), b->GetCachedName()); // Sort by name (natural sorting).
|
||||
if (r == 0) return a->index < b->index;
|
||||
@@ -281,13 +290,13 @@ protected:
|
||||
}
|
||||
|
||||
/** Sort stations by their type */
|
||||
static bool StationTypeSorter(const Station * const &a, const Station * const &b)
|
||||
static bool StationTypeSorter(const Station * const &a, const Station * const &b, const CargoTypes &)
|
||||
{
|
||||
return a->facilities < b->facilities;
|
||||
}
|
||||
|
||||
/** Sort stations by their waiting cargo */
|
||||
static bool StationWaitingTotalSorter(const Station * const &a, const Station * const &b)
|
||||
static bool StationWaitingTotalSorter(const Station * const &a, const Station * const &b, const CargoTypes &cargo_filter)
|
||||
{
|
||||
int diff = 0;
|
||||
|
||||
@@ -299,7 +308,7 @@ protected:
|
||||
}
|
||||
|
||||
/** Sort stations by their available waiting cargo */
|
||||
static bool StationWaitingAvailableSorter(const Station * const &a, const Station * const &b)
|
||||
static bool StationWaitingAvailableSorter(const Station * const &a, const Station * const &b, const CargoTypes &cargo_filter)
|
||||
{
|
||||
int diff = 0;
|
||||
|
||||
@@ -311,7 +320,7 @@ protected:
|
||||
}
|
||||
|
||||
/** Sort stations by their rating */
|
||||
static bool StationRatingMaxSorter(const Station * const &a, const Station * const &b)
|
||||
static bool StationRatingMaxSorter(const Station * const &a, const Station * const &b, const CargoTypes &cargo_filter)
|
||||
{
|
||||
byte maxr1 = 0;
|
||||
byte maxr2 = 0;
|
||||
@@ -325,7 +334,7 @@ protected:
|
||||
}
|
||||
|
||||
/** Sort stations by their rating */
|
||||
static bool StationRatingMinSorter(const Station * const &a, const Station * const &b)
|
||||
static bool StationRatingMinSorter(const Station * const &a, const Station * const &b, const CargoTypes &cargo_filter)
|
||||
{
|
||||
byte minr1 = 255;
|
||||
byte minr2 = 255;
|
||||
@@ -350,8 +359,12 @@ protected:
|
||||
public:
|
||||
CompanyStationsWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
|
||||
{
|
||||
this->stations.SetListing(this->last_sorting);
|
||||
this->stations.SetSortFuncs(this->sorter_funcs);
|
||||
/* Load initial filter state. */
|
||||
this->filter = CompanyStationsWindow::initial_state;
|
||||
if (this->filter.cargoes == ALL_CARGOTYPES) this->filter.cargoes = _cargo_mask;
|
||||
|
||||
this->stations.SetListing(this->filter.last_sorting);
|
||||
this->stations.SetSortFuncs(CompanyStationsWindow::sorter_funcs);
|
||||
this->stations.ForceRebuild();
|
||||
this->stations.NeedResort();
|
||||
this->SortStationsList();
|
||||
@@ -363,25 +376,27 @@ public:
|
||||
|
||||
uint8_t index = 0;
|
||||
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||
if (HasBit(this->cargo_filter, cs->Index())) {
|
||||
if (HasBit(this->filter.cargoes, cs->Index())) {
|
||||
this->LowerWidget(WID_STL_CARGOSTART + index);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
if (this->cargo_filter == this->cargo_filter_max) this->cargo_filter = _cargo_mask;
|
||||
if (this->filter.cargoes == ALL_CARGOTYPES) this->filter.cargoes = _cargo_mask;
|
||||
|
||||
for (uint i = 0; i < 5; i++) {
|
||||
if (HasBit(this->facilities, i)) this->LowerWidget(i + WID_STL_TRAIN);
|
||||
if (HasBit(this->filter.facilities, i)) this->LowerWidget(i + WID_STL_TRAIN);
|
||||
}
|
||||
this->SetWidgetLoweredState(WID_STL_NOCARGOWAITING, this->include_empty);
|
||||
this->SetWidgetLoweredState(WID_STL_NOCARGOWAITING, this->filter.include_empty);
|
||||
|
||||
this->GetWidget<NWidgetCore>(WID_STL_SORTDROPBTN)->widget_data = this->sorter_names[this->stations.SortType()];
|
||||
}
|
||||
|
||||
~CompanyStationsWindow()
|
||||
{
|
||||
this->last_sorting = this->stations.GetListing();
|
||||
/* Save filter state. */
|
||||
this->filter.last_sorting = this->stations.GetListing();
|
||||
CompanyStationsWindow::initial_state = this->filter;
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(int widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
|
||||
@@ -397,8 +412,8 @@ public:
|
||||
|
||||
case WID_STL_SORTDROPBTN: {
|
||||
Dimension d = {0, 0};
|
||||
for (int i = 0; this->sorter_names[i] != INVALID_STRING_ID; i++) {
|
||||
d = maxdim(d, GetStringBoundingBox(this->sorter_names[i]));
|
||||
for (int i = 0; CompanyStationsWindow::sorter_names[i] != INVALID_STRING_ID; i++) {
|
||||
d = maxdim(d, GetStringBoundingBox(CompanyStationsWindow::sorter_names[i]));
|
||||
}
|
||||
d.width += padding.width;
|
||||
d.height += padding.height;
|
||||
@@ -502,7 +517,7 @@ public:
|
||||
if (widget >= WID_STL_CARGOSTART) {
|
||||
Rect br = r.Shrink(WidgetDimensions::scaled.bevel);
|
||||
const CargoSpec *cs = _sorted_cargo_specs[widget - WID_STL_CARGOSTART];
|
||||
int cg_ofst = HasBit(this->cargo_filter, cs->Index()) ? WidgetDimensions::scaled.pressed : 0;
|
||||
int cg_ofst = HasBit(this->filter.cargoes, cs->Index()) ? WidgetDimensions::scaled.pressed : 0;
|
||||
br = br.Translate(cg_ofst, cg_ofst);
|
||||
GfxFillRect(br, cs->rating_colour);
|
||||
TextColour tc = GetContrastColour(cs->rating_colour);
|
||||
@@ -545,13 +560,13 @@ public:
|
||||
case WID_STL_AIRPLANE:
|
||||
case WID_STL_SHIP:
|
||||
if (_ctrl_pressed) {
|
||||
ToggleBit(this->facilities, widget - WID_STL_TRAIN);
|
||||
ToggleBit(this->filter.facilities, widget - WID_STL_TRAIN);
|
||||
this->ToggleWidgetLoweredState(widget);
|
||||
} else {
|
||||
for (uint i : SetBitIterator(this->facilities)) {
|
||||
for (uint i : SetBitIterator(this->filter.facilities)) {
|
||||
this->RaiseWidget(i + WID_STL_TRAIN);
|
||||
}
|
||||
this->facilities = 1 << (widget - WID_STL_TRAIN);
|
||||
this->filter.facilities = 1 << (widget - WID_STL_TRAIN);
|
||||
this->LowerWidget(widget);
|
||||
}
|
||||
this->stations.ForceRebuild();
|
||||
@@ -563,7 +578,7 @@ public:
|
||||
this->LowerWidget(i);
|
||||
}
|
||||
|
||||
this->facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
|
||||
this->filter.facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
|
||||
this->stations.ForceRebuild();
|
||||
this->SetDirty();
|
||||
break;
|
||||
@@ -574,8 +589,8 @@ public:
|
||||
}
|
||||
this->LowerWidget(WID_STL_NOCARGOWAITING);
|
||||
|
||||
this->cargo_filter = _cargo_mask;
|
||||
this->include_empty = true;
|
||||
this->filter.cargoes = _cargo_mask;
|
||||
this->filter.include_empty = true;
|
||||
this->stations.ForceRebuild();
|
||||
this->SetDirty();
|
||||
break;
|
||||
@@ -592,15 +607,15 @@ public:
|
||||
|
||||
case WID_STL_NOCARGOWAITING:
|
||||
if (_ctrl_pressed) {
|
||||
this->include_empty = !this->include_empty;
|
||||
this->filter.include_empty = !this->filter.include_empty;
|
||||
this->ToggleWidgetLoweredState(WID_STL_NOCARGOWAITING);
|
||||
} else {
|
||||
for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) {
|
||||
this->RaiseWidget(WID_STL_CARGOSTART + i);
|
||||
}
|
||||
|
||||
this->cargo_filter = 0;
|
||||
this->include_empty = true;
|
||||
this->filter.cargoes = 0;
|
||||
this->filter.include_empty = true;
|
||||
|
||||
this->LowerWidget(WID_STL_NOCARGOWAITING);
|
||||
}
|
||||
@@ -614,7 +629,7 @@ public:
|
||||
const CargoSpec *cs = _sorted_cargo_specs[widget - WID_STL_CARGOSTART];
|
||||
|
||||
if (_ctrl_pressed) {
|
||||
ToggleBit(this->cargo_filter, cs->Index());
|
||||
ToggleBit(this->filter.cargoes, cs->Index());
|
||||
this->ToggleWidgetLoweredState(widget);
|
||||
} else {
|
||||
for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) {
|
||||
@@ -622,10 +637,10 @@ public:
|
||||
}
|
||||
this->RaiseWidget(WID_STL_NOCARGOWAITING);
|
||||
|
||||
this->cargo_filter = 0;
|
||||
this->include_empty = false;
|
||||
this->filter.cargoes = 0;
|
||||
this->filter.include_empty = false;
|
||||
|
||||
SetBit(this->cargo_filter, cs->Index());
|
||||
SetBit(this->filter.cargoes, cs->Index());
|
||||
this->LowerWidget(widget);
|
||||
}
|
||||
this->stations.ForceRebuild();
|
||||
@@ -642,7 +657,7 @@ public:
|
||||
this->stations.SetSortType(index);
|
||||
|
||||
/* Display the current sort variant */
|
||||
this->GetWidget<NWidgetCore>(WID_STL_SORTDROPBTN)->widget_data = this->sorter_names[this->stations.SortType()];
|
||||
this->GetWidget<NWidgetCore>(WID_STL_SORTDROPBTN)->widget_data = CompanyStationsWindow::sorter_names[this->stations.SortType()];
|
||||
|
||||
this->SetDirty();
|
||||
}
|
||||
@@ -678,12 +693,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
Listing CompanyStationsWindow::last_sorting = {false, 0};
|
||||
byte CompanyStationsWindow::facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
|
||||
bool CompanyStationsWindow::include_empty = true;
|
||||
const CargoTypes CompanyStationsWindow::cargo_filter_max = ALL_CARGOTYPES;
|
||||
CargoTypes CompanyStationsWindow::cargo_filter = ALL_CARGOTYPES;
|
||||
|
||||
/* Available station sorting functions */
|
||||
GUIStationList::SortFunction * const CompanyStationsWindow::sorter_funcs[] = {
|
||||
&StationNameSorter,
|
||||
|
@@ -47,7 +47,7 @@
|
||||
|
||||
TownKdtree _town_local_authority_kdtree(&Kdtree_TownXYFunc);
|
||||
|
||||
typedef GUIList<const Town*> GUITownList;
|
||||
typedef GUIList<const Town*, const bool &> GUITownList;
|
||||
|
||||
static const NWidgetPart _nested_town_authority_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
@@ -707,7 +707,7 @@ private:
|
||||
StringFilter string_filter; ///< Filter for towns
|
||||
QueryString townname_editbox; ///< Filter editbox
|
||||
|
||||
GUITownList towns;
|
||||
GUITownList towns{TownDirectoryWindow::last_sorting.order};
|
||||
|
||||
Scrollbar *vscroll;
|
||||
|
||||
@@ -736,31 +736,31 @@ private:
|
||||
}
|
||||
|
||||
/** Sort by town name */
|
||||
static bool TownNameSorter(const Town * const &a, const Town * const &b)
|
||||
static bool TownNameSorter(const Town * const &a, const Town * const &b, const bool &)
|
||||
{
|
||||
return StrNaturalCompare(a->GetCachedName(), b->GetCachedName()) < 0; // Sort by name (natural sorting).
|
||||
}
|
||||
|
||||
/** Sort by population (default descending, as big towns are of the most interest). */
|
||||
static bool TownPopulationSorter(const Town * const &a, const Town * const &b)
|
||||
static bool TownPopulationSorter(const Town * const &a, const Town * const &b, const bool &order)
|
||||
{
|
||||
uint32_t a_population = a->cache.population;
|
||||
uint32_t b_population = b->cache.population;
|
||||
if (a_population == b_population) return TownDirectoryWindow::TownNameSorter(a, b);
|
||||
if (a_population == b_population) return TownDirectoryWindow::TownNameSorter(a, b, order);
|
||||
return a_population < b_population;
|
||||
}
|
||||
|
||||
/** Sort by town rating */
|
||||
static bool TownRatingSorter(const Town * const &a, const Town * const &b)
|
||||
static bool TownRatingSorter(const Town * const &a, const Town * const &b, const bool &order)
|
||||
{
|
||||
bool before = !TownDirectoryWindow::last_sorting.order; // Value to get 'a' before 'b'.
|
||||
bool before = !order; // Value to get 'a' before 'b'.
|
||||
|
||||
/* Towns without rating are always after towns with rating. */
|
||||
if (HasBit(a->have_ratings, _local_company)) {
|
||||
if (HasBit(b->have_ratings, _local_company)) {
|
||||
int16_t a_rating = a->ratings[_local_company];
|
||||
int16_t b_rating = b->ratings[_local_company];
|
||||
if (a_rating == b_rating) return TownDirectoryWindow::TownNameSorter(a, b);
|
||||
if (a_rating == b_rating) return TownDirectoryWindow::TownNameSorter(a, b, order);
|
||||
return a_rating < b_rating;
|
||||
}
|
||||
return before;
|
||||
@@ -768,8 +768,8 @@ private:
|
||||
if (HasBit(b->have_ratings, _local_company)) return !before;
|
||||
|
||||
/* Sort unrated towns always on ascending town name. */
|
||||
if (before) return TownDirectoryWindow::TownNameSorter(a, b);
|
||||
return TownDirectoryWindow::TownNameSorter(b, a);
|
||||
if (before) return TownDirectoryWindow::TownNameSorter(a, b, order);
|
||||
return TownDirectoryWindow::TownNameSorter(b, a, order);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@@ -19,7 +19,7 @@
|
||||
#include "window_gui.h"
|
||||
#include "widgets/dropdown_type.h"
|
||||
|
||||
typedef GUIList<const Vehicle*, CargoID> GUIVehicleList;
|
||||
typedef GUIList<const Vehicle*, std::nullptr_t, CargoID> GUIVehicleList;
|
||||
|
||||
struct GUIVehicleGroup {
|
||||
VehicleList::const_iterator vehicles_begin; ///< Pointer to beginning element of this vehicle group.
|
||||
@@ -62,7 +62,7 @@ struct GUIVehicleGroup {
|
||||
}
|
||||
};
|
||||
|
||||
typedef GUIList<GUIVehicleGroup, CargoID> GUIVehicleGroupList;
|
||||
typedef GUIList<GUIVehicleGroup, std::nullptr_t, CargoID> GUIVehicleGroupList;
|
||||
|
||||
struct BaseVehicleListWindow : public Window {
|
||||
|
||||
|
@@ -37,6 +37,8 @@ enum SpriteAlignerWidgets {
|
||||
WID_SA_PICKER, ///< Sprite picker.
|
||||
WID_SA_LIST, ///< Queried sprite list.
|
||||
WID_SA_SCROLLBAR, ///< Scrollbar for sprite list.
|
||||
WID_SA_ZOOM, ///< Zoom level buttons (from ZOOM_LVL_BEGIN to ZOOM_LVL_END).
|
||||
WID_SA_ZOOM_LAST = WID_SA_ZOOM + ZOOM_LVL_END - 1, ///< Marker for last zoom level button.
|
||||
WID_SA_RESET_REL, ///< Reset relative sprite offset
|
||||
WID_SA_CENTRE, ///< Toggle centre sprite.
|
||||
WID_SA_CROSSHAIR, ///< Toggle crosshair.
|
||||
|
Reference in New Issue
Block a user