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
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.
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.
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.
26 #include "core/layout/LayoutThemeDefault.h"
28 #include "core/CSSValueKeywords.h"
29 #include "core/layout/LayoutObject.h"
30 #include "core/layout/LayoutProgress.h"
31 #include "core/layout/LayoutThemeFontProvider.h"
32 #include "core/paint/MediaControlsPainter.h"
33 #include "platform/LayoutTestSupport.h"
34 #include "platform/PlatformResourceLoader.h"
35 #include "platform/graphics/Color.h"
36 #include "platform/scroll/ScrollbarTheme.h"
37 #include "public/platform/Platform.h"
38 #include "public/platform/WebThemeEngine.h"
49 static const int styledMenuListInternalPadding
[4] = { 1, 4, 1, 4 };
51 // These values all match Safari/Win.
52 static const float defaultControlFontPixelSize
= 13;
53 static const float defaultCancelButtonSize
= 9;
54 static const float minCancelButtonSize
= 5;
55 static const float maxCancelButtonSize
= 21;
56 static const float defaultSearchFieldResultsDecorationSize
= 13;
57 static const float minSearchFieldResultsDecorationSize
= 9;
58 static const float maxSearchFieldResultsDecorationSize
= 30;
60 static bool useMockTheme()
62 return LayoutTestSupport::isRunningLayoutTest();
65 unsigned LayoutThemeDefault::m_activeSelectionBackgroundColor
= 0xff1e90ff;
66 unsigned LayoutThemeDefault::m_activeSelectionForegroundColor
= Color::black
;
67 unsigned LayoutThemeDefault::m_inactiveSelectionBackgroundColor
= 0xffc8c8c8;
68 unsigned LayoutThemeDefault::m_inactiveSelectionForegroundColor
= 0xff323232;
70 double LayoutThemeDefault::m_caretBlinkInterval
;
72 LayoutThemeDefault::LayoutThemeDefault()
74 m_caretBlinkInterval
= LayoutTheme::caretBlinkInterval();
77 LayoutThemeDefault::~LayoutThemeDefault()
81 bool LayoutThemeDefault::supportsFocusRing(const ComputedStyle
& style
) const
84 // Don't use focus rings for buttons when mocking controls.
85 return style
.appearance() == ButtonPart
86 || style
.appearance() == PushButtonPart
87 || style
.appearance() == SquareButtonPart
;
90 // This causes Blink to draw the focus rings for us.
94 Color
LayoutThemeDefault::systemColor(CSSValueID cssValueId
) const
96 static const Color
defaultButtonGrayColor(0xffdddddd);
97 static const Color
defaultMenuColor(0xfff7f7f7);
99 if (cssValueId
== CSSValueButtonface
) {
101 return Color(0xc0, 0xc0, 0xc0);
102 return defaultButtonGrayColor
;
104 if (cssValueId
== CSSValueMenu
)
105 return defaultMenuColor
;
106 return LayoutTheme::systemColor(cssValueId
);
109 // Use the Windows style sheets to match their metrics.
110 String
LayoutThemeDefault::extraDefaultStyleSheet()
112 return LayoutTheme::extraDefaultStyleSheet()
113 + loadResourceAsASCIIString("themeWin.css")
114 + loadResourceAsASCIIString("themeChromiumSkia.css")
115 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
116 + loadResourceAsASCIIString("themeInputMultipleFields.css")
118 + loadResourceAsASCIIString("themeChromium.css");
121 String
LayoutThemeDefault::extraQuirksStyleSheet()
123 return loadResourceAsASCIIString("themeWinQuirks.css");
126 Color
LayoutThemeDefault::activeListBoxSelectionBackgroundColor() const
128 return Color(0x28, 0x28, 0x28);
131 Color
LayoutThemeDefault::activeListBoxSelectionForegroundColor() const
136 Color
LayoutThemeDefault::inactiveListBoxSelectionBackgroundColor() const
138 return Color(0xc8, 0xc8, 0xc8);
141 Color
LayoutThemeDefault::inactiveListBoxSelectionForegroundColor() const
143 return Color(0x32, 0x32, 0x32);
146 Color
LayoutThemeDefault::platformActiveSelectionBackgroundColor() const
149 return Color(0x00, 0x00, 0xff); // Royal blue.
150 return m_activeSelectionBackgroundColor
;
153 Color
LayoutThemeDefault::platformInactiveSelectionBackgroundColor() const
156 return Color(0x99, 0x99, 0x99); // Medium gray.
157 return m_inactiveSelectionBackgroundColor
;
160 Color
LayoutThemeDefault::platformActiveSelectionForegroundColor() const
163 return Color(0xff, 0xff, 0xcc); // Pale yellow.
164 return m_activeSelectionForegroundColor
;
167 Color
LayoutThemeDefault::platformInactiveSelectionForegroundColor() const
171 return m_inactiveSelectionForegroundColor
;
174 IntSize
LayoutThemeDefault::sliderTickSize() const
177 return IntSize(1, 3);
178 return IntSize(1, 6);
181 int LayoutThemeDefault::sliderTickOffsetFromTrackCenter() const
188 void LayoutThemeDefault::adjustSliderThumbSize(ComputedStyle
& style
) const
190 IntSize size
= Platform::current()->themeEngine()->getSize(WebThemeEngine::PartSliderThumb
);
192 // FIXME: Mock theme doesn't handle zoomed sliders.
193 float zoomLevel
= useMockTheme() ? 1 : style
.effectiveZoom();
194 if (style
.appearance() == SliderThumbHorizontalPart
) {
195 style
.setWidth(Length(size
.width() * zoomLevel
, Fixed
));
196 style
.setHeight(Length(size
.height() * zoomLevel
, Fixed
));
197 } else if (style
.appearance() == SliderThumbVerticalPart
) {
198 style
.setWidth(Length(size
.height() * zoomLevel
, Fixed
));
199 style
.setHeight(Length(size
.width() * zoomLevel
, Fixed
));
201 MediaControlsPainter::adjustMediaSliderThumbSize(style
);
205 void LayoutThemeDefault::setCaretBlinkInterval(double interval
)
207 m_caretBlinkInterval
= interval
;
210 void LayoutThemeDefault::setSelectionColors(
211 unsigned activeBackgroundColor
,
212 unsigned activeForegroundColor
,
213 unsigned inactiveBackgroundColor
,
214 unsigned inactiveForegroundColor
)
216 m_activeSelectionBackgroundColor
= activeBackgroundColor
;
217 m_activeSelectionForegroundColor
= activeForegroundColor
;
218 m_inactiveSelectionBackgroundColor
= inactiveBackgroundColor
;
219 m_inactiveSelectionForegroundColor
= inactiveForegroundColor
;
222 void LayoutThemeDefault::setCheckboxSize(ComputedStyle
& 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 IntSize size
= Platform::current()->themeEngine()->getSize(WebThemeEngine::PartCheckbox
);
229 float zoomLevel
= style
.effectiveZoom();
230 size
.setWidth(size
.width() * zoomLevel
);
231 size
.setHeight(size
.height() * zoomLevel
);
232 setSizeIfAuto(style
, size
);
235 void LayoutThemeDefault::setRadioSize(ComputedStyle
& style
) const
237 // If the width and height are both specified, then we have nothing to do.
238 if (!style
.width().isIntrinsicOrAuto() && !style
.height().isAuto())
241 IntSize size
= Platform::current()->themeEngine()->getSize(WebThemeEngine::PartRadio
);
242 float zoomLevel
= style
.effectiveZoom();
243 size
.setWidth(size
.width() * zoomLevel
);
244 size
.setHeight(size
.height() * zoomLevel
);
245 setSizeIfAuto(style
, size
);
248 void LayoutThemeDefault::adjustInnerSpinButtonStyle(ComputedStyle
& style
) const
250 IntSize size
= Platform::current()->themeEngine()->getSize(WebThemeEngine::PartInnerSpinButton
);
252 style
.setWidth(Length(size
.width(), Fixed
));
253 style
.setMinWidth(Length(size
.width(), Fixed
));
256 bool LayoutThemeDefault::shouldOpenPickerWithF4Key() const
261 bool LayoutThemeDefault::shouldUseFallbackTheme(const ComputedStyle
& style
) const
263 if (useMockTheme()) {
264 // The mock theme can't handle zoomed controls, so we fall back to the "fallback" theme.
265 ControlPart part
= style
.appearance();
266 if (part
== CheckboxPart
|| part
== RadioPart
)
267 return style
.effectiveZoom() != 1;
269 return LayoutTheme::shouldUseFallbackTheme(style
);
272 bool LayoutThemeDefault::supportsHover(const ComputedStyle
& style
) const
277 Color
LayoutThemeDefault::platformFocusRingColor() const
279 static Color
focusRingColor(229, 151, 0, 255);
280 return focusRingColor
;
283 double LayoutThemeDefault::caretBlinkInterval() const
285 // Disable the blinking caret in layout test mode, as it introduces
286 // a race condition for the pixel tests. http://b/1198440
287 if (LayoutTestSupport::isRunningLayoutTest())
290 return m_caretBlinkInterval
;
293 void LayoutThemeDefault::systemFont(CSSValueID systemFontID
, FontStyle
& fontStyle
, FontWeight
& fontWeight
, float& fontSize
, AtomicString
& fontFamily
) const
295 LayoutThemeFontProvider::systemFont(systemFontID
, fontStyle
, fontWeight
, fontSize
, fontFamily
);
298 int LayoutThemeDefault::minimumMenuListSize(const ComputedStyle
& style
) const
303 // Return a rectangle that has the same center point as |original|, but with a
304 // size capped at |width| by |height|.
305 IntRect
center(const IntRect
& original
, int width
, int height
)
307 width
= std::min(original
.width(), width
);
308 height
= std::min(original
.height(), height
);
309 int x
= original
.x() + (original
.width() - width
) / 2;
310 int y
= original
.y() + (original
.height() - height
) / 2;
312 return IntRect(x
, y
, width
, height
);
315 void LayoutThemeDefault::adjustButtonStyle(ComputedStyle
& style
) const
317 if (style
.appearance() == PushButtonPart
) {
318 // Ignore line-height.
319 style
.setLineHeight(ComputedStyle::initialLineHeight());
323 void LayoutThemeDefault::adjustSearchFieldStyle(ComputedStyle
& style
) const
325 // Ignore line-height.
326 style
.setLineHeight(ComputedStyle::initialLineHeight());
329 void LayoutThemeDefault::adjustSearchFieldCancelButtonStyle(ComputedStyle
& style
) const
331 // Scale the button size based on the font size
332 float fontScale
= style
.fontSize() / defaultControlFontPixelSize
;
333 int cancelButtonSize
= lroundf(std::min(std::max(minCancelButtonSize
, defaultCancelButtonSize
* fontScale
), maxCancelButtonSize
));
334 style
.setWidth(Length(cancelButtonSize
, Fixed
));
335 style
.setHeight(Length(cancelButtonSize
, Fixed
));
338 void LayoutThemeDefault::adjustSearchFieldDecorationStyle(ComputedStyle
& style
) const
340 IntSize
emptySize(1, 11);
341 style
.setWidth(Length(emptySize
.width(), Fixed
));
342 style
.setHeight(Length(emptySize
.height(), Fixed
));
345 void LayoutThemeDefault::adjustSearchFieldResultsDecorationStyle(ComputedStyle
& style
) const
347 // Scale the decoration size based on the font size
348 float fontScale
= style
.fontSize() / defaultControlFontPixelSize
;
349 int magnifierSize
= lroundf(std::min(std::max(minSearchFieldResultsDecorationSize
, defaultSearchFieldResultsDecorationSize
* fontScale
),
350 maxSearchFieldResultsDecorationSize
));
351 style
.setWidth(Length(magnifierSize
, Fixed
));
352 style
.setHeight(Length(magnifierSize
, Fixed
));
355 void LayoutThemeDefault::adjustMenuListStyle(ComputedStyle
& style
, Element
*) const
357 // Height is locked to auto on all browsers.
358 style
.setLineHeight(ComputedStyle::initialLineHeight());
361 void LayoutThemeDefault::adjustMenuListButtonStyle(ComputedStyle
& style
, Element
* e
) const
363 adjustMenuListStyle(style
, e
);
366 int LayoutThemeDefault::popupInternalPaddingLeft(const ComputedStyle
& style
) const
368 return menuListInternalPadding(style
, LeftPadding
);
371 int LayoutThemeDefault::popupInternalPaddingRight(const ComputedStyle
& style
) const
373 return menuListInternalPadding(style
, RightPadding
);
376 int LayoutThemeDefault::popupInternalPaddingTop(const ComputedStyle
& style
) const
378 return menuListInternalPadding(style
, TopPadding
);
381 int LayoutThemeDefault::popupInternalPaddingBottom(const ComputedStyle
& style
) const
383 return menuListInternalPadding(style
, BottomPadding
);
387 void LayoutThemeDefault::setDefaultFontSize(int fontSize
)
389 LayoutThemeFontProvider::setDefaultFontSize(fontSize
);
392 int LayoutThemeDefault::menuListArrowPadding() const
394 return ScrollbarTheme::theme()->scrollbarThickness();
397 int LayoutThemeDefault::menuListInternalPadding(const ComputedStyle
& style
, int paddingType
) const
399 // This internal padding is in addition to the user-supplied padding.
400 // Matches the FF behavior.
401 int padding
= styledMenuListInternalPadding
[paddingType
];
403 // Reserve the space for right arrow here. The rest of the padding is
404 // set by adjustMenuListStyle, since PopMenuWin.cpp uses the padding from
405 // LayoutMenuList to lay out the individual items in the popup.
406 // If the MenuList actually has appearance "NoAppearance", then that means
407 // we don't draw a button, so don't reserve space for it.
408 const int barType
= style
.direction() == LTR
? RightPadding
: LeftPadding
;
409 if (paddingType
== barType
&& style
.appearance() != NoControlPart
)
410 padding
+= menuListArrowPadding();
416 // Following values are come from default of GTK+
418 static const int progressAnimationFrames
= 10;
419 static const double progressAnimationInterval
= 0.125;
421 double LayoutThemeDefault::animationRepeatIntervalForProgressBar() const
423 return progressAnimationInterval
;
426 double LayoutThemeDefault::animationDurationForProgressBar() const
428 return progressAnimationInterval
* progressAnimationFrames
* 2; // "2" for back and forth