+ if (attr.GetTextColour().IsOk())
+ dc.SetTextForeground(attr.GetTextColour());
+
+ dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
+
+ int charHeight = dc.GetCharHeight();
+ wxCoord tw, th;
+ dc.GetTextExtent(text, & tw, & th);
+
+ int x = rect.x;
+
+ // Calculate the top position of the character (as opposed to the whole line height)
+ int y = rect.y + (rect.height - charHeight);
+
+ // The margin between a bullet and text.
+ int margin = paragraph->ConvertTenthsMMToPixels(dc, wxRichTextBuffer::GetBulletRightMargin());
+
+ if (attr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT)
+ x = (rect.x + rect.width) - tw - margin;
+ else if (attr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_ALIGN_CENTRE)
+ x = x + (rect.width)/2 - tw/2;
+
+ dc.DrawText(text, x, y);
+
+ return true;
+ }
+ else
+ return false;
+}
+
+bool wxRichTextStdRenderer::DrawBitmapBullet(wxRichTextParagraph* WXUNUSED(paragraph), wxDC& WXUNUSED(dc), const wxRichTextAttr& WXUNUSED(attr), const wxRect& WXUNUSED(rect))
+{
+ // Currently unimplemented. The intention is to store bitmaps by name in a media store associated
+ // with the buffer. The store will allow retrieval from memory, disk or other means.
+ return false;
+}
+
+/// Enumerate the standard bullet names currently supported
+bool wxRichTextStdRenderer::EnumerateStandardBulletNames(wxArrayString& bulletNames)
+{
+ bulletNames.Add(wxTRANSLATE("standard/circle"));
+ bulletNames.Add(wxTRANSLATE("standard/circle-outline"));
+ bulletNames.Add(wxTRANSLATE("standard/square"));
+ bulletNames.Add(wxTRANSLATE("standard/diamond"));
+ bulletNames.Add(wxTRANSLATE("standard/triangle"));
+
+ return true;
+}
+
+/*!
+ * wxRichTextBox
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(wxRichTextBox, wxRichTextParagraphLayoutBox)
+
+wxRichTextBox::wxRichTextBox(wxRichTextObject* parent):
+ wxRichTextParagraphLayoutBox(parent)
+{
+}
+
+/// Draw the item
+bool wxRichTextBox::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
+{
+ if (!IsShown())
+ return true;
+
+ // TODO: if the active object in the control, draw an indication.
+ // We need to add the concept of active object, and not just focus object,
+ // 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, context, range, selection, rect, descent, style);
+}
+
+/// Copy
+void wxRichTextBox::Copy(const wxRichTextBox& obj)
+{
+ wxRichTextParagraphLayoutBox::Copy(obj);
+}
+
+// Edit properties via a GUI
+bool wxRichTextBox::EditProperties(wxWindow* parent, wxRichTextBuffer* buffer)
+{
+ wxRichTextObjectPropertiesDialog boxDlg(this, wxGetTopLevelParent(parent), wxID_ANY, _("Box Properties"));
+ boxDlg.SetAttributes(GetAttributes());
+
+ if (boxDlg.ShowModal() == wxID_OK)
+ {
+ // By passing wxRICHTEXT_SETSTYLE_RESET, indeterminate attributes set by the user will be set as
+ // indeterminate in the object.
+ boxDlg.ApplyStyle(buffer->GetRichTextCtrl(), wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RESET);
+ return true;
+ }
+ else
+ return false;
+}
+
+/*!
+ * wxRichTextField
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(wxRichTextField, wxRichTextParagraphLayoutBox)
+
+wxRichTextField::wxRichTextField(const wxString& fieldType, wxRichTextObject* parent):
+ wxRichTextParagraphLayoutBox(parent)
+{
+ SetFieldType(fieldType);
+}
+
+/// Draw the item
+bool wxRichTextField::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
+{
+ if (!IsShown())
+ return true;
+
+ wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
+ if (fieldType && fieldType->Draw(this, dc, context, range, selection, rect, descent, style))
+ return true;
+
+ // Fallback; but don't draw guidelines.
+ style &= ~wxRICHTEXT_DRAW_GUIDELINES;
+ return wxRichTextParagraphLayoutBox::Draw(dc, context, range, selection, rect, descent, style);
+}
+
+bool wxRichTextField::Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style)
+{
+ wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
+ if (fieldType && fieldType->Layout(this, dc, context, rect, parentRect, style))
+ return true;
+
+ // Fallback
+ return wxRichTextParagraphLayoutBox::Layout(dc, context, rect, parentRect, style);
+}
+
+bool wxRichTextField::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, const wxPoint& position, const wxSize& parentSize, wxArrayInt* partialExtents) const
+{
+ wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
+ if (fieldType)
+ return fieldType->GetRangeSize((wxRichTextField*) this, range, size, descent, dc, context, flags, position, parentSize, partialExtents);
+
+ return wxRichTextParagraphLayoutBox::GetRangeSize(range, size, descent, dc, context, flags, position, parentSize, partialExtents);
+}
+
+/// Calculate range
+void wxRichTextField::CalculateRange(long start, long& end)
+{
+ if (IsTopLevel())
+ wxRichTextParagraphLayoutBox::CalculateRange(start, end);
+ else
+ wxRichTextObject::CalculateRange(start, end);
+}
+
+/// Copy
+void wxRichTextField::Copy(const wxRichTextField& obj)
+{
+ wxRichTextParagraphLayoutBox::Copy(obj);
+
+ UpdateField(GetBuffer());
+}
+
+// Edit properties via a GUI
+bool wxRichTextField::EditProperties(wxWindow* parent, wxRichTextBuffer* buffer)
+{
+ wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
+ if (fieldType)
+ return fieldType->EditProperties(this, parent, buffer);
+
+ return false;
+}
+
+bool wxRichTextField::CanEditProperties() const
+{
+ wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
+ if (fieldType)
+ return fieldType->CanEditProperties((wxRichTextField*) this);
+
+ return false;
+}
+
+wxString wxRichTextField::GetPropertiesMenuLabel() const
+{
+ wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
+ if (fieldType)
+ return fieldType->GetPropertiesMenuLabel((wxRichTextField*) this);
+
+ return wxEmptyString;
+}
+
+bool wxRichTextField::UpdateField(wxRichTextBuffer* buffer)
+{
+ wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
+ if (fieldType)
+ return fieldType->UpdateField(buffer, (wxRichTextField*) this);
+
+ return false;
+}
+
+bool wxRichTextField::IsTopLevel() const
+{
+ wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
+ if (fieldType)
+ return fieldType->IsTopLevel((wxRichTextField*) this);
+
+ return true;
+}
+
+IMPLEMENT_CLASS(wxRichTextFieldType, wxObject)
+
+IMPLEMENT_CLASS(wxRichTextFieldTypeStandard, wxRichTextFieldType)
+
+wxRichTextFieldTypeStandard::wxRichTextFieldTypeStandard(const wxString& name, const wxString& label, int displayStyle)
+{
+ Init();
+
+ SetName(name);
+ SetLabel(label);
+ SetDisplayStyle(displayStyle);
+}
+
+wxRichTextFieldTypeStandard::wxRichTextFieldTypeStandard(const wxString& name, const wxBitmap& bitmap, int displayStyle)
+{
+ Init();
+
+ SetName(name);
+ SetBitmap(bitmap);
+ SetDisplayStyle(displayStyle);
+}
+
+void wxRichTextFieldTypeStandard::Init()
+{
+ m_displayStyle = wxRICHTEXT_FIELD_STYLE_RECTANGLE;
+ m_font = wxFont(6, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
+ m_textColour = *wxWHITE;
+ m_borderColour = *wxBLACK;
+ m_backgroundColour = *wxBLACK;
+ m_verticalPadding = 1;
+ m_horizontalPadding = 3;
+ m_horizontalMargin = 2;
+ m_verticalMargin = 0;
+}
+
+void wxRichTextFieldTypeStandard::Copy(const wxRichTextFieldTypeStandard& field)
+{
+ wxRichTextFieldType::Copy(field);
+
+ m_label = field.m_label;
+ m_displayStyle = field.m_displayStyle;
+ m_font = field.m_font;
+ m_textColour = field.m_textColour;
+ m_borderColour = field.m_borderColour;
+ m_backgroundColour = field.m_backgroundColour;
+ m_verticalPadding = field.m_verticalPadding;
+ m_horizontalPadding = field.m_horizontalPadding;
+ m_horizontalMargin = field.m_horizontalMargin;
+ m_bitmap = field.m_bitmap;
+}
+
+bool wxRichTextFieldTypeStandard::Draw(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& WXUNUSED(context), const wxRichTextRange& WXUNUSED(range), const wxRichTextSelection& selection, const wxRect& rect, int descent, int WXUNUSED(style))
+{
+ if (m_displayStyle == wxRICHTEXT_FIELD_STYLE_COMPOSITE)
+ return false; // USe default composite drawing
+ else // if (m_displayStyle == wxRICHTEXT_FIELD_STYLE_RECTANGLE || m_displayStyle == wxRICHTEXT_FIELD_STYLE_NOBORDER)
+ {
+ int borderSize = 1;