diff options
Diffstat (limited to 'dw/ooffloatsmgr.hh')
-rw-r--r-- | dw/ooffloatsmgr.hh | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/dw/ooffloatsmgr.hh b/dw/ooffloatsmgr.hh new file mode 100644 index 00000000..27d296a9 --- /dev/null +++ b/dw/ooffloatsmgr.hh @@ -0,0 +1,275 @@ +#ifndef __DW_OOFFLOATSMGR_HH__ +#define __DW_OOFFLOATSMGR_HH__ + +#include "outofflowmgr.hh" + +namespace dw { + +namespace oof { + +/** + * \brief OutOfFlowMgr implementation dealing with floats. + * + * Note: The identifiers and comments of this class still refer to + * "Textblock" instead of "OOFAwareWidget"; should be cleaned up some + * day. (OTOH, these widgets are always textblocks.) + */ +class OOFFloatsMgr: public OutOfFlowMgr +{ + friend class WidgetInfo; + +private: + enum Side { LEFT, RIGHT }; + + OOFAwareWidget *container; + int oofmIndex; + + core::Allocation containerAllocation; + + class WidgetInfo: public lout::object::Object + { + private: + OOFFloatsMgr *oofm; + core::Widget *widget; + + protected: + OOFFloatsMgr *getOOFFloatsMgr () { return oofm; } + + public: + WidgetInfo (OOFFloatsMgr *oofm, core::Widget *widget); + + inline core::Widget *getWidget () { return widget; } + }; + + class Float: public WidgetInfo + { + public: + class ComparePosition: public lout::object::Comparator + { + public: + 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: + OOFFloatsMgr *oofm; + + public: + CompareGBAndExtIndex (OOFFloatsMgr *oofm) + { this->oofm = oofm; } + int compare(Object *o1, Object *o2); + }; + + OOFAwareWidget *generator; + int externalIndex; + int index; // TODO Needed after SRDOP? + int yReq, yReal; // relative to container + int sideSpanningIndex; + core::Requisition size; + bool dirty; + + Float (OOFFloatsMgr *oofm, core::Widget *widget, + OOFAwareWidget *generatingBlock, int externalIndex); + + void intoStringBuffer(lout::misc::StringBuffer *sb); + + bool covers (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> + { + private: + OOFFloatsMgr *oofm; + Side side; + + public: + inline SortedFloatsVector (OOFFloatsMgr *oofm, Side side) : + lout::container::typed::Vector<Float> (1, false) + { this->oofm = oofm; this->side = side; } + + int findFloatIndex (OOFAwareWidget *lastGB, int lastExtIndex); + int find (int y, int start, int end); + int findFirst (int y, int h, OOFAwareWidget *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 index; // position within "tbInfos" + + TBInfo *parent; + int parentExtIndex; + + // These two lists store all floats of a generator, in the order + // in which they are defined. Used for optimization + lout::container::typed::Vector<Float> *leftFloats, *rightFloats; + + TBInfo (OOFFloatsMgr *oofm, OOFAwareWidget *textblock, + TBInfo *parent, int parentExtIndex); + ~TBInfo (); + + inline OOFAwareWidget *getOOFAwareWidget () + { return (OOFAwareWidget*)getWidget (); } + }; + + SortedFloatsVector *leftFloats, *rightFloats; + + 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<OOFAwareWidget>, + TBInfo> *tbInfosByOOFAwareWidget; + + int lastLeftTBIndex, lastRightTBIndex, leftFloatsMark, rightFloatsMark; + + void moveExternalIndices (lout::container::typed::Vector<Float> *list, + int oldStartIndex, int diff); + Float *findFloatByWidget (core::Widget *widget); + + void sizeAllocateFloats (Side side); + int getGBWidthForAllocation (Float *vloat); + int calcFloatX (Float *vloat); + + void drawFloats (SortedFloatsVector *list, core::View *view, + core::Rectangle *area, core::DrawingContext *context); + core::Widget *getFloatWidgetAtPoint (SortedFloatsVector *list, int x, int y, + core::GettingWidgetAtPointContext + *context); + + bool collidesV (Float *vloat, Float *other, int *yReal); + bool collidesH (Float *vloat, Float *other); + + 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 *getOOFAwareWidget (OOFAwareWidget *widget); + TBInfo *getOOFAwareWidgetWhenRegistered (OOFAwareWidget *widget); + inline bool isOOFAwareWidgetRegistered (OOFAwareWidget *widget) + { return getOOFAwareWidgetWhenRegistered (widget) != NULL; } + + int getBorder (Side side, int y, int h, OOFAwareWidget *lastGB, + int lastExtIndex); + bool hasFloat (Side side, int y, int h, OOFAwareWidget *lastGB, + int lastExtIndex); + int getFloatHeight (Side side, int y, int h, OOFAwareWidget *lastGB, + int lastExtIndex); + + int getClearPosition (OOFAwareWidget *widget, Side side); + + void ensureFloatSize (Float *vloat); + + inline static int createSubRefLeftFloat (int index) { return index << 1; } + inline static int createSubRefRightFloat (int index) + { return (index << 1) | 1; } + + inline static bool isSubRefLeftFloat (int ref) + { return ref != -1 && (ref & 1) == 0; } + inline static bool isSubRefRightFloat (int ref) + { return ref != -1 && (ref & 1) == 1; } + + inline static int getFloatIndexFromSubRef (int ref) + { return ref == -1 ? ref : (ref >> 1); } + +public: + OOFFloatsMgr (OOFAwareWidget *container, int oofmIndex); + ~OOFFloatsMgr (); + + void sizeAllocateStart (OOFAwareWidget *caller, + core::Allocation *allocation); + void sizeAllocateEnd (OOFAwareWidget *caller); + void containerSizeChangedForChildren (); + void draw (core::View *view, core::Rectangle *area, + core::DrawingContext *context); + + void markSizeChange (int ref); + void markExtremesChange (int ref); + core::Widget *getWidgetAtPoint (int x, int y, + core::GettingWidgetAtPointContext *context); + + void addWidgetInFlow (OOFAwareWidget *textblock, OOFAwareWidget *parentBlock, + int externalIndex); + int addWidgetOOF (core::Widget *widget, OOFAwareWidget *generatingBlock, + int externalIndex); + void calcWidgetRefSize (core::Widget *widget,core::Requisition *size); + void moveExternalIndices (OOFAwareWidget *generatingBlock, int oldStartIndex, + int diff); + + void tellPosition1 (core::Widget *widget, int x, int y); + void tellPosition2 (core::Widget *widget, int x, int y); + void tellIncompletePosition1 (core::Widget *generator, core::Widget *widget, + int x, int y); + void tellIncompletePosition2 (core::Widget *generator, core::Widget *widget, + int x, int y); + + void getSize (core::Requisition *cbReq, int *oofWidth, int *oofHeight); + bool containerMustAdjustExtraSpace (); + void getExtremes (core::Extremes *cbExtr, + int *oofMinWidth, int *oofMaxWidth); + + int getLeftBorder (int y, int h, OOFAwareWidget *lastGB, int lastExtIndex); + int getRightBorder (int y, int h, OOFAwareWidget *lastGB, int lastExtIndex); + + bool hasFloatLeft (int y, int h, OOFAwareWidget *lastGB, int lastExtIndex); + bool hasFloatRight (int y, int h, OOFAwareWidget *lastGB, int lastExtIndex); + + int getLeftFloatHeight (int y, int h, OOFAwareWidget *lastGB, + int lastExtIndex); + int getRightFloatHeight (int y, int h, OOFAwareWidget *lastGB, + int lastExtIndex); + + bool affectsLeftBorder (core::Widget *widget); + bool affectsRightBorder (core::Widget *widget); + bool mayAffectBordersAtAll (); + + int getClearPosition (OOFAwareWidget *textblock); + + bool dealingWithSizeOfChild (core::Widget *child); + int getAvailWidthOfChild (core::Widget *child, bool forceValue); + int getAvailHeightOfChild (core::Widget *child, bool forceValue); + + int getNumWidgets (); + core::Widget *getWidget (int i); +}; + +} // namespace oof + +} // namespace dw + +#endif // __DW_OOFFLOATSMGR_HH__ |