• 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     if (Page* page = frame()->page()) {
50         m_page = page;
51         m_page->addScrollableArea(this);
52     }
53 }
54 
~RenderDataGrid()55 RenderDataGrid::~RenderDataGrid()
56 {
57     if (m_page)
58         m_page->removeScrollableArea(this);
59 }
60 
styleDidChange(StyleDifference diff,const RenderStyle * oldStyle)61 void RenderDataGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
62 {
63     RenderBlock::styleDidChange(diff, oldStyle);
64     recalcStyleForColumns();
65 }
66 
recalcStyleForColumns()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 
recalcStyleForColumn(DataGridColumn * column)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 
columnStyle(DataGridColumn * column)83 RenderStyle* RenderDataGrid::columnStyle(DataGridColumn* column)
84 {
85     if (!column->columnStyle())
86         recalcStyleForColumn(column);
87     return column->columnStyle();
88 }
89 
headerStyle(DataGridColumn * column)90 RenderStyle* RenderDataGrid::headerStyle(DataGridColumn* column)
91 {
92     if (!column->headerStyle())
93         recalcStyleForColumn(column);
94     return column->headerStyle();
95 }
96 
computePreferredLogicalWidths()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 
layout()127 void RenderDataGrid::layout()
128 {
129     RenderBlock::layout();
130     layoutColumns();
131 }
132 
layoutColumns()133 void RenderDataGrid::layoutColumns()
134 {
135     // FIXME: Implement.
136 }
137 
paintObject(PaintInfo & paintInfo,int tx,int ty)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 
paintColumnHeaders(PaintInfo & paintInfo,int tx,int ty)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 
paintColumnHeader(DataGridColumn *,PaintInfo &,int,int)173 void RenderDataGrid::paintColumnHeader(DataGridColumn*, PaintInfo&, int, int)
174 {
175     // FIXME: Implement.
176 }
177 
178 // Scrolling implementation functions
scrollSize(ScrollbarOrientation orientation) const179 int RenderDataGrid::scrollSize(ScrollbarOrientation orientation) const
180 {
181     return ((orientation == VerticallScrollbar) && m_vBar) ? (m_vBar->totalSize() - m_vBar->visibleSize()) : 0;
182 }
183 
setScrollOffsetFromAnimation(const IntPoint & offset)184 void RenderDataGrid::setScrollOffsetFromAnimation(const IntPoint& offset)
185 {
186     if (m_vBar)
187         m_vBar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
188 }
189 
valueChanged(Scrollbar *)190 void RenderDataGrid::valueChanged(Scrollbar*)
191 {
192     // FIXME: Implement.
193 }
194 
invalidateScrollbarRect(Scrollbar *,const IntRect &)195 void RenderDataGrid::invalidateScrollbarRect(Scrollbar*, const IntRect&)
196 {
197     // FIXME: Implement.
198 }
199 
isActive() const200 bool RenderDataGrid::isActive() const
201 {
202     Page* page = frame()->page();
203     return page && page->focusController()->isActive();
204 }
205 
206 
convertFromScrollbarToContainingView(const Scrollbar * scrollbar,const IntRect & scrollbarRect) const207 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 
convertFromContainingViewToScrollbar(const Scrollbar * scrollbar,const IntRect & parentRect) const222 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 
convertFromScrollbarToContainingView(const Scrollbar * scrollbar,const IntPoint & scrollbarPoint) const236 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 
convertFromContainingViewToScrollbar(const Scrollbar * scrollbar,const IntPoint & parentPoint) const251 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 
shouldSuspendScrollAnimations() const265 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