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

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: Cast stroke width. 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::kCurveDistance = 13;
Peter Kasting 2011/03/07 20:14:30 Nit: kCurveWidth?
Sheridan Rawlins 2011/03/08 01:38:19 Done.
45 const int InfoBarView::kIconWidth = 29;
Peter Kasting 2011/03/07 20:14:30 Nit: kMaxIconWidth?
Sheridan Rawlins 2011/03/08 01:38:19 Done.
46 const int InfoBarView::kTabHeight = 9;
47 const int InfoBarView::kTabStrokeWidth = 1;
48 const int InfoBarView::kTabPadding = 4;
Peter Kasting 2011/03/07 20:14:30 Nit: Seems like it'd be clearer to have a padding
Sheridan Rawlins 2011/03/08 01:38:19 Done.
49
50 const int InfoBarView::kTabWidth = kCurveDistance * 2 + kIconWidth +
51 kTabPadding;
52
44 InfoBarView::InfoBarView(InfoBarDelegate* delegate) 53 InfoBarView::InfoBarView(InfoBarDelegate* delegate)
45 : InfoBar(delegate), 54 : InfoBar(delegate),
46 container_(NULL), 55 container_(NULL),
47 delegate_(delegate), 56 delegate_(delegate),
48 icon_(NULL), 57 icon_(NULL),
49 close_button_(NULL), 58 close_button_(NULL),
50 ALLOW_THIS_IN_INITIALIZER_LIST(animation_(new ui::SlideAnimation(this))), 59 ALLOW_THIS_IN_INITIALIZER_LIST(animation_(new ui::SlideAnimation(this))),
51 ALLOW_THIS_IN_INITIALIZER_LIST(delete_factory_(this)), 60 ALLOW_THIS_IN_INITIALIZER_LIST(delete_factory_(this)),
52 target_height_(kDefaultTargetHeight) { 61 target_height_(kDefaultTargetHeight),
62 fill_path_(new SkPath),
63 stroke_path_(new SkPath) {
53 set_parent_owned(false); // InfoBar deletes itself at the appropriate time. 64 set_parent_owned(false); // InfoBar deletes itself at the appropriate time.
54 65
55 InfoBarDelegate::Type infobar_type = delegate->GetInfoBarType(); 66 InfoBarDelegate::Type infobar_type = delegate->GetInfoBarType();
56 set_background(new InfoBarBackground(infobar_type)); 67 set_background(new InfoBarBackground(infobar_type));
57 SetAccessibleName(l10n_util::GetStringUTF16( 68 SetAccessibleName(l10n_util::GetStringUTF16(
58 (infobar_type == InfoBarDelegate::WARNING_TYPE) ? 69 (infobar_type == InfoBarDelegate::WARNING_TYPE) ?
59 IDS_ACCNAME_INFOBAR_WARNING : IDS_ACCNAME_INFOBAR_PAGE_ACTION)); 70 IDS_ACCNAME_INFOBAR_WARNING : IDS_ACCNAME_INFOBAR_PAGE_ACTION));
60 71
61 animation_->SetTweenType(ui::Tween::LINEAR); 72 animation_->SetTweenType(ui::Tween::LINEAR);
62 } 73 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 container_->OnInfoBarAnimated(true); 106 container_->OnInfoBarAnimated(true);
96 // Note that we only tell the delegate we're closed here, and not when we're 107 // Note that we only tell the delegate we're closed here, and not when we're
97 // simply destroyed (by virtue of a tab switch or being moved from window to 108 // simply destroyed (by virtue of a tab switch or being moved from window to
98 // window), since this action can cause the delegate to destroy itself. 109 // window), since this action can cause the delegate to destroy itself.
99 if (delegate_) { 110 if (delegate_) {
100 delegate_->InfoBarClosed(); 111 delegate_->InfoBarClosed();
101 delegate_ = NULL; 112 delegate_ = NULL;
102 } 113 }
103 } 114 }
104 115
105 void InfoBarView::PaintArrow(gfx::Canvas* canvas,
106 View* outer_view,
107 int arrow_center_x) {
108 gfx::Point infobar_top(0, y());
109 ConvertPointToView(parent(), outer_view, &infobar_top);
110 int infobar_top_y = infobar_top.y();
111 SkPoint gradient_points[2] = {
112 {SkIntToScalar(0), SkIntToScalar(infobar_top_y)},
113 {SkIntToScalar(0), SkIntToScalar(infobar_top_y + target_height_)}
114 };
115 InfoBarDelegate::Type infobar_type = delegate_->GetInfoBarType();
116 SkColor gradient_colors[2] = {
117 InfoBarBackground::GetTopColor(infobar_type),
118 InfoBarBackground::GetBottomColor(infobar_type),
119 };
120 SkShader* gradient_shader = SkGradientShader::CreateLinear(gradient_points,
121 gradient_colors, NULL, 2, SkShader::kMirror_TileMode);
122 SkPaint paint;
123 paint.setStrokeWidth(1);
124 paint.setStyle(SkPaint::kFill_Style);
125 paint.setShader(gradient_shader);
126 gradient_shader->unref();
127
128 // The size of the arrow (its height; also half its width). The
129 // arrow area is |arrow_size| ^ 2. By taking the square root of the
130 // animation value, we cause a linear animation of the area, which
131 // matches the perception of the animation of the InfoBar.
132 const int kArrowSize = 10;
133 int arrow_size = static_cast<int>(kArrowSize *
134 sqrt(animation_->GetCurrentValue()));
135 SkPath fill_path;
136 fill_path.moveTo(SkPoint::Make(SkIntToScalar(arrow_center_x - arrow_size),
137 SkIntToScalar(infobar_top_y)));
138 fill_path.rLineTo(SkIntToScalar(arrow_size), SkIntToScalar(-arrow_size));
139 fill_path.rLineTo(SkIntToScalar(arrow_size), SkIntToScalar(arrow_size));
140 SkPath border_path(fill_path);
141 fill_path.close();
142 gfx::CanvasSkia* canvas_skia = canvas->AsCanvasSkia();
143 canvas_skia->drawPath(fill_path, paint);
144
145 // Fill and stroke have different opinions about how to treat paths. Because
146 // in Skia integral coordinates represent pixel boundaries, offsetting the
147 // path makes it go exactly through pixel centers; this results in lines that
148 // are exactly where we expect, instead of having odd "off by one" issues.
149 // Were we to do this for |fill_path|, however, which tries to fill "inside"
150 // the path (using some questionable math), we'd get a fill at a very
151 // different place than we'd want.
152 border_path.offset(SK_ScalarHalf, SK_ScalarHalf);
153 paint.setShader(NULL);
154 paint.setColor(SkColorSetA(ResourceBundle::toolbar_separator_color,
155 SkColorGetA(gradient_colors[0])));
156 paint.setStyle(SkPaint::kStroke_Style);
157 canvas_skia->drawPath(border_path, paint);
158 }
159
160 InfoBarView::~InfoBarView() { 116 InfoBarView::~InfoBarView() {
161 } 117 }
162 118
163 // static 119 // static
164 views::Label* InfoBarView::CreateLabel(const string16& text) { 120 views::Label* InfoBarView::CreateLabel(const string16& text) {
165 views::Label* label = new views::Label(UTF16ToWideHack(text), 121 views::Label* label = new views::Label(UTF16ToWideHack(text),
166 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont)); 122 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont));
167 label->SetColor(SK_ColorBLACK); 123 label->SetColor(SK_ColorBLACK);
168 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 124 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
169 return label; 125 return label;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 gfx::Size(GetSystemMetrics(SM_CXSMICON), 193 gfx::Size(GetSystemMetrics(SM_CXSMICON),
238 GetSystemMetrics(SM_CYSMICON)))); 194 GetSystemMetrics(SM_CYSMICON))));
239 } 195 }
240 #endif 196 #endif
241 return text_button; 197 return text_button;
242 } 198 }
243 199
244 void InfoBarView::Layout() { 200 void InfoBarView::Layout() {
245 int start_x = kHorizontalPadding; 201 int start_x = kHorizontalPadding;
246 if (icon_ != NULL) { 202 if (icon_ != NULL) {
203 // Center the icon vertically and horizontally within the tab.
Peter Kasting 2011/03/07 20:14:30 Nit: This is a little unclear since you're not act
Sheridan Rawlins 2011/03/08 01:38:19 Done.
247 gfx::Size icon_size = icon_->GetPreferredSize(); 204 gfx::Size icon_size = icon_->GetPreferredSize();
248 icon_->SetBounds(start_x, OffsetY(icon_size), icon_size.width(), 205 int center_x = std::max((kTabWidth - icon_size.width()) / 2, 0);
249 icon_size.height()); 206 int full_height = target_height_ + kTabHeight;
Peter Kasting 2011/03/07 20:14:30 Nit: I'd stick a comment here that you're duplicat
Sheridan Rawlins 2011/03/08 01:38:19 Done.
207 int preferred_height = preferred_tab_height() + preferred_bar_height();
Peter Kasting 2011/03/07 20:14:30 Nit: This temp is unnecessary.
Sheridan Rawlins 2011/03/08 01:38:19 Done.
208 int center_y =
209 std::max((full_height - icon_size.height()) / 2, 0) -
210 (full_height - preferred_height);
211 icon_->SetBounds(center_x, center_y, icon_size.width(), icon_size.height());
250 start_x += icon_->bounds().right(); 212 start_x += icon_->bounds().right();
251 } 213 }
252 214
253 gfx::Size button_size = close_button_->GetPreferredSize(); 215 gfx::Size button_size = close_button_->GetPreferredSize();
254 close_button_->SetBounds(std::max(start_x + ContentMinimumWidth(), 216 close_button_->SetBounds(std::max(start_x + ContentMinimumWidth(),
255 width() - kHorizontalPadding - button_size.width()), 217 width() - kHorizontalPadding - button_size.width()),
256 OffsetY(button_size), button_size.width(), button_size.height()); 218 OffsetY(button_size), button_size.width(), button_size.height());
257 } 219 }
258 220
259 void InfoBarView::ViewHierarchyChanged(bool is_add, View* parent, View* child) { 221 void InfoBarView::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 275
314 // For accessibility, ensure the close button is the last child view. 276 // For accessibility, ensure the close button is the last child view.
315 if ((close_button_ != NULL) && (parent == this) && (child != close_button_) && 277 if ((close_button_ != NULL) && (parent == this) && (child != close_button_) &&
316 (close_button_->parent() == this) && 278 (close_button_->parent() == this) &&
317 (GetChildViewAt(child_count() - 1) != close_button_)) { 279 (GetChildViewAt(child_count() - 1) != close_button_)) {
318 RemoveChildView(close_button_); 280 RemoveChildView(close_button_);
319 AddChildView(close_button_); 281 AddChildView(close_button_);
320 } 282 }
321 } 283 }
322 284
285 void InfoBarView::PaintChildren(gfx::Canvas* canvas) {
286 canvas->Save();
287
288 // TODO(scr): This really should be the |clip_path_|, but the
289 // clipPath seems broken. Try to get a reduction and file a bug
290 // with skia. For now, just clip to the bar bounds.
Peter Kasting 2011/03/07 20:14:30 Nit: This is on file now, might want to change the
Sheridan Rawlins 2011/03/08 01:38:19 Done.
291 //
292 // gfx::CanvasSkia* canvas_skia = canvas->AsCanvasSkia();
293 // canvas_skia->clipPath(*clip_path_);
294 int tab_height = preferred_tab_height();
295 int bar_height = preferred_bar_height();
296 DCHECK_EQ(tab_height + bar_height, height());
Peter Kasting 2011/03/07 20:14:30 Nit: This DCHECK and the temps above seem unnecess
Sheridan Rawlins 2011/03/08 01:38:19 It was there to test assumption that animation wou
297 canvas->ClipRectInt(0, tab_height, width(), bar_height);
298
299 views::View::PaintChildren(canvas);
300 canvas->Restore();
301 }
302
323 void InfoBarView::ButtonPressed(views::Button* sender, 303 void InfoBarView::ButtonPressed(views::Button* sender,
324 const views::Event& event) { 304 const views::Event& event) {
325 if (sender == close_button_) { 305 if (sender == close_button_) {
326 if (delegate_) 306 if (delegate_)
327 delegate_->InfoBarDismissed(); 307 delegate_->InfoBarDismissed();
328 RemoveInfoBar(); 308 RemoveInfoBar();
329 } 309 }
330 } 310 }
331 311
332 void InfoBarView::AnimationProgressed(const ui::Animation* animation) { 312 void InfoBarView::AnimationProgressed(const ui::Animation* animation) {
(...skipping 21 matching lines...) Expand all
354 int InfoBarView::EndX() const { 334 int InfoBarView::EndX() const {
355 const int kCloseButtonSpacing = 12; 335 const int kCloseButtonSpacing = 12;
356 return close_button_->x() - kCloseButtonSpacing; 336 return close_button_->x() - kCloseButtonSpacing;
357 } 337 }
358 338
359 int InfoBarView::CenterY(const gfx::Size prefsize) const { 339 int InfoBarView::CenterY(const gfx::Size prefsize) const {
360 return std::max((target_height_ - prefsize.height()) / 2, 0); 340 return std::max((target_height_ - prefsize.height()) / 2, 0);
361 } 341 }
362 342
363 int InfoBarView::OffsetY(const gfx::Size prefsize) const { 343 int InfoBarView::OffsetY(const gfx::Size prefsize) const {
364 return CenterY(prefsize) - (target_height_ - height()); 344 return CenterY(prefsize) + preferred_tab_height() - (target_height_ -
345 preferred_bar_height());
346 }
347
348 int InfoBarView::preferred_tab_height() const {
349 return static_cast<int>(kTabHeight * animation_->GetCurrentValue());
350 }
351
352 int InfoBarView::preferred_bar_height() const {
353 return static_cast<int>(target_height_ * animation_->GetCurrentValue());
365 } 354 }
366 355
367 AccessibilityTypes::Role InfoBarView::GetAccessibleRole() { 356 AccessibilityTypes::Role InfoBarView::GetAccessibleRole() {
368 return AccessibilityTypes::ROLE_ALERT; 357 return AccessibilityTypes::ROLE_ALERT;
369 } 358 }
370 359
371 gfx::Size InfoBarView::GetPreferredSize() { 360 gfx::Size InfoBarView::GetPreferredSize() {
372 return gfx::Size(0, 361 return gfx::Size(0, preferred_tab_height() + preferred_bar_height());
373 static_cast<int>(target_height_ * animation_->GetCurrentValue())); 362 }
363
364 void InfoBarView::OnBoundsChanged() {
365 views::View::OnBoundsChanged();
366 int tab_height = preferred_tab_height();
367 int bar_height = preferred_bar_height();
368 DCHECK_EQ(tab_height + bar_height, height());
Peter Kasting 2011/03/07 20:14:30 Nit: This DCHECK seems unnecessary.
Sheridan Rawlins 2011/03/08 01:38:19 It was there to test assumption that animation wou
369
370 // Fill and stroke have different opinions about how to treat paths. Because
Peter Kasting 2011/03/07 20:14:30 Nit: This comment goes above the offset() call.
Sheridan Rawlins 2011/03/08 01:38:19 Done.
371 // in Skia integral coordinates represent pixel boundaries, offsetting the
372 // path makes it go exactly through pixel centers; this results in lines that
373 // are exactly where we expect, instead of having odd "off by one" issues.
374 // Were we to do this for |fill_path|, however, which tries to fill "inside"
375 // the path (using some questionable math), we'd get a fill at a very
376 // different place than we'd want.
377 int mirrored_x = GetMirroredXWithWidthInView(0, kTabWidth);
378 stroke_path_->rewind();
379 fill_path_->rewind();
380
381 if (tab_height) {
Peter Kasting 2011/03/07 20:14:30 Nit: You can get rid of all the conditionals in th
Sheridan Rawlins 2011/03/08 01:38:19 without these, there is some anti aliasing artifac
382 stroke_path_->moveTo(SkIntToScalar(mirrored_x),
383 SkIntToScalar(tab_height));
384 stroke_path_->rCubicTo(
385 SkScalarDiv(kCurveDistance, 2), 0.0,
386 SkScalarDiv(kCurveDistance, 2),
387 SkIntToScalar(kTabStrokeWidth - tab_height),
388 SkIntToScalar(kCurveDistance),
389 SkIntToScalar(kTabStrokeWidth - tab_height));
390 stroke_path_->rLineTo(SkIntToScalar(kTabPadding + kIconWidth), 0.0);
391 stroke_path_->rCubicTo(
392 SkScalarDiv(kCurveDistance, 2), 0.0,
393 SkScalarDiv(kCurveDistance, 2),
394 SkIntToScalar(tab_height - kTabStrokeWidth),
395 SkIntToScalar(kCurveDistance),
396 SkIntToScalar(tab_height - kTabStrokeWidth));
397
398 if (bar_height) {
399 *fill_path_ = *stroke_path_;
400 fill_path_->lineTo(SkIntToScalar(width()), SkIntToScalar(tab_height));
401 fill_path_->lineTo(SkIntToScalar(width()),
402 SkIntToScalar(height()));
403 fill_path_->lineTo(SkIntToScalar(0), SkIntToScalar(height()));
404 fill_path_->lineTo(SkIntToScalar(0), SkIntToScalar(tab_height));
405 fill_path_->close();
406 }
407
408 stroke_path_->offset(SK_ScalarHalf, -SK_ScalarHalf);
Peter Kasting 2011/03/07 20:14:30 This still is not right. You should be offsetting
Sheridan Rawlins 2011/03/08 01:38:19 If it is offset by +.5 then it draws below the lin
Sheridan Rawlins 2011/03/08 03:47:04 Ok. Figured it out. Needed to fill the 1 pixel b
409 }
410 else if (bar_height) {
411 fill_path_->addRect(SkRect::MakeXYWH(SkIntToScalar(mirrored_x),
412 SkIntToScalar(tab_height),
413 SkIntToScalar(width()),
414 SkIntToScalar(bar_height)));
415 }
374 } 416 }
375 417
376 void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) { 418 void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) {
377 // This will trigger some screen readers to read the entire contents of this 419 // This will trigger some screen readers to read the entire contents of this
378 // infobar. 420 // infobar.
379 if (focused_before && focused_now && !this->Contains(focused_before) && 421 if (focused_before && focused_now && !this->Contains(focused_before) &&
380 this->Contains(focused_now)) 422 this->Contains(focused_now))
381 NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT); 423 NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT);
382 } 424 }
383 425
384 void InfoBarView::AnimationEnded(const ui::Animation* animation) { 426 void InfoBarView::AnimationEnded(const ui::Animation* animation) {
385 if (container_ && !animation_->IsShowing()) 427 if (container_ && !animation_->IsShowing())
386 Close(); 428 Close();
387 } 429 }
388 430
389 void InfoBarView::DestroyFocusTracker(bool restore_focus) { 431 void InfoBarView::DestroyFocusTracker(bool restore_focus) {
390 if (focus_tracker_ != NULL) { 432 if (focus_tracker_ != NULL) {
391 if (restore_focus) 433 if (restore_focus)
392 focus_tracker_->FocusLastFocusedExternalView(); 434 focus_tracker_->FocusLastFocusedExternalView();
393 focus_tracker_->SetFocusManager(NULL); 435 focus_tracker_->SetFocusManager(NULL);
394 focus_tracker_.reset(); 436 focus_tracker_.reset();
395 } 437 }
396 } 438 }
397 439
398 void InfoBarView::DeleteSelf() { 440 void InfoBarView::DeleteSelf() {
399 delete this; 441 delete this;
400 } 442 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698