Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / remoting / host / chromeos / message_box.cc
blobe4f8da5274420c6eb2721b7712ab52bc1081b85f
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.
5 #include "remoting/host/chromeos/message_box.h"
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"
12 namespace remoting {
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.
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);
32 // Mirrors the public MessageBox interface.
33 void Show();
34 void Hide();
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;
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;
49 // Called by MessageBox::Core when it is destroyed.
50 void OnMessageBoxDestroyed();
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_;
59 // Owned by the native widget hierarchy.
60 views::MessageBoxView* message_box_view_;
62 DISALLOW_COPY_AND_ASSIGN(Core);
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_);
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 */);
88 if (widget) {
89 widget->Show();
93 void MessageBox::Core::Hide() {
94 if (GetWidget()) {
95 GetWidget()->Close();
99 bool MessageBox::Core::Accept() {
100 if (!result_callback_.is_null()) {
101 base::ResetAndReturn(&result_callback_).Run(OK);
103 return true /* close the window*/;
106 bool MessageBox::Core::Cancel() {
107 if (!result_callback_.is_null()) {
108 base::ResetAndReturn(&result_callback_).Run(CANCEL);
110 return true /* close the window*/;
113 ui::ModalType MessageBox::Core::GetModalType() const {
114 return ui::MODAL_TYPE_SYSTEM;
117 base::string16 MessageBox::Core::GetWindowTitle() const {
118 return title_label_;
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();
134 views::View* MessageBox::Core::GetContentsView() {
135 return message_box_view_;
138 views::Widget* MessageBox::Core::GetWidget() {
139 return message_box_view_->GetWidget();
142 const views::Widget* MessageBox::Core::GetWidget() const {
143 return message_box_view_->GetWidget();
146 void MessageBox::Core::DeleteDelegate() {
147 if (message_box_) {
148 message_box_->core_ = nullptr;
150 delete this;
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();
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();
174 MessageBox::~MessageBox() {
175 if (core_) {
176 core_->OnMessageBoxDestroyed();
177 core_->Hide();
178 core_ = nullptr;
182 void MessageBox::Show() {
183 DCHECK(thread_checker_.CalledOnValidThread());
184 core_->Show();
187 void MessageBox::Hide() {
188 DCHECK(thread_checker_.CalledOnValidThread());
189 if (core_) {
190 core_->Hide();
194 } // namespace remoting