[wx] Enable wxWebKit to run using the wxGC Cairo backend on platforms other than...
[WebKit-https.git] / Source / WebCore / platform / wx / wxcode / win / scrollbar_render.cpp
1 /*
2  * Copyright (C) 2009 Kevin Ollivier  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 COMPUTER, 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 COMPUTER, 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
28 #include "scrollbar_render.h"
29
30 #include <wx/defs.h>
31
32 #include <wx/dc.h>
33 #include <wx/dcgraph.h>
34 #include <wx/graphics.h>
35 #include <wx/renderer.h>
36 #include <wx/window.h>
37
38 #include <wx/msw/private.h>
39 #include <wx/msw/uxtheme.h>
40
41 // constants
42 #define SP_BUTTON          1
43 #define SP_THUMBHOR        2
44 #define SP_THUMBVERT       3
45 #define SP_TRACKENDHOR      4
46 #define SP_TRACKENDVERT     7
47 #define SP_GRIPPERHOR       8
48 #define SP_GRIPPERVERT      9
49
50 #define TS_NORMAL           1
51 #define TS_HOVER            2
52 #define TS_ACTIVE           3
53 #define TS_DISABLED         4
54
55 #define TS_UP_BUTTON       0
56 #define TS_DOWN_BUTTON     4
57 #define TS_LEFT_BUTTON     8
58 #define TS_RIGHT_BUTTON    12
59
60 #if wxUSE_GRAPHICS_CONTEXT
61 // TODO remove this dependency (gdiplus needs the macros)
62 // we need to undef because the macros are being defined in WebCorePrefix.h
63 // but GdiPlus.h is not accepting them
64 #undef max
65 #define max(a,b)            (((a) > (b)) ? (a) : (b))
66
67 #undef min
68 #define min(a,b)            (((a) < (b)) ? (a) : (b))
69
70 #include <wx/dcgraph.h>
71 #include "gdiplus.h"
72 using namespace Gdiplus;
73 #endif // wxUSE_GRAPHICS_CONTEXT
74
75 class GraphicsHDC
76 {
77 public:
78     GraphicsHDC(wxDC* dc)
79     {
80 #if wxUSE_GRAPHICS_CONTEXT && (!defined(wxUSE_CAIRO) || !wxUSE_CAIRO)
81         m_graphics = NULL;
82         wxGCDC* gcdc = wxDynamicCast(dc, wxGCDC);
83         if (gcdc) {
84             m_graphics = (Graphics*)gcdc->GetGraphicsContext()->GetNativeContext();
85             m_hdc = m_graphics->GetHDC();
86         }
87         else
88 #endif
89             m_hdc = GetHdcOf(*dc);
90     }
91
92     ~GraphicsHDC()
93     {
94 #if wxUSE_GRAPHICS_CONTEXT  && (!defined(wxUSE_CAIRO) || !wxUSE_CAIRO)
95         if (m_graphics)
96             m_graphics->ReleaseHDC(m_hdc);
97 #endif
98     }
99
100     operator HDC() const { return m_hdc; }
101
102 private:
103     HDC         m_hdc;
104 #if wxUSE_GRAPHICS_CONTEXT  && (!defined(wxUSE_CAIRO) || !wxUSE_CAIRO)
105     Graphics*   m_graphics;
106 #endif
107 };
108
109 int getTSStateForPart(wxScrollbarPart part, wxScrollbarPart focusPart, wxScrollbarPart hoverPart, int flags = 0)
110 {
111     int xpState = TS_NORMAL;
112     if (flags & wxCONTROL_DISABLED)
113         xpState = TS_DISABLED;
114     else if (part == focusPart)
115         xpState = TS_ACTIVE;
116     else if (part == hoverPart)
117         xpState = TS_HOVER;
118         
119     return xpState;
120 }
121
122 void wxRenderer_DrawScrollbar(wxWindow* window, wxDC& dc,
123                              const wxRect& rect, wxOrientation orient, int current, wxScrollbarPart focusPart, wxScrollbarPart hoverPart, int max, int step, int flags)
124 {
125     wxUxThemeEngine *engine = wxUxThemeEngine::Get();
126     HTHEME hTheme = (HTHEME)engine->OpenThemeData(0, L"SCROLLBAR");
127
128     bool horiz = orient == wxHORIZONTAL;
129     int part = 0;
130     if (horiz)
131         part = SP_TRACKENDHOR;
132     else
133         part = SP_TRACKENDVERT;
134
135     int xpState = TS_NORMAL;
136     wxRect transRect = rect;
137
138 #if USE(WXGC) && !defined(wxUSE_CAIRO) || !wxUSE_CAIRO
139     // when going from GdiPlus -> Gdi, any GdiPlus transformations are lost
140     // so we need to alter the coordinates to reflect their transformed point.
141     double xtrans = 0;
142     double ytrans = 0;
143     
144     wxGCDC* gcdc = wxDynamicCast(&dc, wxGCDC);
145     wxGraphicsContext* gc = gcdc->GetGraphicsContext();
146     gc->GetTransform().TransformPoint(&xtrans, &ytrans);
147
148     transRect.x += (int)xtrans;
149     transRect.y += (int)ytrans;
150 #else
151
152 #endif
153
154     RECT r;
155     wxCopyRectToRECT(transRect, r);
156
157     // Unlike Mac, on MSW you draw the scrollbar piece by piece.
158     // so we draw the track first, then the buttons
159     if (hTheme)
160     {
161         engine->DrawThemeBackground(hTheme, GraphicsHDC(&dc), part, xpState, &r, 0);
162
163         int buttonSize = 16;
164             
165         part = SP_BUTTON;
166         xpState = getTSStateForPart(wxSCROLLPART_BACKBTNSTART, focusPart, hoverPart, flags);
167         xpState += horiz ? TS_LEFT_BUTTON : TS_UP_BUTTON;
168         RECT buttonRect = r;
169         buttonRect.bottom = buttonRect.top + buttonSize;
170         buttonRect.right = buttonRect.left + buttonSize;
171         engine->DrawThemeBackground(hTheme, GraphicsHDC(&dc), part, xpState, &buttonRect, 0);
172
173         xpState = getTSStateForPart(wxSCROLLPART_FWDBTNEND, focusPart, hoverPart, flags);
174         xpState += horiz ? TS_RIGHT_BUTTON : TS_DOWN_BUTTON;
175         buttonRect = r;
176         buttonRect.top = buttonRect.bottom - buttonSize;
177         buttonRect.left = buttonRect.right - buttonSize;
178         engine->DrawThemeBackground(hTheme, GraphicsHDC(&dc), part, xpState, &buttonRect, 0);
179
180         part = horiz ? SP_THUMBHOR : SP_THUMBVERT;
181
182         int physicalLength = horiz ? rect.width : rect.height;
183         physicalLength -= buttonSize*2;
184         int thumbStart = 0;
185         int thumbLength = 0;
186         calcThumbStartAndLength(physicalLength, max, 
187                             current, step, &thumbStart, &thumbLength);
188         buttonRect = r;
189         if (horiz) {
190             buttonRect.left = buttonRect.left + thumbStart + buttonSize;
191             buttonRect.right = buttonRect.left + thumbLength;
192         } else {
193             buttonRect.top = buttonRect.top + thumbStart + buttonSize;
194             buttonRect.bottom = buttonRect.top + thumbLength;
195         }
196
197         xpState = getTSStateForPart(wxSCROLLPART_THUMB, focusPart, hoverPart, flags);
198         engine->DrawThemeBackground(hTheme, GraphicsHDC(&dc), part, xpState, &buttonRect, 0);
199         
200         // draw the gripper
201         int thickness = ::GetSystemMetrics(SM_CXVSCROLL) / 2;
202         
203         buttonRect.left += ((buttonRect.right - buttonRect.left) - thickness) / 2;
204         buttonRect.top += ((buttonRect.bottom - buttonRect.top) - thickness) / 2;
205         buttonRect.right = buttonRect.left + thickness;
206         buttonRect.bottom = buttonRect.top + thickness;
207         
208         if (horiz)
209             part = SP_GRIPPERHOR;
210         else
211             part = SP_GRIPPERVERT;
212         
213
214
215         engine->DrawThemeBackground(hTheme, GraphicsHDC(&dc), part, xpState, &buttonRect, 0);
216     }
217 }