From 80075e4089ffd657e300d928fb59d3b622d039da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Wed, 21 Jan 2026 18:45:22 +0100 Subject: [PATCH] Expand tutorial again. Took 46 minutes Took 6 seconds --- .../deck_analytics/deck_analytics_widget.cpp | 43 +++++++++++++++++++ .../deck_analytics/deck_analytics_widget.h | 2 + .../deck_editor_deck_dock_widget.cpp | 17 ++++++++ .../deck_editor_deck_dock_widget.h | 3 ++ .../tab_deck_editor_visual.cpp | 21 +++++++++ .../visual_deck_editor_sample_hand_widget.cpp | 24 +++++++++++ .../visual_deck_editor_sample_hand_widget.h | 2 + 7 files changed, 112 insertions(+) diff --git a/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.cpp index ea61302f0..a85597910 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.cpp @@ -1,5 +1,7 @@ #include "deck_analytics_widget.h" +#include "../general/tutorial/tutorial_controller.h" +#include "../tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.h" #include "abstract_analytics_panel_widget.h" #include "add_analytics_panel_dialog.h" #include "analytics_panel_widget_factory.h" @@ -7,6 +9,7 @@ #include "analyzer_modules/mana_curve/mana_curve_config.h" #include "analyzer_modules/mana_devotion/mana_devotion_config.h" #include "deck_list_statistics_analyzer.h" +#include "libcockatrice/utility/qt_utils.h" #include "resizable_panel.h" #include @@ -60,6 +63,46 @@ DeckAnalyticsWidget::DeckAnalyticsWidget(QWidget *parent, DeckListStatisticsAnal retranslateUi(); } +TutorialSequence DeckAnalyticsWidget::generateTutorialSequence() +{ + TutorialSequence analyticsSequence; + analyticsSequence.name = tr("Deck Analytics"); + + TutorialStep introStep; + introStep.targetWidget = this; + introStep.text = tr("This is the deck analytics tab.\n\nHere, you can view more detailed information about your " + "deck via the use of specialized analytics widgets."); + introStep.onEnter = [this]() { + auto tabWidget = QtUtils::findParentOfType(this); + if (tabWidget) { + tabWidget->setCurrentWidget(tabWidget->deckAnalytics); + } + }; + + analyticsSequence.addStep(introStep); + + TutorialStep controlStep; + controlStep.targetWidget = controlContainer; + controlStep.text = tr( + "These controls will allow you to customize your analytics widget layout.\n\nAll widgets can be resized or " + "reordered with the handle at their bottom.\nTo remove a widget, you first have to select it.\nSaving your " + "layout will ensure that it is the default for all future decks you open, whereas loading the layout will " + "allow you to revert back to your previous configuration in case you decide you do not like your new layout."); + + analyticsSequence.addStep(controlStep); + + TutorialStep widgetStep; + widgetStep.targetWidget = this; + widgetStep.text = + tr("Finally, let's talk about the analytics widgets themselves.\n\nHow the various analytics are displayed for " + "each widget can be configured by clicking on the cogwheel next to the respective banner.\nHovering over " + "the segments of different diagram types will reveal which cards belong to the respective segment."); + + analyticsSequence.addStep(widgetStep); + + return analyticsSequence; +} + void DeckAnalyticsWidget::retranslateUi() { addButton->setText(tr("Add Panel")); diff --git a/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.h b/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.h index 31ee36fbb..faef4e6d2 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.h +++ b/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.h @@ -7,6 +7,7 @@ #ifndef DECK_ANALYTICS_WIDGET_H #define DECK_ANALYTICS_WIDGET_H +#include "../general/tutorial/tutorial_controller.h" #include "abstract_analytics_panel_widget.h" #include "deck_list_statistics_analyzer.h" #include "resizable_panel.h" @@ -29,6 +30,7 @@ public slots: public: explicit DeckAnalyticsWidget(QWidget *parent, DeckListStatisticsAnalyzer *analyzer); void retranslateUi(); + TutorialSequence generateTutorialSequence(); private slots: void onAddPanel(); diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp index f939ae99d..ddabc9b56 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp @@ -1,6 +1,7 @@ #include "deck_editor_deck_dock_widget.h" #include "../../../client/settings/cache_settings.h" +#include "../general/tutorial/tutorial_controller.h" #include "deck_list_style_proxy.h" #include "deck_state_manager.h" @@ -280,6 +281,22 @@ void DeckEditorDeckDockWidget::createDeckDock() } } +TutorialSequence DeckEditorDeckDockWidget::generateTutorialSequence() +{ + TutorialSequence sequence; + sequence.name = tr("The Deck Info Widget"); + + TutorialStep introStep; + introStep.targetWidget = this; + introStep.text = tr("This is the deck info widget.\n\nHere, you can adjust all kinds of metadata such as the name, " + "the comments, or the tags of a deck.\nIt also displays the contents of your deck in a list " + "and provides buttons to manipulate the decklist."); + + sequence.addStep(introStep); + + return sequence; +} + void DeckEditorDeckDockWidget::initializeFormats() { QStringList allFormats = CardDatabaseManager::query()->getAllFormatsWithCount().keys(); diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h index 8dddf5882..5ef1b176e 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h @@ -10,6 +10,7 @@ #include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" #include "../../key_signals.h" +#include "../general/tutorial/tutorial_controller.h" #include "../utility/custom_line_edit.h" #include "../visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h" #include "deck_list_history_manager_widget.h" @@ -46,6 +47,8 @@ public: return deckView->selectionModel(); } + TutorialSequence generateTutorialSequence(); + public slots: void selectPrevCard(); void selectNextCard(); diff --git a/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.cpp b/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.cpp index c08dd27e7..53dc24b04 100644 --- a/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.cpp +++ b/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.cpp @@ -54,6 +54,10 @@ TabDeckEditorVisual::TabDeckEditorVisual(TabSupervisor *_tabSupervisor) : Abstra cardDatabaseDockWidget->setHidden(true); tutorialController = new TutorialController(this); + auto deckDockSequence = deckDockWidget->generateTutorialSequence(); + + tutorialController->addSequence(deckDockSequence); + auto sequence = TutorialSequence(); sequence.addStep({tabContainer->tabBar(), @@ -80,6 +84,23 @@ TabDeckEditorVisual::TabDeckEditorVisual(TabSupervisor *_tabSupervisor) : Abstra [this]() { tabContainer->setCurrentWidget(tabContainer->visualDatabaseDisplay); }}); tutorialController->addSequence(vddSequence); + + auto analyticsSequence = tabContainer->deckAnalytics->generateTutorialSequence(); + analyticsSequence.steps.prepend({tabContainer->tabBar(), "Let's look at the analytics tab now."}); + + TutorialStep analyticsConclusionStep; + analyticsConclusionStep.targetWidget = tabContainer->tabBar(); + analyticsConclusionStep.text = + tr("That was it for the analytics tab.\n\nLet's now look at an equally useful tab, which provides you with " + "detailed information about possible hands, invaluable information when testing out a new deck."); + + analyticsSequence.addStep(analyticsConclusionStep); + + tutorialController->addSequence(analyticsSequence); + + auto sampleHandSequence = tabContainer->sampleHandWidget->generateTutorialSequence(); + + tutorialController->addSequence(sampleHandSequence); } void TabDeckEditorVisual::showEvent(QShowEvent *ev) diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp index 3a34e07a7..a885fa927 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp @@ -5,6 +5,9 @@ #include "../cards/card_info_picture_widget.h" #include "../deck_analytics/analyzer_modules/draw_probability/draw_probability_widget.h" #include "../deck_analytics/deck_list_statistics_analyzer.h" +#include "../general/tutorial/tutorial_controller.h" +#include "../tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.h" +#include "libcockatrice/utility/qt_utils.h" #include #include @@ -66,6 +69,27 @@ VisualDeckEditorSampleHandWidget::VisualDeckEditorSampleHandWidget(QWidget *pare retranslateUi(); } +TutorialSequence VisualDeckEditorSampleHandWidget::generateTutorialSequence() +{ + TutorialSequence sampleHandSequence; + sampleHandSequence.name = tr("Sample Hand"); + + TutorialStep introStep; + introStep.targetWidget = this; + introStep.text = tr("This is the sample hand tab.\n\nHere, you can draw a sample hand from your deck without " + "having to start a game as well as view statistical information about your draws."); + introStep.onEnter = [this]() { + auto tabWidget = QtUtils::findParentOfType(this); + if (tabWidget) { + tabWidget->setCurrentWidget(tabWidget->sampleHandWidget); + } + }; + + sampleHandSequence.addStep(introStep); + + return sampleHandSequence; +} + void VisualDeckEditorSampleHandWidget::retranslateUi() { resetButton->setText(tr("Draw a new sample hand")); diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.h b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.h index c63c74a4d..083400772 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.h @@ -10,6 +10,7 @@ #include "../cards/card_size_widget.h" #include "../deck_analytics/deck_list_statistics_analyzer.h" #include "../general/layout_containers/flow_widget.h" +#include "../general/tutorial/tutorial_controller.h" #include #include @@ -25,6 +26,7 @@ public: DeckListModel *deckListModel, DeckListStatisticsAnalyzer *statsAnalyzer); QList getRandomCards(int amountToGet); + TutorialSequence generateTutorialSequence(); public slots: void updateDisplay();