/* | |
* Copyright (C) 2009 Apple Inc. All rights reserved. | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions | |
* are met: | |
* 1. Redistributions of source code must retain the above copyright | |
* notice, this list of conditions and the following disclaimer. | |
* 2. Redistributions in binary form must reproduce the above copyright | |
* notice, this list of conditions and the following disclaimer in the | |
* documentation and/or other materials provided with the distribution. | |
* | |
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | |
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
*/ | |
#include "config.h" | |
#if ENABLE(DATAGRID) | |
#include "RenderDataGrid.h" | |
#include "CSSStyleSelector.h" | |
#include "FocusController.h" | |
#include "Frame.h" | |
#include "GraphicsContext.h" | |
#include "Page.h" | |
#include "RenderView.h" | |
#include "Scrollbar.h" | |
using std::min; | |
namespace WebCore { | |
static const int cDefaultWidth = 300; | |
RenderDataGrid::RenderDataGrid(Element* elt) | |
: RenderBlock(elt) | |
{ | |
} | |
RenderDataGrid::~RenderDataGrid() | |
{ | |
} | |
void RenderDataGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) | |
{ | |
RenderBlock::styleDidChange(diff, oldStyle); | |
recalcStyleForColumns(); | |
} | |
void RenderDataGrid::recalcStyleForColumns() | |
{ | |
DataGridColumnList* columns = gridElement()->columns(); | |
unsigned length = columns->length(); | |
for (unsigned i = 0; i < length; ++i) | |
recalcStyleForColumn(columns->item(i)); | |
} | |
void RenderDataGrid::recalcStyleForColumn(DataGridColumn* column) | |
{ | |
if (!column->columnStyle()) | |
column->setColumnStyle(document()->styleSelector()->pseudoStyleForDataGridColumn(column, style())); | |
if (!column->headerStyle()) | |
column->setHeaderStyle(document()->styleSelector()->pseudoStyleForDataGridColumnHeader(column, style())); | |
} | |
RenderStyle* RenderDataGrid::columnStyle(DataGridColumn* column) | |
{ | |
if (!column->columnStyle()) | |
recalcStyleForColumn(column); | |
return column->columnStyle(); | |
} | |
RenderStyle* RenderDataGrid::headerStyle(DataGridColumn* column) | |
{ | |
if (!column->headerStyle()) | |
recalcStyleForColumn(column); | |
return column->headerStyle(); | |
} | |
void RenderDataGrid::calcPrefWidths() | |
{ | |
m_minPrefWidth = 0; | |
m_maxPrefWidth = 0; | |
if (style()->width().isFixed() && style()->width().value() > 0) | |
m_minPrefWidth = m_maxPrefWidth = calcContentBoxWidth(style()->width().value()); | |
else | |
m_maxPrefWidth = calcContentBoxWidth(cDefaultWidth); | |
if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) { | |
m_maxPrefWidth = max(m_maxPrefWidth, calcContentBoxWidth(style()->minWidth().value())); | |
m_minPrefWidth = max(m_minPrefWidth, calcContentBoxWidth(style()->minWidth().value())); | |
} else if (style()->width().isPercent() || (style()->width().isAuto() && style()->height().isPercent())) | |
m_minPrefWidth = 0; | |
else | |
m_minPrefWidth = m_maxPrefWidth; | |
if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) { | |
m_maxPrefWidth = min(m_maxPrefWidth, calcContentBoxWidth(style()->maxWidth().value())); | |
m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value())); | |
} | |
int toAdd = paddingLeft() + paddingRight() + borderLeft() + borderRight(); | |
m_minPrefWidth += toAdd; | |
m_maxPrefWidth += toAdd; | |
setPrefWidthsDirty(false); | |
} | |
void RenderDataGrid::layout() | |
{ | |
RenderBlock::layout(); | |
layoutColumns(); | |
} | |
void RenderDataGrid::layoutColumns() | |
{ | |
// FIXME: Implement. | |
} | |
void RenderDataGrid::paintObject(PaintInfo& paintInfo, int tx, int ty) | |
{ | |
if (style()->visibility() != VISIBLE) | |
return; | |
// Paint our background and border. | |
RenderBlock::paintObject(paintInfo, tx, ty); | |
if (paintInfo.phase != PaintPhaseForeground) | |
return; | |
// Paint our column headers first. | |
paintColumnHeaders(paintInfo, tx, ty); | |
} | |
void RenderDataGrid::paintColumnHeaders(PaintInfo& paintInfo, int tx, int ty) | |
{ | |
DataGridColumnList* columns = gridElement()->columns(); | |
unsigned length = columns->length(); | |
for (unsigned i = 0; i < length; ++i) { | |
DataGridColumn* column = columns->item(i); | |
RenderStyle* columnStyle = headerStyle(column); | |
// Don't render invisible columns. | |
if (!columnStyle || columnStyle->display() == NONE || columnStyle->visibility() != VISIBLE) | |
continue; | |
// Paint the column header if it intersects the dirty rect. | |
IntRect columnRect(column->rect()); | |
columnRect.move(tx, ty); | |
if (columnRect.intersects(paintInfo.rect)) | |
paintColumnHeader(column, paintInfo, tx, ty); | |
} | |
} | |
void RenderDataGrid::paintColumnHeader(DataGridColumn*, PaintInfo&, int, int) | |
{ | |
// FIXME: Implement. | |
} | |
// Scrolling implementation functions | |
void RenderDataGrid::valueChanged(Scrollbar*) | |
{ | |
// FIXME: Implement. | |
} | |
void RenderDataGrid::invalidateScrollbarRect(Scrollbar*, const IntRect&) | |
{ | |
// FIXME: Implement. | |
} | |
bool RenderDataGrid::isActive() const | |
{ | |
Page* page = document()->frame()->page(); | |
return page && page->focusController()->isActive(); | |
} | |
IntRect RenderDataGrid::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const | |
{ | |
RenderView* view = this->view(); | |
if (!view) | |
return scrollbarRect; | |
IntRect rect = scrollbarRect; | |
int scrollbarLeft = width() - borderRight() - scrollbar->width(); | |
int scrollbarTop = borderTop(); | |
rect.move(scrollbarLeft, scrollbarTop); | |
return view->frameView()->convertFromRenderer(this, rect); | |
} | |
IntRect RenderDataGrid::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const | |
{ | |
RenderView* view = this->view(); | |
if (!view) | |
return parentRect; | |
IntRect rect = view->frameView()->convertToRenderer(this, parentRect); | |
int scrollbarLeft = width() - borderRight() - scrollbar->width(); | |
int scrollbarTop = borderTop(); | |
rect.move(-scrollbarLeft, -scrollbarTop); | |
return rect; | |
} | |
IntPoint RenderDataGrid::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const | |
{ | |
RenderView* view = this->view(); | |
if (!view) | |
return scrollbarPoint; | |
IntPoint point = scrollbarPoint; | |
int scrollbarLeft = width() - borderRight() - scrollbar->width(); | |
int scrollbarTop = borderTop(); | |
point.move(scrollbarLeft, scrollbarTop); | |
return view->frameView()->convertFromRenderer(this, point); | |
} | |
IntPoint RenderDataGrid::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const | |
{ | |
RenderView* view = this->view(); | |
if (!view) | |
return parentPoint; | |
IntPoint point = view->frameView()->convertToRenderer(this, parentPoint); | |
int scrollbarLeft = width() - borderRight() - scrollbar->width(); | |
int scrollbarTop = borderTop(); | |
point.move(-scrollbarLeft, -scrollbarTop); | |
return point; | |
} | |
} | |
#endif |