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 |