1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
|
#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,
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);
};
} // namespace oof
} // namespace dw
#endif // __DW_OOFFLOATSMGR_HH__
|