• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RenderDataGrid(Element * elt)46 RenderDataGrid::RenderDataGrid(Element* elt)
47     : RenderBlock(elt)
48 {
49 }
50 
~RenderDataGrid()51 RenderDataGrid::~RenderDataGrid()
52 {
53 }
54 
styleDidChange(StyleDifference diff,const RenderStyle * oldStyle)55 void RenderDataGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
56 {
57     RenderBlock::styleDidChange(diff, oldStyle);
58     recalcStyleForColumns();
59 }
60 
recalcStyleForColumns()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 
recalcStyleForColumn(DataGridColumn * column)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 
columnStyle(DataGridColumn * column)77 RenderStyle* RenderDataGrid::columnStyle(DataGridColumn* column)
78 {
79     if (!column->columnStyle())
80         recalcStyleForColumn(column);
81     return column->columnStyle();
82 }
83 
headerStyle(DataGridColumn * column)84 RenderStyle* RenderDataGrid::headerStyle(DataGridColumn* column)
85 {
86     if (!column->headerStyle())
87         recalcStyleForColumn(column);
88     return column->headerStyle();
89 }
90 
calcPrefWidths()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 
layout()121 void RenderDataGrid::layout()
122 {
123     RenderBlock::layout();
124     layoutColumns();
125 }
126 
layoutColumns()127 void RenderDataGrid::layoutColumns()
128 {
129     // FIXME: Implement.
130 }
131 
paintObject(PaintInfo & paintInfo,int tx,int ty)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 
paintColumnHeaders(PaintInfo & paintInfo,int tx,int ty)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 
paintColumnHeader(DataGridColumn *,PaintInfo &,int,int)167 void RenderDataGrid::paintColumnHeader(DataGridColumn*, PaintInfo&, int, int)
168 {
169     // FIXME: Implement.
170 }
171 
172 // Scrolling implementation functions
valueChanged(Scrollbar *)173 void RenderDataGrid::valueChanged(Scrollbar*)
174 {
175     // FIXME: Implement.
176 }
177 
invalidateScrollbarRect(Scrollbar *,const IntRect &)178 void RenderDataGrid::invalidateScrollbarRect(Scrollbar*, const IntRect&)
179 {
180     // FIXME: Implement.
181 }
182 
isActive() const183 bool RenderDataGrid::isActive() const
184 {
185     Page* page = document()->frame()->page();
186     return page && page->focusController()->isActive();
187 }
188 
189 
convertFromScrollbarToContainingView(const Scrollbar * scrollbar,const IntRect & scrollbarRect) const190 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 
convertFromContainingViewToScrollbar(const Scrollbar * scrollbar,const IntRect & parentRect) const205 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 
convertFromScrollbarToContainingView(const Scrollbar * scrollbar,const IntPoint & scrollbarPoint) const219 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 
convertFromContainingViewToScrollbar(const Scrollbar * scrollbar,const IntPoint & parentPoint) const234 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