aboutsummaryrefslogtreecommitdiff
path: root/dw/outofflowmgr.hh
diff options
context:
space:
mode:
Diffstat (limited to 'dw/outofflowmgr.hh')
-rw-r--r--dw/outofflowmgr.hh486
1 files changed, 70 insertions, 416 deletions
diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh
index 78146d08..0ca19ee6 100644
--- a/dw/outofflowmgr.hh
+++ b/dw/outofflowmgr.hh
@@ -5,431 +5,85 @@
namespace dw {
-class Textblock;
+/**
+ * \brief Out Of Flow. See \ref dw-out-of-flow.
+ */
+namespace oof {
+
+class OOFAwareWidget;
/**
- * \brief Represents additional data for containing blocks.
+ * \brief Represents additional data for OOF containers.
*/
class OutOfFlowMgr
{
- friend class WidgetInfo;
-
-private:
- enum Side { LEFT, RIGHT };
- enum SFVType { GB, CB };
-
- Textblock *containingBlock;
-
- // These two values are redundant to TBInfo::wasAllocated and
- // TBInfo::allocation, for some special cases.
- bool containingBlockWasAllocated;
- core::Allocation containingBlockAllocation;
-
- class WidgetInfo: public lout::object::Object
- {
- private:
- bool wasAllocated;
- int xCB, yCB; // relative to the containing block
- int width, height;
-
- OutOfFlowMgr *oofm;
- core::Widget *widget;
-
- protected:
- OutOfFlowMgr *getOutOfFlowMgr () { return oofm; }
-
- public:
- WidgetInfo (OutOfFlowMgr *oofm, core::Widget *widget);
-
- inline bool wasThenAllocated () { return wasAllocated; }
- inline int getOldXCB () { return xCB; }
- inline int getOldYCB () { return yCB; }
- inline int getOldWidth () { return width; }
- inline int getOldHeight () { return height; }
-
-
- void update (bool wasAllocated, int xCB, int yCB, int width, int height);
-
- inline core::Widget *getWidget () { return widget; }
- };
-
- class Float: public WidgetInfo
- {
- public:
- class ComparePosition: public lout::object::Comparator
- {
- private:
- OutOfFlowMgr *oofm;
- Textblock *refTB;
- SFVType type; // actually only used for debugging
-
- public:
- ComparePosition (OutOfFlowMgr *oofm, Textblock *refTB, SFVType type)
- { this->oofm = oofm; this->refTB = refTB; this->type = type; }
- int compare(Object *o1, Object *o2);
- };
-
- class CompareSideSpanningIndex: public lout::object::Comparator
- {
- public:
- int compare(Object *o1, Object *o2);
- };
-
- class CompareGBAndExtIndex: public lout::object::Comparator
- {
- private:
- OutOfFlowMgr *oofm;
- SFVType type; // actually only used for debugging
-
- public:
- CompareGBAndExtIndex (OutOfFlowMgr *oofm, SFVType type)
- { this->oofm = oofm; this->type = type; }
- int compare(Object *o1, Object *o2);
- };
-
- Textblock *generatingBlock;
- int externalIndex;
- int yReq, yReal; // relative to generator, not container
- int indexGBList; /* Refers to TBInfo::leftFloatsGB or
- TBInfo::rightFloatsGB, respectively. -1
- initially. */
- int indexCBList; /* Refers to leftFloatsCB or rightFloatsCB,
- respectively. -1 initially. */
- int sideSpanningIndex, mark;
- core::Requisition size;
- int cbLineBreakWidth; /* On which the calculation of relative sizes
- is based. Height not yet used, and probably
- not added before size redesign. */
- bool dirty, sizeChangedSinceLastAllocation;
-
- Float (OutOfFlowMgr *oofm, core::Widget *widget,
- Textblock *generatingBlock, int externalIndex);
-
- inline bool isNowAllocated () { return getWidget()->wasAllocated (); }
- inline int getNewXCB () { return getWidget()->getAllocation()->x -
- getOutOfFlowMgr()->containingBlockAllocation.x; }
- inline int getNewYCB () { return getWidget()->getAllocation()->y -
- getOutOfFlowMgr()->containingBlockAllocation.y; }
- inline int getNewWidth () { return getWidget()->getAllocation()->width; }
- inline int getNewHeight () { return getWidget()->getAllocation()->ascent +
- getWidget()->getAllocation()->descent; }
- void updateAllocation ();
-
- inline int *getIndexRef (SFVType type) {
- return type == GB ? &indexGBList : &indexCBList; }
- inline int getIndex (SFVType type) { return *(getIndexRef (type)); }
- inline void setIndex (SFVType type, int value) {
- *(getIndexRef (type)) = value; }
-
- void intoStringBuffer(lout::misc::StringBuffer *sb);
-
- bool covers (Textblock *textblock, int y, int h);
- };
-
- /**
- * This list is kept sorted.
- *
- * To prevent accessing methods of the base class in an
- * uncontrolled way, the inheritance is private, not public; this
- * means that all methods must be delegated (see iterator(), size()
- * etc. below.)
- *
- * TODO Update comment: still sorted, but ...
- *
- * More: add() and change() may check order again.
- */
- class SortedFloatsVector: private lout::container::typed::Vector<Float>
- {
- public:
- SFVType type;
-
- private:
- OutOfFlowMgr *oofm;
- Side side;
-
- public:
- inline SortedFloatsVector (OutOfFlowMgr *oofm, Side side, SFVType type) :
- lout::container::typed::Vector<Float> (1, false)
- { this->oofm = oofm; this->side = side; this->type = type; }
-
- int findFloatIndex (Textblock *lastGB, int lastExtIndex);
- int find (Textblock *textblock, int y, int start, int end);
- int findFirst (Textblock *textblock, int y, int h, Textblock *lastGB,
- int lastExtIndex, int *lastReturn);
- int findLastBeforeSideSpanningIndex (int sideSpanningIndex);
- void put (Float *vloat);
-
- inline lout::container::typed::Iterator<Float> iterator()
- { return lout::container::typed::Vector<Float>::iterator (); }
- inline int size ()
- { return lout::container::typed::Vector<Float>::size (); }
- inline Float *get (int pos)
- { return lout::container::typed::Vector<Float>::get (pos); }
- inline void clear ()
- { lout::container::typed::Vector<Float>::clear (); }
- };
-
- class TBInfo: public WidgetInfo
- {
- public:
- int lineBreakWidth;
- int index; // position within "tbInfos"
-
- TBInfo *parent;
- int parentExtIndex;
-
- // These two values are set by sizeAllocateStart(), and they are
- // accessable also within sizeAllocateEnd() for the same
- // textblock, for which allocation and WAS_ALLOCATED is set
- // *after* sizeAllocateEnd(). See the two functions
- // wasAllocated(Widget*) and getAllocation(Widget*) (further
- // down) for usage.
- bool wasAllocated;
- core::Allocation allocation;
- int clearPosition;
-
- // These two lists store all floats generated by this textblock,
- // as long as this textblock is not allocates.
- SortedFloatsVector *leftFloatsGB, *rightFloatsGB;
-
- TBInfo (OutOfFlowMgr *oofm, Textblock *textblock,
- TBInfo *parent, int parentExtIndex);
- ~TBInfo ();
-
- inline bool isNowAllocated () {
- return getOutOfFlowMgr()->wasAllocated (getTextblock ()); }
- inline int getNewXCB () {
- return getOutOfFlowMgr()->getAllocation (getTextblock ())->x -
- getOutOfFlowMgr()->containingBlockAllocation.x; }
- inline int getNewYCB () {
- return getOutOfFlowMgr()->getAllocation (getTextblock ())->y -
- getOutOfFlowMgr()->containingBlockAllocation.y; }
- inline int getNewWidth () {
- return getOutOfFlowMgr()->getAllocation (getTextblock ())->width; }
- inline int getNewHeight () {
- core::Allocation *allocation =
- getOutOfFlowMgr()->getAllocation (getTextblock ());
- return allocation->ascent + allocation->descent; }
- void updateAllocation ();
-
- inline Textblock *getTextblock () { return (Textblock*)getWidget (); }
- };
-
- // These two lists store all floats, in the order in which they are
- // defined. Only used for iterators.
- lout::container::typed::Vector<Float> *leftFloatsAll, *rightFloatsAll;
-
- // These two lists store all floats whose generators are already
- // allocated.
- SortedFloatsVector *leftFloatsCB, *rightFloatsCB;
-
- // These two attributes are used in the size allocation process;
- // see sizeAllocateStart and sizeAllocateEnd.
- int lastAllocatedLeftFloat, lastAllocatedRightFloat;
-
- lout::container::typed::HashTable<lout::object::TypedPointer
- <dw::core::Widget>, Float> *floatsByWidget;
-
- lout::container::typed::Vector<TBInfo> *tbInfos;
- lout::container::typed::HashTable<lout::object::TypedPointer <Textblock>,
- TBInfo> *tbInfosByTextblock;
-
- int lastLeftTBIndex, lastRightTBIndex, leftFloatsMark, rightFloatsMark;
-
- /**
- * Variant of Widget::wasAllocated(), which can also be used within
- * OOFM::sizeAllocateEnd().
- */
- inline bool wasAllocated (Textblock *textblock) {
- return getTextblock(textblock)->wasAllocated;
- }
-
- /**
- * Variant of Widget::getAllocation(), which can also be used
- * within OOFM::sizeAllocateEnd().
- */
- inline core::Allocation *getAllocation (Textblock *textblock) {
- return &(getTextblock(textblock)->allocation);
- }
-
- void moveExternalIndices (SortedFloatsVector *list, int oldStartIndex,
- int diff);
- Float *findFloatByWidget (core::Widget *widget);
-
- void moveFromGBToCB (Side side);
- void sizeAllocateFloats (Side side, int newLastAllocatedFloat);
- int getGBWidthForAllocation (Float *vloat);
- int calcFloatX (Float *vloat, Side side, int gbX, int gbWidth);
-
- bool hasRelationChanged (TBInfo *tbInfo,int *minFloatPos,
- core::Widget **minFloat);
- bool hasRelationChanged (TBInfo *tbInfo, Side side, int *minFloatPos,
- core::Widget **minFloat);
- bool hasRelationChanged (bool oldTBAlloc,
- int oldTBx, int oldTBy, int oldTBw, int oldTBh,
- int newTBx, int newTBy, int newTBw, int newTBh,
- bool oldFlAlloc,
- int oldFlx, int oldFly, int oldFlw, int oldFlh,
- int newFlx, int newFly, int newFlw, int newFlh,
- Side side, int *floatPos);
-
- void checkAllocatedFloatCollisions (Side side);
-
- bool doFloatsExceedCB (Side side);
- bool haveExtremesChanged (Side side);
-
- void drawFloats (SortedFloatsVector *list, core::View *view,
- core::Rectangle *area);
- core::Widget *getFloatWidgetAtPoint (SortedFloatsVector *list, int x, int y,
- int level);
-
- bool collidesV (Float *vloat, Float *other, SFVType type, int *yReal,
- bool useAllocation);
- bool collidesH (Float *vloat, Float *other, SFVType type);
-
- void getFloatsListsAndSide (Float *vloat, SortedFloatsVector **listSame,
- SortedFloatsVector **listOpp, Side *side);
-
- void getFloatsSize (core::Requisition *cbReq, Side side, int *width,
- int *height);
- void getFloatsExtremes (core::Extremes *cbExtr, Side side, int *minWidth,
- int *maxWidth);
-
- TBInfo *getTextblock (Textblock *textblock);
- int getBorder (Textblock *textblock, Side side, int y, int h,
- Textblock *lastGB, int lastExtIndex);
- SortedFloatsVector *getFloatsListForTextblock (Textblock *textblock,
- Side side);
- bool hasFloat (Textblock *textblock, Side side, int y, int h,
- Textblock *lastGB, int lastExtIndex);
-
- int getFloatHeight (Textblock *textblock, Side side, int y, int h,
- Textblock *lastGB, int lastExtIndex);
-
- int calcClearPosition (Textblock *tb, Side side);
- int calcClearPosition (Textblock *tb);
-
- void ensureFloatSize (Float *vloat);
-
- void tellFloatPosition (core::Widget *widget, int yReq);
-
- static inline bool isStyleFloat (core::style::Style *style)
- { return style->vloat != core::style::FLOAT_NONE; }
- static inline bool isWidgetFloat (core::Widget *widget)
- { return isStyleFloat (widget->getStyle()); }
-
- /*
- * Format for parent ref (see also below for isRefOutOfFlow,
- * createRefNormalFlow, and getLineNoFromRef.
- *
- * Widget in flow:
- *
- * +---+ - - - +---+---+- - - - - -+---+---+---+---+
- * | line number | 0 |
- * +---+ - - - +---+---+- - - - - -+---+---+---+---+
- *
- * So, anything with the least signifant bit set to 1 is out of flow.
- *
- * Floats:
- *
- * +---+ - - - +---+---+- - - - - -+---+---+---+---+
- * | left float index | 0 | 0 | 1 |
- * +---+ - - - +---+---+- - - - - -+---+---+---+---+
- *
- * +---+ - - - +---+---+- - - - - -+---+---+---+---+
- * | right float index | 1 | 0 | 1 |
- * +---+ - - - +---+---+- - - - - -+---+---+---+---+
- *
- * Absolutely positioned blocks: solved differently in the
- * "dillo_grows" repository.
- */
-
- inline static bool isRefFloat (int ref)
- { return ref != -1 && (ref & 3) == 1; }
- inline static bool isRefLeftFloat (int ref)
- { return ref != -1 && (ref & 7) == 1; }
- inline static bool isRefRightFloat (int ref)
- { return ref != -1 && (ref & 7) == 5; }
-
- inline static int createRefLeftFloat (int index)
- { return (index << 3) | 1; }
- inline static int createRefRightFloat (int index)
- { return (index << 3) | 5; }
-
- inline static int getFloatIndexFromRef (int ref)
- { return ref == -1 ? ref : (ref >> 3); }
-
public:
- OutOfFlowMgr (Textblock *containingBlock);
- ~OutOfFlowMgr ();
-
- void sizeAllocateStart (Textblock *caller, core::Allocation *allocation);
- void sizeAllocateEnd (Textblock *caller);
- void containerSizeChangedForChildren ();
- void draw (core::View *view, core::Rectangle *area);
-
- void markSizeChange (int ref);
- void markExtremesChange (int ref);
- core::Widget *getWidgetAtPoint (int x, int y, int level);
-
- static bool isStyleOutOfFlow (core::style::Style *style)
- { return isStyleFloat (style); }
- static inline bool isWidgetOutOfFlow (core::Widget *widget)
- { return isStyleOutOfFlow (widget->getStyle()); }
-
- void addWidgetInFlow (Textblock *textblock, Textblock *parentBlock,
- int externalIndex);
- void addWidgetOOF (core::Widget *widget, Textblock *generatingBlock,
- int externalIndex);
- void moveExternalIndices (Textblock *generatingBlock, int oldStartIndex,
- int diff);
-
- void tellPosition (core::Widget *widget, int yReq);
-
- void getSize (core::Requisition *cbReq, int *oofWidth, int *oofHeight);
- void getExtremes (core::Extremes *cbExtr,
- int *oofMinWidth, int *oofMaxWidth);
-
- int getLeftBorder (Textblock *textblock, int y, int h, Textblock *lastGB,
- int lastExtIndex);
- int getRightBorder (Textblock *textblock, int y, int h, Textblock *lastGB,
- int lastExtIndex);
-
- bool hasFloatLeft (Textblock *textblock, int y, int h, Textblock *lastGB,
- int lastExtIndex);
- bool hasFloatRight (Textblock *textblock, int y, int h, Textblock *lastGB,
- int lastExtIndex);
-
- int getLeftFloatHeight (Textblock *textblock, int y, int h,
- Textblock *lastGB, int lastExtIndex);
- int getRightFloatHeight (Textblock *textblock, int y, int h,
- Textblock *lastGB, int lastExtIndex);
-
- int getClearPosition (Textblock *tb);
-
- inline static bool isRefOutOfFlow (int ref)
- { return ref != -1 && (ref & 1) != 0; }
- inline static int createRefNormalFlow (int lineNo) { return lineNo << 1; }
- inline static int getLineNoFromRef (int ref)
- { return ref == -1 ? ref : (ref >> 1); }
-
+ OutOfFlowMgr ();
+ virtual ~OutOfFlowMgr ();
+
+ virtual void sizeAllocateStart (OOFAwareWidget *caller,
+ core::Allocation *allocation) = 0;
+ virtual void sizeAllocateEnd (OOFAwareWidget *caller) = 0;
+ virtual void containerSizeChangedForChildren () = 0;
+ virtual void draw (core::View *view, core::Rectangle *area,
+ core::DrawingContext *context) = 0;
+
+ virtual void markSizeChange (int ref) = 0;
+ virtual void markExtremesChange (int ref) = 0;
+ virtual core::Widget *getWidgetAtPoint (int x, int y,
+ core::GettingWidgetAtPointContext
+ *context) = 0;
+
+ virtual void addWidgetInFlow (OOFAwareWidget *widget,
+ OOFAwareWidget *parent, int externalIndex) = 0;
+ virtual int addWidgetOOF (core::Widget *widget, OOFAwareWidget *generator,
+ int externalIndex) = 0;
+ virtual void moveExternalIndices (OOFAwareWidget *generator,
+ int oldStartIndex, int diff) = 0;
+
+ virtual void tellPosition (core::Widget *widget, int x, int y) = 0;
+
+ virtual void getSize (core::Requisition *containerReq, int *oofWidth,
+ int *oofHeight) = 0;
+ virtual bool containerMustAdjustExtraSpace ()= 0;
+ virtual void getExtremes (core::Extremes *containerExtr, int *oofMinWidth,
+ int *oofMaxWidth) = 0;
+
+
+ virtual int getLeftBorder (OOFAwareWidget *widget, int y, int h,
+ OOFAwareWidget *lastGen, int lastExtIndex) = 0;
+ virtual int getRightBorder (OOFAwareWidget *widget, int y, int h,
+ OOFAwareWidget *lastGen, int lastExtIndex) = 0;
+
+ virtual bool hasFloatLeft (OOFAwareWidget *widget, int y, int h,
+ OOFAwareWidget *lastGen, int lastExtIndex) = 0;
+ virtual bool hasFloatRight (OOFAwareWidget *widget, int y, int h,
+ OOFAwareWidget *lastGen, int lastExtIndex) = 0;
+
+ virtual int getLeftFloatHeight (OOFAwareWidget *widget, int y, int h,
+ OOFAwareWidget *lastGen, int lastExtIndex)
+ = 0;
+ virtual int getRightFloatHeight (OOFAwareWidget *widget, int y, int h,
+ OOFAwareWidget *lastGen, int lastExtIndex)
+ = 0;
+
+ virtual bool affectsLeftBorder (core::Widget *widget) = 0;
+ virtual bool affectsRightBorder (core::Widget *widget) = 0;
+ virtual bool mayAffectBordersAtAll () = 0;
+
+ virtual int getClearPosition (OOFAwareWidget *widget) = 0;
+
+ virtual bool dealingWithSizeOfChild (core::Widget *child) = 0;
+ virtual int getAvailWidthOfChild (core::Widget *child, bool forceValue) = 0;
+ virtual int getAvailHeightOfChild (core::Widget *child, bool forceValue) = 0;
+
// for iterators
- inline int getNumWidgets ()
- { return leftFloatsAll->size() + rightFloatsAll->size(); }
-
- inline core::Widget *getWidget (int i) {
- if (i < leftFloatsAll->size())
- return leftFloatsAll->get(i)->getWidget ();
- else
- return rightFloatsAll->get(i - leftFloatsAll->size())->getWidget ();
- }
-
- inline bool affectsLeftBorder (core::Widget *widget) {
- return widget->getStyle()->vloat == core::style::FLOAT_LEFT; }
- inline bool affectsRightBorder (core::Widget *widget) {
- return widget->getStyle()->vloat == core::style::FLOAT_RIGHT; }
+ virtual int getNumWidgets () = 0;
+ virtual core::Widget *getWidget (int i) = 0;
};
+} // namespace oof
+
} // namespace dw
#endif // __DW_OUTOFFLOWMGR_HH__