OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "remoting/host/chromeos/message_box.h" |
| 6 |
| 7 #include "ui/base/l10n/l10n_util.h" |
| 8 #include "ui/views/controls/message_box_view.h" |
| 9 #include "ui/views/widget/widget.h" |
| 10 #include "ui/views/window/dialog_delegate.h" |
| 11 |
| 12 namespace remoting { |
| 13 |
| 14 // MessageBox::Core creates the dialog using the views::DialogWidget. The |
| 15 // DialogWidget is created by the caller but its lifetime is managed by the |
| 16 // NativeWidget. The DialogWidget communicates with the caller using the |
| 17 //.DialogDelegateView interface, which must remain valid until DeleteDelegate() |
| 18 // is called, at which the DialogDelegateView deletes itself. |
| 19 // |
| 20 // The Core class is introduced to abstract this awkward ownership model. The |
| 21 // Core and the MessageBox hold a raw references to each other, which is |
| 22 // invalidated when either side are destroyed. |
| 23 class MessageBox::Core : public views::DialogDelegateView { |
| 24 public: |
| 25 Core(const base::string16& title_label, |
| 26 const base::string16& message_label, |
| 27 const base::string16& ok_label, |
| 28 const base::string16& cancel_label, |
| 29 ResultCallback result_callback, |
| 30 MessageBox* message_box); |
| 31 |
| 32 // Mirrors the public MessageBox interface. |
| 33 void Show(); |
| 34 void Hide(); |
| 35 |
| 36 // views::DialogDelegateView interface. |
| 37 bool Accept() override; |
| 38 bool Cancel() override; |
| 39 ui::ModalType GetModalType() const override; |
| 40 base::string16 GetWindowTitle() const override; |
| 41 base::string16 GetDialogButtonLabel(ui::DialogButton button) const override; |
| 42 |
| 43 // views::WidgetDelegate interface. |
| 44 views::View* GetContentsView() override; |
| 45 views::Widget* GetWidget() override; |
| 46 const views::Widget* GetWidget() const override; |
| 47 void DeleteDelegate() override; |
| 48 |
| 49 // Called by MessageBox::Core when it is destroyed. |
| 50 void OnMessageBoxDestroyed(); |
| 51 |
| 52 private: |
| 53 const base::string16 title_label_; |
| 54 const base::string16 ok_label_; |
| 55 const base::string16 cancel_label_; |
| 56 ResultCallback result_callback_; |
| 57 MessageBox* message_box_; |
| 58 |
| 59 // Owned by the native widget hierarchy. |
| 60 views::MessageBoxView* message_box_view_; |
| 61 |
| 62 DISALLOW_COPY_AND_ASSIGN(Core); |
| 63 }; |
| 64 |
| 65 MessageBox::Core::Core(const base::string16& title_label, |
| 66 const base::string16& message_label, |
| 67 const base::string16& ok_label, |
| 68 const base::string16& cancel_label, |
| 69 ResultCallback result_callback, |
| 70 MessageBox* message_box) |
| 71 : title_label_(title_label), |
| 72 ok_label_(ok_label), |
| 73 cancel_label_(cancel_label), |
| 74 result_callback_(result_callback), |
| 75 message_box_(message_box), |
| 76 message_box_view_(new views::MessageBoxView( |
| 77 views::MessageBoxView::InitParams(message_label))) { |
| 78 DCHECK(message_box_); |
| 79 } |
| 80 |
| 81 void MessageBox::Core::Show() { |
| 82 // The widget is owned by the NativeWidget. See comments in widget.h. |
| 83 views::Widget* widget = |
| 84 CreateDialogWidget(this, /* delegate */ |
| 85 nullptr /* parent window*/, |
| 86 nullptr /* parent view */); |
| 87 |
| 88 if (widget) { |
| 89 widget->Show(); |
| 90 } |
| 91 } |
| 92 |
| 93 void MessageBox::Core::Hide() { |
| 94 if (GetWidget()) { |
| 95 GetWidget()->Close(); |
| 96 } |
| 97 } |
| 98 |
| 99 bool MessageBox::Core::Accept() { |
| 100 if (!result_callback_.is_null()) { |
| 101 base::ResetAndReturn(&result_callback_).Run(OK); |
| 102 } |
| 103 return true /* close the window*/; |
| 104 } |
| 105 |
| 106 bool MessageBox::Core::Cancel() { |
| 107 if (!result_callback_.is_null()) { |
| 108 base::ResetAndReturn(&result_callback_).Run(CANCEL); |
| 109 } |
| 110 return true /* close the window*/; |
| 111 } |
| 112 |
| 113 ui::ModalType MessageBox::Core::GetModalType() const { |
| 114 return ui::MODAL_TYPE_SYSTEM; |
| 115 } |
| 116 |
| 117 base::string16 MessageBox::Core::GetWindowTitle() const { |
| 118 return title_label_; |
| 119 } |
| 120 |
| 121 base::string16 MessageBox::Core::GetDialogButtonLabel( |
| 122 ui::DialogButton button) const { |
| 123 switch (button) { |
| 124 case ui::DIALOG_BUTTON_OK: |
| 125 return ok_label_; |
| 126 case ui::DIALOG_BUTTON_CANCEL: |
| 127 return cancel_label_; |
| 128 default: |
| 129 NOTREACHED(); |
| 130 return base::string16(); |
| 131 } |
| 132 } |
| 133 |
| 134 views::View* MessageBox::Core::GetContentsView() { |
| 135 return message_box_view_; |
| 136 } |
| 137 |
| 138 views::Widget* MessageBox::Core::GetWidget() { |
| 139 return message_box_view_->GetWidget(); |
| 140 } |
| 141 |
| 142 const views::Widget* MessageBox::Core::GetWidget() const { |
| 143 return message_box_view_->GetWidget(); |
| 144 } |
| 145 |
| 146 void MessageBox::Core::DeleteDelegate() { |
| 147 if (message_box_) { |
| 148 message_box_->core_ = nullptr; |
| 149 } |
| 150 delete this; |
| 151 } |
| 152 |
| 153 void MessageBox::Core::OnMessageBoxDestroyed() { |
| 154 DCHECK(message_box_); |
| 155 message_box_ = nullptr; |
| 156 // The callback should not be invoked after MessageBox is destroyed. |
| 157 result_callback_.Reset(); |
| 158 } |
| 159 |
| 160 MessageBox::MessageBox(const base::string16& title_label, |
| 161 const base::string16& message_label, |
| 162 const base::string16& ok_label, |
| 163 const base::string16& cancel_label, |
| 164 ResultCallback result_callback) |
| 165 : core_(new Core(title_label, |
| 166 message_label, |
| 167 ok_label, |
| 168 cancel_label, |
| 169 result_callback, |
| 170 this)) { |
| 171 thread_checker_.DetachFromThread(); |
| 172 } |
| 173 |
| 174 MessageBox::~MessageBox() { |
| 175 if (core_) { |
| 176 core_->OnMessageBoxDestroyed(); |
| 177 core_->Hide(); |
| 178 core_ = nullptr; |
| 179 } |
| 180 } |
| 181 |
| 182 void MessageBox::Show() { |
| 183 DCHECK(thread_checker_.CalledOnValidThread()); |
| 184 core_->Show(); |
| 185 } |
| 186 |
| 187 void MessageBox::Hide() { |
| 188 DCHECK(thread_checker_.CalledOnValidThread()); |
| 189 if (core_) { |
| 190 core_->Hide(); |
| 191 } |
| 192 } |
| 193 |
| 194 } // namespace remoting |
OLD | NEW |