--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/wmlengine/src/lmgr/src/LMgrStaticTableRowBox.cpp Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,490 @@
+/*
+* Copyright (c) 2000 - 2001 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "nw_lmgr_statictablerowboxi.h"
+#include "nw_lmgr_statictablecellbox.h"
+#include "nw_lmgr_cssproperties.h"
+#include "BrsrStatusCodes.h"
+#include "nw_lmgr_textbox.h"
+
+
+
+/* ------------------------------------------------------------------------- */
+
+
+const
+NW_LMgr_StaticTableRowBox_Class_t NW_LMgr_StaticTableRowBox_Class = {
+ { /* NW_Object_Core */
+ /* super */ &NW_LMgr_FormatBox_Class,
+ /* queryInterface */ _NW_Object_Base_QueryInterface
+ },
+ { /* NW_Object_Base */
+ /* interfaceList */ NULL
+ },
+ { /* NW_Object_Dynamic */
+ /* instanceSize */ sizeof (NW_LMgr_StaticTableRowBox_t),
+ /* construct */ _NW_LMgr_ContainerBox_Construct,
+ /* destruct */ NULL
+ },
+ { /* NW_LMgr_Box */
+ /* split */ _NW_LMgr_Box_Split,
+ /* resize */ _NW_LMgr_StaticTableRowBox_ResizeRow,
+ /* postResize */ _NW_LMgr_StaticTableRowBox_PostResizeRow,
+ /* getMinimumContentSize */ _NW_LMgr_Box_GetMinimumContentSize,
+ /* hasFixedContentSize */ _NW_LMgr_Box_HasFixedContentSize,
+ /* constrain */ _NW_LMgr_Box_Constrain,
+ /* draw */ _NW_LMgr_StaticTableRowBox_Draw,
+ /* render */ _NW_LMgr_StaticTableRowBox_Render,
+ /* getBaseline */ _NW_LMgr_StaticTableRowBox_GetBaseline,
+ /* shift */ _NW_LMgr_ContainerBox_Shift,
+ /* clone */ _NW_LMgr_Box_Clone
+ },
+ { /* NW_LMgr_ContainerBox */
+ /* unused */ NW_Object_Unused
+ },
+ { /* NW_LMgr_FormatBox */
+ /* applyFormatProps */ _NW_LMgr_StaticTableRowBox_ApplyFormatProps
+ },
+ /* NW_LMgr_StaticTableRowBox */
+ {
+ /* unused */ NW_Object_Unused
+ }
+};
+
+/* ------------------------------------------------------------------------- */
+/* Virtual method implementations */
+/* ------------------------------------------------------------------------- */
+
+NW_GDI_Metric_t
+_NW_LMgr_StaticTableRowBox_GetBaseline(NW_LMgr_Box_t* rowBox)
+{
+ NW_LMgr_ContainerBox_t *rowContainer = NW_LMgr_ContainerBoxOf(rowBox);
+ NW_ADT_Vector_Metric_t cellIndex, cellCount;
+ NW_LMgr_PropertyValueToken_t align;
+ NW_LMgr_Box_t *cellBox;
+ NW_GDI_Metric_t tempBase = 0, rowBaseline = 0;
+ NW_LMgr_Property_t prop;
+
+ cellCount = NW_LMgr_ContainerBox_GetChildCount(rowContainer);
+
+ /* Look for a baseline-aligned box */
+ for (cellIndex = 0; cellIndex < cellCount; cellIndex++) {
+
+ cellBox = NW_LMgr_ContainerBox_GetChild(rowContainer, cellIndex);
+
+ /* Get the alignment property */
+ prop.value.token = NW_CSS_PropValue_baseline;
+ (void)NW_LMgr_Box_GetProperty (cellBox, NW_CSS_Prop_verticalAlign, &prop);
+ align = prop.value.token;
+
+ if (align == NW_CSS_PropValue_baseline) {
+ tempBase = NW_LMgr_Box_GetBaseline(cellBox);
+ if (tempBase > rowBaseline) {
+ rowBaseline = tempBase;
+ }
+ }
+ }
+
+ /* Otherwise, the baseline is not defined */
+ return rowBaseline;
+}
+
+/* -------------------------------------------------------------------------
+ * Function: NW_LMgr_StaticTableRowBox_Draw
+ * Parameters: box - the table box
+ * deviceContext - the device context
+ * hasFocus - does the box have focus?
+ * Description: This method overrides the base class draw. We leave it
+ * blank because we don't want the table row to draw its own
+ * borders. Table borders will be drawn by the cells that
+ * own them.
+ * Returns: KBrsrSuccess, KBrsrOutOfMemory
+ */
+TBrowserStatusCode
+_NW_LMgr_StaticTableRowBox_Draw (NW_LMgr_Box_t* box,
+ CGDIDeviceContext* deviceContext,
+ NW_Uint8 hasFocus)
+{
+ NW_REQUIRED_PARAM(box);
+ NW_REQUIRED_PARAM(deviceContext);
+ NW_REQUIRED_PARAM(hasFocus);
+
+ return KBrsrSuccess;
+}
+
+/* ------------------------------------------------------------------------- */
+TBrowserStatusCode
+_NW_LMgr_StaticTableRowBox_Render (NW_LMgr_Box_t* box,
+ CGDIDeviceContext *deviceContext,
+ NW_GDI_Rectangle_t* clipRect,
+ NW_LMgr_Box_t *currentBox,
+ NW_Uint8 flags,
+ NW_Bool* hasFocus,
+ NW_Bool* skipChildren,
+ NW_LMgr_RootBox_t* rootBox )
+{
+ NW_LMgr_PropertyValue_t visibilityVal;
+
+ // Check if visibility val for the row is collapse
+ visibilityVal.token = NW_CSS_PropValue_visible;
+ (void) NW_LMgr_Box_GetPropertyValue (box, NW_CSS_Prop_visibility,
+ NW_CSS_ValueType_Token, &visibilityVal);
+ if (visibilityVal.token == NW_CSS_PropValue_collapse)
+ {
+ return KBrsrSuccess;
+ }
+
+ // Now call the base class render to render the children
+ // invoke our superclass constructor
+ return _NW_LMgr_ContainerBox_Render (box,
+ deviceContext,
+ clipRect,
+ currentBox,
+ flags,
+ hasFocus,
+ skipChildren,
+ rootBox );
+}
+
+TBrowserStatusCode
+_NW_LMgr_StaticTableRowBox_ApplyFormatProps(NW_LMgr_FormatBox_t* format,
+ NW_LMgr_FormatContext_t* context)
+{
+ NW_REQUIRED_PARAM(format);
+ NW_REQUIRED_PARAM(context);
+
+ return NW_TRUE;
+}
+
+/* ------------------------------------------------------------------------- *
+ * Public final methods
+ * ------------------------------------------------------------------------- */
+
+/* ------------------------------------------------------------------------- */
+TBrowserStatusCode
+NW_LMgr_StaticTableRowBox_ConstrainRow (NW_LMgr_StaticTableRowBox_t* rowBox)
+{
+ NW_LMgr_Box_t *thisRow = NW_LMgr_BoxOf(rowBox);
+ NW_LMgr_Box_t *thisTable = NW_LMgr_BoxOf(thisRow->parent);
+
+ NW_GDI_Rectangle_t rowBoxBounds = NW_LMgr_Box_GetFormatBounds( thisRow );
+ NW_GDI_Rectangle_t tableBoxBounds = NW_LMgr_Box_GetFormatBounds( thisTable );
+
+ rowBoxBounds.dimension.width = tableBoxBounds.dimension.width;
+ NW_LMgr_Box_SetFormatBounds( thisRow, rowBoxBounds );
+
+ return KBrsrSuccess;
+}
+
+
+TBrowserStatusCode
+_NW_LMgr_StaticTableRowBox_ResizeRow (NW_LMgr_Box_t* box, NW_LMgr_FormatContext_t* context)
+{
+ NW_LMgr_StaticTableRowBox_t* rowBox = (NW_LMgr_StaticTableRowBox_t*) box;
+ NW_LMgr_StaticTableBox_t* thisObj = (NW_LMgr_StaticTableBox_t*)NW_LMgr_Box_GetParent(rowBox);
+ NW_LMgr_PropertyValue_t visibilityVal;
+ TBrowserStatusCode status = KBrsrSuccess;
+
+ visibilityVal.token = NW_CSS_PropValue_visible;
+ (void) NW_LMgr_Box_GetPropertyValue (box,
+ NW_CSS_Prop_visibility,
+ NW_CSS_ValueType_Token,
+ &visibilityVal);
+ if (visibilityVal.token != NW_CSS_PropValue_collapse) {
+ // call contraint row only on fixed algorithm
+ if( thisObj->automaticWidthPass == NW_LMgr_StaticTableBox_AutomaticWidth_UndefinedPass )
+ {
+ (void)NW_LMgr_StaticTableRowBox_ConstrainRow( NW_LMgr_StaticTableRowBoxOf( rowBox ) );
+ }
+
+ context->formatBox = box;
+ context->formatChildren = NW_TRUE;
+ context->newFormatContext = context;
+ context->referenceCount ++;
+ }
+ return status;
+}
+
+/* ------------------------------------------------------------------------- */
+/* ResizeRow resizes the individual cells in the row and calculates
+ * its final height and baseline. At the end we increment the cumulative
+ * height of the table content.
+ * ResizeRow assumes that the row originates at (0,0). We will shift it
+ * to its final vertical position in PlaceRow.
+ */
+TBrowserStatusCode
+_NW_LMgr_StaticTableRowBox_PostResizeRow (NW_LMgr_Box_t* box)
+{
+ TBrowserStatusCode status ;
+ NW_LMgr_StaticTableRowBox_t* rowBox = (NW_LMgr_StaticTableRowBox_t*) box;
+ NW_LMgr_Box_t *thisRow = NW_LMgr_BoxOf(rowBox);
+ NW_LMgr_ContainerBox_t *rowContainer = NW_LMgr_ContainerBoxOf(rowBox);
+ NW_LMgr_Box_t *tableBox = NW_LMgr_BoxOf(thisRow->parent);
+ NW_LMgr_ContainerBox_t *tableContainer = NW_LMgr_ContainerBoxOf(tableBox);
+
+ NW_ADT_Vector_Metric_t cellCount, cellIndex;
+ NW_ADT_Vector_Metric_t currentRow;
+ NW_ADT_Vector_Metric_t rowSpan;
+ NW_ADT_Vector_Metric_t i;
+ NW_GDI_Metric_t rowHeight, rowBaseline, rowDescent;
+ NW_GDI_Metric_t cellHeight, cellBaseline;
+ NW_LMgr_Property_t prop;
+ NW_LMgr_Box_t* cellBox;
+ NW_GDI_Dimension2D_t rowSize;
+ NW_LMgr_PropertyValueToken_t align;
+ NW_Uint8 pass;
+ NW_LMgr_Box_t *tempRowBox;
+
+
+ /* Visit each cell in the row */
+ cellCount =
+ NW_LMgr_ContainerBox_GetChildCount(rowContainer);
+
+ /* Initialize the row info */
+ currentRow = NW_LMgr_ContainerBox_GetChildIndex(tableContainer, thisRow);
+ rowHeight = 0;
+ rowBaseline = 0;
+
+ /* We pass through the row twice. In the first pass we calculate the
+ * baseline for the row, if any. Next we calculate the height
+ * for the row given the baseline */
+ for (pass = 0; pass < 2; pass++) {
+ for (cellIndex = 0; cellIndex < cellCount; cellIndex++) {
+
+ /* Get the cell */
+ cellBox = NW_LMgr_ContainerBox_GetChild(rowContainer, cellIndex);
+
+ /* Get the cell info */
+ cellBaseline = NW_LMgr_Box_GetBaseline (cellBox);
+ NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( cellBox );
+
+ cellHeight = boxBounds.dimension.height;
+
+ /* Get the alignment property */
+ prop.value.token = NW_CSS_PropValue_baseline;
+ status = NW_LMgr_Box_GetProperty (cellBox, NW_CSS_Prop_verticalAlign, &prop);
+ if (status == KBrsrNotFound) {
+ (void)NW_LMgr_Box_GetProperty (thisRow, NW_CSS_Prop_verticalAlign, &prop);
+ }
+ align = prop.value.token;
+
+ /* If the rowSpan property is >1, we must take into account the other
+ * rows that the cell spans. The minimum height that this cell will
+ * take up on our row will be its height minus the total height of
+ * any other rows that it spans */
+ prop.value.integer = 1;
+ (void)NW_LMgr_Box_GetPropertyFromList (cellBox, NW_CSS_Prop_rowSpan,
+ &prop);
+ rowSpan = (NW_ADT_Vector_Metric_t)prop.value.integer;
+ for (i = (NW_ADT_Vector_Metric_t)(currentRow + 1);
+ i < currentRow + rowSpan;
+ i++) {
+ tempRowBox = NW_LMgr_ContainerBox_GetChild(tableContainer, i);
+ if (tempRowBox)
+ {
+ NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( tempRowBox );
+ cellHeight = (NW_GDI_Metric_t)
+ (cellHeight - boxBounds.dimension.height);
+ }
+ }
+
+ /* Calculate the baseline and the height */
+ switch (pass) {
+ case 0:
+ if (align == NW_CSS_PropValue_baseline) {
+ if (cellHeight - cellBaseline > rowHeight - rowBaseline) {
+ rowDescent = (NW_GDI_Metric_t)(cellHeight - cellBaseline);
+ }
+ else {
+ rowDescent = (NW_GDI_Metric_t)(rowHeight - rowBaseline);
+ }
+ rowBaseline = (NW_GDI_Metric_t)
+ ((rowBaseline > cellBaseline) ? rowBaseline : cellBaseline);
+ rowHeight = (NW_GDI_Metric_t)(rowBaseline + rowDescent);
+ }
+ break;
+ case 1:
+ if (rowHeight < cellHeight) {
+ switch (align) {
+ case NW_CSS_PropValue_bottom:
+ rowBaseline =
+ (NW_GDI_Metric_t)(rowBaseline + cellHeight - rowHeight);
+ break;
+ case NW_CSS_PropValue_middle:
+ rowBaseline =
+ (NW_GDI_Metric_t)(rowBaseline + (cellHeight - rowHeight)/2);
+ break;
+ }
+ rowHeight = cellHeight;
+ }
+ break;
+ }
+ }
+ }
+ /* If the row height we obtained is less than the specified row height,
+ we use the specified value */
+ NW_LMgr_Box_GetSizeProperties(thisRow, &rowSize);
+ if (rowSize.height > rowHeight) {
+ rowHeight = rowSize.height;
+ }
+ NW_GDI_Rectangle_t rowBoxBounds = NW_LMgr_Box_GetFormatBounds( thisRow );
+ rowBoxBounds.dimension.height = rowHeight;
+ NW_LMgr_Box_SetFormatBounds( thisRow, rowBoxBounds );
+ return KBrsrSuccess;
+ }
+
+
+
+/* ------------------------------------------------------------------------- */
+/* The alignment algorithm is defined in [CSS2 17.5.3].
+ * 1. First we align any cells with align=baseline. This establishes the
+ * baseline for the row.
+ * 2. Next we align cells with align=top. This establishes the top position
+ * for the row and a provisional height.
+ * 3. Finally we align the bottom- and middle-aligned cells. This may
+ * increase the total height of the row.
+ * 4. If a cell spans several rows, it is positioned at the time we
+ * reach the first row in which it is contained. We start with the
+ * last row in order to facilitate this behavior. [This not in CSS2]
+ */
+TBrowserStatusCode
+NW_LMgr_StaticTableRowBox_PlaceRow (NW_LMgr_StaticTableRowBox_t* rowBox,
+ NW_GDI_Metric_t atX, NW_GDI_Metric_t atY)
+{
+ NW_LMgr_Box_t *thisRow ;
+ NW_LMgr_ContainerBox_t *rowContainer ;
+ NW_LMgr_Box_t *tableBox ;
+ NW_LMgr_ContainerBox_t *tableContainer ;
+ NW_LMgr_StaticTableContext_t *thisContext ;
+
+ NW_GDI_Rectangle_t newRect;
+ NW_ADT_Vector_Metric_t cellCount, cellIndex;
+ NW_ADT_Vector_Metric_t currentRow, currentCol, prevCol;
+ NW_ADT_Vector_Metric_t i;
+ NW_GDI_Metric_t cellHeight;
+ NW_GDI_Metric_t currentX;
+ NW_ADT_Vector_Metric_t rowSpan, colSpan;
+ NW_LMgr_Box_t* cellBox;
+ NW_LMgr_Box_t* currentRowBox;
+
+
+ thisRow = NW_LMgr_BoxOf(rowBox);
+
+ rowContainer = NW_LMgr_ContainerBoxOf(rowBox);
+
+
+ tableBox = NW_LMgr_BoxOf(thisRow->parent);
+ tableContainer = NW_LMgr_ContainerBoxOf(tableBox);
+ thisContext = NW_LMgr_StaticTableBoxOf(tableBox)->ctx;
+ NW_TRY(status) {
+ /* Visit each cell in the row */
+ cellCount =
+ NW_LMgr_ContainerBox_GetChildCount(rowContainer);
+
+ /* Initialize the row info */
+ currentRow = NW_LMgr_ContainerBox_GetChildIndex(tableContainer, thisRow);
+ currentX = atX;
+ currentCol = 0;
+
+ /* Place the cells */
+ for (cellIndex = 0; cellIndex < cellCount; cellIndex++) {
+
+ /* Get the cell */
+ cellBox = NW_LMgr_ContainerBox_GetChild(rowContainer, cellIndex);
+ // JADE hack; to-do: why cellbox is not staticcellbox?
+ if (!NW_Object_IsInstanceOf (cellBox, &NW_LMgr_StaticTableCellBox_Class))
+ {
+ continue;
+ }
+
+ /* Determine its position */
+ prevCol = currentCol;
+ status = NW_LMgr_StaticTableContext_LxLyToPxPy
+ (thisContext, cellIndex, currentRow,
+ ¤tCol, ¤tRow,
+ &colSpan, &rowSpan);
+ if (status == KBrsrNotFound) {
+ status = KBrsrSuccess;
+ break;
+ }
+ NW_THROW_ON_ERROR(status);
+
+ for (i = prevCol; i < currentCol; i++) {
+ currentX = (NW_GDI_Metric_t)
+ (currentX + NW_LMgr_StaticTableContext_GetColConstraint(thisContext, i));
+ }
+
+ /* If the rowSpan property is >1, we calculate the total space that
+ * the cell will occupy by adding the heights of all its rows. */
+ cellHeight = 0;
+ for (i = currentRow; i < currentRow + rowSpan; i++) {
+ currentRowBox = NW_LMgr_ContainerBox_GetChild(tableContainer, i);
+ NW_GDI_Rectangle_t rowBoxBounds = NW_LMgr_Box_GetFormatBounds( currentRowBox);
+
+ cellHeight = (NW_GDI_Metric_t)
+ (cellHeight
+ + rowBoxBounds.dimension.height);
+ }
+
+ /* Get the new rectangle for the cell */
+ NW_GDI_Metric_t currentColConstraint =
+ NW_LMgr_StaticTableContext_GetColConstraint(thisContext, currentCol);
+ NW_GDI_Rectangle_t cellBoxBounds = NW_LMgr_Box_GetFormatBounds( cellBox );
+ newRect.point.x = currentX;
+ newRect.point.y = atY;
+ newRect.dimension.width = cellBoxBounds.dimension.width;
+ if (newRect.dimension.width < currentColConstraint)
+ {
+ newRect.dimension.width = currentColConstraint;
+ }
+ newRect.dimension.height = cellHeight;
+
+ /* Stretch both moves the cell to its final position in the flow and
+ * stretches it to its final size. Stretch also takes care of
+ * any vertical alignment adjustments that need to be made. */
+ status =
+ NW_LMgr_StaticTableCellBox_Stretch((NW_LMgr_StaticTableCellBox_t*)cellBox,
+ &newRect);
+ _NW_THROW_ON_ERROR(status);
+
+ /* Prepare the tableContext for the next cell */
+ currentX = (NW_GDI_Metric_t)(currentX + newRect.dimension.width);
+ currentCol = (NW_ADT_Vector_Metric_t)(currentCol + colSpan);
+ }
+
+ /* Finally, place the row */
+ NW_GDI_Rectangle_t rowBoxBounds = NW_LMgr_Box_GetFormatBounds( thisRow );
+ rowBoxBounds.point.x = atX;
+ rowBoxBounds.point.y = atY;
+ NW_LMgr_Box_SetFormatBounds( thisRow, rowBoxBounds );
+ }
+ NW_CATCH(status) {
+ }
+ NW_FINALLY {
+ return status;
+ }
+ NW_END_TRY
+}
+
+/* ------------------------------------------------------------------------- */
+NW_LMgr_StaticTableRowBox_t*
+NW_LMgr_StaticTableRowBox_New (NW_ADT_Vector_Metric_t numProperties)
+{
+ return (NW_LMgr_StaticTableRowBox_t*)
+ NW_Object_New (&NW_LMgr_StaticTableRowBox_Class, numProperties);
+}