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

Side by Side Diff: chrome/browser/ui/views/first_run_bubble.cc

Issue 8265005: first run bubble using the views/bubble api. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: update. Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698