| Index: remoting/host/chromeos/message_box.cc
|
| diff --git a/remoting/host/chromeos/message_box.cc b/remoting/host/chromeos/message_box.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e4f8da5274420c6eb2721b7712ab52bc1081b85f
|
| --- /dev/null
|
| +++ b/remoting/host/chromeos/message_box.cc
|
| @@ -0,0 +1,194 @@
|
| +// 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 "ui/base/l10n/l10n_util.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:
|
| + Core(const base::string16& title_label,
|
| + const base::string16& message_label,
|
| + const base::string16& ok_label,
|
| + const base::string16& cancel_label,
|
| + ResultCallback result_callback,
|
| + MessageBox* message_box);
|
| +
|
| + // Mirrors the public MessageBox interface.
|
| + void Show();
|
| + void Hide();
|
| +
|
| + // views::DialogDelegateView interface.
|
| + bool Accept() override;
|
| + bool Cancel() override;
|
| + ui::ModalType GetModalType() const override;
|
| + base::string16 GetWindowTitle() const override;
|
| + base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
|
| +
|
| + // views::WidgetDelegate interface.
|
| + views::View* GetContentsView() override;
|
| + views::Widget* GetWidget() override;
|
| + const views::Widget* GetWidget() const override;
|
| + void DeleteDelegate() override;
|
| +
|
| + // Called by MessageBox::Core when it is destroyed.
|
| + void OnMessageBoxDestroyed();
|
| +
|
| + private:
|
| + const base::string16 title_label_;
|
| + const base::string16 ok_label_;
|
| + const base::string16 cancel_label_;
|
| + ResultCallback result_callback_;
|
| + MessageBox* message_box_;
|
| +
|
| + // Owned by the native widget hierarchy.
|
| + views::MessageBoxView* message_box_view_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Core);
|
| +};
|
| +
|
| +MessageBox::Core::Core(const base::string16& title_label,
|
| + const base::string16& message_label,
|
| + const base::string16& ok_label,
|
| + const base::string16& cancel_label,
|
| + ResultCallback result_callback,
|
| + MessageBox* message_box)
|
| + : title_label_(title_label),
|
| + ok_label_(ok_label),
|
| + cancel_label_(cancel_label),
|
| + result_callback_(result_callback),
|
| + message_box_(message_box),
|
| + message_box_view_(new views::MessageBoxView(
|
| + views::MessageBoxView::InitParams(message_label))) {
|
| + DCHECK(message_box_);
|
| +}
|
| +
|
| +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();
|
| + }
|
| +}
|
| +
|
| +bool MessageBox::Core::Accept() {
|
| + if (!result_callback_.is_null()) {
|
| + base::ResetAndReturn(&result_callback_).Run(OK);
|
| + }
|
| + return true /* close the window*/;
|
| +}
|
| +
|
| +bool MessageBox::Core::Cancel() {
|
| + if (!result_callback_.is_null()) {
|
| + base::ResetAndReturn(&result_callback_).Run(CANCEL);
|
| + }
|
| + return true /* close the window*/;
|
| +}
|
| +
|
| +ui::ModalType MessageBox::Core::GetModalType() const {
|
| + return ui::MODAL_TYPE_SYSTEM;
|
| +}
|
| +
|
| +base::string16 MessageBox::Core::GetWindowTitle() const {
|
| + return title_label_;
|
| +}
|
| +
|
| +base::string16 MessageBox::Core::GetDialogButtonLabel(
|
| + ui::DialogButton button) const {
|
| + switch (button) {
|
| + case ui::DIALOG_BUTTON_OK:
|
| + return ok_label_;
|
| + case ui::DIALOG_BUTTON_CANCEL:
|
| + return cancel_label_;
|
| + default:
|
| + NOTREACHED();
|
| + return base::string16();
|
| + }
|
| +}
|
| +
|
| +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::DeleteDelegate() {
|
| + if (message_box_) {
|
| + message_box_->core_ = nullptr;
|
| + }
|
| + delete this;
|
| +}
|
| +
|
| +void MessageBox::Core::OnMessageBoxDestroyed() {
|
| + DCHECK(message_box_);
|
| + message_box_ = nullptr;
|
| + // The callback should not be invoked after MessageBox is destroyed.
|
| + result_callback_.Reset();
|
| +}
|
| +
|
| +MessageBox::MessageBox(const base::string16& title_label,
|
| + const base::string16& message_label,
|
| + const base::string16& ok_label,
|
| + const base::string16& cancel_label,
|
| + ResultCallback result_callback)
|
| + : core_(new Core(title_label,
|
| + message_label,
|
| + ok_label,
|
| + cancel_label,
|
| + result_callback,
|
| + this)) {
|
| + thread_checker_.DetachFromThread();
|
| +}
|
| +
|
| +MessageBox::~MessageBox() {
|
| + if (core_) {
|
| + core_->OnMessageBoxDestroyed();
|
| + core_->Hide();
|
| + core_ = nullptr;
|
| + }
|
| +}
|
| +
|
| +void MessageBox::Show() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + core_->Show();
|
| +}
|
| +
|
| +void MessageBox::Hide() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + if (core_) {
|
| + core_->Hide();
|
| + }
|
| +}
|
| +
|
| +} // namespace remoting
|
|
|