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

Side by Side Diff: chrome/browser/views/status_bubble_views.cc

Issue 67059: Fix status bubble shadow being opaque, which made the bubble appear to be off... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 8 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
« no previous file with comments | « chrome/browser/views/status_bubble_views.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/views/status_bubble_views.h" 5 #include "chrome/browser/views/status_bubble_views.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "chrome/common/animation.h" 10 #include "chrome/common/animation.h"
11 #include "chrome/common/gfx/chrome_canvas.h" 11 #include "chrome/common/gfx/chrome_canvas.h"
12 #include "chrome/common/gfx/text_elider.h" 12 #include "chrome/common/gfx/text_elider.h"
13 #include "chrome/common/l10n_util.h" 13 #include "chrome/common/l10n_util.h"
14 #include "chrome/common/l10n_util_win.h" 14 #include "chrome/common/l10n_util_win.h"
15 #include "chrome/common/resource_bundle.h" 15 #include "chrome/common/resource_bundle.h"
16 #include "chrome/views/controls/label.h" 16 #include "chrome/views/controls/label.h"
17 #include "chrome/views/widget/root_view.h" 17 #include "chrome/views/widget/root_view.h"
18 #include "chrome/views/widget/widget_win.h" 18 #include "chrome/views/widget/widget_win.h"
19 #include "googleurl/src/gurl.h" 19 #include "googleurl/src/gurl.h"
20 #include "grit/generated_resources.h" 20 #include "grit/generated_resources.h"
21 #include "grit/theme_resources.h" 21 #include "grit/theme_resources.h"
22 #include "net/base/net_util.h" 22 #include "net/base/net_util.h"
23 #include "SkPaint.h" 23 #include "SkPaint.h"
24 #include "SkPath.h" 24 #include "SkPath.h"
25 #include "SkRect.h" 25 #include "SkRect.h"
26 26
27 // The color of the background bubble. 27 // The color of the background bubble.
28 static const SkColor kBubbleColor = SkColorSetRGB(222, 234, 248); 28 static const SkColor kBubbleColor = SkColorSetRGB(222, 234, 248);
29 29
30 // The alpha and color of the bubble's shadow. This is a composite of the above 30 // The alpha and color of the bubble's shadow.
31 // background color with 30% gray. 31 static const SkColor kShadowColor = SkColorSetARGB(30, 0, 0, 0);
32 static const SkColor kShadowColor = SkColorSetRGB(196, 206, 212);
33
34 // How wide the bubble's shadow is.
35 static const int kShadowSize = 1;
36 32
37 // The roundedness of the edges of our bubble. 33 // The roundedness of the edges of our bubble.
38 static const int kBubbleCornerRadius = 4; 34 static const int kBubbleCornerRadius = 4;
39 35
40 // How close the mouse can get to the infobubble before it starts sliding 36 // How close the mouse can get to the infobubble before it starts sliding
41 // off-screen. 37 // off-screen.
42 static const int kMousePadding = 20; 38 static const int kMousePadding = 20;
43 39
44 // The color of the text 40 // The color of the text
45 static const SkColor kTextColor = SkColorSetRGB(100, 100, 100); 41 static const SkColor kTextColor = SkColorSetRGB(100, 100, 100);
46 42
47 // The color of the highlight text 43 // The color of the highlight text
48 static const SkColor kTextHighlightColor = SkColorSetRGB(242, 250, 255); 44 static const SkColor kTextHighlightColor = SkColorSetRGB(242, 250, 255);
49 45
50 static const int kTextPadding = 3; 46 // The horizontal offset of the text within the status bubble, not including the
51 static const int kTextPositionX = 4; 47 // outer shadow ring.
52 static const int kTextPositionY = 1; 48 static const int kTextPositionX = 3;
49
50 // The minimum horizontal space between the (right) end of the text and the edge
51 // of the status bubble, not including the outer shadow ring, or a 1 px gap we
52 // leave so we can shit all the text by 1 px to produce a "highlight" effect.
53 static const int kTextHorizPadding = 1;
53 54
54 // Delays before we start hiding or showing the bubble after we receive a 55 // Delays before we start hiding or showing the bubble after we receive a
55 // show or hide request. 56 // show or hide request.
56 static const int kShowDelay = 80; 57 static const int kShowDelay = 80;
57 static const int kHideDelay = 250; 58 static const int kHideDelay = 250;
58 59
59 // How long each fade should last for. 60 // How long each fade should last for.
60 static const int kShowFadeDurationMS = 120; 61 static const int kShowFadeDurationMS = 120;
61 static const int kHideFadeDurationMS = 200; 62 static const int kHideFadeDurationMS = 200;
62 static const int kFramerate = 25; 63 static const int kFramerate = 25;
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 320
320 void StatusBubbleViews::StatusView::Paint(ChromeCanvas* canvas) { 321 void StatusBubbleViews::StatusView::Paint(ChromeCanvas* canvas) {
321 SkPaint paint; 322 SkPaint paint;
322 paint.setStyle(SkPaint::kFill_Style); 323 paint.setStyle(SkPaint::kFill_Style);
323 paint.setFlags(SkPaint::kAntiAlias_Flag); 324 paint.setFlags(SkPaint::kAntiAlias_Flag);
324 paint.setColor(kBubbleColor); 325 paint.setColor(kBubbleColor);
325 326
326 RECT parent_rect; 327 RECT parent_rect;
327 ::GetWindowRect(popup_->GetNativeView(), &parent_rect); 328 ::GetWindowRect(popup_->GetNativeView(), &parent_rect);
328 329
329 // Draw our background.
330 SkRect rect;
331 int width = parent_rect.right - parent_rect.left;
332 int height = parent_rect.bottom - parent_rect.top;
333
334 // Figure out how to round the bubble's four corners. 330 // Figure out how to round the bubble's four corners.
335 SkScalar rad[8]; 331 SkScalar rad[8];
336 332
337 // Top Edges - if the bubble is in its bottom position (sticking downwards), 333 // Top Edges - if the bubble is in its bottom position (sticking downwards),
338 // then we square the top edges. Otherwise, we square the edges based on the 334 // then we square the top edges. Otherwise, we square the edges based on the
339 // position of the bubble within the window (the bubble is positioned in the 335 // position of the bubble within the window (the bubble is positioned in the
340 // southeast corner in RTL and in the southwest corner in LTR). 336 // southeast corner in RTL and in the southwest corner in LTR).
341 if (style_ == STYLE_BOTTOM) { 337 if (style_ == STYLE_BOTTOM) {
342 // Top Left corner. 338 // Top Left corner.
343 rad[0] = 0; 339 rad[0] = 0;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 // Bottom Right Corner. 376 // Bottom Right Corner.
381 rad[4] = SkIntToScalar(kBubbleCornerRadius); 377 rad[4] = SkIntToScalar(kBubbleCornerRadius);
382 rad[5] = SkIntToScalar(kBubbleCornerRadius); 378 rad[5] = SkIntToScalar(kBubbleCornerRadius);
383 379
384 // Bottom Left Corner. 380 // Bottom Left Corner.
385 rad[6] = SkIntToScalar(kBubbleCornerRadius); 381 rad[6] = SkIntToScalar(kBubbleCornerRadius);
386 rad[7] = SkIntToScalar(kBubbleCornerRadius); 382 rad[7] = SkIntToScalar(kBubbleCornerRadius);
387 } 383 }
388 384
389 // Draw the bubble's shadow. 385 // Draw the bubble's shadow.
386 int width = parent_rect.right - parent_rect.left;
387 int height = parent_rect.bottom - parent_rect.top;
388 SkRect rect;
389 rect.set(0, 0,
390 SkIntToScalar(width),
391 SkIntToScalar(height));
392 SkPath shadow_path;
393 shadow_path.addRoundRect(rect, rad, SkPath::kCW_Direction);
390 SkPaint shadow_paint; 394 SkPaint shadow_paint;
391 shadow_paint.setFlags(SkPaint::kAntiAlias_Flag); 395 shadow_paint.setFlags(SkPaint::kAntiAlias_Flag);
392 shadow_paint.setColor(kShadowColor); 396 shadow_paint.setColor(kShadowColor);
393
394 rect.set(0, 0,
395 SkIntToScalar(width),
396 SkIntToScalar(height));
397
398 SkPath shadow_path;
399 shadow_path.addRoundRect(rect, rad, SkPath::kCW_Direction);
400 canvas->drawPath(shadow_path, shadow_paint); 397 canvas->drawPath(shadow_path, shadow_paint);
401 398
402 // Draw the bubble. 399 // Draw the bubble.
400 rect.set(SkIntToScalar(kShadowThickness),
401 SkIntToScalar(kShadowThickness),
402 SkIntToScalar(width - kShadowThickness),
403 SkIntToScalar(height - kShadowThickness));
403 SkPath path; 404 SkPath path;
404 rect.set(SkIntToScalar(kShadowSize),
405 SkIntToScalar(kShadowSize),
406 SkIntToScalar(width - kShadowSize),
407 SkIntToScalar(height - kShadowSize));
408
409 path.addRoundRect(rect, rad, SkPath::kCW_Direction); 405 path.addRoundRect(rect, rad, SkPath::kCW_Direction);
410 canvas->drawPath(path, paint); 406 canvas->drawPath(path, paint);
411 407
412
413 int text_width = std::min(static_cast<int>(parent_rect.right -
414 parent_rect.left - kTextPositionX -
415 kTextPadding),
416 static_cast<int>(views::Label::GetFont()
417 .GetStringWidth(text_)));
418
419 // Draw highlight text and then the text body. In order to make sure the text 408 // Draw highlight text and then the text body. In order to make sure the text
420 // is aligned to the right on RTL UIs, we mirror the text bounds if the 409 // is aligned to the right on RTL UIs, we mirror the text bounds if the
421 // locale is RTL. 410 // locale is RTL.
422 gfx::Rect body_bounds(kTextPositionX, 411 // The "- 1" on the end of the width and height ensures that when we add one
423 kTextPositionY, 412 // to x() and y() for the highlight text, we still won't overlap the shadow.
413 int text_width = std::min(views::Label::GetFont().GetStringWidth(text_),
414 width - (kShadowThickness * 2) - kTextPositionX - kTextHorizPadding - 1);
415 gfx::Rect body_bounds(kShadowThickness + kTextPositionX,
416 kShadowThickness,
424 text_width, 417 text_width,
425 parent_rect.bottom - parent_rect.top); 418 height - (kShadowThickness * 2) - 1);
426 body_bounds.set_x(MirroredLeftPointForRect(body_bounds)); 419 body_bounds.set_x(MirroredLeftPointForRect(body_bounds));
427 canvas->DrawStringInt(text_, 420 canvas->DrawStringInt(text_,
428 views::Label::GetFont(), 421 views::Label::GetFont(),
429 kTextHighlightColor, 422 kTextHighlightColor,
430 body_bounds.x() + 1, 423 body_bounds.x() + 1,
431 body_bounds.y() + 1, 424 body_bounds.y() + 1,
432 body_bounds.width(), 425 body_bounds.width(),
433 body_bounds.height()); 426 body_bounds.height());
434 427
435 canvas->DrawStringInt(text_, 428 canvas->DrawStringInt(text_,
436 views::Label::GetFont(), 429 views::Label::GetFont(),
437 kTextColor, 430 kTextColor,
438 body_bounds.x(), 431 body_bounds.x(),
439 body_bounds.y(), 432 body_bounds.y(),
440 body_bounds.width(), 433 body_bounds.width(),
441 body_bounds.height()); 434 body_bounds.height());
442 } 435 }
443 436
444 // StatusBubble --------------------------------------------------------------- 437 // StatusBubble ---------------------------------------------------------------
445 438
439 const int StatusBubbleViews::kShadowThickness = 1;
440
446 StatusBubbleViews::StatusBubbleViews(views::Widget* frame) 441 StatusBubbleViews::StatusBubbleViews(views::Widget* frame)
447 : popup_(NULL), 442 : popup_(NULL),
448 frame_(frame), 443 frame_(frame),
449 view_(NULL), 444 view_(NULL),
450 opacity_(0), 445 opacity_(0),
451 position_(0, 0), 446 position_(0, 0),
452 size_(0, 0), 447 size_(0, 0),
453 offset_(0) { 448 offset_(0) {
454 } 449 }
455 450
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 // display, display that status instead. 501 // display, display that status instead.
507 if (url.is_empty() && !status_text_.empty()) { 502 if (url.is_empty() && !status_text_.empty()) {
508 url_text_ = std::wstring(); 503 url_text_ = std::wstring();
509 view_->SetText(status_text_); 504 view_->SetText(status_text_);
510 return; 505 return;
511 } 506 }
512 507
513 // Set Elided Text corresponding to the GURL object. 508 // Set Elided Text corresponding to the GURL object.
514 RECT parent_rect; 509 RECT parent_rect;
515 ::GetWindowRect(popup_->GetNativeView(), &parent_rect); 510 ::GetWindowRect(popup_->GetNativeView(), &parent_rect);
516 int text_width = static_cast<int>(parent_rect.right - 511 int text_width = static_cast<int>(parent_rect.right - parent_rect.left -
517 parent_rect.left - kTextPositionX - 512 (kShadowThickness * 2) - kTextPositionX - kTextHorizPadding - 1);
518 kTextPadding);
519 url_text_ = gfx::ElideUrl(url, view_->Label::GetFont(), text_width, 513 url_text_ = gfx::ElideUrl(url, view_->Label::GetFont(), text_width,
520 languages); 514 languages);
521 515
522 // An URL is always treated as a left-to-right string. On right-to-left UIs 516 // An URL is always treated as a left-to-right string. On right-to-left UIs
523 // we need to explicitly mark the URL as LTR to make sure it is displayed 517 // we need to explicitly mark the URL as LTR to make sure it is displayed
524 // correctly. 518 // correctly.
525 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT && 519 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT &&
526 !url_text_.empty()) 520 !url_text_.empty())
527 l10n_util::WrapStringWithLTRFormatting(&url_text_); 521 l10n_util::WrapStringWithLTRFormatting(&url_text_);
528 view_->SetText(url_text_); 522 view_->SetText(url_text_);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 if (cursor_location.x > size_.cx) { 570 if (cursor_location.x > size_.cx) {
577 offset = static_cast<int>(static_cast<float>(offset) * ( 571 offset = static_cast<int>(static_cast<float>(offset) * (
578 static_cast<float>(kMousePadding - 572 static_cast<float>(kMousePadding -
579 (cursor_location.x - size_.cx)) / 573 (cursor_location.x - size_.cx)) /
580 static_cast<float>(kMousePadding))); 574 static_cast<float>(kMousePadding)));
581 } 575 }
582 576
583 // Cap the offset and change the visual presentation of the bubble 577 // Cap the offset and change the visual presentation of the bubble
584 // depending on where it ends up (so that rounded corners square off 578 // depending on where it ends up (so that rounded corners square off
585 // and mate to the edges of the tab content). 579 // and mate to the edges of the tab content).
586 if (offset >= size_.cy - kShadowSize * 2) { 580 if (offset >= size_.cy - kShadowThickness * 2) {
587 offset = size_.cy - kShadowSize * 2; 581 offset = size_.cy - kShadowThickness * 2;
588 view_->SetStyle(StatusView::STYLE_BOTTOM); 582 view_->SetStyle(StatusView::STYLE_BOTTOM);
589 } else if (offset > kBubbleCornerRadius / 2 - kShadowSize) { 583 } else if (offset > kBubbleCornerRadius / 2 - kShadowThickness) {
590 view_->SetStyle(StatusView::STYLE_FLOATING); 584 view_->SetStyle(StatusView::STYLE_FLOATING);
591 } else { 585 } else {
592 view_->SetStyle(StatusView::STYLE_STANDARD); 586 view_->SetStyle(StatusView::STYLE_STANDARD);
593 } 587 }
594 588
595 offset_ = offset; 589 offset_ = offset;
596 popup_->MoveWindow(top_left.x() + position_.x, 590 popup_->MoveWindow(top_left.x() + position_.x,
597 top_left.y() + position_.y + offset_, 591 top_left.y() + position_.y + offset_,
598 size_.cx, 592 size_.cx,
599 size_.cy); 593 size_.cy);
(...skipping 27 matching lines...) Expand all
627 frame_->GetBounds(&frame_bounds, false); 621 frame_->GetBounds(&frame_bounds, false);
628 int mirrored_x = frame_bounds.width() - x - w; 622 int mirrored_x = frame_bounds.width() - x - w;
629 position_.SetPoint(mirrored_x, y); 623 position_.SetPoint(mirrored_x, y);
630 } else { 624 } else {
631 position_.SetPoint(x, y); 625 position_.SetPoint(x, y);
632 } 626 }
633 627
634 size_.SetSize(w, h); 628 size_.SetSize(w, h);
635 Reposition(); 629 Reposition();
636 } 630 }
OLDNEW
« no previous file with comments | « chrome/browser/views/status_bubble_views.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698