2 * Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.com>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "RenderTheme.h"
30 #include "FrameView.h"
31 #include "GraphicsContext.h"
32 #include "HostWindow.h"
33 #include "NotImplemented.h"
34 #include "RenderView.h"
39 #include <wx/dcgraph.h>
40 #include <wx/renderer.h>
41 #include <wx/dcclient.h>
42 #include <wx/scrolwin.h>
43 #include <wx/settings.h>
47 class RenderThemeWx : public RenderTheme {
49 RenderThemeWx() : RenderTheme() { }
50 virtual ~RenderThemeWx();
53 static PassRefPtr<RenderTheme> create();
55 // A method asking if the theme's controls actually care about redrawing when hovered.
56 virtual bool supportsHover(const RenderStyle*) const { return true; }
58 virtual bool paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r)
60 return paintButton(o, i, r);
63 virtual void setCheckboxSize(RenderStyle*) const;
65 virtual bool paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& r)
67 return paintButton(o, i, r);
70 virtual void setRadioSize(RenderStyle*) const;
72 virtual void adjustRepaintRect(const RenderObject*, IntRect&);
74 virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
75 virtual bool paintButton(RenderObject*, const PaintInfo&, const IntRect&);
77 virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
78 virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&);
80 virtual int minimumMenuListSize(RenderStyle*) const;
82 virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
83 virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&);
85 virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
86 virtual bool paintMenuListButton(RenderObject*, const PaintInfo&, const IntRect&);
88 virtual bool isControlStyled(const RenderStyle*, const BorderData&,
89 const FillLayer&, const Color&) const;
91 virtual bool controlSupportsTints(const RenderObject*) const;
93 virtual void systemFont(int propId, FontDescription&) const;
95 virtual Color platformActiveSelectionBackgroundColor() const;
96 virtual Color platformInactiveSelectionBackgroundColor() const;
98 virtual Color platformActiveSelectionForegroundColor() const;
99 virtual Color platformInactiveSelectionForegroundColor() const;
101 virtual int popupInternalPaddingLeft(RenderStyle*) const;
102 virtual int popupInternalPaddingRight(RenderStyle*) const;
103 virtual int popupInternalPaddingTop(RenderStyle*) const;
104 virtual int popupInternalPaddingBottom(RenderStyle*) const;
107 void addIntrinsicMargins(RenderStyle*) const;
110 bool supportsFocus(ControlPart) const;
116 #define MINIMUM_MENU_LIST_SIZE 21
117 #define POPUP_INTERNAL_PADDING_LEFT 6
118 #define POPUP_INTERNAL_PADDING_TOP 2
119 #define POPUP_INTERNAL_PADDING_BOTTOM 2
122 #define POPUP_INTERNAL_PADDING_RIGHT 22
124 #define POPUP_INTERNAL_PADDING_RIGHT 20
127 RenderThemeWx::~RenderThemeWx()
131 PassRefPtr<RenderTheme> RenderThemeWx::create()
133 return adoptRef(new RenderThemeWx());
136 PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
138 static RenderTheme* rt = RenderThemeWx::create().releaseRef();
142 wxWindow* nativeWindowForRenderObject(RenderObject* o)
144 FrameView* frameView = o->view()->frameView();
146 ASSERT(frameView->hostWindow());
147 return frameView->hostWindow()->platformPageClient();
151 bool RenderThemeWx::isControlStyled(const RenderStyle* style, const BorderData& border,
152 const FillLayer& background, const Color& backgroundColor) const
154 if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart)
155 return style->border() != border;
157 // Normally CSS can be used to set properties of form controls (such as adding a background bitmap).
158 // However, for this to work RenderThemeWx needs to adjust uncustomized elements (e.g. buttons) to reflect the
159 // changes made by CSS. Since we don't do that right now, the native parts of form elements appear in odd places.
160 // Until we have time to implement that support, we return false here, so that we ignore customizations
161 // and always use the native theme drawing to draw form controls.
165 void RenderThemeWx::adjustRepaintRect(const RenderObject* o, IntRect& r)
167 switch (o->style()->appearance()) {
169 r.setWidth(r.width() + 100);
177 bool RenderThemeWx::controlSupportsTints(const RenderObject* o) const
182 // Checkboxes only have tint when checked.
183 if (o->style()->appearance() == CheckboxPart)
186 // For now assume other controls have tint if enabled.
190 void RenderThemeWx::systemFont(int propId, FontDescription& fontDescription) const
195 void RenderThemeWx::addIntrinsicMargins(RenderStyle* style) const
197 // Cut out the intrinsic margins completely if we end up using a small font size
198 if (style->fontSize() < 11)
201 // Intrinsic margin value.
204 // FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed.
205 if (style->width().isIntrinsicOrAuto()) {
206 if (style->marginLeft().quirk())
207 style->setMarginLeft(Length(m, Fixed));
209 if (style->marginRight().quirk())
210 style->setMarginRight(Length(m, Fixed));
213 if (style->height().isAuto()) {
214 if (style->marginTop().quirk())
215 style->setMarginTop(Length(m, Fixed));
217 if (style->marginBottom().quirk())
218 style->setMarginBottom(Length(m, Fixed));
222 void RenderThemeWx::setCheckboxSize(RenderStyle* style) const
224 // If the width and height are both specified, then we have nothing to do.
225 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
228 // FIXME: A hard-coded size of 13 is used. This is wrong but necessary for now. It matches Firefox.
229 // At different DPI settings on Windows, querying the theme gives you a larger size that accounts for
230 // the higher DPI. Until our entire engine honors a DPI setting other than 96, we can't rely on the theme's
232 if (style->width().isIntrinsicOrAuto())
233 style->setWidth(Length(13, Fixed));
235 if (style->height().isAuto())
236 style->setHeight(Length(13, Fixed));
239 void RenderThemeWx::setRadioSize(RenderStyle* style) const
241 // This is the same as checkboxes.
242 setCheckboxSize(style);
245 bool RenderThemeWx::supportsFocus(ControlPart part) const
252 default: // No for all others...
257 void RenderThemeWx::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
259 addIntrinsicMargins(style);
262 bool RenderThemeWx::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
264 wxWindow* window = nativeWindowForRenderObject(o);
265 wxDC* dc = static_cast<wxDC*>(i.context->platformContext());
270 // On Mac, wxGraphicsContext and wxDC share the same native implementation,
271 // and so transformations are available.
272 // On Win and Linux, however, this is not true and transforms are lost,
273 // so we need to restore them here.
274 #if USE(WXGC) && !defined(__WXMAC__)
278 wxGCDC* gcdc = static_cast<wxGCDC*>(dc);
279 wxGraphicsContext* gc = gcdc->GetGraphicsContext();
280 gc->GetTransform().TransformPoint(&xtrans, &ytrans);
281 rect.setX(r.x() + (int)xtrans);
282 rect.setY(r.y() + (int)ytrans);
286 flags |= wxCONTROL_DISABLED;
288 ControlPart part = o->style()->appearance();
289 if (supportsFocus(part) && isFocused(o))
290 flags |= wxCONTROL_FOCUSED;
293 flags |= wxCONTROL_PRESSED;
295 if (part == PushButtonPart || part == ButtonPart)
296 wxRendererNative::Get().DrawPushButton(window, *dc, rect, flags);
297 else if(part == RadioPart) {
299 flags |= wxCONTROL_CHECKED;
300 #if wxCHECK_VERSION(2,9,1)
301 wxRendererNative::Get().DrawRadioBitmap(window, *dc, rect, flags);
302 #elif wxCHECK_VERSION(2,9,0)
303 wxRendererNative::Get().DrawRadioButton(window, *dc, rect, flags);
305 wxRenderer_DrawRadioButton(window, *dc, rect, flags);
308 else if(part == CheckboxPart) {
310 flags |= wxCONTROL_CHECKED;
311 wxRendererNative::Get().DrawCheckBox(window, *dc, rect, flags);
316 void RenderThemeWx::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
321 bool RenderThemeWx::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r)
323 wxWindow* window = nativeWindowForRenderObject(o);
324 wxDC* dc = static_cast<wxDC*>(i.context->platformContext());
325 #if wxCHECK_VERSION(2,9,0)
326 wxRendererNative::Get().DrawTextCtrl(window, *dc, r, 0);
328 wxRenderer_DrawTextCtrl(window, *dc, r, 0);
334 int RenderThemeWx::minimumMenuListSize(RenderStyle*) const
336 return MINIMUM_MENU_LIST_SIZE;
339 void RenderThemeWx::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
343 bool RenderThemeWx::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r)
345 wxWindow* window = nativeWindowForRenderObject(o);
346 wxDC* dc = static_cast<wxDC*>(i.context->platformContext());
350 flags |= wxCONTROL_DISABLED;
352 if (supportsFocus(o->style()->appearance()) && isFocused(o))
353 flags |= wxCONTROL_FOCUSED;
356 flags |= wxCONTROL_PRESSED;
358 #if wxCHECK_VERSION(2,9,0)
359 wxRendererNative::Get().DrawChoice(window, *dc, r, flags);
361 wxRenderer_DrawChoice(window, *dc, r, flags);
367 void RenderThemeWx::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const
372 bool RenderThemeWx::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
374 wxWindow* window = nativeWindowForRenderObject(o);
375 wxDC* dc = static_cast<wxDC*>(i.context->platformContext());
379 flags |= wxCONTROL_DISABLED;
381 if (supportsFocus(o->style()->appearance()) && isFocused(o))
382 flags |= wxCONTROL_FOCUSED;
385 flags |= wxCONTROL_PRESSED;
387 wxRendererNative::Get().DrawComboBoxDropButton(window, *dc, r, flags);
393 Color RenderThemeWx::platformActiveSelectionBackgroundColor() const
395 return wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
398 Color RenderThemeWx::platformInactiveSelectionBackgroundColor() const
400 return wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW);
403 Color RenderThemeWx::platformActiveSelectionForegroundColor() const
405 // FIXME: Get wx to return the correct value for each platform.
409 return Color(255, 255, 255);
413 Color RenderThemeWx::platformInactiveSelectionForegroundColor() const
418 return Color(255, 255, 255);
422 int RenderThemeWx::popupInternalPaddingLeft(RenderStyle*) const
424 return POPUP_INTERNAL_PADDING_LEFT;
427 int RenderThemeWx::popupInternalPaddingRight(RenderStyle*) const
429 return POPUP_INTERNAL_PADDING_RIGHT;
432 int RenderThemeWx::popupInternalPaddingTop(RenderStyle*) const
434 return POPUP_INTERNAL_PADDING_TOP;
437 int RenderThemeWx::popupInternalPaddingBottom(RenderStyle*) const
439 return POPUP_INTERNAL_PADDING_BOTTOM;