[webkit-changes] cvs commit: WebCore/khtml/xml dom_nodeimpl.cpp

David hyatt at opensource.apple.com
Tue Jul 26 18:12:30 PDT 2005


hyatt       05/07/26 18:12:30

  Modified:    .        ChangeLog
               khtml/css cssstyleselector.cpp
               khtml/html html_formimpl.cpp
               khtml/rendering render_block.cpp render_box.cpp
                        render_object.cpp render_style.h render_theme.cpp
                        render_theme.h render_theme_mac.h
                        render_theme_mac.mm
               khtml/xml dom_nodeimpl.cpp
  Log:
  Have to commit with my own checkin message, since commit-log-editor dies on this patch for some odd reason.
  
  Revision  Changes    Path
  1.4474    +62 -0     WebCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebCore/ChangeLog,v
  retrieving revision 1.4473
  retrieving revision 1.4474
  diff -u -r1.4473 -r1.4474
  --- ChangeLog	26 Jul 2005 23:12:11 -0000	1.4473
  +++ ChangeLog	27 Jul 2005 01:12:23 -0000	1.4474
  @@ -1,3 +1,65 @@
  +2005-07-26  David Hyatt  <hyatt at apple.com>
  +
  +	Land current checkbox work.  The checkbox can now check/uncheck,
  +	supports looking pressed, and can dynamically enable/disable.
  +
  +	Entire patch reviewed by darin, portions reviewed by
  +	sullivan as well.
  +
  +        * khtml/css/cssstyleselector.cpp:
  +        (khtml::CSSStyleSelector::adjustRenderStyle):
  +        * khtml/html/html_formimpl.cpp:
  +        (DOM::HTMLGenericFormElementImpl::parseMappedAttribute):
  +        (DOM::HTMLInputElementImpl::click):
  +        (DOM::HTMLInputElementImpl::setChecked):
  +        (DOM::HTMLInputElementImpl::defaultEventHandler):
  +        * khtml/rendering/render_block.cpp:
  +        (khtml::RenderBlock::baselinePosition):
  +        * khtml/rendering/render_box.cpp:
  +        (RenderBox::paintBoxDecorations):
  +        (RenderBox::getAbsoluteRepaintRect):
  +        * khtml/rendering/render_object.cpp:
  +        (RenderObject::paintOutline):
  +        (RenderObject::setStyle):
  +        * khtml/rendering/render_style.h:
  +        (khtml::RenderStyle::hasAppearance):
  +        (khtml::RenderStyle::resetBorder):
  +        * khtml/rendering/render_theme.cpp:
  +        (khtml::RenderTheme::baselinePosition):
  +        (khtml::RenderTheme::isChecked):
  +        (khtml::RenderTheme::isEnabled):
  +        (khtml::RenderTheme::isFocused):
  +        (khtml::RenderTheme::isPressed):
  +        * khtml/rendering/render_theme.h:
  +        (khtml::RenderTheme::RenderTheme):
  +        (khtml::RenderTheme::~RenderTheme):
  +        (khtml::RenderTheme::isControlContainer):
  +        (khtml::RenderTheme::adjustRepaintRect):
  +        * khtml/rendering/render_theme_mac.h:
  +        (khtml::RenderThemeMac::~RenderThemeMac):
  +        * khtml/rendering/render_theme_mac.mm:
  +        (khtml::RenderThemeMac::RenderThemeMac):
  +        (khtml::RenderThemeMac::adjustRepaintRect):
  +        (khtml::RenderThemeMac::inflateRect):
  +        (khtml::RenderThemeMac::updateCheckedState):
  +        (khtml::RenderThemeMac::updateEnabledState):
  +        (khtml::RenderThemeMac::updateFocusedState):
  +        (khtml::RenderThemeMac::updatePressedState):
  +        (khtml::RenderThemeMac::baselinePosition):
  +        (khtml::RenderThemeMac::isControlContainer):
  +        (khtml::RenderThemeMac::controlSizeForFont):
  +        (khtml::RenderThemeMac::setSizeFromFont):
  +        (khtml::RenderThemeMac::setControlSize):
  +        (khtml::RenderThemeMac::adjustCheckboxStyle):
  +        (khtml::RenderThemeMac::paintCheckbox):
  +        (khtml::RenderThemeMac::checkboxSizes):
  +        (khtml::RenderThemeMac::checkboxMargins):
  +        (khtml::RenderThemeMac::setCheckboxSize):
  +        (khtml::RenderThemeMac::setCheckboxCellState):
  +        * khtml/xml/dom_nodeimpl.cpp:
  +        (DOM::ContainerNodeImpl::setFocus):
  +        (DOM::ContainerNodeImpl::setActive):
  +
   2005-07-26  Eric Seidel  <eseidel at apple.com>
   
           Reviewed by darin.
  
  
  
  1.194     +1 -1      WebCore/khtml/css/cssstyleselector.cpp
  
  Index: cssstyleselector.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/css/cssstyleselector.cpp,v
  retrieving revision 1.193
  retrieving revision 1.194
  diff -u -r1.193 -r1.194
  --- cssstyleselector.cpp	20 Jul 2005 00:45:48 -0000	1.193
  +++ cssstyleselector.cpp	27 Jul 2005 01:12:27 -0000	1.194
  @@ -959,7 +959,7 @@
       style->adjustBackgroundLayers();
   
       // Let the theme get a crack at changing the style if an appearance has been set.
  -    if (style->appearance() != NoAppearance)
  +    if (style->hasAppearance())
           theme()->adjustStyle(style);
   
       // Only use slow repaints if we actually have a background image.
  
  
  
  1.177     +35 -16    WebCore/khtml/html/html_formimpl.cpp
  
  Index: html_formimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/html/html_formimpl.cpp,v
  retrieving revision 1.176
  retrieving revision 1.177
  diff -u -r1.176 -r1.177
  --- html_formimpl.cpp	20 Jul 2005 02:35:31 -0000	1.176
  +++ html_formimpl.cpp	27 Jul 2005 01:12:27 -0000	1.177
  @@ -862,8 +862,13 @@
       } else if (attr->name() == HTMLAttributes::disabled()) {
           bool oldDisabled = m_disabled;
           m_disabled = !attr->isNull();
  -        if (oldDisabled != m_disabled)
  +        if (oldDisabled != m_disabled) {
               setChanged();
  +            if (renderer() && renderer()->style()->hasAppearance())
  +                // FIXME: Let the theme decide whether a repaint is necessary.
  +                // Repaint the renderer when its disabled state changes so the theme will redraw properly.
  +                renderer()->repaint();
  +        }
       } else if (attr->name() == HTMLAttributes::readonly()) {
           bool oldReadOnly = m_readOnly;
           m_readOnly = !attr->isNull();
  @@ -1604,6 +1609,12 @@
               // a no-op for this type
               break;
           case CHECKBOX:
  +            if (renderer() && renderer()->style()->hasAppearance()) {
  +                // Do the click.
  +                HTMLGenericFormElementImpl::click(sendMouseEvents);
  +                break;
  +            }
  +            // Fall through for now 
           case RADIO:
           case SUBMIT:
           case RESET:
  @@ -2069,6 +2080,11 @@
       m_useDefaultChecked = false;
       m_checked = _checked;
       setChanged();
  +    if (renderer() && renderer()->style()->hasAppearance())
  +        // FIXME: Let the theme decide whether a repaint is necessary.
  +        // Repaint the renderer when its checked state changes so the theme will redraw
  +        // properly.
  +        renderer()->repaint();
   }
   
   
  @@ -2210,22 +2226,25 @@
       // actually submitting the form. For reset inputs, the form is reset. These events are sent when the user clicks
       // on the element, or presses enter while it is the active element. Javacsript code wishing to activate the element
       // must dispatch a DOMActivate event - a click event will not do the job.
  -    if ((evt->id() == EventImpl::DOMACTIVATE_EVENT) &&
  -        (m_type == IMAGE || m_type == SUBMIT || m_type == RESET)){
  -
  -        if (!m_form)
  -            return;
  -
  -        if (m_type == RESET) {
  -            m_form->reset();
  -        }
  -        else {
  -            m_activeSubmit = true;
  -            if (!m_form->prepareSubmit()) {
  -                xPos = 0;
  -                yPos = 0;
  +    if (evt->id() == EventImpl::DOMACTIVATE_EVENT) {
  +        if (m_type == IMAGE || m_type == SUBMIT || m_type == RESET) {
  +            if (!m_form)
  +                return;
  +            if (m_type == RESET)
  +                m_form->reset();
  +            else {
  +                m_activeSubmit = true;
  +                if (!m_form->prepareSubmit()) {
  +                    xPos = 0;
  +                    yPos = 0;
  +                }
  +                m_activeSubmit = false;
               }
  -            m_activeSubmit = false;
  +        } else if (m_type == CHECKBOX || m_type == RADIO) {
  +            if (renderer() && renderer()->style()->hasAppearance())
  +                // FIXME: We key off appearance for now, but this is temporary.  When we cut over
  +                // for real this will just always be used.
  +                setChecked(!checked());
           }
       }
   
  
  
  
  1.192     +5 -1      WebCore/khtml/rendering/render_block.cpp
  
  Index: render_block.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_block.cpp,v
  retrieving revision 1.191
  retrieving revision 1.192
  diff -u -r1.191 -r1.192
  --- render_block.cpp	25 Jul 2005 21:50:27 -0000	1.191
  +++ render_block.cpp	27 Jul 2005 01:12:28 -0000	1.192
  @@ -37,6 +37,7 @@
   #include "html/html_formimpl.h"
   #include "render_block.h"
   #include "editing/selection.h"
  +#include "render_theme.h"
   
   #include "khtmlview.h"
   #include "khtml_part.h"
  @@ -3182,8 +3183,11 @@
       // the base class.  If we're being queried as though we're the root line
       // box, then the fact that we're an inline-block is irrelevant, and we behave
       // just like a block.
  -    if (isReplaced() && !isRootLineBox)
  +    if (isReplaced() && !isRootLineBox) {
  +        if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance()))
  +            return theme()->baselinePosition(this);
           return height() + marginTop() + marginBottom();
  +    }
       return RenderFlow::baselinePosition(b, isRootLineBox);
   }
   
  
  
  
  1.159     +8 -3      WebCore/khtml/rendering/render_box.cpp
  
  Index: render_box.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_box.cpp,v
  retrieving revision 1.158
  retrieving revision 1.159
  diff -u -r1.158 -r1.159
  --- render_box.cpp	20 Jul 2005 00:45:49 -0000	1.158
  +++ render_box.cpp	27 Jul 2005 01:12:28 -0000	1.159
  @@ -318,7 +318,7 @@
           mh = kMin(i.r.height(), h);
   
       // If we have a native theme appearance, use that instead of painting our border/background.
  -    if (style()->appearance() != NoAppearance)
  +    if (style()->hasAppearance())
           return theme()->paint(this, i, QRect(_tx, _ty, w, h));
           
       // The <body> only paints its background if the root element has defined a background
  @@ -687,8 +687,13 @@
   
   QRect RenderBox::getAbsoluteRepaintRect()
   {
  -    int ow = style() ? style()->outlineSize() : 0;
  -    QRect r(-ow, -ow, overflowWidth(false)+ow*2, overflowHeight(false)+ow*2);
  +    QRect r(0, 0, overflowWidth(false), overflowHeight(false));
  +    if (style()) {
  +        if (style()->hasAppearance())
  +            // The theme may wish to inflate the rect used when repainting.
  +            theme()->adjustRepaintRect(this, r);
  +        r.inflate(style()->outlineSize()); // FIXME: Technically the outline inflation could fit within the theme inflation.
  +    }
       computeAbsoluteRepaintRect(r);
       return r;
   }
  
  
  
  1.201     +10 -5     WebCore/khtml/rendering/render_object.cpp
  
  Index: render_object.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_object.cpp,v
  retrieving revision 1.200
  retrieving revision 1.201
  diff -u -r1.200 -r1.201
  --- render_object.cpp	18 Jul 2005 21:52:32 -0000	1.200
  +++ render_object.cpp	27 Jul 2005 01:12:28 -0000	1.201
  @@ -1152,10 +1152,15 @@
       
   #ifdef APPLE_CHANGES
       if (style->outlineStyleIsAuto()) {
  -        p->initFocusRing(ow, offset, oc);
  -        addFocusRingRects(p, _tx, _ty);
  -        p->drawFocusRing();
  -        p->clearFocusRing();
  +        if (!style->hasAppearance()) {
  +            // Only paint the focus ring by hand if there is no custom appearance
  +            // specified.  Otherwise we let the theme paint the focus ring, since the ring
  +            // might not be rectangular (or match the dimensions of the control exactly).
  +            p->initFocusRing(ow, offset, oc);
  +            addFocusRingRects(p, _tx, _ty);
  +            p->drawFocusRing();
  +            p->clearFocusRing();
  +        }
           return;
       }
   #endif
  @@ -1618,7 +1623,7 @@
       if (oldStyle)
           oldStyle->deref(renderArena());
   
  -    setShouldPaintBackgroundOrBorder(m_style->hasBorder() || m_style->hasBackground());
  +    setShouldPaintBackgroundOrBorder(m_style->hasBorder() || m_style->hasBackground() || m_style->hasAppearance());
   
       if (affectsParentBlock)
           handleDynamicFloatPositionChange();
  
  
  
  1.86      +2 -0      WebCore/khtml/rendering/render_style.h
  
  Index: render_style.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_style.h,v
  retrieving revision 1.85
  retrieving revision 1.86
  diff -u -r1.85 -r1.86
  --- render_style.h	19 Jul 2005 00:02:08 -0000	1.85
  +++ render_style.h	27 Jul 2005 01:12:28 -0000	1.86
  @@ -1111,6 +1111,7 @@
                                       return true;
                                    return background->m_background.hasImage(); }
       bool hasFixedBackgroundImage() const { return background->m_background.hasFixedImage(); }
  +    bool hasAppearance() const { return appearance() != NoAppearance; }
   
       bool visuallyOrdered() const { return inherited_flags._visuallyOrdered; }
       void setVisuallyOrdered(bool b) {  inherited_flags._visuallyOrdered = b; }
  @@ -1333,6 +1334,7 @@
       }
   #endif
   
  +    void resetBorder() { resetBorderTop(); resetBorderRight(); resetBorderBottom(); resetBorderLeft(); }
       void resetBorderTop() { SET_VAR(surround, border.top, BorderValue()) }
       void resetBorderRight() { SET_VAR(surround, border.right, BorderValue()) }
       void resetBorderBottom() { SET_VAR(surround, border.bottom, BorderValue()) }
  
  
  
  1.2       +38 -0     WebCore/khtml/rendering/render_theme.cpp
  
  Index: render_theme.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_theme.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- render_theme.cpp	20 Jul 2005 00:45:49 -0000	1.1
  +++ render_theme.cpp	27 Jul 2005 01:12:28 -0000	1.2
  @@ -21,6 +21,11 @@
   
   #include "render_theme.h"
   #include "render_style.h"
  +#include "htmlnames.h"
  +#include "html_formimpl.h"
  +
  +using DOM::HTMLTags;
  +using DOM::HTMLInputElementImpl;
   
   // The methods in this file are shared by all themes on every platform.
   
  @@ -54,4 +59,37 @@
       }
   }
   
  +short RenderTheme::baselinePosition(const RenderObject* o) const
  +{
  +    return o->height() + o->marginTop() + o->marginBottom();
  +}
  +
  +bool RenderTheme::isChecked(const RenderObject* o)
  +{
  +    if (!o->element() || !o->element()->hasTagName(HTMLTags::input()))
  +        return false;
  +    return static_cast<HTMLInputElementImpl*>(o->element())->checked();
  +}
  +
  +bool RenderTheme::isEnabled(const RenderObject* o)
  +{
  +    if (!o->element() || !o->element()->hasTagName(HTMLTags::input()))
  +        return true;
  +    return !static_cast<HTMLInputElementImpl*>(o->element())->disabled();
  +}
  +
  +bool RenderTheme::isFocused(const RenderObject* o)
  +{
  +    if (!o->element())
  +        return false;
  +    return o->element() == o->element()->getDocument()->focusNode();
  +}
  +
  +bool RenderTheme::isPressed(const RenderObject* o)
  +{
  +    if (!o->element())
  +        return false;
  +    return o->element()->active();
  +}
  +
   }
  
  
  
  1.3       +25 -4     WebCore/khtml/rendering/render_theme.h
  
  Index: render_theme.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_theme.h,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- render_theme.h	20 Jul 2005 01:17:28 -0000	1.2
  +++ render_theme.h	27 Jul 2005 01:12:28 -0000	1.3
  @@ -31,6 +31,9 @@
   
   class RenderTheme {
   public:
  +    RenderTheme() {}
  +    virtual ~RenderTheme() {}
  +
       // This method is called whenever style has been computed for an element and the appearance
       // property has been set to a value other than "none".  The theme should map in all of the appropriate
       // metrics and defaults given the contents of the style.  This includes sophisticated operations like
  @@ -44,15 +47,33 @@
   
       // The remaining methods should be implemented by the platform-specific portion of the theme, e.g.,
       // render_theme_mac.cpp for Mac OS X.
  +    
  +    // An API to obtain the baseline position for a "leaf" control.  This will only be used if a baseline
  +    // position cannot be determined by examining child content. Checkboxes and radio buttons are examples of
  +    // controls that need to do this.
  +    virtual short baselinePosition(const RenderObject* o) const;
  +
  +    // An API for asking if a control is a container or not.  Leaf controls have to have some special behavior (like
  +    // the baseline position API above).
  +    virtual bool isControlContainer(EAppearance appearance) const { return true; }
  +
  +    // Some controls may spill out of their containers (e.g., the check on an OS X checkbox).  When these controls repaint,
  +    // the theme needs to communicate this inflated rect to the engine so that it can invalidate the whole control.
  +    virtual void adjustRepaintRect(const RenderObject* o, QRect& r) { }
  +    
       // This method is called whenever the theme changes on the system in order to flush cached resources from the
       // old theme.
       void themeChanged();
  -    
  -    virtual ~RenderTheme() {};
  -    
  +
   protected:
  +    // Methods for state querying
  +    bool isChecked(const RenderObject* o);
  +    bool isEnabled(const RenderObject* o);
  +    bool isFocused(const RenderObject* o);
  +    bool isPressed(const RenderObject* o);
  +
       // Methods for each appearance value.
  -    virtual void adjustCheckboxStyle(RenderStyle* style) = 0;
  +    virtual void adjustCheckboxStyle(RenderStyle* style) const = 0;
       virtual void paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const QRect& r) = 0;
   };
   
  
  
  
  1.2       +39 -1     WebCore/khtml/rendering/render_theme_mac.h
  
  Index: render_theme_mac.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_theme_mac.h,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- render_theme_mac.h	20 Jul 2005 00:45:49 -0000	1.1
  +++ render_theme_mac.h	27 Jul 2005 01:12:28 -0000	1.2
  @@ -30,10 +30,48 @@
   class RenderStyle;
   
   class RenderThemeMac : public RenderTheme {
  +public:
  +    RenderThemeMac();
  +    virtual ~RenderThemeMac() { /* Have to just leak the cells, since statics are destroyed with no autorelease pool available */ }
  +
  +    // An API to obtain the baseline position for a "leaf" control.  This will only be used if a baseline
  +    // position cannot be determined by examining child content. Checkboxes and radio buttons are examples of
  +    // controls that need to do this.
  +    virtual short baselinePosition(const RenderObject* o) const;
  +
  +    // An API for asking if a control is a container or not.  Leaf controls have to have some special behavior (like
  +    // the baseline position API above).
  +    virtual bool isControlContainer(EAppearance appearance) const;
  +
  +    virtual void adjustRepaintRect(const RenderObject* o, QRect& r);
  +
   protected:
       // Methods for each appearance value.
  -    virtual void adjustCheckboxStyle(RenderStyle* style);
  +    virtual void adjustCheckboxStyle(RenderStyle* style) const;
       virtual void paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const QRect& r);
  +    
  +private:
  +    QRect inflateRect(const QRect& r, int size, const int* margins) const;
  +
  +    // Get the control size based off the font.  Used by some of the controls (like buttons).
  +    NSControlSize controlSizeForFont(RenderStyle* style) const;
  +    void setSizeFromFont(RenderStyle* style, const int* sizes) const;
  +    void setControlSize(NSCell* cell, const int* sizes, int minSize);
  +
  +    void updateCheckedState(NSCell* cell, const RenderObject* o);
  +    void updateEnabledState(NSCell* cell, const RenderObject* o);
  +    void updateFocusedState(NSCell* cell, const RenderObject* o);
  +    void updatePressedState(NSCell* cell, const RenderObject* o);
  +
  +    // Helpers for adjusting appearance and for painting
  +    const int* checkboxSizes() const;
  +    const int* checkboxMargins() const;
  +    void setCheckboxSize(RenderStyle* style) const;
  +    void setCheckboxCellState(const RenderObject* o, const QRect& r);
  +    
  +    
  +private:
  +    NSButtonCell* checkbox;
   };
   
   }
  
  
  
  1.2       +200 -10   WebCore/khtml/rendering/render_theme_mac.mm
  
  Index: render_theme_mac.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_theme_mac.mm,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- render_theme_mac.mm	20 Jul 2005 00:45:49 -0000	1.1
  +++ render_theme_mac.mm	27 Jul 2005 01:12:28 -0000	1.2
  @@ -20,10 +20,21 @@
    */
   
   #import "render_theme_mac.h"
  +
   #import "render_style.h"
  +#import "render_canvas.h"
  +#import "dom_elementimpl.h"
  +#import "khtmlview.h"
   
   // The methods in this file are specific to the Mac OS X platform.
   
  +enum {
  +    topMargin,
  +    rightMargin,
  +    bottomMargin,
  +    leftMargin
  +};
  +    
   namespace khtml {
   
   RenderTheme* theme()
  @@ -32,23 +43,202 @@
       return &macTheme;
   }
   
  -void RenderThemeMac::adjustCheckboxStyle(RenderStyle* style)
  +RenderThemeMac::RenderThemeMac()
  +{
  +    checkbox = nil;
  +}
  +
  +void RenderThemeMac::adjustRepaintRect(const RenderObject* o, QRect& r)
  +{
  +    if (o->style()->appearance() == CheckboxAppearance) {
  +        // Since we query the prototype cell, we need to update its state to match.
  +        setCheckboxCellState(o, r);
  +    
  +        // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox
  +        // shadow" and the check.  We don't consider this part of the bounds of the control in WebKit.
  +        r = inflateRect(r, checkboxSizes()[[checkbox controlSize]], checkboxMargins());
  +    }
  +}
  +
  +QRect RenderThemeMac::inflateRect(const QRect& r, int size, const int* margins) const
  +{
  +    // Only do the inflation if the available width/height are too small.  Otherwise try to
  +    // fit the glow/check space into the available box's width/height.
  +    int widthDelta = r.width() - (size + margins[leftMargin] + margins[rightMargin]);
  +    int heightDelta = r.height() - (size + margins[topMargin] + margins[bottomMargin]);
  +    QRect result(r);
  +    if (widthDelta < 0) {
  +        result.setX(result.x() - margins[leftMargin]);
  +        result.setWidth(result.width() - widthDelta);
  +    }
  +    if (heightDelta < 0) {
  +        result.setY(result.y() - margins[topMargin]);
  +        result.setHeight(result.height() - heightDelta);
  +    }
  +    return result;
  +}
  +
  +void RenderThemeMac::updateCheckedState(NSCell* cell, const RenderObject* o)
  +{
  +    bool oldChecked = [cell state] == NSOnState;
  +    bool checked = isChecked(o);
  +    if (checked != oldChecked)
  +        [cell setState:checked ? NSOnState : NSOffState];
  +}
  +
  +void RenderThemeMac::updateEnabledState(NSCell* cell, const RenderObject* o)
  +{
  +    bool oldEnabled = [cell isEnabled];
  +    bool enabled = isEnabled(o);
  +    if (enabled != oldEnabled)
  +        [cell setEnabled:enabled];
  +}
  +
  +void RenderThemeMac::updateFocusedState(NSCell* cell, const RenderObject* o)
  +{
  +    // FIXME: Need to add a key window test here, or the element will look
  +    // focused even when in the background.
  +    bool oldFocused = [cell showsFirstResponder];
  +    bool focused = (o->element() && o->document()->focusNode() == o->element()) && (o->style()->outlineStyleIsAuto());
  +    if (focused != oldFocused)
  +        [cell setShowsFirstResponder:focused];
  +}
  +
  +void RenderThemeMac::updatePressedState(NSCell* cell, const RenderObject* o)
  +{
  +    bool oldPressed = [cell isHighlighted];
  +    bool pressed = (o->element() && o->element()->active());
  +    if (pressed != oldPressed)
  +        [cell setHighlighted:pressed];
  +}
  +
  +short RenderThemeMac::baselinePosition(const RenderObject* o) const
  +{
  +    if (o->style()->appearance() == CheckboxAppearance)
  +        return o->marginTop() + o->height() - 2; // The baseline is 2px up from the bottom of the checkbox in AppKit.
  +    return RenderTheme::baselinePosition(o);
  +}
  +
  +bool RenderThemeMac::isControlContainer(EAppearance appearance) const
  +{
  +    // There are more leaves than this, but we'll patch this function as we add support for
  +    // more controls.
  +    return appearance != CheckboxAppearance && appearance != RadioAppearance;
  +}
  +    
  +NSControlSize RenderThemeMac::controlSizeForFont(RenderStyle* style) const
  +{
  +    int fontSize = style->fontSize();
  +    if (fontSize >= 16)
  +        return NSRegularControlSize;
  +    if (fontSize >= 11)
  +        return NSSmallControlSize;
  +    return NSMiniControlSize;
  +}
  +
  +void RenderThemeMac::setSizeFromFont(RenderStyle* style, const int* sizes) const
  +{
  +    int size = sizes[controlSizeForFont(style)];
  +    style->setWidth(Length(size, Fixed));
  +    style->setHeight(Length(size, Fixed));
  +}
  +
  +void RenderThemeMac::setControlSize(NSCell* cell, const int* sizes, int minSize)
  +{
  +    NSControlSize size;
  +    if (minSize >= sizes[NSRegularControlSize])
  +        size = NSRegularControlSize;
  +    else if (minSize >= sizes[NSSmallControlSize])
  +        size = NSSmallControlSize;
  +    else
  +        size = NSMiniControlSize;
  +    if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same.
  +        [cell setControlSize:size];
  +}
  +
  +// ========================================================================================
  +// Checkboxes - <input type="checkbox">
  +//      Mouse States - Pressed
  +//      Control States - Checked, Enabled, Focused
  +// ========================================================================================
  +
  +void RenderThemeMac::adjustCheckboxStyle(RenderStyle* style) const
   {
       // A summary of the rules for checkbox designed to match WinIE:
  -    // width/height - honored but we won't let ourselves get smaller than the mini checkbox.
  -    //                (WinIE actually scales its control for small widths, but lets it overflow for small heights.)
  -    // padding - not honored, needs to be removed.
  -    // border - not honored, needs to be removed (WinIE honors it but just paints it around the control, which just looks awful.)
  +    // width/height - honored (WinIE actually scales its control for small widths, but lets it overflow for small heights.)
  +    // font-size - not honored (control has no text), but we use it to decide which control size to use.
  +    setCheckboxSize(style);
       
  +    // padding - not honored by WinIE, needs to be removed.
  +    style->resetPadding();
  +    
  +    // border - honored by WinIE, but looks terrible (just paints in the control box and turns off the Windows XP theme)
  +    // for now, we will not honor it.
  +    style->resetBorder();
   }
   
   void RenderThemeMac::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const QRect& r)
   {
  -    // A summary of the rules for checkbox designed to match WinIE:
  -    //
  -    // width/height - if larger than the control size, then the control should paint itself centered
  -    //                within the larger area.
  +    // Determine the width and height needed for the control and prepare the cell for painting.
  +    setCheckboxCellState(o, r);
  +    
  +    // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox
  +    // shadow" and the check.  We don't consider this part of the bounds of the control in WebKit.
  +    QRect inflatedRect = inflateRect(r, checkboxSizes()[[checkbox controlSize]], checkboxMargins());
  +    [checkbox drawWithFrame:NSRect(inflatedRect) inView:o->canvas()->view()->getDocumentView()];
  +    [checkbox setControlView: nil];
  +}
  +
  +const int* RenderThemeMac::checkboxSizes() const
  +{
  +    static const int sizes[3] = { 14, 12, 10 };
  +    return sizes;
  +}
  +
  +const int* RenderThemeMac::checkboxMargins() const
  +{
  +    static const int margins[3][4] = 
  +    {
  +        { 3, 4, 4, 2 },
  +        { 4, 3, 3, 3 },
  +        { 4, 3, 3, 3 },
  +    };
  +    return margins[[checkbox controlSize]];
  +}
  +
  +void RenderThemeMac::setCheckboxSize(RenderStyle* style) const
  +{
  +    // If the width and height are both specified, then we have nothing to do.
  +    if (!style->width().isVariable() && !style->height().isVariable())
  +        return;
  +
  +    // The control is a square, so make the two values match.
  +    if (!style->width().isVariable())
  +        style->setHeight(style->width());
  +    else if (!style->height().isVariable())
  +        style->setWidth(style->width());
  +    else
  +        // Use the font size to determine the intrinsic width of the control.
  +        // Checkboxes are either 14, 12, or 10 pixels tall.
  +        setSizeFromFont(style, checkboxSizes());
  +}
  +
  +void RenderThemeMac::setCheckboxCellState(const RenderObject* o, const QRect& r)
  +{
  +    if (!checkbox) {
  +        checkbox = [[NSButtonCell alloc] init];
  +        [checkbox setButtonType:NSSwitchButton];
  +        [checkbox setTitle:nil];
  +    }
  +    
  +    // Set the control size based off the rectangle we're painting into.
  +    setControlSize(checkbox, checkboxSizes(), kMin(r.width(), r.height()));
       
  +    // Update the various states we respond to.
  +    updateCheckedState(checkbox, o);
  +    updateEnabledState(checkbox, o);
  +    updatePressedState(checkbox, o);
  +    updateFocusedState(checkbox, o);
   }
   
  -}
  \ No newline at end of file
  +}
  
  
  
  1.161     +9 -2      WebCore/khtml/xml/dom_nodeimpl.cpp
  
  Index: dom_nodeimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom_nodeimpl.cpp,v
  retrieving revision 1.160
  retrieving revision 1.161
  diff -u -r1.160 -r1.161
  --- dom_nodeimpl.cpp	18 Jul 2005 21:52:34 -0000	1.160
  +++ dom_nodeimpl.cpp	27 Jul 2005 01:12:29 -0000	1.161
  @@ -2286,6 +2286,7 @@
   
       NodeImpl::setFocus(received);
   
  +    // FIXME: Move to ElementImpl
       if (received && isEditableBlock() && !hasChildNodes()) {
           getDocument()->part()->setSelection(Selection(Position(this, 0), DOWNSTREAM));
       }
  @@ -2301,8 +2302,14 @@
       NodeImpl::setActive(down);
   
       // note that we need to recalc the style
  -    if (m_render && m_render->style()->affectedByActiveRules())
  -        setChanged();
  +    // FIXME: Move to ElementImpl
  +    if (m_render) {
  +        if (m_render->style()->affectedByActiveRules())
  +            setChanged();
  +        // FIXME: Let the theme decide if the repaint is necessary.
  +        if (m_render->style()->hasAppearance())
  +            m_render->repaint();
  +    }
   }
   
   unsigned long ContainerNodeImpl::childNodeCount() const
  
  
  



More information about the webkit-changes mailing list