summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dw/ruler.cc2
-rw-r--r--dw/table.cc4
-rw-r--r--dw/textblock.cc112
-rw-r--r--dw/textblock.hh8
-rw-r--r--dw/widget.cc135
-rw-r--r--dw/widget.hh20
6 files changed, 254 insertions, 27 deletions
diff --git a/dw/ruler.cc b/dw/ruler.cc
index 3599c32a..c19b30c0 100644
--- a/dw/ruler.cc
+++ b/dw/ruler.cc
@@ -34,7 +34,7 @@ Ruler::Ruler ()
void Ruler::sizeRequestImpl (core::Requisition *requisition)
{
- requisition->width = lout::misc::max (getAvailWidth (),
+ requisition->width = lout::misc::max (getAvailWidth (true),
getStyle()->boxDiffWidth ());
requisition->ascent = getStyle()->boxOffsetY ();
requisition->descent = getStyle()->boxRestHeight ();
diff --git a/dw/table.cc b/dw/table.cc
index d15100b7..e40d43ca 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -477,13 +477,13 @@ void Table::forceCalcCellSizes ()
* rendering is implemented, to handle fixed positions etc.,
* as defined by CSS2.)
*/
- int availWidth = getAvailWidth ();
+ int availWidth = getAvailWidth (true);
totalWidth =
misc::min (core::style::multiplyWithPerLength (availWidth,
getStyle()->width),
availWidth);
} else if (getStyle()->width == core::style::LENGTH_AUTO) {
- totalWidth = getAvailWidth ();
+ totalWidth = getAvailWidth (true);
forceTotalWidth = 0;
}
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 7da706f7..e5f16186 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -333,7 +333,7 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition)
DBG_OBJ_MSG ("resize", 0, "<b>sizeRequestImpl</b> ()");
DBG_OBJ_MSG_START ();
- lineBreakWidth = getAvailWidth ();
+ lineBreakWidth = getAvailWidth (true);
rewrap ();
showMissingLines ();
@@ -401,6 +401,8 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition)
requisition->width);
}
+ correctRequisition (requisition, core::splitHeightPreserveAscent);
+
DBG_OBJ_MSGF ("resize", 1, "=> %d * (%d + %d)",
requisition->width, requisition->ascent, requisition->descent);
@@ -776,12 +778,13 @@ bool Textblock::isBlockLevel ()
return true;
}
-int Textblock::getAvailWidthOfChild (Widget *child)
+int Textblock::getAvailWidthOfChild (Widget *child, bool forceValue)
{
// TODO Implement also for ListItem (subtract space for bullet).
// TODO Correct by extremes?
- DBG_OBJ_MSGF ("resize", 0, "<b>getAvailWidthOfChild</b> (%p)", child);
+ DBG_OBJ_MSGF ("resize", 0, "<b>getAvailWidthOfChild</b> (%p, %s)",
+ child, forceValue ? "true" : "false");
DBG_OBJ_MSG_START ();
int width;
@@ -790,12 +793,21 @@ int Textblock::getAvailWidthOfChild (Widget *child)
// TODO What does "width" exactly stand for? (Content or all?)
width = core::style::absLengthVal (child->getStyle()->width);
else {
- int containerWidth = getAvailWidth () - boxDiffWidth ();
- if (core::style::isPerLength (child->getStyle()->width))
- width = core::style::multiplyWithPerLength (containerWidth,
- child->getStyle()->width);
- else
- width = containerWidth;
+ int availWidth = getAvailWidth (forceValue);
+ if (availWidth == -1) {
+ assert (!forceValue);
+ width = -1;
+ } else {
+ int containerWidth = availWidth - boxDiffWidth ();
+ if (core::style::isPerLength (child->getStyle()->width))
+ width =
+ core::style::multiplyWithPerLength (containerWidth,
+ child->getStyle()->width);
+ else
+ // A textblock will use the whole width (but not the whole
+ // height, see getAvailHeightOfChild()).
+ width = forceValue ? containerWidth : 1;
+ }
}
DBG_OBJ_MSGF ("resize", 1, "=> %d", width);
@@ -804,6 +816,88 @@ int Textblock::getAvailWidthOfChild (Widget *child)
return width;
}
+int Textblock::getAvailHeightOfChild (Widget *child)
+{
+ // TODO Implement also for ListItem (subtract space for bullet).
+ // TODO Correct by extremes?
+
+ DBG_OBJ_MSGF ("resize", 0, "<b>getAvailHeightOfChild</b> (%p)", child);
+ DBG_OBJ_MSG_START ();
+
+ int height;
+
+ if (core::style::isAbsLength (child->getStyle()->height))
+ // TODO What does "height" exactly stand for? (Content or all?)
+ height = core::style::absLengthVal (child->getStyle()->height);
+ else {
+ int availHeight = getAvailHeight ();
+ if (availHeight == -1)
+ height = -1;
+ else {
+ int containerHeight = availHeight - boxDiffHeight ();
+ if (core::style::isPerLength (child->getStyle()->height))
+ height =
+ core::style::multiplyWithPerLength (containerHeight,
+ child->getStyle()->height);
+ else
+ height = -1;
+ }
+ }
+
+ DBG_OBJ_MSGF ("resize", 1, "=> %d", height);
+ DBG_OBJ_MSG_END ();
+
+ return height;
+}
+
+void Textblock::correctRequisitionOfChild (Widget *child,
+ core::Requisition *requisition,
+ void (*splitHeightFun)(int height,
+ int *ascent,
+ int *descent))
+{
+ // TODO Implement also for ListItem (subtract space for bullet).
+ // TODO Correct by extremes?
+
+ DBG_OBJ_MSGF ("resize", 0,
+ "<b>correctRequisitionOfChild</b> (%p, %d * (%d + %d), ...)",
+ child, requisition->width, requisition->ascent,
+ requisition->descent);
+ DBG_OBJ_MSG_START ();
+
+ if (core::style::isAbsLength (child->getStyle()->width))
+ // TODO What does "width" exactly stand for? (Content or all?)
+ requisition->width = core::style::absLengthVal (child->getStyle()->width);
+ else if (core::style::isPerLength (child->getStyle()->width)) {
+ int availWidth = getAvailWidth (false);
+ if (availWidth != -1) {
+ int containerWidth = availWidth - boxDiffWidth ();
+ requisition->width =
+ core::style::multiplyWithPerLength (containerWidth,
+ child->getStyle()->width);
+ }
+ }
+
+ if (core::style::isAbsLength (child->getStyle()->height))
+ // TODO What does "height" exactly stand for? (Content or all?)
+ splitHeightFun (core::style::absLengthVal (child->getStyle()->height),
+ &requisition->ascent, &requisition->descent);
+ else if (core::style::isPerLength (child->getStyle()->height)) {
+ int availHeight = getAvailHeight ();
+ if (availHeight != -1) {
+ int containerHeight = availHeight - boxDiffHeight ();
+ splitHeightFun (core::style::multiplyWithPerLength
+ (containerHeight, child->getStyle()->height),
+ &requisition->ascent, &requisition->descent);
+ }
+ }
+
+ DBG_OBJ_MSGF ("resize", 1, "=> %d * (%d + %d)",
+ requisition->width, requisition->ascent,
+ requisition->descent);
+ DBG_OBJ_MSG_END ();
+}
+
bool Textblock::buttonPressImpl (core::EventButton *event)
{
return sendSelectionEvent (core::SelectionState::BUTTON_PRESS, event);
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 2f35acb5..dfedeeef 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -749,7 +749,13 @@ protected:
void markSizeChange (int ref);
void markExtremesChange (int ref);
- int getAvailWidthOfChild (Widget *child);
+ int getAvailWidthOfChild (Widget *child, bool forceValue);
+ int getAvailHeightOfChild (Widget *child);
+ void correctRequisitionOfChild (Widget *child,
+ core::Requisition *requisition,
+ void (*splitHeightFun)(int height,
+ int *ascent,
+ int *descent));
void notifySetAsTopLevel();
void notifySetParent();
diff --git a/dw/widget.cc b/dw/widget.cc
index 792647e9..79689e48 100644
--- a/dw/widget.cc
+++ b/dw/widget.cc
@@ -340,29 +340,32 @@ void Widget::sizeRequest (Requisition *requisition)
DBG_OBJ_MSG_END ();
}
-int Widget::getAvailWidth ()
+int Widget::getAvailWidth (bool forceValue)
{
// TODO Correct by extremes?
- DBG_OBJ_MSG ("resize", 0, "<b>getAvailWidth</b> ()");
+ DBG_OBJ_MSGF ("resize", 0, "<b>getAvailWidth</b> (%s)",
+ forceValue ? "true" : "false");
DBG_OBJ_MSG_START ();
int width;
if (container == NULL) {
// TODO Consider nested layouts (e. g. <button>).
- int viewportWidth =
- layout->viewportWidth - (layout->canvasHeightGreater ?
- layout->vScrollbarThickness : 0);
if (style::isAbsLength (getStyle()->width))
width = style::absLengthVal (getStyle()->width);
- else if (style::isPerLength (getStyle()->width))
- width = style::multiplyWithPerLength (viewportWidth,
- getStyle()->width);
- else
- width = viewportWidth;
+ else {
+ int viewportWidth =
+ layout->viewportWidth - (layout->canvasHeightGreater ?
+ layout->vScrollbarThickness : 0);
+ if (style::isPerLength (getStyle()->width)) {
+ width = style::multiplyWithPerLength (viewportWidth,
+ getStyle()->width);
+ } else
+ width = forceValue ? viewportWidth : -1;
+ }
} else
- width = container->getAvailWidthOfChild (this);
+ width = container->getAvailWidthOfChild (this, forceValue);
DBG_OBJ_MSGF ("resize", 1, "=> %d", width);
DBG_OBJ_MSG_END ();
@@ -370,6 +373,80 @@ int Widget::getAvailWidth ()
return width;
}
+int Widget::getAvailHeight ()
+{
+ // TODO Correct by ... not extremes, but ...? (Height extremes?)
+
+ DBG_OBJ_MSG ("resize", 0, "<b>getAvailHeight</b> ()");
+ DBG_OBJ_MSG_START ();
+
+ int height;
+
+ if (container == NULL) {
+ // TODO Consider nested layouts (e. g. <button>).
+ if (style::isAbsLength (getStyle()->height))
+ height = style::absLengthVal (getStyle()->height);
+ else if (style::isPerLength (getStyle()->height))
+ // Notice that here -- unlike getAvailWidth() --
+ // layout->hScrollbarThickness is not considered here;
+ // something like canvasWidthGreater (analogue to
+ // canvasHeightGreater) would be complicated and lead to
+ // possibly contradictory self-references.
+ height = style::multiplyWithPerLength (layout->viewportHeight,
+ getStyle()->height);
+ else
+ height = -1;
+ } else
+ height = container->getAvailHeightOfChild (this);
+
+ DBG_OBJ_MSGF ("resize", 1, "=> %d", height);
+ DBG_OBJ_MSG_END ();
+
+ return height;
+}
+
+void Widget::correctRequisition (Requisition *requisition,
+ void (*splitHeightFun)(int height, int *ascent,
+ int *descent))
+{
+ // TODO Correct by extremes?
+
+ DBG_OBJ_MSGF ("resize", 0, "<b>correctRequisition</b> (%d * (%d + %d), ...)",
+ requisition->width, requisition->ascent, requisition->descent);
+ DBG_OBJ_MSG_START ();
+
+ if (container == NULL) {
+ if (core::style::isAbsLength (getStyle()->width))
+ // TODO What does "width" exactly stand for? (Content or all?)
+ requisition->width = core::style::absLengthVal (getStyle()->width);
+ else if (core::style::isPerLength (getStyle()->width)) {
+ int viewportWidth =
+ layout->viewportWidth - (layout->canvasHeightGreater ?
+ layout->vScrollbarThickness : 0);
+ requisition->width = style::multiplyWithPerLength (viewportWidth,
+ getStyle()->width);
+ }
+
+ if (core::style::isAbsLength (getStyle()->height))
+ // TODO What does "height" exactly stand for? (Content or all?)
+ splitHeightFun (core::style::absLengthVal (getStyle()->height),
+ &requisition->ascent, &requisition->descent);
+ else if (core::style::isPerLength (getStyle()->height)) {
+ // For layout->viewportHeight, see comment in getAvailHeight().
+ splitHeightFun (core::style::multiplyWithPerLength
+ (layout->viewportHeight, getStyle()->height),
+ &requisition->ascent, &requisition->descent);
+ }
+ } else
+ container->correctRequisitionOfChild (this, requisition, splitHeightFun);
+
+ DBG_OBJ_MSGF ("resize", 1, "=> %d * (%d + %d)",
+ requisition->width, requisition->ascent,
+ requisition->descent);
+ DBG_OBJ_MSG_END ();
+
+}
+
/**
* \brief Wrapper for Widget::getExtremesImpl().
*/
@@ -847,13 +924,29 @@ void Widget::markExtremesChange (int ref)
{
}
-int Widget::getAvailWidthOfChild (Widget *child)
+int Widget::getAvailWidthOfChild (Widget *child, bool forceValue)
+{
+ // Must be implemented for possible containers.
+ misc::assertNotReached ();
+ return 0;
+}
+
+int Widget::getAvailHeightOfChild (Widget *child)
{
// Must be implemented for possible containers.
misc::assertNotReached ();
return 0;
}
+void Widget::correctRequisitionOfChild (Widget *child, Requisition *requisition,
+ void (*splitHeightFun)(int height,
+ int *ascent,
+ int *descent))
+{
+ // Must be implemented for possible containers.
+ misc::assertNotReached ();
+}
+
/**
* \brief This method is called after a widget has been set as the top of a
* widget tree.
@@ -922,5 +1015,23 @@ void Widget::removeChild (Widget *child)
misc::assertNotReached ();
}
+void splitHeightPreserveAscent (int height, int *ascent, int *descent)
+{
+ *descent = height - *ascent;
+ if (*descent < 0) {
+ *descent = 0;
+ *ascent = height;
+ }
+}
+
+void splitHeightPreserveDescent (int height, int *ascent, int *descent)
+{
+ *ascent = height - *descent;
+ if (*ascent < 0) {
+ *ascent = 0;
+ *descent = height;
+ }
+}
+
} // namespace core
} // namespace dw
diff --git a/dw/widget.hh b/dw/widget.hh
index 3d8cdbd6..09749012 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -312,7 +312,14 @@ protected:
*/
virtual void markExtremesChange (int ref);
- virtual int getAvailWidthOfChild (Widget *child);
+ virtual int getAvailWidthOfChild (Widget *child, bool forceValue);
+ virtual int getAvailHeightOfChild (Widget *child);
+ virtual void correctRequisitionOfChild (Widget *child,
+ Requisition *requisition,
+ void (*splitHeightFun)(int height,
+ int *ascent,
+ int
+ *descent));
virtual void notifySetAsTopLevel();
virtual void notifySetParent();
@@ -424,8 +431,13 @@ public:
void sizeRequest (Requisition *requisition);
void getExtremes (Extremes *extremes);
void sizeAllocate (Allocation *allocation);
- int getAvailWidth ();
+ int getAvailWidth (bool forceValue);
+ int getAvailHeight ();
+ void correctRequisition (Requisition *requisition,
+ void (*splitHeightFun)(int height, int *ascent,
+ int *descent));
+
virtual bool isBlockLevel ();
virtual bool isPossibleContainer ();
@@ -486,6 +498,10 @@ public:
virtual void removeChild (Widget *child);
};
+void splitHeightPreserveAscent (int height, int *ascent, int *descent);
+void splitHeightPreserveDescent (int height, int *ascent, int *descent);
+
+
} // namespace core
} // namespace dw