1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/os2/ownerdrw.cpp
3 // Purpose:     implementation of wxOwnerDrawn class
4 // Author:      David Webster
5 // Modified by: Marcin Malich
6 // Created:     10/12/99
7 // Copyright:   (c) David Webster
8 // Licence:     wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13 
14 #if wxUSE_OWNER_DRAWN
15 
16 #include "wx/ownerdrw.h"
17 #include "wx/os2/private.h"
18 #include "wx/os2/dcclient.h"
19 
20 // ----------------------------------------------------------------------------
21 // constants for base class
22 // ----------------------------------------------------------------------------
23 
24 int wxOwnerDrawnBase::ms_defaultMargin = 3;
25 
26 // ============================================================================
27 // implementation of wxOwnerDrawn class
28 // ============================================================================
29 
30 // draw the item
OnDrawItem(wxDC & rDC,const wxRect & rRect,wxODAction eAction,wxODStatus eStatus)31 bool wxOwnerDrawn::OnDrawItem( wxDC& rDC,
32                                const wxRect& rRect,
33                                wxODAction eAction,
34                                wxODStatus eStatus )
35 {
36 
37     //
38     // Select the font and draw the text
39     // ---------------------------------
40     //
41 
42     CHARBUNDLE                      vCbnd;
43     wxPMDCImpl                      *impl = (wxPMDCImpl*) rDC.GetImpl();
44     HPS                             hPS= impl->GetHPS();
45     wxFont                          vFont;
46     wxColour                        vColBack;
47     wxColour                        vColText;
48     COLORREF                        vRef;
49     RECTL                           vRect = {rRect.x + 4, rRect.y + 1, rRect.x + (rRect.width - 2), rRect.y + rRect.height};
50 
51     memset(&vCbnd, 0, sizeof(CHARBUNDLE));
52 
53     GetFontToUse(vFont);
54     GetColourToUse(eStatus, vColText, vColBack);
55 
56     rDC.SetFont(vFont);
57     rDC.SetTextBackground(vColBack);
58     rDC.SetTextForeground(vColText);
59     rDC.SetBackgroundMode(wxTRANSPARENT);
60 
61     vCbnd.lColor     = vColText.GetPixel();
62     vCbnd.lBackColor = vColBack.GetPixel();
63     ::GpiSetAttrs( hPS
64                   ,PRIM_CHAR
65                   ,CBB_BACK_COLOR | CBB_COLOR
66                   ,0
67                   ,&vCbnd
68                  );
69     ::GpiSetBackMix( hPS
70                     ,BM_LEAVEALONE
71                    );
72 
73     //
74     // Paint the background
75     //
76     ::WinFillRect(hPS, &vRect, vColBack.GetPixel());
77 
78     //
79     // Determine where to draw and leave space for a check-mark.
80     //
81     int nX = rRect.x + GetMarginWidth();
82 
83     //
84     // Unfortunately, unlike Win32, PM has no owner drawn specific text
85     // drawing methods like ::DrawState that can cleanly handle accel
86     // mnemonics and deal, automatically, with various states, so we have
87     // to handle them ourselves. Notice Win32 can't handle \t in ownerdrawn
88     // strings either.  We cannot handle mnemonics either.  We display
89     // them, though, in the hope we can figure them out some day.
90     //
91 
92     //
93     // Display main text
94     //
95     wxString sFullString = GetItemLabel(); // need to save the original text
96     int      nIndex;
97     size_t   nWidth;
98     size_t   nCharWidth;
99     size_t   nHeight;
100     bool     bFoundMnemonic = false;
101 
102     //
103     // Deal with the mnemonic character
104     //
105     nIndex = sFullString.Find(wxT("~"));
106     if (nIndex != -1)
107     {
108         wxString sTmp = sFullString;
109 
110         bFoundMnemonic = true;
111         sTmp.Remove(nIndex);
112         rDC.GetTextExtent( sTmp
113                           ,(wxCoord *)&nWidth
114                           ,(wxCoord *)&nHeight
115                          );
116         sTmp = sFullString[(size_t)(nIndex + 1)];
117         rDC.GetTextExtent( sTmp
118                           ,(wxCoord *)&nCharWidth
119                           ,(wxCoord *)&nHeight
120                          );
121         sFullString.Replace(sTgt.c_str(), wxEmptyString, true);
122     }
123 
124     //
125     // Draw the main item text sans the accel text
126     //
127     POINTL                      vPntStart = {nX, rRect.y + 4};
128     ::GpiCharStringAt( impl->GetHPS()
129                       ,&vPntStart
130                       ,sFullString.length()
131                       ,sFullString.char_str()
132                      );
133     if (bFoundMnemonic)
134     {
135         //
136         // Underline the mnemonic -- still won't work, but at least it "looks" right
137         //
138         wxPen                       vPen;
139         POINTL                      vPntEnd = {nX + nWidth + nCharWidth - 3, rRect.y + 2}; //CharWidth is bit wide
140 
141         vPntStart.x = nX + nWidth - 1;
142         vPntStart.y = rRect.y + 2; // Make it look pretty!
143         vPen = wxPen(vColText, 1, wxSOLID); // Assuming we are always black
144         rDC.SetPen(vPen);
145         ::GpiMove(hPS, &vPntStart);
146         ::GpiLine(hPS, &vPntEnd);
147     }
148 
149     return true;
150 } // end of wxOwnerDrawn::OnDrawItem
151 
152 #endif //wxUSE_OWNER_DRAWN
153