• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
6 
7 #include "third_party/skia/include/core/SkColor.h"
8 #include "third_party/skia/include/core/SkXfermode.h"
9 #include "ui/gfx/canvas.h"
10 #include "ui/views/background.h"
11 #include "ui/views/border.h"
12 #include "ui/views/controls/scrollbar/base_scroll_bar_thumb.h"
13 
14 namespace views {
15 namespace {
16 
17 const int kScrollbarWidth = 10;
18 const int kThumbInsetInside = 3;
19 const int kThumbInsetFromEdge = 1;
20 const int kThumbCornerRadius = 2;
21 const int kThumbMinimumSize = kScrollbarWidth;
22 const int kThumbHoverAlpha = 128;
23 const int kThumbDefaultAlpha = 64;
24 
25 class OverlayScrollBarThumb : public BaseScrollBarThumb,
26                               public gfx::AnimationDelegate {
27  public:
28   explicit OverlayScrollBarThumb(BaseScrollBar* scroll_bar);
29   virtual ~OverlayScrollBarThumb();
30 
31  protected:
32   // View overrides:
33   virtual gfx::Size GetPreferredSize() const OVERRIDE;
34   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
35 
36   // gfx::AnimationDelegate overrides:
37   virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
38 
39  private:
40   double animation_opacity_;
41   DISALLOW_COPY_AND_ASSIGN(OverlayScrollBarThumb);
42 };
43 
OverlayScrollBarThumb(BaseScrollBar * scroll_bar)44 OverlayScrollBarThumb::OverlayScrollBarThumb(BaseScrollBar* scroll_bar)
45     : BaseScrollBarThumb(scroll_bar),
46       animation_opacity_(0.0) {
47   // This is necessary, otherwise the thumb will be rendered below the views if
48   // those views paint to their own layers.
49   SetPaintToLayer(true);
50   SetFillsBoundsOpaquely(false);
51 }
52 
~OverlayScrollBarThumb()53 OverlayScrollBarThumb::~OverlayScrollBarThumb() {
54 }
55 
GetPreferredSize() const56 gfx::Size OverlayScrollBarThumb::GetPreferredSize() const {
57   return gfx::Size(kThumbMinimumSize, kThumbMinimumSize);
58 }
59 
OnPaint(gfx::Canvas * canvas)60 void OverlayScrollBarThumb::OnPaint(gfx::Canvas* canvas) {
61   gfx::Rect local_bounds(GetLocalBounds());
62   SkPaint paint;
63   int alpha = kThumbDefaultAlpha * animation_opacity_;
64   if (GetState() == CustomButton::STATE_HOVERED) {
65     alpha = kThumbHoverAlpha * animation_opacity_;
66   } else if(GetState() == CustomButton::STATE_PRESSED) {
67     // If we are in pressed state, no need to worry about animation,
68     // just display the deeper color.
69     alpha = kThumbHoverAlpha;
70   }
71 
72   paint.setStyle(SkPaint::kFill_Style);
73   paint.setColor(SkColorSetARGB(alpha, 0, 0, 0));
74   canvas->DrawRoundRect(local_bounds, kThumbCornerRadius, paint);
75 }
76 
AnimationProgressed(const gfx::Animation * animation)77 void OverlayScrollBarThumb::AnimationProgressed(
78     const gfx::Animation* animation) {
79   animation_opacity_ = animation->GetCurrentValue();
80   SchedulePaint();
81 }
82 
83 }  // namespace
84 
OverlayScrollBar(bool horizontal)85 OverlayScrollBar::OverlayScrollBar(bool horizontal)
86     : BaseScrollBar(horizontal, new OverlayScrollBarThumb(this)),
87       animation_(static_cast<OverlayScrollBarThumb*>(GetThumb())) {
88   set_notify_enter_exit_on_child(true);
89 }
90 
~OverlayScrollBar()91 OverlayScrollBar::~OverlayScrollBar() {
92 }
93 
GetTrackBounds() const94 gfx::Rect OverlayScrollBar::GetTrackBounds() const {
95   gfx::Rect local_bounds(GetLocalBounds());
96   if (IsHorizontal()) {
97     local_bounds.Inset(kThumbInsetFromEdge, kThumbInsetInside,
98                        kThumbInsetFromEdge, kThumbInsetFromEdge);
99   } else {
100     local_bounds.Inset(kThumbInsetInside, kThumbInsetFromEdge,
101                        kThumbInsetFromEdge, kThumbInsetFromEdge);
102   }
103   gfx::Size track_size = local_bounds.size();
104   track_size.SetToMax(GetThumb()->size());
105   local_bounds.set_size(track_size);
106   return local_bounds;
107 }
108 
GetLayoutSize() const109 int OverlayScrollBar::GetLayoutSize() const {
110   return 0;
111 }
112 
GetContentOverlapSize() const113 int OverlayScrollBar::GetContentOverlapSize() const {
114   return kScrollbarWidth;
115 }
116 
OnMouseEnteredScrollView(const ui::MouseEvent & event)117 void OverlayScrollBar::OnMouseEnteredScrollView(const ui::MouseEvent& event) {
118   animation_.Show();
119 }
120 
OnMouseExitedScrollView(const ui::MouseEvent & event)121 void OverlayScrollBar::OnMouseExitedScrollView(const ui::MouseEvent& event) {
122   animation_.Hide();
123 }
124 
OnGestureEvent(ui::GestureEvent * event)125 void OverlayScrollBar::OnGestureEvent(ui::GestureEvent* event) {
126   switch (event->type()) {
127     case ui::ET_GESTURE_SCROLL_BEGIN:
128       animation_.Show();
129       break;
130     case ui::ET_GESTURE_SCROLL_END:
131     case ui::ET_SCROLL_FLING_START:
132     case ui::ET_GESTURE_END:
133       animation_.Hide();
134       break;
135     default:
136       break;
137   }
138   BaseScrollBar::OnGestureEvent(event);
139 }
140 
GetPreferredSize() const141 gfx::Size OverlayScrollBar::GetPreferredSize() const {
142   return gfx::Size();
143 }
144 
Layout()145 void OverlayScrollBar::Layout() {
146   gfx::Rect thumb_bounds = GetTrackBounds();
147   BaseScrollBarThumb* thumb = GetThumb();
148   if (IsHorizontal()) {
149     thumb_bounds.set_x(thumb->x());
150     thumb_bounds.set_width(thumb->width());
151   } else {
152     thumb_bounds.set_y(thumb->y());
153     thumb_bounds.set_height(thumb->height());
154   }
155   thumb->SetBoundsRect(thumb_bounds);
156 }
157 
OnPaint(gfx::Canvas * canvas)158 void OverlayScrollBar::OnPaint(gfx::Canvas* canvas) {
159 }
160 
161 }  // namespace views
162