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