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

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

Issue 2247563002: Change status bubble rendering at hidpi and when there is no client edge (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments and nits Created 4 years, 3 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
« no previous file with comments | « chrome/browser/ui/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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/status_bubble_views.h" 5 #include "chrome/browser/ui/views/status_bubble_views.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/i18n/rtl.h" 10 #include "base/i18n/rtl.h"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/single_thread_task_runner.h" 13 #include "base/single_thread_task_runner.h"
14 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "build/build_config.h" 17 #include "build/build_config.h"
18 #include "chrome/browser/themes/theme_properties.h" 18 #include "chrome/browser/themes/theme_properties.h"
19 #include "components/url_formatter/elide_url.h" 19 #include "components/url_formatter/elide_url.h"
20 #include "components/url_formatter/url_formatter.h" 20 #include "components/url_formatter/url_formatter.h"
21 #include "third_party/skia/include/core/SkPaint.h" 21 #include "third_party/skia/include/core/SkPaint.h"
22 #include "third_party/skia/include/core/SkRRect.h" 22 #include "third_party/skia/include/core/SkPath.h"
23 #include "third_party/skia/include/pathops/SkPathOps.h"
23 #include "ui/base/theme_provider.h" 24 #include "ui/base/theme_provider.h"
24 #include "ui/display/display.h" 25 #include "ui/display/display.h"
25 #include "ui/display/screen.h" 26 #include "ui/display/screen.h"
26 #include "ui/gfx/animation/animation_delegate.h" 27 #include "ui/gfx/animation/animation_delegate.h"
27 #include "ui/gfx/animation/linear_animation.h" 28 #include "ui/gfx/animation/linear_animation.h"
28 #include "ui/gfx/canvas.h" 29 #include "ui/gfx/canvas.h"
29 #include "ui/gfx/font_list.h" 30 #include "ui/gfx/font_list.h"
30 #include "ui/gfx/geometry/point.h" 31 #include "ui/gfx/geometry/point.h"
31 #include "ui/gfx/geometry/rect.h" 32 #include "ui/gfx/geometry/rect.h"
32 #include "ui/gfx/skia_util.h" 33 #include "ui/gfx/skia_util.h"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 }; 129 };
129 130
130 enum BubbleStyle { 131 enum BubbleStyle {
131 STYLE_BOTTOM, 132 STYLE_BOTTOM,
132 STYLE_FLOATING, 133 STYLE_FLOATING,
133 STYLE_STANDARD, 134 STYLE_STANDARD,
134 STYLE_STANDARD_RIGHT 135 STYLE_STANDARD_RIGHT
135 }; 136 };
136 137
137 StatusView(views::Widget* popup, 138 StatusView(views::Widget* popup,
138 const ui::ThemeProvider* theme_provider); 139 const gfx::Size& popup_size_,
140 SkColor bubble_color,
141 SkColor bubble_text_color,
142 bool has_client_edge);
139 ~StatusView() override; 143 ~StatusView() override;
140 144
141 // Set the bubble text to a certain value, hides the bubble if text is 145 // Set the bubble text to a certain value, hides the bubble if text is
142 // an empty string. Trigger animation sequence to display if 146 // an empty string. Trigger animation sequence to display if
143 // |should_animate_open|. 147 // |should_animate_open|.
144 void SetText(const base::string16& text, bool should_animate_open); 148 void SetText(const base::string16& text, bool should_animate_open);
145 149
146 BubbleState state() const { return state_; } 150 BubbleState state() const { return state_; }
147 BubbleStyle style() const { return style_; } 151 BubbleStyle style() const { return style_; }
148 void SetStyle(BubbleStyle style); 152 void SetStyle(BubbleStyle style);
149 153
150 // Show the bubble instantly. 154 // Show the bubble instantly.
151 void Show(); 155 void Show();
152 156
153 // Hide the bubble instantly. 157 // Hide the bubble instantly.
154 void Hide(); 158 void Hide();
155 159
156 // Resets any timers we have. Typically called when the user moves a 160 // Resets any timers we have. Typically called when the user moves a
157 // mouse. 161 // mouse.
158 void ResetTimer(); 162 void ResetTimer();
159 163
160 // This call backs the StatusView in order to fade the bubble in and out. 164 // This call backs the StatusView in order to fade the bubble in and out.
161 void SetOpacity(float opacity); 165 void SetOpacity(float opacity);
162 166
163 // Depending on the state of the bubble this will either hide the popup or 167 // Depending on the state of the bubble this will either hide the popup or
164 // not. 168 // not.
165 void OnAnimationEnded(); 169 void OnAnimationEnded();
166 170
171 void SetWidth(int new_width);
172
167 private: 173 private:
168 class InitialTimer; 174 class InitialTimer;
169 175
170 // Manage the timers that control the delay before a fade begins or ends. 176 // Manage the timers that control the delay before a fade begins or ends.
171 void StartTimer(base::TimeDelta time); 177 void StartTimer(base::TimeDelta time);
172 void OnTimer(); 178 void OnTimer();
173 void CancelTimer(); 179 void CancelTimer();
174 void RestartTimer(base::TimeDelta delay); 180 void RestartTimer(base::TimeDelta delay);
175 181
176 // Manage the fades and starting and stopping the animations correctly. 182 // Manage the fades and starting and stopping the animations correctly.
177 void StartFade(float start, float end, int duration); 183 void StartFade(float start, float end, int duration);
178 void StartHiding(); 184 void StartHiding();
179 void StartShowing(); 185 void StartShowing();
180 186
181 // views::View: 187 // views::View:
182 const char* GetClassName() const override; 188 const char* GetClassName() const override;
183 void OnPaint(gfx::Canvas* canvas) override; 189 void OnPaint(gfx::Canvas* canvas) override;
184 190
185 BubbleState state_; 191 BubbleState state_;
186 BubbleStyle style_; 192 BubbleStyle style_;
187 193
188 std::unique_ptr<StatusViewAnimation> animation_; 194 std::unique_ptr<StatusViewAnimation> animation_;
189 195
190 // Handle to the widget that contains us. 196 // Handle to the widget that contains us.
191 views::Widget* popup_; 197 views::Widget* popup_;
192 198
193 // The currently-displayed text. 199 // The currently-displayed text.
194 base::string16 text_; 200 base::string16 text_;
195 201
196 // Holds the theme provider of the frame that created us. 202 gfx::Size popup_size_;
197 const ui::ThemeProvider* theme_provider_; 203
204 const SkColor bubble_color_;
205 const SkColor bubble_text_color_;
206 const bool has_client_edge_;
198 207
199 base::WeakPtrFactory<StatusBubbleViews::StatusView> timer_factory_; 208 base::WeakPtrFactory<StatusBubbleViews::StatusView> timer_factory_;
200 209
201 DISALLOW_COPY_AND_ASSIGN(StatusView); 210 DISALLOW_COPY_AND_ASSIGN(StatusView);
202 }; 211 };
203 212
204 StatusBubbleViews::StatusView::StatusView( 213 StatusBubbleViews::StatusView::StatusView(views::Widget* popup,
205 views::Widget* popup, 214 const gfx::Size& popup_size,
206 const ui::ThemeProvider* theme_provider) 215 SkColor bubble_color,
216 SkColor bubble_text_color,
217 bool has_client_edge)
207 : state_(BUBBLE_HIDDEN), 218 : state_(BUBBLE_HIDDEN),
208 style_(STYLE_STANDARD), 219 style_(STYLE_STANDARD),
209 animation_(new StatusViewAnimation(this, 0, 0)), 220 animation_(new StatusViewAnimation(this, 0, 0)),
210 popup_(popup), 221 popup_(popup),
211 theme_provider_(theme_provider), 222 popup_size_(popup_size),
223 bubble_color_(bubble_color),
224 bubble_text_color_(bubble_text_color),
225 has_client_edge_(has_client_edge),
212 timer_factory_(this) {} 226 timer_factory_(this) {}
213 227
214 StatusBubbleViews::StatusView::~StatusView() { 228 StatusBubbleViews::StatusView::~StatusView() {
215 animation_->Stop(); 229 animation_->Stop();
216 CancelTimer(); 230 CancelTimer();
217 } 231 }
218 232
219 void StatusBubbleViews::StatusView::SetText(const base::string16& text, 233 void StatusBubbleViews::StatusView::SetText(const base::string16& text,
220 bool should_animate_open) { 234 bool should_animate_open) {
221 if (text.empty()) { 235 if (text.empty()) {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 368
355 void StatusBubbleViews::StatusView::OnAnimationEnded() { 369 void StatusBubbleViews::StatusView::OnAnimationEnded() {
356 if (state_ == BUBBLE_HIDING_FADE) { 370 if (state_ == BUBBLE_HIDING_FADE) {
357 state_ = BUBBLE_HIDDEN; 371 state_ = BUBBLE_HIDDEN;
358 popup_->Hide(); 372 popup_->Hide();
359 } else if (state_ == BUBBLE_SHOWING_FADE) { 373 } else if (state_ == BUBBLE_SHOWING_FADE) {
360 state_ = BUBBLE_SHOWN; 374 state_ = BUBBLE_SHOWN;
361 } 375 }
362 } 376 }
363 377
378 void StatusBubbleViews::StatusView::SetWidth(int new_width) {
379 popup_size_.set_width(new_width);
380 }
381
364 const char* StatusBubbleViews::StatusView::GetClassName() const { 382 const char* StatusBubbleViews::StatusView::GetClassName() const {
365 return "StatusBubbleViews::StatusView"; 383 return "StatusBubbleViews::StatusView";
366 } 384 }
367 385
368 void StatusBubbleViews::StatusView::OnPaint(gfx::Canvas* canvas) { 386 void StatusBubbleViews::StatusView::OnPaint(gfx::Canvas* canvas) {
369 SkPaint paint; 387 canvas->Save();
370 paint.setStyle(SkPaint::kFill_Style); 388 float scale = canvas->UndoDeviceScaleFactor();
371 paint.setAntiAlias(true); 389 const float radius = kBubbleCornerRadius * scale;
372 SkColor toolbar_color = theme_provider_->GetColor(
373 ThemeProperties::COLOR_TOOLBAR);
374 paint.setColor(toolbar_color);
375
376 gfx::Rect popup_bounds = popup_->GetWindowBoundsInScreen();
377 390
378 SkScalar rad[8] = {}; 391 SkScalar rad[8] = {};
379 392
380 // Top Edges - if the bubble is in its bottom position (sticking downwards), 393 // Top Edges - if the bubble is in its bottom position (sticking downwards),
381 // then we square the top edges. Otherwise, we square the edges based on the 394 // then we square the top edges. Otherwise, we square the edges based on the
382 // position of the bubble within the window (the bubble is positioned in the 395 // position of the bubble within the window (the bubble is positioned in the
383 // southeast corner in RTL and in the southwest corner in LTR). 396 // southeast corner in RTL and in the southwest corner in LTR).
384 if (style_ != STYLE_BOTTOM) { 397 if (style_ != STYLE_BOTTOM) {
385 if (base::i18n::IsRTL() != (style_ == STYLE_STANDARD_RIGHT)) { 398 if (base::i18n::IsRTL() != (style_ == STYLE_STANDARD_RIGHT)) {
386 // The text is RtL or the bubble is on the right side (but not both). 399 // The text is RtL or the bubble is on the right side (but not both).
387 400
388 // Top Left corner. 401 // Top Left corner.
389 rad[0] = kBubbleCornerRadius; 402 rad[0] = radius;
390 rad[1] = kBubbleCornerRadius; 403 rad[1] = radius;
391 } else { 404 } else {
392 // Top Right corner. 405 // Top Right corner.
393 rad[2] = kBubbleCornerRadius; 406 rad[2] = radius;
394 rad[3] = kBubbleCornerRadius; 407 rad[3] = radius;
395 } 408 }
396 } 409 }
397 410
398 // Bottom edges - Keep these squared off if the bubble is in its standard 411 // Bottom edges - Keep these squared off if the bubble is in its standard
399 // position (sticking upward). 412 // position (sticking upward).
400 if (style_ != STYLE_STANDARD && style_ != STYLE_STANDARD_RIGHT) { 413 if (style_ != STYLE_STANDARD && style_ != STYLE_STANDARD_RIGHT) {
401 // Bottom Right Corner. 414 // Bottom Right Corner.
402 rad[4] = kBubbleCornerRadius; 415 rad[4] = radius;
403 rad[5] = kBubbleCornerRadius; 416 rad[5] = radius;
404 417
405 // Bottom Left Corner. 418 // Bottom Left Corner.
406 rad[6] = kBubbleCornerRadius; 419 rad[6] = radius;
407 rad[7] = kBubbleCornerRadius; 420 rad[7] = radius;
408 } 421 }
409 422
410 // Draw the bubble's shadow. 423 // Snap to pixels to avoid shadow blurriness.
411 int width = popup_bounds.width(); 424 const int width = std::round(popup_size_.width() * scale);
412 int height = popup_bounds.height(); 425 const int height = std::round(popup_size_.height() * scale);
Peter Kasting 2016/08/30 00:41:58 Oh, I missed that we were still rounding here. Th
Bret 2016/08/30 00:46:19 We inset to the inner pixel when aligning to pixel
413 gfx::Rect rect(gfx::Rect(popup_bounds.size()));
414 SkPaint shadow_paint;
415 shadow_paint.setAntiAlias(true);
416 shadow_paint.setColor(kShadowColor);
417 426
418 SkRRect rrect; 427 // This needs to be pixel-aligned too. Floor is perferred here because a more
419 rrect.setRectRadii(RectToSkRect(rect), (const SkVector*)rad); 428 // conservative value prevents the bottom edge from occasionally leaving a gap
420 canvas->sk_canvas()->drawRRect(rrect, shadow_paint); 429 // where the web content is visible.
430 const int shadow_thickness_pixels = std::floor(kShadowThickness * scale);
421 431
422 const int shadow_size = 2 * kShadowThickness; 432 if (!has_client_edge_) {
423 // Draw the bubble. 433 // When there's no client edge the shadow will overlap the window frame.
424 rect.SetRect(SkIntToScalar(kShadowThickness), SkIntToScalar(kShadowThickness), 434 // Clip it off when the bubble is docked. Otherwise when the bubble is
425 SkIntToScalar(width - shadow_size), 435 // floating preserve the full shadow so the bubble looks complete.
426 SkIntToScalar(height - shadow_size)); 436 const int clip_left =
427 rrect.setRectRadii(RectToSkRect(rect), (const SkVector*)rad); 437 style_ == STYLE_STANDARD ? shadow_thickness_pixels : 0;
428 canvas->sk_canvas()->drawRRect(rrect, paint); 438 const int clip_right =
439 style_ == STYLE_STANDARD_RIGHT ? shadow_thickness_pixels : 0;
440 const int clip_bottom =
441 clip_left || clip_right ? shadow_thickness_pixels : 0;
442 gfx::Rect clip_rect(clip_left, 0, width - clip_right, height - clip_bottom);
443 canvas->ClipRect(clip_rect);
444 }
445
446 gfx::RectF bubble_rect(width, height);
447 // Reposition() moves the bubble down and to the left in order to overlap the
448 // client edge (or window frame when there's no client edge) by 1 DIP. We want
449 // a 1 pixel shadow on the innermost pixel of that overlap. So we inset the
450 // bubble bounds by 1 DIP minus 1 pixel. Failing to do this results in drawing
451 // further and further outside the window as the scale increases.
452 const int inset = shadow_thickness_pixels - 1;
453 bubble_rect.Inset(style_ == STYLE_STANDARD_RIGHT ? 0 : inset, 0,
454 style_ == STYLE_STANDARD_RIGHT ? inset : 0, inset);
455 // Align to pixel centers now that the layout is correct.
456 bubble_rect.Inset(0.5, 0.5);
457
458 SkPath path;
459 path.addRoundRect(gfx::RectFToSkRect(bubble_rect), rad);
460
461 SkPaint paint;
462 paint.setStyle(SkPaint::kStroke_Style);
463 paint.setStrokeWidth(1);
464 paint.setAntiAlias(true);
465
466 SkPath stroke_path;
467 paint.getFillPath(path, &stroke_path);
468
469 // Get the fill path by subtracting the shadow so they align neatly.
470 SkPath fill_path;
471 Op(path, stroke_path, kDifference_SkPathOp, &fill_path);
472 paint.setStyle(SkPaint::kFill_Style);
473 paint.setColor(bubble_color_);
474 canvas->sk_canvas()->drawPath(fill_path, paint);
475
476 paint.setColor(kShadowColor);
477 canvas->sk_canvas()->drawPath(stroke_path, paint);
478
479 canvas->Restore();
429 480
430 // Compute text bounds. 481 // Compute text bounds.
431 const gfx::FontList font_list; 482 gfx::Rect text_rect(kTextPositionX, 0,
432 int text_width = 483 popup_size_.width() - kTextHorizPadding,
433 std::min(gfx::GetStringWidth(text_, font_list), 484 popup_size_.height());
434 width - shadow_size - kTextPositionX - kTextHorizPadding); 485 text_rect.Inset(kShadowThickness, kShadowThickness);
435 int text_height = height - shadow_size;
436 gfx::Rect text_bounds(kShadowThickness + kTextPositionX,
437 kShadowThickness,
438 std::max(0, text_width),
439 std::max(0, text_height));
440 // Make sure the text is aligned to the right on RTL UIs. 486 // Make sure the text is aligned to the right on RTL UIs.
441 text_bounds.set_x(GetMirroredXForRect(text_bounds)); 487 text_rect.set_x(GetMirroredXForRect(text_rect));
442 488
443 // Text color is the foreground tab text color at 60% alpha. 489 // Text color is the foreground tab text color at 60% alpha.
444 SkColor text_color = color_utils::AlphaBlend( 490 SkColor blended_text_color =
445 theme_provider_->GetColor(ThemeProperties::COLOR_TAB_TEXT), toolbar_color, 491 color_utils::AlphaBlend(bubble_text_color_, bubble_color_, 0x99);
446 0x99);
447 canvas->DrawStringRect( 492 canvas->DrawStringRect(
448 text_, font_list, 493 text_, gfx::FontList(),
449 color_utils::GetReadableColor(text_color, toolbar_color), text_bounds); 494 color_utils::GetReadableColor(blended_text_color, bubble_color_),
495 text_rect);
450 } 496 }
451 497
452 498
453 // StatusBubbleViews::StatusViewAnimation -------------------------------------- 499 // StatusBubbleViews::StatusViewAnimation --------------------------------------
454 500
455 StatusBubbleViews::StatusViewAnimation::StatusViewAnimation( 501 StatusBubbleViews::StatusViewAnimation::StatusViewAnimation(
456 StatusView* status_view, 502 StatusView* status_view,
457 float opacity_start, 503 float opacity_start,
458 float opacity_end) 504 float opacity_end)
459 : gfx::LinearAnimation(kFramerate, this), 505 : gfx::LinearAnimation(kFramerate, this),
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 status_view_(status_view), 544 status_view_(status_view),
499 expansion_start_(0), 545 expansion_start_(0),
500 expansion_end_(0) { 546 expansion_end_(0) {
501 } 547 }
502 548
503 // Manage the expansion of the bubble. 549 // Manage the expansion of the bubble.
504 void StartExpansion(const base::string16& expanded_text, 550 void StartExpansion(const base::string16& expanded_text,
505 int current_width, 551 int current_width,
506 int expansion_end); 552 int expansion_end);
507 553
508 // Set width of fully expanded bubble.
509 void SetExpandedWidth(int expanded_width);
510
511 private: 554 private:
512 // Animation functions. 555 // Animation functions.
513 int GetCurrentBubbleWidth(); 556 int GetCurrentBubbleWidth();
514 void SetBubbleWidth(int width); 557 void SetBubbleWidth(int width);
515 void AnimateToState(double state) override; 558 void AnimateToState(double state) override;
516 void AnimationEnded(const gfx::Animation* animation) override; 559 void AnimationEnded(const gfx::Animation* animation) override;
517 560
518 // Manager that owns us. 561 // Manager that owns us.
519 StatusBubbleViews* status_bubble_; 562 StatusBubbleViews* status_bubble_;
520 563
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 void StatusBubbleViews::StatusViewExpander::SetBubbleWidth(int width) { 605 void StatusBubbleViews::StatusViewExpander::SetBubbleWidth(int width) {
563 status_bubble_->SetBubbleWidth(width); 606 status_bubble_->SetBubbleWidth(width);
564 status_view_->SchedulePaint(); 607 status_view_->SchedulePaint();
565 } 608 }
566 609
567 610
568 // StatusBubbleViews ----------------------------------------------------------- 611 // StatusBubbleViews -----------------------------------------------------------
569 612
570 const int StatusBubbleViews::kShadowThickness = 1; 613 const int StatusBubbleViews::kShadowThickness = 1;
571 614
572 StatusBubbleViews::StatusBubbleViews(views::View* base_view) 615 StatusBubbleViews::StatusBubbleViews(views::View* base_view,
616 bool has_client_edge)
573 : contains_mouse_(false), 617 : contains_mouse_(false),
574 offset_(0), 618 offset_(0),
575 base_view_(base_view), 619 base_view_(base_view),
576 view_(NULL), 620 view_(NULL),
577 download_shelf_is_visible_(false), 621 download_shelf_is_visible_(false),
578 is_expanded_(false), 622 is_expanded_(false),
623 has_client_edge_(has_client_edge),
579 expand_timer_factory_(this) { 624 expand_timer_factory_(this) {
580 expand_view_.reset(); 625 expand_view_.reset();
581 } 626 }
582 627
583 StatusBubbleViews::~StatusBubbleViews() { 628 StatusBubbleViews::~StatusBubbleViews() {
584 CancelExpandTimer(); 629 CancelExpandTimer();
585 if (popup_.get()) 630 if (popup_.get())
586 popup_->CloseNow(); 631 popup_->CloseNow();
587 } 632 }
588 633
589 void StatusBubbleViews::Init() { 634 void StatusBubbleViews::Init() {
590 if (!popup_.get()) { 635 if (!popup_.get()) {
591 popup_.reset(new views::Widget); 636 popup_.reset(new views::Widget);
592 views::Widget* frame = base_view_->GetWidget(); 637 views::Widget* frame = base_view_->GetWidget();
593 if (!view_) 638 if (!view_) {
594 view_ = new StatusView(popup_.get(), frame->GetThemeProvider()); 639 const ui::ThemeProvider* theme_provider = frame->GetThemeProvider();
640 view_ = new StatusView(
641 popup_.get(), size_,
642 theme_provider->GetColor(ThemeProperties::COLOR_TOOLBAR),
643 theme_provider->GetColor(ThemeProperties::COLOR_TAB_TEXT),
644 has_client_edge_);
645 }
595 if (!expand_view_.get()) 646 if (!expand_view_.get())
596 expand_view_.reset(new StatusViewExpander(this, view_)); 647 expand_view_.reset(new StatusViewExpander(this, view_));
597 648
598 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); 649 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
599 #if defined(OS_WIN) 650 #if defined(OS_WIN)
600 // On Windows use the software compositor to ensure that we don't block 651 // On Windows use the software compositor to ensure that we don't block
601 // the UI thread blocking issue during command buffer creation. We can 652 // the UI thread blocking issue during command buffer creation. We can
602 // revert this change once http://crbug.com/125248 is fixed. 653 // revert this change once http://crbug.com/125248 is fixed.
603 params.force_software_compositing = true; 654 params.force_software_compositing = true;
604 #endif 655 #endif
(...skipping 14 matching lines...) Expand all
619 popup_->SetContentsView(view_); 670 popup_->SetContentsView(view_);
620 #if defined(USE_ASH) 671 #if defined(USE_ASH)
621 ash::wm::GetWindowState(popup_->GetNativeWindow())-> 672 ash::wm::GetWindowState(popup_->GetNativeWindow())->
622 set_ignored_by_shelf(true); 673 set_ignored_by_shelf(true);
623 #endif 674 #endif
624 RepositionPopup(); 675 RepositionPopup();
625 } 676 }
626 } 677 }
627 678
628 void StatusBubbleViews::Reposition() { 679 void StatusBubbleViews::Reposition() {
629 // In restored mode, the client area has a client edge between it and the 680 // Overlap the client edge that's shown in restored mode, or when there is no
630 // frame. 681 // client edge this makes the bubble snug with the corner of the window.
631 int overlap = kShadowThickness; 682 int overlap = kShadowThickness;
632 int height = GetPreferredSize().height(); 683 int height = GetPreferredSize().height();
633 int base_view_height = base_view()->bounds().height(); 684 int base_view_height = base_view()->bounds().height();
634 gfx::Point origin(-overlap, base_view_height - height + overlap); 685 gfx::Point origin(-overlap, base_view_height - height + overlap);
635 SetBounds(origin.x(), origin.y(), base_view()->bounds().width() / 3, height); 686 SetBounds(origin.x(), origin.y(), base_view()->bounds().width() / 3, height);
636 } 687 }
637 688
638 void StatusBubbleViews::RepositionPopup() { 689 void StatusBubbleViews::RepositionPopup() {
639 if (popup_.get()) { 690 if (popup_.get()) {
640 gfx::Point top_left; 691 gfx::Point top_left;
641 // TODO(flackr): Get the non-transformed point so that the status bubble 692 // TODO(flackr): Get the non-transformed point so that the status bubble
642 // popup window's position is consistent with the base_view_'s window. 693 // popup window's position is consistent with the base_view_'s window.
643 views::View::ConvertPointToScreen(base_view_, &top_left); 694 views::View::ConvertPointToScreen(base_view_, &top_left);
644 695
696 view_->SetWidth(size_.width());
645 popup_->SetBounds(gfx::Rect(top_left.x() + position_.x(), 697 popup_->SetBounds(gfx::Rect(top_left.x() + position_.x(),
646 top_left.y() + position_.y(), 698 top_left.y() + position_.y(),
647 size_.width(), size_.height())); 699 size_.width(), size_.height()));
648 } 700 }
649 } 701 }
650 702
651 gfx::Size StatusBubbleViews::GetPreferredSize() { 703 gfx::Size StatusBubbleViews::GetPreferredSize() {
652 return gfx::Size(0, gfx::FontList().GetHeight() + kTotalVerticalPadding); 704 return gfx::Size(0, gfx::FontList().GetHeight() + kTotalVerticalPadding);
653 } 705 }
654 706
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 return; 751 return;
700 } 752 }
701 753
702 // Reset expansion state only when bubble is completely hidden. 754 // Reset expansion state only when bubble is completely hidden.
703 if (view_->state() == StatusView::BUBBLE_HIDDEN) { 755 if (view_->state() == StatusView::BUBBLE_HIDDEN) {
704 is_expanded_ = false; 756 is_expanded_ = false;
705 SetBubbleWidth(GetStandardStatusBubbleWidth()); 757 SetBubbleWidth(GetStandardStatusBubbleWidth());
706 } 758 }
707 759
708 // Set Elided Text corresponding to the GURL object. 760 // Set Elided Text corresponding to the GURL object.
709 gfx::Rect popup_bounds = popup_->GetWindowBoundsInScreen(); 761 int text_width = static_cast<int>(size_.width() - (kShadowThickness * 2) -
710 int text_width = static_cast<int>(popup_bounds.width() - 762 kTextPositionX - kTextHorizPadding - 1);
711 (kShadowThickness * 2) - kTextPositionX - kTextHorizPadding - 1);
712 url_text_ = 763 url_text_ =
713 url_formatter::ElideUrl(url, gfx::FontList(), text_width); 764 url_formatter::ElideUrl(url, gfx::FontList(), text_width);
714 765
715 // An URL is always treated as a left-to-right string. On right-to-left UIs 766 // An URL is always treated as a left-to-right string. On right-to-left UIs
716 // we need to explicitly mark the URL as LTR to make sure it is displayed 767 // we need to explicitly mark the URL as LTR to make sure it is displayed
717 // correctly. 768 // correctly.
718 url_text_ = base::i18n::GetDisplayStringInLTRDirectionality(url_text_); 769 url_text_ = base::i18n::GetDisplayStringInLTRDirectionality(url_text_);
719 770
720 if (IsFrameVisible()) { 771 if (IsFrameVisible()) {
721 view_->SetText(url_text_, true); 772 view_->SetText(url_text_, true);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 916
866 bool StatusBubbleViews::IsFrameMaximized() { 917 bool StatusBubbleViews::IsFrameMaximized() {
867 views::Widget* frame = base_view_->GetWidget(); 918 views::Widget* frame = base_view_->GetWidget();
868 views::Widget* window = frame->GetTopLevelWidget(); 919 views::Widget* window = frame->GetTopLevelWidget();
869 return window && window->IsMaximized(); 920 return window && window->IsMaximized();
870 } 921 }
871 922
872 void StatusBubbleViews::ExpandBubble() { 923 void StatusBubbleViews::ExpandBubble() {
873 // Elide URL to maximum possible size, then check actual length (it may 924 // Elide URL to maximum possible size, then check actual length (it may
874 // still be too long to fit) before expanding bubble. 925 // still be too long to fit) before expanding bubble.
875 gfx::Rect popup_bounds = popup_->GetWindowBoundsInScreen();
876 int max_status_bubble_width = GetMaxStatusBubbleWidth(); 926 int max_status_bubble_width = GetMaxStatusBubbleWidth();
877 const gfx::FontList font_list; 927 const gfx::FontList font_list;
878 url_text_ = url_formatter::ElideUrl(url_, font_list, max_status_bubble_width); 928 url_text_ = url_formatter::ElideUrl(url_, font_list, max_status_bubble_width);
879 int expanded_bubble_width = 929 int expanded_bubble_width =
880 std::max(GetStandardStatusBubbleWidth(), 930 std::max(GetStandardStatusBubbleWidth(),
881 std::min(gfx::GetStringWidth(url_text_, font_list) + 931 std::min(gfx::GetStringWidth(url_text_, font_list) +
882 (kShadowThickness * 2) + kTextPositionX + 932 (kShadowThickness * 2) + kTextPositionX +
883 kTextHorizPadding + 1, 933 kTextHorizPadding + 1,
884 max_status_bubble_width)); 934 max_status_bubble_width));
885 is_expanded_ = true; 935 is_expanded_ = true;
886 expand_view_->StartExpansion(url_text_, popup_bounds.width(), 936 expand_view_->StartExpansion(url_text_, size_.width(), expanded_bubble_width);
887 expanded_bubble_width);
888 } 937 }
889 938
890 int StatusBubbleViews::GetStandardStatusBubbleWidth() { 939 int StatusBubbleViews::GetStandardStatusBubbleWidth() {
891 return base_view_->bounds().width() / 3; 940 return base_view_->bounds().width() / 3;
892 } 941 }
893 942
894 int StatusBubbleViews::GetMaxStatusBubbleWidth() { 943 int StatusBubbleViews::GetMaxStatusBubbleWidth() {
895 const ui::NativeTheme* theme = base_view_->GetNativeTheme(); 944 const ui::NativeTheme* theme = base_view_->GetNativeTheme();
896 return static_cast<int>(std::max(0, base_view_->bounds().width() - 945 return static_cast<int>(std::max(0, base_view_->bounds().width() -
897 (kShadowThickness * 2) - kTextPositionX - kTextHorizPadding - 1 - 946 (kShadowThickness * 2) - kTextPositionX - kTextHorizPadding - 1 -
898 views::NativeScrollBar::GetVerticalScrollBarWidth(theme))); 947 views::NativeScrollBar::GetVerticalScrollBarWidth(theme)));
899 } 948 }
900 949
901 void StatusBubbleViews::SetBubbleWidth(int width) { 950 void StatusBubbleViews::SetBubbleWidth(int width) {
902 size_.set_width(width); 951 size_.set_width(width);
903 SetBounds(original_position_.x(), original_position_.y(), 952 SetBounds(original_position_.x(), original_position_.y(),
904 size_.width(), size_.height()); 953 size_.width(), size_.height());
905 } 954 }
906 955
907 void StatusBubbleViews::CancelExpandTimer() { 956 void StatusBubbleViews::CancelExpandTimer() {
908 if (expand_timer_factory_.HasWeakPtrs()) 957 if (expand_timer_factory_.HasWeakPtrs())
909 expand_timer_factory_.InvalidateWeakPtrs(); 958 expand_timer_factory_.InvalidateWeakPtrs();
910 } 959 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/status_bubble_views.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698