mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-07 18:43:26 -08:00
[Tutorial] Fix review blockers: null VDS guard, overlay QPointer, bounded fill, upgrade seeding
This commit is contained in:
parent
89ef10c862
commit
bfc970b6a9
6 changed files with 33 additions and 5 deletions
|
|
@ -112,7 +112,10 @@ TutorialSequence DeckViewContainer::generateTutorialSequence()
|
||||||
{this, tr("There are multiple ways to select a deck:\n\n- From a local file"
|
{this, tr("There are multiple ways to select a deck:\n\n- From a local file"
|
||||||
"\n- From the contents of your clipboard\nFrom an external online service")});
|
"\n- From the contents of your clipboard\nFrom an external online service")});
|
||||||
|
|
||||||
visualDeckStorageWidget->generateTutorialSequence(deckViewContainerSequence);
|
// The VDS widget only exists when "show visual deck storage in game" is on.
|
||||||
|
if (visualDeckStorageWidget) {
|
||||||
|
visualDeckStorageWidget->generateTutorialSequence(deckViewContainerSequence);
|
||||||
|
}
|
||||||
|
|
||||||
return deckViewContainerSequence;
|
return deckViewContainerSequence;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ private:
|
||||||
|
|
||||||
QWidget *tutorializedWidget;
|
QWidget *tutorializedWidget;
|
||||||
TutorialOverlay *tutorialOverlay;
|
TutorialOverlay *tutorialOverlay;
|
||||||
QVector<TutorialSequence> sequences;
|
QList<TutorialSequence> sequences;
|
||||||
|
|
||||||
bool tutorialCompleted = false;
|
bool tutorialCompleted = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef TUTORIAL_OVERLAY_H
|
#ifndef TUTORIAL_OVERLAY_H
|
||||||
#define TUTORIAL_OVERLAY_H
|
#define TUTORIAL_OVERLAY_H
|
||||||
|
|
||||||
|
#include <QPointer>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class QFrame;
|
class QFrame;
|
||||||
|
|
@ -49,7 +50,9 @@ private:
|
||||||
void recomputeLayout();
|
void recomputeLayout();
|
||||||
QRect computeBubbleRect(const QRect &hole, const QSize &bubbleSize) const;
|
QRect computeBubbleRect(const QRect &hole, const QSize &bubbleSize) const;
|
||||||
|
|
||||||
QWidget *targetWidget = nullptr;
|
// QPointer: the target can be deleted while the overlay lives on (e.g. toggling
|
||||||
|
// the in-game VDS setting deleteLater()s it), so never hold a raw pointer across steps.
|
||||||
|
QPointer<QWidget> targetWidget;
|
||||||
QFrame *controlBar = nullptr;
|
QFrame *controlBar = nullptr;
|
||||||
QLabel *titleLabel = nullptr;
|
QLabel *titleLabel = nullptr;
|
||||||
QPushButton *nextButton = nullptr;
|
QPushButton *nextButton = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,11 @@ void TabGame::finishTutorialInitialization()
|
||||||
tutorialInitialized = true;
|
tutorialInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No sequence building (and no widget access) once the tutorial is done.
|
||||||
|
if (SettingsCache::instance().userInterface().getTutorialCompleted()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto deckViewSequence = deckViewContainers.first()->generateTutorialSequence();
|
auto deckViewSequence = deckViewContainers.first()->generateTutorialSequence();
|
||||||
|
|
||||||
tutorialController->addSequence(deckViewSequence);
|
tutorialController->addSequence(deckViewSequence);
|
||||||
|
|
@ -328,7 +333,7 @@ void TabGame::finishTutorialInitialization()
|
||||||
|
|
||||||
tutorialController->addSequence(gamePlaySequence);
|
tutorialController->addSequence(gamePlaySequence);
|
||||||
|
|
||||||
if (tutorialStarted || SettingsCache::instance().userInterface().getTutorialCompleted()) {
|
if (tutorialStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// The tab may have been shown before the local player joined; start now that
|
// The tab may have been shown before the local player joined; start now that
|
||||||
|
|
|
||||||
|
|
@ -507,8 +507,14 @@ TutorialSequence VisualDeckEditorWidget::addTutorialSteps()
|
||||||
organizationStep.text = "Let's look at how cards are organized and displayed now.\n\nWe'll add some random cards "
|
organizationStep.text = "Let's look at how cards are organized and displayed now.\n\nWe'll add some random cards "
|
||||||
"from the database to your deck, so you can see it in action properly.";
|
"from the database to your deck, so you can see it in action properly.";
|
||||||
organizationStep.onExit = [this]() {
|
organizationStep.onExit = [this]() {
|
||||||
while (deckListModel->getDeckList()->getCardList().size() < 60) {
|
// getCardList() counts distinct card nodes, not copies, so once every random pick only bumps an
|
||||||
|
// existing node's count the size never grows. With fewer than ~60 distinct cards in the database
|
||||||
|
// this would loop forever, so bound the attempts to always terminate.
|
||||||
|
static constexpr int MaxFillAttempts = 600;
|
||||||
|
int attempts = 0;
|
||||||
|
while (deckListModel->getDeckList()->getCardList().size() < 60 && attempts < MaxFillAttempts) {
|
||||||
deckListModel->addCard(CardDatabaseManager::query()->getRandomCard(), DECK_ZONE_MAIN);
|
deckListModel->addCard(CardDatabaseManager::query()->getRandomCard(), DECK_ZONE_MAIN);
|
||||||
|
++attempts;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
#include "interface_settings.h"
|
#include "interface_settings.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
InterfaceSettings::InterfaceSettings(const QString &settingPath, QObject *parent)
|
InterfaceSettings::InterfaceSettings(const QString &settingPath, QObject *parent)
|
||||||
: SettingsManager(settingPath + "interface.ini", "interface", QString(), parent)
|
: SettingsManager(settingPath + "interface.ini", "interface", QString(), parent)
|
||||||
{
|
{
|
||||||
|
|
@ -157,6 +160,14 @@ bool InterfaceSettings::getShowGameSelectorFilterToolbar() const
|
||||||
|
|
||||||
bool InterfaceSettings::getTutorialCompleted() const
|
bool InterfaceSettings::getTutorialCompleted() const
|
||||||
{
|
{
|
||||||
|
// Upgrading users have settings files but no tutorial key yet: treat the tutorial as seen so they are
|
||||||
|
// not overlaid on upgrade. Genuinely new installs have no settings files at all, so they still get it.
|
||||||
|
if (!getSettings().contains("interface/tutorialCompleted")) {
|
||||||
|
QDir settingsDir = QFileInfo(settingPath).dir();
|
||||||
|
if (!settingsDir.entryList({"*.ini"}, QDir::Files).isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return getValue("tutorialCompleted", QString(), QString(), false).toBool();
|
return getValue("tutorialCompleted", QString(), QString(), false).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue