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 }
     50 
     51 RenderDataGrid::~RenderDataGrid()
     52 {
     53 }
     54 
     55 void RenderDataGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
     56 {
     57     RenderBlock::styleDidChange(diff, oldStyle);
     58     recalcStyleForColumns();
     59 }
     60 
     61 void RenderDataGrid::recalcStyleForColumns()
     62 {
     63     DataGridColumnList* columns = gridElement()->columns();
     64     unsigned length = columns->length();
     65     for (unsigned i = 0; i < length; ++i)
     66         recalcStyleForColumn(columns->item(i));
     67 }
     68 
     69 void RenderDataGrid::recalcStyleForColumn(DataGridColumn* column)
     70 {
     71     if (!column->columnStyle())
     72         column->setColumnStyle(document()->styleSelector()->pseudoStyleForDataGridColumn(column, style()));
     73     if (!column->headerStyle())
     74         column->setHeaderStyle(document()->styleSelector()->pseudoStyleForDataGridColumnHeader(column, style()));
     75 }
     76 
     77 RenderStyle* RenderDataGrid::columnStyle(DataGridColumn* column)
     78 {
     79     if (!column->columnStyle())
     80         recalcStyleForColumn(column);
     81     return column->columnStyle();
     82 }
     83 
     84 RenderStyle* RenderDataGrid::headerStyle(DataGridColumn* column)
     85 {
     86     if (!column->headerStyle())
     87         recalcStyleForColumn(column);
     88     return column->headerStyle();
     89 }
     90 
     91 void RenderDataGrid::calcPrefWidths()
     92 {
     93     m_minPrefWidth = 0;
     94     m_maxPrefWidth = 0;
     95 
     96     if (style()->width().isFixed() && style()->width().value() > 0)
     97         m_minPrefWidth = m_maxPrefWidth = calcContentBoxWidth(style()->width().value());
     98     else
     99         m_maxPrefWidth = calcContentBoxWidth(cDefaultWidth);
    100 
    101     if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
    102         m_maxPrefWidth = max(m_maxPrefWidth, calcContentBoxWidth(style()->minWidth().value()));
    103         m_minPrefWidth = max(m_minPrefWidth, calcContentBoxWidth(style()->minWidth().value()));
    104     } else if (style()->width().isPercent() || (style()->width().isAuto() && style()->height().isPercent()))
    105         m_minPrefWidth = 0;
    106     else
    107         m_minPrefWidth = m_maxPrefWidth;
    108 
    109     if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) {
    110         m_maxPrefWidth = min(m_maxPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));
    111         m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));
    112     }
    113 
    114     int toAdd = paddingLeft() + paddingRight() + borderLeft() + borderRight();
    115     m_minPrefWidth += toAdd;
    116     m_maxPrefWidth += toAdd;
    117 
    118     setPrefWidthsDirty(false);
    119 }
    120 
    121 void RenderDataGrid::layout()
    122 {
    123     RenderBlock::layout();
    124     layoutColumns();
    125 }
    126 
    127 void RenderDataGrid::layoutColumns()
    128 {
    129     // FIXME: Implement.
    130 }
    131 
    132 void RenderDataGrid::paintObject(PaintInfo& paintInfo, int tx, int ty)
    133 {
    134     if (style()->visibility() != VISIBLE)
    135         return;
    136 
    137     // Paint our background and border.
    138     RenderBlock::paintObject(paintInfo, tx, ty);
    139 
    140     if (paintInfo.phase != PaintPhaseForeground)
    141         return;
    142 
    143     // Paint our column headers first.
    144     paintColumnHeaders(paintInfo, tx, ty);
    145 }
    146 
    147 void RenderDataGrid::paintColumnHeaders(PaintInfo& paintInfo, int tx, int ty)
    148 {
    149     DataGridColumnList* columns = gridElement()->columns();
    150     unsigned length = columns->length();
    151     for (unsigned i = 0; i < length; ++i) {
    152         DataGridColumn* column = columns->item(i);
    153         RenderStyle* columnStyle = headerStyle(column);
    154 
    155         // Don't render invisible columns.
    156         if (!columnStyle || columnStyle->display() == NONE || columnStyle->visibility() != VISIBLE)
    157             continue;
    158 
    159         // Paint the column header if it intersects the dirty rect.
    160         IntRect columnRect(column->rect());
    161         columnRect.move(tx, ty);
    162         if (columnRect.intersects(paintInfo.rect))
    163             paintColumnHeader(column, paintInfo, tx, ty);
    164     }
    165 }
    166 
    167 void RenderDataGrid::paintColumnHeader(DataGridColumn*, PaintInfo&, int, int)
    168 {
    169     // FIXME: Implement.
    170 }
    171 
    172 // Scrolling implementation functions
    173 void RenderDataGrid::valueChanged(Scrollbar*)
    174 {
    175     // FIXME: Implement.
    176 }
    177 
    178 void RenderDataGrid::invalidateScrollbarRect(Scrollbar*, const IntRect&)
    179 {
    180     // FIXME: Implement.
    181 }
    182 
    183 bool RenderDataGrid::isActive() const
    184 {
    185     Page* page = document()->frame()->page();
    186     return page && page->focusController()->isActive();
    187 }
    188 
    189 
    190 IntRect RenderDataGrid::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
    191 {
    192     RenderView* view = this->view();
    193     if (!view)
    194         return scrollbarRect;
    195 
    196     IntRect rect = scrollbarRect;
    197 
    198     int scrollbarLeft = width() - borderRight() - scrollbar->width();
    199     int scrollbarTop = borderTop();
    200     rect.move(scrollbarLeft, scrollbarTop);
    201 
    202     return view->frameView()->convertFromRenderer(this, rect);
    203 }
    204 
    205 IntRect RenderDataGrid::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
    206 {
    207     RenderView* view = this->view();
    208     if (!view)
    209         return parentRect;
    210 
    211     IntRect rect = view->frameView()->convertToRenderer(this, parentRect);
    212 
    213     int scrollbarLeft = width() - borderRight() - scrollbar->width();
    214     int scrollbarTop = borderTop();
    215     rect.move(-scrollbarLeft, -scrollbarTop);
    216     return rect;
    217 }
    218 
    219 IntPoint RenderDataGrid::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
    220 {
    221     RenderView* view = this->view();
    222     if (!view)
    223         return scrollbarPoint;
    224 
    225     IntPoint point = scrollbarPoint;
    226 
    227     int scrollbarLeft = width() - borderRight() - scrollbar->width();
    228     int scrollbarTop = borderTop();
    229     point.move(scrollbarLeft, scrollbarTop);
    230 
    231     return view->frameView()->convertFromRenderer(this, point);
    232 }
    233 
    234 IntPoint RenderDataGrid::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
    235 {
    236     RenderView* view = this->view();
    237     if (!view)
    238         return parentPoint;
    239 
    240     IntPoint point = view->frameView()->convertToRenderer(this, parentPoint);
    241 
    242     int scrollbarLeft = width() - borderRight() - scrollbar->width();
    243     int scrollbarTop = borderTop();
    244     point.move(-scrollbarLeft, -scrollbarTop);
    245     return point;
    246 }
    247 
    248 }
    249 
    250 #endif
    251