]> git.saurik.com Git - wxWidgets.git/blame - src/os2/ownerdrw.cpp
merged Ctrl-Space fix from 2.2 branch
[wxWidgets.git] / src / os2 / ownerdrw.cpp
CommitLineData
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//
43wxOwnerDrawn::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 58size_t wxOwnerDrawn::ms_nDefaultMarginWidth = 15;
63415778
DW
59
60size_t wxOwnerDrawn::ms_nLastMarginWidth = ms_nDefaultMarginWidth;
61
402e2f7c
DW
62//
63// Drawing
63415778 64// -------
402e2f7c 65//
63415778 66
402e2f7c
DW
67bool 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
100bool 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