#include "ui/views/examples/dialog_model_example.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/combobox_model.h"
#include "ui/base/models/dialog_model.h"
#include "ui/views/bubble/bubble_dialog_model_host.h"
#include "ui/views/controls/button/checkbox.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/label.h"
#include "ui/views/examples/examples_window.h"
#include "ui/views/layout/box_layout_view.h"
#include "ui/views/widget/widget.h"
namespace views::examples {
namespace {
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kNameTextfield);
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kPasswordField);
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kRememberMeCheckbox);
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kFruitCombobox);
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kCustomField);
class FruitsComboboxModel : public ui::ComboboxModel {
public:
FruitsComboboxModel() {
fruits_.push_back(u"Apple");
fruits_.push_back(u"Banana");
fruits_.push_back(u"Orange");
}
FruitsComboboxModel(const FruitsComboboxModel&) = delete;
FruitsComboboxModel& operator=(const FruitsComboboxModel&) = delete;
~FruitsComboboxModel() override = default;
size_t GetItemCount() const override { return fruits_.size(); }
std::u16string GetItemAt(size_t index) const override {
return fruits_[index];
}
private:
std::vector<std::u16string> fruits_;
};
class DialogModelExampleDelegate : public ui::DialogModelDelegate {
public:
DialogModelExampleDelegate() = default;
DialogModelExampleDelegate(const DialogModelExampleDelegate&) = delete;
DialogModelExampleDelegate& operator=(const DialogModelExampleDelegate&) =
delete;
~DialogModelExampleDelegate() override = default;
void set_custom_checkbox(Checkbox* checkbox) { custom_checkbox_ = checkbox; }
void OnDialogAccepted() {
std::u16string output = base::StrCat(
{u"Hello ",
dialog_model()->GetTextfieldByUniqueId(kNameTextfield)->text(),
u", your password is ",
dialog_model()->GetPasswordFieldByUniqueId(kPasswordField)->text(),
dialog_model()
->GetCheckboxByUniqueId(kRememberMeCheckbox)
->is_checked()
? u". You want to be remembered."
: u".",
u"Your favorite fruit is ",
dialog_model()
->GetComboboxByUniqueId(kFruitCombobox)
->combobox_model()
->GetItemAt(dialog_model()
->GetComboboxByUniqueId(kFruitCombobox)
->selected_index()),
custom_checkbox_ && custom_checkbox_->GetChecked()
? u". Custom checkbox is checked!"
: u"."});
PrintStatus(base::UTF16ToUTF8(output));
}
void OnDialogCancelled() { PrintStatus("Dialog cancelled."); }
void OnExtraButtonPressed(const ui::Event& event) {
PrintStatus("Extra button pressed.");
}
private:
raw_ptr<Checkbox> custom_checkbox_ = nullptr;
};
}
DialogModelExample::DialogModelExample() : ExampleBase("Dialog Model") {}
DialogModelExample::~DialogModelExample() = default;
void DialogModelExample::CreateExampleView(View* container) {
container->SetUseDefaultFillLayout(true);
auto view = Builder<BoxLayoutView>()
.SetCrossAxisAlignment(BoxLayout::CrossAxisAlignment::kStart)
.AddChildren(Builder<MdTextButton>()
.CopyAddressTo(&show_dialog_button_)
.SetText(u"Show Dialog")
.SetCallback(base::BindRepeating(
&DialogModelExample::ShowDialog,
base::Unretained(this))))
.Build();
container->AddChildView(std::move(view));
}
void DialogModelExample::ShowDialog() {
auto model_delegate = std::make_unique<DialogModelExampleDelegate>();
auto* model_delegate_ptr = model_delegate.get();
auto custom_view_builder =
Builder<BoxLayoutView>()
.SetOrientation(BoxLayout::Orientation::kHorizontal)
.AddChildren(Builder<Label>().SetText(u"This is a custom field!"));
Checkbox* custom_checkbox = nullptr;
auto custom_view = std::move(custom_view_builder)
.AddChild(Builder<Checkbox>()
.SetText(u"Check me")
.CopyAddressTo(&custom_checkbox))
.Build();
model_delegate_ptr->set_custom_checkbox(custom_checkbox);
auto dialog_model =
ui::DialogModel::Builder(std::move(model_delegate))
.SetTitle(u"Hello, world!")
.AddParagraph(ui::DialogModelLabel(u"This is a paragraph."))
.AddTextfield(kNameTextfield, u"Name", u"")
.AddPasswordField(kPasswordField, u"Password", u"Password", u"")
.AddCheckbox(kRememberMeCheckbox,
ui::DialogModelLabel(u"Remember me"))
.AddSeparator()
.AddParagraph(ui::DialogModelLabel(u"This is another paragraph."))
.AddCombobox(kFruitCombobox, u"Favorite Fruit",
std::make_unique<FruitsComboboxModel>())
.AddCustomField(std::make_unique<BubbleDialogModelHost::CustomView>(
std::move(custom_view),
BubbleDialogModelHost::FieldType::kText),
kCustomField)
.AddOkButton(
base::BindOnce(&DialogModelExampleDelegate::OnDialogAccepted,
base::Unretained(model_delegate_ptr)))
.AddCancelButton(
base::BindOnce(&DialogModelExampleDelegate::OnDialogCancelled,
base::Unretained(model_delegate_ptr)))
.AddExtraButton(
base::BindRepeating(
&DialogModelExampleDelegate::OnExtraButtonPressed,
base::Unretained(model_delegate_ptr)),
ui::DialogModel::Button::Params().SetLabel(u"Extra Button"))
.SetFootnote(ui::DialogModelLabel(u"This is a footnote."))
.Build();
auto bubble = std::make_unique<BubbleDialogModelHost>(
std::move(dialog_model), show_dialog_button_, BubbleBorder::TOP_LEFT);
BubbleDialogDelegate::CreateBubble(std::move(bubble))->Show();
}
}