• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007, 2008 Apple Inc. All Rights Reserved.
3  * Copyright (C) 2007 Staikos Computing Services Inc. <info@staikos.net>
4  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "config.h"
29 #include "ScrollbarThemeQt.h"
30 
31 #include "GraphicsContext.h"
32 #include "PlatformMouseEvent.h"
33 #include "RenderThemeQt.h"
34 #include "ScrollView.h"
35 #include "Scrollbar.h"
36 
37 #include <QApplication>
38 #include <QDebug>
39 #include <QMenu>
40 #include <QPainter>
41 #include <QStyle>
42 #include <QStyleOptionSlider>
43 
44 namespace WebCore {
45 
nativeTheme()46 ScrollbarTheme* ScrollbarTheme::nativeTheme()
47 {
48     static ScrollbarThemeQt theme;
49     return &theme;
50 }
51 
~ScrollbarThemeQt()52 ScrollbarThemeQt::~ScrollbarThemeQt()
53 {
54 }
55 
scPart(const ScrollbarPart & part)56 static QStyle::SubControl scPart(const ScrollbarPart& part)
57 {
58     switch (part) {
59     case NoPart:
60         return QStyle::SC_None;
61     case BackButtonStartPart:
62     case BackButtonEndPart:
63         return QStyle::SC_ScrollBarSubLine;
64     case BackTrackPart:
65         return QStyle::SC_ScrollBarSubPage;
66     case ThumbPart:
67         return QStyle::SC_ScrollBarSlider;
68     case ForwardTrackPart:
69         return QStyle::SC_ScrollBarAddPage;
70     case ForwardButtonStartPart:
71     case ForwardButtonEndPart:
72         return QStyle::SC_ScrollBarAddLine;
73     }
74 
75     return QStyle::SC_None;
76 }
77 
scrollbarPart(const QStyle::SubControl & sc)78 static ScrollbarPart scrollbarPart(const QStyle::SubControl& sc)
79 {
80     switch (sc) {
81     case QStyle::SC_None:
82         return NoPart;
83     case QStyle::SC_ScrollBarSubLine:
84         return BackButtonStartPart;
85     case QStyle::SC_ScrollBarSubPage:
86         return BackTrackPart;
87     case QStyle::SC_ScrollBarSlider:
88         return ThumbPart;
89     case QStyle::SC_ScrollBarAddPage:
90         return ForwardTrackPart;
91     case QStyle::SC_ScrollBarAddLine:
92         return ForwardButtonStartPart;
93     }
94     return NoPart;
95 }
96 
styleOptionSlider(Scrollbar * scrollbar,QWidget * widget=0)97 static QStyleOptionSlider* styleOptionSlider(Scrollbar* scrollbar, QWidget* widget = 0)
98 {
99     static QStyleOptionSlider opt;
100     if (widget)
101         opt.initFrom(widget);
102     else
103         opt.state |= QStyle::State_Active;
104 
105     opt.state &= ~QStyle::State_HasFocus;
106 
107     opt.rect = scrollbar->frameRect();
108     if (scrollbar->enabled())
109         opt.state |= QStyle::State_Enabled;
110     if (scrollbar->controlSize() != RegularScrollbar)
111         opt.state |= QStyle::State_Mini;
112     opt.orientation = (scrollbar->orientation() == VerticalScrollbar) ? Qt::Vertical : Qt::Horizontal;
113 
114     if (scrollbar->orientation() == HorizontalScrollbar)
115         opt.state |= QStyle::State_Horizontal;
116     else
117         opt.state &= ~QStyle::State_Horizontal;
118 
119     opt.sliderValue = scrollbar->value();
120     opt.sliderPosition = opt.sliderValue;
121     opt.pageStep = scrollbar->pageStep();
122     opt.singleStep = scrollbar->lineStep();
123     opt.minimum = 0;
124     opt.maximum = qMax(0, scrollbar->maximum());
125     ScrollbarPart pressedPart = scrollbar->pressedPart();
126     ScrollbarPart hoveredPart = scrollbar->hoveredPart();
127     if (pressedPart != NoPart) {
128         opt.activeSubControls = scPart(scrollbar->pressedPart());
129         if (pressedPart == BackButtonStartPart || pressedPart == ForwardButtonStartPart
130             || pressedPart == BackButtonEndPart || pressedPart == ForwardButtonEndPart
131             || pressedPart == ThumbPart)
132             opt.state |= QStyle::State_Sunken;
133     } else
134         opt.activeSubControls = scPart(hoveredPart);
135     if (hoveredPart != NoPart)
136         opt.state |= QStyle::State_MouseOver;
137     return &opt;
138 }
139 
paint(Scrollbar * scrollbar,GraphicsContext * graphicsContext,const IntRect & damageRect)140 bool ScrollbarThemeQt::paint(Scrollbar* scrollbar, GraphicsContext* graphicsContext, const IntRect& damageRect)
141 {
142     if (graphicsContext->updatingControlTints()) {
143        scrollbar->invalidateRect(damageRect);
144        return false;
145     }
146 
147     StylePainter p(this, graphicsContext);
148     if (!p.isValid())
149       return true;
150 
151     p.painter->save();
152     QStyleOptionSlider* opt = styleOptionSlider(scrollbar, p.widget);
153 
154     p.painter->setClipRect(opt->rect.intersected(damageRect), Qt::IntersectClip);
155 
156 #ifdef Q_WS_MAC
157     p.drawComplexControl(QStyle::CC_ScrollBar, *opt);
158 #else
159     const QPoint topLeft = opt->rect.topLeft();
160     p.painter->translate(topLeft);
161     opt->rect.moveTo(QPoint(0, 0));
162 
163     // The QStyle expects the background to be already filled
164     p.painter->fillRect(opt->rect, opt->palette.background());
165 
166     p.drawComplexControl(QStyle::CC_ScrollBar, *opt);
167     opt->rect.moveTo(topLeft);
168 #endif
169     p.painter->restore();
170 
171     return true;
172 }
173 
hitTest(Scrollbar * scrollbar,const PlatformMouseEvent & evt)174 ScrollbarPart ScrollbarThemeQt::hitTest(Scrollbar* scrollbar, const PlatformMouseEvent& evt)
175 {
176     QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
177     const QPoint pos = scrollbar->convertFromContainingWindow(evt.pos());
178     opt->rect.moveTo(QPoint(0, 0));
179     QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ScrollBar, opt, pos, 0);
180     return scrollbarPart(sc);
181 }
182 
shouldCenterOnThumb(Scrollbar *,const PlatformMouseEvent & evt)183 bool ScrollbarThemeQt::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt)
184 {
185     // Middle click centers slider thumb (if supported)
186     return style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition) && evt.button() == MiddleButton;
187 }
188 
invalidatePart(Scrollbar * scrollbar,ScrollbarPart)189 void ScrollbarThemeQt::invalidatePart(Scrollbar* scrollbar, ScrollbarPart)
190 {
191     // FIXME: Do more precise invalidation.
192     scrollbar->invalidate();
193 }
194 
scrollbarThickness(ScrollbarControlSize controlSize)195 int ScrollbarThemeQt::scrollbarThickness(ScrollbarControlSize controlSize)
196 {
197 #if USE(QT_MOBILE_THEME)
198     return 0;
199 #endif
200     QStyleOptionSlider o;
201     o.orientation = Qt::Vertical;
202     o.state &= ~QStyle::State_Horizontal;
203     if (controlSize != RegularScrollbar)
204         o.state |= QStyle::State_Mini;
205     return style()->pixelMetric(QStyle::PM_ScrollBarExtent, &o, 0);
206 }
207 
thumbPosition(Scrollbar * scrollbar)208 int ScrollbarThemeQt::thumbPosition(Scrollbar* scrollbar)
209 {
210     if (scrollbar->enabled())
211         return (int)((float)scrollbar->currentPos() * (trackLength(scrollbar) - thumbLength(scrollbar)) / scrollbar->maximum());
212     return 0;
213 }
214 
thumbLength(Scrollbar * scrollbar)215 int ScrollbarThemeQt::thumbLength(Scrollbar* scrollbar)
216 {
217     QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
218     IntRect thumb = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarSlider, 0);
219     return scrollbar->orientation() == HorizontalScrollbar ? thumb.width() : thumb.height();
220 }
221 
trackPosition(Scrollbar * scrollbar)222 int ScrollbarThemeQt::trackPosition(Scrollbar* scrollbar)
223 {
224     QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
225     IntRect track = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0);
226     return scrollbar->orientation() == HorizontalScrollbar ? track.x() - scrollbar->x() : track.y() - scrollbar->y();
227 }
228 
trackLength(Scrollbar * scrollbar)229 int ScrollbarThemeQt::trackLength(Scrollbar* scrollbar)
230 {
231     QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
232     IntRect track = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0);
233     return scrollbar->orientation() == HorizontalScrollbar ? track.width() : track.height();
234 }
235 
paintScrollCorner(ScrollView * scrollView,GraphicsContext * context,const IntRect & rect)236 void ScrollbarThemeQt::paintScrollCorner(ScrollView* scrollView, GraphicsContext* context, const IntRect& rect)
237 {
238     if (context->updatingControlTints()) {
239        scrollView->invalidateRect(rect);
240        return;
241     }
242 
243     StylePainter p(this, context);
244     if (!p.isValid())
245         return;
246 
247     QStyleOption option;
248     option.rect = rect;
249     p.drawPrimitive(QStyle::PE_PanelScrollAreaCorner, option);
250 }
251 
style() const252 QStyle* ScrollbarThemeQt::style() const
253 {
254     return QApplication::style();
255 }
256 
257 }
258 
259