]>
Commit | Line | Data |
---|---|---|
63415778 DW |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: msw/ownerdrw.cpp | |
3 | // Purpose: implementation of wxOwnerDrawn class | |
4 | // Author: David Webster | |
fb46a9a6 | 5 | // Modified by: |
63415778 DW |
6 | // Created: 10/12/99 |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) David Webster | |
9 | // Licence: wxWindows license | |
10 | /////////////////////////////////////////////////////////////////////////////// | |
11 | ||
aa213887 SN |
12 | #ifdef __GNUG__ |
13 | #pragma implementation | |
14 | #endif | |
15 | ||
63415778 DW |
16 | // For compilers that support precompilation, includes "wx.h". |
17 | #include "wx/wxprec.h" | |
18 | ||
19 | #ifndef WX_PRECOMP | |
20 | #include "wx/window.h" | |
21 | #include "wx/msw/private.h" | |
22 | #include "wx/font.h" | |
23 | #include "wx/bitmap.h" | |
24 | #include "wx/dcmemory.h" | |
25 | #include "wx/menu.h" | |
26 | #include "wx/utils.h" | |
27 | #endif | |
28 | ||
7e99520b DW |
29 | #if wxUSE_OWNER_DRAWN |
30 | ||
63415778 DW |
31 | #include "wx/ownerdrw.h" |
32 | #include "wx/menuitem.h" | |
33 | ||
34 | ||
35 | // ============================================================================ | |
36 | // implementation of wxOwnerDrawn class | |
37 | // ============================================================================ | |
38 | ||
402e2f7c | 39 | // |
63415778 DW |
40 | // ctor |
41 | // ---- | |
402e2f7c DW |
42 | // |
43 | wxOwnerDrawn::wxOwnerDrawn( | |
44 | const wxString& rsStr | |
45 | , bool bCheckable | |
46 | , bool bMenuItem | |
47 | ) | |
48 | : m_strName(rsStr) | |
63415778 | 49 | { |
402e2f7c DW |
50 | m_bCheckable = bCheckable; |
51 | m_bOwnerDrawn = FALSE; | |
52 | m_nHeight = 0; | |
53 | m_nMarginWidth = ms_nLastMarginWidth; | |
54 | if (wxNORMAL_FONT) | |
55 | m_font = *wxNORMAL_FONT; | |
56 | } // end of wxOwnerDrawn::wxOwnerDrawn | |
63415778 | 57 | |
402e2f7c | 58 | size_t wxOwnerDrawn::ms_nDefaultMarginWidth = 15; |
63415778 DW |
59 | |
60 | size_t wxOwnerDrawn::ms_nLastMarginWidth = ms_nDefaultMarginWidth; | |
61 | ||
402e2f7c DW |
62 | // |
63 | // Drawing | |
63415778 | 64 | // ------- |
402e2f7c | 65 | // |
63415778 | 66 | |
402e2f7c DW |
67 | bool wxOwnerDrawn::OnMeasureItem( |
68 | size_t* pWidth | |
69 | , size_t* pHeight | |
70 | ) | |
63415778 | 71 | { |
402e2f7c DW |
72 | wxMemoryDC vDC; |
73 | ||
74 | vDC.SetFont(GetFont()); | |
75 | ||
76 | wxString sStr = wxStripMenuCodes(m_strName); | |
77 | ||
23122f8c DW |
78 | wxString sTgt = "\t"; |
79 | size_t nIndex; | |
80 | ||
81 | nIndex = sStr.Find(sTgt.c_str()); | |
82 | if (nIndex != -1) | |
83 | sStr.Remove(nIndex); | |
84 | sTgt = "~"; | |
85 | nIndex = sStr.Find(sTgt.c_str()); | |
86 | if (nIndex != -1) | |
87 | sStr.Replace(sTgt.c_str(), "", TRUE); | |
88 | ||
402e2f7c DW |
89 | vDC.GetTextExtent( sStr |
90 | ,(long *)pWidth | |
91 | ,(long *)pHeight | |
92 | ); | |
93 | ||
402e2f7c DW |
94 | (*pHeight) = (*pHeight) + 2; |
95 | m_nHeight = *pHeight; // remember height for use in OnDrawItem | |
96 | return TRUE; | |
97 | } // end of wxOwnerDrawn::OnMeasureItem | |
63415778 | 98 | |
63415778 | 99 | // draw the item |
402e2f7c DW |
100 | bool wxOwnerDrawn::OnDrawItem( |
101 | wxDC& rDC | |
102 | , const wxRect& rRect | |
103 | , wxODAction eAction | |
104 | , wxODStatus eStatus | |
105 | ) | |
63415778 | 106 | { |
402e2f7c | 107 | // |
23122f8c DW |
108 | // We do nothing on focus change |
109 | if (eAction == wxODFocusChanged ) | |
110 | return TRUE; | |
402e2f7c DW |
111 | // |
112 | // WxWinGdi_CColour <-> RGB | |
113 | // | |
114 | #define ToRGB(col) OS2RGB(col.Red(), col.Green(), col.Blue()) | |
115 | #define UnRGB(col) GetRValue(col), GetGValue(col), GetBValue(col) | |
116 | ||
117 | CHARBUNDLE vCbndText; | |
118 | CHARBUNDLE vCbndBack; | |
119 | HPS hPS= rDC.GetHPS(); | |
120 | ULONG lColBack; | |
121 | ULONG lColText; | |
122 | ||
123 | if (eStatus & wxODSelected) | |
124 | { | |
23122f8c | 125 | lColBack = (ULONG)::WinQuerySysColor( HWND_DESKTOP |
402e2f7c DW |
126 | ,SYSCLR_MENUHILITEBGND // Light gray |
127 | ,0L | |
128 | ); | |
23122f8c | 129 | lColText = (ULONG)::WinQuerySysColor( HWND_DESKTOP |
402e2f7c DW |
130 | ,SYSCLR_MENUTEXT // Black |
131 | ,0L | |
132 | ); | |
133 | } | |
134 | else if (eStatus & wxODDisabled) | |
135 | { | |
23122f8c | 136 | lColBack = (ULONG)::WinQuerySysColor( HWND_DESKTOP |
402e2f7c DW |
137 | ,SYSCLR_MENU // Light gray |
138 | ,0L | |
139 | ); | |
23122f8c | 140 | lColText = (ULONG)::WinQuerySysColor( HWND_DESKTOP |
402e2f7c DW |
141 | ,SYSCLR_MENUDISABLEDTEXT // dark gray |
142 | ,0L | |
143 | ); | |
144 | } | |
145 | else | |
146 | { | |
147 | // | |
148 | // Fall back to default colors if none explicitly specified | |
149 | // | |
150 | lColBack = m_colBack.Ok() ? ToRGB(m_colBack) : ::WinQuerySysColor( HWND_DESKTOP | |
151 | ,SYSCLR_MENU // we are using gray for all our window backgrounds in wxWindows | |
152 | ,0L | |
153 | ); | |
154 | lColText = m_colText.Ok() ? ToRGB(m_colText) : ::WinQuerySysColor( HWND_DESKTOP | |
155 | ,SYSCLR_WINDOWTEXT // Black | |
156 | ,0L | |
157 | ); | |
158 | } | |
159 | vCbndText.lColor = (LONG)lColText; | |
160 | vCbndBack.lColor = (LONG)lColBack; | |
161 | ||
162 | ::GpiSetAttrs( hPS | |
163 | ,PRIM_CHAR | |
164 | ,CBB_BACK_COLOR | |
165 | ,0 | |
166 | ,&vCbndBack | |
167 | ); | |
168 | ::GpiSetAttrs( hPS | |
169 | ,PRIM_CHAR | |
170 | ,CBB_COLOR | |
171 | ,0 | |
172 | ,&vCbndText | |
173 | ); | |
174 | ||
175 | ||
176 | // | |
177 | // Determine where to draw and leave space for a check-mark. | |
178 | // | |
179 | int nX = rRect.x + GetMarginWidth(); | |
180 | ||
181 | // | |
182 | // Select the font and draw the text | |
183 | // --------------------------------- | |
184 | // | |
185 | ||
186 | // | |
187 | // Use default font if no font set | |
188 | // | |
189 | if (m_font.Ok()) | |
190 | { | |
191 | m_font.RealizeResource(); | |
192 | } | |
193 | else | |
194 | { | |
195 | ::GpiSetCharSet(hPS, LCID_DEFAULT); | |
196 | } | |
63415778 | 197 | |
402e2f7c DW |
198 | // |
199 | // Unfortunately, unlike Win32, PM has no owner drawn specific text | |
200 | // drawing methods like ::DrawState that can cleanly handle accel | |
201 | // pneumonics and deal, automatically, with various states, so we have | |
202 | // to handle them ourselves. Notice Win32 can't handle \t in ownerdrawn | |
203 | // strings either. | |
204 | ||
23122f8c DW |
205 | // |
206 | // Manually replace the tab with spaces | |
207 | // | |
208 | wxString sTgt = "\t"; | |
209 | wxString sReplace = " "; | |
210 | size_t nIndex; | |
211 | ||
212 | nIndex = m_strName.Find(sTgt.c_str()); | |
213 | if (nIndex != -1) | |
214 | m_strName.Replace(sTgt.c_str(), sReplace.c_str(), TRUE); | |
215 | sTgt = "~"; | |
216 | nIndex = m_strName.Find(sTgt.c_str()); | |
217 | if (nIndex != -1) | |
218 | m_strName.Replace(sTgt.c_str(), "", TRUE); | |
219 | ||
402e2f7c DW |
220 | rDC.DrawText( m_strName |
221 | ,nX | |
23122f8c | 222 | ,rRect.y + 4 |
402e2f7c DW |
223 | ); |
224 | ||
23122f8c | 225 | #if 0 |
402e2f7c DW |
226 | // |
227 | // Draw the bitmap | |
228 | // --------------- | |
229 | // | |
230 | if (IsCheckable() && !m_bmpChecked.Ok()) | |
231 | { | |
232 | if (eStatus & wxODChecked) | |
233 | { | |
234 | RECTL vRect; | |
235 | HBITMAP hBmpCheck = ::WinGetSysBitmap(HWND_DESKTOP, SBMP_MENUCHECK); | |
236 | ||
237 | vRect.xLeft = rRect.x; | |
238 | vRect.xRight = rRect.x + GetMarginWidth(); | |
239 | vRect.yBottom = rRect.y; | |
240 | vRect.yTop = rRect.y + m_nHeight; | |
241 | ||
242 | ::WinDrawBitmap( hPS // PS for this menuitem | |
243 | ,hBmpCheck // system checkmark | |
244 | ,NULL // draw the whole bitmap | |
245 | ,(PPOINTL)&vRect // destination -- bottom left corner of the menuitem area | |
246 | ,0L // ignored | |
247 | ,0L // draw a bitmap | |
248 | ,DBM_NORMAL // draw normal size | |
249 | ); | |
250 | } | |
63415778 | 251 | } |
402e2f7c DW |
252 | else |
253 | { | |
254 | // | |
255 | // For uncheckable item we use only the 'checked' bitmap | |
256 | // | |
257 | wxBitmap vBmp(GetBitmap(IsCheckable() ? ((eStatus & wxODChecked) != 0) : TRUE)); | |
258 | ||
259 | if (vBmp.Ok()) | |
260 | { | |
261 | wxMemoryDC vDCMem(&rDC); | |
262 | ||
263 | vDCMem.SelectObject(vBmp); | |
264 | ||
265 | // | |
266 | // Center bitmap | |
267 | // | |
268 | int nBmpWidth = vBmp.GetWidth(); | |
269 | int nBmpHeight = vBmp.GetHeight(); | |
270 | ||
271 | // | |
272 | // There should be enough space! | |
273 | // | |
274 | wxASSERT((nBmpWidth <= rRect.width) && (nBmpHeight <= rRect.height)); | |
275 | ||
276 | // | |
277 | //MT: blit with mask enabled. | |
278 | // | |
279 | rDC.Blit( rRect.x + (GetMarginWidth() - nBmpWidth) / 2 | |
280 | ,rRect.y + (m_nHeight - nBmpHeight) /2 | |
281 | ,nBmpWidth | |
282 | ,nBmpHeight | |
283 | ,&vDCMem | |
284 | ,0 | |
285 | ,0 | |
286 | ,wxCOPY | |
287 | ,TRUE | |
288 | ); | |
289 | ||
290 | if (eStatus & wxODSelected) | |
291 | { | |
292 | RECT vRectBmp = { rRect.x | |
293 | ,rRect.y | |
294 | ,rRect.x + GetMarginWidth() | |
295 | ,rRect.y + m_nHeight | |
296 | }; | |
297 | LINEBUNDLE vLine; | |
298 | ||
299 | vLine.lColor = lColBack; | |
300 | ::GpiSetAttrs( hPS | |
301 | ,PRIM_LINE | |
302 | ,LBB_COLOR | |
303 | ,0 | |
304 | ,&vLine | |
305 | ); | |
306 | ::GpiBox( hPS | |
307 | ,DRO_OUTLINE | |
308 | ,(PPOINTL)&vRectBmp | |
309 | ,0L | |
310 | ,0L | |
311 | ); | |
312 | } | |
313 | } | |
63415778 | 314 | } |
23122f8c DW |
315 | #endif |
316 | return TRUE; | |
317 | } // end of wxOwnerDrawn::OnDrawItem | |
63415778 | 318 | |
7e99520b | 319 | #endif //wxUSE_OWNER_DRAWN |