1 /*
2 * Copyright (C) 2011 Google 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 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27 #include "platform/scroll/ScrollbarThemeOverlay.h"
28
29 #include "platform/PlatformMouseEvent.h"
30 #include "platform/graphics/GraphicsContext.h"
31 #include "platform/scroll/ScrollbarThemeClient.h"
32 #include "platform/transforms/TransformationMatrix.h"
33 #include "public/platform/Platform.h"
34 #include "public/platform/WebRect.h"
35 #include "public/platform/WebThemeEngine.h"
36
37 #include <algorithm>
38
39 namespace blink {
40
ScrollbarThemeOverlay(int thumbThickness,int scrollbarMargin,HitTestBehavior allowHitTest,Color color)41 ScrollbarThemeOverlay::ScrollbarThemeOverlay(int thumbThickness, int scrollbarMargin, HitTestBehavior allowHitTest, Color color)
42 : ScrollbarTheme()
43 , m_thumbThickness(thumbThickness)
44 , m_scrollbarMargin(scrollbarMargin)
45 , m_allowHitTest(allowHitTest)
46 , m_color(color)
47 , m_useSolidColor(true)
48 {
49 }
50
ScrollbarThemeOverlay(int thumbThickness,int scrollbarMargin,HitTestBehavior allowHitTest)51 ScrollbarThemeOverlay::ScrollbarThemeOverlay(int thumbThickness, int scrollbarMargin, HitTestBehavior allowHitTest)
52 : ScrollbarTheme()
53 , m_thumbThickness(thumbThickness)
54 , m_scrollbarMargin(scrollbarMargin)
55 , m_allowHitTest(allowHitTest)
56 , m_useSolidColor(false)
57 {
58 }
59
scrollbarThickness(ScrollbarControlSize controlSize)60 int ScrollbarThemeOverlay::scrollbarThickness(ScrollbarControlSize controlSize)
61 {
62 return m_thumbThickness + m_scrollbarMargin;
63 }
64
usesOverlayScrollbars() const65 bool ScrollbarThemeOverlay::usesOverlayScrollbars() const
66 {
67 return true;
68 }
69
thumbPosition(ScrollbarThemeClient * scrollbar)70 int ScrollbarThemeOverlay::thumbPosition(ScrollbarThemeClient* scrollbar)
71 {
72 if (!scrollbar->totalSize())
73 return 0;
74
75 int trackLen = trackLength(scrollbar);
76 float proportion = static_cast<float>(scrollbar->currentPos()) / scrollbar->totalSize();
77 return round(proportion * trackLen);
78 }
79
thumbLength(ScrollbarThemeClient * scrollbar)80 int ScrollbarThemeOverlay::thumbLength(ScrollbarThemeClient* scrollbar)
81 {
82 int trackLen = trackLength(scrollbar);
83
84 if (!scrollbar->totalSize())
85 return trackLen;
86
87 float proportion = static_cast<float>(scrollbar->visibleSize()) / scrollbar->totalSize();
88 int length = round(proportion * trackLen);
89 length = std::min(std::max(length, minimumThumbLength(scrollbar)), trackLen);
90 return length;
91 }
92
hasThumb(ScrollbarThemeClient * scrollbar)93 bool ScrollbarThemeOverlay::hasThumb(ScrollbarThemeClient* scrollbar)
94 {
95 return true;
96 }
97
backButtonRect(ScrollbarThemeClient *,ScrollbarPart,bool)98 IntRect ScrollbarThemeOverlay::backButtonRect(ScrollbarThemeClient*, ScrollbarPart, bool)
99 {
100 return IntRect();
101 }
102
forwardButtonRect(ScrollbarThemeClient *,ScrollbarPart,bool)103 IntRect ScrollbarThemeOverlay::forwardButtonRect(ScrollbarThemeClient*, ScrollbarPart, bool)
104 {
105 return IntRect();
106 }
107
trackRect(ScrollbarThemeClient * scrollbar,bool)108 IntRect ScrollbarThemeOverlay::trackRect(ScrollbarThemeClient* scrollbar, bool)
109 {
110 IntRect rect = scrollbar->frameRect();
111 if (scrollbar->orientation() == HorizontalScrollbar)
112 rect.inflateX(-m_scrollbarMargin);
113 else
114 rect.inflateY(-m_scrollbarMargin);
115 return rect;
116 }
117
thumbThickness(ScrollbarThemeClient *)118 int ScrollbarThemeOverlay::thumbThickness(ScrollbarThemeClient*)
119 {
120 return m_thumbThickness;
121 }
122
paintThumb(GraphicsContext * context,ScrollbarThemeClient * scrollbar,const IntRect & rect)123 void ScrollbarThemeOverlay::paintThumb(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect)
124 {
125 IntRect thumbRect = rect;
126 if (scrollbar->orientation() == HorizontalScrollbar) {
127 thumbRect.setHeight(thumbRect.height() - m_scrollbarMargin);
128 } else {
129 thumbRect.setWidth(thumbRect.width() - m_scrollbarMargin);
130 if (scrollbar->isLeftSideVerticalScrollbar())
131 thumbRect.setX(thumbRect.x() + m_scrollbarMargin);
132 }
133
134 if (m_useSolidColor) {
135 context->fillRect(thumbRect, m_color);
136 return;
137 }
138
139 blink::WebThemeEngine::State state = blink::WebThemeEngine::StateNormal;
140 if (scrollbar->pressedPart() == ThumbPart)
141 state = blink::WebThemeEngine::StatePressed;
142 else if (scrollbar->hoveredPart() == ThumbPart)
143 state = blink::WebThemeEngine::StateHover;
144
145 blink::WebCanvas* canvas = context->canvas();
146
147 blink::WebThemeEngine::Part part = blink::WebThemeEngine::PartScrollbarHorizontalThumb;
148 if (scrollbar->orientation() == VerticalScrollbar)
149 part = blink::WebThemeEngine::PartScrollbarVerticalThumb;
150
151 blink::Platform::current()->themeEngine()->paint(canvas, part, state, blink::WebRect(rect), 0);
152 }
153
hitTest(ScrollbarThemeClient * scrollbar,const IntPoint & position)154 ScrollbarPart ScrollbarThemeOverlay::hitTest(ScrollbarThemeClient* scrollbar, const IntPoint& position)
155 {
156 if (m_allowHitTest == DisallowHitTest)
157 return NoPart;
158
159 return ScrollbarTheme::hitTest(scrollbar, position);
160 }
161
162 } // namespace blink
163