]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/spinbutt.cpp
Optimized sizers to not call CalcMin more often than neccessary
[wxWidgets.git] / src / os2 / spinbutt.cpp
index 9ad28c1b3ac8a3362198f99a1174a48a8836a422..0bd30bf97c577b6cecc552b860df0b0bc8f0404b 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef WX_PRECOMP
     #include "wx/wx.h"
 #endif
+#if wxUSE_SPINBTN
 
 // Can't resolve reference to CreateUpDownControl in
 // TWIN32, but could probably use normal CreateWindow instead.
 
 #include "wx/spinbutt.h"
 
+extern void  wxAssociateWinWithHandle( HWND         hWnd
+                                      ,wxWindowOS2* pWin
+                                     );
+static WXFARPROC fnWndProcSpinCtrl = (WXFARPROC)NULL;
+
 IMPLEMENT_DYNAMIC_CLASS(wxSpinEvent, wxNotifyEvent)
 
 #include "wx/os2/private.h"
@@ -43,29 +49,113 @@ IMPLEMENT_DYNAMIC_CLASS(wxSpinEvent, wxNotifyEvent)
 IMPLEMENT_DYNAMIC_CLASS(wxSpinButton, wxControl)
 
 bool wxSpinButton::Create(
-  wxWindow*                         parent
-, wxWindowID                        id
-, const wxPoint&                    pos
-, const wxSize&                     size
-, long                              style
-, const wxString&                   name
+  wxWindow*                         pParent
+, wxWindowID                        vId
+, const wxPoint&                    rPos
+, const wxSize&                     rSize
+, long                              lStyle
+, const wxString&                   rsName
 )
 {
-    SetName(name);
-
-    m_windowStyle = style;
-
-    SetParent(parent);
-
-    m_windowId = (id == -1) ? NewControlId() : id;
+    int                             nX      = rPos.x;
+    int                             nY      = rPos.y;
+    int                             nWidth  = rSize.x;
+    int                             nHeight = rSize.y;
+    SWP                             vSwp;
+
+    m_min = 0;
+    m_max = 100;
+    if (vId == -1)
+        m_windowId = NewControlId();
+    else
+        m_windowId = vId;
+    m_backgroundColour = pParent->GetBackgroundColour();
+    m_foregroundColour = pParent->GetForegroundColour();
+    SetName(rsName);
+    SetParent(pParent);
+    m_windowStyle      = lStyle;
+
+    //
+    // Get the right size for the control
+    //
+    if (nWidth <= 0 || nHeight <= 0 )
+    {
+        wxSize                      vSize = DoGetBestSize();
 
-    // TODO create spin button
-    return FALSE;
-}
+        if (nWidth <= 0 )
+            nWidth = vSize.x;
+        if (nHeight <= 0 )
+            nHeight = vSize.y;
+    }
+    if (nX < 0 )
+        nX = 0;
+    if (nY < 0 )
+        nY = 0;
+
+    long                            lSstyle = 0L;
+
+    lSstyle = WS_VISIBLE      |
+              WS_TABSTOP      |
+              SPBS_MASTER     | // We use only single field spin buttons
+              SPBS_NUMERICONLY; // We default to numeric data
+
+    if (m_windowStyle & wxCLIP_SIBLINGS )
+        lSstyle |= WS_CLIPSIBLINGS;
+
+    m_hWnd = (WXHWND)::WinCreateWindow( GetWinHwnd(pParent)
+                                       ,WC_SPINBUTTON
+                                       ,(PSZ)NULL
+                                       ,lSstyle
+                                       ,0L, 0L, 0L, 0L
+                                       ,GetWinHwnd(pParent)
+                                       ,HWND_TOP
+                                       ,(HMENU)vId
+                                       ,NULL
+                                       ,NULL
+                                      );
+    if (m_hWnd == 0)
+    {
+        return FALSE;
+    }
+    SetRange(m_min, m_max);
+    if(pParent)
+        pParent->AddChild((wxSpinButton *)this);
+
+    ::WinQueryWindowPos(m_hWnd, &vSwp);
+    SetXComp(vSwp.x);
+    SetYComp(vSwp.y);
+    wxFont*                          pTextFont = new wxFont( 10
+                                                            ,wxMODERN
+                                                            ,wxNORMAL
+                                                            ,wxNORMAL
+                                                           );
+    SetFont(*pTextFont);
+    //
+    // For OS/2 we want to hide the text portion so we can substitute an
+    // independent text ctrl in its place.  10 device units does this
+    //
+    SetSize( nX
+            ,nY
+            ,10L
+            ,nHeight
+           );
+    wxAssociateWinWithHandle( m_hWnd
+                             ,(wxWindowOS2*)this
+                            );
+#if 0
+    // FIXME:
+    // Apparently, this does not work, as it crashes in setvalue/setrange calls
+    // What's it supposed to do anyway?
+    ::WinSetWindowULong(GetHwnd(), QWL_USER, (LONG)this);
+    fnWndProcSpinCtrl = (WXFARPROC)::WinSubclassWindow(m_hWnd, (PFNWP)wxSpinCtrlWndProc);
+#endif
+    delete pTextFont;
+    return TRUE;
+} // end of wxSpinButton::Create
 
 wxSpinButton::~wxSpinButton()
 {
-}
+} // end of wxSpinButton::~wxSpinButton
 
 // ----------------------------------------------------------------------------
 // size calculation
@@ -73,23 +163,13 @@ wxSpinButton::~wxSpinButton()
 
 wxSize wxSpinButton::DoGetBestSize() const
 {
-    // TODO:
-/*
-    if ( (GetWindowStyle() & wxSP_VERTICAL) != 0 )
-    {
-        // vertical control
-        return wxSize(GetSystemMetrics(SM_CXVSCROLL),
-                      2*GetSystemMetrics(SM_CYVSCROLL));
-    }
-    else
-    {
-        // horizontal control
-        return wxSize(2*GetSystemMetrics(SM_CXHSCROLL),
-                      GetSystemMetrics(SM_CYHSCROLL));
-    }
-*/
-    return wxSize(0, 0);
-}
+    //
+    // OS/2 PM does not really have system metrics so we'll just set  it to
+    // 24x20 which is the size of the buttons and the borders.
+    // Also we have no horizontal spin buttons.
+    //
+    return (wxSize(24,20));
+} // end of wxSpinButton::DoGetBestSize
 
 // ----------------------------------------------------------------------------
 // Attributes
@@ -97,65 +177,67 @@ wxSize wxSpinButton::DoGetBestSize() const
 
 int wxSpinButton::GetValue() const
 {
-    // TODO
-    return 0;
-}
-
-void wxSpinButton::SetValue(int val)
-{
-    // TODO
-}
-
-void wxSpinButton::SetRange(int minVal, int maxVal)
+    long                            lVal = 0L;
+    char                            zVal[10];
+
+    ::WinSendMsg( GetHwnd()
+                 ,SPBM_QUERYVALUE
+                 ,MPFROMP(zVal)
+                 ,MPFROM2SHORT( (USHORT)10
+                               ,SPBQ_UPDATEIFVALID
+                              )
+                );
+    lVal = atol(zVal);
+    return ((int)lVal);
+} // end of wxSpinButton::GetValue
+
+bool wxSpinButton::OS2OnScroll(
+  int                               nOrientation
+, WXWORD                            wParam
+, WXWORD                            wPos
+, WXHWND                            hControl
+)
 {
-    // TODO
-}
+    wxCHECK_MSG(hControl, FALSE, wxT("scrolling what?") )
 
-bool wxSpinButton::OS2OnScroll(int orientation, WXWORD wParam,
-                               WXWORD pos, WXHWND control)
-{
-    wxCHECK_MSG( control, FALSE, wxT("scrolling what?") )
-// TODO:
-/*
-    if ( wParam != SB_THUMBPOSITION )
-    {
-        // probable SB_ENDSCROLL - we don't react to it
-        return FALSE;
-    }
+    wxSpinEvent                     vEvent( wxEVT_SCROLL_THUMBTRACK
+                                           ,m_windowId
+                                          );
+    int                             nVal = (int)wPos;    // cast is important for negative values!
 
-    wxSpinEvent event(wxEVT_SCROLL_THUMBTRACK, m_windowId);
-    event.SetPosition((short)pos);    // cast is important for negative values!
-    event.SetEventObject(this);
-
-    return GetEventHandler()->ProcessEvent(event);
-*/
-    return FALSE;
-}
+    vEvent.SetPosition(nVal);
+    vEvent.SetEventObject(this);
+    return(GetEventHandler()->ProcessEvent(vEvent));
+} // end of wxSpinButton::OS2OnScroll
 
-bool wxSpinButton::OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
+bool wxSpinButton::OS2Command(
+  WXUINT                            uCmd
+, WXWORD                            wId
+)
 {
-    // TODO:
-/*
-    LPNM_UPDOWN lpnmud = (LPNM_UPDOWN)lParam;
-
-    wxSpinEvent event(lpnmud->iDelta > 0 ? wxEVT_SCROLL_LINEUP
-                                         : wxEVT_SCROLL_LINEDOWN,
-                      m_windowId);
-    event.SetPosition(lpnmud->iPos + lpnmud->iDelta);
-    event.SetEventObject(this);
-
-    bool processed = GetEventHandler()->ProcessEvent(event);
-
-    *result = event.IsAllowed() ? 0 : 1;
-
-    return processed;
-*/
     return FALSE;
-}
+} // end of wxSpinButton::OS2Command
 
-bool wxSpinButton::OS2Command(WXUINT cmd, WXWORD id)
+void wxSpinButton::SetRange(
+  int                               nMinVal
+, int                               nMaxVal
+)
 {
-    // No command messages
-    return FALSE;
-}
+    m_min = nMinVal;
+    m_max = nMaxVal;
+
+    ::WinSendMsg( GetHwnd()
+                 ,SPBM_SETLIMITS
+                 ,MPFROMLONG(nMaxVal)
+                 ,MPFROMLONG(nMinVal)
+                );
+} // end of wxSpinButton::SetRange
+
+void wxSpinButton::SetValue(
+  int                               nValue
+)
+{
+    ::WinSendMsg(GetHwnd(), SPBM_SETCURRENTVALUE, MPFROMLONG(nValue), MPARAM(0));
+} // end of wxSpinButton::SetValue
 
+#endif //wxUSE_SPINBTN