| 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 |