]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/ownerdrw.cpp
   1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        msw/ownerdrw.cpp 
   3 // Purpose:     implementation of wxOwnerDrawn class 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows license 
  10 /////////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  20   #include "wx/window.h" 
  21   #include "wx/msw/private.h" 
  23   #include "wx/bitmap.h" 
  24   #include "wx/dcmemory.h" 
  31 #include "wx/ownerdrw.h" 
  32 #include "wx/menuitem.h" 
  35 // ============================================================================ 
  36 // implementation of wxOwnerDrawn class 
  37 // ============================================================================ 
  43 wxOwnerDrawn::wxOwnerDrawn( 
  50     m_bCheckable   
= bCheckable
; 
  51     m_bOwnerDrawn  
= FALSE
; 
  53     m_nMarginWidth 
= ms_nLastMarginWidth
; 
  55         m_font 
= *wxNORMAL_FONT
; 
  56 } // end of wxOwnerDrawn::wxOwnerDrawn 
  58 size_t wxOwnerDrawn::ms_nDefaultMarginWidth 
= 15; 
  60 size_t wxOwnerDrawn::ms_nLastMarginWidth 
= ms_nDefaultMarginWidth
; 
  67 bool wxOwnerDrawn::OnMeasureItem( 
  74     vDC
.SetFont(GetFont()); 
  76     wxString                        sStr 
= wxStripMenuCodes(m_strName
); 
  78     vDC
.GetTextExtent( sStr
 
  83     (*pHeight
) = (*pHeight
) + 2; 
  84     m_nHeight 
= *pHeight
;        // remember height for use in OnDrawItem 
  86 } // end of wxOwnerDrawn::OnMeasureItem 
  89 bool wxOwnerDrawn::OnDrawItem( 
  97     // We do nothing on focus change 
  99     if (eAction 
== wxODFocusChanged 
) 
 103     // Select the font and draw the text 
 104     // --------------------------------- 
 108     HPS                             hPS
= rDC
.GetHPS(); 
 112     RECTL                           vRect 
= {rRect
.x 
+ 4, rRect
.y 
+ 1, rRect
.x 
+ (rRect
.width 
- 2), rRect
.y 
+ rRect
.height
}; 
 114     memset(&vCbnd
, 0, sizeof(CHARBUNDLE
)); 
 117     // Use default font if no font set 
 121         m_font
.RealizeResource(); 
 125         ::GpiSetCharSet(hPS
, LCID_DEFAULT
); 
 129     // Base on the status of the menu item pick the right colors 
 131     if (eStatus 
& wxODSelected
) 
 133         wxColour                        
vCol2("WHITE"); 
 134         vColBack
.Set( (unsigned char)0 
 137                     ); // no dark blue in color table 
 140     else if (eStatus 
& wxODDisabled
) 
 142         vRef 
= (ULONG
)::WinQuerySysColor( HWND_DESKTOP
 
 143                                          ,SYSCLR_MENU 
// Light gray 
 146         vColBack
.Set( GetRValue(vRef
) 
 150         vRef 
= (ULONG
)::WinQuerySysColor( HWND_DESKTOP
 
 151                                          ,SYSCLR_MENUDISABLEDTEXT 
// dark gray 
 154         vColText
.Set( GetRValue(vRef
) 
 162         // Fall back to default colors if none explicitly specified 
 164         vRef 
= ::WinQuerySysColor( HWND_DESKTOP
 
 165                                   ,SYSCLR_MENU  
// we are using gray for all our window backgrounds in wxWindows 
 168         vColBack
.Set( GetRValue(vRef
) 
 172         vRef 
= ::WinQuerySysColor( HWND_DESKTOP
 
 173                                   ,SYSCLR_WINDOWTEXT 
// Black 
 176         vColText
.Set( GetRValue(vRef
) 
 182     rDC
.SetTextBackground(vColBack
); 
 183     rDC
.SetTextForeground(vColText
); 
 184     rDC
.SetBackgroundMode(wxTRANSPARENT
); 
 185     vCbnd
.lColor     
= vColText
.GetPixel(); 
 186     vCbnd
.lBackColor 
= vColBack
.GetPixel(); 
 189                   ,CBB_BACK_COLOR 
| CBB_COLOR
 
 198     // Paint the background 
 200     ::WinFillRect(hPS
, &vRect
, vColBack
.GetPixel()); 
 203     // Determine where to draw and leave space for a check-mark. 
 205     int                             nX 
= rRect
.x 
+ GetMarginWidth(); 
 208     // Unfortunately, unlike Win32, PM has no owner drawn specific text 
 209     // drawing methods like ::DrawState that can cleanly handle accel 
 210     // pneumonics and deal, automatically, with various states, so we have 
 211     // to handle them ourselves. Notice Win32 can't handle \t in ownerdrawn 
 212     // strings either.  We cannot handle mneumonics either.  We display 
 213     // it, though, in hopes we can figure it out some day. 
 217     // Display main text and accel text separately to allign better 
 219     wxString                        sTgt 
= "\t"; 
 220     wxString                        sFullString 
= m_strName
; // need to save the original text 
 226     bool                            bFoundMneumonic 
= FALSE
; 
 227     bool                            bFoundAccel 
= FALSE
; 
 230     // Deal with the tab, extracting the Accel text 
 232     nIndex 
= sFullString
.Find(sTgt
.c_str()); 
 236         sAccel 
= sFullString
.Mid(nIndex 
+ 1); 
 237         sFullString
.Remove(nIndex
); 
 241     // Deal with the mneumonic character 
 244     nIndex 
= sFullString
.Find(sTgt
.c_str()); 
 247         wxString                    sTmp 
= sFullString
; 
 249         bFoundMneumonic 
= TRUE
; 
 251         rDC
.GetTextExtent( sTmp
 
 255         sTmp 
= sFullString
[nIndex 
+ 1]; 
 256         rDC
.GetTextExtent( sTmp
 
 260         sFullString
.Replace(sTgt
.c_str(), "", TRUE
); 
 264     // Draw the main item text sans the accel text 
 266     POINTL                      vPntStart 
= {nX
, rRect
.y 
+ 4}; 
 267     ::GpiCharStringAt( rDC
.GetHPS() 
 269                       ,sFullString
.length() 
 270                       ,(PCH
)sFullString
.c_str() 
 275         // Underline the mneumonic -- still won't work, but at least it "looks" right 
 278         POINTL                      vPntEnd 
= {nX 
+ nWidth 
+ nCharWidth 
- 3, rRect
.y 
+ 2}; //CharWidth is bit wide 
 280         vPntStart
.x 
= nX 
+ nWidth 
- 1; 
 281         vPntStart
.y 
= rRect
.y 
+ 2; // Make it look pretty! 
 282         vPen 
= wxPen(vColText
, 1, wxSOLID
); // Assuming we are always black 
 284         ::GpiMove(hPS
, &vPntStart
); 
 285         ::GpiLine(hPS
, &vPntEnd
); 
 289     // Now draw the accel text 
 296         rDC
.GetTextExtent( sAccel
 
 301         // Back off the starting position from the right edge 
 303         vPntStart
.x 
= rRect
.width 
- (nWidth 
+ 7); 
 304         vPntStart
.y 
= rRect
.y 
+ 4; 
 305         ::GpiCharStringAt( rDC
.GetHPS() 
 316     if (IsCheckable() && !m_bmpChecked
.Ok()) 
 318         if (eStatus 
& wxODChecked
) 
 321             HBITMAP                 hBmpCheck 
= ::WinGetSysBitmap(HWND_DESKTOP
, SBMP_MENUCHECK
); 
 323             vRect
.xLeft   
= rRect
.x
; 
 324             vRect
.xRight  
= rRect
.x 
+ GetMarginWidth(); 
 325             vRect
.yBottom 
= rRect
.y
; 
 326             vRect
.yTop    
= rRect
.y 
+ m_nHeight 
- 3; 
 328             ::WinDrawBitmap( hPS             
// PS for this menuitem 
 329                             ,hBmpCheck       
// system checkmark 
 330                             ,NULL            
// draw the whole bitmap 
 331                             ,(PPOINTL
)&vRect 
// destination -- bottom left corner of the menuitem area 
 334                             ,DBM_NORMAL      
// draw normal size 
 341         // For uncheckable item we use only the 'checked' bitmap 
 343         wxBitmap                    
vBmp(GetBitmap(IsCheckable() ? ((eStatus 
& wxODChecked
) != 0) : TRUE
)); 
 348             wxMemoryDC              
vDCMem(&rDC
); 
 349             wxMemoryDC
*             pOldDC 
= (wxMemoryDC
*)vBmp
.GetSelectedInto(); 
 353                 vBmp
.SetSelectedInto(NULL
); 
 355             vDCMem
.SelectObject(vBmp
); 
 360             int                     nBmpWidth 
= vBmp
.GetWidth(); 
 361             int                     nBmpHeight 
= vBmp
.GetHeight(); 
 364             // There should be enough space! 
 366             wxASSERT((nBmpWidth 
<= rRect
.width
) && (nBmpHeight 
<= rRect
.height
)); 
 369             //MT: blit with mask enabled. 
 371             rDC
.Blit( rRect
.x 
+ (GetMarginWidth() - nBmpWidth
) / 2 
 372                      ,rRect
.y 
+ (m_nHeight 
- nBmpHeight
) /2 
 382             if (eStatus 
& wxODSelected
) 
 384                 RECT                vRectBmp 
= { rRect
.x
 
 386                                                 ,rRect
.x 
+ GetMarginWidth() 
 389                 POINTL              vPnt1 
= {2, 4}; // Leave a little background border 
 390                 POINTL              vPnt2 
= {rRect
.x 
+ GetMarginWidth(), rRect
.y 
+ m_nHeight 
- 3}; 
 393                 vLine
.lColor 
= vColBack
.GetPixel(); 
 400                 ::GpiMove(hPS
, &vPnt1
); 
 408             vBmp
.SetSelectedInto(NULL
); 
 412 } // end of wxOwnerDrawn::OnDrawItem 
 414 #endif //wxUSE_OWNER_DRAWN