Changeset 37790 in webkit


Ignore:
Timestamp:
Oct 22, 2008 2:51:23 PM (15 years ago)
Author:
hyatt@apple.com
Message:

2008-10-22 David Hyatt <hyatt@apple.com>

https://bugs.webkit.org/show_bug.cgi?id=21775

Convert buttons over to use the new Theme API on OS X.

Reviewed by Adam Roben

  • platform/LengthBox.h: (WebCore::LengthBox::LengthBox):
  • platform/Theme.cpp: (WebCore::Theme::controlBorder): (WebCore::Theme::controlPadding):
  • platform/Theme.h: (WebCore::Theme::controlFont): (WebCore::Theme::controlSize): (WebCore::Theme::minControlSize): (WebCore::Theme::controlRequiresPreWhiteSpace):
  • platform/mac/ThemeMac.h: (WebCore::ThemeMac::controlRequiresPreWhiteSpace):
  • platform/mac/ThemeMac.mm: (WebCore::checkboxSize): (WebCore::radioSize): (WebCore::buttonSizes): (WebCore::buttonMargins): (WebCore::button): (WebCore::paintButton): (WebCore::ThemeMac::controlFont): (WebCore::ThemeMac::controlSize): (WebCore::ThemeMac::minControlSize): (WebCore::ThemeMac::controlBorder): (WebCore::ThemeMac::controlPadding): (WebCore::ThemeMac::inflateControlPaintRect): (WebCore::ThemeMac::paint):
  • rendering/RenderTheme.cpp: (WebCore::RenderTheme::adjustStyle): (WebCore::RenderTheme::paint): (WebCore::RenderTheme::controlStatesForRenderer): (WebCore::RenderTheme::isDefault): (WebCore::RenderTheme::adjustRadioStyle):
  • rendering/RenderTheme.h: (WebCore::RenderTheme::setRadioSize):
  • rendering/RenderThemeMac.h:
  • rendering/RenderThemeMac.mm: (WebCore::RenderThemeMac::adjustRepaintRect): (WebCore::menuListButtonSizes): (WebCore::RenderThemeMac::adjustMenuListStyle):
  • rendering/style/RenderStyle.h: (WebCore::InheritedFlags::paddingBox): (WebCore::InheritedFlags::setPaddingBox):
Location:
trunk/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r37786 r37790  
     12008-10-22  David Hyatt  <hyatt@apple.com>
     2
     3        https://bugs.webkit.org/show_bug.cgi?id=21775
     4
     5        Convert buttons over to use the new Theme API on OS X.
     6
     7        Reviewed by Adam Roben
     8
     9        * platform/LengthBox.h:
     10        (WebCore::LengthBox::LengthBox):
     11        * platform/Theme.cpp:
     12        (WebCore::Theme::controlBorder):
     13        (WebCore::Theme::controlPadding):
     14        * platform/Theme.h:
     15        (WebCore::Theme::controlFont):
     16        (WebCore::Theme::controlSize):
     17        (WebCore::Theme::minControlSize):
     18        (WebCore::Theme::controlRequiresPreWhiteSpace):
     19        * platform/mac/ThemeMac.h:
     20        (WebCore::ThemeMac::controlRequiresPreWhiteSpace):
     21        * platform/mac/ThemeMac.mm:
     22        (WebCore::checkboxSize):
     23        (WebCore::radioSize):
     24        (WebCore::buttonSizes):
     25        (WebCore::buttonMargins):
     26        (WebCore::button):
     27        (WebCore::paintButton):
     28        (WebCore::ThemeMac::controlFont):
     29        (WebCore::ThemeMac::controlSize):
     30        (WebCore::ThemeMac::minControlSize):
     31        (WebCore::ThemeMac::controlBorder):
     32        (WebCore::ThemeMac::controlPadding):
     33        (WebCore::ThemeMac::inflateControlPaintRect):
     34        (WebCore::ThemeMac::paint):
     35        * rendering/RenderTheme.cpp:
     36        (WebCore::RenderTheme::adjustStyle):
     37        (WebCore::RenderTheme::paint):
     38        (WebCore::RenderTheme::controlStatesForRenderer):
     39        (WebCore::RenderTheme::isDefault):
     40        (WebCore::RenderTheme::adjustRadioStyle):
     41        * rendering/RenderTheme.h:
     42        (WebCore::RenderTheme::setRadioSize):
     43        * rendering/RenderThemeMac.h:
     44        * rendering/RenderThemeMac.mm:
     45        (WebCore::RenderThemeMac::adjustRepaintRect):
     46        (WebCore::menuListButtonSizes):
     47        (WebCore::RenderThemeMac::adjustMenuListStyle):
     48        * rendering/style/RenderStyle.h:
     49        (WebCore::InheritedFlags::paddingBox):
     50        (WebCore::InheritedFlags::setPaddingBox):
     51
    1522008-10-22  Chris Marrin  <cmarrin@apple.com>
    253
  • trunk/WebCore/platform/LengthBox.h

    r37746 r37790  
    3939    }
    4040
     41    LengthBox(int v)
     42        : m_left(Length(v, Fixed))
     43        , m_right(Length(v, Fixed))
     44        , m_top(Length(v, Fixed))
     45        , m_bottom(Length(v, Fixed))
     46    {
     47    }
     48   
     49    LengthBox(int t, int r, int b, int l)
     50        : m_left(Length(l, Fixed))
     51        , m_right(Length(r, Fixed))
     52        , m_top(Length(t, Fixed))
     53        , m_bottom(Length(b, Fixed))
     54    {
     55    }
     56
    4157    Length left() const { return m_left; }
    4258    Length right() const { return m_right; }
  • trunk/WebCore/platform/Theme.cpp

    r37743 r37790  
    2929namespace WebCore {
    3030
    31 bool Theme::controlSupportsBorder(ControlPart part) const
     31LengthBox Theme::controlBorder(ControlPart part, const Font&, const LengthBox& zoomedBox, float zoomFactor) const
    3232{
    3333    switch (part) {
     
    3737        case CheckboxPart:
    3838        case RadioPart:
    39             return false;
     39            return LengthBox(0);
    4040        default:
    41             return true;
     41            return zoomedBox;
    4242    }
    4343}
    4444
    45 bool Theme::controlSupportsPadding(ControlPart part) const
     45LengthBox Theme::controlPadding(ControlPart part, const Font&, const LengthBox& zoomedBox, float zoomFactor) const
    4646{
    4747    switch (part) {
     
    5050        case CheckboxPart:
    5151        case RadioPart:
    52             return false;
     52            return LengthBox(0);
    5353        default:
    54             return true;
     54            return zoomedBox;
    5555    }
    5656}
  • trunk/WebCore/platform/Theme.h

    r37746 r37790  
    3030#include "Font.h"
    3131#include "IntRect.h"
     32#include "LengthBox.h"
    3233#include "LengthSize.h"
    3334#include "PlatformString.h"
     
    8081    // Methods used to adjust the RenderStyles of controls.
    8182   
     83    // The font description result should have a zoomed font size.
     84    virtual FontDescription controlFont(ControlPart, const Font& font, float zoomFactor) const { return font.fontDescription(); }
     85   
    8286    // The size here is in zoomed coordinates already.  If a new size is returned, it also needs to be in zoomed coordinates.
    8387    virtual LengthSize controlSize(ControlPart, const Font&, const LengthSize& zoomedSize, float zoomFactor) const { return zoomedSize; }
    84     virtual bool controlSupportsBorder(ControlPart) const;
    85     virtual bool controlSupportsPadding(ControlPart) const;
    8688   
     89    // Returns the minimum size for a control in zoomed coordinates. 
     90    virtual LengthSize minimumControlSize(ControlPart, const Font&, float zoomFactor) const { return LengthSize(Length(0, Fixed), Length(0, Fixed)); }
     91   
     92    // Allows the theme to modify the existing padding/border.
     93    virtual LengthBox controlPadding(ControlPart, const Font&, const LengthBox& zoomedBox, float zoomFactor) const;
     94    virtual LengthBox controlBorder(ControlPart, const Font&, const LengthBox& zoomedBox, float zoomFactor) const;
     95   
     96    // Whether or not whitespace: pre should be forced on always.
     97    virtual bool controlRequiresPreWhiteSpace(ControlPart) const { return false; }
     98
    8799    // Method for painting a control.  The rect is in zoomed coordinates.
    88100    virtual void paint(ControlPart, ControlStates, GraphicsContext*, const IntRect& zoomedRect, float zoomFactor, ScrollView*) const { };
  • trunk/WebCore/platform/mac/ThemeMac.h

    r37743 r37790  
    3838    virtual int baselinePositionAdjustment(ControlPart) const;
    3939
     40    virtual FontDescription controlFont(ControlPart, const Font&, float zoomFactor) const;
     41   
    4042    virtual LengthSize controlSize(ControlPart, const Font&, const LengthSize&, float zoomFactor) const;
    41    
     43    virtual LengthSize minimumControlSize(ControlPart, const Font&, float zoomFactor) const;
     44
     45    virtual LengthBox controlPadding(ControlPart, const Font&, const LengthBox& zoomedBox, float zoomFactor) const;
     46    virtual LengthBox controlBorder(ControlPart, const Font&, const LengthBox& zoomedBox, float zoomFactor) const;
     47
     48    virtual bool controlRequiresPreWhiteSpace(ControlPart part) const { return part == PushButtonPart; }
     49
    4250    virtual void paint(ControlPart, ControlStates, GraphicsContext*, const IntRect&, float zoomFactor, ScrollView*) const;
    4351    virtual void inflateControlPaintRect(ControlPart, ControlStates, IntRect&, float zoomFactor) const;
  • trunk/WebCore/platform/mac/ThemeMac.mm

    r37743 r37790  
    2828
    2929#import "GraphicsContext.h"
     30#import "LocalCurrentGraphicsContext.h"
    3031#import "ScrollView.h"
     32#import "WebCoreSystemInterface.h"
    3133
    3234using namespace std;
     35
     36// FIXME: Default buttons really should be more like push buttons and not like buttons.
    3337
    3438namespace WebCore {
     
    158162}
    159163
    160 static LengthSize checkboxSize(ControlPart part, const Font& font, const LengthSize& zoomedSize, float zoomFactor)
     164static LengthSize checkboxSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor)
    161165{
    162166    // If the width and height are both specified, then we have nothing to do.
     
    235239}
    236240
    237 static LengthSize radioSize(ControlPart part, const Font& font, const LengthSize& zoomedSize, float zoomFactor)
     241static LengthSize radioSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor)
    238242{
    239243    // If the width and height are both specified, then we have nothing to do.
     
    291295}
    292296
     297// Buttons
     298
     299// Buttons really only constrain height. They respect width.
     300static const IntSize* buttonSizes()
     301{
     302    static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
     303    return sizes;
     304}
     305
     306static const int* buttonMargins(NSControlSize controlSize)
     307{
     308    static const int margins[3][4] =
     309    {
     310        { 4, 6, 7, 6 },
     311        { 4, 5, 6, 5 },
     312        { 0, 1, 1, 1 },
     313    };
     314    return margins[controlSize];
     315}
     316
     317static NSButtonCell* button(ControlPart part, ControlStates states, const IntRect& zoomedRect, float zoomFactor)
     318{
     319    static NSButtonCell *buttonCell;
     320    static bool defaultButton;
     321    if (!buttonCell) {
     322        buttonCell = [[NSButtonCell alloc] init];
     323        [buttonCell setTitle:nil];
     324        [buttonCell setButtonType:NSMomentaryPushInButton];
     325    }
     326
     327    // Set the control size based off the rectangle we're painting into.
     328    if (part == SquareButtonPart || zoomedRect.height() > buttonSizes()[NSRegularControlSize].height() * zoomFactor) {
     329        // Use the square button
     330        if ([buttonCell bezelStyle] != NSShadowlessSquareBezelStyle)
     331            [buttonCell setBezelStyle:NSShadowlessSquareBezelStyle];
     332    } else if ([buttonCell bezelStyle] != NSRoundedBezelStyle)
     333        [buttonCell setBezelStyle:NSRoundedBezelStyle];
     334
     335    setControlSize(buttonCell, buttonSizes(), zoomedRect.size(), zoomFactor);
     336
     337    if (defaultButton != (states & DefaultState)) {
     338        defaultButton = !defaultButton;
     339        [buttonCell setKeyEquivalent:(defaultButton ? @"\r" : @"")];
     340    }
     341
     342    // Update the various states we respond to.
     343    updateStates(buttonCell, states);
     344   
     345    return buttonCell;
     346}
     347
     348static void paintButton(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView)
     349{
     350    // Determine the width and height needed for the control and prepare the cell for painting.
     351    NSButtonCell *buttonCell = button(part, states, zoomedRect, zoomFactor);
     352    LocalCurrentGraphicsContext localContext(context);
     353
     354    NSControlSize controlSize = [buttonCell controlSize];
     355    IntSize zoomedSize = buttonSizes()[controlSize];
     356    zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored.
     357    zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
     358    IntRect inflatedRect = zoomedRect;
     359    if ([buttonCell bezelStyle] == NSRoundedBezelStyle) {
     360        // Center the button within the available space.
     361        if (inflatedRect.height() > zoomedSize.height()) {
     362            inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - zoomedSize.height()) / 2);
     363            inflatedRect.setHeight(zoomedSize.height());
     364        }
     365
     366        // Now inflate it to account for the shadow.
     367        inflatedRect = inflateRect(inflatedRect, zoomedSize, buttonMargins(controlSize), zoomFactor);
     368
     369        if (zoomFactor != 1.0f) {
     370            inflatedRect.setWidth(inflatedRect.width() / zoomFactor);
     371            inflatedRect.setHeight(inflatedRect.height() / zoomFactor);
     372            context->translate(inflatedRect.x(), inflatedRect.y());
     373            context->scale(FloatSize(zoomFactor, zoomFactor));
     374            context->translate(-inflatedRect.x(), -inflatedRect.y());
     375        }
     376    }
     377
     378    NSView *view = scrollView->documentView();
     379    NSWindow *window = [view window];
     380    NSButtonCell *previousDefaultButtonCell = [window defaultButtonCell];
     381
     382    if ((states & DefaultState) && [window isKeyWindow]) {
     383        [window setDefaultButtonCell:buttonCell];
     384        wkAdvanceDefaultButtonPulseAnimation(buttonCell);
     385    } else if ([previousDefaultButtonCell isEqual:buttonCell])
     386        [window setDefaultButtonCell:nil];
     387
     388    [buttonCell drawWithFrame:NSRect(inflatedRect) inView:view];
     389    [buttonCell setControlView:nil];
     390
     391    if (![previousDefaultButtonCell isEqual:buttonCell])
     392        [window setDefaultButtonCell:previousDefaultButtonCell];
     393}
     394
    293395// Theme overrides
    294396
     
    300402}
    301403
     404FontDescription ThemeMac::controlFont(ControlPart part, const Font& font, float zoomFactor) const
     405{
     406    switch (part) {
     407        case PushButtonPart: {
     408            FontDescription fontDescription;
     409            fontDescription.setIsAbsoluteSize(true);
     410            fontDescription.setGenericFamily(FontDescription::SerifFamily);
     411
     412            NSFont* nsFont = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:controlSizeForFont(font)]];
     413            fontDescription.firstFamily().setFamily([nsFont familyName]);
     414            fontDescription.setComputedSize([nsFont pointSize] * zoomFactor);
     415            fontDescription.setSpecifiedSize([nsFont pointSize] * zoomFactor);
     416            return fontDescription;
     417        }
     418        default:
     419            return Theme::controlFont(part, font, zoomFactor);
     420    }
     421}
     422
    302423LengthSize ThemeMac::controlSize(ControlPart part, const Font& font, const LengthSize& zoomedSize, float zoomFactor) const
    303424{
    304425    switch (part) {
    305426        case CheckboxPart:
    306             return checkboxSize(part, font, zoomedSize, zoomFactor);
     427            return checkboxSize(font, zoomedSize, zoomFactor);
    307428        case RadioPart:
    308             return radioSize(part, font, zoomedSize, zoomFactor);
     429            return radioSize(font, zoomedSize, zoomFactor);
     430        case PushButtonPart:
     431            // Height is reset to auto so that specified heights can be ignored.
     432            return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, buttonSizes());
    309433        default:
    310434            return zoomedSize;
     435    }
     436}
     437
     438LengthSize ThemeMac::minimumControlSize(ControlPart part, const Font& font, float zoomFactor) const
     439{
     440    switch (part) {
     441        case SquareButtonPart:
     442        case DefaultButtonPart:
     443        case ButtonPart:
     444            return LengthSize(Length(0, Fixed), Length(static_cast<int>(15 * zoomFactor), Fixed));
     445        default:
     446            return Theme::minimumControlSize(part, font, zoomFactor);
     447    }
     448}
     449
     450LengthBox ThemeMac::controlBorder(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const
     451{
     452    switch (part) {
     453        case SquareButtonPart:
     454        case DefaultButtonPart:
     455        case ButtonPart:
     456            return LengthBox(0, zoomedBox.right().value(), 0, zoomedBox.left().value());
     457        default:
     458            return Theme::controlBorder(part, font, zoomedBox, zoomFactor);
     459    }
     460}
     461
     462LengthBox ThemeMac::controlPadding(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const
     463{
     464    switch (part) {
     465        case PushButtonPart: {
     466            // Just use 8px.  AppKit wants to use 11px for mini buttons, but that padding is just too large
     467            // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is
     468            // by definition constrained, since we select mini only for small cramped environments.
     469            // This also guarantees the HTML <button> will match our rendering by default, since we're using a consistent
     470            // padding.
     471            const int padding = 8 * zoomFactor;
     472            return LengthBox(0, padding, 0, padding);
     473        }
     474        default:
     475            return Theme::controlPadding(part, font, zoomedBox, zoomFactor);
    311476    }
    312477}
     
    318483            // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox
    319484            // shadow" and the check.  We don't consider this part of the bounds of the control in WebKit.
    320             NSCell* cell = checkbox(states, zoomedRect, zoomFactor);
     485            NSCell *cell = checkbox(states, zoomedRect, zoomFactor);
    321486            NSControlSize controlSize = [cell controlSize];
    322487            IntSize zoomedSize = checkboxSizes()[controlSize];
     
    329494            // We inflate the rect as needed to account for padding included in the cell to accommodate the radio button
    330495            // shadow".  We don't consider this part of the bounds of the control in WebKit.
    331             NSCell* cell = radio(states, zoomedRect, zoomFactor);
     496            NSCell *cell = radio(states, zoomedRect, zoomFactor);
    332497            NSControlSize controlSize = [cell controlSize];
    333498            IntSize zoomedSize = radioSizes()[controlSize];
     
    337502            break;
    338503        }
     504        case PushButtonPart:
     505        case DefaultButtonPart:
     506        case ButtonPart: {
     507            NSButtonCell *cell = button(part, states, zoomedRect, zoomFactor);
     508            NSControlSize controlSize = [cell controlSize];
     509
     510            // We inflate the rect as needed to account for the Aqua button's shadow.
     511            if ([cell bezelStyle] == NSRoundedBezelStyle) {
     512                IntSize zoomedSize = buttonSizes()[controlSize];
     513                zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
     514                zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored.
     515                zoomedRect = inflateRect(zoomedRect, zoomedSize, buttonMargins(controlSize), zoomFactor);
     516            }
     517            break;
     518        }
    339519        default:
    340520            break;
     
    351531            paintRadio(states, context, zoomedRect, zoomFactor, scrollView);
    352532            break;
    353         default:
    354             break;
    355     }
    356 }
    357 
    358 }
     533        case PushButtonPart:
     534        case DefaultButtonPart:
     535        case ButtonPart:
     536        case SquareButtonPart:
     537            paintButton(part, states, context, zoomedRect, zoomFactor, scrollView);
     538            break;
     539        default:
     540            break;
     541    }
     542}
     543
     544}
  • trunk/WebCore/rendering/RenderTheme.cpp

    r37743 r37790  
    2626#include "Document.h"
    2727#include "FocusController.h"
     28#include "FontSelector.h"
    2829#include "Frame.h"
    2930#include "GraphicsContext.h"
     
    6364
    6465    if (UAHasAppearance && theme()->isControlStyled(style, border, background, backgroundColor)) {
    65         if (part == MenulistPart)
     66        if (part == MenulistPart) {
    6667            style->setAppearance(MenulistButtonPart);
    67         else
     68            part = MenulistButtonPart;
     69        } else
    6870            style->setAppearance(NoControlPart);
    6971    }
     
    7678   
    7779#if USE(NEW_THEME)
    78     if (part == CheckboxPart || part == RadioPart) {
    79         if (!m_theme->controlSupportsBorder(part))
    80             style->resetBorder();
    81         if (!m_theme->controlSupportsPadding(part))
    82             style->resetPadding();
     80    switch (part) {
     81        case CheckboxPart:
     82        case RadioPart:
     83        case PushButtonPart:
     84        case SquareButtonPart:
     85        case DefaultButtonPart:
     86        case ButtonPart: {
     87            // Border
     88            LengthBox borderBox(style->borderTopWidth(), style->borderRightWidth(), style->borderBottomWidth(), style->borderLeftWidth());
     89            borderBox = m_theme->controlBorder(part, style->font(), borderBox, style->effectiveZoom());
     90            if (borderBox.top().value() != style->borderTopWidth()) {
     91                if (borderBox.top().value())
     92                    style->setBorderTopWidth(borderBox.top().value());
     93                else
     94                    style->resetBorderTop();
     95            }
     96            if (borderBox.right().value() != style->borderRightWidth()) {
     97                if (borderBox.right().value())
     98                    style->setBorderRightWidth(borderBox.right().value());
     99                else
     100                    style->resetBorderRight();
     101            }
     102            if (borderBox.bottom().value() != style->borderBottomWidth()) {
     103                style->setBorderBottomWidth(borderBox.bottom().value());
     104                if (borderBox.bottom().value())
     105                    style->setBorderBottomWidth(borderBox.bottom().value());
     106                else
     107                    style->resetBorderBottom();
     108            }
     109            if (borderBox.left().value() != style->borderLeftWidth()) {
     110                style->setBorderLeftWidth(borderBox.left().value());
     111                if (borderBox.left().value())
     112                    style->setBorderLeftWidth(borderBox.left().value());
     113                else
     114                    style->resetBorderLeft();
     115            }
     116
     117            // Padding
     118            LengthBox paddingBox = m_theme->controlPadding(part, style->font(), style->paddingBox(), style->effectiveZoom());
     119            if (paddingBox != style->paddingBox())
     120                style->setPaddingBox(paddingBox);
     121
     122            // Whitespace
     123            if (m_theme->controlRequiresPreWhiteSpace(part))
     124                style->setWhiteSpace(PRE);
    83125           
    84         // The width and height here are affected by the zoom.
    85         // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
    86         LengthSize controlSize = m_theme->controlSize(part, style->font(), LengthSize(style->width(), style->height()), style->effectiveZoom());
    87         if (controlSize.width() != style->width())
    88             style->setWidth(controlSize.width());
    89         if (controlSize.height() != style->height())
    90             style->setHeight(controlSize.height());
     126            // Width / Height
     127            // The width and height here are affected by the zoom.
     128            // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
     129            LengthSize controlSize = m_theme->controlSize(part, style->font(), LengthSize(style->width(), style->height()), style->effectiveZoom());
     130            if (controlSize.width() != style->width())
     131                style->setWidth(controlSize.width());
     132            if (controlSize.height() != style->height())
     133                style->setHeight(controlSize.height());
     134               
     135            // Min-Width / Min-Height
     136            LengthSize minControlSize = m_theme->minimumControlSize(part, style->font(), style->effectiveZoom());
     137            if (minControlSize.width() != style->minWidth())
     138                style->setMinWidth(minControlSize.width());
     139            if (minControlSize.height() != style->minHeight())
     140                style->setMinHeight(minControlSize.height());
     141               
     142            // Font
     143            FontDescription controlFont = m_theme->controlFont(part, style->font(), style->effectiveZoom());
     144            if (controlFont != style->font().fontDescription()) {
     145                // Reset our line-height
     146                style->setLineHeight(RenderStyle::initialLineHeight());
     147               
     148                // Now update our font.
     149                if (style->setFontDescription(controlFont))
     150                    style->font().update(0);
     151            }
     152        }
     153        default:
     154            break;
    91155    }
    92156#endif
     
    99163        case RadioPart:
    100164            return adjustRadioStyle(selector, style, e);
    101 #endif
    102165        case PushButtonPart:
    103166        case SquareButtonPart:
     
    105168        case ButtonPart:
    106169            return adjustButtonStyle(selector, style, e);
     170#endif
    107171        case TextFieldPart:
    108172            return adjustTextFieldStyle(selector, style, e);
     
    157221
    158222#if USE(NEW_THEME)
    159     if (part == CheckboxPart || part == RadioPart) {
    160         m_theme->paint(part, controlStatesForRenderer(o), const_cast<GraphicsContext*>(paintInfo.context), r, o->style()->effectiveZoom(), o->view()->frameView());
    161         return false;
     223    switch (part) {
     224        case CheckboxPart:
     225        case RadioPart:
     226        case PushButtonPart:
     227        case SquareButtonPart:
     228        case DefaultButtonPart:
     229        case ButtonPart:
     230            m_theme->paint(part, controlStatesForRenderer(o), const_cast<GraphicsContext*>(paintInfo.context), r, o->style()->effectiveZoom(), o->view()->frameView());
     231            return false;
     232        default:
     233            break;
    162234    }
    163235#endif
     
    170242        case RadioPart:
    171243            return paintRadio(o, paintInfo, r);
    172 #endif
    173244        case PushButtonPart:
    174245        case SquareButtonPart:
     
    176247        case ButtonPart:
    177248            return paintButton(o, paintInfo, r);
     249#endif
    178250        case MenulistPart:
    179251            return paintMenuList(o, paintInfo, r);
     
    523595        return false;
    524596   
    525     if (!o->style())
    526         return false;
    527    
    528597    return o->style()->appearance() == DefaultButtonPart;
    529598}
     
    563632    style->setBoxShadow(0);
    564633}
    565 #endif
    566634
    567635void RenderTheme::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
     
    571639    setButtonSize(style);
    572640}
     641#endif
    573642
    574643void RenderTheme::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
  • trunk/WebCore/rendering/RenderTheme.h

    r37743 r37790  
    149149    virtual bool paintRadio(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
    150150    virtual void setRadioSize(RenderStyle*) const { }
    151 #endif
    152151
    153152    virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
    154153    virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return true; }
    155154    virtual void setButtonSize(RenderStyle*) const { }
     155#endif
    156156
    157157    virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
  • trunk/WebCore/rendering/RenderThemeMac.h

    r37731 r37790  
    7777
    7878protected:
    79     // Methods for each appearance value.
    80     virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, WebCore::Element*) const;
    81     virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
    82     virtual void setButtonSize(RenderStyle*) const;
    83 
    8479    virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
    8580    virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
     
    142137    // Helpers for adjusting appearance and for painting
    143138
    144     void setButtonPaddingFromControlSize(RenderStyle*, NSControlSize) const;
    145     const IntSize* buttonSizes() const;
    146     const int* buttonMargins() const;
    147     void setButtonCellState(const RenderObject*, const IntRect&);
    148 
    149139    void setPopupButtonCellState(const RenderObject*, const IntRect&);
    150140    const IntSize* popupButtonSizes() const;
     
    160150    void setSearchFieldSize(RenderStyle*) const;
    161151   
    162     NSButtonCell* button() const;
    163152    NSPopUpButtonCell* popupButton() const;
    164153    NSSearchFieldCell* search() const;
     
    168157
    169158private:
    170     mutable RetainPtr<NSButtonCell> m_button;
    171159    mutable RetainPtr<NSPopUpButtonCell> m_popupButton;
    172160    mutable RetainPtr<NSSearchFieldCell> m_search;
  • trunk/WebCore/rendering/RenderThemeMac.mm

    r37731 r37790  
    425425   
    426426#if USE(NEW_THEME)
    427     if (part == CheckboxPart || part == RadioPart)
    428         return RenderTheme::adjustRepaintRect(o, r);
     427    switch (part) {
     428        case CheckboxPart:
     429        case RadioPart:
     430        case PushButtonPart:
     431        case SquareButtonPart:
     432        case DefaultButtonPart:
     433        case ButtonPart:
     434            return RenderTheme::adjustRepaintRect(o, r);
     435        default:
     436            break;
     437    }
    429438#endif
    430439
    431440    float zoomLevel = o->style()->effectiveZoom();
    432441
    433     switch (o->style()->appearance()) {
    434         case PushButtonPart:
    435         case DefaultButtonPart:
    436         case ButtonPart: {
    437             // Since we query the prototype cell, we need to update its state to match.
    438             setButtonCellState(o, r);
    439 
    440             // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox
    441             // shadow" and the check.  We don't consider this part of the bounds of the control in WebKit.
    442             if ([button() bezelStyle] == NSRoundedBezelStyle) {
    443                 IntSize size = buttonSizes()[[button() controlSize]];
    444                 size.setHeight(size.height() * zoomLevel);
    445                 size.setWidth(r.width());
    446                 r = inflateRect(r, size, buttonMargins(), zoomLevel);
    447             }
    448             break;
    449         }
    450         case MenulistPart: {
    451             setPopupButtonCellState(o, r);
    452             IntSize size = popupButtonSizes()[[popupButton() controlSize]];
    453             size.setHeight(size.height() * zoomLevel);
    454             size.setWidth(r.width());
    455             r = inflateRect(r, size, popupButtonMargins(), zoomLevel);
    456             break;
    457         }
    458         default:
    459             break;
     442    if (part == MenulistPart) {
     443        setPopupButtonCellState(o, r);
     444        IntSize size = popupButtonSizes()[[popupButton() controlSize]];
     445        size.setHeight(size.height() * zoomLevel);
     446        size.setWidth(r.width());
     447        r = inflateRect(r, size, popupButtonMargins(), zoomLevel);
    460448    }
    461449}
     
    618606}
    619607
    620 void RenderThemeMac::setButtonPaddingFromControlSize(RenderStyle* style, NSControlSize size) const
    621 {
    622     // Just use 8px.  AppKit wants to use 11px for mini buttons, but that padding is just too large
    623     // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is
    624     // by definition constrained, since we select mini only for small cramped environments.
    625     // This also guarantees the HTML4 <button> will match our rendering by default, since we're using a consistent
    626     // padding.
    627     const int padding = 8 * style->effectiveZoom();
    628     style->setPaddingLeft(Length(padding, Fixed));
    629     style->setPaddingRight(Length(padding, Fixed));
    630     style->setPaddingTop(Length(0, Fixed));
    631     style->setPaddingBottom(Length(0, Fixed));
    632 }
    633 
    634 void RenderThemeMac::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
    635 {
    636     // There are three appearance constants for buttons.
    637     // (1) Push-button is the constant for the default Aqua system button.  Push buttons will not scale vertically and will not allow
    638     // custom fonts or colors.  <input>s use this constant.  This button will allow custom colors and font weights/variants but won't
    639     // scale vertically.
    640     // (2) square-button is the constant for the square button.  This button will allow custom fonts and colors and will scale vertically.
    641     // (3) Button is the constant that means "pick the best button as appropriate."  <button>s use this constant.  This button will
    642     // also scale vertically and allow custom fonts and colors.  It will attempt to use Aqua if possible and will make this determination
    643     // solely on the rectangle of the control.
    644 
    645     // Determine our control size based off our font.
    646     NSControlSize controlSize = controlSizeForFont(style);
    647 
    648     if (style->appearance() == PushButtonPart) {
    649         // Ditch the border.
    650         style->resetBorder();
    651 
    652         // Height is locked to auto.
    653         style->setHeight(Length(Auto));
    654 
    655         // White-space is locked to pre
    656         style->setWhiteSpace(PRE);
    657 
    658         // Set the button's vertical size.
    659         setButtonSize(style);
    660 
    661         // Add in the padding that we'd like to use.
    662         setButtonPaddingFromControlSize(style, controlSize);
    663 
    664         // Our font is locked to the appropriate system font size for the control.  To clarify, we first use the CSS-specified font to figure out
    665         // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate
    666         // system font for the control size instead.
    667         setFontFromControlSize(selector, style, controlSize);
    668     } else {
    669         // Set a min-height so that we can't get smaller than the mini button.
    670         style->setMinHeight(Length(static_cast<int>(15 * style->effectiveZoom()), Fixed));
    671 
    672         // Reset the top and bottom borders.
    673         style->resetBorderTop();
    674         style->resetBorderBottom();
    675     }
    676 
    677     style->setBoxShadow(0);
    678 }
    679 
    680 const IntSize* RenderThemeMac::buttonSizes() const
    681 {
    682     static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
    683     return sizes;
    684 }
    685 
    686 const int* RenderThemeMac::buttonMargins() const
    687 {
    688     static const int margins[3][4] =
    689     {
    690         { 4, 6, 7, 6 },
    691         { 4, 5, 6, 5 },
    692         { 0, 1, 1, 1 },
    693     };
    694     return margins[[button() controlSize]];
    695 }
    696 
    697 void RenderThemeMac::setButtonSize(RenderStyle* style) const
    698 {
    699     // If the width and height are both specified, then we have nothing to do.
    700     if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
    701         return;
    702 
    703     // Use the font size to determine the intrinsic width of the control.
    704     setSizeFromFont(style, buttonSizes());
    705 }
    706 
    707 void RenderThemeMac::setButtonCellState(const RenderObject* o, const IntRect& r)
    708 {
    709     NSButtonCell* button = this->button();
    710 
    711     // Set the control size based off the rectangle we're painting into.
    712     if (o->style()->appearance() == SquareButtonPart ||
    713         r.height() > buttonSizes()[NSRegularControlSize].height() * o->style()->effectiveZoom()) {
    714         // Use the square button
    715         if ([button bezelStyle] != NSShadowlessSquareBezelStyle)
    716             [button setBezelStyle:NSShadowlessSquareBezelStyle];
    717     } else if ([button bezelStyle] != NSRoundedBezelStyle)
    718         [button setBezelStyle:NSRoundedBezelStyle];
    719 
    720     setControlSize(button, buttonSizes(), r.size(), o->style()->effectiveZoom());
    721 
    722     NSWindow *window = [o->view()->frameView()->documentView() window];
    723     BOOL isDefaultButton = (isDefault(o) && [window isKeyWindow]);
    724     [button setKeyEquivalent:(isDefaultButton ? @"\r" : @"")];
    725 
    726     // Update the various states we respond to.
    727     updateCheckedState(button, o);
    728     updateEnabledState(button, o);
    729     updatePressedState(button, o);
    730     updateFocusedState(button, o);
    731 }
    732 
    733 bool RenderThemeMac::paintButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
    734 {
    735     NSButtonCell* button = this->button();
    736     LocalCurrentGraphicsContext localContext(paintInfo.context);
    737 
    738     // Determine the width and height needed for the control and prepare the cell for painting.
    739     setButtonCellState(o, r);
    740 
    741     paintInfo.context->save();
    742 
    743     // We inflate the rect as needed to account for padding included in the cell to accommodate the button
    744     // shadow.  We don't consider this part of the bounds of the control in WebKit.
    745     float zoomLevel = o->style()->effectiveZoom();
    746     IntSize size = buttonSizes()[[button controlSize]];
    747     size.setWidth(r.width());
    748     size.setHeight(size.height() * zoomLevel);
    749     IntRect inflatedRect = r;
    750     if ([button bezelStyle] == NSRoundedBezelStyle) {
    751         // Center the button within the available space.
    752         if (inflatedRect.height() > size.height()) {
    753             inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - size.height()) / 2);
    754             inflatedRect.setHeight(size.height());
    755         }
    756 
    757         // Now inflate it to account for the shadow.
    758         inflatedRect = inflateRect(inflatedRect, size, buttonMargins(), zoomLevel);
    759 
    760         if (zoomLevel != 1.0f) {
    761             inflatedRect.setWidth(inflatedRect.width() / zoomLevel);
    762             inflatedRect.setHeight(inflatedRect.height() / zoomLevel);
    763             paintInfo.context->translate(inflatedRect.x(), inflatedRect.y());
    764             paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
    765             paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y());
    766         }
    767     }
    768 
    769     NSView *view = o->view()->frameView()->documentView();
    770     NSWindow *window = [view window];
    771     NSButtonCell *previousDefaultButtonCell = [window defaultButtonCell];
    772 
    773     if (isDefault(o) && [window isKeyWindow]) {
    774         [window setDefaultButtonCell:button];
    775         wkAdvanceDefaultButtonPulseAnimation(button);
    776     } else if ([previousDefaultButtonCell isEqual:button])
    777         [window setDefaultButtonCell:nil];
    778 
    779     [button drawWithFrame:NSRect(inflatedRect) inView:view];
    780     [button setControlView:nil];
    781 
    782     if (![previousDefaultButtonCell isEqual:button])
    783         [window setDefaultButtonCell:previousDefaultButtonCell];
    784 
    785     paintInfo.context->restore();
    786 
    787     return false;
    788 }
    789 
    790608bool RenderThemeMac::paintTextField(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
    791609{
     
    1066884}
    1067885
     886static const IntSize* menuListButtonSizes()
     887{
     888    static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
     889    return sizes;
     890}
     891
    1068892void RenderThemeMac::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
    1069893{
     
    1084908
    1085909    // Set the button's vertical size.
    1086     setButtonSize(style);
     910    setSizeFromFont(style, menuListButtonSizes());
    1087911
    1088912    // Our font is locked to the appropriate system font size for the control.  To clarify, we first use the CSS-specified font to figure out
     
    16311455}
    16321456
    1633 NSButtonCell* RenderThemeMac::button() const
    1634 {
    1635     if (!m_button) {
    1636         m_button.adoptNS([[NSButtonCell alloc] init]);
    1637         [m_button.get() setTitle:nil];
    1638         [m_button.get() setButtonType:NSMomentaryPushInButton];
    1639     }
    1640    
    1641     return m_button.get();
    1642 }
    1643 
    16441457NSPopUpButtonCell* RenderThemeMac::popupButton() const
    16451458{
  • trunk/WebCore/rendering/style/RenderStyle.h

    r37746 r37790  
    544544    Length marginRight() const { return surround->margin.right(); }
    545545
     546    LengthBox paddingBox() const { return surround->padding; }
    546547    Length paddingTop() const { return surround->padding.top(); }
    547548    Length paddingBottom() const { return surround->padding.bottom(); }
     
    828829
    829830    void resetPadding() { SET_VAR(surround, padding, LengthBox(Auto)) }
     831    void setPaddingBox(const LengthBox& b) { SET_VAR(surround, padding, b) }
    830832    void setPaddingTop(Length v) { SET_VAR(surround, padding.m_top, v) }
    831833    void setPaddingBottom(Length v) { SET_VAR(surround, padding.m_bottom, v) }
Note: See TracChangeset for help on using the changeset viewer.