blob: 1a178c558eb9081e822e31f696ef5c89713602fe [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/user_education/common/tutorial/tutorial_description.h"
#include <string_view>
#include <variant>
#include "components/user_education/common/user_education_events.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/base/interaction/element_tracker.h"
#include "ui/base/interaction/interaction_sequence.h"
namespace user_education {
ScopedTutorialState::ScopedTutorialState(ui::ElementContext context)
: context_(context) {}
ScopedTutorialState::~ScopedTutorialState() = default;
TutorialDescription::TutorialDescription() = default;
TutorialDescription::TutorialDescription(TutorialDescription&&) noexcept =
default;
TutorialDescription& TutorialDescription::operator=(
TutorialDescription&&) noexcept = default;
TutorialDescription::~TutorialDescription() = default;
TutorialDescription::Step::Step() = default;
TutorialDescription::Step::Step(ElementSpecifier element,
ui::InteractionSequence::StepType step_type,
HelpBubbleArrow arrow,
ui::CustomElementEventType event_type)
: element_(element), step_type_(step_type), event_type_(event_type) {}
TutorialDescription::Step::Step(const TutorialDescription::Step&) = default;
TutorialDescription::Step& TutorialDescription::Step::operator=(
const TutorialDescription::Step&) = default;
TutorialDescription::Step::~Step() = default;
TutorialDescription::Step& TutorialDescription::Step::NameElement(
std::string name) {
return NameElements(base::BindRepeating(
[](std::string name, ui::InteractionSequence* sequence,
ui::TrackedElement* element) {
sequence->NameElement(element, std::string_view(name));
return true;
},
name));
}
bool TutorialDescription::Step::ShouldShowBubble() const {
// Hide steps and steps with no body text are "hidden" steps.
return body_text_id_ &&
step_type_ != ui::InteractionSequence::StepType::kHidden &&
step_type_ != ui::InteractionSequence::StepType::kSubsequence;
}
TutorialDescription::BubbleStep&
TutorialDescription::BubbleStep::AddDefaultNextButton() {
return AddCustomNextButton(
base::BindRepeating([](ui::TrackedElement* current_anchor) {
ui::ElementTracker::GetFrameworkDelegate()->NotifyCustomEvent(
current_anchor, kHelpBubbleNextButtonClickedEvent);
}));
}
TutorialDescription::WaitForAnyOf::WaitForAnyOf(ElementSpecifier first,
bool wait_for_event)
: HiddenStep(ui::ElementIdentifier(),
ui::InteractionSequence::StepType::kSubsequence) {
subsequence_mode_ = ui::InteractionSequence::SubsequenceMode::kAtLeastOne;
Or(first, wait_for_event);
}
TutorialDescription::WaitForAnyOf& TutorialDescription::WaitForAnyOf::Or(
ElementSpecifier element,
bool wait_for_event) {
branches_.emplace_back(
AlwaysRun(), Steps(wait_for_event ? HiddenStep::WaitForShowEvent(element)
: HiddenStep::WaitForShown(element)));
return *this;
}
// static
TutorialDescription::ConditionalCallback TutorialDescription::AlwaysRun() {
return base::BindRepeating([](const ui::TrackedElement*) { return true; });
}
// static
TutorialDescription::ConditionalCallback TutorialDescription::RunIfPresent() {
return base::BindRepeating(
[](const ui::TrackedElement* el) { return el != nullptr; });
}
} // namespace user_education