int GetLastRectBottom();
// Draw the floats inside a rect
- void Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
+ void Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
// HitTest the floats
- int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int flags);
+ int HitTest(wxDC& dc, wxRichTextDrawingContext& context, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int flags);
// Get floating object count
int GetFloatingObjectCount() const { return m_left.GetCount() + m_right.GetCount(); }
static void FreeFloatRectMapArray(wxRichTextFloatRectMapArray& array);
- static void DrawFloat(const wxRichTextFloatRectMapArray& array, wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
+ static void DrawFloat(const wxRichTextFloatRectMapArray& array, wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
- static int HitTestFloat(const wxRichTextFloatRectMapArray& array, wxDC& WXUNUSED(dc), const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int flags);
+ static int HitTestFloat(const wxRichTextFloatRectMapArray& array, wxDC& dc, wxRichTextDrawingContext& context, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int flags);
private:
wxRichTextFloatRectMapArray m_left;
return ret;
}
-void wxRichTextFloatCollector::DrawFloat(const wxRichTextFloatRectMapArray& array, wxDC& dc, const wxRichTextRange& WXUNUSED(range), const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
+void wxRichTextFloatCollector::DrawFloat(const wxRichTextFloatRectMapArray& array, wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& WXUNUSED(range), const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
{
int start = rect.y;
int end = rect.y + rect.height;
{
wxRichTextObject* obj = array[i]->anchor;
wxRichTextRange r = obj->GetRange();
- obj->Draw(dc, r, selection, wxRect(obj->GetPosition(), obj->GetCachedSize()), descent, style);
+ obj->Draw(dc, context, r, selection, wxRect(obj->GetPosition(), obj->GetCachedSize()), descent, style);
i++;
}
}
-void wxRichTextFloatCollector::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
+void wxRichTextFloatCollector::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
{
if (m_left.GetCount() > 0)
- DrawFloat(m_left, dc, range, selection, rect, descent, style);
+ DrawFloat(m_left, dc, context, range, selection, rect, descent, style);
if (m_right.GetCount() > 0)
- DrawFloat(m_right, dc, range, selection, rect, descent, style);
+ DrawFloat(m_right, dc, context, range, selection, rect, descent, style);
}
-int wxRichTextFloatCollector::HitTestFloat(const wxRichTextFloatRectMapArray& array, wxDC& WXUNUSED(dc), const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int WXUNUSED(flags))
+int wxRichTextFloatCollector::HitTestFloat(const wxRichTextFloatRectMapArray& array, wxDC& WXUNUSED(dc), wxRichTextDrawingContext& WXUNUSED(context), const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int WXUNUSED(flags))
{
int i;
if (array.GetCount() == 0)
return wxRICHTEXT_HITTEST_NONE;
}
-int wxRichTextFloatCollector::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int flags)
+int wxRichTextFloatCollector::HitTest(wxDC& dc, wxRichTextDrawingContext& context, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int flags)
{
- int ret = HitTestFloat(m_left, dc, pt, textPosition, obj, flags);
+ int ret = HitTestFloat(m_left, dc, context, pt, textPosition, obj, flags);
if (ret == wxRICHTEXT_HITTEST_NONE)
{
- ret = HitTestFloat(m_right, dc, pt, textPosition, obj, flags);
+ ret = HitTestFloat(m_right, dc, context, pt, textPosition, obj, flags);
}
return ret;
}
// Calculate the available content space in the given rectangle, given the
// margins, border and padding specified in the object's attributes.
-wxRect wxRichTextObject::GetAvailableContentArea(wxDC& dc, const wxRect& outerRect) const
+wxRect wxRichTextObject::GetAvailableContentArea(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& outerRect) const
{
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
marginRect = outerRect;
- GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+ wxRichTextAttr attr(GetAttributes());
+ context.ApplyVirtualAttributes(attr, (wxRichTextObject*) this);
+ GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
return contentRect;
}
// 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;
}
// Hit-testing: returns a flag indicating hit test details, plus
// information about position
-int wxRichTextObject::HitTest(wxDC& WXUNUSED(dc), const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int WXUNUSED(flags))
+int wxRichTextObject::HitTest(wxDC& WXUNUSED(dc), wxRichTextDrawingContext& WXUNUSED(context), const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int WXUNUSED(flags))
{
if (!IsShown())
return wxRICHTEXT_HITTEST_NONE;
// 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,
+bool wxRichTextObject::LayoutToBestSize(wxDC& dc, wxRichTextDrawingContext& context, wxRichTextBuffer* buffer,
+ 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, context, 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
if (attr.HasAlignment() && !GetContainer()->GetFloatCollector()->HasFloats()) // FIXME: aligning whole paragraph not compatible with floating objects
{
// centering, right-justification
- if (GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
+ if (attr.GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
{
availableChildRect.x = (originalAvailableRect.GetWidth() - availableChildRect.GetWidth())/2 + availableChildRect.x;
}
- else if (GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_RIGHT)
+ else if (attr.GetAlignment() == wxTEXT_ALIGNMENT_RIGHT)
{
availableChildRect.x = availableChildRect.x + originalAvailableRect.GetWidth() - availableChildRect.GetWidth();
}
}
- Layout(dc, availableChildRect, style);
+ Layout(dc, context, availableChildRect, availableContainerSpace, style);
}
/*
/// Hit-testing: returns a flag indicating hit test details, plus
/// information about position
-int wxRichTextCompositeObject::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags)
+int wxRichTextCompositeObject::HitTest(wxDC& dc, wxRichTextDrawingContext& context, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags)
{
if (!IsShown())
return wxRICHTEXT_HITTEST_NONE;
if (child->IsShown() && child->IsTopLevel() && (flags & wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS))
{
// Just check if we hit the overall object
- int ret = child->wxRichTextObject::HitTest(dc, pt, textPosition, obj, contextObj, flags);
+ int ret = child->wxRichTextObject::HitTest(dc, context, pt, textPosition, obj, contextObj, flags);
if (ret != wxRICHTEXT_HITTEST_NONE)
return ret;
}
else if (child->IsShown())
{
- int ret = child->HitTest(dc, pt, textPosition, obj, contextObj, flags);
+ int ret = child->HitTest(dc, context, pt, textPosition, obj, contextObj, flags);
if (ret != wxRICHTEXT_HITTEST_NONE)
return ret;
}
}
/// Finds the absolute position and row height for the given character position
-bool wxRichTextCompositeObject::FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart)
+bool wxRichTextCompositeObject::FindPosition(wxDC& dc, wxRichTextDrawingContext& context, long index, wxPoint& pt, int* height, bool forceLineStart)
{
wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
while (node)
// such as a text box, because the character position will no longer
// apply. By definition, a top-level object has its own range of
// character positions.
- if (!child->IsTopLevel() && child->FindPosition(dc, index, pt, height, forceLineStart))
+ if (!child->IsTopLevel() && child->FindPosition(dc, context, index, pt, height, forceLineStart))
return true;
node = node->GetNext();
/// Get/set the object size for the given range. Returns false if the range
/// is invalid for this object.
-bool wxRichTextCompositeObject::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position, wxArrayInt* partialExtents) const
+bool wxRichTextCompositeObject::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position, wxArrayInt* partialExtents) const
{
if (!range.IsWithin(GetRange()))
return false;
sz.x += childSize.x;
descent = wxMax(descent, childDescent);
}
- else if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, wxPoint(position.x + sz.x, position.y), p))
+ else if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, context, flags, wxPoint(position.x + sz.x, position.y), p))
{
sz.y = wxMax(sz.y, childSize.y);
sz.x += childSize.x;
}
// HitTest
-int wxRichTextParagraphLayoutBox::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags)
+int wxRichTextParagraphLayoutBox::HitTest(wxDC& dc, wxRichTextDrawingContext& context, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags)
{
if (!IsShown())
return wxRICHTEXT_HITTEST_NONE;
int ret = wxRICHTEXT_HITTEST_NONE;
if (m_floatCollector && (flags & wxRICHTEXT_HITTEST_NO_FLOATING_OBJECTS) == 0)
- ret = m_floatCollector->HitTest(dc, pt, textPosition, obj, flags);
+ ret = m_floatCollector->HitTest(dc, context, pt, textPosition, obj, flags);
if (ret == wxRICHTEXT_HITTEST_NONE)
- return wxRichTextCompositeObject::HitTest(dc, pt, textPosition, obj, contextObj, flags);
+ return wxRichTextCompositeObject::HitTest(dc, context, pt, textPosition, obj, contextObj, flags);
else
{
*contextObj = this;
}
/// Draw the floating objects
-void wxRichTextParagraphLayoutBox::DrawFloats(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
+void wxRichTextParagraphLayoutBox::DrawFloats(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
{
if (m_floatCollector)
- m_floatCollector->Draw(dc, range, selection, rect, descent, style);
+ m_floatCollector->Draw(dc, context, range, selection, rect, descent, style);
}
void wxRichTextParagraphLayoutBox::MoveAnchoredObjectToParagraph(wxRichTextParagraph* from, wxRichTextParagraph* to, wxRichTextObject* obj)
}
/// Draw the item
-bool wxRichTextParagraphLayoutBox::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
+bool wxRichTextParagraphLayoutBox::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
{
if (!IsShown())
return true;
wxRect thisRect(GetPosition(), GetCachedSize());
+ wxRichTextAttr attr(GetAttributes());
+ context.ApplyVirtualAttributes(attr, this);
+
int flags = style;
if (selection.IsValid() && GetParentContainer() != this && selection.WithinSelection(GetRange().GetStart(), GetParentContainer()))
flags |= wxRICHTEXT_DRAW_SELECTED;
int theseFlags = flags;
if (!GetParent())
theseFlags &= ~wxRICHTEXT_DRAW_GUIDELINES;
- DrawBoxAttributes(dc, GetBuffer(), GetAttributes(), thisRect, theseFlags);
+ DrawBoxAttributes(dc, GetBuffer(), attr, thisRect, theseFlags);
- DrawFloats(dc, range, selection, rect, descent, style);
+ DrawFloats(dc, context, range, selection, rect, descent, style);
wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
while (node)
{
// Skip
}
else
- child->Draw(dc, childRange, selection, rect, descent, style);
+ child->Draw(dc, context, childRange, selection, rect, descent, style);
}
node = node->GetNext();
}
/// Lay the item out
-bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int style)
+bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style)
{
SetPosition(rect.GetPosition());
wxRect availableSpace;
bool formatRect = (style & wxRICHTEXT_LAYOUT_SPECIFIED_RECT) == wxRICHTEXT_LAYOUT_SPECIFIED_RECT;
+ wxRichTextAttr attr(GetAttributes());
+ context.ApplyVirtualAttributes(attr, this);
+
// If only laying out a specific area, the passed rect has a different meaning:
// the visible part of the buffer. This is used in wxRichTextCtrl::OnSize,
// so that during a size, only the visible part will be relaid out, or
if (formatRect)
{
wxRect rect2(0, 0, rect.width, rect.height);
- availableSpace = GetAvailableContentArea(dc, rect2);
+ availableSpace = GetAvailableContentArea(dc, context, rect2);
// Invalidate the part of the buffer from the first visible line
// to the end. If other parts of the buffer are currently invalid,
}
else
{
- availableSpace = GetAvailableContentArea(dc, rect);
+ availableSpace = GetAvailableContentArea(dc, context, rect);
}
int leftMargin, rightMargin, topMargin, bottomMargin;
- wxRichTextObject::GetTotalMargin(dc, GetBuffer(), GetAttributes(), leftMargin, rightMargin,
+ wxRichTextObject::GetTotalMargin(dc, GetBuffer(), attr, leftMargin, rightMargin,
topMargin, bottomMargin);
int maxWidth = 0;
int maxMinWidth = 0;
// If we have vertical alignment, we must recalculate everything.
- bool hasVerticalAlignment = (GetAttributes().GetTextBoxAttr().HasVerticalAlignment() &&
- (GetAttributes().GetTextBoxAttr().GetVerticalAlignment() > wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_TOP));
+ bool hasVerticalAlignment = (attr.GetTextBoxAttr().HasVerticalAlignment() &&
+ (attr.GetTextBoxAttr().GetVerticalAlignment() > wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_TOP));
wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
{
// 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);
+ child->LayoutToBestSize(dc, context, GetBuffer(),
+ attr, 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);
+ child->LayoutToBestSize(dc, context, GetBuffer(),
+ attr, 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 (attr.GetTextBoxAttr().GetSize().GetWidth().IsValid())
+ {
+ wxRect r = AdjustAvailableSpace(dc, GetBuffer(), wxRichTextAttr() /* not used */, attr, 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.
{
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
contentRect = wxRect(wxPoint(0, 0), wxSize(maxWidth, maxHeight));
- GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+ GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
SetCachedSize(marginRect.GetSize());
}
{
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
contentRect = wxRect(wxPoint(0, 0), wxSize(maxMaxWidth, maxHeight)); // Actually max height is a lie, we can't know it
- GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+ GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
SetMaxSize(marginRect.GetSize());
}
{
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
contentRect = wxRect(wxPoint(0, 0), wxSize(maxMinWidth, maxHeight)); // Actually max height is a lie, we can't know it
- GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+ GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
SetMinSize(marginRect.GetSize());
}
- if (GetAttributes().GetTextBoxAttr().HasVerticalAlignment() &&
- (GetAttributes().GetTextBoxAttr().GetVerticalAlignment() > wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_TOP))
+ if (attr.GetTextBoxAttr().HasVerticalAlignment() &&
+ (attr.GetTextBoxAttr().GetVerticalAlignment() > wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_TOP))
{
int yOffset = 0;
int leftOverSpace = availableSpace.height - topMargin - bottomMargin - maxHeight;
if (leftOverSpace > 0)
{
- if (GetAttributes().GetTextBoxAttr().GetVerticalAlignment() == wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_CENTRE)
+ if (attr.GetTextBoxAttr().GetVerticalAlignment() == wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_CENTRE)
{
yOffset = (leftOverSpace/2);
}
- else if (GetAttributes().GetTextBoxAttr().GetVerticalAlignment() == wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_BOTTOM)
+ else if (attr.GetTextBoxAttr().GetVerticalAlignment() == wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_BOTTOM)
{
yOffset = leftOverSpace;
}
}
/// Get/set the size for the given range.
-bool wxRichTextParagraphLayoutBox::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position, wxArrayInt* WXUNUSED(partialExtents)) const
+bool wxRichTextParagraphLayoutBox::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position, wxArrayInt* WXUNUSED(partialExtents)) const
{
wxSize sz;
wxSize childSize;
int childDescent = 0;
- child->GetRangeSize(rangeToFind, childSize, childDescent, dc, flags, position);
+ child->GetRangeSize(rangeToFind, childSize, childDescent, dc, context, flags, position);
descent = wxMax(childDescent, descent);
return foundCount == matchingCount && foundCount != 0;
}
+void wxRichTextParagraphLayoutBox::PrepareContent(wxRichTextParagraphLayoutBox& container)
+{
+ wxRichTextBuffer* buffer = GetBuffer();
+ if (buffer && buffer->GetRichTextCtrl())
+ buffer->GetRichTextCtrl()->PrepareContent(container);
+}
+
+
+/// Set character or paragraph properties
+bool wxRichTextParagraphLayoutBox::SetProperties(const wxRichTextRange& range, const wxRichTextProperties& properties, int flags)
+{
+ wxRichTextBuffer* buffer = GetBuffer();
+
+ bool withUndo = ((flags & wxRICHTEXT_SETPROPERTIES_WITH_UNDO) != 0);
+ bool parasOnly = ((flags & wxRICHTEXT_SETPROPERTIES_PARAGRAPHS_ONLY) != 0);
+ bool charactersOnly = ((flags & wxRICHTEXT_SETPROPERTIES_CHARACTERS_ONLY) != 0);
+ bool resetExistingProperties = ((flags & wxRICHTEXT_SETPROPERTIES_RESET) != 0);
+ bool removeProperties = ((flags & wxRICHTEXT_SETPROPERTIES_REMOVE) != 0);
+
+ // If we are associated with a control, make undoable; otherwise, apply immediately
+ // to the data.
+
+ bool haveControl = (buffer->GetRichTextCtrl() != NULL);
+
+ wxRichTextAction* action = NULL;
+
+ if (haveControl && withUndo)
+ {
+ action = new wxRichTextAction(NULL, _("Change Properties"), wxRICHTEXT_CHANGE_PROPERTIES, buffer, this, buffer->GetRichTextCtrl());
+ action->SetRange(range);
+ action->SetPosition(buffer->GetRichTextCtrl()->GetCaretPosition());
+ }
+
+ wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
+ while (node)
+ {
+ wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph);
+ // wxASSERT (para != NULL);
+
+ if (para && para->GetChildCount() > 0)
+ {
+ // Stop searching if we're beyond the range of interest
+ if (para->GetRange().GetStart() > range.GetEnd())
+ break;
+
+ if (!para->GetRange().IsOutside(range))
+ {
+ // We'll be using a copy of the paragraph to make style changes,
+ // not updating the buffer directly.
+ wxRichTextParagraph* newPara wxDUMMY_INITIALIZE(NULL);
+
+ if (haveControl && withUndo)
+ {
+ newPara = new wxRichTextParagraph(*para);
+ action->GetNewParagraphs().AppendChild(newPara);
+
+ // Also store the old ones for Undo
+ action->GetOldParagraphs().AppendChild(new wxRichTextParagraph(*para));
+ }
+ else
+ newPara = para;
+
+ if (parasOnly)
+ {
+ if (removeProperties)
+ {
+ // Removes the given style from the paragraph
+ // TODO
+ newPara->GetProperties().RemoveProperties(properties);
+ }
+ else if (resetExistingProperties)
+ newPara->GetProperties() = properties;
+ else
+ newPara->GetProperties().MergeProperties(properties);
+ }
+
+ // When applying paragraph styles dynamically, don't change the text objects' attributes
+ // since they will computed as needed. Only apply the character styling if it's _only_
+ // character styling. This policy is subject to change and might be put under user control.
+
+ // Hm. we might well be applying a mix of paragraph and character styles, in which
+ // case we _do_ want to apply character styles regardless of what para styles are set.
+ // But if we're applying a paragraph style, which has some character attributes, but
+ // we only want the paragraphs to hold this character style, then we _don't_ want to
+ // apply the character style. So we need to be able to choose.
+
+ if (!parasOnly && charactersOnly && range.GetStart() != newPara->GetRange().GetEnd())
+ {
+ wxRichTextRange childRange(range);
+ childRange.LimitTo(newPara->GetRange());
+
+ // Find the starting position and if necessary split it so
+ // we can start applying different properties.
+ // TODO: check that the properties actually change or are different
+ // from properties outside of range
+ wxRichTextObject* firstObject wxDUMMY_INITIALIZE(NULL);
+ wxRichTextObject* lastObject wxDUMMY_INITIALIZE(NULL);
+
+ if (childRange.GetStart() == newPara->GetRange().GetStart())
+ firstObject = newPara->GetChildren().GetFirst()->GetData();
+ else
+ firstObject = newPara->SplitAt(range.GetStart());
+
+ // Increment by 1 because we're apply the style one _after_ the split point
+ long splitPoint = childRange.GetEnd();
+ if (splitPoint != newPara->GetRange().GetEnd())
+ splitPoint ++;
+
+ // Find last object
+ if (splitPoint == newPara->GetRange().GetEnd())
+ lastObject = newPara->GetChildren().GetLast()->GetData();
+ else
+ // lastObject is set as a side-effect of splitting. It's
+ // returned as the object before the new object.
+ (void) newPara->SplitAt(splitPoint, & lastObject);
+
+ wxASSERT(firstObject != NULL);
+ wxASSERT(lastObject != NULL);
+
+ if (!firstObject || !lastObject)
+ continue;
+
+ wxRichTextObjectList::compatibility_iterator firstNode = newPara->GetChildren().Find(firstObject);
+ wxRichTextObjectList::compatibility_iterator lastNode = newPara->GetChildren().Find(lastObject);
+
+ wxASSERT(firstNode);
+ wxASSERT(lastNode);
+
+ wxRichTextObjectList::compatibility_iterator node2 = firstNode;
+
+ while (node2)
+ {
+ wxRichTextObject* child = node2->GetData();
+
+ if (removeProperties)
+ {
+ // Removes the given properties from the paragraph
+ child->GetProperties().RemoveProperties(properties);
+ }
+ else if (resetExistingProperties)
+ child->GetProperties() = properties;
+ else
+ {
+ child->GetProperties().MergeProperties(properties);
+ }
+
+ if (node2 == lastNode)
+ break;
+
+ node2 = node2->GetNext();
+ }
+ }
+ }
+ }
+
+ node = node->GetNext();
+ }
+
+ // Do action, or delay it until end of batch.
+ if (haveControl && withUndo)
+ buffer->SubmitAction(action);
+
+ return true;
+}
+
void wxRichTextParagraphLayoutBox::Reset()
{
Clear();
AddParagraph(wxEmptyString);
+ PrepareContent(*this);
+
InvalidateHierarchy(wxRICHTEXT_ALL);
}
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.
}
/// Draw the item
-bool wxRichTextParagraph::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int WXUNUSED(descent), int style)
+bool wxRichTextParagraph::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int WXUNUSED(descent), int style)
{
if (!IsShown())
return true;
// for all paragraphs). But generally box attributes are likely to be
// different for different objects.
wxRect paraRect = GetRect();
- DrawBoxAttributes(dc, GetBuffer(), GetAttributes(), paraRect);
-
wxRichTextAttr attr = GetCombinedAttributes();
+ context.ApplyVirtualAttributes(attr, this);
+
+ DrawBoxAttributes(dc, GetBuffer(), attr, paraRect);
// Draw the bullet, if any
if (attr.GetBulletStyle() != wxTEXT_ATTR_BULLET_STYLE_NONE)
int spaceBeforePara = ConvertTenthsMMToPixels(dc, attr.GetParagraphSpacingBefore());
int leftIndent = ConvertTenthsMMToPixels(dc, attr.GetLeftIndent());
- wxRichTextAttr bulletAttr(GetCombinedAttributes());
+ wxRichTextAttr bulletAttr(attr);
// Combine with the font of the first piece of content, if one is specified
if (GetChildren().GetCount() > 0)
#endif
{
int descent = 0;
- child->GetRangeSize(objectRange, objectSize, descent, dc, wxRICHTEXT_UNFORMATTED, objectPosition);
+ child->GetRangeSize(objectRange, objectSize, descent, dc, context, wxRICHTEXT_UNFORMATTED, objectPosition);
}
}
// Use the child object's width, but the whole line's height
wxRect childRect(objectPosition, wxSize(objectSize.x, line->GetSize().y));
- child->Draw(dc, objectRange, selection, childRect, maxDescent, style);
+ child->Draw(dc, context, objectRange, selection, childRect, maxDescent, style);
objectPosition.x += objectSize.x;
i ++;
}
/// Lay the item out
-bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
+bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style)
{
// Deal with floating objects firstly before the normal layout
wxRichTextBuffer* buffer = GetBuffer();
wxASSERT(buffer);
wxRichTextFloatCollector* collector = GetContainer()->GetFloatCollector();
wxASSERT(collector);
- LayoutFloat(dc, rect, style, collector);
+ LayoutFloat(dc, context, rect, style, collector);
wxRichTextAttr attr = GetCombinedAttributes();
+ context.ApplyVirtualAttributes(attr, this);
// ClearLines();
int paraDescent = 0;
// This calculates the partial text extents
- GetRangeSize(GetRange(), paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_CACHE_SIZE, rect.GetPosition(), & partialExtents);
+ GetRangeSize(GetRange(), paraSize, paraDescent, dc, context, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_CACHE_SIZE, rect.GetPosition(), & partialExtents);
#else
node = m_children.GetFirst();
while (node)
wxRichTextObject* child = node->GetData();
//child->SetCachedSize(wxDefaultSize);
- child->Layout(dc, rect, style);
+ child->Layout(dc, context, rect, style);
node = node->GetNext();
}
// lays out the object again using the minimum size
// 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);
+ child->LayoutToBestSize(dc, context, buffer,
+ attr, child->GetAttributes(), availableRect, parentRect, style);
if (oldSize != child->GetCachedSize())
{
partialExtents.Clear();
// Recalculate the partial text extents since the child object changed size
- GetRangeSize(GetRange(), paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_CACHE_SIZE, wxPoint(0,0), & partialExtents);
+ GetRangeSize(GetRange(), paraSize, paraDescent, dc, context, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_CACHE_SIZE, wxPoint(0,0), & partialExtents);
}
}
{
#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS
// Get height only, then the width using the partial extents
- GetRangeSize(wxRichTextRange(lastEndPos+1, lastPosToUse), childSize, childDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_HEIGHT_ONLY);
+ GetRangeSize(wxRichTextRange(lastEndPos+1, lastPosToUse), childSize, childDescent, dc, context, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_HEIGHT_ONLY);
childSize.x = wxRichTextGetRangeWidth(*this, wxRichTextRange(lastEndPos+1, lastPosToUse), partialExtents);
#else
- GetRangeSize(wxRichTextRange(lastEndPos+1, lastPosToUse), childSize, childDescent, dc, wxRICHTEXT_UNFORMATTED, rect.GetPosition());
+ GetRangeSize(wxRichTextRange(lastEndPos+1, lastPosToUse), childSize, childDescent, dc, context, wxRICHTEXT_UNFORMATTED, rect.GetPosition());
#endif
}
// 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->Invalidate(wxRICHTEXT_ALL);
- child->LayoutToBestSize(dc, buffer,
- GetAttributes(), child->GetAttributes(), availableRect, style);
+ child->LayoutToBestSize(dc, context, buffer,
+ attr, child->GetAttributes(), availableRect, parentRect, style);
childSize = child->GetCachedSize();
childDescent = child->GetDescent();
//child->SetPosition(availableRect.GetPosition());
partialExtents.Clear();
// Recalculate the partial text extents since the child object changed size
- GetRangeSize(GetRange(), paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_CACHE_SIZE, wxPoint(0,0), & partialExtents);
+ GetRangeSize(GetRange(), paraSize, paraDescent, dc, context, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_CACHE_SIZE, wxPoint(0,0), & partialExtents);
}
// Go around the loop finding the available rect for the given floating objects
// Note: one object must contains only one wxTextAtrr, so the line height will not
// change inside one object. Thus, we can pass the remain line width to the
// FindWrapPosition function.
- if (!FindWrapPosition(wxRichTextRange(lastCompletedEndPos+1, child->GetRange().GetEnd()), dc, availableRect.width, wrapPosition, & partialExtents))
+ if (!FindWrapPosition(wxRichTextRange(lastCompletedEndPos+1, child->GetRange().GetEnd()), dc, context, availableRect.width, wrapPosition, & partialExtents))
{
// If the function failed, just cut it off at the end of this child.
wrapPosition = child->GetRange().GetEnd();
if (!child->IsEmpty())
{
// Get height only, then the width using the partial extents
- GetRangeSize(actualRange, actualSize, childDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_HEIGHT_ONLY);
+ GetRangeSize(actualRange, actualSize, childDescent, dc, context, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_HEIGHT_ONLY);
actualSize.x = wxRichTextGetRangeWidth(*this, actualRange, partialExtents);
}
else
#endif
- GetRangeSize(actualRange, actualSize, childDescent, dc, wxRICHTEXT_UNFORMATTED);
+ GetRangeSize(actualRange, actualSize, childDescent, dc, context, wxRICHTEXT_UNFORMATTED);
currentWidth = actualSize.x;
maxDescent = wxMax(childDescent, maxDescent);
{
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
contentRect = wxRect(wxPoint(0, 0), wxSize(maxWidth, currentPosition.y + spaceAfterPara));
- GetBoxRects(dc, buffer, GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+ GetBoxRects(dc, buffer, attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
SetCachedSize(marginRect.GetSize());
}
{
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
contentRect = wxRect(wxPoint(0, 0), wxSize(paraSize.x + wxMax(leftIndent, leftIndent + leftSubIndent) + rightIndent, currentPosition.y + spaceAfterPara));
- GetBoxRects(dc, buffer, GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+ GetBoxRects(dc, buffer, attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
SetMaxSize(marginRect.GetSize());
}
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
contentRect = wxRect(wxPoint(0, 0), wxSize(minWidth, currentPosition.y + spaceAfterPara));
- GetBoxRects(dc, buffer, GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+ GetBoxRects(dc, buffer, attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
SetMinSize(marginRect.GetSize());
}
wxSize size = line->GetSize();
// centering, right-justification
- if (attr.HasAlignment() && GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
+ if (attr.HasAlignment() && attr.GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
{
int rightIndent = ConvertTenthsMMToPixels(dc, attr.GetRightIndent());
pos.x = (rect.GetWidth() - rightIndent - size.x)/2 + pos.x;
line->SetPosition(pos);
}
- else if (attr.HasAlignment() && GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_RIGHT)
+ else if (attr.HasAlignment() && attr.GetAlignment() == wxTEXT_ALIGNMENT_RIGHT)
{
int rightIndent = ConvertTenthsMMToPixels(dc, attr.GetRightIndent());
pos.x = pos.x + rect.GetWidth() - size.x - rightIndent;
/// Get/set the object size for the given range. Returns false if the range
/// is invalid for this object.
-bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position, wxArrayInt* partialExtents) const
+bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position, wxArrayInt* partialExtents) const
{
if (!range.IsWithin(GetRange()))
return false;
partialExtents->Add(childSize.x + lastSize);
}
}
- else if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, wxPoint(position.x + sz.x, position.y), p))
+ else if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, context, flags, wxPoint(position.x + sz.x, position.y), p))
{
sz.y = wxMax(sz.y, childSize.y);
sz.x += childSize.x;
wxSize childSize;
int childDescent = 0;
- if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, wxPoint(position.x + sz.x, position.y)))
+ if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, context, flags, wxPoint(position.x + sz.x, position.y)))
{
lineSize.y = wxMax(lineSize.y, childSize.y);
lineSize.x += childSize.x;
}
/// Finds the absolute position and row height for the given character position
-bool wxRichTextParagraph::FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart)
+bool wxRichTextParagraph::FindPosition(wxDC& dc, wxRichTextDrawingContext& context, long index, wxPoint& pt, int* height, bool forceLineStart)
{
if (index == -1)
{
// then we can add this size to the line start position and
// paragraph start position to find the actual position.
- if (GetRangeSize(r, rangeSize, descent, dc, wxRICHTEXT_UNFORMATTED, line->GetPosition()+ GetPosition()))
+ if (GetRangeSize(r, rangeSize, descent, dc, context, wxRICHTEXT_UNFORMATTED, line->GetPosition()+ GetPosition()))
{
pt.x = line->GetPosition().x + GetPosition().x + rangeSize.x;
*height = line->GetSize().y;
/// Hit-testing: returns a flag indicating hit test details, plus
/// information about position
-int wxRichTextParagraph::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags)
+int wxRichTextParagraph::HitTest(wxDC& dc, wxRichTextDrawingContext& context, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags)
{
if (!IsShown())
return wxRICHTEXT_HITTEST_NONE;
{
long tmpPos;
wxRichTextObject* tempObj, *tempContextObj;
- if (GetParent() && GetParent()->wxRichTextObject::HitTest(dc, pt, tmpPos, & tempObj, & tempContextObj, flags) == wxRICHTEXT_HITTEST_NONE)
+ if (GetParent() && GetParent()->wxRichTextObject::HitTest(dc, context, pt, tmpPos, & tempObj, & tempContextObj, flags) == wxRICHTEXT_HITTEST_NONE)
return wxRICHTEXT_HITTEST_NONE;
}
if (child->IsTopLevel() && ((flags & wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS) == 0))
{
{
- int hitTest = child->HitTest(dc, pt, textPosition, obj, contextObj);
+ int hitTest = child->HitTest(dc, context, pt, textPosition, obj, contextObj);
if (hitTest != wxRICHTEXT_HITTEST_NONE)
return hitTest;
}
int paraDescent;
// This calculates the partial text extents
- GetRangeSize(lineRange, paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED, linePos, & partialExtents);
+ GetRangeSize(lineRange, paraSize, paraDescent, dc, context, wxRICHTEXT_UNFORMATTED, linePos, & partialExtents);
int lastX = linePos.x;
size_t i;
wxRichTextRange rangeToUse(lineRange.GetStart(), i);
- GetRangeSize(rangeToUse, childSize, descent, dc, wxRICHTEXT_UNFORMATTED, linePos);
+ GetRangeSize(rangeToUse, childSize, descent, dc, context, wxRICHTEXT_UNFORMATTED, linePos);
int nextX = childSize.x + linePos.x;
}
/// Find a suitable wrap position.
-bool wxRichTextParagraph::FindWrapPosition(const wxRichTextRange& range, wxDC& dc, int availableSpace, long& wrapPosition, wxArrayInt* partialExtents)
+bool wxRichTextParagraph::FindWrapPosition(const wxRichTextRange& range, wxDC& dc, wxRichTextDrawingContext& context, int availableSpace, long& wrapPosition, wxArrayInt* partialExtents)
{
if (range.GetLength() <= 0)
return false;
if (minPos == maxPos)
{
int descent = 0;
- GetRangeSize(wxRichTextRange(range.GetStart(), minPos), sz, descent, dc, wxRICHTEXT_UNFORMATTED);
+ GetRangeSize(wxRichTextRange(range.GetStart(), minPos), sz, descent, dc, context, wxRICHTEXT_UNFORMATTED);
if (sz.x > availableSpace)
breakPosition = minPos - 1;
else if ((maxPos - minPos) == 1)
{
int descent = 0;
- GetRangeSize(wxRichTextRange(range.GetStart(), minPos), sz, descent, dc, wxRICHTEXT_UNFORMATTED);
+ GetRangeSize(wxRichTextRange(range.GetStart(), minPos), sz, descent, dc, context, wxRICHTEXT_UNFORMATTED);
if (sz.x > availableSpace)
breakPosition = minPos - 1;
else
{
- GetRangeSize(wxRichTextRange(range.GetStart(), maxPos), sz, descent, dc, wxRICHTEXT_UNFORMATTED);
+ GetRangeSize(wxRichTextRange(range.GetStart(), maxPos), sz, descent, dc, context, wxRICHTEXT_UNFORMATTED);
if (sz.x > availableSpace)
breakPosition = maxPos-1;
}
long nextPos = minPos + ((maxPos - minPos) / 2);
int descent = 0;
- GetRangeSize(wxRichTextRange(range.GetStart(), nextPos), sz, descent, dc, wxRICHTEXT_UNFORMATTED);
+ GetRangeSize(wxRichTextRange(range.GetStart(), nextPos), sz, descent, dc, context, wxRICHTEXT_UNFORMATTED);
if (sz.x > availableSpace)
{
sm_defaultTabs.Clear();
}
-void wxRichTextParagraph::LayoutFloat(wxDC& dc, const wxRect& rect, int style, wxRichTextFloatCollector* floatCollector)
+void wxRichTextParagraph::LayoutFloat(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, int style, wxRichTextFloatCollector* floatCollector)
{
wxRichTextObjectList::compatibility_iterator node = GetChildren().GetFirst();
while (node)
{
wxSize size;
int descent, x = 0;
- anchored->GetRangeSize(anchored->GetRange(), size, descent, dc, style);
+ anchored->GetRangeSize(anchored->GetRange(), size, descent, dc, context, style);
int offsetY = 0;
if (anchored->GetAttributes().GetTextBoxAttr().GetTop().IsValid())
#define WIDTH_FOR_DEFAULT_TABS 50
/// Draw the item
-bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int WXUNUSED(style))
+bool wxRichTextPlainText::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int WXUNUSED(style))
{
wxRichTextParagraph* para = wxDynamicCast(GetParent(), wxRichTextParagraph);
wxASSERT (para != NULL);
wxRichTextAttr textAttr(para ? para->GetCombinedAttributes(GetAttributes(), false /* no box attributes */) : GetAttributes());
+ context.ApplyVirtualAttributes(textAttr, this);
// Let's make the assumption for now that for content in a paragraph, including
// text, we never have a discontinuous selection. So we only deal with a
}
/// Lay the item out
-bool wxRichTextPlainText::Layout(wxDC& dc, const wxRect& WXUNUSED(rect), int WXUNUSED(style))
+bool wxRichTextPlainText::Layout(wxDC& dc, wxRichTextDrawingContext& context, 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)
- GetRangeSize(GetRange(), m_size, m_descent, dc, 0, wxPoint(0, 0));
+ GetRangeSize(GetRange(), m_size, m_descent, dc, context, 0, wxPoint(0, 0));
m_maxSize = m_size;
// Eventually we want to have a reasonable estimate of minimum size.
m_minSize = wxSize(0, 0);
/// Get/set the object size for the given range. Returns false if the range
/// is invalid for this object.
-bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int WXUNUSED(flags), wxPoint position, wxArrayInt* partialExtents) const
+bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int WXUNUSED(flags), wxPoint position, wxArrayInt* partialExtents) const
{
if (!range.IsWithin(GetRange()))
return false;
int relativeX = position.x - GetParent()->GetPosition().x;
wxRichTextAttr textAttr(para ? para->GetCombinedAttributes(GetAttributes()) : GetAttributes());
+ context.ApplyVirtualAttributes(textAttr, (wxRichTextObject*) this);
// Always assume unformatted text, since at this level we have no knowledge
// of line breaks - and we don't need it, since we'll calculate size within
wxRichTextPlainText* newObject = new wxRichTextPlainText(secondPart);
newObject->SetAttributes(GetAttributes());
+ newObject->SetProperties(GetProperties());
newObject->SetRange(wxRichTextRange(pos, GetRange().GetEnd()));
GetRange().SetEnd(pos-1);
bool wxRichTextPlainText::CanMerge(wxRichTextObject* object) const
{
return object->GetClassInfo() == CLASSINFO(wxRichTextPlainText) &&
- (m_text.empty() || wxTextAttrEq(GetAttributes(), object->GetAttributes()));
+ (m_text.empty() || (wxTextAttrEq(GetAttributes(), object->GetAttributes()) && m_properties == object->GetProperties()));
}
/// Returns true if this object merged itself with the given one.
IMPLEMENT_DYNAMIC_CLASS(wxRichTextBuffer, wxRichTextParagraphLayoutBox)
wxList wxRichTextBuffer::sm_handlers;
+wxList wxRichTextBuffer::sm_drawingHandlers;
wxRichTextRenderer* wxRichTextBuffer::sm_renderer = NULL;
int wxRichTextBuffer::sm_bulletRightMargin = 20;
float wxRichTextBuffer::sm_bulletProportion = (float) 0.3;
/// Submit immediately, or delay according to whether collapsing is on
bool wxRichTextBuffer::SubmitAction(wxRichTextAction* action)
{
+ if (action && !action->GetNewParagraphs().IsEmpty())
+ PrepareContent(action->GetNewParagraphs());
+
if (BatchingUndo() && m_batchedCommand && !SuppressingUndo())
{
wxRichTextCommand* cmd = new wxRichTextCommand(action->GetName());
/// Hit-testing: returns a flag indicating hit test details, plus
/// information about position
-int wxRichTextBuffer::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags)
+int wxRichTextBuffer::HitTest(wxDC& dc, wxRichTextDrawingContext& context, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags)
{
- int ret = wxRichTextParagraphLayoutBox::HitTest(dc, pt, textPosition, obj, contextObj, flags);
+ int ret = wxRichTextParagraphLayoutBox::HitTest(dc, context, pt, textPosition, obj, contextObj, flags);
if (ret != wxRICHTEXT_HITTEST_NONE)
{
return ret;
}
/// Draw the item
-bool wxRichTextBox::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
+bool wxRichTextBox::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
{
if (!IsShown())
return true;
// so we can apply commands (properties, delete, ...) to objects such as text boxes and images.
// Ultimately we would like to be able to interactively resize an active object
// using drag handles.
- return wxRichTextParagraphLayoutBox::Draw(dc, range, selection, rect, descent, style);
+ return wxRichTextParagraphLayoutBox::Draw(dc, context, range, selection, rect, descent, style);
}
/// Copy
}
/// Draw the item
-bool wxRichTextCell::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
+bool wxRichTextCell::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
{
- return wxRichTextBox::Draw(dc, range, selection, rect, descent, style);
+ return wxRichTextBox::Draw(dc, context, range, selection, rect, descent, style);
}
/// Copy
}
// Draws the object.
-bool wxRichTextTable::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
+bool wxRichTextTable::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
{
- return wxRichTextBox::Draw(dc, range, selection, rect, descent, style);
+ return wxRichTextBox::Draw(dc, context, range, selection, rect, descent, style);
}
WX_DECLARE_OBJARRAY(wxRect, wxRichTextRectArray);
// 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, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& WXUNUSED(parentRect), int style)
{
SetPosition(rect.GetPosition());
wxRichTextBuffer* buffer = GetBuffer();
if (buffer) scale = buffer->GetScale();
- wxRect availableSpace = GetAvailableContentArea(dc, rect);
+ wxRect availableSpace = GetAvailableContentArea(dc, context, rect);
wxTextAttrDimensionConverter converter(dc, scale, availableSpace.GetSize());
+ wxRichTextAttr attr(GetAttributes());
+ context.ApplyVirtualAttributes(attr, this);
+
// If we have no fixed table size, and assuming we're not pushed for
// space, then we don't have to try to stretch the table to fit the contents.
bool stretchToFitTableWidth = false;
int tableWidth = rect.width;
- if (GetAttributes().GetTextBoxAttr().GetWidth().IsValid())
+ if (attr.GetTextBoxAttr().GetWidth().IsValid())
{
- tableWidth = converter.GetPixels(GetAttributes().GetTextBoxAttr().GetWidth());
+ tableWidth = converter.GetPixels(attr.GetTextBoxAttr().GetWidth());
// Fixed table width, so we do want to stretch columns out if necessary.
stretchToFitTableWidth = true;
// Get internal padding
int paddingLeft = 0, paddingTop = 0;
- if (GetAttributes().GetTextBoxAttr().GetPadding().GetLeft().IsValid())
- paddingLeft = converter.GetPixels(GetAttributes().GetTextBoxAttr().GetPadding().GetLeft());
- if (GetAttributes().GetTextBoxAttr().GetPadding().GetTop().IsValid())
- paddingTop = converter.GetPixels(GetAttributes().GetTextBoxAttr().GetPadding().GetTop());
+ if (attr.GetTextBoxAttr().GetPadding().GetLeft().IsValid())
+ paddingLeft = converter.GetPixels(attr.GetTextBoxAttr().GetPadding().GetLeft());
+ if (attr.GetTextBoxAttr().GetPadding().GetTop().IsValid())
+ paddingTop = converter.GetPixels(attr.GetTextBoxAttr().GetPadding().GetTop());
// Assume that left and top padding are also used for inter-cell padding.
int paddingX = paddingLeft;
int paddingY = paddingTop;
int totalLeftMargin = 0, totalRightMargin = 0, totalTopMargin = 0, totalBottomMargin = 0;
- GetTotalMargin(dc, buffer, GetAttributes(), totalLeftMargin, totalRightMargin, totalTopMargin, totalBottomMargin);
+ GetTotalMargin(dc, buffer, attr, totalLeftMargin, totalRightMargin, totalTopMargin, totalBottomMargin);
// Internal table width - the area for content
int internalTableWidth = tableWidth - totalLeftMargin - totalRightMargin;
}
// 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, context, 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, context, 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, context, availableCellSpace, availableSpace, style);
// Make sure the cell size really is the appropriate size,
// not the calculated box size
{
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
contentRect = wxRect(wxPoint(0, 0), wxSize(maxRight - availableSpace.x, y - availableSpace.y));
- GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+ GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
SetCachedSize(marginRect.GetSize());
}
}
// Finds the absolute position and row height for the given character position
-bool wxRichTextTable::FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart)
+bool wxRichTextTable::FindPosition(wxDC& dc, wxRichTextDrawingContext& context, long index, wxPoint& pt, int* height, bool forceLineStart)
{
wxRichTextCell* child = GetCell(index+1);
if (child)
{
// Find the position at the start of the child cell, since the table doesn't
// have any caret position of its own.
- return child->FindPosition(dc, -1, pt, height, forceLineStart);
+ return child->FindPosition(dc, context, -1, pt, height, forceLineStart);
}
else
return false;
}
// Gets the range size.
-bool wxRichTextTable::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position, wxArrayInt* partialExtents) const
+bool wxRichTextTable::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position, wxArrayInt* partialExtents) const
{
- return wxRichTextBox::GetRangeSize(range, size, descent, dc, flags, position, partialExtents);
+ return wxRichTextBox::GetRangeSize(range, size, descent, dc, context, flags, position, partialExtents);
}
// Deletes content in the given range.
void OnExit()
{
wxRichTextBuffer::CleanUpHandlers();
+ wxRichTextBuffer::CleanUpDrawingHandlers();
wxRichTextDecimalToRoman(-1);
wxRichTextParagraph::ClearDefaultTabs();
wxRichTextCtrl::ClearAvailableFontNames();
break;
}
case wxRICHTEXT_CHANGE_STYLE:
+ case wxRICHTEXT_CHANGE_PROPERTIES:
{
ApplyParagraphs(GetNewParagraphs());
UpdateAppearance(GetPosition());
wxRichTextEvent cmdEvent(
- wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED,
+ m_cmdId == wxRICHTEXT_CHANGE_STYLE ? wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED : wxEVT_COMMAND_RICHTEXT_PROPERTIES_CHANGED,
m_ctrl ? m_ctrl->GetId() : -1);
cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer);
cmdEvent.SetRange(GetRange());
break;
}
case wxRICHTEXT_CHANGE_STYLE:
+ case wxRICHTEXT_CHANGE_PROPERTIES:
{
ApplyParagraphs(GetOldParagraphs());
// InvalidateHierarchy goes up the hierarchy as well as down, otherwise with a nested object,
UpdateAppearance(GetPosition());
wxRichTextEvent cmdEvent(
- wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED,
+ m_cmdId == wxRICHTEXT_CHANGE_STYLE ? wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED : wxEVT_COMMAND_RICHTEXT_PROPERTIES_CHANGED,
m_ctrl ? m_ctrl->GetId() : -1);
cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer);
cmdEvent.SetRange(GetRange());
}
/// Draw the item
-bool wxRichTextImage::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int WXUNUSED(descent), int WXUNUSED(style))
+bool wxRichTextImage::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int WXUNUSED(descent), int WXUNUSED(style))
{
if (!IsShown())
return true;
if (!LoadImageCache(dc))
return false;
- DrawBoxAttributes(dc, GetBuffer(), GetAttributes(), wxRect(rect.GetPosition(), GetCachedSize()));
+ wxRichTextAttr attr(GetAttributes());
+ context.ApplyVirtualAttributes(attr, this);
+
+ DrawBoxAttributes(dc, GetBuffer(), attr, wxRect(rect.GetPosition(), GetCachedSize()));
#if 0
int y = rect.y + (rect.height - m_imageCache.GetHeight());
wxSize imageSize(m_imageCache.GetWidth(), m_imageCache.GetHeight());
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
marginRect = rect; // outer rectangle, will calculate contentRect
- GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+ GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
dc.DrawBitmap(m_imageCache, contentRect.x, contentRect.y, true);
}
/// Lay the item out
-bool wxRichTextImage::Layout(wxDC& dc, const wxRect& rect, int WXUNUSED(style))
+bool wxRichTextImage::Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& WXUNUSED(parentRect), int WXUNUSED(style))
{
if (!LoadImageCache(dc))
return false;
wxSize imageSize(m_imageCache.GetWidth(), m_imageCache.GetHeight());
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
contentRect = wxRect(wxPoint(0,0), imageSize);
- GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+
+ wxRichTextAttr attr(GetAttributes());
+ context.ApplyVirtualAttributes(attr, this);
+
+ GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
wxSize overallSize = marginRect.GetSize();
/// Get/set the object size for the given range. Returns false if the range
/// is invalid for this object.
-bool wxRichTextImage::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& WXUNUSED(descent), wxDC& dc, int WXUNUSED(flags), wxPoint WXUNUSED(position), wxArrayInt* partialExtents) const
+bool wxRichTextImage::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& WXUNUSED(descent), wxDC& dc, wxRichTextDrawingContext& context, int WXUNUSED(flags), wxPoint WXUNUSED(position), wxArrayInt* partialExtents) const
{
if (!range.IsWithin(GetRange()))
return false;
return false;
}
+ wxRichTextAttr attr(GetAttributes());
+ context.ApplyVirtualAttributes(attr, (wxRichTextObject*) this);
+
wxSize imageSize(m_imageCache.GetWidth(), m_imageCache.GetHeight());
wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;
contentRect = wxRect(wxPoint(0,0), imageSize);
- GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect);
+ GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
wxSize overallSize = marginRect.GetSize();
m_position.Reset();
m_size.Reset();
+ m_minSize.Reset();
+ m_maxSize.Reset();
m_border.Reset();
m_outline.Reset();
m_position == attr.m_position &&
m_size == attr.m_size &&
+ m_minSize == attr.m_minSize &&
+ m_maxSize == attr.m_maxSize &&
m_border == attr.m_border &&
m_outline == attr.m_outline &&
if (!m_position.EqPartial(attr.m_position))
return false;
+ // Size
+
+ if (!m_size.EqPartial(attr.m_size))
+ return false;
+ if (!m_minSize.EqPartial(attr.m_minSize))
+ return false;
+ if (!m_maxSize.EqPartial(attr.m_maxSize))
+ return false;
+
// Margins
if (!m_margins.EqPartial(attr.m_margins))
m_position.Apply(attr.m_position, compareWith ? (& attr.m_position) : (const wxTextAttrDimensions*) NULL);
m_size.Apply(attr.m_size, compareWith ? (& attr.m_size) : (const wxTextAttrSize*) NULL);
+ m_minSize.Apply(attr.m_minSize, compareWith ? (& attr.m_minSize) : (const wxTextAttrSize*) NULL);
+ m_maxSize.Apply(attr.m_maxSize, compareWith ? (& attr.m_maxSize) : (const wxTextAttrSize*) NULL);
m_border.Apply(attr.m_border, compareWith ? (& attr.m_border) : (const wxTextAttrBorders*) NULL);
m_outline.Apply(attr.m_outline, compareWith ? (& attr.m_outline) : (const wxTextAttrBorders*) NULL);
m_position.RemoveStyle(attr.m_position);
m_size.RemoveStyle(attr.m_size);
+ m_minSize.RemoveStyle(attr.m_minSize);
+ m_maxSize.RemoveStyle(attr.m_maxSize);
m_border.RemoveStyle(attr.m_border);
m_outline.RemoveStyle(attr.m_outline);
m_position.CollectCommonAttributes(attr.m_position, clashingAttr.m_position, absentAttr.m_position);
m_size.CollectCommonAttributes(attr.m_size, clashingAttr.m_size, absentAttr.m_size);
+ m_minSize.CollectCommonAttributes(attr.m_minSize, clashingAttr.m_minSize, absentAttr.m_minSize);
+ m_maxSize.CollectCommonAttributes(attr.m_maxSize, clashingAttr.m_maxSize, absentAttr.m_maxSize);
m_border.CollectCommonAttributes(attr.m_border, clashingAttr.m_border, absentAttr.m_border);
m_outline.CollectCommonAttributes(attr.m_outline, clashingAttr.m_outline, absentAttr.m_outline);
bool wxTextBoxAttr::IsDefault() const
{
return GetFlags() == 0 && !m_border.IsValid() && !m_outline.IsValid() &&
- !m_size.GetWidth().IsValid() && !m_size.GetHeight().IsValid() &&
+ !m_size.IsValid() && !m_minSize.IsValid() && !m_maxSize.IsValid() &&
!m_position.IsValid() && !m_padding.IsValid() && !m_margins.IsValid();
}
return -1;
}
+bool wxRichTextProperties::Remove(const wxString& name)
+{
+ int idx = Find(name);
+ if (idx != -1)
+ {
+ m_properties.RemoveAt(idx);
+ return true;
+ }
+ else
+ return false;
+}
+
wxVariant* wxRichTextProperties::FindOrCreateProperty(const wxString& name)
{
int idx = Find(name);
SetProperty(name, wxVariant(value, name));
}
+void wxRichTextProperties::RemoveProperties(const wxRichTextProperties& properties)
+{
+ size_t i;
+ for (i = 0; i < properties.GetCount(); i++)
+ {
+ wxString name = properties.GetProperties()[i].GetName();
+ if (HasProperty(name))
+ Remove(name);
+ }
+}
+
+void wxRichTextProperties::MergeProperties(const wxRichTextProperties& properties)
+{
+ size_t i;
+ for (i = 0; i < properties.GetCount(); i++)
+ {
+ SetProperty(properties.GetProperties()[i]);
+ }
+}
+
wxRichTextObject* wxRichTextObjectAddress::GetObject(wxRichTextParagraphLayoutBox* topLevelContainer) const
{
if (m_address.GetCount() == 0)
return false;
}
+IMPLEMENT_CLASS(wxRichTextDrawingHandler, wxObject)
+IMPLEMENT_CLASS(wxRichTextDrawingContext, wxObject)
+
+bool wxRichTextDrawingContext::HasVirtualAttributes(wxRichTextObject* obj) const
+{
+ wxList::compatibility_iterator node = m_buffer->GetDrawingHandlers().GetFirst();
+ while (node)
+ {
+ wxRichTextDrawingHandler *handler = (wxRichTextDrawingHandler*)node->GetData();
+ if (handler->HasVirtualAttributes(obj))
+ return true;
+
+ node = node->GetNext();
+ }
+ return false;
+}
+
+wxRichTextAttr wxRichTextDrawingContext::GetVirtualAttributes(wxRichTextObject* obj) const
+{
+ wxRichTextAttr attr;
+ // We apply all handlers, so we can may combine several different attributes
+ wxList::compatibility_iterator node = m_buffer->GetDrawingHandlers().GetFirst();
+ while (node)
+ {
+ wxRichTextDrawingHandler *handler = (wxRichTextDrawingHandler*)node->GetData();
+ if (handler->HasVirtualAttributes(obj))
+ {
+ bool success = handler->GetVirtualAttributes(attr, obj);
+ wxASSERT(success);
+ wxUnusedVar(success);
+ }
+
+ node = node->GetNext();
+ }
+ return attr;
+}
+
+bool wxRichTextDrawingContext::ApplyVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const
+{
+ if (HasVirtualAttributes(obj))
+ {
+ wxRichTextAttr a(GetVirtualAttributes(obj));
+ attr.Apply(a);
+ return true;
+ }
+ else
+ return false;
+}
+
+/// Adds a handler to the end
+void wxRichTextBuffer::AddDrawingHandler(wxRichTextDrawingHandler *handler)
+{
+ sm_drawingHandlers.Append(handler);
+}
+
+/// Inserts a handler at the front
+void wxRichTextBuffer::InsertDrawingHandler(wxRichTextDrawingHandler *handler)
+{
+ sm_drawingHandlers.Insert( handler );
+}
+
+/// Removes a handler
+bool wxRichTextBuffer::RemoveDrawingHandler(const wxString& name)
+{
+ wxRichTextDrawingHandler *handler = FindDrawingHandler(name);
+ if (handler)
+ {
+ sm_drawingHandlers.DeleteObject(handler);
+ delete handler;
+ return true;
+ }
+ else
+ return false;
+}
+
+wxRichTextDrawingHandler* wxRichTextBuffer::FindDrawingHandler(const wxString& name)
+{
+ wxList::compatibility_iterator node = sm_drawingHandlers.GetFirst();
+ while (node)
+ {
+ wxRichTextDrawingHandler *handler = (wxRichTextDrawingHandler*)node->GetData();
+ if (handler->GetName().Lower() == name.Lower()) return handler;
+
+ node = node->GetNext();
+ }
+ return NULL;
+}
+
+void wxRichTextBuffer::CleanUpDrawingHandlers()
+{
+ wxList::compatibility_iterator node = sm_drawingHandlers.GetFirst();
+ while (node)
+ {
+ wxRichTextDrawingHandler* handler = (wxRichTextDrawingHandler*)node->GetData();
+ wxList::compatibility_iterator next = node->GetNext();
+ delete handler;
+ node = next;
+ }
+
+ sm_drawingHandlers.Clear();
+}
#endif
// wxUSE_RICHTEXT