/* | |
* This file is part of the WebKit project. | |
* | |
* Copyright (C) 2006, 2007 Apple Computer, Inc. | |
* Copyright (C) 2007-2009 Torch Mobile, Inc. | |
* | |
* This library is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU Library General Public | |
* License as published by the Free Software Foundation; either | |
* version 2 of the License, or (at your option) any later version. | |
* | |
* This library is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
* Library General Public License for more details. | |
* | |
* You should have received a copy of the GNU Library General Public License | |
* along with this library; see the file COPYING.LIB. If not, write to | |
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
* Boston, MA 02110-1301, USA. | |
* | |
*/ | |
#include "config.h" | |
#include "RenderThemeWince.h" | |
#include "CSSStyleSheet.h" | |
#include "CSSValueKeywords.h" | |
#include "Document.h" | |
#include "GraphicsContext.h" | |
#include "NotImplemented.h" | |
#if ENABLE(VIDEO) | |
#include "HTMLMediaElement.h" | |
#endif | |
#include <windows.h> | |
/* | |
* The following constants are used to determine how a widget is drawn using | |
* Windows' Theme API. For more information on theme parts and states see | |
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp | |
*/ | |
#define THEME_COLOR 204 | |
#define THEME_FONT 210 | |
// Generic state constants | |
#define TS_NORMAL 1 | |
#define TS_HOVER 2 | |
#define TS_ACTIVE 3 | |
#define TS_DISABLED 4 | |
#define TS_FOCUSED 5 | |
// Button constants | |
#define BP_BUTTON 1 | |
#define BP_RADIO 2 | |
#define BP_CHECKBOX 3 | |
// Textfield constants | |
#define TFP_TEXTFIELD 1 | |
#define TFS_READONLY 6 | |
typedef HANDLE (WINAPI*openThemeDataPtr)(HWND hwnd, LPCWSTR pszClassList); | |
typedef HRESULT (WINAPI*closeThemeDataPtr)(HANDLE hTheme); | |
typedef HRESULT (WINAPI*drawThemeBackgroundPtr)(HANDLE hTheme, HDC hdc, int iPartId, | |
int iStateId, const RECT *pRect, | |
const RECT* pClipRect); | |
typedef HRESULT (WINAPI*drawThemeEdgePtr)(HANDLE hTheme, HDC hdc, int iPartId, | |
int iStateId, const RECT *pRect, | |
unsigned uEdge, unsigned uFlags, | |
const RECT* pClipRect); | |
typedef HRESULT (WINAPI*getThemeContentRectPtr)(HANDLE hTheme, HDC hdc, int iPartId, | |
int iStateId, const RECT* pRect, | |
RECT* pContentRect); | |
typedef HRESULT (WINAPI*getThemePartSizePtr)(HANDLE hTheme, HDC hdc, int iPartId, | |
int iStateId, RECT* prc, int ts, | |
SIZE* psz); | |
typedef HRESULT (WINAPI*getThemeSysFontPtr)(HANDLE hTheme, int iFontId, OUT LOGFONT* pFont); | |
typedef HRESULT (WINAPI*getThemeColorPtr)(HANDLE hTheme, HDC hdc, int iPartId, | |
int iStateId, int iPropId, OUT COLORREF* pFont); | |
namespace WebCore { | |
static const int dropDownButtonWidth = 17; | |
static const int trackWidth = 4; | |
PassRefPtr<RenderTheme> RenderThemeWince::create() | |
{ | |
return adoptRef(new RenderThemeWince); | |
} | |
PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) | |
{ | |
static RenderTheme* winceTheme = RenderThemeWince::create().releaseRef(); | |
return winceTheme; | |
} | |
RenderThemeWince::RenderThemeWince() | |
{ | |
} | |
RenderThemeWince::~RenderThemeWince() | |
{ | |
} | |
Color RenderThemeWince::platformActiveSelectionBackgroundColor() const | |
{ | |
COLORREF color = GetSysColor(COLOR_HIGHLIGHT); | |
return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); | |
} | |
Color RenderThemeWince::platformInactiveSelectionBackgroundColor() const | |
{ | |
COLORREF color = GetSysColor(COLOR_GRAYTEXT); | |
return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); | |
} | |
Color RenderThemeWince::platformActiveSelectionForegroundColor() const | |
{ | |
COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT); | |
return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); | |
} | |
Color RenderThemeWince::platformInactiveSelectionForegroundColor() const | |
{ | |
return Color::white; | |
} | |
bool RenderThemeWince::supportsFocus(ControlPart appearance) const | |
{ | |
switch (appearance) { | |
case PushButtonPart: | |
case ButtonPart: | |
case TextFieldPart: | |
case TextAreaPart: | |
return true; | |
default: | |
return false; | |
} | |
return false; | |
} | |
bool RenderThemeWince::supportsFocusRing(const RenderStyle *style) const | |
{ | |
return supportsFocus(style->appearance()); | |
} | |
unsigned RenderThemeWince::determineClassicState(RenderObject* o) | |
{ | |
unsigned result = 0; | |
if (!isEnabled(o) || isReadOnlyControl(o)) | |
result = DFCS_INACTIVE; | |
else if (isPressed(o)) // Active supersedes hover | |
result = DFCS_PUSHED; | |
if (isChecked(o)) | |
result |= DFCS_CHECKED; | |
return result; | |
} | |
ThemeData RenderThemeWince::getThemeData(RenderObject* o) | |
{ | |
ThemeData result; | |
switch (o->style()->appearance()) { | |
case PushButtonPart: | |
case ButtonPart: | |
result.m_part = BP_BUTTON; | |
result.m_classicState = DFCS_BUTTONPUSH; | |
break; | |
case CheckboxPart: | |
result.m_part = BP_CHECKBOX; | |
result.m_classicState = DFCS_BUTTONCHECK; | |
break; | |
case RadioPart: | |
result.m_part = BP_RADIO; | |
result.m_classicState = DFCS_BUTTONRADIO; | |
break; | |
case ListboxPart: | |
case MenulistPart: | |
case TextFieldPart: | |
case TextAreaPart: | |
result.m_part = TFP_TEXTFIELD; | |
break; | |
} | |
result.m_classicState |= determineClassicState(o); | |
return result; | |
} | |
bool RenderThemeWince::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) | |
{ | |
// Get the correct theme data for a button | |
ThemeData themeData = getThemeData(o); | |
// Now paint the button. | |
i.context->drawFrameControl(r, DFC_BUTTON, themeData.m_classicState); | |
if (isFocused(o)) { | |
if (themeData.m_part == BP_BUTTON) { | |
IntRect focusRect(r); | |
focusRect.inflate(-2); | |
i.context->drawFocusRect(focusRect); | |
} else | |
i.context->drawFocusRect(r); | |
} | |
return false; | |
} | |
void RenderThemeWince::setCheckboxSize(RenderStyle* style) const | |
{ | |
// If the width and height are both specified, then we have nothing to do. | |
if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) | |
return; | |
// FIXME: A hard-coded size of 13 is used. This is wrong but necessary for now. It matches Firefox. | |
// At different DPI settings on Windows, querying the theme gives you a larger size that accounts for | |
// the higher DPI. Until our entire engine honors a DPI setting other than 96, we can't rely on the theme's | |
// metrics. | |
if (style->width().isIntrinsicOrAuto()) | |
style->setWidth(Length(13, Fixed)); | |
if (style->height().isAuto()) | |
style->setHeight(Length(13, Fixed)); | |
} | |
bool RenderThemeWince::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) | |
{ | |
// Get the correct theme data for a textfield | |
ThemeData themeData = getThemeData(o); | |
// Now paint the text field. | |
i.context->paintTextField(r, themeData.m_classicState); | |
return false; | |
} | |
void RenderThemeWince::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const | |
{ | |
style->resetBorder(); | |
adjustMenuListButtonStyle(selector, style, e); | |
} | |
bool RenderThemeWince::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) | |
{ | |
paintTextField(o, i, r); | |
paintMenuListButton(o, i, r); | |
return true; | |
} | |
bool RenderThemeWince::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) | |
{ | |
IntRect buttonRect(r.right() - dropDownButtonWidth - 1, r.y(), dropDownButtonWidth, r.height()); | |
buttonRect.inflateY(-1); | |
i.context->drawFrameControl(buttonRect, DFC_SCROLL, DFCS_SCROLLCOMBOBOX | determineClassicState(o)); | |
return true; | |
} | |
void RenderThemeWince::systemFont(int propId, FontDescription& fontDescription) const | |
{ | |
notImplemented(); | |
} | |
void RenderThemeWince::themeChanged() | |
{ | |
} | |
String RenderThemeWince::extraDefaultStyleSheet() | |
{ | |
notImplemented(); | |
return String(); | |
} | |
String RenderThemeWince::extraQuirksStyleSheet() | |
{ | |
notImplemented(); | |
return String(); | |
} | |
bool RenderThemeWince::supportsHover(const RenderStyle*) const | |
{ | |
return false; | |
} | |
// Map a CSSValue* system color to an index understood by GetSysColor | |
static int cssValueIdToSysColorIndex(int cssValueId) | |
{ | |
switch (cssValueId) { | |
case CSSValueActiveborder: return COLOR_ACTIVEBORDER; | |
case CSSValueActivecaption: return COLOR_ACTIVECAPTION; | |
case CSSValueAppworkspace: return COLOR_APPWORKSPACE; | |
case CSSValueBackground: return COLOR_BACKGROUND; | |
case CSSValueButtonface: return COLOR_BTNFACE; | |
case CSSValueButtonhighlight: return COLOR_BTNHIGHLIGHT; | |
case CSSValueButtonshadow: return COLOR_BTNSHADOW; | |
case CSSValueButtontext: return COLOR_BTNTEXT; | |
case CSSValueCaptiontext: return COLOR_CAPTIONTEXT; | |
case CSSValueGraytext: return COLOR_GRAYTEXT; | |
case CSSValueHighlight: return COLOR_HIGHLIGHT; | |
case CSSValueHighlighttext: return COLOR_HIGHLIGHTTEXT; | |
case CSSValueInactiveborder: return COLOR_INACTIVEBORDER; | |
case CSSValueInactivecaption: return COLOR_INACTIVECAPTION; | |
case CSSValueInactivecaptiontext: return COLOR_INACTIVECAPTIONTEXT; | |
case CSSValueInfobackground: return COLOR_INFOBK; | |
case CSSValueInfotext: return COLOR_INFOTEXT; | |
case CSSValueMenu: return COLOR_MENU; | |
case CSSValueMenutext: return COLOR_MENUTEXT; | |
case CSSValueScrollbar: return COLOR_SCROLLBAR; | |
case CSSValueThreeddarkshadow: return COLOR_3DDKSHADOW; | |
case CSSValueThreedface: return COLOR_3DFACE; | |
case CSSValueThreedhighlight: return COLOR_3DHIGHLIGHT; | |
case CSSValueThreedlightshadow: return COLOR_3DLIGHT; | |
case CSSValueThreedshadow: return COLOR_3DSHADOW; | |
case CSSValueWindow: return COLOR_WINDOW; | |
case CSSValueWindowframe: return COLOR_WINDOWFRAME; | |
case CSSValueWindowtext: return COLOR_WINDOWTEXT; | |
default: return -1; // Unsupported CSSValue | |
} | |
} | |
Color RenderThemeWince::systemColor(int cssValueId) const | |
{ | |
int sysColorIndex = cssValueIdToSysColorIndex(cssValueId); | |
if (sysColorIndex == -1) | |
return RenderTheme::systemColor(cssValueId); | |
COLORREF color = GetSysColor(sysColorIndex); | |
return Color(GetRValue(color), GetGValue(color), GetBValue(color)); | |
} | |
const int sliderThumbWidth = 7; | |
const int sliderThumbHeight = 15; | |
void RenderThemeWince::adjustSliderThumbSize(RenderObject* o) const | |
{ | |
if (o->style()->appearance() == SliderThumbVerticalPart) { | |
o->style()->setWidth(Length(sliderThumbHeight, Fixed)); | |
o->style()->setHeight(Length(sliderThumbWidth, Fixed)); | |
} else if (o->style()->appearance() == SliderThumbHorizontalPart) { | |
o->style()->setWidth(Length(sliderThumbWidth, Fixed)); | |
o->style()->setHeight(Length(sliderThumbHeight, Fixed)); | |
} | |
} | |
#if 0 | |
void RenderThemeWince::adjustButtonInnerStyle(RenderStyle* style) const | |
{ | |
// This inner padding matches Firefox. | |
style->setPaddingTop(Length(1, Fixed)); | |
style->setPaddingRight(Length(3, Fixed)); | |
style->setPaddingBottom(Length(1, Fixed)); | |
style->setPaddingLeft(Length(3, Fixed)); | |
} | |
void RenderThemeWince::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const | |
{ | |
// Override padding size to match AppKit text positioning. | |
const int padding = 1; | |
style->setPaddingLeft(Length(padding, Fixed)); | |
style->setPaddingRight(Length(padding, Fixed)); | |
style->setPaddingTop(Length(padding, Fixed)); | |
style->setPaddingBottom(Length(padding, Fixed)); | |
} | |
#endif | |
bool RenderThemeWince::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) | |
{ | |
return paintTextField(o, i, r); | |
} | |
bool RenderThemeWince::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) | |
{ | |
Color buttonColor = (o->node() && o->node()->active()) ? Color(138, 138, 138) : Color(186, 186, 186); | |
IntSize cancelSize(10, 10); | |
IntSize cancelRadius(cancelSize.width() / 2, cancelSize.height() / 2); | |
int x = r.x() + (r.width() - cancelSize.width()) / 2; | |
int y = r.y() + (r.height() - cancelSize.height()) / 2 + 1; | |
IntRect cancelBounds(IntPoint(x, y), cancelSize); | |
paintInfo.context->save(); | |
paintInfo.context->addRoundedRectClip(cancelBounds, cancelRadius, cancelRadius, cancelRadius, cancelRadius); | |
paintInfo.context->fillRect(cancelBounds, buttonColor, DeviceColorSpace); | |
// Draw the 'x' | |
IntSize xSize(3, 3); | |
IntRect xBounds(cancelBounds.location() + IntSize(3, 3), xSize); | |
paintInfo.context->setStrokeColor(Color::white, DeviceColorSpace); | |
paintInfo.context->drawLine(xBounds.location(), xBounds.location() + xBounds.size()); | |
paintInfo.context->drawLine(IntPoint(xBounds.right(), xBounds.y()), IntPoint(xBounds.x(), xBounds.bottom())); | |
paintInfo.context->restore(); | |
return false; | |
} | |
void RenderThemeWince::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const | |
{ | |
IntSize cancelSize(13, 11); | |
style->setWidth(Length(cancelSize.width(), Fixed)); | |
style->setHeight(Length(cancelSize.height(), Fixed)); | |
} | |
void RenderThemeWince::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const | |
{ | |
IntSize emptySize(1, 11); | |
style->setWidth(Length(emptySize.width(), Fixed)); | |
style->setHeight(Length(emptySize.height(), Fixed)); | |
} | |
void RenderThemeWince::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const | |
{ | |
IntSize magnifierSize(15, 11); | |
style->setWidth(Length(magnifierSize.width(), Fixed)); | |
style->setHeight(Length(magnifierSize.height(), Fixed)); | |
} | |
bool RenderThemeWince::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) | |
{ | |
notImplemented(); | |
return false; | |
} | |
void RenderThemeWince::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const | |
{ | |
IntSize magnifierSize(15, 11); | |
style->setWidth(Length(magnifierSize.width(), Fixed)); | |
style->setHeight(Length(magnifierSize.height(), Fixed)); | |
} | |
bool RenderThemeWince::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) | |
{ | |
paintSearchFieldResultsDecoration(o, paintInfo, r); | |
return false; | |
} | |
void RenderThemeWince::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const | |
{ | |
// These are the paddings needed to place the text correctly in the <select> box | |
const int dropDownBoxPaddingTop = 2; | |
const int dropDownBoxPaddingRight = style->direction() == LTR ? 4 + dropDownButtonWidth : 4; | |
const int dropDownBoxPaddingBottom = 2; | |
const int dropDownBoxPaddingLeft = style->direction() == LTR ? 4 : 4 + dropDownButtonWidth; | |
// The <select> box must be at least 12px high for the button to render nicely on Windows | |
const int dropDownBoxMinHeight = 12; | |
// Position the text correctly within the select box and make the box wide enough to fit the dropdown button | |
style->setPaddingTop(Length(dropDownBoxPaddingTop, Fixed)); | |
style->setPaddingRight(Length(dropDownBoxPaddingRight, Fixed)); | |
style->setPaddingBottom(Length(dropDownBoxPaddingBottom, Fixed)); | |
style->setPaddingLeft(Length(dropDownBoxPaddingLeft, Fixed)); | |
// Height is locked to auto | |
style->setHeight(Length(Auto)); | |
// Calculate our min-height | |
int minHeight = style->font().height(); | |
minHeight = max(minHeight, dropDownBoxMinHeight); | |
style->setMinHeight(Length(minHeight, Fixed)); | |
// White-space is locked to pre | |
style->setWhiteSpace(PRE); | |
DWORD colorMenu = GetSysColor(COLOR_MENU); | |
DWORD colorMenuText = GetSysColor(COLOR_MENUTEXT); | |
Color bgColor(GetRValue(colorMenu), GetGValue(colorMenu), GetBValue(colorMenu), 255); | |
Color textColor(GetRValue(colorMenuText), GetGValue(colorMenuText), GetBValue(colorMenuText), 255); | |
if (bgColor == textColor) | |
textColor.setRGB((~bgColor.rgb()) | 0xFF000000); | |
style->clearBackgroundLayers(); | |
style->accessBackgroundLayers()->setClip(ContentFillBox); | |
style->setBackgroundColor(bgColor); | |
style->setColor(textColor); | |
} | |
#if ENABLE(VIDEO) | |
// Attempt to retrieve a HTMLMediaElement from a Node. Returns 0 if one cannot be found. | |
static HTMLMediaElement* mediaElementParent(Node* node) | |
{ | |
if (!node) | |
return 0; | |
Node* mediaNode = node->shadowAncestorNode(); | |
if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag))) | |
return 0; | |
return static_cast<HTMLMediaElement*>(mediaNode); | |
} | |
#endif | |
bool RenderThemeWince::paintSliderTrack(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) | |
{ | |
bool rc = RenderTheme::paintSliderTrack(o, i, r); | |
IntPoint left = IntPoint(r.x() + 2, (r.y() + r.bottom()) / 2); | |
i.context->save(); | |
i.context->setStrokeColor(Color::gray, DeviceColorSpace); | |
i.context->setFillColor(Color::gray, DeviceColorSpace); | |
i.context->fillRect(r); | |
#if ENABLE(VIDEO) | |
HTMLMediaElement* mediaElement = mediaElementParent(o->node()); | |
if (mediaElement) { | |
i.context->setStrokeColor(Color(0, 0xff, 0)); | |
IntPoint right = IntPoint(left.x() + mediaElement->percentLoaded() * (r.right() - r.x() - 4), (r.y() + r.bottom()) / 2); | |
i.context->drawLine(left, right); | |
left = right; | |
} | |
#endif | |
i.context->setStrokeColor(Color::black, DeviceColorSpace); | |
i.context->drawLine(left, IntPoint(r.right() - 2, left.y())); | |
i.context->restore(); | |
return rc; | |
} | |
bool RenderThemeWince::paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) | |
{ | |
bool rc = RenderTheme::paintSliderThumb(o, i, r); | |
i.context->save(); | |
i.context->setStrokeColor(Color::black, DeviceColorSpace); | |
i.context->setFillColor(Color::black, DeviceColorSpace); | |
#if ENABLE(VIDEO) | |
HTMLMediaElement* mediaElement = mediaElementParent(o->node()); | |
if (mediaElement) { | |
float pt = (mediaElement->currentTime() - mediaElement->startTime()) / mediaElement->duration(); | |
FloatRect intRect = r; | |
intRect.setX(intRect.x() + intRect.width() * pt - 2); | |
intRect.setWidth(5); | |
i.context->fillRect(intRect); | |
} | |
#endif | |
i.context->restore(); | |
return rc; | |
} | |
int RenderThemeWince::buttonInternalPaddingLeft() const | |
{ | |
return 3; | |
} | |
int RenderThemeWince::buttonInternalPaddingRight() const | |
{ | |
return 3; | |
} | |
int RenderThemeWince::buttonInternalPaddingTop() const | |
{ | |
return 1; | |
} | |
int RenderThemeWince::buttonInternalPaddingBottom() const | |
{ | |
return 1; | |
} | |
void RenderThemeWince::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const | |
{ | |
const int padding = 1; | |
style->setPaddingLeft(Length(padding, Fixed)); | |
style->setPaddingRight(Length(padding, Fixed)); | |
style->setPaddingTop(Length(padding, Fixed)); | |
style->setPaddingBottom(Length(padding, Fixed)); | |
} | |
#if ENABLE(VIDEO) | |
bool RenderThemeWince::paintMediaFullscreenButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) | |
{ | |
bool rc = paintButton(o, paintInfo, r); | |
FloatRect imRect = r; | |
imRect.inflate(-2); | |
paintInfo.context->save(); | |
paintInfo.context->setStrokeColor(Color::black); | |
paintInfo.context->setFillColor(Color::gray); | |
paintInfo.context->fillRect(imRect); | |
paintInfo.context->restore(); | |
return rc; | |
} | |
bool RenderThemeWince::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) | |
{ | |
bool rc = paintButton(o, paintInfo, r); | |
HTMLMediaElement* mediaElement = mediaElementParent(o->node()); | |
bool muted = !mediaElement || mediaElement->muted(); | |
FloatRect imRect = r; | |
imRect.inflate(-2); | |
paintInfo.context->save(); | |
paintInfo.context->setStrokeColor(Color::black); | |
paintInfo.context->setFillColor(Color::black); | |
FloatPoint pts[6] = { | |
FloatPoint(imRect.x() + 1, imRect.y() + imRect.height() / 3.0), | |
FloatPoint(imRect.x() + 1 + imRect.width() / 2.0, imRect.y() + imRect.height() / 3.0), | |
FloatPoint(imRect.right() - 1, imRect.y()), | |
FloatPoint(imRect.right() - 1, imRect.bottom()), | |
FloatPoint(imRect.x() + 1 + imRect.width() / 2.0, imRect.y() + 2.0 * imRect.height() / 3.0), | |
FloatPoint(imRect.x() + 1, imRect.y() + 2.0 * imRect.height() / 3.0) | |
}; | |
paintInfo.context->drawConvexPolygon(6, pts); | |
if (muted) | |
paintInfo.context->drawLine(IntPoint(imRect.right(), imRect.y()), IntPoint(imRect.x(), imRect.bottom())); | |
paintInfo.context->restore(); | |
return rc; | |
} | |
bool RenderThemeWince::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) | |
{ | |
bool rc = paintButton(o, paintInfo, r); | |
FloatRect imRect = r; | |
imRect.inflate(-3); | |
paintInfo.context->save(); | |
paintInfo.context->setStrokeColor(Color::black); | |
paintInfo.context->setFillColor(Color::black); | |
HTMLMediaElement* mediaElement = mediaElementParent(o->node()); | |
bool paused = !mediaElement || mediaElement->paused(); | |
if (paused) { | |
float width = imRect.width(); | |
imRect.setWidth(width / 3.0); | |
paintInfo.context->fillRect(imRect); | |
imRect.move(2.0 * width / 3.0, 0); | |
paintInfo.context->fillRect(imRect); | |
} else { | |
FloatPoint pts[3] = { FloatPoint(imRect.x(), imRect.y()), FloatPoint(imRect.right(), (imRect.y() + imRect.bottom()) / 2.0), FloatPoint(imRect.x(), imRect.bottom()) }; | |
paintInfo.context->drawConvexPolygon(3, pts); | |
} | |
paintInfo.context->restore(); | |
return rc; | |
} | |
bool RenderThemeWince::paintMediaSeekBackButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) | |
{ | |
bool rc = paintButton(o, paintInfo, r); | |
FloatRect imRect = r; | |
imRect.inflate(-3); | |
FloatPoint pts[3] = { FloatPoint((imRect.x() + imRect.right()) / 2.0, imRect.y()), FloatPoint(imRect.x(), (imRect.y() + imRect.bottom()) / 2.0), FloatPoint((imRect.x() + imRect.right()) / 2.0, imRect.bottom()) }; | |
FloatPoint pts2[3] = { FloatPoint(imRect.right(), imRect.y()), FloatPoint((imRect.x() + imRect.right()) / 2.0, (imRect.y() + imRect.bottom()) / 2.0), FloatPoint(imRect.right(), imRect.bottom()) }; | |
paintInfo.context->save(); | |
paintInfo.context->setStrokeColor(Color::black); | |
paintInfo.context->setFillColor(Color::black); | |
paintInfo.context->drawConvexPolygon(3, pts); | |
paintInfo.context->drawConvexPolygon(3, pts2); | |
paintInfo.context->restore(); | |
return rc; | |
} | |
bool RenderThemeWince::paintMediaSeekForwardButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) | |
{ | |
bool rc = paintButton(o, paintInfo, r); | |
FloatRect imRect = r; | |
imRect.inflate(-3); | |
FloatPoint pts[3] = { FloatPoint(imRect.x(), imRect.y()), FloatPoint((imRect.x() + imRect.right()) / 2.0, (imRect.y() + imRect.bottom()) / 2.0), FloatPoint(imRect.x(), imRect.bottom()) }; | |
FloatPoint pts2[3] = { FloatPoint((imRect.x() + imRect.right()) / 2.0, imRect.y()), FloatPoint(imRect.right(), (imRect.y() + imRect.bottom()) / 2.0), FloatPoint((imRect.x() + imRect.right()) / 2.0, imRect.bottom()) }; | |
paintInfo.context->save(); | |
paintInfo.context->setStrokeColor(Color::black); | |
paintInfo.context->setFillColor(Color::black); | |
paintInfo.context->drawConvexPolygon(3, pts); | |
paintInfo.context->drawConvexPolygon(3, pts2); | |
paintInfo.context->restore(); | |
return rc; | |
} | |
bool RenderThemeWince::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) | |
{ | |
return paintSliderTrack(o, paintInfo, r); | |
} | |
bool RenderThemeWince::paintMediaSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) | |
{ | |
return paintSliderThumb(o, paintInfo, r); | |
} | |
#endif | |
} | |