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/first_run/first_run.h" | 9 #include "chrome/browser/first_run/first_run.h" |
10 #include "chrome/browser/search_engines/util.h" | 10 #include "chrome/browser/search_engines/util.h" |
11 #include "chrome/browser/ui/browser.h" | 11 #include "chrome/browser/ui/browser.h" |
12 #include "chrome/browser/ui/browser_list.h" | 12 #include "chrome/browser/ui/browser_list.h" |
13 #include "chrome/browser/ui/browser_window.h" | 13 #include "chrome/browser/ui/browser_window.h" |
14 #include "content/browser/user_metrics.h" | 14 #include "content/browser/user_metrics.h" |
15 #include "grit/chromium_strings.h" | 15 #include "grit/chromium_strings.h" |
16 #include "grit/generated_resources.h" | 16 #include "grit/generated_resources.h" |
17 #include "grit/locale_settings.h" | 17 #include "grit/locale_settings.h" |
18 #include "grit/theme_resources_standard.h" | 18 #include "grit/theme_resources_standard.h" |
19 #include "ui/base/l10n/l10n_font_util.h" | 19 #include "ui/base/l10n/l10n_font_util.h" |
20 #include "ui/base/l10n/l10n_util.h" | 20 #include "ui/base/l10n/l10n_util.h" |
21 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
22 #include "views/controls/button/image_button.h" | 22 #include "views/controls/button/image_button.h" |
23 #include "views/controls/button/text_button.h" | 23 #include "views/controls/button/text_button.h" |
24 #include "views/controls/label.h" | 24 #include "views/controls/label.h" |
25 #include "views/events/event.h" | 25 #include "views/events/event.h" |
26 #include "views/focus/focus_manager.h" | 26 #include "views/focus/focus_manager.h" |
27 #include "views/layout/fill_layout.h" | |
27 #include "views/layout/layout_constants.h" | 28 #include "views/layout/layout_constants.h" |
29 #if defined(OS_WIN) && !defined(USE_AURA) | |
28 #include "views/widget/native_widget_win.h" | 30 #include "views/widget/native_widget_win.h" |
31 #endif | |
29 #include "views/widget/widget.h" | 32 #include "views/widget/widget.h" |
30 | 33 |
31 namespace { | 34 namespace { |
32 | 35 |
33 // How much extra padding to put around our content over what the Bubble | 36 // How much extra padding to put around our content over what the Bubble |
34 // provides. | 37 // provides. |
35 const int kBubblePadding = 4; | 38 const int kBubblePadding = 4; |
36 | 39 |
37 // How much extra padding to put around our content over what the Bubble | 40 // How much extra padding to put around our content over what the Bubble |
38 // provides in alternative OEM bubble. | 41 // provides in alternative OEM bubble. |
39 const int kOEMBubblePadding = 4; | 42 const int kOEMBubblePadding = 4; |
40 | 43 |
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. | 44 // Margin around close button. |
46 const int kMarginRightOfCloseButton = 7; | 45 const int kMarginRightOfCloseButton = 7; |
47 | 46 |
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 | 47 } // namespace |
58 | 48 |
59 // Base class for implementations of the client view which appears inside the | 49 // 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. | 50 // first run bubble. It is a dialog-ish view, but is not a true dialog. |
61 class FirstRunBubbleViewBase : public views::View, | 51 class FirstRunBubbleViewBase : public views::View, |
62 public views::ButtonListener, | 52 public views::ButtonListener, |
63 public views::FocusChangeListener { | 53 public views::FocusChangeListener { |
64 public: | 54 public: |
65 // Called by FirstRunBubble::Show to request focus for the proper button | 55 // Called by FirstRunBubble::Show to request focus for the proper button |
66 // in the FirstRunBubbleView when it is shown. | 56 // in the FirstRunBubbleView when it is shown. |
67 virtual void BubbleShown() = 0; | 57 virtual void BubbleShown() = 0; |
58 | |
59 protected: | |
60 FirstRunBubbleViewBase(FirstRunBubble* bubble_window, Profile* profile); | |
61 virtual ~FirstRunBubbleViewBase(); | |
62 FirstRunBubble* bubble_window() { return bubble_window_; } | |
63 Profile* profile() { return profile_; } | |
64 | |
65 private: | |
66 FirstRunBubble* bubble_window_; | |
67 Profile* profile_; | |
68 DISALLOW_COPY_AND_ASSIGN(FirstRunBubbleViewBase); | |
68 }; | 69 }; |
69 | 70 |
71 FirstRunBubbleViewBase::FirstRunBubbleViewBase(FirstRunBubble* bubble_window, | |
72 Profile* profile) | |
msw
2011/10/29 02:55:11
Fix this indenting.
alicet1
2011/11/02 06:51:25
Done.
| |
73 : bubble_window_(bubble_window), profile_(profile) {} | |
74 | |
75 FirstRunBubbleViewBase::~FirstRunBubbleViewBase() { | |
76 GetFocusManager()->RemoveFocusChangeListener(this); | |
77 } | |
78 | |
70 // FirstRunBubbleView --------------------------------------------------------- | 79 // FirstRunBubbleView --------------------------------------------------------- |
71 | |
msw
2011/10/29 02:55:11
Replace this blank line.
alicet1
2011/11/02 06:51:25
Done.
| |
72 class FirstRunBubbleView : public FirstRunBubbleViewBase { | 80 class FirstRunBubbleView : public FirstRunBubbleViewBase { |
73 public: | 81 public: |
74 FirstRunBubbleView(FirstRunBubble* bubble_window, Profile* profile); | 82 FirstRunBubbleView(FirstRunBubble* bubble_window, Profile* profile); |
75 | 83 |
84 // Override from FirstRunBubbleViewBase: | |
85 void BubbleShown(); | |
msw
2011/10/29 02:55:11
Please use the OVERRIDE keyword for this and other
alicet1
2011/11/02 06:51:25
removed.
| |
86 | |
76 private: | 87 private: |
77 virtual ~FirstRunBubbleView() {} | 88 virtual ~FirstRunBubbleView() {} |
78 | 89 |
79 // FirstRunBubbleViewBase: | 90 // Override from View: |
80 virtual void BubbleShown(); | 91 virtual void ButtonPressed(views::Button* sender, const views::Event& event); |
92 virtual gfx::Size GetPreferredSize(); | |
93 virtual void Layout(); | |
81 | 94 |
82 // Overridden from View: | 95 // Override from FocusChangeListener: |
83 virtual void ButtonPressed(views::Button* sender, const views::Event& event); | |
84 virtual void Layout(); | |
85 virtual gfx::Size GetPreferredSize(); | |
86 | |
87 // FocusChangeListener: | |
88 virtual void FocusWillChange(View* focused_before, View* focused_now); | 96 virtual void FocusWillChange(View* focused_before, View* focused_now); |
89 | 97 |
90 FirstRunBubble* bubble_window_; | |
91 views::Label* label1_; | 98 views::Label* label1_; |
92 views::Label* label2_; | 99 views::Label* label2_; |
93 views::Label* label3_; | 100 views::Label* label3_; |
101 views::NativeTextButton* keep_button_; | |
94 views::NativeTextButton* change_button_; | 102 views::NativeTextButton* change_button_; |
95 views::NativeTextButton* keep_button_; | |
96 Profile* profile_; | |
97 | 103 |
98 DISALLOW_COPY_AND_ASSIGN(FirstRunBubbleView); | 104 DISALLOW_COPY_AND_ASSIGN(FirstRunBubbleView); |
99 }; | 105 }; |
100 | 106 |
101 FirstRunBubbleView::FirstRunBubbleView(FirstRunBubble* bubble_window, | 107 FirstRunBubbleView::FirstRunBubbleView(FirstRunBubble* bubble_window, |
102 Profile* profile) | 108 Profile* profile) |
103 : bubble_window_(bubble_window), | 109 : FirstRunBubbleViewBase(bubble_window, profile), |
104 label1_(NULL), | 110 label1_(NULL), |
105 label2_(NULL), | 111 label2_(NULL), |
106 label3_(NULL), | 112 label3_(NULL), |
107 keep_button_(NULL), | 113 keep_button_(NULL), |
108 change_button_(NULL), | 114 change_button_(NULL) { |
109 profile_(profile) { | |
110 const gfx::Font& font = | 115 const gfx::Font& font = |
111 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont); | 116 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont); |
112 | 117 |
113 label1_ = new views::Label(l10n_util::GetStringUTF16(IDS_FR_BUBBLE_TITLE)); | 118 label1_ = new views::Label(l10n_util::GetStringUTF16(IDS_FR_BUBBLE_TITLE)); |
114 label1_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); | 119 label1_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); |
115 label1_->SetBackgroundColor(Bubble::kBackgroundColor); | 120 label1_->SetBackgroundColor(SK_ColorWHITE); |
msw
2011/10/29 02:55:11
Define a local constant as white to use instead of
msw
2011/10/30 21:02:15
Actually, I suspect all of these label backgrounds
alicet1
2011/11/02 06:51:25
removed.
| |
116 label1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 121 label1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
117 AddChildView(label1_); | 122 AddChildView(label1_); |
118 | 123 |
119 gfx::Size ps = GetPreferredSize(); | 124 gfx::Size ps = GetPreferredSize(); |
120 | 125 |
121 label2_ = new views::Label(l10n_util::GetStringUTF16(IDS_FR_BUBBLE_SUBTEXT)); | 126 label2_ = new views::Label(l10n_util::GetStringUTF16(IDS_FR_BUBBLE_SUBTEXT)); |
122 label2_->SetMultiLine(true); | 127 label2_->SetMultiLine(true); |
123 label2_->SetFont(font); | 128 label2_->SetFont(font); |
124 label2_->SetBackgroundColor(Bubble::kBackgroundColor); | 129 label2_->SetBackgroundColor(SK_ColorWHITE); |
125 label2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 130 label2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
126 label2_->SizeToFit(ps.width() - kBubblePadding * 2); | 131 label2_->SizeToFit(ps.width() - kBubblePadding * 2); |
127 AddChildView(label2_); | 132 AddChildView(label2_); |
128 | 133 |
129 string16 question_str = l10n_util::GetStringFUTF16( | 134 string16 question_str = l10n_util::GetStringFUTF16( |
130 IDS_FR_BUBBLE_QUESTION, | 135 IDS_FR_BUBBLE_QUESTION, |
131 GetDefaultSearchEngineName(profile)); | 136 GetDefaultSearchEngineName(profile)); |
132 label3_ = new views::Label(question_str); | 137 label3_ = new views::Label(question_str); |
133 label3_->SetMultiLine(true); | 138 label3_->SetMultiLine(true); |
134 label3_->SetFont(font); | 139 label3_->SetFont(font); |
135 label3_->SetBackgroundColor(Bubble::kBackgroundColor); | 140 label3_->SetBackgroundColor(SK_ColorWHITE); |
136 label3_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 141 label3_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
137 label3_->SizeToFit(ps.width() - kBubblePadding * 2); | 142 label3_->SizeToFit(ps.width() - kBubblePadding * 2); |
138 AddChildView(label3_); | 143 AddChildView(label3_); |
139 | 144 |
140 std::wstring keep_str = UTF16ToWide(l10n_util::GetStringFUTF16( | 145 string16 keep_str = l10n_util::GetStringFUTF16( |
141 IDS_FR_BUBBLE_OK, | 146 IDS_FR_BUBBLE_OK, |
142 GetDefaultSearchEngineName(profile))); | 147 GetDefaultSearchEngineName(profile)); |
143 keep_button_ = new views::NativeTextButton(this, keep_str); | 148 keep_button_ = new views::NativeTextButton(this, keep_str); |
144 keep_button_->SetIsDefault(true); | 149 keep_button_->SetIsDefault(true); |
145 AddChildView(keep_button_); | 150 AddChildView(keep_button_); |
146 | 151 |
147 std::wstring change_str = | 152 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); | 153 change_button_ = new views::NativeTextButton(this, change_str); |
150 AddChildView(change_button_); | 154 AddChildView(change_button_); |
151 } | 155 } |
152 | 156 |
157 void FirstRunBubbleView::ButtonPressed(views::Button* sender, | |
158 const views::Event& event) { | |
159 UserMetrics::RecordAction(UserMetricsAction("FirstRunBubbleView_Clicked")); | |
160 static_cast<views::BubbleDelegateView*>(GetWidget()->widget_delegate()) | |
161 ->StartFade(false); | |
162 if (change_button_ == sender) { | |
msw
2011/10/29 02:55:11
Code after StartFade is technically in a race cond
alicet1
2011/11/02 06:51:25
this is removed as part of removing this bubble --
| |
163 UserMetrics::RecordAction( | |
164 UserMetricsAction("FirstRunBubbleView_ChangeButton")); | |
msw
2011/10/29 02:55:11
Fix this indenting.
alicet1
2011/11/02 06:51:25
Done.
| |
165 | |
166 Browser* browser = BrowserList::GetLastActiveWithProfile(profile()); | |
167 if (browser) { | |
168 browser->OpenSearchEngineOptionsDialog(); | |
msw
2011/10/29 02:55:11
Single line if doesn't require braces.
alicet1
2011/11/02 06:51:25
removed.
| |
169 } | |
170 } | |
171 GetWidget()->Close(); | |
msw
2011/10/29 02:55:11
Why is this closing the bubble mid-fade?
alicet1
2011/11/02 06:51:25
I changed it to close only. I'm not sure why a but
| |
172 } | |
173 | |
153 void FirstRunBubbleView::BubbleShown() { | 174 void FirstRunBubbleView::BubbleShown() { |
154 keep_button_->RequestFocus(); | 175 keep_button_->RequestFocus(); |
155 } | 176 } |
156 | 177 |
157 void FirstRunBubbleView::ButtonPressed(views::Button* sender, | |
158 const views::Event& event) { | |
159 UserMetrics::RecordAction(UserMetricsAction("FirstRunBubbleView_Clicked")); | |
160 bubble_window_->set_fade_away_on_close(true); | |
161 bubble_window_->Close(); | |
162 if (change_button_ == sender) { | |
163 UserMetrics::RecordAction( | |
164 UserMetricsAction("FirstRunBubbleView_ChangeButton")); | |
165 | |
166 Browser* browser = BrowserList::GetLastActiveWithProfile(profile_); | |
167 if (browser) { | |
168 browser->OpenSearchEngineOptionsDialog(); | |
169 } | |
170 } | |
171 } | |
172 | |
173 void FirstRunBubbleView::Layout() { | 178 void FirstRunBubbleView::Layout() { |
174 gfx::Size canvas = GetPreferredSize(); | 179 gfx::Size canvas = GetPreferredSize(); |
175 | 180 |
176 // The multiline business that follows is dirty hacks to get around | 181 // The multiline business that follows is dirty hacks to get around |
177 // bug 1325257. | 182 // bug 1325257. |
178 label1_->SetMultiLine(false); | 183 label1_->SetMultiLine(false); |
179 gfx::Size pref_size = label1_->GetPreferredSize(); | 184 gfx::Size pref_size = label1_->GetPreferredSize(); |
180 label1_->SetMultiLine(true); | 185 label1_->SetMultiLine(true); |
181 label1_->SizeToFit(canvas.width() - kBubblePadding * 2); | 186 label1_->SizeToFit(canvas.width() - kBubblePadding * 2); |
182 label1_->SetBounds(kBubblePadding, kBubblePadding, | 187 label1_->SetBounds(kBubblePadding, kBubblePadding, |
(...skipping 27 matching lines...) Expand all Loading... | |
210 views::kRelatedButtonHSpacing, change_button_->y(), | 215 views::kRelatedButtonHSpacing, change_button_->y(), |
211 pref_size.width(), pref_size.height()); | 216 pref_size.width(), pref_size.height()); |
212 } | 217 } |
213 | 218 |
214 gfx::Size FirstRunBubbleView::GetPreferredSize() { | 219 gfx::Size FirstRunBubbleView::GetPreferredSize() { |
215 return gfx::Size(views::Widget::GetLocalizedContentsSize( | 220 return gfx::Size(views::Widget::GetLocalizedContentsSize( |
216 IDS_FIRSTRUNBUBBLE_DIALOG_WIDTH_CHARS, | 221 IDS_FIRSTRUNBUBBLE_DIALOG_WIDTH_CHARS, |
217 IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES)); | 222 IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES)); |
218 } | 223 } |
219 | 224 |
220 void FirstRunBubbleView::FocusWillChange(View* focused_before, | 225 void FirstRunBubbleView::FocusWillChange(View* focused_before, |
msw
2011/10/29 02:55:11
This is the only view that actually watches focus
alicet1
2011/11/02 06:51:25
removed other classes. we talked about this -- I t
| |
221 View* focused_now) { | 226 View* focused_now) { |
222 if (focused_before && | 227 if (focused_before && |
223 (focused_before->GetClassName() == | 228 (focused_before->GetClassName() == |
224 views::NativeTextButton::kViewClassName)) { | 229 views::NativeTextButton::kViewClassName)) { |
225 views::NativeTextButton* before = | 230 views::NativeTextButton* before = |
226 static_cast<views::NativeTextButton*>(focused_before); | 231 static_cast<views::NativeTextButton*>(focused_before); |
227 before->SetIsDefault(false); | 232 before->SetIsDefault(false); |
228 } | 233 } |
229 if (focused_now && | 234 if (focused_now && |
230 (focused_now->GetClassName() == | 235 (focused_now->GetClassName() == |
231 views::NativeTextButton::kViewClassName)) { | 236 views::NativeTextButton::kViewClassName)) { |
232 views::NativeTextButton* after = | 237 views::NativeTextButton* after = |
233 static_cast<views::NativeTextButton*>(focused_now); | 238 static_cast<views::NativeTextButton*>(focused_now); |
234 after->SetIsDefault(true); | 239 after->SetIsDefault(true); |
235 } | 240 } |
236 } | 241 } |
237 | 242 |
238 // FirstRunOEMBubbleView ------------------------------------------------------ | 243 // FirstRunOEMBubbleView ------------------------------------------------------ |
239 | 244 |
240 class FirstRunOEMBubbleView : public FirstRunBubbleViewBase { | 245 class FirstRunOEMBubbleView : public FirstRunBubbleViewBase { |
241 public: | 246 public: |
242 FirstRunOEMBubbleView(FirstRunBubble* bubble_window, Profile* profile); | 247 FirstRunOEMBubbleView(FirstRunBubble* bubble_window, Profile* profile); |
243 | 248 |
249 // Override from FirstRunBubbleViewBase: | |
250 void BubbleShown(); | |
251 | |
244 private: | 252 private: |
245 virtual ~FirstRunOEMBubbleView() { } | 253 virtual ~FirstRunOEMBubbleView() {} |
246 | 254 |
247 // FirstRunBubbleViewBase: | 255 // Override from View: |
248 virtual void BubbleShown(); | 256 virtual void ButtonPressed(views::Button* sender, const views::Event& event); |
257 virtual gfx::Size GetPreferredSize(); | |
258 virtual void Layout(); | |
249 | 259 |
250 // Overridden from View: | 260 // Override from FocusChangeListener: |
251 virtual void ButtonPressed(views::Button* sender, const views::Event& event); | |
252 virtual void Layout(); | |
253 virtual gfx::Size GetPreferredSize(); | |
254 | |
255 // FocusChangeListener: | |
256 virtual void FocusWillChange(View* focused_before, View* focused_now); | 261 virtual void FocusWillChange(View* focused_before, View* focused_now); |
257 | 262 |
258 FirstRunBubble* bubble_window_; | |
259 views::Label* label1_; | 263 views::Label* label1_; |
260 views::Label* label2_; | 264 views::Label* label2_; |
261 views::Label* label3_; | 265 views::Label* label3_; |
262 views::ImageButton* close_button_; | 266 views::ImageButton* close_button_; |
263 Profile* profile_; | |
264 | 267 |
265 DISALLOW_COPY_AND_ASSIGN(FirstRunOEMBubbleView); | 268 DISALLOW_COPY_AND_ASSIGN(FirstRunOEMBubbleView); |
266 }; | 269 }; |
267 | 270 |
268 FirstRunOEMBubbleView::FirstRunOEMBubbleView(FirstRunBubble* bubble_window, | 271 FirstRunOEMBubbleView::FirstRunOEMBubbleView(FirstRunBubble* bubble_window, |
269 Profile* profile) | 272 Profile* profile) |
270 : bubble_window_(bubble_window), | 273 : FirstRunBubbleViewBase(bubble_window, profile), |
271 label1_(NULL), | 274 label1_(NULL), |
272 label2_(NULL), | 275 label2_(NULL), |
273 label3_(NULL), | 276 label3_(NULL), |
274 close_button_(NULL), | 277 close_button_(NULL) { |
275 profile_(profile) { | |
276 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 278 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
277 const gfx::Font& font = rb.GetFont(ResourceBundle::MediumFont); | 279 const gfx::Font& font = rb.GetFont(ResourceBundle::MediumFont); |
278 | 280 |
279 label1_ = new views::Label( | 281 label1_ = new views::Label( |
280 l10n_util::GetStringUTF16(IDS_FR_OEM_BUBBLE_TITLE_1)); | 282 l10n_util::GetStringUTF16(IDS_FR_OEM_BUBBLE_TITLE_1)); |
281 label1_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); | 283 label1_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); |
282 label1_->SetBackgroundColor(Bubble::kBackgroundColor); | 284 label1_->SetBackgroundColor(SK_ColorWHITE); |
283 label1_->SetEnabledColor(SK_ColorRED); | 285 label1_->SetEnabledColor(SK_ColorRED); |
284 label1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 286 label1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
285 AddChildView(label1_); | 287 AddChildView(label1_); |
286 | 288 |
287 label2_ = new views::Label( | 289 label2_ = new views::Label( |
288 l10n_util::GetStringUTF16(IDS_FR_OEM_BUBBLE_TITLE_2)); | 290 l10n_util::GetStringUTF16(IDS_FR_OEM_BUBBLE_TITLE_2)); |
289 label2_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); | 291 label2_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); |
290 label2_->SetBackgroundColor(Bubble::kBackgroundColor); | 292 label2_->SetBackgroundColor(SK_ColorWHITE); |
291 label2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 293 label2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
292 AddChildView(label2_); | 294 AddChildView(label2_); |
293 | 295 |
294 gfx::Size ps = GetPreferredSize(); | 296 gfx::Size ps = GetPreferredSize(); |
295 | 297 |
296 label3_ = new views::Label( | 298 label3_ = new views::Label( |
297 l10n_util::GetStringUTF16(IDS_FR_OEM_BUBBLE_SUBTEXT)); | 299 l10n_util::GetStringUTF16(IDS_FR_OEM_BUBBLE_SUBTEXT)); |
298 label3_->SetMultiLine(true); | 300 label3_->SetMultiLine(true); |
299 label3_->SetFont(font); | 301 label3_->SetFont(font); |
300 label3_->SetBackgroundColor(Bubble::kBackgroundColor); | 302 label3_->SetBackgroundColor(SK_ColorWHITE); |
301 label3_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 303 label3_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
302 label3_->SizeToFit(ps.width() - kOEMBubblePadding * 2); | 304 label3_->SizeToFit(ps.width() - kOEMBubblePadding * 2); |
303 AddChildView(label3_); | 305 AddChildView(label3_); |
304 | 306 |
305 close_button_ = new views::ImageButton(this); | 307 close_button_ = new views::ImageButton(this); |
306 close_button_->SetImage(views::CustomButton::BS_NORMAL, | 308 close_button_->SetImage(views::CustomButton::BS_NORMAL, |
307 rb.GetBitmapNamed(IDR_CLOSE_BAR)); | 309 rb.GetBitmapNamed(IDR_CLOSE_BAR)); |
308 close_button_->SetImage(views::CustomButton::BS_HOT, | 310 close_button_->SetImage(views::CustomButton::BS_HOT, |
309 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); | 311 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); |
310 close_button_->SetImage(views::CustomButton::BS_PUSHED, | 312 close_button_->SetImage(views::CustomButton::BS_PUSHED, |
311 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); | 313 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); |
312 | 314 |
313 AddChildView(close_button_); | 315 AddChildView(close_button_); |
314 } | 316 } |
315 | 317 |
316 void FirstRunOEMBubbleView::BubbleShown() { | 318 void FirstRunOEMBubbleView::BubbleShown() { |
317 RequestFocus(); | 319 RequestFocus(); |
msw
2011/10/29 02:55:11
This probably isn't necessary.
alicet1
2011/11/02 06:51:25
removed.
| |
318 // No button in oem_bubble to request focus. | |
319 } | 320 } |
320 | 321 |
321 void FirstRunOEMBubbleView::ButtonPressed(views::Button* sender, | 322 void FirstRunOEMBubbleView::ButtonPressed(views::Button* sender, |
322 const views::Event& event) { | 323 const views::Event& event) { |
323 UserMetrics::RecordAction( | 324 UserMetrics::RecordAction( |
324 UserMetricsAction("FirstRunOEMBubbleView_Clicked")); | 325 UserMetricsAction("FirstRunOEMBubbleView_Clicked")); |
325 bubble_window_->set_fade_away_on_close(true); | 326 static_cast<views::BubbleDelegateView*>(GetWidget()->widget_delegate()) |
326 bubble_window_->Close(); | 327 ->StartFade(false); |
327 } | 328 } |
328 | 329 |
329 void FirstRunOEMBubbleView::Layout() { | 330 void FirstRunOEMBubbleView::Layout() { |
330 gfx::Size canvas = GetPreferredSize(); | 331 gfx::Size canvas = GetPreferredSize(); |
331 | 332 |
332 // First, draw the close button on the far right. | 333 // First, draw the close button on the far right. |
333 gfx::Size sz = close_button_->GetPreferredSize(); | 334 gfx::Size sz = close_button_->GetPreferredSize(); |
334 close_button_->SetBounds( | 335 close_button_->SetBounds( |
335 canvas.width() - sz.width() - kMarginRightOfCloseButton, | 336 canvas.width() - sz.width() - kMarginRightOfCloseButton, |
336 kOEMBubblePadding, sz.width(), sz.height()); | 337 kOEMBubblePadding, sz.width(), sz.height()); |
(...skipping 22 matching lines...) Expand all Loading... | |
359 gfx::Size FirstRunOEMBubbleView::GetPreferredSize() { | 360 gfx::Size FirstRunOEMBubbleView::GetPreferredSize() { |
360 // Calculate width based on font and text. | 361 // Calculate width based on font and text. |
361 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 362 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
362 const gfx::Font& font = rb.GetFont( | 363 const gfx::Font& font = rb.GetFont( |
363 ResourceBundle::MediumFont).DeriveFont(3, gfx::Font::BOLD); | 364 ResourceBundle::MediumFont).DeriveFont(3, gfx::Font::BOLD); |
364 gfx::Size size = gfx::Size( | 365 gfx::Size size = gfx::Size( |
365 ui::GetLocalizedContentsWidthForFont( | 366 ui::GetLocalizedContentsWidthForFont( |
366 IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS, font), | 367 IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS, font), |
367 ui::GetLocalizedContentsHeightForFont( | 368 ui::GetLocalizedContentsHeightForFont( |
368 IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES, font)); | 369 IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES, font)); |
369 | 370 #if defined(OS_WIN) && !defined(USE_AURA) |
370 // WARNING: HACK. Vista and XP calculate font size differently; this means | 371 // 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 | 372 // 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 | 373 // 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 | 374 // 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 | 375 // 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 | 376 // 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. | 377 // stored in a variable because it's a hack and should go away. |
377 if (views::NativeWidgetWin::IsAeroGlassEnabled()) { | 378 if (views::NativeWidgetWin::IsAeroGlassEnabled()) { |
378 size.set_width(static_cast<int>(size.width() * 0.85)); | 379 size.set_width(static_cast<int>(size.width() * 0.85)); |
379 size.set_height(static_cast<int>(size.height() * 0.85)); | 380 size.set_height(static_cast<int>(size.height() * 0.85)); |
380 } | 381 } |
382 #endif | |
381 return size; | 383 return size; |
382 } | 384 } |
383 | 385 |
384 void FirstRunOEMBubbleView::FocusWillChange(View* focused_before, | 386 void FirstRunOEMBubbleView::FocusWillChange(View* focused_before, |
385 View* focused_now) { | 387 View* focused_now) { |
386 // No buttons in oem_bubble to register focus changes. | 388 // No buttons in oem_bubble to register focus changes. |
387 } | 389 } |
388 | 390 |
389 // FirstRunMinimalBubbleView -------------------------------------------------- | 391 // FirstRunMinimalBubbleView -------------------------------------------------- |
390 // TODO(mirandac): combine FRBubbles more elegantly. http://crbug.com/41353 | 392 // TODO(mirandac): combine FRBubbles more elegantly. http://crbug.com/41353 |
391 | 393 |
392 class FirstRunMinimalBubbleView : public FirstRunBubbleViewBase { | 394 class FirstRunMinimalBubbleView : public FirstRunBubbleViewBase { |
393 public: | 395 public: |
394 FirstRunMinimalBubbleView(FirstRunBubble* bubble_window, Profile* profile); | 396 FirstRunMinimalBubbleView(FirstRunBubble* bubble_window, Profile* profile); |
395 | 397 |
398 // Override from FirstRunBubbleViewBase: | |
399 void BubbleShown(); | |
400 | |
396 private: | 401 private: |
397 virtual ~FirstRunMinimalBubbleView() { } | 402 virtual ~FirstRunMinimalBubbleView(); |
398 | 403 |
399 // FirstRunBubbleViewBase: | 404 // Override from View: |
400 virtual void BubbleShown(); | |
401 | |
402 // Overridden from View: | |
403 virtual void ButtonPressed(views::Button* sender, | 405 virtual void ButtonPressed(views::Button* sender, |
404 const views::Event& event) { } | 406 const views::Event& event) { } |
msw
2011/10/29 02:55:11
I think inline virtual overrides break clang.
alicet1
2011/11/02 06:51:25
removed.
| |
407 virtual gfx::Size GetPreferredSize(); | |
405 virtual void Layout(); | 408 virtual void Layout(); |
406 virtual gfx::Size GetPreferredSize(); | |
407 | 409 |
408 // FocusChangeListener: | 410 // Override from FocusChangeListener: |
409 virtual void FocusWillChange(View* focused_before, View* focused_now); | 411 virtual void FocusWillChange(View* focused_before, View* focused_now); |
410 | 412 |
411 FirstRunBubble* bubble_window_; | |
412 Profile* profile_; | |
413 views::Label* label1_; | 413 views::Label* label1_; |
414 views::Label* label2_; | 414 views::Label* label2_; |
415 | 415 |
416 DISALLOW_COPY_AND_ASSIGN(FirstRunMinimalBubbleView); | 416 DISALLOW_COPY_AND_ASSIGN(FirstRunMinimalBubbleView); |
417 }; | 417 }; |
418 | 418 |
419 FirstRunMinimalBubbleView::FirstRunMinimalBubbleView( | 419 FirstRunMinimalBubbleView::FirstRunMinimalBubbleView( |
420 FirstRunBubble* bubble_window, | 420 FirstRunBubble* bubble_window, |
421 Profile* profile) | 421 Profile* profile) |
422 : bubble_window_(bubble_window), | 422 : FirstRunBubbleViewBase(bubble_window, profile), |
423 profile_(profile), | |
424 label1_(NULL), | 423 label1_(NULL), |
425 label2_(NULL) { | 424 label2_(NULL) { |
426 const gfx::Font& font = | 425 const gfx::Font& font = |
427 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont); | 426 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont); |
428 | 427 |
429 label1_ = new views::Label(l10n_util::GetStringFUTF16( | 428 label1_ = new views::Label(l10n_util::GetStringFUTF16( |
430 IDS_FR_SE_BUBBLE_TITLE, | 429 IDS_FR_SE_BUBBLE_TITLE, |
431 GetDefaultSearchEngineName(profile_))); | 430 GetDefaultSearchEngineName(profile))); |
432 label1_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); | 431 label1_->SetFont(font.DeriveFont(3, gfx::Font::BOLD)); |
433 label1_->SetBackgroundColor(Bubble::kBackgroundColor); | 432 label1_->SetBackgroundColor(SK_ColorWHITE); |
434 label1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 433 label1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
435 AddChildView(label1_); | 434 AddChildView(label1_); |
436 | 435 |
437 gfx::Size ps = GetPreferredSize(); | 436 gfx::Size ps = GetPreferredSize(); |
438 | 437 |
439 label2_ = new views::Label( | 438 label2_ = new views::Label( |
440 l10n_util::GetStringUTF16(IDS_FR_BUBBLE_SUBTEXT)); | 439 l10n_util::GetStringUTF16(IDS_FR_BUBBLE_SUBTEXT)); |
441 label2_->SetMultiLine(true); | 440 label2_->SetMultiLine(true); |
442 label2_->SetFont(font); | 441 label2_->SetFont(font); |
443 label2_->SetBackgroundColor(Bubble::kBackgroundColor); | 442 label2_->SetBackgroundColor(SK_ColorWHITE); |
444 label2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 443 label2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
445 label2_->SizeToFit(ps.width() - kBubblePadding * 2); | 444 label2_->SizeToFit(ps.width() - kBubblePadding * 2); |
446 AddChildView(label2_); | 445 AddChildView(label2_); |
447 } | 446 } |
448 | 447 |
448 FirstRunMinimalBubbleView::~FirstRunMinimalBubbleView() { | |
449 GetFocusManager()->RemoveFocusChangeListener(this); | |
450 } | |
451 | |
449 void FirstRunMinimalBubbleView::BubbleShown() { | 452 void FirstRunMinimalBubbleView::BubbleShown() { |
450 RequestFocus(); | 453 RequestFocus(); |
451 } | 454 } |
452 | 455 |
453 void FirstRunMinimalBubbleView::Layout() { | 456 void FirstRunMinimalBubbleView::Layout() { |
454 gfx::Size canvas = GetPreferredSize(); | 457 gfx::Size canvas = GetPreferredSize(); |
455 | 458 |
456 // See comments in FirstRunOEMBubbleView::Layout explaining this hack. | 459 // See comments in FirstRunOEMBubbleView::Layout explaining this hack. |
457 label1_->SetMultiLine(false); | 460 label1_->SetMultiLine(false); |
458 gfx::Size pref_size = label1_->GetPreferredSize(); | 461 gfx::Size pref_size = label1_->GetPreferredSize(); |
(...skipping 20 matching lines...) Expand all Loading... | |
479 | 482 |
480 void FirstRunMinimalBubbleView::FocusWillChange(View* focused_before, | 483 void FirstRunMinimalBubbleView::FocusWillChange(View* focused_before, |
481 View* focused_now) { | 484 View* focused_now) { |
482 // No buttons in minimal bubble to register focus changes. | 485 // No buttons in minimal bubble to register focus changes. |
483 } | 486 } |
484 | 487 |
485 | 488 |
486 // FirstRunBubble ------------------------------------------------------------- | 489 // FirstRunBubble ------------------------------------------------------------- |
487 | 490 |
488 // static | 491 // static |
489 FirstRunBubble* FirstRunBubble::Show( | 492 views::Widget* FirstRunBubble::Show( |
490 Profile* profile, | 493 Profile* profile, |
491 views::Widget* parent, | 494 views::Widget* parent, |
492 const gfx::Rect& position_relative_to, | 495 const gfx::Rect& position_relative_to, |
493 views::BubbleBorder::ArrowLocation arrow_location, | 496 views::BubbleBorder::ArrowLocation arrow_location, |
494 FirstRun::BubbleType bubble_type) { | 497 FirstRun::BubbleType bubble_type) { |
495 FirstRunBubble* bubble = new FirstRunBubble(); | 498 FirstRunBubble* delegate = |
499 new FirstRunBubble(profile, | |
500 parent, | |
501 position_relative_to, | |
502 arrow_location, | |
503 bubble_type); | |
504 views::Widget* widget = | |
505 views::BubbleDelegateView::CreateBubble(delegate, parent); | |
506 delegate->StartFade(true); | |
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); |
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 : views::BubbleDelegateView(position_relative_to.origin(), | |
538 arrow_location, SK_ColorWHITE), | |
539 profile_(profile), | |
540 parent_(parent), | |
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 #if defined(OS_WIN) && !defined(USE_AURA) | |
530 void FirstRunBubble::EnableParent() { | 551 void FirstRunBubble::EnableParent() { |
531 ::EnableWindow(GetParent(), true); | 552 ::EnableWindow(GetParent(), true); |
532 // The EnableWindow() call above causes the parent to become active, which | 553 // The EnableWindow() call above causes the parent to become active, which |
533 // resets the flag set by Bubble's call to DisableInactiveRendering(), so we | 554 // 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 | 555 // have to call it again before activating the bubble to prevent the parent |
535 // window from rendering inactive. | 556 // window from rendering inactive. |
536 // TODO(beng): this only works in custom-frame mode, not glass-frame mode. | 557 // TODO(beng): this only works in custom-frame mode, not glass-frame mode. |
537 HWND bubble_owner = GetLogicalBubbleOwner(GetNativeView()); | 558 if (parent_) |
538 views::Widget* parent = views::Widget::GetWidgetForNativeView(bubble_owner); | 559 parent_->DisableInactiveRendering(); |
539 if (parent) | |
540 parent->DisableInactiveRendering(); | |
541 // Reactivate the FirstRunBubble so it responds to OnActivate messages. | 560 // Reactivate the FirstRunBubble so it responds to OnActivate messages. |
542 SetWindowPos(GetParent(), 0, 0, 0, 0, | 561 SetWindowPos(GetParent(), 0, 0, 0, 0, |
543 SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_SHOWWINDOW); | 562 SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_SHOWWINDOW); |
544 } | 563 } |
545 | 564 |
546 #if defined(OS_WIN) && !defined(USE_AURA) | |
547 void FirstRunBubble::OnActivate(UINT action, BOOL minimized, HWND window) { | 565 void FirstRunBubble::OnActivate(UINT action, BOOL minimized, HWND window) { |
548 // Keep the bubble around for kLingerTime milliseconds, to prevent accidental | 566 // Keep the bubble around for kLingerTime milliseconds, to prevent accidental |
549 // closure. | 567 // closure. |
550 const int kLingerTime = 3000; | 568 const int kLingerTime = 3000; |
551 | 569 |
552 // We might get re-enabled right before we are closed (sequence is: we get | 570 // 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 | 571 // deactivated, we call close, before we are actually closed we get |
554 // reactivated). Don't do the disabling of the parent in such cases. | 572 // reactivated). Don't do the disabling of the parent in such cases. |
555 if (action == WA_ACTIVE && !has_been_activated_) { | 573 if (action == WA_ACTIVE && !has_been_activated_) { |
556 has_been_activated_ = true; | 574 has_been_activated_ = true; |
557 | 575 |
558 ::EnableWindow(GetParent(), false); | 576 ::EnableWindow(GetParent(), false); |
559 | 577 |
560 MessageLoop::current()->PostDelayedTask( | 578 MessageLoop::current()->PostDelayedTask( |
561 FROM_HERE, | 579 FROM_HERE, |
562 base::Bind(&FirstRunBubble::EnableParent, | 580 base::Bind(&FirstRunBubble::EnableParent, |
563 enable_window_method_factory_.GetWeakPtr()), | 581 enable_window_method_factory_.GetWeakPtr()), |
564 kLingerTime); | 582 kLingerTime); |
565 return; | 583 return; |
566 } | 584 } |
567 | 585 |
568 // Keep window from automatically closing until kLingerTime has passed. | 586 // Keep window from automatically closing until kLingerTime has passed. |
569 if (::IsWindowEnabled(GetParent())) | 587 if (::IsWindowEnabled(GetParent())) |
570 Bubble::OnActivate(action, minimized, window); | 588 Bubble::OnActivate(action, minimized, window); |
571 } | 589 } |
572 #endif | 590 #endif |
573 | 591 |
574 void FirstRunBubble::BubbleClosing(Bubble* bubble, bool closed_by_escape) { | 592 void FirstRunBubble::WindowClosing() { |
575 // Make sure our parent window is re-enabled. | 593 // Make sure our parent window is re-enabled. |
576 if (!IsWindowEnabled(GetParent())) | 594 GetFocusManager()->FocusNativeView(parent_->GetNativeView()); |
msw
2011/10/29 02:55:11
Can you check if this is necessary? I suspect it i
alicet1
2011/11/02 06:51:25
as in, when bubble widget is closing, parent shoul
Miranda Callahan
2011/11/02 15:36:14
I remember there being bizarre focus problems that
| |
577 ::EnableWindow(GetParent(), true); | |
578 } | 595 } |
OLD | NEW |