]> git.saurik.com Git - wxWidgets.git/blob - src/os2/ownerdrw.cpp
assert in GetNextItem() fixed (?)
[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 #include "wx/ownerdrw.h"
30 #include "wx/menuitem.h"
31
32
33 // ============================================================================
34 // implementation of wxOwnerDrawn class
35 // ============================================================================
36
37 // ctor
38 // ----
39 wxOwnerDrawn::wxOwnerDrawn(const wxString& str,
40 bool bCheckable, bool bMenuItem)
41 : m_strName(str)
42 {
43 m_bCheckable = bCheckable;
44 m_bOwnerDrawn = FALSE;
45 m_nHeight = 0;
46 m_nMarginWidth = ms_nLastMarginWidth;
47 }
48
49 size_t wxOwnerDrawn::ms_nDefaultMarginWidth = 15;
50
51 size_t wxOwnerDrawn::ms_nLastMarginWidth = ms_nDefaultMarginWidth;
52
53 // drawing
54 // -------
55
56 // get size of the item
57 bool wxOwnerDrawn::OnMeasureItem(size_t *pwidth, size_t *pheight)
58 {
59 wxMemoryDC dc;
60 dc.SetFont(GetFont());
61
62 // ## ugly...
63 wxChar *szStripped = new wxChar[m_strName.Len()];
64 wxStripMenuCodes((wxChar *)m_strName.c_str(), szStripped);
65 wxString str = szStripped;
66 delete [] szStripped;
67
68 // # without this menu items look too tightly packed (at least under Windows)
69 str += wxT('W'); // 'W' is typically the widest letter
70
71 dc.GetTextExtent(str, (long *)pwidth, (long *)pheight);
72
73 // JACS: items still look too tightly packed, so adding 2 pixels.
74 (*pheight) = (*pheight) + 2;
75
76 m_nHeight = *pheight; // remember height for use in OnDrawItem
77
78 return TRUE;
79 }
80
81 // searching for this macro you'll find all the code where I'm using the native
82 // Win32 GDI functions and not wxWindows ones. Might help to whoever decides to
83 // port this code to X. (VZ)
84
85 // JACS: TODO. Why does a disabled but highlighted item still
86 // get drawn embossed? How can we tell DrawState that we don't want the
87 // embossing?
88
89 // draw the item
90 bool wxOwnerDrawn::OnDrawItem(wxDC& dc, const wxRect& rc, wxODAction act, wxODStatus st)
91 {
92 ///////////////////////////////////////////////////////////////////////////////////////////////////
93 // Might want to check the native drawing apis for here and doo something like MSW does for WIN95
94 ///////////////////////////////////////////////////////////////////////////////////////////////////
95
96 // we do nothing on focus change
97 if ( act == wxODFocusChanged )
98 return TRUE;
99
100 // wxColor <-> RGB
101 #define ToRGB(col) RGB(col.Red(), col.Green(), col.Blue())
102 #define UnRGB(col) GetRValue(col), GetGValue(col), GetBValue(col)
103
104 // set the colors
105 // --------------
106 DWORD colBack, colText;
107 // TODO:
108 /*
109 if ( st & wxODSelected ) {
110 colBack = GetSysColor(COLOR_HIGHLIGHT);
111 colText = GetSysColor(COLOR_HIGHLIGHTTEXT);
112 }
113 else {
114 // fall back to default colors if none explicitly specified
115 colBack = m_colBack.Ok() ? ToRGB(m_colBack) : GetSysColor(COLOR_WINDOW);
116 colText = m_colText.Ok() ? ToRGB(m_colText) : GetSysColor(COLOR_WINDOWTEXT);
117 }
118 */
119 // dc.SetTextForeground(wxColor(UnRGB(colText)));
120 // dc.SetTextBackground(wxColor(UnRGB(colBack)));
121
122 // select the font and draw the text
123 // ---------------------------------
124
125 // determine where to draw and leave space for a check-mark.
126 int x = rc.x + GetMarginWidth();
127
128 dc.SetFont(GetFont());
129 dc.DrawText(m_strName, x, rc.y);
130
131 // draw the bitmap
132 // ---------------
133 if ( IsCheckable() && !m_bmpChecked.Ok() ) {
134 if ( st & wxODChecked ) {
135 // using native APIs for performance and simplicity
136 // TODO:
137 /*
138 HDC hdcMem = CreateCompatibleDC(hdc);
139 HBITMAP hbmpCheck = CreateBitmap(GetMarginWidth(), m_nHeight, 1, 1, 0);
140 SelectObject(hdcMem, hbmpCheck);
141 // then draw a check mark into it
142 RECT rect = { 0, 0, GetMarginWidth(), m_nHeight };
143
144 // finally copy it to screen DC and clean up
145 BitBlt(hdc, rc.x, rc.y, GetMarginWidth(), m_nHeight,
146 hdcMem, 0, 0, SRCCOPY);
147 DeleteDC(hdcMem);
148 */
149 }
150 }
151 else {
152 // for uncheckable item we use only the 'checked' bitmap
153 wxBitmap bmp(GetBitmap(IsCheckable() ? ((st & wxODChecked) != 0) : TRUE));
154 if ( bmp.Ok() ) {
155 wxMemoryDC dcMem(&dc);
156 dcMem.SelectObject(bmp);
157
158 // center bitmap
159 int nBmpWidth = bmp.GetWidth(),
160 nBmpHeight = bmp.GetHeight();
161
162 // there should be enough place!
163 wxASSERT((nBmpWidth <= rc.GetWidth()) && (nBmpHeight <= rc.GetHeight()));
164
165 //MT: blit with mask enabled.
166 // TODO:
167 /*
168 dc.Blit(rc.x + (GetMarginWidth() - nBmpWidth) / 2,
169 rc.y + (m_nHeight - nBmpHeight) /2,
170 nBmpWidth, nBmpHeight,
171 &dcMem, 0, 0, wxCOPY,true);
172
173 if ( st & wxODSelected ) {
174 #ifdef O_DRAW_NATIVE_API
175 RECT rectBmp = { rc.GetLeft(), rc.GetTop(),
176 rc.GetLeft() + GetMarginWidth(),
177 rc.GetTop() + m_nHeight };
178 SetBkColor(hdc, colBack);
179 DrawEdge(hdc, &rectBmp, EDGE_RAISED, BF_SOFT | BF_RECT);
180 }
181 */
182 }
183 }
184 /*
185 #ifdef O_DRAW_NATIVE_API
186 ::SetTextColor(hdc, colOldText);
187 ::SetBkColor(hdc, colOldBack);
188
189 #undef hdc
190 #endif //O_DRAW_NATIVE_API
191 */
192 return TRUE;
193 }
194