]> git.saurik.com Git - wxWidgets.git/commitdiff
wxCalendarCtrl works under MSW too
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 29 Dec 1999 23:34:18 +0000 (23:34 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 29 Dec 1999 23:34:18 +0000 (23:34 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5149 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/calctrl.h
include/wx/msw/choice.h
include/wx/msw/combobox.h
include/wx/msw/spinctrl.h
src/generic/calctrl.cpp
src/msw/choice.cpp
src/msw/combobox.cpp
src/msw/spinbutt.cpp
src/msw/spinctrl.cpp
src/msw/window.cpp

index 5bde99940d39b6f6799c06b4702af9e75a7280b2..c685deeb4846a4348b94faf05c767909fc5e52b7 100644 (file)
@@ -40,7 +40,8 @@ public:
                    const wxSize& size = wxDefaultSize,
                    long style = 0,
                    const wxString& name = wxCalendarNameStr)
-        : wxControl(parent, id, pos, size, style, wxDefaultValidator, name)
+        : wxControl(parent, id, pos, size,
+                    style | wxWANTS_CHARS, wxDefaultValidator, name)
     {
         Init();
 
@@ -55,6 +56,8 @@ public:
                 long style = 0,
                 const wxString& name = wxCalendarNameStr);
 
+    virtual ~wxCalendarCtrl();
+
     // set/get the current date
     void SetDate(const wxDateTime& date);
     const wxDateTime& GetDate() const { return m_date; }
@@ -63,25 +66,34 @@ public:
     // value
     bool HitTest(const wxPoint& pos, wxDateTime *date);
 
+    // implementation only from now on
+    // -------------------------------
+
+    // forward these functions to all subcontrols
+    virtual bool Enable(bool enable = TRUE);
+    virtual bool Show(bool show = TRUE);
+
+    // event handlers
+    void OnPaint(wxPaintEvent& event);
+    void OnClick(wxMouseEvent& event);
+    void OnChar(wxKeyEvent& event);
+    void OnMonthChange(wxCommandEvent& event);
+    void OnYearChange(wxSpinEvent& event);
+
 private:
     // common part of all ctors
     void Init();
 
     // override some base class virtuals
     virtual wxSize DoGetBestSize() const;
+    virtual void DoGetPosition(int *x, int *y) const;
+    virtual void DoGetSize(int *width, int *height) const;
     virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags);
     virtual void DoMoveWindow(int x, int y, int width, int height);
 
     // (re)calc m_widthCol and m_heightRow
     void RecalcGeometry();
 
-    // event handlers
-    void OnPaint(wxPaintEvent& event);
-    void OnClick(wxMouseEvent& event);
-    void OnChar(wxKeyEvent& event);
-    void OnMonthChange(wxCommandEvent& event);
-    void OnYearChange(wxSpinEvent& event);
-
     // set the date and send the notification
     void SetDateAndNotify(const wxDateTime& date);
 
index 654f1af915fc9723eef709817b2ac6bbf47bd876..f60a02305716fc4f2c11096a3f75d63d6aba3122 100644 (file)
@@ -74,7 +74,7 @@ protected:
     virtual wxClientData* DoGetItemClientObject( int n ) const;
 
     // MSW implementation
-    virtual wxSize DoGetBestSize();
+    virtual wxSize DoGetBestSize() const;
     virtual void DoSetSize(int x, int y,
                            int width, int height,
                            int sizeFlags = wxSIZE_AUTO);
index 52e8a9d6dbc590f196f13645620716a216e89a47..1828e0045a9fc1d0c861b065ddac36dfc0ae6c4e 100644 (file)
@@ -78,9 +78,8 @@ public:
     virtual bool MSWCommand(WXUINT param, WXWORD id);
 
 protected:
-    virtual void DoSetSize(int x, int y,
-                           int width, int height,
-                           int sizeFlags = wxSIZE_AUTO);
+    virtual void DoMoveWindow(int x, int y, int width, int height);
+    virtual wxSize DoGetBestSize() const;
 };
 
 #endif // wxUSE_COMBOBOX
index f6c8f8fd52210371cb0aa158cc366bbab3243983..37f8e1c2e4edba5d8792e1983891fc009bba8556 100644 (file)
@@ -54,11 +54,16 @@ public:
     // because the base class already has one returning int!)
     void SetValue(const wxString& text);
 
-    // override some of the base class virtuals
+    // implementation only from now on
+    // -------------------------------
+
     virtual void SetValue(int val) { wxSpinButton::SetValue(val); }
     virtual int GetValue() const;
     virtual bool SetFont(const wxFont &font);
 
+    virtual bool Enable(bool enable = TRUE);
+    virtual bool Show(bool show = TRUE);
+
 protected:
     virtual void DoMoveWindow(int x, int y, int width, int height);
     virtual wxSize DoGetBestSize() const;
index 5419de38ceb061378d5c8a715721cb798acdd23b..ed540c9dd43c6af015c1f6af992b826924ac95b5 100644 (file)
 
 #include "wx/calctrl.h"
 
+#define DEBUG_PAINT 0
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+class wxMonthComboBox : public wxComboBox
+{
+public:
+    wxMonthComboBox(wxCalendarCtrl *cal);
+
+    void OnMonthChange(wxCommandEvent& event) { m_cal->OnMonthChange(event); }
+
+private:
+    wxCalendarCtrl *m_cal;
+
+    DECLARE_EVENT_TABLE()
+};
+
+class wxYearSpinCtrl : public wxSpinCtrl
+{
+public:
+    wxYearSpinCtrl(wxCalendarCtrl *cal);
+
+    void OnYearChange(wxSpinEvent& event) { m_cal->OnYearChange(event); }
+
+private:
+    wxCalendarCtrl *m_cal;
+
+    DECLARE_EVENT_TABLE()
+};
+
 // ----------------------------------------------------------------------------
 // wxWin macros
 // ----------------------------------------------------------------------------
@@ -46,9 +78,14 @@ BEGIN_EVENT_TABLE(wxCalendarCtrl, wxControl)
     EVT_CHAR(wxCalendarCtrl::OnChar)
 
     EVT_LEFT_DOWN(wxCalendarCtrl::OnClick)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxMonthComboBox, wxComboBox)
+    EVT_COMBOBOX(-1, wxMonthComboBox::OnMonthChange)
+END_EVENT_TABLE()
 
-    EVT_COMBOBOX(-1, wxCalendarCtrl::OnMonthChange)
-    EVT_SPINCTRL(-1, wxCalendarCtrl::OnYearChange)
+BEGIN_EVENT_TABLE(wxYearSpinCtrl, wxSpinCtrl)
+    EVT_SPINCTRL(-1, wxYearSpinCtrl::OnYearChange)
 END_EVENT_TABLE()
 
 IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl, wxControl)
@@ -57,6 +94,40 @@ IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl, wxControl)
 // implementation
 // ============================================================================
 
+// ----------------------------------------------------------------------------
+// wxMonthComboBox and wxYearSpinCtrl
+// ----------------------------------------------------------------------------
+
+wxMonthComboBox::wxMonthComboBox(wxCalendarCtrl *cal)
+               : wxComboBox(cal->GetParent(), -1,
+                            wxEmptyString,
+                            wxDefaultPosition,
+                            wxDefaultSize,
+                            0, NULL,
+                            wxCB_READONLY)
+{
+    m_cal = cal;
+
+    wxDateTime::Month m;
+    for ( m = wxDateTime::Jan; m < wxDateTime::Inv_Month; wxNextMonth(m) )
+    {
+        Append(wxDateTime::GetMonthName(m));
+    }
+
+    SetSelection(m_cal->GetDate().GetMonth());
+}
+
+wxYearSpinCtrl::wxYearSpinCtrl(wxCalendarCtrl *cal)
+              : wxSpinCtrl(cal->GetParent(), -1,
+                           cal->GetDate().Format(_T("%Y")),
+                           wxDefaultPosition,
+                           wxDefaultSize,
+                           wxSP_ARROW_KEYS,
+                           -4300, 10000, cal->GetDate().GetYear())
+{
+    m_cal = cal;
+}
+
 // ----------------------------------------------------------------------------
 // wxCalendarCtrl
 // ----------------------------------------------------------------------------
@@ -84,32 +155,12 @@ bool wxCalendarCtrl::Create(wxWindow *parent,
                             long style,
                             const wxString& name)
 {
-    m_date = date.IsValid() ? date : wxDateTime::Today();
+    SetWindowStyle(style | (wxBORDER | wxWANTS_CHARS));
 
-    wxString monthNames[12];
-    wxDateTime::Month m;
-    for ( m = wxDateTime::Jan; m < wxDateTime::Inv_Month; wxNextMonth(m) )
-    {
-        monthNames[m] = wxDateTime::GetMonthName(m);
-    }
-
-    m_comboMonth = new wxComboBox(parent, -1,
-                                  monthNames[m_date.GetMonth()],
-                                  wxDefaultPosition,
-                                  wxDefaultSize,
-                                  WXSIZEOF(monthNames), monthNames,
-                                  wxCB_READONLY);
-
-    m_spinYear = new wxSpinCtrl(parent, -1,
-                                m_date.Format(_T("%Y")),
-                                wxDefaultPosition,
-                                wxDefaultSize,
-                                wxSP_ARROW_KEYS,
-                                -4300, 10000, m_date.GetYear());
+    m_date = date.IsValid() ? date : wxDateTime::Today();
 
-    // we want to process the events from these controls
-    m_comboMonth->PushEventHandler(this);
-    m_spinYear->PushEventHandler(this);
+    m_comboMonth = new wxMonthComboBox(this);
+    m_spinYear = new wxYearSpinCtrl(this);
 
     wxSize sizeReal;
     if ( size.x == -1 || size.y == -1 )
@@ -133,6 +184,44 @@ bool wxCalendarCtrl::Create(wxWindow *parent,
     return TRUE;
 }
 
+wxCalendarCtrl::~wxCalendarCtrl()
+{
+#if 0
+    m_comboMonth->PopEventHandler();
+    m_spinYear->PopEventHandler();
+#endif // 0
+}
+
+// ----------------------------------------------------------------------------
+// forward wxWin functions to subcontrols
+// ----------------------------------------------------------------------------
+
+bool wxCalendarCtrl::Show(bool show)
+{
+    if ( !wxControl::Show(show) )
+    {
+        return FALSE;
+    }
+
+    m_comboMonth->Show(show);
+    m_spinYear->Show(show);
+
+    return TRUE;
+}
+
+bool wxCalendarCtrl::Enable(bool enable)
+{
+    if ( !wxControl::Enable(enable) )
+    {
+        return FALSE;
+    }
+
+    m_comboMonth->Enable(enable);
+    m_spinYear->Enable(enable);
+
+    return TRUE;
+}
+
 // ----------------------------------------------------------------------------
 // changing date
 // ----------------------------------------------------------------------------
@@ -270,7 +359,7 @@ void wxCalendarCtrl::DoMoveWindow(int x, int y, int width, int height)
     m_comboMonth->Move(x, y);
 
     int xDiff = sizeCombo.x + HORZ_MARGIN;
-    m_spinYear->SetSize(x + xDiff, y, width - xDiff, -1);
+    m_spinYear->SetSize(x + xDiff, y, width - xDiff, sizeCombo.y);
 
     wxSize sizeSpin = m_spinYear->GetSize();
     int yDiff = wxMax(sizeSpin.y, sizeCombo.y) + VERT_MARGIN;
@@ -278,6 +367,28 @@ void wxCalendarCtrl::DoMoveWindow(int x, int y, int width, int height)
     wxControl::DoMoveWindow(x, y + yDiff, width, height - yDiff);
 }
 
+void wxCalendarCtrl::DoGetPosition(int *x, int *y) const
+{
+    wxControl::DoGetPosition(x, y);
+
+    // our real top corner is not in this position
+    if ( y )
+    {
+        *y -= m_comboMonth->GetSize().y + VERT_MARGIN;
+    }
+}
+
+void wxCalendarCtrl::DoGetSize(int *width, int *height) const
+{
+    wxControl::DoGetSize(width, height);
+
+    // our real height is bigger
+    if ( height )
+    {
+        *height += m_comboMonth->GetSize().y + VERT_MARGIN;
+    }
+}
+
 void wxCalendarCtrl::RecalcGeometry()
 {
     if ( m_widthCol != 0 )
@@ -320,14 +431,18 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& event)
 
     RecalcGeometry();
 
+#if DEBUG_PAINT
     printf("--- starting to paint, selection: %s, week %u\n",
            m_date.Format("%a %d-%m-%Y %H:%M:%S").c_str(),
            GetWeek(m_date));
+#endif
 
     // first draw the week days
     if ( IsExposed(0, 0, 7*m_widthCol, m_heightRow) )
     {
+#if DEBUG_PAINT
         puts("painting the header");
+#endif
 
         dc.SetTextForeground(*wxBLUE);
         dc.SetBrush(wxBrush(*wxLIGHT_GREY, wxSOLID));
@@ -347,8 +462,10 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& event)
     wxCoord y = m_heightRow;
 
     wxDateTime date = GetStartDate();
+#if DEBUG_PAINT
     printf("starting calendar from %s\n",
             date.Format("%a %d-%m-%Y %H:%M:%S").c_str());
+#endif
 
     dc.SetBackgroundMode(wxSOLID);
     for ( size_t nWeek = 1; nWeek <= 6; nWeek++, y += m_heightRow )
@@ -360,13 +477,16 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& event)
 
             continue;
         }
-        
+
+#if DEBUG_PAINT        
         printf("painting week %d at y = %d\n", nWeek, y);
+#endif
 
         for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) )
         {
             if ( IsDateShown(date) )
             {
+                // don't use wxDate::Format() which prepends 0s
                 wxString day = wxString::Format(_T("%u"), date.GetDay());
                 wxCoord width;
                 dc.GetTextExtent(day, &width, (wxCoord *)NULL);
@@ -391,8 +511,9 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& event)
             date += wxDateSpan::Day();
         }
     }
-
+#if DEBUG_PAINT
     puts("+++ finished painting");
+#endif
 }
 
 void wxCalendarCtrl::RefreshDate(const wxDateTime& date)
@@ -409,10 +530,12 @@ void wxCalendarCtrl::RefreshDate(const wxDateTime& date)
     rect.width = 7*m_widthCol;
     rect.height = m_heightRow;
 
+#if DEBUG_PAINT
     printf("*** refreshing week %d at (%d, %d)-(%d, %d)\n",
            GetWeek(date),
            rect.x, rect.y,
            rect.x + rect.width, rect.y + rect.height);
+#endif
 
     Refresh(TRUE, &rect);
 }
@@ -513,12 +636,12 @@ void wxCalendarCtrl::OnChar(wxKeyEvent& event)
             SetDateAndNotify(m_date - wxDateSpan::Year());
             break;
 
-        case WXK_PAGEDOWN:
-            SetDateAndNotify(m_date + wxDateSpan::Year());
+        case WXK_PRIOR:
+            SetDateAndNotify(m_date - wxDateSpan::Month());
             break;
 
-        case WXK_PAGEUP:
-            SetDateAndNotify(m_date - wxDateSpan::Year());
+        case WXK_NEXT:
+            SetDateAndNotify(m_date + wxDateSpan::Month());
             break;
 
         case WXK_RIGHT:
index 2c5fd437f1e6134154ab92267be4b0883762281b..a6144b1da21cfd3df3ea448ef044b117077bdf09 100644 (file)
@@ -261,7 +261,7 @@ void wxChoice::DoSetSize(int x, int y,
     wxControl::DoSetSize(x, y, width, -1, sizeFlags);
 }
 
-wxSize wxChoice::DoGetBestSize()
+wxSize wxChoice::DoGetBestSize() const
 {
     // find the widest string
     int wLine;
index d4ec3f017a87955daaa47c53d98e9807a99b7dfa..9bab1a0cdb7b03407ffc888376d048d559a78a2c 100644 (file)
@@ -325,11 +325,31 @@ void wxComboBox::SetSelection(long from, long to)
 #endif
 }
 
-void wxComboBox::DoSetSize(int x, int y,
-                           int width, int height,
-                           int sizeFlags)
+void wxComboBox::DoMoveWindow(int x, int y, int width, int height)
 {
-    wxControl::DoSetSize(x, y, width, height, sizeFlags);
+    int cx, cy;
+    wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
+
+    int n = GetCount();
+    if ( !n )
+        n = 10;
+
+    height = n * EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
+
+    wxControl::DoMoveWindow(x, y, width, height);
+}
+
+wxSize wxComboBox::DoGetBestSize() const
+{
+    // the choice calculates the horz size correctly, but not the vertical
+    // component: correct it
+    wxSize size = wxChoice::DoGetBestSize();
+
+    int cx, cy;
+    wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
+    size.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
+
+    return size;
 }
 
 #endif
index 9c3b36bffb3f90220470cf126173e5e3aa303a8f..cbd779d665cd3eb52df51d901d8a237359b2d6c8 100644 (file)
@@ -104,7 +104,8 @@ bool wxSpinButton::Create(wxWindow *parent,
 
     // translate the styles
     DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP |
-                   UDS_SETBUDDYINT; // it doesn't harm if we don't have buddy
+                   UDS_NOTHOUSANDS | // never useful, sometimes harmful
+                   UDS_SETBUDDYINT;  // it doesn't harm if we don't have buddy
 
     if ( m_windowStyle & wxSP_HORIZONTAL )
         wstyle |= UDS_HORZ;
index 1724bf68d837687a197a2d3d9c5c704c8303f5b6..3946d365a9398f6ec0b57a39225a15a5b76e8ae5 100644 (file)
@@ -85,7 +85,8 @@ bool wxSpinCtrl::Create(wxWindow *parent,
     // before using DoGetBestSize(), have to set style to let the base class
     // know whether this is a horizontal or vertical control (we're always
     // vertical)
-    SetWindowStyle(style | wxSP_VERTICAL);
+    style |= wxSP_VERTICAL;
+    SetWindowStyle(style);
 
     // calculate the sizes: the size given is the toal size for both controls
     // and we need to fit them both in the given width (height is the same)
@@ -144,8 +145,10 @@ bool wxSpinCtrl::Create(wxWindow *parent,
     // couldn't call DoGetBestSize() before as font wasn't set
     if ( sizeText.y <= 0 )
     {
-        // make it the same height as the button then
-        sizeText.y = DoGetBestSize().y;
+        int cx, cy;
+        wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
+
+        sizeText.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
     }
 
     DoMoveWindow(pos.x, pos.y,
@@ -170,7 +173,7 @@ bool wxSpinCtrl::Create(wxWindow *parent,
 
 void wxSpinCtrl::SetValue(const wxString& text)
 {
-    if ( ::SetWindowText((HWND)m_hwndBuddy, text.c_str()) )
+    if ( !::SetWindowText((HWND)m_hwndBuddy, text.c_str()) )
     {
         wxLogLastError("SetWindowText(buddy)");
     }
@@ -188,7 +191,7 @@ int wxSpinCtrl::GetValue() const
 }
 
 // ----------------------------------------------------------------------------
-// when setting font, we need to do it for both controls
+// forward some methods to subcontrols
 // ----------------------------------------------------------------------------
 
 bool wxSpinCtrl::SetFont(const wxFont& font)
@@ -205,6 +208,30 @@ bool wxSpinCtrl::SetFont(const wxFont& font)
     return TRUE;
 }
 
+bool wxSpinCtrl::Show(bool show)
+{
+    if ( !wxControl::Show(show) )
+    {
+        return FALSE;
+    }
+
+    ::ShowWindow((HWND)m_hwndBuddy, show ? SW_SHOW : SW_HIDE);
+
+    return TRUE;
+}
+
+bool wxSpinCtrl::Enable(bool enable)
+{
+    if ( !wxControl::Enable(enable) )
+    {
+        return FALSE;
+    }
+
+    ::EnableWindow((HWND)m_hwndBuddy, enable);
+
+    return TRUE;
+}
+
 // ----------------------------------------------------------------------------
 // event processing
 // ----------------------------------------------------------------------------
index eefebd74d7d0dc2a566ca469dc51bfb11e758cc7..e8b06acbe9d65246c909d65a75dab41e87c9d61c 100644 (file)
@@ -1841,6 +1841,11 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
            break;
 
         case WM_LBUTTONDOWN:
+           // set focus to this window
+           SetFocus();
+
+           // fall through
+
         case WM_LBUTTONUP:
         case WM_LBUTTONDBLCLK:
         case WM_RBUTTONDOWN:
@@ -1950,6 +1955,8 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
                 case VK_RETURN:
                 case VK_BACK:
                 case VK_TAB:
+                case VK_ADD:
+                case VK_SUBTRACT:
                     // but set processed to FALSE, not TRUE to still pass them to
                     // the control's default window proc - otherwise built-in
                     // keyboard handling won't work