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

Side by Side Diff: chrome/browser/ui/views/infobars/infobar_view.cc

Issue 6609047: [linux_views][Win] spoof proof redesign infobar extension with tab. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: renames, don't const_cast, ditch InfoBarView::VerticalOffset. Created 9 years, 9 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/infobars/infobar_view.h" 5 #include "chrome/browser/ui/views/infobars/infobar_view.h"
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h" 9 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
10 #include "chrome/browser/ui/views/infobars/infobar_background.h" 10 #include "chrome/browser/ui/views/infobars/infobar_background.h"
(...skipping 23 matching lines...) Expand all
34 #include "ui/base/win/hwnd_util.h" 34 #include "ui/base/win/hwnd_util.h"
35 #include "ui/gfx/icon_util.h" 35 #include "ui/gfx/icon_util.h"
36 #endif 36 #endif
37 37
38 // static 38 // static
39 const int InfoBarView::kDefaultTargetHeight = 36; 39 const int InfoBarView::kDefaultTargetHeight = 36;
40 const int InfoBarView::kButtonButtonSpacing = 10; 40 const int InfoBarView::kButtonButtonSpacing = 10;
41 const int InfoBarView::kEndOfLabelSpacing = 16; 41 const int InfoBarView::kEndOfLabelSpacing = 16;
42 const int InfoBarView::kHorizontalPadding = 6; 42 const int InfoBarView::kHorizontalPadding = 6;
43 43
44 const int InfoBarView::kCurveWidth = 13;
45 const int InfoBarView::kMaxIconWidth = 30;
46 const int InfoBarView::kTabHeight = 9;
47 const int InfoBarView::kTabIconPadding = 2;
48
49 const int InfoBarView::kTabWidth = (kCurveWidth + kTabIconPadding) * 2 +
50 kMaxIconWidth;
51
44 InfoBarView::InfoBarView(InfoBarDelegate* delegate) 52 InfoBarView::InfoBarView(InfoBarDelegate* delegate)
45 : InfoBar(delegate), 53 : InfoBar(delegate),
46 container_(NULL), 54 container_(NULL),
47 delegate_(delegate), 55 delegate_(delegate),
48 icon_(NULL), 56 icon_(NULL),
49 close_button_(NULL), 57 close_button_(NULL),
50 ALLOW_THIS_IN_INITIALIZER_LIST(animation_(new ui::SlideAnimation(this))), 58 ALLOW_THIS_IN_INITIALIZER_LIST(animation_(new ui::SlideAnimation(this))),
51 ALLOW_THIS_IN_INITIALIZER_LIST(delete_factory_(this)), 59 ALLOW_THIS_IN_INITIALIZER_LIST(delete_factory_(this)),
52 target_height_(kDefaultTargetHeight) { 60 target_height_(kDefaultTargetHeight),
61 fill_path_(new SkPath),
62 stroke_path_(new SkPath) {
53 set_parent_owned(false); // InfoBar deletes itself at the appropriate time. 63 set_parent_owned(false); // InfoBar deletes itself at the appropriate time.
54 64
55 InfoBarDelegate::Type infobar_type = delegate->GetInfoBarType(); 65 InfoBarDelegate::Type infobar_type = delegate->GetInfoBarType();
56 set_background(new InfoBarBackground(infobar_type)); 66 set_background(new InfoBarBackground(infobar_type));
57 SetAccessibleName(l10n_util::GetStringUTF16( 67 SetAccessibleName(l10n_util::GetStringUTF16(
58 (infobar_type == InfoBarDelegate::WARNING_TYPE) ? 68 (infobar_type == InfoBarDelegate::WARNING_TYPE) ?
59 IDS_ACCNAME_INFOBAR_WARNING : IDS_ACCNAME_INFOBAR_PAGE_ACTION)); 69 IDS_ACCNAME_INFOBAR_WARNING : IDS_ACCNAME_INFOBAR_PAGE_ACTION));
60 70
61 animation_->SetTweenType(ui::Tween::LINEAR); 71 animation_->SetTweenType(ui::Tween::LINEAR);
62 } 72 }
(...skipping 19 matching lines...) Expand all
82 restore_focus = false; 92 restore_focus = false;
83 #endif // defined(OS_WIN) 93 #endif // defined(OS_WIN)
84 DestroyFocusTracker(restore_focus); 94 DestroyFocusTracker(restore_focus);
85 animation_->Hide(); 95 animation_->Hide();
86 } else { 96 } else {
87 animation_->Reset(0.0); 97 animation_->Reset(0.0);
88 Close(); 98 Close();
89 } 99 }
90 } 100 }
91 101
92 void InfoBarView::PaintArrow(gfx::Canvas* canvas,
93 View* outer_view,
94 int arrow_center_x) {
95 gfx::Point infobar_top(0, y());
96 ConvertPointToView(parent(), outer_view, &infobar_top);
97 int infobar_top_y = infobar_top.y();
98 SkPoint gradient_points[2] = {
99 {SkIntToScalar(0), SkIntToScalar(infobar_top_y)},
100 {SkIntToScalar(0), SkIntToScalar(infobar_top_y + target_height_)}
101 };
102 InfoBarDelegate::Type infobar_type = delegate_->GetInfoBarType();
103 SkColor gradient_colors[2] = {
104 InfoBarBackground::GetTopColor(infobar_type),
105 InfoBarBackground::GetBottomColor(infobar_type),
106 };
107 SkShader* gradient_shader = SkGradientShader::CreateLinear(gradient_points,
108 gradient_colors, NULL, 2, SkShader::kMirror_TileMode);
109 SkPaint paint;
110 paint.setStrokeWidth(1);
111 paint.setStyle(SkPaint::kFill_Style);
112 paint.setShader(gradient_shader);
113 gradient_shader->unref();
114
115 // The size of the arrow (its height; also half its width). The
116 // arrow area is |arrow_size| ^ 2. By taking the square root of the
117 // animation value, we cause a linear animation of the area, which
118 // matches the perception of the animation of the InfoBar.
119 const int kArrowSize = 10;
120 int arrow_size = static_cast<int>(kArrowSize *
121 sqrt(animation_->GetCurrentValue()));
122 SkPath fill_path;
123 fill_path.moveTo(SkPoint::Make(SkIntToScalar(arrow_center_x - arrow_size),
124 SkIntToScalar(infobar_top_y)));
125 fill_path.rLineTo(SkIntToScalar(arrow_size), SkIntToScalar(-arrow_size));
126 fill_path.rLineTo(SkIntToScalar(arrow_size), SkIntToScalar(arrow_size));
127 SkPath border_path(fill_path);
128 fill_path.close();
129 gfx::CanvasSkia* canvas_skia = canvas->AsCanvasSkia();
130 canvas_skia->drawPath(fill_path, paint);
131
132 // Fill and stroke have different opinions about how to treat paths. Because
133 // in Skia integral coordinates represent pixel boundaries, offsetting the
134 // path makes it go exactly through pixel centers; this results in lines that
135 // are exactly where we expect, instead of having odd "off by one" issues.
136 // Were we to do this for |fill_path|, however, which tries to fill "inside"
137 // the path (using some questionable math), we'd get a fill at a very
138 // different place than we'd want.
139 border_path.offset(SK_ScalarHalf, SK_ScalarHalf);
140 paint.setShader(NULL);
141 paint.setColor(SkColorSetA(ResourceBundle::toolbar_separator_color,
142 SkColorGetA(gradient_colors[0])));
143 paint.setStyle(SkPaint::kStroke_Style);
144 canvas_skia->drawPath(border_path, paint);
145 }
146
147 InfoBarView::~InfoBarView() { 102 InfoBarView::~InfoBarView() {
148 } 103 }
149 104
150 // static 105 // static
151 views::Label* InfoBarView::CreateLabel(const string16& text) { 106 views::Label* InfoBarView::CreateLabel(const string16& text) {
152 views::Label* label = new views::Label(UTF16ToWideHack(text), 107 views::Label* label = new views::Label(UTF16ToWideHack(text),
153 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont)); 108 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont));
154 label->SetColor(SK_ColorBLACK); 109 label->SetColor(SK_ColorBLACK);
155 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 110 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
156 return label; 111 return label;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 gfx::Size(GetSystemMetrics(SM_CXSMICON), 179 gfx::Size(GetSystemMetrics(SM_CXSMICON),
225 GetSystemMetrics(SM_CYSMICON)))); 180 GetSystemMetrics(SM_CYSMICON))));
226 } 181 }
227 #endif 182 #endif
228 return text_button; 183 return text_button;
229 } 184 }
230 185
231 void InfoBarView::Layout() { 186 void InfoBarView::Layout() {
232 int start_x = kHorizontalPadding; 187 int start_x = kHorizontalPadding;
233 if (icon_ != NULL) { 188 if (icon_ != NULL) {
189 // Center the icon horizontally within the tab, and vertically between the
190 // entire height (tab + bar).
234 gfx::Size icon_size = icon_->GetPreferredSize(); 191 gfx::Size icon_size = icon_->GetPreferredSize();
235 icon_->SetBounds(start_x, OffsetY(icon_size), icon_size.width(), 192 int center_x = std::max((kTabWidth - icon_size.width()) / 2, 0);
236 icon_size.height()); 193 int full_height = target_height_ + kTabHeight;
194
195 // This duplicates OffsetY except centered within the entire height (tab +
196 // bar) instead of just within the bar.
197 int offset_y =
198 std::max((full_height - icon_size.height()) / 2, 0) -
199 (full_height - height());
200 icon_->SetBounds(center_x, offset_y, icon_size.width(), icon_size.height());
237 start_x += icon_->bounds().right(); 201 start_x += icon_->bounds().right();
238 } 202 }
239 203
240 gfx::Size button_size = close_button_->GetPreferredSize(); 204 gfx::Size button_size = close_button_->GetPreferredSize();
241 close_button_->SetBounds(std::max(start_x + ContentMinimumWidth(), 205 close_button_->SetBounds(std::max(start_x + ContentMinimumWidth(),
242 width() - kHorizontalPadding - button_size.width()), 206 width() - kHorizontalPadding - button_size.width()),
243 OffsetY(button_size), button_size.width(), button_size.height()); 207 OffsetY(button_size), button_size.width(), button_size.height());
244 } 208 }
245 209
246 void InfoBarView::ViewHierarchyChanged(bool is_add, View* parent, View* child) { 210 void InfoBarView::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 264
301 // For accessibility, ensure the close button is the last child view. 265 // For accessibility, ensure the close button is the last child view.
302 if ((close_button_ != NULL) && (parent == this) && (child != close_button_) && 266 if ((close_button_ != NULL) && (parent == this) && (child != close_button_) &&
303 (close_button_->parent() == this) && 267 (close_button_->parent() == this) &&
304 (GetChildViewAt(child_count() - 1) != close_button_)) { 268 (GetChildViewAt(child_count() - 1) != close_button_)) {
305 RemoveChildView(close_button_); 269 RemoveChildView(close_button_);
306 AddChildView(close_button_); 270 AddChildView(close_button_);
307 } 271 }
308 } 272 }
309 273
274 void InfoBarView::PaintChildren(gfx::Canvas* canvas) {
275 canvas->Save();
276
277 // TODO(scr): This really should be the |fill_path_|, but the clipPath seems
278 // broken on non-Windows platforms (crbug.com/75154). For now, just clip to
279 // the bar bounds.
280 //
281 // gfx::CanvasSkia* canvas_skia = canvas->AsCanvasSkia();
282 // canvas_skia->clipPath(*fill_path_);
283 int tab_height = AnimatedTabHeight();
284 int bar_height = AnimatedBarHeight();
285 DCHECK_EQ(tab_height + bar_height, height())
286 << "Animation progressed between OnBoundsChanged & PaintChildren.";
287 canvas->ClipRectInt(0, tab_height, width(), bar_height);
288
289 views::View::PaintChildren(canvas);
290 canvas->Restore();
291 }
292
310 void InfoBarView::ButtonPressed(views::Button* sender, 293 void InfoBarView::ButtonPressed(views::Button* sender,
311 const views::Event& event) { 294 const views::Event& event) {
312 if (sender == close_button_) { 295 if (sender == close_button_) {
313 if (delegate_) 296 if (delegate_)
314 delegate_->InfoBarDismissed(); 297 delegate_->InfoBarDismissed();
315 RemoveInfoBar(); 298 RemoveInfoBar();
316 } 299 }
317 } 300 }
318 301
319 void InfoBarView::AnimationProgressed(const ui::Animation* animation) { 302 void InfoBarView::AnimationProgressed(const ui::Animation* animation) {
(...skipping 21 matching lines...) Expand all
341 int InfoBarView::EndX() const { 324 int InfoBarView::EndX() const {
342 const int kCloseButtonSpacing = 12; 325 const int kCloseButtonSpacing = 12;
343 return close_button_->x() - kCloseButtonSpacing; 326 return close_button_->x() - kCloseButtonSpacing;
344 } 327 }
345 328
346 int InfoBarView::CenterY(const gfx::Size prefsize) const { 329 int InfoBarView::CenterY(const gfx::Size prefsize) const {
347 return std::max((target_height_ - prefsize.height()) / 2, 0); 330 return std::max((target_height_ - prefsize.height()) / 2, 0);
348 } 331 }
349 332
350 int InfoBarView::OffsetY(const gfx::Size prefsize) const { 333 int InfoBarView::OffsetY(const gfx::Size prefsize) const {
351 return CenterY(prefsize) - (target_height_ - height()); 334 return CenterY(prefsize) + AnimatedTabHeight() -
335 (target_height_ - AnimatedBarHeight());
336 }
337
338 int InfoBarView::AnimatedTabHeight() const {
339 return static_cast<int>(kTabHeight * animation_->GetCurrentValue());
340 }
341
342 int InfoBarView::AnimatedBarHeight() const {
343 return static_cast<int>(target_height_ * animation_->GetCurrentValue());
352 } 344 }
353 345
354 AccessibilityTypes::Role InfoBarView::GetAccessibleRole() { 346 AccessibilityTypes::Role InfoBarView::GetAccessibleRole() {
355 return AccessibilityTypes::ROLE_ALERT; 347 return AccessibilityTypes::ROLE_ALERT;
356 } 348 }
357 349
358 gfx::Size InfoBarView::GetPreferredSize() { 350 gfx::Size InfoBarView::GetPreferredSize() {
359 return gfx::Size(0, 351 return gfx::Size(0, AnimatedTabHeight() + AnimatedBarHeight());
360 static_cast<int>(target_height_ * animation_->GetCurrentValue())); 352 }
353
354 void InfoBarView::OnBoundsChanged() {
355 views::View::OnBoundsChanged();
356 int tab_height = AnimatedTabHeight();
357 int bar_height = AnimatedBarHeight();
358 int divider_y = tab_height - 1;
359 DCHECK_EQ(tab_height + bar_height, height())
360 << "Animation progressed between Layout & OnBoundsChanged.";
361
362 int mirrored_x = GetMirroredXWithWidthInView(0, kTabWidth);
363 stroke_path_->rewind();
364 fill_path_->rewind();
365
366 if (tab_height) {
367 stroke_path_->moveTo(SkIntToScalar(mirrored_x),
368 SkIntToScalar(divider_y));
369 stroke_path_->rCubicTo(
370 SkScalarDiv(kCurveWidth, 2), 0.0,
371 SkScalarDiv(kCurveWidth, 2),
372 SkIntToScalar(-divider_y),
373 SkIntToScalar(kCurveWidth),
374 SkIntToScalar(-divider_y));
375 stroke_path_->rLineTo(SkScalarMulAdd(kTabIconPadding, 2, kMaxIconWidth),
376 0.0);
377 stroke_path_->rCubicTo(
378 SkScalarDiv(kCurveWidth, 2), 0.0,
379 SkScalarDiv(kCurveWidth, 2),
380 SkIntToScalar(divider_y),
381 SkIntToScalar(kCurveWidth),
382 SkIntToScalar(divider_y));
383
384 // Create the fill portion of the tab. Because the fill is inside the
385 // bounds and will not cover the separator, we need to extend downward by a
386 // pixel before closing.
387 *fill_path_ = *stroke_path_;
388 fill_path_->rLineTo(0.0, 1.0);
389 fill_path_->rLineTo(-SkIntToScalar(kTabWidth), 0.0);
390 fill_path_->close();
391
392 // Fill and stroke have different opinions about how to treat paths.
393 // Because in Skia integral coordinates represent pixel boundaries,
394 // offsetting the path makes it go exactly through pixel centers; this
395 // results in lines that are exactly where we expect, instead of having odd
396 // "off by one" issues. Were we to do this for |fill_path|, however, which
397 // tries to fill "inside" the path (using some questionable math), we'd get
398 // a fill at a very different place than we'd want.
399 stroke_path_->offset(SK_ScalarHalf, SK_ScalarHalf);
400 }
401 if (bar_height) {
402 fill_path_->addRect(0.0, SkIntToScalar(tab_height),
403 SkIntToScalar(width()), SkIntToScalar(height()));
404 }
361 } 405 }
362 406
363 void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) { 407 void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) {
364 // This will trigger some screen readers to read the entire contents of this 408 // This will trigger some screen readers to read the entire contents of this
365 // infobar. 409 // infobar.
366 if (focused_before && focused_now && !this->Contains(focused_before) && 410 if (focused_before && focused_now && !this->Contains(focused_before) &&
367 this->Contains(focused_now)) 411 this->Contains(focused_now))
368 NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT); 412 NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT);
369 } 413 }
370 414
(...skipping 24 matching lines...) Expand all
395 // window), since this action can cause the delegate to destroy itself. 439 // window), since this action can cause the delegate to destroy itself.
396 if (delegate_) { 440 if (delegate_) {
397 delegate_->InfoBarClosed(); 441 delegate_->InfoBarClosed();
398 delegate_ = NULL; 442 delegate_ = NULL;
399 } 443 }
400 } 444 }
401 445
402 void InfoBarView::DeleteSelf() { 446 void InfoBarView::DeleteSelf() {
403 delete this; 447 delete this;
404 } 448 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698