]>
Commit | Line | Data |
---|---|---|
1 | /////////////////////////////////////////////////////////////////////////////// | |
2 | // Name: wx/private/markupparserattr.h | |
3 | // Purpose: Classes mapping markup attributes to wxFont/wxColour. | |
4 | // Author: Vadim Zeitlin | |
5 | // Created: 2011-02-18 | |
6 | // Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org> | |
7 | // Licence: wxWindows licence | |
8 | /////////////////////////////////////////////////////////////////////////////// | |
9 | ||
10 | #ifndef _WX_PRIVATE_MARKUPPARSERATTR_H_ | |
11 | #define _WX_PRIVATE_MARKUPPARSERATTR_H_ | |
12 | ||
13 | #include "wx/private/markupparser.h" | |
14 | ||
15 | #include "wx/stack.h" | |
16 | ||
17 | #include "wx/colour.h" | |
18 | #include "wx/font.h" | |
19 | ||
20 | // ---------------------------------------------------------------------------- | |
21 | // wxMarkupParserAttrOutput: simplified wxFont-using version of the above. | |
22 | // ---------------------------------------------------------------------------- | |
23 | ||
24 | // This class assumes that wxFont and wxColour are used to perform all the | |
25 | // markup tags and implements the base class virtual functions in terms of | |
26 | // OnAttr{Start,End}() only. | |
27 | // | |
28 | // Notice that you still must implement OnText() inherited from the base class | |
29 | // when deriving from this one. | |
30 | class wxMarkupParserAttrOutput : public wxMarkupParserOutput | |
31 | { | |
32 | public: | |
33 | // A simple container of font and colours. | |
34 | struct Attr | |
35 | { | |
36 | Attr(const wxFont& font_, | |
37 | const wxColour& foreground_ = wxColour(), | |
38 | const wxColour& background_ = wxColour()) | |
39 | : font(font_), foreground(foreground_), background(background_) | |
40 | { | |
41 | } | |
42 | ||
43 | wxFont font; | |
44 | wxColour foreground, | |
45 | background; | |
46 | }; | |
47 | ||
48 | ||
49 | // This object must be initialized with the font and colours to use | |
50 | // initially, i.e. the ones used before any tags in the string. | |
51 | wxMarkupParserAttrOutput(const wxFont& font, | |
52 | const wxColour& foreground, | |
53 | const wxColour& background) | |
54 | { | |
55 | m_attrs.push(Attr(font, foreground, background)); | |
56 | } | |
57 | ||
58 | // Indicates the change of the font and/or colours used. Any of the | |
59 | // fields of the argument may be invalid indicating that the corresponding | |
60 | // attribute didn't actually change. | |
61 | virtual void OnAttrStart(const Attr& attr) = 0; | |
62 | ||
63 | // Indicates the end of the region affected by the given attributes | |
64 | // (the same ones that were passed to the matching OnAttrStart(), use | |
65 | // GetAttr() to get the ones that will be used from now on). | |
66 | virtual void OnAttrEnd(const Attr& attr) = 0; | |
67 | ||
68 | ||
69 | // Implement all pure virtual methods inherited from the base class in | |
70 | // terms of our own ones. | |
71 | virtual void OnBoldStart() { DoChangeFont(&wxFont::Bold); } | |
72 | virtual void OnBoldEnd() { DoEndAttr(); } | |
73 | ||
74 | virtual void OnItalicStart() { DoChangeFont(&wxFont::Italic); } | |
75 | virtual void OnItalicEnd() { DoEndAttr(); } | |
76 | ||
77 | virtual void OnUnderlinedStart() { DoChangeFont(&wxFont::Underlined); } | |
78 | virtual void OnUnderlinedEnd() { DoEndAttr(); } | |
79 | ||
80 | virtual void OnStrikethroughStart() { DoChangeFont(&wxFont::Strikethrough); } | |
81 | virtual void OnStrikethroughEnd() { DoEndAttr(); } | |
82 | ||
83 | virtual void OnBigStart() { DoChangeFont(&wxFont::Larger); } | |
84 | virtual void OnBigEnd() { DoEndAttr(); } | |
85 | ||
86 | virtual void OnSmallStart() { DoChangeFont(&wxFont::Smaller); } | |
87 | virtual void OnSmallEnd() { DoEndAttr(); } | |
88 | ||
89 | virtual void OnTeletypeStart() | |
90 | { | |
91 | wxFont font(GetFont()); | |
92 | font.SetFamily(wxFONTFAMILY_TELETYPE); | |
93 | DoSetFont(font); | |
94 | } | |
95 | virtual void OnTeletypeEnd() { DoEndAttr(); } | |
96 | ||
97 | virtual void OnSpanStart(const wxMarkupSpanAttributes& spanAttr) | |
98 | { | |
99 | wxFont font(GetFont()); | |
100 | if ( !spanAttr.m_fontFace.empty() ) | |
101 | font.SetFaceName(spanAttr.m_fontFace); | |
102 | ||
103 | FontModifier<wxFontWeight>()(spanAttr.m_isBold, | |
104 | font, &wxFont::SetWeight, | |
105 | wxFONTWEIGHT_NORMAL, wxFONTWEIGHT_BOLD); | |
106 | ||
107 | FontModifier<wxFontStyle>()(spanAttr.m_isItalic, | |
108 | font, &wxFont::SetStyle, | |
109 | wxFONTSTYLE_NORMAL, wxFONTSTYLE_ITALIC); | |
110 | ||
111 | FontModifier<bool>()(spanAttr.m_isUnderlined, | |
112 | font, &wxFont::SetUnderlined, | |
113 | false, true); | |
114 | ||
115 | // TODO: No support for strike-through yet. | |
116 | ||
117 | switch ( spanAttr.m_sizeKind ) | |
118 | { | |
119 | case wxMarkupSpanAttributes::Size_Unspecified: | |
120 | break; | |
121 | ||
122 | case wxMarkupSpanAttributes::Size_Relative: | |
123 | if ( spanAttr.m_fontSize > 0 ) | |
124 | font.MakeLarger(); | |
125 | else | |
126 | font.MakeSmaller(); | |
127 | break; | |
128 | ||
129 | case wxMarkupSpanAttributes::Size_Symbolic: | |
130 | // The values of font size intentionally coincide with the | |
131 | // values of wxFontSymbolicSize enum elements so simply cast | |
132 | // one to the other. | |
133 | font.SetSymbolicSize( | |
134 | static_cast<wxFontSymbolicSize>(spanAttr.m_fontSize) | |
135 | ); | |
136 | break; | |
137 | ||
138 | case wxMarkupSpanAttributes::Size_PointParts: | |
139 | font.SetPointSize((spanAttr.m_fontSize + 1023)/1024); | |
140 | break; | |
141 | } | |
142 | ||
143 | ||
144 | const Attr attr(font, spanAttr.m_fgCol, spanAttr.m_bgCol); | |
145 | OnAttrStart(attr); | |
146 | ||
147 | m_attrs.push(attr); | |
148 | } | |
149 | ||
150 | virtual void OnSpanEnd(const wxMarkupSpanAttributes& WXUNUSED(spanAttr)) | |
151 | { | |
152 | DoEndAttr(); | |
153 | } | |
154 | ||
155 | protected: | |
156 | // Get the current attributes, i.e. the ones that should be used for | |
157 | // rendering (or measuring or whatever) the text at the current position in | |
158 | // the string. | |
159 | // | |
160 | // It may be called from OnAttrStart() to get the old attributes used | |
161 | // before and from OnAttrEnd() to get the new attributes that will be used | |
162 | // from now on but is mostly meant to be used from overridden OnText() | |
163 | // implementations. | |
164 | const Attr& GetAttr() const { return m_attrs.top(); } | |
165 | ||
166 | // A shortcut for accessing the font of the current attribute. | |
167 | const wxFont& GetFont() const { return GetAttr().font; } | |
168 | ||
169 | private: | |
170 | // Change only the font to the given one. Call OnAttrStart() to notify | |
171 | // about the change and update the attributes stack. | |
172 | void DoSetFont(const wxFont& font) | |
173 | { | |
174 | const Attr attr(font); | |
175 | ||
176 | OnAttrStart(attr); | |
177 | ||
178 | m_attrs.push(attr); | |
179 | } | |
180 | ||
181 | // Apply the given function to the font currently on top of the font stack, | |
182 | // push the new font on the stack and call OnAttrStart() with it. | |
183 | void DoChangeFont(wxFont (wxFont::*func)() const) | |
184 | { | |
185 | DoSetFont((GetFont().*func)()); | |
186 | } | |
187 | ||
188 | void DoEndAttr() | |
189 | { | |
190 | const Attr attr(m_attrs.top()); | |
191 | m_attrs.pop(); | |
192 | ||
193 | OnAttrEnd(attr); | |
194 | } | |
195 | ||
196 | // A helper class used to apply the given function to a wxFont object | |
197 | // depending on the value of an OptionalBool. | |
198 | template <typename T> | |
199 | struct FontModifier | |
200 | { | |
201 | FontModifier() { } | |
202 | ||
203 | void operator()(wxMarkupSpanAttributes::OptionalBool isIt, | |
204 | wxFont& font, | |
205 | void (wxFont::*func)(T), | |
206 | T noValue, | |
207 | T yesValue) | |
208 | { | |
209 | switch ( isIt ) | |
210 | { | |
211 | case wxMarkupSpanAttributes::Unspecified: | |
212 | break; | |
213 | ||
214 | case wxMarkupSpanAttributes::No: | |
215 | (font.*func)(noValue); | |
216 | break; | |
217 | ||
218 | case wxMarkupSpanAttributes::Yes: | |
219 | (font.*func)(yesValue); | |
220 | break; | |
221 | } | |
222 | } | |
223 | }; | |
224 | ||
225 | ||
226 | wxStack<Attr> m_attrs; | |
227 | ||
228 | wxDECLARE_NO_COPY_CLASS(wxMarkupParserAttrOutput); | |
229 | }; | |
230 | ||
231 | #endif // _WX_PRIVATE_MARKUPPARSERATTR_H_ |