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