RenderThemeAndroid.cpp [plain text]
#include "config.h"
#include "RenderThemeAndroid.h"
#include "Color.h"
#include "FormControlElement.h"
#include "GraphicsContext.h"
#include "PlatformGraphicsContext.h"
#include "RenderSkinAndroid.h"
#include "RenderSkinButton.h"
#include "RenderSkinCombo.h"
#include "RenderSkinRadio.h"
#include "SkCanvas.h"
namespace WebCore {
const int MAX_COMBO_HEIGHT = 20;
const int BUTTON_PADDING = 18;
const int LISTBOX_PADDING = 5;
const RGBA32 SELECTION_COLOR = makeRGB(255, 146, 0);
static SkCanvas* getCanvasFromInfo(const RenderObject::PaintInfo& info)
{
return info.context->platformContext()->mCanvas;
}
RenderTheme* theme()
{
static RenderThemeAndroid androidTheme;
return &androidTheme;
}
RenderThemeAndroid::RenderThemeAndroid()
{
}
RenderThemeAndroid::~RenderThemeAndroid()
{
}
void RenderThemeAndroid::close()
{
}
bool RenderThemeAndroid::stateChanged(RenderObject* obj, ControlState state) const
{
if (CheckedState == state) {
obj->repaint();
return true;
}
return false;
}
Color RenderThemeAndroid::platformActiveSelectionBackgroundColor() const
{
return Color(SELECTION_COLOR);
}
Color RenderThemeAndroid::platformInactiveSelectionBackgroundColor() const
{
return Color(Color::transparent);
}
Color RenderThemeAndroid::platformActiveSelectionForegroundColor() const
{
return Color::black;
}
Color RenderThemeAndroid::platformInactiveSelectionForegroundColor() const
{
return Color::black;
}
Color RenderThemeAndroid::platformTextSearchHighlightColor() const
{
return Color(Color::transparent);
}
int RenderThemeAndroid::baselinePosition(const RenderObject* obj) const
{
return RenderTheme::baselinePosition(obj) - 5;
}
void RenderThemeAndroid::addIntrinsicMargins(RenderStyle* style) const
{
if (style->fontSize() < 11)
return;
const int m = 2;
if (style->width().isIntrinsicOrAuto()) {
if (style->marginLeft().quirk())
style->setMarginLeft(Length(m, Fixed));
if (style->marginRight().quirk())
style->setMarginRight(Length(m, Fixed));
}
if (style->height().isAuto()) {
if (style->marginTop().quirk())
style->setMarginTop(Length(m, Fixed));
if (style->marginBottom().quirk())
style->setMarginBottom(Length(m, Fixed));
}
}
bool RenderThemeAndroid::supportsFocus(ControlPart appearance)
{
switch (appearance) {
case PushButtonPart:
case ButtonPart:
case TextFieldPart:
return true;
default:
return false;
}
return false;
}
void RenderThemeAndroid::adjustButtonStyle(CSSStyleSelector*, RenderStyle* style, WebCore::Element*) const
{
const int padding = 8;
style->setPaddingLeft(Length(padding, Fixed));
style->setPaddingRight(Length(padding, Fixed));
style->setMinHeight(Length(style->fontSize() + BUTTON_PADDING, Fixed));
}
bool RenderThemeAndroid::paintCheckbox(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect)
{
RenderSkinRadio::Draw(getCanvasFromInfo(info), obj->node(), rect, true);
return false;
}
bool RenderThemeAndroid::paintButton(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect)
{
Node* node = obj->node();
FormControlElement* formControlElement = toFormControlElement(static_cast<Element*>(node));
if (formControlElement && !formControlElement->isEnabled())
RenderSkinButton::Draw(getCanvasFromInfo(info), rect, RenderSkinAndroid::kDisabled);
else
info.context->platformContext()->storeButtonInfo(node, rect);
return false;
}
bool RenderThemeAndroid::paintRadio(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect)
{
RenderSkinRadio::Draw(getCanvasFromInfo(info), obj->node(), rect, false);
return false;
}
void RenderThemeAndroid::setCheckboxSize(RenderStyle* style) const
{
style->setWidth(Length(19, Fixed));
style->setHeight(Length(19, Fixed));
}
void RenderThemeAndroid::setRadioSize(RenderStyle* style) const
{
setCheckboxSize(style);
}
void RenderThemeAndroid::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style, WebCore::Element*) const
{
addIntrinsicMargins(style);
}
bool RenderThemeAndroid::paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&)
{
return true;
}
void RenderThemeAndroid::adjustTextAreaStyle(CSSStyleSelector*, RenderStyle* style, WebCore::Element*) const
{
addIntrinsicMargins(style);
}
bool RenderThemeAndroid::paintTextArea(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect)
{
if (obj->isMenuList())
return paintCombo(obj, info, rect);
return true;
}
void RenderThemeAndroid::adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
{
addIntrinsicMargins(style);
}
bool RenderThemeAndroid::paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&)
{
return true;
}
void RenderThemeAndroid::adjustListboxStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
{
style->setPaddingRight(Length(RenderSkinCombo::extraWidth(), Fixed));
style->setMaxHeight(Length(style->fontSize() + LISTBOX_PADDING, Fixed));
addIntrinsicMargins(style);
}
static void adjustMenuListStyleCommon(RenderStyle* style, Element* e)
{
style->setPaddingRight(Length(RenderSkinCombo::extraWidth(), Fixed));
bool isEnabled = true;
if (FormControlElement* formControlElement = toFormControlElement(e))
isEnabled = formControlElement->isEnabled();
style->setColor(isEnabled ? Color::black : Color::darkGray);
}
void RenderThemeAndroid::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, Element* e) const
{
adjustMenuListStyleCommon(style, e);
addIntrinsicMargins(style);
}
bool RenderThemeAndroid::paintCombo(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect)
{
if (obj->style() && !obj->style()->backgroundColor().alpha())
return true;
Node* node = obj->node();
int height = rect.height();
int y = rect.y();
if (height > MAX_COMBO_HEIGHT) {
y += (height - MAX_COMBO_HEIGHT) >> 1;
height = MAX_COMBO_HEIGHT;
}
return RenderSkinCombo::Draw(getCanvasFromInfo(info), node, rect.x(), y,
rect.width(), height);
}
bool RenderThemeAndroid::paintMenuList(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect)
{
return paintCombo(obj, info, rect);
}
void RenderThemeAndroid::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle* style, Element* e) const
{
const float baseFontSize = 11.0f;
const int baseBorderRadius = 5;
float fontScale = style->fontSize() / baseFontSize;
style->resetPadding();
style->setBorderRadius(IntSize(int(baseBorderRadius + fontScale - 1), int(baseBorderRadius + fontScale - 1)));
const int minHeight = 15;
style->setMinHeight(Length(minHeight, Fixed));
style->setLineHeight(RenderStyle::initialLineHeight());
const int padding = 4;
style->setPaddingTop(Length(padding, Fixed));
style->setPaddingLeft(Length(padding, Fixed));
adjustMenuListStyleCommon(style, e);
}
bool RenderThemeAndroid::paintMenuListButton(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect)
{
return paintCombo(obj, info, rect);
}
bool RenderThemeAndroid::supportsFocusRing(const RenderStyle* style) const
{
return style->opacity() > 0
&& style->hasAppearance()
&& style->appearance() != TextFieldPart
&& style->appearance() != SearchFieldPart
&& style->appearance() != TextAreaPart
&& style->appearance() != CheckboxPart
&& style->appearance() != RadioPart
&& style->appearance() != PushButtonPart
&& style->appearance() != SquareButtonPart
&& style->appearance() != ButtonPart
&& style->appearance() != ButtonBevelPart
&& style->appearance() != MenulistPart
&& style->appearance() != MenulistButtonPart;
}
}