Files
flenser/dw/ooffloatsmgr.hh

293 lines
9.8 KiB
C++

#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; }
inline const core::Widget *getWidget () const { 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) const override;
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,
bool ownerOfObjects) :
lout::container::typed::Vector<Float> (1, ownerOfObjects)
{ 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:
class ComparePosition: public lout::object::Comparator
{
private:
int oofmIndex;
public:
inline ComparePosition (int oofmIndex) { this->oofmIndex = oofmIndex; }
int compare (Object *o1, Object *o2);
};
int index; // position within "tbInfos"
int y; // used for sorting
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;
bool SizeChanged;
void moveExternalIndices (lout::container::typed::Vector<Float> *list,
int oldStartIndex, int diff);
Float *findFloatByWidget (core::Widget *widget);
void updateGenerators (Float *vloat);
int findTBInfo (int y);
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);
const core::Widget *getWidget (int i) const;
};
} // namespace oof
} // namespace dw
#endif // __DW_OOFFLOATSMGR_HH__