23#include "../lout/msg.h"
24#include "../lout/misc.hh"
25#include "../lout/debug.hh"
52 children =
new misc::SimpleVector <Child*> (16);
56 colWidths =
new misc::SimpleVector <int> (8);
57 cumHeight =
new misc::SimpleVector <int> (8);
59 baseline =
new misc::SimpleVector <int> (8);
60 rowStyle =
new misc::SimpleVector <core::style::Style*> (8);
75 for (
int i = 0; i <
children->size (); i++) {
79 delete children->get(i)->cell.widget;
89 for (
int i = 0; i <
rowStyle->size (); i++)
117 for (
int col = 0; col <
numCols; col++)
147 for (
int col = 0; col <
numCols; col++) {
168 DBG_OBJ_ENTER (
"resize", 0,
"sizeAllocateImpl",
"%d, %d; %d * (%d + %d)",
183 for (
int col = 0; col <
numCols; col++) {
184 for (
int row = 0; row <
numRows; row++) {
187 int width = (
children->get(n)->cell.colspanEff - 1)
189 for (
int i = 0; i <
children->get(n)->cell.colspanEff; i++)
195 children->get(n)->cell.widget->sizeRequest (&childRequisition);
197 childAllocation.
x = x;
199 childAllocation.
width = width;
204 - childRequisition.
ascent;
205 children->get(n)->cell.widget->sizeAllocate (&childAllocation);
227 DBG_OBJ_ENTER (
"resize", 0,
"getAvailWidthOfChild",
"%p, %s",
228 child, forceValue ?
"true" :
"false");
273 DBG_OBJ_ENTER (
"resize", 0,
"calcAvailWidthForDescendant",
"%p", child);
277 Widget *actualChild = child;
278 while (actualChild != NULL && actualChild->getParent () !=
this)
279 actualChild = actualChild->getParent ();
281 assert (actualChild != NULL);
289 "childNo = getParentRefInFlowSubRef (%d) = %d, "
290 "column = %d %% %d = %d",
291 actualChild, actualChild->parentRef, childNo, childNo,
293 int colspanEff =
children->get(childNo)->cell.colspanEff;
294 DBG_OBJ_MSGF (
"resize", 1,
"calculated from column %d, colspanEff = %d",
298 for (
int i = 0; i < colspanEff; i++)
302 if (child != actualChild) {
308 int corrWidth = width;
309 child->calcFinalWidth (child->getStyle(), -1,
this, 0,
true, &corrWidth);
334 for (
int col = 0; col <
numCols; col++) {
335 for (
int row = 0; row <
numRows; row++) {
338 children->get(n)->cell.widget->containerSizeChanged ();
349 DBG_OBJ_ENTER (
"resize", 0,
"affectsSizeChangeContainerChild",
"%p", child);
364 DBG_OBJ_MSGF (
"resize", 1,
"=> %s", ret ?
"true" :
"false");
382 DBG_OBJ_ENTER (
"draw", 0,
"Table::drawLevel",
"[%d, %d, %d * %d], %s",
394 for (
int row = 0; row <
numRows; row++) {
398 width - 2*
getStyle()->hBorderSpacing,
400 -
getStyle()->vBorderSpacing,
false);
406 for (
int i = 0; i <
children->size (); i++) {
411 && child->intersects (
this, area, &childArea))
412 child->
draw (view, &childArea, context);
418 OOFAwareWidget::drawLevel (view, area, level, context);
429 DBG_OBJ_ENTER (
"events", 0,
"Table::getWidgetAtPointLevel",
"%d, %d, %s",
432 Widget *widgetAtPoint = NULL;
436 for (
int i =
children->size () - 1; widgetAtPoint == NULL && i >= 0;
441 widgetAtPoint = child->getWidgetAtPoint (x, y, context);
448 OOFAwareWidget::getWidgetAtPointLevel (x, y, level, context);
455 return widgetAtPoint;
471 widget, colspan, rowspan);
473 const int maxspan = 100;
479 if (colspan > maxspan || colspan < 0) {
480 MSG_WARN(
"colspan = %d is set to %d.\n", colspan, maxspan);
483 if (rowspan > maxspan || rowspan <= 0) {
484 MSG_WARN(
"rowspan = %d is set to %d.\n", rowspan, maxspan);
490 MSG(
"addCell: cell without row.\n");
495 MSG_WARN(
"Last cell had colspan=0.\n");
503 colspanEff = colspan;
511 _MSG(
"Table::addCell numCols=%d,curCol=%d,colspan=%d,colspanEff=%d\n",
521 for (
int col = 0; col < colspanEff; col++)
522 for (
int row = 0; row < rowspan; row++)
523 if (!(col == 0 && row == 0)) {
528 MSG(
"Overlapping spans in table.\n");
532 child =
new Child ();
540 child =
new Child ();
556 widget->setParent (
this);
563 for (
int row = 0; row <
numRows; row++) {
564 for (
int col = 0; col <
numCols; col++) {
606 for (
int row = 0; row <=
numRows; row++) {
609 child =
children->get(n)->cell.widget;
726 assert (newNumCols >=
numCols);
727 assert (newNumRows >=
numRows);
729 children->setSize (newNumCols * newNumRows);
733 for (
int row = newNumRows - 1; row >= 0; row--) {
734 int colspan0Col = -1, colspan0Row = -1;
737 for (
int col =
numCols - 1; col >= 0; col--) {
738 int n = row * newNumCols + col;
743 if (
children->get(n)->cell.colspanOrig == 0) {
746 children->get(n)->cell.colspanEff = newNumCols - col;
752 children->get(n)->spanSpace.startCol)
753 ->cell.colspanOrig == 0) {
754 colspan0Col =
children->get(n)->spanSpace.startCol;
755 colspan0Row =
children->get(n)->spanSpace.startRow;
763 if (colspan0Col == -1) {
764 for (
int col =
numCols; col < newNumCols; col++)
765 children->set (row * newNumCols + col, NULL);
767 for (
int col =
numCols; col < newNumCols; col++) {
772 children->set (row * newNumCols + col, child);
779 for (
int row =
numRows; row < newNumRows; row++)
780 for (
int col = 0; col < newNumCols; col++)
781 children->set (row * newNumCols + col, NULL);
785 for (
int row =
numRows; row < newNumRows; row++)
791 for (
int row = 1; row < newNumRows; row++)
792 for (
int col = 0; col < newNumCols; col++) {
793 int n = row * newNumCols + col;
827 calcHeights ?
"true" :
"false");
832 if (calcHeights ? (extremesChanget || sizeChanged) :
843 calcHeights ?
"true" :
"false");
861 for (
int row = 0; row <
numRows; row++) {
862 int n = row *
numCols + col, col2;
866 switch (child->
type) {
880 for (col2 = col - 1; col2 >= 0 && cell == NULL; col2--) {
894 cell->containerSizeChanged ();
906 calcHeights ?
"true" :
"false");
919 int totalWidth =
misc::max (availWidth, corrWidth)
923 "totalWidth = max (%d, %d) - ((%d - 1) * %d + %d) = <b>%d</b>",
933 colWidths =
new misc::SimpleVector <int> (8);
936 int minWidth = 0, minWidthIntrinsic = 0, maxWidth = 0;
937 for (
int col = 0; col <
colExtremes->size(); col++) {
939 minWidthIntrinsic +=
colExtremes->getRef(col)->minWidthIntrinsic;
944 bool totalWidthSpecified =
false;
951 if (testReq.
width != -1)
952 totalWidthSpecified =
true;
956 "minWidth = %d, minWidthIntrinsic = %d, maxWidth %d, "
957 "totalWidth = %d, %s",
958 minWidth, minWidthIntrinsic, maxWidth, totalWidth,
959 totalWidthSpecified ?
"specified" :
"not specified");
961 if (minWidth > totalWidth) {
962 DBG_OBJ_MSG (
"resize", 1,
"case 1: minWidth > totalWidth");
999 DBG_OBJ_MSG (
"resize", 1,
"case 1a: simple apportioning");
1004 DBG_OBJ_MSG (
"resize", 1,
"case 1b: treat percentages specially");
1011 int widthPartPer = totalWidth, minWidthIntrinsicPer = 0;
1012 for (
int col = 0; col <
colExtremes->size(); col++)
1014 minWidthIntrinsicPer +=
1024 "widthPartPer = %d, minWidthIntrinsicPer = %d",
1025 widthPartPer, minWidthIntrinsicPer);
1027 for (
int col = 0; col <
colExtremes->size(); col++)
1029 int colWidth =
colExtremes->getRef(col)->minWidth;
1030 int minIntr =
colExtremes->getRef(col)->minWidthIntrinsic;
1032 minWidthIntrinsicPer -= minIntr;
1034 if (colWidth > widthPartPer - minWidthIntrinsicPer)
1035 colWidth = widthPartPer - minWidthIntrinsicPer;
1038 widthPartPer -= colWidth;
1041 "#%d: colWidth = %d ... widthPartPer = %d, "
1042 "minWidthIntrinsicPer = %d",
1043 col, colWidth, widthPartPer, minWidthIntrinsicPer);
1050 }
else if (totalWidthSpecified && totalWidth > maxWidth) {
1052 "case 2: totalWidthSpecified && totalWidth > maxWidth");
1071 "subcase 2a: no or all columns with specified width");
1076 "subcase 2b: %d column(s) with specified width",
1085 widthsNotSpecified.
setSize (numNotSpecified);
1088 int totalWidthNotSpecified = totalWidth, indexNotSpecified = 0;
1089 for (
int col = 0; col <
colExtremes->size(); col++)
1091 totalWidthNotSpecified -=
colExtremes->getRef(col)->maxWidth;
1093 widthsNotSpecified.
set (indexNotSpecified,
1095 indexNotSpecified++;
1099 DBG_OBJ_MSGF (
"resize", 1,
"totalWidthNotSpecified = %d",
1100 totalWidthNotSpecified);
1105 for (
int i = 0; i < widthsNotSpecified.
size (); i++)
1107 i, widthsNotSpecified.
get (i));
1113 (
void*)&widthsNotSpecified, &apportionDest, 0);
1119 for (
int i = 0; i < apportionDest.
size (); i++)
1125 DBG_OBJ_MSG (
"resize", 1,
"finally setting column widths:");
1128 indexNotSpecified = 0;
1129 for (
int col = 0; col <
colExtremes->size(); col++)
1131 DBG_OBJ_MSGF (
"resize", 1,
"#%d: specified, gets maximum %d",
1135 DBG_OBJ_MSGF (
"resize", 1,
"#%d: not specified, gets value %d "
1136 "at position %d from temporary list",
1137 col, apportionDest.
get (indexNotSpecified),
1140 indexNotSpecified++;
1148 totalWidthSpecified ? totalWidth :
misc::min (totalWidth, maxWidth);
1149 DBG_OBJ_MSGF (
"resize", 1,
"case 3: else; width = %d", width);
1157 for (
int col = 0; col <
colExtremes->size(); col++) {
1172 for (
int col = 0; col <
numCols; col++) {
1176 for (
int row = 0; row <
numRows; row++) {
1181 children->get(n)->cell.widget->containerSizeChanged ();
1186 delete oldColWidths;
1190 for (
int row = 0; row <
numRows; row++) {
1196 for (
int col = 0; col <
numCols; col++) {
1201 int width = (
children->get(n)->cell.colspanEff - 1)
1203 for (
int i = 0; i <
children->get(n)->cell.colspanEff; i++)
1209 children->get(n)->cell.widget->sizeRequest (&childRequisition);
1210 childHeight = childRequisition.
ascent + childRequisition.
descent;
1211 if (
children->get(n)->cell.rowspan == 1) {
1212 rowHeight =
misc::max (rowHeight, childHeight);
1234 int *rowHeight = NULL;
1239 int rs =
children->get(n)->cell.rowspan;
1242 children->get(n)->cell.widget->sizeRequest (&childRequisition);
1243 int spanHeight = childRequisition.
ascent + childRequisition.
descent
1245 if (sumRows >= spanHeight)
1249 _MSG(
"Short cell %d, sumRows=%d spanHeight=%d\n",
1250 n,sumRows,spanHeight);
1255 for (
int i = 0; i <
numRows; i++)
1259 MSG(
" rowHeight { ");
1260 for (
int i = 0; i <
numRows; i++)
1261 MSG(
"%d ", rowHeight[i]);
1266 int cumHnew_i = 0, cumh_i = 0, hnew_i;
1267 for (
int i = row; i < row + rs; ++i) {
1269 sumRows == 0 ? (int)((
float)(spanHeight-cumHnew_i)/(row+rs-i)) :
1270 (sumRows-cumh_i) <= 0 ? 0 :
1271 (int)((
float)(spanHeight-cumHnew_i)*rowHeight[i]/(sumRows-cumh_i));
1273 _MSG(
" i=%-3d h=%d hnew_i=%d =%d*%d/%d cumh_i=%d cumHnew_i=%d\n",
1274 i,rowHeight[i],hnew_i,
1275 spanHeight-cumHnew_i,rowHeight[i],sumRows-cumh_i,
1278 cumHnew_i += hnew_i;
1279 cumh_i += rowHeight[i];
1280 rowHeight[i] = hnew_i;
1283 for (
int i = 0; i <
numRows; ++i)
1306 for (
int col = 0; col <
numCols; col++) {
1319 for (
int row = 0; row <
numRows; row++) {
1326 if (
children->get(n)->cell.colspanEff == 1) {
1328 children->get(n)->cell.widget->getExtremes (&cellExtremes);
1354 children->get(n)->cell.widget->getStyle()->width;
1361 DBG_OBJ_MSGF (
"resize", 1,
"column: %d / %d (%d / %d)",
1383 for (
int i = 0; i < colSpanCells.
size(); i++) {
1384 int n = colSpanCells.
get (i);
1386 int cs =
children->get(n)->cell.colspanEff;
1389 children->get(n)->cell.widget->getExtremes (&cellExtremes);
1397 children->get(n)->cell.widget->getStyle()->width;
1399 for (
int j = 0; j < cs; j++)
1402 for (
int j = 0; j < cs; j++)
1456 "%d, %d, ..., %s, %s, ...",
1460 int cellMin =
getExtreme (cellExtremes, minExtrMod);
1461 int cellMax =
getExtreme (cellExtremes, maxExtrMod);
1463 int minSumCols = 0, maxSumCols = 0;
1465 for (
int j = 0; j < cs; j++) {
1466 minSumCols +=
getColExtreme (col + j, minExtrMod, extrData);
1467 maxSumCols +=
getColExtreme (col + j, maxExtrMod, extrData);
1470 DBG_OBJ_MSGF (
"resize", 1,
"cs = %d, cell: %d / %d, sum: %d / %d\n",
1471 cs, cellMin, cellMax, minSumCols, maxSumCols);
1473 bool changeMin = cellMin > minSumCols;
1474 bool changeMax = cellMax > maxSumCols;
1475 if (changeMin || changeMax) {
1483 for (
int j = 0; j < cs; j++) {
1504 DBG_OBJ_ENTER (
"resize", 0,
"calcAdjustmentWidthSpanMultiCols",
1505 "%d, %d, ...", col, cs);
1507 int sumAdjustmentWidth = 0;
1508 for (
int j = 0; j < cs; j++)
1509 sumAdjustmentWidth +=
colExtremes->getRef(col + j)->adjustmentWidth;
1514 NULL, &newAdjustmentWidth, 0);
1515 for (
int j = 0; j < cs; j++)
1517 newAdjustmentWidth.
get (j);
1530 DBG_OBJ_ENTER (
"resize", 0,
"apportion2",
"%d, %d, %d, %s, %s, ..., %d",
1534 if (lastCol >= firstCol) {
1535 dest->
setSize (destOffset + lastCol - firstCol + 1, 0);
1537 int totalMin = 0, totalMax = 0;
1538 for (
int col = firstCol; col <= lastCol; col++) {
1544 "totalWidth = %d, totalMin = %d, totalMax = %d",
1545 totalWidth, totalMin, totalMax);
1581 int totalDiffExtr = totalMax - totalMin;
1582 if (totalDiffExtr != 0) {
1593 int totalDiffWidth = totalWidth - totalMin;
1594 int cumDiffExtr = 0, cumDiffWidth = 0;
1596 for (
int col = firstCol; col <= lastCol; col++) {
1599 int diffExtr = max - min;
1601 cumDiffExtr += diffExtr;
1603 (cumDiffExtr * totalDiffWidth) / totalDiffExtr - cumDiffWidth;
1604 cumDiffWidth += diffWidth;
1606 dest->
set (destOffset - firstCol + col, diffWidth + min);
1608 }
else if (totalMin != 0) {
1618 int cumMin = 0, cumWidth = 0;
1619 for (
int col = firstCol; col <= lastCol; col++) {
1622 int width = (cumMin * totalWidth) / totalMin - cumWidth;
1625 dest->
set (destOffset - firstCol + col, width);
1637 int cumWidth = 0, n = (lastCol - firstCol + 1);
1638 for (
int col = firstCol; col <= lastCol; col++) {
1639 int i = (col - firstCol + 1);
1640 int width = (i * totalWidth) / n - cumWidth;
1643 dest->
set (destOffset - firstCol + col, width);
AlignedTableCell * getCellRef()
void drawLevel(core::View *view, core::Rectangle *area, int level, core::DrawingContext *context)
int getExtreme(core::Extremes *extremes, ExtrMod mod)
void setCumHeight(int row, int value)
lout::misc::SimpleVector< core::style::Style * > * rowStyle
int calcAvailWidthForDescendant(Widget *child)
Table(bool limitTextWidth)
void calcAdjustmentWidthSpanMultiCols(int col, int cs, core::Extremes *cellExtremes)
int getColExtreme(int col, ExtrMod mod, void *data)
lout::misc::SimpleVector< int > * baseline
void calcExtremesSpanMultiCols(int col, int cs, core::Extremes *cellExtremes, ExtrMod minExtrMod, ExtrMod maxExtrMod, void *extrData)
void forceCalcColumnExtremes()
Fills dw::Table::colExtremes in all cases.
void calcCellSizes(bool calcHeights)
void forceCalcCellSizes(bool calcHeights)
lout::misc::SimpleVector< int > * colWidths
The widths of all columns.
int applyPerWidth(int containerWidth, core::style::Length perWidth)
int getAvailWidthOfChild(Widget *child, bool forceValue)
void resizeDrawImpl()
Called after sizeAllocateImpl() to redraw necessary areas.
bool affectsSizeChangeContainerChild(Widget *child)
void addCell(Widget *widget, int colspan, int rowspan)
void getExtremesSimpl(core::Extremes *extremes)
Simple variant, to be implemented by widgets with extremes not depending on positions.
void containerSizeChangedForChildren()
void addRow(core::style::Style *style)
bool usesAvailWidth()
Must be implemengted by a method returning true, when getAvailWidth() is called.
lout::misc::SimpleVector< core::Extremes > * colExtremes
The extremes of all columns.
lout::misc::SimpleVector< int > * rowSpanCells
If a Cell has rowspan > 1, it goes into this array.
lout::misc::SimpleVector< Child * > * children
void actuallyCalcCellSizes(bool calcHeights)
void sizeAllocateImpl(core::Allocation *allocation)
See Sizes of Dillo Widgets.
bool colWidthsUpToDateWidthColExtremes
void sizeRequestSimpl(core::Requisition *requisition)
Simple variant, to be implemented by widgets with sizes not depending on positions.
void removeChild(Widget *child)
int numColWidthPercentage
core::Iterator * iterator(core::Content::Type mask, bool atEnd)
Return an iterator for this widget.
void setColExtreme(int col, ExtrMod mod, void *data, int value)
static bool getAdjustTableMinWidth()
lout::misc::SimpleVector< int > * cumHeight
Row cumulative height array: cumHeight->size() is numRows + 1, cumHeight->get(0) is 0,...
void setExtreme(core::Extremes *extremes, ExtrMod mod, int value)
lout::misc::SimpleVector< bool > * colWidthPercentage
Wether the column itself (in the future?) or at least one cell in this column or spanning over this c...
void reallocChildren(int newNumCols, int newNumRows)
void apportion2(int totalWidth, int firstCol, int lastCol, ExtrMod minExtrMod, ExtrMod maxExtrMod, void *extrData, lout::misc::SimpleVector< int > *dest, int destOffset)
Actual apportionment function.
int applyPerHeight(int containerHeight, core::style::Length perHeight)
Widget * getWidgetAtPointLevel(int x, int y, int level, core::GettingWidgetAtPointContext *context)
lout::misc::SimpleVector< bool > * colWidthSpecified
Wether the column itself (in the future?) or at least one cell in this column or spanning over this c...
static bool adjustTableMinWidth
const char * getExtrModName(ExtrMod mod)
Set at the top when drawing.
Set at the top when getting the widget at the point.
Iterators are used to iterate through the contents of a widget.
dw::core::Shape implemtation for simple rectangles.
void draw(core::View *view, core::style::Style *style, int x, int y)
static bool handledByStackingContextMgr(Widget *widget)
An interface to encapsulate platform dependent drawing.
Represents additional data for OOF containers.
virtual int getAvailWidthOfChild(core::Widget *child, bool forceValue)=0
virtual bool dealingWithSizeOfChild(core::Widget *child)=0
bool instanceOf(int otherClassId)
Returns, whether this class is an instance of the class, given by otherClassId, or of a sub class of ...
void registerName(const char *className, int *classId)
This method must be called in the constructor for the sub class.
Simple (simpler than container::untyped::Vector and container::typed::Vector) template based vector.
void setSize(int newSize)
Set the size explicitly.
void increase()
Increase the vector size by one.
void copyTo(SimpleVector< T > *dest, int thisStart=0, int thisLast=-1, int destStart=0)
Copies some elements into another vector of the same type.
void set(int i, T t)
Store an object in the vector.
T get(int i) const
Return the one element, explicitly.
int size() const
Return the number of elements put into this vector.
void setLast(T t)
Store an object at the end of the vector.
#define DBG_OBJ_ENTER0(aspect, prio, funname)
#define DBG_OBJ_ARRSET_BOOL(var, ind, val)
#define DBG_OBJ_CREATE(klass)
#define DBG_OBJ_SET_BOOL(var, val)
#define DBG_OBJ_MSG_END()
#define DBG_OBJ_MSGF(aspect, prio, fmt,...)
#define DBG_OBJ_SET_NUM(var, val)
#define DBG_OBJ_MSG(aspect, prio, msg)
#define DBG_OBJ_ARRSET_NUM(var, ind, val)
#define DBG_OBJ_ENTER(aspect, prio, funname, fmt,...)
#define DBG_OBJ_MSG_START()
#define DBG_OBJ_ARRATTRSET_NUM(var, ind, attr, val)
#define DBG_OBJ_SET_NUM_O(obj, var, val)
int multiplyWithPerLength(int x, Length l)
Multiply an int with a percentage length, returning int.
int Length
Type for representing all lengths within dw::core::style.
bool isPerLength(Length l)
Returns true if l is a percentage.
@ LENGTH_AUTO
Represents "auto" lengths.
void splitHeightPreserveDescent(int height, int *ascent, int *descent)
Dw is in this namespace, or sub namespaces of this one.
struct SpanSpace spanSpace
enum dw::Table::Child::@22 type
Represents the allocation, i.e.