int RenderThemeSafari::popupInternalPaddingBottom(RenderStyle& style) const { if (style.appearance() == MenulistPart) return popupButtonPadding(controlSizeForFont(style))[bottomPadding]; if (style.appearance() == MenulistButtonPart) return styledPopupPaddingBottom; return 0; }
void RenderThemeSafari::adjustSliderThumbSize(RenderStyle& style, Element*) const { if (style.appearance() == SliderThumbHorizontalPart || style.appearance() == SliderThumbVerticalPart) { style.setWidth(Length(sliderThumbWidth, Fixed)); style.setHeight(Length(sliderThumbHeight, Fixed)); } #if ENABLE(VIDEO) else if (style.appearance() == MediaSliderThumbPart) RenderMediaControls::adjustMediaSliderThumbSize(style); #endif }
int RenderThemeSafari::popupInternalPaddingRight(RenderStyle& style) const { if (style.appearance() == MenulistPart) return popupButtonPadding(controlSizeForFont(style))[rightPadding]; if (style.appearance() == MenulistButtonPart) { float fontScale = style.fontSize() / baseFontSize; float arrowWidth = baseArrowWidth * fontScale; return static_cast<int>(ceilf(arrowWidth + arrowPaddingLeft + arrowPaddingRight + paddingBeforeSeparator)); } return 0; }
bool RenderThemeSafari::isControlStyled(const RenderStyle& style, const BorderData& border, const FillLayer& background, const Color& backgroundColor) const { // If we didn't find SafariTheme.dll we won't be able to paint any themed controls. if (!SafariThemeLibrary()) return true; if (style.appearance() == TextFieldPart || style.appearance() == TextAreaPart || style.appearance() == ListboxPart) return style.border() != border; return RenderTheme::isControlStyled(style, border, background, backgroundColor); }
bool RenderThemeAndroid::paintCombo(RenderObject* obj, const PaintInfo& info, const IntRect& rect) { if (obj->style() && !obj->style()->visitedDependentColor(CSSPropertyBackgroundColor).alpha()) return true; Node* node = obj->node(); Element* element = static_cast<Element*>(node); if (element) { InputElement* input = element->toInputElement(); GraphicsContext* context = info.context; if (!element->isEnabledFormControl()) { context->setAlpha(0.5f); } IntRect bounds = IntRect(rect.x(), rect.y(), rect.width(), rect.height()); // paint bg color RenderStyle* style = obj->style(); context->setFillColor(style->visitedDependentColor(CSSPropertyBackgroundColor), context->fillColorSpace()); context->fillRect(FloatRect(bounds)); // copied form the original RenderSkinCombo: // If this is an appearance where RenderTheme::paint returns true // without doing anything, this means that // RenderBox::PaintBoxDecorationWithSize will end up painting the // border, so we shouldn't paint a border here. if (style->appearance() != MenulistButtonPart && style->appearance() != ListboxPart && style->appearance() != TextFieldPart && style->appearance() != TextAreaPart) { const int arrowSize = bounds.height(); // dropdown button bg context->setFillColor(Color(defaultBgColor), context->fillColorSpace()); context->fillRect(FloatRect(bounds.maxX() - arrowSize + 0.5f, bounds.y() + .5f, arrowSize - 1, bounds.height() - 1)); // outline context->setStrokeThickness(1.0f); context->setStrokeColor(Color(defaultBgDark), context->strokeColorSpace()); context->strokeRect(bounds, 1.0f); // arrow context->setFillColor(Color(defaultFgColor), context->fillColorSpace()); Path tri = Path(); tri.clear(); const float aw = arrowSize - 10; FloatPoint br = FloatPoint(bounds.maxX() - 4, bounds.maxY() - 4); tri.moveTo(br); tri.addLineTo(FloatPoint(br.x() - aw, br.y())); tri.addLineTo(FloatPoint(br.x(), br.y() - aw)); context->fillPath(tri); } } return false; }
bool RenderTheme::isControlStyled(const RenderStyle& style, const BorderData& border, const FillLayer& background, const Color& backgroundColor) const { switch (style.appearance()) { case PushButtonPart: case SquareButtonPart: case DefaultButtonPart: case ButtonPart: case ListboxPart: case MenulistPart: case ProgressBarPart: case MeterPart: case RelevancyLevelIndicatorPart: case ContinuousCapacityLevelIndicatorPart: case DiscreteCapacityLevelIndicatorPart: case RatingLevelIndicatorPart: // FIXME: SearchFieldPart should be included here when making search fields style-able. case TextFieldPart: case TextAreaPart: // Test the style to see if the UA border and background match. return (style.border() != border || *style.backgroundLayers() != background || style.visitedDependentColor(CSSPropertyBackgroundColor) != backgroundColor); default: return false; } }
AccessibilityOrientation AccessibilitySlider::orientation() const { // Default to horizontal in the unknown case. if (!m_renderer) return AccessibilityOrientationHorizontal; RenderStyle* style = m_renderer->style(); if (!style) return AccessibilityOrientationHorizontal; ControlPart styleAppearance = style->appearance(); switch (styleAppearance) { case SliderThumbHorizontalPart: case SliderHorizontalPart: case MediaSliderPart: case MediaFullScreenVolumeSliderPart: return AccessibilityOrientationHorizontal; case SliderThumbVerticalPart: case SliderVerticalPart: case MediaVolumeSliderPart: return AccessibilityOrientationVertical; default: return AccessibilityOrientationHorizontal; } }
ControlPart RenderThemeQStyle::initializeCommonQStyleOptions(QStyleFacadeOption &option, RenderObject* o) const { // Default bits: no focus, no mouse over, enabled option.state &= ~(QStyleFacade::State_HasFocus | QStyleFacade::State_MouseOver); option.state |= QStyleFacade::State_Enabled; if (isReadOnlyControl(o)) // Readonly is supported on textfields. option.state |= QStyleFacade::State_ReadOnly; option.direction = Qt::LeftToRight; if (isHovered(o)) option.state |= QStyleFacade::State_MouseOver; setPaletteFromPageClientIfExists(option.palette); if (!isEnabled(o)) { option.palette.setCurrentColorGroup(QPalette::Disabled); option.state &= ~QStyleFacade::State_Enabled; } RenderStyle* style = o->style(); if (!style) return NoControlPart; ControlPart result = style->appearance(); if (supportsFocus(result) && isFocused(o)) { option.state |= QStyleFacade::State_HasFocus; option.state |= QStyleFacade::State_KeyboardFocusChange; } if (style->direction() == WebCore::RTL) option.direction = Qt::RightToLeft; switch (result) { case PushButtonPart: case SquareButtonPart: case ButtonPart: case ButtonBevelPart: case ListItemPart: case MenulistButtonPart: case InnerSpinButtonPart: case SearchFieldResultsButtonPart: case SearchFieldCancelButtonPart: { if (isPressed(o)) option.state |= QStyleFacade::State_Sunken; else if (result == PushButtonPart || result == ButtonPart) option.state |= QStyleFacade::State_Raised; break; } case RadioPart: case CheckboxPart: option.state |= (isChecked(o) ? QStyleFacade::State_On : QStyleFacade::State_Off); } return result; }
void RenderSliderThumb::layout() { // FIXME: Hard-coding this cascade of appearance is bad, because it's something // that CSS usually does. We need to find a way to express this in CSS. RenderStyle* parentStyle = parent()->style(); if (parentStyle->appearance() == SliderVerticalPart) style()->setAppearance(SliderThumbVerticalPart); else if (parentStyle->appearance() == SliderHorizontalPart) style()->setAppearance(SliderThumbHorizontalPart); else if (parentStyle->appearance() == MediaSliderPart) style()->setAppearance(MediaSliderThumbPart); else if (parentStyle->appearance() == MediaVolumeSliderPart) style()->setAppearance(MediaVolumeSliderThumbPart); if (style()->hasAppearance()) { // FIXME: This should pass the style, not the renderer, to the theme. theme()->adjustSliderThumbSize(this); } RenderBlock::layout(); }
bool RenderSkinCombo::Draw(SkCanvas* canvas, Node* element, int x, int y, int width, int height) { if (!isDecodingAttempted) Decode(); if (!isDecoded) return true; State state = (element->isElementNode() && static_cast<Element*>(element)->isEnabledFormControl()) ? kNormal : kDisabled; height = std::max(height, (stretchMargin[RenderSkinAndroid::DrawableResolution()]<<1) + 1); SkRect bounds; BorderStyle drawBorder = FullAsset; bounds.set(SkIntToScalar(x+1), SkIntToScalar(y+1), SkIntToScalar(x + width-1), SkIntToScalar(y + height-1)); RenderStyle* style = element->renderStyle(); SkPaint paint; paint.setColor(style->visitedDependentColor(CSSPropertyBackgroundColor).rgb()); canvas->drawRect(bounds, paint); bounds.set(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + width), SkIntToScalar(y + height)); // If this is an appearance where RenderTheme::paint returns true // without doing anything, this means that // RenderBox::PaintBoxDecorationWithSize will end up painting the // border, so we shouldn't paint a border here. if (style->appearance() == MenulistButtonPart || style->appearance() == ListboxPart || style->appearance() == TextFieldPart || style->appearance() == TextAreaPart) { bounds.fLeft += SkIntToScalar(width - RenderSkinCombo::extraWidth()); bounds.fRight -= SkIntToScalar(style->borderRightWidth()); bounds.fTop += SkIntToScalar(style->borderTopWidth()); bounds.fBottom -= SkIntToScalar(style->borderBottomWidth()); drawBorder = NoBorder; } SkNinePatch::DrawNine(canvas, bounds, bitmaps[state][drawBorder], margin[drawBorder]); return false; }
void SliderThumbElement::setPositionFromPoint(const IntPoint& point) { HTMLInputElement* input = hostInput(); ASSERT(input); if (!input->renderer() || !renderer()) return; IntPoint offset = roundedIntPoint(input->renderer()->absoluteToLocal(point, false, true)); RenderStyle* sliderStyle = input->renderer()->style(); bool isVertical = sliderStyle->appearance() == SliderVerticalPart || sliderStyle->appearance() == MediaVolumeSliderPart; int trackSize; int position; int currentPosition; if (isVertical) { trackSize = input->renderBox()->contentHeight() - renderBox()->height(); position = offset.y() - renderBox()->height() / 2; currentPosition = renderBox()->y() - input->renderBox()->contentBoxRect().y(); } else { trackSize = input->renderBox()->contentWidth() - renderBox()->width(); position = offset.x() - renderBox()->width() / 2; currentPosition = renderBox()->x() - input->renderBox()->contentBoxRect().x(); } position = max(0, min(position, trackSize)); if (position == currentPosition) return; StepRange range(input); double fraction = static_cast<double>(position) / trackSize; if (isVertical) fraction = 1 - fraction; double value = range.clampValue(range.valueFromProportion(fraction)); // FIXME: This is no longer being set from renderer. Consider updating the method name. input->setValueFromRenderer(serializeForNumberType(value)); renderer()->setNeedsLayout(true); input->dispatchFormControlChangeEvent(); }
void RenderThemeSafari::adjustButtonStyle(StyleResolver& styleResolver, RenderStyle& style, Element*) const { // There are three appearance constants for buttons. // (1) Push-button is the constant for the default Aqua system button. Push buttons will not scale vertically and will not allow // custom fonts or colors. <input>s use this constant. This button will allow custom colors and font weights/variants but won't // scale vertically. // (2) square-button is the constant for the square button. This button will allow custom fonts and colors and will scale vertically. // (3) Button is the constant that means "pick the best button as appropriate." <button>s use this constant. This button will // also scale vertically and allow custom fonts and colors. It will attempt to use Aqua if possible and will make this determination // solely on the rectangle of the control. // Determine our control size based off our font. NSControlSize controlSize = controlSizeForFont(style); if (style.appearance() == PushButtonPart) { // Ditch the border. style.resetBorder(); // Height is locked to auto. style.setHeight(Length(Auto)); // White-space is locked to pre style.setWhiteSpace(PRE); // Set the button's vertical size. setButtonSize(style); // Add in the padding that we'd like to use. setButtonPaddingFromControlSize(style, controlSize); // Our font is locked to the appropriate system font size for the control. To clarify, we first use the CSS-specified font to figure out // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate // system font for the control size instead. setFontFromControlSize(styleResolver, style, controlSize); } else { // Set a min-height so that we can't get smaller than the mini button. style.setMinHeight(Length(15, Fixed)); // Reset the top and bottom borders. style.resetBorderTop(); style.resetBorderBottom(); } }
void RenderMediaControls::adjustMediaSliderThumbSize(RenderStyle& style) { int part; switch (style.appearance()) { case MediaSliderThumbPart: part = MediaSliderThumb; break; case MediaVolumeSliderThumbPart: part = MediaVolumeSliderThumb; break; case MediaFullScreenVolumeSliderThumbPart: part = MediaFullScreenVolumeSliderThumb; break; default: return; } CGSize size; wkMeasureMediaUIPart(part, 0, &size); float zoomLevel = style.effectiveZoom(); style.setWidth(Length(static_cast<int>(size.width * zoomLevel), Fixed)); style.setHeight(Length(static_cast<int>(size.height * zoomLevel), Fixed)); }
void RenderTheme::adjustStyle(StyleResolver& styleResolver, RenderStyle& style, Element* element, bool UAHasAppearance, const BorderData& border, const FillLayer& background, const Color& backgroundColor) { // Force inline and table display styles to be inline-block (except for table- which is block) ControlPart part = style.appearance(); if (style.display() == INLINE || style.display() == INLINE_TABLE || style.display() == TABLE_ROW_GROUP || style.display() == TABLE_HEADER_GROUP || style.display() == TABLE_FOOTER_GROUP || style.display() == TABLE_ROW || style.display() == TABLE_COLUMN_GROUP || style.display() == TABLE_COLUMN || style.display() == TABLE_CELL || style.display() == TABLE_CAPTION) style.setDisplay(INLINE_BLOCK); else if (style.display() == COMPACT || style.display() == LIST_ITEM || style.display() == TABLE) style.setDisplay(BLOCK); if (UAHasAppearance && isControlStyled(style, border, background, backgroundColor)) { if (part == MenulistPart) { style.setAppearance(MenulistButtonPart); part = MenulistButtonPart; } else style.setAppearance(NoControlPart); } if (!style.hasAppearance()) return; // Never support box-shadow on native controls. style.setBoxShadow(nullptr); #if USE(NEW_THEME) switch (part) { case CheckboxPart: case InnerSpinButtonPart: case RadioPart: case PushButtonPart: case SquareButtonPart: case DefaultButtonPart: case ButtonPart: { // Border LengthBox borderBox(style.borderTopWidth(), style.borderRightWidth(), style.borderBottomWidth(), style.borderLeftWidth()); borderBox = m_theme->controlBorder(part, style.fontCascade(), borderBox, style.effectiveZoom()); if (borderBox.top().value() != static_cast<int>(style.borderTopWidth())) { if (borderBox.top().value()) style.setBorderTopWidth(borderBox.top().value()); else style.resetBorderTop(); } if (borderBox.right().value() != static_cast<int>(style.borderRightWidth())) { if (borderBox.right().value()) style.setBorderRightWidth(borderBox.right().value()); else style.resetBorderRight(); } if (borderBox.bottom().value() != static_cast<int>(style.borderBottomWidth())) { style.setBorderBottomWidth(borderBox.bottom().value()); if (borderBox.bottom().value()) style.setBorderBottomWidth(borderBox.bottom().value()); else style.resetBorderBottom(); } if (borderBox.left().value() != static_cast<int>(style.borderLeftWidth())) { style.setBorderLeftWidth(borderBox.left().value()); if (borderBox.left().value()) style.setBorderLeftWidth(borderBox.left().value()); else style.resetBorderLeft(); } // Padding LengthBox paddingBox = m_theme->controlPadding(part, style.fontCascade(), style.paddingBox(), style.effectiveZoom()); if (paddingBox != style.paddingBox()) style.setPaddingBox(paddingBox); // Whitespace if (m_theme->controlRequiresPreWhiteSpace(part)) style.setWhiteSpace(PRE); // Width / Height // The width and height here are affected by the zoom. // FIXME: Check is flawed, since it doesn't take min-width/max-width into account. LengthSize controlSize = m_theme->controlSize(part, style.fontCascade(), LengthSize(style.width(), style.height()), style.effectiveZoom()); if (controlSize.width() != style.width()) style.setWidth(controlSize.width()); if (controlSize.height() != style.height()) style.setHeight(controlSize.height()); // Min-Width / Min-Height LengthSize minControlSize = m_theme->minimumControlSize(part, style.fontCascade(), style.effectiveZoom()); if (minControlSize.width() != style.minWidth()) style.setMinWidth(minControlSize.width()); if (minControlSize.height() != style.minHeight()) style.setMinHeight(minControlSize.height()); // Font if (auto themeFont = m_theme->controlFont(part, style.fontCascade(), style.effectiveZoom())) { // If overriding the specified font with the theme font, also override the line height with the standard line height. style.setLineHeight(RenderStyle::initialLineHeight()); if (style.setFontDescription(themeFont.value())) style.fontCascade().update(nullptr); } // Special style that tells enabled default buttons in active windows to use the ActiveButtonText color. // The active window part of the test has to be done at paint time since it's not triggered by a style change. style.setInsideDefaultButton(part == DefaultButtonPart && element && !element->isDisabledFormControl()); break; } default: break; } #endif // Call the appropriate style adjustment method based off the appearance value. switch (style.appearance()) { #if !USE(NEW_THEME) case CheckboxPart: return adjustCheckboxStyle(styleResolver, style, element); case RadioPart: return adjustRadioStyle(styleResolver, style, element); case PushButtonPart: case SquareButtonPart: case DefaultButtonPart: case ButtonPart: return adjustButtonStyle(styleResolver, style, element); case InnerSpinButtonPart: return adjustInnerSpinButtonStyle(styleResolver, style, element); #endif case TextFieldPart: return adjustTextFieldStyle(styleResolver, style, element); case TextAreaPart: return adjustTextAreaStyle(styleResolver, style, element); case MenulistPart: return adjustMenuListStyle(styleResolver, style, element); case MenulistButtonPart: return adjustMenuListButtonStyle(styleResolver, style, element); case MediaPlayButtonPart: case MediaCurrentTimePart: case MediaTimeRemainingPart: case MediaEnterFullscreenButtonPart: case MediaExitFullscreenButtonPart: case MediaMuteButtonPart: case MediaVolumeSliderContainerPart: return adjustMediaControlStyle(styleResolver, style, element); case MediaSliderPart: case MediaVolumeSliderPart: case MediaFullScreenVolumeSliderPart: case SliderHorizontalPart: case SliderVerticalPart: return adjustSliderTrackStyle(styleResolver, style, element); case SliderThumbHorizontalPart: case SliderThumbVerticalPart: return adjustSliderThumbStyle(styleResolver, style, element); case SearchFieldPart: return adjustSearchFieldStyle(styleResolver, style, element); case SearchFieldCancelButtonPart: return adjustSearchFieldCancelButtonStyle(styleResolver, style, element); case SearchFieldDecorationPart: return adjustSearchFieldDecorationPartStyle(styleResolver, style, element); case SearchFieldResultsDecorationPart: return adjustSearchFieldResultsDecorationPartStyle(styleResolver, style, element); case SearchFieldResultsButtonPart: return adjustSearchFieldResultsButtonStyle(styleResolver, style, element); case ProgressBarPart: return adjustProgressBarStyle(styleResolver, style, element); #if ENABLE(METER_ELEMENT) case MeterPart: case RelevancyLevelIndicatorPart: case ContinuousCapacityLevelIndicatorPart: case DiscreteCapacityLevelIndicatorPart: case RatingLevelIndicatorPart: return adjustMeterStyle(styleResolver, style, element); #endif #if ENABLE(SERVICE_CONTROLS) case ImageControlsButtonPart: break; #endif case CapsLockIndicatorPart: return adjustCapsLockIndicatorStyle(styleResolver, style, element); #if ENABLE(ATTACHMENT_ELEMENT) case AttachmentPart: return adjustAttachmentStyle(styleResolver, style, element); #endif default: break; } }
bool RenderTheme::supportsFocusRing(const RenderStyle& style) const { return (style.hasAppearance() && style.appearance() != TextFieldPart && style.appearance() != TextAreaPart && style.appearance() != MenulistButtonPart && style.appearance() != ListboxPart); }
void RenderThemeGtk::adjustButtonStyle(StyleResolver&, RenderStyle& style, WebCore::Element&) const { // Some layout tests check explicitly that buttons ignore line-height. if (style.appearance() == PushButtonPart) style.setLineHeight(RenderStyle::initialLineHeight()); }
inline static bool hasVerticalAppearance(HTMLInputElement* input) { ASSERT(input->renderer()); RenderStyle* sliderStyle = input->renderer()->style(); return sliderStyle->appearance() == SliderVerticalPart || sliderStyle->appearance() == MediaVolumeSliderPart; }
bool RenderThemeGtk::supportsFocusRing(const RenderStyle& style) const { return supportsFocus(style.appearance()); }