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..724cf48de52d652b8c486d9dcf89d2ee75adb391 |
--- /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 |
Wez
2014/11/04 19:10:20
nit: s/is/are
kelvinp
2014/11/04 19:28:27
Done.
|
+// invalidated when either side is 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 MessageBox::Core interface |
Wez
2014/11/04 19:10:20
You mean mirrors the public MessageBox interface?
kelvinp
2014/11/04 19:28:27
Done.
|
+ 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 |