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

Side by Side Diff: ui/views/controls/scrollbar/cocoa_scroll_bar.mm

Issue 1671313002: MacViews: Overlay Scrollbars with Show/Hide Animations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update layout according to scroller style Created 4 years, 10 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
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
tapted 2016/02/17 08:46:20 2016
spqchan 2016/02/19 00:14:03 Done.
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/cocoa_scroll_bar.h"
tapted 2016/02/17 08:46:21 nit:import
spqchan 2016/02/19 00:14:03 Done.
6
7 #import "base/mac/sdk_forward_declarations.h"
8 #include "third_party/skia/include/core/SkColor.h"
9 #include "third_party/skia/include/effects/SkGradientShader.h"
10 #include "ui/compositor/layer.h"
11 #include "ui/compositor/layer_animator.h"
12 #include "ui/compositor/scoped_layer_animation_settings.h"
13 #include "ui/gfx/canvas.h"
14 #include "ui/views/controls/scrollbar/base_scroll_bar_thumb.h"
15
16 namespace views {
17
18 namespace {
19
20 // The length of the fade animation.
21 const int kFadeDurationMs = 240;
22
23 // How long we should wait before hiding the scrollbar.
24 const int kScrollbarHideTimeoutMs = 500;
25
26 // The width of the scrollbar.
27 const int kScrollbarWidth = 15;
28
29 // The width of the scrollbar thumb.
30 const int kScrollbarThumbWidth = 10;
31
32 // The width of the scroller track border.
33 const int kScrollerTrackBorderWidth = 1;
34
35 // The amount the thumb is inset from both the ends and the sides of the track.
36 const int kScrollbarThumbInset = 3;
37
38 // Scrollbar thumb color.
39 const SkColor kScrollerThumbColor = SkColorSetARGB(0x38, 0, 0, 0);
tapted 2016/02/17 08:46:20 I think we've lost the Hover color - SkColorSetARG
spqchan 2016/02/19 00:14:03 Ah I see what you mean. The color is darker in Ove
40
41 // Scroller track colors.
42 const SkColor kScrollerTrackGradientColors[] = {
43 SkColorSetRGB(0xEF, 0xEF, 0xEF),
44 SkColorSetRGB(0xF9, 0xF9, 0xF9),
45 SkColorSetRGB(0xFD, 0xFD, 0xFD),
46 SkColorSetRGB(0xF6, 0xF6, 0xF6) };
47 const SkColor kScrollerTrackInnerBorderColor = SkColorSetRGB(0xE4, 0xE4, 0xE4);
48 const SkColor kScrollerTrackOuterBorderColor = SkColorSetRGB(0xEF, 0xEF, 0xEF);
49
50
51 //////////////////////////////////////////////////////////////////
52 // CocoaScrollBarThumb
53
54 class CocoaScrollBarThumb : public BaseScrollBarThumb {
55 public:
56 explicit CocoaScrollBarThumb(CocoaScrollBar* scroll_bar);
57 ~CocoaScrollBarThumb() override;
58
59 protected:
60 // View overrides:
61 gfx::Size GetPreferredSize() const override;
62 void OnPaint(gfx::Canvas* canvas) override;
63 void OnMouseEntered(const ui::MouseEvent& event) override;
64 void OnMouseExited(const ui::MouseEvent& event) override;
65
66 private:
67 DISALLOW_COPY_AND_ASSIGN(CocoaScrollBarThumb);
68 };
69
70 CocoaScrollBarThumb::CocoaScrollBarThumb(CocoaScrollBar* scroll_bar)
71 : BaseScrollBarThumb(scroll_bar) {
72 // This is necessary, otherwise the thumb will be rendered below the views if
73 // those views paint to their own layers.
74 SetPaintToLayer(true);
75 SetFillsBoundsOpaquely(false);
76 }
77
78 CocoaScrollBarThumb::~CocoaScrollBarThumb() {}
79
80 gfx::Size CocoaScrollBarThumb::GetPreferredSize() const {
81 return gfx::Size(kScrollbarThumbWidth, kScrollbarThumbWidth);
82 }
83
84 void CocoaScrollBarThumb::OnPaint(gfx::Canvas* canvas) {
85 gfx::Rect local_bounds(GetLocalBounds());
86 SkPaint paint;
tapted 2016/02/17 08:46:20 paint.setAntiAlias(true); after this (it's easier
spqchan 2016/02/19 00:14:03 Done.
87 paint.setStyle(SkPaint::kFill_Style);
88 paint.setColor(kScrollerThumbColor);
89 const SkScalar radius = std::min(local_bounds.width(), local_bounds.height());
90 canvas->DrawRoundRect(local_bounds, radius, paint);
91 }
92
93 void CocoaScrollBarThumb::OnMouseEntered(const ui::MouseEvent& event) {
94 BaseScrollBarThumb::OnMouseEntered(event);
95 CocoaScrollBar* scrollbar = static_cast<CocoaScrollBar*>(scroll_bar());
96 scrollbar->OnMouseEnteredScrollbarThumb(event);
97 }
98
99 void CocoaScrollBarThumb::OnMouseExited(const ui::MouseEvent& event) {
100 BaseScrollBarThumb::OnMouseExited(event);
101 CocoaScrollBar* scrollbar = static_cast<CocoaScrollBar*>(scroll_bar());
102 scrollbar->OnMouseExitedScrollbarThumb(event);
103 }
104
105 } // namespace
106
107 //////////////////////////////////////////////////////////////////
108 // CocoaScrollBar class
109
110 CocoaScrollBar::CocoaScrollBar(bool horizontal)
111 : BaseScrollBar(horizontal, new CocoaScrollBarThumb(this)),
112 is_hovering_(false) {
113 bridge_.reset([[ViewsScrollbarBridge alloc] init]);
114 [bridge_ setDelegate:this];
115
116 scroller_style_ = [ViewsScrollbarBridge getPreferredScrollerStyle];
117
118 SetPaintToLayer(true);
119 has_scrolltrack_ = scroller_style_ == NSScrollerStyleLegacy;
120 layer()->SetOpacity(scroller_style_ == NSScrollerStyleOverlay ? 0.0 : 1.0);
121 }
122
123 CocoaScrollBar::~CocoaScrollBar() {
124 [bridge_ setDelegate:nullptr];
125 }
126
127 //////////////////////////////////////////////////////////////////
128 // CocoaScrollBar, BaseScrollBar:
129
130 gfx::Rect CocoaScrollBar::GetTrackBounds() const {
131 gfx::Rect local_bounds(GetLocalBounds());
132 local_bounds.Inset(kScrollbarThumbInset, kScrollbarThumbInset);
133
134 gfx::Size track_size = local_bounds.size();
135 track_size.SetToMax(GetThumb()->size());
136 local_bounds.set_size(track_size);
137 return local_bounds;
138 }
139
140 //////////////////////////////////////////////////////////////////
141 // CocoaScrollBar, ScrollBar:
142
143 int CocoaScrollBar::GetLayoutSize() const {
144 return scroller_style_ == NSScrollerStyleOverlay ? 0 : kScrollbarWidth;
145 }
146
147 int CocoaScrollBar::GetContentOverlapSize() const {
148 return scroller_style_ == NSScrollerStyleLegacy ? 0 : kScrollbarWidth;
149 }
150
151 //////////////////////////////////////////////////////////////////
152 // CocoaScrollBar::Views:
153
154 gfx::Size CocoaScrollBar::GetPreferredSize() const {
155 return gfx::Size();
156 }
157
158 void CocoaScrollBar::OnPaint(gfx::Canvas* canvas) {
159 if (!has_scrolltrack_)
160 return;
161
162 // Paint the scrollbar track background.
163 gfx::Rect track_rect = GetLocalBounds();
164
165 SkPoint gradient_bounds[2];
166 if (IsHorizontal()) {
167 gradient_bounds[0].set(track_rect.x(), track_rect.y());
168 gradient_bounds[1].set(track_rect.x(), track_rect.bottom());
169 } else {
170 gradient_bounds[0].set(track_rect.x(), track_rect.y());
171 gradient_bounds[1].set(track_rect.right(), track_rect.y());
172 }
173 skia::RefPtr<SkShader> shader = skia::AdoptRef(
174 SkGradientShader::CreateLinear(gradient_bounds,
175 kScrollerTrackGradientColors,
176 NULL,
tapted 2016/02/17 08:46:20 nit: nullptr
spqchan 2016/02/19 00:14:02 Done.
177 arraysize(kScrollerTrackGradientColors),
178 SkShader::kClamp_TileMode));
179 SkPaint gradient;
180 gradient.setShader(shader.get());
181 canvas->DrawRect(track_rect, gradient);
182
183 // Draw the inner border: top if horizontal, left if vertical.
184 SkPaint paint;
185 paint.setColor(kScrollerTrackInnerBorderColor);
186 gfx::Rect inner_border(track_rect);
187 if (IsHorizontal())
188 inner_border.set_height(kScrollerTrackBorderWidth);
189 else
190 inner_border.set_width(kScrollerTrackBorderWidth);
191 canvas->DrawRect(inner_border, paint);
192
193 // Draw the outer border: bottom if horizontal, right if veritcal.
194 paint.setColor(kScrollerTrackOuterBorderColor);
195 gfx::Rect outer_border(inner_border);
196 if (IsHorizontal())
197 outer_border.set_y(track_rect.bottom());
198 else
199 outer_border.set_x(track_rect.right());
200 canvas->DrawRect(outer_border, paint);
201 }
202
203 void CocoaScrollBar::OnMouseEnteredScrollbarThumb(const ui::MouseEvent& event) {
204 if (scroller_style_ != NSScrollerStyleOverlay)
205 return;
206
207 hide_scrollbar_timer_.Stop();
208 is_hovering_ = true;
209 if (layer()->opacity()) {
tapted 2016/02/17 08:46:20 this is subtle.. probably needs a comment, like /
spqchan 2016/02/19 00:14:03 Sure thing. The reason why I didn't put ResetTimer
210 ShowScrollbar();
211 }
tapted 2016/02/17 08:46:20 nit: doesn't need curlies
spqchan 2016/02/19 00:14:03 Done.
212 }
213
214 void CocoaScrollBar::OnMouseExitedScrollbarThumb(const ui::MouseEvent& event) {
215 if (scroller_style_ != NSScrollerStyleOverlay)
216 return;
217
218 is_hovering_ = false;
219 ResetTimer();
220 }
221
222 //////////////////////////////////////////////////////////////////
223 // CocoaScrollBar::ScrollDelegate:
224
225 bool CocoaScrollBar::OnScroll(float dx, float dy) {
226 bool did_scroll = BaseScrollBar::OnScroll(dx, dy);
227 if (did_scroll && scroller_style_ == NSScrollerStyleOverlay) {
228 if (layer()->opacity() < 1.0)
tapted 2016/02/17 08:46:20 is this check needed (can we just always ShowScrol
spqchan 2016/02/19 00:14:03 This check was needed earlier because of an edge c
229 ShowScrollbar();
230 ResetTimer();
231 }
232 return did_scroll;
233 }
234
235 //////////////////////////////////////////////////////////////////
236 // CocoaScrollBar::ViewsScrollbarBridge:
237
238 void CocoaScrollBar::OnScrollerStyleChanged() {
239 NSScrollerStyle scroller_style =
240 [ViewsScrollbarBridge getPreferredScrollerStyle];
241 if (scroller_style_ == scroller_style)
242 return;
243
244 scroller_style_ = scroller_style;
245
246 // Ensure that the ScrollView updates the scrollbar's layout.
247 if (parent())
248 parent()->Layout();
249
250 if (scroller_style_ == NSScrollerStyleOverlay)
251 HideScrollbar();
252 else
253 ShowScrollbar();
254 }
255
256 //////////////////////////////////////////////////////////////////
257 // CocoaScrollBar, private:
258
259 void CocoaScrollBar::HideScrollbar() {
260 ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator());
tapted 2016/02/17 08:46:20 DCHECK in here that the scroller_style_ is overlay
spqchan 2016/02/19 00:14:02 Done.
261 animation.SetTransitionDuration(
262 base::TimeDelta::FromMilliseconds(kFadeDurationMs));
263 layer()->SetOpacity(0.0);
264 }
265
266 void CocoaScrollBar::ShowScrollbar() {
267 // Updates the scrolltrack and repaint it, if necessary.
268 bool has_scrolltrack =
269 scroller_style_ == NSScrollerStyleLegacy || is_hovering_;
270 if (has_scrolltrack_ != has_scrolltrack) {
271 has_scrolltrack_ = has_scrolltrack;
272 SchedulePaint();
273 }
274 layer()->SetOpacity(1.0);
275 }
tapted 2016/02/17 08:46:21 I think we need to cancel the timer here. E.g. hid
spqchan 2016/02/19 00:14:03 Done.
276
277 void CocoaScrollBar::ResetTimer() {
278 if (hide_scrollbar_timer_.IsRunning()) {
279 hide_scrollbar_timer_.Reset();
280 } else {
281 hide_scrollbar_timer_.Start(
282 FROM_HERE, base::TimeDelta::FromMilliseconds(kScrollbarHideTimeoutMs),
283 this, &CocoaScrollBar::HideScrollbar);
284 }
285 }
286
287 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698