wxCalendarCtrl works under MSW too

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5149 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1999-12-29 23:34:18 +00:00
parent 5d5b3a40f3
commit 882a8f40e2
10 changed files with 254 additions and 60 deletions

View File

@@ -40,7 +40,8 @@ public:
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
long style = 0, long style = 0,
const wxString& name = wxCalendarNameStr) const wxString& name = wxCalendarNameStr)
: wxControl(parent, id, pos, size, style, wxDefaultValidator, name) : wxControl(parent, id, pos, size,
style | wxWANTS_CHARS, wxDefaultValidator, name)
{ {
Init(); Init();
@@ -55,6 +56,8 @@ public:
long style = 0, long style = 0,
const wxString& name = wxCalendarNameStr); const wxString& name = wxCalendarNameStr);
virtual ~wxCalendarCtrl();
// set/get the current date // set/get the current date
void SetDate(const wxDateTime& date); void SetDate(const wxDateTime& date);
const wxDateTime& GetDate() const { return m_date; } const wxDateTime& GetDate() const { return m_date; }
@@ -63,17 +66,12 @@ public:
// value // value
bool HitTest(const wxPoint& pos, wxDateTime *date); bool HitTest(const wxPoint& pos, wxDateTime *date);
private: // implementation only from now on
// common part of all ctors // -------------------------------
void Init();
// override some base class virtuals // forward these functions to all subcontrols
virtual wxSize DoGetBestSize() const; virtual bool Enable(bool enable = TRUE);
virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags); virtual bool Show(bool show = TRUE);
virtual void DoMoveWindow(int x, int y, int width, int height);
// (re)calc m_widthCol and m_heightRow
void RecalcGeometry();
// event handlers // event handlers
void OnPaint(wxPaintEvent& event); void OnPaint(wxPaintEvent& event);
@@ -82,6 +80,20 @@ private:
void OnMonthChange(wxCommandEvent& event); void OnMonthChange(wxCommandEvent& event);
void OnYearChange(wxSpinEvent& 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();
// set the date and send the notification // set the date and send the notification
void SetDateAndNotify(const wxDateTime& date); void SetDateAndNotify(const wxDateTime& date);

View File

@@ -74,7 +74,7 @@ protected:
virtual wxClientData* DoGetItemClientObject( int n ) const; virtual wxClientData* DoGetItemClientObject( int n ) const;
// MSW implementation // MSW implementation
virtual wxSize DoGetBestSize(); virtual wxSize DoGetBestSize() const;
virtual void DoSetSize(int x, int y, virtual void DoSetSize(int x, int y,
int width, int height, int width, int height,
int sizeFlags = wxSIZE_AUTO); int sizeFlags = wxSIZE_AUTO);

View File

@@ -78,9 +78,8 @@ public:
virtual bool MSWCommand(WXUINT param, WXWORD id); virtual bool MSWCommand(WXUINT param, WXWORD id);
protected: protected:
virtual void DoSetSize(int x, int y, virtual void DoMoveWindow(int x, int y, int width, int height);
int width, int height, virtual wxSize DoGetBestSize() const;
int sizeFlags = wxSIZE_AUTO);
}; };
#endif // wxUSE_COMBOBOX #endif // wxUSE_COMBOBOX

View File

@@ -54,11 +54,16 @@ public:
// because the base class already has one returning int!) // because the base class already has one returning int!)
void SetValue(const wxString& text); 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 void SetValue(int val) { wxSpinButton::SetValue(val); }
virtual int GetValue() const; virtual int GetValue() const;
virtual bool SetFont(const wxFont &font); virtual bool SetFont(const wxFont &font);
virtual bool Enable(bool enable = TRUE);
virtual bool Show(bool show = TRUE);
protected: protected:
virtual void DoMoveWindow(int x, int y, int width, int height); virtual void DoMoveWindow(int x, int y, int width, int height);
virtual wxSize DoGetBestSize() const; virtual wxSize DoGetBestSize() const;

View File

@@ -36,6 +36,38 @@
#include "wx/calctrl.h" #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 // wxWin macros
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -46,9 +78,14 @@ BEGIN_EVENT_TABLE(wxCalendarCtrl, wxControl)
EVT_CHAR(wxCalendarCtrl::OnChar) EVT_CHAR(wxCalendarCtrl::OnChar)
EVT_LEFT_DOWN(wxCalendarCtrl::OnClick) EVT_LEFT_DOWN(wxCalendarCtrl::OnClick)
END_EVENT_TABLE()
EVT_COMBOBOX(-1, wxCalendarCtrl::OnMonthChange) BEGIN_EVENT_TABLE(wxMonthComboBox, wxComboBox)
EVT_SPINCTRL(-1, wxCalendarCtrl::OnYearChange) EVT_COMBOBOX(-1, wxMonthComboBox::OnMonthChange)
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(wxYearSpinCtrl, wxSpinCtrl)
EVT_SPINCTRL(-1, wxYearSpinCtrl::OnYearChange)
END_EVENT_TABLE() END_EVENT_TABLE()
IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl, wxControl) IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl, wxControl)
@@ -57,6 +94,40 @@ IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl, wxControl)
// implementation // 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 // wxCalendarCtrl
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -84,32 +155,12 @@ bool wxCalendarCtrl::Create(wxWindow *parent,
long style, long style,
const wxString& name) const wxString& name)
{ {
SetWindowStyle(style | (wxBORDER | wxWANTS_CHARS));
m_date = date.IsValid() ? date : wxDateTime::Today(); m_date = date.IsValid() ? date : wxDateTime::Today();
wxString monthNames[12]; m_comboMonth = new wxMonthComboBox(this);
wxDateTime::Month m; m_spinYear = new wxYearSpinCtrl(this);
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());
// we want to process the events from these controls
m_comboMonth->PushEventHandler(this);
m_spinYear->PushEventHandler(this);
wxSize sizeReal; wxSize sizeReal;
if ( size.x == -1 || size.y == -1 ) if ( size.x == -1 || size.y == -1 )
@@ -133,6 +184,44 @@ bool wxCalendarCtrl::Create(wxWindow *parent,
return TRUE; 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 // changing date
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -270,7 +359,7 @@ void wxCalendarCtrl::DoMoveWindow(int x, int y, int width, int height)
m_comboMonth->Move(x, y); m_comboMonth->Move(x, y);
int xDiff = sizeCombo.x + HORZ_MARGIN; 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(); wxSize sizeSpin = m_spinYear->GetSize();
int yDiff = wxMax(sizeSpin.y, sizeCombo.y) + VERT_MARGIN; 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); 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() void wxCalendarCtrl::RecalcGeometry()
{ {
if ( m_widthCol != 0 ) if ( m_widthCol != 0 )
@@ -320,14 +431,18 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& event)
RecalcGeometry(); RecalcGeometry();
#if DEBUG_PAINT
printf("--- starting to paint, selection: %s, week %u\n", printf("--- starting to paint, selection: %s, week %u\n",
m_date.Format("%a %d-%m-%Y %H:%M:%S").c_str(), m_date.Format("%a %d-%m-%Y %H:%M:%S").c_str(),
GetWeek(m_date)); GetWeek(m_date));
#endif
// first draw the week days // first draw the week days
if ( IsExposed(0, 0, 7*m_widthCol, m_heightRow) ) if ( IsExposed(0, 0, 7*m_widthCol, m_heightRow) )
{ {
#if DEBUG_PAINT
puts("painting the header"); puts("painting the header");
#endif
dc.SetTextForeground(*wxBLUE); dc.SetTextForeground(*wxBLUE);
dc.SetBrush(wxBrush(*wxLIGHT_GREY, wxSOLID)); dc.SetBrush(wxBrush(*wxLIGHT_GREY, wxSOLID));
@@ -347,8 +462,10 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& event)
wxCoord y = m_heightRow; wxCoord y = m_heightRow;
wxDateTime date = GetStartDate(); wxDateTime date = GetStartDate();
#if DEBUG_PAINT
printf("starting calendar from %s\n", printf("starting calendar from %s\n",
date.Format("%a %d-%m-%Y %H:%M:%S").c_str()); date.Format("%a %d-%m-%Y %H:%M:%S").c_str());
#endif
dc.SetBackgroundMode(wxSOLID); dc.SetBackgroundMode(wxSOLID);
for ( size_t nWeek = 1; nWeek <= 6; nWeek++, y += m_heightRow ) for ( size_t nWeek = 1; nWeek <= 6; nWeek++, y += m_heightRow )
@@ -360,13 +477,16 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& event)
continue; continue;
} }
#if DEBUG_PAINT
printf("painting week %d at y = %d\n", nWeek, y); printf("painting week %d at y = %d\n", nWeek, y);
#endif
for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) ) for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) )
{ {
if ( IsDateShown(date) ) if ( IsDateShown(date) )
{ {
// don't use wxDate::Format() which prepends 0s
wxString day = wxString::Format(_T("%u"), date.GetDay()); wxString day = wxString::Format(_T("%u"), date.GetDay());
wxCoord width; wxCoord width;
dc.GetTextExtent(day, &width, (wxCoord *)NULL); dc.GetTextExtent(day, &width, (wxCoord *)NULL);
@@ -391,8 +511,9 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& event)
date += wxDateSpan::Day(); date += wxDateSpan::Day();
} }
} }
#if DEBUG_PAINT
puts("+++ finished painting"); puts("+++ finished painting");
#endif
} }
void wxCalendarCtrl::RefreshDate(const wxDateTime& date) void wxCalendarCtrl::RefreshDate(const wxDateTime& date)
@@ -409,10 +530,12 @@ void wxCalendarCtrl::RefreshDate(const wxDateTime& date)
rect.width = 7*m_widthCol; rect.width = 7*m_widthCol;
rect.height = m_heightRow; rect.height = m_heightRow;
#if DEBUG_PAINT
printf("*** refreshing week %d at (%d, %d)-(%d, %d)\n", printf("*** refreshing week %d at (%d, %d)-(%d, %d)\n",
GetWeek(date), GetWeek(date),
rect.x, rect.y, rect.x, rect.y,
rect.x + rect.width, rect.y + rect.height); rect.x + rect.width, rect.y + rect.height);
#endif
Refresh(TRUE, &rect); Refresh(TRUE, &rect);
} }
@@ -513,12 +636,12 @@ void wxCalendarCtrl::OnChar(wxKeyEvent& event)
SetDateAndNotify(m_date - wxDateSpan::Year()); SetDateAndNotify(m_date - wxDateSpan::Year());
break; break;
case WXK_PAGEDOWN: case WXK_PRIOR:
SetDateAndNotify(m_date + wxDateSpan::Year()); SetDateAndNotify(m_date - wxDateSpan::Month());
break; break;
case WXK_PAGEUP: case WXK_NEXT:
SetDateAndNotify(m_date - wxDateSpan::Year()); SetDateAndNotify(m_date + wxDateSpan::Month());
break; break;
case WXK_RIGHT: case WXK_RIGHT:

View File

@@ -261,7 +261,7 @@ void wxChoice::DoSetSize(int x, int y,
wxControl::DoSetSize(x, y, width, -1, sizeFlags); wxControl::DoSetSize(x, y, width, -1, sizeFlags);
} }
wxSize wxChoice::DoGetBestSize() wxSize wxChoice::DoGetBestSize() const
{ {
// find the widest string // find the widest string
int wLine; int wLine;

View File

@@ -325,11 +325,31 @@ void wxComboBox::SetSelection(long from, long to)
#endif #endif
} }
void wxComboBox::DoSetSize(int x, int y, void wxComboBox::DoMoveWindow(int x, int y, int width, int height)
int width, int height,
int sizeFlags)
{ {
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 #endif

View File

@@ -104,7 +104,8 @@ bool wxSpinButton::Create(wxWindow *parent,
// translate the styles // translate the styles
DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP | 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 ) if ( m_windowStyle & wxSP_HORIZONTAL )
wstyle |= UDS_HORZ; wstyle |= UDS_HORZ;

View File

@@ -85,7 +85,8 @@ bool wxSpinCtrl::Create(wxWindow *parent,
// before using DoGetBestSize(), have to set style to let the base class // before using DoGetBestSize(), have to set style to let the base class
// know whether this is a horizontal or vertical control (we're always // know whether this is a horizontal or vertical control (we're always
// vertical) // vertical)
SetWindowStyle(style | wxSP_VERTICAL); style |= wxSP_VERTICAL;
SetWindowStyle(style);
// calculate the sizes: the size given is the toal size for both controls // 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) // 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 // couldn't call DoGetBestSize() before as font wasn't set
if ( sizeText.y <= 0 ) if ( sizeText.y <= 0 )
{ {
// make it the same height as the button then int cx, cy;
sizeText.y = DoGetBestSize().y; wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
sizeText.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
} }
DoMoveWindow(pos.x, pos.y, DoMoveWindow(pos.x, pos.y,
@@ -170,7 +173,7 @@ bool wxSpinCtrl::Create(wxWindow *parent,
void wxSpinCtrl::SetValue(const wxString& text) 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)"); 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) bool wxSpinCtrl::SetFont(const wxFont& font)
@@ -205,6 +208,30 @@ bool wxSpinCtrl::SetFont(const wxFont& font)
return TRUE; 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 // event processing
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -1841,6 +1841,11 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
break; break;
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
// set focus to this window
SetFocus();
// fall through
case WM_LBUTTONUP: case WM_LBUTTONUP:
case WM_LBUTTONDBLCLK: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONDOWN:
@@ -1950,6 +1955,8 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
case VK_RETURN: case VK_RETURN:
case VK_BACK: case VK_BACK:
case VK_TAB: case VK_TAB:
case VK_ADD:
case VK_SUBTRACT:
// but set processed to FALSE, not TRUE to still pass them to // but set processed to FALSE, not TRUE to still pass them to
// the control's default window proc - otherwise built-in // the control's default window proc - otherwise built-in
// keyboard handling won't work // keyboard handling won't work