15e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// found in the LICENSE file. 45e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 55e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "ui/views/controls/scrollbar/overlay_scroll_bar.h" 65e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 75e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "third_party/skia/include/core/SkColor.h" 85e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "third_party/skia/include/core/SkXfermode.h" 95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "ui/gfx/canvas.h" 105e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "ui/views/background.h" 115e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "ui/views/border.h" 125e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "ui/views/controls/scrollbar/base_scroll_bar_thumb.h" 135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace views { 155e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace { 165e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 175e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)const int kScrollbarWidth = 10; 185e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)const int kThumbInsetInside = 3; 195e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)const int kThumbInsetFromEdge = 1; 205e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)const int kThumbCornerRadius = 2; 215e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)const int kThumbMinimumSize = kScrollbarWidth; 225e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)const int kThumbHoverAlpha = 128; 235e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)const int kThumbDefaultAlpha = 64; 245e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 255e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class OverlayScrollBarThumb : public BaseScrollBarThumb, 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public gfx::AnimationDelegate { 275e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) public: 285e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) explicit OverlayScrollBarThumb(BaseScrollBar* scroll_bar); 295e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) virtual ~OverlayScrollBarThumb(); 305e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 315e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) protected: 325e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) // View overrides: 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual gfx::Size GetPreferredSize() const OVERRIDE; 345e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; 355e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // gfx::AnimationDelegate overrides: 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; 385e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 395e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) private: 405e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) double animation_opacity_; 415e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OverlayScrollBarThumb); 425e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)}; 435e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 445e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)OverlayScrollBarThumb::OverlayScrollBarThumb(BaseScrollBar* scroll_bar) 455e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) : BaseScrollBarThumb(scroll_bar), 465e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) animation_opacity_(0.0) { 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This is necessary, otherwise the thumb will be rendered below the views if 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // those views paint to their own layers. 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SetPaintToLayer(true); 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SetFillsBoundsOpaquely(false); 515e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 525e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 535e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)OverlayScrollBarThumb::~OverlayScrollBarThumb() { 545e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 555e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size OverlayScrollBarThumb::GetPreferredSize() const { 575e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return gfx::Size(kThumbMinimumSize, kThumbMinimumSize); 585e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 595e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 605e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)void OverlayScrollBarThumb::OnPaint(gfx::Canvas* canvas) { 615e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) gfx::Rect local_bounds(GetLocalBounds()); 625e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) SkPaint paint; 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int alpha = kThumbDefaultAlpha * animation_opacity_; 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (GetState() == CustomButton::STATE_HOVERED) { 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch alpha = kThumbHoverAlpha * animation_opacity_; 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if(GetState() == CustomButton::STATE_PRESSED) { 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If we are in pressed state, no need to worry about animation, 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // just display the deeper color. 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch alpha = kThumbHoverAlpha; 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 725e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) paint.setStyle(SkPaint::kFill_Style); 735e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) paint.setColor(SkColorSetARGB(alpha, 0, 0, 0)); 745e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) canvas->DrawRoundRect(local_bounds, kThumbCornerRadius, paint); 755e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 765e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 775e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)void OverlayScrollBarThumb::AnimationProgressed( 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const gfx::Animation* animation) { 795e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) animation_opacity_ = animation->GetCurrentValue(); 805e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) SchedulePaint(); 815e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 825e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 835e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} // namespace 845e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 855e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)OverlayScrollBar::OverlayScrollBar(bool horizontal) 865e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) : BaseScrollBar(horizontal, new OverlayScrollBarThumb(this)), 875e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) animation_(static_cast<OverlayScrollBarThumb*>(GetThumb())) { 885e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) set_notify_enter_exit_on_child(true); 895e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 905e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 915e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)OverlayScrollBar::~OverlayScrollBar() { 925e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 935e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 945e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)gfx::Rect OverlayScrollBar::GetTrackBounds() const { 955e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) gfx::Rect local_bounds(GetLocalBounds()); 965e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (IsHorizontal()) { 975e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) local_bounds.Inset(kThumbInsetFromEdge, kThumbInsetInside, 985e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) kThumbInsetFromEdge, kThumbInsetFromEdge); 995e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) } else { 1005e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) local_bounds.Inset(kThumbInsetInside, kThumbInsetFromEdge, 1015e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) kThumbInsetFromEdge, kThumbInsetFromEdge); 1025e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) } 1035e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) gfx::Size track_size = local_bounds.size(); 1045e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) track_size.SetToMax(GetThumb()->size()); 1055e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) local_bounds.set_size(track_size); 1065e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return local_bounds; 1075e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 1085e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 1095e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)int OverlayScrollBar::GetLayoutSize() const { 1105e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return 0; 1115e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 1125e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 1135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)int OverlayScrollBar::GetContentOverlapSize() const { 1145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return kScrollbarWidth; 1155e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 1165e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 1175e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)void OverlayScrollBar::OnMouseEnteredScrollView(const ui::MouseEvent& event) { 1185e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) animation_.Show(); 1195e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 1205e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 1215e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)void OverlayScrollBar::OnMouseExitedScrollView(const ui::MouseEvent& event) { 1225e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) animation_.Hide(); 1235e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 1245e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OverlayScrollBar::OnGestureEvent(ui::GestureEvent* event) { 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch switch (event->type()) { 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case ui::ET_GESTURE_SCROLL_BEGIN: 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch animation_.Show(); 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case ui::ET_GESTURE_SCROLL_END: 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case ui::ET_SCROLL_FLING_START: 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case ui::ET_GESTURE_END: 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch animation_.Hide(); 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default: 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BaseScrollBar::OnGestureEvent(event); 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size OverlayScrollBar::GetPreferredSize() const { 1425e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return gfx::Size(); 1435e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 1445e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 1455e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)void OverlayScrollBar::Layout() { 1465e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) gfx::Rect thumb_bounds = GetTrackBounds(); 1475e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) BaseScrollBarThumb* thumb = GetThumb(); 1485e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (IsHorizontal()) { 1495e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) thumb_bounds.set_x(thumb->x()); 1505e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) thumb_bounds.set_width(thumb->width()); 1515e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) } else { 1525e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) thumb_bounds.set_y(thumb->y()); 1535e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) thumb_bounds.set_height(thumb->height()); 1545e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) } 1555e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) thumb->SetBoundsRect(thumb_bounds); 1565e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 1575e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 1585e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)void OverlayScrollBar::OnPaint(gfx::Canvas* canvas) { 1595e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 1605e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 1615e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} // namespace views 162