Use pointer-to-member signal connections for tutorial validation

Took 10 minutes
This commit is contained in:
Lukas Brübach 2026-08-09 03:30:57 +02:00
parent 0909d356e0
commit b47f4b3d0a
7 changed files with 56 additions and 36 deletions

View file

@ -108,8 +108,10 @@ HomeWidget::HomeWidget(QWidget *parent, TabSupervisor *_tabSupervisor)
vdeStep.validationTiming = ValidationTiming::OnSignal;
vdeStep.autoAdvanceOnValid = true;
vdeStep.validator = []() { return true; };
vdeStep.signalSource = visualDeckEditorButton;
vdeStep.signalName = SIGNAL(clicked());
vdeStep.signalHook = [this](TutorialController *controller) {
return connect(visualDeckEditorButton, &QAbstractButton::clicked, controller,
&TutorialController::checkValidation);
};
sequence.addStep(vdeStep);
sequence.addStep({visualDeckStorageButton, "Browse the decks in your local collection."});

View file

@ -294,10 +294,8 @@ void TutorialController::setupValidationMonitoring()
const auto &step = sequences[currentSequence].steps[currentStep];
// Handle OnSignal validation - connect to any custom signal
if (step.validationTiming == ValidationTiming::OnSignal && step.validator) {
if (step.signalSource && step.signalName) {
validationConnection = connect(step.signalSource, step.signalName, this, SLOT(checkValidation()));
}
if (step.validationTiming == ValidationTiming::OnSignal && step.signalHook) {
validationConnection = step.signalHook(this);
return;
}

View file

@ -15,6 +15,8 @@ enum class ValidationTiming
Manual // Only validate when explicitly triggered
};
class TutorialController;
struct TutorialStep
{
QWidget *targetWidget = nullptr;
@ -35,9 +37,11 @@ struct TutorialStep
// Custom interaction hint (overrides default "Click to continue")
QString customInteractionHint = nullptr;
// Signal-based validation (for ValidationTiming::OnSignal)
QObject *signalSource = nullptr; // Object that emits the signal
const char *signalName = nullptr; // Signal to connect to (use SIGNAL() macro)
// Establishes the connection used for signal-based validation (ValidationTiming::OnSignal).
// Called with the controller so call sites can connect a specific signal to
// TutorialController::checkValidation using pointer-to-member, which is checked at
// compile time unlike string-based SIGNAL() connections.
std::function<QMetaObject::Connection(TutorialController *)> signalHook = nullptr;
};
struct TutorialSequence