mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-23 10:52:16 -07:00
refactor to allow for sorting by property of choice
This commit is contained in:
parent
37bb1367db
commit
2c3a15208a
4 changed files with 84 additions and 25 deletions
|
|
@ -31,18 +31,49 @@ CardItem *CardList::findCard(const int cardId) const
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardList::sort(int flags)
|
/**
|
||||||
|
* @brief sorts the list by using string comparison on properties extracted from the CardItem
|
||||||
|
* The cards are compared using each property in order.
|
||||||
|
* If two cards have the same value for a property, then the next property in the list is used.
|
||||||
|
*
|
||||||
|
* @param option the option to compare the cards by, in order of usage.
|
||||||
|
*/
|
||||||
|
void CardList::sortBy(const QList<SortOption> &option)
|
||||||
{
|
{
|
||||||
auto comparator = [flags](CardItem *a, CardItem *b) {
|
// early return if we know we won't be sorting
|
||||||
if (flags & SortByType) {
|
if (option.isEmpty()) {
|
||||||
QString t1 = a->getInfo() ? a->getInfo()->getMainCardType() : QString();
|
return;
|
||||||
QString t2 = b->getInfo() ? b->getInfo()->getMainCardType() : QString();
|
}
|
||||||
if ((t1 == t2) && (flags & SortByName))
|
|
||||||
return a->getName() < b->getName();
|
auto comparator = [&option](CardItem *a, CardItem *b) {
|
||||||
return t1 < t2;
|
for (auto prop : option) {
|
||||||
} else
|
auto extractor = getExtractorFor(prop);
|
||||||
return a->getName() < b->getName();
|
QString t1 = extractor(a);
|
||||||
|
QString t2 = extractor(b);
|
||||||
|
if (t1 != t2) {
|
||||||
|
return t1 < t2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::sort(begin(), end(), comparator);
|
std::sort(begin(), end(), comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief returns the function that extracts the given property from the CardItem.
|
||||||
|
*/
|
||||||
|
std::function<QString(CardItem *)> CardList::getExtractorFor(SortOption option)
|
||||||
|
{
|
||||||
|
switch (option) {
|
||||||
|
case NoSort:
|
||||||
|
return [](CardItem *c) { return ""; };
|
||||||
|
case SortByName:
|
||||||
|
return [](CardItem *c) { return c->getName(); };
|
||||||
|
case SortByType:
|
||||||
|
return [](CardItem *c) { return c->getInfo() ? c->getInfo()->getMainCardType() : ""; };
|
||||||
|
case SortByManaValue:
|
||||||
|
// getCmc returns the int as a string. We pad with 0's so that string comp also works on it
|
||||||
|
return [](CardItem *c) { return c->getInfo() ? c->getInfo()->getCmc().rightJustified(4, '0') : ""; };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,10 +11,12 @@ protected:
|
||||||
bool contentsKnown;
|
bool contentsKnown;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum SortFlags
|
enum SortOption
|
||||||
{
|
{
|
||||||
SortByName = 1,
|
NoSort,
|
||||||
SortByType = 2
|
SortByName,
|
||||||
|
SortByType,
|
||||||
|
SortByManaValue
|
||||||
};
|
};
|
||||||
CardList(bool _contentsKnown);
|
CardList(bool _contentsKnown);
|
||||||
CardItem *findCard(const int cardId) const;
|
CardItem *findCard(const int cardId) const;
|
||||||
|
|
@ -22,7 +24,10 @@ public:
|
||||||
{
|
{
|
||||||
return contentsKnown;
|
return contentsKnown;
|
||||||
}
|
}
|
||||||
void sort(int flags = SortByName);
|
|
||||||
|
void sortBy(const QList<SortOption> &options);
|
||||||
|
|
||||||
|
static std::function<QString(CardItem *)> getExtractorFor(SortOption option);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -113,11 +113,28 @@ void ZoneViewZone::reorganizeCards()
|
||||||
cards[i]->setId(i);
|
cards[i]->setId(i);
|
||||||
|
|
||||||
CardList cardsToDisplay(cards);
|
CardList cardsToDisplay(cards);
|
||||||
if (sortByName || sortByType)
|
|
||||||
cardsToDisplay.sort((sortByName ? CardList::SortByName : 0) | (sortByType ? CardList::SortByType : 0));
|
|
||||||
|
|
||||||
auto gridSize = positionCardsForDisplay(cardsToDisplay, pileView && sortByType);
|
// sort cards
|
||||||
|
QList<CardList::SortOption> sortOptions;
|
||||||
|
if (sortByType) {
|
||||||
|
sortOptions << CardList::SortByType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sortByName) {
|
||||||
|
sortOptions << CardList::SortByName;
|
||||||
|
}
|
||||||
|
|
||||||
|
cardsToDisplay.sortBy(sortOptions);
|
||||||
|
|
||||||
|
// position cards
|
||||||
|
GridSize gridSize;
|
||||||
|
if (pileView && sortByType) {
|
||||||
|
gridSize = positionCardsForDisplay(cardsToDisplay, CardList::SortByType);
|
||||||
|
} else {
|
||||||
|
gridSize = positionCardsForDisplay(cardsToDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine bounding rect
|
||||||
qreal aleft = 0;
|
qreal aleft = 0;
|
||||||
qreal atop = 0;
|
qreal atop = 0;
|
||||||
qreal awidth = gridSize.cols * CARD_WIDTH + (CARD_WIDTH / 2) + HORIZONTAL_PADDING;
|
qreal awidth = gridSize.cols * CARD_WIDTH + (CARD_WIDTH / 2) + HORIZONTAL_PADDING;
|
||||||
|
|
@ -132,24 +149,30 @@ void ZoneViewZone::reorganizeCards()
|
||||||
* @brief Sets the position of each card to the proper position for the view
|
* @brief Sets the position of each card to the proper position for the view
|
||||||
*
|
*
|
||||||
* @param cards The cards to reposition. Will modify the cards in the list.
|
* @param cards The cards to reposition. Will modify the cards in the list.
|
||||||
* @param groupByType Whether to make piles by card type. If true, then expects `cards` to be sorted by type.
|
* @param pileOption Property used to group cards for the piles. Expects `cards` to be sorted by that property. Pass in
|
||||||
|
* NoSort to not make piles.
|
||||||
*
|
*
|
||||||
* @returns The number of rows and columns to display
|
* @returns The number of rows and columns to display
|
||||||
*/
|
*/
|
||||||
ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, bool groupByType)
|
ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, CardList::SortOption pileOption)
|
||||||
{
|
{
|
||||||
int cardCount = cards.size();
|
int cardCount = cards.size();
|
||||||
if (groupByType) {
|
|
||||||
|
if (pileOption != CardList::NoSort) {
|
||||||
int row = 0;
|
int row = 0;
|
||||||
int col = 0;
|
int col = 0;
|
||||||
int longestRow = 0;
|
int longestRow = 0;
|
||||||
QString lastCardType;
|
|
||||||
|
QString lastColumnProp;
|
||||||
|
|
||||||
|
const auto extractor = CardList::getExtractorFor(pileOption);
|
||||||
|
|
||||||
for (int i = 0; i < cardCount; i++) {
|
for (int i = 0; i < cardCount; i++) {
|
||||||
CardItem *c = cards.at(i);
|
CardItem *c = cards.at(i);
|
||||||
QString cardType = c->getInfo() ? c->getInfo()->getMainCardType() : "";
|
QString columnProp = extractor(c);
|
||||||
|
|
||||||
if (i) { // if not the first card
|
if (i) { // if not the first card
|
||||||
if (cardType == lastCardType)
|
if (columnProp == lastColumnProp)
|
||||||
row++; // add below current card
|
row++; // add below current card
|
||||||
else { // if no match then move card to next column
|
else { // if no match then move card to next column
|
||||||
col++;
|
col++;
|
||||||
|
|
@ -157,7 +180,7 @@ ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, bo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastCardType = cardType;
|
lastColumnProp = columnProp;
|
||||||
qreal x = col * CARD_WIDTH;
|
qreal x = col * CARD_WIDTH;
|
||||||
qreal y = row * CARD_HEIGHT / 3;
|
qreal y = row * CARD_HEIGHT / 3;
|
||||||
c->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y);
|
c->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y);
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ private:
|
||||||
int cols;
|
int cols;
|
||||||
};
|
};
|
||||||
|
|
||||||
GridSize positionCardsForDisplay(CardList &cards, bool groupByType = false);
|
GridSize positionCardsForDisplay(CardList &cards, CardList::SortOption pileOption = CardList::NoSort);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ZoneViewZone(Player *_p,
|
ZoneViewZone(Player *_p,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue