90251ad9b505780d0d72f4b2ce51761b991d5ab6
[WebKit-https.git] / Source / WebCore / rendering / RenderThemeChromiumLinux.cpp
1 /*
2  * Copyright (C) 2007 Apple Inc.
3  * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4  * Copyright (C) 2008 Collabora Ltd.
5  * Copyright (C) 2008, 2009 Google Inc.
6  * Copyright (C) 2009 Kenneth Rohde Christiansen
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #include "config.h"
26 #include "RenderThemeChromiumLinux.h"
27
28 #include "CSSValueKeywords.h"
29 #include "Color.h"
30 #include "PaintInfo.h"
31 #include "PlatformContextSkia.h"
32 #include "RenderObject.h"
33 #include "RenderProgress.h"
34 #include "RenderSlider.h"
35 #include "ScrollbarTheme.h"
36 #include "UserAgentStyleSheets.h"
37 #include <public/Platform.h>
38 #include <public/WebRect.h>
39 #include <public/linux/WebThemeEngine.h>
40
41 namespace WebCore {
42
43 unsigned RenderThemeChromiumLinux::m_activeSelectionBackgroundColor =
44     0xff1e90ff;
45 unsigned RenderThemeChromiumLinux::m_activeSelectionForegroundColor =
46     Color::black;
47 unsigned RenderThemeChromiumLinux::m_inactiveSelectionBackgroundColor =
48     0xffc8c8c8;
49 unsigned RenderThemeChromiumLinux::m_inactiveSelectionForegroundColor =
50     0xff323232;
51
52 double RenderThemeChromiumLinux::m_caretBlinkInterval;
53
54 static const unsigned defaultButtonBackgroundColor = 0xffdddddd;
55
56 static WebKit::WebThemeEngine::State getWebThemeState(const RenderTheme* theme, const RenderObject* o)
57 {
58     if (!theme->isEnabled(o))
59         return WebKit::WebThemeEngine::StateDisabled;
60     if (theme->isPressed(o))
61         return WebKit::WebThemeEngine::StatePressed;
62     if (theme->isHovered(o))
63         return WebKit::WebThemeEngine::StateHover;
64
65     return WebKit::WebThemeEngine::StateNormal;
66 }
67
68 PassRefPtr<RenderTheme> RenderThemeChromiumLinux::create()
69 {
70     return adoptRef(new RenderThemeChromiumLinux());
71 }
72
73 // RenderTheme::themeForPage for Android is defined in RenderThemeChromiumAndroid.cpp.
74 #if !OS(ANDROID)
75 PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
76 {
77     static RenderTheme* rt = RenderThemeChromiumLinux::create().leakRef();
78     return rt;
79 }
80 #endif
81
82 RenderThemeChromiumLinux::RenderThemeChromiumLinux()
83 {
84     m_caretBlinkInterval = RenderTheme::caretBlinkInterval();
85 }
86
87 RenderThemeChromiumLinux::~RenderThemeChromiumLinux()
88 {
89 }
90
91 Color RenderThemeChromiumLinux::systemColor(int cssValueId) const
92 {
93     static const Color linuxButtonGrayColor(0xffdddddd);
94
95     if (cssValueId == CSSValueButtonface)
96         return linuxButtonGrayColor;
97     return RenderTheme::systemColor(cssValueId);
98 }
99
100 String RenderThemeChromiumLinux::extraDefaultStyleSheet()
101 {
102     return RenderThemeChromiumSkia::extraDefaultStyleSheet() +
103            String(themeChromiumLinuxUserAgentStyleSheet, sizeof(themeChromiumLinuxUserAgentStyleSheet));
104 }
105
106 bool RenderThemeChromiumLinux::controlSupportsTints(const RenderObject* o) const
107 {
108     return isEnabled(o);
109 }
110
111 Color RenderThemeChromiumLinux::activeListBoxSelectionBackgroundColor() const
112 {
113     return Color(0x28, 0x28, 0x28);
114 }
115
116 Color RenderThemeChromiumLinux::activeListBoxSelectionForegroundColor() const
117 {
118     return Color::black;
119 }
120
121 Color RenderThemeChromiumLinux::inactiveListBoxSelectionBackgroundColor() const
122 {
123     return Color(0xc8, 0xc8, 0xc8);
124 }
125
126 Color RenderThemeChromiumLinux::inactiveListBoxSelectionForegroundColor() const
127 {
128     return Color(0x32, 0x32, 0x32);
129 }
130
131 Color RenderThemeChromiumLinux::platformActiveSelectionBackgroundColor() const
132 {
133     return m_activeSelectionBackgroundColor;
134 }
135
136 Color RenderThemeChromiumLinux::platformInactiveSelectionBackgroundColor() const
137 {
138     return m_inactiveSelectionBackgroundColor;
139 }
140
141 Color RenderThemeChromiumLinux::platformActiveSelectionForegroundColor() const
142 {
143     return m_activeSelectionForegroundColor;
144 }
145
146 Color RenderThemeChromiumLinux::platformInactiveSelectionForegroundColor() const
147 {
148     return m_inactiveSelectionForegroundColor;
149 }
150
151 #if ENABLE(DATALIST_ELEMENT)
152 IntSize RenderThemeChromiumLinux::sliderTickSize() const
153 {
154     return IntSize(1, 6);
155 }
156
157 int RenderThemeChromiumLinux::sliderTickOffsetFromTrackCenter() const
158 {
159     return -16;
160 }
161 #endif
162
163 void RenderThemeChromiumLinux::adjustSliderThumbSize(RenderStyle* style, Element* element) const
164 {
165     IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartSliderThumb);
166
167     if (style->appearance() == SliderThumbHorizontalPart) {
168         style->setWidth(Length(size.width(), Fixed));
169         style->setHeight(Length(size.height(), Fixed));
170     } else if (style->appearance() == SliderThumbVerticalPart) {
171         style->setWidth(Length(size.height(), Fixed));
172         style->setHeight(Length(size.width(), Fixed));
173     } else
174         RenderThemeChromiumSkia::adjustSliderThumbSize(style, element);
175 }
176
177 bool RenderThemeChromiumLinux::supportsControlTints() const
178 {
179     return true;
180 }
181
182 void RenderThemeChromiumLinux::setCaretBlinkInterval(double interval)
183 {
184     m_caretBlinkInterval = interval;
185 }
186
187 double RenderThemeChromiumLinux::caretBlinkIntervalInternal() const
188 {
189     return m_caretBlinkInterval;
190 }
191
192 void RenderThemeChromiumLinux::setSelectionColors(
193     unsigned activeBackgroundColor,
194     unsigned activeForegroundColor,
195     unsigned inactiveBackgroundColor,
196     unsigned inactiveForegroundColor)
197 {
198     m_activeSelectionBackgroundColor = activeBackgroundColor;
199     m_activeSelectionForegroundColor = activeForegroundColor;
200     m_inactiveSelectionBackgroundColor = inactiveBackgroundColor;
201     m_inactiveSelectionForegroundColor = inactiveForegroundColor;
202 }
203
204 bool RenderThemeChromiumLinux::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& rect)
205 {
206     WebKit::WebThemeEngine::ExtraParams extraParams;
207     WebKit::WebCanvas* canvas = i.context->platformContext()->canvas();
208     extraParams.button.checked = isChecked(o);
209     extraParams.button.indeterminate = isIndeterminate(o);
210
211     WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartCheckbox, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams);
212     return false;
213 }
214
215 void RenderThemeChromiumLinux::setCheckboxSize(RenderStyle* style) const
216 {
217     // If the width and height are both specified, then we have nothing to do.
218     if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
219         return;
220
221     IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartCheckbox);
222     setSizeIfAuto(style, size);
223 }
224
225 bool RenderThemeChromiumLinux::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& rect)
226 {
227     WebKit::WebThemeEngine::ExtraParams extraParams;
228     WebKit::WebCanvas* canvas = i.context->platformContext()->canvas();
229     extraParams.button.checked = isChecked(o);
230
231     WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartRadio, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams);
232     return false;
233 }
234
235 void RenderThemeChromiumLinux::setRadioSize(RenderStyle* style) const
236 {
237     // If the width and height are both specified, then we have nothing to do.
238     if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
239         return;
240
241     IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartRadio);
242     setSizeIfAuto(style, size);
243 }
244
245 bool RenderThemeChromiumLinux::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& rect)
246 {
247     WebKit::WebThemeEngine::ExtraParams extraParams;
248     WebKit::WebCanvas* canvas = i.context->platformContext()->canvas();
249     extraParams.button.isDefault = isDefault(o);
250     extraParams.button.hasBorder = true;
251     extraParams.button.backgroundColor = defaultButtonBackgroundColor;
252     if (o->hasBackground())
253         extraParams.button.backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor).rgb();
254
255     WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartButton, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams);
256     return false;
257 }
258
259 bool RenderThemeChromiumLinux::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& rect)
260 {
261     // WebThemeEngine does not handle border rounded corner and background image
262     // so return true to draw CSS border and background.
263     if (o->style()->hasBorderRadius() || o->style()->hasBackgroundImage())
264         return true;
265
266     ControlPart part = o->style()->appearance();
267
268     WebKit::WebThemeEngine::ExtraParams extraParams;
269     extraParams.textField.isTextArea = part == TextAreaPart;
270     extraParams.textField.isListbox = part == ListboxPart;
271
272     WebKit::WebCanvas* canvas = i.context->platformContext()->canvas();
273
274     // Fallback to white if the specified color object is invalid.
275     Color backgroundColor(Color::white);
276     if (o->style()->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
277         backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor);
278     extraParams.textField.backgroundColor = backgroundColor.rgb();
279
280     WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartTextField, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams);
281     return false;
282 }
283
284 bool RenderThemeChromiumLinux::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& rect)
285 {
286     if (!o->isBox())
287         return false;
288
289     const int right = rect.x() + rect.width();
290     const int middle = rect.y() + rect.height() / 2;
291
292     WebKit::WebThemeEngine::ExtraParams extraParams;
293     extraParams.menuList.arrowX = (o->style()->direction() == RTL) ? rect.x() + 7 : right - 13;
294     extraParams.menuList.arrowY = middle;
295     const RenderBox* box = toRenderBox(o);
296     // Match Chromium Win behaviour of showing all borders if any are shown.
297     extraParams.menuList.hasBorder = box->borderRight() || box->borderLeft() || box->borderTop() || box->borderBottom();
298     extraParams.menuList.hasBorderRadius = o->style()->hasBorderRadius();
299     // Fallback to transparent if the specified color object is invalid.
300     extraParams.menuList.backgroundColor = Color::transparent;
301     if (o->hasBackground())
302         extraParams.menuList.backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor).rgb();
303
304     WebKit::WebCanvas* canvas = i.context->platformContext()->canvas();
305
306     WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartMenuList, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams);
307     return false;
308 }
309
310 bool RenderThemeChromiumLinux::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& rect)
311 {
312     WebKit::WebThemeEngine::ExtraParams extraParams;
313     WebKit::WebCanvas* canvas = i.context->platformContext()->canvas();
314     extraParams.slider.vertical = o->style()->appearance() == SliderVerticalPart;
315
316     WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartSliderTrack, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams);
317
318 #if ENABLE(DATALIST_ELEMENT)
319     paintSliderTicks(o, i, rect);
320 #endif
321
322     return false;
323 }
324
325 bool RenderThemeChromiumLinux::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& rect)
326 {
327     WebKit::WebThemeEngine::ExtraParams extraParams;
328     WebKit::WebCanvas* canvas = i.context->platformContext()->canvas();
329     extraParams.slider.vertical = o->style()->appearance() == SliderThumbVerticalPart;
330     extraParams.slider.inDrag = isPressed(o);
331
332     WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartSliderThumb, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams);
333     return false;
334 }
335
336 void RenderThemeChromiumLinux::adjustInnerSpinButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
337 {
338     IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartInnerSpinButton);
339
340     style->setWidth(Length(size.width(), Fixed));
341     style->setMinWidth(Length(size.width(), Fixed));
342 }
343
344 bool RenderThemeChromiumLinux::paintInnerSpinButton(RenderObject* o, const PaintInfo& i, const IntRect& rect)
345 {
346     WebKit::WebThemeEngine::ExtraParams extraParams;
347     WebKit::WebCanvas* canvas = i.context->platformContext()->canvas();
348     extraParams.innerSpin.spinUp = (controlStatesForRenderer(o) & SpinUpState);
349     extraParams.innerSpin.readOnly = isReadOnlyControl(o);
350
351     WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartInnerSpinButton, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams);
352     return false;
353 }
354
355 #if ENABLE(PROGRESS_ELEMENT)
356
357 bool RenderThemeChromiumLinux::paintProgressBar(RenderObject* o, const PaintInfo& i, const IntRect& rect)
358 {
359     if (!o->isProgress())
360         return true;
361
362     RenderProgress* renderProgress = toRenderProgress(o);
363     IntRect valueRect = progressValueRectFor(renderProgress, rect);
364
365     WebKit::WebThemeEngine::ExtraParams extraParams;
366     extraParams.progressBar.determinate = renderProgress->isDeterminate();
367     extraParams.progressBar.valueRectX = valueRect.x();
368     extraParams.progressBar.valueRectY = valueRect.y();
369     extraParams.progressBar.valueRectWidth = valueRect.width();
370     extraParams.progressBar.valueRectHeight = valueRect.height();
371
372     DirectionFlippingScope scope(o, i, rect);
373     WebKit::WebCanvas* canvas = i.context->platformContext()->canvas();
374     WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartProgressBar, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams);
375     return false;
376 }
377
378 #endif
379
380 } // namespace WebCore