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