Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2009 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 
     28 #if ENABLE(DATAGRID)
     29 
     30 #include "RenderDataGrid.h"
     31 
     32 #include "CSSStyleSelector.h"
     33 #include "FocusController.h"
     34 #include "Frame.h"
     35 #include "GraphicsContext.h"
     36 #include "Page.h"
     37 #include "RenderView.h"
     38 #include "Scrollbar.h"
     39 
     40 using std::min;
     41 
     42 namespace WebCore {
     43 
     44 static const int cDefaultWidth = 300;
     45 
     46 RenderDataGrid::RenderDataGrid(Element* elt)
     47     : RenderBlock(elt)
     48 {
     49     if (Page* page = frame()->page()) {
     50         m_page = page;
     51         m_page->addScrollableArea(this);
     52     }
     53 }
     54 
     55 RenderDataGrid::~RenderDataGrid()
     56 {
     57     if (m_page)
     58         m_page->removeScrollableArea(this);
     59 }
     60 
     61 void RenderDataGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
     62 {
     63     RenderBlock::styleDidChange(diff, oldStyle);
     64     recalcStyleForColumns();
     65 }
     66 
     67 void RenderDataGrid::recalcStyleForColumns()
     68 {
     69     DataGridColumnList* columns = gridElement()->columns();
     70     unsigned length = columns->length();
     71     for (unsigned i = 0; i < length; ++i)
     72         recalcStyleForColumn(columns->item(i));
     73 }
     74 
     75 void RenderDataGrid::recalcStyleForColumn(DataGridColumn* column)
     76 {
     77     if (!column->columnStyle())
     78         column->setColumnStyle(document()->styleSelector()->pseudoStyleForDataGridColumn(column, style()));
     79     if (!column->headerStyle())
     80         column->setHeaderStyle(document()->styleSelector()->pseudoStyleForDataGridColumnHeader(column, style()));
     81 }
     82 
     83 RenderStyle* RenderDataGrid::columnStyle(DataGridColumn* column)
     84 {
     85     if (!column->columnStyle())
     86         recalcStyleForColumn(column);
     87     return column->columnStyle();
     88 }
     89 
     90 RenderStyle* RenderDataGrid::headerStyle(DataGridColumn* column)
     91 {
     92     if (!column->headerStyle())
     93         recalcStyleForColumn(column);
     94     return column->headerStyle();
     95 }
     96 
     97 void RenderDataGrid::computePreferredLogicalWidths()
     98 {
     99     m_minPreferredLogicalWidth = 0;
    100     m_maxPreferredLogicalWidth = 0;
    101 
    102     if (style()->width().isFixed() && style()->width().value() > 0)
    103         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->width().value());
    104     else
    105         m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(cDefaultWidth);
    106 
    107     if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
    108         m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value()));
    109         m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value()));
    110     } else if (style()->width().isPercent() || (style()->width().isAuto() && style()->height().isPercent()))
    111         m_minPreferredLogicalWidth = 0;
    112     else
    113         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
    114 
    115     if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) {
    116         m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value()));
    117         m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value()));
    118     }
    119 
    120     int toAdd = borderAndPaddingWidth();
    121     m_minPreferredLogicalWidth += toAdd;
    122     m_maxPreferredLogicalWidth += toAdd;
    123 
    124     setPreferredLogicalWidthsDirty(false);
    125 }
    126 
    127 void RenderDataGrid::layout()
    128 {
    129     RenderBlock::layout();
    130     layoutColumns();
    131 }
    132 
    133 void RenderDataGrid::layoutColumns()
    134 {
    135     // FIXME: Implement.
    136 }
    137 
    138 void RenderDataGrid::paintObject(PaintInfo& paintInfo, int tx, int ty)
    139 {
    140     if (style()->visibility() != VISIBLE)
    141         return;
    142 
    143     // Paint our background and border.
    144     RenderBlock::paintObject(paintInfo, tx, ty);
    145 
    146     if (paintInfo.phase != PaintPhaseForeground)
    147         return;
    148 
    149     // Paint our column headers first.
    150     paintColumnHeaders(paintInfo, tx, ty);
    151 }
    152 
    153 void RenderDataGrid::paintColumnHeaders(PaintInfo& paintInfo, int tx, int ty)
    154 {
    155     DataGridColumnList* columns = gridElement()->columns();
    156     unsigned length = columns->length();
    157     for (unsigned i = 0; i < length; ++i) {
    158         DataGridColumn* column = columns->item(i);
    159         RenderStyle* columnStyle = headerStyle(column);
    160 
    161         // Don't render invisible columns.
    162         if (!columnStyle || columnStyle->display() == NONE || columnStyle->visibility() != VISIBLE)
    163             continue;
    164 
    165         // Paint the column header if it intersects the dirty rect.
    166         IntRect columnRect(column->rect());
    167         columnRect.move(tx, ty);
    168         if (columnRect.intersects(paintInfo.rect))
    169             paintColumnHeader(column, paintInfo, tx, ty);
    170     }
    171 }
    172 
    173 void RenderDataGrid::paintColumnHeader(DataGridColumn*, PaintInfo&, int, int)
    174 {
    175     // FIXME: Implement.
    176 }
    177 
    178 // Scrolling implementation functions
    179 int RenderDataGrid::scrollSize(ScrollbarOrientation orientation) const
    180 {
    181     return ((orientation == VerticallScrollbar) && m_vBar) ? (m_vBar->totalSize() - m_vBar->visibleSize()) : 0;
    182 }
    183 
    184 void RenderDataGrid::setScrollOffsetFromAnimation(const IntPoint& offset)
    185 {
    186     if (m_vBar)
    187         m_vBar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
    188 }
    189 
    190 void RenderDataGrid::valueChanged(Scrollbar*)
    191 {
    192     // FIXME: Implement.
    193 }
    194 
    195 void RenderDataGrid::invalidateScrollbarRect(Scrollbar*, const IntRect&)
    196 {
    197     // FIXME: Implement.
    198 }
    199 
    200 bool RenderDataGrid::isActive() const
    201 {
    202     Page* page = frame()->page();
    203     return page && page->focusController()->isActive();
    204 }
    205 
    206 
    207 IntRect RenderDataGrid::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
    208 {
    209     RenderView* view = this->view();
    210     if (!view)
    211         return scrollbarRect;
    212 
    213     IntRect rect = scrollbarRect;
    214 
    215     int scrollbarLeft = width() - borderRight() - scrollbar->width();
    216     int scrollbarTop = borderTop();
    217     rect.move(scrollbarLeft, scrollbarTop);
    218 
    219     return view->frameView()->convertFromRenderer(this, rect);
    220 }
    221 
    222 IntRect RenderDataGrid::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
    223 {
    224     RenderView* view = this->view();
    225     if (!view)
    226         return parentRect;
    227 
    228     IntRect rect = view->frameView()->convertToRenderer(this, parentRect);
    229 
    230     int scrollbarLeft = width() - borderRight() - scrollbar->width();
    231     int scrollbarTop = borderTop();
    232     rect.move(-scrollbarLeft, -scrollbarTop);
    233     return rect;
    234 }
    235 
    236 IntPoint RenderDataGrid::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
    237 {
    238     RenderView* view = this->view();
    239     if (!view)
    240         return scrollbarPoint;
    241 
    242     IntPoint point = scrollbarPoint;
    243 
    244     int scrollbarLeft = width() - borderRight() - scrollbar->width();
    245     int scrollbarTop = borderTop();
    246     point.move(scrollbarLeft, scrollbarTop);
    247 
    248     return view->frameView()->convertFromRenderer(this, point);
    249 }
    250 
    251 IntPoint RenderDataGrid::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
    252 {
    253     RenderView* view = this->view();
    254     if (!view)
    255         return parentPoint;
    256 
    257     IntPoint point = view->frameView()->convertToRenderer(this, parentPoint);
    258 
    259     int scrollbarLeft = width() - borderRight() - scrollbar->width();
    260     int scrollbarTop = borderTop();
    261     point.move(-scrollbarLeft, -scrollbarTop);
    262     return point;
    263 }
    264 
    265 bool RenderDataGrid::shouldSuspendScrollAnimations() const
    266 {
    267     RenderView* view = this->view();
    268     if (!view)
    269         return true;
    270     return view->frameView()->shouldSuspendScrollAnimations();
    271 }
    272 
    273 }
    274 
    275 #endif
    276