1 // Copyright (c) 2012 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 "ui/views/window/dialog_delegate.h"
7 #include "base/logging.h"
8 #include "ui/accessibility/ax_view_state.h"
9 #include "ui/base/l10n/l10n_util.h"
10 #include "ui/strings/grit/ui_strings.h"
11 #include "ui/views/bubble/bubble_border.h"
12 #include "ui/views/bubble/bubble_frame_view.h"
13 #include "ui/views/controls/button/label_button.h"
14 #include "ui/views/widget/widget.h"
15 #include "ui/views/widget/widget_observer.h"
16 #include "ui/views/window/dialog_client_view.h"
19 #include "ui/base/win/shell.h"
24 ////////////////////////////////////////////////////////////////////////////////
27 DialogDelegate::DialogDelegate() : supports_new_style_(true) {
30 DialogDelegate::~DialogDelegate() {
34 Widget
* DialogDelegate::CreateDialogWidget(WidgetDelegate
* delegate
,
35 gfx::NativeWindow context
,
36 gfx::NativeView parent
) {
37 return CreateDialogWidgetWithBounds(delegate
, context
, parent
, gfx::Rect());
41 Widget
* DialogDelegate::CreateDialogWidgetWithBounds(WidgetDelegate
* delegate
,
42 gfx::NativeWindow context
,
43 gfx::NativeView parent
,
44 const gfx::Rect
& bounds
) {
45 views::Widget
* widget
= new views::Widget
;
46 views::Widget::InitParams params
;
47 params
.delegate
= delegate
;
48 params
.bounds
= bounds
;
49 DialogDelegate
* dialog
= delegate
->AsDialogDelegate();
51 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
52 // The new style doesn't support unparented dialogs on Linux desktop.
54 dialog
->supports_new_style_
&= parent
!= NULL
;
56 // The new style doesn't support unparented dialogs on Windows Classic themes.
57 if (dialog
&& !ui::win::IsAeroGlassEnabled())
58 dialog
->supports_new_style_
&= parent
!= NULL
;
61 if (!dialog
|| dialog
->UseNewStyleForThisDialog()) {
62 params
.opacity
= Widget::InitParams::TRANSLUCENT_WINDOW
;
63 params
.remove_standard_frame
= true;
64 // The bubble frame includes its own shadow; remove any native shadowing.
65 params
.shadow_type
= views::Widget::InitParams::SHADOW_TYPE_NONE
;
67 params
.context
= context
;
68 params
.parent
= parent
;
69 // Web-modal (ui::MODAL_TYPE_CHILD) dialogs with parents are marked as child
70 // widgets to prevent top-level window behavior (independent movement, etc).
71 params
.child
= parent
&& (delegate
->GetModalType() == ui::MODAL_TYPE_CHILD
);
76 View
* DialogDelegate::CreateExtraView() {
80 View
* DialogDelegate::CreateTitlebarExtraView() {
84 View
* DialogDelegate::CreateFootnoteView() {
88 bool DialogDelegate::Cancel() {
92 bool DialogDelegate::Accept(bool window_closing
) {
96 bool DialogDelegate::Accept() {
100 bool DialogDelegate::Close() {
101 int buttons
= GetDialogButtons();
102 if ((buttons
& ui::DIALOG_BUTTON_CANCEL
) ||
103 (buttons
== ui::DIALOG_BUTTON_NONE
)) {
109 base::string16
DialogDelegate::GetDialogTitle() const {
110 return GetWindowTitle();
113 int DialogDelegate::GetDialogButtons() const {
114 return ui::DIALOG_BUTTON_OK
| ui::DIALOG_BUTTON_CANCEL
;
117 int DialogDelegate::GetDefaultDialogButton() const {
118 if (GetDialogButtons() & ui::DIALOG_BUTTON_OK
)
119 return ui::DIALOG_BUTTON_OK
;
120 if (GetDialogButtons() & ui::DIALOG_BUTTON_CANCEL
)
121 return ui::DIALOG_BUTTON_CANCEL
;
122 return ui::DIALOG_BUTTON_NONE
;
125 bool DialogDelegate::ShouldDefaultButtonBeBlue() const {
129 base::string16
DialogDelegate::GetDialogButtonLabel(
130 ui::DialogButton button
) const {
131 if (button
== ui::DIALOG_BUTTON_OK
)
132 return l10n_util::GetStringUTF16(IDS_APP_OK
);
133 if (button
== ui::DIALOG_BUTTON_CANCEL
) {
134 if (GetDialogButtons() & ui::DIALOG_BUTTON_OK
)
135 return l10n_util::GetStringUTF16(IDS_APP_CANCEL
);
136 return l10n_util::GetStringUTF16(IDS_APP_CLOSE
);
139 return base::string16();
142 bool DialogDelegate::IsDialogButtonEnabled(ui::DialogButton button
) const {
146 View
* DialogDelegate::GetInitiallyFocusedView() {
147 // Focus the default button if any.
148 const DialogClientView
* dcv
= GetDialogClientView();
149 int default_button
= GetDefaultDialogButton();
150 if (default_button
== ui::DIALOG_BUTTON_NONE
)
153 if ((default_button
& GetDialogButtons()) == 0) {
154 // The default button is a button we don't have.
159 if (default_button
& ui::DIALOG_BUTTON_OK
)
160 return dcv
->ok_button();
161 if (default_button
& ui::DIALOG_BUTTON_CANCEL
)
162 return dcv
->cancel_button();
166 DialogDelegate
* DialogDelegate::AsDialogDelegate() {
170 ClientView
* DialogDelegate::CreateClientView(Widget
* widget
) {
171 return new DialogClientView(widget
, GetContentsView());
174 NonClientFrameView
* DialogDelegate::CreateNonClientFrameView(Widget
* widget
) {
175 if (UseNewStyleForThisDialog())
176 return CreateDialogFrameView(widget
);
177 return WidgetDelegate::CreateNonClientFrameView(widget
);
181 NonClientFrameView
* DialogDelegate::CreateDialogFrameView(Widget
* widget
) {
182 BubbleFrameView
* frame
= new BubbleFrameView(gfx::Insets());
183 scoped_ptr
<BubbleBorder
> border(new BubbleBorder(
184 BubbleBorder::FLOAT
, BubbleBorder::SMALL_SHADOW
, SK_ColorRED
));
185 border
->set_use_theme_background_color(true);
186 frame
->SetBubbleBorder(border
.Pass());
187 DialogDelegate
* delegate
= widget
->widget_delegate()->AsDialogDelegate();
189 View
* titlebar_view
= delegate
->CreateTitlebarExtraView();
191 frame
->SetTitlebarExtraView(titlebar_view
);
196 bool DialogDelegate::UseNewStyleForThisDialog() const {
197 return supports_new_style_
;
200 const DialogClientView
* DialogDelegate::GetDialogClientView() const {
201 return GetWidget()->client_view()->AsDialogClientView();
204 DialogClientView
* DialogDelegate::GetDialogClientView() {
205 return GetWidget()->client_view()->AsDialogClientView();
208 ui::AXRole
DialogDelegate::GetAccessibleWindowRole() const {
209 return ui::AX_ROLE_DIALOG
;
212 ////////////////////////////////////////////////////////////////////////////////
213 // DialogDelegateView:
215 DialogDelegateView::DialogDelegateView() {
216 // A WidgetDelegate should be deleted on DeleteDelegate.
217 set_owned_by_client();
220 DialogDelegateView::~DialogDelegateView() {}
222 void DialogDelegateView::DeleteDelegate() {
226 Widget
* DialogDelegateView::GetWidget() {
227 return View::GetWidget();
230 const Widget
* DialogDelegateView::GetWidget() const {
231 return View::GetWidget();
234 View
* DialogDelegateView::GetContentsView() {
238 void DialogDelegateView::GetAccessibleState(ui::AXViewState
* state
) {
239 state
->name
= GetDialogTitle();
240 state
->role
= ui::AX_ROLE_DIALOG
;
243 void DialogDelegateView::ViewHierarchyChanged(
244 const ViewHierarchyChangedDetails
& details
) {
245 if (details
.is_add
&& details
.child
== this && GetWidget())
246 NotifyAccessibilityEvent(ui::AX_EVENT_ALERT
, true);