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"
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
{
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.
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();
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
),
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
))) {
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 */);
93 void MessageBox::Core::Hide() {
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 {
121 base::string16
MessageBox::Core::GetDialogButtonLabel(
122 ui::DialogButton button
) const {
124 case ui::DIALOG_BUTTON_OK
:
126 case ui::DIALOG_BUTTON_CANCEL
:
127 return cancel_label_
;
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() {
148 message_box_
->core_
= nullptr;
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
,
171 thread_checker_
.DetachFromThread();
174 MessageBox::~MessageBox() {
176 core_
->OnMessageBoxDestroyed();
182 void MessageBox::Show() {
183 DCHECK(thread_checker_
.CalledOnValidThread());
187 void MessageBox::Hide() {
188 DCHECK(thread_checker_
.CalledOnValidThread());
194 } // namespace remoting