123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- // Copyright 2014 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 "remoting/host/chromeos/message_box.h"
- #include <utility>
- #include "ui/base/l10n/l10n_util.h"
- #include "ui/base/metadata/metadata_header_macros.h"
- #include "ui/base/metadata/metadata_impl_macros.h"
- #include "ui/views/controls/message_box_view.h"
- #include "ui/views/widget/widget.h"
- #include "ui/views/window/dialog_delegate.h"
- namespace remoting {
- // MessageBox::Core creates the dialog using the views::DialogWidget. The
- // DialogWidget is created by the caller but its lifetime is managed by the
- // NativeWidget. The DialogWidget communicates with the caller using the
- // DialogDelegateView interface, which must remain valid until DeleteDelegate()
- // is called, at which the DialogDelegateView deletes itself.
- //
- // The Core class is introduced to abstract this awkward ownership model. The
- // Core and the MessageBox hold a raw references to each other, which is
- // invalidated when either side are destroyed.
- class MessageBox::Core : public views::DialogDelegateView {
- public:
- METADATA_HEADER(Core);
- Core(const std::u16string& title_label,
- const std::u16string& message_label,
- const std::u16string& ok_label,
- const std::u16string& cancel_label,
- ResultCallback result_callback,
- MessageBox* message_box);
- Core(const Core&) = delete;
- Core& operator=(const Core&) = delete;
- // Mirrors the public MessageBox interface.
- void Show();
- void Hide();
- // views::DialogDelegateView:
- ui::ModalType GetModalType() const override;
- std::u16string GetWindowTitle() const override;
- views::View* GetContentsView() override;
- views::Widget* GetWidget() override;
- const views::Widget* GetWidget() const override;
- // Called by MessageBox::Core when it is destroyed.
- void OnMessageBoxDestroyed();
- private:
- const std::u16string title_label_;
- ResultCallback result_callback_;
- MessageBox* message_box_;
- // Owned by the native widget hierarchy.
- views::MessageBoxView* message_box_view_;
- };
- MessageBox::Core::Core(const std::u16string& title_label,
- const std::u16string& message_label,
- const std::u16string& ok_label,
- const std::u16string& cancel_label,
- ResultCallback result_callback,
- MessageBox* message_box)
- : title_label_(title_label),
- result_callback_(std::move(result_callback)),
- message_box_(message_box),
- message_box_view_(new views::MessageBoxView(message_label)) {
- DCHECK(message_box_);
- SetButtonLabel(ui::DIALOG_BUTTON_OK, ok_label);
- SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, cancel_label);
- auto run_callback = [](MessageBox::Core* core, Result result) {
- if (core->result_callback_)
- std::move(core->result_callback_).Run(result);
- };
- SetAcceptCallback(base::BindOnce(run_callback, base::Unretained(this), OK));
- SetCancelCallback(
- base::BindOnce(run_callback, base::Unretained(this), CANCEL));
- SetCloseCallback(
- base::BindOnce(run_callback, base::Unretained(this), CANCEL));
- RegisterDeleteDelegateCallback(base::BindOnce(
- [](Core* dialog) {
- if (dialog->message_box_)
- dialog->message_box_->core_ = nullptr;
- },
- this));
- }
- void MessageBox::Core::Show() {
- // The widget is owned by the NativeWidget. See comments in widget.h.
- views::Widget* widget =
- CreateDialogWidget(this, /* delegate */
- nullptr /* parent window*/, nullptr /* parent view */);
- if (widget) {
- widget->Show();
- }
- }
- void MessageBox::Core::Hide() {
- if (GetWidget()) {
- GetWidget()->Close();
- }
- }
- ui::ModalType MessageBox::Core::GetModalType() const {
- return ui::MODAL_TYPE_SYSTEM;
- }
- std::u16string MessageBox::Core::GetWindowTitle() const {
- return title_label_;
- }
- views::View* MessageBox::Core::GetContentsView() {
- return message_box_view_;
- }
- views::Widget* MessageBox::Core::GetWidget() {
- return message_box_view_->GetWidget();
- }
- const views::Widget* MessageBox::Core::GetWidget() const {
- return message_box_view_->GetWidget();
- }
- void MessageBox::Core::OnMessageBoxDestroyed() {
- DCHECK(message_box_);
- message_box_ = nullptr;
- // The callback should not be invoked after MessageBox is destroyed.
- result_callback_.Reset();
- }
- BEGIN_METADATA(MessageBox, Core, views::DialogDelegateView)
- END_METADATA
- MessageBox::MessageBox(const std::u16string& title_label,
- const std::u16string& message_label,
- const std::u16string& ok_label,
- const std::u16string& cancel_label,
- ResultCallback result_callback)
- : core_(new Core(title_label,
- message_label,
- ok_label,
- cancel_label,
- std::move(result_callback),
- this)) {}
- void MessageBox::Show() {
- core_->Show();
- }
- MessageBox::~MessageBox() {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (core_) {
- core_->OnMessageBoxDestroyed();
- core_->Hide();
- core_ = nullptr;
- }
- }
- } // namespace remoting
|