aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.h.in3
-rw-r--r--dw/layout.cc1
-rw-r--r--dw/style.cc8
-rw-r--r--dw/style.hh17
-rw-r--r--dw/textblock.cc370
-rw-r--r--dw/textblock.hh85
-rw-r--r--dw/types.hh3
-rw-r--r--dw/widget.cc21
-rw-r--r--dw/widget.hh3
-rw-r--r--lout/identity.cc3
-rw-r--r--test/Makefile.am9
11 files changed, 498 insertions, 25 deletions
diff --git a/config.h.in b/config.h.in
index 767c86e4..54501855 100644
--- a/config.h.in
+++ b/config.h.in
@@ -78,6 +78,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
/* Define to the version of this package. */
#undef PACKAGE_VERSION
diff --git a/dw/layout.cc b/dw/layout.cc
index 2e29b05d..060c182f 100644
--- a/dw/layout.cc
+++ b/dw/layout.cc
@@ -134,6 +134,7 @@ void Layout::addWidget (Widget *widget)
topLevel = widget;
widget->layout = this;
+ widget->notifySetAsTopLevel();
findtextState.setWidget (widget);
diff --git a/dw/style.cc b/dw/style.cc
index bdb04f25..207c47a3 100644
--- a/dw/style.cc
+++ b/dw/style.cc
@@ -18,8 +18,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
-
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -44,6 +42,8 @@ void StyleAttrs::initValues ()
backgroundColor = NULL;
width = LENGTH_AUTO;
height = LENGTH_AUTO;
+ vloat = FLOAT_NONE;
+ clear = CLEAR_NONE;
margin.setVal (0);
borderWidth.setVal (0);
@@ -71,6 +71,8 @@ void StyleAttrs::resetValues ()
textAlign = TEXT_ALIGN_LEFT; /* ??? */
valign = VALIGN_MIDDLE;
textAlignChar = '.';
+ vloat = FLOAT_NONE; /** \todo Correct? Check specification. */
+ clear = CLEAR_NONE; /** \todo Correct? Check specification. */
backgroundColor = NULL;
width = LENGTH_AUTO;
height = LENGTH_AUTO;
@@ -232,6 +234,8 @@ void Style::copyAttrs (StyleAttrs *attrs)
textAlign = attrs->textAlign;
valign = attrs->valign;
textAlignChar = attrs->textAlignChar;
+ vloat = attrs->vloat;
+ clear = attrs->clear;
hBorderSpacing = attrs->hBorderSpacing;
vBorderSpacing = attrs->vBorderSpacing;
width = attrs->width;
diff --git a/dw/style.hh b/dw/style.hh
index 492efd30..a96a3471 100644
--- a/dw/style.hh
+++ b/dw/style.hh
@@ -256,7 +256,6 @@ enum DisplayType {
DISPLAY_LAST
};
-
enum ListStyleType {
LIST_STYLE_TYPE_DISC,
LIST_STYLE_TYPE_CIRCLE,
@@ -301,6 +300,19 @@ enum WhiteSpace {
WHITE_SPACE_NOWRAP
};
+enum FloatType {
+ FLOAT_LEFT,
+ FLOAT_RIGHT,
+ FLOAT_NONE
+};
+
+enum ClearType {
+ CLEAR_LEFT,
+ CLEAR_RIGHT,
+ CLEAR_BOTH,
+ CLEAR_NONE
+};
+
/**
* \brief Type for representing all lengths within dw::core::style.
*
@@ -417,6 +429,9 @@ public:
TextAlignType textAlign;
VAlignType valign;
char textAlignChar; /* In future, strings will be supported. */
+
+ FloatType vloat; /* "float" is a keyword. */
+ ClearType clear;
int hBorderSpacing, vBorderSpacing;
Length width, height;
diff --git a/dw/textblock.cc b/dw/textblock.cc
index d80a7ad4..6bfd4d90 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -18,12 +18,12 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
-
#include "textblock.hh"
+#include "table.hh" // Yes, this is ugly. -- SG
#include "../lout/misc.hh"
#include <stdio.h>
+#include <math.h> // remove again
#include <limits.h>
namespace dw {
@@ -55,6 +55,7 @@ Textblock::Textblock (bool limitTextWidth)
*/
lines = new misc::SimpleVector <Line> (1);
words = new misc::SimpleVector <Word> (1);
+ leftFloatSide = rightFloatSide = NULL;
//DBG_OBJ_SET_NUM(page, "num_lines", num_lines);
@@ -107,6 +108,11 @@ Textblock::~Textblock ()
delete lines;
delete words;
+ if(leftFloatSide)
+ delete leftFloatSide;
+ if(rightFloatSide)
+ delete rightFloatSide;
+
/* Make sure we don't own widgets anymore. Necessary before call of
parent class destructor. (???) */
words = NULL;
@@ -418,6 +424,11 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
xCursor += (word->size.width + word->effSpace);
}
}
+
+ if(leftFloatSide)
+ leftFloatSide->sizeAllocate(allocation);
+ if(rightFloatSide)
+ rightFloatSide->sizeAllocate(allocation);
}
void Textblock::resizeDrawImpl ()
@@ -449,15 +460,65 @@ void Textblock::markExtremesChange (int ref)
*/
void Textblock::markChange (int ref)
{
- if (ref != -1) {
+ printf("markChange(%d)\n", ref);
+
+ int refEquiv = (ref == 0) ? 1 | (dw::core::style::FLOAT_NONE << 1) : ref;
+
+ if (refEquiv != -1 && (refEquiv & 1)) {
//DBG_MSGF (page, "wrap", 0, "Dw_page_mark_size_change (ref = %d)", ref);
- if (wrapRef == -1)
- wrapRef = ref;
- else
- wrapRef = misc::min (wrapRef, ref);
+ // ABC
+ switch((refEquiv >> 1) & 3)
+ {
+ case dw::core::style::FLOAT_NONE:
+ if (wrapRef == -1)
+ wrapRef = refEquiv >> 3;
+ else
+ wrapRef = misc::min (wrapRef, refEquiv >> 3);
+ //DBG_OBJ_SET_NUM (page, "wrap_ref", page->wrap_ref);
+ printf("wrapRef = %d\n", wrapRef);
+ break;
+
+ case dw::core::style::FLOAT_LEFT:
+ leftFloatSide->queueResize(refEquiv);
+ break;
+
+ case dw::core::style::FLOAT_RIGHT:
+ rightFloatSide->queueResize(refEquiv);
+ break;
+ }
+ }
+}
- //DBG_OBJ_SET_NUM (page, "wrap_ref", page->wrap_ref);
+void Textblock::notifySetAsTopLevel()
+{
+ containingBox = this;
+}
+
+void Textblock::notifySetParent()
+{
+ // Search for containing Box. It can be assumed that this widget has a
+ // parent, otherwise, notifySetAsToplevel would have been called.
+ containingBox = NULL;
+ Textblock *topmostTextblock = this;
+
+ for(Widget *widget = getParent(); widget != NULL; widget = widget->getParent())
+ {
+ if(widget->instanceOf(Textblock::CLASS_ID))
+ topmostTextblock = (Textblock*)widget;
+ }
+
+ for(Widget *widget = getParent(); containingBox == NULL; widget = widget->getParent())
+ {
+ if(widget->getParent() == NULL)
+ // No other widget left.
+ containingBox = topmostTextblock;
+ else if(widget->instanceOf(Textblock::CLASS_ID))
+ {
+ if(widget->getParent()->instanceOf(Table::CLASS_ID) /* this widget is a table cell */ ||
+ widget->getStyle()->vloat != dw::core::style::FLOAT_NONE /* this widget is a float */)
+ containingBox = (Textblock*)widget;
+ }
}
}
@@ -472,7 +533,11 @@ void Textblock::setWidth (int width)
// page->num_words);
availWidth = width;
+//<<<<<<< textblock.cc
+// queueResize (false, dw::core::style::FLOAT_NONE, false);
+//=======
queueResize (0, false);
+//>>>>>>> 1.24
mustQueueResize = false;
redrawY = 0;
}
@@ -487,7 +552,11 @@ void Textblock::setAscent (int ascent)
// page->num_words);
availAscent = ascent;
+//<<<<<<< textblock.cc
+// queueResize (false, dw::core::style::FLOAT_NONE, false);
+//=======
queueResize (0, false);
+//>>>>>>> 1.24
mustQueueResize = false;
}
}
@@ -501,7 +570,11 @@ void Textblock::setDescent (int descent)
// page->num_words);
availDescent = descent;
+//<<<<<<< textblock.cc
+// queueResize (false, dw::core::style::FLOAT_NONE, false);
+//=======
queueResize (0, false);
+//>>>>>>> 1.24
mustQueueResize = false;
}
}
@@ -804,6 +877,8 @@ void Textblock::addLine (int wordInd, bool newPar)
lastLine->marginDescent = 0;
lastLine->breakSpace = 0;
lastLine->leftOffset = 0;
+ lastLine->boxLeft = 0;
+ lastLine->boxRight = 0;
//DBG_OBJ_ARRSET_NUM (page, "lines.%d.ascent", page->num_lines - 1,
// lastLine->ascent);
@@ -874,6 +949,17 @@ void Textblock::wordWrap(int wordIndex)
word = words->getRef (wordIndex);
+ if(word->content.type == dw::core::Content::FLOAT_REF)
+ {
+ Line *line = lines->size() > 0 ? lines->getRef(lines->size() - 1) : NULL;
+ int y =
+ allocation.y - containingBox->allocation.y + getStyle()->boxOffsetY() +
+ (line ? line->top : 0);
+ int lineHeight = line ? line->ascent + line->descent : 0;
+
+ containingBox->handleFloatInContainer(word->content.widget, misc::max(lines->size() - 1, 0), y, lastLineWidth, lineHeight);
+ }
+
if (lines->size () == 0) {
//DBG_MSG (page, "wrap", 0, "first line");
newLine = true;
@@ -903,8 +989,10 @@ void Textblock::wordWrap(int wordIndex)
// word_ind, a_Dw_content_html (&word->content),
// page->lastLine_width, prevWord->orig_space,
// word->size.width, availWidth);
- newLine = (lastLineWidth + prevWord->origSpace
- + word->size.width > availWidth);
+ newLine = (lastLineWidth + prevWord->origSpace +
+ word->size.width
+ > availWidth -
+ (lastLine->boxLeft + lastLine->boxRight));
//DBG_MSGF (page, "wrap", 0, "... %s.",
// newLine ? "No" : "Yes");
}
@@ -1021,7 +1109,7 @@ void Textblock::wordWrap(int wordIndex)
case core::style::TEXT_ALIGN_LEFT:
case core::style::TEXT_ALIGN_JUSTIFY: /* see some lines above */
case core::style::TEXT_ALIGN_STRING: /* handled elsewhere (in the
- * future) */
+ * future) */
leftOffset = 0;
break;
@@ -1050,10 +1138,16 @@ void Textblock::wordWrap(int wordIndex)
// page->words[0].eff_space);
} else
lastLine->leftOffset = leftOffset;
+
+ int y =
+ allocation.y - containingBox->allocation.y +
+ getStyle()->boxOffsetX () + lastLine->top;
+ lastLine->boxLeft = calcLeftFloatBorder(y, this);
+ lastLine->boxRight = calcRightFloatBorder(y, this);
}
mustQueueResize = true;
-
+
//DBG_MSG_END (page);
}
@@ -1176,7 +1270,9 @@ void Textblock::rewrap ()
wordWrap (wordIndex);
if (word->content.type == core::Content::WIDGET) {
- word->content.widget->parentRef = lines->size () - 1;
+ // ABC
+ word->content.widget->parentRef = 1 | (dw::core::style::FLOAT_NONE << 1) | ((lines->size () - 1) << 3);
+ printf("parentRef = %d\n", word->content.widget->parentRef);
//DBG_OBJ_SET_NUM (word->content.widget, "parent_ref",
// word->content.widget->parent_ref);
}
@@ -1525,6 +1621,11 @@ void Textblock::draw (core::View *view, core::Rectangle *area)
drawLine (line, view, area);
}
+
+ if(leftFloatSide)
+ leftFloatSide->draw(view, area);
+ if(rightFloatSide)
+ rightFloatSide->draw(view, area);
}
/**
@@ -1634,7 +1735,9 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style)
// word->content.widget);
wordWrap (words->size () - 1);
- word->content.widget->parentRef = lines->size () - 1;
+ // ABC
+ word->content.widget->parentRef = 1 | (dw::core::style::FLOAT_NONE << 1) | ((lines->size () - 1) << 3);
+ printf("parentRef = %d\n", word->content.widget->parentRef);
//DBG_OBJ_SET_NUM (word->content.widget, "parent_ref",
// word->content.widget->parent_ref);
@@ -1760,7 +1863,8 @@ void Textblock::addParbreak (int space, core::style::Style *style)
&& textblock2->words->get(0).content.widget == widget);
if (!isfirst) {
/* The page we searched for has been found. */
- lineno = widget->parentRef;
+ // ABC
+ lineno = widget->parentRef >> 3;
if (lineno > 0 &&
(word2 =
textblock2->words->getRef(textblock2->lines
@@ -1768,7 +1872,11 @@ void Textblock::addParbreak (int space, core::style::Style *style)
word2->content.type == core::Content::BREAK) {
if (word2->content.breakSpace < space) {
word2->content.breakSpace = space;
+//<<<<<<< textblock.cc
+// textblock2->queueResize (false, 1 | (dw::core::style::FLOAT_NONE << 1) | (lineno << 3), false);
+//=======
textblock2->queueResize (lineno, false);
+//>>>>>>> 1.24
textblock2->mustQueueResize = false;
}
}
@@ -1822,6 +1930,22 @@ void Textblock::addLinebreak (core::style::Style *style)
wordWrap (words->size () - 1);
}
+/** \todo This MUST be commented! */
+void Textblock::addFloatIntoGenerator (core::Widget *widget, core::style::Style *style)
+{
+ Word *word;
+
+ widget->setStyle (style);
+ containingBox->addFloatIntoContainer(widget, this);
+
+ word = addWord (0, 0, 0, style);
+ word->content.type = core::Content::FLOAT_REF;
+ word->content.breakSpace = 0;
+ word->content.widget = widget;
+ word->style = style;
+ wordWrap (words->size () - 1);
+}
+
/**
* \brief Search recursively through widget.
@@ -1895,8 +2019,14 @@ void Textblock::handOverBreak (core::style::Style *style)
*/
void Textblock::flush ()
{
+//<<<<<<< textblock.cc
+// if (asap || mustQueueResize) {
+// printf("queueResize(%s, -1, true)\n", asap ? "true" : "false");
+// queueResize (asap, -1, true);
+//=======
if (mustQueueResize) {
queueResize (-1, true);
+//>>>>>>> 1.24
mustQueueResize = false;
}
}
@@ -1964,6 +2094,216 @@ void Textblock::changeWordStyle (int from, int to, core::style::Style *style,
// ----------------------------------------------------------------------
+/** \todo This MUST be commented! */
+void Textblock::addFloatIntoContainer(Widget *widget,
+ Textblock *floatGenerator)
+{
+ FloatSide *floatSide = NULL;
+
+ switch(widget->getStyle()->vloat)
+ {
+ case dw::core::style::FLOAT_LEFT:
+ if(leftFloatSide == NULL)
+ leftFloatSide = new LeftFloatSide(this);
+ floatSide = leftFloatSide;
+ break;
+
+ case dw::core::style::FLOAT_RIGHT:
+ if(rightFloatSide == NULL)
+ rightFloatSide = new RightFloatSide(this);
+ floatSide = rightFloatSide;
+ break;
+
+ default:
+ //TODO lout::misc::fail("invalid value %d for float to be added", widget->getStyle()->vloat);
+ break;
+ }
+
+ // ABC
+ widget->parentRef = 1 | (widget->getStyle()->vloat << 1) | (floatSide->size() << 3);
+ widget->parentRef = 0;
+ printf("parentRef = %d\n", widget->parentRef);
+ widget->setParent(this);
+
+ floatSide->addFloat(widget, floatGenerator);
+}
+
+void Textblock::handleFloatInContainer(Widget *widget, int lineNo,
+ int y, int lineWidth, int lineHeight)
+{
+ FloatSide *floatSide = NULL;
+
+ switch(widget->getStyle()->vloat)
+ {
+ case dw::core::style::FLOAT_LEFT:
+ floatSide = leftFloatSide;
+ break;
+
+ case dw::core::style::FLOAT_RIGHT:
+ floatSide = rightFloatSide;
+ break;
+
+ default:
+ //TODO lout::misc::fail("invalid value %d for float to be handled", widget->getStyle()->vloat);
+ break;
+ }
+
+ floatSide->handleFloat(widget, lineNo, y, lineWidth, lineHeight);
+}
+
+Textblock::FloatSide::FloatSide(Textblock *floatContainer)
+{
+ this->floatContainer = floatContainer;
+ floats = new container::typed::Vector<Float>(1, false);
+ floatsByWidget =
+ new container::typed::HashTable<object::TypedPointer<dw::core::Widget>, Float>(true, true);
+}
+
+Textblock::FloatSide::~FloatSide()
+{
+ delete floats;
+ delete floatsByWidget;
+}
+
+void Textblock::FloatSide::addFloat(Widget *widget, Textblock *floatGenerator)
+{
+ Float *vloat = new Float();
+ vloat->floatGenerator = floatGenerator;
+ vloat->widget = widget;
+ floats->put(vloat);
+ object::TypedPointer<Widget> *pointer = new object::TypedPointer<Widget>(widget);
+ floatsByWidget->put(pointer, vloat);
+}
+
+void Textblock::FloatSide::handleFloat(Widget *widget, int lineNo,
+ int y, int lineWidth, int lineHeight)
+{
+ /** \todo lineHeight may change afterwards */
+ object::TypedPointer<Widget> pointer(widget);
+ Float *vloat = floatsByWidget->get(&pointer);
+
+ printf("searching %s in %s\n", pointer.toString(), floatsByWidget->toString());
+
+ dw::core::Requisition requisition;
+ widget->sizeRequest(&requisition);
+
+ int effY;
+ /** \todo Check for another float. Futhermore: what, if the float does not fit
+ * into a line at all? */
+ if(requisition.ascent + requisition.descent > vloat->floatGenerator->availWidth - lineWidth)
+ effY = y + lineHeight;
+ else
+ effY = y;
+
+ vloat->lineNo = lineNo;
+ vloat->y = effY;
+ vloat->width = requisition.width;
+ vloat->ascent = requisition.ascent;
+ vloat->descent = requisition.descent;
+}
+
+int Textblock::FloatSide::calcBorder(int y, Textblock *viewdFrom)
+{
+ Float *vloat = findFloat(y);
+ if(vloat) {
+ int fromContainer = calcBorderFromContainer(vloat);
+ int fromThisViewedFrom = fromContainer - calcBorderDiff(viewdFrom);
+ //printf("fromThisViewedFrom = %d\n", fromThisViewedFrom);
+ return misc::max(fromThisViewedFrom, 0);
+ } else
+ return 0;
+}
+
+Textblock::FloatSide::Float *Textblock::FloatSide::findFloat(int y)
+{
+ for(int i = 0; i < floats->size(); i++)
+ {
+ Float *vloat = floats->get(i);
+ if(y >= vloat->y && y < vloat->y + vloat->ascent + vloat->descent)
+ return vloat;
+ }
+
+ return NULL;
+}
+
+void Textblock::FloatSide::draw (core::View *view, core::Rectangle *area)
+{
+ for(int i = 0; i < floats->size(); i++)
+ {
+ Float *vloat = floats->get(i);
+ core::Rectangle childArea;
+ if (vloat->widget->intersects (area, &childArea))
+ vloat->widget->draw (view, &childArea);
+ }
+}
+
+void Textblock::FloatSide::queueResize(int ref)
+{
+ // TODO Float *vloat = floats->get(ref >> 3);
+ // TODO vloat->floatGenerator->queueResize(false, 1 | (dw::core::style::FLOAT_NONE << 1) | (vloat->lineNo << 3), true);
+}
+
+int Textblock::LeftFloatSide::calcBorderFromContainer(Textblock::FloatSide::Float *vloat)
+{
+ return vloat->width + floatContainer->getStyle()->boxOffsetX() +
+ (vloat->floatGenerator->allocation.x - floatContainer->allocation.x);
+}
+
+int Textblock::LeftFloatSide::calcBorderDiff(Textblock *child)
+{
+ return child->getStyle()->boxOffsetX();
+}
+
+void Textblock::LeftFloatSide::sizeAllocate(core::Allocation *containingBoxAllocation)
+{
+ for(int i = 0; i < floats->size(); i++)
+ {
+ Float *vloat = floats->get(i);
+ core::Allocation childAllocation;
+ childAllocation.x =
+ containingBoxAllocation->x + floatContainer->getStyle()->boxOffsetX() +
+ (vloat->floatGenerator->allocation.x - floatContainer->allocation.x);
+ childAllocation.y = containingBoxAllocation->y + vloat->y;
+ childAllocation.width = vloat->width;
+ childAllocation.ascent = vloat->ascent;
+ childAllocation.descent = vloat->descent;
+ vloat->widget->sizeAllocate(&childAllocation);
+ }
+}
+
+int Textblock::RightFloatSide::calcBorderFromContainer(Textblock::FloatSide::Float *vloat)
+{
+ return vloat->width + floatContainer->getStyle()->boxRestWidth() +
+ (vloat->floatGenerator->allocation.x + vloat->floatGenerator->allocation.width -
+ (floatContainer->allocation.x + floatContainer->allocation.width));
+}
+
+int Textblock::RightFloatSide::calcBorderDiff(Textblock *child)
+{
+ return child->getStyle()->boxRestWidth();
+}
+
+void Textblock::RightFloatSide::sizeAllocate(core::Allocation *containingBoxAllocation)
+{
+ for(int i = 0; i < floats->size(); i++)
+ {
+ Float *vloat = floats->get(i);
+ core::Allocation childAllocation;
+ childAllocation.x =
+ containingBoxAllocation->x + containingBoxAllocation->width -
+ floatContainer->getStyle()->boxRestWidth() - vloat->width +
+ (vloat->floatGenerator->allocation.x + vloat->floatGenerator->allocation.width -
+ (floatContainer->allocation.x + floatContainer->allocation.width));
+ childAllocation.y = containingBoxAllocation->y + vloat->y;
+ childAllocation.width = vloat->width;
+ childAllocation.ascent = vloat->ascent;
+ childAllocation.descent = vloat->descent;
+ vloat->widget->sizeAllocate(&childAllocation);
+ }
+}
+
+// ----------------------------------------------------------------------
+
Textblock::TextblockIterator::TextblockIterator (Textblock *textblock,
core::Content::Type mask,
bool atEnd):
diff --git a/dw/textblock.hh b/dw/textblock.hh
index d3198b69..80e16393 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -12,6 +12,9 @@ using namespace lout;
* \brief A Widget for rendering text blocks, i.e. paragraphs or sequences
* of paragraphs.
*
+ * <strong>Important Note:</strong>: This documentation is out of date, since
+ * floats have been implementet. Will be updated and extended soon.
+ *
* <h3>Signals</h3>
*
* dw::Textblock uses the signals defined in
@@ -132,6 +135,66 @@ using namespace lout;
*/
class Textblock: public core::Widget
{
+private:
+ Textblock *containingBox;
+
+ class FloatSide
+ {
+ protected:
+ class Float: public object::Object
+ {
+ public:
+ Textblock *floatGenerator;
+ core::Widget *widget;
+ int lineNo, y, width, ascent, descent;
+ };
+
+ Textblock *floatContainer;
+ container::typed::Vector<Float> *floats;
+ container::typed::HashTable<object::TypedPointer<dw::core::Widget>, Float> *floatsByWidget;
+
+ Float *findFloat(int y);
+
+ virtual int calcBorderFromContainer(Float *vloat) = 0;
+ virtual int calcBorderDiff(Textblock *child) = 0;
+
+ public:
+ FloatSide(Textblock *floatContainer);
+ virtual ~FloatSide();
+
+ inline int size() { return floats->size(); }
+ void addFloat(Widget *widget, Textblock *floatGenerator);
+ void handleFloat(Widget *widget, int lineNo, int y, int lineWidth, int lineHeight);
+ int calcBorder(int y, Textblock *viewdFrom);
+ virtual void sizeAllocate(core::Allocation *containingBoxAllocation) = 0;
+ void draw (core::View *view, core::Rectangle *area);
+ void queueResize(int ref);
+ };
+
+ class LeftFloatSide: public FloatSide
+ {
+ protected:
+ int calcBorderFromContainer(Float *vloat);
+ int calcBorderDiff(Textblock *child);
+
+ public:
+ LeftFloatSide(Textblock *floatContainer) : FloatSide(floatContainer) { }
+ void sizeAllocate(core::Allocation *containingBoxAllocation);
+ };
+
+ class RightFloatSide: public FloatSide
+ {
+ protected:
+ int calcBorderFromContainer(Float *vloat);
+ int calcBorderDiff(Textblock *child);
+
+ public:
+ RightFloatSide(Textblock *floatContainer) : FloatSide(floatContainer) { }
+ void sizeAllocate(core::Allocation *containingBoxAllocation);
+ };
+
+ FloatSide *leftFloatSide, *rightFloatSide;
+
protected:
struct Line
{
@@ -140,8 +203,10 @@ protected:
/* "top" is always relative to the top of the first line, i.e.
* page->lines[0].top is always 0. */
- int top, ascent, descent, breakSpace, leftOffset;
-
+ int top, ascent, descent, breakSpace;
+ int leftOffset; /* nonzero for centered and rightly-aligned text */
+ int boxLeft, boxRight;
+
/* This is similar to descent, but includes the bottom margins of the
* widgets within this line. */
int marginDescent;
@@ -272,7 +337,15 @@ protected:
void calcTextSize (const char *text, core::style::Style *style,
core::Requisition *size);
-
+ void addFloatIntoContainer(core::Widget *widget, Textblock *floatGenerator);
+ void handleFloatInContainer(Widget *widget, int lineNo,
+ int y, int lineWidth, int lineHeight);
+
+ inline int calcLeftFloatBorder(int y, Textblock *viewedFrom)
+ { return leftFloatSide ? leftFloatSide->calcBorder(y, viewedFrom) : 0; }
+ inline int calcRightFloatBorder(int y, Textblock *viewedFrom)
+ { return rightFloatSide ? rightFloatSide->calcBorder(y, viewedFrom) : 0; }
+
/**
* \brief Returns the x offset (the indentation plus any offset needed for
* centering or right justification) for the line.
@@ -282,7 +355,7 @@ protected:
*/
inline int lineXOffsetContents (Line *line)
{
- return innerPadding + line->leftOffset +
+ return innerPadding + line->leftOffset + line->boxLeft +
(line == lines->getRef (0) ? line1OffsetEff : 0);
}
@@ -345,6 +418,8 @@ protected:
void markSizeChange (int ref);
void markExtremesChange (int ref);
+ void notifySetAsTopLevel();
+ void notifySetParent();
void setWidth (int width);
void setAscent (int ascent);
void setDescent (int descent);
@@ -375,6 +450,8 @@ public:
void addParbreak (int space, core::style::Style *style);
void addLinebreak (core::style::Style *style);
+ void addFloatIntoGenerator (core::Widget *widget, core::style::Style *style);
+
core::Widget *getWidgetAtPoint (int x, int y, int level);
void handOverBreak (core::style::Style *style);
void changeLinkColor (int link, int newColor);
diff --git a/dw/types.hh b/dw/types.hh
index bdfca629..cd35e1f6 100644
--- a/dw/types.hh
+++ b/dw/types.hh
@@ -181,8 +181,9 @@ struct Content
WIDGET = 1 << 3,
ANCHOR = 1 << 4,
BREAK = 1 << 5,
+ FLOAT_REF = 1 << 6, /** \todo A bit ugly. */
ALL = 0xff,
- REAL_CONTENT = 0xff ^ (START | END),
+ REAL_CONTENT = 0xff ^ (START | END | FLOAT_REF),
SELECTION_CONTENT = TEXT | WIDGET | BREAK
};
/* Content is embedded in struct Word therefore we
diff --git a/dw/widget.cc b/dw/widget.cc
index e3ce8e3d..b664b433 100644
--- a/dw/widget.cc
+++ b/dw/widget.cc
@@ -308,6 +308,8 @@ void Widget::setParent (Widget *parent)
if (!buttonSensitiveSet)
buttonSensitive = parent->buttonSensitive;
+ notifySetParent();
+
//DBG_OBJ_ASSOC (widget, parent);
}
@@ -775,6 +777,25 @@ void Widget::markExtremesChange (int ref)
{
}
+/**
+ * \brief This method is called after a widget has been set as the top of a
+ * widget tree.
+ *
+ * A widget may override this method when it is necessary to be notified.
+ */
+void Widget::notifySetAsTopLevel()
+{
+}
+
+/**
+ * \brief This method is called after a widget has been added to a parent.
+ *
+ * A widget may override this method when it is necessary to be notified.
+ */
+void Widget::notifySetParent()
+{
+}
+
void Widget::setWidth (int width)
{
}
diff --git a/dw/widget.hh b/dw/widget.hh
index 1bcfd032..fde48ecc 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -306,6 +306,9 @@ protected:
*/
virtual void markExtremesChange (int ref);
+ virtual void notifySetAsTopLevel();
+ virtual void notifySetParent();
+
virtual bool buttonPressImpl (EventButton *event);
virtual bool buttonReleaseImpl (EventButton *event);
virtual bool motionNotifyImpl (EventMotion *event);
diff --git a/lout/identity.cc b/lout/identity.cc
index b124d6ad..8a5d68fd 100644
--- a/lout/identity.cc
+++ b/lout/identity.cc
@@ -18,8 +18,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
-
#include "identity.hh"
#include <stdio.h>
@@ -79,6 +77,7 @@ void IdentifiableObject::registerName (const char *className, int *classId)
}
this->classId = klass->id;
+ *classId = klass->id;
currentlyConstructedClass = klass;
}
diff --git a/test/Makefile.am b/test/Makefile.am
index bde2b0f8..e6946adf 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -5,6 +5,7 @@ noinst_PROGRAMS = \
dw-anchors-test \
dw-example \
dw-find-test \
+ dw-float-test \
dw-links \
dw-links2 \
dw-images-simple \
@@ -44,6 +45,14 @@ dw_find_test_LDADD = \
../lout/liblout.a \
@LIBFLTK_LIBS@
+dw_float_test_SOURCES = dw_float_test.cc
+dw_float_test_LDADD = \
+ ../dw/libDw-widgets.a \
+ ../dw/libDw-fltk.a \
+ ../dw/libDw-core.a \
+ ../lout/liblout.a \
+ @LIBFLTK_LIBS@
+
dw_links_SOURCES = dw_links.cc
dw_links_LDADD = \
../dw/libDw-widgets.a \