From 2ef31e80ee0e9c597ffca0fd7a0eb9d018a2f51b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 29 Dec 1999 10:28:20 +0000 Subject: [PATCH] 1. some minor compilation fixes in datetime.cppm 2. implemented wxTreeCtrl::Insert(size_t index) 3. draft of wxCalendarCtrl git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5135 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/datetime.h | 25 ++-- include/wx/generic/calctrl.h | 101 +++++++++++++ include/wx/generic/treectrl.h | 4 +- include/wx/msw/treectrl.h | 7 + src/common/datetime.cpp | 45 +++--- src/generic/calctrl.cpp | 258 ++++++++++++++++++++++++++++++++++ src/msw/treectrl.cpp | 24 ++++ 7 files changed, 429 insertions(+), 35 deletions(-) create mode 100644 include/wx/generic/calctrl.h create mode 100644 src/generic/calctrl.cpp diff --git a/include/wx/datetime.h b/include/wx/datetime.h index a159dc517a..e19d049dd3 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -91,19 +91,21 @@ class WXDLLEXPORT wxDateSpan; the copy of the object with the changed sign. */ +// an invalid/default date time object which may be used as the default +// argument for arguments of type wxDateTime; it is also returned by all +// functions returning wxDateTime on failure (this is why it is also called +// wxInvalidDateTime) +class WXDLLEXPORT wxDateTime; + +WXDLLEXPORT_DATA(extern wxDateTime&) wxDefaultDateTime; +#define wxInvalidDateTime wxDefaultDateTime + // ---------------------------------------------------------------------------- // wxDateTime represents an absolute moment in the time // ---------------------------------------------------------------------------- class WXDLLEXPORT wxDateTime { -private: - // invalid wxDateTime object - returned by all functions which return - // "wxDateTime &" on failure. - // This variable has to be declared at the start of the class, - // or some compilers (e.g. Watcom C++) won't like it being used further down. - static wxDateTime ms_InvDateTime; - public: // types // ------------------------------------------------------------------------ @@ -617,7 +619,7 @@ public: // set to the next week day following this one wxDateTime& SetToNextWeekDay(WeekDay weekday); - // set to the previous week day following this one + // set to the previous week day before this one wxDateTime& SetToPrevWeekDay(WeekDay weekday); // set to Nth occurence of given weekday in the given month of the @@ -722,9 +724,8 @@ public: // result of timezone shift) // ------------------------------------------------------------------------ - // is the date valid (FALSE for uninitialized objects as well as after - // the functions which failed to convert the date to supported range) - inline bool IsValid() const { return this != &ms_InvDateTime; } + // is the date valid (TRUE even for non initialized objects)? + inline bool IsValid() const { return this != &wxInvalidDateTime; } // get the broken down date/time representation in the given timezone // @@ -860,7 +861,7 @@ public: // default to Today() otherwise) const wxChar *ParseFormat(const wxChar *date, const wxChar *format = _T("%c"), - const wxDateTime& dateDef = wxDateTime::ms_InvDateTime); + const wxDateTime& dateDef = wxDefaultDateTime); // parse a string containing the date/time in "free" format, this // function will try to make an educated guess at the string contents const wxChar *ParseDateTime(const wxChar *datetime); diff --git a/include/wx/generic/calctrl.h b/include/wx/generic/calctrl.h new file mode 100644 index 0000000000..c781064441 --- /dev/null +++ b/include/wx/generic/calctrl.h @@ -0,0 +1,101 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: generic/calctrl.h +// Purpose: generic implementation of date-picker control +// Author: Vadim Zeitlin +// Modified by: +// Created: 29.12.99 +// RCS-ID: $Id$ +// Copyright: (c) 1999 Vadim Zeitlin +// Licence: wxWindows license +/////////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma interface "calctrl.h" +#endif + +#ifndef _WX_GENERIC_CALCTRL_H +#define _WX_GENERIC_CALCTRL_H + +#include "wx/control.h" // the base class + +#include "wx/datetime.h" // for m_date +#include "wx/combobox.h" // for m_comboMonth +#include "wx/spinctrl.h" // for m_spinYear + +#define wxCalendarNameStr _T("CalendarCtrl") + +// ---------------------------------------------------------------------------- +// wxCalendarCtrl: a control allowing the user to pick a date interactively +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxCalendarCtrl : public wxControl +{ +public: + // construction + wxCalendarCtrl() { Init(); } + wxCalendarCtrl(wxWindow *parent, + wxWindowID id, + const wxDateTime& date = wxDefaultDateTime, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxCalendarNameStr) + : wxControl(parent, id, pos, size, style, wxDefaultValidator, name) + { + Init(); + + (void)Create(parent, id, date, pos, size, style, name); + } + + bool Create(wxWindow *parent, + wxWindowID id, + const wxDateTime& date = wxDefaultDateTime, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxCalendarNameStr); + + // set/get the current date + void SetDate(const wxDateTime& date); + const wxDateTime& GetDate() const { return m_date; } + + // returns TRUE if the given point is on a day and fills date with its + // value + bool HitTest(const wxPoint& pos, wxDateTime *date); + + // implementation only from now on + // ------------------------------- + + void OnPaint(wxPaintEvent& event); + void OnClick(wxMouseEvent& event); + +private: + // common part of all ctors + void Init(); + + // override some base class virtuals + virtual wxSize DoGetBestSize() 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); + + // get the date from which we start drawing days + wxDateTime GetStartDate() const; + + // is this date shown? + bool IsDateShown(const wxDateTime& date) const; + + // the subcontrols + wxComboBox *m_comboMonth; + wxSpinCtrl *m_spinYear; + + wxDateTime m_date; + + // the width and height of one column/row in the calendar + wxCoord m_widthCol, + m_heightRow; + + DECLARE_DYNAMIC_CLASS(wxCalendarCtrl) + DECLARE_EVENT_TABLE() +}; + +#endif // _WX_GENERIC_CALCTRL_H diff --git a/include/wx/generic/treectrl.h b/include/wx/generic/treectrl.h index 76ca47975b..0b0f137571 100644 --- a/include/wx/generic/treectrl.h +++ b/include/wx/generic/treectrl.h @@ -337,9 +337,9 @@ public: int image = -1, int selectedImage = -1, wxTreeItemData *data = NULL); - // insert a new item before a given one + // insert a new item before the one with the given index wxTreeItemId InsertItem(const wxTreeItemId& parent, - size_t before, + size_t index, const wxString& text, int image = -1, int selectedImage = -1, wxTreeItemData *data = NULL); diff --git a/include/wx/msw/treectrl.h b/include/wx/msw/treectrl.h index 32c41d8554..eef174b0c4 100644 --- a/include/wx/msw/treectrl.h +++ b/include/wx/msw/treectrl.h @@ -319,6 +319,13 @@ public: int image = -1, int selectedImage = -1, wxTreeItemData *data = NULL); + // insert a new item before the one with the given index + wxTreeItemId InsertItem(const wxTreeItemId& parent, + size_t index, + const wxString& text, + int image = -1, int selectedImage = -1, + wxTreeItemData *data = NULL); + // insert a new item in as the last child of the parent wxTreeItemId AppendItem(const wxTreeItemId& parent, const wxString& text, diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 8ca53f3b25..5e6df3b2d1 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -137,13 +137,23 @@ static const wxDateTime::wxDateTime_t gs_cumulatedDays[2][MONTHS_IN_YEAR] = }; // ---------------------------------------------------------------------------- -// globals +// global data +// ---------------------------------------------------------------------------- + +static wxDateTime gs_dtDefault; + +wxDateTime& wxDefaultDateTime = gs_dtDefault; + +wxDateTime::Country wxDateTime::ms_country = wxDateTime::Country_Unknown; + +// ---------------------------------------------------------------------------- +// private globals // ---------------------------------------------------------------------------- // a critical section is needed to protect GetTimeZone() static // variable in MT case #if wxUSE_THREADS - wxCriticalSection gs_critsectTimezone; + static wxCriticalSection gs_critsectTimezone; #endif // wxUSE_THREADS // ---------------------------------------------------------------------------- @@ -364,13 +374,6 @@ static wxString GetAlphaToken(const wxChar*& p) // implementation of wxDateTime // ============================================================================ -// ---------------------------------------------------------------------------- -// static data -// ---------------------------------------------------------------------------- - -wxDateTime::Country wxDateTime::ms_country = wxDateTime::Country_Unknown; -wxDateTime wxDateTime::ms_InvDateTime; - // ---------------------------------------------------------------------------- // struct Tm // ---------------------------------------------------------------------------- @@ -424,7 +427,7 @@ void wxDateTime::Tm::AddMonths(int monDiff) monDiff += MONTHS_IN_YEAR; } - while ( monDiff + mon > MONTHS_IN_YEAR ) + while ( monDiff + mon >= MONTHS_IN_YEAR ) { year++; @@ -817,7 +820,7 @@ wxDateTime wxDateTime::GetBeginDST(int year, Country country) if ( !IsDSTApplicable(year, country) ) { - return ms_InvDateTime; + return wxInvalidDateTime; } wxDateTime dt; @@ -918,7 +921,7 @@ wxDateTime wxDateTime::GetEndDST(int year, Country country) if ( !IsDSTApplicable(year, country) ) { - return ms_InvDateTime; + return wxInvalidDateTime; } wxDateTime dt; @@ -1010,7 +1013,7 @@ wxDateTime& wxDateTime::Set(const struct tm& tm) wxFAIL_MSG( _T("mktime() failed") ); - return ms_InvDateTime; + return wxInvalidDateTime; } else { @@ -1028,14 +1031,14 @@ wxDateTime& wxDateTime::Set(wxDateTime_t hour, // we allow seconds to be 61 to account for the leap seconds, even if we // don't use them really wxCHECK_MSG( hour < 24 && second < 62 && minute < 60 && millisec < 1000, - ms_InvDateTime, + wxInvalidDateTime, _T("Invalid time in wxDateTime::Set()") ); // get the current date from system time_t timet = GetTimeNow(); struct tm *tm = localtime(&timet); - wxCHECK_MSG( tm, ms_InvDateTime, _T("localtime() failed") ); + wxCHECK_MSG( tm, wxInvalidDateTime, _T("localtime() failed") ); // adjust the time tm->tm_hour = hour; @@ -1059,13 +1062,13 @@ wxDateTime& wxDateTime::Set(wxDateTime_t day, wxASSERT_MSG( IsValid(), _T("invalid wxDateTime") ); wxCHECK_MSG( hour < 24 && second < 62 && minute < 60 && millisec < 1000, - ms_InvDateTime, + wxInvalidDateTime, _T("Invalid time in wxDateTime::Set()") ); ReplaceDefaultYearMonthWithCurrent(&year, &month); wxCHECK_MSG( (0 < day) && (day <= GetNumberOfDays(month, year)), - ms_InvDateTime, + wxInvalidDateTime, _T("Invalid date in wxDateTime::Set()") ); // the range of time_t type (inclusive) @@ -1364,7 +1367,7 @@ wxDateTime& wxDateTime::SetToLastMonthDay(Month month, wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday) { - wxCHECK_MSG( weekday != Inv_WeekDay, ms_InvDateTime, _T("invalid weekday") ); + wxCHECK_MSG( weekday != Inv_WeekDay, wxInvalidDateTime, _T("invalid weekday") ); WeekDay wdayThis = GetWeekDay(); if ( weekday == wdayThis ) @@ -1384,7 +1387,7 @@ wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday) wxDateTime& wxDateTime::SetToNextWeekDay(WeekDay weekday) { - wxCHECK_MSG( weekday != Inv_WeekDay, ms_InvDateTime, _T("invalid weekday") ); + wxCHECK_MSG( weekday != Inv_WeekDay, wxInvalidDateTime, _T("invalid weekday") ); int diff; WeekDay wdayThis = GetWeekDay(); @@ -1408,7 +1411,7 @@ wxDateTime& wxDateTime::SetToNextWeekDay(WeekDay weekday) wxDateTime& wxDateTime::SetToPrevWeekDay(WeekDay weekday) { - wxCHECK_MSG( weekday != Inv_WeekDay, ms_InvDateTime, _T("invalid weekday") ); + wxCHECK_MSG( weekday != Inv_WeekDay, wxInvalidDateTime, _T("invalid weekday") ); int diff; WeekDay wdayThis = GetWeekDay(); @@ -1555,7 +1558,7 @@ wxDateTime& wxDateTime::SetToYearDay(wxDateTime::wxDateTime_t yday) { int year = GetYear(); wxCHECK_MSG( (0 < yday) && (yday <= GetNumberOfDays(year)), - ms_InvDateTime, _T("invalid year day") ); + wxInvalidDateTime, _T("invalid year day") ); bool isLeap = IsLeapYear(year); for ( Month mon = Jan; mon < Inv_Month; wxNextMonth(mon) ) diff --git a/src/generic/calctrl.cpp b/src/generic/calctrl.cpp new file mode 100644 index 0000000000..5417b7d49b --- /dev/null +++ b/src/generic/calctrl.cpp @@ -0,0 +1,258 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: generic/calctrl.cpp +// Purpose: implementation fo the generic wxCalendarCtrl +// Author: Vadim Zeitlin +// Modified by: +// Created: 29.12.99 +// RCS-ID: $Id$ +// Copyright: (c) 1999 Vadim Zeitlin +// Licence: wxWindows license +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "calctrl.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#endif //WX_PRECOMP + +#include "wx/generic/calctrl.h" + +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(wxCalendarCtrl, wxControl) + EVT_PAINT(wxCalendarCtrl::OnPaint) + + EVT_LEFT_DOWN(wxCalendarCtrl::OnClick) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl, wxControl) + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxCalendarCtrl +// ---------------------------------------------------------------------------- + +void wxCalendarCtrl::Init() +{ + m_comboMonth = NULL; + m_spinYear = NULL; + + m_widthCol = + m_heightRow = 0; +} + +bool wxCalendarCtrl::Create(wxWindow *parent, + wxWindowID id, + const wxDateTime& date, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + m_date = date.IsValid() ? date : wxDateTime::Today(); + + wxSize sizeReal; + if ( size.x == -1 || size.y == -1 ) + { + sizeReal = DoGetBestSize(); + if ( size.x != -1 ) + sizeReal.x = size.x; + if ( size.y != -1 ) + sizeReal.y = size.y; + } + else + { + sizeReal = size; + } + + SetSize(sizeReal); + + SetBackgroundColour(*wxWHITE); + + return TRUE; +} + +// ---------------------------------------------------------------------------- +// date helpers +// ---------------------------------------------------------------------------- + +wxDateTime wxCalendarCtrl::GetStartDate() const +{ + wxDateTime::Tm tm = m_date.GetTm(); + + wxDateTime date = wxDateTime(1, tm.mon, tm.year); + date.SetToPrevWeekDay(wxDateTime::Sun); + + return date; +} + +bool wxCalendarCtrl::IsDateShown(const wxDateTime& date) const +{ + return date.GetMonth() == m_date.GetMonth(); +} + +// ---------------------------------------------------------------------------- +// size management +// ---------------------------------------------------------------------------- + +wxSize wxCalendarCtrl::DoGetBestSize() const +{ + return wxSize(230, 200); +} + +void wxCalendarCtrl::DoSetSize(int x, int y, + int width, int height, + int sizeFlags) +{ + wxControl::DoSetSize(x, y, width, height, sizeFlags); +} + +void wxCalendarCtrl::DoMoveWindow(int x, int y, int width, int height) +{ + wxControl::DoMoveWindow(x, y, width, height); +} + +// ---------------------------------------------------------------------------- +// drawing +// ---------------------------------------------------------------------------- + +void wxCalendarCtrl::OnPaint(wxPaintEvent& event) +{ + wxPaintDC dc(this); + + wxDateTime::WeekDay wd; + wxString weekdays[7]; + + dc.SetFont(*wxSWISS_FONT); + + // determine the column width (we assume that the weekday names are always + // wider (in any language) than the numbers) + m_widthCol = 0; + for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) ) + { + weekdays[wd] = wxDateTime::GetWeekDayName(wd, wxDateTime::Name_Abbr); + + wxCoord width; + dc.GetTextExtent(weekdays[wd], &width, &m_heightRow); + if ( width > m_widthCol ) + { + m_widthCol = width; + } + } + + // leave some margins + m_widthCol += 2; + m_heightRow += 2; + + // first draw the week days + dc.SetTextForeground(*wxBLUE); + dc.SetBrush(wxBrush(*wxLIGHT_GREY, wxSOLID)); + dc.SetBackgroundMode(wxTRANSPARENT); + dc.SetPen(*wxWHITE_PEN); + dc.DrawRectangle(0, 0, 7*m_widthCol - 1, m_heightRow); + for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) ) + { + dc.DrawText(weekdays[wd], wd*m_widthCol + 1, 0); + } + + // then the calendar itself + dc.SetTextForeground(*wxBLACK); + //dc.SetFont(*wxNORMAL_FONT); + + wxCoord y = m_heightRow; + + wxDateTime date = GetStartDate(); + dc.SetBackgroundMode(wxSOLID); + for ( size_t nWeek = 0; nWeek < 6; nWeek++ ) + { + for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) ) + { + if ( IsDateShown(date) ) + { + wxString day = wxString::Format(_T("%u"), date.GetDay()); + wxCoord width; + dc.GetTextExtent(day, &width, (wxCoord *)NULL); + + bool isSel = m_date == date; + if ( isSel ) + { + dc.SetTextForeground(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHTTEXT)); + dc.SetTextBackground(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT)); + } + + dc.DrawText(day, wd*m_widthCol + (m_widthCol - width) / 2, y); + + if ( isSel ) + { + dc.SetTextForeground(*wxBLACK); + dc.SetTextBackground(m_backgroundColour); + } + } + //else: just don't draw it + + date += wxDateSpan::Day(); + } + + y += m_heightRow; + } +} + +// ---------------------------------------------------------------------------- +// mouse handling +// ---------------------------------------------------------------------------- + +void wxCalendarCtrl::OnClick(wxMouseEvent& event) +{ + wxDateTime date; + if ( !HitTest(event.GetPosition(), &date) ) + { + event.Skip(); + } + else + { + m_date = date; + + Refresh(); + } +} + +bool wxCalendarCtrl::HitTest(const wxPoint& pos, wxDateTime *date) +{ + wxCoord y = pos.y; + if ( y < m_heightRow ) + return FALSE; + + y -= m_heightRow; + int week = y / m_heightRow, + wday = pos.x / m_widthCol; + + if ( week >= 6 || wday >= 7 ) + return FALSE; + + wxCHECK_MSG( date, FALSE, _T("bad pointer in wxCalendarCtrl::HitTest") ); + + *date = GetStartDate(); + *date += wxDateSpan::Days(7*week + wday); + return IsDateShown(*date); +} diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index c2b1403ee8..a470179ed7 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -1052,6 +1052,30 @@ wxTreeItemId wxTreeCtrl::InsertItem(const wxTreeItemId& parent, return DoInsertItem(parent, idPrevious, text, image, selectedImage, data); } +wxTreeItemId wxTreeCtrl::InsertItem(const wxTreeItemId& parent, + size_t index, + const wxString& text, + int image, int selectedImage, + wxTreeItemData *data) +{ + // find the item from index + long cookie; + wxTreeItemId idPrev, idCur = GetFirstChild(parent, cookie); + while ( index != 0 && idCur.IsOk() ) + { + index--; + + idPrev = idCur; + idCur = GetNextChild(parent, cookie); + } + + // assert, not check: if the index is invalid, we will append the item + // to the end + wxASSERT_MSG( index == 0, _T("bad index in wxTreeCtrl::InsertItem") ); + + return DoInsertItem(parent, idPrev, text, image, selectedImage, data); +} + wxTreeItemId wxTreeCtrl::AppendItem(const wxTreeItemId& parent, const wxString& text, int image, int selectedImage, -- 2.45.2