diff --git a/docs/changes.txt b/docs/changes.txt index d9af046d56..42da06b321 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -107,6 +107,7 @@ All (GUI): - Added parameter to wxScrolledWindow XRC handler. - wxRichTextCtrl performance has been improved considerably. - Several wxRichTextCtrl style, paste and undo bugs fixed. +- Added wxRichTextCtrl superscript and subscript support (Knut Petter Lehre). - wxNotebook RTTI corrected, so now wxDynamicCast(notebook, wxBookCtrlBase) works. - When focus is set to wxScrolledWindow child, scroll it into view. @@ -128,8 +129,8 @@ All (GUI): - Fixed crash in wxHtmlHelpController if the help window is still open. - Fixed generic art provider to scale bitmaps down to client-specific best size if needed. -- Made wxSpinCtrl::Reparent() in MSW and generic versions (Angelo Mottola) -- Fixed timing of malformed animated GIFs in wxHTML (Gennady Feller) +- Made wxSpinCtrl::Reparent() in MSW and generic versions (Angelo Mottola). +- Fixed timing of malformed animated GIFs in wxHTML (Gennady Feller). All (Unix): diff --git a/include/wx/richtext/richtextbuffer.h b/include/wx/richtext/richtextbuffer.h index 102b7bc3ac..ee0be4678b 100644 --- a/include/wx/richtext/richtextbuffer.h +++ b/include/wx/richtext/richtextbuffer.h @@ -277,6 +277,12 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextBuffer; #define wxTEXT_ATTR_ALL (wxTEXT_ATTR_CHARACTER|wxTEXT_ATTR_PARAGRAPH) +/*! + * Default superscript/subscript font multiplication factor + */ + +#define wxSCRIPT_MUL_FACTOR 1.5 + /*! * wxRichTextRange class declaration * This stores beginning and end positions for a range of data. diff --git a/include/wx/richtext/richtextfontpage.h b/include/wx/richtext/richtextfontpage.h index 839e9ce978..c9975a5c45 100644 --- a/include/wx/richtext/richtextfontpage.h +++ b/include/wx/richtext/richtextfontpage.h @@ -103,6 +103,12 @@ public: /// wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_RICHTEXTFONTPAGE_CAPSCTRL void OnCapsctrlClick( wxCommandEvent& event ); + /// wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_RICHTEXTFONTPAGE_SUPERSCRIPT + void OnRichtextfontpageSuperscriptClick( wxCommandEvent& event ); + + /// wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_RICHTEXTFONTPAGE_SUBSCRIPT + void OnRichtextfontpageSubscriptClick( wxCommandEvent& event ); + ////@end wxRichTextFontPage event handler declarations ////@begin wxRichTextFontPage member function declarations @@ -128,6 +134,8 @@ public: wxRichTextColourSwatchCtrl* m_colourCtrl; wxCheckBox* m_strikethroughCtrl; wxCheckBox* m_capitalsCtrl; + wxCheckBox* m_superscriptCtrl; + wxCheckBox* m_subscriptCtrl; wxRichTextFontPreviewCtrl* m_previewCtrl; /// Control identifiers enum { @@ -142,6 +150,8 @@ public: ID_RICHTEXTFONTPAGE_COLOURCTRL = 10009, ID_RICHTEXTFONTPAGE_STRIKETHROUGHCTRL = 10010, ID_RICHTEXTFONTPAGE_CAPSCTRL = 10011, + ID_RICHTEXTFONTPAGE_SUPERSCRIPT = 10012, + ID_RICHTEXTFONTPAGE_SUBSCRIPT = 10013, ID_RICHTEXTFONTPAGE_PREVIEWCTRL = 10003 }; ////@end wxRichTextFontPage member variables diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index ea91634cec..41d219fedc 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -4432,17 +4432,47 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR long len = range.GetLength(); wxString stringChunk = str.Mid(range.GetStart() - offset, (size_t) len); + wxFont textFont = textAttr.GetFont(); + if (textFont.Ok()) + wxCheckSetFont(dc, textFont); + int charHeight = dc.GetCharHeight(); - int x = rect.x; - int y = rect.y + (rect.height - charHeight - (descent - m_descent)); + int x, y; + if ( textFont.Ok() ) + { + if ( textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT) ) + { + double size = static_cast(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR; + textFont.SetPointSize( static_cast(size) ); + x = rect.x; + y = rect.y; + wxCheckSetFont(dc, textFont); + } + else if ( textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT) ) + { + double size = static_cast(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR; + textFont.SetPointSize( static_cast(size) ); + x = rect.x; + int sub_height = static_cast( static_cast(charHeight) / wxSCRIPT_MUL_FACTOR); + y = rect.y + (rect.height - sub_height + (descent - m_descent)); + wxCheckSetFont(dc, textFont); + } + else + { + x = rect.x; + y = rect.y + (rect.height - charHeight - (descent - m_descent)); + } + } + else + { + x = rect.x; + y = rect.y + (rect.height - charHeight - (descent - m_descent)); + } // Test for the optimized situations where all is selected, or none // is selected. - if (textAttr.GetFont().Ok()) - wxCheckSetFont(dc, textAttr.GetFont()); - // (a) All selected. if (selectionRange.GetStart() <= range.GetStart() && selectionRange.GetEnd() >= range.GetEnd()) { @@ -4695,8 +4725,24 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz // of line breaks - and we don't need it, since we'll calculate size within // formatted text by doing it in chunks according to the line ranges - if (textAttr.GetFont().Ok()) - wxCheckSetFont(dc, textAttr.GetFont()); + bool bScript(false); + wxFont font(textAttr.GetFont()); + if (font.Ok()) + { + if ( textAttr.HasTextEffects() && ( (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT) + || (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT) ) ) + { + wxFont textFont = font; + double size = static_cast(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR; + textFont.SetPointSize( static_cast(size) ); + wxCheckSetFont(dc, textFont); + bScript = true; + } + else + { + wxCheckSetFont(dc, font); + } + } int startPos = range.GetStart() - GetRange().GetStart(); long len = range.GetLength(); @@ -4765,6 +4811,10 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz } dc.GetTextExtent(stringChunk, & w, & h, & descent); width += w; + + if ( bScript ) + dc.SetFont(font); + size = wxSize(width, dc.GetCharHeight()); return true; diff --git a/src/richtext/richtextdialogs.pjd b/src/richtext/richtextdialogs.pjd index 3067855f07..8a3c6b51ce 100644 --- a/src/richtext/richtextdialogs.pjd +++ b/src/richtext/richtextdialogs.pjd @@ -136,6 +136,7 @@ 0 "" 1 + 0 "" "Debug" "ANSI" @@ -177,6 +178,8 @@ "%AUTO%" "%AUTO%" "%AUTO%" + 0 + 1 @@ -248,7 +251,6 @@ 0 0 1 - 0 0 0 0 @@ -291,14 +293,6 @@ "wbBoxSizerProxy" "Vertical" "" - "Centre" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 0 0 0 @@ -1688,6 +1682,136 @@ "" "" + + "wxCheckBox: ID_RICHTEXTFONTPAGE_SUPERSCRIPT" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "10/4/2008" + "wbCheckBoxProxy" + "wxEVT_COMMAND_CHECKBOX_CLICKED|OnRichtextfontpageSuperscriptClick|NONE||wxRichTextFontPage" + "ID_RICHTEXTFONTPAGE_SUPERSCRIPT" + 10012 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_superscriptCtrl" + "Supe&rscript" + 0 + "Check to show the text in superscript." + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxCheckBox: ID_RICHTEXTFONTPAGE_SUBSCRIPT" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "10/4/2008" + "wbCheckBoxProxy" + "wxEVT_COMMAND_CHECKBOX_CLICKED|OnRichtextfontpageSubscriptClick|NONE||wxRichTextFontPage" + "ID_RICHTEXTFONTPAGE_SUBSCRIPT" + 10013 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_subscriptCtrl" + "Subscrip&t" + 0 + "Check to show the text in subscript." + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "Spacer" @@ -1836,7 +1960,6 @@ 0 0 1 - 0 0 0 0 @@ -1867,6 +1990,7 @@ 300 0 "" + 0 "wxBoxSizer V" "dialog-control-document" @@ -4345,7 +4469,6 @@ 0 0 1 - 0 0 0 0 @@ -4376,6 +4499,7 @@ 300 0 "" + 0 "wxBoxSizer V" "dialog-control-document" @@ -5082,7 +5206,6 @@ 0 0 1 - 0 0 0 0 @@ -5113,6 +5236,7 @@ 300 0 "" + 0 "wxBoxSizer V" "dialog-control-document" @@ -6755,7 +6879,6 @@ 0 0 1 - 0 0 0 0 @@ -6786,6 +6909,7 @@ 300 0 "" + 0 "wxBoxSizer V" "dialog-control-document" @@ -7391,7 +7515,6 @@ 1 0 1 - 0 0 0 0 @@ -7422,6 +7545,7 @@ 300 0 "" + 0 "wxBoxSizer V" "dialog-control-document" @@ -7435,6 +7559,14 @@ "wbBoxSizerProxy" "Vertical" "" + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 0 0 0 @@ -8739,7 +8871,6 @@ 1 0 1 - 0 1 0 0 @@ -8770,6 +8901,7 @@ 300 0 "" + 0 "wxBoxSizer V" "dialog-control-document" @@ -10166,7 +10298,6 @@ 0 0 1 - 0 0 0 0 @@ -10197,6 +10328,7 @@ 300 0 "" + 0 "wxBoxSizer V" "dialog-control-document" diff --git a/src/richtext/richtextfontpage.cpp b/src/richtext/richtextfontpage.cpp index 47444f2284..ba8c918ed8 100644 --- a/src/richtext/richtextfontpage.cpp +++ b/src/richtext/richtextfontpage.cpp @@ -42,6 +42,10 @@ BEGIN_EVENT_TABLE( wxRichTextFontPage, wxPanel ) EVT_CHECKBOX( ID_RICHTEXTFONTPAGE_CAPSCTRL, wxRichTextFontPage::OnCapsctrlClick ) + EVT_CHECKBOX( ID_RICHTEXTFONTPAGE_SUPERSCRIPT, wxRichTextFontPage::OnRichtextfontpageSuperscriptClick ) + + EVT_CHECKBOX( ID_RICHTEXTFONTPAGE_SUBSCRIPT, wxRichTextFontPage::OnRichtextfontpageSubscriptClick ) + ////@end wxRichTextFontPage event table entries END_EVENT_TABLE() @@ -81,6 +85,8 @@ void wxRichTextFontPage::Init() m_colourCtrl = NULL; m_strikethroughCtrl = NULL; m_capitalsCtrl = NULL; + m_superscriptCtrl = NULL; + m_subscriptCtrl = NULL; m_previewCtrl = NULL; ////@end wxRichTextFontPage member initialisation } @@ -230,6 +236,20 @@ void wxRichTextFontPage::CreateControls() m_capitalsCtrl->SetToolTip(_("Check to show the text in capitals.")); itemBoxSizer26->Add(m_capitalsCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + m_superscriptCtrl = new wxCheckBox( itemPanel1, ID_RICHTEXTFONTPAGE_SUPERSCRIPT, _("Supe&rscript"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); + m_superscriptCtrl->SetValue(false); + m_superscriptCtrl->SetHelpText(_("Check to show the text in superscript.")); + if (wxRichTextFontPage::ShowToolTips()) + m_superscriptCtrl->SetToolTip(_("Check to show the text in superscript.")); + itemBoxSizer26->Add(m_superscriptCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_subscriptCtrl = new wxCheckBox( itemPanel1, ID_RICHTEXTFONTPAGE_SUBSCRIPT, _("Subscrip&t"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); + m_subscriptCtrl->SetValue(false); + m_subscriptCtrl->SetHelpText(_("Check to show the text in subscript.")); + if (wxRichTextFontPage::ShowToolTips()) + m_subscriptCtrl->SetToolTip(_("Check to show the text in subscript.")); + itemBoxSizer26->Add(m_subscriptCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + itemBoxSizer3->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL, 5); m_previewCtrl = new wxRichTextFontPreviewCtrl( itemPanel1, ID_RICHTEXTFONTPAGE_PREVIEWCTRL, wxDefaultPosition, wxSize(100, 60), 0 ); @@ -373,6 +393,24 @@ bool wxRichTextFontPage::TransferDataFromWindow() attr->SetTextEffects(attr->GetTextEffects() & ~wxTEXT_ATTR_EFFECT_CAPITALS); } + if (m_superscriptCtrl->Get3StateValue() == wxCHK_CHECKED) + { + attr->SetTextEffectFlags(attr->GetTextEffectFlags() | wxTEXT_ATTR_EFFECT_SUPERSCRIPT); + attr->SetTextEffects(attr->GetTextEffects() | wxTEXT_ATTR_EFFECT_SUPERSCRIPT); + attr->SetTextEffects(attr->GetTextEffects() & ~wxTEXT_ATTR_EFFECT_SUBSCRIPT); + } + else if (m_subscriptCtrl->Get3StateValue() == wxCHK_CHECKED) + { + attr->SetTextEffectFlags(attr->GetTextEffectFlags() | wxTEXT_ATTR_EFFECT_SUBSCRIPT); + attr->SetTextEffects(attr->GetTextEffects() | wxTEXT_ATTR_EFFECT_SUBSCRIPT); + attr->SetTextEffects(attr->GetTextEffects() & ~wxTEXT_ATTR_EFFECT_SUPERSCRIPT); + } + else + { + attr->SetTextEffectFlags(attr->GetTextEffectFlags() | wxTEXT_ATTR_EFFECT_SUBSCRIPT | wxTEXT_ATTR_EFFECT_SUPERSCRIPT ); + attr->SetTextEffects(attr->GetTextEffects() & ~( wxTEXT_ATTR_EFFECT_SUPERSCRIPT | wxTEXT_ATTR_EFFECT_SUBSCRIPT)); + } + return true; } @@ -470,11 +508,37 @@ bool wxRichTextFontPage::TransferDataToWindow() } else m_capitalsCtrl->Set3StateValue(wxCHK_UNDETERMINED); + + if ( attr->GetTextEffectFlags() & (wxTEXT_ATTR_EFFECT_SUPERSCRIPT | wxTEXT_ATTR_EFFECT_SUBSCRIPT) ) + { + if (attr->GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT) + { + m_superscriptCtrl->Set3StateValue(wxCHK_CHECKED); + m_subscriptCtrl->Set3StateValue(wxCHK_UNCHECKED); + } + else if (attr->GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT) + { + m_superscriptCtrl->Set3StateValue(wxCHK_UNCHECKED); + m_subscriptCtrl->Set3StateValue(wxCHK_CHECKED); + } + else + { + m_superscriptCtrl->Set3StateValue(wxCHK_UNCHECKED); + m_subscriptCtrl->Set3StateValue(wxCHK_UNCHECKED); + } + } + else + { + m_superscriptCtrl->Set3StateValue(wxCHK_UNCHECKED); + m_subscriptCtrl->Set3StateValue(wxCHK_UNCHECKED); + } } else { m_strikethroughCtrl->Set3StateValue(wxCHK_UNDETERMINED); m_capitalsCtrl->Set3StateValue(wxCHK_UNDETERMINED); + m_superscriptCtrl->Set3StateValue(wxCHK_UNCHECKED); + m_subscriptCtrl->Set3StateValue(wxCHK_UNCHECKED); } UpdatePreview(); @@ -556,6 +620,11 @@ void wxRichTextFontPage::UpdatePreview() textEffects |= wxTEXT_ATTR_EFFECT_CAPITALS; } + if ( m_superscriptCtrl->Get3StateValue() == wxCHK_CHECKED ) + textEffects |= wxTEXT_ATTR_EFFECT_SUPERSCRIPT; + else if ( m_subscriptCtrl->Get3StateValue() == wxCHK_CHECKED ) + textEffects |= wxTEXT_ATTR_EFFECT_SUBSCRIPT; + m_previewCtrl->SetFont(font); m_previewCtrl->SetTextEffects(textEffects); m_previewCtrl->Refresh(); @@ -730,4 +799,24 @@ void wxRichTextFontPage::OnCapsctrlClick( wxCommandEvent& WXUNUSED(event) ) UpdatePreview(); } +/*! + * wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_RICHTEXTFONTPAGE_SUPERSCRIPT + */ +void wxRichTextFontPage::OnRichtextfontpageSuperscriptClick( wxCommandEvent& WXUNUSED(event) ) +{ + if ( m_superscriptCtrl->Get3StateValue() == wxCHK_CHECKED && m_subscriptCtrl->Get3StateValue() == wxCHK_CHECKED ) + m_subscriptCtrl->Set3StateValue( wxCHK_UNCHECKED ); + UpdatePreview(); +} + +/*! + * wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_RICHTEXTFONTPAGE_SUBSCRIPT + */ + +void wxRichTextFontPage::OnRichtextfontpageSubscriptClick( wxCommandEvent& WXUNUSED(event) ) +{ + if ( m_superscriptCtrl->Get3StateValue() == wxCHK_CHECKED && m_subscriptCtrl->Get3StateValue() == wxCHK_CHECKED ) + m_superscriptCtrl->Set3StateValue( wxCHK_UNCHECKED ); + UpdatePreview(); +} diff --git a/src/richtext/richtextformatdlg.cpp b/src/richtext/richtextformatdlg.cpp index 0c1d173365..f171898bd3 100644 --- a/src/richtext/richtextformatdlg.cpp +++ b/src/richtext/richtextformatdlg.cpp @@ -401,6 +401,12 @@ void wxRichTextFontPreviewCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) wxSize size = GetSize(); wxFont font = GetFont(); + if ((GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT) || (GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT)) + { + double size = static_cast(font.GetPointSize()) / wxSCRIPT_MUL_FACTOR; + font.SetPointSize( static_cast(size) ); + } + if ( font.Ok() ) { dc.SetFont(font); @@ -415,6 +421,11 @@ void wxRichTextFontPreviewCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) int cx = wxMax(2, (size.x/2) - (w/2)); int cy = wxMax(2, (size.y/2) - (h/2)); + if ( GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT ) + cy -= h/2; + if ( GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT ) + cy += h/2; + dc.SetTextForeground(GetForegroundColour()); dc.SetClippingRegion(2, 2, size.x-4, size.y-4); dc.DrawText(text, cx, cy);