#ifndef UI_BASE_MODELS_DIALOG_MODEL_H_
#define UI_BASE_MODELS_DIALOG_MODEL_H_
#include <memory>
#include <string>
#include "base/component_export.h"
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/types/pass_key.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/base/models/dialog_model_field.h"
#include "ui/base/models/dialog_model_host.h"
#include "ui/base/models/image_model.h"
#include "ui/base/ui_base_types.h"
namespace ui {
class ComboboxModel;
class COMPONENT_EXPORT(UI_BASE) DialogModelDelegate {
public:
DialogModelDelegate() = default;
DialogModelDelegate(const DialogModelDelegate&) = delete;
DialogModelDelegate& operator=(const DialogModelDelegate&) = delete;
virtual ~DialogModelDelegate() = default;
DialogModel* dialog_model() { return dialog_model_; }
private:
friend class DialogModel;
void set_dialog_model(DialogModel* model) { dialog_model_ = model; }
raw_ptr<DialogModel> dialog_model_ = nullptr;
};
class COMPONENT_EXPORT(UI_BASE) DialogModel final {
public:
class COMPONENT_EXPORT(UI_BASE) Builder final {
public:
explicit Builder(std::unique_ptr<DialogModelDelegate> delegate);
Builder();
Builder(const Builder&) = delete;
Builder& operator=(const Builder&) = delete;
~Builder();
[[nodiscard]] std::unique_ptr<DialogModel> Build();
DialogModel* model() { return model_.get(); }
Builder& OverrideShowCloseButton(bool show_close_button) {
model_->override_show_close_button_ = show_close_button;
return *this;
}
Builder& SetInternalName(std::string internal_name) {
model_->internal_name_ = std::move(internal_name);
return *this;
}
Builder& SetTitle(std::u16string title) {
model_->title_ = std::move(title);
return *this;
}
Builder& SetAccessibleTitle(std::u16string accessible_title) {
model_->accessible_title_ = std::move(accessible_title);
return *this;
}
Builder& SetSubtitle(std::u16string subtitle) {
model_->subtitle_ = std::move(subtitle);
return *this;
}
Builder& SetBannerImage(ImageModel banner,
ImageModel dark_mode_banner = ImageModel()) {
model_->banner_ = std::move(banner);
model_->dark_mode_banner_ = std::move(dark_mode_banner);
return *this;
}
Builder& SetIcon(ImageModel icon,
ImageModel dark_mode_icon = ImageModel()) {
model_->icon_ = std::move(icon);
model_->dark_mode_icon_ = std::move(dark_mode_icon);
return *this;
}
Builder& SetMainImage(ImageModel main_image) {
model_->main_image_ = std::move(main_image);
return *this;
}
Builder& SetIsAlertDialog() {
model_->is_alert_dialog_ = true;
return *this;
}
Builder& DisableCloseOnDeactivate() {
model_->close_on_deactivate_ = false;
return *this;
}
Builder& SetCloseActionCallback(base::OnceClosure callback) {
model_->close_action_callback_ = std::move(callback);
return *this;
}
Builder& SetDialogDestroyingCallback(base::OnceClosure callback) {
model_->dialog_destroying_callback_ = std::move(callback);
return *this;
}
Builder& AddOkButton(
base::OnceClosure callback,
const DialogModelButton::Params& params = DialogModelButton::Params());
Builder& AddCancelButton(
base::OnceClosure callback,
const DialogModelButton::Params& params = DialogModelButton::Params());
Builder& AddExtraButton(
base::RepeatingCallback<void(const Event&)> callback,
const DialogModelButton::Params& params);
Builder& AddExtraLink(DialogModelLabel::TextReplacement link);
Builder& AddParagraph(const DialogModelLabel& label,
std::u16string header = std::u16string(),
ElementIdentifier id = ElementIdentifier()) {
model_->AddParagraph(label, header, id);
return *this;
}
Builder& AddCheckbox(ElementIdentifier id,
const DialogModelLabel& label,
const DialogModelCheckbox::Params& params =
DialogModelCheckbox::Params()) {
model_->AddCheckbox(id, label, params);
return *this;
}
Builder& AddCombobox(ElementIdentifier id,
std::u16string label,
std::unique_ptr<ui::ComboboxModel> combobox_model,
const DialogModelCombobox::Params& params =
DialogModelCombobox::Params()) {
model_->AddCombobox(id, std::move(label), std::move(combobox_model),
params);
return *this;
}
Builder& AddMenuItem(ImageModel icon,
std::u16string label,
base::RepeatingCallback<void(int)> callback,
const DialogModelMenuItem::Params& params =
DialogModelMenuItem::Params()) {
model_->AddMenuItem(std::move(icon), std::move(label),
std::move(callback), params);
return *this;
}
Builder& AddSeparator() {
model_->AddSeparator();
return *this;
}
Builder& AddTextfield(ElementIdentifier id,
std::u16string label,
std::u16string text,
const DialogModelTextfield::Params& params =
DialogModelTextfield::Params()) {
model_->AddTextfield(id, std::move(label), std::move(text), params);
return *this;
}
Builder& AddCustomField(
std::unique_ptr<DialogModelCustomField::Field> field,
ElementIdentifier id = ElementIdentifier()) {
model_->AddCustomField(std::move(field), id);
return *this;
}
Builder& OverrideDefaultButton(DialogButton button);
Builder& SetInitiallyFocusedField(ElementIdentifier id);
private:
std::unique_ptr<DialogModel> model_;
};
DialogModel(base::PassKey<DialogModel::Builder>,
std::unique_ptr<DialogModelDelegate> delegate);
DialogModel(const DialogModel&) = delete;
DialogModel& operator=(const DialogModel&) = delete;
~DialogModel();
DialogModelHost* host() { return host_; }
void AddParagraph(const DialogModelLabel& label,
std::u16string header,
ElementIdentifier id = ElementIdentifier());
void AddCheckbox(ElementIdentifier id,
const DialogModelLabel& label,
const DialogModelCheckbox::Params& params =
DialogModelCheckbox::Params());
void AddCombobox(ElementIdentifier id,
std::u16string label,
std::unique_ptr<ui::ComboboxModel> combobox_model,
const DialogModelCombobox::Params& params =
DialogModelCombobox::Params());
void AddMenuItem(ImageModel icon,
std::u16string label,
base::RepeatingCallback<void(int)> callback,
const DialogModelMenuItem::Params& params =
DialogModelMenuItem::Params());
void AddSeparator();
void AddTextfield(ElementIdentifier id,
std::u16string label,
std::u16string text,
const DialogModelTextfield::Params& params =
DialogModelTextfield::Params());
void AddCustomField(std::unique_ptr<DialogModelCustomField::Field> field,
ElementIdentifier id = ElementIdentifier());
bool HasField(ElementIdentifier id) const;
DialogModelField* GetFieldByUniqueId(ElementIdentifier id);
DialogModelCheckbox* GetCheckboxByUniqueId(ElementIdentifier id);
DialogModelCombobox* GetComboboxByUniqueId(ElementIdentifier id);
DialogModelTextfield* GetTextfieldByUniqueId(ElementIdentifier id);
void OnDialogAcceptAction(base::PassKey<DialogModelHost>);
void OnDialogCancelAction(base::PassKey<DialogModelHost>);
void OnDialogCloseAction(base::PassKey<DialogModelHost>);
void OnDialogDestroying(base::PassKey<DialogModelHost>);
void set_host(base::PassKey<DialogModelHost>, DialogModelHost* host) {
host_ = host;
}
const absl::optional<bool>& override_show_close_button(
base::PassKey<DialogModelHost>) const {
return override_show_close_button_;
}
const std::string& internal_name(base::PassKey<DialogModelHost>) const {
return internal_name_;
}
const std::u16string& title(base::PassKey<DialogModelHost>) const {
return title_;
}
const std::u16string& accessible_title(base::PassKey<DialogModelHost>) const {
return accessible_title_;
}
const std::u16string& subtitle(base::PassKey<DialogModelHost>) const {
return subtitle_;
}
const ImageModel& main_image(base::PassKey<DialogModelHost>) const {
return main_image_;
}
const ImageModel& icon(base::PassKey<DialogModelHost>) const { return icon_; }
const ImageModel& dark_mode_icon(base::PassKey<DialogModelHost>) const {
return dark_mode_icon_;
}
const ImageModel& banner(base::PassKey<DialogModelHost>) const {
return banner_;
}
const ImageModel& dark_mode_banner(base::PassKey<DialogModelHost>) const {
return dark_mode_banner_;
}
const absl::optional<DialogButton>& override_default_button(
base::PassKey<DialogModelHost>) const {
return override_default_button_;
}
ElementIdentifier initially_focused_field(
base::PassKey<DialogModelHost>) const {
return initially_focused_field_;
}
bool is_alert_dialog(base::PassKey<DialogModelHost>) const {
return is_alert_dialog_;
}
DialogModelButton* ok_button(base::PassKey<DialogModelHost>) {
return ok_button_.has_value() ? &ok_button_.value() : nullptr;
}
DialogModelButton* cancel_button(base::PassKey<DialogModelHost>) {
return cancel_button_.has_value() ? &cancel_button_.value() : nullptr;
}
DialogModelButton* extra_button(base::PassKey<DialogModelHost>) {
return extra_button_.has_value() ? &extra_button_.value() : nullptr;
}
DialogModelLabel::TextReplacement* extra_link(
base::PassKey<DialogModelHost>) {
return extra_link_.has_value() ? &extra_link_.value() : nullptr;
}
bool close_on_deactivate(base::PassKey<DialogModelHost>) const {
return close_on_deactivate_;
}
const std::vector<std::unique_ptr<DialogModelField>>& fields(
base::PassKey<DialogModelHost>) {
return fields_;
}
private:
base::PassKey<DialogModel> GetPassKey() {
return base::PassKey<DialogModel>();
}
void AddField(std::unique_ptr<DialogModelField> field);
std::unique_ptr<DialogModelDelegate> delegate_;
raw_ptr<DialogModelHost> host_ = nullptr;
absl::optional<bool> override_show_close_button_;
bool close_on_deactivate_ = true;
std::string internal_name_;
std::u16string title_;
std::u16string accessible_title_;
std::u16string subtitle_;
ImageModel icon_;
ImageModel dark_mode_icon_;
ImageModel main_image_;
ImageModel banner_;
ImageModel dark_mode_banner_;
absl::optional<DialogButton> override_default_button_;
std::vector<std::unique_ptr<DialogModelField>> fields_;
ElementIdentifier initially_focused_field_;
bool is_alert_dialog_ = false;
absl::optional<DialogModelButton> ok_button_;
absl::optional<DialogModelButton> cancel_button_;
absl::optional<DialogModelButton> extra_button_;
absl::optional<DialogModelLabel::TextReplacement> extra_link_;
base::OnceClosure accept_action_callback_;
base::OnceClosure cancel_action_callback_;
base::OnceClosure close_action_callback_;
base::OnceClosure dialog_destroying_callback_;
};
}
#endif