diff --git a/docs/changes.txt b/docs/changes.txt index c29def0fd8..00a598370a 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -84,8 +84,10 @@ All (GUI): - Fix vertical scrollbar visibility in wxStyledTextCtrl (yenwu, NewPagodi). - Fix bug with not being able to select AUI tab after dragging. - Make wxDataViewCtrl::Expand() expand ancestors in native ports too. +- Add wxDataViewTextRenderer::EnableMarkup(). - Add wxDataViewCtrl::SetHeaderAttr(). - Add wxListCtrl::SetHeaderAttr(). +- Add support for using markup in wxDataViewCtrl text items. - Implement auto complete in generic wxSearchCtrl (Eric Jensen). wxGTK: diff --git a/include/wx/generic/dvrenderers.h b/include/wx/generic/dvrenderers.h index a56beaf034..3e7f6825af 100644 --- a/include/wx/generic/dvrenderers.h +++ b/include/wx/generic/dvrenderers.h @@ -53,6 +53,11 @@ public: wxDataViewTextRenderer( const wxString &varianttype = GetDefaultType(), wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, int align = wxDVR_DEFAULT_ALIGNMENT ); + virtual ~wxDataViewTextRenderer(); + +#if wxUSE_MARKUP + void EnableMarkup(bool enable = true); +#endif // wxUSE_MARKUP virtual bool SetValue( const wxVariant &value ); virtual bool GetValue( wxVariant &value ) const; @@ -69,7 +74,11 @@ public: protected: wxString m_text; -protected: +private: +#if wxUSE_MARKUP + class wxMarkupText *m_markupText; +#endif // wxUSE_MARKUP + wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewTextRenderer); }; diff --git a/include/wx/gtk/dvrenderers.h b/include/wx/gtk/dvrenderers.h index 68e4d4a980..3305203057 100644 --- a/include/wx/gtk/dvrenderers.h +++ b/include/wx/gtk/dvrenderers.h @@ -31,6 +31,10 @@ public: wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, int align = wxDVR_DEFAULT_ALIGNMENT ); +#if wxUSE_MARKUP + void EnableMarkup(bool enable = true); +#endif // wxUSE_MARKUP + virtual bool SetValue( const wxVariant &value ) wxOVERRIDE { return SetTextValue(value); @@ -58,6 +62,14 @@ protected: bool SetTextValue(const wxString& str); bool GetTextValue(wxString& str) const; + // Return the name of the GtkCellRendererText property to use: "text" or + // "markup". + const char* GetTextPropertyName() const; + +#if wxUSE_MARKUP + // True if we should interpret markup in our text. + bool m_useMarkup; +#endif // wxUSE_MARKUP wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewTextRenderer); }; diff --git a/include/wx/osx/dvrenderers.h b/include/wx/osx/dvrenderers.h index 4da26441a6..c62a19ffb5 100644 --- a/include/wx/osx/dvrenderers.h +++ b/include/wx/osx/dvrenderers.h @@ -55,6 +55,10 @@ public: wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, int align = wxDVR_DEFAULT_ALIGNMENT); +#if wxUSE_MARKUP && wxOSX_USE_COCOA + void EnableMarkup(bool enable = true); +#endif // wxUSE_MARKUP && Cocoa + virtual bool MacRender(); virtual void OSXOnCellChanged(NSObject *value, @@ -62,6 +66,11 @@ public: unsigned col); private: +#if wxUSE_MARKUP && wxOSX_USE_COCOA + // True if we should interpret markup in our text. + bool m_useMarkup; +#endif // wxUSE_MARKUP && Cocoa + wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewTextRenderer); }; diff --git a/interface/wx/dataview.h b/interface/wx/dataview.h index 2c29c76049..e68a589097 100644 --- a/interface/wx/dataview.h +++ b/interface/wx/dataview.h @@ -1966,6 +1966,49 @@ public: wxDataViewTextRenderer(const wxString& varianttype = GetDefaultType(), wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, int align = wxDVR_DEFAULT_ALIGNMENT ); + + /** + Enable interpretation of markup in the item data. + + If this method is called with @true argument, markup (@ref + wxControl::SetLabelMarkup()) in the data of the items in this column + will be interpreted, which can be used for a more fine-grained + appearance control than just setting an attribute, which affects all of + the item text. + + For example, as shown in the @ref page_samples_dataview, after creating + a column using a markup-enabled renderer: + @code + wxDataViewTextRenderer* renderer = new wxDataViewTextRenderer(); + renderer->EnableMarkup(); + dataViewCtrl->AppendColumn(new wxDataViewColumn("title", renderer, 0)); + @endcode + + The overridden model wxDataViewModel::GetValue() method may return + values containing markup for this column: + @code + void MyModel::GetValue(wxVariant& variant, + const wxDataViewItem& item, + unsigned int col) const + { + if ( col == 0 && item == ... ) + { + variant = "light and " + "dark blue"; + } + + ... + } + @endcode + + @note Currently wxDataViewIconTextRenderer only provides EnableMarkup() + EnableMarkup() in wxGTK, but not under the other platforms, so you + should only use it for plain wxDataViewTextRenderer columns, + without icons, in portable code. + + @since 3.1.1 + */ + void EnableMarkup(bool enable = true); }; diff --git a/samples/dataview/dataview.cpp b/samples/dataview/dataview.cpp index fca7630647..6cd58d97b6 100644 --- a/samples/dataview/dataview.cpp +++ b/samples/dataview/dataview.cpp @@ -702,9 +702,14 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l m_ctrl[1]->AppendDateColumn("date", MyListModel::Col_Date); + + wxDataViewTextRenderer* const markupRenderer = new wxDataViewTextRenderer(); +#if wxUSE_MARKUP + markupRenderer->EnableMarkup(); +#endif // wxUSE_MARKUP m_attributes = new wxDataViewColumn("attributes", - new wxDataViewTextRenderer, + markupRenderer, MyListModel::Col_TextWithAttr, wxCOL_WIDTH_AUTOSIZE, wxALIGN_RIGHT, diff --git a/samples/dataview/mymodels.cpp b/samples/dataview/mymodels.cpp index bf6b219206..1ee62f8083 100644 --- a/samples/dataview/mymodels.cpp +++ b/samples/dataview/mymodels.cpp @@ -436,7 +436,14 @@ void MyListModel::GetValueByRow( wxVariant &variant, { static const char *labels[5] = { - "blue", "green", "red", "bold cyan", "default", + // These strings will look wrong without wxUSE_MARKUP, but + // it's just a sample, so we don't care. + "light and " + "dark blue", + "growing green", + "emphatic red", + "bold cyan", + "dull default", }; variant = labels[row % 5]; diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index a18f8a5cd2..24d8a36010 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -50,6 +50,7 @@ #include "wx/selstore.h" #include "wx/stopwatch.h" #include "wx/weakref.h" +#include "wx/generic/private/markuptext.h" #include "wx/generic/private/widthcalc.h" //----------------------------------------------------------------------------- @@ -1004,12 +1005,48 @@ wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString &varianttype, wxDataViewCellMode mode, int align ) : wxDataViewRenderer( varianttype, mode, align ) { +#if wxUSE_MARKUP + m_markupText = NULL; +#endif // wxUSE_MARKUP } +wxDataViewTextRenderer::~wxDataViewTextRenderer() +{ +#if wxUSE_MARKUP + delete m_markupText; +#endif // wxUSE_MARKUP +} + +#if wxUSE_MARKUP +void wxDataViewTextRenderer::EnableMarkup(bool enable) +{ + if ( enable ) + { + if ( !m_markupText ) + { + m_markupText = new wxMarkupText(wxString()); + } + } + else + { + if ( m_markupText ) + { + delete m_markupText; + m_markupText = NULL; + } + } +} +#endif // wxUSE_MARKUP + bool wxDataViewTextRenderer::SetValue( const wxVariant &value ) { m_text = value.GetString(); +#if wxUSE_MARKUP + if ( m_markupText ) + m_markupText->SetMarkupText(m_text); +#endif // wxUSE_MARKUP + return true; } @@ -1038,14 +1075,39 @@ bool wxDataViewTextRenderer::GetValueFromEditorCtrl( wxWindow *editor, wxVariant bool wxDataViewTextRenderer::Render(wxRect rect, wxDC *dc, int state) { - RenderText(m_text, 0, rect, dc, state); +#if wxUSE_MARKUP + if ( m_markupText ) + { + int flags = 0; + if ( state & wxDATAVIEW_CELL_SELECTED ) + flags |= wxCONTROL_SELECTED; + m_markupText->RenderItemText(GetView(), *dc, rect, flags); + } + else +#endif // wxUSE_MARKUP + RenderText(m_text, 0, rect, dc, state); + return true; } wxSize wxDataViewTextRenderer::GetSize() const { if (!m_text.empty()) + { +#if wxUSE_MARKUP + if ( m_markupText ) + { + wxDataViewCtrl* const view = GetView(); + wxClientDC dc(view); + if ( GetAttr().HasFont() ) + dc.SetFont(GetAttr().GetEffectiveFont(view->GetFont())); + + return m_markupText->Measure(dc); + } +#endif // wxUSE_MARKUP + return GetTextExtent(m_text); + } else return wxSize(wxDVC_DEFAULT_RENDERER_SIZE,wxDVC_DEFAULT_RENDERER_SIZE); } diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index 8be64c4633..9a3c82e39c 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -2277,6 +2277,10 @@ wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString &varianttype, wxD int align ) : wxDataViewRenderer( varianttype, mode, align ) { +#if wxUSE_MARKUP + m_useMarkup = false; +#endif // wxUSE_MARKUP + GtkWxCellRendererText *text_renderer = gtk_wx_cell_renderer_text_new(); text_renderer->wx_renderer = this; m_renderer = (GtkCellRenderer*) text_renderer; @@ -2298,12 +2302,29 @@ wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString &varianttype, wxD SetAlignment(align); } +#if wxUSE_MARKUP +void wxDataViewTextRenderer::EnableMarkup(bool enable) +{ + m_useMarkup = enable; +} +#endif // wxUSE_MARKUP + +const char* wxDataViewTextRenderer::GetTextPropertyName() const +{ +#if wxUSE_MARKUP + if ( m_useMarkup ) + return "markup"; +#endif // wxUSE_MARKUP + + return "text"; +} + bool wxDataViewTextRenderer::SetTextValue(const wxString& str) { GValue gvalue = G_VALUE_INIT; g_value_init( &gvalue, G_TYPE_STRING ); g_value_set_string( &gvalue, wxGTK_CONV_FONT( str, GetOwner()->GetOwner()->GetFont() ) ); - g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue ); + g_object_set_property( G_OBJECT(m_renderer), GetTextPropertyName(), &gvalue ); g_value_unset( &gvalue ); return true; @@ -2313,7 +2334,7 @@ bool wxDataViewTextRenderer::GetTextValue(wxString& str) const { GValue gvalue = G_VALUE_INIT; g_value_init( &gvalue, G_TYPE_STRING ); - g_object_get_property( G_OBJECT(m_renderer), "text", &gvalue ); + g_object_get_property( G_OBJECT(m_renderer), GetTextPropertyName(), &gvalue ); str = wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue ), const_cast(this)->GetOwner()->GetOwner()->GetFont() ); g_value_unset( &gvalue ); diff --git a/src/osx/cocoa/dataview.mm b/src/osx/cocoa/dataview.mm index db4f96d6d1..427945316c 100644 --- a/src/osx/cocoa/dataview.mm +++ b/src/osx/cocoa/dataview.mm @@ -30,6 +30,10 @@ #include "wx/stopwatch.h" #include "wx/dcgraph.h" +#if wxUSE_MARKUP + #include "wx/osx/cocoa/private/markuptoattr.h" +#endif // wxUSE_MARKUP + // ============================================================================ // Constants used locally // ============================================================================ @@ -2730,6 +2734,10 @@ wxDataViewTextRenderer::wxDataViewTextRenderer(const wxString& varianttype, int align) : wxDataViewRenderer(varianttype,mode,align) { +#if wxUSE_MARKUP + m_useMarkup = false; +#endif // wxUSE_MARKUP + NSTextFieldCell* cell; @@ -2739,8 +2747,27 @@ wxDataViewTextRenderer::wxDataViewTextRenderer(const wxString& varianttype, [cell release]; } +#if wxUSE_MARKUP + +void wxDataViewTextRenderer::EnableMarkup(bool enable) +{ + m_useMarkup = enable; +} + +#endif // wxUSE_MARKUP + bool wxDataViewTextRenderer::MacRender() { +#if wxUSE_MARKUP + if ( m_useMarkup ) + { + wxMarkupToAttrString toAttr(GetView(), GetValue().GetString()); + + [GetNativeData()->GetItemCell() setAttributedStringValue:toAttr.GetNSAttributedString()]; + return true; + } +#endif // wxUSE_MARKUP + [GetNativeData()->GetItemCell() setObjectValue:wxCFStringRef(GetValue().GetString()).AsNSString()]; return true; }