From 00826781d4b5f07e130c9ed6d8d1b05eb57cab3a Mon Sep 17 00:00:00 2001 From: Karsten Heimrich Date: Sun, 14 Oct 2007 13:53:53 +0000 Subject: [PATCH] * implemented Time, Date, DateTime classes to be used in CalendarView * implemented new Calendarview, capable to show/hide week numbers and day names weekstart sunday/monday and getting the current selected date etc... * updated mail addresses * make use of the new calendar view in time prefs * changed required classes to use the new date, time classes * gmt/ local time change implementation is missing atm, will come next git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22554 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/preferences/time/AnalogClock.cpp | 2 +- src/preferences/time/AnalogClock.h | 2 +- src/preferences/time/BaseView.cpp | 98 +- src/preferences/time/BaseView.h | 10 +- src/preferences/time/Bitmaps.cpp | 5 +- src/preferences/time/Bitmaps.h | 5 +- src/preferences/time/CalendarView.cpp | 1544 ++++++++++++++++++------- src/preferences/time/CalendarView.h | 213 +++- src/preferences/time/DateTime.cpp | 483 ++++++++ src/preferences/time/DateTime.h | 100 ++ src/preferences/time/DateTimeEdit.cpp | 430 ++++--- src/preferences/time/DateTimeEdit.h | 27 +- src/preferences/time/DateUtils.cpp | 54 - src/preferences/time/DateUtils.h | 20 - src/preferences/time/Jamfile | 2 +- src/preferences/time/SectionEdit.cpp | 46 +- src/preferences/time/SectionEdit.h | 3 +- src/preferences/time/SettingsView.cpp | 184 +-- src/preferences/time/SettingsView.h | 23 +- src/preferences/time/TZDisplay.cpp | 4 +- src/preferences/time/TZDisplay.h | 4 +- src/preferences/time/Time.cpp | 2 +- src/preferences/time/Time.h | 2 +- src/preferences/time/TimeMessages.h | 12 +- src/preferences/time/TimeSettings.cpp | 3 +- src/preferences/time/TimeSettings.h | 2 +- src/preferences/time/TimeWindow.cpp | 17 +- src/preferences/time/TimeWindow.h | 1 + src/preferences/time/ZoneView.cpp | 2 +- src/preferences/time/ZoneView.h | 2 +- 30 files changed, 2339 insertions(+), 963 deletions(-) create mode 100755 src/preferences/time/DateTime.cpp create mode 100755 src/preferences/time/DateTime.h delete mode 100644 src/preferences/time/DateUtils.cpp delete mode 100644 src/preferences/time/DateUtils.h diff --git a/src/preferences/time/AnalogClock.cpp b/src/preferences/time/AnalogClock.cpp index b597f87014..72f8fbcc51 100644 --- a/src/preferences/time/AnalogClock.cpp +++ b/src/preferences/time/AnalogClock.cpp @@ -3,7 +3,7 @@ * Distributed under the terms of the MIT License. * * Authors: - * Mike Berg (inseculous) + * Mike Berg * Julun * Stephan Aßmus */ diff --git a/src/preferences/time/AnalogClock.h b/src/preferences/time/AnalogClock.h index 6cc4169455..bcce2bca72 100644 --- a/src/preferences/time/AnalogClock.h +++ b/src/preferences/time/AnalogClock.h @@ -3,7 +3,7 @@ * Distributed under the terms of the MIT License. * * Authors: - * Mike Berg (inseculous) + * Mike Berg * Julun */ #ifndef ANALOG_CLOCK_H diff --git a/src/preferences/time/BaseView.cpp b/src/preferences/time/BaseView.cpp index abb580a587..0dfcce9368 100644 --- a/src/preferences/time/BaseView.cpp +++ b/src/preferences/time/BaseView.cpp @@ -3,21 +3,20 @@ * Distributed under the terms of the MIT License. * * Authors: - * Mike Berg (inseculous) + * Mike Berg * Julun */ #include "BaseView.h" +#include "DateTime.h" #include "TimeMessages.h" -#include #include TTimeBaseView::TTimeBaseView(BRect frame, const char *name) : BView(frame, name, B_FOLLOW_ALL_SIDES, B_PULSE_NEEDED), - fIsGMT(false), fMessage(H_TIME_UPDATE) { } @@ -32,7 +31,7 @@ void TTimeBaseView::Pulse() { if (IsWatched()) - DispatchMessage(); + _SendNotices(); } @@ -43,13 +42,6 @@ TTimeBaseView::AttachedToWindow() } -void -TTimeBaseView::SetGMTime(bool gmt) -{ - fIsGMT = gmt; -} - - void TTimeBaseView::ChangeTime(BMessage *message) { @@ -57,64 +49,62 @@ TTimeBaseView::ChangeTime(BMessage *message) if (message->FindBool("time", &isTime) != B_OK) return; - time_t tmp = time(NULL); - struct tm *tm_struct = localtime(&tmp); - + BDateTime dateTime = BDateTime::CurrentDateTime(B_LOCAL_TIME); + if (isTime) { - int32 hour = 0; - if (message->FindInt32("hour", &hour) == B_OK) - tm_struct->tm_hour = hour; + BTime time = dateTime.Time(); + int32 hour; + if (message->FindInt32("hour", &hour) != B_OK) + hour = time.Hour(); - int32 minute = 0; - if (message->FindInt32("minute", &minute) == B_OK) - tm_struct->tm_min = minute; + int32 minute; + if (message->FindInt32("minute", &minute) != B_OK) + minute = time.Minute(); - int32 second = 0; - if (message->FindInt32("second", &second) == B_OK) - tm_struct->tm_sec = second; + int32 second; + if (message->FindInt32("second", &second) != B_OK) + second = time.Second(); - bool isAM = false; - if (message->FindBool("isam", &isAM) == B_OK) { - if (!isAM) - tm_struct->tm_hour += 12; - } + time.SetTime(hour, minute, second); + dateTime.SetTime(time); } else { - int32 month = 0; - if (message->FindInt32("month", &month) == B_OK) - tm_struct->tm_mon = month; + BDate date = dateTime.Date(); + int32 day; + if (message->FindInt32("day", &day) != B_OK) + day = date.Day(); - int32 day = 0; - if (message->FindInt32("day", &day) == B_OK) - tm_struct->tm_mday = day; + int32 year; + if (message->FindInt32("year", &year) != B_OK) + year = date.Year(); - int32 year = 0; - if (message->FindInt32("year", &year) == B_OK) - tm_struct->tm_year = year; + int32 month; + if (message->FindInt32("month", &month) != B_OK) + month = date.Month(); + + if (year >= 1970 && year <= 2037) { + date.SetDate(year, month, day); + dateTime.SetDate(date); + } } - - tmp = mktime(tm_struct); - set_real_time_clock(tmp); + + set_real_time_clock(dateTime.Time_t()); } void -TTimeBaseView::DispatchMessage() +TTimeBaseView::_SendNotices() { - time_t tmp = time(NULL); - struct tm *tm_struct = localtime(&tmp); - - if (fIsGMT) - tm_struct = gmtime(&tmp); - fMessage.MakeEmpty(); + + BDate date = BDate::CurrentDate(B_LOCAL_TIME); + fMessage.AddInt32("day", date.Day()); + fMessage.AddInt32("year", date.Year()); + fMessage.AddInt32("month", date.Month()); - fMessage.AddInt32("month", tm_struct->tm_mon); - fMessage.AddInt32("day", tm_struct->tm_mday); - fMessage.AddInt32("year", tm_struct->tm_year); - - fMessage.AddInt32("hour", tm_struct->tm_hour); - fMessage.AddInt32("minute", tm_struct->tm_min); - fMessage.AddInt32("second", tm_struct->tm_sec); + BTime time = BTime::CurrentTime(B_LOCAL_TIME); + fMessage.AddInt32("hour", time.Hour()); + fMessage.AddInt32("minute", time.Minute()); + fMessage.AddInt32("second", time.Second()); SendNotices(H_TM_CHANGED, &fMessage); } diff --git a/src/preferences/time/BaseView.h b/src/preferences/time/BaseView.h index f0bddbcc21..68dba56eb3 100644 --- a/src/preferences/time/BaseView.h +++ b/src/preferences/time/BaseView.h @@ -3,15 +3,15 @@ * Distributed under the terms of the MIT License. * * Authors: - * Mike Berg (inseculous) + * Mike Berg * Julun */ #ifndef TIMEBASE_H #define TIMEBASE_H -#include #include +#include class TTimeBaseView: public BView { @@ -22,14 +22,12 @@ class TTimeBaseView: public BView { virtual void Pulse(); virtual void AttachedToWindow(); - void SetGMTime(bool gmtTime); void ChangeTime(BMessage *message); - protected: - virtual void DispatchMessage(); + private: + void _SendNotices(); private: - bool fIsGMT; BMessage fMessage; }; diff --git a/src/preferences/time/Bitmaps.cpp b/src/preferences/time/Bitmaps.cpp index a7e35b33fe..55b8b28b53 100644 --- a/src/preferences/time/Bitmaps.cpp +++ b/src/preferences/time/Bitmaps.cpp @@ -3,9 +3,10 @@ * Distributed under the terms of the MIT License. * * Authors: - * probably Mike Berg - * and/or Andrew McCall + * Andrew McCall + * Mike Berg * Julun + * */ #include "Bitmaps.h" diff --git a/src/preferences/time/Bitmaps.h b/src/preferences/time/Bitmaps.h index c9073339e3..f4dd1e6349 100644 --- a/src/preferences/time/Bitmaps.h +++ b/src/preferences/time/Bitmaps.h @@ -3,9 +3,10 @@ * Distributed under the terms of the MIT License. * * Authors: - * probably Mike Berg - * and/or Andrew McCall + * Andrew McCall + * Mike Berg * Julun + * */ #ifndef ANALOG_CLOCK_H #define ANALOG_CLOCK_H diff --git a/src/preferences/time/CalendarView.cpp b/src/preferences/time/CalendarView.cpp index 3d4d37bae6..bfae23f9f2 100644 --- a/src/preferences/time/CalendarView.cpp +++ b/src/preferences/time/CalendarView.cpp @@ -1,466 +1,1234 @@ /* - * Copyright 2004-2007, Haiku. + * Copyright 2007, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: - * Michael Berg + * Julun */ -#include +#include "CalendarView.h" + + #include -#include "CalendarView.h" -#include "DateUtils.h" -#include "TimeMessages.h" -#include +#include -#define SEGMENT_CHANGE 'ostd' +namespace { + float + FontHeight(const BView *view) + { + if (!view) + return 0.0; - -// ToDo: read these out of the locale -static const char kDays[7] = { 'S', 'M', 'T', 'W', 'T', 'F', 'S' }; - - -static float -FontHeight(BView* target, bool full) -{ - font_height finfo; - target->GetFontHeight(&finfo); - float h = ceil(finfo.ascent) + ceil(finfo.descent); - - if (full) - h += ceil(finfo.leading); - - return h; + BFont font; + view->GetFont(&font); + font_height fheight; + font.GetHeight(&fheight); + return ceilf(fheight.ascent + fheight.descent + fheight.leading); + } } -// #pragma mark - - - -TDay::TDay(BRect frame, int day) - : BControl(frame, B_EMPTY_STRING, NULL, NULL, B_FOLLOW_NONE, B_WILL_DRAW) - , f_day(day) +BCalendarView::BCalendarView(BRect frame, const char *name, + uint32 resizeMask, uint32 flags) + : BView(frame, name, resizeMask, flags), + BInvoker(), + fSelectionMessage(NULL), + fDay(0), + fYear(0), + fMonth(0), + fFocusChanged(false), + fSelectionChanged(false), + fWeekStart(B_WEEK_START_SUNDAY), + fDayNameHeaderVisible(true), + fWeekNumberHeaderVisible(true) { + _InitObject(); } -TDay::~TDay() +BCalendarView::BCalendarView(BRect frame, const char *name, week_start start, + uint32 resizeMask, uint32 flags) + : BView(frame, name, resizeMask, flags), + BInvoker(), + fSelectionMessage(NULL), + fDay(0), + fYear(0), + fMonth(0), + fFocusChanged(false), + fSelectionChanged(false), + fWeekStart(start), + fDayNameHeaderVisible(true), + fWeekNumberHeaderVisible(true) { + _InitObject(); +} + + +BCalendarView::~BCalendarView() +{ + SetSelectionMessage(NULL); +} + + +BCalendarView::BCalendarView(BMessage *archive) + : BView(archive), + BInvoker(), + fSelectionMessage(NULL), + fDay(0), + fYear(0), + fMonth(0), + fFocusChanged(false), + fSelectionChanged(false), + fWeekStart(B_WEEK_START_SUNDAY), + fDayNameHeaderVisible(true), + fWeekNumberHeaderVisible(true) +{ + if (archive->HasMessage("_invokeMsg")) { + BMessage *invokationMessage = new BMessage; + archive->FindMessage("_invokeMsg", invokationMessage); + SetInvocationMessage(invokationMessage); + } + + if (archive->HasMessage("_selectMsg")) { + BMessage *selectionMessage = new BMessage; + archive->FindMessage("selectMsg", selectionMessage); + SetSelectionMessage(selectionMessage); + } + + if (archive->FindInt32("_day", &fDay) != B_OK + || archive->FindInt32("_month", &fMonth) != B_OK + || archive->FindInt32("_year", &fYear) != B_OK) { + BDate date = BDate::CurrentDate(B_LOCAL_TIME); + fDay = date.Day(); + fMonth = date.Month(); + fYear = date.Year(); + } + + int32 start; + if (archive->FindInt32("_weekStart", &start) == B_OK) + fWeekStart = week_start(start); + + if (archive->FindBool("_dayHeader", &fDayNameHeaderVisible) != B_OK) + fDayNameHeaderVisible = true; + + if (archive->FindBool("_weekHeader", &fWeekNumberHeaderVisible) != B_OK) + fWeekNumberHeaderVisible = true; + + _SetupDayNames(); + _SetupDayNumbers(); + _SetupWeekNumbers(); +} + + +BArchivable* +BCalendarView::Instantiate(BMessage *archive) +{ + if (validate_instantiation(archive, "BCalendarView")) + return new BCalendarView(archive); + + return NULL; +} + + +status_t +BCalendarView::Archive(BMessage *archive, bool deep) const +{ + status_t status = BView::Archive(archive, deep); + + if (status == B_OK && InvocationMessage()) + status = archive->AddMessage("_invokeMsg", InvocationMessage()); + + if (status == B_OK && SelectionMessage()) + status = archive->AddMessage("_selectMsg", SelectionMessage()); + + if (status == B_OK) + status = archive->AddInt32("_day", fDay); + + if (status == B_OK) + status = archive->AddInt32("_month", fMonth); + + if (status == B_OK) + status = archive->AddInt32("_year", fYear); + + if (status == B_OK) + status = archive->AddInt32("_weekStart", int32(fWeekStart)); + + if (status == B_OK) + status = archive->AddBool("_dayHeader", fDayNameHeaderVisible); + + if (status == B_OK) + status = archive->AddBool("_weekHeader", fWeekNumberHeaderVisible); + + return status; } void -TDay::AttachedToWindow() +BCalendarView::AttachedToWindow() { - if (Parent()) - SetViewColor(Parent()->ViewColor()); + BView::AttachedToWindow(); + + if (!Messenger().IsValid()) + SetTarget(Window(), NULL); } void -TDay::MouseDown(BPoint where) +BCalendarView::DetachedFromWindow() { - if (f_day> 0) { - // only allow if not currently selected - if (Value() == B_CONTROL_ON) + BView::DetachedFromWindow(); +} + + +void +BCalendarView::AllAttached() +{ + BView::AllAttached(); +} + + +void +BCalendarView::AllDetached() +{ + BView::AllDetached(); +} + + +void +BCalendarView::FrameMoved(BPoint newPosition) +{ + BView::FrameMoved(newPosition); +} + + +void +BCalendarView::FrameResized(float width, float height) +{ + Invalidate(Bounds()); +} + + +void +BCalendarView::Draw(BRect updateRect) +{ + if (LockLooper()) { + if (fFocusChanged) { + _DrawFocusRect(); + UnlockLooper(); return; - - SetValue(B_CONTROL_ON); - Invoke(); - - //update display - Draw(Bounds()); - } -} - - -void -TDay::KeyDown(const char *bytes, int32 numbytes) -{ - BControl::KeyDown(bytes, numbytes); - Parent()->KeyDown(bytes, numbytes); -} - - -void -TDay::MakeFocus(bool focused) -{ - if (focused != IsFocus()) { - BView::MakeFocus(focused); - Draw(Bounds()); - Flush(); - } -} - - -void -TDay::Stroke3dFrame(BRect frame, rgb_color light, rgb_color dark, bool inset) -{ - rgb_color color1; - rgb_color color2; - - if (inset) { - color1 = dark; - color2 = light; - } else { - color1 = light; - color2 = dark; - } - - BeginLineArray(4); - AddLine(frame.LeftTop(), frame.RightTop(), color1); - AddLine(frame.LeftTop(), frame.LeftBottom(), color1); - AddLine(frame.LeftBottom(), frame.RightBottom(), color2); - AddLine(frame.RightBottom(), frame.RightTop(), color2); - EndLineArray(); -} - - -void -TDay::Draw(BRect updaterect) -{ - BRect bounds(Bounds()); - - SetHighColor(ViewColor()); - FillRect(Bounds(), B_SOLID_HIGH); - - rgb_color bgcolor; - rgb_color dark; - rgb_color light; - - BString text; - - if (Value() == 1) { - bgcolor = tint_color(ViewColor(), B_DARKEN_2_TINT); - } else { - bgcolor = tint_color(ViewColor(), B_DARKEN_1_TINT); - } - text << f_day; - - dark = tint_color(bgcolor, B_DARKEN_1_TINT); - light = tint_color(bgcolor, B_LIGHTEN_MAX_TINT); - - SetHighColor(bgcolor); - FillRect(bounds); - - if (f_day > 0) { - if (!(Value() == 1)) - SetHighColor(0, 0, 0, 255); - else - SetHighColor(255, 255, 255, 255); - - SetLowColor(bgcolor); - - // calc font size; - float width = be_plain_font->StringWidth(text.String()); - font_height finfo; - be_plain_font->GetHeight(&finfo); - float height = finfo.descent +finfo.ascent +finfo.leading; - - BPoint drawpt((bounds.Width()/2.0) -(width/2.0) +1, (bounds.Height()/2.0) +(height/2.0) -2); - DrawString(text.String(), drawpt); - } - - if (IsFocus()) { - rgb_color nav_color = keyboard_navigation_color(); - SetHighColor(nav_color); - StrokeRect(bounds); - - } else { - SetHighColor(bgcolor); - StrokeRect(bounds); - if (Value() == 1) - Stroke3dFrame(bounds, light, dark, true); - } -} - - -void -TDay::SetValue(int32 value) -{ - BControl::SetValue(value); - - if (Value() == 1) { - SetFlags(Flags() & ~B_NAVIGABLE); - } else { - SetFlags(Flags()|B_NAVIGABLE); - } - Draw(Bounds()); -} - - -void -TDay::SetTo(BRect frame, int day) -{ - MoveTo(frame.LeftTop()); - f_day = day; - Draw(Bounds()); -} - - -void -TDay::SetTo(int day, bool selected) -{ - f_day = day; - SetValue(selected); - if (Value() == 1) { - SetFlags(Flags() | B_NAVIGABLE); - } else { - SetFlags(Flags() & ~B_NAVIGABLE); - } - Draw(Bounds()); -} - - -// #pragma mark - - - -TCalendarView::TCalendarView(BRect frame, const char *name, - uint32 resizingmode, uint32 flags) - : BView(frame, name, resizingmode, flags) - , f_firstday(0) - , f_month(0) - , f_day(0) - , f_year(0) -{ - InitView(); -} - - -TCalendarView::~TCalendarView() -{ -} - - -void -TCalendarView::AttachedToWindow() -{ - if (Parent()) - SetViewColor(Parent()->ViewColor()); -} - - -void -TCalendarView::MessageReceived(BMessage *message) -{ - switch(message->what) { - case H_DAY_CHANGED: - { - TDay *day; - message->FindPointer("source", (void **)&day); - if (f_cday != NULL) - f_cday->SetValue(B_CONTROL_OFF); - f_cday = day; - - DispatchMessage(); } - break; - + + if (fSelectionChanged) { + _UpdateSelection(); + UnlockLooper(); + return; + + } + + _DrawDays(); + _DrawDayHeader(); + _DrawWeekHeader(); + + rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR); + SetHighColor(tint_color(background, B_DARKEN_3_TINT)); + StrokeRect(Bounds()); + + UnlockLooper(); + } +} + + +void +BCalendarView::DrawDay(BView *owner, BRect frame, const char *text, + bool isSelected, bool isEnabled, bool focus) +{ + _DrawItem(owner, frame, text, isSelected, isEnabled, focus); +} + + +void +BCalendarView::DrawDayName(BView *owner, BRect frame, const char *text) +{ + // we get the full rect, fake this as the internal function + // shrinks the frame to work properly when drawing a day item + _DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true); +} + + +void +BCalendarView::DrawWeekNumber(BView *owner, BRect frame, const char *text) +{ + // we get the full rect, fake this as the internal function + // shrinks the frame to work properly when drawing a day item + _DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true); +} + + +void +BCalendarView::MessageReceived(BMessage *message) +{ + BView::MessageReceived(message); +} + + +uint32 +BCalendarView::SelectionCommand() const +{ + if (SelectionMessage()) + return SelectionMessage()->what; + + return 0; +} + + +BMessage* +BCalendarView::SelectionMessage() const +{ + return fSelectionMessage; +} + + +void +BCalendarView::SetSelectionMessage(BMessage *message) +{ + delete fSelectionMessage; + fSelectionMessage = message; +} + + +uint32 +BCalendarView::InvocationCommand() const +{ + return BInvoker::Command(); +} + + +BMessage* +BCalendarView::InvocationMessage() const +{ + return BInvoker::Message(); +} + + +void +BCalendarView::SetInvocationMessage(BMessage *message) +{ + BInvoker::SetMessage(message); +} + + +void +BCalendarView::WindowActivated(bool state) +{ + BView::WindowActivated(state); +} + + +void +BCalendarView::MakeFocus(bool state) +{ + if (IsFocus() == state) + return; + + BView::MakeFocus(state); + + fFocusChanged = true; + Draw(_RectOfDay(fFocusedDay)); + fFocusChanged = false; +} + + +status_t +BCalendarView::Invoke(BMessage *message) +{ + bool notify = false; + uint32 kind = InvokeKind(¬ify); + + BMessage clone(kind); + status_t status = B_BAD_VALUE; + + if (!message && !notify) + message = Message(); + + if (!message) { + if (!IsWatched()) + return status; + } else + clone = *message; + + clone.AddPointer("source", this); + clone.AddInt64("when", (int64)system_time()); + clone.AddMessenger("be:sender", BMessenger(this)); + + int32 year; + int32 month; + _GetYearMonth(&year, &month); + + clone.AddInt32("year", year); + clone.AddInt32("month", month); + clone.AddInt32("day", fDay); + + if (message) + status = BInvoker::Invoke(&clone); + + SendNotices(kind, &clone); + + return status; +} + + +void +BCalendarView::MouseUp(BPoint point) +{ + BView::MouseUp(point); +} + + +void +BCalendarView::MouseDown(BPoint where) +{ + if (!IsFocus()) { + MakeFocus(); + Sync(); + Window()->UpdateIfNeeded(); + } + + BRect frame = Bounds(); + if (fDayNameHeaderVisible) + frame.top += frame.Height() / 7 - 1.0; + + if (fWeekNumberHeaderVisible) + frame.left += frame.Width() / 8 - 1.0; + + if (!frame.Contains(where)) + return; + + // try to set to new day + frame = _SetNewSelectedDay(where); + + // on success + if (fSelectedDay != fNewSelectedDay) { + // update focus + fFocusChanged = true; + fNewFocusedDay = fNewSelectedDay; + Draw(_RectOfDay(fFocusedDay)); + fFocusChanged = false; + + // update selection + fSelectionChanged = true; + Draw(frame); + Draw(_RectOfDay(fSelectedDay)); + fSelectionChanged = false; + + // notify that selection changed + InvokeNotify(SelectionMessage(), B_CONTROL_MODIFIED); + } + + int32 clicks; + // on double click invoke + BMessage *message = Looper()->CurrentMessage(); + if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1) + Invoke(); +} + + +void +BCalendarView::MouseMoved(BPoint point, uint32 code, const BMessage *dragMessage) +{ + BView::MouseMoved(point, code, dragMessage); +} + + +void +BCalendarView::KeyDown(const char *bytes, int32 numBytes) +{ + const int32 kRows = 6; + const int32 kColumns = 7; + + int32 row = fFocusedDay.row; + int32 column = fFocusedDay.column; + + switch (bytes[0]) { + case B_LEFT_ARROW: + { + column -= 1; + if (column < 0) { + column = kColumns -1; + row -= 1; + if (row >= 0) + fFocusChanged = true; + } else + fFocusChanged = true; + } break; + + case B_RIGHT_ARROW: + { + column += 1; + if (column == kColumns) { + column = 0; + row += 1; + if (row < kRows) + fFocusChanged = true; + } else + fFocusChanged = true; + } break; + + case B_UP_ARROW: + { + row -= 1; + if (row >= 0) + fFocusChanged = true; + } break; + + case B_DOWN_ARROW: + { + row += 1; + if (row < kRows) + fFocusChanged = true; + } break; + + case B_RETURN: + case B_SPACE: { + fSelectionChanged = true; + BPoint pt = _RectOfDay(fFocusedDay).LeftTop(); + Draw(_SetNewSelectedDay(pt + BPoint(4.0, 4.0))); + Draw(_RectOfDay(fSelectedDay)); + fSelectionChanged = false; + + Invoke(); + } break; + default: - BView::MessageReceived(message); + BView::KeyDown(bytes, numBytes); break; } + + if (fFocusChanged) { + fNewFocusedDay.SetTo(row, column); + Draw(_RectOfDay(fFocusedDay)); + Draw(_RectOfDay(fNewFocusedDay)); + fFocusChanged = false; + } +} + + +BHandler* +BCalendarView::ResolveSpecifier(BMessage *message, int32 index, + BMessage *specifier, int32 form, const char *property) +{ + return BView::ResolveSpecifier(message, index, specifier, form, property); +} + + +status_t +BCalendarView::GetSupportedSuites(BMessage *data) +{ + return BView::GetSupportedSuites(data); +} + + +status_t +BCalendarView::Perform(perform_code code, void *arg) +{ + return BView::Perform(code, arg); } void -TCalendarView::KeyDown(const char *bytes, int32 numbytes) +BCalendarView::ResizeToPreferred() { - if (f_focused == NULL) - f_focused = f_cday; - - switch(bytes[0]) { - case B_LEFT_ARROW: { - TDay *newfocus = dynamic_cast(f_focused->PreviousSibling()); - if (newfocus == NULL || newfocus->Day() == 0) - break; - f_focused->MakeFocus(false); - f_focused = newfocus; - f_focused->MakeFocus(true); - } - break; - - case B_RIGHT_ARROW: { - TDay *newfocus = dynamic_cast(f_focused->NextSibling()); - if (newfocus == NULL || newfocus->Day() == 0) - break; - f_focused->MakeFocus(false); - f_focused = newfocus; - f_focused->MakeFocus(true); - } - break; - - case B_UP_ARROW: { - int32 idx = IndexOf(f_focused) -7; - if (idx> f_daybound.x -1 ) { - f_focused->MakeFocus(false); - f_focused = dynamic_cast(ChildAt(idx)); - f_focused->MakeFocus(true); - } - } - break; - - case B_DOWN_ARROW: { - int32 idx = IndexOf(f_focused) +7; - if (idx < f_daybound.y +1) { - f_focused->MakeFocus(false); - f_focused = dynamic_cast(ChildAt(idx)); - f_focused->MakeFocus(true); - } - } - break; - - default: - break; - } + float width; + float height; + + GetPreferredSize(&width, &height); + BView::ResizeTo(width, height); +} + + +void +BCalendarView::GetPreferredSize(float *width, float *height) +{ + _GetPreferredSize(width, height); } int32 -TCalendarView::IndexOf(BView *child) const +BCalendarView::Day() const { - BView *test; - for (int32 index = 0; index < CountChildren(); index++) { - test = ChildAt(index); - if (test == child) - return index; + return fDay; +} + + +int32 +BCalendarView::Year() const +{ + int32 year; + int32 month; + _GetYearMonth(&year, &month); + + return year; +} + + +int32 +BCalendarView::Month() const +{ + int32 year; + int32 month; + _GetYearMonth(&year, &month); + + return month; +} + + +BDate +BCalendarView::Date() const +{ + int32 year; + int32 month; + _GetYearMonth(&year, &month); + return BDate(year, month, fDay); +} + + +bool +BCalendarView::SetDate(const BDate &date) +{ + return SetDate(date.Year(), date.Month(), date.Day()); +} + + +bool +BCalendarView::SetDate(int32 year, int32 month, int32 day) +{ + if (!BDate(year, month, day).IsValid()) + return false; + + if (fYear == year && fMonth == month && fDay == day) + return true; + + fDay = day; + if (fYear == year && fMonth == month) { + _SetToDay(); + // update focus + fFocusChanged = true; + Draw(_RectOfDay(fFocusedDay)); + fFocusChanged = false; + + // update selection + fSelectionChanged = true; + Draw(_RectOfDay(fSelectedDay)); + Draw(_RectOfDay(fNewSelectedDay)); + fSelectionChanged = false; + } else { + fYear = year; + fMonth = month; + + _SetupDayNumbers(); + _SetupWeekNumbers(); + + BRect frame = Bounds(); + if (fDayNameHeaderVisible) + frame.top += frame.Height() / 7 - 1.0; + + if (fWeekNumberHeaderVisible) + frame.left += frame.Width() / 8 - 1.0; + + Invalidate(frame.InsetBySelf(4.0, 4.0)); } - return -1; + return true; +} + + +week_start +BCalendarView::WeekStart() const +{ + return fWeekStart; } void -TCalendarView::Draw(BRect updaterect) -{ - BRect bounds(0.0, 0.0, f_dayrect.Width(), f_dayrect.Height()); +BCalendarView::SetWeekStart(week_start start) +{ + if (fWeekStart == start) + return; - SetLowColor(ViewColor()); - SetHighColor(0, 0, 0); - - BPoint drawpt; - drawpt.y = (bounds.top + bounds.bottom + FontHeight(this, true)) / 2.0; - - float width = 0; - float x = bounds.Width() / 2.0; - BString day; - for (int i = 0; i < 7; i++) { - day = BString(&kDays[i], 1); - width = be_plain_font->StringWidth(day.String()); - drawpt.x = bounds.left + (x - width / 2.0 + 2); - DrawString(day.String(), drawpt); - bounds.OffsetBy(bounds.Width() + 1, 0); - } + fWeekStart = start; + + _SetupDayNames(); + _SetupDayNumbers(); + _SetupWeekNumbers(); + + Invalidate(Bounds().InsetBySelf(1.0, 1.0)); +} + + +bool +BCalendarView::IsDayNameHeaderVisible() const +{ + return fDayNameHeaderVisible; } void -TCalendarView::InitView() +BCalendarView::SetDayNameHeaderVisible(bool visible) { - font_height finfo; - be_plain_font->GetHeight(&finfo); - float text_height = finfo.ascent +finfo.descent +finfo.leading; - - BRect bounds(Bounds()); - float width = (bounds.Width() -7)/7; - float height = ((bounds.Height() -(text_height +4)) -6)/6; - f_dayrect.Set(0.0, text_height +6, width, text_height +6 +height); + if (fDayNameHeaderVisible == visible) + return; - BRect dayrect(f_dayrect); - TDay *day; - for (int row = 0; row < 6; row++) { - for (int col = 0; col < 7; col++) { - day = new TDay(dayrect.InsetByCopy(1, 1), 0); - AddChild(day); - dayrect.OffsetBy(width +1, 0); - } - dayrect.OffsetBy(0, height +1); - dayrect.OffsetTo(0, dayrect.top); - } - - f_cday = NULL; + fDayNameHeaderVisible = visible; + Invalidate(Bounds().InsetBySelf(1.0, 1.0)); } -void -TCalendarView::InitDates() -{ - TDay *day; - - int32 label = 0; - int idx = 0; - f_firstday = getFirstDay(f_month, f_year); - int daycnt = getDaysInMonth(f_month, f_year); - bool cday = false; - for (int row = 0; row < 6; row++) { - for (int col = 0; col < 7; col++) { - day = dynamic_cast(ChildAt((row *7) +col)); - - if (idx < f_firstday || idx > daycnt + f_firstday - 1) - label = 0; - else - label = idx - (f_firstday - 1); - - idx++; - cday = label == f_day; - day->SetTo(label, cday); - if (label> 0) { - BMessage *message = new BMessage(H_DAY_CHANGED); - message->AddInt32("Day", label); - - day->SetTarget(this); - day->SetMessage(message); - if (label == 1) - f_daybound.x = row *7 +col; - if (label == daycnt) - f_daybound.y = row *7 +col; +bool +BCalendarView::IsWeekNumberHeaderVisible() const +{ + return fWeekNumberHeaderVisible; +} + + +void +BCalendarView::SetWeekNumberHeaderVisible(bool visible) +{ + if (fWeekNumberHeaderVisible == visible) + return; + + fWeekNumberHeaderVisible = visible; + Invalidate(Bounds().InsetBySelf(1.0, 1.0)); +} + + +void +BCalendarView::_InitObject() +{ + BDate date = BDate::CurrentDate(B_LOCAL_TIME); + fDay = date.Day(); + fYear = date.Year(); + fMonth = date.Month(); + + _SetupDayNames(); + _SetupDayNumbers(); + _SetupWeekNumbers(); +} + + +void +BCalendarView::_SetToDay() +{ + BDate date(fYear, fMonth, 1); + if (!date.IsValid()) + return; + + fNewFocusedDay.SetTo(0, 0); + fNewSelectedDay.SetTo(0, 0); + + const int32 dayCountCurrent = date.DaysInMonth(); + + int32 firstDay = date.DayOfWeek(); + if (fWeekStart == B_WEEK_START_MONDAY) + firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1; + + int32 counter = 0; + for (int32 row = 0; row < 6; ++row) { + for (int32 column = 0; column < 7; ++column) { + int32 day = counter - (firstDay - 1); + if (counter >= firstDay && counter <= dayCountCurrent + firstDay - 1) { + if (day == fDay) { + fNewFocusedDay.SetTo(row, column); + fNewSelectedDay.SetTo(row, column); + return; + } } - - if (cday) { - f_cday = day; - } - cday = false; + counter++; } } - if (f_focused == NULL) - f_focused = f_cday; } void -TCalendarView::SetTo(int32 year, int32 month, int32 day) +BCalendarView::_GetYearMonth(int32 *year, int32 *month) const { - if (f_month != month||f_year != year) { - f_month = month; - f_day = day; - f_year = year; - InitDates(); - } else if (f_day != day) { - f_day = day; - int idx = ((f_day/7)*7) + (f_day%7 +f_firstday - 1); - TDay *day = dynamic_cast(ChildAt(idx)); - f_cday->SetValue(B_CONTROL_OFF); - f_cday = day; - day->SetValue(B_CONTROL_ON); + BDate date(fYear, fMonth, 1); + + const int32 dayCountCurrent = date.DaysInMonth(); + + int32 firstDay = date.DayOfWeek(); + if (fWeekStart == B_WEEK_START_MONDAY) + firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1; + + // set the date to one month before + if (date.Month() == 1) + date.SetDate(date.Year() -1, 12, fDay); + else + date.SetDate(date.Year(), date.Month() - 1, fDay); + + const int32 currRow = fSelectedDay.row; + const int32 currColumn = fSelectedDay.column; + + *year = fYear; + *month = fMonth; + + int32 counter = 0; + for (int32 row = 0; row < 6; ++row) { + for (int32 column = 0; column < 7; ++column) { + if (counter < firstDay || counter > dayCountCurrent + firstDay - 1) { + if (counter - firstDay < 0) { + if (row == currRow && column == currColumn) { + *year = date.Year(); + *month = date.Month(); + break; + } + } else { + if (row == currRow && column == currColumn) { + *year = fYear; + *month = fMonth +1; + if (fMonth == 12) { + *year = fYear +1; + *month = 1; + } + break; + } + } + } else { + if (row == currRow && column == currColumn) + break; + } + counter++; + } } } void -TCalendarView::DispatchMessage() +BCalendarView::_GetPreferredSize(float *_width, float *_height) { - // send message to update timedate - BMessage msg(H_USER_CHANGE); - msg.AddBool("time", false); - msg.AddInt32("month", f_month); - msg.AddInt32("year", f_year); + BFont font; + GetFont(&font); + font_height fontHeight; + font.GetHeight(&fontHeight); - if (f_cday != NULL) - msg.AddInt32("day", f_cday->Day()); - - Window()->PostMessage(&msg); + const float height = FontHeight(this) + 4.0; + + int32 rows = 7; + if (!fDayNameHeaderVisible) + rows = 6; + + // height = font height * rows + 8 px border + *_height = height * rows + 8.0; + + float width = 0.0; + for (int32 column = 0; column < 7; ++column) { + float tmp = StringWidth(fDayNames[column].String()) + 2.0; + width = tmp > width ? tmp : width; + } + + int32 columns = 8; + if (!fWeekNumberHeaderVisible) + columns = 7; + + // width = max width day name * 8 column + 8 px border + *_width = width * columns + 8.0; } + +void +BCalendarView::_SetupDayNames() +{ + const BDate date(fYear, fMonth, fDay); + if (!date.IsValid()) + return; + + if (fWeekStart == B_WEEK_START_MONDAY) { + for (int32 i = 1; i <= 7; ++i) { + fDayNames[i -1] = date.ShortDayName(i); + } + } else { + fDayNames[0] = date.ShortDayName(7); + for (int32 i = 1; i < 7; ++i) { + fDayNames[i] = date.ShortDayName(i); + } + } +} + + +void +BCalendarView::_SetupDayNumbers() +{ + BDate date(fYear, fMonth, 1); + if (!date.IsValid()) + return; + + fFocusedDay.SetTo(0, 0); + fSelectedDay.SetTo(0, 0); + fNewFocusedDay.SetTo(0, 0); + + const int32 dayCountCurrent = date.DaysInMonth(); + + int32 firstDay = date.DayOfWeek(); + if (fWeekStart == B_WEEK_START_MONDAY) + firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1; + + // calc the last day one month before + if (date.Month() == 1) + date.SetDate(date.Year() -1, 12, fDay); + else + date.SetDate(date.Year(), date.Month() - 1, fDay); + const int32 lastDayBefore = date.DaysInMonth(); + + int32 counter = 0; + int32 firstDayAfter = 1; + for (int32 row = 0; row < 6; ++row) { + for (int32 column = 0; column < 7; ++column) { + int32 day = counter - (firstDay - 1); + if (counter < firstDay || counter > dayCountCurrent + firstDay - 1) { + if (counter - firstDay < 0) + day += lastDayBefore; + else + day = firstDayAfter++; + } else { + if (day == fDay) { + fFocusedDay.SetTo(row, column); + fSelectedDay.SetTo(row, column); + fNewFocusedDay.SetTo(row, column); + } + } + counter++; + fDayNumbers[row][column].SetTo(""); + fDayNumbers[row][column] << day; + } + } +} + + +void +BCalendarView::_SetupWeekNumbers() +{ + BDate date(fYear, fMonth, fDay); + if (!date.IsValid()) + return; + + date.SetDate(fYear, fMonth, 1); + int32 firstDay = date.DayOfWeek(); + if (fWeekStart == B_WEEK_START_MONDAY) + firstDay -= 1; + + const int32 kWeekNumber = date.WeekNumber(); + int32 dateWeekNumber = kWeekNumber; + if (kWeekNumber == 52 && firstDay == 0) + dateWeekNumber = 1; + + for (int32 row = 0; row < 6; ++row) { + int32 weekNumber = dateWeekNumber + row; + if (kWeekNumber == 52 && firstDay != 0 || kWeekNumber == 53) + dateWeekNumber = 0; + fWeekNumbers[row].SetTo(""); + fWeekNumbers[row] << weekNumber; + } +} + + +void +BCalendarView::_DrawDay(int32 currRow, int32 currColumn, int32 row, int32 column, + int32 counter, BRect frame, const char *text, bool focus) +{ + const BDate date(fYear, fMonth, 1); + const int32 daysMonth = date.DaysInMonth(); + + int32 firstDay = date.DayOfWeek(); + if (fWeekStart == B_WEEK_START_MONDAY) + firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1; + + bool enabled = true; + bool selected = false; + // check for the current date + if (currRow == row && currColumn == column) { + selected = true; // draw current date selected + if (counter <= firstDay || counter > firstDay + daysMonth) { + enabled = false; // days of month before or after + selected = false; // not selected but able to get focus + } + } else { + if (counter <= firstDay || counter > firstDay + daysMonth) + enabled = false; // days of month before or after + } + + DrawDay(this, frame, text, selected, enabled, focus); +} + + +void +BCalendarView::_DrawDays() +{ + BRect frame = _FirstCalendarItemFrame(); + + const int32 currRow = fSelectedDay.row; + const int32 currColumn = fSelectedDay.column; + + const bool isFocus = IsFocus(); + const int32 focusRow = fFocusedDay.row; + const int32 focusColumn = fFocusedDay.column; + + int32 counter = 0; + for (int32 row = 0; row < 6; ++row) { + BRect tmp = frame; + for (int32 column = 0; column < 7; ++column) { + counter++; + const char *day = fDayNumbers[row][column].String(); + bool focus = isFocus && focusRow == row && focusColumn == column; + _DrawDay(currRow, currColumn, row, column, counter, tmp, day, focus); + + tmp.OffsetBy(tmp.Width(), 0.0); + } + frame.OffsetBy(0.0, frame.Height()); + } +} + + +void +BCalendarView::_DrawFocusRect() +{ + BRect frame = _FirstCalendarItemFrame(); + + const int32 currRow = fSelectedDay.row; + const int32 currColumn = fSelectedDay.column; + + const int32 focusRow = fFocusedDay.row; + const int32 focusColumn = fFocusedDay.column; + + int32 counter = 0; + for (int32 row = 0; row < 6; ++row) { + BRect tmp = frame; + for (int32 column = 0; column < 7; ++column) { + counter++; + if (fNewFocusedDay.row == row && fNewFocusedDay.column == column) { + fFocusedDay.SetTo(row, column); + + bool focus = IsFocus() && true; + const char *day = fDayNumbers[row][column].String(); + _DrawDay(currRow, currColumn, row, column, counter, tmp, day, focus); + } + else if (focusRow == row && focusColumn == column) { + const char *day = fDayNumbers[row][column].String(); + _DrawDay(currRow, currColumn, row, column, counter, tmp, day, false); + } + tmp.OffsetBy(tmp.Width(), 0.0); + } + frame.OffsetBy(0.0, frame.Height()); + } +} + + +void +BCalendarView::_DrawDayHeader() +{ + if (!fDayNameHeaderVisible) + return; + + int32 offset = 1; + int32 columns = 8; + if (!fWeekNumberHeaderVisible) { + offset = 0; + columns = 7; + } + + BRect frame = Bounds(); + frame.right = frame.Width() / columns - 1.0; + frame.bottom = frame.Height() / 7.0 - 2.0; + frame.OffsetBy(4.0, 4.0); + + for (int32 i = 0; i < columns; ++i) { + if (i == 0 && fWeekNumberHeaderVisible) { + DrawDayName(this, frame, ""); + frame.OffsetBy(frame.Width(), 0.0); + continue; + } + DrawDayName(this, frame, fDayNames[i - offset].String()); + frame.OffsetBy(frame.Width(), 0.0); + } +} + + +void +BCalendarView::_DrawWeekHeader() +{ + if (!fWeekNumberHeaderVisible) + return; + + int32 rows = 7; + if (!fDayNameHeaderVisible) + rows = 6; + + BRect frame = Bounds(); + frame.right = frame.Width() / 8.0 - 2.0; + frame.bottom = frame.Height() / rows - 1.0; + + float offsetY = 4.0; + if (fDayNameHeaderVisible) + offsetY += frame.Height(); + + frame.OffsetBy(4.0, offsetY); + + for (int32 row = 0; row < 6; ++row) { + DrawWeekNumber(this, frame, fWeekNumbers[row].String()); + frame.OffsetBy(0.0, frame.Height()); + } +} + + +void +BCalendarView::_DrawItem(BView *owner, BRect frame, const char *text, + bool isSelected, bool isEnabled, bool focus) +{ + rgb_color lColor = LowColor(); + rgb_color highColor = HighColor(); + + rgb_color lowColor = { 255, 255, 255, 255 }; + + if (isSelected) { + SetHighColor(tint_color(lowColor, B_DARKEN_2_TINT)); + SetLowColor(HighColor()); + } else + SetHighColor(lowColor); + + FillRect(frame.InsetByCopy(1.0, 1.0)); + + if (focus) { + SetHighColor(keyboard_navigation_color()); + StrokeRect(frame.InsetByCopy(1.0, 1.0)); + } + + rgb_color black = { 0, 0, 0, 255 }; + SetHighColor(black); + if (!isEnabled) + SetHighColor(tint_color(black, B_LIGHTEN_2_TINT)); + + float offsetH = frame.Width() / 2.0; + float offsetV = (frame.Height() / 2.0) + (FontHeight(owner) / 2.0) - 2.0; + + DrawString(text, BPoint(frame.right - offsetH + - (StringWidth(text) / 2.0), frame.top + offsetV)); + + SetLowColor(lColor); + SetHighColor(highColor); +} + + +void +BCalendarView::_UpdateSelection() +{ + BRect frame = _FirstCalendarItemFrame(); + + const int32 currRow = fSelectedDay.row; + const int32 currColumn = fSelectedDay.column; + + const int32 focusRow = fFocusedDay.row; + const int32 focusColumn = fFocusedDay.column; + + int32 counter = 0; + for (int32 row = 0; row < 6; ++row) { + BRect tmp = frame; + for (int32 column = 0; column < 7; ++column) { + counter++; + if (fNewSelectedDay.row == row && fNewSelectedDay.column == column) { + fSelectedDay.SetTo(row, column); + + const char *day = fDayNumbers[row][column].String(); + bool focus = IsFocus() && focusRow == row && focusColumn == column; + _DrawDay(row, column, row, column, counter, tmp, day, focus); + } + else if (currRow == row && currColumn == column) { + const char *day = fDayNumbers[row][column].String(); + bool focus = IsFocus() && focusRow == row && focusColumn == column; + _DrawDay(currRow, currColumn, -1, -1, counter, tmp, day, focus); + } + tmp.OffsetBy(tmp.Width(), 0.0); + } + frame.OffsetBy(0.0, frame.Height()); + } +} + + +BRect +BCalendarView::_FirstCalendarItemFrame() const +{ + int32 rows = 7; + int32 columns = 8; + + if (!fDayNameHeaderVisible) + rows = 6; + + if (!fWeekNumberHeaderVisible) + columns = 7; + + BRect frame = Bounds(); + frame.right = frame.Width() / columns - 1.0; + frame.bottom = frame.Height() / rows - 1.0; + + float offsetY = 4.0; + if (fDayNameHeaderVisible) + offsetY += frame.Height(); + + float offsetX = 4.0; + if (fWeekNumberHeaderVisible) + offsetX += frame.Width(); + + return frame.OffsetBySelf(offsetX, offsetY); +} + + +BRect +BCalendarView::_SetNewSelectedDay(const BPoint &where) +{ + BRect frame = _FirstCalendarItemFrame(); + + int32 counter = 0; + for (int32 row = 0; row < 6; ++row) { + BRect tmp = frame; + for (int32 column = 0; column < 7; ++column) { + counter++; + if (tmp.Contains(where)) { + fNewSelectedDay.SetTo(row, column); + fDay = atoi(fDayNumbers[row][column].String()); + return tmp; + } + tmp.OffsetBy(tmp.Width(), 0.0); + } + frame.OffsetBy(0.0, frame.Height()); + } + + return frame; +} + + +BRect +BCalendarView::_RectOfDay(const Selection &selection) const +{ + BRect frame = _FirstCalendarItemFrame(); + + int32 counter = 0; + for (int32 row = 0; row < 6; ++row) { + BRect tmp = frame; + for (int32 column = 0; column < 7; ++column) { + counter++; + if (selection.row == row && selection.column == column) { + return tmp; + } + tmp.OffsetBy(tmp.Width(), 0.0); + } + frame.OffsetBy(0.0, frame.Height()); + } + + return frame; +} + + +BCalendarView& +BCalendarView::operator=(const BCalendarView &view) +{ + return *this; +} diff --git a/src/preferences/time/CalendarView.h b/src/preferences/time/CalendarView.h index 4ba1efa0a7..5e78f86c29 100644 --- a/src/preferences/time/CalendarView.h +++ b/src/preferences/time/CalendarView.h @@ -1,68 +1,179 @@ /* - * Copyright 2004-2007, Haiku, Inc. All Rights Reserved. + * Copyright 2007, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. - * - * Authors: - * probably Mike Berg - * and/or Andrew McCall */ -#ifndef CALENDAR_VIEW_H -#define CALENDAR_VIEW_H +#ifndef _CALENDAR_VIEW_H_ +#define _CALENDAR_VIEW_H_ -#include +#include "DateTime.h" + + +#include +#include +#include #include -class TDay: public BControl { - public: - TDay(BRect frame, int day); - virtual ~TDay(); - virtual void AttachedToWindow(); - virtual void Draw(BRect updaterect); - virtual void KeyDown(const char *bytes, int32 numbytes); - virtual void MakeFocus(bool focused); - virtual void MouseDown(BPoint where); - virtual void SetValue(int32 value); - - void SetTo(BRect frame, int day); - void SetTo(int day, bool selected = false); +class BMessage; - int Day() - { return f_day; } - protected: - virtual void Stroke3dFrame(BRect frame, rgb_color light, rgb_color dark, bool inset); - private: - int f_day; + +enum week_start { + B_WEEK_START_MONDAY, + B_WEEK_START_SUNDAY }; -class TCalendarView: public BView { + +class BCalendarView : public BView, public BInvoker { public: - TCalendarView(BRect frame, const char *name, uint32 resizingmode, uint32 flags); - virtual ~TCalendarView(); - virtual void AttachedToWindow(); - virtual void Draw(BRect bounds); - void KeyDown(const char *bytes, int32 numbytes); - virtual void MessageReceived(BMessage *message); + BCalendarView(BRect frame, const char *name, + uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE); + + BCalendarView(BRect frame, const char *name, week_start start, + uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE); + + virtual ~BCalendarView(); + + BCalendarView(BMessage *archive); + static BArchivable* Instantiate(BMessage *archive); + virtual status_t Archive(BMessage *archive, bool deep = true) const; + + virtual void AttachedToWindow(); + virtual void DetachedFromWindow(); + + virtual void AllAttached(); + virtual void AllDetached(); + + virtual void FrameMoved(BPoint newPosition); + virtual void FrameResized(float width, float height); + + virtual void Draw(BRect updateRect); - void SetTo(int32, int32, int32); - protected: - virtual void InitView(); - virtual void DispatchMessage(); + virtual void DrawDay(BView *owner, BRect frame, const char *text, + bool isSelected = false, bool isEnabled = true, + bool focus = false); + virtual void DrawDayName(BView *owner, BRect frame, const char *text); + virtual void DrawWeekNumber(BView *owner, BRect frame, const char *text); + + virtual void MessageReceived(BMessage *message); + + uint32 SelectionCommand() const; + BMessage* SelectionMessage() const; + virtual void SetSelectionMessage(BMessage *message); + + uint32 InvocationCommand() const; + BMessage* InvocationMessage() const; + virtual void SetInvocationMessage(BMessage *message); + + virtual void WindowActivated(bool state); + virtual void MakeFocus(bool state = true); + virtual status_t Invoke(BMessage* message = NULL); + + virtual void MouseUp(BPoint point); + virtual void MouseDown(BPoint where); + virtual void MouseMoved(BPoint point, uint32 code, + const BMessage *dragMessage); + + virtual void KeyDown(const char *bytes, int32 numBytes); + + virtual BHandler* ResolveSpecifier(BMessage *message, int32 index, + BMessage *specifier, int32 form, const char *property); + virtual status_t GetSupportedSuites(BMessage *data); + virtual status_t Perform(perform_code code, void* arg); + + virtual void ResizeToPreferred(); + virtual void GetPreferredSize(float *width, float *height); + + int32 Day() const; + int32 Year() const; + int32 Month() const; + + BDate Date() const; + bool SetDate(const BDate &date); + bool SetDate(int32 year, int32 month, int32 day); + + week_start WeekStart() const; + void SetWeekStart(week_start start); + + bool IsDayNameHeaderVisible() const; + void SetDayNameHeaderVisible(bool visible); + + bool IsWeekNumberHeaderVisible() const; + void SetWeekNumberHeaderVisible(bool visible); + private: - void InitDates(); - void CalcFlags(); - int32 IndexOf(BView *) const; + void _InitObject(); - TDay *f_cday; - TDay *f_focused; - BRect f_dayrect; - // x = index of first day; y = index of last; - BPoint f_daybound; - int f_firstday; - int f_month; - int f_day; - int f_year; + void _SetToDay(); + void _GetYearMonth(int32 *year, int32 *month) const; + void _GetPreferredSize(float *width, float *height); + + void _SetupDayNames(); + void _SetupDayNumbers(); + void _SetupWeekNumbers(); + + void _DrawDays(); + void _DrawFocusRect(); + void _DrawDayHeader(); + void _DrawWeekHeader(); + void _DrawDay(int32 curRow, int32 curColumn, + int32 row, int32 column, int32 counter, + BRect frame, const char *text, bool focus = false); + void _DrawItem(BView *owner, BRect frame, const char *text, + bool isSelected = false, bool isEnabled = true, + bool focus = false); + + void _UpdateSelection(); + BRect _FirstCalendarItemFrame() const; + BRect _SetNewSelectedDay(const BPoint &where); + + BCalendarView& operator=(const BCalendarView &view); + + private: + struct Selection { + Selection() + : row(0), column(0) { } + + void SetTo(int32 _row, int32 _column) + { row = _row; column = _column; } + + int32 row; + int32 column; + + Selection& operator=(const Selection &s) + { row = s.row; column = s.column; return *this; } + + bool operator==(const Selection &s) const + { return row == s.row && column == s.column; } + + bool operator!=(const Selection &s) const + { return row != s.row || column != s.column; } + }; + BRect _RectOfDay(const Selection &selection) const; + + BMessage *fSelectionMessage; + + int32 fDay; + int32 fYear; + int32 fMonth; + + Selection fFocusedDay; + bool fFocusChanged; + Selection fNewFocusedDay; + + Selection fSelectedDay; + Selection fNewSelectedDay; + bool fSelectionChanged; + + week_start fWeekStart; + bool fDayNameHeaderVisible; + bool fWeekNumberHeaderVisible; + + BString fDayNames[7]; + BString fWeekNumbers[6]; + BString fDayNumbers[6][7]; }; -#endif // CALENDAR_VIEW_H +#endif // _CALENDAR_VIEW_H_ diff --git a/src/preferences/time/DateTime.cpp b/src/preferences/time/DateTime.cpp new file mode 100755 index 0000000000..e3b5cad819 --- /dev/null +++ b/src/preferences/time/DateTime.cpp @@ -0,0 +1,483 @@ +/* + * Copyright 2004-2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Julun + * Stephan Aßmus + */ + +#include "DateTime.h" + + +#include + + +BTime::BTime() + : fHour(-1), + fMinute(-1), + fSecond(-1) +{ +} + + +BTime::BTime(int32 hour, int32 minute, int32 second) + : fHour(hour), + fMinute(minute), + fSecond(second) +{ +} + + +BTime::~BTime() +{ +} + + +bool +BTime::IsValid() const +{ + if (fHour < 0 || fHour >= 24) + return false; + + if (fMinute < 0 || fMinute >= 60) + return false; + + if (fSecond < 0 || fSecond >= 60) + return false; + + return true; +} + + +BTime +BTime::CurrentTime(time_type type) +{ + time_t timer; + struct tm result; + struct tm* timeinfo; + + time(&timer); + + if (type == B_GMT_TIME) + timeinfo = gmtime_r(&timer, &result); + else + timeinfo = localtime_r(&timer, &result); + + int32 sec = timeinfo->tm_sec; + return BTime(timeinfo->tm_hour, timeinfo->tm_min, (sec > 59) ? 59 : sec); +} + + +bool +BTime::SetTime(int32 hour, int32 minute, int32 second) +{ + fHour = hour; + fMinute = minute; + fSecond = second; + + return IsValid(); +} + + +int32 +BTime::Hour() const +{ + return fHour; +} + + +int32 +BTime::Minute() const +{ + return fMinute; +} + + +int32 +BTime::Second() const +{ + return fSecond; +} + + +// #pragma mark - + + +BDate::BDate() + : fDay(-1), + fYear(-1), + fMonth(-1) +{ +} + + +BDate::BDate(int32 year, int32 month, int32 day) + : fDay(day), + fYear(year), + fMonth(month) +{ +} + + +BDate::~BDate() +{ +} + + +bool +BDate::IsValid() const +{ + // fail if the year goes less 1583 + // 10/15/1582 start of Gregorian calendar + if (fYear < 1583) + return false; + + if (fMonth < 1 || fMonth > 12) + return false; + + if (fDay < 1 || fDay > DaysInMonth()) + return false; + + return true; +} + + +BDate +BDate::CurrentDate(time_type type) +{ + time_t timer; + struct tm result; + struct tm* timeinfo; + + time(&timer); + + if (type == B_GMT_TIME) + timeinfo = gmtime_r(&timer, &result); + else + timeinfo = localtime_r(&timer, &result); + + return BDate(timeinfo->tm_year + 1900, timeinfo->tm_mon +1, timeinfo->tm_mday); +} + + +bool +BDate::SetDate(int32 year, int32 month, int32 day) +{ + fDay = day; + fYear = year; + fMonth = month; + + return IsValid(); +} + + +int32 +BDate::Day() const +{ + return fDay; +} + + +int32 +BDate::Year() const +{ + return fYear; +} + + +int32 +BDate::Month() const +{ + return fMonth; +} + + +int32 +BDate::WeekNumber() const +{ + /* + This algorithm is taken from: + Frequently Asked Questions about Calendars + Version 2.8 Claus Tøndering 15 December 2005 + + Note: it will work only within the Gregorian Calendar + */ + + if (!IsValid()) + return 0; + + int32 a; + int32 b; + int32 s; + int32 e; + int32 f; + + if (fMonth > 0 && fMonth < 3) { + a = fYear - 1; + b = (a / 4) - (a / 100) + (a / 400); + int32 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a -1) / 400); + s = b - c; + e = 0; + f = fDay - 1 + 31 * (fMonth - 1); + } else if (fMonth >= 3 && fMonth <= 12) { + a = fYear; + b = (a / 4) - (a / 100) + (a / 400); + int32 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a -1) / 400); + s = b - c; + e = s + 1; + f = fDay + ((153 * (fMonth - 3) + 2) / 5) + 58 + s; + } else + return 0; + + int32 g = (a + b) % 7; + int32 d = (f + g - e) % 7; + int32 n = f + 3 - d; + + int32 weekNumber; + if (n < 0) + weekNumber = 53 - (g -s) / 5; + else if (n > 364 + s) + weekNumber = 1; + else + weekNumber = n / 7 + 1; + + return weekNumber; +} + + +int32 +BDate::DayOfWeek() const +{ + /* + This algorithm is taken from: + Frequently Asked Questions about Calendars + Version 2.8 Claus Tøndering 15 December 2005 + + Note: it will work only within the Gregorian Calendar + */ + + if (!IsValid()) + return -1; + + int32 a = (14 - fMonth) / 12; + int32 y = fYear - a; + int32 m = fMonth + 12 * a - 2; + int32 d = (fDay + y + (y / 4) - (y / 100) + (y / 400) + ((31 * m) / 12)) % 7; + + return d; +} + + +int32 +BDate::DayOfYear() const +{ + /* + Note: this function might fail for 1582... + + http://en.wikipedia.org/wiki/Gregorian_calendar: + The last day of the Julian calendar was Thursday October 4, 1582 + and this was followed by the first day of the Gregorian calendar, + Friday October 15, 1582 (the cycle of weekdays was not affected). + */ + + if (!IsValid()) + return -1; + + const int kFirstDayOfMonth[2][12] = { + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 } + }; + + if (IsLeapYear(fYear)) + return kFirstDayOfMonth[1][fMonth -1] + fDay; + + return kFirstDayOfMonth[0][fMonth -1] + fDay; +} + + +bool +BDate::IsLeapYear(int32 year) const +{ + return year % 400 == 0 || year % 4 == 0 && year % 100 != 0; +} + + +int32 +BDate::DaysInYear() const +{ + if (!IsValid()) + return 0; + + return IsLeapYear(fYear) ? 366 : 365; +} + + +int32 +BDate::DaysInMonth() const +{ + if (fMonth == 2 && IsLeapYear(fYear)) + return 29; + + const int32 daysInMonth[12] = + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + return daysInMonth[fMonth -1]; +} + + +BString +BDate::ShortDayName(int32 day) const +{ + if (day < 1 || day > 7) + return BString(); + + tm tm_struct; + memset(&tm_struct, 0, sizeof(tm)); + tm_struct.tm_wday = day == 7 ? 0 : day; + + char buffer[256]; + strftime(buffer, sizeof(buffer), "%a", &tm_struct); + + return BString(buffer); +} + + +BString +BDate::ShortMonthName(int32 month) const +{ + if (month < 1 || month > 12) + return BString(); + + tm tm_struct; + memset(&tm_struct, 0, sizeof(tm)); + tm_struct.tm_mon = month -1; + + char buffer[256]; + strftime(buffer, sizeof(buffer), "%b", &tm_struct); + + return BString(buffer); +} + + +BString +BDate::LongDayName(int32 day) const +{ + if (day < 1 || day > 7) + return BString(); + + tm tm_struct; + memset(&tm_struct, 0, sizeof(tm)); + tm_struct.tm_wday = day == 7 ? 0 : day; + + char buffer[256]; + strftime(buffer, sizeof(buffer), "%A", &tm_struct); + + return BString(buffer); +} + + +BString +BDate::LongMonthName(int32 month) const +{ + if (month < 1 || month > 12) + return BString(); + + tm tm_struct; + memset(&tm_struct, 0, sizeof(tm)); + tm_struct.tm_mon = month -1; + + char buffer[256]; + strftime(buffer, sizeof(buffer), "%B", &tm_struct); + + return BString(buffer); +} + + +// #pragma mark - + + +BDateTime::BDateTime(const BDate &date, const BTime &time) + : fDate(date), + fTime(time) +{ +} + + +BDateTime::~BDateTime() +{ +} + + +bool +BDateTime::IsValid() const +{ + return fDate.IsValid() && fTime.IsValid(); +} + + +BDateTime +BDateTime::CurrentDateTime(time_type type) +{ + BDate date = BDate::CurrentDate(type); + BTime time = BTime::CurrentTime(type); + + return BDateTime(date, time); +} + + +void +BDateTime::SetDateTime(const BDate &date, const BTime &time) +{ + fDate = date; + fTime = time; +} + + +BDate +BDateTime::Date() const +{ + return fDate; +} + + +void +BDateTime::SetDate(const BDate &date) +{ + fDate = date; +} + + +BTime +BDateTime::Time() const +{ + return fTime; +} + + +void +BDateTime::SetTime(const BTime &time) +{ + fTime = time; +} + + +uint32 +BDateTime::Time_t() const +{ + tm tm_struct; + + tm_struct.tm_hour = fTime.Hour(); + tm_struct.tm_min = fTime.Minute(); + tm_struct.tm_sec = fTime.Second(); + + tm_struct.tm_year = fDate.Year() - 1900; + tm_struct.tm_mon = fDate.Month() - 1; + tm_struct.tm_mday = fDate.Day(); + + // set less 0 as we wan't use it + tm_struct.tm_isdst = -1; + + // return secs_since_jan1_1970 or -1 on error + return uint32(mktime(&tm_struct)); +} diff --git a/src/preferences/time/DateTime.h b/src/preferences/time/DateTime.h new file mode 100755 index 0000000000..3fe9a3ce2a --- /dev/null +++ b/src/preferences/time/DateTime.h @@ -0,0 +1,100 @@ +/* + * Copyright 2007, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _DATE_TIME_H_ +#define _DATE_TIME_H_ + + +#include + + +enum time_type { + B_GMT_TIME, + B_LOCAL_TIME +}; + + +class BTime { + public: + BTime(); + BTime(int32 hour, int32 minute, int32 second); + ~BTime(); + + bool IsValid() const; + + static BTime CurrentTime(time_type type); + bool SetTime(int32 hour, int32 minute, int32 second); + + int32 Hour() const; + int32 Minute() const; + int32 Second() const; + + private: + int32 fHour; + int32 fMinute; + int32 fSecond; +}; + + +class BDate { + public: + BDate(); + BDate(int32 year, int32 month, int32 day); + ~BDate(); + + bool IsValid() const; + + static BDate CurrentDate(time_type type); + bool SetDate(int32 year, int32 month, int32 day); + + int32 Day() const; + int32 Year() const; + int32 Month() const; + + int32 DayOfWeek() const; + int32 DayOfYear() const; + + int32 WeekNumber() const; + bool IsLeapYear(int32 year) const; + + int32 DaysInYear() const; + int32 DaysInMonth() const; + + BString ShortDayName(int32 day) const; + BString ShortMonthName(int32 month) const; + + BString LongDayName(int32 day) const; + BString LongMonthName(int32 month) const; + + private: + int32 fDay; + int32 fYear; + int32 fMonth; +}; + + +class BDateTime { + public: + BDateTime(const BDate &date, const BTime &time); + ~BDateTime(); + + bool IsValid() const; + + static BDateTime CurrentDateTime(time_type type); + void SetDateTime(const BDate &date, const BTime &time); + + BDate Date() const; + void SetDate(const BDate &date); + + BTime Time() const; + void SetTime(const BTime &time); + + uint32 Time_t() const; + + private: + BDate fDate; + BTime fTime; +}; + +#endif // _DATE_TIME_H_ diff --git a/src/preferences/time/DateTimeEdit.cpp b/src/preferences/time/DateTimeEdit.cpp index 97642d6ada..3468935620 100644 --- a/src/preferences/time/DateTimeEdit.cpp +++ b/src/preferences/time/DateTimeEdit.cpp @@ -3,45 +3,24 @@ * Distributed under the terms of the MIT License. * * Authors: - * probably Mike Berg - * and/or Andrew McCall + * McCall + * Mike Berg * Julun * */ #include "DateTimeEdit.h" -#include "DateUtils.h" #include #include -#define YEAR_DELTA_MAX 110 -#define YEAR_DELTA_MIN 64 - - -class TDateTimeSection : public TSection { - public: - TDateTimeSection(BRect frame, uint32 data = 0) - : TSection(frame), fData(data) { } - ~TDateTimeSection(); - - uint32 Data() const { return fData; } - void SetData(uint32 data) { fData = data; } - - private: - uint32 fData; -}; - - -// #pragma mark - - - TTimeEdit::TTimeEdit(BRect frame, const char *name, uint32 sections) : TSectionEdit(frame, name, sections) { InitView(); + fTime = BTime::CurrentTime(B_LOCAL_TIME); } @@ -64,27 +43,25 @@ void TTimeEdit::DrawSection(uint32 index, bool hasFocus) { // user defined section drawing - TDateTimeSection *section; - section = (TDateTimeSection *)fSectionList->ItemAt(index); + TSection *section = NULL; + section = static_cast (fSectionList->ItemAt(index)); + + if (!section) + return; BRect bounds = section->Frame(); + uint32 value = _SectionValue(index); - // format value to display - - uint32 value; - + SetLowColor(ViewColor()); if (hasFocus) { SetLowColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); value = fHoldValue; - } else { - SetLowColor(ViewColor()); - value = section->Data(); } BString text; - // format value (new method?) switch (index) { - case 0: // hour + case 0: + { // hour if (value > 12) { if (value < 22) text << "0"; @@ -96,53 +73,55 @@ TTimeEdit::DrawSection(uint32 index, bool hasFocus) text << "0"; text << value; } - break; + } break; - case 1: // minute - case 2: // second + case 1: + case 2: + { // minute + // second if (value < 10) text << "0"; text << value; - break; + } break; - case 3: // am/pm - value = ((TDateTimeSection *)fSectionList->ItemAt(0))->Data(); + case 3: + { // am/pm + value = fTime.Hour(); if (value >= 12) text << "PM"; else text << "AM"; - break; + } break; default: return; - break; + break; } // calc and center text in section rect float width = be_plain_font->StringWidth(text.String()); - BPoint offset(-(bounds.Width() / 2.0 -width / 2.0) -1.0, bounds.Height() / 2.0 -6.0); - - BPoint drawpt(bounds.LeftBottom() -offset); + BPoint offset(-((bounds.Width()- width) / 2.0) -1.0 + , bounds.Height() / 2.0 -6.0); SetHighColor(0, 0, 0, 255); FillRect(bounds, B_SOLID_LOW); - DrawString(text.String(), drawpt); + DrawString(text.String(), bounds.LeftBottom() - offset); } -/* - DrawSeperator(uint32 index) user drawn seperator. Section is the - index of the section in fSectionList or the section to the seps left -*/ void TTimeEdit::DrawSeperator(uint32 index) { if (index == 3) return; - TDateTimeSection *section = (TDateTimeSection *)fSectionList->ItemAt(index); + TSection *section = NULL; + section = static_cast (fSectionList->ItemAt(index)); + if (!section) + return; + BRect bounds = section->Frame(); float sepWidth = SeperatorWidth(); @@ -151,20 +130,17 @@ TTimeEdit::DrawSeperator(uint32 index) sep = "-"; float width = be_plain_font->StringWidth(sep); - - BPoint offset(-(sepWidth / 2.0 - width / 2.0) -1.0, bounds.Height() / 2.0 -6.0); - BPoint drawpt(bounds.RightBottom() -offset); - - DrawString(sep, drawpt); + BPoint offset(-((sepWidth - width) / 2.0) -1.0 + , bounds.Height() / 2.0 -6.0); + DrawString(sep, bounds.RightBottom() - offset); } void TTimeEdit::SetSections(BRect area) { - // by default divie up the sections evenly + // by default divide up the sections evenly BRect bounds(area); - // no comp for sep width float sepWidth = SeperatorWidth(); @@ -173,13 +149,13 @@ TTimeEdit::SetSections(BRect area) bounds.right = bounds.left + (width -sepWidth / fSectionCount); for (uint32 idx = 0; idx < fSectionCount; idx++) { - fSectionList->AddItem(new TDateTimeSection(bounds)); + fSectionList->AddItem(new TSection(bounds)); bounds.left = bounds.right + sepWidth; if (idx == fSectionCount -2) bounds.right = area.right -1; else - bounds.right = bounds.left + (width -sep_2); + bounds.right = bounds.left + (width - sep_2); } } @@ -187,7 +163,7 @@ TTimeEdit::SetSections(BRect area) float TTimeEdit::SeperatorWidth() const { - return 8.0f; + return 10.0f; } @@ -195,42 +171,20 @@ void TTimeEdit::SectionFocus(uint32 index) { fFocus = index; - - // update hold value - fHoldValue = ((TDateTimeSection *)fSectionList->ItemAt(fFocus))->Data(); - + fHoldValue = _SectionValue(index); Draw(Bounds()); } void -TTimeEdit::SetTime(uint32 hour, uint32 minute, uint32 second) +TTimeEdit::SetTime(int32 hour, int32 minute, int32 second) { - if (fSectionList->CountItems()> 0) - { - bool update = false; - - TDateTimeSection *section = (TDateTimeSection *)fSectionList->ItemAt(0); - if (section->Data() != hour) { - section->SetData(hour); - update = true; - } - - section = (TDateTimeSection *)fSectionList->ItemAt(1); - if (section->Data() != minute) { - section->SetData(minute); - update = true; - } - - section = (TDateTimeSection *)fSectionList->ItemAt(2); - if (section->Data() != second) { - section->SetData(second); - update = true; - } - - if (update) - Draw(Bounds()); - } + if (fTime.Hour() == hour && fTime.Minute() == minute + && fTime.Second() == second) + return; + + fTime.SetTime(hour, minute, second); + Invalidate(Bounds()); } @@ -243,7 +197,7 @@ TTimeEdit::DoUpPress() // update displayed value fHoldValue += 1; - CheckRange(); + _CheckRange(); // send message to change time DispatchMessage(); @@ -259,7 +213,7 @@ TTimeEdit::DoDownPress() // update display value fHoldValue -= 1; - CheckRange(); + _CheckRange(); // send message to change time DispatchMessage(); @@ -269,74 +223,105 @@ TTimeEdit::DoDownPress() void TTimeEdit::BuildDispatch(BMessage *message) { - const char *fields[4] = {"hour", "minute", "second", "isam"}; + const char *fields[3] = { "hour", "minute", "second" }; message->AddBool("time", true); - for (int32 idx = 0; idx < fSectionList->CountItems() -1; idx++) { - uint32 data = ((TDateTimeSection *)fSectionList->ItemAt(idx))->Data(); + for (int32 index = 0; index < fSectionList->CountItems() -1; ++index) { + uint32 data = _SectionValue(index); - if (fFocus == idx) + if (fFocus == index) data = fHoldValue; - if (idx == 3) // isam - message->AddBool(fields[idx], data == 1); - else - message->AddInt32(fields[idx], data); + message->AddInt32(fields[index], data); } } void -TTimeEdit::CheckRange() +TTimeEdit::_CheckRange() { int32 value = fHoldValue; switch (fFocus) { - case 0: // hour - if (value> 23) + case 0: + { // hour + if (value > 23) value = 0; else if (value < 0) value = 23; - break; - case 1: // minute + fTime.SetTime(value, fTime.Minute(), fTime.Second()); + } break; + + case 1: + { // minute if (value> 59) value = 0; else if (value < 0) value = 59; - break; - case 2: // second + fTime.SetTime(fTime.Hour(), value, fTime.Second()); + } break; + + case 2: + { // second if (value > 59) value = 0; else if (value < 0) value = 59; - - break; + + fTime.SetTime(fTime.Hour(), fTime.Minute(), value); + } break; case 3: - // modify hour value to reflect change in am/pm - value = ((TDateTimeSection *)fSectionList->ItemAt(0))->Data(); + { + value = fTime.Hour(); if (value < 13) value += 12; else value -= 12; if (value == 24) value = 0; - ((TDateTimeSection *)fSectionList->ItemAt(0))->SetData(value); - break; + + // modify hour value to reflect change in am/ pm + fTime.SetTime(value, fTime.Minute(), fTime.Second()); + } break; default: return; } - ((TDateTimeSection *)fSectionList->ItemAt(fFocus))->SetData(value); fHoldValue = value; - Invalidate(Bounds()); } +int32 +TTimeEdit::_SectionValue(int32 index) const +{ + int32 value; + switch (index) { + case 0: + value = fTime.Hour(); + break; + + case 1: + value = fTime.Minute(); + break; + + case 2: + value = fTime.Second(); + break; + + default: + value = 0; + break; + } + + return value; +} + + // #pragma mark - @@ -344,6 +329,7 @@ TDateEdit::TDateEdit(BRect frame, const char *name, uint32 sections) : TSectionEdit(frame, name, sections) { InitView(); + fDate = BDate::CurrentDate(B_LOCAL_TIME); } @@ -366,54 +352,32 @@ void TDateEdit::DrawSection(uint32 index, bool hasFocus) { // user defined section drawing - TDateTimeSection *section; - section = (TDateTimeSection *)fSectionList->ItemAt(index); + TSection *section = NULL; + section = static_cast (fSectionList->ItemAt(index)); + + if (!section) + return; BRect bounds = section->Frame(); + uint32 value = _SectionValue(index); - // format value to display - - uint32 value; - + SetLowColor(ViewColor()); if (hasFocus) { SetLowColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); value = fHoldValue; - } else { - SetLowColor(ViewColor()); - value = section->Data(); } BString text; - switch (index) { - case 0: - { // month - struct tm tm; - tm.tm_mon = value; - - char buffer[64]; - memset(buffer, 0, sizeof(buffer)); - strftime(buffer, sizeof(buffer), "%B", &tm); - text.SetTo(buffer); - } break; - - case 1: // day - text << value; - break; - - case 2: // year - text << (value + 1900); - break; - - default: - return; - } + if (index != 0) { + if (value < 10) text << "0"; + text << value; + } else + text.SetTo(fDate.LongMonthName(value)); // calc and center text in section rect float width = StringWidth(text.String()); - BPoint offset(-(bounds.Width() - width) / 2.0 - 1.0, (bounds.Height() / 2.0 - 6.0)); - - if (index == 0) - offset.x = -(bounds.Width() - width) ; + BPoint offset(-(bounds.Width() - width) / 2.0 - 1.0 + , (bounds.Height() / 2.0 - 6.0)); SetHighColor(0, 0, 0, 255); FillRect(bounds, B_SOLID_LOW); @@ -421,26 +385,24 @@ TDateEdit::DrawSection(uint32 index, bool hasFocus) } -/* - DrawSeperator(uint32 index) user drawn seperator. Section is the - index of the section in fSectionList or the section to the seps left -*/ void TDateEdit::DrawSeperator(uint32 index) { if (index == 3) return; - TDateTimeSection *section = (TDateTimeSection *)fSectionList->ItemAt(index); + TSection *section = NULL; + section = static_cast (fSectionList->ItemAt(index)); BRect bounds = section->Frame(); float sepWidth = SeperatorWidth(); float width = be_plain_font->StringWidth("/"); - BPoint offset(-(sepWidth / 2.0 - width / 2.0) -1.0, bounds.Height() / 2.0 -6.0); - BPoint drawpt(bounds.RightBottom() - offset); + BPoint offset(-(sepWidth / 2.0 - width / 2.0) -1.0 + , bounds.Height() / 2.0 -6.0); - DrawString("/", drawpt); + SetHighColor(0, 0, 0, 255); + DrawString("/", bounds.RightBottom() - offset); } @@ -449,35 +411,38 @@ TDateEdit::SetSections(BRect area) { // create sections for (uint32 idx = 0; idx < fSectionCount; idx++) - fSectionList->AddItem(new TDateTimeSection(area)); + fSectionList->AddItem(new TSection(area)); BRect bounds(area); + float sepWidth = SeperatorWidth(); // year + TSection *section = NULL; float width = be_plain_font->StringWidth("0000") +6; bounds.right = area.right; bounds.left = bounds.right -width; - ((TDateTimeSection *)fSectionList->ItemAt(2))->SetFrame(bounds); - - float sepWidth = SeperatorWidth(); + section = static_cast (fSectionList->ItemAt(2)); + section->SetFrame(bounds); // day width = be_plain_font->StringWidth("00") +6; bounds.right = bounds.left -sepWidth; bounds.left = bounds.right -width; - ((TDateTimeSection *)fSectionList->ItemAt(1))->SetFrame(bounds); + section = static_cast (fSectionList->ItemAt(1)); + section->SetFrame(bounds); // month bounds.right = bounds.left - sepWidth; bounds.left = area.left; - ((TDateTimeSection *)fSectionList->ItemAt(0))->SetFrame(bounds); + section = static_cast (fSectionList->ItemAt(0)); + section->SetFrame(bounds); } float TDateEdit::SeperatorWidth() const { - return 8.0f; + return 10.0f; } @@ -485,41 +450,19 @@ void TDateEdit::SectionFocus(uint32 index) { fFocus = index; - - // update hold value - fHoldValue = ((TDateTimeSection *)fSectionList->ItemAt(fFocus))->Data(); - + fHoldValue = _SectionValue(index); Draw(Bounds()); } void -TDateEdit::SetDate(uint32 year, uint32 month, uint32 day) +TDateEdit::SetDate(int32 year, int32 month, int32 day) { - if (fSectionList->CountItems() > 0) { - bool update = false; + if (year == fDate.Year() && month == fDate.Month() && day == fDate.Day()) + return; - TDateTimeSection *section = (TDateTimeSection *)fSectionList->ItemAt(0); - if (section->Data() != month) { - section->SetData(month); - update = true; - } - - section = (TDateTimeSection *)fSectionList->ItemAt(1); - if (section->Data() != day) { - section->SetData(day); - update = true; - } - - section = (TDateTimeSection *)fSectionList->ItemAt(2); - if (section->Data() != year) { - section->SetData(year); - update = true; - } - - if (update) - Invalidate(Bounds()); - } + fDate.SetDate(year, month, day); + Invalidate(Bounds()); } @@ -532,7 +475,7 @@ TDateEdit::DoUpPress() // update displayed value fHoldValue += 1; - CheckRange(); + _CheckRange(); // send message to change Date DispatchMessage(); @@ -548,7 +491,7 @@ TDateEdit::DoDownPress() // update display value fHoldValue -= 1; - CheckRange(); + _CheckRange(); // send message to change Date DispatchMessage(); @@ -558,65 +501,88 @@ TDateEdit::DoDownPress() void TDateEdit::BuildDispatch(BMessage *message) { - const char *fields[3] = {"month", "day", "year"}; + const char *fields[3] = { "month", "day", "year" }; message->AddBool("time", false); - for (int32 idx = 0; idx < fSectionList->CountItems(); idx++) { - uint32 data = ((TDateTimeSection *)fSectionList->ItemAt(idx))->Data(); + int32 value; + for (int32 index = 0; index < fSectionList->CountItems(); ++index) { + value = _SectionValue(index); - if (fFocus == idx) - data = fHoldValue; + if (index == fFocus) + value = fHoldValue; - message->AddInt32(fields[idx], data); + message->AddInt32(fields[index], value); } } void -TDateEdit::CheckRange() +TDateEdit::_CheckRange() { int32 value = fHoldValue; switch (fFocus) { - case 0: // month + case 0: { - if (value > 11) - value = 0; - else if (value < 0) - value = 11; - break; - } - - case 1: //day - { - uint32 month = ((TDateTimeSection *)fSectionList->ItemAt(0))->Data(); - uint32 year = ((TDateTimeSection *)fSectionList->ItemAt(2))->Data(); - - int daycnt = getDaysInMonth(month, year); - if (value > daycnt) + // month + if (value > 12) value = 1; else if (value < 1) - value = daycnt; - break; - } + value = 12; - case 2: //year + fDate.SetDate(fDate.Year(), value, fDate.Day()); + } break; + + case 1: { - if (value > YEAR_DELTA_MAX) - value = YEAR_DELTA_MIN; - else if (value < YEAR_DELTA_MIN) - value = YEAR_DELTA_MAX; - break; - } + //day + int32 days = fDate.DaysInMonth(); + if (value > days) + value = 1; + else if (value < 1) + value = days; + + fDate.SetDate(fDate.Year(), fDate.Month(), value); + } break; + + case 2: + { + //year + if (value > 2037) + value = 2037; + else if (value < 1970) + value = 1970; + + fDate.SetDate(value, fDate.Month(), fDate.Day()); + } break; default: return; } - ((TDateTimeSection *)fSectionList->ItemAt(fFocus))->SetData(value); fHoldValue = value; - Draw(Bounds()); } + +int32 +TDateEdit::_SectionValue(int32 index) const +{ + int32 value = 0; + switch (index) { + case 0: + value = fDate.Month(); + break; + + case 1: + value = fDate.Day(); + break; + + default: + value = fDate.Year(); + break; + } + + return value; +} diff --git a/src/preferences/time/DateTimeEdit.h b/src/preferences/time/DateTimeEdit.h index d2013d4e16..13eac1523d 100644 --- a/src/preferences/time/DateTimeEdit.h +++ b/src/preferences/time/DateTimeEdit.h @@ -3,8 +3,8 @@ * Distributed under the terms of the MIT License. * * Authors: - * probably Mike Berg - * and/or Andrew McCall + * McCall + * Mike Berg * Julun * */ @@ -12,6 +12,7 @@ #define DATETIME_H +#include "DateTime.h" #include "SectionEdit.h" @@ -28,14 +29,19 @@ class TTimeEdit : public TSectionEdit { virtual void SectionFocus(uint32 index); virtual float SeperatorWidth() const; - void CheckRange(); - virtual void DoUpPress(); virtual void DoDownPress(); virtual void BuildDispatch(BMessage *message); - void SetTime(uint32 hour, uint32 minute, uint32 second); + void SetTime(int32 hour, int32 minute, int32 second); + + private: + void _CheckRange(); + int32 _SectionValue(int32 index) const; + + private: + BTime fTime; }; @@ -52,14 +58,19 @@ class TDateEdit : public TSectionEdit { virtual void SectionFocus(uint32 index); virtual float SeperatorWidth() const; - void CheckRange(); - virtual void DoUpPress(); virtual void DoDownPress(); virtual void BuildDispatch(BMessage *message); - void SetDate(uint32 year, uint32 month, uint32 day); + void SetDate(int32 year, int32 month, int32 day); + + private: + void _CheckRange(); + int32 _SectionValue(int32 index) const; + + private: + BDate fDate; }; #endif // DATETIME_H diff --git a/src/preferences/time/DateUtils.cpp b/src/preferences/time/DateUtils.cpp deleted file mode 100644 index 5cdb76f0af..0000000000 --- a/src/preferences/time/DateUtils.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2004-2007, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * probably Mike Berg - * and/or Andrew McCall - */ -#include "DateUtils.h" -#include "math.h" - -#include - -bool -isLeapYear(const int year) -{ - int realYear = year + 1900; - return ((realYear % 400 == 0) || (realYear % 4 == 0 && realYear % 100 != 0)); -} - - -int -getDaysInMonth(const int month, const int year) -{ - if (month == 1 && isLeapYear(year)) - return 29; - - static const int DaysinMonth[12] = - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - - return DaysinMonth[month]; -} - - -int -getFirstDay(const int month, const int year) -{ - struct tm tm; - time_t currentTime = time(NULL); - localtime_r(¤tTime, &tm); - - // TODO: review this. - // We rely on the fact that tm.tm_wday is calculated - // starting from the following parameters - tm.tm_mon = month; - tm.tm_year = year; - tm.tm_mday = 1; - - currentTime = mktime(&tm); - localtime_r(¤tTime, &tm); - - return tm.tm_wday; -} - diff --git a/src/preferences/time/DateUtils.h b/src/preferences/time/DateUtils.h deleted file mode 100644 index c1d138977c..0000000000 --- a/src/preferences/time/DateUtils.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2004-2007, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * probably Mike Berg - * and/or Andrew McCall - * - */ -#ifndef CAL_HELPERS -#define CAL_HELPERS - - -bool isLeapYear(const int year); -int getDaysInMonth(const int month, const int year); -int getFirstDay(const int month, const int year); - - -#endif //CAL_HELPERS - diff --git a/src/preferences/time/Jamfile b/src/preferences/time/Jamfile index e1a5222e8a..b522cd70ba 100644 --- a/src/preferences/time/Jamfile +++ b/src/preferences/time/Jamfile @@ -9,7 +9,6 @@ Preference Time : Bitmaps.cpp CalendarView.cpp DateTimeEdit.cpp - DateUtils.cpp SectionEdit.cpp SettingsView.cpp Time.cpp @@ -17,6 +16,7 @@ Preference Time : TimeWindow.cpp TZDisplay.cpp ZoneView.cpp + DateTime.cpp : be : Time.rdef ; diff --git a/src/preferences/time/SectionEdit.cpp b/src/preferences/time/SectionEdit.cpp index 741a004d2c..8ef77bfaa3 100644 --- a/src/preferences/time/SectionEdit.cpp +++ b/src/preferences/time/SectionEdit.cpp @@ -3,7 +3,7 @@ * Distributed under the terms of the MIT License. * * Authors: - * probably Mike Berg + * Mike Berg * Julun * */ @@ -19,7 +19,6 @@ const uint32 kArrowAreaWidth = 16; -const uint32 kSeperatorWidth = 8; TSectionEdit::TSectionEdit(BRect frame, const char *name, uint32 sections) @@ -60,13 +59,12 @@ TSectionEdit::AttachedToWindow() void -TSectionEdit::Draw(BRect updaterect) +TSectionEdit::Draw(BRect updateRect) { DrawBorder(); - for (uint32 idx = 0; idx < fSectionCount; idx++) - { + for (uint32 idx = 0; idx < fSectionCount; idx++) { DrawSection(idx, ((uint32)fFocus == idx) && IsFocus()); - if (idx PostMessage(msg); + BMessage message(H_USER_CHANGE); + BuildDispatch(&message); + Window()->PostMessage(&message); } @@ -157,13 +171,15 @@ void TSectionEdit::InitView() { // create arrow bitmaps + BRect rect(0, 0, kUpArrowWidth -1, kUpArrowHeight -1); + fUpArrow = new BBitmap(rect, kUpArrowColorSpace); + fUpArrow->SetBits(kUpArrowBits, (kUpArrowWidth) *(kUpArrowHeight+1), 0 + , kUpArrowColorSpace); - fUpArrow = new BBitmap(BRect(0, 0, kUpArrowWidth -1, kUpArrowHeight -1), kUpArrowColorSpace); - fUpArrow->SetBits(kUpArrowBits, (kUpArrowWidth) *(kUpArrowHeight+1), 0, kUpArrowColorSpace); - - fDownArrow = new BBitmap(BRect(0, 0, kDownArrowWidth -1, kDownArrowHeight -2), kDownArrowColorSpace); - fDownArrow->SetBits(kDownArrowBits, (kDownArrowWidth) *(kDownArrowHeight), 0, kDownArrowColorSpace); - + rect = BRect(0, 0, kDownArrowWidth -1, kDownArrowHeight -2); + fDownArrow = new BBitmap(rect, kDownArrowColorSpace); + fDownArrow->SetBits(kDownArrowBits, (kDownArrowWidth) *(kDownArrowHeight) + , 0, kDownArrowColorSpace); // setup sections fSectionList = new BList(fSectionCount); diff --git a/src/preferences/time/SectionEdit.h b/src/preferences/time/SectionEdit.h index fed6afe254..72e0cdc612 100644 --- a/src/preferences/time/SectionEdit.h +++ b/src/preferences/time/SectionEdit.h @@ -3,7 +3,7 @@ * Distributed under the terms of the MIT License. * * Authors: - * probably Mike Berg + * Mike Berg * Julun * */ @@ -48,6 +48,7 @@ class TSectionEdit: public BControl { virtual void AttachedToWindow(); virtual void Draw(BRect updateRect); virtual void MouseDown(BPoint point); + virtual void MakeFocus(bool focused = true); virtual void KeyDown(const char *bytes, int32 numBytes); uint32 CountSections() const; diff --git a/src/preferences/time/SettingsView.cpp b/src/preferences/time/SettingsView.cpp index d274ce188d..0345df853e 100644 --- a/src/preferences/time/SettingsView.cpp +++ b/src/preferences/time/SettingsView.cpp @@ -3,8 +3,8 @@ * Distributed under the terms of the MIT License. * * Authors: - * probably Mike Berg - * and/or Andrew McCall + * Andrew McCall + * Mike Berg * Julun */ @@ -15,29 +15,31 @@ #include "TimeMessages.h" +#include #include #include #include +#include #include #include #include #include +#include -#include -#include TSettingsView::TSettingsView(BRect frame) : BView(frame,"Settings", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP), - fGmtTime(NULL) + fGmtTime(NULL), + fInitialized(false) { - InitView(); + _ReadRTCSettings(); } TSettingsView::~TSettingsView() { - WriteRTCSettings(); + _WriteRTCSettings(); } @@ -46,6 +48,35 @@ TSettingsView::AttachedToWindow() { if (Parent()) SetViewColor(Parent()->ViewColor()); + + if (!fInitialized) { + _InitView(); + fInitialized = true; + } +} + + +void +TSettingsView::Draw(BRect /*updateRect*/) +{ + rgb_color viewcolor = ViewColor(); + rgb_color dark = tint_color(viewcolor, B_DARKEN_4_TINT); + rgb_color light = tint_color(viewcolor, B_LIGHTEN_MAX_TINT); + + //draw a separator line + BRect bounds(Bounds()); + BPoint start(bounds.Width() / 2.0f + 2.0f, bounds.top + 2.0f); + BPoint end(bounds.Width() / 2.0 + 2.0f, bounds.bottom - 2.0f); + + BeginLineArray(2); + AddLine(start, end, dark); + start.x++; + end.x++; + AddLine(start, end, light); + EndLineArray(); + + fTimeEdit->Draw(bounds); + fDateEdit->Draw(bounds); } @@ -56,10 +87,9 @@ TSettingsView::MessageReceived(BMessage *message) switch(message->what) { case B_OBSERVER_NOTICE_CHANGE: message->FindInt32(B_OBSERVE_WHAT_CHANGE, &change); - switch(change) - { + switch(change) { case H_TM_CHANGED: - UpdateDateTime(message); + _UpdateDateTime(message); break; default: @@ -68,6 +98,14 @@ TSettingsView::MessageReceived(BMessage *message) } break; + case kDayChanged: + { + BMessage msg(*message); + msg.what = H_USER_CHANGE; + msg.AddBool("time", false); + Window()->PostMessage(&msg); + } break; + default: BView::MessageReceived(message); break; @@ -79,10 +117,10 @@ void TSettingsView::GetPreferredSize(float *width, float *height) { // hardcode in TimeWindow ... - *width = 361.0f; + *width = 470.0f; *height = 227.0f; - if (fGmtTime) { + if (fInitialized) { // we are initialized *width = Bounds().Width(); *height = fGmtTime->Frame().bottom; @@ -91,19 +129,17 @@ TSettingsView::GetPreferredSize(float *width, float *height) void -TSettingsView::InitView() +TSettingsView::_InitView() { - ReadRTCSettings(); - font_height fontHeight; be_plain_font->GetHeight(&fontHeight); float textHeight = fontHeight.descent + fontHeight.ascent + fontHeight.leading; // left side BRect frameLeft(Bounds()); - frameLeft.right = frameLeft.Width() / 2; + frameLeft.right = frameLeft.Width() / 2.0; frameLeft.InsetBy(10.0f, 10.0f); - frameLeft.bottom = frameLeft.top + textHeight +6; + frameLeft.bottom = frameLeft.top + textHeight + 6.0; fDateEdit = new TDateEdit(frameLeft, "date_edit", 3); AddChild(fDateEdit); @@ -111,24 +147,28 @@ TSettingsView::InitView() frameLeft.top = fDateEdit->Frame().bottom + 10; frameLeft.bottom = Bounds().bottom - 10; - fCalendar = new TCalendarView(frameLeft, "calendar", B_FOLLOW_NONE, B_WILL_DRAW); - AddChild(fCalendar); + fCalendarView = new BCalendarView(frameLeft, "calendar"); + fCalendarView->SetWeekNumberHeaderVisible(false); + AddChild(fCalendarView); + fCalendarView->SetSelectionMessage(new BMessage(kDayChanged)); + fCalendarView->SetInvocationMessage(new BMessage(kDayChanged)); + fCalendarView->SetTarget(this); - // right side + // right side BRect frameRight(Bounds()); - frameRight.left = frameRight.Width() / 2; + frameRight.left = frameRight.Width() / 2.0; frameRight.InsetBy(10.0f, 10.0f); - frameRight.bottom = frameRight.top + textHeight +6; + frameRight.bottom = frameRight.top + textHeight + 6.0; fTimeEdit = new TTimeEdit(frameRight, "time_edit", 4); AddChild(fTimeEdit); - frameRight.top = fTimeEdit->Frame().bottom + 10; - frameRight.bottom = Bounds().bottom - 10; + frameRight.top = fTimeEdit->Frame().bottom + 10.0; + frameRight.bottom = Bounds().bottom - 10.0; float left = fTimeEdit->Frame().left; float tmp = MIN(frameRight.Width(), frameRight.Height()); - frameRight.left = left + (fTimeEdit->Bounds().Width() - tmp) /2; + frameRight.left = left + (fTimeEdit->Bounds().Width() - tmp) / 2.0; frameRight.bottom = frameRight.top + tmp; frameRight.right = frameRight.left + tmp; @@ -137,13 +177,13 @@ TSettingsView::InitView() // clock radio buttons frameRight.left = left; - frameRight.top = fClock->Frame().bottom + 10; + frameRight.top = fClock->Frame().bottom + 10.0; BStringView *text = new BStringView(frameRight, "clockis", "Clock set to:"); AddChild(text); text->ResizeToPreferred(); frameRight.left += 10.0f; - frameRight.top = text->Frame().bottom + 5; + frameRight.top = text->Frame().bottom + 5.0; fLocalTime = new BRadioButton(frameRight, "local", "Local time", new BMessage(H_RTC_CHANGE)); @@ -164,66 +204,7 @@ TSettingsView::InitView() void -TSettingsView::Draw(BRect /*updateRect*/) -{ - //draw a separator line - BRect bounds(Bounds()); - - rgb_color viewcolor = ViewColor(); - rgb_color dark = tint_color(viewcolor, B_DARKEN_4_TINT); - rgb_color light = tint_color(viewcolor, B_LIGHTEN_MAX_TINT); - - BPoint start(bounds.Width() / 2.0f +2.0f, bounds.top +1.0f); - BPoint end(bounds.Width() / 2.0 +2.0f, bounds.bottom -1.0f); - - BeginLineArray(2); - AddLine(start, end, dark); - start.x++; - end.x++; - AddLine(start, end, light); - EndLineArray(); - - fTimeEdit->Draw(bounds); - fDateEdit->Draw(bounds); -} - - -bool -TSettingsView::GMTime() -{ - return fGmtTime->Value() == B_CONTROL_ON; -} - - -void -TSettingsView::UpdateDateTime(BMessage *message) -{ - int32 day; - int32 month; - int32 year; - if (message->FindInt32("month", &month) == B_OK - && message->FindInt32("day", &day) == B_OK - && message->FindInt32("year", &year) == B_OK) - { - fDateEdit->SetDate(year, month, day); - fCalendar->SetTo(year, month, day); - } - - int32 hour; - int32 minute; - int32 second; - if (message->FindInt32("hour", &hour) == B_OK - && message->FindInt32("minute", &minute) == B_OK - && message->FindInt32("second", &second) == B_OK) - { - fTimeEdit->SetTime(hour, minute, second); - fClock->SetTime(hour, minute, second); - } -} - - -void -TSettingsView::ReadRTCSettings() +TSettingsView::_ReadRTCSettings() { BPath path; if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) @@ -254,7 +235,7 @@ TSettingsView::ReadRTCSettings() void -TSettingsView::WriteRTCSettings() +TSettingsView::_WriteRTCSettings() { BPath path; if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) @@ -270,3 +251,30 @@ TSettingsView::WriteRTCSettings() file.Write("gmt", 3); } } + + +void +TSettingsView::_UpdateDateTime(BMessage *message) +{ + int32 day; + int32 month; + int32 year; + if (message->FindInt32("month", &month) == B_OK + && message->FindInt32("day", &day) == B_OK + && message->FindInt32("year", &year) == B_OK) + { + fDateEdit->SetDate(year, month, day); + fCalendarView->SetDate(year, month, day); + } + + int32 hour; + int32 minute; + int32 second; + if (message->FindInt32("hour", &hour) == B_OK + && message->FindInt32("minute", &minute) == B_OK + && message->FindInt32("second", &second) == B_OK) + { + fTimeEdit->SetTime(hour, minute, second); + fClock->SetTime(hour, minute, second); + } +} diff --git a/src/preferences/time/SettingsView.h b/src/preferences/time/SettingsView.h index b35db9a31b..92aefe06c7 100644 --- a/src/preferences/time/SettingsView.h +++ b/src/preferences/time/SettingsView.h @@ -3,8 +3,8 @@ * Distributed under the terms of the MIT License. * * Authors: - * probably Mike Berg - * and/or Andrew McCall + * Andrew McCall + * Mike Berg * Julun */ #ifndef SETTINGS_VIEW_H @@ -16,9 +16,9 @@ class TDateEdit; class TTimeEdit; -class TCalendarView; -class TAnalogClock; +class BCalendarView; class BRadioButton; +class TAnalogClock; class TSettingsView : public BView { @@ -31,21 +31,22 @@ class TSettingsView : public BView { virtual void MessageReceived(BMessage *message); virtual void GetPreferredSize(float *width, float *height); - bool GMTime(); + private: + void _InitView(); + void _ReadRTCSettings(); + void _WriteRTCSettings(); + void _UpdateDateTime(BMessage *message); private: - void InitView(); - void ReadRTCSettings(); - void WriteRTCSettings(); - void UpdateDateTime(BMessage *message); - BRadioButton *fLocalTime; BRadioButton *fGmtTime; TDateEdit *fDateEdit; TTimeEdit *fTimeEdit; - TCalendarView *fCalendar; + BCalendarView *fCalendarView; TAnalogClock *fClock; + bool fIsLocalTime; + bool fInitialized; }; #endif // SETTINGS_VIEW_H diff --git a/src/preferences/time/TZDisplay.cpp b/src/preferences/time/TZDisplay.cpp index 80fcecedf1..c24ad748f0 100644 --- a/src/preferences/time/TZDisplay.cpp +++ b/src/preferences/time/TZDisplay.cpp @@ -3,8 +3,8 @@ * Distributed under the terms of the MIT License. * * Authors: - * probably Mike Berg - * and/or Andrew McCall + * Andrew McCall + * Mike Berg * Julun * */ diff --git a/src/preferences/time/TZDisplay.h b/src/preferences/time/TZDisplay.h index b93f13ebfb..3fa1b62e5f 100644 --- a/src/preferences/time/TZDisplay.h +++ b/src/preferences/time/TZDisplay.h @@ -3,8 +3,8 @@ * Distributed under the terms of the MIT License. * * Authors: - * probably Mike Berg - * and/or Andrew McCall + * Andrew McCall + * Mike Berg * Julun * */ diff --git a/src/preferences/time/Time.cpp b/src/preferences/time/Time.cpp index 4d949da621..5c7aa79f49 100644 --- a/src/preferences/time/Time.cpp +++ b/src/preferences/time/Time.cpp @@ -4,7 +4,7 @@ * * Authors: * Andrew McCall - * Mike Berg + * Mike Berg * Julun */ diff --git a/src/preferences/time/Time.h b/src/preferences/time/Time.h index c4c43392ad..5df1d5aa3e 100644 --- a/src/preferences/time/Time.h +++ b/src/preferences/time/Time.h @@ -4,7 +4,7 @@ * * Authors: * Andrew McCall, mccall@digitalparadise.co.uk - * Mike Berg + * Mike Berg * Julun */ #ifndef TIME_H diff --git a/src/preferences/time/TimeMessages.h b/src/preferences/time/TimeMessages.h index fcc7690237..85cb99783e 100644 --- a/src/preferences/time/TimeMessages.h +++ b/src/preferences/time/TimeMessages.h @@ -4,7 +4,7 @@ * * Authors: * Andrew McCall, mccall@digitalparadise.co.uk - * Mike Berg + * Mike Berg * Julun */ #ifndef TIME_MESSAGES_H @@ -29,20 +29,20 @@ const uint32 RTC_SETTINGS = 'RTse'; // clock tick message const uint32 H_TIME_UPDATE ='obTU'; -// clicked on day in claendar -const uint32 H_DAY_CHANGED = 'obDC'; - //notice for clock ticks const uint32 H_TM_CHANGED = 'obTC'; //notice for user changes const uint32 H_USER_CHANGE = 'obUC'; -// local/gmt radiobuttons +// local/ gmt radiobuttons const uint32 H_RTC_CHANGE = 'obRC'; -// sunday/monday radio button +// sunday/ monday radio button const uint32 kWeekStart = '_kws'; +// clicked on day in calendar +const uint32 kDayChanged = '_kdc'; + #endif //TIME_MESSAGES_H diff --git a/src/preferences/time/TimeSettings.cpp b/src/preferences/time/TimeSettings.cpp index b5efc48e8d..cb4ad3a5a2 100644 --- a/src/preferences/time/TimeSettings.cpp +++ b/src/preferences/time/TimeSettings.cpp @@ -4,8 +4,9 @@ * * Authors: * Andrew McCall, mccall@digitalparadise.co.uk - * Mike Berg + * Mike Berg * Julun + * */ #include "TimeSettings.h" diff --git a/src/preferences/time/TimeSettings.h b/src/preferences/time/TimeSettings.h index 4b6eca3bae..d92ad38dd6 100644 --- a/src/preferences/time/TimeSettings.h +++ b/src/preferences/time/TimeSettings.h @@ -4,7 +4,7 @@ * * Authors: * Andrew McCall, mccall@digitalparadise.co.uk - * Mike Berg + * Mike Berg * Julun */ #ifndef TIME_SETTINGS_H diff --git a/src/preferences/time/TimeWindow.cpp b/src/preferences/time/TimeWindow.cpp index bcfeb7436c..0469940175 100644 --- a/src/preferences/time/TimeWindow.cpp +++ b/src/preferences/time/TimeWindow.cpp @@ -5,6 +5,7 @@ * Authors: * Andrew McCall * Julun + * */ #include "TimeWindow.h" @@ -20,7 +21,7 @@ #include -#define WINDOW_RIGHT 400 +#define WINDOW_RIGHT 470 #define WINDOW_BOTTOM 227 @@ -46,17 +47,9 @@ TTimeWindow::MessageReceived(BMessage *message) { switch(message->what) { case H_USER_CHANGE: - { - bool isTime; - if (message->FindBool("time", &isTime) == B_OK) - fBaseView->ChangeTime(message); + fBaseView->ChangeTime(message); break; - } - case H_RTC_CHANGE: - fBaseView->SetGMTime(fTimeSettings->GMTime()); - break; - default: BWindow::MessageReceived(message); break; @@ -114,8 +107,8 @@ TTimeWindow::_InitWindow() float width; float height; - fTimeSettings->GetPreferredSize(&width, &height); // width/ height from settingsview + all InsetBy etc.. - ResizeTo(width +5, height + tabview->TabHeight() +25); + fTimeSettings->GetPreferredSize(&width, &height); + ResizeTo(width +10, height + tabview->TabHeight() +25); } diff --git a/src/preferences/time/TimeWindow.h b/src/preferences/time/TimeWindow.h index ec3f568359..85459e4209 100644 --- a/src/preferences/time/TimeWindow.h +++ b/src/preferences/time/TimeWindow.h @@ -5,6 +5,7 @@ * Authors: * Andrew McCall * Julun + * */ #ifndef TIME_WINDOW_H #define TIME_WINDOW_H diff --git a/src/preferences/time/ZoneView.cpp b/src/preferences/time/ZoneView.cpp index 2d04cc050a..bb601b5af1 100644 --- a/src/preferences/time/ZoneView.cpp +++ b/src/preferences/time/ZoneView.cpp @@ -3,7 +3,7 @@ * Distributed under the terms of the MIT License. * * Authors: - * Mike Berg + * Mike Berg * Julun */ diff --git a/src/preferences/time/ZoneView.h b/src/preferences/time/ZoneView.h index 25a2957569..cd24b3be05 100644 --- a/src/preferences/time/ZoneView.h +++ b/src/preferences/time/ZoneView.h @@ -3,7 +3,7 @@ * Distributed under the terms of the MIT License. * * Authors: - * Mike Berg + * Mike Berg * Julun */ #ifndef ZONE_VIEW_H