• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3  * Copyright (C) 2008, 2009 Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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 INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include "config.h"
28 #include "ScrollbarThemeChromium.h"
29 
30 #include <windows.h>
31 #include <vsstyle.h>
32 
33 #include "ChromiumBridge.h"
34 #include "GraphicsContext.h"
35 #include "PlatformContextSkia.h"
36 #include "PlatformMouseEvent.h"
37 #include "Scrollbar.h"
38 #include "WindowsVersion.h"
39 
40 namespace WebCore {
41 
42 // The scrollbar size in DumpRenderTree on the Mac - so we can match their
43 // layout results.  Entries are for regular, small, and mini scrollbars.
44 // Metrics obtained using [NSScroller scrollerWidthForControlSize:]
45 static const int kMacScrollbarSize[3] = { 15, 11, 15 };
46 
scrollbarThickness(ScrollbarControlSize controlSize)47 int ScrollbarThemeChromium::scrollbarThickness(ScrollbarControlSize controlSize)
48 {
49     static int thickness;
50     if (!thickness) {
51         if (ChromiumBridge::layoutTestMode())
52             return kMacScrollbarSize[controlSize];
53         thickness = GetSystemMetrics(SM_CXVSCROLL);
54     }
55     return thickness;
56 }
57 
invalidateOnMouseEnterExit()58 bool ScrollbarThemeChromium::invalidateOnMouseEnterExit()
59 {
60     return isVistaOrNewer();
61 }
62 
paintTrackPiece(GraphicsContext * gc,Scrollbar * scrollbar,const IntRect & rect,ScrollbarPart partType)63 void ScrollbarThemeChromium::paintTrackPiece(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart partType)
64 {
65     bool horz = scrollbar->orientation() == HorizontalScrollbar;
66 
67     int partId;
68     if (partType == BackTrackPart)
69         partId = horz ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
70     else
71         partId = horz ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
72 
73     IntRect alignRect = trackRect(scrollbar, false);
74 
75     // Draw the track area before/after the thumb on the scroll bar.
76     ChromiumBridge::paintScrollbarTrack(
77         gc,
78         partId,
79         getThemeState(scrollbar, partType),
80         getClassicThemeState(scrollbar, partType),
81         rect,
82         alignRect);
83 }
84 
paintButton(GraphicsContext * gc,Scrollbar * scrollbar,const IntRect & rect,ScrollbarPart part)85 void ScrollbarThemeChromium::paintButton(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part)
86 {
87     bool horz = scrollbar->orientation() == HorizontalScrollbar;
88 
89     int partId;
90     if (part == BackButtonStartPart || part == ForwardButtonStartPart)
91         partId = horz ? DFCS_SCROLLLEFT : DFCS_SCROLLUP;
92     else
93         partId = horz ? DFCS_SCROLLRIGHT : DFCS_SCROLLDOWN;
94 
95     // Draw the thumb (the box you drag in the scroll bar to scroll).
96     ChromiumBridge::paintScrollbarArrow(
97         gc,
98         getThemeArrowState(scrollbar, part),
99         partId | getClassicThemeState(scrollbar, part),
100         rect);
101 }
102 
paintThumb(GraphicsContext * gc,Scrollbar * scrollbar,const IntRect & rect)103 void ScrollbarThemeChromium::paintThumb(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect)
104 {
105     bool horz = scrollbar->orientation() == HorizontalScrollbar;
106 
107     // Draw the thumb (the box you drag in the scroll bar to scroll).
108     ChromiumBridge::paintScrollbarThumb(
109         gc,
110         horz ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT,
111         getThemeState(scrollbar, ThumbPart),
112         getClassicThemeState(scrollbar, ThumbPart),
113         rect);
114 
115     // Draw the gripper (the three little lines on the thumb).
116     ChromiumBridge::paintScrollbarThumb(
117         gc,
118         horz ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT,
119         getThemeState(scrollbar, ThumbPart),
120         getClassicThemeState(scrollbar, ThumbPart),
121         rect);
122 }
123 
getThemeState(Scrollbar * scrollbar,ScrollbarPart part) const124 int ScrollbarThemeChromium::getThemeState(Scrollbar* scrollbar, ScrollbarPart part) const
125 {
126     // When dragging the thumb, draw thumb pressed and other segments normal
127     // regardless of where the cursor actually is.  See also four places in
128     // getThemeArrowState().
129     if (scrollbar->pressedPart() == ThumbPart) {
130         if (part == ThumbPart)
131             return SCRBS_PRESSED;
132         return isVistaOrNewer() ? SCRBS_HOVER : SCRBS_NORMAL;
133     }
134     if (!scrollbar->enabled())
135         return SCRBS_DISABLED;
136     if (scrollbar->hoveredPart() != part || part == BackTrackPart || part == ForwardTrackPart)
137         return (scrollbar->hoveredPart() == NoPart || !isVistaOrNewer()) ? SCRBS_NORMAL : SCRBS_HOVER;
138     if (scrollbar->pressedPart() == NoPart)
139         return SCRBS_HOT;
140     return (scrollbar->pressedPart() == part) ? SCRBS_PRESSED : SCRBS_NORMAL;
141 }
142 
getThemeArrowState(Scrollbar * scrollbar,ScrollbarPart part) const143 int ScrollbarThemeChromium::getThemeArrowState(Scrollbar* scrollbar, ScrollbarPart part) const
144 {
145     // We could take advantage of knowing the values in the state enum to write
146     // some simpler code, but treating the state enum as a black box seems
147     // clearer and more future-proof.
148     if (part == BackButtonStartPart || part == ForwardButtonStartPart) {
149         if (scrollbar->orientation() == HorizontalScrollbar) {
150             if (scrollbar->pressedPart() == ThumbPart)
151                 return !isVistaOrNewer() ? ABS_LEFTNORMAL : ABS_LEFTHOVER;
152             if (!scrollbar->enabled())
153                 return ABS_LEFTDISABLED;
154             if (scrollbar->hoveredPart() != part)
155                 return ((scrollbar->hoveredPart() == NoPart) || !isVistaOrNewer()) ? ABS_LEFTNORMAL : ABS_LEFTHOVER;
156             if (scrollbar->pressedPart() == NoPart)
157                 return ABS_LEFTHOT;
158             return (scrollbar->pressedPart() == part) ?
159                 ABS_LEFTPRESSED : ABS_LEFTNORMAL;
160         }
161         if (scrollbar->pressedPart() == ThumbPart)
162             return !isVistaOrNewer() ? ABS_UPNORMAL : ABS_UPHOVER;
163         if (!scrollbar->enabled())
164             return ABS_UPDISABLED;
165         if (scrollbar->hoveredPart() != part)
166             return ((scrollbar->hoveredPart() == NoPart) || !isVistaOrNewer()) ? ABS_UPNORMAL : ABS_UPHOVER;
167         if (scrollbar->pressedPart() == NoPart)
168             return ABS_UPHOT;
169         return (scrollbar->pressedPart() == part) ? ABS_UPPRESSED : ABS_UPNORMAL;
170     }
171     if (scrollbar->orientation() == HorizontalScrollbar) {
172         if (scrollbar->pressedPart() == ThumbPart)
173             return !isVistaOrNewer() ? ABS_RIGHTNORMAL : ABS_RIGHTHOVER;
174         if (!scrollbar->enabled())
175             return ABS_RIGHTDISABLED;
176         if (scrollbar->hoveredPart() != part)
177             return ((scrollbar->hoveredPart() == NoPart) || !isVistaOrNewer()) ? ABS_RIGHTNORMAL : ABS_RIGHTHOVER;
178         if (scrollbar->pressedPart() == NoPart)
179             return ABS_RIGHTHOT;
180         return (scrollbar->pressedPart() == part) ? ABS_RIGHTPRESSED : ABS_RIGHTNORMAL;
181     }
182     if (scrollbar->pressedPart() == ThumbPart)
183         return !isVistaOrNewer() ? ABS_DOWNNORMAL : ABS_DOWNHOVER;
184     if (!scrollbar->enabled())
185         return ABS_DOWNDISABLED;
186     if (scrollbar->hoveredPart() != part)
187         return ((scrollbar->hoveredPart() == NoPart) || !isVistaOrNewer()) ? ABS_DOWNNORMAL : ABS_DOWNHOVER;
188     if (scrollbar->pressedPart() == NoPart)
189         return ABS_DOWNHOT;
190     return (scrollbar->pressedPart() == part) ? ABS_DOWNPRESSED : ABS_DOWNNORMAL;
191 }
192 
getClassicThemeState(Scrollbar * scrollbar,ScrollbarPart part) const193 int ScrollbarThemeChromium::getClassicThemeState(Scrollbar* scrollbar, ScrollbarPart part) const
194 {
195     // When dragging the thumb, draw the buttons normal even when hovered.
196     if (scrollbar->pressedPart() == ThumbPart)
197         return 0;
198     if (!scrollbar->enabled())
199         return DFCS_INACTIVE;
200     if (scrollbar->hoveredPart() != part || part == BackTrackPart || part == ForwardTrackPart)
201         return 0;
202     if (scrollbar->pressedPart() == NoPart)
203         return DFCS_HOT;
204     return (scrollbar->pressedPart() == part) ? (DFCS_PUSHED | DFCS_FLAT) : 0;
205 }
206 
207 } // namespace WebCore
208