| /* |
| * Copyright (C) 2006, 2007 Apple Inc. |
| * Copyright (C) 2009 Google Inc. |
| * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser 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 |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| #include "config.h" |
| #include "RenderThemeBlackBerry.h" |
| |
| #include "CSSValueKeywords.h" |
| #include "Frame.h" |
| #include "HTMLMediaElement.h" |
| #include "HostWindow.h" |
| #include "MediaControlElements.h" |
| #include "MediaPlayerPrivateBlackBerry.h" |
| #include "Page.h" |
| #include "PaintInfo.h" |
| #include "RenderFullScreen.h" |
| #include "RenderProgress.h" |
| #include "RenderSlider.h" |
| #include "RenderView.h" |
| #include "UserAgentStyleSheets.h" |
| |
| #include <BlackBerryPlatformLog.h> |
| |
| namespace WebCore { |
| |
| // Sizes (unit px) |
| const unsigned smallRadius = 1; |
| const unsigned largeRadius = 3; |
| const unsigned lineWidth = 1; |
| const float marginSize = 4; |
| const float mediaControlsHeight = 32; |
| const float mediaSliderThumbWidth = 40; |
| const float mediaSliderThumbHeight = 13; |
| const float mediaSliderThumbRadius = 5; |
| const float sliderThumbWidth = 15; |
| const float sliderThumbHeight = 25; |
| |
| // Checkbox check scalers |
| const float checkboxLeftX = 7 / 40.0; |
| const float checkboxLeftY = 1 / 2.0; |
| const float checkboxMiddleX = 19 / 50.0; |
| const float checkboxMiddleY = 7 / 25.0; |
| const float checkboxRightX = 33 / 40.0; |
| const float checkboxRightY = 1 / 5.0; |
| const float checkboxStrokeThickness = 6.5; |
| |
| // Radio button scaler |
| const float radioButtonCheckStateScaler = 7 / 30.0; |
| |
| // Multipliers |
| const unsigned paddingDivisor = 5; |
| const unsigned fullScreenEnlargementFactor = 2; |
| const float scaleFactorThreshold = 2.0; |
| |
| // Slice length |
| const int smallSlice = 8; |
| const int mediumSlice = 10; |
| const int largeSlice = 13; |
| |
| // Slider Aura, calculated from UX spec |
| const float auraRatio = 1.62; |
| |
| // Dropdown arrow position, calculated from UX spec |
| const float xPositionRatio = 3; |
| const float yPositionRatio = 0.38; |
| const float widthRatio = 3; |
| const float heightRatio = 0.23; |
| |
| // Colors |
| const RGBA32 caretBottom = 0xff2163bf; |
| const RGBA32 caretTop = 0xff69a5fa; |
| |
| const RGBA32 regularBottom = 0xffdcdee4; |
| const RGBA32 regularTop = 0xfff7f2ee; |
| const RGBA32 hoverBottom = 0xffb5d3fc; |
| const RGBA32 hoverTop = 0xffcceaff; |
| const RGBA32 depressedBottom = 0xff3388ff; |
| const RGBA32 depressedTop = 0xff66a0f2; |
| const RGBA32 disabledBottom = 0xffe7e7e7; |
| const RGBA32 disabledTop = 0xffefefef; |
| |
| const RGBA32 regularBottomOutline = 0xff6e7073; |
| const RGBA32 regularTopOutline = 0xffb9b8b8; |
| const RGBA32 hoverBottomOutline = 0xff2163bf; |
| const RGBA32 hoverTopOutline = 0xff69befa; |
| const RGBA32 depressedBottomOutline = 0xff0c3d81; |
| const RGBA32 depressedTopOutline = 0xff1d4d70; |
| const RGBA32 disabledOutline = 0xffd5d9de; |
| |
| const RGBA32 progressRegularBottom = caretTop; |
| const RGBA32 progressRegularTop = caretBottom; |
| |
| const RGBA32 rangeSliderRegularBottom = 0xfff6f2ee; |
| const RGBA32 rangeSliderRegularTop = 0xffdee0e5; |
| const RGBA32 rangeSliderRollBottom = 0xffc9e8fe; |
| const RGBA32 rangeSliderRollTop = 0xffb5d3fc; |
| |
| const RGBA32 rangeSliderRegularBottomOutline = 0xffb9babd; |
| const RGBA32 rangeSliderRegularTopOutline = 0xffb7b7b7; |
| const RGBA32 rangeSliderRollBottomOutline = 0xff67abe0; |
| const RGBA32 rangeSliderRollTopOutline = 0xff69adf9; |
| |
| const RGBA32 dragRegularLight = 0xfffdfdfd; |
| const RGBA32 dragRegularDark = 0xffbababa; |
| const RGBA32 dragRollLight = 0xfff2f2f2; |
| const RGBA32 dragRollDark = 0xff69a8ff; |
| |
| const RGBA32 selection = 0xff2b8fff; |
| |
| const RGBA32 blackPen = Color::black; |
| const RGBA32 focusRingPen = 0xffa3c8fe; |
| const RGBA32 activeTextColor = 0xfffafafa; |
| |
| float RenderThemeBlackBerry::defaultFontSize = 16; |
| |
| const String& RenderThemeBlackBerry::defaultGUIFont() |
| { |
| DEFINE_STATIC_LOCAL(String, fontFace, (ASCIILiteral("Slate Pro"))); |
| return fontFace; |
| } |
| |
| static PassRefPtr<Gradient> createLinearGradient(RGBA32 top, RGBA32 bottom, const IntPoint& a, const IntPoint& b) |
| { |
| RefPtr<Gradient> gradient = Gradient::create(a, b); |
| gradient->addColorStop(0.0, Color(top)); |
| gradient->addColorStop(1.0, Color(bottom)); |
| return gradient.release(); |
| } |
| |
| static RenderSlider* determineRenderSlider(RenderObject* object) |
| { |
| ASSERT(object->isSliderThumb()); |
| // The RenderSlider is an ancestor of the slider thumb. |
| while (object && !object->isSlider()) |
| object = object->parent(); |
| return toRenderSlider(object); |
| } |
| |
| static float determineFullScreenMultiplier(Element* element) |
| { |
| float fullScreenMultiplier = 1.0; |
| #if ENABLE(FULLSCREEN_API) && ENABLE(VIDEO) |
| if (element && element->document()->webkitIsFullScreen() && element->document()->webkitCurrentFullScreenElement() == toParentMediaElement(element)) { |
| if (element->document()->page()->deviceScaleFactor() < scaleFactorThreshold) |
| fullScreenMultiplier = fullScreenEnlargementFactor; |
| |
| // The way the BlackBerry port implements the FULLSCREEN_API for media elements |
| // might result in the controls being oversized, proportionally to the current page |
| // scale. That happens because the fullscreen element gets sized to be as big as the |
| // viewport size, and the viewport size might get outstretched to fit to the screen dimensions. |
| // To fix that, lets strips out the Page scale factor from the media controls multiplier. |
| float scaleFactor = element->document()->view()->hostWindow()->platformPageClient()->currentZoomFactor(); |
| static ViewportArguments defaultViewportArguments; |
| float scaleFactorFudge = 1 / element->document()->page()->deviceScaleFactor(); |
| fullScreenMultiplier /= scaleFactor * scaleFactorFudge; |
| } |
| #endif |
| return fullScreenMultiplier; |
| } |
| |
| static void drawControl(GraphicsContext* gc, const FloatRect& rect, Image* img) |
| { |
| if (!img) |
| return; |
| FloatRect srcRect(0, 0, img->width(), img->height()); |
| gc->drawImage(img, ColorSpaceDeviceRGB, rect, srcRect); |
| } |
| |
| static void drawNineSlice(GraphicsContext* gc, const IntRect& rect, double scale, Image* img, int slice) |
| { |
| if (!img) |
| return; |
| if (rect.height() * scale < 101.0) |
| scale = 101.0 / rect.height(); |
| FloatSize dstSlice(slice / scale, slice / scale); |
| FloatRect srcRect(0, 0, slice, slice); |
| FloatRect dstRect(rect.location(), dstSlice); |
| gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect); |
| srcRect.move(img->width() - srcRect.width(), 0); |
| dstRect.move(rect.width() - dstRect.width(), 0); |
| gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect); |
| srcRect.move(0, img->height() - srcRect.height()); |
| dstRect.move(0, rect.height() - dstRect.height()); |
| gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect); |
| srcRect.move(-(img->width() - srcRect.width()), 0); |
| dstRect.move(-(rect.width() - dstRect.width()), 0); |
| gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect); |
| |
| srcRect = FloatRect(slice, 0, img->width() - 2 * slice, slice); |
| dstRect = FloatRect(rect.x() + dstSlice.width(), rect.y(), rect.width() - 2 * dstSlice.width(), dstSlice.height()); |
| gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect); |
| srcRect.move(0, img->height() - srcRect.height()); |
| dstRect.move(0, rect.height() - dstRect.height()); |
| gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect); |
| |
| srcRect = FloatRect(0, slice, slice, img->height() - 2 * slice); |
| dstRect = FloatRect(rect.x(), rect.y() + dstSlice.height(), dstSlice.width(), rect.height() - 2 * dstSlice.height()); |
| gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect); |
| srcRect.move(img->width() - srcRect.width(), 0); |
| dstRect.move(rect.width() - dstRect.width(), 0); |
| gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect); |
| |
| srcRect = FloatRect(slice, slice, img->width() - 2 * slice, img->height() - 2 * slice); |
| dstRect = FloatRect(rect.x() + dstSlice.width(), rect.y() + dstSlice.height(), rect.width() - 2 * dstSlice.width(), rect.height() - 2 * dstSlice.height()); |
| gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect); |
| } |
| |
| static RefPtr<Image> loadImage(const char* filename) |
| { |
| RefPtr<Image> resource; |
| resource = Image::loadPlatformResource(filename).leakRef(); |
| if (!resource) { |
| BlackBerry::Platform::logAlways(BlackBerry::Platform::LogLevelWarn, "RenderThemeBlackBerry failed to load %s.png", filename); |
| return 0; |
| } |
| return resource; |
| } |
| |
| PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) |
| { |
| static RenderTheme* theme = RenderThemeBlackBerry::create().leakRef(); |
| return theme; |
| } |
| |
| PassRefPtr<RenderTheme> RenderThemeBlackBerry::create() |
| { |
| return adoptRef(new RenderThemeBlackBerry()); |
| } |
| |
| RenderThemeBlackBerry::RenderThemeBlackBerry() |
| { |
| } |
| |
| RenderThemeBlackBerry::~RenderThemeBlackBerry() |
| { |
| } |
| |
| String RenderThemeBlackBerry::extraDefaultStyleSheet() |
| { |
| return String(themeBlackBerryUserAgentStyleSheet, sizeof(themeBlackBerryUserAgentStyleSheet)); |
| } |
| |
| #if ENABLE(VIDEO) |
| String RenderThemeBlackBerry::extraMediaControlsStyleSheet() |
| { |
| return String(mediaControlsBlackBerryUserAgentStyleSheet, sizeof(mediaControlsBlackBerryUserAgentStyleSheet)); |
| } |
| |
| String RenderThemeBlackBerry::formatMediaControlsRemainingTime(float, float duration) const |
| { |
| // This is a workaround to make the appearance of media time controller in |
| // in-page mode the same as in fullscreen mode. |
| return formatMediaControlsTime(duration); |
| } |
| #endif |
| |
| double RenderThemeBlackBerry::caretBlinkInterval() const |
| { |
| return 0; // Turn off caret blinking. |
| } |
| |
| void RenderThemeBlackBerry::systemFont(int propId, FontDescription& fontDescription) const |
| { |
| float fontSize = defaultFontSize; |
| |
| // Both CSSValueWebkitControl and CSSValueWebkitSmallControl should use default font size which looks better on the controls. |
| if (propId == CSSValueWebkitMiniControl) { |
| // Why 2 points smaller? Because that's what Gecko does. Note that we |
| // are assuming a 96dpi screen, which is the default value we use on Windows. |
| static const float pointsPerInch = 72.0f; |
| static const float pixelsPerInch = 96.0f; |
| fontSize -= (2.0f / pointsPerInch) * pixelsPerInch; |
| } |
| |
| fontDescription.firstFamily().setFamily(defaultGUIFont()); |
| fontDescription.setSpecifiedSize(fontSize); |
| fontDescription.setIsAbsoluteSize(true); |
| fontDescription.setGenericFamily(FontDescription::NoFamily); |
| fontDescription.setWeight(FontWeightNormal); |
| fontDescription.setItalic(false); |
| } |
| |
| void RenderThemeBlackBerry::setButtonStyle(RenderStyle* style) const |
| { |
| Length vertPadding(int(style->fontSize() / paddingDivisor), Fixed); |
| style->setPaddingTop(vertPadding); |
| style->setPaddingBottom(vertPadding); |
| } |
| |
| void RenderThemeBlackBerry::adjustButtonStyle(StyleResolver*, RenderStyle* style, Element*) const |
| { |
| setButtonStyle(style); |
| style->setCursor(CURSOR_WEBKIT_GRAB); |
| } |
| |
| void RenderThemeBlackBerry::adjustTextAreaStyle(StyleResolver*, RenderStyle* style, Element*) const |
| { |
| setButtonStyle(style); |
| } |
| |
| bool RenderThemeBlackBerry::paintTextArea(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| return paintTextFieldOrTextAreaOrSearchField(object, info, rect); |
| } |
| |
| void RenderThemeBlackBerry::adjustTextFieldStyle(StyleResolver*, RenderStyle* style, Element*) const |
| { |
| setButtonStyle(style); |
| } |
| |
| bool RenderThemeBlackBerry::paintTextFieldOrTextAreaOrSearchField(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| ASSERT(info.context); |
| GraphicsContext* context = info.context; |
| |
| static RefPtr<Image> bg, bgDisabled, bgHighlight; |
| if (!bg) { |
| bg = loadImage("core_textinput_bg"); |
| bgDisabled = loadImage("core_textinput_bg_disabled"); |
| bgHighlight = loadImage("core_textinput_bg_highlight"); |
| } |
| |
| AffineTransform ctm = context->getCTM(); |
| if (isEnabled(object) && bg) |
| drawNineSlice(context, rect, ctm.xScale(), bg.get(), smallSlice); |
| if (!isEnabled(object) && bgDisabled) |
| drawNineSlice(context, rect, ctm.xScale(), bgDisabled.get(), smallSlice); |
| |
| if ((isHovered(object) || isFocused(object) || isPressed(object)) && bgHighlight) |
| drawNineSlice(context, rect, ctm.xScale(), bgHighlight.get(), smallSlice); |
| |
| return false; |
| } |
| |
| bool RenderThemeBlackBerry::paintTextField(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| return paintTextFieldOrTextAreaOrSearchField(object, info, rect); |
| } |
| |
| void RenderThemeBlackBerry::adjustSearchFieldStyle(StyleResolver*, RenderStyle* style, Element*) const |
| { |
| setButtonStyle(style); |
| } |
| |
| void RenderThemeBlackBerry::adjustSearchFieldCancelButtonStyle(StyleResolver*, RenderStyle* style, Element*) const |
| { |
| static const float defaultControlFontPixelSize = 10; |
| static const float defaultCancelButtonSize = 13; |
| static const float minCancelButtonSize = 5; |
| |
| // Scale the button size based on the font size |
| float fontScale = style->fontSize() / defaultControlFontPixelSize; |
| int cancelButtonSize = lroundf(std::max(minCancelButtonSize, defaultCancelButtonSize * fontScale)); |
| Length length(cancelButtonSize, Fixed); |
| style->setWidth(length); |
| style->setHeight(length); |
| } |
| |
| bool RenderThemeBlackBerry::paintSearchField(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| return paintTextFieldOrTextAreaOrSearchField(object, info, rect); |
| } |
| |
| IntRect RenderThemeBlackBerry::convertToPaintingRect(RenderObject* inputRenderer, const RenderObject* partRenderer, LayoutRect partRect, const IntRect& localOffset) const |
| { |
| // Compute an offset between the part renderer and the input renderer. |
| LayoutSize offsetFromInputRenderer = -partRenderer->offsetFromAncestorContainer(inputRenderer); |
| // Move the rect into partRenderer's coords. |
| partRect.move(offsetFromInputRenderer); |
| // Account for the local drawing offset. |
| partRect.move(localOffset.x(), localOffset.y()); |
| |
| return pixelSnappedIntRect(partRect); |
| } |
| |
| |
| bool RenderThemeBlackBerry::paintSearchFieldCancelButton(RenderObject* cancelButtonObject, const PaintInfo& paintInfo, const IntRect& r) |
| { |
| Node* input = cancelButtonObject->node()->shadowAncestorNode(); |
| if (!input->renderer()->isBox()) |
| return false; |
| |
| RenderBox* inputRenderBox = toRenderBox(input->renderer()); |
| LayoutRect inputContentBox = inputRenderBox->contentBoxRect(); |
| |
| // Make sure the scaled button stays square and will fit in its parent's box. |
| LayoutUnit cancelButtonSize = std::min(inputContentBox.width(), std::min<LayoutUnit>(inputContentBox.height(), r.height())); |
| // Calculate cancel button's coordinates relative to the input element. |
| // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will |
| // be one pixel closer to the bottom of the field. This tends to look better with the text. |
| LayoutRect cancelButtonRect(cancelButtonObject->offsetFromAncestorContainer(inputRenderBox).width(), |
| inputContentBox.y() + (inputContentBox.height() - cancelButtonSize + 1) / 2, |
| cancelButtonSize, cancelButtonSize); |
| IntRect paintingRect = convertToPaintingRect(inputRenderBox, cancelButtonObject, cancelButtonRect, r); |
| |
| static Image* cancelImage = Image::loadPlatformResource("searchCancel").leakRef(); |
| static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").leakRef(); |
| paintInfo.context->drawImage(isPressed(cancelButtonObject) ? cancelPressedImage : cancelImage, |
| cancelButtonObject->style()->colorSpace(), paintingRect); |
| return false; |
| } |
| |
| void RenderThemeBlackBerry::adjustMenuListButtonStyle(StyleResolver*, RenderStyle* style, Element*) const |
| { |
| // These seem to be reasonable padding values from observation. |
| const int paddingLeft = 8; |
| const int paddingRight = 4; |
| |
| const int minHeight = style->fontSize() * 2; |
| |
| style->resetPadding(); |
| style->setHeight(Length(Auto)); |
| |
| style->setPaddingRight(Length(minHeight + paddingRight, Fixed)); |
| style->setPaddingLeft(Length(paddingLeft, Fixed)); |
| style->setCursor(CURSOR_WEBKIT_GRAB); |
| } |
| |
| void RenderThemeBlackBerry::calculateButtonSize(RenderStyle* style) const |
| { |
| int size = style->fontSize(); |
| Length length(size, Fixed); |
| if (style->appearance() == CheckboxPart || style->appearance() == RadioPart) { |
| style->setWidth(length); |
| style->setHeight(length); |
| return; |
| } |
| |
| // If the width and height are both specified, then we have nothing to do. |
| if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) |
| return; |
| |
| if (style->width().isIntrinsicOrAuto()) |
| style->setWidth(length); |
| |
| if (style->height().isAuto()) |
| style->setHeight(length); |
| } |
| |
| bool RenderThemeBlackBerry::paintCheckbox(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| ASSERT(info.context); |
| GraphicsContext* context = info.context; |
| |
| static RefPtr<Image> disabled, background, inactive, pressed, active, activeMark, disableMark; |
| if (!disabled) { |
| disabled = loadImage("core_checkbox_disabled"); |
| background = loadImage("core_checkbox_moat"); |
| inactive = loadImage("core_checkbox_inactive"); |
| pressed = loadImage("core_checkbox_pressed"); |
| active = loadImage("core_checkbox_active"); |
| activeMark = loadImage("core_checkbox_active_mark"); |
| disableMark = loadImage("core_checkbox_disabled_mark"); |
| } |
| |
| // Caculate where to put center checkmark. |
| FloatRect tmpRect(rect); |
| |
| float centerX = ((float(inactive->width()) - float(activeMark->width())) / float(inactive->width()) * tmpRect.width() / 2) + tmpRect.x(); |
| float centerY = ((float(inactive->height()) - float(activeMark->height())) / float(inactive->height()) * tmpRect.height() / 2) + tmpRect.y(); |
| float width = float(activeMark->width()) / float(inactive->width()) * tmpRect.width(); |
| float height = float(activeMark->height()) / float(inactive->height()) * tmpRect.height(); |
| FloatRect centerRect(centerX, centerY, width, height); |
| |
| drawControl(context, rect, background.get()); |
| |
| if (isEnabled(object)) { |
| if (isPressed(object)) { |
| drawControl(context, rect, pressed.get()); |
| if (isChecked(object)) { |
| // FIXME: need opacity 30% on activeMark |
| drawControl(context, centerRect, activeMark.get()); |
| } |
| } else { |
| drawControl(context, rect, inactive.get()); |
| if (isChecked(object)) { |
| drawControl(context, rect, active.get()); |
| drawControl(context, centerRect, activeMark.get()); |
| } |
| } |
| } else { |
| drawControl(context, rect, disabled.get()); |
| if (isChecked(object)) |
| drawControl(context, rect, disableMark.get()); |
| } |
| return false; |
| } |
| |
| void RenderThemeBlackBerry::setCheckboxSize(RenderStyle* style) const |
| { |
| calculateButtonSize(style); |
| } |
| |
| bool RenderThemeBlackBerry::paintRadio(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| ASSERT(info.context); |
| GraphicsContext* context = info.context; |
| |
| static RefPtr<Image> disabled, disabledActive, inactive, pressed, active, activeMark; |
| if (!disabled) { |
| disabled = loadImage("core_radiobutton_disabled"); |
| disabledActive = loadImage("core_radiobutton_disabled_active"); |
| inactive = loadImage("core_radiobutton_inactive"); |
| pressed = loadImage("core_radiobutton_pressed"); |
| active = loadImage("core_radiobutton_active"); |
| activeMark = loadImage("core_radiobutton_active_mark"); |
| } |
| |
| // Caculate where to put center circle. |
| FloatRect tmpRect(rect); |
| |
| float centerX = ((float(inactive->width()) - float(activeMark->width())) / float(inactive->width()) * tmpRect.width() / 2)+ tmpRect.x(); |
| float centerY = ((float(inactive->height()) - float(activeMark->height())) / float(inactive->height()) * tmpRect.height() / 2) + tmpRect.y(); |
| float width = float(activeMark->width()) / float(inactive->width()) * tmpRect.width(); |
| float height = float(activeMark->height()) / float(inactive->height()) * tmpRect.height(); |
| FloatRect centerRect(centerX, centerY, width, height); |
| |
| if (isEnabled(object)) { |
| if (isPressed(object)) { |
| drawControl(context, rect, pressed.get()); |
| if (isChecked(object)) { |
| // FIXME: need opacity 30% on activeMark |
| drawControl(context, centerRect, activeMark.get()); |
| } |
| } else { |
| drawControl(context, rect, inactive.get()); |
| if (isChecked(object)) { |
| drawControl(context, rect, active.get()); |
| drawControl(context, centerRect, activeMark.get()); |
| } |
| } |
| } else { |
| drawControl(context, rect, inactive.get()); |
| if (isChecked(object)) |
| drawControl(context, rect, disabledActive.get()); |
| else |
| drawControl(context, rect, disabled.get()); |
| } |
| return false; |
| } |
| |
| void RenderThemeBlackBerry::setRadioSize(RenderStyle* style) const |
| { |
| calculateButtonSize(style); |
| } |
| |
| // If this function returns false, WebCore assumes the button is fully decorated |
| bool RenderThemeBlackBerry::paintButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| ASSERT(info.context); |
| info.context->save(); |
| GraphicsContext* context = info.context; |
| |
| static RefPtr<Image> disabled, inactive, pressed; |
| if (!disabled) { |
| disabled = loadImage("core_button_disabled"); |
| inactive = loadImage("core_button_inactive"); |
| pressed = loadImage("core_button_pressed"); |
| } |
| |
| AffineTransform ctm = context->getCTM(); |
| if (!isEnabled(object)) { |
| drawNineSlice(context, rect, ctm.xScale(), inactive.get(), largeSlice); |
| drawNineSlice(context, rect, ctm.xScale(), disabled.get(), largeSlice); |
| } else if (isPressed(object)) { |
| drawNineSlice(context, rect, ctm.xScale(), pressed.get(), largeSlice); |
| object->style()->setTextFillColor(activeTextColor); |
| } else |
| drawNineSlice(context, rect, ctm.xScale(), inactive.get(), largeSlice); |
| |
| context->restore(); |
| return false; |
| } |
| |
| void RenderThemeBlackBerry::adjustMenuListStyle(StyleResolver* css, RenderStyle* style, Element* element) const |
| { |
| adjustMenuListButtonStyle(css, style, element); |
| } |
| |
| void RenderThemeBlackBerry::adjustCheckboxStyle(StyleResolver*, RenderStyle* style, Element*) const |
| { |
| setCheckboxSize(style); |
| style->setBoxShadow(nullptr); |
| Length margin(marginSize, Fixed); |
| style->setMarginBottom(margin); |
| style->setMarginRight(margin); |
| style->setCursor(CURSOR_WEBKIT_GRAB); |
| } |
| |
| void RenderThemeBlackBerry::adjustRadioStyle(StyleResolver*, RenderStyle* style, Element*) const |
| { |
| setRadioSize(style); |
| style->setBoxShadow(nullptr); |
| Length margin(marginSize, Fixed); |
| style->setMarginBottom(margin); |
| style->setMarginRight(margin); |
| style->setCursor(CURSOR_WEBKIT_GRAB); |
| } |
| |
| static IntRect computeMenuListArrowButtonRect(const IntRect& rect) |
| { |
| // FIXME: The menu list arrow button should have a minimum and maximum width (to ensure usability) or |
| // scale with respect to the font size used in the menu list control or some combination of both. |
| return IntRect(IntPoint(rect.maxX() - rect.height(), rect.y()), IntSize(rect.height(), rect.height())); |
| } |
| |
| bool RenderThemeBlackBerry::paintMenuList(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| ASSERT(info.context); |
| info.context->save(); |
| GraphicsContext* context = info.context; |
| |
| static RefPtr<Image> disabled, inactive, pressed, arrowUp, arrowUpPressed; |
| if (!disabled) { |
| disabled = loadImage("core_button_disabled"); |
| inactive = loadImage("core_button_inactive"); |
| pressed = loadImage("core_button_pressed"); |
| arrowUp = loadImage("core_dropdown_button_arrowup"); |
| arrowUpPressed = loadImage("core_dropdown_button_arrowup_pressed"); |
| } |
| |
| FloatRect arrowButtonRectangle(computeMenuListArrowButtonRect(rect)); |
| float x = arrowButtonRectangle.x() + arrowButtonRectangle.width() / xPositionRatio; |
| float y = arrowButtonRectangle.y() + arrowButtonRectangle.height() * yPositionRatio; |
| float width = arrowButtonRectangle.width() / widthRatio; |
| float height = arrowButtonRectangle.height() * heightRatio; |
| FloatRect tmpRect(x, y, width, height); |
| |
| AffineTransform ctm = context->getCTM(); |
| if (!isEnabled(object)) { |
| drawNineSlice(context, rect, ctm.xScale(), inactive.get(), largeSlice); |
| drawNineSlice(context, rect, ctm.xScale(), disabled.get(), largeSlice); |
| drawControl(context, tmpRect, arrowUp.get()); // FIXME: should have a disabled image. |
| } else if (isFocused(object)) { |
| drawNineSlice(context, rect, ctm.xScale(), pressed.get(), largeSlice); |
| drawControl(context, tmpRect, arrowUpPressed.get()); |
| object->style()->setTextFillColor(activeTextColor); |
| } else { |
| drawNineSlice(context, rect, ctm.xScale(), inactive.get(), largeSlice); |
| drawControl(context, tmpRect, arrowUp.get()); |
| } |
| context->restore(); |
| return false; |
| } |
| |
| bool RenderThemeBlackBerry::paintMenuListButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| return paintMenuList(object, info, rect); |
| } |
| |
| void RenderThemeBlackBerry::adjustSliderThumbSize(RenderStyle* style, Element* element) const |
| { |
| float fullScreenMultiplier = 1; |
| ControlPart part = style->appearance(); |
| |
| if (part == MediaSliderThumbPart || part == MediaVolumeSliderThumbPart) { |
| RenderSlider* slider = determineRenderSlider(element->renderer()); |
| if (slider) |
| fullScreenMultiplier = determineFullScreenMultiplier(toElement(slider->node())); |
| } |
| |
| if (part == MediaVolumeSliderThumbPart || part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) { |
| style->setWidth(Length((part == SliderThumbVerticalPart ? sliderThumbHeight : sliderThumbWidth) * fullScreenMultiplier, Fixed)); |
| style->setHeight(Length((part == SliderThumbVerticalPart ? sliderThumbWidth : sliderThumbHeight) * fullScreenMultiplier, Fixed)); |
| } else if (part == MediaSliderThumbPart) { |
| style->setWidth(Length(mediaSliderThumbWidth * fullScreenMultiplier, Fixed)); |
| style->setHeight(Length(mediaSliderThumbHeight * fullScreenMultiplier, Fixed)); |
| } |
| } |
| |
| bool RenderThemeBlackBerry::paintSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| const static int SliderTrackHeight = 5; |
| IntRect rect2; |
| if (object->style()->appearance() == SliderHorizontalPart) { |
| rect2.setHeight(SliderTrackHeight); |
| rect2.setWidth(rect.width()); |
| rect2.setX(rect.x()); |
| rect2.setY(rect.y() + (rect.height() - SliderTrackHeight) / 2); |
| } else { |
| rect2.setHeight(rect.height()); |
| rect2.setWidth(SliderTrackHeight); |
| rect2.setX(rect.x() + (rect.width() - SliderTrackHeight) / 2); |
| rect2.setY(rect.y()); |
| } |
| return paintSliderTrackRect(object, info, rect2); |
| } |
| |
| bool RenderThemeBlackBerry::paintSliderTrackRect(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| return paintSliderTrackRect(object, info, rect, rangeSliderRegularTopOutline, rangeSliderRegularBottomOutline, |
| rangeSliderRegularTop, rangeSliderRegularBottom); |
| } |
| |
| bool RenderThemeBlackBerry::paintSliderTrackRect(RenderObject* object, const PaintInfo& info, const IntRect& rect, |
| RGBA32 strokeColorStart, RGBA32 strokeColorEnd, RGBA32 fillColorStart, RGBA32 fillColorEnd) |
| { |
| FloatSize smallCorner(smallRadius, smallRadius); |
| |
| info.context->save(); |
| info.context->setStrokeStyle(SolidStroke); |
| info.context->setStrokeThickness(lineWidth); |
| |
| info.context->setStrokeGradient(createLinearGradient(strokeColorStart, strokeColorEnd, rect.maxXMinYCorner(), rect. maxXMaxYCorner())); |
| info.context->setFillGradient(createLinearGradient(fillColorStart, fillColorEnd, rect.maxXMinYCorner(), rect.maxXMaxYCorner())); |
| |
| Path path; |
| path.addRoundedRect(rect, smallCorner); |
| info.context->fillPath(path); |
| |
| info.context->restore(); |
| return false; |
| } |
| |
| bool RenderThemeBlackBerry::paintSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| FloatSize largeCorner(largeRadius, largeRadius); |
| info.context->save(); |
| info.context->setStrokeStyle(SolidStroke); |
| info.context->setStrokeThickness(lineWidth); |
| if (isPressed(object) || isHovered(object)) { |
| info.context->setStrokeGradient(createLinearGradient(hoverTopOutline, hoverBottomOutline, rect.maxXMinYCorner(), rect. maxXMaxYCorner())); |
| info.context->setFillGradient(createLinearGradient(hoverTop, hoverBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner())); |
| } else { |
| info.context->setStrokeGradient(createLinearGradient(regularTopOutline, regularBottomOutline, rect.maxXMinYCorner(), rect. maxXMaxYCorner())); |
| info.context->setFillGradient(createLinearGradient(regularTop, regularBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner())); |
| } |
| Path path; |
| path.addRoundedRect(rect, largeCorner); |
| info.context->fillPath(path); |
| bool isVertical = rect.width() > rect.height(); |
| IntPoint startPoint(rect.x() + (isVertical ? 5 : 2), rect.y() + (isVertical ? 2 : 5)); |
| IntPoint endPoint(rect.x() + (isVertical ? 20 : 2), rect.y() + (isVertical ? 2 : 20)); |
| const int lineOffset = 2; |
| const int shadowOffset = 1; |
| for (int i = 0; i < 3; i++) { |
| if (isVertical) { |
| startPoint.setY(startPoint.y() + lineOffset); |
| endPoint.setY(endPoint.y() + lineOffset); |
| } else { |
| startPoint.setX(startPoint.x() + lineOffset); |
| endPoint.setX(endPoint.x() + lineOffset); |
| } |
| if (isPressed(object) || isHovered(object)) |
| info.context->setStrokeColor(dragRollLight, ColorSpaceDeviceRGB); |
| else |
| info.context->setStrokeColor(dragRegularLight, ColorSpaceDeviceRGB); |
| info.context->drawLine(startPoint, endPoint); |
| if (isVertical) { |
| startPoint.setY(startPoint.y() + shadowOffset); |
| endPoint.setY(endPoint.y() + shadowOffset); |
| } else { |
| startPoint.setX(startPoint.x() + shadowOffset); |
| endPoint.setX(endPoint.x() + shadowOffset); |
| } |
| if (isPressed(object) || isHovered(object)) |
| info.context->setStrokeColor(dragRollDark, ColorSpaceDeviceRGB); |
| else |
| info.context->setStrokeColor(dragRegularDark, ColorSpaceDeviceRGB); |
| info.context->drawLine(startPoint, endPoint); |
| } |
| info.context->restore(); |
| return false; |
| } |
| |
| void RenderThemeBlackBerry::adjustMediaControlStyle(StyleResolver*, RenderStyle* style, Element* element) const |
| { |
| float fullScreenMultiplier = determineFullScreenMultiplier(element); |
| HTMLMediaElement* mediaElement = toParentMediaElement(element); |
| if (!mediaElement) |
| return; |
| |
| // We use multiples of mediaControlsHeight to make all objects scale evenly |
| Length zero(0, Fixed); |
| Length controlsHeight(mediaControlsHeight * fullScreenMultiplier, Fixed); |
| Length timeWidth(mediaControlsHeight * 3 / 2 * fullScreenMultiplier, Fixed); |
| Length volumeHeight(mediaControlsHeight * 4 * fullScreenMultiplier, Fixed); |
| Length padding(mediaControlsHeight / 8 * fullScreenMultiplier, Fixed); |
| float fontSize = mediaControlsHeight / 2 * fullScreenMultiplier; |
| |
| switch (style->appearance()) { |
| case MediaPlayButtonPart: |
| case MediaEnterFullscreenButtonPart: |
| case MediaExitFullscreenButtonPart: |
| case MediaMuteButtonPart: |
| style->setWidth(controlsHeight); |
| style->setHeight(controlsHeight); |
| break; |
| case MediaCurrentTimePart: |
| case MediaTimeRemainingPart: |
| style->setWidth(timeWidth); |
| style->setHeight(controlsHeight); |
| style->setPaddingRight(padding); |
| style->setFontSize(static_cast<int>(fontSize)); |
| break; |
| case MediaVolumeSliderContainerPart: |
| style->setWidth(controlsHeight); |
| style->setHeight(volumeHeight); |
| style->setBottom(controlsHeight); |
| break; |
| default: |
| break; |
| } |
| |
| if (!isfinite(mediaElement->duration())) { |
| // Live streams have infinite duration with no timeline. Force the mute |
| // and fullscreen buttons to the right. This is needed when webkit does |
| // not render the timeline container because it has a webkit-box-flex |
| // of 1 and normally allows those buttons to be on the right. |
| switch (style->appearance()) { |
| case MediaEnterFullscreenButtonPart: |
| case MediaExitFullscreenButtonPart: |
| style->setPosition(AbsolutePosition); |
| style->setBottom(zero); |
| style->setRight(controlsHeight); |
| break; |
| case MediaMuteButtonPart: |
| style->setPosition(AbsolutePosition); |
| style->setBottom(zero); |
| style->setRight(zero); |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| |
| void RenderThemeBlackBerry::adjustSliderTrackStyle(StyleResolver*, RenderStyle* style, Element* element) const |
| { |
| float fullScreenMultiplier = determineFullScreenMultiplier(element); |
| |
| // We use multiples of mediaControlsHeight to make all objects scale evenly |
| Length controlsHeight(mediaControlsHeight * fullScreenMultiplier, Fixed); |
| Length volumeHeight(mediaControlsHeight * 4 * fullScreenMultiplier, Fixed); |
| switch (style->appearance()) { |
| case MediaSliderPart: |
| style->setHeight(controlsHeight); |
| break; |
| case MediaVolumeSliderPart: |
| style->setWidth(controlsHeight); |
| style->setHeight(volumeHeight); |
| break; |
| case MediaFullScreenVolumeSliderPart: |
| default: |
| break; |
| } |
| } |
| |
| static bool paintMediaButton(GraphicsContext* context, const IntRect& rect, Image* image) |
| { |
| context->drawImage(image, ColorSpaceDeviceRGB, rect); |
| return false; |
| } |
| |
| bool RenderThemeBlackBerry::paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) |
| { |
| #if ENABLE(VIDEO) |
| HTMLMediaElement* mediaElement = toParentMediaElement(object); |
| |
| if (!mediaElement) |
| return false; |
| |
| static Image* mediaPlay = Image::loadPlatformResource("play").leakRef(); |
| static Image* mediaPause = Image::loadPlatformResource("pause").leakRef(); |
| |
| return paintMediaButton(paintInfo.context, rect, mediaElement->canPlay() ? mediaPlay : mediaPause); |
| #else |
| UNUSED_PARAM(object); |
| UNUSED_PARAM(paintInfo); |
| UNUSED_PARAM(rect); |
| return false; |
| #endif |
| } |
| |
| bool RenderThemeBlackBerry::paintMediaMuteButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) |
| { |
| #if ENABLE(VIDEO) |
| HTMLMediaElement* mediaElement = toParentMediaElement(object); |
| |
| if (!mediaElement) |
| return false; |
| |
| static Image* mediaMute = Image::loadPlatformResource("speaker").leakRef(); |
| static Image* mediaUnmute = Image::loadPlatformResource("speaker_mute").leakRef(); |
| |
| return paintMediaButton(paintInfo.context, rect, mediaElement->muted() || !mediaElement->volume() ? mediaUnmute : mediaMute); |
| #else |
| UNUSED_PARAM(object); |
| UNUSED_PARAM(paintInfo); |
| UNUSED_PARAM(rect); |
| return false; |
| #endif |
| } |
| |
| bool RenderThemeBlackBerry::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) |
| { |
| #if ENABLE(VIDEO) |
| HTMLMediaElement* mediaElement = toParentMediaElement(object); |
| if (!mediaElement) |
| return false; |
| |
| static Image* mediaEnterFullscreen = Image::loadPlatformResource("fullscreen").leakRef(); |
| static Image* mediaExitFullscreen = Image::loadPlatformResource("exit_fullscreen").leakRef(); |
| |
| Image* buttonImage = mediaEnterFullscreen; |
| #if ENABLE(FULLSCREEN_API) |
| if (mediaElement->document()->webkitIsFullScreen() && mediaElement->document()->webkitCurrentFullScreenElement() == mediaElement) |
| buttonImage = mediaExitFullscreen; |
| #endif |
| return paintMediaButton(paintInfo.context, rect, buttonImage); |
| #else |
| UNUSED_PARAM(object); |
| UNUSED_PARAM(paintInfo); |
| UNUSED_PARAM(rect); |
| return false; |
| #endif |
| } |
| |
| bool RenderThemeBlackBerry::paintMediaSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) |
| { |
| #if ENABLE(VIDEO) |
| HTMLMediaElement* mediaElement = toParentMediaElement(object); |
| if (!mediaElement) |
| return false; |
| |
| float fullScreenMultiplier = determineFullScreenMultiplier(mediaElement); |
| float loaded = mediaElement->percentLoaded(); |
| float position = mediaElement->duration() > 0 ? (mediaElement->currentTime() / mediaElement->duration()) : 0; |
| |
| int x = ceil(rect.x() + 2 * fullScreenMultiplier - fullScreenMultiplier / 2); |
| int y = ceil(rect.y() + 14 * fullScreenMultiplier + fullScreenMultiplier / 2); |
| int w = ceil(rect.width() - 4 * fullScreenMultiplier + fullScreenMultiplier / 2); |
| int h = ceil(2 * fullScreenMultiplier); |
| IntRect rect2(x, y, w, h); |
| |
| int wPlayed = ceil(w * position); |
| int wLoaded = ceil((w - mediaSliderThumbWidth * fullScreenMultiplier) * loaded + mediaSliderThumbWidth * fullScreenMultiplier); |
| |
| IntRect played(x, y, wPlayed, h); |
| IntRect buffered(x, y, wLoaded, h); |
| |
| // This is to paint main slider bar. |
| bool result = paintSliderTrackRect(object, paintInfo, rect2); |
| |
| if (loaded > 0 || position > 0) { |
| // This is to paint buffered bar. |
| paintSliderTrackRect(object, paintInfo, buffered, Color::darkGray, Color::darkGray, Color::darkGray, Color::darkGray); |
| |
| // This is to paint played part of bar (left of slider thumb) using selection color. |
| paintSliderTrackRect(object, paintInfo, played, selection, selection, selection, selection); |
| } |
| return result; |
| |
| #else |
| UNUSED_PARAM(object); |
| UNUSED_PARAM(paintInfo); |
| UNUSED_PARAM(rect); |
| return false; |
| #endif |
| } |
| |
| bool RenderThemeBlackBerry::paintMediaSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) |
| { |
| #if ENABLE(VIDEO) |
| RenderSlider* slider = determineRenderSlider(object); |
| if (!slider) |
| return false; |
| |
| float fullScreenMultiplier = determineFullScreenMultiplier(toElement(slider->node())); |
| |
| paintInfo.context->save(); |
| Path mediaThumbRoundedRectangle; |
| mediaThumbRoundedRectangle.addRoundedRect(rect, FloatSize(mediaSliderThumbRadius * fullScreenMultiplier, mediaSliderThumbRadius * fullScreenMultiplier)); |
| paintInfo.context->setStrokeStyle(SolidStroke); |
| paintInfo.context->setStrokeThickness(0.5); |
| paintInfo.context->setStrokeColor(Color::black, ColorSpaceDeviceRGB); |
| |
| if (isPressed(object) || isHovered(object) || slider->inDragMode()) { |
| paintInfo.context->setFillGradient(createLinearGradient(selection, Color(selection).dark().rgb(), |
| rect.maxXMinYCorner(), rect.maxXMaxYCorner())); |
| } else { |
| paintInfo.context->setFillGradient(createLinearGradient(Color::white, Color(Color::white).dark().rgb(), |
| rect.maxXMinYCorner(), rect.maxXMaxYCorner())); |
| } |
| paintInfo.context->fillPath(mediaThumbRoundedRectangle); |
| paintInfo.context->restore(); |
| |
| return true; |
| #else |
| UNUSED_PARAM(object); |
| UNUSED_PARAM(paintInfo); |
| UNUSED_PARAM(rect); |
| return false; |
| #endif |
| } |
| |
| bool RenderThemeBlackBerry::paintMediaVolumeSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) |
| { |
| #if ENABLE(VIDEO) |
| float pad = rect.width() * 0.45; |
| float x = rect.x() + pad; |
| float y = rect.y() + pad; |
| float width = rect.width() * 0.1; |
| float height = rect.height() - (2.0 * pad); |
| |
| IntRect rect2(x, y, width, height); |
| |
| return paintSliderTrackRect(object, paintInfo, rect2); |
| #else |
| UNUSED_PARAM(object); |
| UNUSED_PARAM(paintInfo); |
| UNUSED_PARAM(rect); |
| return false; |
| #endif |
| } |
| |
| bool RenderThemeBlackBerry::paintMediaVolumeSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) |
| { |
| #if ENABLE(VIDEO) |
| static Image* mediaVolumeThumb = Image::loadPlatformResource("volume_thumb").leakRef(); |
| |
| return paintMediaButton(paintInfo.context, rect, mediaVolumeThumb); |
| #else |
| UNUSED_PARAM(object); |
| UNUSED_PARAM(paintInfo); |
| UNUSED_PARAM(rect); |
| return false; |
| #endif |
| } |
| |
| Color RenderThemeBlackBerry::platformFocusRingColor() const |
| { |
| return focusRingPen; |
| } |
| |
| #if ENABLE(TOUCH_EVENTS) |
| Color RenderThemeBlackBerry::platformTapHighlightColor() const |
| { |
| return Color(0, 168, 223, 50); |
| } |
| #endif |
| |
| Color RenderThemeBlackBerry::platformActiveSelectionBackgroundColor() const |
| { |
| return Color(0, 168, 223, 50); |
| } |
| |
| double RenderThemeBlackBerry::animationRepeatIntervalForProgressBar(RenderProgress* renderProgress) const |
| { |
| return renderProgress->isDeterminate() ? 0.0 : 0.1; |
| } |
| |
| double RenderThemeBlackBerry::animationDurationForProgressBar(RenderProgress* renderProgress) const |
| { |
| return renderProgress->isDeterminate() ? 0.0 : 2.0; |
| } |
| |
| bool RenderThemeBlackBerry::paintProgressBar(RenderObject* object, const PaintInfo& info, const IntRect& rect) |
| { |
| if (!object->isProgress()) |
| return true; |
| |
| RenderProgress* renderProgress = toRenderProgress(object); |
| |
| FloatSize smallCorner(smallRadius, smallRadius); |
| |
| info.context->save(); |
| info.context->setStrokeStyle(SolidStroke); |
| info.context->setStrokeThickness(lineWidth); |
| |
| info.context->setStrokeGradient(createLinearGradient(rangeSliderRegularTopOutline, rangeSliderRegularBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner())); |
| info.context->setFillGradient(createLinearGradient(rangeSliderRegularTop, rangeSliderRegularBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner())); |
| |
| Path path; |
| path.addRoundedRect(rect, smallCorner); |
| info.context->fillPath(path); |
| |
| IntRect rect2 = rect; |
| rect2.setX(rect2.x() + 1); |
| rect2.setHeight(rect2.height() - 2); |
| rect2.setY(rect2.y() + 1); |
| info.context->setStrokeStyle(NoStroke); |
| info.context->setStrokeThickness(0); |
| if (renderProgress->isDeterminate()) { |
| rect2.setWidth(rect2.width() * renderProgress->position() - 2); |
| info.context->setFillGradient(createLinearGradient(progressRegularTop, progressRegularBottom, rect2.maxXMinYCorner(), rect2.maxXMaxYCorner())); |
| } else { |
| // Animating |
| rect2.setWidth(rect2.width() - 2); |
| RefPtr<Gradient> gradient = Gradient::create(rect2.minXMaxYCorner(), rect2.maxXMaxYCorner()); |
| gradient->addColorStop(0.0, Color(progressRegularBottom)); |
| gradient->addColorStop(renderProgress->animationProgress(), Color(progressRegularTop)); |
| gradient->addColorStop(1.0, Color(progressRegularBottom)); |
| info.context->setFillGradient(gradient); |
| } |
| Path path2; |
| path2.addRoundedRect(rect2, smallCorner); |
| info.context->fillPath(path2); |
| |
| info.context->restore(); |
| return false; |
| } |
| |
| Color RenderThemeBlackBerry::platformActiveTextSearchHighlightColor() const |
| { |
| return Color(255, 150, 50); // Orange. |
| } |
| |
| Color RenderThemeBlackBerry::platformInactiveTextSearchHighlightColor() const |
| { |
| return Color(255, 255, 0); // Yellow. |
| } |
| |
| } // namespace WebCore |