// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/views/examples/dialog_example.h" #include #include #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" #include "ui/views/controls/button/checkbox.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/button/md_text_button.h" #include "ui/views/controls/combobox/combobox.h" #include "ui/views/controls/label.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/examples/examples_window.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/grid_layout.h" #include "ui/views/layout/layout_provider.h" #include "ui/views/widget/widget.h" #include "ui/views/window/dialog_delegate.h" using base::ASCIIToUTF16; namespace views { namespace examples { namespace { constexpr int kFieldsColumnId = 0; constexpr int kButtonsColumnId = 1; constexpr int kFakeModeless = ui::MODAL_TYPE_SYSTEM + 1; } // namespace template class DialogExample::Delegate : public virtual DialogType { public: explicit Delegate(DialogExample* parent) : parent_(parent) { DialogDelegate::SetButtons(parent_->GetDialogButtons()); DialogDelegate::SetButtonLabel(ui::DIALOG_BUTTON_OK, parent_->ok_button_label_->GetText()); DialogDelegate::SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, parent_->cancel_button_label_->GetText()); } void InitDelegate() { this->SetLayoutManager(std::make_unique()); Label* body = new Label(parent_->body_->GetText()); body->SetMultiLine(true); body->SetHorizontalAlignment(gfx::ALIGN_LEFT); this->AddChildView(body); if (parent_->has_extra_button_->GetChecked()) { DialogDelegate::SetExtraView(MdTextButton::CreateSecondaryUiButton( nullptr, parent_->extra_button_label_->GetText())); } // Give the example code a way to change the body text. parent_->last_body_label_ = body; } protected: // WidgetDelegate: ui::ModalType GetModalType() const override { return parent_->GetModalType(); } base::string16 GetWindowTitle() const override { return parent_->title_->GetText(); } bool Cancel() override { return parent_->AllowDialogClose(false); } bool Accept() override { return parent_->AllowDialogClose(true); } private: DialogExample* parent_; DISALLOW_COPY_AND_ASSIGN(Delegate); }; class DialogExample::Bubble : public Delegate { public: Bubble(DialogExample* parent, View* anchor) : BubbleDialogDelegateView(anchor, BubbleBorder::TOP_LEFT), Delegate(parent) { set_close_on_deactivate(!parent->persistent_bubble_->GetChecked()); } // BubbleDialogDelegateView: void Init() override { InitDelegate(); } private: DISALLOW_COPY_AND_ASSIGN(Bubble); }; class DialogExample::Dialog : public Delegate { public: explicit Dialog(DialogExample* parent) : Delegate(parent) {} // WidgetDelegate: bool CanResize() const override { // Mac supports resizing of modal dialogs (parent or window-modal). On other // platforms this will be weird unless the modal type is "none", but helps // test layout. return true; } private: DISALLOW_COPY_AND_ASSIGN(Dialog); }; DialogExample::DialogExample() : ExampleBase("Dialog"), mode_model_({ base::ASCIIToUTF16("Modeless"), base::ASCIIToUTF16("Window Modal"), base::ASCIIToUTF16("Child Modal"), base::ASCIIToUTF16("System Modal"), base::ASCIIToUTF16("Fake Modeless (non-bubbles)"), }) {} DialogExample::~DialogExample() = default; void DialogExample::CreateExampleView(View* container) { // GridLayout |resize_percent| constants. const float kFixed = 0.f; const float kStretchy = 1.f; views::LayoutProvider* provider = views::LayoutProvider::Get(); const int horizontal_spacing = provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL); GridLayout* layout = container->SetLayoutManager(std::make_unique()); ColumnSet* column_set = layout->AddColumnSet(kFieldsColumnId); column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, kFixed, GridLayout::USE_PREF, 0, 0); column_set->AddPaddingColumn(kFixed, horizontal_spacing); column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, kStretchy, GridLayout::USE_PREF, 0, 0); column_set->AddPaddingColumn(kFixed, horizontal_spacing); column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, kFixed, GridLayout::USE_PREF, 0, 0); StartTextfieldRow(layout, &title_, "Dialog Title", "Title"); StartTextfieldRow(layout, &body_, "Dialog Body Text", "Body Text"); StartTextfieldRow(layout, &ok_button_label_, "OK Button Label", "Done"); AddCheckbox(layout, &has_ok_button_); StartTextfieldRow(layout, &cancel_button_label_, "Cancel Button Label", "Cancel"); AddCheckbox(layout, &has_cancel_button_); StartTextfieldRow(layout, &extra_button_label_, "Extra Button Label", "Edit"); AddCheckbox(layout, &has_extra_button_); StartRowWithLabel(layout, "Modal Type"); mode_ = layout->AddView(std::make_unique(&mode_model_)); mode_->set_listener(this); mode_->SetSelectedIndex(ui::MODAL_TYPE_CHILD); StartRowWithLabel(layout, "Bubble"); AddCheckbox(layout, &bubble_); AddCheckbox(layout, &persistent_bubble_); persistent_bubble_->SetText(base::ASCIIToUTF16("Persistent")); column_set = layout->AddColumnSet(kButtonsColumnId); column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, kStretchy, GridLayout::USE_PREF, 0, 0); layout->StartRowWithPadding( kFixed, kButtonsColumnId, kFixed, provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL)); show_ = layout->AddView( MdTextButton::CreateSecondaryUiButton(this, base::ASCIIToUTF16("Show"))); } void DialogExample::StartRowWithLabel(GridLayout* layout, const char* label) { const float kFixedVerticalResize = 0.f; layout->StartRowWithPadding(kFixedVerticalResize, kFieldsColumnId, kFixedVerticalResize, views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL)); layout->AddView(std::make_unique