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. 4 5 #include "ui/views/window/dialog_delegate.h" 6 7 #include "base/logging.h" 8 #include "grit/ui_strings.h" 9 #include "ui/base/l10n/l10n_util.h" 10 #include "ui/views/bubble/bubble_border.h" 11 #include "ui/views/bubble/bubble_frame_view.h" 12 #include "ui/views/controls/button/label_button.h" 13 #include "ui/views/widget/widget.h" 14 #include "ui/views/widget/widget_observer.h" 15 #include "ui/views/window/dialog_client_view.h" 16 17 #if defined(OS_WIN) 18 #include "ui/base/win/shell.h" 19 #endif 20 21 namespace views { 22 23 //////////////////////////////////////////////////////////////////////////////// 24 // DialogDelegate: 25 26 DialogDelegate::DialogDelegate() : supports_new_style_(true) { 27 } 28 29 DialogDelegate::~DialogDelegate() { 30 } 31 32 // static 33 Widget* DialogDelegate::CreateDialogWidget(WidgetDelegate* delegate, 34 gfx::NativeView context, 35 gfx::NativeView parent) { 36 views::Widget* widget = new views::Widget; 37 views::Widget::InitParams params; 38 params.delegate = delegate; 39 DialogDelegate* dialog = delegate->AsDialogDelegate(); 40 41 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 42 // The new style doesn't support unparented dialogs on Linux desktop. 43 if (dialog) 44 dialog->supports_new_style_ &= parent != NULL; 45 #elif defined(OS_WIN) 46 // The new style doesn't support unparented dialogs on Windows Classic themes. 47 if (dialog && !ui::win::IsAeroGlassEnabled()) 48 dialog->supports_new_style_ &= parent != NULL; 49 #endif 50 51 if (!dialog || dialog->UseNewStyleForThisDialog()) { 52 params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW; 53 params.remove_standard_frame = true; 54 // The bubble frame includes its own shadow; remove any native shadowing. 55 params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; 56 } 57 params.context = context; 58 params.parent = parent; 59 // Web-modal (ui::MODAL_TYPE_CHILD) dialogs with parents are marked as child 60 // widgets to prevent top-level window behavior (independent movement, etc). 61 params.child = parent && (delegate->GetModalType() == ui::MODAL_TYPE_CHILD); 62 widget->Init(params); 63 return widget; 64 } 65 66 View* DialogDelegate::CreateExtraView() { 67 return NULL; 68 } 69 70 View* DialogDelegate::CreateTitlebarExtraView() { 71 return NULL; 72 } 73 74 View* DialogDelegate::CreateFootnoteView() { 75 return NULL; 76 } 77 78 bool DialogDelegate::Cancel() { 79 return true; 80 } 81 82 bool DialogDelegate::Accept(bool window_closing) { 83 return Accept(); 84 } 85 86 bool DialogDelegate::Accept() { 87 return true; 88 } 89 90 bool DialogDelegate::Close() { 91 int buttons = GetDialogButtons(); 92 if ((buttons & ui::DIALOG_BUTTON_CANCEL) || 93 (buttons == ui::DIALOG_BUTTON_NONE)) { 94 return Cancel(); 95 } 96 return Accept(true); 97 } 98 99 base::string16 DialogDelegate::GetDialogLabel() const { 100 return base::string16(); 101 } 102 103 base::string16 DialogDelegate::GetDialogTitle() const { 104 return GetWindowTitle(); 105 } 106 107 int DialogDelegate::GetDialogButtons() const { 108 return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL; 109 } 110 111 int DialogDelegate::GetDefaultDialogButton() const { 112 if (GetDialogButtons() & ui::DIALOG_BUTTON_OK) 113 return ui::DIALOG_BUTTON_OK; 114 if (GetDialogButtons() & ui::DIALOG_BUTTON_CANCEL) 115 return ui::DIALOG_BUTTON_CANCEL; 116 return ui::DIALOG_BUTTON_NONE; 117 } 118 119 bool DialogDelegate::ShouldDefaultButtonBeBlue() const { 120 return false; 121 } 122 123 base::string16 DialogDelegate::GetDialogButtonLabel( 124 ui::DialogButton button) const { 125 if (button == ui::DIALOG_BUTTON_OK) 126 return l10n_util::GetStringUTF16(IDS_APP_OK); 127 if (button == ui::DIALOG_BUTTON_CANCEL) { 128 if (GetDialogButtons() & ui::DIALOG_BUTTON_OK) 129 return l10n_util::GetStringUTF16(IDS_APP_CANCEL); 130 return l10n_util::GetStringUTF16(IDS_APP_CLOSE); 131 } 132 NOTREACHED(); 133 return base::string16(); 134 } 135 136 bool DialogDelegate::IsDialogButtonEnabled(ui::DialogButton button) const { 137 return true; 138 } 139 140 View* DialogDelegate::GetInitiallyFocusedView() { 141 // Focus the default button if any. 142 const DialogClientView* dcv = GetDialogClientView(); 143 int default_button = GetDefaultDialogButton(); 144 if (default_button == ui::DIALOG_BUTTON_NONE) 145 return NULL; 146 147 if ((default_button & GetDialogButtons()) == 0) { 148 // The default button is a button we don't have. 149 NOTREACHED(); 150 return NULL; 151 } 152 153 if (default_button & ui::DIALOG_BUTTON_OK) 154 return dcv->ok_button(); 155 if (default_button & ui::DIALOG_BUTTON_CANCEL) 156 return dcv->cancel_button(); 157 return NULL; 158 } 159 160 DialogDelegate* DialogDelegate::AsDialogDelegate() { 161 return this; 162 } 163 164 ClientView* DialogDelegate::CreateClientView(Widget* widget) { 165 return new DialogClientView(widget, GetContentsView()); 166 } 167 168 NonClientFrameView* DialogDelegate::CreateNonClientFrameView(Widget* widget) { 169 if (UseNewStyleForThisDialog()) 170 return CreateDialogFrameView(widget); 171 return WidgetDelegate::CreateNonClientFrameView(widget); 172 } 173 174 // static 175 NonClientFrameView* DialogDelegate::CreateDialogFrameView(Widget* widget) { 176 BubbleFrameView* frame = new BubbleFrameView(gfx::Insets()); 177 scoped_ptr<BubbleBorder> border(new BubbleBorder( 178 BubbleBorder::FLOAT, BubbleBorder::SMALL_SHADOW, SK_ColorRED)); 179 border->set_use_theme_background_color(true); 180 frame->SetBubbleBorder(border.Pass()); 181 DialogDelegate* delegate = widget->widget_delegate()->AsDialogDelegate(); 182 if (delegate) { 183 View* titlebar_view = delegate->CreateTitlebarExtraView(); 184 if (titlebar_view) 185 frame->SetTitlebarExtraView(titlebar_view); 186 } 187 return frame; 188 } 189 190 bool DialogDelegate::UseNewStyleForThisDialog() const { 191 return supports_new_style_; 192 } 193 194 const DialogClientView* DialogDelegate::GetDialogClientView() const { 195 return GetWidget()->client_view()->AsDialogClientView(); 196 } 197 198 DialogClientView* DialogDelegate::GetDialogClientView() { 199 return GetWidget()->client_view()->AsDialogClientView(); 200 } 201 202 ui::AXRole DialogDelegate::GetAccessibleWindowRole() const { 203 return ui::AX_ROLE_DIALOG; 204 } 205 206 //////////////////////////////////////////////////////////////////////////////// 207 // DialogDelegateView: 208 209 DialogDelegateView::DialogDelegateView() { 210 // A WidgetDelegate should be deleted on DeleteDelegate. 211 set_owned_by_client(); 212 } 213 214 DialogDelegateView::~DialogDelegateView() {} 215 216 void DialogDelegateView::DeleteDelegate() { 217 delete this; 218 } 219 220 Widget* DialogDelegateView::GetWidget() { 221 return View::GetWidget(); 222 } 223 224 const Widget* DialogDelegateView::GetWidget() const { 225 return View::GetWidget(); 226 } 227 228 View* DialogDelegateView::GetContentsView() { 229 return this; 230 } 231 232 } // namespace views 233