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 "PlatformBridge.h"
32 #include "RenderObject.h"
33 #include "RenderProgress.h"
34 #include "RenderSlider.h"
35 #include "ScrollbarTheme.h"
36 #include "UserAgentStyleSheets.h"
37
38 namespace WebCore {
39
40 unsigned RenderThemeChromiumLinux::m_activeSelectionBackgroundColor =
41 0xff1e90ff;
42 unsigned RenderThemeChromiumLinux::m_activeSelectionForegroundColor =
43 Color::black;
44 unsigned RenderThemeChromiumLinux::m_inactiveSelectionBackgroundColor =
45 0xffc8c8c8;
46 unsigned RenderThemeChromiumLinux::m_inactiveSelectionForegroundColor =
47 0xff323232;
48
49 double RenderThemeChromiumLinux::m_caretBlinkInterval;
50
51 static const unsigned defaultButtonBackgroundColor = 0xffdddddd;
52
getWebThemeState(const RenderTheme * theme,const RenderObject * o)53 static PlatformBridge::ThemePaintState getWebThemeState(const RenderTheme* theme, const RenderObject* o)
54 {
55 if (!theme->isEnabled(o))
56 return PlatformBridge::StateDisabled;
57 if (theme->isPressed(o))
58 return PlatformBridge::StatePressed;
59 if (theme->isHovered(o))
60 return PlatformBridge::StateHover;
61
62 return PlatformBridge::StateNormal;
63 }
64
65
create()66 PassRefPtr<RenderTheme> RenderThemeChromiumLinux::create()
67 {
68 return adoptRef(new RenderThemeChromiumLinux());
69 }
70
themeForPage(Page * page)71 PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
72 {
73 static RenderTheme* rt = RenderThemeChromiumLinux::create().releaseRef();
74 return rt;
75 }
76
RenderThemeChromiumLinux()77 RenderThemeChromiumLinux::RenderThemeChromiumLinux()
78 {
79 m_caretBlinkInterval = RenderTheme::caretBlinkInterval();
80 }
81
~RenderThemeChromiumLinux()82 RenderThemeChromiumLinux::~RenderThemeChromiumLinux()
83 {
84 }
85
systemColor(int cssValueId) const86 Color RenderThemeChromiumLinux::systemColor(int cssValueId) const
87 {
88 static const Color linuxButtonGrayColor(0xffdddddd);
89
90 if (cssValueId == CSSValueButtonface)
91 return linuxButtonGrayColor;
92 return RenderTheme::systemColor(cssValueId);
93 }
94
extraDefaultStyleSheet()95 String RenderThemeChromiumLinux::extraDefaultStyleSheet()
96 {
97 return RenderThemeChromiumSkia::extraDefaultStyleSheet() +
98 String(themeChromiumLinuxUserAgentStyleSheet, sizeof(themeChromiumLinuxUserAgentStyleSheet));
99 }
100
controlSupportsTints(const RenderObject * o) const101 bool RenderThemeChromiumLinux::controlSupportsTints(const RenderObject* o) const
102 {
103 return isEnabled(o);
104 }
105
activeListBoxSelectionBackgroundColor() const106 Color RenderThemeChromiumLinux::activeListBoxSelectionBackgroundColor() const
107 {
108 return Color(0x28, 0x28, 0x28);
109 }
110
activeListBoxSelectionForegroundColor() const111 Color RenderThemeChromiumLinux::activeListBoxSelectionForegroundColor() const
112 {
113 return Color::black;
114 }
115
inactiveListBoxSelectionBackgroundColor() const116 Color RenderThemeChromiumLinux::inactiveListBoxSelectionBackgroundColor() const
117 {
118 return Color(0xc8, 0xc8, 0xc8);
119 }
120
inactiveListBoxSelectionForegroundColor() const121 Color RenderThemeChromiumLinux::inactiveListBoxSelectionForegroundColor() const
122 {
123 return Color(0x32, 0x32, 0x32);
124 }
125
platformActiveSelectionBackgroundColor() const126 Color RenderThemeChromiumLinux::platformActiveSelectionBackgroundColor() const
127 {
128 return m_activeSelectionBackgroundColor;
129 }
130
platformInactiveSelectionBackgroundColor() const131 Color RenderThemeChromiumLinux::platformInactiveSelectionBackgroundColor() const
132 {
133 return m_inactiveSelectionBackgroundColor;
134 }
135
platformActiveSelectionForegroundColor() const136 Color RenderThemeChromiumLinux::platformActiveSelectionForegroundColor() const
137 {
138 return m_activeSelectionForegroundColor;
139 }
140
platformInactiveSelectionForegroundColor() const141 Color RenderThemeChromiumLinux::platformInactiveSelectionForegroundColor() const
142 {
143 return m_inactiveSelectionForegroundColor;
144 }
145
adjustSliderThumbSize(RenderObject * o) const146 void RenderThemeChromiumLinux::adjustSliderThumbSize(RenderObject* o) const
147 {
148 IntSize size = PlatformBridge::getThemePartSize(PlatformBridge::PartSliderThumb);
149
150 if (o->style()->appearance() == SliderThumbHorizontalPart) {
151 o->style()->setWidth(Length(size.width(), Fixed));
152 o->style()->setHeight(Length(size.height(), Fixed));
153 } else if (o->style()->appearance() == SliderThumbVerticalPart) {
154 o->style()->setWidth(Length(size.height(), Fixed));
155 o->style()->setHeight(Length(size.width(), Fixed));
156 } else
157 RenderThemeChromiumSkia::adjustSliderThumbSize(o);
158 }
159
supportsControlTints() const160 bool RenderThemeChromiumLinux::supportsControlTints() const
161 {
162 return true;
163 }
164
setCaretBlinkInterval(double interval)165 void RenderThemeChromiumLinux::setCaretBlinkInterval(double interval)
166 {
167 m_caretBlinkInterval = interval;
168 }
169
caretBlinkIntervalInternal() const170 double RenderThemeChromiumLinux::caretBlinkIntervalInternal() const
171 {
172 return m_caretBlinkInterval;
173 }
174
setSelectionColors(unsigned activeBackgroundColor,unsigned activeForegroundColor,unsigned inactiveBackgroundColor,unsigned inactiveForegroundColor)175 void RenderThemeChromiumLinux::setSelectionColors(
176 unsigned activeBackgroundColor,
177 unsigned activeForegroundColor,
178 unsigned inactiveBackgroundColor,
179 unsigned inactiveForegroundColor)
180 {
181 m_activeSelectionBackgroundColor = activeBackgroundColor;
182 m_activeSelectionForegroundColor = activeForegroundColor;
183 m_inactiveSelectionBackgroundColor = inactiveBackgroundColor;
184 m_inactiveSelectionForegroundColor = inactiveForegroundColor;
185 }
186
paintCheckbox(RenderObject * o,const PaintInfo & i,const IntRect & rect)187 bool RenderThemeChromiumLinux::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& rect)
188 {
189 PlatformBridge::ThemePaintExtraParams extraParams;
190 extraParams.button.checked = isChecked(o);
191 extraParams.button.indeterminate = isIndeterminate(o);
192
193 PlatformBridge::paintThemePart(i.context, PlatformBridge::PartCheckbox, getWebThemeState(this, o), rect, &extraParams);
194 return false;
195 }
196
setCheckboxSize(RenderStyle * style) const197 void RenderThemeChromiumLinux::setCheckboxSize(RenderStyle* style) const
198 {
199 // If the width and height are both specified, then we have nothing to do.
200 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
201 return;
202
203 IntSize size = PlatformBridge::getThemePartSize(PlatformBridge::PartCheckbox);
204 setSizeIfAuto(style, size);
205 }
206
paintRadio(RenderObject * o,const PaintInfo & i,const IntRect & rect)207 bool RenderThemeChromiumLinux::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& rect)
208 {
209 PlatformBridge::ThemePaintExtraParams extraParams;
210 extraParams.button.checked = isChecked(o);
211
212 PlatformBridge::paintThemePart(i.context, PlatformBridge::PartRadio, getWebThemeState(this, o), rect, &extraParams);
213 return false;
214 }
215
setRadioSize(RenderStyle * style) const216 void RenderThemeChromiumLinux::setRadioSize(RenderStyle* style) const
217 {
218 // If the width and height are both specified, then we have nothing to do.
219 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
220 return;
221
222 IntSize size = PlatformBridge::getThemePartSize(PlatformBridge::PartRadio);
223 setSizeIfAuto(style, size);
224 }
225
paintButton(RenderObject * o,const PaintInfo & i,const IntRect & rect)226 bool RenderThemeChromiumLinux::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& rect)
227 {
228 PlatformBridge::ThemePaintExtraParams extraParams;
229 extraParams.button.isDefault = isDefault(o);
230 extraParams.button.hasBorder = true;
231 extraParams.button.backgroundColor = defaultButtonBackgroundColor;
232 if (o->hasBackground())
233 extraParams.button.backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor).rgb();
234
235 PlatformBridge::paintThemePart(i.context, PlatformBridge::PartButton, getWebThemeState(this, o), rect, &extraParams);
236 return false;
237 }
238
paintTextField(RenderObject * o,const PaintInfo & i,const IntRect & rect)239 bool RenderThemeChromiumLinux::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& rect)
240 {
241 // WebThemeEngine does not handle border rounded corner and background image
242 // so return true to draw CSS border and background.
243 if (o->style()->hasBorderRadius() || o->style()->hasBackgroundImage())
244 return true;
245
246 ControlPart part = o->style()->appearance();
247
248 PlatformBridge::ThemePaintExtraParams extraParams;
249 extraParams.textField.isTextArea = part == TextAreaPart;
250 extraParams.textField.isListbox = part == ListboxPart;
251
252 // Fallback to white if the specified color object is invalid.
253 Color backgroundColor(Color::white);
254 if (o->style()->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
255 backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor);
256 extraParams.textField.backgroundColor = backgroundColor.rgb();
257
258 PlatformBridge::paintThemePart(i.context, PlatformBridge::PartTextField, getWebThemeState(this, o), rect, &extraParams);
259 return false;
260 }
261
paintMenuList(RenderObject * o,const PaintInfo & i,const IntRect & rect)262 bool RenderThemeChromiumLinux::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& rect)
263 {
264 if (!o->isBox())
265 return false;
266
267 const int right = rect.x() + rect.width();
268 const int middle = rect.y() + rect.height() / 2;
269
270 PlatformBridge::ThemePaintExtraParams extraParams;
271 extraParams.menuList.arrowX = (o->style()->direction() == RTL) ? rect.x() + 7 : right - 13;
272 extraParams.menuList.arrowY = middle;
273 const RenderBox* box = toRenderBox(o);
274 // Match Chromium Win behaviour of showing all borders if any are shown.
275 extraParams.menuList.hasBorder = box->borderRight() || box->borderLeft() || box->borderTop() || box->borderBottom();
276 extraParams.menuList.hasBorderRadius = o->style()->hasBorderRadius();
277 // Fallback to transparent if the specified color object is invalid.
278 extraParams.menuList.backgroundColor = Color::transparent;
279 if (o->hasBackground())
280 extraParams.menuList.backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor).rgb();
281
282 PlatformBridge::paintThemePart(i.context, PlatformBridge::PartMenuList, getWebThemeState(this, o), rect, &extraParams);
283 return false;
284 }
285
paintSliderTrack(RenderObject * o,const PaintInfo & i,const IntRect & rect)286 bool RenderThemeChromiumLinux::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& rect)
287 {
288 PlatformBridge::ThemePaintExtraParams extraParams;
289 extraParams.slider.vertical = o->style()->appearance() == SliderVerticalPart;
290
291 PlatformBridge::paintThemePart(i.context, PlatformBridge::PartSliderTrack, getWebThemeState(this, o), rect, &extraParams);
292 return false;
293 }
294
paintSliderThumb(RenderObject * o,const PaintInfo & i,const IntRect & rect)295 bool RenderThemeChromiumLinux::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& rect)
296 {
297 PlatformBridge::ThemePaintExtraParams extraParams;
298 extraParams.slider.vertical = o->style()->appearance() == SliderThumbVerticalPart;
299 extraParams.slider.inDrag = toRenderSlider(o->parent())->inDragMode();
300
301 PlatformBridge::paintThemePart(i.context, PlatformBridge::PartSliderThumb, getWebThemeState(this, o), rect, &extraParams);
302 return false;
303 }
304
adjustInnerSpinButtonStyle(CSSStyleSelector *,RenderStyle * style,Element *) const305 void RenderThemeChromiumLinux::adjustInnerSpinButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
306 {
307 IntSize size = PlatformBridge::getThemePartSize(PlatformBridge::PartInnerSpinButton);
308
309 style->setWidth(Length(size.width(), Fixed));
310 style->setMinWidth(Length(size.width(), Fixed));
311 }
312
paintInnerSpinButton(RenderObject * o,const PaintInfo & i,const IntRect & rect)313 bool RenderThemeChromiumLinux::paintInnerSpinButton(RenderObject* o, const PaintInfo& i, const IntRect& rect)
314 {
315 PlatformBridge::ThemePaintExtraParams extraParams;
316 extraParams.innerSpin.spinUp = (controlStatesForRenderer(o) & SpinUpState);
317 extraParams.innerSpin.readOnly = isReadOnlyControl(o);
318
319 PlatformBridge::paintThemePart(i.context, PlatformBridge::PartInnerSpinButton, getWebThemeState(this, o), rect, &extraParams);
320 return false;
321 }
322
323 #if ENABLE(PROGRESS_TAG)
324
paintProgressBar(RenderObject * o,const PaintInfo & i,const IntRect & rect)325 bool RenderThemeChromiumLinux::paintProgressBar(RenderObject* o, const PaintInfo& i, const IntRect& rect)
326 {
327 if (!o->isProgress())
328 return true;
329
330 RenderProgress* renderProgress = toRenderProgress(o);
331 IntRect valueRect = progressValueRectFor(renderProgress, rect);
332
333 PlatformBridge::ThemePaintExtraParams extraParams;
334 extraParams.progressBar.determinate = renderProgress->isDeterminate();
335 extraParams.progressBar.valueRectX = valueRect.x();
336 extraParams.progressBar.valueRectY = valueRect.y();
337 extraParams.progressBar.valueRectWidth = valueRect.width();
338 extraParams.progressBar.valueRectHeight = valueRect.height();
339
340 PlatformBridge::paintThemePart(i.context, PlatformBridge::PartProgressBar, getWebThemeState(this, o), rect, &extraParams);
341 return false;
342 }
343
344 #endif
345
346 } // namespace WebCore
347