Changeset 132967 in webkit


Ignore:
Timestamp:
Oct 30, 2012 5:12:46 PM (11 years ago)
Author:
commit-queue@webkit.org
Message:

[BlackBerry] update form theme for BB10.
https://bugs.webkit.org/show_bug.cgi?id=100760

Patch by Tiancheng Jiang <tijiang@rim.com> on 2012-10-30
Reviewed by Rob Buis.

RIM PR:222126
Introduce slide function to paint new theme for the form controls.

No new tests.

  • css/themeBlackBerry.css:

(select):

  • platform/blackberry/RenderThemeBlackBerry.cpp:

(WebCore):
(WebCore::drawControl): Added.
(WebCore::drawThreeSlice): Added.
(WebCore::drawNineSlice): Added.
(WebCore::loadImage): Added.
(WebCore::RenderThemeBlackBerry::systemFont): Modified.
(WebCore::RenderThemeBlackBerry::paintTextFieldOrTextAreaOrSearchField): Modified.
(WebCore::RenderThemeBlackBerry::paintCheckbox): Modified.
(WebCore::RenderThemeBlackBerry::paintRadio): Modified.
(WebCore::RenderThemeBlackBerry::paintButton): Modified.
(WebCore::RenderThemeBlackBerry::paintMenuList): Modified.
(WebCore::RenderThemeBlackBerry::paintMenuListButton): Modified.
(WebCore::RenderThemeBlackBerry::paintSliderTrackRect): Modified.
(WebCore::RenderThemeBlackBerry::paintSliderThumb): Modified.

  • platform/blackberry/RenderThemeBlackBerry.h:

(RenderThemeBlackBerry):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r132966 r132967  
     12012-10-30  Tiancheng Jiang  <tijiang@rim.com>
     2
     3        [BlackBerry] update form theme for BB10.
     4        https://bugs.webkit.org/show_bug.cgi?id=100760
     5
     6        Reviewed by Rob Buis.
     7
     8        RIM PR:222126
     9        Introduce slide function to paint new theme for the form controls.
     10
     11        No new tests.
     12
     13        * css/themeBlackBerry.css:
     14        (select):
     15        * platform/blackberry/RenderThemeBlackBerry.cpp:
     16        (WebCore):
     17        (WebCore::drawControl): Added.
     18        (WebCore::drawThreeSlice): Added.
     19        (WebCore::drawNineSlice): Added.
     20        (WebCore::loadImage): Added.
     21        (WebCore::RenderThemeBlackBerry::systemFont): Modified.
     22        (WebCore::RenderThemeBlackBerry::paintTextFieldOrTextAreaOrSearchField): Modified.
     23        (WebCore::RenderThemeBlackBerry::paintCheckbox): Modified.
     24        (WebCore::RenderThemeBlackBerry::paintRadio): Modified.
     25        (WebCore::RenderThemeBlackBerry::paintButton): Modified.
     26        (WebCore::RenderThemeBlackBerry::paintMenuList): Modified.
     27        (WebCore::RenderThemeBlackBerry::paintMenuListButton): Modified.
     28        (WebCore::RenderThemeBlackBerry::paintSliderTrackRect): Modified.
     29        (WebCore::RenderThemeBlackBerry::paintSliderThumb): Modified.
     30        * platform/blackberry/RenderThemeBlackBerry.h:
     31        (RenderThemeBlackBerry):
     32
    1332012-10-30  Rick Byers  <rbyers@chromium.org>
    234
  • trunk/Source/WebCore/css/themeBlackBerry.css

    r130516 r132967  
    2121}
    2222
    23 input, textarea {
    24     border-radius: 3px;
    25 }
    26 
    2723input[type="datetime"],
    2824input[type="date"],
     
    3632}
    3733
    38 select:focus {
    39     border: 1px solid black;
    40     outline: none;
     34select {
     35    border-radius: 0;
    4136}
    42 
    43 select[size],
    44 select[multiple],
    45 select[size][multiple] {
    46     padding: 5px;
    47     border-radius: 5px;
    48     border: 1px solid rgb(139,139,139);
    49 }
    50 
    51 select[size]:focus,
    52 select[multiple]:focus,
    53 select[size][multiple]:focus {
    54     border: 1px solid black;
    55     outline: none;
    56 }
  • trunk/Source/WebCore/platform/blackberry/RenderThemeBlackBerry.cpp

    r130960 r132967  
    3636#include "UserAgentStyleSheets.h"
    3737
     38#include <BlackBerryPlatformLog.h>
     39
    3840namespace WebCore {
    3941
     
    6769const float scaleFactorThreshold = 2.0;
    6870
     71// Slice length
     72const int smallSlice = 8;
     73const int mediumSlice = 10;
     74const int largeSlice = 13;
     75
     76// Slider Aura, calculated from UX spec
     77const float auraRatio = 1.62;
     78
     79// Dropdown arrow position, calculated from UX spec
     80const float xPositionRatio = 3;
     81const float yPositionRatio = 0.38;
     82const float widthRatio = 3;
     83const float heightRatio = 0.23;
     84
    6985// Colors
    7086const RGBA32 caretBottom = 0xff2163bf;
     
    110126const RGBA32 blackPen = Color::black;
    111127const RGBA32 focusRingPen = 0xffa3c8fe;
     128const RGBA32 activeTextColor = 0xfffafafa;
    112129
    113130float RenderThemeBlackBerry::defaultFontSize = 16;
    114 
    115 // We aim to match IE here.
    116 // -IE uses a font based on the encoding as the default font for form controls.
    117 // -Gecko uses MS Shell Dlg (actually calls GetStockObject(DEFAULT_GUI_FONT),
    118 // which returns MS Shell Dlg)
    119 // -Safari uses Lucida Grande.
    120 //
    121 // FIXME: The only case where we know we don't match IE is for ANSI encodings.
    122 // IE uses MS Shell Dlg there, which we render incorrectly at certain pixel
    123 // sizes (e.g. 15px). So we just use Arial for now.
    124 const String& RenderThemeBlackBerry::defaultGUIFont()
    125 {
    126     DEFINE_STATIC_LOCAL(String, fontFace, (ASCIILiteral("Arial")));
    127     return fontFace;
    128 }
    129131
    130132static PassRefPtr<Gradient> createLinearGradient(RGBA32 top, RGBA32 bottom, const IntPoint& a, const IntPoint& b)
     
    134136    gradient->addColorStop(1.0, Color(bottom));
    135137    return gradient.release();
    136 }
    137 
    138 static Path roundedRectForBorder(RenderObject* object, const IntRect& rect)
    139 {
    140     RenderStyle* style = object->style();
    141     LengthSize topLeftRadius = style->borderTopLeftRadius();
    142     LengthSize topRightRadius = style->borderTopRightRadius();
    143     LengthSize bottomLeftRadius = style->borderBottomLeftRadius();
    144     LengthSize bottomRightRadius = style->borderBottomRightRadius();
    145 
    146     Path roundedRect;
    147     roundedRect.addRoundedRect(rect, IntSize(topLeftRadius.width().value(), topLeftRadius.height().value()),
    148                                      IntSize(topRightRadius.width().value(), topRightRadius.height().value()),
    149                                      IntSize(bottomLeftRadius.width().value(), bottomLeftRadius.height().value()),
    150                                      IntSize(bottomRightRadius.width().value(), bottomRightRadius.height().value()));
    151     return roundedRect;
    152138}
    153139
     
    183169}
    184170
     171static void drawControl(GraphicsContext* gc, const FloatRect& rect, Image* img)
     172{
     173    FloatRect srcRect(0, 0, img->width(), img->height());
     174    gc->drawImage(img, ColorSpaceDeviceRGB, rect, srcRect);
     175}
     176
     177static void drawThreeSlice(GraphicsContext* gc, const IntRect& rect, Image* img, int slice)
     178{
     179    FloatSize dstSlice(rect.height() / 2, rect.height());
     180    FloatRect srcRect(0, 0, slice, img->height());
     181    FloatRect dstRect(rect.location(), dstSlice);
     182
     183    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     184    srcRect.move(img->width() - srcRect.width(), 0);
     185    dstRect.move(rect.width() - dstRect.width(), 0);
     186    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     187
     188    srcRect = FloatRect(slice, 0, img->width() - 2 * slice, img->height());
     189    dstRect = FloatRect(rect.x() + dstSlice.width(), rect.y(), rect.width() - 2 * dstSlice.width(), dstSlice.height());
     190    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     191}
     192
     193static void drawNineSlice(GraphicsContext* gc, const IntRect& rect, double scale, Image* img, int slice)
     194{
     195    if (rect.height() * scale < 101.0)
     196        scale = 101.0 / rect.height();
     197    FloatSize dstSlice(slice / scale, slice / scale);
     198    FloatRect srcRect(0, 0, slice, slice);
     199    FloatRect dstRect(rect.location(), dstSlice);
     200    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     201    srcRect.move(img->width() - srcRect.width(), 0);
     202    dstRect.move(rect.width() - dstRect.width(), 0);
     203    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     204    srcRect.move(0, img->height() - srcRect.height());
     205    dstRect.move(0, rect.height() - dstRect.height());
     206    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     207    srcRect.move(-(img->width() - srcRect.width()), 0);
     208    dstRect.move(-(rect.width() - dstRect.width()), 0);
     209    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     210
     211    srcRect = FloatRect(slice, 0, img->width() - 2 * slice, slice);
     212    dstRect = FloatRect(rect.x() + dstSlice.width(), rect.y(), rect.width() - 2 * dstSlice.width(), dstSlice.height());
     213    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     214    srcRect.move(0, img->height() - srcRect.height());
     215    dstRect.move(0, rect.height() - dstRect.height());
     216    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     217
     218    srcRect = FloatRect(0, slice, slice, img->height() - 2 * slice);
     219    dstRect = FloatRect(rect.x(), rect.y() + dstSlice.height(), dstSlice.width(), rect.height() - 2 * dstSlice.height());
     220    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     221    srcRect.move(img->width() - srcRect.width(), 0);
     222    dstRect.move(rect.width() - dstRect.width(), 0);
     223    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     224
     225    srcRect = FloatRect(slice, slice, img->width() - 2 * slice, img->height() - 2 * slice);
     226    dstRect = FloatRect(rect.x() + dstSlice.width(), rect.y() + dstSlice.height(), rect.width() - 2 * dstSlice.width(), rect.height() - 2 * dstSlice.height());
     227    gc->drawImage(img, ColorSpaceDeviceRGB, dstRect, srcRect);
     228}
     229
     230static RefPtr<Image> loadImage(const char* filename)
     231{
     232    RefPtr<Image> resource;
     233    resource = Image::loadPlatformResource(filename).leakRef();
     234    if (!resource) {
     235        BlackBerry::Platform::logAlways(BlackBerry::Platform::LogLevelWarn, "RenderThemeBlackBerry failed to load %s.png", filename);
     236        return 0;
     237    }
     238    return resource;
     239}
     240
    185241PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
    186242{
     
    230286    float fontSize = defaultFontSize;
    231287
    232     if (propId == CSSValueWebkitMiniControl || propId ==  CSSValueWebkitSmallControl || propId == CSSValueWebkitControl) {
     288    // Both CSSValueWebkitControl and CSSValueWebkitSmallControl should use default font size which looks better on the controls.
     289    if (propId == CSSValueWebkitMiniControl) {
    233290        // Why 2 points smaller? Because that's what Gecko does. Note that we
    234291        // are assuming a 96dpi screen, which is the default value we use on Windows.
     
    238295    }
    239296
    240     fontDescription.firstFamily().setFamily(defaultGUIFont());
    241297    fontDescription.setSpecifiedSize(fontSize);
    242298    fontDescription.setIsAbsoluteSize(true);
    243     fontDescription.setGenericFamily(FontDescription::NoFamily);
     299    fontDescription.setGenericFamily(FontDescription::SansSerifFamily);
    244300    fontDescription.setWeight(FontWeightNormal);
    245301    fontDescription.setItalic(false);
     
    279335    GraphicsContext* context = info.context;
    280336
    281     context->save();
    282     context->setStrokeStyle(SolidStroke);
    283     context->setStrokeThickness(lineWidth);
    284     if (!isEnabled(object))
    285         context->setStrokeColor(disabledOutline, ColorSpaceDeviceRGB);
    286     else if (isPressed(object))
    287         info.context->setStrokeGradient(createLinearGradient(depressedTopOutline, depressedBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    288     else if (isHovered(object) || isFocused(object))
    289         context->setStrokeGradient(createLinearGradient(hoverTopOutline, hoverBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    290     else
    291         context->setStrokeGradient(createLinearGradient(regularTopOutline, regularBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    292 
    293     Path textFieldRoundedRectangle = roundedRectForBorder(object, rect);
    294     if (object->style()->appearance() == SearchFieldPart) {
    295         // We force the fill color to White so as to match the background color of the search cancel button graphic.
    296         context->setFillColor(Color::white, ColorSpaceDeviceRGB);
    297         context->fillPath(textFieldRoundedRectangle);
    298         context->strokePath(textFieldRoundedRectangle);
    299     } else
    300         context->strokePath(textFieldRoundedRectangle);
    301     context->restore();
     337    static RefPtr<Image> bg, bgDisabled, bgHighlight;
     338    if (!bg) {
     339        bg = loadImage("core_textinput_bg");
     340        bgDisabled = loadImage("core_textinput_bg_disabled");
     341        bgHighlight = loadImage("core_textinput_bg_highlight");
     342    }
     343
     344    AffineTransform ctm = context->getCTM();
     345    if (isEnabled(object) && bg)
     346        drawNineSlice(context, rect, ctm.xScale(), bg.get(), smallSlice);
     347    if (!isEnabled(object) && bgDisabled)
     348        drawNineSlice(context, rect, ctm.xScale(), bgDisabled.get(), smallSlice);
     349
     350    if ((isHovered(object) || isFocused(object) || isPressed(object)) && bgHighlight)
     351        drawNineSlice(context, rect, ctm.xScale(), bgHighlight.get(), smallSlice);
     352
    302353    return false;
    303354}
     
    410461bool RenderThemeBlackBerry::paintCheckbox(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    411462{
    412     return paintButton(object, info, rect);
     463    ASSERT(info.context);
     464    GraphicsContext* context = info.context;
     465
     466    static RefPtr<Image> disabled, background, inactive, pressed, active, activeMark, disableMark;
     467    if (!disabled) {
     468        disabled = loadImage("core_checkbox_disabled");
     469        background = loadImage("core_checkbox_moat");
     470        inactive = loadImage("core_checkbox_inactive");
     471        pressed = loadImage("core_checkbox_pressed");
     472        active = loadImage("core_checkbox_active");
     473        activeMark = loadImage("core_checkbox_active_mark");
     474        disableMark = loadImage("core_checkbox_disabled_mark");
     475    }
     476
     477    // Caculate where to put center checkmark.
     478    FloatRect tmpRect(rect);
     479
     480    float centerX = ((float(inactive->width()) - float(activeMark->width())) / float(inactive->width()) * tmpRect.width() / 2) + tmpRect.x();
     481    float centerY = ((float(inactive->height()) - float(activeMark->height())) / float(inactive->height()) * tmpRect.height() / 2) + tmpRect.y();
     482    float width = float(activeMark->width()) / float(inactive->width()) * tmpRect.width();
     483    float height = float(activeMark->height()) / float(inactive->height()) * tmpRect.height();
     484    FloatRect centerRect(centerX, centerY, width, height);
     485
     486    drawControl(context, rect, background.get());
     487
     488    if (isEnabled(object)) {
     489        if (isPressed(object)) {
     490            drawControl(context, rect, pressed.get());
     491            if (isChecked(object)) {
     492                // FIXME: need opacity 30% on activeMark
     493                drawControl(context, centerRect, activeMark.get());
     494            }
     495        } else {
     496            drawControl(context, rect, inactive.get());
     497            if (isChecked(object)) {
     498                drawControl(context, rect, active.get());
     499                drawControl(context, centerRect, activeMark.get());
     500            }
     501        }
     502    } else {
     503        drawControl(context, rect, disabled.get());
     504        if (isChecked(object))
     505            drawControl(context, rect, disableMark.get());
     506    }
     507    return false;
    413508}
    414509
     
    420515bool RenderThemeBlackBerry::paintRadio(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    421516{
    422     return paintButton(object, info, rect);
     517    ASSERT(info.context);
     518    GraphicsContext* context = info.context;
     519
     520    static RefPtr<Image> disabled, disabledActive, inactive, pressed, active, activeMark;
     521    if (!disabled) {
     522        disabled = loadImage("core_radiobutton_disabled");
     523        disabledActive = loadImage("core_radiobutton_disabled_active");
     524        inactive = loadImage("core_radiobutton_inactive");
     525        pressed = loadImage("core_radiobutton_pressed");
     526        active = loadImage("core_radiobutton_active");
     527        activeMark = loadImage("core_radiobutton_active_mark");
     528    }
     529
     530    // Caculate where to put center circle.
     531    FloatRect tmpRect(rect);
     532
     533    float centerX = ((float(inactive->width()) - float(activeMark->width())) / float(inactive->width()) * tmpRect.width() / 2)+ tmpRect.x();
     534    float centerY = ((float(inactive->height()) - float(activeMark->height())) / float(inactive->height()) * tmpRect.height() / 2) + tmpRect.y();
     535    float width = float(activeMark->width()) / float(inactive->width()) * tmpRect.width();
     536    float height = float(activeMark->height()) / float(inactive->height()) * tmpRect.height();
     537    FloatRect centerRect(centerX, centerY, width, height);
     538
     539    if (isEnabled(object)) {
     540        if (isPressed(object)) {
     541            drawControl(context, rect, pressed.get());
     542            if (isChecked(object)) {
     543                // FIXME: need opacity 30% on activeMark
     544                drawControl(context, centerRect, activeMark.get());
     545            }
     546        } else {
     547            drawControl(context, rect, inactive.get());
     548            if (isChecked(object)) {
     549                drawControl(context, rect, active.get());
     550                drawControl(context, centerRect, activeMark.get());
     551            }
     552        }
     553    } else {
     554        drawControl(context, rect, inactive.get());
     555        if (isChecked(object))
     556            drawControl(context, rect, disabledActive.get());
     557        else
     558            drawControl(context, rect, disabled.get());
     559    }
     560    return false;
    423561}
    424562
     
    433571    ASSERT(info.context);
    434572    info.context->save();
    435 
    436     info.context->setStrokeStyle(SolidStroke);
    437     info.context->setStrokeThickness(lineWidth);
    438 
    439     Color check(blackPen);
     573    GraphicsContext* context = info.context;
     574
     575    static RefPtr<Image> disabled, inactive, pressed;
     576    if (!disabled) {
     577        disabled = loadImage("core_button_disabled");
     578        inactive = loadImage("core_button_inactive");
     579        pressed = loadImage("core_button_pressed");
     580    }
     581
     582    AffineTransform ctm = context->getCTM();
    440583    if (!isEnabled(object)) {
    441         info.context->setFillGradient(createLinearGradient(disabledTop, disabledBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    442         info.context->setStrokeColor(disabledOutline, ColorSpaceDeviceRGB);
     584        drawNineSlice(context, rect, ctm.xScale(), inactive.get(), largeSlice);
     585        drawNineSlice(context, rect, ctm.xScale(), disabled.get(), largeSlice);
    443586    } else if (isPressed(object)) {
    444         info.context->setFillGradient(createLinearGradient(depressedTop, depressedBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    445         info.context->setStrokeGradient(createLinearGradient(depressedTopOutline, depressedBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    446     } else if (isHovered(object)) {
    447         info.context->setFillGradient(createLinearGradient(hoverTop, hoverBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    448         info.context->setStrokeGradient(createLinearGradient(hoverTopOutline, hoverBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    449     } else {
    450         info.context->setFillGradient(createLinearGradient(regularTop, regularBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    451         info.context->setStrokeGradient(createLinearGradient(regularTopOutline, regularBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    452     }
    453 
    454     ControlPart part = object->style()->appearance();
    455     switch (part) {
    456     case CheckboxPart: {
    457         FloatSize smallCorner(smallRadius, smallRadius);
    458         Path path;
    459         path.addRoundedRect(rect, smallCorner);
    460         info.context->fillPath(path);
    461         info.context->strokePath(path);
    462 
    463         if (isChecked(object)) {
    464             Path checkPath;
    465             IntRect rect2 = rect;
    466             rect2.inflate(-1);
    467             checkPath.moveTo(FloatPoint(rect2.x() + rect2.width() * checkboxLeftX, rect2.y() + rect2.height() * checkboxLeftY));
    468             checkPath.addLineTo(FloatPoint(rect2.x() + rect2.width() * checkboxMiddleX, rect2.maxY() - rect2.height() * checkboxMiddleY));
    469             checkPath.addLineTo(FloatPoint(rect2.x() + rect2.width() * checkboxRightX, rect2.y() + rect2.height() * checkboxRightY));
    470             info.context->setLineCap(RoundCap);
    471             info.context->setStrokeColor(blackPen, ColorSpaceDeviceRGB);
    472             info.context->setStrokeThickness(rect2.width() / checkboxStrokeThickness);
    473             info.context->fillPath(checkPath);
    474             info.context->strokePath(checkPath);
    475         }
    476         break;
    477     }
    478     case RadioPart:
    479         info.context->drawEllipse(rect);
    480         if (isChecked(object)) {
    481             IntRect rect2 = rect;
    482             rect2.inflate(-rect.width() * radioButtonCheckStateScaler);
    483             info.context->setFillColor(check, ColorSpaceDeviceRGB);
    484             info.context->setStrokeColor(check, ColorSpaceDeviceRGB);
    485             info.context->drawEllipse(rect2);
    486         }
    487         break;
    488     case ButtonPart:
    489     case PushButtonPart: {
    490         FloatSize largeCorner(largeRadius, largeRadius);
    491         Path path;
    492         path.addRoundedRect(rect, largeCorner);
    493         info.context->fillPath(path);
    494         info.context->strokePath(path);
    495         break;
    496     }
    497     case SquareButtonPart: {
    498         Path path;
    499         path.addRect(rect);
    500         info.context->fillPath(path);
    501         info.context->strokePath(path);
    502         break;
    503     }
    504     default:
    505         info.context->restore();
    506         return true;
    507     }
    508 
    509     info.context->restore();
     587        drawNineSlice(context, rect, ctm.xScale(), pressed.get(), largeSlice);
     588        object->style()->setTextFillColor(activeTextColor);
     589    } else
     590        drawNineSlice(context, rect, ctm.xScale(), inactive.get(), largeSlice);
     591
     592    context->restore();
    510593    return false;
    511594}
     
    536619}
    537620
    538 void RenderThemeBlackBerry::paintMenuListButtonGradientAndArrow(GraphicsContext* context, RenderObject* object, IntRect buttonRect, const Path& clipPath)
    539 {
    540     ASSERT(context);
    541     context->save();
    542     if (!isEnabled(object))
    543         context->setFillGradient(createLinearGradient(disabledTop, disabledBottom, buttonRect.maxXMinYCorner(), buttonRect.maxXMaxYCorner()));
    544     else if (isPressed(object))
    545         context->setFillGradient(createLinearGradient(depressedTop, depressedBottom, buttonRect.maxXMinYCorner(), buttonRect.maxXMaxYCorner()));
    546     else if (isHovered(object))
    547         context->setFillGradient(createLinearGradient(hoverTop, hoverBottom, buttonRect.maxXMinYCorner(), buttonRect.maxXMaxYCorner()));
    548     else
    549         context->setFillGradient(createLinearGradient(regularTop, regularBottom, buttonRect.maxXMinYCorner(), buttonRect.maxXMaxYCorner()));
    550 
    551     // 1. Paint the background of the button.
    552     context->clip(clipPath);
    553     context->drawRect(buttonRect);
    554     context->restore();
    555 
    556     // 2. Paint the button arrow.
    557     buttonRect.inflate(-buttonRect.width() / 3);
    558     buttonRect.move(0, buttonRect.height() * 7 / 20);
    559     Path path;
    560     path.moveTo(FloatPoint(buttonRect.x(), buttonRect.y()));
    561     path.addLineTo(FloatPoint(buttonRect.x() + buttonRect.width(), buttonRect.y()));
    562     path.addLineTo(FloatPoint(buttonRect.x() + buttonRect.width() / 2.0, buttonRect.y() + buttonRect.height() / 2.0));
    563     path.closeSubpath();
    564 
    565     context->save();
    566     context->setStrokeStyle(SolidStroke);
    567     context->setStrokeThickness(lineWidth);
    568     context->setStrokeColor(Color::black, ColorSpaceDeviceRGB);
    569     context->setFillColor(Color::black, ColorSpaceDeviceRGB);
    570     context->setLineJoin(BevelJoin);
    571     context->fillPath(path);
    572     context->restore();
    573 }
    574 
    575621static IntRect computeMenuListArrowButtonRect(const IntRect& rect)
    576622{
     
    580626}
    581627
    582 static void paintMenuListBackground(GraphicsContext* context, const Path& menuListPath, const Color& backgroundColor)
    583 {
    584     ASSERT(context);
    585     context->save();
    586     context->setFillColor(backgroundColor, ColorSpaceDeviceRGB);
    587     context->fillPath(menuListPath);
     628bool RenderThemeBlackBerry::paintMenuList(RenderObject* object, const PaintInfo& info, const IntRect& rect)
     629{
     630    ASSERT(info.context);
     631    info.context->save();
     632    GraphicsContext* context = info.context;
     633
     634    static RefPtr<Image> disabled, inactive, pressed, arrowUp, arrowUpPressed;
     635    if (!disabled) {
     636        disabled = loadImage("core_button_disabled");
     637        inactive = loadImage("core_button_inactive");
     638        pressed = loadImage("core_button_pressed");
     639        arrowUp = loadImage("core_dropdown_button_arrowup");
     640        arrowUpPressed = loadImage("core_dropdown_button_arrowup_pressed");
     641    }
     642
     643    FloatRect arrowButtonRectangle(computeMenuListArrowButtonRect(rect));
     644    float x = arrowButtonRectangle.x() + arrowButtonRectangle.width() / xPositionRatio;
     645    float y = arrowButtonRectangle.y() + arrowButtonRectangle.height() * yPositionRatio;
     646    float width = arrowButtonRectangle.width() / widthRatio;
     647    float height = arrowButtonRectangle.height() * heightRatio;
     648    FloatRect tmpRect(x, y, width, height);
     649
     650    AffineTransform ctm = context->getCTM();
     651    if (!isEnabled(object)) {
     652        drawNineSlice(context, rect, ctm.xScale(), inactive.get(), largeSlice);
     653        drawNineSlice(context, rect, ctm.xScale(), disabled.get(), largeSlice);
     654        drawControl(context, tmpRect, arrowUp.get()); // FIXME: should have a disabled image.
     655    } else if (isFocused(object)) {
     656        drawNineSlice(context, rect, ctm.xScale(), pressed.get(), largeSlice);
     657        drawControl(context, tmpRect, arrowUpPressed.get());
     658        object->style()->setTextFillColor(activeTextColor);
     659    } else {
     660        drawNineSlice(context, rect, ctm.xScale(), inactive.get(), largeSlice);
     661        drawControl(context, tmpRect, arrowUp.get());
     662    }
    588663    context->restore();
    589 }
    590 
    591 bool RenderThemeBlackBerry::paintMenuList(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    592 {
    593     // Note, this method is not called if the menu list explicitly specifies either a border or background color.
    594     // Instead, RenderThemeBlackBerry::paintMenuListButton is called. Therefore, when this method is called, we don't
    595     // have to adjust rect with respect to the border dimensions.
    596 
    597     ASSERT(info.context);
    598     GraphicsContext* context = info.context;
    599 
    600     Path menuListRoundedRectangle = roundedRectForBorder(object, rect);
    601 
    602     // 1. Paint the background of the entire control.
    603     paintMenuListBackground(context, menuListRoundedRectangle, Color::white);
    604 
    605     // 2. Paint the background of the button and its arrow.
    606     IntRect arrowButtonRectangle = computeMenuListArrowButtonRect(rect);
    607     paintMenuListButtonGradientAndArrow(context, object, arrowButtonRectangle, menuListRoundedRectangle);
    608 
    609     // 4. Stroke an outline around the entire control.
    610     context->save();
    611     context->setStrokeStyle(SolidStroke);
    612     context->setStrokeThickness(lineWidth);
    613     if (!isEnabled(object))
    614         context->setStrokeColor(disabledOutline, ColorSpaceDeviceRGB);
    615     else if (isPressed(object))
    616         context->setStrokeGradient(createLinearGradient(depressedTopOutline, depressedBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    617     else if (isHovered(object))
    618         context->setStrokeGradient(createLinearGradient(hoverTopOutline, hoverBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    619     else
    620         context->setStrokeGradient(createLinearGradient(regularTopOutline, regularBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    621 
    622     context->strokePath(menuListRoundedRectangle);
    623     context->restore();
    624664    return false;
    625665}
     
    627667bool RenderThemeBlackBerry::paintMenuListButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    628668{
    629     // Note, this method is only called if the menu list explicitly specifies either a border or background color.
    630     // Otherwise, RenderThemeBlackBerry::paintMenuList is called. We need to fit the arrow button with the border box
    631     // of the menu-list so as to not occlude the custom border.
    632 
    633     // We compute menuListRoundedRectangle with respect to the dimensions of the entire menu-list control (i.e. rect) and
    634     // its border radius so that we clip the contour of the arrow button (when we paint it below) to match the contour of
    635     // the control.
    636     Path menuListRoundedRectangle = roundedRectForBorder(object, rect);
    637 
    638     // 1. Paint the background of the entire control.
    639     Color fillColor = object->style()->visitedDependentColor(CSSPropertyBackgroundColor);
    640     if (!fillColor.isValid())
    641         fillColor = Color::white;
    642     paintMenuListBackground(info.context, menuListRoundedRectangle, fillColor);
    643 
    644     // 2. Paint the background of the button and its arrow.
    645     IntRect bounds = IntRect(rect.x() + object->style()->borderLeftWidth(),
    646                          rect.y() + object->style()->borderTopWidth(),
    647                          rect.width() - object->style()->borderLeftWidth() - object->style()->borderRightWidth(),
    648                          rect.height() - object->style()->borderTopWidth() - object->style()->borderBottomWidth());
    649 
    650     IntRect arrowButtonRectangle = computeMenuListArrowButtonRect(bounds); // Fit the arrow button within the border box of the menu-list.
    651     paintMenuListButtonGradientAndArrow(info.context, object, arrowButtonRectangle, menuListRoundedRectangle);
    652     return false;
     669    return paintMenuList(object, info, rect);
    653670}
    654671
     
    700717        RGBA32 strokeColorStart, RGBA32 strokeColorEnd, RGBA32 fillColorStart, RGBA32 fillColorEnd)
    701718{
    702     FloatSize smallCorner(smallRadius, smallRadius);
    703 
     719    ASSERT(info.context);
    704720    info.context->save();
    705     info.context->setStrokeStyle(SolidStroke);
    706     info.context->setStrokeThickness(lineWidth);
    707 
    708     info.context->setStrokeGradient(createLinearGradient(strokeColorStart, strokeColorEnd, rect.maxXMinYCorner(), rect. maxXMaxYCorner()));
    709     info.context->setFillGradient(createLinearGradient(fillColorStart, fillColorEnd, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    710 
    711     Path path;
    712     path.addRoundedRect(rect, smallCorner);
    713     info.context->fillPath(path);
    714 
    715     info.context->restore();
     721    GraphicsContext* context = info.context;
     722
     723    static RefPtr<Image> disabled, inactive;
     724    if (!disabled) {
     725        disabled = loadImage("core_slider_fill_disabled");
     726        inactive = loadImage("core_slider_bg");
     727    }
     728
     729    if (isEnabled(object))
     730        drawThreeSlice(context, rect, inactive.get(), mediumSlice);
     731    else
     732        drawThreeSlice(context, rect, disabled.get(), (smallSlice - 1));
     733
     734    context->restore();
    716735    return false;
    717736}
     
    719738bool RenderThemeBlackBerry::paintSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    720739{
    721     FloatSize largeCorner(largeRadius, largeRadius);
    722 
     740    ASSERT(info.context);
    723741    info.context->save();
    724     info.context->setStrokeStyle(SolidStroke);
    725     info.context->setStrokeThickness(lineWidth);
    726 
    727     if (isPressed(object) || isHovered(object)) {
    728         info.context->setStrokeGradient(createLinearGradient(hoverTopOutline, hoverBottomOutline, rect.maxXMinYCorner(), rect. maxXMaxYCorner()));
    729         info.context->setFillGradient(createLinearGradient(hoverTop, hoverBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
     742    GraphicsContext* context = info.context;
     743
     744    static RefPtr<Image> disabled, inactive, pressed, aura;
     745    if (!disabled) {
     746        disabled = loadImage("core_slider_handle_disabled");
     747        inactive = loadImage("core_slider_handle");
     748        pressed = loadImage("core_slider_handle_pressed");
     749        aura = loadImage("core_slider_aura");
     750    }
     751
     752    FloatRect tmpRect(rect);
     753    float length = std::max(tmpRect.width(), tmpRect.height());
     754    if (tmpRect.width() > tmpRect.height()) {
     755        tmpRect.setY(tmpRect.y() - (length - tmpRect.height()) / 2);
     756        tmpRect.setHeight(length);
    730757    } else {
    731         info.context->setStrokeGradient(createLinearGradient(regularTopOutline, regularBottomOutline, rect.maxXMinYCorner(), rect. maxXMaxYCorner()));
    732         info.context->setFillGradient(createLinearGradient(regularTop, regularBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
    733     }
    734 
    735     Path path;
    736     path.addRoundedRect(rect, largeCorner);
    737     info.context->fillPath(path);
    738 
    739     bool isVertical = rect.width() > rect.height();
    740     IntPoint startPoint(rect.x() + (isVertical ? 5 : 2), rect.y() + (isVertical ? 2 : 5));
    741     IntPoint endPoint(rect.x() + (isVertical ? 20 : 2), rect.y() + (isVertical ? 2 : 20));
    742     const int lineOffset = 2;
    743     const int shadowOffset = 1;
    744 
    745     for (int i = 0; i < 3; i++) {
    746         if (isVertical) {
    747             startPoint.setY(startPoint.y() + lineOffset);
    748             endPoint.setY(endPoint.y() + lineOffset);
     758        tmpRect.setX(tmpRect.x() - (length - tmpRect.width()) / 2);
     759        tmpRect.setWidth(length);
     760    }
     761
     762    float auraHeight = length * auraRatio;
     763    float auraWidth = auraHeight;
     764    float auraX = tmpRect.x() - (auraWidth - tmpRect.width()) / 2;
     765    float auraY = tmpRect.y() - (auraHeight - tmpRect.height()) / 2;
     766    FloatRect auraRect(auraX, auraY, auraWidth, auraHeight);
     767
     768    if (!isEnabled(object))
     769        drawControl(context, tmpRect, disabled.get());
     770    else {
     771        if (isPressed(object) || isHovered(object) || isFocused(object)) {
     772            drawControl(context, tmpRect, pressed.get());
     773            drawControl(context, auraRect, aura.get());
    749774        } else {
    750             startPoint.setX(startPoint.x() + lineOffset);
    751             endPoint.setX(endPoint.x() + lineOffset);
     775            drawControl(context, tmpRect, inactive.get());
    752776        }
    753         if (isPressed(object) || isHovered(object))
    754             info.context->setStrokeColor(dragRollLight, ColorSpaceDeviceRGB);
    755         else
    756             info.context->setStrokeColor(dragRegularLight, ColorSpaceDeviceRGB);
    757         info.context->drawLine(startPoint, endPoint);
    758 
    759         if (isVertical) {
    760             startPoint.setY(startPoint.y() + shadowOffset);
    761             endPoint.setY(endPoint.y() + shadowOffset);
    762         } else {
    763             startPoint.setX(startPoint.x() + shadowOffset);
    764             endPoint.setX(endPoint.x() + shadowOffset);
    765         }
    766         if (isPressed(object) || isHovered(object))
    767             info.context->setStrokeColor(dragRollDark, ColorSpaceDeviceRGB);
    768         else
    769             info.context->setStrokeColor(dragRegularDark, ColorSpaceDeviceRGB);
    770         info.context->drawLine(startPoint, endPoint);
    771     }
    772     info.context->restore();
     777    }
     778
     779    context->restore();
    773780    return false;
    774781}
  • trunk/Source/WebCore/platform/blackberry/RenderThemeBlackBerry.h

    r119547 r132967  
    106106    void setButtonStyle(RenderStyle*) const;
    107107
    108     void paintMenuListButtonGradientAndArrow(GraphicsContext*, RenderObject*, IntRect buttonRect, const Path& clipPath);
    109108    bool paintTextFieldOrTextAreaOrSearchField(RenderObject*, const PaintInfo&, const IntRect&);
    110109    bool paintSliderTrackRect(RenderObject*, const PaintInfo&, const IntRect&);
Note: See TracChangeset for help on using the changeset viewer.