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

Side by Side Diff: sky/engine/platform/scroll/Scrollbar.cpp

Issue 879993004: Remove ScrollableArea and Scrollbar (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 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 /*
2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "sky/engine/config.h"
27 #include "sky/engine/platform/scroll/Scrollbar.h"
28
29 #include "sky/engine/platform/graphics/GraphicsContext.h"
30 #include "sky/engine/platform/scroll/ScrollAnimator.h"
31 #include "sky/engine/platform/scroll/ScrollableArea.h"
32 #include "sky/engine/platform/scroll/Scrollbar.h"
33 #include "sky/engine/public/platform/Platform.h"
34 #include "sky/engine/public/platform/WebPoint.h"
35 #include "sky/engine/public/platform/WebRect.h"
36
37 // The position of the scrollbar thumb affects the appearance of the steppers, s o
38 // when the thumb moves, we have to invalidate them for painting.
39 #define THUMB_POSITION_AFFECTS_BUTTONS
40
41 namespace blink {
42
43 static const int kThumbThickness = 3;
44 static const int kScrollbarMargin = 3;
45
46 PassRefPtr<Scrollbar> Scrollbar::create(ScrollableArea* scrollableArea, Scrollba rOrientation orientation)
47 {
48 return adoptRef(new Scrollbar(scrollableArea, orientation));
49 }
50
51 Scrollbar::Scrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orient ation)
52 : m_scrollableArea(scrollableArea)
53 , m_orientation(orientation)
54 , m_visibleSize(0)
55 , m_totalSize(0)
56 , m_currentPos(0)
57 , m_dragOrigin(0)
58 , m_hoveredPart(NoPart)
59 , m_pressedPart(NoPart)
60 , m_pressedPos(0)
61 , m_scrollPos(0)
62 , m_documentDragPos(0)
63 , m_scrollTimer(this, &Scrollbar::autoscrollTimerFired)
64 , m_overlapsResizer(false)
65 {
66 // FIXME: This is ugly and would not be necessary if we fix cross-platform c ode to actually query for
67 // scrollbar thickness and use it when sizing scrollbars (rather than leavin g one dimension of the scrollbar
68 // alone when sizing).
69 int thickness = scrollbarThickness();
70 Widget::setFrameRect(IntRect(0, 0, thickness, thickness));
71
72 m_currentPos = scrollableAreaCurrentPos();
73 }
74
75 Scrollbar::~Scrollbar()
76 {
77 stopTimerIfNeeded();
78 }
79
80 bool Scrollbar::isScrollableAreaActive() const
81 {
82 return m_scrollableArea && m_scrollableArea->isActive();
83 }
84
85 bool Scrollbar::isLeftSideVerticalScrollbar() const
86 {
87 if (m_orientation == VerticalScrollbar && m_scrollableArea)
88 return m_scrollableArea->shouldPlaceVerticalScrollbarOnLeft();
89 return false;
90 }
91
92 void Scrollbar::offsetDidChange()
93 {
94 ASSERT(m_scrollableArea);
95
96 float position = scrollableAreaCurrentPos();
97 if (position == m_currentPos)
98 return;
99
100 int oldThumbPosition = thumbPosition();
101 m_currentPos = position;
102 if (m_pressedPart == ThumbPart)
103 setPressedPos(m_pressedPos + thumbPosition() - oldThumbPosition);
104 }
105
106 void Scrollbar::setProportion(int visibleSize, int totalSize)
107 {
108 if (visibleSize == m_visibleSize && totalSize == m_totalSize)
109 return;
110
111 m_visibleSize = visibleSize;
112 m_totalSize = totalSize;
113 }
114
115 void Scrollbar::paint(GraphicsContext* context, const IntRect& damageRect)
116 {
117 if (!frameRect().intersects(damageRect))
118 return;
119
120 IntRect startTrackRect;
121 IntRect thumbRect;
122 IntRect endTrackRect;
123 splitTrack(trackRect(), startTrackRect, thumbRect, endTrackRect);
124 if (damageRect.intersects(thumbRect))
125 paintThumb(context, thumbRect);
126 }
127
128 void Scrollbar::autoscrollTimerFired(Timer<Scrollbar>*)
129 {
130 autoscrollPressedPart(autoscrollTimerDelay());
131 }
132
133 void Scrollbar::autoscrollPressedPart(double delay)
134 {
135 // Don't do anything for the thumb or if nothing was pressed.
136 if (m_pressedPart == ThumbPart || m_pressedPart == NoPart)
137 return;
138
139 // Handle the arrows and track.
140 if (m_scrollableArea && m_scrollableArea->scroll(pressedPartScrollDirection( ), pressedPartScrollGranularity()))
141 startTimerIfNeeded(delay);
142 }
143
144 void Scrollbar::startTimerIfNeeded(double delay)
145 {
146 // Don't do anything for the thumb.
147 if (m_pressedPart == ThumbPart)
148 return;
149
150 // We can't scroll if we've hit the beginning or end.
151 ScrollDirection dir = pressedPartScrollDirection();
152 if (dir == ScrollUp || dir == ScrollLeft) {
153 if (m_currentPos == 0)
154 return;
155 } else {
156 if (m_currentPos == maximum())
157 return;
158 }
159
160 m_scrollTimer.startOneShot(delay, FROM_HERE);
161 }
162
163 void Scrollbar::stopTimerIfNeeded()
164 {
165 if (m_scrollTimer.isActive())
166 m_scrollTimer.stop();
167 }
168
169 ScrollDirection Scrollbar::pressedPartScrollDirection()
170 {
171 if (m_orientation == HorizontalScrollbar) {
172 if (m_pressedPart == BackTrackPart)
173 return ScrollLeft;
174 return ScrollRight;
175 } else {
176 if (m_pressedPart == BackTrackPart)
177 return ScrollUp;
178 return ScrollDown;
179 }
180 }
181
182 ScrollGranularity Scrollbar::pressedPartScrollGranularity()
183 {
184 // FIXME(sky): Remove
185 return ScrollByPage;
186 }
187
188 void Scrollbar::moveThumb(int pos)
189 {
190 if (!m_scrollableArea)
191 return;
192
193 int delta = pos - m_pressedPos;
194
195 // Drag the thumb.
196 int thumbPos = thumbPosition();
197 int thumbLen = thumbLength();
198 int trackLen = trackLength();
199 if (delta > 0)
200 delta = std::min(trackLen - thumbLen - thumbPos, delta);
201 else if (delta < 0)
202 delta = std::max(-thumbPos, delta);
203
204 float minPos = m_scrollableArea->minimumScrollPosition(m_orientation);
205 float maxPos = m_scrollableArea->maximumScrollPosition(m_orientation);
206 if (delta) {
207 float newPosition = static_cast<float>(thumbPos + delta) * (maxPos - min Pos) / (trackLen - thumbLen) + minPos;
208 m_scrollableArea->scrollToOffsetWithoutAnimation(m_orientation, newPosit ion);
209 }
210 }
211
212 void Scrollbar::setHoveredPart(ScrollbarPart part)
213 {
214 if (part == m_hoveredPart)
215 return;
216 m_hoveredPart = part;
217 }
218
219 void Scrollbar::setPressedPart(ScrollbarPart part)
220 {
221 m_pressedPart = part;
222 }
223
224 bool Scrollbar::isOverlayScrollbar() const
225 {
226 // FIXME(sky): Remove
227 return true;
228 }
229
230 bool Scrollbar::shouldParticipateInHitTesting()
231 {
232 // Non-overlay scrollbars should always participate in hit testing.
233 if (!isOverlayScrollbar())
234 return true;
235 return m_scrollableArea->scrollAnimator()->shouldScrollbarParticipateInHitTe sting(this);
236 }
237
238 IntRect Scrollbar::convertToContainingView(const IntRect& localRect) const
239 {
240 if (m_scrollableArea)
241 return m_scrollableArea->convertFromScrollbarToContainingView(this, loca lRect);
242
243 return Widget::convertToContainingView(localRect);
244 }
245
246 IntRect Scrollbar::convertFromContainingView(const IntRect& parentRect) const
247 {
248 if (m_scrollableArea)
249 return m_scrollableArea->convertFromContainingViewToScrollbar(this, pare ntRect);
250
251 return Widget::convertFromContainingView(parentRect);
252 }
253
254 IntPoint Scrollbar::convertToContainingView(const IntPoint& localPoint) const
255 {
256 if (m_scrollableArea)
257 return m_scrollableArea->convertFromScrollbarToContainingView(this, loca lPoint);
258
259 return Widget::convertToContainingView(localPoint);
260 }
261
262 IntPoint Scrollbar::convertFromContainingView(const IntPoint& parentPoint) const
263 {
264 if (m_scrollableArea)
265 return m_scrollableArea->convertFromContainingViewToScrollbar(this, pare ntPoint);
266
267 return Widget::convertFromContainingView(parentPoint);
268 }
269
270 float Scrollbar::scrollableAreaCurrentPos() const
271 {
272 if (!m_scrollableArea)
273 return 0;
274
275 if (m_orientation == HorizontalScrollbar)
276 return m_scrollableArea->scrollPosition().x() - m_scrollableArea->minimu mScrollPosition().x();
277
278 return m_scrollableArea->scrollPosition().y() - m_scrollableArea->minimumScr ollPosition().y();
279 }
280
281 int Scrollbar::scrollbarThickness()
282 {
283 return kThumbThickness + kScrollbarMargin;
284 }
285
286 int Scrollbar::thumbPosition()
287 {
288 if (!totalSize())
289 return 0;
290
291 int trackLen = trackLength();
292 float proportion = static_cast<float>(currentPos()) / totalSize();
293 return round(proportion * trackLen);
294 }
295
296 int Scrollbar::thumbLength()
297 {
298 int trackLen = trackLength();
299
300 if (!totalSize())
301 return trackLen;
302
303 float proportion = static_cast<float>(visibleSize()) / totalSize();
304 int length = round(proportion * trackLen);
305 length = std::min(std::max(length, minimumThumbLength()), trackLen);
306 return length;
307 }
308
309 int Scrollbar::trackPosition()
310 {
311 IntRect rect = trackRect();
312 return (orientation() == HorizontalScrollbar) ? rect.x() - x() : rect.y() - y();
313 }
314
315 int Scrollbar::trackLength()
316 {
317 IntRect rect = trackRect();
318 return (orientation() == HorizontalScrollbar) ? rect.width() : rect.height() ;
319 }
320
321 IntRect Scrollbar::trackRect()
322 {
323 IntRect rect = frameRect();
324 if (orientation() == HorizontalScrollbar)
325 rect.inflateX(-kScrollbarMargin);
326 else
327 rect.inflateY(-kScrollbarMargin);
328 return rect;
329 }
330
331 IntRect Scrollbar::thumbRect()
332 {
333 IntRect track = trackRect();
334 IntRect startTrackRect;
335 IntRect thumbRect;
336 IntRect endTrackRect;
337 splitTrack(track, startTrackRect, thumbRect, endTrackRect);
338
339 return thumbRect;
340 }
341
342 int Scrollbar::thumbThickness()
343 {
344 return kThumbThickness;
345 }
346
347 int Scrollbar::minimumThumbLength()
348 {
349 return scrollbarThickness();
350 }
351
352 void Scrollbar::splitTrack(const IntRect& trackRect, IntRect& beforeThumbRect, I ntRect& thumbRect, IntRect& afterThumbRect)
353 {
354 // This function won't even get called unless we're big enough to have some combination of these three rects where at least
355 // one of them is non-empty.
356 int thumbPos = thumbPosition();
357 if (orientation() == HorizontalScrollbar) {
358 thumbRect = IntRect(trackRect.x() + thumbPos, trackRect.y(), thumbLength (), height());
359 beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), thumbPos + thumb Rect.width() / 2, trackRect.height());
360 afterThumbRect = IntRect(trackRect.x() + beforeThumbRect.width(), trackR ect.y(), trackRect.maxX() - beforeThumbRect.maxX(), trackRect.height());
361 } else {
362 thumbRect = IntRect(trackRect.x(), trackRect.y() + thumbPos, width(), th umbLength());
363 beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), trackRect.width( ), thumbPos + thumbRect.height() / 2);
364 afterThumbRect = IntRect(trackRect.x(), trackRect.y() + beforeThumbRect. height(), trackRect.width(), trackRect.maxY() - beforeThumbRect.maxY());
365 }
366 }
367
368 void Scrollbar::paintThumb(GraphicsContext* context, const IntRect& rect)
369 {
370 // FIXME(sky): This function appears to be dead code.
371 IntRect thumbRect = rect;
372 if (orientation() == HorizontalScrollbar) {
373 thumbRect.setHeight(thumbRect.height() - kScrollbarMargin);
374 } else {
375 thumbRect.setWidth(thumbRect.width() - kScrollbarMargin);
376 if (isLeftSideVerticalScrollbar())
377 thumbRect.setX(thumbRect.x() + kScrollbarMargin);
378 }
379
380 DEFINE_STATIC_LOCAL(Color, color, (128, 128, 128, 128));
381 context->fillRect(thumbRect, color);
382 }
383
384 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/platform/scroll/Scrollbar.h ('k') | sky/engine/public/platform/WebFallbackThemeEngine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698