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