[wx] Enable wxWebKit to run using the wxGC Cairo backend on platforms other than...
[WebKit-https.git] / Source / WebCore / platform / wx / ScrollbarThemeWx.cpp
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 "ScrollbarThemeWx.h"
28
29 // see http://trac.wxwidgets.org/ticket/11482
30 // we need to include this before LocalDC as it includes wx headers
31 #ifdef __WXMSW__
32 #   include "wx/msw/winundef.h"
33 #endif
34
35 #include "HostWindow.h"
36 #include "LocalDC.h"
37 #include "NotImplemented.h"
38 #include "PlatformMouseEvent.h"
39 #include "ScrollableArea.h"
40 #include "Scrollbar.h"
41 #include "scrollbar_render.h"
42 #include "ScrollbarThemeComposite.h"
43 #include "ScrollView.h"
44
45 #include <wx/defs.h>
46 #include <wx/dcgraph.h>
47 #include <wx/settings.h>
48
49 const int cMacButtonOverlap = 4;
50
51 namespace WebCore {
52
53 ScrollbarTheme* ScrollbarTheme::nativeTheme()
54 {
55     static ScrollbarThemeWx theme;
56     return &theme;
57 }
58
59 ScrollbarThemeWx::~ScrollbarThemeWx()
60 {
61 }
62
63 int ScrollbarThemeWx::scrollbarThickness(ScrollbarControlSize size)
64 {
65     int thickness = wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
66     
67     // fallback for when a platform doesn't define this metric
68     if (thickness <= 0)
69         thickness = 20;
70     
71     return thickness;
72 }
73
74 bool ScrollbarThemeWx::hasThumb(Scrollbar* scrollbar)
75 {
76     // This method is just called as a paint-time optimization to see if
77     // painting the thumb can be skipped.  We don't have to be exact here.
78     return thumbLength(scrollbar) > 0;
79 }
80
81 int ScrollbarThemeWx::minimumThumbLength(Scrollbar* scrollbar)
82 {
83     return 20;
84 }
85
86 IntSize ScrollbarThemeWx::buttonSize(Scrollbar*) 
87 {
88 #ifdef __WXMAC__
89     return IntSize(20,20);
90 #else
91     return IntSize(16,16);
92 #endif
93 }
94
95 void ScrollbarThemeWx::splitTrack(Scrollbar* scrollbar, const IntRect& unconstrainedTrackRect, IntRect& beforeThumbRect, IntRect& thumbRect, IntRect& afterThumbRect)
96 {
97     ScrollbarThemeComposite::splitTrack(scrollbar, unconstrainedTrackRect, beforeThumbRect, thumbRect, afterThumbRect);
98 #ifdef __WXMAC__
99     // on Mac, there are a few pixels drawn above the actual track and so adjust
100     // the hit testing rects accordingly
101     int trackStart = 10; 
102     if (scrollbar->orientation() == HorizontalScrollbar) {
103         thumbRect.setX(thumbRect.x() + trackStart);
104         afterThumbRect.setX(afterThumbRect.x() - trackStart);
105     } else {
106         thumbRect.setY(thumbRect.y() + trackStart);
107         afterThumbRect.setY(afterThumbRect.y() - trackStart);
108     }
109 #endif
110 }
111
112 IntRect ScrollbarThemeWx::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
113 {
114     // FIXME: Handling this case is needed when there are two sets of arrow buttons
115     // on Mac, one at the top and one at the bottom.
116     if (part == BackButtonEndPart)
117         return IntRect();
118
119     IntSize size = buttonSize(scrollbar);
120     int x = scrollbar->x();
121     int y = scrollbar->y();
122     
123 #if __WXMAC__
124     if (scrollbar->orientation() == HorizontalScrollbar)
125         x += scrollbar->width() - (size.width() * 2) + cMacButtonOverlap;
126     else
127         y += scrollbar->height() - (size.height() * 2) + cMacButtonOverlap;
128 #endif
129     
130     return IntRect(x, y, size.width(), size.height());
131 }
132
133 IntRect ScrollbarThemeWx::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
134 {
135     // FIXME: Handling this case is needed when there are two sets of arrow buttons
136     // on Mac, one at the top and one at the bottom.
137     if (part == ForwardButtonStartPart)
138         return IntRect();
139
140     IntSize size = buttonSize(scrollbar);
141     int x, y;
142     if (scrollbar->orientation() == HorizontalScrollbar) {
143 #ifdef __WXMAC__
144         size.setWidth(size.width() + cMacButtonOverlap);
145 #endif
146         x = scrollbar->x() + scrollbar->width() - size.width();
147         y = scrollbar->y();
148     } else {
149         x = scrollbar->x();
150 #ifdef __WXMAC__
151         size.setHeight(size.height() + cMacButtonOverlap);
152 #endif
153         y = scrollbar->y() + scrollbar->height() - size.height();
154     }
155     return IntRect(x, y, size.width(), size.height());
156 }
157
158 IntRect ScrollbarThemeWx::trackRect(Scrollbar* scrollbar, bool)
159 {
160     IntSize bs = buttonSize(scrollbar);
161     int trackStart = 0;
162     if (scrollbar->orientation() == HorizontalScrollbar)
163         trackStart = bs.width();
164     else
165         trackStart = bs.height();
166         
167 #if __WXMAC__
168     trackStart = 0;
169 #endif
170     
171     int thickness = scrollbarThickness(scrollbar->controlSize());
172     if (scrollbar->orientation() == HorizontalScrollbar) {
173         if (scrollbar->width() < 2 * thickness)
174             return IntRect();
175         return IntRect(scrollbar->x() + trackStart, scrollbar->y(), scrollbar->width() - 2 * bs.width(), thickness);
176     }
177     if (scrollbar->height() < 2 * thickness)
178         return IntRect();
179     return IntRect(scrollbar->x(), scrollbar->y() + trackStart, thickness, scrollbar->height() - 2 * bs.height());
180 }
181
182 void ScrollbarThemeWx::paintScrollCorner(ScrollView* view, GraphicsContext* context, const IntRect& cornerRect)
183 {
184     // ScrollbarThemeComposite::paintScrollCorner incorrectly assumes that the
185     // ScrollView is a FrameView (see FramelessScrollView), so we cannot let
186     // that code run.  For FrameView's this is correct since we don't do custom
187     // scrollbar corner rendering, which ScrollbarThemeComposite supports.
188     ScrollbarTheme::paintScrollCorner(view, context, cornerRect);
189 }
190
191 bool ScrollbarThemeWx::paint(Scrollbar* scrollbar, GraphicsContext* context, const IntRect& rect)
192 {
193     wxOrientation orientation = (scrollbar->orientation() == HorizontalScrollbar) ? wxHORIZONTAL : wxVERTICAL;
194     int flags = 0;
195     if (scrollbar->scrollableArea()->isActive())
196         flags |= wxCONTROL_FOCUSED;
197     
198     if (!scrollbar->enabled())
199         flags |= wxCONTROL_DISABLED;
200     
201     wxDC* dc = static_cast<wxDC*>(context->platformContext());
202     
203     ScrollView* root = scrollbar->root();
204     ASSERT(root);
205     if (!root)
206         return false;
207     
208     wxWindow* webview = root->hostWindow()->platformPageClient();
209     LocalDC localDC(dc, scrollbar->frameRect());
210     
211     wxRenderer_DrawScrollbar(webview, *localDC.context(), scrollbar->frameRect(), orientation, scrollbar->currentPos(), static_cast<wxScrollbarPart>(scrollbar->pressedPart()),    
212                      static_cast<wxScrollbarPart>(scrollbar->hoveredPart()), scrollbar->maximum(), scrollbar->pageStep(), flags);
213
214     return true;
215 }
216
217 }
218