Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: ui/views/window/dialog_client_view.cc

Issue 14230018: Handle dialog acclerators explicitly; nix default button switching. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Limit the focused view handling to LabelButton; update tests. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/views/window/dialog_client_view.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « ui/views/window/dialog_client_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698