OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 "views/window/dialog_client_view.h" | |
6 | |
7 #include "build/build_config.h" | |
8 | |
9 #if defined(OS_WIN) | |
10 #include <windows.h> | |
11 #include <uxtheme.h> | |
12 #include <vsstyle.h> | |
13 #elif defined(TOOLKIT_USES_GTK) | |
14 #include <gtk/gtk.h> | |
15 #endif | |
16 | |
17 #include <algorithm> | |
18 | |
19 #include "base/utf_string_conversions.h" | |
20 #include "grit/ui_strings.h" | |
21 #include "ui/base/hit_test.h" | |
22 #include "ui/base/keycodes/keyboard_codes.h" | |
23 #include "ui/base/l10n/l10n_util.h" | |
24 #include "ui/base/resource/resource_bundle.h" | |
25 #include "ui/gfx/canvas_skia.h" | |
26 #include "ui/gfx/font.h" | |
27 #include "views/controls/button/text_button.h" | |
28 #include "views/layout/layout_constants.h" | |
29 #include "views/widget/root_view.h" | |
30 #include "views/widget/widget.h" | |
31 #include "views/window/dialog_delegate.h" | |
32 | |
33 #if defined(OS_WIN) | |
34 #include "ui/gfx/native_theme.h" | |
35 #else | |
36 #include "ui/gfx/skia_utils_gtk.h" | |
37 #endif | |
38 | |
39 namespace views { | |
40 namespace { | |
41 | |
42 // Updates any of the standard buttons according to the delegate. | |
43 void UpdateButtonHelper(NativeTextButton* button_view, | |
44 DialogDelegate* delegate, | |
45 ui::DialogButton button) { | |
46 string16 label = delegate->GetDialogButtonLabel(button); | |
47 if (!label.empty()) | |
48 button_view->SetText(label); | |
49 button_view->SetEnabled(delegate->IsDialogButtonEnabled(button)); | |
50 button_view->SetVisible(delegate->IsDialogButtonVisible(button)); | |
51 } | |
52 | |
53 #if defined(OS_WIN) | |
54 void FillViewWithSysColor(gfx::Canvas* canvas, View* view, COLORREF color) { | |
55 SkColor sk_color = | |
56 SkColorSetRGB(GetRValue(color), GetGValue(color), GetBValue(color)); | |
57 canvas->FillRect(sk_color, view->GetLocalBounds()); | |
58 } | |
59 #endif | |
60 | |
61 // DialogButton ---------------------------------------------------------------- | |
62 | |
63 // DialogButtons is used for the ok/cancel buttons of the window. DialogButton | |
64 // forwards AcceleratorPressed to the delegate. | |
65 | |
66 class DialogButton : public NativeTextButton { | |
67 public: | |
68 DialogButton(ButtonListener* listener, | |
69 Widget* owner, | |
70 ui::DialogButton type, | |
71 const string16& title, | |
72 bool is_default) | |
73 : NativeTextButton(listener, title), | |
74 owner_(owner), | |
75 type_(type) { | |
76 SetIsDefault(is_default); | |
77 } | |
78 | |
79 // Overridden to forward to the delegate. | |
80 virtual bool AcceleratorPressed(const Accelerator& accelerator) { | |
81 if (!owner_->widget_delegate()->AsDialogDelegate()-> | |
82 AreAcceleratorsEnabled(type_)) { | |
83 return false; | |
84 } | |
85 return NativeTextButton::AcceleratorPressed(accelerator); | |
86 } | |
87 | |
88 private: | |
89 Widget* owner_; | |
90 const ui::DialogButton type_; | |
91 | |
92 DISALLOW_COPY_AND_ASSIGN(DialogButton); | |
93 }; | |
94 | |
95 } // namespace | |
96 | |
97 // static | |
98 gfx::Font* DialogClientView::dialog_button_font_ = NULL; | |
99 static const int kDialogMinButtonWidth = 75; | |
100 static const int kDialogButtonLabelSpacing = 16; | |
101 static const int kDialogButtonContentSpacing = 5; | |
102 | |
103 // The group used by the buttons. This name is chosen voluntarily big not to | |
104 // conflict with other groups that could be in the dialog content. | |
105 static const int kButtonGroup = 6666; | |
106 | |
107 /////////////////////////////////////////////////////////////////////////////// | |
108 // DialogClientView, public: | |
109 | |
110 DialogClientView::DialogClientView(Widget* owner, View* contents_view) | |
111 : ClientView(owner, contents_view), | |
112 ok_button_(NULL), | |
113 cancel_button_(NULL), | |
114 default_button_(NULL), | |
115 extra_view_(NULL), | |
116 size_extra_view_height_to_buttons_(false), | |
117 notified_delegate_(false), | |
118 listening_to_focus_(false), | |
119 saved_focus_manager_(NULL), | |
120 bottom_view_(NULL) { | |
121 InitClass(); | |
122 } | |
123 | |
124 DialogClientView::~DialogClientView() { | |
125 } | |
126 | |
127 void DialogClientView::ShowDialogButtons() { | |
128 DialogDelegate* dd = GetDialogDelegate(); | |
129 int buttons = dd->GetDialogButtons(); | |
130 if (buttons & ui::DIALOG_BUTTON_OK && !ok_button_) { | |
131 string16 label = dd->GetDialogButtonLabel(ui::DIALOG_BUTTON_OK); | |
132 if (label.empty()) | |
133 label = l10n_util::GetStringUTF16(IDS_APP_OK); | |
134 bool is_default_button = | |
135 (dd->GetDefaultDialogButton() & ui::DIALOG_BUTTON_OK) != 0; | |
136 ok_button_ = new DialogButton(this, | |
137 GetWidget(), | |
138 ui::DIALOG_BUTTON_OK, | |
139 label, | |
140 is_default_button); | |
141 ok_button_->SetGroup(kButtonGroup); | |
142 if (is_default_button) | |
143 default_button_ = ok_button_; | |
144 if (!(buttons & ui::DIALOG_BUTTON_CANCEL)) | |
145 ok_button_->AddAccelerator(Accelerator(ui::VKEY_ESCAPE, | |
146 false, false, false)); | |
147 AddChildView(ok_button_); | |
148 } | |
149 if (buttons & ui::DIALOG_BUTTON_CANCEL && !cancel_button_) { | |
150 string16 label = | |
151 dd->GetDialogButtonLabel(ui::DIALOG_BUTTON_CANCEL); | |
152 if (label.empty()) { | |
153 if (buttons & ui::DIALOG_BUTTON_OK) { | |
154 label = l10n_util::GetStringUTF16(IDS_APP_CANCEL); | |
155 } else { | |
156 label = l10n_util::GetStringUTF16(IDS_APP_CLOSE); | |
157 } | |
158 } | |
159 bool is_default_button = | |
160 (dd->GetDefaultDialogButton() & ui::DIALOG_BUTTON_CANCEL) | |
161 != 0; | |
162 cancel_button_ = new DialogButton(this, | |
163 GetWidget(), | |
164 ui::DIALOG_BUTTON_CANCEL, | |
165 label, | |
166 is_default_button); | |
167 cancel_button_->SetGroup(kButtonGroup); | |
168 cancel_button_->AddAccelerator(Accelerator(ui::VKEY_ESCAPE, | |
169 false, false, false)); | |
170 if (is_default_button) | |
171 default_button_ = ok_button_; | |
172 AddChildView(cancel_button_); | |
173 } | |
174 if (!buttons) { | |
175 // Register the escape key as an accelerator which will close the window | |
176 // if there are no dialog buttons. | |
177 AddAccelerator(Accelerator(ui::VKEY_ESCAPE, false, false, false)); | |
178 } | |
179 } | |
180 | |
181 void DialogClientView::SetDefaultButton(NativeTextButton* new_default_button) { | |
182 if (default_button_ && default_button_ != new_default_button) { | |
183 default_button_->SetIsDefault(false); | |
184 default_button_ = NULL; | |
185 } | |
186 | |
187 if (new_default_button) { | |
188 default_button_ = new_default_button; | |
189 default_button_->SetIsDefault(true); | |
190 } | |
191 } | |
192 | |
193 void DialogClientView::OnWillChangeFocus(View* focused_before, | |
194 View* focused_now) { | |
195 NativeTextButton* new_default_button = NULL; | |
196 if (focused_now && | |
197 focused_now->GetClassName() == NativeTextButton::kViewClassName) { | |
198 new_default_button = static_cast<NativeTextButton*>(focused_now); | |
199 } else { | |
200 // The focused view is not a button, get the default button from the | |
201 // delegate. | |
202 DialogDelegate* dd = GetDialogDelegate(); | |
203 if ((dd->GetDefaultDialogButton() & ui::DIALOG_BUTTON_OK) != 0) | |
204 new_default_button = ok_button_; | |
205 if ((dd->GetDefaultDialogButton() & ui::DIALOG_BUTTON_CANCEL) | |
206 != 0) | |
207 new_default_button = cancel_button_; | |
208 } | |
209 SetDefaultButton(new_default_button); | |
210 } | |
211 | |
212 void DialogClientView::OnDidChangeFocus(View* focused_before, | |
213 View* focused_now) { | |
214 } | |
215 | |
216 // Changing dialog labels will change button widths. | |
217 void DialogClientView::UpdateDialogButtons() { | |
218 DialogDelegate* dd = GetDialogDelegate(); | |
219 int buttons = dd->GetDialogButtons(); | |
220 | |
221 if (buttons & ui::DIALOG_BUTTON_OK) | |
222 UpdateButtonHelper(ok_button_, dd, ui::DIALOG_BUTTON_OK); | |
223 | |
224 if (buttons & ui::DIALOG_BUTTON_CANCEL) { | |
225 UpdateButtonHelper(cancel_button_, dd, ui::DIALOG_BUTTON_CANCEL); | |
226 } | |
227 | |
228 LayoutDialogButtons(); | |
229 SchedulePaint(); | |
230 } | |
231 | |
232 void DialogClientView::AcceptWindow() { | |
233 if (notified_delegate_) { | |
234 // Only notify the delegate once. See comment in header above | |
235 // notified_delegate_ for details. | |
236 return; | |
237 } | |
238 if (GetDialogDelegate()->Accept(false)) { | |
239 notified_delegate_ = true; | |
240 Close(); | |
241 } | |
242 } | |
243 | |
244 void DialogClientView::CancelWindow() { | |
245 // Call the standard Close handler, which checks with the delegate before | |
246 // proceeding. This checking _isn't_ done here, but in the WM_CLOSE handler, | |
247 // so that the close box on the window also shares this code path. | |
248 Close(); | |
249 } | |
250 | |
251 void DialogClientView::SetBottomView(View* bottom_view) { | |
252 if (bottom_view_) { | |
253 RemoveChildView(bottom_view_); | |
254 delete bottom_view_; | |
255 } | |
256 bottom_view_ = bottom_view; | |
257 if (bottom_view_) | |
258 AddChildView(bottom_view_); | |
259 } | |
260 | |
261 /////////////////////////////////////////////////////////////////////////////// | |
262 // DialogClientView, View overrides: | |
263 | |
264 void DialogClientView::NativeViewHierarchyChanged( | |
265 bool attached, | |
266 gfx::NativeView native_view, | |
267 internal::RootView* root_view) { | |
268 if (attached) { | |
269 UpdateFocusListener(); | |
270 } | |
271 } | |
272 | |
273 /////////////////////////////////////////////////////////////////////////////// | |
274 // DialogClientView, ClientView overrides: | |
275 | |
276 bool DialogClientView::CanClose() { | |
277 if (notified_delegate_) | |
278 return true; | |
279 | |
280 DialogDelegate* dd = GetDialogDelegate(); | |
281 int buttons = dd->GetDialogButtons(); | |
282 bool close = true; | |
283 if (buttons & ui::DIALOG_BUTTON_CANCEL) | |
284 close = dd->Cancel(); | |
285 else if (buttons & ui::DIALOG_BUTTON_OK) | |
286 close = dd->Accept(true); | |
287 notified_delegate_ = close; | |
288 return close; | |
289 } | |
290 | |
291 void DialogClientView::WidgetClosing() { | |
292 if (listening_to_focus_) { | |
293 DCHECK(saved_focus_manager_); | |
294 if (saved_focus_manager_) | |
295 saved_focus_manager_->RemoveFocusChangeListener(this); | |
296 } | |
297 } | |
298 | |
299 int DialogClientView::NonClientHitTest(const gfx::Point& point) { | |
300 if (size_box_bounds_.Contains(point.x() - x(), point.y() - y())) | |
301 return HTBOTTOMRIGHT; | |
302 return ClientView::NonClientHitTest(point); | |
303 } | |
304 | |
305 DialogClientView* DialogClientView::AsDialogClientView() { | |
306 return this; | |
307 } | |
308 | |
309 const DialogClientView* DialogClientView::AsDialogClientView() const { | |
310 return this; | |
311 } | |
312 | |
313 //////////////////////////////////////////////////////////////////////////////// | |
314 // DialogClientView, View overrides: | |
315 | |
316 void DialogClientView::OnPaint(gfx::Canvas* canvas) { | |
317 #if defined(OS_WIN) | |
318 FillViewWithSysColor(canvas, this, GetSysColor(COLOR_3DFACE)); | |
319 #elif defined(USE_WAYLAND) || defined(USE_AURA) | |
320 SkColor sk_color = SkColorSetARGB(200, 255, 255, 255); | |
321 canvas->FillRect(sk_color, GetLocalBounds()); | |
322 #else | |
323 GtkWidget* widget = GetWidget()->GetNativeView(); | |
324 if (GTK_IS_WINDOW(widget)) { | |
325 GtkStyle* window_style = gtk_widget_get_style(widget); | |
326 canvas->FillRect(gfx::GdkColorToSkColor(window_style->bg[GTK_STATE_NORMAL]), | |
327 GetLocalBounds()); | |
328 } | |
329 #endif | |
330 } | |
331 | |
332 void DialogClientView::PaintChildren(gfx::Canvas* canvas) { | |
333 View::PaintChildren(canvas); | |
334 if (!GetWidget()->IsMaximized() && !GetWidget()->IsMinimized()) | |
335 PaintSizeBox(canvas); | |
336 } | |
337 | |
338 void DialogClientView::Layout() { | |
339 if (has_dialog_buttons()) | |
340 LayoutDialogButtons(); | |
341 if (bottom_view_) { | |
342 gfx::Rect bounds = GetContentsBounds(); | |
343 gfx::Size pref = bottom_view_->GetPreferredSize(); | |
344 bottom_view_->SetBounds(bounds.x(), | |
345 bounds.bottom() - pref.height() - kButtonVEdgeMargin, | |
346 bounds.width(), pref.height()); | |
347 } | |
348 LayoutContentsView(); | |
349 } | |
350 | |
351 void DialogClientView::ViewHierarchyChanged(bool is_add, View* parent, | |
352 View* child) { | |
353 if (is_add && child == this) { | |
354 // Can only add and update the dialog buttons _after_ they are added to the | |
355 // view hierarchy since they are native controls and require the | |
356 // Container's HWND. | |
357 ShowDialogButtons(); | |
358 ClientView::ViewHierarchyChanged(is_add, parent, child); | |
359 | |
360 UpdateFocusListener(); | |
361 | |
362 // The "extra view" must be created and installed after the contents view | |
363 // has been inserted into the view hierarchy. | |
364 CreateExtraView(); | |
365 UpdateDialogButtons(); | |
366 Layout(); | |
367 } | |
368 } | |
369 | |
370 gfx::Size DialogClientView::GetPreferredSize() { | |
371 gfx::Size prefsize = contents_view()->GetPreferredSize(); | |
372 int button_height = 0; | |
373 if (has_dialog_buttons()) { | |
374 if (cancel_button_) | |
375 button_height = cancel_button_->height(); | |
376 else | |
377 button_height = ok_button_->height(); | |
378 // Account for padding above and below the button. | |
379 button_height += kDialogButtonContentSpacing + kButtonVEdgeMargin; | |
380 | |
381 // Make sure the view is sized to the buttons's width if they are wider than | |
382 // the contents. | |
383 int width = 0; | |
384 if (cancel_button_) | |
385 width += GetButtonWidth(ui::DIALOG_BUTTON_CANCEL); | |
386 if (ok_button_) { | |
387 width += GetButtonWidth(ui::DIALOG_BUTTON_OK); | |
388 if (cancel_button_) | |
389 width += kRelatedButtonHSpacing; | |
390 } | |
391 if (extra_view_) { | |
392 width += extra_view_->GetPreferredSize().width(); | |
393 if (cancel_button_ || ok_button_) | |
394 width += kRelatedButtonHSpacing; | |
395 } | |
396 if (width > 0) { | |
397 width += 2 * kButtonHEdgeMargin; | |
398 prefsize.set_width(std::max(prefsize.width(), width)); | |
399 } | |
400 } | |
401 if (bottom_view_) { | |
402 gfx::Size bottom_pref = bottom_view_->GetPreferredSize(); | |
403 prefsize.Enlarge(0, bottom_pref.height() + kButtonVEdgeMargin); | |
404 } | |
405 prefsize.Enlarge(0, button_height); | |
406 return prefsize; | |
407 } | |
408 | |
409 bool DialogClientView::AcceleratorPressed(const Accelerator& accelerator) { | |
410 // We only expect Escape key. | |
411 DCHECK(accelerator.key_code() == ui::VKEY_ESCAPE); | |
412 Close(); | |
413 return true; | |
414 } | |
415 | |
416 //////////////////////////////////////////////////////////////////////////////// | |
417 // DialogClientView, ButtonListener implementation: | |
418 | |
419 void DialogClientView::ButtonPressed( | |
420 Button* sender, const views::Event& event) { | |
421 // We NULL check the delegate here since the buttons can receive WM_COMMAND | |
422 // messages even after they (and the window containing us) are destroyed. | |
423 if (!GetDialogDelegate()) | |
424 return; | |
425 | |
426 if (sender == ok_button_) { | |
427 AcceptWindow(); | |
428 } else if (sender == cancel_button_) { | |
429 CancelWindow(); | |
430 } else { | |
431 NOTREACHED(); | |
432 } | |
433 } | |
434 | |
435 //////////////////////////////////////////////////////////////////////////////// | |
436 // DialogClientView, private: | |
437 | |
438 void DialogClientView::PaintSizeBox(gfx::Canvas* canvas) { | |
439 if (GetWidget()->widget_delegate()->CanResize() || | |
440 GetWidget()->widget_delegate()->CanMaximize()) { | |
441 #if defined(OS_WIN) | |
442 gfx::NativeTheme::ExtraParams extra; | |
443 gfx::Size gripper_size = gfx::NativeTheme::instance()->GetPartSize( | |
444 gfx::NativeTheme::kWindowResizeGripper, gfx::NativeTheme::kNormal, | |
445 extra); | |
446 | |
447 // TODO(beng): (http://b/1085509) In "classic" rendering mode, there isn't | |
448 // a theme-supplied gripper. We should probably improvise | |
449 // something, which would also require changing |gripper_size| | |
450 // to have different default values, too... | |
451 size_box_bounds_ = GetContentsBounds(); | |
452 size_box_bounds_.set_x(size_box_bounds_.right() - gripper_size.width()); | |
453 size_box_bounds_.set_y(size_box_bounds_.bottom() - gripper_size.height()); | |
454 | |
455 gfx::NativeTheme::instance()->Paint(canvas->GetSkCanvas(), | |
456 gfx::NativeTheme::kWindowResizeGripper, | |
457 gfx::NativeTheme::kNormal, | |
458 size_box_bounds_, | |
459 extra); | |
460 #else | |
461 NOTIMPLEMENTED(); | |
462 // TODO(port): paint size box | |
463 #endif | |
464 } | |
465 } | |
466 | |
467 int DialogClientView::GetButtonWidth(int button) const { | |
468 DialogDelegate* dd = GetDialogDelegate(); | |
469 string16 button_label = dd->GetDialogButtonLabel( | |
470 static_cast<ui::DialogButton>(button)); | |
471 int string_width = dialog_button_font_->GetStringWidth(button_label); | |
472 return std::max(string_width + kDialogButtonLabelSpacing, | |
473 kDialogMinButtonWidth); | |
474 } | |
475 | |
476 int DialogClientView::GetButtonsHeight() const { | |
477 if (has_dialog_buttons()) { | |
478 if (cancel_button_) | |
479 return cancel_button_->height() + kDialogButtonContentSpacing; | |
480 return ok_button_->height() + kDialogButtonContentSpacing; | |
481 } | |
482 return 0; | |
483 } | |
484 | |
485 void DialogClientView::LayoutDialogButtons() { | |
486 gfx::Rect lb = GetContentsBounds(); | |
487 gfx::Rect extra_bounds; | |
488 int bottom_y = lb.bottom() - kButtonVEdgeMargin; | |
489 int button_height = 0; | |
490 if (bottom_view_) { | |
491 gfx::Size bottom_pref = bottom_view_->GetPreferredSize(); | |
492 bottom_y -= bottom_pref.height() + kButtonVEdgeMargin + kButtonVEdgeMargin; | |
493 } | |
494 if (cancel_button_) { | |
495 gfx::Size ps = cancel_button_->GetPreferredSize(); | |
496 int button_width = std::max( | |
497 GetButtonWidth(ui::DIALOG_BUTTON_CANCEL), ps.width()); | |
498 int button_x = lb.right() - button_width - kButtonHEdgeMargin; | |
499 int button_y = bottom_y - ps.height(); | |
500 cancel_button_->SetBounds(button_x, button_y, button_width, ps.height()); | |
501 // The extra view bounds are dependent on this button. | |
502 extra_bounds.set_width(std::max(0, cancel_button_->x())); | |
503 extra_bounds.set_y(cancel_button_->y()); | |
504 button_height = std::max(button_height, ps.height()); | |
505 } | |
506 if (ok_button_) { | |
507 gfx::Size ps = ok_button_->GetPreferredSize(); | |
508 int button_width = std::max( | |
509 GetButtonWidth(ui::DIALOG_BUTTON_OK), ps.width()); | |
510 int ok_button_right = lb.right() - kButtonHEdgeMargin; | |
511 if (cancel_button_) | |
512 ok_button_right = cancel_button_->x() - kRelatedButtonHSpacing; | |
513 int button_x = ok_button_right - button_width; | |
514 int button_y = bottom_y - ps.height(); | |
515 ok_button_->SetBounds(button_x, button_y, ok_button_right - button_x, | |
516 ps.height()); | |
517 // The extra view bounds are dependent on this button. | |
518 extra_bounds.set_width(std::max(0, ok_button_->x())); | |
519 extra_bounds.set_y(ok_button_->y()); | |
520 button_height = std::max(button_height, ps.height()); | |
521 } | |
522 if (extra_view_) { | |
523 gfx::Size ps = extra_view_->GetPreferredSize(); | |
524 extra_bounds.set_x(lb.x() + kButtonHEdgeMargin); | |
525 int height = size_extra_view_height_to_buttons_ ? | |
526 std::max(ps.height(), button_height) : ps.height(); | |
527 extra_bounds.set_height(height); | |
528 extra_view_->SetBoundsRect(extra_bounds); | |
529 } | |
530 } | |
531 | |
532 void DialogClientView::LayoutContentsView() { | |
533 gfx::Rect lb = GetContentsBounds(); | |
534 lb.set_height(std::max(0, lb.height() - GetButtonsHeight())); | |
535 contents_view()->SetBoundsRect(lb); | |
536 contents_view()->Layout(); | |
537 } | |
538 | |
539 void DialogClientView::CreateExtraView() { | |
540 View* extra_view = GetDialogDelegate()->GetExtraView(); | |
541 if (extra_view && !extra_view_) { | |
542 extra_view_ = extra_view; | |
543 extra_view_->SetGroup(kButtonGroup); | |
544 AddChildView(extra_view_); | |
545 size_extra_view_height_to_buttons_ = | |
546 GetDialogDelegate()->GetSizeExtraViewHeightToButtons(); | |
547 } | |
548 } | |
549 | |
550 DialogDelegate* DialogClientView::GetDialogDelegate() const { | |
551 return GetWidget()->widget_delegate()->AsDialogDelegate(); | |
552 } | |
553 | |
554 void DialogClientView::Close() { | |
555 GetWidget()->Close(); | |
556 GetDialogDelegate()->OnClose(); | |
557 } | |
558 | |
559 void DialogClientView::UpdateFocusListener() { | |
560 FocusManager* focus_manager = GetFocusManager(); | |
561 // Listen for focus change events so we can update the default button. | |
562 // focus_manager can be NULL when the dialog is created on un-shown view. | |
563 // We start listening for focus changes when the page is visible. | |
564 // Focus manager could also change if window host changes a parent. | |
565 if (listening_to_focus_) { | |
566 if (saved_focus_manager_ == focus_manager) | |
567 return; | |
568 DCHECK(saved_focus_manager_); | |
569 if (saved_focus_manager_) | |
570 saved_focus_manager_->RemoveFocusChangeListener(this); | |
571 listening_to_focus_ = false; | |
572 } | |
573 saved_focus_manager_ = focus_manager; | |
574 // Listen for focus change events so we can update the default button. | |
575 if (focus_manager) { | |
576 focus_manager->AddFocusChangeListener(this); | |
577 listening_to_focus_ = true; | |
578 } | |
579 } | |
580 | |
581 // static | |
582 void DialogClientView::InitClass() { | |
583 static bool initialized = false; | |
584 if (!initialized) { | |
585 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | |
586 dialog_button_font_ = new gfx::Font(rb.GetFont(ResourceBundle::BaseFont)); | |
587 initialized = true; | |
588 } | |
589 } | |
590 | |
591 } // namespace views | |
OLD | NEW |