diff --git a/include/wx/osx/button.h b/include/wx/osx/button.h index 987c8e9792..1d0353ef87 100644 --- a/include/wx/osx/button.h +++ b/include/wx/osx/button.h @@ -68,6 +68,11 @@ protected: InvalidateBestSize(); } +#if wxUSE_MARKUP && wxOSX_USE_COCOA + virtual bool DoSetLabelMarkup(const wxString& markup); +#endif // wxUSE_MARKUP && wxOSX_USE_COCOA + + // the margins around the bitmap int m_marginX; int m_marginY; diff --git a/include/wx/osx/cocoa/private/markuptoattr.h b/include/wx/osx/cocoa/private/markuptoattr.h new file mode 100644 index 0000000000..63269e3999 --- /dev/null +++ b/include/wx/osx/cocoa/private/markuptoattr.h @@ -0,0 +1,120 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/osx/cocoa/private/markuptoattr.h +// Purpose: Class to convert markup to Cocoa attributed strings. +// Author: Vadim Zeitlin +// Created: 2011-02-22 +// RCS-ID: $Id: wxhead.h,v 1.12 2010-04-22 12:44:51 zeitlin Exp $ +// Copyright: (c) 2011 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_OSX_COCOA_PRIVATE_MARKUPTOATTR_H_ +#define _WX_OSX_COCOA_PRIVATE_MARKUPTOATTR_H_ + +#include "wx/private/markupparserattr.h" + +// ---------------------------------------------------------------------------- +// wxMarkupToAttrString: create NSAttributedString from markup. +// ---------------------------------------------------------------------------- + +class wxMarkupToAttrString : public wxMarkupParserAttrOutput +{ +public: + // We don't care about the original colours because we never use them but + // we do need the correct initial font as we apply modifiers (e.g. create a + // font larger than it) to it and so it must be valid. + wxMarkupToAttrString(wxWindow *win, const wxString& markup) + : wxMarkupParserAttrOutput(win->GetFont(), wxColour(), wxColour()) + { + const wxCFStringRef + label(wxControl::RemoveMnemonics(wxMarkupParser::Strip(markup))); + m_attrString = [[NSMutableAttributedString alloc] + initWithString: label.AsNSString()]; + + m_pos = 0; + + [m_attrString beginEditing]; + + // First thing we do is change the default string font: as mentioned in + // Apple documentation, attributed strings use "Helvetica 12" font by + // default which is different from the system "Lucida Grande" font. So + // we need to explicitly change the font for the entire string. + [m_attrString addAttribute:NSFontAttributeName + value:win->GetFont().OSXGetNSFont() + range:NSMakeRange(0, [m_attrString length])]; + + // Now translate the markup tags to corresponding attributes. + wxMarkupParser parser(*this); + parser.Parse(markup); + + [m_attrString endEditing]; + } + + ~wxMarkupToAttrString() + { + [m_attrString release]; + } + + // Accessor for the users of this class. + // + // We keep ownership of the returned string. + NSMutableAttributedString *GetNSAttributedString() const + { + return m_attrString; + } + + + // Implement base class pure virtual methods to process markup tags. + virtual void OnText(const wxString& text) + { + m_pos += wxControl::RemoveMnemonics(text).length(); + } + + virtual void OnAttrStart(const Attr& WXUNUSED(attr)) + { + // Just remember the starting position of the range, we can't really + // set the attribute until we find the end of it. + m_rangeStarts.push(m_pos); + } + + virtual void OnAttrEnd(const Attr& attr) + { + unsigned start = m_rangeStarts.top(); + m_rangeStarts.pop(); + + const NSRange range = NSMakeRange(start, m_pos - start); + + [m_attrString addAttribute:NSFontAttributeName + value:attr.font.OSXGetNSFont() + range:range]; + + if ( attr.foreground.IsOk() ) + { + [m_attrString addAttribute:NSForegroundColorAttributeName + value:attr.foreground.OSXGetNSColor() + range:range]; + } + + if ( attr.background.IsOk() ) + { + [m_attrString addAttribute:NSBackgroundColorAttributeName + value:attr.background.OSXGetNSColor() + range:range]; + } + } + +private: + // The attributed string we're building. + NSMutableAttributedString *m_attrString; + + // The current position in the output string. + unsigned m_pos; + + // The positions of starting ranges. + wxStack m_rangeStarts; + + + wxDECLARE_NO_COPY_CLASS(wxMarkupToAttrString); +}; + +#endif // _WX_OSX_COCOA_PRIVATE_MARKUPTOATTR_H_ diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index 285561a45d..a42f8287ab 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -270,6 +270,9 @@ public : virtual void SetDefaultButton( bool isDefault ) = 0; virtual void PerformClick() = 0; virtual void SetLabel( const wxString& title, wxFontEncoding encoding ) = 0; +#if wxOSX_USE_COCOA + virtual void SetLabelMarkup( const wxString& WXUNUSED(markup) ) { } +#endif virtual void SetCursor( const wxCursor & cursor ) = 0; virtual void CaptureMouse() = 0; diff --git a/include/wx/osx/stattext.h b/include/wx/osx/stattext.h index 3f76b748a4..fe366452a4 100644 --- a/include/wx/osx/stattext.h +++ b/include/wx/osx/stattext.h @@ -47,6 +47,10 @@ protected : virtual wxSize DoGetBestSize() const ; +#if wxUSE_MARKUP && wxOSX_USE_COCOA + virtual bool DoSetLabelMarkup(const wxString& markup); +#endif // wxUSE_MARKUP && wxOSX_USE_COCOA + DECLARE_DYNAMIC_CLASS_NO_COPY(wxStaticText) }; diff --git a/src/osx/button_osx.cpp b/src/osx/button_osx.cpp index 045ea79675..358fffffd3 100644 --- a/src/osx/button_osx.cpp +++ b/src/osx/button_osx.cpp @@ -142,6 +142,20 @@ void wxButton::DoSetBitmapPosition(wxDirection dir) InvalidateBestSize(); } +#if wxUSE_MARKUP && wxOSX_USE_COCOA + +bool wxButton::DoSetLabelMarkup(const wxString& markup) +{ + if ( !wxButtonBase::DoSetLabelMarkup(markup) ) + return false; + + m_peer->SetLabelMarkup(markup); + + return true; +} + +#endif // wxUSE_MARKUP && wxOSX_USE_COCOA + wxWindow *wxButton::SetDefault() { wxWindow *btnOldDefault = wxButtonBase::SetDefault(); diff --git a/src/osx/cocoa/button.mm b/src/osx/cocoa/button.mm index babc50e429..8e25f09c48 100644 --- a/src/osx/cocoa/button.mm +++ b/src/osx/cocoa/button.mm @@ -18,6 +18,11 @@ #include "wx/osx/private.h" +#if wxUSE_MARKUP + #include "wx/osx/cocoa/private/markuptoattr.h" +#endif // wxUSE_MARKUP + + wxSize wxButton::DoGetBestSize() const { // We only use help button bezel if we don't have any (non standard) label @@ -125,6 +130,23 @@ public: wxWidgetCocoaImpl::SetBitmap(bitmap); } + virtual void SetLabelMarkup(const wxString& markup) + { + wxMarkupToAttrString toAttr(GetWXPeer(), markup); + NSMutableAttributedString *attrString = toAttr.GetNSAttributedString(); + + // Button text is always centered. + NSMutableParagraphStyle * + paragraphStyle = [[NSMutableParagraphStyle alloc] init]; + [paragraphStyle setAlignment: NSCenterTextAlignment]; + [attrString addAttribute:NSParagraphStyleAttributeName + value:paragraphStyle + range:NSMakeRange(0, [attrString length])]; + [paragraphStyle release]; + + [GetNSButton() setAttributedTitle:attrString]; + } + void SetPressedBitmap( const wxBitmap& bitmap ) { NSButton* button = GetNSButton(); diff --git a/src/osx/cocoa/stattext.mm b/src/osx/cocoa/stattext.mm index 57ba5c4069..c096753e0b 100644 --- a/src/osx/cocoa/stattext.mm +++ b/src/osx/cocoa/stattext.mm @@ -25,6 +25,10 @@ #include "wx/osx/private.h" +#if wxUSE_MARKUP + #include "wx/osx/cocoa/private/markuptoattr.h" +#endif // wxUSE_MARKUP + #include @interface wxNSStaticTextView : NSTextField @@ -75,26 +79,42 @@ public: virtual void SetLabel(const wxString& title, wxFontEncoding encoding) { - wxNSStaticTextView* v = (wxNSStaticTextView*)GetWXWidget(); - wxWindow* wxpeer = GetWXPeer(); - NSCell* cell = [v cell]; wxCFStringRef text( title , encoding ); + NSMutableAttributedString * + attrstring = [[NSMutableAttributedString alloc] initWithString:text.AsNSString()]; + DoSetAttrString(attrstring); + [attrstring release]; + } + +#if wxUSE_MARKUP + virtual void SetLabelMarkup( const wxString& markup) + { + wxMarkupToAttrString toAttr(GetWXPeer(), markup); + + DoSetAttrString(toAttr.GetNSAttributedString()); + } +#endif // wxUSE_MARKUP + +private: + void DoSetAttrString(NSMutableAttributedString *attrstring) + { NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; [paragraphStyle setLineBreakMode:m_lineBreak]; - int style = wxpeer->GetWindowStyleFlag(); + int style = GetWXPeer()->GetWindowStyleFlag(); if (style & wxALIGN_CENTER) [paragraphStyle setAlignment: NSCenterTextAlignment]; else if (style & wxALIGN_RIGHT) [paragraphStyle setAlignment: NSRightTextAlignment]; - NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:paragraphStyle, NSParagraphStyleAttributeName, nil]; - NSAttributedString *attrstring = [[NSAttributedString alloc] initWithString:text.AsNSString() attributes:dict]; + [attrstring addAttribute:NSParagraphStyleAttributeName + value:paragraphStyle + range:NSMakeRange(0, [attrstring length])]; + NSCell* cell = [(wxNSStaticTextView *)GetWXWidget() cell]; [cell setAttributedStringValue:attrstring]; - [attrstring release]; [paragraphStyle release]; } -private : + NSLineBreakMode m_lineBreak; }; diff --git a/src/osx/stattext_osx.cpp b/src/osx/stattext_osx.cpp index bf1e915c0d..0ff943ff6d 100644 --- a/src/osx/stattext_osx.cpp +++ b/src/osx/stattext_osx.cpp @@ -104,6 +104,20 @@ void wxStaticText::DoSetLabel(const wxString& label) m_peer->SetLabel(m_label , GetFont().GetEncoding() ); } +#if wxUSE_MARKUP && wxOSX_USE_COCOA + +bool wxStaticText::DoSetLabelMarkup(const wxString& markup) +{ + if ( !wxStaticTextBase::DoSetLabelMarkup(markup) ) + return false; + + m_peer->SetLabelMarkup(markup); + + return true; +} + +#endif // wxUSE_MARKUP && wxOSX_USE_COCOA + wxString wxStaticText::DoGetLabel() const { return m_label;