diff options
-rw-r--r-- | config.h.in | 3 | ||||
-rw-r--r-- | dw/layout.cc | 1 | ||||
-rw-r--r-- | dw/style.cc | 8 | ||||
-rw-r--r-- | dw/style.hh | 17 | ||||
-rw-r--r-- | dw/textblock.cc | 370 | ||||
-rw-r--r-- | dw/textblock.hh | 85 | ||||
-rw-r--r-- | dw/types.hh | 3 | ||||
-rw-r--r-- | dw/widget.cc | 21 | ||||
-rw-r--r-- | dw/widget.hh | 3 | ||||
-rw-r--r-- | lout/identity.cc | 3 | ||||
-rw-r--r-- | test/Makefile.am | 9 |
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 \ |