diff --git a/src/data/statistics.cpp b/src/data/statistics.cpp index 8d4bca25..944faf60 100644 --- a/src/data/statistics.cpp +++ b/src/data/statistics.cpp @@ -17,15 +17,17 @@ DECLARE_TYPEOF_COLLECTION(ChoiceField::ChoiceP); // ----------------------------------------------------------------------------- : Statistics dimension StatsDimension::StatsDimension() - : automatic (false) - , numeric (false) - , show_empty(false) + : automatic (false) + , position_hint(0) + , numeric (false) + , show_empty (false) {} StatsDimension::StatsDimension(const Field& field) : automatic (true) , name (field.name) , description (field.description) + , position_hint(0) , icon_filename(field.icon_filename) , numeric (false) , show_empty (false) @@ -63,6 +65,7 @@ IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsDimension) { if (!automatic) { REFLECT(name); REFLECT(description); + REFLECT(position_hint); REFLECT_N("icon", icon_filename); REFLECT(script); REFLECT(numeric); @@ -76,6 +79,7 @@ IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsDimension) { StatsCategory::StatsCategory() : automatic(false) + , position_hint(0) , type(GRAPH_TYPE_BAR) {} @@ -83,6 +87,7 @@ StatsCategory::StatsCategory(const StatsDimensionP& dim) : automatic(true) , name (dim->name) , description (dim->description) + , position_hint(dim->position_hint) , icon_filename(dim->icon_filename) , dimensions(1, dim) , type(GRAPH_TYPE_BAR) @@ -92,6 +97,7 @@ IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsCategory) { if (!automatic) { REFLECT(name); REFLECT(description); + REFLECT(position_hint); REFLECT_N("icon", icon_filename); REFLECT(type); REFLECT_N("dimensions", dimension_names); diff --git a/src/data/statistics.hpp b/src/data/statistics.hpp index fba30c9d..1322db03 100644 --- a/src/data/statistics.hpp +++ b/src/data/statistics.hpp @@ -27,9 +27,10 @@ class StatsDimension : public IntrusivePtrBase { StatsDimension(); StatsDimension(const Field&); - bool automatic; ///< Based on a card field? + const bool automatic; ///< Based on a card field? String name; ///< Name of this dimension String description; ///< Description, used in status bar + int position_hint; ///< Hint for the ordering String icon_filename; ///< Icon for lists OptionalScript script; ///< Script that determines the value(s) bool numeric; ///< Are the values numeric? If so, they require special sorting @@ -49,9 +50,10 @@ class StatsCategory : public IntrusivePtrBase { StatsCategory(); StatsCategory(const StatsDimensionP&); - bool automatic; ///< Automatically generated? + const bool automatic; ///< Automatically generated? String name; ///< Name/label String description; ///< Description, used in status bar + int position_hint; ///< Hint for the ordering String icon_filename; ///< Icon for lists Bitmap icon; ///< The loaded icon (optional of course) vector dimension_names;///< Names of the dimensions to use diff --git a/src/gui/set/stats_panel.cpp b/src/gui/set/stats_panel.cpp index de613275..540d13e9 100644 --- a/src/gui/set/stats_panel.cpp +++ b/src/gui/set/stats_panel.cpp @@ -39,30 +39,39 @@ class StatCategoryList : public GalleryList { /// The selected category inline StatsCategory& getSelection() { - return *game->statistics_categories.at(selection); + return *categories.at(selection); } protected: virtual size_t itemCount() const; virtual void drawItem(DC& dc, int x, int y, size_t item, bool selected); - + private: GameP game; + vector categories; ///< Categories, sorted by position_hint +}; + +struct ComparePositionHint{ + inline bool operator () (const StatsCategoryP& a, const StatsCategoryP& b) { + return a->position_hint < b->position_hint; + } }; void StatCategoryList::show(const GameP& game) { this->game = game; + categories = game->statistics_categories; + stable_sort(categories.begin(), categories.end(), ComparePositionHint()); update(); // select first item selection = itemCount() > 0 ? 0 : NO_SELECTION; } size_t StatCategoryList::itemCount() const { - return game ? game->statistics_categories.size() : 0; + return categories.size(); } void StatCategoryList::drawItem(DC& dc, int x, int y, size_t item, bool selected) { - StatsCategory& cat = *game->statistics_categories.at(item); + StatsCategory& cat = *categories.at(item); // draw icon if (!cat.icon_filename.empty() && !cat.icon.Ok()) { InputStreamP file = game->openIn(cat.icon_filename);