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 142530274dSRyan Leavengood #include <LayoutUtils.h> 1578092ae7SKarsten Heimrich #include <Window.h> 1678092ae7SKarsten Heimrich 1778092ae7SKarsten Heimrich 1878092ae7SKarsten Heimrich namespace BPrivate { 1978092ae7SKarsten Heimrich 201b3303e7SAxel Dörfler 21c8b61804SAxel Dörfler static float 2278092ae7SKarsten Heimrich FontHeight(const BView* view) 2378092ae7SKarsten Heimrich { 2478092ae7SKarsten Heimrich if (!view) 2578092ae7SKarsten Heimrich return 0.0; 2678092ae7SKarsten Heimrich 2778092ae7SKarsten Heimrich BFont font; 2878092ae7SKarsten Heimrich view->GetFont(&font); 2978092ae7SKarsten Heimrich font_height fheight; 3078092ae7SKarsten Heimrich font.GetHeight(&fheight); 3178092ae7SKarsten Heimrich return ceilf(fheight.ascent + fheight.descent + fheight.leading); 3278092ae7SKarsten Heimrich } 331b3303e7SAxel Dörfler 34c8b61804SAxel Dörfler 35c8b61804SAxel Dörfler // #pragma mark - 3678092ae7SKarsten Heimrich 3778092ae7SKarsten Heimrich 38*6846765fSOliver Tappe BCalendarView::BCalendarView(BRect frame, const char* name, uint32 resizeMask, 39*6846765fSOliver Tappe uint32 flags) 401b3303e7SAxel Dörfler : 411b3303e7SAxel Dörfler BView(frame, name, resizeMask, flags), 4278092ae7SKarsten Heimrich BInvoker(), 4378092ae7SKarsten Heimrich fSelectionMessage(NULL), 44*6846765fSOliver Tappe fDate(), 4578092ae7SKarsten Heimrich fFocusChanged(false), 4678092ae7SKarsten Heimrich fSelectionChanged(false), 47*6846765fSOliver Tappe fStartOfWeek((int32)B_WEEKDAY_MONDAY), 4878092ae7SKarsten Heimrich fDayNameHeaderVisible(true), 4978092ae7SKarsten Heimrich fWeekNumberHeaderVisible(true) 5078092ae7SKarsten Heimrich { 5178092ae7SKarsten Heimrich _InitObject(); 5278092ae7SKarsten Heimrich } 5378092ae7SKarsten Heimrich 5478092ae7SKarsten Heimrich 552530274dSRyan Leavengood BCalendarView::BCalendarView(const char* name, uint32 flags) 562530274dSRyan Leavengood : 572530274dSRyan Leavengood BView(name, flags), 582530274dSRyan Leavengood BInvoker(), 592530274dSRyan Leavengood fSelectionMessage(NULL), 60*6846765fSOliver Tappe fDate(), 612530274dSRyan Leavengood fFocusChanged(false), 622530274dSRyan Leavengood fSelectionChanged(false), 63*6846765fSOliver Tappe fStartOfWeek((int32)B_WEEKDAY_MONDAY), 641e07062bSOliver Tappe fDayNameHeaderVisible(true), 651e07062bSOliver Tappe fWeekNumberHeaderVisible(true) 661e07062bSOliver Tappe { 671e07062bSOliver Tappe _InitObject(); 681e07062bSOliver Tappe } 691e07062bSOliver Tappe 701e07062bSOliver Tappe 7178092ae7SKarsten Heimrich BCalendarView::~BCalendarView() 7278092ae7SKarsten Heimrich { 7378092ae7SKarsten Heimrich SetSelectionMessage(NULL); 7478092ae7SKarsten Heimrich } 7578092ae7SKarsten Heimrich 7678092ae7SKarsten Heimrich 7778092ae7SKarsten Heimrich BCalendarView::BCalendarView(BMessage* archive) 781b3303e7SAxel Dörfler : 791b3303e7SAxel Dörfler BView(archive), 8078092ae7SKarsten Heimrich BInvoker(), 8178092ae7SKarsten Heimrich fSelectionMessage(NULL), 82*6846765fSOliver Tappe fDate(archive), 8378092ae7SKarsten Heimrich fFocusChanged(false), 8478092ae7SKarsten Heimrich fSelectionChanged(false), 85*6846765fSOliver Tappe fStartOfWeek((int32)B_WEEKDAY_MONDAY), 8678092ae7SKarsten Heimrich fDayNameHeaderVisible(true), 8778092ae7SKarsten Heimrich fWeekNumberHeaderVisible(true) 8878092ae7SKarsten Heimrich { 8978092ae7SKarsten Heimrich if (archive->HasMessage("_invokeMsg")) { 9078092ae7SKarsten Heimrich BMessage* invokationMessage = new BMessage; 9178092ae7SKarsten Heimrich archive->FindMessage("_invokeMsg", invokationMessage); 9278092ae7SKarsten Heimrich SetInvocationMessage(invokationMessage); 9378092ae7SKarsten Heimrich } 9478092ae7SKarsten Heimrich 9578092ae7SKarsten Heimrich if (archive->HasMessage("_selectMsg")) { 9678092ae7SKarsten Heimrich BMessage* selectionMessage = new BMessage; 9778092ae7SKarsten Heimrich archive->FindMessage("selectMsg", selectionMessage); 9878092ae7SKarsten Heimrich SetSelectionMessage(selectionMessage); 9978092ae7SKarsten Heimrich } 10078092ae7SKarsten Heimrich 101*6846765fSOliver Tappe if (archive->FindInt32("_weekStart", &fStartOfWeek) != B_OK) 102*6846765fSOliver Tappe fStartOfWeek = (int32)B_WEEKDAY_MONDAY; 10378092ae7SKarsten Heimrich 10478092ae7SKarsten Heimrich if (archive->FindBool("_dayHeader", &fDayNameHeaderVisible) != B_OK) 10578092ae7SKarsten Heimrich fDayNameHeaderVisible = true; 10678092ae7SKarsten Heimrich 10778092ae7SKarsten Heimrich if (archive->FindBool("_weekHeader", &fWeekNumberHeaderVisible) != B_OK) 10878092ae7SKarsten Heimrich fWeekNumberHeaderVisible = true; 10978092ae7SKarsten Heimrich 11078092ae7SKarsten Heimrich _SetupDayNames(); 11178092ae7SKarsten Heimrich _SetupDayNumbers(); 11278092ae7SKarsten Heimrich _SetupWeekNumbers(); 11378092ae7SKarsten Heimrich } 11478092ae7SKarsten Heimrich 11578092ae7SKarsten Heimrich 11678092ae7SKarsten Heimrich BArchivable* 11778092ae7SKarsten Heimrich BCalendarView::Instantiate(BMessage* archive) 11878092ae7SKarsten Heimrich { 11978092ae7SKarsten Heimrich if (validate_instantiation(archive, "BCalendarView")) 12078092ae7SKarsten Heimrich return new BCalendarView(archive); 12178092ae7SKarsten Heimrich 12278092ae7SKarsten Heimrich return NULL; 12378092ae7SKarsten Heimrich } 12478092ae7SKarsten Heimrich 12578092ae7SKarsten Heimrich 12678092ae7SKarsten Heimrich status_t 12778092ae7SKarsten Heimrich BCalendarView::Archive(BMessage* archive, bool deep) const 12878092ae7SKarsten Heimrich { 12978092ae7SKarsten Heimrich status_t status = BView::Archive(archive, deep); 13078092ae7SKarsten Heimrich 13178092ae7SKarsten Heimrich if (status == B_OK && InvocationMessage()) 13278092ae7SKarsten Heimrich status = archive->AddMessage("_invokeMsg", InvocationMessage()); 13378092ae7SKarsten Heimrich 13478092ae7SKarsten Heimrich if (status == B_OK && SelectionMessage()) 13578092ae7SKarsten Heimrich status = archive->AddMessage("_selectMsg", SelectionMessage()); 13678092ae7SKarsten Heimrich 13778092ae7SKarsten Heimrich if (status == B_OK) 138*6846765fSOliver Tappe status = fDate.Archive(archive); 13978092ae7SKarsten Heimrich 14078092ae7SKarsten Heimrich if (status == B_OK) 141*6846765fSOliver Tappe status = archive->AddInt32("_weekStart", fStartOfWeek); 14278092ae7SKarsten Heimrich 14378092ae7SKarsten Heimrich if (status == B_OK) 14478092ae7SKarsten Heimrich status = archive->AddBool("_dayHeader", fDayNameHeaderVisible); 14578092ae7SKarsten Heimrich 14678092ae7SKarsten Heimrich if (status == B_OK) 14778092ae7SKarsten Heimrich status = archive->AddBool("_weekHeader", fWeekNumberHeaderVisible); 14878092ae7SKarsten Heimrich 14978092ae7SKarsten Heimrich return status; 15078092ae7SKarsten Heimrich } 15178092ae7SKarsten Heimrich 15278092ae7SKarsten Heimrich 15378092ae7SKarsten Heimrich void 15478092ae7SKarsten Heimrich BCalendarView::AttachedToWindow() 15578092ae7SKarsten Heimrich { 15678092ae7SKarsten Heimrich BView::AttachedToWindow(); 15778092ae7SKarsten Heimrich 15878092ae7SKarsten Heimrich if (!Messenger().IsValid()) 15978092ae7SKarsten Heimrich SetTarget(Window(), NULL); 16078092ae7SKarsten Heimrich } 16178092ae7SKarsten Heimrich 16278092ae7SKarsten Heimrich 16378092ae7SKarsten Heimrich void 16478092ae7SKarsten Heimrich BCalendarView::FrameResized(float width, float height) 16578092ae7SKarsten Heimrich { 16678092ae7SKarsten Heimrich Invalidate(Bounds()); 16778092ae7SKarsten Heimrich } 16878092ae7SKarsten Heimrich 16978092ae7SKarsten Heimrich 17078092ae7SKarsten Heimrich void 17178092ae7SKarsten Heimrich BCalendarView::Draw(BRect updateRect) 17278092ae7SKarsten Heimrich { 17378092ae7SKarsten Heimrich if (LockLooper()) { 17478092ae7SKarsten Heimrich if (fFocusChanged) { 17578092ae7SKarsten Heimrich _DrawFocusRect(); 17678092ae7SKarsten Heimrich UnlockLooper(); 17778092ae7SKarsten Heimrich return; 17878092ae7SKarsten Heimrich } 17978092ae7SKarsten Heimrich 18078092ae7SKarsten Heimrich if (fSelectionChanged) { 18178092ae7SKarsten Heimrich _UpdateSelection(); 18278092ae7SKarsten Heimrich UnlockLooper(); 18378092ae7SKarsten Heimrich return; 18478092ae7SKarsten Heimrich } 18578092ae7SKarsten Heimrich 18678092ae7SKarsten Heimrich _DrawDays(); 18778092ae7SKarsten Heimrich _DrawDayHeader(); 18878092ae7SKarsten Heimrich _DrawWeekHeader(); 18978092ae7SKarsten Heimrich 19078092ae7SKarsten Heimrich rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR); 19178092ae7SKarsten Heimrich SetHighColor(tint_color(background, B_DARKEN_3_TINT)); 19278092ae7SKarsten Heimrich StrokeRect(Bounds()); 19378092ae7SKarsten Heimrich 19478092ae7SKarsten Heimrich UnlockLooper(); 19578092ae7SKarsten Heimrich } 19678092ae7SKarsten Heimrich } 19778092ae7SKarsten Heimrich 19878092ae7SKarsten Heimrich 19978092ae7SKarsten Heimrich void 20078092ae7SKarsten Heimrich BCalendarView::DrawDay(BView* owner, BRect frame, const char* text, 20178092ae7SKarsten Heimrich bool isSelected, bool isEnabled, bool focus) 20278092ae7SKarsten Heimrich { 20378092ae7SKarsten Heimrich _DrawItem(owner, frame, text, isSelected, isEnabled, focus); 20478092ae7SKarsten Heimrich } 20578092ae7SKarsten Heimrich 20678092ae7SKarsten Heimrich 20778092ae7SKarsten Heimrich void 20878092ae7SKarsten Heimrich BCalendarView::DrawDayName(BView* owner, BRect frame, const char* text) 20978092ae7SKarsten Heimrich { 21078092ae7SKarsten Heimrich // we get the full rect, fake this as the internal function 21178092ae7SKarsten Heimrich // shrinks the frame to work properly when drawing a day item 21278092ae7SKarsten Heimrich _DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true); 21378092ae7SKarsten Heimrich } 21478092ae7SKarsten Heimrich 21578092ae7SKarsten Heimrich 21678092ae7SKarsten Heimrich void 21778092ae7SKarsten Heimrich BCalendarView::DrawWeekNumber(BView* owner, BRect frame, const char* text) 21878092ae7SKarsten Heimrich { 21978092ae7SKarsten Heimrich // we get the full rect, fake this as the internal function 22078092ae7SKarsten Heimrich // shrinks the frame to work properly when drawing a day item 22178092ae7SKarsten Heimrich _DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true); 22278092ae7SKarsten Heimrich } 22378092ae7SKarsten Heimrich 22478092ae7SKarsten Heimrich 22578092ae7SKarsten Heimrich uint32 22678092ae7SKarsten Heimrich BCalendarView::SelectionCommand() const 22778092ae7SKarsten Heimrich { 22878092ae7SKarsten Heimrich if (SelectionMessage()) 22978092ae7SKarsten Heimrich return SelectionMessage()->what; 23078092ae7SKarsten Heimrich 23178092ae7SKarsten Heimrich return 0; 23278092ae7SKarsten Heimrich } 23378092ae7SKarsten Heimrich 23478092ae7SKarsten Heimrich 23578092ae7SKarsten Heimrich BMessage* 23678092ae7SKarsten Heimrich BCalendarView::SelectionMessage() const 23778092ae7SKarsten Heimrich { 23878092ae7SKarsten Heimrich return fSelectionMessage; 23978092ae7SKarsten Heimrich } 24078092ae7SKarsten Heimrich 24178092ae7SKarsten Heimrich 24278092ae7SKarsten Heimrich void 24378092ae7SKarsten Heimrich BCalendarView::SetSelectionMessage(BMessage* message) 24478092ae7SKarsten Heimrich { 24578092ae7SKarsten Heimrich delete fSelectionMessage; 24678092ae7SKarsten Heimrich fSelectionMessage = message; 24778092ae7SKarsten Heimrich } 24878092ae7SKarsten Heimrich 24978092ae7SKarsten Heimrich 25078092ae7SKarsten Heimrich uint32 25178092ae7SKarsten Heimrich BCalendarView::InvocationCommand() const 25278092ae7SKarsten Heimrich { 25378092ae7SKarsten Heimrich return BInvoker::Command(); 25478092ae7SKarsten Heimrich } 25578092ae7SKarsten Heimrich 25678092ae7SKarsten Heimrich 25778092ae7SKarsten Heimrich BMessage* 25878092ae7SKarsten Heimrich BCalendarView::InvocationMessage() const 25978092ae7SKarsten Heimrich { 26078092ae7SKarsten Heimrich return BInvoker::Message(); 26178092ae7SKarsten Heimrich } 26278092ae7SKarsten Heimrich 26378092ae7SKarsten Heimrich 26478092ae7SKarsten Heimrich void 26578092ae7SKarsten Heimrich BCalendarView::SetInvocationMessage(BMessage* message) 26678092ae7SKarsten Heimrich { 26778092ae7SKarsten Heimrich BInvoker::SetMessage(message); 26878092ae7SKarsten Heimrich } 26978092ae7SKarsten Heimrich 27078092ae7SKarsten Heimrich 27178092ae7SKarsten Heimrich void 27278092ae7SKarsten Heimrich BCalendarView::MakeFocus(bool state) 27378092ae7SKarsten Heimrich { 27478092ae7SKarsten Heimrich if (IsFocus() == state) 27578092ae7SKarsten Heimrich return; 27678092ae7SKarsten Heimrich 27778092ae7SKarsten Heimrich BView::MakeFocus(state); 27878092ae7SKarsten Heimrich 2791b3303e7SAxel Dörfler // TODO: solve this better 28078092ae7SKarsten Heimrich fFocusChanged = true; 28178092ae7SKarsten Heimrich Draw(_RectOfDay(fFocusedDay)); 28278092ae7SKarsten Heimrich fFocusChanged = false; 28378092ae7SKarsten Heimrich } 28478092ae7SKarsten Heimrich 28578092ae7SKarsten Heimrich 28678092ae7SKarsten Heimrich status_t 28778092ae7SKarsten Heimrich BCalendarView::Invoke(BMessage* message) 28878092ae7SKarsten Heimrich { 28978092ae7SKarsten Heimrich bool notify = false; 29078092ae7SKarsten Heimrich uint32 kind = InvokeKind(¬ify); 29178092ae7SKarsten Heimrich 29278092ae7SKarsten Heimrich BMessage clone(kind); 29378092ae7SKarsten Heimrich status_t status = B_BAD_VALUE; 29478092ae7SKarsten Heimrich 29578092ae7SKarsten Heimrich if (!message && !notify) 29678092ae7SKarsten Heimrich message = Message(); 29778092ae7SKarsten Heimrich 29878092ae7SKarsten Heimrich if (!message) { 29978092ae7SKarsten Heimrich if (!IsWatched()) 30078092ae7SKarsten Heimrich return status; 30178092ae7SKarsten Heimrich } else 30278092ae7SKarsten Heimrich clone = *message; 30378092ae7SKarsten Heimrich 30478092ae7SKarsten Heimrich clone.AddPointer("source", this); 30578092ae7SKarsten Heimrich clone.AddInt64("when", (int64)system_time()); 30678092ae7SKarsten Heimrich clone.AddMessenger("be:sender", BMessenger(this)); 30778092ae7SKarsten Heimrich 30878092ae7SKarsten Heimrich int32 year; 30978092ae7SKarsten Heimrich int32 month; 310*6846765fSOliver Tappe _GetYearMonthForSelection(fSelectedDay, &year, &month); 31178092ae7SKarsten Heimrich 312*6846765fSOliver Tappe clone.AddInt32("year", fDate.Year()); 313*6846765fSOliver Tappe clone.AddInt32("month", fDate.Month()); 314*6846765fSOliver Tappe clone.AddInt32("day", fDate.Day()); 31578092ae7SKarsten Heimrich 31678092ae7SKarsten Heimrich if (message) 31778092ae7SKarsten Heimrich status = BInvoker::Invoke(&clone); 31878092ae7SKarsten Heimrich 31978092ae7SKarsten Heimrich SendNotices(kind, &clone); 32078092ae7SKarsten Heimrich 32178092ae7SKarsten Heimrich return status; 32278092ae7SKarsten Heimrich } 32378092ae7SKarsten Heimrich 32478092ae7SKarsten Heimrich 32578092ae7SKarsten Heimrich void 32678092ae7SKarsten Heimrich BCalendarView::MouseDown(BPoint where) 32778092ae7SKarsten Heimrich { 32878092ae7SKarsten Heimrich if (!IsFocus()) { 32978092ae7SKarsten Heimrich MakeFocus(); 33078092ae7SKarsten Heimrich Sync(); 33178092ae7SKarsten Heimrich Window()->UpdateIfNeeded(); 33278092ae7SKarsten Heimrich } 33378092ae7SKarsten Heimrich 33478092ae7SKarsten Heimrich BRect frame = Bounds(); 33578092ae7SKarsten Heimrich if (fDayNameHeaderVisible) 33678092ae7SKarsten Heimrich frame.top += frame.Height() / 7 - 1.0; 33778092ae7SKarsten Heimrich 33878092ae7SKarsten Heimrich if (fWeekNumberHeaderVisible) 33978092ae7SKarsten Heimrich frame.left += frame.Width() / 8 - 1.0; 34078092ae7SKarsten Heimrich 34178092ae7SKarsten Heimrich if (!frame.Contains(where)) 34278092ae7SKarsten Heimrich return; 34378092ae7SKarsten Heimrich 34478092ae7SKarsten Heimrich // try to set to new day 34578092ae7SKarsten Heimrich frame = _SetNewSelectedDay(where); 34678092ae7SKarsten Heimrich 34778092ae7SKarsten Heimrich // on success 34878092ae7SKarsten Heimrich if (fSelectedDay != fNewSelectedDay) { 34978092ae7SKarsten Heimrich // update focus 35078092ae7SKarsten Heimrich fFocusChanged = true; 35178092ae7SKarsten Heimrich fNewFocusedDay = fNewSelectedDay; 35278092ae7SKarsten Heimrich Draw(_RectOfDay(fFocusedDay)); 35378092ae7SKarsten Heimrich fFocusChanged = false; 35478092ae7SKarsten Heimrich 35578092ae7SKarsten Heimrich // update selection 35678092ae7SKarsten Heimrich fSelectionChanged = true; 35778092ae7SKarsten Heimrich Draw(frame); 35878092ae7SKarsten Heimrich Draw(_RectOfDay(fSelectedDay)); 35978092ae7SKarsten Heimrich fSelectionChanged = false; 36078092ae7SKarsten Heimrich 36178092ae7SKarsten Heimrich // notify that selection changed 36278092ae7SKarsten Heimrich InvokeNotify(SelectionMessage(), B_CONTROL_MODIFIED); 36378092ae7SKarsten Heimrich } 36478092ae7SKarsten Heimrich 36578092ae7SKarsten Heimrich int32 clicks; 36678092ae7SKarsten Heimrich // on double click invoke 36778092ae7SKarsten Heimrich BMessage* message = Looper()->CurrentMessage(); 36878092ae7SKarsten Heimrich if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1) 36978092ae7SKarsten Heimrich Invoke(); 37078092ae7SKarsten Heimrich } 37178092ae7SKarsten Heimrich 37278092ae7SKarsten Heimrich 37378092ae7SKarsten Heimrich void 37478092ae7SKarsten Heimrich BCalendarView::KeyDown(const char* bytes, int32 numBytes) 37578092ae7SKarsten Heimrich { 37678092ae7SKarsten Heimrich const int32 kRows = 6; 37778092ae7SKarsten Heimrich const int32 kColumns = 7; 37878092ae7SKarsten Heimrich 37978092ae7SKarsten Heimrich int32 row = fFocusedDay.row; 38078092ae7SKarsten Heimrich int32 column = fFocusedDay.column; 38178092ae7SKarsten Heimrich 38278092ae7SKarsten Heimrich switch (bytes[0]) { 38378092ae7SKarsten Heimrich case B_LEFT_ARROW: 38478092ae7SKarsten Heimrich column -= 1; 38578092ae7SKarsten Heimrich if (column < 0) { 38678092ae7SKarsten Heimrich column = kColumns - 1; 38778092ae7SKarsten Heimrich row -= 1; 38878092ae7SKarsten Heimrich if (row >= 0) 38978092ae7SKarsten Heimrich fFocusChanged = true; 39078092ae7SKarsten Heimrich } else 39178092ae7SKarsten Heimrich fFocusChanged = true; 392*6846765fSOliver Tappe break; 39378092ae7SKarsten Heimrich 39478092ae7SKarsten Heimrich case B_RIGHT_ARROW: 39578092ae7SKarsten Heimrich column += 1; 39678092ae7SKarsten Heimrich if (column == kColumns) { 39778092ae7SKarsten Heimrich column = 0; 39878092ae7SKarsten Heimrich row += 1; 39978092ae7SKarsten Heimrich if (row < kRows) 40078092ae7SKarsten Heimrich fFocusChanged = true; 40178092ae7SKarsten Heimrich } else 40278092ae7SKarsten Heimrich fFocusChanged = true; 403*6846765fSOliver Tappe break; 40478092ae7SKarsten Heimrich 40578092ae7SKarsten Heimrich case B_UP_ARROW: 40678092ae7SKarsten Heimrich row -= 1; 40778092ae7SKarsten Heimrich if (row >= 0) 40878092ae7SKarsten Heimrich fFocusChanged = true; 409*6846765fSOliver Tappe break; 41078092ae7SKarsten Heimrich 41178092ae7SKarsten Heimrich case B_DOWN_ARROW: 41278092ae7SKarsten Heimrich row += 1; 41378092ae7SKarsten Heimrich if (row < kRows) 41478092ae7SKarsten Heimrich fFocusChanged = true; 415*6846765fSOliver Tappe break; 416*6846765fSOliver Tappe 417*6846765fSOliver Tappe case B_PAGE_UP: 418*6846765fSOliver Tappe { 419*6846765fSOliver Tappe BDate date(fDate); 420*6846765fSOliver Tappe date.AddMonths(-1); 421*6846765fSOliver Tappe SetDate(date); 422*6846765fSOliver Tappe 423*6846765fSOliver Tappe Invoke(); 424*6846765fSOliver Tappe break; 425*6846765fSOliver Tappe } 426*6846765fSOliver Tappe 427*6846765fSOliver Tappe case B_PAGE_DOWN: 428*6846765fSOliver Tappe { 429*6846765fSOliver Tappe BDate date(fDate); 430*6846765fSOliver Tappe date.AddMonths(1); 431*6846765fSOliver Tappe SetDate(date); 432*6846765fSOliver Tappe 433*6846765fSOliver Tappe Invoke(); 434*6846765fSOliver Tappe break; 435*6846765fSOliver Tappe } 43678092ae7SKarsten Heimrich 43778092ae7SKarsten Heimrich case B_RETURN: 438*6846765fSOliver Tappe case B_SPACE: 439*6846765fSOliver Tappe { 44078092ae7SKarsten Heimrich fSelectionChanged = true; 44178092ae7SKarsten Heimrich BPoint pt = _RectOfDay(fFocusedDay).LeftTop(); 44278092ae7SKarsten Heimrich Draw(_SetNewSelectedDay(pt + BPoint(4.0, 4.0))); 44378092ae7SKarsten Heimrich Draw(_RectOfDay(fSelectedDay)); 44478092ae7SKarsten Heimrich fSelectionChanged = false; 44578092ae7SKarsten Heimrich 44678092ae7SKarsten Heimrich Invoke(); 447*6846765fSOliver Tappe break; 448*6846765fSOliver Tappe } 44978092ae7SKarsten Heimrich 45078092ae7SKarsten Heimrich default: 45178092ae7SKarsten Heimrich BView::KeyDown(bytes, numBytes); 45278092ae7SKarsten Heimrich break; 45378092ae7SKarsten Heimrich } 45478092ae7SKarsten Heimrich 45578092ae7SKarsten Heimrich if (fFocusChanged) { 45678092ae7SKarsten Heimrich fNewFocusedDay.SetTo(row, column); 45778092ae7SKarsten Heimrich Draw(_RectOfDay(fFocusedDay)); 45878092ae7SKarsten Heimrich Draw(_RectOfDay(fNewFocusedDay)); 45978092ae7SKarsten Heimrich fFocusChanged = false; 46078092ae7SKarsten Heimrich } 46178092ae7SKarsten Heimrich } 46278092ae7SKarsten Heimrich 46378092ae7SKarsten Heimrich 46478092ae7SKarsten Heimrich void 46578092ae7SKarsten Heimrich BCalendarView::ResizeToPreferred() 46678092ae7SKarsten Heimrich { 46778092ae7SKarsten Heimrich float width; 46878092ae7SKarsten Heimrich float height; 46978092ae7SKarsten Heimrich 47078092ae7SKarsten Heimrich GetPreferredSize(&width, &height); 47178092ae7SKarsten Heimrich BView::ResizeTo(width, height); 47278092ae7SKarsten Heimrich } 47378092ae7SKarsten Heimrich 47478092ae7SKarsten Heimrich 47578092ae7SKarsten Heimrich void 47678092ae7SKarsten Heimrich BCalendarView::GetPreferredSize(float* width, float* height) 47778092ae7SKarsten Heimrich { 47878092ae7SKarsten Heimrich _GetPreferredSize(width, height); 47978092ae7SKarsten Heimrich } 48078092ae7SKarsten Heimrich 48178092ae7SKarsten Heimrich 4822530274dSRyan Leavengood BSize 4832530274dSRyan Leavengood BCalendarView::MaxSize() 4842530274dSRyan Leavengood { 4852530274dSRyan Leavengood return BLayoutUtils::ComposeSize(ExplicitMaxSize(), 4862530274dSRyan Leavengood BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); 4872530274dSRyan Leavengood } 4882530274dSRyan Leavengood 4892530274dSRyan Leavengood 4902530274dSRyan Leavengood BSize 4912530274dSRyan Leavengood BCalendarView::MinSize() 4922530274dSRyan Leavengood { 4932530274dSRyan Leavengood float width, height; 4942530274dSRyan Leavengood _GetPreferredSize(&width, &height); 495*6846765fSOliver Tappe return BLayoutUtils::ComposeSize(ExplicitMinSize(), BSize(width, height)); 4962530274dSRyan Leavengood } 4972530274dSRyan Leavengood 4982530274dSRyan Leavengood 4992530274dSRyan Leavengood BSize 5002530274dSRyan Leavengood BCalendarView::PreferredSize() 5012530274dSRyan Leavengood { 502*6846765fSOliver Tappe return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), MinSize()); 5032530274dSRyan Leavengood } 5042530274dSRyan Leavengood 5052530274dSRyan Leavengood 50678092ae7SKarsten Heimrich int32 50778092ae7SKarsten Heimrich BCalendarView::Day() const 50878092ae7SKarsten Heimrich { 509*6846765fSOliver Tappe return fDate.Day(); 51078092ae7SKarsten Heimrich } 51178092ae7SKarsten Heimrich 51278092ae7SKarsten Heimrich 51378092ae7SKarsten Heimrich int32 51478092ae7SKarsten Heimrich BCalendarView::Year() const 51578092ae7SKarsten Heimrich { 51678092ae7SKarsten Heimrich int32 year; 517*6846765fSOliver Tappe _GetYearMonthForSelection(fSelectedDay, &year, NULL); 51878092ae7SKarsten Heimrich 51978092ae7SKarsten Heimrich return year; 52078092ae7SKarsten Heimrich } 52178092ae7SKarsten Heimrich 52278092ae7SKarsten Heimrich 52378092ae7SKarsten Heimrich int32 52478092ae7SKarsten Heimrich BCalendarView::Month() const 52578092ae7SKarsten Heimrich { 52678092ae7SKarsten Heimrich int32 month; 527*6846765fSOliver Tappe _GetYearMonthForSelection(fSelectedDay, NULL, &month); 52878092ae7SKarsten Heimrich 52978092ae7SKarsten Heimrich return month; 53078092ae7SKarsten Heimrich } 53178092ae7SKarsten Heimrich 53278092ae7SKarsten Heimrich 53378092ae7SKarsten Heimrich BDate 53478092ae7SKarsten Heimrich BCalendarView::Date() const 53578092ae7SKarsten Heimrich { 53678092ae7SKarsten Heimrich int32 year; 53778092ae7SKarsten Heimrich int32 month; 538*6846765fSOliver Tappe _GetYearMonthForSelection(fSelectedDay, &year, &month); 539*6846765fSOliver Tappe return BDate(year, month, fDate.Day()); 54078092ae7SKarsten Heimrich } 54178092ae7SKarsten Heimrich 54278092ae7SKarsten Heimrich 54378092ae7SKarsten Heimrich bool 54478092ae7SKarsten Heimrich BCalendarView::SetDate(const BDate& date) 54578092ae7SKarsten Heimrich { 546c1ed5d75SKarsten Heimrich if (!date.IsValid()) 547c1ed5d75SKarsten Heimrich return false; 548c1ed5d75SKarsten Heimrich 549*6846765fSOliver Tappe if (fDate == date) 55078092ae7SKarsten Heimrich return true; 55178092ae7SKarsten Heimrich 552*6846765fSOliver Tappe if (fDate.Year() == date.Year() && fDate.Month() == date.Month()) { 553*6846765fSOliver Tappe fDate = date; 554*6846765fSOliver Tappe 55578092ae7SKarsten Heimrich _SetToDay(); 55678092ae7SKarsten Heimrich // update focus 55778092ae7SKarsten Heimrich fFocusChanged = true; 55878092ae7SKarsten Heimrich Draw(_RectOfDay(fFocusedDay)); 55978092ae7SKarsten Heimrich fFocusChanged = false; 56078092ae7SKarsten Heimrich 56178092ae7SKarsten Heimrich // update selection 56278092ae7SKarsten Heimrich fSelectionChanged = true; 56378092ae7SKarsten Heimrich Draw(_RectOfDay(fSelectedDay)); 56478092ae7SKarsten Heimrich Draw(_RectOfDay(fNewSelectedDay)); 56578092ae7SKarsten Heimrich fSelectionChanged = false; 56678092ae7SKarsten Heimrich } else { 567*6846765fSOliver Tappe fDate = date; 56878092ae7SKarsten Heimrich 56978092ae7SKarsten Heimrich _SetupDayNumbers(); 57078092ae7SKarsten Heimrich _SetupWeekNumbers(); 57178092ae7SKarsten Heimrich 57278092ae7SKarsten Heimrich BRect frame = Bounds(); 57378092ae7SKarsten Heimrich if (fDayNameHeaderVisible) 57478092ae7SKarsten Heimrich frame.top += frame.Height() / 7 - 1.0; 57578092ae7SKarsten Heimrich 57678092ae7SKarsten Heimrich if (fWeekNumberHeaderVisible) 57778092ae7SKarsten Heimrich frame.left += frame.Width() / 8 - 1.0; 57878092ae7SKarsten Heimrich 57978092ae7SKarsten Heimrich Draw(frame.InsetBySelf(4.0, 4.0)); 58078092ae7SKarsten Heimrich } 58178092ae7SKarsten Heimrich 58278092ae7SKarsten Heimrich return true; 58378092ae7SKarsten Heimrich } 58478092ae7SKarsten Heimrich 58578092ae7SKarsten Heimrich 586*6846765fSOliver Tappe bool 587*6846765fSOliver Tappe BCalendarView::SetDate(int32 year, int32 month, int32 day) 58878092ae7SKarsten Heimrich { 589*6846765fSOliver Tappe return SetDate(BDate(year, month, day)); 590*6846765fSOliver Tappe } 591*6846765fSOliver Tappe 592*6846765fSOliver Tappe 593*6846765fSOliver Tappe BWeekday 594*6846765fSOliver Tappe BCalendarView::StartOfWeek() const 595*6846765fSOliver Tappe { 596*6846765fSOliver Tappe return BWeekday(fStartOfWeek); 59778092ae7SKarsten Heimrich } 59878092ae7SKarsten Heimrich 59978092ae7SKarsten Heimrich 60078092ae7SKarsten Heimrich void 601*6846765fSOliver Tappe BCalendarView::SetStartOfWeek(BWeekday startOfWeek) 60278092ae7SKarsten Heimrich { 603*6846765fSOliver Tappe if (fStartOfWeek == (int32)startOfWeek) 60478092ae7SKarsten Heimrich return; 60578092ae7SKarsten Heimrich 606*6846765fSOliver Tappe fStartOfWeek = (int32)startOfWeek; 60778092ae7SKarsten Heimrich 60878092ae7SKarsten Heimrich _SetupDayNames(); 60978092ae7SKarsten Heimrich _SetupDayNumbers(); 61078092ae7SKarsten Heimrich _SetupWeekNumbers(); 61178092ae7SKarsten Heimrich 61278092ae7SKarsten Heimrich Invalidate(Bounds().InsetBySelf(1.0, 1.0)); 61378092ae7SKarsten Heimrich } 61478092ae7SKarsten Heimrich 61578092ae7SKarsten Heimrich 61678092ae7SKarsten Heimrich bool 61778092ae7SKarsten Heimrich BCalendarView::IsDayNameHeaderVisible() const 61878092ae7SKarsten Heimrich { 61978092ae7SKarsten Heimrich return fDayNameHeaderVisible; 62078092ae7SKarsten Heimrich } 62178092ae7SKarsten Heimrich 62278092ae7SKarsten Heimrich 62378092ae7SKarsten Heimrich void 62478092ae7SKarsten Heimrich BCalendarView::SetDayNameHeaderVisible(bool visible) 62578092ae7SKarsten Heimrich { 62678092ae7SKarsten Heimrich if (fDayNameHeaderVisible == visible) 62778092ae7SKarsten Heimrich return; 62878092ae7SKarsten Heimrich 62978092ae7SKarsten Heimrich fDayNameHeaderVisible = visible; 63078092ae7SKarsten Heimrich Invalidate(Bounds().InsetBySelf(1.0, 1.0)); 63178092ae7SKarsten Heimrich } 63278092ae7SKarsten Heimrich 63378092ae7SKarsten Heimrich 63478092ae7SKarsten Heimrich bool 63578092ae7SKarsten Heimrich BCalendarView::IsWeekNumberHeaderVisible() const 63678092ae7SKarsten Heimrich { 63778092ae7SKarsten Heimrich return fWeekNumberHeaderVisible; 63878092ae7SKarsten Heimrich } 63978092ae7SKarsten Heimrich 64078092ae7SKarsten Heimrich 64178092ae7SKarsten Heimrich void 64278092ae7SKarsten Heimrich BCalendarView::SetWeekNumberHeaderVisible(bool visible) 64378092ae7SKarsten Heimrich { 64478092ae7SKarsten Heimrich if (fWeekNumberHeaderVisible == visible) 64578092ae7SKarsten Heimrich return; 64678092ae7SKarsten Heimrich 64778092ae7SKarsten Heimrich fWeekNumberHeaderVisible = visible; 64878092ae7SKarsten Heimrich Invalidate(Bounds().InsetBySelf(1.0, 1.0)); 64978092ae7SKarsten Heimrich } 65078092ae7SKarsten Heimrich 65178092ae7SKarsten Heimrich 65278092ae7SKarsten Heimrich void 65378092ae7SKarsten Heimrich BCalendarView::_InitObject() 65478092ae7SKarsten Heimrich { 655*6846765fSOliver Tappe fDate = BDate::CurrentDate(B_LOCAL_TIME); 656*6846765fSOliver Tappe 657*6846765fSOliver Tappe BLocale::Default()->GetStartOfWeek((BWeekday*)&fStartOfWeek); 65878092ae7SKarsten Heimrich 65978092ae7SKarsten Heimrich _SetupDayNames(); 66078092ae7SKarsten Heimrich _SetupDayNumbers(); 66178092ae7SKarsten Heimrich _SetupWeekNumbers(); 66278092ae7SKarsten Heimrich } 66378092ae7SKarsten Heimrich 66478092ae7SKarsten Heimrich 66578092ae7SKarsten Heimrich void 66678092ae7SKarsten Heimrich BCalendarView::_SetToDay() 66778092ae7SKarsten Heimrich { 668*6846765fSOliver Tappe BDate date(fDate.Year(), fDate.Month(), 1); 66978092ae7SKarsten Heimrich if (!date.IsValid()) 67078092ae7SKarsten Heimrich return; 67178092ae7SKarsten Heimrich 672*6846765fSOliver Tappe const int32 firstDayOffset = (7 + date.DayOfWeek() - fStartOfWeek) % 7; 67378092ae7SKarsten Heimrich 674*6846765fSOliver Tappe int32 day = 1 - firstDayOffset; 67578092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 67678092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 677*6846765fSOliver Tappe if (day == fDate.Day()) { 67878092ae7SKarsten Heimrich fNewFocusedDay.SetTo(row, column); 67978092ae7SKarsten Heimrich fNewSelectedDay.SetTo(row, column); 68078092ae7SKarsten Heimrich return; 68178092ae7SKarsten Heimrich } 682*6846765fSOliver Tappe day++; 68378092ae7SKarsten Heimrich } 68478092ae7SKarsten Heimrich } 685*6846765fSOliver Tappe 686*6846765fSOliver Tappe fNewFocusedDay.SetTo(0, 0); 687*6846765fSOliver Tappe fNewSelectedDay.SetTo(0, 0); 68878092ae7SKarsten Heimrich } 68978092ae7SKarsten Heimrich 69078092ae7SKarsten Heimrich 69178092ae7SKarsten Heimrich void 692*6846765fSOliver Tappe BCalendarView::_GetYearMonthForSelection(const Selection& selection, 693*6846765fSOliver Tappe int32* year, int32* month) const 69478092ae7SKarsten Heimrich { 695*6846765fSOliver Tappe BDate startOfMonth(fDate.Year(), fDate.Month(), 1); 696*6846765fSOliver Tappe const int32 firstDayOffset 697*6846765fSOliver Tappe = (7 + startOfMonth.DayOfWeek() - fStartOfWeek) % 7; 698*6846765fSOliver Tappe const int32 daysInMonth = startOfMonth.DaysInMonth(); 69978092ae7SKarsten Heimrich 700*6846765fSOliver Tappe BDate date(fDate); 701*6846765fSOliver Tappe const int32 dayOffset = selection.row * 7 + selection.column; 702*6846765fSOliver Tappe if (dayOffset < firstDayOffset) 703*6846765fSOliver Tappe date.AddMonths(-1); 704*6846765fSOliver Tappe else if (dayOffset >= firstDayOffset + daysInMonth) 705*6846765fSOliver Tappe date.AddMonths(1); 706*6846765fSOliver Tappe if (year != NULL) 70778092ae7SKarsten Heimrich *year = date.Year(); 708*6846765fSOliver Tappe if (month != NULL) 70978092ae7SKarsten Heimrich *month = date.Month(); 71078092ae7SKarsten Heimrich } 71178092ae7SKarsten Heimrich 71278092ae7SKarsten Heimrich 71378092ae7SKarsten Heimrich void 71478092ae7SKarsten Heimrich BCalendarView::_GetPreferredSize(float* _width, float* _height) 71578092ae7SKarsten Heimrich { 71678092ae7SKarsten Heimrich BFont font; 71778092ae7SKarsten Heimrich GetFont(&font); 71878092ae7SKarsten Heimrich font_height fontHeight; 71978092ae7SKarsten Heimrich font.GetHeight(&fontHeight); 72078092ae7SKarsten Heimrich 72178092ae7SKarsten Heimrich const float height = FontHeight(this) + 4.0; 72278092ae7SKarsten Heimrich 72378092ae7SKarsten Heimrich int32 rows = 7; 72478092ae7SKarsten Heimrich if (!fDayNameHeaderVisible) 72578092ae7SKarsten Heimrich rows = 6; 72678092ae7SKarsten Heimrich 72778092ae7SKarsten Heimrich // height = font height * rows + 8 px border 72878092ae7SKarsten Heimrich *_height = height * rows + 8.0; 72978092ae7SKarsten Heimrich 73078092ae7SKarsten Heimrich float width = 0.0; 73178092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 73278092ae7SKarsten Heimrich float tmp = StringWidth(fDayNames[column].String()) + 2.0; 73378092ae7SKarsten Heimrich width = tmp > width ? tmp : width; 73478092ae7SKarsten Heimrich } 73578092ae7SKarsten Heimrich 73678092ae7SKarsten Heimrich int32 columns = 8; 73778092ae7SKarsten Heimrich if (!fWeekNumberHeaderVisible) 73878092ae7SKarsten Heimrich columns = 7; 73978092ae7SKarsten Heimrich 74078092ae7SKarsten Heimrich // width = max width day name * 8 column + 8 px border 74178092ae7SKarsten Heimrich *_width = width * columns + 8.0; 74278092ae7SKarsten Heimrich } 74378092ae7SKarsten Heimrich 74478092ae7SKarsten Heimrich 74578092ae7SKarsten Heimrich void 74678092ae7SKarsten Heimrich BCalendarView::_SetupDayNames() 74778092ae7SKarsten Heimrich { 748*6846765fSOliver Tappe for (int32 i = 0; i <= 6; ++i) 749*6846765fSOliver Tappe fDayNames[i] = fDate.ShortDayName(1 + (fStartOfWeek - 1 + i) % 7); 75078092ae7SKarsten Heimrich } 75178092ae7SKarsten Heimrich 75278092ae7SKarsten Heimrich 75378092ae7SKarsten Heimrich void 75478092ae7SKarsten Heimrich BCalendarView::_SetupDayNumbers() 75578092ae7SKarsten Heimrich { 756*6846765fSOliver Tappe BDate startOfMonth(fDate.Year(), fDate.Month(), 1); 757*6846765fSOliver Tappe if (!startOfMonth.IsValid()) 75878092ae7SKarsten Heimrich return; 75978092ae7SKarsten Heimrich 76078092ae7SKarsten Heimrich fFocusedDay.SetTo(0, 0); 76178092ae7SKarsten Heimrich fSelectedDay.SetTo(0, 0); 76278092ae7SKarsten Heimrich fNewFocusedDay.SetTo(0, 0); 76378092ae7SKarsten Heimrich 764*6846765fSOliver Tappe const int32 daysInMonth = startOfMonth.DaysInMonth(); 765*6846765fSOliver Tappe const int32 firstDayOffset 766*6846765fSOliver Tappe = (7 + startOfMonth.DayOfWeek() - fStartOfWeek) % 7; 76778092ae7SKarsten Heimrich 76878092ae7SKarsten Heimrich // calc the last day one month before 769*6846765fSOliver Tappe BDate lastDayInMonthBefore(startOfMonth); 770*6846765fSOliver Tappe lastDayInMonthBefore.AddDays(-1); 771*6846765fSOliver Tappe const int32 lastDayBefore = lastDayInMonthBefore.DaysInMonth(); 77278092ae7SKarsten Heimrich 77378092ae7SKarsten Heimrich int32 counter = 0; 77478092ae7SKarsten Heimrich int32 firstDayAfter = 1; 77578092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 77678092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 777*6846765fSOliver Tappe int32 day = 1 + counter - firstDayOffset; 778*6846765fSOliver Tappe if (counter < firstDayOffset) 77978092ae7SKarsten Heimrich day += lastDayBefore; 780*6846765fSOliver Tappe else if (counter >= firstDayOffset + daysInMonth) 78178092ae7SKarsten Heimrich day = firstDayAfter++; 782*6846765fSOliver Tappe else if (day == fDate.Day()) { 78378092ae7SKarsten Heimrich fFocusedDay.SetTo(row, column); 78478092ae7SKarsten Heimrich fSelectedDay.SetTo(row, column); 78578092ae7SKarsten Heimrich fNewFocusedDay.SetTo(row, column); 78678092ae7SKarsten Heimrich } 78778092ae7SKarsten Heimrich counter++; 788*6846765fSOliver Tappe fDayNumbers[row][column].Truncate(0); 78978092ae7SKarsten Heimrich fDayNumbers[row][column] << day; 79078092ae7SKarsten Heimrich } 79178092ae7SKarsten Heimrich } 79278092ae7SKarsten Heimrich } 79378092ae7SKarsten Heimrich 794*6846765fSOliver Tappe 79578092ae7SKarsten Heimrich void 79678092ae7SKarsten Heimrich BCalendarView::_SetupWeekNumbers() 79778092ae7SKarsten Heimrich { 798*6846765fSOliver Tappe BDate date(fDate.Year(), fDate.Month(), 1); 79978092ae7SKarsten Heimrich if (!date.IsValid()) 80078092ae7SKarsten Heimrich return; 80178092ae7SKarsten Heimrich 802c1ed5d75SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 80378092ae7SKarsten Heimrich fWeekNumbers[row].SetTo(""); 804f0932941SMichael Pfeiffer fWeekNumbers[row] << date.WeekNumber(); 805f0932941SMichael Pfeiffer date.AddDays(7); 806c1ed5d75SKarsten Heimrich } 80778092ae7SKarsten Heimrich } 80878092ae7SKarsten Heimrich 80978092ae7SKarsten Heimrich 81078092ae7SKarsten Heimrich void 81187663db4SOliver Tappe BCalendarView::_DrawDay(int32 currRow, int32 currColumn, int32 row, 81287663db4SOliver Tappe int32 column, int32 counter, BRect frame, const char* text, bool focus) 81378092ae7SKarsten Heimrich { 814*6846765fSOliver Tappe BDate startOfMonth(fDate.Year(), fDate.Month(), 1); 815*6846765fSOliver Tappe const int32 firstDayOffset 816*6846765fSOliver Tappe = (7 + startOfMonth.DayOfWeek() - fStartOfWeek) % 7; 817*6846765fSOliver Tappe const int32 daysMonth = startOfMonth.DaysInMonth(); 81878092ae7SKarsten Heimrich 81978092ae7SKarsten Heimrich bool enabled = true; 82078092ae7SKarsten Heimrich bool selected = false; 82178092ae7SKarsten Heimrich // check for the current date 82278092ae7SKarsten Heimrich if (currRow == row && currColumn == column) { 82378092ae7SKarsten Heimrich selected = true; // draw current date selected 824*6846765fSOliver Tappe if (counter <= firstDayOffset || counter > firstDayOffset + daysMonth) { 82578092ae7SKarsten Heimrich enabled = false; // days of month before or after 82678092ae7SKarsten Heimrich selected = false; // not selected but able to get focus 82778092ae7SKarsten Heimrich } 82878092ae7SKarsten Heimrich } else { 829*6846765fSOliver Tappe if (counter <= firstDayOffset || counter > firstDayOffset + daysMonth) 83078092ae7SKarsten Heimrich enabled = false; // days of month before or after 83178092ae7SKarsten Heimrich } 83278092ae7SKarsten Heimrich 83378092ae7SKarsten Heimrich DrawDay(this, frame, text, selected, enabled, focus); 83478092ae7SKarsten Heimrich } 83578092ae7SKarsten Heimrich 83678092ae7SKarsten Heimrich 83778092ae7SKarsten Heimrich void 83878092ae7SKarsten Heimrich BCalendarView::_DrawDays() 83978092ae7SKarsten Heimrich { 84078092ae7SKarsten Heimrich BRect frame = _FirstCalendarItemFrame(); 84178092ae7SKarsten Heimrich 84278092ae7SKarsten Heimrich const int32 currRow = fSelectedDay.row; 84378092ae7SKarsten Heimrich const int32 currColumn = fSelectedDay.column; 84478092ae7SKarsten Heimrich 84578092ae7SKarsten Heimrich const bool isFocus = IsFocus(); 84678092ae7SKarsten Heimrich const int32 focusRow = fFocusedDay.row; 84778092ae7SKarsten Heimrich const int32 focusColumn = fFocusedDay.column; 84878092ae7SKarsten Heimrich 84978092ae7SKarsten Heimrich int32 counter = 0; 85078092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 85178092ae7SKarsten Heimrich BRect tmp = frame; 85278092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 85378092ae7SKarsten Heimrich counter++; 85478092ae7SKarsten Heimrich const char* day = fDayNumbers[row][column].String(); 85578092ae7SKarsten Heimrich bool focus = isFocus && focusRow == row && focusColumn == column; 85687663db4SOliver Tappe _DrawDay(currRow, currColumn, row, column, counter, tmp, day, 85787663db4SOliver Tappe focus); 85878092ae7SKarsten Heimrich 85978092ae7SKarsten Heimrich tmp.OffsetBy(tmp.Width(), 0.0); 86078092ae7SKarsten Heimrich } 86178092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 86278092ae7SKarsten Heimrich } 86378092ae7SKarsten Heimrich } 86478092ae7SKarsten Heimrich 86578092ae7SKarsten Heimrich 86678092ae7SKarsten Heimrich void 86778092ae7SKarsten Heimrich BCalendarView::_DrawFocusRect() 86878092ae7SKarsten Heimrich { 86978092ae7SKarsten Heimrich BRect frame = _FirstCalendarItemFrame(); 87078092ae7SKarsten Heimrich 87178092ae7SKarsten Heimrich const int32 currRow = fSelectedDay.row; 87278092ae7SKarsten Heimrich const int32 currColumn = fSelectedDay.column; 87378092ae7SKarsten Heimrich 87478092ae7SKarsten Heimrich const int32 focusRow = fFocusedDay.row; 87578092ae7SKarsten Heimrich const int32 focusColumn = fFocusedDay.column; 87678092ae7SKarsten Heimrich 87778092ae7SKarsten Heimrich int32 counter = 0; 87878092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 87978092ae7SKarsten Heimrich BRect tmp = frame; 88078092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 88178092ae7SKarsten Heimrich counter++; 88278092ae7SKarsten Heimrich if (fNewFocusedDay.row == row && fNewFocusedDay.column == column) { 88378092ae7SKarsten Heimrich fFocusedDay.SetTo(row, column); 88478092ae7SKarsten Heimrich 88578092ae7SKarsten Heimrich bool focus = IsFocus() && true; 88678092ae7SKarsten Heimrich const char* day = fDayNumbers[row][column].String(); 88787663db4SOliver Tappe _DrawDay(currRow, currColumn, row, column, counter, tmp, day, 88887663db4SOliver Tappe focus); 889*6846765fSOliver Tappe } else if (focusRow == row && focusColumn == column) { 89078092ae7SKarsten Heimrich const char* day = fDayNumbers[row][column].String(); 89187663db4SOliver Tappe _DrawDay(currRow, currColumn, row, column, counter, tmp, day, 89287663db4SOliver Tappe false); 89378092ae7SKarsten Heimrich } 89478092ae7SKarsten Heimrich tmp.OffsetBy(tmp.Width(), 0.0); 89578092ae7SKarsten Heimrich } 89678092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 89778092ae7SKarsten Heimrich } 89878092ae7SKarsten Heimrich } 89978092ae7SKarsten Heimrich 90078092ae7SKarsten Heimrich 90178092ae7SKarsten Heimrich void 90278092ae7SKarsten Heimrich BCalendarView::_DrawDayHeader() 90378092ae7SKarsten Heimrich { 90478092ae7SKarsten Heimrich if (!fDayNameHeaderVisible) 90578092ae7SKarsten Heimrich return; 90678092ae7SKarsten Heimrich 90778092ae7SKarsten Heimrich int32 offset = 1; 90878092ae7SKarsten Heimrich int32 columns = 8; 90978092ae7SKarsten Heimrich if (!fWeekNumberHeaderVisible) { 91078092ae7SKarsten Heimrich offset = 0; 91178092ae7SKarsten Heimrich columns = 7; 91278092ae7SKarsten Heimrich } 91378092ae7SKarsten Heimrich 91478092ae7SKarsten Heimrich BRect frame = Bounds(); 91578092ae7SKarsten Heimrich frame.right = frame.Width() / columns - 1.0; 91678092ae7SKarsten Heimrich frame.bottom = frame.Height() / 7.0 - 2.0; 91778092ae7SKarsten Heimrich frame.OffsetBy(4.0, 4.0); 91878092ae7SKarsten Heimrich 91978092ae7SKarsten Heimrich for (int32 i = 0; i < columns; ++i) { 92078092ae7SKarsten Heimrich if (i == 0 && fWeekNumberHeaderVisible) { 92178092ae7SKarsten Heimrich DrawDayName(this, frame, ""); 92278092ae7SKarsten Heimrich frame.OffsetBy(frame.Width(), 0.0); 92378092ae7SKarsten Heimrich continue; 92478092ae7SKarsten Heimrich } 92578092ae7SKarsten Heimrich DrawDayName(this, frame, fDayNames[i - offset].String()); 92678092ae7SKarsten Heimrich frame.OffsetBy(frame.Width(), 0.0); 92778092ae7SKarsten Heimrich } 92878092ae7SKarsten Heimrich } 92978092ae7SKarsten Heimrich 93078092ae7SKarsten Heimrich 93178092ae7SKarsten Heimrich void 93278092ae7SKarsten Heimrich BCalendarView::_DrawWeekHeader() 93378092ae7SKarsten Heimrich { 93478092ae7SKarsten Heimrich if (!fWeekNumberHeaderVisible) 93578092ae7SKarsten Heimrich return; 93678092ae7SKarsten Heimrich 93778092ae7SKarsten Heimrich int32 rows = 7; 93878092ae7SKarsten Heimrich if (!fDayNameHeaderVisible) 93978092ae7SKarsten Heimrich rows = 6; 94078092ae7SKarsten Heimrich 94178092ae7SKarsten Heimrich BRect frame = Bounds(); 94278092ae7SKarsten Heimrich frame.right = frame.Width() / 8.0 - 2.0; 94378092ae7SKarsten Heimrich frame.bottom = frame.Height() / rows - 1.0; 94478092ae7SKarsten Heimrich 94578092ae7SKarsten Heimrich float offsetY = 4.0; 94678092ae7SKarsten Heimrich if (fDayNameHeaderVisible) 94778092ae7SKarsten Heimrich offsetY += frame.Height(); 94878092ae7SKarsten Heimrich 94978092ae7SKarsten Heimrich frame.OffsetBy(4.0, offsetY); 95078092ae7SKarsten Heimrich 95178092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 95278092ae7SKarsten Heimrich DrawWeekNumber(this, frame, fWeekNumbers[row].String()); 95378092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 95478092ae7SKarsten Heimrich } 95578092ae7SKarsten Heimrich } 95678092ae7SKarsten Heimrich 95778092ae7SKarsten Heimrich 95878092ae7SKarsten Heimrich void 95978092ae7SKarsten Heimrich BCalendarView::_DrawItem(BView* owner, BRect frame, const char* text, 96078092ae7SKarsten Heimrich bool isSelected, bool isEnabled, bool focus) 96178092ae7SKarsten Heimrich { 96278092ae7SKarsten Heimrich rgb_color lColor = LowColor(); 96378092ae7SKarsten Heimrich rgb_color highColor = HighColor(); 96478092ae7SKarsten Heimrich 96578092ae7SKarsten Heimrich rgb_color lowColor = { 255, 255, 255, 255 }; 96678092ae7SKarsten Heimrich 96778092ae7SKarsten Heimrich if (isSelected) { 96878092ae7SKarsten Heimrich SetHighColor(tint_color(lowColor, B_DARKEN_2_TINT)); 96978092ae7SKarsten Heimrich SetLowColor(HighColor()); 97078092ae7SKarsten Heimrich } else 97178092ae7SKarsten Heimrich SetHighColor(lowColor); 97278092ae7SKarsten Heimrich 97378092ae7SKarsten Heimrich FillRect(frame.InsetByCopy(1.0, 1.0)); 97478092ae7SKarsten Heimrich 97578092ae7SKarsten Heimrich if (focus) { 97678092ae7SKarsten Heimrich SetHighColor(keyboard_navigation_color()); 97778092ae7SKarsten Heimrich StrokeRect(frame.InsetByCopy(1.0, 1.0)); 97878092ae7SKarsten Heimrich } 97978092ae7SKarsten Heimrich 98078092ae7SKarsten Heimrich rgb_color black = { 0, 0, 0, 255 }; 98178092ae7SKarsten Heimrich SetHighColor(black); 98278092ae7SKarsten Heimrich if (!isEnabled) 98378092ae7SKarsten Heimrich SetHighColor(tint_color(black, B_LIGHTEN_2_TINT)); 98478092ae7SKarsten Heimrich 98578092ae7SKarsten Heimrich float offsetH = frame.Width() / 2.0; 986*6846765fSOliver Tappe float offsetV = frame.Height() / 2.0 + FontHeight(owner) / 2.0 - 2.0; 98778092ae7SKarsten Heimrich 988*6846765fSOliver Tappe DrawString(text, BPoint(frame.right - offsetH - StringWidth(text) / 2.0, 989*6846765fSOliver Tappe frame.top + offsetV)); 99078092ae7SKarsten Heimrich 99178092ae7SKarsten Heimrich SetLowColor(lColor); 99278092ae7SKarsten Heimrich SetHighColor(highColor); 99378092ae7SKarsten Heimrich } 99478092ae7SKarsten Heimrich 99578092ae7SKarsten Heimrich 99678092ae7SKarsten Heimrich void 99778092ae7SKarsten Heimrich BCalendarView::_UpdateSelection() 99878092ae7SKarsten Heimrich { 99978092ae7SKarsten Heimrich BRect frame = _FirstCalendarItemFrame(); 100078092ae7SKarsten Heimrich 100178092ae7SKarsten Heimrich const int32 currRow = fSelectedDay.row; 100278092ae7SKarsten Heimrich const int32 currColumn = fSelectedDay.column; 100378092ae7SKarsten Heimrich 100478092ae7SKarsten Heimrich const int32 focusRow = fFocusedDay.row; 100578092ae7SKarsten Heimrich const int32 focusColumn = fFocusedDay.column; 100678092ae7SKarsten Heimrich 100778092ae7SKarsten Heimrich int32 counter = 0; 100878092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 100978092ae7SKarsten Heimrich BRect tmp = frame; 101078092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 101178092ae7SKarsten Heimrich counter++; 101287663db4SOliver Tappe if (fNewSelectedDay.row == row 101387663db4SOliver Tappe && fNewSelectedDay.column == column) { 101478092ae7SKarsten Heimrich fSelectedDay.SetTo(row, column); 101578092ae7SKarsten Heimrich 101678092ae7SKarsten Heimrich const char* day = fDayNumbers[row][column].String(); 101787663db4SOliver Tappe bool focus = IsFocus() && focusRow == row 101887663db4SOliver Tappe && focusColumn == column; 101978092ae7SKarsten Heimrich _DrawDay(row, column, row, column, counter, tmp, day, focus); 1020*6846765fSOliver Tappe } else if (currRow == row && currColumn == column) { 102178092ae7SKarsten Heimrich const char* day = fDayNumbers[row][column].String(); 102287663db4SOliver Tappe bool focus = IsFocus() && focusRow == row 102387663db4SOliver Tappe && focusColumn == column; 102478092ae7SKarsten Heimrich _DrawDay(currRow, currColumn, -1, -1, counter, tmp, day, focus); 102578092ae7SKarsten Heimrich } 102678092ae7SKarsten Heimrich tmp.OffsetBy(tmp.Width(), 0.0); 102778092ae7SKarsten Heimrich } 102878092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 102978092ae7SKarsten Heimrich } 103078092ae7SKarsten Heimrich } 103178092ae7SKarsten Heimrich 103278092ae7SKarsten Heimrich 103378092ae7SKarsten Heimrich BRect 103478092ae7SKarsten Heimrich BCalendarView::_FirstCalendarItemFrame() const 103578092ae7SKarsten Heimrich { 103678092ae7SKarsten Heimrich int32 rows = 7; 103778092ae7SKarsten Heimrich int32 columns = 8; 103878092ae7SKarsten Heimrich 103978092ae7SKarsten Heimrich if (!fDayNameHeaderVisible) 104078092ae7SKarsten Heimrich rows = 6; 104178092ae7SKarsten Heimrich 104278092ae7SKarsten Heimrich if (!fWeekNumberHeaderVisible) 104378092ae7SKarsten Heimrich columns = 7; 104478092ae7SKarsten Heimrich 104578092ae7SKarsten Heimrich BRect frame = Bounds(); 104678092ae7SKarsten Heimrich frame.right = frame.Width() / columns - 1.0; 104778092ae7SKarsten Heimrich frame.bottom = frame.Height() / rows - 1.0; 104878092ae7SKarsten Heimrich 104978092ae7SKarsten Heimrich float offsetY = 4.0; 105078092ae7SKarsten Heimrich if (fDayNameHeaderVisible) 105178092ae7SKarsten Heimrich offsetY += frame.Height(); 105278092ae7SKarsten Heimrich 105378092ae7SKarsten Heimrich float offsetX = 4.0; 105478092ae7SKarsten Heimrich if (fWeekNumberHeaderVisible) 105578092ae7SKarsten Heimrich offsetX += frame.Width(); 105678092ae7SKarsten Heimrich 105778092ae7SKarsten Heimrich return frame.OffsetBySelf(offsetX, offsetY); 105878092ae7SKarsten Heimrich } 105978092ae7SKarsten Heimrich 106078092ae7SKarsten Heimrich 106178092ae7SKarsten Heimrich BRect 106278092ae7SKarsten Heimrich BCalendarView::_SetNewSelectedDay(const BPoint& where) 106378092ae7SKarsten Heimrich { 106478092ae7SKarsten Heimrich BRect frame = _FirstCalendarItemFrame(); 106578092ae7SKarsten Heimrich 106678092ae7SKarsten Heimrich int32 counter = 0; 106778092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 106878092ae7SKarsten Heimrich BRect tmp = frame; 106978092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 107078092ae7SKarsten Heimrich counter++; 107178092ae7SKarsten Heimrich if (tmp.Contains(where)) { 107278092ae7SKarsten Heimrich fNewSelectedDay.SetTo(row, column); 1073*6846765fSOliver Tappe int32 year; 1074*6846765fSOliver Tappe int32 month; 1075*6846765fSOliver Tappe _GetYearMonthForSelection(fNewSelectedDay, &year, &month); 1076*6846765fSOliver Tappe if (month == fDate.Month()) { 1077*6846765fSOliver Tappe // only change date if a day in the current month has been 1078*6846765fSOliver Tappe // selected 1079*6846765fSOliver Tappe int32 day = atoi(fDayNumbers[row][column].String()); 1080*6846765fSOliver Tappe fDate.SetDate(year, month, day); 1081*6846765fSOliver Tappe } 108278092ae7SKarsten Heimrich return tmp; 108378092ae7SKarsten Heimrich } 108478092ae7SKarsten Heimrich tmp.OffsetBy(tmp.Width(), 0.0); 108578092ae7SKarsten Heimrich } 108678092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 108778092ae7SKarsten Heimrich } 108878092ae7SKarsten Heimrich 108978092ae7SKarsten Heimrich return frame; 109078092ae7SKarsten Heimrich } 109178092ae7SKarsten Heimrich 109278092ae7SKarsten Heimrich 109378092ae7SKarsten Heimrich BRect 109478092ae7SKarsten Heimrich BCalendarView::_RectOfDay(const Selection& selection) const 109578092ae7SKarsten Heimrich { 109678092ae7SKarsten Heimrich BRect frame = _FirstCalendarItemFrame(); 109778092ae7SKarsten Heimrich 109878092ae7SKarsten Heimrich int32 counter = 0; 109978092ae7SKarsten Heimrich for (int32 row = 0; row < 6; ++row) { 110078092ae7SKarsten Heimrich BRect tmp = frame; 110178092ae7SKarsten Heimrich for (int32 column = 0; column < 7; ++column) { 110278092ae7SKarsten Heimrich counter++; 1103*6846765fSOliver Tappe if (selection.row == row && selection.column == column) 110478092ae7SKarsten Heimrich return tmp; 110578092ae7SKarsten Heimrich tmp.OffsetBy(tmp.Width(), 0.0); 110678092ae7SKarsten Heimrich } 110778092ae7SKarsten Heimrich frame.OffsetBy(0.0, frame.Height()); 110878092ae7SKarsten Heimrich } 110978092ae7SKarsten Heimrich 111078092ae7SKarsten Heimrich return frame; 111178092ae7SKarsten Heimrich } 111278092ae7SKarsten Heimrich 111378092ae7SKarsten Heimrich 111478092ae7SKarsten Heimrich } // namespace BPrivate 1115