/**
Lay the item out at the specified position with the given size constraint.
- Layout must set the cached size.
+ Layout must set the cached size. @rect is the available space for the object,
+ and @a parentRect is the container that is used to determine a relative size
+ or position (for example if a text box must be 50% of the parent text box).
*/
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style) = 0;
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style) = 0;
/**
Hit-testing: returns a flag indicating hit test details, plus
/**
Lays out the object first with a given amount of space, and then if no width was specified in attr,
- lays out the object again using the minimum size
+ lays out the object again using the minimum size. @a availableParentSpace is the maximum space
+ for the object, whereas @a availableContainerSpace is the container with which relative positions and
+ sizes should be computed. For example, a text box whose space has already been constrained
+ in a previous layout pass to @a availableParentSpace, but should have a width of 50% of @a availableContainerSpace.
+ (If these two rects were the same, a 2nd pass could see the object getting too small.)
*/
virtual bool LayoutToBestSize(wxDC& dc, wxRichTextBuffer* buffer,
- const wxRichTextAttr& parentAttr, const wxRichTextAttr& attr, const wxRect& availableParentSpace, int style);
+ const wxRichTextAttr& parentAttr, const wxRichTextAttr& attr,
+ const wxRect& availableParentSpace, const wxRect& availableContainerSpace, int style);
/**
Sets the object's attributes.
/**
Returns the rectangle which the child has available to it given restrictions specified in the
child attribute, e.g. 50% width of the parent, 400 pixels, x position 20% of the parent, etc.
+ availableContainerSpace might be a parent that the cell has to compute its width relative to.
+ E.g. a cell that's 50% of its parent.
*/
- static wxRect AdjustAvailableSpace(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& parentAttr, const wxRichTextAttr& childAttr, const wxRect& availableParentSpace);
+ static wxRect AdjustAvailableSpace(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& parentAttr, const wxRichTextAttr& childAttr,
+ const wxRect& availableParentSpace, const wxRect& availableContainerSpace);
protected:
wxSize m_size;
virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
virtual wxString GetXMLNodeName() const { return wxT("table"); }
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
/**
Lay the item out at the specified position with the given size constraint.
- Layout must set the cached size.
+ Layout must set the cached size. @rect is the available space for the object,
+ and @a parentRect is the container that is used to determine a relative size
+ or position (for example if a text box must be 50% of the parent text box).
*/
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style) = 0;
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style) = 0;
/**
Hit-testing: returns a flag indicating hit test details, plus
/**
Lays out the object first with a given amount of space, and then if no width was specified in attr,
- lays out the object again using the minimum size
+ lays out the object again using the minimum size. @a availableParentSpace is the maximum space
+ for the object, whereas @a availableContainerSpace is the container with which relative positions and
+ sizes should be computed. For example, a text box whose space has already been constrained
+ in a previous layout pass to @a availableParentSpace, but should have a width of 50% of @a availableContainerSpace.
+ (If these two rects were the same, a 2nd pass could see the object getting too small.)
*/
virtual bool LayoutToBestSize(wxDC& dc, wxRichTextBuffer* buffer,
- const wxRichTextAttr& parentAttr, const wxRichTextAttr& attr, const wxRect& availableParentSpace, int style);
+ const wxRichTextAttr& parentAttr, const wxRichTextAttr& attr,
+ const wxRect& availableParentSpace, const wxRect& availableContainerSpace, int style);
/**
Sets the object's attributes.
/**
Returns the rectangle which the child has available to it given restrictions specified in the
child attribute, e.g. 50% width of the parent, 400 pixels, x position 20% of the parent, etc.
+ availableContainerSpace might be a parent that the cell has to compute its width relative to.
+ E.g. a cell that's 50% of its parent.
*/
- static wxRect AdjustAvailableSpace(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& parentAttr, const wxRichTextAttr& childAttr, const wxRect& availableParentSpace);
+ static wxRect AdjustAvailableSpace(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& parentAttr, const wxRichTextAttr& childAttr,
+ const wxRect& availableParentSpace, const wxRect& availableContainerSpace);
protected:
wxSize m_size;
virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
virtual wxString GetXMLNodeName() const { return wxT("table"); }
- virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
+ virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
// Returns the rectangle which the child has available to it given restrictions specified in the
// child attribute, e.g. 50% width of the parent, 400 pixels, x position 20% of the parent, etc.
-wxRect wxRichTextObject::AdjustAvailableSpace(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& WXUNUSED(parentAttr), const wxRichTextAttr& childAttr, const wxRect& availableParentSpace)
+// availableContainerSpace might be a parent that the cell has to compute its width relative to.
+// E.g. a cell that's 50% of its parent.
+wxRect wxRichTextObject::AdjustAvailableSpace(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& WXUNUSED(parentAttr), const wxRichTextAttr& childAttr, const wxRect& availableParentSpace, const wxRect& availableContainerSpace)
{
wxRect rect = availableParentSpace;
double scale = 1.0;
if (buffer)
scale = buffer->GetScale();
- wxTextAttrDimensionConverter converter(dc, scale, availableParentSpace.GetSize());
+ wxTextAttrDimensionConverter converter(dc, scale, availableContainerSpace.GetSize());
if (childAttr.GetTextBoxAttr().GetWidth().IsValid())
rect.width = converter.GetPixels(childAttr.GetTextBoxAttr().GetWidth());
{
int x = converter.GetPixels(childAttr.GetTextBoxAttr().GetPosition().GetRight());
if (childAttr.GetTextBoxAttr().GetPosition().GetRight().GetPosition() == wxTEXT_BOX_ATTR_POSITION_RELATIVE)
- rect.x = availableParentSpace.x + availableParentSpace.width - rect.width;
+ rect.x = availableContainerSpace.x + availableContainerSpace.width - rect.width;
else
rect.x += x;
}
{
int y = converter.GetPixels(childAttr.GetTextBoxAttr().GetPosition().GetBottom());
if (childAttr.GetTextBoxAttr().GetPosition().GetBottom().GetPosition() == wxTEXT_BOX_ATTR_POSITION_RELATIVE)
- rect.y = availableParentSpace.y + availableParentSpace.height - rect.height;
+ rect.y = availableContainerSpace.y + availableContainerSpace.height - rect.height;
else
rect.y += y;
}
+ if (rect.GetWidth() > availableParentSpace.GetWidth())
+ rect.SetWidth(availableParentSpace.GetWidth());
+
return rect;
}
// Lays out the object first with a given amount of space, and then if no width was specified in attr,
// lays out the object again using the maximum ('best') size
bool wxRichTextObject::LayoutToBestSize(wxDC& dc, wxRichTextBuffer* buffer,
- const wxRichTextAttr& parentAttr, const wxRichTextAttr& attr, const wxRect& availableParentSpace,
+ const wxRichTextAttr& parentAttr, const wxRichTextAttr& attr,
+ const wxRect& availableParentSpace, const wxRect& availableContainerSpace,
int style)
{
- wxRect availableChildRect = AdjustAvailableSpace(dc, buffer, parentAttr, attr, availableParentSpace);
+ wxRect availableChildRect = AdjustAvailableSpace(dc, buffer, parentAttr, attr, availableParentSpace, availableContainerSpace);
wxRect originalAvailableRect = availableChildRect;
- Layout(dc, availableChildRect, style);
+ Layout(dc, availableChildRect, availableContainerSpace, style);
wxSize maxSize = GetMaxSize();
// Don't ignore if maxSize.x is zero, since we need to redo the paragraph's lines
// on this basis
- if (!attr.GetTextBoxAttr().GetWidth().IsValid() && maxSize.x < availableChildRect.width /* && maxSize.x > 0 */)
+ if (!attr.GetTextBoxAttr().GetWidth().IsValid() && maxSize.x < availableChildRect.width)
{
// Redo the layout with a fixed, minimum size this time.
Invalidate(wxRICHTEXT_ALL);
newAttr.GetTextBoxAttr().GetWidth().SetValue(maxSize.x, wxTEXT_ATTR_UNITS_PIXELS);
newAttr.GetTextBoxAttr().GetWidth().SetPosition(wxTEXT_BOX_ATTR_POSITION_ABSOLUTE);
- availableChildRect = AdjustAvailableSpace(dc, buffer, parentAttr, newAttr, availableParentSpace);
+ availableChildRect = AdjustAvailableSpace(dc, buffer, parentAttr, newAttr, availableParentSpace, availableContainerSpace);
// If a paragraph, align the whole paragraph.
// Problem with this: if we're limited by a floating object, a line may be centered
}
}
- Layout(dc, availableChildRect, style);
+ Layout(dc, availableChildRect, availableContainerSpace, style);
}
/*
}
/// Lay the item out
-bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int style)
+bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style)
{
SetPosition(rect.GetPosition());
// Lays out the object first with a given amount of space, and then if no width was specified in attr,
// lays out the object again using the minimum size
child->LayoutToBestSize(dc, GetBuffer(),
- GetAttributes(), child->GetAttributes(), availableSpace, style&~wxRICHTEXT_LAYOUT_SPECIFIED_RECT);
+ GetAttributes(), child->GetAttributes(), availableSpace, rect, style&~wxRICHTEXT_LAYOUT_SPECIFIED_RECT);
// Layout must set the cached size
availableSpace.y += child->GetCachedSize().y;
// Lays out the object first with a given amount of space, and then if no width was specified in attr,
// lays out the object again using the minimum size
child->LayoutToBestSize(dc, GetBuffer(),
- GetAttributes(), child->GetAttributes(), availableSpace, style&~wxRICHTEXT_LAYOUT_SPECIFIED_RECT);
+ GetAttributes(), child->GetAttributes(), availableSpace, rect, style&~wxRICHTEXT_LAYOUT_SPECIFIED_RECT);
//child->Layout(dc, availableChildRect, style);
}
if (node && node->GetData()->IsShown())
{
wxRichTextObject* child = node->GetData();
- // maxHeight = (child->GetPosition().y - GetPosition().y) + child->GetCachedSize().y;
maxHeight = child->GetPosition().y - (GetPosition().y + topMargin) + child->GetCachedSize().y;
}
else
maxHeight = 0; // topMargin + bottomMargin;
+ if (GetAttributes().GetTextBoxAttr().GetSize().GetWidth().IsValid())
+ {
+ wxRect r = AdjustAvailableSpace(dc, GetBuffer(), wxRichTextAttr() /* not used */, GetAttributes(), parentRect, parentRect);
+ int w = r.GetWidth();
+
+ // Convert external to content rect
+ w = w - leftMargin - rightMargin;
+ maxWidth = wxMax(maxWidth, w);
+ maxMaxWidth = wxMax(maxMaxWidth, w);
+ }
+
// TODO: (also in para layout) should set the
// object's size to an absolute one if specified,
// but if not specified, calculate it from content.
levels[i] = -1; // start from the number we found, if any
}
+#if wxDEBUG_LEVEL
wxASSERT(!specifyLevel || (specifyLevel && (specifiedLevel >= 0)));
+#endif
// If we are associated with a control, make undoable; otherwise, apply immediately
// to the data.
}
/// Lay the item out
-bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
+bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, const wxRect& parentRect, int style)
{
// Deal with floating objects firstly before the normal layout
wxRichTextBuffer* buffer = GetBuffer();
// The position will be determined by its location in its line,
// and not by the child's actual position.
child->LayoutToBestSize(dc, buffer,
- GetAttributes(), child->GetAttributes(), availableRect, style);
+ GetAttributes(), child->GetAttributes(), availableRect, parentRect, style);
if (oldSize != child->GetCachedSize())
{
// lays out the object again using the minimum size
child->Invalidate(wxRICHTEXT_ALL);
child->LayoutToBestSize(dc, buffer,
- GetAttributes(), child->GetAttributes(), availableRect, style);
+ GetAttributes(), child->GetAttributes(), availableRect, parentRect, style);
childSize = child->GetCachedSize();
childDescent = child->GetDescent();
//child->SetPosition(availableRect.GetPosition());
}
/// Lay the item out
-bool wxRichTextPlainText::Layout(wxDC& dc, const wxRect& WXUNUSED(rect), int WXUNUSED(style))
+bool wxRichTextPlainText::Layout(wxDC& dc, const wxRect& WXUNUSED(rect), const wxRect& WXUNUSED(parentRect), int WXUNUSED(style))
{
// Only lay out if we haven't already cached the size
if (m_size.x == -1)
// layout to a particular size, or it could be the total space available in the
// parent. rect is the overall size, so we must subtract margins and padding.
// to get the actual available space.
-bool wxRichTextTable::Layout(wxDC& dc, const wxRect& rect, int style)
+bool wxRichTextTable::Layout(wxDC& dc, const wxRect& rect, const wxRect& WXUNUSED(parentRect), int style)
{
SetPosition(rect.GetPosition());
}
// The final calculated widths
- wxArrayInt colWidths(m_colCount);
+ wxArrayInt colWidths;
+ colWidths.Add(0, m_colCount);
- wxArrayInt absoluteColWidths(m_colCount);
+ wxArrayInt absoluteColWidths;
+ absoluteColWidths.Add(0, m_colCount);
// wxArrayInt absoluteColWidthsSpanning(m_colCount);
- wxArrayInt percentageColWidths(m_colCount);
+ wxArrayInt percentageColWidths;
+ percentageColWidths.Add(0, m_colCount);
// wxArrayInt percentageColWidthsSpanning(m_colCount);
// These are only relevant when the first column contains spanning information.
// wxArrayInt columnSpans(m_colCount); // Each contains 1 for non-spanning cell, > 1 for spanning cell.
- wxArrayInt maxColWidths(m_colCount);
- wxArrayInt minColWidths(m_colCount);
+ wxArrayInt maxColWidths;
+ maxColWidths.Add(0, m_colCount);
+ wxArrayInt minColWidths;
+ minColWidths.Add(0, m_colCount);
wxSize tableSize(tableWidth, 0);
// Lay out cell to find min/max widths
cell->Invalidate(wxRICHTEXT_ALL);
- cell->Layout(dc, availableSpace, style);
+ cell->Layout(dc, availableSpace, availableSpace, style);
if (colSpan == 1)
{
int maxCellHeight = 0;
int maxSpecifiedCellHeight = 0;
- wxArrayInt actualWidths(m_colCount);
+ wxArrayInt actualWidths;
+ actualWidths.Add(0, m_colCount);
wxTextAttrDimensionConverter converter(dc, scale);
for (i = 0; i < m_colCount; i++)
// Lay out cell
cell->Invalidate(wxRICHTEXT_ALL);
- cell->Layout(dc, availableCellSpace, style);
+ cell->Layout(dc, availableCellSpace, availableSpace, style);
// TODO: use GetCachedSize().x to compute 'natural' size
wxRect availableCellSpace = wxRect(cell->GetPosition(), wxSize(actualWidths[i], maxCellHeight));
// Lay out cell with new height
cell->Invalidate(wxRICHTEXT_ALL);
- cell->Layout(dc, availableCellSpace, style);
+ cell->Layout(dc, availableCellSpace, availableSpace, style);
// Make sure the cell size really is the appropriate size,
// not the calculated box size
}
/// Lay the item out
-bool wxRichTextImage::Layout(wxDC& dc, const wxRect& rect, int WXUNUSED(style))
+bool wxRichTextImage::Layout(wxDC& dc, const wxRect& rect, const wxRect& WXUNUSED(parentRect), int WXUNUSED(style))
{
if (!LoadImageCache(dc))
return false;
wxRect availableSpace(GetClientSize());
if (GetBuffer().IsDirty())
{
- GetBuffer().Layout(dc, availableSpace, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT);
+ GetBuffer().Layout(dc, availableSpace, availableSpace, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT);
GetBuffer().Invalidate(wxRICHTEXT_NONE);
SetupScrollbars();
}
GetBuffer().Defragment();
GetBuffer().UpdateRanges(); // If items were deleted, ranges need recalculation
- GetBuffer().Layout(dc, availableSpace, flags);
+ GetBuffer().Layout(dc, availableSpace, availableSpace, flags);
GetBuffer().Invalidate(wxRICHTEXT_NONE);
if (!IsFrozen())
{
GetRichTextBuffer()->Invalidate(wxRICHTEXT_ALL);
- GetRichTextBuffer()->Layout(*GetDC(), rect, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT);
+ GetRichTextBuffer()->Layout(*GetDC(), rect, rect, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT);
// Now calculate the page breaks
lastLine = line;
m_numPages ++;
-
+
// Now create page breaks for the rest of the line, if it's larger than the page height
int contentLeft = line->GetSize().y - rect.GetHeight();
while (contentLeft >= 0)
{
yOffset += rect.GetHeight();
contentLeft -= rect.GetHeight();
-
+
m_pageBreaksStart.Add(lastStartPos);
m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd());
m_pageYOffsets.Add(yOffset);
- }
+ }
}
lastLine = line;
}
wxRichTextRange rangeToDraw(m_pageBreaksStart[page-1], m_pageBreaksEnd[page-1]);
-
+
wxPoint oldOrigin = dc->GetLogicalOrigin();
double scaleX, scaleY;
dc->GetUserScale(& scaleX, & scaleY);
int yOffset = 0;
if (page > 1)
yOffset = m_pageYOffsets[page-2];
-
+
if (yOffset != oldOrigin.y)
dc->SetLogicalOrigin(oldOrigin.x, oldOrigin.y + yOffset);