OwnerDrawn updates
[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 if (eAction == wxODFocusChanged )
110 return TRUE;
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 {
125 lColBack = (ULONG)::WinQuerySysColor( HWND_DESKTOP
126 ,SYSCLR_MENUHILITEBGND // Light gray
127 ,0L
128 );
129 lColText = (ULONG)::WinQuerySysColor( HWND_DESKTOP
130 ,SYSCLR_MENUTEXT // Black
131 ,0L
132 );
133 }
134 else if (eStatus & wxODDisabled)
135 {
136 lColBack = (ULONG)::WinQuerySysColor( HWND_DESKTOP
137 ,SYSCLR_MENU // Light gray
138 ,0L
139 );
140 lColText = (ULONG)::WinQuerySysColor( HWND_DESKTOP
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 }
197
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
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
220 rDC.DrawText( m_strName
221 ,nX
222 ,rRect.y + 4
223 );
224
225 #if 0
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 }
251 }
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 }
314 }
315 #endif
316 return TRUE;
317 } // end of wxOwnerDrawn::OnDrawItem
318
319 #endif //wxUSE_OWNER_DRAWN