diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index e2fc703e9..4ca3b07fa 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -48,6 +48,7 @@ set(cockatrice_SOURCES src/dialogs/dlg_load_deck_from_clipboard.cpp src/dialogs/dlg_load_remote_deck.cpp src/dialogs/dlg_manage_sets.cpp + src/dialogs/dlg_move_top_cards_until.cpp src/dialogs/dlg_register.cpp src/dialogs/dlg_roll_dice.cpp src/dialogs/dlg_settings.cpp diff --git a/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp b/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp new file mode 100644 index 000000000..15293fd8c --- /dev/null +++ b/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp @@ -0,0 +1,66 @@ +#include "dlg_move_top_cards_until.h" + +#include "../game/filters/filter_string.h" +#include "trice_limits.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QString _expr, uint _numberOfHits) : QDialog(parent) +{ + exprLabel = new QLabel(tr("Card name (or search expressions):")); + + exprEdit = new QLineEdit(this); + exprEdit->setFocus(); + exprEdit->setText(_expr); + exprLabel->setBuddy(exprEdit); + + numberOfHitsLabel = new QLabel(tr("Number of hits:")); + numberOfHitsEdit = new QSpinBox(this); + numberOfHitsEdit->setRange(1, 99); + numberOfHitsEdit->setValue(_numberOfHits); + numberOfHitsLabel->setBuddy(numberOfHitsEdit); + + auto *grid = new QGridLayout; + grid->addWidget(numberOfHitsLabel, 0, 0); + grid->addWidget(numberOfHitsEdit, 0, 1); + + buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgMoveTopCardsUntil::validateAndAccept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + + auto *mainLayout = new QVBoxLayout; + mainLayout->addWidget(exprLabel); + mainLayout->addWidget(exprEdit); + mainLayout->addItem(grid); + mainLayout->addWidget(buttonBox); + + setLayout(mainLayout); + setWindowTitle(tr("Put top cards on stack until...")); +} + +void DlgMoveTopCardsUntil::validateAndAccept() +{ + auto movingCardsUntilFilter = FilterString(exprEdit->text()); + if (movingCardsUntilFilter.valid()) { + accept(); + } else { + QMessageBox::warning(this, tr("Invalid filter"), movingCardsUntilFilter.error(), QMessageBox::Ok); + } +} + +QString DlgMoveTopCardsUntil::getExpr() const +{ + return exprEdit->text(); +} + +uint DlgMoveTopCardsUntil::getNumberOfHits() const +{ + return numberOfHitsEdit->text().toUInt(); +} diff --git a/cockatrice/src/dialogs/dlg_move_top_cards_until.h b/cockatrice/src/dialogs/dlg_move_top_cards_until.h new file mode 100644 index 000000000..7b026a942 --- /dev/null +++ b/cockatrice/src/dialogs/dlg_move_top_cards_until.h @@ -0,0 +1,28 @@ +#ifndef DLG_MOVE_TOP_CARDS_UNTIL_H +#define DLG_MOVE_TOP_CARDS_UNTIL_H + +#include +#include +#include +#include +#include +#include + +class DlgMoveTopCardsUntil : public QDialog +{ + Q_OBJECT + + QLabel *exprLabel, *numberOfHitsLabel; + QLineEdit *exprEdit; + QSpinBox *numberOfHitsEdit; + QDialogButtonBox *buttonBox; + + void validateAndAccept(); + +public: + explicit DlgMoveTopCardsUntil(QWidget *parent = nullptr, QString expr = QString(), uint numberOfHits = 1); + QString getExpr() const; + uint getNumberOfHits() const; +}; + +#endif // DLG_MOVE_TOP_CARDS_UNTIL_H diff --git a/cockatrice/src/game/player/player.cpp b/cockatrice/src/game/player/player.cpp index 5565e1129..313e4c1d6 100644 --- a/cockatrice/src/game/player/player.cpp +++ b/cockatrice/src/game/player/player.cpp @@ -5,6 +5,7 @@ #include "../../client/ui/theme_manager.h" #include "../../deck/deck_loader.h" #include "../../dialogs/dlg_create_token.h" +#include "../../dialogs/dlg_move_top_cards_until.h" #include "../../dialogs/dlg_roll_dice.h" #include "../../main.h" #include "../../settings/cache_settings.h" @@ -1330,30 +1331,21 @@ void Player::actMoveTopCardsToExile() void Player::actMoveTopCardsUntil() { - moveTopCardTimer->stop(); - movingCardsUntil = false; - QString expr = previousMovingCardsUntilExpr; - for (;;) { - bool ok; - expr = QInputDialog::getText(game, "Put top cards on stack until", "Card name (or search expressions)", {}, - expr, &ok); - if (!ok) { - return; - } - movingCardsUntilFilter = FilterString(expr); - if (movingCardsUntilFilter.valid()) { - break; - } else { - auto button = QMessageBox::warning(game, "Invalid filter", movingCardsUntilFilter.error()); - if (button != QMessageBox::Ok) { - return; - } - } + stopMoveTopCardsUntil(); + + DlgMoveTopCardsUntil dlg(game, previousMovingCardsUntilExpr, previousMovingCardsUntilNumberOfHits); + if (!dlg.exec()) { + return; } - previousMovingCardsUntilExpr = expr; + + previousMovingCardsUntilExpr = dlg.getExpr(); + previousMovingCardsUntilNumberOfHits = dlg.getNumberOfHits(); + if (zones.value("deck")->getCards().empty()) { - movingCardsUntil = false; + stopMoveTopCardsUntil(); } else { + movingCardsUntilFilter = FilterString(previousMovingCardsUntilExpr); + movingCardsUntilCounter = previousMovingCardsUntilNumberOfHits; movingCardsUntil = true; actMoveTopCardToPlay(); } @@ -1362,13 +1354,30 @@ void Player::actMoveTopCardsUntil() void Player::moveOneCardUntil(const CardInfoPtr card) { moveTopCardTimer->stop(); - if (zones.value("deck")->getCards().empty() || card.isNull() || movingCardsUntilFilter.check(card)) { - movingCardsUntil = false; + if (zones.value("deck")->getCards().empty() || card.isNull()) { + stopMoveTopCardsUntil(); + } else if (movingCardsUntilFilter.check(card)) { + --movingCardsUntilCounter; + if (movingCardsUntilCounter > 0) { + moveTopCardTimer->start(); + } else { + stopMoveTopCardsUntil(); + } } else { moveTopCardTimer->start(); } } +/** + * @brief Immediately stops any ongoing `play top card to stack until...` process, resetting all variables involved. + */ +void Player::stopMoveTopCardsUntil() +{ + moveTopCardTimer->stop(); + movingCardsUntilCounter = 0; + movingCardsUntil = false; +} + void Player::actMoveTopCardToBottom() { if (zones.value("deck")->getCards().empty()) { diff --git a/cockatrice/src/game/player/player.h b/cockatrice/src/game/player/player.h index 7f744a909..24641679f 100644 --- a/cockatrice/src/game/player/player.h +++ b/cockatrice/src/game/player/player.h @@ -267,7 +267,10 @@ private: bool movingCardsUntil; QTimer *moveTopCardTimer; QString previousMovingCardsUntilExpr = {}; + int previousMovingCardsUntilNumberOfHits = 1; FilterString movingCardsUntilFilter; + int movingCardsUntilCounter = 0; + void stopMoveTopCardsUntil(); bool shortcutsActive; int defaultNumberTopCards = 1;