178092ae7SKarsten Heimrich /* 2c8b61804SAxel Dörfler * Copyright 2007-2011, Haiku, Inc. All Rights Reserved. 378092ae7SKarsten Heimrich * Distributed under the terms of the MIT License. 478092ae7SKarsten Heimrich * 578092ae7SKarsten Heimrich * Authors: 678092ae7SKarsten Heimrich * Julun <host.haiku@gmx.de> 778092ae7SKarsten Heimrich */ 878092ae7SKarsten Heimrich 91b3303e7SAxel Dörfler 1078092ae7SKarsten Heimrich #include "CalendarView.h" 1178092ae7SKarsten Heimrich 121b3303e7SAxel Dörfler #include <stdlib.h> 1378092ae7SKarsten Heimrich 1422d88eb4SAkshay Agarwal #include <DateFormat.h> 152530274dSRyan Leavengood #include <LayoutUtils.h> 1678092ae7SKarsten Heimrich #include <Window.h> 1778092ae7SKarsten Heimrich 1878092ae7SKarsten Heimrich 1978092ae7SKarsten Heimrich namespace BPrivate { 2078092ae7SKarsten Heimrich 211b3303e7SAxel Dörfler 22c8b61804SAxel Dörfler static float 2378092ae7SKarsten Heimrich FontHeight(const BView* view) 2478092ae7SKarsten Heimrich { 2578092ae7SKarsten Heimrich if (!view) 2678092ae7SKarsten Heimrich return 0.0; 2778092ae7SKarsten Heimrich 2878092ae7SKarsten Heimrich BFont font; 2978092ae7SKarsten Heimrich view->GetFont(&font); 3078092ae7SKarsten Heimrich font_height fheight; 3178092ae7SKarsten Heimrich font.GetHeight(&fheight); 3278092ae7SKarsten Heimrich return ceilf(fheight.ascent + fheight.descent + fheight.leading); 3378092ae7SKarsten Heimrich } 341b3303e7SAxel Dörfler 35c8b61804SAxel Dörfler 36c8b61804SAxel Dörfler // #pragma mark - 3778092ae7SKarsten Heimrich 3878092ae7SKarsten Heimrich 396846765fSOliver Tappe BCalendarView::BCalendarView(BRect frame, const char* name, uint32 resizeMask, 406846765fSOliver Tappe uint32 flags) 411b3303e7SAxel Dörfler : 421b3303e7SAxel Dörfler BView(frame, name, resizeMask, flags), 4378092ae7SKarsten Heimrich BInvoker(), 4478092ae7SKarsten Heimrich fSelectionMessage(NULL), 456846765fSOliver Tappe fDate(), 468013f2e0SAkshay Agarwal fCurrentDate(BDate::CurrentDate(B_LOCAL_TIME)), 4778092ae7SKarsten Heimrich fFocusChanged(false), 4878092ae7SKarsten Heimrich fSelectionChanged(false), 498013f2e0SAkshay Agarwal fCurrentDayChanged(false), 506846765fSOliver Tappe fStartOfWeek((int32)B_WEEKDAY_MONDAY), 5178092ae7SKarsten Heimrich fDayNameHeaderVisible(true), 5278092ae7SKarsten Heimrich fWeekNumberHeaderVisible(true) 5378092ae7SKarsten Heimrich { 5478092ae7SKarsten Heimrich _InitObject(); 5578092ae7SKarsten Heimrich } 5678092ae7SKarsten Heimrich 5778092ae7SKarsten Heimrich 582530274dSRyan Leavengood BCalendarView::BCalendarView(const char* name, uint32 flags) 592530274dSRyan Leavengood : 602530274dSRyan Leavengood BView(name, flags), 612530274dSRyan Leavengood BInvoker(), 622530274dSRyan Leavengood fSelectionMessage(NULL), 636846765fSOliver Tappe fDate(), 648013f2e0SAkshay Agarwal fCurrentDate(BDate::CurrentDate(B_LOCAL_TIME)), 652530274dSRyan Leavengood fFocusChanged(false), 662530274dSRyan Leavengood fSelectionChanged(false), 678013f2e0SAkshay Agarwal fCurrentDayChanged(false), 686846765fSOliver Tappe fStartOfWeek((int32)B_WEEKDAY_MONDAY), 691e07062bSOliver Tappe fDayNameHeaderVisible(true), 701e07062bSOliver Tappe fWeekNumberHeaderVisible(true) 711e07062bSOliver Tappe { 721e07062bSOliver Tappe _InitObject(); 731e07062bSOliver Tappe } 741e07062bSOliver Tappe 751e07062bSOliver Tappe 7678092ae7SKarsten Heimrich BCalendarView::~BCalendarView() 7778092ae7SKarsten Heimrich { 7878092ae7SKarsten Heimrich SetSelectionMessage(NULL); 7978092ae7SKarsten Heimrich } 8078092ae7SKarsten Heimrich 8178092ae7SKarsten Heimrich 8278092ae7SKarsten Heimrich BCalendarView::BCalendarView(BMessage* archive) 831b3303e7SAxel Dörfler : 841b3303e7SAxel Dörfler BView(archive), 8578092ae7SKarsten Heimrich BInvoker(), 8678092ae7SKarsten Heimrich fSelectionMessage(NULL), 876846765fSOliver Tappe fDate(archive), 888013f2e0SAkshay Agarwal fCurrentDate(BDate::CurrentDate(B_LOCAL_TIME)), 8978092ae7SKarsten Heimrich fFocusChanged(false), 9078092ae7SKarsten Heimrich fSelectionChanged(false), 918013f2e0SAkshay Agarwal fCurrentDayChanged(false), 926846765fSOliver Tappe fStartOfWeek((int32)B_WEEKDAY_MONDAY), 9378092ae7SKarsten Heimrich fDayNameHeaderVisible(true), 9478092ae7SKarsten Heimrich fWeekNumberHeaderVisible(true) 9578092ae7SKarsten Heimrich { 9678092ae7SKarsten Heimrich if (archive->HasMessage("_invokeMsg")) { 9778092ae7SKarsten Heimrich BMessage* invokationMessage = new BMessage; 9878092ae7SKarsten Heimrich archive->FindMessage("_invokeMsg", invokationMessage); 9978092ae7SKarsten Heimrich SetInvocationMessage(invokationMessage); 10078092ae7SKarsten Heimrich } 10178092ae7SKarsten Heimrich 10278092ae7SKarsten Heimrich if (archive->HasMessage("_selectMsg")) { 10378092ae7SKarsten Heimrich BMessage* selectionMessage = new BMessage; 10478092ae7SKarsten Heimrich archive->FindMessage("selectMsg", selectionMessage); 10578092ae7SKarsten Heimrich SetSelectionMessage(selectionMessage); 10678092ae7SKarsten Heimrich } 10778092ae7SKarsten Heimrich 1086846765fSOliver Tappe if (archive->FindInt32("_weekStart", &fStartOfWeek) != B_OK) 1096846765fSOliver Tappe fStartOfWeek = (int32)B_WEEKDAY_MONDAY; 11078092ae7SKarsten Heimrich 11178092ae7SKarsten Heimrich if (archive->FindBool("_dayHeader", &fDayNameHeaderVisible) != B_OK) 11278092ae7SKarsten Heimrich fDayNameHeaderVisible = true; 11378092ae7SKarsten Heimrich 11478092ae7SKarsten Heimrich if (archive->FindBool("_weekHeader", &fWeekNumberHeaderVisible) != B_OK) 11578092ae7SKarsten Heimrich fWeekNumberHeaderVisible = true; 11678092ae7SKarsten Heimrich 11778092ae7SKarsten Heimrich _SetupDayNames(); 11878092ae7SKarsten Heimrich _SetupDayNumbers(); 11978092ae7SKarsten Heimrich _SetupWeekNumbers(); 12078092ae7SKarsten Heimrich } 12178092ae7SKarsten Heimrich 12278092ae7SKarsten Heimrich 12378092ae7SKarsten Heimrich BArchivable* 12478092ae7SKarsten Heimrich BCalendarView::Instantiate(BMessage* archive) 12578092ae7SKarsten Heimrich { 12678092ae7SKarsten Heimrich if (validate_instantiation(archive, "BCalendarView")) 12778092ae7SKarsten Heimrich return new BCalendarView(archive); 12878092ae7SKarsten Heimrich 12978092ae7SKarsten Heimrich return NULL; 13078092ae7SKarsten Heimrich } 13178092ae7SKarsten Heimrich 13278092ae7SKarsten Heimrich 13378092ae7SKarsten Heimrich status_t 13478092ae7SKarsten Heimrich BCalendarView::Archive(BMessage* archive, bool deep) const 13578092ae7SKarsten Heimrich { 13678092ae7SKarsten Heimrich status_t status = BView::Archive(archive, deep); 13778092ae7SKarsten Heimrich 13878092ae7SKarsten Heimrich if (status == B_OK && InvocationMessage()) 13978092ae7SKarsten Heimrich status = archive->AddMessage("_invokeMsg", InvocationMessage()); 14078092ae7SKarsten Heimrich 14178092ae7SKarsten Heimrich if (status == B_OK && SelectionMessage()) 14278092ae7SKarsten Heimrich status = archive->AddMessage("_selectMsg", SelectionMessage()); 14378092ae7SKarsten Heimrich 14478092ae7SKarsten Heimrich if (status == B_OK) 1456846765fSOliver Tappe status = fDate.Archive(archive); 14678092ae7SKarsten Heimrich 14778092ae7SKarsten Heimrich if (status == B_OK) 1486846765fSOliver Tappe status = archive->AddInt32("_weekStart", fStartOfWeek); 14978092ae7SKarsten Heimrich 15078092ae7SKarsten Heimrich if (status == B_OK) 15178092ae7SKarsten Heimrich status = archive->AddBool("_dayHeader", fDayNameHeaderVisible); 15278092ae7SKarsten Heimrich 15378092ae7SKarsten Heimrich if (status == B_OK) 15478092ae7SKarsten Heimrich status = archive->AddBool("_weekHeader", fWeekNumberHeaderVisible); 15578092ae7SKarsten Heimrich 15678092ae7SKarsten Heimrich return status; 15778092ae7SKarsten Heimrich } 15878092ae7SKarsten Heimrich 15978092ae7SKarsten Heimrich 16078092ae7SKarsten Heimrich void 16178092ae7SKarsten Heimrich BCalendarView::AttachedToWindow() 16278092ae7SKarsten Heimrich { 16378092ae7SKarsten Heimrich BView::AttachedToWindow(); 16478092ae7SKarsten Heimrich 16578092ae7SKarsten Heimrich if (!Messenger().IsValid()) 16678092ae7SKarsten Heimrich SetTarget(Window(), NULL); 16799e015b4SJanus 168f696e88aSlooncraz SetViewUIColor(B_LIST_BACKGROUND_COLOR); 16978092ae7SKarsten Heimrich } 17078092ae7SKarsten Heimrich 17178092ae7SKarsten Heimrich 17278092ae7SKarsten Heimrich void 17378092ae7SKarsten Heimrich BCalendarView::FrameResized(float width, float height) 17478092ae7SKarsten Heimrich { 17522d88eb4SAkshay Agarwal _SetupDayNames(); 17678092ae7SKarsten Heimrich Invalidate(Bounds()); 17778092ae7SKarsten Heimrich } 17878092ae7SKarsten Heimrich 17978092ae7SKarsten Heimrich 18078092ae7SKarsten Heimrich void 18178092ae7SKarsten Heimrich BCalendarView::Draw(BRect updateRect) 18278092ae7SKarsten Heimrich { 18378092ae7SKarsten Heimrich if (LockLooper()) { 18478092ae7SKarsten Heimrich if (fFocusChanged) { 18578092ae7SKarsten Heimrich _DrawFocusRect(); 18678092ae7SKarsten Heimrich UnlockLooper(); 18778092ae7SKarsten Heimrich return; 18878092ae7SKarsten Heimrich } 18978092ae7SKarsten Heimrich 19078092ae7SKarsten Heimrich if (fSelectionChanged) { 19178092ae7SKarsten Heimrich _UpdateSelection(); 19278092ae7SKarsten Heimrich UnlockLooper(); 19378092ae7SKarsten Heimrich return; 19478092ae7SKarsten Heimrich } 19578092ae7SKarsten Heimrich 1968013f2e0SAkshay Agarwal if (fCurrentDayChanged) { 1978013f2e0SAkshay Agarwal _UpdateCurrentDay(); 1988013f2e0SAkshay Agarwal UnlockLooper(); 1998013f2e0SAkshay Agarwal return; 2008013f2e0SAkshay Agarwal } 2018013f2e0SAkshay Agarwal 20278092ae7SKarsten Heimrich _DrawDays(); 20378092ae7SKarsten Heimrich _DrawDayHeader(); 20478092ae7SKarsten Heimrich _DrawWeekHeader(); 20578092ae7SKarsten Heimrich 20678092ae7SKarsten Heimrich rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR); 20778092ae7SKarsten Heimrich SetHighColor(tint_color(background, B_DARKEN_3_TINT)); 20878092ae7SKarsten Heimrich StrokeRect(Bounds()); 20978092ae7SKarsten Heimrich 21078092ae7SKarsten Heimrich UnlockLooper(); 21178092ae7SKarsten Heimrich } 21278092ae7SKarsten Heimrich } 21378092ae7SKarsten Heimrich 21478092ae7SKarsten Heimrich 21578092ae7SKarsten Heimrich void 21678092ae7SKarsten Heimrich BCalendarView::DrawDay(BView* owner, BRect frame, const char* text, 2178013f2e0SAkshay Agarwal bool isSelected, bool isEnabled, bool focus, bool highlight) 21878092ae7SKarsten Heimrich { 2198013f2e0SAkshay Agarwal _DrawItem(owner, frame, text, isSelected, isEnabled, focus, highlight); 22078092ae7SKarsten Heimrich } 22178092ae7SKarsten Heimrich 22278092ae7SKarsten Heimrich 22378092ae7SKarsten Heimrich void 22478092ae7SKarsten Heimrich BCalendarView::DrawDayName(BView* owner, BRect frame, const char* text) 22578092ae7SKarsten Heimrich { 22678092ae7SKarsten Heimrich // we get the full rect, fake this as the internal function 22778092ae7SKarsten Heimrich // shrinks the frame to work properly when drawing a day item 22878092ae7SKarsten Heimrich _DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true); 22978092ae7SKarsten Heimrich } 23078092ae7SKarsten Heimrich 23178092ae7SKarsten Heimrich 23278092ae7SKarsten Heimrich void 23378092ae7SKarsten Heimrich BCalendarView::DrawWeekNumber(BView* owner, BRect frame, const char* text) 23478092ae7SKarsten Heimrich { 23578092ae7SKarsten Heimrich // we get the full rect, fake this as the internal function 23678092ae7SKarsten Heimrich // shrinks the frame to work properly when drawing a day item 23778092ae7SKarsten Heimrich _DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true); 23878092ae7SKarsten Heimrich } 23978092ae7SKarsten Heimrich 24078092ae7SKarsten Heimrich 24178092ae7SKarsten Heimrich uint32 24278092ae7SKarsten Heimrich BCalendarView::SelectionCommand() const 24378092ae7SKarsten Heimrich { 24478092ae7SKarsten Heimrich if (SelectionMessage()) 24578092ae7SKarsten Heimrich return SelectionMessage()->what; 24678092ae7SKarsten Heimrich 24778092ae7SKarsten Heimrich return 0; 24878092ae7SKarsten Heimrich } 24978092ae7SKarsten Heimrich 25078092ae7SKarsten Heimrich 25178092ae7SKarsten Heimrich BMessage* 25278092ae7SKarsten Heimrich BCalendarView::SelectionMessage() const 25378092ae7SKarsten Heimrich { 25478092ae7SKarsten Heimrich return fSelectionMessage; 25578092ae7SKarsten Heimrich } 25678092ae7SKarsten Heimrich 25778092ae7SKarsten Heimrich 25878092ae7SKarsten Heimrich void 25978092ae7SKarsten Heimrich BCalendarView::SetSelectionMessage(BMessage* message) 26078092ae7SKarsten Heimrich { 26178092ae7SKarsten Heimrich delete fSelectionMessage; 26278092ae7SKarsten Heimrich fSelectionMessage = message; 26378092ae7SKarsten Heimrich } 26478092ae7SKarsten Heimrich 26578092ae7SKarsten Heimrich 26678092ae7SKarsten Heimrich uint32 26778092ae7SKarsten Heimrich BCalendarView::InvocationCommand() const 26878092ae7SKarsten Heimrich { 26978092ae7SKarsten Heimrich return BInvoker::Command(); 27078092ae7SKarsten Heimrich } 27178092ae7SKarsten Heimrich 27278092ae7SKarsten Heimrich 27378092ae7SKarsten Heimrich BMessage* 27478092ae7SKarsten Heimrich BCalendarView::InvocationMessage() const 27578092ae7SKarsten Heimrich { 27678092ae7SKarsten Heimrich return BInvoker::Message(); 27778092ae7SKarsten Heimrich } 27878092ae7SKarsten Heimrich 27978092ae7SKarsten Heimrich 28078092ae7SKarsten Heimrich void 28178092ae7SKarsten Heimrich BCalendarView::SetInvocationMessage(BMessage* message) 28278092ae7SKarsten Heimrich { 28378092ae7SKarsten Heimrich BInvoker::SetMessage(message); 28478092ae7SKarsten Heimrich } 28578092ae7SKarsten Heimrich 28678092ae7SKarsten Heimrich 28778092ae7SKarsten Heimrich void 28878092ae7SKarsten Heimrich BCalendarView::MakeFocus(bool state) 28978092ae7SKarsten Heimrich { 29078092ae7SKarsten Heimrich if (IsFocus() == state) 29178092ae7SKarsten Heimrich return; 29278092ae7SKarsten Heimrich 29378092ae7SKarsten Heimrich BView::MakeFocus(state); 29478092ae7SKarsten Heimrich 2951b3303e7SAxel Dörfler // TODO: solve this better 29678092ae7SKarsten Heimrich fFocusChanged = true; 29778092ae7SKarsten Heimrich Draw(_RectOfDay(fFocusedDay)); 29878092ae7SKarsten Heimrich fFocusChanged = false; 29978092ae7SKarsten Heimrich } 30078092ae7SKarsten Heimrich 30178092ae7SKarsten Heimrich 30278092ae7SKarsten Heimrich status_t 30378092ae7SKarsten Heimrich BCalendarView::Invoke(BMessage* message) 30478092ae7SKarsten Heimrich { 30578092ae7SKarsten Heimrich bool notify = false; 30678092ae7SKarsten Heimrich uint32 kind = InvokeKind(¬ify); 30778092ae7SKarsten Heimrich 30878092ae7SKarsten Heimrich BMessage clone(kind); 30978092ae7SKarsten Heimrich status_t status = B_BAD_VALUE; 31078092ae7SKarsten Heimrich 31178092ae7SKarsten Heimrich if (!message && !notify) 31278092ae7SKarsten Heimrich message = Message(); 31378092ae7SKarsten Heimrich 31478092ae7SKarsten Heimrich if (!message) { 31578092ae7SKarsten Heimrich if (!IsWatched()) 31678092ae7SKarsten Heimrich return status; 31778092ae7SKarsten Heimrich } else 31878092ae7SKarsten Heimrich clone = *message; 31978092ae7SKarsten Heimrich 32078092ae7SKarsten Heimrich clone.AddPointer("source", this); 32178092ae7SKarsten Heimrich clone.AddInt64("when", (int64)system_time()); 32278092ae7SKarsten Heimrich clone.AddMessenger("be:sender", BMessenger(this)); 32378092ae7SKarsten Heimrich 32478092ae7SKarsten Heimrich int32 year; 32578092ae7SKarsten Heimrich int32 month; 3266846765fSOliver Tappe _GetYearMonthForSelection(fSelectedDay, &year, &month); 32778092ae7SKarsten Heimrich 3286846765fSOliver Tappe clone.AddInt32("year", fDate.Year()); 3296846765fSOliver Tappe clone.AddInt32("month", fDate.Month()); 3306846765fSOliver Tappe clone.AddInt32("day", fDate.Day()); 33178092ae7SKarsten Heimrich 33278092ae7SKarsten Heimrich if (message) 33378092ae7SKarsten Heimrich status = BInvoker::Invoke(&clone); 33478092ae7SKarsten Heimrich 33578092ae7SKarsten Heimrich SendNotices(kind, &clone); 33678092ae7SKarsten Heimrich 33778092ae7SKarsten Heimrich return status; 33878092ae7SKarsten Heimrich } 33978092ae7SKarsten Heimrich 34078092ae7SKarsten Heimrich 34178092ae7SKarsten Heimrich void 34278092ae7SKarsten Heimrich BCalendarView::MouseDown(BPoint where) 34378092ae7SKarsten Heimrich { 34478092ae7SKarsten Heimrich if (!IsFocus()) { 34578092ae7SKarsten Heimrich MakeFocus(); 34678092ae7SKarsten Heimrich Sync(); 34778092ae7SKarsten Heimrich Window()->UpdateIfNeeded(); 34878092ae7SKarsten Heimrich } 34978092ae7SKarsten Heimrich 35078092ae7SKarsten Heimrich BRect frame = Bounds(); 35178092ae7SKarsten Heimrich if (fDayNameHeaderVisible) 35278092ae7SKarsten Heimrich frame.top += frame.Height() / 7 - 1.0; 35378092ae7SKarsten Heimrich 35478092ae7SKarsten Heimrich if (fWeekNumberHeaderVisible) 35578092ae7SKarsten Heimrich frame.left += frame.Width() / 8 - 1.0; 35678092ae7SKarsten Heimrich 35778092ae7SKarsten Heimrich if (!frame.Contains(where)) 35878092ae7SKarsten Heimrich return; 35978092ae7SKarsten Heimrich 36078092ae7SKarsten Heimrich // try to set to new day 36178092ae7SKarsten Heimrich frame = _SetNewSelectedDay(where); 36278092ae7SKarsten Heimrich 36378092ae7SKarsten Heimrich // on success 36478092ae7SKarsten Heimrich if (fSelectedDay != fNewSelectedDay) { 36578092ae7SKarsten Heimrich // update focus 36678092ae7SKarsten Heimrich fFocusChanged = true; 36778092ae7SKarsten Heimrich fNewFocusedDay = fNewSelectedDay; 36878092ae7SKarsten Heimrich Draw(_RectOfDay(fFocusedDay)); 36978092ae7SKarsten Heimrich fFocusChanged = false; 37078092ae7SKarsten Heimrich 37178092ae7SKarsten Heimrich // update selection 37278092ae7SKarsten Heimrich fSelectionChanged = true; 37378092ae7SKarsten Heimrich Draw(frame); 37478092ae7SKarsten Heimrich Draw(_RectOfDay(fSelectedDay)); 37578092ae7SKarsten Heimrich fSelectionChanged = false; 37678092ae7SKarsten Heimrich 37778092ae7SKarsten Heimrich // notify that selection changed 37878092ae7SKarsten Heimrich InvokeNotify(SelectionMessage(), B_CONTROL_MODIFIED); 37978092ae7SKarsten Heimrich } 38078092ae7SKarsten Heimrich 38178092ae7SKarsten Heimrich int32 clicks; 38278092ae7SKarsten Heimrich // on double click invoke 38378092ae7SKarsten Heimrich BMessage* message = Looper()->CurrentMessage(); 38478092ae7SKarsten Heimrich if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1) 38578092ae7SKarsten Heimrich Invoke(); 38678092ae7SKarsten Heimrich } 38778092ae7SKarsten Heimrich 38878092ae7SKarsten Heimrich 38978092ae7SKarsten Heimrich void 39078092ae7SKarsten Heimrich BCalendarView::KeyDown(const char* bytes, int32 numBytes) 39178092ae7SKarsten Heimrich { 39278092ae7SKarsten Heimrich const int32 kRows = 6; 39378092ae7SKarsten Heimrich const int32 kColumns = 7; 39478092ae7SKarsten Heimrich 39578092ae7SKarsten Heimrich int32 row = fFocusedDay.row; 39678092ae7SKarsten Heimrich int32 column = fFocusedDay.column; 39778092ae7SKarsten Heimrich 39878092ae7SKarsten Heimrich switch (bytes[0]) { 39978092ae7SKarsten Heimrich case B_LEFT_ARROW: 40078092ae7SKarsten Heimrich column -= 1; 40178092ae7SKarsten Heimrich if (column < 0) { 40278092ae7SKarsten Heimrich column = kColumns - 1; 40378092ae7SKarsten Heimrich row -= 1; 40478092ae7SKarsten Heimrich if (row >= 0) 40578092ae7SKarsten Heimrich fFocusChanged = true; 40678092ae7SKarsten Heimrich } else 40778092ae7SKarsten Heimrich fFocusChanged = true; 4086846765fSOliver Tappe break; 40978092ae7SKarsten Heimrich 41078092ae7SKarsten Heimrich case B_RIGHT_ARROW: 41178092ae7SKarsten Heimrich column += 1; 41278092ae7SKarsten Heimrich if (column == kColumns) { 41378092ae7SKarsten Heimrich column = 0; 41478092ae7SKarsten Heimrich row += 1; 41578092ae7SKarsten Heimrich if (row < kRows) 41678092ae7SKarsten Heimrich fFocusChanged = true; 41778092ae7SKarsten Heimrich } else 41878092ae7SKarsten Heimrich fFocusChanged = true; 4196846765fSOliver Tappe break; 42078092ae7SKarsten Heimrich 42178092ae7SKarsten Heimrich case B_UP_ARROW: 42278092ae7SKarsten Heimrich row -= 1; 42378092ae7SKarsten Heimrich if (row >= 0) 42478092ae7SKarsten Heimrich fFocusChanged = true; 4256846765fSOliver Tappe break; 42678092ae7SKarsten Heimrich 42778092ae7SKarsten Heimrich case B_DOWN_ARROW: 42878092ae7SKarsten Heimrich row += 1; 42978092ae7SKarsten Heimrich if (row < kRows) 43078092ae7SKarsten Heimrich fFocusChanged = true; 4316846765fSOliver Tappe break; 4326846765fSOliver Tappe 4336846765fSOliver Tappe case B_PAGE_UP: 4346846765fSOliver Tappe { 4356846765fSOliver Tappe BDate date(fDate); 4366846765fSOliver Tappe date.AddMonths(-1); 4376846765fSOliver Tappe SetDate(date); 4386846765fSOliver Tappe 4396846765fSOliver Tappe Invoke(); 4406846765fSOliver Tappe break; 4416846765fSOliver Tappe } 4426846765fSOliver Tappe 4436846765fSOliver Tappe case B_PAGE_DOWN: 4446846765fSOliver Tappe { 4456846765fSOliver Tappe BDate date(fDate); 4466846765fSOliver Tappe date.AddMonths(1); 4476846765fSOliver Tappe SetDate(date); 4486846765fSOliver Tappe 4496846765fSOliver Tappe Invoke(); 4506846765fSOliver Tappe break; 4516846765fSOliver Tappe } 45278092ae7SKarsten Heimrich 45378092ae7SKarsten Heimrich case B_RETURN: 4546846765fSOliver Tappe case B_SPACE: 4556846765fSOliver Tappe { 45678092ae7SKarsten Heimrich fSelectionChanged = true; 45778092ae7SKarsten Heimrich BPoint pt = _RectOfDay(fFocusedDay).LeftTop(); 45878092ae7SKarsten Heimrich Draw(_SetNewSelectedDay(pt + BPoint(4.0, 4.0))); 45978092ae7SKarsten Heimrich Draw(_RectOfDay(fSelectedDay)); 46078092ae7SKarsten Heimrich fSelectionChanged = false; 46178092ae7SKarsten Heimrich 46278092ae7SKarsten Heimrich Invoke(); 4636846765fSOliver Tappe break; 4646846765fSOliver Tappe } 46578092ae7SKarsten Heimrich 46678092ae7SKarsten Heimrich default: 46778092ae7SKarsten Heimrich BView::KeyDown(bytes, numBytes); 46878092ae7SKarsten Heimrich break; 46978092ae7SKarsten Heimrich } 47078092ae7SKarsten Heimrich 47178092ae7SKarsten Heimrich if (fFocusChanged) { 47278092ae7SKarsten Heimrich fNewFocusedDay.SetTo(row, column); 47378092ae7SKarsten Heimrich Draw(_RectOfDay(fFocusedDay)); 47478092ae7SKarsten Heimrich Draw(_RectOfDay(fNewFocusedDay)); 47578092ae7SKarsten Heimrich fFocusChanged = false; 47678092ae7SKarsten Heimrich } 47778092ae7SKarsten Heimrich } 47878092ae7SKarsten Heimrich 47978092ae7SKarsten Heimrich 48078092ae7SKarsten Heimrich void 4818013f2e0SAkshay Agarwal BCalendarView::Pulse() 4828013f2e0SAkshay Agarwal { 4838013f2e0SAkshay Agarwal _UpdateCurrentDate(); 4848013f2e0SAkshay Agarwal } 4858013f2e0SAkshay Agarwal 4868013f2e0SAkshay Agarwal 4878013f2e0SAkshay Agarwal void 48878092ae7SKarsten Heimrich BCalendarView::ResizeToPreferred() 48978092ae7SKarsten Heimrich { 49078092ae7SKarsten Heimrich float width; 49178092ae7SKarsten Heimrich float height; 49278092ae7SKarsten Heimrich 49378092ae7SKarsten Heimrich GetPreferredSize(&width, &height); 49478092ae7SKarsten Heimrich BView::ResizeTo(width, height); 49578092ae7SKarsten Heimrich } 49678092ae7SKarsten Heimrich 49778092ae7SKarsten Heimrich 49878092ae7SKarsten Heimrich void 49978092ae7SKarsten Heimrich BCalendarView::GetPreferredSize(float* width, float* height) 50078092ae7SKarsten Heimrich { 50178092ae7SKarsten Heimrich _GetPreferredSize(width, height); 50278092ae7SKarsten Heimrich } 50378092ae7SKarsten Heimrich 50478092ae7SKarsten Heimrich 5052530274dSRyan Leavengood BSize 5062530274dSRyan Leavengood BCalendarView::MaxSize() 5072530274dSRyan Leavengood { 5082530274dSRyan Leavengood return BLayoutUtils::ComposeSize(ExplicitMaxSize(), 5092530274dSRyan Leavengood BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); 5102530274dSRyan Leavengood } 5112530274dSRyan Leavengood 5122530274dSRyan Leavengood 5132530274dSRyan Leavengood BSize 5142530274dSRyan Leavengood BCalendarView::MinSize() 5152530274dSRyan Leavengood { 5162530274dSRyan Leavengood float width, height; 5172530274dSRyan Leavengood _GetPreferredSize(&width, &height); 5186846765fSOliver Tappe return BLayoutUtils::ComposeSize(ExplicitMinSize(), BSize(width, height)); 5192530274dSRyan Leavengood } 5202530274dSRyan Leavengood 5212530274dSRyan Leavengood 5222530274dSRyan Leavengood BSize 5232530274dSRyan Leavengood BCalendarView::PreferredSize() 5242530274dSRyan Leavengood { 5256846765fSOliver Tappe return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), MinSize()); 5262530274dSRyan Leavengood } 5272530274dSRyan Leavengood 5282530274dSRyan Leavengood 52978092ae7SKarsten Heimrich int32 53078092ae7SKarsten Heimrich BCalendarView::Day() const 53178092ae7SKarsten Heimrich { 5326846765fSOliver Tappe return fDate.Day(); 53378092ae7SKarsten Heimrich } 53478092ae7SKarsten Heimrich 53578092ae7SKarsten Heimrich 53678092ae7SKarsten Heimrich int32 53778092ae7SKarsten Heimrich BCalendarView::Year() const 53878092ae7SKarsten Heimrich { 53978092ae7SKarsten Heimrich int32 year; 5406846765fSOliver Tappe _GetYearMonthForSelection(fSelectedDay, &year, NULL); 54178092ae7SKarsten Heimrich 54278092ae7SKarsten Heimrich return year; 54378092ae7SKarsten Heimrich } 54478092ae7SKarsten Heimrich 54578092ae7SKarsten Heimrich 54678092ae7SKarsten Heimrich int32 54778092ae7SKarsten Heimrich BCalendarView::Month() const 54878092ae7SKarsten Heimrich { 54978092ae7SKarsten Heimrich int32 month; 5506846765fSOliver Tappe _GetYearMonthForSelection(fSelectedDay, NULL, &month); 55178092ae7SKarsten Heimrich 55278092ae7SKarsten Heimrich return month; 55378092ae7SKarsten Heimrich } 55478092ae7SKarsten Heimrich 55578092ae7SKarsten Heimrich 556afd5ec11SAdrien Destugues bool 557afd5ec11SAdrien Destugues BCalendarView::SetDay(int32 day) 558afd5ec11SAdrien Destugues { 559afd5ec11SAdrien Destugues BDate date = Date(); 560afd5ec11SAdrien Destugues date.SetDay(day); 561afd5ec11SAdrien Destugues if (!date.IsValid()) 562afd5ec11SAdrien Destugues return false; 563afd5ec11SAdrien Destugues SetDate(date); 564afd5ec11SAdrien Destugues return true; 565afd5ec11SAdrien Destugues } 566afd5ec11SAdrien Destugues 567afd5ec11SAdrien Destugues 568afd5ec11SAdrien Destugues bool 569afd5ec11SAdrien Destugues BCalendarView::SetMonth(int32 month) 570afd5ec11SAdrien Destugues { 571afd5ec11SAdrien Destugues if (month < 1 || month > 12) 572afd5ec11SAdrien Destugues return false; 573afd5ec11SAdrien Destugues BDate date = Date(); 574afd5ec11SAdrien Destugues int32 oldDay = date.Day(); 575afd5ec11SAdrien Destugues 576afd5ec11SAdrien Destugues date.SetMonth(month); 577afd5ec11SAdrien Destugues date.SetDay(1); // make sure the date is valid 578afd5ec11SAdrien Destugues 579afd5ec11SAdrien Destugues // We must make sure that the day in month fits inside the new month. 580afd5ec11SAdrien Destugues if (oldDay > date.DaysInMonth()) 581afd5ec11SAdrien Destugues date.SetDay(date.DaysInMonth()); 582afd5ec11SAdrien Destugues else 583afd5ec11SAdrien Destugues date.SetDay(oldDay); 584afd5ec11SAdrien Destugues SetDate(date); 585afd5ec11SAdrien Destugues return true; 586afd5ec11SAdrien Destugues } 587afd5ec11SAdrien Destugues 588afd5ec11SAdrien Destugues 589afd5ec11SAdrien Destugues bool 590afd5ec11SAdrien Destugues BCalendarView::SetYear(int32 year) 591afd5ec11SAdrien Destugues { 592afd5ec11SAdrien Destugues BDate date = Date(); 593afd5ec11SAdrien Destugues 594afd5ec11SAdrien Destugues // This can fail when going from 29 feb. on a leap year to a non-leap year. 595afd5ec11SAdrien Destugues if (date.Month() == 2 && date.Day() == 29 && !date.IsLeapYear(year)) 596afd5ec11SAdrien Destugues date.SetDay(28); 597afd5ec11SAdrien Destugues 598afd5ec11SAdrien Destugues // TODO we should also handle the "hole" at the switch between Julian and 599afd5ec11SAdrien Destugues // Gregorian calendars, which will result in an invalid date. 600afd5ec11SAdrien Destugues 601afd5ec11SAdrien Destugues date.SetYear(year); 602afd5ec11SAdrien Destugues SetDate(date); 603afd5ec11SAdrien Destugues return true; 604afd5ec11SAdrien Destugues } 605afd5ec11SAdrien Destugues 606afd5ec11SAdrien Destugues 60778092ae7SKarsten Heimrich BDate 60878092ae7SKarsten Heimrich BCalendarView::Date() const 60978092ae7SKarsten Heimrich { 61078092ae7SKarsten Heimrich int32 year; 61178092ae7SKarsten Heimrich int32 month; 6126846765fSOliver Tappe _GetYearMonthForSelection(fSelectedDay, &year, &month); 6136846765fSOliver Tappe return BDate(year, month, fDate.Day()); 61478092ae7SKarsten Heimrich } 61578092ae7SKarsten Heimrich 61678092ae7SKarsten Heimrich 61778092ae7SKarsten Heimrich bool 61878092ae7SKarsten Heimrich BCalendarView::SetDate(const BDate& date) 61978092ae7SKarsten Heimrich { 620c1ed5d75SKarsten Heimrich if (!date.IsValid()) 621c1ed5d75SKarsten Heimrich return false; 622c1ed5d75SKarsten Heimrich 6236846765fSOliver Tappe if (fDate == date) 62478092ae7SKarsten Heimrich return true; 62578092ae7SKarsten Heimrich 6266846765fSOliver Tappe if (fDate.Year() == date.Year() && fDate.Month() == date.Month()) { 6276846765fSOliver Tappe fDate = date; 6286846765fSOliver Tappe 62978092ae7SKarsten Heimrich _SetToDay(); 63078092ae7SKarsten Heimrich // update focus 63178092ae7SKarsten Heimrich fFocusChanged = true; 63278092ae7SKarsten Heimrich Draw(_RectOfDay(fFocusedDay)); 63378092ae7SKarsten Heimrich fFocusChanged = false; 63478092ae7SKarsten Heimrich 63578092ae7SKarsten Heimrich // update selection 63678092ae7SKarsten Heimrich fSelectionChanged = true; 63778092ae7SKarsten Heimrich Draw(_RectOfDay(fSelectedDay)); 63878092ae7SKarsten Heimrich Draw(_RectOfDay(fNewSelectedDay)); 63978092ae7SKarsten Heimrich fSelectionChanged = false; 64078092ae7SKarsten Heimrich } else { 6416846765fSOliver Tappe fDate = date; 64278092ae7SKarsten Heimrich 64378092ae7SKarsten Heimrich _SetupDayNumbers(); 64478092ae7SKarsten Heimrich _SetupWeekNumbers(); 64578092ae7SKarsten Heimrich 64678092ae7SKarsten Heimrich BRect frame = Bounds(); 64778092ae7SKarsten Heimrich if (fDayNameHeaderVisible) 64878092ae7SKarsten Heimrich frame.top += frame.Height() / 7 - 1.0; 64978092ae7SKarsten Heimrich 65078092ae7SKarsten Heimrich if (fWeekNumberHeaderVisible) 65178092ae7SKarsten Heimrich frame.left += frame.Width() / 8 - 1.0; 65278092ae7SKarsten Heimrich 65378092ae7SKarsten Heimrich Draw(frame.InsetBySelf(4.0, 4.0)); 65478092ae7SKarsten Heimrich } 65578092ae7SKarsten Heimrich 65678092ae7SKarsten Heimrich return true; 65778092ae7SKarsten Heimrich } 65878092ae7SKarsten Heimrich 65978092ae7SKarsten Heimrich 6606846765fSOliver Tappe bool 6616846765fSOliver Tappe BCalendarView::SetDate(int32 year, int32 month, int32 day) 66278092ae7SKarsten Heimrich { 6636846765fSOliver Tappe return SetDate(BDate(year, month, day)); 6646846765fSOliver Tappe } 6656846765fSOliver Tappe 6666846765fSOliver Tappe 6676846765fSOliver Tappe BWeekday 6686846765fSOliver Tappe BCalendarView::StartOfWeek() const 6696846765fSOliver Tappe { 6706846765fSOliver Tappe return BWeekday(fStartOfWeek); 67178092ae7SKarsten Heimrich } 67278092ae7SKarsten Heimrich 67378092ae7SKarsten Heimrich 67478092ae7SKarsten Heimrich void 6756846765fSOliver Tappe BCalendarView::SetStartOfWeek(BWeekday startOfWeek) 67678092ae7SKarsten Heimrich { 6776846765fSOliver Tappe if (fStartOfWeek == (int32)startOfWeek) 67878092ae7SKarsten Heimrich return; 67978092ae7SKarsten Heimrich 6806846765fSOliver Tappe fStartOfWeek = (int32)startOfWeek; 68178092ae7SKarsten Heimrich 68278092ae7SKarsten Heimrich _SetupDayNames(); 68378092ae7SKarsten Heimrich _SetupDayNumbers(); 68478092ae7SKarsten Heimrich _SetupWeekNumbers(); 68578092ae7SKarsten Heimrich 68678092ae7SKarsten Heimrich Invalidate(Bounds().InsetBySelf(1.0, 1.0)); 68778092ae7SKarsten Heimrich } 68878092ae7SKarsten Heimrich 68978092ae7SKarsten Heimrich 69078092ae7SKarsten Heimrich bool 69178092ae7SKarsten Heimrich BCalendarView::IsDayNameHeaderVisible() const 69278092ae7SKarsten Heimrich { 69378092ae7SKarsten Heimrich return fDayNameHeaderVisible; 69478092ae7SKarsten Heimrich } 69578092ae7SKarsten Heimrich 69678092ae7SKarsten Heimrich 69778092ae7SKarsten Heimrich void 69878092ae7SKarsten Heimrich BCalendarView::SetDayNameHeaderVisible(bool visible) 69978092ae7SKarsten Heimrich { 70078092ae7SKarsten Heimrich if (fDayNameHeaderVisible == visible) 70178092ae7SKarsten Heimrich return; 70278092ae7SKarsten Heimrich 70378092ae7SKarsten Heimrich fDayNameHeaderVisible = visible; 70478092ae7SKarsten Heimrich Invalidate(Bounds().InsetBySelf(1.0, 1.0)); 70578092ae7SKarsten Heimrich } 70678092ae7SKarsten Heimrich 70778092ae7SKarsten Heimrich 70822d88eb4SAkshay Agarwal void 70922d88eb4SAkshay Agarwal BCalendarView::UpdateDayNameHeader() 71022d88eb4SAkshay Agarwal { 71122d88eb4SAkshay Agarwal if (!fDayNameHeaderVisible) 71222d88eb4SAkshay Agarwal return; 71322d88eb4SAkshay Agarwal 71422d88eb4SAkshay Agarwal _SetupDayNames(); 71522d88eb4SAkshay Agarwal Invalidate(Bounds().InsetBySelf(1.0, 1.0)); 71622d88eb4SAkshay Agarwal } 71722d88eb4SAkshay Agarwal 71822d88eb4SAkshay Agarwal 71978092ae7SKarsten Heimrich bool 72078092ae7SKarsten Heimrich BCalendarView::IsWeekNumberHeaderVisible() const 72178092ae7SKarsten Heimrich { 72278092ae7SKarsten Heimrich return fWeekNumberHeaderVisible; 72378092ae7SKarsten Heimrich } 72478092ae7SKarsten Heimrich 72578092ae7SKarsten Heimrich 72678092ae7SKarsten Heimrich void 72778092ae7SKarsten Heimrich BCalendarView::SetWeekNumberHeaderVisible(bool visible) 72878092ae7SKarsten Heimrich { 72978092ae7SKarsten Heimrich if (fWeekNumberHeaderVisible == visible) 73078092ae7SKarsten Heimrich return; 73178092ae7SKarsten Heimrich 73278092ae7SKarsten Heimrich fWeekNumberHeaderVisible = visible; 73378092ae7SKarsten Heimrich Invalidate(Bounds().InsetBySelf(1.0, 1.0)); 73478092ae7SKarsten Heimrich } 73578092ae7SKarsten Heimrich 73678092ae7SKarsten Heimrich 73778092ae7SKarsten Heimrich void 73878092ae7SKarsten Heimrich BCalendarView::_InitObject() 73978092ae7SKarsten Heimrich { 7406846765fSOliver Tappe fDate = BDate::CurrentDate(B_LOCAL_TIME); 7416846765fSOliver Tappe 7420a925409SAdrien Destugues BDateFormat().GetStartOfWeek((BWeekday*)&fStartOfWeek); 74378092ae7SKarsten Heimrich 74478092ae7SKarsten Heimrich _SetupDayNames(); 74578092ae7SKarsten Heimrich _SetupDayNumbers(); 74678092ae7SKarsten Heimrich _SetupWeekNumbers(); 74778092ae7SKarsten Heimrich } 74878092ae7SKarsten Heimrich 74978092ae7SKarsten Heimrich 75078092ae7SKarsten Heimrich void 75178092ae7SKarsten Heimrich BCalendarView::_SetToDay() 75278092ae7SKarsten Heimrich { 7536846765fSOliver Tappe BDate date(fDate.Year(), fDate.Month(), 1); 75478092ae7SKarsten Heimrich if (!date.IsValid()) 75578092ae7SKarsten Heimrich return; 75678092ae7SKarsten Heimrich 7576846765fSOliver Tappe const int32 firstDayOffset = (7 + date.DayOfWeek() - fStartOfWeek) % 7; 75878092ae7SKarsten Heimrich 7596846765fSOliver Tappe int32 day = 1 - firstDayOffset; 76078092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 76178092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 7626846765fSOliver Tappe if (day == fDate.Day()) { 76378092ae7SKarsten Heimrich fNewFocusedDay.SetTo(row, column); 76478092ae7SKarsten Heimrich fNewSelectedDay.SetTo(row, column); 76578092ae7SKarsten Heimrich return; 76678092ae7SKarsten Heimrich } 7676846765fSOliver Tappe day++; 76878092ae7SKarsten Heimrich } 76978092ae7SKarsten Heimrich } 7706846765fSOliver Tappe 7716846765fSOliver Tappe fNewFocusedDay.SetTo(0, 0); 7726846765fSOliver Tappe fNewSelectedDay.SetTo(0, 0); 77378092ae7SKarsten Heimrich } 77478092ae7SKarsten Heimrich 77578092ae7SKarsten Heimrich 77678092ae7SKarsten Heimrich void 7778013f2e0SAkshay Agarwal BCalendarView::_SetToCurrentDay() 7788013f2e0SAkshay Agarwal { 779b32b6a86SAkshay Agarwal BDate date(fCurrentDate.Year(), fCurrentDate.Month(), 1); 7808013f2e0SAkshay Agarwal if (!date.IsValid()) 7818013f2e0SAkshay Agarwal return; 782b32b6a86SAkshay Agarwal if (fDate.Year() != date.Year() || fDate.Month() != date.Month()) { 783b32b6a86SAkshay Agarwal fNewCurrentDay.SetTo(-1, -1); 784b32b6a86SAkshay Agarwal return; 785b32b6a86SAkshay Agarwal } 7868013f2e0SAkshay Agarwal const int32 firstDayOffset = (7 + date.DayOfWeek() - fStartOfWeek) % 7; 7878013f2e0SAkshay Agarwal 7888013f2e0SAkshay Agarwal int32 day = 1 - firstDayOffset; 7898013f2e0SAkshay Agarwal for (int32 row = 0; row < 6; ++row) { 7908013f2e0SAkshay Agarwal for (int32 column = 0; column < 7; ++column) { 7918013f2e0SAkshay Agarwal if (day == fCurrentDate.Day()) { 7928013f2e0SAkshay Agarwal fNewCurrentDay.SetTo(row, column); 7938013f2e0SAkshay Agarwal return; 7948013f2e0SAkshay Agarwal } 7958013f2e0SAkshay Agarwal day++; 7968013f2e0SAkshay Agarwal } 7978013f2e0SAkshay Agarwal } 7988013f2e0SAkshay Agarwal 799b32b6a86SAkshay Agarwal fNewCurrentDay.SetTo(-1, -1); 8008013f2e0SAkshay Agarwal } 8018013f2e0SAkshay Agarwal 8028013f2e0SAkshay Agarwal 8038013f2e0SAkshay Agarwal void 8046846765fSOliver Tappe BCalendarView::_GetYearMonthForSelection(const Selection& selection, 8056846765fSOliver Tappe int32* year, int32* month) const 80678092ae7SKarsten Heimrich { 8076846765fSOliver Tappe BDate startOfMonth(fDate.Year(), fDate.Month(), 1); 8086846765fSOliver Tappe const int32 firstDayOffset 8096846765fSOliver Tappe = (7 + startOfMonth.DayOfWeek() - fStartOfWeek) % 7; 8106846765fSOliver Tappe const int32 daysInMonth = startOfMonth.DaysInMonth(); 81178092ae7SKarsten Heimrich 8126846765fSOliver Tappe BDate date(fDate); 8136846765fSOliver Tappe const int32 dayOffset = selection.row * 7 + selection.column; 8146846765fSOliver Tappe if (dayOffset < firstDayOffset) 8156846765fSOliver Tappe date.AddMonths(-1); 8166846765fSOliver Tappe else if (dayOffset >= firstDayOffset + daysInMonth) 8176846765fSOliver Tappe date.AddMonths(1); 8186846765fSOliver Tappe if (year != NULL) 81978092ae7SKarsten Heimrich *year = date.Year(); 8206846765fSOliver Tappe if (month != NULL) 82178092ae7SKarsten Heimrich *month = date.Month(); 82278092ae7SKarsten Heimrich } 82378092ae7SKarsten Heimrich 82478092ae7SKarsten Heimrich 82578092ae7SKarsten Heimrich void 82678092ae7SKarsten Heimrich BCalendarView::_GetPreferredSize(float* _width, float* _height) 82778092ae7SKarsten Heimrich { 82878092ae7SKarsten Heimrich BFont font; 82978092ae7SKarsten Heimrich GetFont(&font); 83078092ae7SKarsten Heimrich font_height fontHeight; 83178092ae7SKarsten Heimrich font.GetHeight(&fontHeight); 83278092ae7SKarsten Heimrich 83378092ae7SKarsten Heimrich const float height = FontHeight(this) + 4.0; 83478092ae7SKarsten Heimrich 83578092ae7SKarsten Heimrich int32 rows = 7; 83678092ae7SKarsten Heimrich if (!fDayNameHeaderVisible) 83778092ae7SKarsten Heimrich rows = 6; 83878092ae7SKarsten Heimrich 83978092ae7SKarsten Heimrich // height = font height * rows + 8 px border 84078092ae7SKarsten Heimrich *_height = height * rows + 8.0; 84178092ae7SKarsten Heimrich 84278092ae7SKarsten Heimrich float width = 0.0; 84378092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 84478092ae7SKarsten Heimrich float tmp = StringWidth(fDayNames[column].String()) + 2.0; 84578092ae7SKarsten Heimrich width = tmp > width ? tmp : width; 84678092ae7SKarsten Heimrich } 84778092ae7SKarsten Heimrich 84878092ae7SKarsten Heimrich int32 columns = 8; 84978092ae7SKarsten Heimrich if (!fWeekNumberHeaderVisible) 85078092ae7SKarsten Heimrich columns = 7; 85178092ae7SKarsten Heimrich 85278092ae7SKarsten Heimrich // width = max width day name * 8 column + 8 px border 85378092ae7SKarsten Heimrich *_width = width * columns + 8.0; 85478092ae7SKarsten Heimrich } 85578092ae7SKarsten Heimrich 85678092ae7SKarsten Heimrich 85778092ae7SKarsten Heimrich void 85878092ae7SKarsten Heimrich BCalendarView::_SetupDayNames() 85978092ae7SKarsten Heimrich { 86022d88eb4SAkshay Agarwal BDateFormatStyle style = B_LONG_DATE_FORMAT; 86122d88eb4SAkshay Agarwal float width, height; 86222d88eb4SAkshay Agarwal while (style != B_DATE_FORMAT_STYLE_COUNT) { 86322d88eb4SAkshay Agarwal _PopulateDayNames(style); 86422d88eb4SAkshay Agarwal GetPreferredSize(&width, &height); 86522d88eb4SAkshay Agarwal if (width < Bounds().Width()) 86622d88eb4SAkshay Agarwal return; 86722d88eb4SAkshay Agarwal style = static_cast<BDateFormatStyle>(static_cast<int>(style) + 1); 86822d88eb4SAkshay Agarwal } 86922d88eb4SAkshay Agarwal } 87022d88eb4SAkshay Agarwal 87122d88eb4SAkshay Agarwal 87222d88eb4SAkshay Agarwal void 87322d88eb4SAkshay Agarwal BCalendarView::_PopulateDayNames(BDateFormatStyle style) 87422d88eb4SAkshay Agarwal { 87522d88eb4SAkshay Agarwal for (int32 i = 0; i <= 6; ++i) { 87622d88eb4SAkshay Agarwal fDayNames[i] = ""; 87722d88eb4SAkshay Agarwal BDateFormat().GetDayName(1 + (fStartOfWeek - 1 + i) % 7, 87822d88eb4SAkshay Agarwal fDayNames[i], style); 87922d88eb4SAkshay Agarwal } 88078092ae7SKarsten Heimrich } 88178092ae7SKarsten Heimrich 88278092ae7SKarsten Heimrich 88378092ae7SKarsten Heimrich void 88478092ae7SKarsten Heimrich BCalendarView::_SetupDayNumbers() 88578092ae7SKarsten Heimrich { 8866846765fSOliver Tappe BDate startOfMonth(fDate.Year(), fDate.Month(), 1); 8876846765fSOliver Tappe if (!startOfMonth.IsValid()) 88878092ae7SKarsten Heimrich return; 88978092ae7SKarsten Heimrich 89078092ae7SKarsten Heimrich fFocusedDay.SetTo(0, 0); 89178092ae7SKarsten Heimrich fSelectedDay.SetTo(0, 0); 89278092ae7SKarsten Heimrich fNewFocusedDay.SetTo(0, 0); 8938013f2e0SAkshay Agarwal fCurrentDay.SetTo(-1, -1); 89478092ae7SKarsten Heimrich 8956846765fSOliver Tappe const int32 daysInMonth = startOfMonth.DaysInMonth(); 8966846765fSOliver Tappe const int32 firstDayOffset 8976846765fSOliver Tappe = (7 + startOfMonth.DayOfWeek() - fStartOfWeek) % 7; 89878092ae7SKarsten Heimrich 89978092ae7SKarsten Heimrich // calc the last day one month before 9006846765fSOliver Tappe BDate lastDayInMonthBefore(startOfMonth); 9016846765fSOliver Tappe lastDayInMonthBefore.AddDays(-1); 9026846765fSOliver Tappe const int32 lastDayBefore = lastDayInMonthBefore.DaysInMonth(); 90378092ae7SKarsten Heimrich 90478092ae7SKarsten Heimrich int32 counter = 0; 90578092ae7SKarsten Heimrich int32 firstDayAfter = 1; 90678092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 90778092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 9086846765fSOliver Tappe int32 day = 1 + counter - firstDayOffset; 9096846765fSOliver Tappe if (counter < firstDayOffset) 91078092ae7SKarsten Heimrich day += lastDayBefore; 9116846765fSOliver Tappe else if (counter >= firstDayOffset + daysInMonth) 91278092ae7SKarsten Heimrich day = firstDayAfter++; 9136846765fSOliver Tappe else if (day == fDate.Day()) { 91478092ae7SKarsten Heimrich fFocusedDay.SetTo(row, column); 91578092ae7SKarsten Heimrich fSelectedDay.SetTo(row, column); 91678092ae7SKarsten Heimrich fNewFocusedDay.SetTo(row, column); 91778092ae7SKarsten Heimrich } 918b32b6a86SAkshay Agarwal if (day == fCurrentDate.Day() && counter >= firstDayOffset 919b32b6a86SAkshay Agarwal && counter < firstDayOffset + daysInMonth 920b32b6a86SAkshay Agarwal && fDate.Month() == fCurrentDate.Month() 921b32b6a86SAkshay Agarwal && fDate.Year() == fCurrentDate.Year()) 9228013f2e0SAkshay Agarwal fCurrentDay.SetTo(row, column); 923b32b6a86SAkshay Agarwal 92478092ae7SKarsten Heimrich counter++; 9256846765fSOliver Tappe fDayNumbers[row][column].Truncate(0); 92678092ae7SKarsten Heimrich fDayNumbers[row][column] << day; 92778092ae7SKarsten Heimrich } 92878092ae7SKarsten Heimrich } 92978092ae7SKarsten Heimrich } 93078092ae7SKarsten Heimrich 9316846765fSOliver Tappe 93278092ae7SKarsten Heimrich void 93378092ae7SKarsten Heimrich BCalendarView::_SetupWeekNumbers() 93478092ae7SKarsten Heimrich { 9356846765fSOliver Tappe BDate date(fDate.Year(), fDate.Month(), 1); 93678092ae7SKarsten Heimrich if (!date.IsValid()) 93778092ae7SKarsten Heimrich return; 93878092ae7SKarsten Heimrich 939c1ed5d75SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 94078092ae7SKarsten Heimrich fWeekNumbers[row].SetTo(""); 941f0932941SMichael Pfeiffer fWeekNumbers[row] << date.WeekNumber(); 942f0932941SMichael Pfeiffer date.AddDays(7); 943c1ed5d75SKarsten Heimrich } 94478092ae7SKarsten Heimrich } 94578092ae7SKarsten Heimrich 94678092ae7SKarsten Heimrich 94778092ae7SKarsten Heimrich void 94887663db4SOliver Tappe BCalendarView::_DrawDay(int32 currRow, int32 currColumn, int32 row, 9498013f2e0SAkshay Agarwal int32 column, int32 counter, BRect frame, const char* text, 9508013f2e0SAkshay Agarwal bool focus, bool highlight) 95178092ae7SKarsten Heimrich { 9526846765fSOliver Tappe BDate startOfMonth(fDate.Year(), fDate.Month(), 1); 9536846765fSOliver Tappe const int32 firstDayOffset 9546846765fSOliver Tappe = (7 + startOfMonth.DayOfWeek() - fStartOfWeek) % 7; 9556846765fSOliver Tappe const int32 daysMonth = startOfMonth.DaysInMonth(); 95678092ae7SKarsten Heimrich 95778092ae7SKarsten Heimrich bool enabled = true; 95878092ae7SKarsten Heimrich bool selected = false; 95978092ae7SKarsten Heimrich // check for the current date 96078092ae7SKarsten Heimrich if (currRow == row && currColumn == column) { 96178092ae7SKarsten Heimrich selected = true; // draw current date selected 9626846765fSOliver Tappe if (counter <= firstDayOffset || counter > firstDayOffset + daysMonth) { 96378092ae7SKarsten Heimrich enabled = false; // days of month before or after 96478092ae7SKarsten Heimrich selected = false; // not selected but able to get focus 96578092ae7SKarsten Heimrich } 96678092ae7SKarsten Heimrich } else { 9676846765fSOliver Tappe if (counter <= firstDayOffset || counter > firstDayOffset + daysMonth) 96878092ae7SKarsten Heimrich enabled = false; // days of month before or after 96978092ae7SKarsten Heimrich } 97078092ae7SKarsten Heimrich 9718013f2e0SAkshay Agarwal DrawDay(this, frame, text, selected, enabled, focus, highlight); 97278092ae7SKarsten Heimrich } 97378092ae7SKarsten Heimrich 97478092ae7SKarsten Heimrich 97578092ae7SKarsten Heimrich void 97678092ae7SKarsten Heimrich BCalendarView::_DrawDays() 97778092ae7SKarsten Heimrich { 97878092ae7SKarsten Heimrich BRect frame = _FirstCalendarItemFrame(); 97978092ae7SKarsten Heimrich 98078092ae7SKarsten Heimrich const int32 currRow = fSelectedDay.row; 98178092ae7SKarsten Heimrich const int32 currColumn = fSelectedDay.column; 98278092ae7SKarsten Heimrich 98378092ae7SKarsten Heimrich const bool isFocus = IsFocus(); 98478092ae7SKarsten Heimrich const int32 focusRow = fFocusedDay.row; 98578092ae7SKarsten Heimrich const int32 focusColumn = fFocusedDay.column; 98678092ae7SKarsten Heimrich 9878013f2e0SAkshay Agarwal const int32 highlightRow = fCurrentDay.row; 9888013f2e0SAkshay Agarwal const int32 highlightColumn = fCurrentDay.column; 9898013f2e0SAkshay Agarwal 99078092ae7SKarsten Heimrich int32 counter = 0; 99178092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 99278092ae7SKarsten Heimrich BRect tmp = frame; 99378092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 99478092ae7SKarsten Heimrich counter++; 99578092ae7SKarsten Heimrich const char* day = fDayNumbers[row][column].String(); 99678092ae7SKarsten Heimrich bool focus = isFocus && focusRow == row && focusColumn == column; 9978013f2e0SAkshay Agarwal bool highlight = highlightRow == row && highlightColumn == column; 99887663db4SOliver Tappe _DrawDay(currRow, currColumn, row, column, counter, tmp, day, 9998013f2e0SAkshay Agarwal focus, highlight); 100078092ae7SKarsten Heimrich 100178092ae7SKarsten Heimrich tmp.OffsetBy(tmp.Width(), 0.0); 100278092ae7SKarsten Heimrich } 100378092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 100478092ae7SKarsten Heimrich } 100578092ae7SKarsten Heimrich } 100678092ae7SKarsten Heimrich 100778092ae7SKarsten Heimrich 100878092ae7SKarsten Heimrich void 100978092ae7SKarsten Heimrich BCalendarView::_DrawFocusRect() 101078092ae7SKarsten Heimrich { 101178092ae7SKarsten Heimrich BRect frame = _FirstCalendarItemFrame(); 101278092ae7SKarsten Heimrich 101378092ae7SKarsten Heimrich const int32 currRow = fSelectedDay.row; 101478092ae7SKarsten Heimrich const int32 currColumn = fSelectedDay.column; 101578092ae7SKarsten Heimrich 101678092ae7SKarsten Heimrich const int32 focusRow = fFocusedDay.row; 101778092ae7SKarsten Heimrich const int32 focusColumn = fFocusedDay.column; 101878092ae7SKarsten Heimrich 10198013f2e0SAkshay Agarwal const int32 highlightRow = fCurrentDay.row; 10208013f2e0SAkshay Agarwal const int32 highlightColumn = fCurrentDay.column; 10218013f2e0SAkshay Agarwal 102278092ae7SKarsten Heimrich int32 counter = 0; 102378092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 102478092ae7SKarsten Heimrich BRect tmp = frame; 102578092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 102678092ae7SKarsten Heimrich counter++; 102778092ae7SKarsten Heimrich if (fNewFocusedDay.row == row && fNewFocusedDay.column == column) { 102878092ae7SKarsten Heimrich fFocusedDay.SetTo(row, column); 102978092ae7SKarsten Heimrich 103078092ae7SKarsten Heimrich bool focus = IsFocus() && true; 10318013f2e0SAkshay Agarwal bool highlight = highlightRow == row && highlightColumn == column; 103278092ae7SKarsten Heimrich const char* day = fDayNumbers[row][column].String(); 103387663db4SOliver Tappe _DrawDay(currRow, currColumn, row, column, counter, tmp, day, 10348013f2e0SAkshay Agarwal focus, highlight); 10356846765fSOliver Tappe } else if (focusRow == row && focusColumn == column) { 103678092ae7SKarsten Heimrich const char* day = fDayNumbers[row][column].String(); 10378013f2e0SAkshay Agarwal bool highlight = highlightRow == row && highlightColumn == column; 103887663db4SOliver Tappe _DrawDay(currRow, currColumn, row, column, counter, tmp, day, 10398013f2e0SAkshay Agarwal false, highlight); 104078092ae7SKarsten Heimrich } 104178092ae7SKarsten Heimrich tmp.OffsetBy(tmp.Width(), 0.0); 104278092ae7SKarsten Heimrich } 104378092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 104478092ae7SKarsten Heimrich } 104578092ae7SKarsten Heimrich } 104678092ae7SKarsten Heimrich 104778092ae7SKarsten Heimrich 104878092ae7SKarsten Heimrich void 104978092ae7SKarsten Heimrich BCalendarView::_DrawDayHeader() 105078092ae7SKarsten Heimrich { 105178092ae7SKarsten Heimrich if (!fDayNameHeaderVisible) 105278092ae7SKarsten Heimrich return; 105378092ae7SKarsten Heimrich 105478092ae7SKarsten Heimrich int32 offset = 1; 105578092ae7SKarsten Heimrich int32 columns = 8; 105678092ae7SKarsten Heimrich if (!fWeekNumberHeaderVisible) { 105778092ae7SKarsten Heimrich offset = 0; 105878092ae7SKarsten Heimrich columns = 7; 105978092ae7SKarsten Heimrich } 106078092ae7SKarsten Heimrich 106178092ae7SKarsten Heimrich BRect frame = Bounds(); 106278092ae7SKarsten Heimrich frame.right = frame.Width() / columns - 1.0; 106378092ae7SKarsten Heimrich frame.bottom = frame.Height() / 7.0 - 2.0; 106478092ae7SKarsten Heimrich frame.OffsetBy(4.0, 4.0); 106578092ae7SKarsten Heimrich 106678092ae7SKarsten Heimrich for (int32 i = 0; i < columns; ++i) { 106778092ae7SKarsten Heimrich if (i == 0 && fWeekNumberHeaderVisible) { 106878092ae7SKarsten Heimrich DrawDayName(this, frame, ""); 106978092ae7SKarsten Heimrich frame.OffsetBy(frame.Width(), 0.0); 107078092ae7SKarsten Heimrich continue; 107178092ae7SKarsten Heimrich } 107278092ae7SKarsten Heimrich DrawDayName(this, frame, fDayNames[i - offset].String()); 107378092ae7SKarsten Heimrich frame.OffsetBy(frame.Width(), 0.0); 107478092ae7SKarsten Heimrich } 107578092ae7SKarsten Heimrich } 107678092ae7SKarsten Heimrich 107778092ae7SKarsten Heimrich 107878092ae7SKarsten Heimrich void 107978092ae7SKarsten Heimrich BCalendarView::_DrawWeekHeader() 108078092ae7SKarsten Heimrich { 108178092ae7SKarsten Heimrich if (!fWeekNumberHeaderVisible) 108278092ae7SKarsten Heimrich return; 108378092ae7SKarsten Heimrich 108478092ae7SKarsten Heimrich int32 rows = 7; 108578092ae7SKarsten Heimrich if (!fDayNameHeaderVisible) 108678092ae7SKarsten Heimrich rows = 6; 108778092ae7SKarsten Heimrich 108878092ae7SKarsten Heimrich BRect frame = Bounds(); 108978092ae7SKarsten Heimrich frame.right = frame.Width() / 8.0 - 2.0; 109078092ae7SKarsten Heimrich frame.bottom = frame.Height() / rows - 1.0; 109178092ae7SKarsten Heimrich 109278092ae7SKarsten Heimrich float offsetY = 4.0; 109378092ae7SKarsten Heimrich if (fDayNameHeaderVisible) 109478092ae7SKarsten Heimrich offsetY += frame.Height(); 109578092ae7SKarsten Heimrich 109678092ae7SKarsten Heimrich frame.OffsetBy(4.0, offsetY); 109778092ae7SKarsten Heimrich 109878092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 109978092ae7SKarsten Heimrich DrawWeekNumber(this, frame, fWeekNumbers[row].String()); 110078092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 110178092ae7SKarsten Heimrich } 110278092ae7SKarsten Heimrich } 110378092ae7SKarsten Heimrich 110478092ae7SKarsten Heimrich 110578092ae7SKarsten Heimrich void 110678092ae7SKarsten Heimrich BCalendarView::_DrawItem(BView* owner, BRect frame, const char* text, 11078013f2e0SAkshay Agarwal bool isSelected, bool isEnabled, bool focus, bool isHighlight) 110878092ae7SKarsten Heimrich { 110978092ae7SKarsten Heimrich rgb_color lColor = LowColor(); 111078092ae7SKarsten Heimrich rgb_color highColor = HighColor(); 111178092ae7SKarsten Heimrich 111299e015b4SJanus rgb_color textColor = ui_color(B_LIST_ITEM_TEXT_COLOR); 1113*9d30b95aSHumdinger rgb_color bgColor = ui_color(B_LIST_BACKGROUND_COLOR); 111499e015b4SJanus float tintDisabled = B_LIGHTEN_2_TINT; 1115*9d30b95aSHumdinger float tintHighlight = B_LIGHTEN_1_TINT; 111699e015b4SJanus 111799e015b4SJanus if (textColor.red + textColor.green + textColor.blue > 125 * 3) 111899e015b4SJanus tintDisabled = B_DARKEN_2_TINT; 111978092ae7SKarsten Heimrich 1120*9d30b95aSHumdinger if (bgColor.red + bgColor.green + bgColor.blue > 125 * 3) 1121*9d30b95aSHumdinger tintHighlight = B_DARKEN_1_TINT; 1122*9d30b95aSHumdinger 112378092ae7SKarsten Heimrich if (isSelected) { 112499e015b4SJanus SetHighColor(ui_color(B_LIST_SELECTED_BACKGROUND_COLOR)); 112599e015b4SJanus textColor = ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR); 1126*9d30b95aSHumdinger } else if (isHighlight) 1127*9d30b95aSHumdinger SetHighColor(tint_color(bgColor, tintHighlight)); 1128*9d30b95aSHumdinger else 1129*9d30b95aSHumdinger SetHighColor(bgColor); 11308013f2e0SAkshay Agarwal 113199e015b4SJanus SetLowColor(HighColor()); 113278092ae7SKarsten Heimrich 113378092ae7SKarsten Heimrich FillRect(frame.InsetByCopy(1.0, 1.0)); 113478092ae7SKarsten Heimrich 113578092ae7SKarsten Heimrich if (focus) { 1136*9d30b95aSHumdinger rgb_color focusColor = keyboard_navigation_color(); 1137*9d30b95aSHumdinger SetHighColor(focusColor); 113878092ae7SKarsten Heimrich StrokeRect(frame.InsetByCopy(1.0, 1.0)); 1139*9d30b95aSHumdinger 1140*9d30b95aSHumdinger if (!isSelected) 1141*9d30b95aSHumdinger textColor = focusColor; 114278092ae7SKarsten Heimrich } 114378092ae7SKarsten Heimrich 114499e015b4SJanus SetHighColor(textColor); 114578092ae7SKarsten Heimrich if (!isEnabled) 114699e015b4SJanus SetHighColor(tint_color(textColor, tintDisabled)); 114778092ae7SKarsten Heimrich 114878092ae7SKarsten Heimrich float offsetH = frame.Width() / 2.0; 11496846765fSOliver Tappe float offsetV = frame.Height() / 2.0 + FontHeight(owner) / 2.0 - 2.0; 115078092ae7SKarsten Heimrich 1151*9d30b95aSHumdinger BFont font(be_plain_font); 1152*9d30b95aSHumdinger if (isHighlight) 1153*9d30b95aSHumdinger font.SetFace(B_BOLD_FACE); 1154*9d30b95aSHumdinger else 1155*9d30b95aSHumdinger font.SetFace(B_REGULAR_FACE); 1156*9d30b95aSHumdinger SetFont(&font); 1157*9d30b95aSHumdinger 11586846765fSOliver Tappe DrawString(text, BPoint(frame.right - offsetH - StringWidth(text) / 2.0, 11596846765fSOliver Tappe frame.top + offsetV)); 116078092ae7SKarsten Heimrich 116178092ae7SKarsten Heimrich SetLowColor(lColor); 116278092ae7SKarsten Heimrich SetHighColor(highColor); 116378092ae7SKarsten Heimrich } 116478092ae7SKarsten Heimrich 116578092ae7SKarsten Heimrich 116678092ae7SKarsten Heimrich void 116778092ae7SKarsten Heimrich BCalendarView::_UpdateSelection() 116878092ae7SKarsten Heimrich { 116978092ae7SKarsten Heimrich BRect frame = _FirstCalendarItemFrame(); 117078092ae7SKarsten Heimrich 117178092ae7SKarsten Heimrich const int32 currRow = fSelectedDay.row; 117278092ae7SKarsten Heimrich const int32 currColumn = fSelectedDay.column; 117378092ae7SKarsten Heimrich 117478092ae7SKarsten Heimrich const int32 focusRow = fFocusedDay.row; 117578092ae7SKarsten Heimrich const int32 focusColumn = fFocusedDay.column; 117678092ae7SKarsten Heimrich 11778013f2e0SAkshay Agarwal const int32 highlightRow = fCurrentDay.row; 11788013f2e0SAkshay Agarwal const int32 highlightColumn = fCurrentDay.column; 11798013f2e0SAkshay Agarwal 118078092ae7SKarsten Heimrich int32 counter = 0; 118178092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 118278092ae7SKarsten Heimrich BRect tmp = frame; 118378092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 118478092ae7SKarsten Heimrich counter++; 118587663db4SOliver Tappe if (fNewSelectedDay.row == row 118687663db4SOliver Tappe && fNewSelectedDay.column == column) { 118778092ae7SKarsten Heimrich fSelectedDay.SetTo(row, column); 118878092ae7SKarsten Heimrich 118978092ae7SKarsten Heimrich const char* day = fDayNumbers[row][column].String(); 119087663db4SOliver Tappe bool focus = IsFocus() && focusRow == row 119187663db4SOliver Tappe && focusColumn == column; 11928013f2e0SAkshay Agarwal bool highlight = highlightRow == row && highlightColumn == column; 11938013f2e0SAkshay Agarwal _DrawDay(row, column, row, column, counter, tmp, day, focus, highlight); 11946846765fSOliver Tappe } else if (currRow == row && currColumn == column) { 119578092ae7SKarsten Heimrich const char* day = fDayNumbers[row][column].String(); 119687663db4SOliver Tappe bool focus = IsFocus() && focusRow == row 119787663db4SOliver Tappe && focusColumn == column; 11988013f2e0SAkshay Agarwal bool highlight = highlightRow == row && highlightColumn == column; 11998013f2e0SAkshay Agarwal _DrawDay(currRow, currColumn, -1, -1, counter, tmp, day, focus, highlight); 120078092ae7SKarsten Heimrich } 120178092ae7SKarsten Heimrich tmp.OffsetBy(tmp.Width(), 0.0); 120278092ae7SKarsten Heimrich } 120378092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 120478092ae7SKarsten Heimrich } 120578092ae7SKarsten Heimrich } 120678092ae7SKarsten Heimrich 120778092ae7SKarsten Heimrich 12088013f2e0SAkshay Agarwal void 12098013f2e0SAkshay Agarwal BCalendarView::_UpdateCurrentDay() 12108013f2e0SAkshay Agarwal { 12118013f2e0SAkshay Agarwal BRect frame = _FirstCalendarItemFrame(); 12128013f2e0SAkshay Agarwal 12138013f2e0SAkshay Agarwal const int32 selectRow = fSelectedDay.row; 12148013f2e0SAkshay Agarwal const int32 selectColumn = fSelectedDay.column; 12158013f2e0SAkshay Agarwal 12168013f2e0SAkshay Agarwal const int32 focusRow = fFocusedDay.row; 12178013f2e0SAkshay Agarwal const int32 focusColumn = fFocusedDay.column; 12188013f2e0SAkshay Agarwal 12198013f2e0SAkshay Agarwal const int32 currRow = fCurrentDay.row; 12208013f2e0SAkshay Agarwal const int32 currColumn = fCurrentDay.column; 12218013f2e0SAkshay Agarwal 12228013f2e0SAkshay Agarwal int32 counter = 0; 12238013f2e0SAkshay Agarwal for (int32 row = 0; row < 6; ++row) { 12248013f2e0SAkshay Agarwal BRect tmp = frame; 12258013f2e0SAkshay Agarwal for (int32 column = 0; column < 7; ++column) { 12268013f2e0SAkshay Agarwal counter++; 12278013f2e0SAkshay Agarwal if (fNewCurrentDay.row == row 12288013f2e0SAkshay Agarwal && fNewCurrentDay.column == column) { 12298013f2e0SAkshay Agarwal fCurrentDay.SetTo(row, column); 12308013f2e0SAkshay Agarwal 12318013f2e0SAkshay Agarwal const char* day = fDayNumbers[row][column].String(); 12328013f2e0SAkshay Agarwal bool focus = IsFocus() && focusRow == row 12338013f2e0SAkshay Agarwal && focusColumn == column; 12348013f2e0SAkshay Agarwal bool isSelected = selectRow == row && selectColumn == column; 12358013f2e0SAkshay Agarwal if (isSelected) 12368013f2e0SAkshay Agarwal _DrawDay(row, column, row, column, counter, tmp, day, focus, true); 12378013f2e0SAkshay Agarwal else 12388013f2e0SAkshay Agarwal _DrawDay(row, column, -1, -1, counter, tmp, day, focus, true); 12398013f2e0SAkshay Agarwal 12408013f2e0SAkshay Agarwal } else if (currRow == row && currColumn == column) { 12418013f2e0SAkshay Agarwal const char* day = fDayNumbers[row][column].String(); 12428013f2e0SAkshay Agarwal bool focus = IsFocus() && focusRow == row 12438013f2e0SAkshay Agarwal && focusColumn == column; 12448013f2e0SAkshay Agarwal bool isSelected = selectRow == row && selectColumn == column; 12458013f2e0SAkshay Agarwal if(isSelected) 12468013f2e0SAkshay Agarwal _DrawDay(currRow, currColumn, row, column, counter, tmp, day, focus, false); 12478013f2e0SAkshay Agarwal else 12488013f2e0SAkshay Agarwal _DrawDay(currRow, currColumn, -1, -1, counter, tmp, day, focus, false); 12498013f2e0SAkshay Agarwal } 12508013f2e0SAkshay Agarwal tmp.OffsetBy(tmp.Width(), 0.0); 12518013f2e0SAkshay Agarwal } 12528013f2e0SAkshay Agarwal frame.OffsetBy(0.0, frame.Height()); 12538013f2e0SAkshay Agarwal } 12548013f2e0SAkshay Agarwal } 12558013f2e0SAkshay Agarwal 12568013f2e0SAkshay Agarwal 12578013f2e0SAkshay Agarwal void 12588013f2e0SAkshay Agarwal BCalendarView::_UpdateCurrentDate() 12598013f2e0SAkshay Agarwal { 12608013f2e0SAkshay Agarwal BDate date = BDate::CurrentDate(B_LOCAL_TIME); 12618013f2e0SAkshay Agarwal 12628013f2e0SAkshay Agarwal if (!date.IsValid()) 12638013f2e0SAkshay Agarwal return; 12648013f2e0SAkshay Agarwal if (date == fCurrentDate) 12658013f2e0SAkshay Agarwal return; 12668013f2e0SAkshay Agarwal 12678013f2e0SAkshay Agarwal fCurrentDate = date; 12688013f2e0SAkshay Agarwal 12698013f2e0SAkshay Agarwal _SetToCurrentDay(); 12708013f2e0SAkshay Agarwal fCurrentDayChanged = true; 12718013f2e0SAkshay Agarwal Draw(_RectOfDay(fCurrentDay)); 12728013f2e0SAkshay Agarwal Draw(_RectOfDay(fNewCurrentDay)); 12738013f2e0SAkshay Agarwal fCurrentDayChanged = false; 12748013f2e0SAkshay Agarwal 12758013f2e0SAkshay Agarwal return; 12768013f2e0SAkshay Agarwal } 12778013f2e0SAkshay Agarwal 12788013f2e0SAkshay Agarwal 127978092ae7SKarsten Heimrich BRect 128078092ae7SKarsten Heimrich BCalendarView::_FirstCalendarItemFrame() const 128178092ae7SKarsten Heimrich { 128278092ae7SKarsten Heimrich int32 rows = 7; 128378092ae7SKarsten Heimrich int32 columns = 8; 128478092ae7SKarsten Heimrich 128578092ae7SKarsten Heimrich if (!fDayNameHeaderVisible) 128678092ae7SKarsten Heimrich rows = 6; 128778092ae7SKarsten Heimrich 128878092ae7SKarsten Heimrich if (!fWeekNumberHeaderVisible) 128978092ae7SKarsten Heimrich columns = 7; 129078092ae7SKarsten Heimrich 129178092ae7SKarsten Heimrich BRect frame = Bounds(); 129278092ae7SKarsten Heimrich frame.right = frame.Width() / columns - 1.0; 129378092ae7SKarsten Heimrich frame.bottom = frame.Height() / rows - 1.0; 129478092ae7SKarsten Heimrich 129578092ae7SKarsten Heimrich float offsetY = 4.0; 129678092ae7SKarsten Heimrich if (fDayNameHeaderVisible) 129778092ae7SKarsten Heimrich offsetY += frame.Height(); 129878092ae7SKarsten Heimrich 129978092ae7SKarsten Heimrich float offsetX = 4.0; 130078092ae7SKarsten Heimrich if (fWeekNumberHeaderVisible) 130178092ae7SKarsten Heimrich offsetX += frame.Width(); 130278092ae7SKarsten Heimrich 130378092ae7SKarsten Heimrich return frame.OffsetBySelf(offsetX, offsetY); 130478092ae7SKarsten Heimrich } 130578092ae7SKarsten Heimrich 130678092ae7SKarsten Heimrich 130778092ae7SKarsten Heimrich BRect 130878092ae7SKarsten Heimrich BCalendarView::_SetNewSelectedDay(const BPoint& where) 130978092ae7SKarsten Heimrich { 131078092ae7SKarsten Heimrich BRect frame = _FirstCalendarItemFrame(); 131178092ae7SKarsten Heimrich 131278092ae7SKarsten Heimrich int32 counter = 0; 131378092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 131478092ae7SKarsten Heimrich BRect tmp = frame; 131578092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 131678092ae7SKarsten Heimrich counter++; 131778092ae7SKarsten Heimrich if (tmp.Contains(where)) { 131878092ae7SKarsten Heimrich fNewSelectedDay.SetTo(row, column); 13196846765fSOliver Tappe int32 year; 13206846765fSOliver Tappe int32 month; 13216846765fSOliver Tappe _GetYearMonthForSelection(fNewSelectedDay, &year, &month); 13226846765fSOliver Tappe if (month == fDate.Month()) { 13236846765fSOliver Tappe // only change date if a day in the current month has been 13246846765fSOliver Tappe // selected 13256846765fSOliver Tappe int32 day = atoi(fDayNumbers[row][column].String()); 13266846765fSOliver Tappe fDate.SetDate(year, month, day); 13276846765fSOliver Tappe } 132878092ae7SKarsten Heimrich return tmp; 132978092ae7SKarsten Heimrich } 133078092ae7SKarsten Heimrich tmp.OffsetBy(tmp.Width(), 0.0); 133178092ae7SKarsten Heimrich } 133278092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 133378092ae7SKarsten Heimrich } 133478092ae7SKarsten Heimrich 133578092ae7SKarsten Heimrich return frame; 133678092ae7SKarsten Heimrich } 133778092ae7SKarsten Heimrich 133878092ae7SKarsten Heimrich 133978092ae7SKarsten Heimrich BRect 134078092ae7SKarsten Heimrich BCalendarView::_RectOfDay(const Selection& selection) const 134178092ae7SKarsten Heimrich { 134278092ae7SKarsten Heimrich BRect frame = _FirstCalendarItemFrame(); 134378092ae7SKarsten Heimrich 134478092ae7SKarsten Heimrich int32 counter = 0; 134578092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 134678092ae7SKarsten Heimrich BRect tmp = frame; 134778092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 134878092ae7SKarsten Heimrich counter++; 13496846765fSOliver Tappe if (selection.row == row && selection.column == column) 135078092ae7SKarsten Heimrich return tmp; 135178092ae7SKarsten Heimrich tmp.OffsetBy(tmp.Width(), 0.0); 135278092ae7SKarsten Heimrich } 135378092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 135478092ae7SKarsten Heimrich } 135578092ae7SKarsten Heimrich 135678092ae7SKarsten Heimrich return frame; 135778092ae7SKarsten Heimrich } 135878092ae7SKarsten Heimrich 135978092ae7SKarsten Heimrich 136078092ae7SKarsten Heimrich } // namespace BPrivate 1361