Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/ui/views/first_run_bubble.h" | 5 #include "chrome/browser/ui/views/first_run_bubble.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
| 9 #include "chrome/browser/ui/views/bubble/bubble.h" // for kBackgroundColor | |
| 9 #include "chrome/browser/first_run/first_run.h" | 10 #include "chrome/browser/first_run/first_run.h" |
| 10 #include "chrome/browser/search_engines/util.h" | 11 #include "chrome/browser/search_engines/util.h" |
| 11 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.h" |
| 12 #include "chrome/browser/ui/browser_list.h" | 13 #include "chrome/browser/ui/browser_list.h" |
| 13 #include "chrome/browser/ui/browser_window.h" | 14 #include "chrome/browser/ui/browser_window.h" |
| 14 #include "content/browser/user_metrics.h" | 15 #include "content/browser/user_metrics.h" |
| 15 #include "grit/chromium_strings.h" | 16 #include "grit/chromium_strings.h" |
| 16 #include "grit/generated_resources.h" | 17 #include "grit/generated_resources.h" |
| 17 #include "grit/locale_settings.h" | 18 #include "grit/locale_settings.h" |
| 18 #include "grit/theme_resources_standard.h" | 19 #include "grit/theme_resources_standard.h" |
| 19 #include "ui/base/l10n/l10n_font_util.h" | 20 #include "ui/base/l10n/l10n_font_util.h" |
| 20 #include "ui/base/l10n/l10n_util.h" | 21 #include "ui/base/l10n/l10n_util.h" |
| 21 #include "ui/base/resource/resource_bundle.h" | 22 #include "ui/base/resource/resource_bundle.h" |
| 23 #include "views/bubble/bubble_view.h" | |
|
msw
2011/10/20 19:17:50
remove to merge with the latest bubble changes.
alicet1
2011/10/21 19:13:16
Done.
| |
| 22 #include "views/controls/button/image_button.h" | 24 #include "views/controls/button/image_button.h" |
| 23 #include "views/controls/button/text_button.h" | 25 #include "views/controls/button/text_button.h" |
| 24 #include "views/controls/label.h" | 26 #include "views/controls/label.h" |
| 25 #include "views/events/event.h" | 27 #include "views/events/event.h" |
| 26 #include "views/focus/focus_manager.h" | 28 #include "views/focus/focus_manager.h" |
| 29 #include "views/layout/fill_layout.h" | |
| 27 #include "views/layout/layout_constants.h" | 30 #include "views/layout/layout_constants.h" |
| 31 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 28 #include "views/widget/native_widget_win.h" | 32 #include "views/widget/native_widget_win.h" |
| 33 #endif | |
| 29 #include "views/widget/widget.h" | 34 #include "views/widget/widget.h" |
| 30 | 35 |
| 31 namespace { | 36 namespace { |
| 32 | 37 |
| 33 // How much extra padding to put around our content over what the Bubble | 38 // How much extra padding to put around our content over what the Bubble |
| 34 // provides. | 39 // provides. |
| 35 const int kBubblePadding = 4; | 40 const int kBubblePadding = 4; |
| 36 | 41 |
| 37 // How much extra padding to put around our content over what the Bubble | 42 // How much extra padding to put around our content over what the Bubble |
| 38 // provides in alternative OEM bubble. | 43 // provides in alternative OEM bubble. |
| 39 const int kOEMBubblePadding = 4; | 44 const int kOEMBubblePadding = 4; |
| 40 | 45 |
| 41 // Padding between parts of strings on the same line (for instance, | |
| 42 // "New!" and "Search from the address bar!" | |
| 43 const int kStringSeparationPadding = 2; | |
| 44 | |
| 45 // Margin around close button. | 46 // Margin around close button. |
| 46 const int kMarginRightOfCloseButton = 7; | 47 const int kMarginRightOfCloseButton = 7; |
| 47 | 48 |
| 48 // The bubble's HWND is actually owned by the border widget, and it's the border | |
| 49 // widget that's owned by the frame window the bubble is anchored to. This | |
| 50 // function makes the two leaps necessary to go from the bubble contents HWND | |
| 51 // to the frame HWND. | |
| 52 HWND GetLogicalBubbleOwner(HWND bubble_hwnd) { | |
| 53 HWND border_widget_hwnd = GetWindow(bubble_hwnd, GW_OWNER); | |
| 54 return GetWindow(border_widget_hwnd, GW_OWNER); | |
| 55 } | |
| 56 | |
| 57 } // namespace | 49 } // namespace |
| 58 | 50 |
| 59 // Base class for implementations of the client view which appears inside the | 51 // Base class for implementations of the client view which appears inside the |
| 60 // first run bubble. It is a dialog-ish view, but is not a true dialog. | 52 // first run bubble. It is a dialog-ish view, but is not a true dialog. |
| 61 class FirstRunBubbleViewBase : public views::View, | 53 class FirstRunBubbleViewBase : public views::View, |
|
msw
2011/10/20 19:17:50
This should be merged with FirstRunBubble (it's ex
alicet1
2011/10/21 19:13:16
I think I'll leave this like this, the three views
| |
| 62 public views::ButtonListener, | 54 public views::ButtonListener, |
| 63 public views::FocusChangeListener { | 55 public views::FocusChangeListener { |
| 64 public: | 56 public: |
| 65 // Called by FirstRunBubble::Show to request focus for the proper button | 57 // Called by FirstRunBubble::Show to request focus for the proper button |
| 66 // in the FirstRunBubbleView when it is shown. | 58 // in the FirstRunBubbleView when it is shown. |
| 67 virtual void BubbleShown() = 0; | 59 virtual void BubbleShown() = 0; |
|
msw
2011/10/20 19:17:50
remove extra space
alicet1
2011/10/21 19:13:16
Done.
| |
| 68 }; | 60 }; |
| 69 | 61 |
| 70 // FirstRunBubbleView --------------------------------------------------------- | 62 // FirstRunBubbleView --------------------------------------------------------- |
| 71 | 63 |
| 72 class FirstRunBubbleView : public FirstRunBubbleViewBase { | 64 class FirstRunBubbleView : public FirstRunBubbleViewBase { |
| 73 public: | 65 public: |
| 74 FirstRunBubbleView(FirstRunBubble* bubble_window, Profile* profile); | 66 FirstRunBubbleView(FirstRunBubble* bubble_window, Profile* profile); |
| 67 // Override from FirstRunBubbleViewBase: | |
|
msw
2011/10/20 19:17:50
Add a blank line above this comment.
alicet1
2011/10/21 19:13:16
Done.
| |
| 68 void BubbleShown(); | |
| 75 | 69 |
| 76 private: | 70 private: |
| 77 virtual ~FirstRunBubbleView() {} | 71 virtual ~FirstRunBubbleView(); |
| 78 | |
| 79 // FirstRunBubbleViewBase: | |
| 80 virtual void BubbleShown(); | |
| 81 | 72 |
| 82 // Overridden from View: | 73 // Overridden from View: |
| 83 virtual void ButtonPressed(views::Button* sender, const views::Event& event); | 74 virtual void ButtonPressed(views::Button* sender, const views::Event& event); |
| 75 virtual gfx::Size GetPreferredSize(); | |
| 84 virtual void Layout(); | 76 virtual void Layout(); |
| 85 virtual gfx::Size GetPreferredSize(); | |
| 86 | 77 |
| 87 // FocusChangeListener: | 78 // FocusChangeListener: |
| 88 virtual void FocusWillChange(View* focused_before, View* focused_now); | 79 virtual void FocusWillChange(View* focused_before, View* focused_now); |
| 89 | 80 |
| 90 FirstRunBubble* bubble_window_; | 81 FirstRunBubble* bubble_window_; |
|
msw
2011/10/20 19:17:50
bubble_window_ and profile_ are use on all three F
alicet1
2011/10/21 19:13:16
Done.
| |
| 91 views::Label* label1_; | 82 views::Label* label1_; |
| 92 views::Label* label2_; | 83 views::Label* label2_; |
| 93 views::Label* label3_; | 84 views::Label* label3_; |
| 85 views::NativeTextButton* keep_button_; | |
| 94 views::NativeTextButton* change_button_; | 86 views::NativeTextButton* change_button_; |
| 95 views::NativeTextButton* keep_button_; | |
| 96 Profile* profile_; | 87 Profile* profile_; |
| 97 | 88 |
| 98 DISALLOW_COPY_AND_ASSIGN(FirstRunBubbleView); | 89 DISALLOW_COPY_AND_ASSIGN(FirstRunBubbleView); |
| 99 }; | 90 }; |
| 100 | 91 |
| 101 FirstRunBubbleView::FirstRunBubbleView(FirstRunBubble* bubble_window, | 92 FirstRunBubbleView::FirstRunBubbleView(FirstRunBubble* bubble_window, |
| 102 Profile* profile) | 93 Profile* profile) |
| 103 : bubble_window_(bubble_window), | 94 : bubble_window_(bubble_window), |
| 104 label1_(NULL), | 95 label1_(NULL), |
| 105 label2_(NULL), | 96 label2_(NULL), |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 130 IDS_FR_BUBBLE_QUESTION, | 121 IDS_FR_BUBBLE_QUESTION, |
| 131 GetDefaultSearchEngineName(profile)); | 122 GetDefaultSearchEngineName(profile)); |
| 132 label3_ = new views::Label(question_str); | 123 label3_ = new views::Label(question_str); |
| 133 label3_->SetMultiLine(true); | 124 label3_->SetMultiLine(true); |
| 134 label3_->SetFont(font); | 125 label3_->SetFont(font); |
| 135 label3_->SetBackgroundColor(Bubble::kBackgroundColor); | 126 label3_->SetBackgroundColor(Bubble::kBackgroundColor); |
| 136 label3_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 127 label3_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| 137 label3_->SizeToFit(ps.width() - kBubblePadding * 2); | 128 label3_->SizeToFit(ps.width() - kBubblePadding * 2); |
| 138 AddChildView(label3_); | 129 AddChildView(label3_); |
| 139 | 130 |
| 140 std::wstring keep_str = UTF16ToWide(l10n_util::GetStringFUTF16( | 131 string16 keep_str = l10n_util::GetStringFUTF16( |
| 141 IDS_FR_BUBBLE_OK, | 132 IDS_FR_BUBBLE_OK, |
| 142 GetDefaultSearchEngineName(profile))); | 133 GetDefaultSearchEngineName(profile)); |
| 143 keep_button_ = new views::NativeTextButton(this, keep_str); | 134 keep_button_ = new views::NativeTextButton(this, keep_str); |
| 144 keep_button_->SetIsDefault(true); | 135 keep_button_->SetIsDefault(true); |
| 145 AddChildView(keep_button_); | 136 AddChildView(keep_button_); |
| 146 | 137 |
| 147 std::wstring change_str = | 138 string16 change_str = l10n_util::GetStringUTF16(IDS_FR_BUBBLE_CHANGE); |
| 148 UTF16ToWide(l10n_util::GetStringUTF16(IDS_FR_BUBBLE_CHANGE)); | |
| 149 change_button_ = new views::NativeTextButton(this, change_str); | 139 change_button_ = new views::NativeTextButton(this, change_str); |
| 150 AddChildView(change_button_); | 140 AddChildView(change_button_); |
| 151 } | 141 } |
| 152 | 142 |
| 153 void FirstRunBubbleView::BubbleShown() { | 143 FirstRunBubbleView::~FirstRunBubbleView() { |
| 154 keep_button_->RequestFocus(); | 144 GetFocusManager()->RemoveFocusChangeListener(this); |
|
msw
2011/10/20 19:17:50
This belongs in ~FirstRunBubbleViewBase.
alicet1
2011/10/21 19:13:16
Done.
| |
| 155 } | 145 } |
| 156 | 146 |
| 157 void FirstRunBubbleView::ButtonPressed(views::Button* sender, | 147 void FirstRunBubbleView::ButtonPressed(views::Button* sender, |
| 158 const views::Event& event) { | 148 const views::Event& event) { |
| 159 UserMetrics::RecordAction(UserMetricsAction("FirstRunBubbleView_Clicked")); | 149 UserMetrics::RecordAction(UserMetricsAction("FirstRunBubbleView_Clicked")); |
| 160 bubble_window_->set_fade_away_on_close(true); | 150 // Fades out. |
| 161 bubble_window_->Close(); | 151 GetWidget()->client_view()->AsBubbleView()->StartFade(false); |
|
msw
2011/10/20 19:17:50
You can just call StartFade on a BubbleDelegateVie
alicet1
2011/10/21 19:13:16
Done.
| |
| 162 if (change_button_ == sender) { | 152 if (change_button_ == sender) { |
| 163 UserMetrics::RecordAction( | 153 UserMetrics::RecordAction( |
| 164 UserMetricsAction("FirstRunBubbleView_ChangeButton")); | 154 UserMetricsAction("FirstRunBubbleView_ChangeButton")); |
| 165 | 155 |
| 166 Browser* browser = BrowserList::GetLastActiveWithProfile(profile_); | 156 Browser* browser = BrowserList::GetLastActiveWithProfile(profile_); |
| 167 if (browser) { | 157 if (browser) { |
| 168 browser->OpenSearchEngineOptionsDialog(); | 158 browser->OpenSearchEngineOptionsDialog(); |
| 169 } | 159 } |
| 170 } | 160 } |
| 161 GetWidget()->Close(); | |
| 162 } | |
| 163 | |
| 164 void FirstRunBubbleView::BubbleShown() { | |
| 165 keep_button_->RequestFocus(); | |
|
msw
2011/10/20 19:17:50
Couldn't this be accomplished by overriding GetIni
alicet1
2011/10/21 19:13:16
if this is a delegate, then it would have GetIniti
| |
| 171 } | 166 } |
| 172 | 167 |
| 173 void FirstRunBubbleView::Layout() { | 168 void FirstRunBubbleView::Layout() { |
| 174 gfx::Size canvas = GetPreferredSize(); | 169 gfx::Size canvas = GetPreferredSize(); |
| 175 | 170 |
| 176 // The multiline business that follows is dirty hacks to get around | 171 // The multiline business that follows is dirty hacks to get around |
| 177 // bug 1325257. | 172 // bug 1325257. |
| 178 label1_->SetMultiLine(false); | 173 label1_->SetMultiLine(false); |
| 179 gfx::Size pref_size = label1_->GetPreferredSize(); | 174 gfx::Size pref_size = label1_->GetPreferredSize(); |
| 180 label1_->SetMultiLine(true); | 175 label1_->SetMultiLine(true); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 234 after->SetIsDefault(true); | 229 after->SetIsDefault(true); |
| 235 } | 230 } |
| 236 } | 231 } |
| 237 | 232 |
| 238 // FirstRunOEMBubbleView ------------------------------------------------------ | 233 // FirstRunOEMBubbleView ------------------------------------------------------ |
| 239 | 234 |
| 240 class FirstRunOEMBubbleView : public FirstRunBubbleViewBase { | 235 class FirstRunOEMBubbleView : public FirstRunBubbleViewBase { |
| 241 public: | 236 public: |
| 242 FirstRunOEMBubbleView(FirstRunBubble* bubble_window, Profile* profile); | 237 FirstRunOEMBubbleView(FirstRunBubble* bubble_window, Profile* profile); |
| 243 | 238 |
| 239 // Override from FirstRunBubbleViewBase: | |
| 240 void BubbleShown(); | |
| 244 private: | 241 private: |
|
msw
2011/10/20 19:17:50
add a blank line above private.
alicet1
2011/10/21 19:13:16
Done.
| |
| 245 virtual ~FirstRunOEMBubbleView() { } | 242 virtual ~FirstRunOEMBubbleView(); |
| 246 | |
| 247 // FirstRunBubbleViewBase: | |
| 248 virtual void BubbleShown(); | |
| 249 | 243 |
| 250 // Overridden from View: | 244 // Overridden from View: |
| 251 virtual void ButtonPressed(views::Button* sender, const views::Event& event); | 245 virtual void ButtonPressed(views::Button* sender, const views::Event& event); |
| 246 virtual gfx::Size GetPreferredSize(); | |
| 252 virtual void Layout(); | 247 virtual void Layout(); |
| 253 virtual gfx::Size GetPreferredSize(); | |
| 254 | 248 |
| 255 // FocusChangeListener: | 249 // FocusChangeListener: |
| 256 virtual void FocusWillChange(View* focused_before, View* focused_now); | 250 virtual void FocusWillChange(View* focused_before, View* focused_now); |
| 257 | 251 |
| 258 FirstRunBubble* bubble_window_; | 252 FirstRunBubble* bubble_window_; |
| 259 views::Label* label1_; | 253 views::Label* label1_; |
| 260 views::Label* label2_; | 254 views::Label* label2_; |
| 261 views::Label* label3_; | 255 views::Label* label3_; |
| 262 views::ImageButton* close_button_; | 256 views::ImageButton* close_button_; |
| 263 Profile* profile_; | 257 Profile* profile_; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 308 close_button_->SetImage(views::CustomButton::BS_HOT, | 302 close_button_->SetImage(views::CustomButton::BS_HOT, |
| 309 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); | 303 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); |
| 310 close_button_->SetImage(views::CustomButton::BS_PUSHED, | 304 close_button_->SetImage(views::CustomButton::BS_PUSHED, |
| 311 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); | 305 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); |
| 312 | 306 |
| 313 AddChildView(close_button_); | 307 AddChildView(close_button_); |
| 314 } | 308 } |
| 315 | 309 |
| 316 void FirstRunOEMBubbleView::BubbleShown() { | 310 void FirstRunOEMBubbleView::BubbleShown() { |
| 317 RequestFocus(); | 311 RequestFocus(); |
| 318 // No button in oem_bubble to request focus. | 312 } |
| 313 | |
| 314 FirstRunOEMBubbleView::~FirstRunOEMBubbleView() { | |
| 315 GetFocusManager()->RemoveFocusChangeListener(this); | |
|
msw
2011/10/20 19:17:50
Ditto, this belongs in ~FirstRunBubbleViewBase.
alicet1
2011/10/21 19:13:16
Done.
| |
| 319 } | 316 } |
| 320 | 317 |
| 321 void FirstRunOEMBubbleView::ButtonPressed(views::Button* sender, | 318 void FirstRunOEMBubbleView::ButtonPressed(views::Button* sender, |
| 322 const views::Event& event) { | 319 const views::Event& event) { |
| 323 UserMetrics::RecordAction( | 320 UserMetrics::RecordAction( |
| 324 UserMetricsAction("FirstRunOEMBubbleView_Clicked")); | 321 UserMetricsAction("FirstRunOEMBubbleView_Clicked")); |
| 325 bubble_window_->set_fade_away_on_close(true); | 322 GetWidget()->client_view()->AsBubbleView()->StartFade(/*fade_in=*/false); |
|
msw
2011/10/20 19:17:50
Ditto on BubbleDelegateView::StartFade comment, al
alicet1
2011/10/21 19:13:16
Done.
| |
| 326 bubble_window_->Close(); | 323 GetWidget()->Close(); |
| 327 } | 324 } |
| 328 | 325 |
| 329 void FirstRunOEMBubbleView::Layout() { | 326 void FirstRunOEMBubbleView::Layout() { |
| 330 gfx::Size canvas = GetPreferredSize(); | 327 gfx::Size canvas = GetPreferredSize(); |
| 331 | 328 |
| 332 // First, draw the close button on the far right. | 329 // First, draw the close button on the far right. |
| 333 gfx::Size sz = close_button_->GetPreferredSize(); | 330 gfx::Size sz = close_button_->GetPreferredSize(); |
| 334 close_button_->SetBounds( | 331 close_button_->SetBounds( |
| 335 canvas.width() - sz.width() - kMarginRightOfCloseButton, | 332 canvas.width() - sz.width() - kMarginRightOfCloseButton, |
| 336 kOEMBubblePadding, sz.width(), sz.height()); | 333 kOEMBubblePadding, sz.width(), sz.height()); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 359 gfx::Size FirstRunOEMBubbleView::GetPreferredSize() { | 356 gfx::Size FirstRunOEMBubbleView::GetPreferredSize() { |
| 360 // Calculate width based on font and text. | 357 // Calculate width based on font and text. |
| 361 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 358 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 362 const gfx::Font& font = rb.GetFont( | 359 const gfx::Font& font = rb.GetFont( |
| 363 ResourceBundle::MediumFont).DeriveFont(3, gfx::Font::BOLD); | 360 ResourceBundle::MediumFont).DeriveFont(3, gfx::Font::BOLD); |
| 364 gfx::Size size = gfx::Size( | 361 gfx::Size size = gfx::Size( |
| 365 ui::GetLocalizedContentsWidthForFont( | 362 ui::GetLocalizedContentsWidthForFont( |
| 366 IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS, font), | 363 IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS, font), |
| 367 ui::GetLocalizedContentsHeightForFont( | 364 ui::GetLocalizedContentsHeightForFont( |
| 368 IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES, font)); | 365 IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES, font)); |
| 369 | 366 #if defined(OS_WIN) && !defined(USE_AURA) |
| 370 // WARNING: HACK. Vista and XP calculate font size differently; this means | 367 // WARNING: HACK. Vista and XP calculate font size differently; this means |
| 371 // that a dialog box correctly proportioned for XP will appear too large in | 368 // that a dialog box correctly proportioned for XP will appear too large in |
| 372 // Vista. The correct thing to do is to change font size calculations in | 369 // Vista. The correct thing to do is to change font size calculations in |
| 373 // XP or Vista so that the length of a string is calculated properly. For | 370 // XP or Vista so that the length of a string is calculated properly. For |
| 374 // now, we force Vista to show a correctly-sized box by taking account of | 371 // now, we force Vista to show a correctly-sized box by taking account of |
| 375 // the difference in font size calculation. The coefficient should not be | 372 // the difference in font size calculation. The coefficient should not be |
| 376 // stored in a variable because it's a hack and should go away. | 373 // stored in a variable because it's a hack and should go away. |
|
msw
2011/10/20 19:17:50
cry :( even if this comment is [still] true, switc
alicet1
2011/10/21 19:13:16
I can probably believe this is still true.
| |
| 377 if (views::NativeWidgetWin::IsAeroGlassEnabled()) { | 374 if (views::NativeWidgetWin::IsAeroGlassEnabled()) { |
| 378 size.set_width(static_cast<int>(size.width() * 0.85)); | 375 size.set_width(static_cast<int>(size.width() * 0.85)); |
| 379 size.set_height(static_cast<int>(size.height() * 0.85)); | 376 size.set_height(static_cast<int>(size.height() * 0.85)); |
| 380 } | 377 } |
| 378 #endif | |
| 381 return size; | 379 return size; |
| 382 } | 380 } |
| 383 | 381 |
| 384 void FirstRunOEMBubbleView::FocusWillChange(View* focused_before, | 382 void FirstRunOEMBubbleView::FocusWillChange(View* focused_before, |
| 385 View* focused_now) { | 383 View* focused_now) { |
| 386 // No buttons in oem_bubble to register focus changes. | 384 // No buttons in oem_bubble to register focus changes. |
| 387 } | 385 } |
| 388 | 386 |
| 389 // FirstRunMinimalBubbleView -------------------------------------------------- | 387 // FirstRunMinimalBubbleView -------------------------------------------------- |
| 390 // TODO(mirandac): combine FRBubbles more elegantly. http://crbug.com/41353 | 388 // TODO(mirandac): combine FRBubbles more elegantly. http://crbug.com/41353 |
| 391 | 389 |
| 392 class FirstRunMinimalBubbleView : public FirstRunBubbleViewBase { | 390 class FirstRunMinimalBubbleView : public FirstRunBubbleViewBase { |
| 393 public: | 391 public: |
| 394 FirstRunMinimalBubbleView(FirstRunBubble* bubble_window, Profile* profile); | 392 FirstRunMinimalBubbleView(FirstRunBubble* bubble_window, Profile* profile); |
| 395 | 393 |
| 394 // Override from FirstRunBubbleViewBase: | |
|
msw
2011/10/20 19:17:50
Can you go through and make sure all the override
alicet1
2011/10/21 19:13:16
Done.
| |
| 395 void BubbleShown(); | |
| 396 | |
| 396 private: | 397 private: |
| 397 virtual ~FirstRunMinimalBubbleView() { } | 398 virtual ~FirstRunMinimalBubbleView(); |
| 398 | |
| 399 // FirstRunBubbleViewBase: | |
| 400 virtual void BubbleShown(); | |
| 401 | 399 |
| 402 // Overridden from View: | 400 // Overridden from View: |
| 403 virtual void ButtonPressed(views::Button* sender, | 401 virtual void ButtonPressed(views::Button* sender, |
| 404 const views::Event& event) { } | 402 const views::Event& event) { } |
| 403 virtual gfx::Size GetPreferredSize(); | |
| 405 virtual void Layout(); | 404 virtual void Layout(); |
| 406 virtual gfx::Size GetPreferredSize(); | |
| 407 | 405 |
| 408 // FocusChangeListener: | 406 // FocusChangeListener: |
| 409 virtual void FocusWillChange(View* focused_before, View* focused_now); | 407 virtual void FocusWillChange(View* focused_before, View* focused_now); |
| 410 | 408 |
| 411 FirstRunBubble* bubble_window_; | 409 FirstRunBubble* bubble_window_; |
| 412 Profile* profile_; | 410 Profile* profile_; |
| 413 views::Label* label1_; | 411 views::Label* label1_; |
| 414 views::Label* label2_; | 412 views::Label* label2_; |
| 415 | 413 |
| 416 DISALLOW_COPY_AND_ASSIGN(FirstRunMinimalBubbleView); | 414 DISALLOW_COPY_AND_ASSIGN(FirstRunMinimalBubbleView); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 439 label2_ = new views::Label( | 437 label2_ = new views::Label( |
| 440 l10n_util::GetStringUTF16(IDS_FR_BUBBLE_SUBTEXT)); | 438 l10n_util::GetStringUTF16(IDS_FR_BUBBLE_SUBTEXT)); |
| 441 label2_->SetMultiLine(true); | 439 label2_->SetMultiLine(true); |
| 442 label2_->SetFont(font); | 440 label2_->SetFont(font); |
| 443 label2_->SetBackgroundColor(Bubble::kBackgroundColor); | 441 label2_->SetBackgroundColor(Bubble::kBackgroundColor); |
| 444 label2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 442 label2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| 445 label2_->SizeToFit(ps.width() - kBubblePadding * 2); | 443 label2_->SizeToFit(ps.width() - kBubblePadding * 2); |
| 446 AddChildView(label2_); | 444 AddChildView(label2_); |
| 447 } | 445 } |
| 448 | 446 |
| 447 FirstRunMinimalBubbleView::~FirstRunMinimalBubbleView() { | |
| 448 GetFocusManager()->RemoveFocusChangeListener(this); | |
|
msw
2011/10/20 19:17:50
Ditto, this belongs in ~FirstRunBubbleViewBase.
alicet1
2011/10/21 19:13:16
Done.
| |
| 449 } | |
| 450 | |
| 449 void FirstRunMinimalBubbleView::BubbleShown() { | 451 void FirstRunMinimalBubbleView::BubbleShown() { |
| 450 RequestFocus(); | 452 RequestFocus(); |
| 451 } | 453 } |
| 452 | 454 |
| 453 void FirstRunMinimalBubbleView::Layout() { | 455 void FirstRunMinimalBubbleView::Layout() { |
| 454 gfx::Size canvas = GetPreferredSize(); | 456 gfx::Size canvas = GetPreferredSize(); |
| 455 | 457 |
| 456 // See comments in FirstRunOEMBubbleView::Layout explaining this hack. | 458 // See comments in FirstRunOEMBubbleView::Layout explaining this hack. |
| 457 label1_->SetMultiLine(false); | 459 label1_->SetMultiLine(false); |
| 458 gfx::Size pref_size = label1_->GetPreferredSize(); | 460 gfx::Size pref_size = label1_->GetPreferredSize(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 479 | 481 |
| 480 void FirstRunMinimalBubbleView::FocusWillChange(View* focused_before, | 482 void FirstRunMinimalBubbleView::FocusWillChange(View* focused_before, |
| 481 View* focused_now) { | 483 View* focused_now) { |
| 482 // No buttons in minimal bubble to register focus changes. | 484 // No buttons in minimal bubble to register focus changes. |
| 483 } | 485 } |
| 484 | 486 |
| 485 | 487 |
| 486 // FirstRunBubble ------------------------------------------------------------- | 488 // FirstRunBubble ------------------------------------------------------------- |
| 487 | 489 |
| 488 // static | 490 // static |
| 489 FirstRunBubble* FirstRunBubble::Show( | 491 views::Widget* FirstRunBubble::Show( |
| 490 Profile* profile, | 492 Profile* profile, |
| 491 views::Widget* parent, | 493 views::Widget* parent, |
| 492 const gfx::Rect& position_relative_to, | 494 const gfx::Rect& position_relative_to, |
| 493 views::BubbleBorder::ArrowLocation arrow_location, | 495 views::BubbleBorder::ArrowLocation arrow_location, |
| 494 FirstRun::BubbleType bubble_type) { | 496 FirstRun::BubbleType bubble_type) { |
| 495 FirstRunBubble* bubble = new FirstRunBubble(); | 497 FirstRunBubble* delegate = |
| 498 new FirstRunBubble(profile, | |
| 499 parent, | |
| 500 position_relative_to, | |
| 501 arrow_location, | |
| 502 bubble_type); | |
| 503 views::Widget* widget = | |
| 504 views::BubbleDelegateView::CreateBubble(delegate, parent); | |
| 505 // StartFade and show. | |
| 506 widget->client_view()->AsBubbleView()->StartFade(/*fade_in=*/true); | |
|
msw
2011/10/20 19:17:50
Ditto on BubbleDelegateView::StartFade comment, al
alicet1
2011/10/21 19:13:16
Done.
| |
| 507 return widget; | |
| 508 } | |
| 509 | |
| 510 void FirstRunBubble::Init() { | |
| 511 SetLayoutManager(new views::FillLayout()); | |
| 496 FirstRunBubbleViewBase* view = NULL; | 512 FirstRunBubbleViewBase* view = NULL; |
| 497 | 513 switch (bubble_type_) { |
| 498 switch (bubble_type) { | |
| 499 case FirstRun::OEM_BUBBLE: | 514 case FirstRun::OEM_BUBBLE: |
| 500 view = new FirstRunOEMBubbleView(bubble, profile); | 515 view = new FirstRunOEMBubbleView(this, profile_); |
| 501 break; | 516 break; |
| 502 case FirstRun::LARGE_BUBBLE: | 517 case FirstRun::LARGE_BUBBLE: |
| 503 view = new FirstRunBubbleView(bubble, profile); | 518 view = new FirstRunBubbleView(this, profile_); |
| 504 break; | 519 break; |
| 505 case FirstRun::MINIMAL_BUBBLE: | 520 case FirstRun::MINIMAL_BUBBLE: |
| 506 view = new FirstRunMinimalBubbleView(bubble, profile); | 521 view = new FirstRunMinimalBubbleView(this, profile_); |
| 507 break; | 522 break; |
| 508 default: | 523 default: |
| 509 NOTREACHED(); | 524 NOTREACHED(); |
| 510 } | 525 } |
| 511 bubble->set_view(view); | 526 AddChildView(view); |
| 512 bubble->InitBubble( | 527 parent_->GetFocusManager()->AddFocusChangeListener(view); |
|
msw
2011/10/20 19:17:50
I think you can just call GetFocusManager on this
alicet1
2011/10/21 19:13:16
Init() is called before we have a widget for this
| |
| 513 parent, position_relative_to, arrow_location, view, bubble); | |
| 514 bubble->GetWidget()->GetFocusManager()->AddFocusChangeListener(view); | |
| 515 view->BubbleShown(); | 528 view->BubbleShown(); |
| 516 return bubble; | |
| 517 } | 529 } |
| 518 | 530 |
| 519 FirstRunBubble::FirstRunBubble() | 531 FirstRunBubble::FirstRunBubble( |
| 520 : has_been_activated_(false), | 532 Profile* profile, |
| 521 ALLOW_THIS_IN_INITIALIZER_LIST(enable_window_method_factory_(this)), | 533 views::Widget* parent, |
| 522 view_(NULL) { | 534 const gfx::Rect& position_relative_to, |
| 535 views::BubbleBorder::ArrowLocation arrow_location, | |
| 536 FirstRun::BubbleType bubble_type) | |
| 537 : profile_(profile), | |
|
msw
2011/10/20 19:17:50
You can use the new BubbleDelegateView ctor here t
alicet1
2011/10/21 19:13:16
Done.
| |
| 538 parent_(parent), | |
| 539 position_relative_to_(position_relative_to), | |
| 540 arrow_location_(arrow_location), | |
| 541 bubble_type_(bubble_type), | |
| 542 has_been_activated_(false), | |
| 543 ALLOW_THIS_IN_INITIALIZER_LIST(enable_window_method_factory_(this)) { | |
| 523 } | 544 } |
| 524 | 545 |
| 525 FirstRunBubble::~FirstRunBubble() { | 546 FirstRunBubble::~FirstRunBubble() { |
| 526 enable_window_method_factory_.InvalidateWeakPtrs(); | 547 enable_window_method_factory_.InvalidateWeakPtrs(); |
| 527 GetWidget()->GetFocusManager()->RemoveFocusChangeListener(view_); | |
| 528 } | 548 } |
| 529 | 549 |
| 550 gfx::Point FirstRunBubble::GetAnchorPoint() const { | |
| 551 return position_relative_to_.origin(); | |
| 552 } | |
| 553 | |
| 554 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 530 void FirstRunBubble::EnableParent() { | 555 void FirstRunBubble::EnableParent() { |
| 531 ::EnableWindow(GetParent(), true); | 556 ::EnableWindow(GetParent(), true); |
| 532 // The EnableWindow() call above causes the parent to become active, which | 557 // The EnableWindow() call above causes the parent to become active, which |
| 533 // resets the flag set by Bubble's call to DisableInactiveRendering(), so we | 558 // resets the flag set by Bubble's call to DisableInactiveRendering(), so we |
| 534 // have to call it again before activating the bubble to prevent the parent | 559 // have to call it again before activating the bubble to prevent the parent |
| 535 // window from rendering inactive. | 560 // window from rendering inactive. |
| 536 // TODO(beng): this only works in custom-frame mode, not glass-frame mode. | 561 // TODO(beng): this only works in custom-frame mode, not glass-frame mode. |
| 537 HWND bubble_owner = GetLogicalBubbleOwner(GetNativeView()); | 562 if (parent_) |
| 538 views::Widget* parent = views::Widget::GetWidgetForNativeView(bubble_owner); | 563 parent_->DisableInactiveRendering(); |
| 539 if (parent) | |
| 540 parent->DisableInactiveRendering(); | |
| 541 // Reactivate the FirstRunBubble so it responds to OnActivate messages. | 564 // Reactivate the FirstRunBubble so it responds to OnActivate messages. |
| 542 SetWindowPos(GetParent(), 0, 0, 0, 0, | 565 SetWindowPos(GetParent(), 0, 0, 0, 0, |
| 543 SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_SHOWWINDOW); | 566 SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_SHOWWINDOW); |
| 544 } | 567 } |
| 545 | 568 |
| 546 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 547 void FirstRunBubble::OnActivate(UINT action, BOOL minimized, HWND window) { | 569 void FirstRunBubble::OnActivate(UINT action, BOOL minimized, HWND window) { |
| 548 // Keep the bubble around for kLingerTime milliseconds, to prevent accidental | 570 // Keep the bubble around for kLingerTime milliseconds, to prevent accidental |
| 549 // closure. | 571 // closure. |
| 550 const int kLingerTime = 3000; | 572 const int kLingerTime = 3000; |
| 551 | 573 |
| 552 // We might get re-enabled right before we are closed (sequence is: we get | 574 // We might get re-enabled right before we are closed (sequence is: we get |
| 553 // deactivated, we call close, before we are actually closed we get | 575 // deactivated, we call close, before we are actually closed we get |
| 554 // reactivated). Don't do the disabling of the parent in such cases. | 576 // reactivated). Don't do the disabling of the parent in such cases. |
| 555 if (action == WA_ACTIVE && !has_been_activated_) { | 577 if (action == WA_ACTIVE && !has_been_activated_) { |
| 556 has_been_activated_ = true; | 578 has_been_activated_ = true; |
| 557 | 579 |
| 558 ::EnableWindow(GetParent(), false); | 580 ::EnableWindow(GetParent(), false); |
| 559 | 581 |
| 560 MessageLoop::current()->PostDelayedTask( | 582 MessageLoop::current()->PostDelayedTask( |
| 561 FROM_HERE, | 583 FROM_HERE, |
| 562 base::Bind(&FirstRunBubble::EnableParent, | 584 base::Bind(&FirstRunBubble::EnableParent, |
| 563 enable_window_method_factory_.GetWeakPtr()), | 585 enable_window_method_factory_.GetWeakPtr()), |
| 564 kLingerTime); | 586 kLingerTime); |
| 565 return; | 587 return; |
| 566 } | 588 } |
| 567 | 589 |
| 568 // Keep window from automatically closing until kLingerTime has passed. | 590 // Keep window from automatically closing until kLingerTime has passed. |
| 569 if (::IsWindowEnabled(GetParent())) | 591 if (::IsWindowEnabled(GetParent())) |
| 570 Bubble::OnActivate(action, minimized, window); | 592 Bubble::OnActivate(action, minimized, window); |
| 571 } | 593 } |
| 572 #endif | 594 #endif |
| 573 | 595 |
| 574 void FirstRunBubble::BubbleClosing(Bubble* bubble, bool closed_by_escape) { | 596 void FirstRunBubble::WindowClosing() { |
| 575 // Make sure our parent window is re-enabled. | 597 // Make sure our parent window is re-enabled. |
| 576 if (!IsWindowEnabled(GetParent())) | 598 parent_->GetRootView()->SetEnabled(true); |
|
msw
2011/10/20 19:17:50
I don't think this is right... perhaps try the Foc
alicet1
2011/10/21 19:13:16
I'm not sure why we need to explicitly enable/set
| |
| 577 ::EnableWindow(GetParent(), true); | |
| 578 } | 599 } |
| OLD | NEW |