[go: nahoru, domu]

blob: a76e16391917d619e71782602ad98270306f648b [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_ACTIONS_ACTIONS_H_
#define UI_ACTIONS_ACTIONS_H_
#include <string>
#include <vector>
#include "base/callback_list.h"
#include "base/component_export.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/actions/action_id.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/models/image_model.h"
#include "ui/events/event.h"
namespace actions {
class ActionItem;
using ActionListVector = std::vector<std::unique_ptr<ActionItem>>;
using ActionItemVector = std::vector<ActionItem*>;
class COMPONENT_EXPORT(ACTIONS) ActionList {
public:
class Delegate {
public:
virtual ~Delegate() = default;
virtual void ActionListChanged() = 0;
};
explicit ActionList(Delegate* delegate);
~ActionList();
const ActionListVector& children() const { return children_; }
bool empty() { return children_.empty(); }
ActionItem* AddAction(std::unique_ptr<ActionItem> action_item);
std::unique_ptr<ActionItem> RemoveAction(ActionItem* action_item);
private:
ActionListVector children_;
raw_ptr<Delegate> delegate_;
};
class COMPONENT_EXPORT(ACTIONS) ActionItem
: public ui::metadata::MetaDataProvider,
public ActionList::Delegate {
public:
using ActionChangedCallback = ui::metadata::PropertyChangedCallback;
using InvokeActionCallback = base::RepeatingCallback<void(ActionItem*)>;
class COMPONENT_EXPORT(ACTIONS) ActionItemBuilder {
public:
using ChildList = std::vector<std::unique_ptr<ActionItemBuilder>>;
ActionItemBuilder();
explicit ActionItemBuilder(InvokeActionCallback callback);
ActionItemBuilder(ActionItemBuilder&&);
ActionItemBuilder& operator=(ActionItemBuilder&&);
~ActionItemBuilder();
ActionItemBuilder& AddChild(ActionItemBuilder&& child_item) &;
ActionItemBuilder&& AddChild(ActionItemBuilder&& child_item) &&;
template <typename Child, typename... Types>
ActionItemBuilder& AddChildren(Child&& child, Types&&... args) & {
return AddChildrenImpl(&child, &args...);
}
template <typename Child, typename... Types>
ActionItemBuilder&& AddChildren(Child&& child, Types&&... args) && {
return std::move(this->AddChildrenImpl(&child, &args...));
}
ActionItemBuilder& SetActionId(absl::optional<ActionId> action_id) &;
ActionItemBuilder&& SetActionId(absl::optional<ActionId> action_id) &&;
ActionItemBuilder& SetAccelerator(ui::Accelerator accelerator) &;
ActionItemBuilder&& SetAccelerator(ui::Accelerator accelerator) &&;
ActionItemBuilder& SetChecked(bool checked) &;
ActionItemBuilder&& SetChecked(bool checked) &&;
ActionItemBuilder& SetEnabled(bool enabled) &;
ActionItemBuilder&& SetEnabled(bool enabled) &&;
ActionItemBuilder& SetImage(const ui::ImageModel& image) &;
ActionItemBuilder&& SetImage(const ui::ImageModel& image) &&;
ActionItemBuilder& SetText(const std::u16string& text) &;
ActionItemBuilder&& SetText(const std::u16string& text) &&;
ActionItemBuilder& SetTooltipText(const std::u16string& tooltip) &;
ActionItemBuilder&& SetTooltipText(const std::u16string& tooltip) &&;
ActionItemBuilder& SetVisible(bool visible) &;
ActionItemBuilder&& SetVisible(bool visible) &&;
ActionItemBuilder& SetInvokeActionCallback(InvokeActionCallback callback) &;
ActionItemBuilder&& SetInvokeActionCallback(
InvokeActionCallback callback) &&;
[[nodiscard]] std::unique_ptr<ActionItem> Build() &&;
private:
template <typename... Args>
ActionItemBuilder& AddChildrenImpl(Args*... args) & {
std::vector<ActionItemBuilder*> children = {args...};
for (auto* child : children) {
children_.emplace_back(child->Release());
}
return *this;
}
void CreateChildren();
[[nodiscard]] std::unique_ptr<ActionItemBuilder> Release();
std::unique_ptr<ActionItem> action_item_;
ChildList children_;
};
METADATA_HEADER_BASE(ActionItem);
ActionItem();
explicit ActionItem(InvokeActionCallback callback);
ActionItem(const ActionItem&) = delete;
ActionItem& operator=(const ActionItem&) = delete;
~ActionItem() override;
absl::optional<ActionId> GetActionId() const;
void SetActionId(absl::optional<ActionId> action_id);
ui::Accelerator GetAccelerator() const;
void SetAccelerator(ui::Accelerator accelerator);
bool GetChecked() const;
void SetChecked(bool checked);
bool GetEnabled() const;
void SetEnabled(bool enabled);
const ui::ImageModel& GetImage() const;
void SetImage(const ui::ImageModel& image);
const std::u16string GetText() const;
void SetText(const std::u16string& text);
const std::u16string GetTooltipText() const;
void SetTooltipText(const std::u16string& tooltip);
ActionItem* GetParent() const;
bool GetVisible() const;
void SetVisible(bool visible);
void SetInvokeActionCallback(InvokeActionCallback callback);
ActionItem* AddChild(std::unique_ptr<ActionItem> action_item);
std::unique_ptr<ActionItem> RemoveChild(ActionItem* action_item);
[[nodiscard]] base::CallbackListSubscription AddActionChangedCallback(
ActionChangedCallback callback);
// Alternative terms used to identify this action. Used for search indexing
void AddSynonyms(std::initializer_list<std::u16string> synonyms);
void InvokeAction();
static ActionItemBuilder Builder(InvokeActionCallback callback);
static ActionItemBuilder Builder();
const ActionList& GetChildren() const { return children_; }
protected:
// ActionList::Delegate override.
void ActionListChanged() override;
void ActionItemChanged();
private:
using Synonyms = std::vector<std::u16string>;
raw_ptr<ActionItem> parent_ = nullptr;
ActionList children_{this};
absl::optional<ActionId> action_id_;
ui::Accelerator accelerator_;
bool checked_ = false;
bool enabled_ = true;
bool visible_ = true;
std::u16string text_;
std::u16string tooltip_;
ui::ImageModel image_;
Synonyms synonyms_;
InvokeActionCallback callback_;
};
class COMPONENT_EXPORT(ACTIONS) ActionManager
: public ui::metadata::MetaDataProvider,
public ActionList::Delegate {
public:
METADATA_HEADER_BASE(ActionManager);
using ActionItemInitializerList =
base::RepeatingCallbackList<void(ActionManager*)>;
ActionManager(const ActionManager&) = delete;
ActionManager& operator=(const ActionManager&) = delete;
static ActionManager& Get();
static ActionManager& GetForTesting();
static void ResetForTesting();
void IndexActions();
ActionItem* FindAction(std::u16string term);
ActionItem* FindAction(ActionId action_id);
ActionItem* FindAction(const ui::KeyEvent& key_event);
void GetActions(ActionItemVector& items);
ActionItem* AddAction(std::unique_ptr<ActionItem> action_item);
std::unique_ptr<ActionItem> RemoveAction(ActionItem* action_item);
// Clears the actions stored in `root_action_list_`.
void ResetActions();
// Resets the current `initializer_list_`.
void ResetActionItemInitializerList();
// Appends `initializer` to the end of the current `initializer_list_`.
void AppendActionItemInitializer(
ActionItemInitializerList::CallbackType initializer);
protected:
ActionManager();
~ActionManager() override;
// ActionList::Delegate override.
void ActionListChanged() override;
private:
void GetActionsImpl(ActionItem* item, ActionItemVector& items);
// Holds the chain of ActionManager initializer callbacks.
std::unique_ptr<ActionItemInitializerList> initializer_list_;
// Holds the subscriptions for initializers in the `initializer_list_`.
std::vector<base::CallbackListSubscription> initializer_subscriptions_;
// Holds all the "root" actions. Most actions will live here.
std::unique_ptr<ActionList> root_action_list_;
};
} // namespace actions
#endif // UI_ACTIONS_ACTIONS_H_