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

Side by Side Diff: Source/WebCore/platform/win/ScrollbarThemeWin.cpp

Issue 13642009: WebCore: Remove PLATFORM(WIN) files we do not use. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 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 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 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 "config.h"
27 #include "ScrollbarThemeWin.h"
28
29 #include "GraphicsContext.h"
30 #include "LocalWindowsContext.h"
31 #include "PlatformMouseEvent.h"
32 #include "Scrollbar.h"
33 #include "SoftLinking.h"
34 #include "SystemInfo.h"
35
36 // Generic state constants
37 #define TS_NORMAL 1
38 #define TS_HOVER 2
39 #define TS_ACTIVE 3
40 #define TS_DISABLED 4
41
42 #define SP_BUTTON 1
43 #define SP_THUMBHOR 2
44 #define SP_THUMBVERT 3
45 #define SP_TRACKSTARTHOR 4
46 #define SP_TRACKENDHOR 5
47 #define SP_TRACKSTARTVERT 6
48 #define SP_TRACKENDVERT 7
49 #define SP_GRIPPERHOR 8
50 #define SP_GRIPPERVERT 9
51
52 #define TS_UP_BUTTON 0
53 #define TS_DOWN_BUTTON 4
54 #define TS_LEFT_BUTTON 8
55 #define TS_RIGHT_BUTTON 12
56 #define TS_UP_BUTTON_HOVER 17
57 #define TS_DOWN_BUTTON_HOVER 18
58 #define TS_LEFT_BUTTON_HOVER 19
59 #define TS_RIGHT_BUTTON_HOVER 20
60
61 using namespace std;
62
63 namespace WebCore {
64
65 static HANDLE scrollbarTheme;
66 static bool runningVista;
67
68 // FIXME: Refactor the soft-linking code so that it can be shared with RenderTh emeWin
69 SOFT_LINK_LIBRARY(uxtheme)
70 SOFT_LINK(uxtheme, OpenThemeData, HANDLE, WINAPI, (HWND hwnd, LPCWSTR pszClassLi st), (hwnd, pszClassList))
71 SOFT_LINK(uxtheme, CloseThemeData, HRESULT, WINAPI, (HANDLE hTheme), (hTheme))
72 SOFT_LINK(uxtheme, DrawThemeBackground, HRESULT, WINAPI, (HANDLE hTheme, HDC hdc , int iPartId, int iStateId, const RECT* pRect, const RECT* pClipRect), (hTheme, hdc, iPartId, iStateId, pRect, pClipRect))
73 SOFT_LINK(uxtheme, IsThemeActive, BOOL, WINAPI, (), ())
74 SOFT_LINK(uxtheme, IsThemeBackgroundPartiallyTransparent, BOOL, WINAPI, (HANDLE hTheme, int iPartId, int iStateId), (hTheme, iPartId, iStateId))
75
76 // Constants used to figure the drag rect outside which we should snap the
77 // scrollbar thumb back to its origin. These calculations are based on
78 // observing the behavior of the MSVC8 main window scrollbar + some
79 // guessing/extrapolation.
80 static const int kOffEndMultiplier = 3;
81 static const int kOffSideMultiplier = 8;
82
83 static void checkAndInitScrollbarTheme()
84 {
85 if (uxthemeLibrary() && !scrollbarTheme && IsThemeActive())
86 scrollbarTheme = OpenThemeData(0, L"Scrollbar");
87 }
88
89 #if !USE(SAFARI_THEME)
90 ScrollbarTheme* ScrollbarTheme::nativeTheme()
91 {
92 static ScrollbarThemeWin winTheme;
93 return &winTheme;
94 }
95 #endif
96
97 ScrollbarThemeWin::ScrollbarThemeWin()
98 {
99 static bool initialized;
100 if (!initialized) {
101 initialized = true;
102 checkAndInitScrollbarTheme();
103 runningVista = (windowsVersion() >= WindowsVista);
104 }
105 }
106
107 ScrollbarThemeWin::~ScrollbarThemeWin()
108 {
109 }
110
111 int ScrollbarThemeWin::scrollbarThickness(ScrollbarControlSize)
112 {
113 static int thickness;
114 if (!thickness)
115 thickness = ::GetSystemMetrics(SM_CXVSCROLL);
116 return thickness;
117 }
118
119 void ScrollbarThemeWin::themeChanged()
120 {
121 if (!scrollbarTheme)
122 return;
123
124 CloseThemeData(scrollbarTheme);
125 scrollbarTheme = 0;
126 }
127
128 bool ScrollbarThemeWin::invalidateOnMouseEnterExit()
129 {
130 return runningVista;
131 }
132
133 bool ScrollbarThemeWin::hasThumb(ScrollbarThemeClient* scrollbar)
134 {
135 return thumbLength(scrollbar) > 0;
136 }
137
138 IntRect ScrollbarThemeWin::backButtonRect(ScrollbarThemeClient* scrollbar, Scrol lbarPart part, bool)
139 {
140 // Windows just has single arrows.
141 if (part == BackButtonEndPart)
142 return IntRect();
143
144 // Our desired rect is essentially 17x17.
145
146 // Our actual rect will shrink to half the available space when
147 // we have < 34 pixels left. This allows the scrollbar
148 // to scale down and function even at tiny sizes.
149 int thickness = scrollbarThickness();
150 if (scrollbar->orientation() == HorizontalScrollbar)
151 return IntRect(scrollbar->x(), scrollbar->y(),
152 scrollbar->width() < 2 * thickness ? scrollbar->width() / 2 : thickness, thickness);
153 return IntRect(scrollbar->x(), scrollbar->y(),
154 thickness, scrollbar->height() < 2 * thickness ? scrollbar->h eight() / 2 : thickness);
155 }
156
157 IntRect ScrollbarThemeWin::forwardButtonRect(ScrollbarThemeClient* scrollbar, Sc rollbarPart part, bool)
158 {
159 // Windows just has single arrows.
160 if (part == ForwardButtonStartPart)
161 return IntRect();
162
163 // Our desired rect is essentially 17x17.
164
165 // Our actual rect will shrink to half the available space when
166 // we have < 34 pixels left. This allows the scrollbar
167 // to scale down and function even at tiny sizes.
168 int thickness = scrollbarThickness();
169 if (scrollbar->orientation() == HorizontalScrollbar) {
170 int w = scrollbar->width() < 2 * thickness ? scrollbar->width() / 2 : th ickness;
171 return IntRect(scrollbar->x() + scrollbar->width() - w, scrollbar->y(), w, thickness);
172 }
173
174 int h = scrollbar->height() < 2 * thickness ? scrollbar->height() / 2 : thic kness;
175 return IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - h, thi ckness, h);
176 }
177
178 IntRect ScrollbarThemeWin::trackRect(ScrollbarThemeClient* scrollbar, bool)
179 {
180 int thickness = scrollbarThickness();
181 if (scrollbar->orientation() == HorizontalScrollbar) {
182 if (scrollbar->width() < 2 * thickness)
183 return IntRect();
184 return IntRect(scrollbar->x() + thickness, scrollbar->y(), scrollbar->wi dth() - 2 * thickness, thickness);
185 }
186 if (scrollbar->height() < 2 * thickness)
187 return IntRect();
188 return IntRect(scrollbar->x(), scrollbar->y() + thickness, thickness, scroll bar->height() - 2 * thickness);
189 }
190
191 bool ScrollbarThemeWin::shouldCenterOnThumb(ScrollbarThemeClient*, const Platfor mMouseEvent& evt)
192 {
193 return evt.shiftKey() && evt.button() == LeftButton;
194 }
195
196 bool ScrollbarThemeWin::shouldSnapBackToDragOrigin(ScrollbarThemeClient* scrollb ar, const PlatformMouseEvent& evt)
197 {
198 // Find the rect within which we shouldn't snap, by expanding the track rect
199 // in both dimensions.
200 IntRect rect = trackRect(scrollbar);
201 const bool horz = scrollbar->orientation() == HorizontalScrollbar;
202 const int thickness = scrollbarThickness(scrollbar->controlSize());
203 rect.inflateX((horz ? kOffEndMultiplier : kOffSideMultiplier) * thickness);
204 rect.inflateY((horz ? kOffSideMultiplier : kOffEndMultiplier) * thickness);
205
206 // Convert the event to local coordinates.
207 IntPoint mousePosition = scrollbar->convertFromContainingWindow(evt.position ());
208 mousePosition.move(scrollbar->x(), scrollbar->y());
209
210 // We should snap iff the event is outside our calculated rect.
211 return !rect.contains(mousePosition);
212 }
213
214 void ScrollbarThemeWin::paintTrackBackground(GraphicsContext* context, Scrollbar ThemeClient* scrollbar, const IntRect& rect)
215 {
216 // Just assume a forward track part. We only paint the track as a single pi ece when there is no thumb.
217 if (!hasThumb(scrollbar))
218 paintTrackPiece(context, scrollbar, rect, ForwardTrackPart);
219 }
220
221 void ScrollbarThemeWin::paintTrackPiece(GraphicsContext* context, ScrollbarTheme Client* scrollbar, const IntRect& rect, ScrollbarPart partType)
222 {
223 checkAndInitScrollbarTheme();
224
225 bool start = partType == BackTrackPart;
226 int part;
227 if (scrollbar->orientation() == HorizontalScrollbar)
228 part = start ? SP_TRACKSTARTHOR : SP_TRACKENDHOR;
229 else
230 part = start ? SP_TRACKSTARTVERT : SP_TRACKENDVERT;
231
232 int state;
233 if (!scrollbar->enabled())
234 state = TS_DISABLED;
235 else if ((scrollbar->hoveredPart() == BackTrackPart && start) ||
236 (scrollbar->hoveredPart() == ForwardTrackPart && !start))
237 state = (scrollbar->pressedPart() == scrollbar->hoveredPart() ? TS_ACTIV E : TS_HOVER);
238 else
239 state = TS_NORMAL;
240
241 bool alphaBlend = false;
242 if (scrollbarTheme)
243 alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, part, state);
244
245 LocalWindowsContext windowsContext(context, rect, alphaBlend);
246 RECT themeRect(rect);
247
248 if (scrollbarTheme)
249 DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), part, state, & themeRect, 0);
250 else {
251 DWORD color3DFace = ::GetSysColor(COLOR_3DFACE);
252 DWORD colorScrollbar = ::GetSysColor(COLOR_SCROLLBAR);
253 DWORD colorWindow = ::GetSysColor(COLOR_WINDOW);
254 HDC hdc = windowsContext.hdc();
255 if ((color3DFace != colorScrollbar) && (colorWindow != colorScrollbar))
256 ::FillRect(hdc, &themeRect, HBRUSH(COLOR_SCROLLBAR+1));
257 else {
258 static WORD patternBits[8] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0 xaa, 0x55 };
259 HBITMAP patternBitmap = ::CreateBitmap(8, 8, 1, 1, patternBits);
260 HBRUSH brush = ::CreatePatternBrush(patternBitmap);
261 SaveDC(hdc);
262 ::SetTextColor(hdc, ::GetSysColor(COLOR_3DHILIGHT));
263 ::SetBkColor(hdc, ::GetSysColor(COLOR_3DFACE));
264 ::SetBrushOrgEx(hdc, rect.x(), rect.y(), NULL);
265 ::SelectObject(hdc, brush);
266 ::FillRect(hdc, &themeRect, brush);
267 ::RestoreDC(hdc, -1);
268 ::DeleteObject(brush);
269 ::DeleteObject(patternBitmap);
270 }
271 }
272
273 #if !OS(WINCE)
274 if (!alphaBlend && !context->isInTransparencyLayer())
275 DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255);
276 #endif
277 }
278
279 void ScrollbarThemeWin::paintButton(GraphicsContext* context, ScrollbarThemeClie nt* scrollbar, const IntRect& rect, ScrollbarPart part)
280 {
281 checkAndInitScrollbarTheme();
282
283 bool start = (part == BackButtonStartPart);
284 int xpState = 0;
285 int classicState = 0;
286 if (scrollbar->orientation() == HorizontalScrollbar)
287 xpState = start ? TS_LEFT_BUTTON : TS_RIGHT_BUTTON;
288 else
289 xpState = start ? TS_UP_BUTTON : TS_DOWN_BUTTON;
290 classicState = xpState / 4;
291
292 if (!scrollbar->enabled()) {
293 xpState += TS_DISABLED;
294 classicState |= DFCS_INACTIVE;
295 } else if ((scrollbar->hoveredPart() == BackButtonStartPart && start) ||
296 (scrollbar->hoveredPart() == ForwardButtonEndPart && !start)) {
297 if (scrollbar->pressedPart() == scrollbar->hoveredPart()) {
298 xpState += TS_ACTIVE;
299 classicState |= DFCS_PUSHED;
300 #if !OS(WINCE)
301 classicState |= DFCS_FLAT;
302 #endif
303 } else
304 xpState += TS_HOVER;
305 } else {
306 if (scrollbar->hoveredPart() == NoPart || !runningVista)
307 xpState += TS_NORMAL;
308 else {
309 if (scrollbar->orientation() == HorizontalScrollbar)
310 xpState = start ? TS_LEFT_BUTTON_HOVER : TS_RIGHT_BUTTON_HOVER;
311 else
312 xpState = start ? TS_UP_BUTTON_HOVER : TS_DOWN_BUTTON_HOVER;
313 }
314 }
315
316 bool alphaBlend = false;
317 if (scrollbarTheme)
318 alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, SP_BU TTON, xpState);
319
320 LocalWindowsContext windowsContext(context, rect, alphaBlend);
321 RECT themeRect(rect);
322 if (scrollbarTheme)
323 DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), SP_BUTTON, xpS tate, &themeRect, 0);
324 else
325 ::DrawFrameControl(windowsContext.hdc(), &themeRect, DFC_SCROLL, classic State);
326
327 #if !OS(WINCE)
328 if (!alphaBlend && !context->isInTransparencyLayer())
329 DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255);
330 #endif
331 }
332
333 static IntRect gripperRect(int thickness, const IntRect& thumbRect)
334 {
335 // Center in the thumb.
336 int gripperThickness = thickness / 2;
337 return IntRect(thumbRect.x() + (thumbRect.width() - gripperThickness) / 2,
338 thumbRect.y() + (thumbRect.height() - gripperThickness) / 2,
339 gripperThickness, gripperThickness);
340 }
341
342 static void paintGripper(ScrollbarThemeClient* scrollbar, HDC hdc, const IntRect & rect)
343 {
344 if (!scrollbarTheme)
345 return; // Classic look has no gripper.
346
347 int state;
348 if (!scrollbar->enabled())
349 state = TS_DISABLED;
350 else if (scrollbar->pressedPart() == ThumbPart)
351 state = TS_ACTIVE; // Thumb always stays active once pressed.
352 else if (scrollbar->hoveredPart() == ThumbPart)
353 state = TS_HOVER;
354 else
355 state = TS_NORMAL;
356
357 RECT themeRect(rect);
358 DrawThemeBackground(scrollbarTheme, hdc, scrollbar->orientation() == Horizon talScrollbar ? SP_GRIPPERHOR : SP_GRIPPERVERT, state, &themeRect, 0);
359 }
360
361 void ScrollbarThemeWin::paintThumb(GraphicsContext* context, ScrollbarThemeClien t* scrollbar, const IntRect& rect)
362 {
363 checkAndInitScrollbarTheme();
364
365 int state;
366 if (!scrollbar->enabled())
367 state = TS_DISABLED;
368 else if (scrollbar->pressedPart() == ThumbPart)
369 state = TS_ACTIVE; // Thumb always stays active once pressed.
370 else if (scrollbar->hoveredPart() == ThumbPart)
371 state = TS_HOVER;
372 else
373 state = TS_NORMAL;
374
375 bool alphaBlend = false;
376 if (scrollbarTheme)
377 alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, scrol lbar->orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state);
378 LocalWindowsContext windowsContext(context, rect, alphaBlend);
379 RECT themeRect(rect);
380 if (scrollbarTheme) {
381 DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), scrollbar->ori entation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state, &themeRec t, 0);
382 paintGripper(scrollbar, windowsContext.hdc(), gripperRect(scrollbarThick ness(), rect));
383 } else
384 ::DrawEdge(windowsContext.hdc(), &themeRect, EDGE_RAISED, BF_RECT | BF_M IDDLE);
385
386 #if !OS(WINCE)
387 if (!alphaBlend && !context->isInTransparencyLayer())
388 DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255);
389 #endif
390 }
391
392 }
393
OLDNEW
« no previous file with comments | « Source/WebCore/platform/win/ScrollbarThemeWin.h ('k') | Source/WebCore/platform/win/SearchPopupMenuWin.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698