]> git.saurik.com Git - wxWidgets.git/commitdiff
Ownerdrawn stuff. Text display done, image display next.
authorDavid Webster <Dave.Webster@bhmi.com>
Thu, 22 Mar 2001 23:23:19 +0000 (23:23 +0000)
committerDavid Webster <Dave.Webster@bhmi.com>
Thu, 22 Mar 2001 23:23:19 +0000 (23:23 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9572 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/os2/dcmemory.h
src/os2/dc.cpp
src/os2/dcclient.cpp
src/os2/dcmemory.cpp
src/os2/ownerdrw.cpp
src/os2/window.cpp

index 85191f6e45ae4c107043508dfe8215d579ce405b..fa9e983e1b0f59567935c46165c9192734c7f168 100644 (file)
 
 class WXDLLEXPORT wxMemoryDC: public wxDC
 {
-  DECLARE_DYNAMIC_CLASS(wxMemoryDC)
+    DECLARE_DYNAMIC_CLASS(wxMemoryDC)
 
-  public:
+public:
     wxMemoryDC(void);
-    wxMemoryDC( wxDC *dc ); // Create compatible DC
+    wxMemoryDC(wxDC* pDC); // Create compatible DC
 
     ~wxMemoryDC(void);
-    virtual void SelectObject( const wxBitmap& bitmap );
-    virtual void DoGetSize( int *width, int *height ) const;
-};
+    virtual void SelectObject(const wxBitmap& rBitmap);
+    virtual void DoGetSize( int* pWidth
+                           ,int* pHeight
+                          ) const;
+}; // end of CLASS wxMemoryDC
 
 #endif
     // _WX_DCMEMORY_H_
index 5a22aabc731e62bad7db5ef472cb78be600be5bc..a2926a2788f30b0ff89fac4f96e1120a71cb63f6 100644 (file)
@@ -1326,19 +1326,178 @@ wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
 // bit blit
 // ---------------------------------------------------------------------------
 
-bool wxDC::DoBlit( wxCoord xdest
-                  ,wxCoord ydest
-                  ,wxCoord width
-                  ,wxCoord height
-                  ,wxDC *source
-                  ,wxCoord xsrc
-                  ,wxCoord ysrc
-                  ,int  rop
-                  ,bool useMask
-                 )
+bool wxDC::DoBlit(
+  wxCoord                           vXdest
+, wxCoord                           vYdest
+, wxCoord                           vWidth
+, wxCoord                           vHeight
+, wxDC*                             pSource
+, wxCoord                           vXsrc
+, wxCoord                           vYsrc
+, int                               nRop
+, bool                              bUseMask
+)
 {
-   // TODO
-   return(TRUE);
+    wxMask*                         pMask = NULL;
+    CHARBUNDLE                      vCbnd;
+    COLORREF                        vOldTextColor;
+    COLORREF                        vOldBackground = ::GpiQueryBackColor(m_hPS);
+    POINTL                          aPoint[4] = { vXdest, vYdest
+                                                 ,vXdest + vWidth, vYdest + vHeight
+                                                 ,vXsrc, vYsrc
+                                                 ,vXsrc + vWidth, vYsrc + vHeight
+                                                };
+
+    if (bUseMask)
+    {
+        const wxBitmap&             rBmp = pSource->m_vSelectedBitmap;
+
+        pMask = rBmp.GetMask();
+        if (!(rBmp.Ok() && pMask && pMask->GetMaskBitmap()))
+        {
+            bUseMask = FALSE;
+        }
+    }
+
+    ::GpiQueryAttrs( m_hPS
+                    ,PRIM_CHAR
+                    ,CBB_COLOR
+                    ,&vCbnd
+                   );
+    vOldTextColor = (COLORREF)vCbnd.lColor;
+
+    if (m_textForegroundColour.Ok())
+    {
+        vCbnd.lColor = (LONG)m_textForegroundColour.GetPixel();
+        ::GpiSetAttrs( m_hPS           // presentation-space handle
+                      ,PRIM_CHAR       // Char primitive.
+                      ,CBB_COLOR       // sets color.
+                      ,0
+                      ,&vCbnd          // buffer for attributes.
+                     );
+    }
+    if (m_textBackgroundColour.Ok())
+    {
+        ::GpiSetBackColor(m_hPS, (LONG)m_textBackgroundColour.GetPixel());
+    }
+
+    LONG                            lRop = ROP_SRCCOPY;
+
+    switch (nRop)
+    {
+        case wxXOR:          lRop = ROP_SRCINVERT;        break;
+        case wxINVERT:       lRop = ROP_DSTINVERT;        break;
+        case wxOR_REVERSE:   lRop = 0x00DD0228;           break;
+        case wxAND_REVERSE:  lRop = ROP_SRCERASE;         break;
+        case wxCLEAR:        lRop = ROP_ZERO;             break;
+        case wxSET:          lRop = ROP_ONE;              break;
+        case wxOR_INVERT:    lRop = ROP_MERGEPAINT;       break;
+        case wxAND:          lRop = ROP_SRCAND;           break;
+        case wxOR:           lRop = ROP_SRCPAINT;         break;
+        case wxEQUIV:        lRop = 0x00990066;           break;
+        case wxNAND:         lRop = 0x007700E6;           break;
+        case wxAND_INVERT:   lRop = 0x00220326;           break;
+        case wxCOPY:         lRop = ROP_SRCCOPY;          break;
+        case wxNO_OP:        lRop = ROP_NOTSRCERASE;      break;
+        case wxSRC_INVERT:   lRop = ROP_SRCINVERT;        break;
+        case wxNOR:          lRop = ROP_NOTSRCCOPY;       break;
+        default:
+           wxFAIL_MSG( wxT("unsupported logical function") );
+           return FALSE;
+    }
+
+    bool                            bSuccess;
+#if 0
+    if (bUseMask)
+    {
+        //
+        // Blit bitmap with mask
+        //
+
+        //
+        // Create a temp buffer bitmap and DCs to access it and the mask
+        //
+            HDC dc_mask = ::CreateCompatibleDC(GetHdcOf(*source));
+            HDC dc_buffer = ::CreateCompatibleDC(GetHdc());
+            HBITMAP buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), width, height);
+            ::SelectObject(dc_mask, (HBITMAP) mask->GetMaskBitmap());
+            ::SelectObject(dc_buffer, buffer_bmap);
+
+            // copy dest to buffer
+            if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
+                           GetHdc(), xdest, ydest, SRCCOPY) )
+            {
+                wxLogLastError(wxT("BitBlt"));
+            }
+
+            // copy src to buffer using selected raster op
+            if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
+                           GetHdcOf(*source), xsrc, ysrc, dwRop) )
+            {
+                wxLogLastError(wxT("BitBlt"));
+            }
+
+            // set masked area in buffer to BLACK (pixel value 0)
+            COLORREF prevBkCol = ::SetBkColor(GetHdc(), RGB(255, 255, 255));
+            COLORREF prevCol = ::SetTextColor(GetHdc(), RGB(0, 0, 0));
+            if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
+                           dc_mask, xsrc, ysrc, SRCAND) )
+            {
+                wxLogLastError(wxT("BitBlt"));
+            }
+
+            // set unmasked area in dest to BLACK
+            ::SetBkColor(GetHdc(), RGB(0, 0, 0));
+            ::SetTextColor(GetHdc(), RGB(255, 255, 255));
+            if ( !::BitBlt(GetHdc(), xdest, ydest, (int)width, (int)height,
+                           dc_mask, xsrc, ysrc, SRCAND) )
+            {
+                wxLogLastError(wxT("BitBlt"));
+            }
+            ::SetBkColor(GetHdc(), prevBkCol);   // restore colours to original values
+            ::SetTextColor(GetHdc(), prevCol);
+
+            // OR buffer to dest
+            success = ::BitBlt(GetHdc(), xdest, ydest,
+                               (int)width, (int)height,
+                               dc_buffer, 0, 0, SRCPAINT) != 0;
+            if ( !success )
+            {
+                wxLogLastError(wxT("BitBlt"));
+            }
+
+            // tidy up temporary DCs and bitmap
+            ::SelectObject(dc_mask, 0);
+            ::DeleteDC(dc_mask);
+            ::SelectObject(dc_buffer, 0);
+            ::DeleteDC(dc_buffer);
+            ::DeleteObject(buffer_bmap);
+        }
+    }
+#endif
+//    else // no mask, just BitBlt() it
+//    {
+        bSuccess = (::GpiBitBlt( m_hPS
+                                ,pSource->GetHPS()
+                                ,4L
+                                ,aPoint
+                                ,lRop
+                                ,BBO_IGNORE
+                               ) != GPI_ERROR);
+        if (!bSuccess )
+        {
+            wxLogLastError(wxT("BitBlt"));
+        }
+//    }
+    vCbnd.lColor = (LONG)vOldTextColor;
+    ::GpiSetAttrs( m_hPS           // presentation-space handle
+                  ,PRIM_CHAR       // Char primitive.
+                  ,CBB_COLOR       // sets color.
+                  ,0
+                  ,&vCbnd          // buffer for attributes.
+                 );
+    ::GpiSetBackColor(m_hPS, (LONG)vOldBackground);
+    return bSuccess;
 }
 
 void wxDC::DoGetSize( int* width, int* height ) const
index bc20d8ac52456654f89b0e713df4545d62f25e7d..1875e60cfbaa88217583e4452128579c1015ff2e 100644 (file)
@@ -123,7 +123,17 @@ wxWindowDC::wxWindowDC(
         sError = wxPMErrorToStr(vError);
         wxLogError("Unable to set current color table. Error: %s\n", sError);
     }
+    ::GpiCreateLogColorTable( m_hPS
+                             ,0L
+                             ,LCOLF_RGB
+                             ,0L
+                             ,0L
+                             ,NULL
+                            );
     SetBackground(wxBrush(m_pCanvas->GetBackgroundColour(), wxSOLID));
+    ::WinQueryWindowRect( GetWinHwnd(m_pCanvas)
+                         ,&m_vRclPaint
+                        );
 }
 
 wxWindowDC::~wxWindowDC()
@@ -190,6 +200,13 @@ wxClientDC::wxClientDC(
         sError = wxPMErrorToStr(vError);
         wxLogError("Unable to set current color table. Error: %s\n", sError);
     }
+    ::GpiCreateLogColorTable( m_hPS
+                             ,0L
+                             ,LCOLF_RGB
+                             ,0L
+                             ,0L
+                             ,NULL
+                            );
     //
     // Default mode is BM_LEAVEALONE so we make no call Set the mix
     //
@@ -197,6 +214,12 @@ wxClientDC::wxClientDC(
                           ,wxSOLID
                          )
                  );
+    //
+    // Set the DC/PS rectangle
+    //
+    ::WinQueryWindowRect( GetWinHwnd(m_pCanvas)
+                         ,&m_vRclPaint
+                        );
 } // end of wxClientDC::wxClientDC
 
 wxClientDC::~wxClientDC()
index d9d6a2201f54d3ff1f62d9b7ccac21222e5b25aa..a0aeef01b21046e3015c569ef676819576212b51 100644 (file)
@@ -28,6 +28,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC)
 
 wxMemoryDC::wxMemoryDC(void)
 {
+    ERRORID                         vError;
+    wxString                        sError;
     HDC                             hDC;
     HPS                             hPS;
     DEVOPENSTRUC                    vDOP = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
@@ -48,6 +50,33 @@ wxMemoryDC::wxMemoryDC(void)
             m_bOwnsDC = TRUE;
             SetBrush(*wxWHITE_BRUSH);
             SetPen(*wxBLACK_PEN);
+            if (!::GpiCreateLogColorTable( m_hPS
+                                          ,0L
+                                          ,LCOLF_CONSECRGB
+                                          ,0L
+                                          ,(LONG)wxTheColourDatabase->m_nSize
+                                          ,(PLONG)wxTheColourDatabase->m_palTable
+                                         ))
+            {
+                vError = ::WinGetLastError(vHabmain);
+                sError = wxPMErrorToStr(vError);
+                wxLogError("Unable to set current color table. Error: %s\n", sError);
+            }
+            //
+            // Set the color table to RGB mode
+            //
+            if (!::GpiCreateLogColorTable( m_hPS
+                                          ,0L
+                                          ,LCOLF_RGB
+                                          ,0L
+                                          ,0L
+                                          ,NULL
+                                         ))
+            {
+                vError = ::WinGetLastError(vHabmain);
+                sError = wxPMErrorToStr(vError);
+                wxLogError("Unable to set current color table. Error: %s\n", sError);
+            }
         }
         else
         {
@@ -155,7 +184,7 @@ void wxMemoryDC::SelectObject(
     m_vSelectedBitmap.SetSelectedInto(this);
     hBmp = (WXHBITMAP)::GpiSetBitmap(m_hPS, (HBITMAP)hBmp);
 
-    if (hBmp != HBM_ERROR)
+    if (hBmp == HBM_ERROR)
     {
         wxLogLastError(wxT("SelectObject(memDC, bitmap)"));
         wxFAIL_MSG(wxT("Couldn't select a bitmap into wxMemoryDC"));
index a270099a340e4c69bf4ffad246fcca9b6aac1fb2..1f58781ed9f53f44b52f144bc11dcc7873c9e098 100644 (file)
@@ -75,6 +75,7 @@ bool wxOwnerDrawn::OnMeasureItem(
 
     wxString                        sStr = wxStripMenuCodes(m_strName);
 
+#if 0
     wxString                        sTgt = "\t";
     size_t                          nIndex;
 
@@ -85,7 +86,7 @@ bool wxOwnerDrawn::OnMeasureItem(
     nIndex = sStr.Find(sTgt.c_str());
     if (nIndex != -1)
         sStr.Replace(sTgt.c_str(), "", TRUE);
-
+#endif
     vDC.GetTextExtent( sStr
                       ,(long *)pWidth
                       ,(long *)pHeight
@@ -120,6 +121,7 @@ bool wxOwnerDrawn::OnDrawItem(
     wxColour                        vColBack;
     wxColour                        vColText;
     COLORREF                        vRef;
+    RECTL                           vRect = {rRect.x + 4, rRect.y + 1, rRect.x + (rRect.width - 2), rRect.y + rRect.height};
     char                            zMsg[128];
 
     //
@@ -133,17 +135,18 @@ bool wxOwnerDrawn::OnDrawItem(
     {
         ::GpiSetCharSet(hPS, LCID_DEFAULT);
     }
+
+    //
+    // Base on the status of the menu item pick the right colors
+    //
     if (eStatus & wxODSelected)
     {
-        vRef = (ULONG)::WinQuerySysColor( HWND_DESKTOP
-                                         ,SYSCLR_MENUHILITEBGND // Light gray
-                                         ,0L
-                                        );
-        vColBack.Set( GetRValue(vRef)
-                     ,GetGValue(vRef)
-                     ,GetBValue(vRef)
-                    );
-        vColText = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_MENUTEXT);
+        wxColour                        vCol2("WHITE");
+        vColBack.Set( (unsigned char)0
+                     ,(unsigned char)0
+                     ,(unsigned char)160
+                    ); // no dark blue in color table
+        vColText = vCol2;
     }
     else if (eStatus & wxODDisabled)
     {
@@ -186,24 +189,14 @@ bool wxOwnerDrawn::OnDrawItem(
                      ,GetBValue(vRef)
                     );
     }
-    vRef = vColBack.GetPixel();
-    vCbnd.lBackColor = (LONG)vRef;
-
-    vRef = vColText.GetPixel();
-    vCbnd.lColor = (LONG)vRef;
+    rDC.SetTextBackground(vColBack);
+    rDC.SetTextForeground(vColText);
+    rDC.SetBackgroundMode(wxTRANSPARENT);
 
-        sprintf(zMsg, "Color: %ld", vRef);
-        wxMessageBox( "wxWindows Menu Sample"
-                     ,zMsg
-                     ,wxICON_INFORMATION
-                    );
-
-    ::GpiSetAttrs( hPS
-                  ,PRIM_CHAR
-                  ,CBB_COLOR | CBB_BACK_COLOR
-                  ,0
-                  ,&vCbnd
-                 );
+    //
+    // Paint the background
+    //
+    ::WinFillRect(hPS, &vRect, vColBack.GetPixel());
 
     //
     // Determine where to draw and leave space for a check-mark.
@@ -215,34 +208,99 @@ bool wxOwnerDrawn::OnDrawItem(
     // drawing methods like ::DrawState that can cleanly handle accel
     // pneumonics and deal, automatically, with various states, so we have
     // to handle them ourselves. Notice Win32 can't handle \t in ownerdrawn
-    // strings either.
+    // strings either.  We cannot handle mneumonics either.  We display
+    // it, though, in hopes we can figure it out some day.
+    //
 
     //
-    // Manually replace the tab with spaces
+    // Display main text and accel text separately to allign better
     //
     wxString                        sTgt = "\t";
-    wxString                        sReplace = "           ";
+    wxString                        sFullString = m_strName; // need to save the original text
+    wxString                        sAccel;
     size_t                          nIndex;
+    size_t                          nWidth;
+    size_t                          nCharWidth;
+    size_t                          nHeight;
+    bool                            bFoundMneumonic = FALSE;
+    bool                            bFoundAccel = FALSE;
 
-    nIndex = m_strName.Find(sTgt.c_str());
+    //
+    // Deal with the tab, extracting the Accel text
+    //
+    nIndex = sFullString.Find(sTgt.c_str());
     if (nIndex != -1)
-        m_strName.Replace(sTgt.c_str(), sReplace.c_str(), TRUE);
+    {
+        bFoundAccel = TRUE;
+        sAccel = sFullString.Mid(nIndex + 1);
+        sFullString.Remove(nIndex);
+    }
+
+    //
+    // Deal with the mneumonic character
+    //
     sTgt = "~";
-    nIndex = m_strName.Find(sTgt.c_str());
+    nIndex = sFullString.Find(sTgt.c_str());
     if (nIndex != -1)
-        m_strName.Replace(sTgt.c_str(), "", TRUE);
+    {
+        wxString                    sTmp = sFullString;
+
+        bFoundMneumonic = TRUE;
+        sTmp.Remove(nIndex);
+        rDC.GetTextExtent( sTmp
+                          ,(long *)&nWidth
+                          ,(long *)&nHeight
+                         );
+        sTmp = sFullString[nIndex + 1];
+        rDC.GetTextExtent( sTmp
+                          ,(long *)&nCharWidth
+                          ,(long *)&nHeight
+                         );
+        sFullString.Replace(sTgt.c_str(), "", TRUE);
+    }
+
+    //
+    // Draw the main item text sans the accel text
+    rDC.DrawText( sFullString
+                 ,nX
+                 ,rRect.y + 4
+                );
+    if (bFoundMneumonic)
+    {
+        //
+        // Underline the mneumonic -- still won't work, but at least it "looks" right
+        //
+        wxPen                       vPen;
+        POINTL                      vPntStart = {nX + nWidth - 1, rRect.y + 2}; // Make it look pretty!
+        POINTL                      vPntEnd = {nX + nWidth + nCharWidth - 3, rRect.y + 2}; //CharWidth is bit wide
+
+        vPen = wxPen(vColText, 1, wxSOLID); // Assuming we are always black
+        rDC.SetPen(vPen);
+        ::GpiMove(hPS, &vPntStart);
+        ::GpiLine(hPS, &vPntEnd);
+    }
 
-    POINTL                          vPoint;
+    //
+    // Now draw the accel text
+    //
+    if (bFoundAccel)
+    {
+        size_t                      nWidth;
+        size_t                      nHeight;
 
-    vPoint.x = nX;
-    vPoint.y = rRect.y + 4;
-    ::GpiCharStringAt( hPS
-                      ,&vPoint
-                      ,m_strName.length()
-                      ,(PCH)m_strName.c_str()
-                     );
+        rDC.GetTextExtent( sAccel
+                          ,(long *)&nWidth
+                          ,(long *)&nHeight
+                         );
+        //
+        // Back off the starting position from the right edge
+        //
+        rDC.DrawText( sAccel
+                     ,rRect.width - (nWidth + 7) // this seems to mimic the default OS/2 positioning
+                     ,rRect.y + 4
+                    );
+    }
 
-#if 0
     //
     // Draw the bitmap
     // ---------------
@@ -316,7 +374,7 @@ bool wxOwnerDrawn::OnDrawItem(
                                                };
                 LINEBUNDLE          vLine;
 
-                vLine.lColor = lColBack;
+                vLine.lColor = vColBack.GetPixel();
                 ::GpiSetAttrs( hPS
                               ,PRIM_LINE
                               ,LBB_COLOR
@@ -332,7 +390,6 @@ bool wxOwnerDrawn::OnDrawItem(
             }
         }
     }
-#endif
     return TRUE;
 } // end of wxOwnerDrawn::OnDrawItem
 
index e3b48ba2e7577b38f97488fdc0c13148b0d5e533..b9729c7770c2800b1a21503361914fc9a6717324 100644 (file)
@@ -2663,6 +2663,8 @@ bool wxWindow::OS2OnDrawItem(
     //
     if (vId == 0)
     {
+        ERRORID                     vError;
+        wxString                    sError;
         POWNERITEM                  pMeasureStruct = (POWNERITEM)pItemStruct;
         wxFrame*                    pFrame = (wxFrame*)this;
         wxMenuItem*                 pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
@@ -2676,6 +2678,36 @@ bool wxWindow::OS2OnDrawItem(
                    ,FALSE
                   );
         vDc.SetHPS(pMeasureStruct->hps);
+        //
+        // Load the wxWindows Pallete and set to RGB mode
+        //
+        if (!::GpiCreateLogColorTable( pMeasureStruct->hps
+                                      ,0L
+                                      ,LCOLF_CONSECRGB
+                                      ,0L
+                                      ,(LONG)wxTheColourDatabase->m_nSize
+                                      ,(PLONG)wxTheColourDatabase->m_palTable
+                                     ))
+        {
+            vError = ::WinGetLastError(vHabmain);
+            sError = wxPMErrorToStr(vError);
+            wxLogError("Unable to set current color table. Error: %s\n", sError);
+        }
+        //
+        // Set the color table to RGB mode
+        //
+        if (!::GpiCreateLogColorTable( pMeasureStruct->hps
+                                      ,0L
+                                      ,LCOLF_RGB
+                                      ,0L
+                                      ,0L
+                                      ,NULL
+                                     ))
+        {
+            vError = ::WinGetLastError(vHabmain);
+            sError = wxPMErrorToStr(vError);
+            wxLogError("Unable to set current color table. Error: %s\n", sError);
+        }
 
         wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
 
@@ -2719,11 +2751,32 @@ bool wxWindow::OS2OnDrawItem(
         }
         else
         {
-            //
-            // For now we don't care about doing our own highlighting so we'll
-            // just ignore the entie message!
-            //
-            return TRUE;
+            if (pMeasureStruct->fsAttribute & MIA_HILITED)
+            {
+                eAction = wxOwnerDrawn::wxODDrawAll;
+                eStatus |= wxOwnerDrawn::wxODSelected;
+                //
+                // Keep the system from trying to highlight with its bogus colors
+                //
+                pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_HILITED;
+            }
+            else if (!(pMeasureStruct->fsAttribute & MIA_HILITED))
+            {
+                eAction = wxOwnerDrawn::wxODDrawAll;
+                eStatus = 0;
+                //
+                // Keep the system from trying to highlight with its bogus colors
+                //
+                pMeasureStruct->fsAttribute = pMeasureStruct->fsAttributeOld &= ~MIA_HILITED;
+            }
+            else
+            {
+                //
+                // For now we don't care about anything else
+                // just ignore the entire message!
+                //
+                return TRUE;
+            }
         }
         //
         // Now redraw the item