| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/views/window/dialog_client_view.h" | 5 #include "ui/views/window/dialog_client_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ui/base/keycodes/keyboard_codes.h" | 9 #include "ui/base/keycodes/keyboard_codes.h" |
| 10 #include "ui/views/controls/button/label_button.h" | 10 #include "ui/views/controls/button/label_button.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 | 36 |
| 37 } // namespace | 37 } // namespace |
| 38 | 38 |
| 39 /////////////////////////////////////////////////////////////////////////////// | 39 /////////////////////////////////////////////////////////////////////////////// |
| 40 // DialogClientView, public: | 40 // DialogClientView, public: |
| 41 | 41 |
| 42 DialogClientView::DialogClientView(Widget* owner, View* contents_view) | 42 DialogClientView::DialogClientView(Widget* owner, View* contents_view) |
| 43 : ClientView(owner, contents_view), | 43 : ClientView(owner, contents_view), |
| 44 ok_button_(NULL), | 44 ok_button_(NULL), |
| 45 cancel_button_(NULL), | 45 cancel_button_(NULL), |
| 46 default_button_(NULL), | |
| 47 focus_manager_(NULL), | |
| 48 extra_view_(NULL), | 46 extra_view_(NULL), |
| 49 footnote_view_(NULL), | 47 footnote_view_(NULL), |
| 50 notified_delegate_(false) { | 48 notified_delegate_(false) { |
| 51 // When using the new style, the background color is set on the bubble frame, | 49 // When using the new style, the background color is set on the bubble frame, |
| 52 // so a transparent background is fine. | 50 // so a transparent background is fine. |
| 53 if (!DialogDelegate::UseNewStyle()) { | 51 if (!DialogDelegate::UseNewStyle()) { |
| 54 const SkColor color = owner->GetNativeTheme()->GetSystemColor( | 52 const SkColor color = owner->GetNativeTheme()->GetSystemColor( |
| 55 ui::NativeTheme::kColorId_DialogBackground); | 53 ui::NativeTheme::kColorId_DialogBackground); |
| 56 set_background(views::Background::CreateSolidBackground(color)); | 54 set_background(views::Background::CreateSolidBackground(color)); |
| 57 } | 55 } |
| 56 |
| 57 // Add accelerators for the return and escape keys. |
| 58 AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)); |
| 59 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); |
| 58 } | 60 } |
| 59 | 61 |
| 60 DialogClientView::~DialogClientView() { | 62 DialogClientView::~DialogClientView() {} |
| 61 if (focus_manager_) | |
| 62 focus_manager_->RemoveFocusChangeListener(this); | |
| 63 focus_manager_ = NULL; | |
| 64 } | |
| 65 | 63 |
| 66 void DialogClientView::AcceptWindow() { | 64 void DialogClientView::AcceptWindow() { |
| 67 // Only notify the delegate once. See |notified_delegate_|'s comment. | 65 // Only notify the delegate once. See |notified_delegate_|'s comment. |
| 68 if (!notified_delegate_ && GetDialogDelegate()->Accept(false)) { | 66 if (!notified_delegate_ && GetDialogDelegate()->Accept(false)) { |
| 69 notified_delegate_ = true; | 67 notified_delegate_ = true; |
| 70 Close(); | 68 Close(); |
| 71 } | 69 } |
| 72 } | 70 } |
| 73 | 71 |
| 74 void DialogClientView::CancelWindow() { | 72 void DialogClientView::CancelWindow() { |
| 75 // Call the standard Close handler, which checks with the delegate before | 73 // Call the standard Close handler, which checks with the delegate before |
| 76 // proceeding. This checking _isn't_ done here, but in the WM_CLOSE handler, | 74 // proceeding. This checking _isn't_ done here, but in the WM_CLOSE handler, |
| 77 // so that the close box on the window also shares this code path. | 75 // so that the close box on the window also shares this code path. |
| 78 Close(); | 76 Close(); |
| 79 } | 77 } |
| 80 | 78 |
| 81 void DialogClientView::UpdateDialogButtons() { | 79 void DialogClientView::UpdateDialogButtons() { |
| 82 DialogDelegate* dialog = GetDialogDelegate(); | 80 DialogDelegate* dialog = GetDialogDelegate(); |
| 83 const int buttons = dialog->GetDialogButtons(); | 81 const int buttons = dialog->GetDialogButtons(); |
| 84 ui::Accelerator escape(ui::VKEY_ESCAPE, ui::EF_NONE); | |
| 85 | 82 |
| 86 if (buttons & ui::DIALOG_BUTTON_OK) { | 83 if (buttons & ui::DIALOG_BUTTON_OK) { |
| 87 if (!ok_button_) { | 84 if (!ok_button_) { |
| 88 ok_button_ = CreateDialogButton(ui::DIALOG_BUTTON_OK); | 85 ok_button_ = CreateDialogButton(ui::DIALOG_BUTTON_OK); |
| 89 if (buttons & ui::DIALOG_BUTTON_CANCEL) | |
| 90 ok_button_->AddAccelerator(escape); | |
| 91 AddChildView(ok_button_); | 86 AddChildView(ok_button_); |
| 92 } | 87 } |
| 93 | 88 |
| 94 UpdateButton(ok_button_, dialog, ui::DIALOG_BUTTON_OK); | 89 UpdateButton(ok_button_, dialog, ui::DIALOG_BUTTON_OK); |
| 95 } else if (ok_button_) { | 90 } else if (ok_button_) { |
| 96 delete ok_button_; | 91 delete ok_button_; |
| 97 ok_button_ = NULL; | 92 ok_button_ = NULL; |
| 98 } | 93 } |
| 99 | 94 |
| 100 if (buttons & ui::DIALOG_BUTTON_CANCEL) { | 95 if (buttons & ui::DIALOG_BUTTON_CANCEL) { |
| 101 if (!cancel_button_) { | 96 if (!cancel_button_) { |
| 102 cancel_button_ = CreateDialogButton(ui::DIALOG_BUTTON_CANCEL); | 97 cancel_button_ = CreateDialogButton(ui::DIALOG_BUTTON_CANCEL); |
| 103 cancel_button_->AddAccelerator(escape); | |
| 104 AddChildView(cancel_button_); | 98 AddChildView(cancel_button_); |
| 105 } | 99 } |
| 106 | 100 |
| 107 UpdateButton(cancel_button_, dialog, ui::DIALOG_BUTTON_CANCEL); | 101 UpdateButton(cancel_button_, dialog, ui::DIALOG_BUTTON_CANCEL); |
| 108 } else if (cancel_button_) { | 102 } else if (cancel_button_) { |
| 109 delete cancel_button_; | 103 delete cancel_button_; |
| 110 cancel_button_ = NULL; | 104 cancel_button_ = NULL; |
| 111 } | 105 } |
| 112 | |
| 113 // Use the escape key to close the window if there are no dialog buttons. | |
| 114 if (!has_dialog_buttons()) | |
| 115 AddAccelerator(escape); | |
| 116 else | |
| 117 ResetAccelerators(); | |
| 118 } | 106 } |
| 119 | 107 |
| 120 /////////////////////////////////////////////////////////////////////////////// | 108 /////////////////////////////////////////////////////////////////////////////// |
| 121 // DialogClientView, ClientView overrides: | 109 // DialogClientView, ClientView overrides: |
| 122 | 110 |
| 123 bool DialogClientView::CanClose() { | 111 bool DialogClientView::CanClose() { |
| 124 if (notified_delegate_) | 112 if (notified_delegate_) |
| 125 return true; | 113 return true; |
| 126 | 114 |
| 127 DialogDelegate* dialog = GetDialogDelegate(); | 115 DialogDelegate* dialog = GetDialogDelegate(); |
| 128 int buttons = dialog->GetDialogButtons(); | 116 int buttons = dialog->GetDialogButtons(); |
| 129 bool close = true; | 117 bool close = true; |
| 130 if ((buttons & ui::DIALOG_BUTTON_CANCEL) || | 118 if ((buttons & ui::DIALOG_BUTTON_CANCEL) || |
| 131 (buttons == ui::DIALOG_BUTTON_NONE)) | 119 (buttons == ui::DIALOG_BUTTON_NONE)) |
| 132 close = dialog->Cancel(); | 120 close = dialog->Cancel(); |
| 133 else if (buttons & ui::DIALOG_BUTTON_OK) | 121 else if (buttons & ui::DIALOG_BUTTON_OK) |
| 134 close = dialog->Accept(true); | 122 close = dialog->Accept(true); |
| 135 notified_delegate_ = close; | 123 notified_delegate_ = close; |
| 136 return close; | 124 return close; |
| 137 } | 125 } |
| 138 | 126 |
| 139 DialogClientView* DialogClientView::AsDialogClientView() { | 127 DialogClientView* DialogClientView::AsDialogClientView() { |
| 140 return this; | 128 return this; |
| 141 } | 129 } |
| 142 | 130 |
| 143 const DialogClientView* DialogClientView::AsDialogClientView() const { | 131 const DialogClientView* DialogClientView::AsDialogClientView() const { |
| 144 return this; | 132 return this; |
| 145 } | 133 } |
| 146 | 134 |
| 147 void DialogClientView::OnWillChangeFocus(View* focused_before, | |
| 148 View* focused_now) { | |
| 149 // New style dialogs do not move the default button with the focus. | |
| 150 // TODO(msw|wittman): Remove this functionality once the new style has landed. | |
| 151 if (DialogDelegate::UseNewStyle()) | |
| 152 return; | |
| 153 | |
| 154 // Make the newly focused button default or restore the dialog's default. | |
| 155 const int default_button = GetDialogDelegate()->GetDefaultDialogButton(); | |
| 156 LabelButton* new_default_button = NULL; | |
| 157 if (focused_now && | |
| 158 (focused_now->GetClassName() == LabelButton::kViewClassName)) { | |
| 159 new_default_button = static_cast<LabelButton*>(focused_now); | |
| 160 } else if (default_button == ui::DIALOG_BUTTON_OK && ok_button_) { | |
| 161 new_default_button = ok_button_; | |
| 162 } else if (default_button == ui::DIALOG_BUTTON_CANCEL && cancel_button_) { | |
| 163 new_default_button = cancel_button_; | |
| 164 } | |
| 165 | |
| 166 if (default_button_ && default_button_ != new_default_button) | |
| 167 default_button_->SetIsDefault(false); | |
| 168 default_button_ = new_default_button; | |
| 169 if (default_button_ && !default_button_->is_default()) | |
| 170 default_button_->SetIsDefault(true); | |
| 171 } | |
| 172 | |
| 173 void DialogClientView::OnDidChangeFocus(View* focused_before, | |
| 174 View* focused_now) { | |
| 175 } | |
| 176 | |
| 177 //////////////////////////////////////////////////////////////////////////////// | 135 //////////////////////////////////////////////////////////////////////////////// |
| 178 // DialogClientView, View overrides: | 136 // DialogClientView, View overrides: |
| 179 | 137 |
| 180 gfx::Size DialogClientView::GetPreferredSize() { | 138 gfx::Size DialogClientView::GetPreferredSize() { |
| 181 // Initialize the size to fit the buttons and extra view row. | 139 // Initialize the size to fit the buttons and extra view row. |
| 182 gfx::Size size( | 140 gfx::Size size( |
| 183 (ok_button_ ? ok_button_->GetPreferredSize().width() : 0) + | 141 (ok_button_ ? ok_button_->GetPreferredSize().width() : 0) + |
| 184 (cancel_button_ ? cancel_button_->GetPreferredSize().width() : 0) + | 142 (cancel_button_ ? cancel_button_->GetPreferredSize().width() : 0) + |
| 185 (cancel_button_ && ok_button_ ? kRelatedButtonHSpacing : 0) + | 143 (cancel_button_ && ok_button_ ? kRelatedButtonHSpacing : 0) + |
| 186 (ShouldShow(extra_view_) ? extra_view_->GetPreferredSize().width() : 0) + | 144 (ShouldShow(extra_view_) ? extra_view_->GetPreferredSize().width() : 0) + |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 } | 216 } |
| 259 | 217 |
| 260 // Layout the contents view to the top and side edges of the contents bounds. | 218 // Layout the contents view to the top and side edges of the contents bounds. |
| 261 // NOTE: The local insets do not apply to the contents view sides or top. | 219 // NOTE: The local insets do not apply to the contents view sides or top. |
| 262 const gfx::Rect contents_bounds = GetContentsBounds(); | 220 const gfx::Rect contents_bounds = GetContentsBounds(); |
| 263 contents_view()->SetBounds(contents_bounds.x(), contents_bounds.y(), | 221 contents_view()->SetBounds(contents_bounds.x(), contents_bounds.y(), |
| 264 contents_bounds.width(), bounds.bottom() - contents_bounds.y()); | 222 contents_bounds.width(), bounds.bottom() - contents_bounds.y()); |
| 265 } | 223 } |
| 266 | 224 |
| 267 bool DialogClientView::AcceleratorPressed(const ui::Accelerator& accelerator) { | 225 bool DialogClientView::AcceleratorPressed(const ui::Accelerator& accelerator) { |
| 268 DCHECK_EQ(accelerator.key_code(), ui::VKEY_ESCAPE); | 226 if (accelerator.key_code() == ui::VKEY_ESCAPE) { |
| 269 Close(); | 227 if (!cancel_button_ || !cancel_button_->AcceleratorPressed(accelerator)) |
| 270 return true; | 228 CancelWindow(); |
| 229 return true; |
| 230 } |
| 231 |
| 232 if (accelerator.key_code() == ui::VKEY_RETURN) { |
| 233 View* focused = GetFocusManager()->GetFocusedView(); |
| 234 const int default_button_id = GetDialogDelegate()->GetDefaultDialogButton(); |
| 235 Button* default_button = ok_button_; |
| 236 if (default_button_id == ui::DIALOG_BUTTON_CANCEL && cancel_button_) |
| 237 default_button = cancel_button_; |
| 238 if (!(focused && focused->GetClassName() == LabelButton::kViewClassName && |
| 239 focused->AcceleratorPressed(accelerator)) && |
| 240 !(default_button && default_button->AcceleratorPressed(accelerator))) |
| 241 AcceptWindow(); |
| 242 return true; |
| 243 } |
| 244 |
| 245 NOTREACHED(); |
| 246 return false; |
| 271 } | 247 } |
| 272 | 248 |
| 273 void DialogClientView::ViewHierarchyChanged(bool is_add, | 249 void DialogClientView::ViewHierarchyChanged(bool is_add, |
| 274 View* parent, | 250 View* parent, |
| 275 View* child) { | 251 View* child) { |
| 276 ClientView::ViewHierarchyChanged(is_add, parent, child); | 252 ClientView::ViewHierarchyChanged(is_add, parent, child); |
| 277 if (is_add && child == this) { | 253 if (is_add && child == this) { |
| 278 focus_manager_ = GetFocusManager(); | |
| 279 if (focus_manager_) | |
| 280 GetFocusManager()->AddFocusChangeListener(this); | |
| 281 | |
| 282 UpdateDialogButtons(); | 254 UpdateDialogButtons(); |
| 283 CreateExtraView(); | 255 CreateExtraView(); |
| 284 CreateFootnoteView(); | 256 CreateFootnoteView(); |
| 285 } | 257 } |
| 286 } | 258 } |
| 287 | 259 |
| 288 //////////////////////////////////////////////////////////////////////////////// | 260 //////////////////////////////////////////////////////////////////////////////// |
| 289 // DialogClientView, ButtonListener implementation: | 261 // DialogClientView, ButtonListener implementation: |
| 290 | 262 |
| 291 void DialogClientView::ButtonPressed(Button* sender, const ui::Event& event) { | 263 void DialogClientView::ButtonPressed(Button* sender, const ui::Event& event) { |
| 292 // Check for a valid delegate to avoid handling events after destruction. | 264 // Check for a valid delegate to avoid handling events after destruction. |
| 293 if (!GetDialogDelegate()) | 265 if (!GetDialogDelegate()) |
| 294 return; | 266 return; |
| 295 | 267 |
| 296 if (sender == ok_button_) | 268 if (sender == ok_button_) |
| 297 AcceptWindow(); | 269 AcceptWindow(); |
| 298 else if (sender == cancel_button_) | 270 else if (sender == cancel_button_) |
| 299 CancelWindow(); | 271 CancelWindow(); |
| 300 else | 272 else |
| 301 NOTREACHED(); | 273 NOTREACHED(); |
| 302 } | 274 } |
| 303 | 275 |
| 304 //////////////////////////////////////////////////////////////////////////////// | 276 //////////////////////////////////////////////////////////////////////////////// |
| 305 // DialogClientView, protected: | 277 // DialogClientView, protected: |
| 306 | 278 |
| 307 DialogClientView::DialogClientView(View* contents_view) | 279 DialogClientView::DialogClientView(View* contents_view) |
| 308 : ClientView(NULL, contents_view), | 280 : ClientView(NULL, contents_view), |
| 309 ok_button_(NULL), | 281 ok_button_(NULL), |
| 310 cancel_button_(NULL), | 282 cancel_button_(NULL), |
| 311 default_button_(NULL), | |
| 312 focus_manager_(NULL), | |
| 313 extra_view_(NULL), | 283 extra_view_(NULL), |
| 314 footnote_view_(NULL), | 284 footnote_view_(NULL), |
| 315 notified_delegate_(false) {} | 285 notified_delegate_(false) {} |
| 316 | 286 |
| 317 DialogDelegate* DialogClientView::GetDialogDelegate() const { | 287 DialogDelegate* DialogClientView::GetDialogDelegate() const { |
| 318 return GetWidget()->widget_delegate()->AsDialogDelegate(); | 288 return GetWidget()->widget_delegate()->AsDialogDelegate(); |
| 319 } | 289 } |
| 320 | 290 |
| 321 void DialogClientView::CreateExtraView() { | 291 void DialogClientView::CreateExtraView() { |
| 322 if (extra_view_) | 292 if (extra_view_) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 338 AddChildView(footnote_view_); | 308 AddChildView(footnote_view_); |
| 339 } | 309 } |
| 340 | 310 |
| 341 //////////////////////////////////////////////////////////////////////////////// | 311 //////////////////////////////////////////////////////////////////////////////// |
| 342 // DialogClientView, private: | 312 // DialogClientView, private: |
| 343 | 313 |
| 344 LabelButton* DialogClientView::CreateDialogButton(ui::DialogButton type) { | 314 LabelButton* DialogClientView::CreateDialogButton(ui::DialogButton type) { |
| 345 const string16 title = GetDialogDelegate()->GetDialogButtonLabel(type); | 315 const string16 title = GetDialogDelegate()->GetDialogButtonLabel(type); |
| 346 LabelButton* button = new LabelButton(this, title); | 316 LabelButton* button = new LabelButton(this, title); |
| 347 button->SetStyle(Button::STYLE_NATIVE_TEXTBUTTON); | 317 button->SetStyle(Button::STYLE_NATIVE_TEXTBUTTON); |
| 348 button->set_focusable(true); | |
| 349 | 318 |
| 350 const int kDialogMinButtonWidth = 75; | 319 const int kDialogMinButtonWidth = 75; |
| 351 button->set_min_size(gfx::Size(kDialogMinButtonWidth, 0)); | 320 button->set_min_size(gfx::Size(kDialogMinButtonWidth, 0)); |
| 352 button->SetGroup(kButtonGroup); | 321 button->SetGroup(kButtonGroup); |
| 353 if (type == GetDialogDelegate()->GetDefaultDialogButton()) { | 322 if (type == GetDialogDelegate()->GetDefaultDialogButton()) { |
| 354 default_button_ = button; | 323 // Make the button appear default, but handle the return key in this view. |
| 355 button->SetIsDefault(true); | 324 button->SetIsDefault(true); |
| 325 button->RemoveAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)); |
| 356 } | 326 } |
| 357 return button; | 327 return button; |
| 358 } | 328 } |
| 359 | 329 |
| 360 int DialogClientView::GetButtonsAndExtraViewRowHeight() const { | 330 int DialogClientView::GetButtonsAndExtraViewRowHeight() const { |
| 361 int extra_view_height = ShouldShow(extra_view_) ? | 331 int extra_view_height = ShouldShow(extra_view_) ? |
| 362 extra_view_->GetPreferredSize().height() : 0; | 332 extra_view_->GetPreferredSize().height() : 0; |
| 363 int buttons_height = std::max( | 333 int buttons_height = std::max( |
| 364 ok_button_ ? ok_button_->GetPreferredSize().height() : 0, | 334 ok_button_ ? ok_button_->GetPreferredSize().height() : 0, |
| 365 cancel_button_ ? cancel_button_->GetPreferredSize().height() : 0); | 335 cancel_button_ ? cancel_button_->GetPreferredSize().height() : 0); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 376 gfx::Insets(0, kButtonHEdgeMargin, | 346 gfx::Insets(0, kButtonHEdgeMargin, |
| 377 kButtonVEdgeMargin, kButtonHEdgeMargin); | 347 kButtonVEdgeMargin, kButtonHEdgeMargin); |
| 378 } | 348 } |
| 379 | 349 |
| 380 void DialogClientView::Close() { | 350 void DialogClientView::Close() { |
| 381 GetWidget()->Close(); | 351 GetWidget()->Close(); |
| 382 GetDialogDelegate()->OnClose(); | 352 GetDialogDelegate()->OnClose(); |
| 383 } | 353 } |
| 384 | 354 |
| 385 } // namespace views | 355 } // namespace views |
| OLD | NEW |