aboutsummaryrefslogtreecommitdiff
path: root/dw/outofflowmgr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dw/outofflowmgr.cc')
-rw-r--r--dw/outofflowmgr.cc265
1 files changed, 265 insertions, 0 deletions
diff --git a/dw/outofflowmgr.cc b/dw/outofflowmgr.cc
new file mode 100644
index 00000000..241e0d27
--- /dev/null
+++ b/dw/outofflowmgr.cc
@@ -0,0 +1,265 @@
+#include "outofflowmgr.hh"
+
+//#include <math.h> // testing
+
+using namespace lout::container::typed;
+using namespace lout::misc;
+using namespace dw::core;
+using namespace dw::core::style;
+
+namespace dw {
+
+OutOfFlowMgr::OutOfFlowMgr (ContainingBlock *containingBlock)
+{
+ //printf ("OutOfFlowMgr::OutOfFlowMgr\n");
+ this->containingBlock = containingBlock;
+
+ leftFloats = new Vector<Float> (1, true);
+ rightFloats = new Vector<Float> (1, true);
+}
+
+OutOfFlowMgr::~OutOfFlowMgr ()
+{
+ //printf ("OutOfFlowMgr::~OutOfFlowMgr\n");
+
+ delete leftFloats;
+ delete rightFloats;
+}
+
+void OutOfFlowMgr::sizeAllocate (Allocation *containingBlockAllocation)
+{
+ // TODO Much copy and paste.
+
+ for (int i = 0; i < leftFloats->size(); i++) {
+ Float *vloat = leftFloats->get(i);
+ assert (vloat->y != -1);
+
+ Allocation childAllocation;
+ childAllocation.x = containingBlockAllocation->x
+ + containingBlock->getCBStyle()->boxOffsetX();
+ childAllocation.y = containingBlockAllocation->y + vloat->y;
+ childAllocation.width =
+ vloat->width - containingBlock->getCBStyle()->boxOffsetX();
+ childAllocation.ascent = vloat->ascent;
+ childAllocation.descent = vloat->descent;
+
+ vloat->widget->sizeAllocate (&childAllocation);
+
+ //printf ("allocate left #%d -> (%d, %d), %d x (%d + %d)\n",
+ // i, childAllocation.x, childAllocation.y, childAllocation.width,
+ // childAllocation.ascent, childAllocation.descent);
+ }
+
+ for (int i = 0; i < rightFloats->size(); i++) {
+ Float *vloat = rightFloats->get(i);
+ assert (vloat->y != -1);
+
+ Allocation childAllocation;
+ childAllocation.x = containingBlockAllocation->x
+ + containingBlockAllocation->width - vloat->width;
+ childAllocation.y = containingBlockAllocation->y + vloat->y;
+ childAllocation.width =
+ vloat->width - containingBlock->getCBStyle()->boxRestWidth();
+ childAllocation.ascent = vloat->ascent;
+ childAllocation.descent = vloat->descent;
+
+ vloat->widget->sizeAllocate (&childAllocation);
+
+ //printf ("allocate right #%d -> (%d, %d), %d x (%d + %d)\n",
+ // i, childAllocation.x, childAllocation.y, childAllocation.width,
+ // childAllocation.ascent, childAllocation.descent);
+ }
+}
+
+
+void OutOfFlowMgr::draw (View *view, Rectangle *area)
+{
+ draw (leftFloats, view, area);
+ draw (rightFloats, view, area);
+}
+
+void OutOfFlowMgr::draw (Vector<Float> *list, View *view, Rectangle *area)
+{
+ for (int i = 0; i < list->size(); i++) {
+ Float *vloat = list->get(i);
+ assert (vloat->y != -1);
+
+ core::Rectangle childArea;
+ if (vloat->widget->intersects (area, &childArea))
+ vloat->widget->draw (view, &childArea);
+ }
+}
+
+void OutOfFlowMgr::queueResize(int ref)
+{
+}
+
+bool OutOfFlowMgr::isWidgetOutOfFlow (core::Widget *widget)
+{
+ // Will be extended for absolute positions.
+ return widget->getStyle()->vloat != FLOAT_NONE;
+}
+
+void OutOfFlowMgr::addWidget (Widget *widget)
+{
+ if (widget->getStyle()->vloat != FLOAT_NONE) {
+ Float *vloat = new Float ();
+ vloat->widget = widget;
+ vloat->y = -1;
+
+ Requisition requisition;
+ widget->sizeRequest (&requisition);
+ vloat->width = requisition.width;
+ vloat->ascent = requisition.ascent;
+ vloat->descent = requisition.descent;
+
+ switch (widget->getStyle()->vloat) {
+ case FLOAT_LEFT:
+ vloat->width += containingBlock->getCBStyle()->boxOffsetX();
+ leftFloats->put (vloat);
+ widget->parentRef = createRefLeftFloat (leftFloats->size() - 1);
+ break;
+
+ case FLOAT_RIGHT:
+ vloat->width += containingBlock->getCBStyle()->boxRestWidth();
+ rightFloats->put (vloat);
+ widget->parentRef = createRefRightFloat (rightFloats->size() - 1);
+ break;
+
+ default:
+ assertNotReached();
+ }
+ } else
+ // Will continue here for absolute positions.
+ assertNotReached();
+}
+
+OutOfFlowMgr::Float *OutOfFlowMgr::findFloatByWidget (Widget *widget)
+{
+ Vector<Float> *list = NULL;
+
+ switch (widget->getStyle()->vloat) {
+ case FLOAT_LEFT:
+ list = leftFloats;
+ break;
+
+ case FLOAT_RIGHT:
+ list = rightFloats;
+ break;
+
+ default:
+ assertNotReached();
+ }
+
+ for(int i = 0; i < list->size(); i++) {
+ Float *vloat = list->get(i);
+ if(vloat->widget == widget)
+ return vloat;
+ }
+
+ assertNotReached();
+ return NULL;
+}
+
+
+void OutOfFlowMgr::markSizeChange (int ref)
+{
+ // TODO Much copy and paste; see addWidget.
+ if (isRefLeftFloat (ref))
+ markSizeChange (leftFloats->get (getFloatIndexFromRef (ref)),
+ containingBlock->getCBStyle()->boxOffsetX());
+ else if (isRefRightFloat (ref))
+ markSizeChange (rightFloats->get (getFloatIndexFromRef (ref)),
+ containingBlock->getCBStyle()->boxRestWidth());
+ else
+ // later: absolute positions
+ assertNotReached();
+}
+
+void OutOfFlowMgr::markSizeChange (Float *vloat, int widthDiff)
+{
+ int oldWidth = vloat->width;
+ int oldHeight = vloat->ascent + vloat->descent;
+
+ Requisition requisition;
+ vloat->widget->sizeRequest (&requisition);
+ vloat->width = requisition.width + widthDiff;
+ vloat->ascent = requisition.ascent;
+ vloat->descent = requisition.descent;
+
+ if (vloat->width != oldWidth)
+ containingBlock->borderChanged (vloat->y);
+ else if (vloat->ascent + vloat->descent != oldHeight)
+ // Width remains the same, so a small optimization is possible.
+ containingBlock->borderChanged (vloat->y +
+ min (vloat->ascent + vloat->descent,
+ oldHeight));
+}
+
+void OutOfFlowMgr::markExtremesChange (int ref)
+{
+}
+
+void OutOfFlowMgr::tellNoPosition (Widget *widget)
+{
+ Float *vloat = findFloatByWidget(widget);
+ int oldY = vloat->y;
+ vloat->y = -1;
+
+ if (oldY != -1)
+ containingBlock->borderChanged (oldY);
+}
+
+void OutOfFlowMgr::tellPosition (Widget *widget, int y)
+{
+ assert (y >= 0);
+
+ // TODO Test collisions; when floats overlap, the vloat->y must be larger
+ // than y.
+
+ Float *vloat = findFloatByWidget(widget);
+ int oldY = vloat->y;
+ vloat->y = y;
+
+ if (oldY == -1)
+ containingBlock->borderChanged (y);
+ else if (y != oldY)
+ containingBlock->borderChanged (min (oldY, y));
+}
+
+int OutOfFlowMgr::getLeftBorder (int y)
+{
+ //return 40 * sin ((double)y / 30);
+
+ for(int i = 0; i < leftFloats->size(); i++) {
+ Float *vloat = leftFloats->get(i);
+ if(vloat->y != - 1 && y >= vloat->y &&
+ y < vloat->y + vloat->ascent + vloat->descent) {
+ //printf (" LEFT: %d ==> %d (%d + %d)\n", y,
+ // vloat->width, vloat->ascent, vloat->descent);
+ return vloat->width;
+ }
+ }
+
+ //printf (" LEFT: %d ==> %d\n", y, 0);
+ return 0;
+}
+
+int OutOfFlowMgr::getRightBorder (int y)
+{
+ //return 40 * cos ((double)y / 30);
+
+ for(int i = 0; i < rightFloats->size(); i++) {
+ Float *vloat = rightFloats->get(i);
+ if(vloat->y != - 1 && y >= vloat->y &&
+ y < vloat->y + vloat->ascent + vloat->descent)
+ //printf (" RIGHT: %d ==> %d (%d + %d)\n", y,
+ // vloat->width, vloat->ascent, vloat->descent);
+ return vloat->width;
+ }
+
+ //printf (" RIGHT: %d ==> %d\n", y, 0);
+ return 0;
+}
+
+} // namespace dw