xref: /haiku/src/kits/shared/CalendarView.cpp (revision 99e015b43983f949ef0096e9379099233979ddf8)
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 
386846765fSOliver Tappe BCalendarView::BCalendarView(BRect frame, const char* name, uint32 resizeMask,
396846765fSOliver Tappe 	uint32 flags)
401b3303e7SAxel Dörfler 	:
411b3303e7SAxel Dörfler 	BView(frame, name, resizeMask, flags),
4278092ae7SKarsten Heimrich 	BInvoker(),
4378092ae7SKarsten Heimrich 	fSelectionMessage(NULL),
446846765fSOliver Tappe 	fDate(),
4578092ae7SKarsten Heimrich 	fFocusChanged(false),
4678092ae7SKarsten Heimrich 	fSelectionChanged(false),
476846765fSOliver 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),
606846765fSOliver Tappe 	fDate(),
612530274dSRyan Leavengood 	fFocusChanged(false),
622530274dSRyan Leavengood 	fSelectionChanged(false),
636846765fSOliver 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),
826846765fSOliver Tappe 	fDate(archive),
8378092ae7SKarsten Heimrich 	fFocusChanged(false),
8478092ae7SKarsten Heimrich 	fSelectionChanged(false),
856846765fSOliver 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 
1016846765fSOliver Tappe 	if (archive->FindInt32("_weekStart", &fStartOfWeek) != B_OK)
1026846765fSOliver 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)
1386846765fSOliver Tappe 		status = fDate.Archive(archive);
13978092ae7SKarsten Heimrich 
14078092ae7SKarsten Heimrich 	if (status == B_OK)
1416846765fSOliver 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);
160*99e015b4SJanus 
161*99e015b4SJanus 	SetViewColor(ui_color(B_LIST_BACKGROUND_COLOR));
16278092ae7SKarsten Heimrich }
16378092ae7SKarsten Heimrich 
16478092ae7SKarsten Heimrich 
16578092ae7SKarsten Heimrich void
16678092ae7SKarsten Heimrich BCalendarView::FrameResized(float width, float height)
16778092ae7SKarsten Heimrich {
16878092ae7SKarsten Heimrich 	Invalidate(Bounds());
16978092ae7SKarsten Heimrich }
17078092ae7SKarsten Heimrich 
17178092ae7SKarsten Heimrich 
17278092ae7SKarsten Heimrich void
17378092ae7SKarsten Heimrich BCalendarView::Draw(BRect updateRect)
17478092ae7SKarsten Heimrich {
17578092ae7SKarsten Heimrich 	if (LockLooper()) {
17678092ae7SKarsten Heimrich 		if (fFocusChanged) {
17778092ae7SKarsten Heimrich 			_DrawFocusRect();
17878092ae7SKarsten Heimrich 			UnlockLooper();
17978092ae7SKarsten Heimrich 			return;
18078092ae7SKarsten Heimrich 		}
18178092ae7SKarsten Heimrich 
18278092ae7SKarsten Heimrich 		if (fSelectionChanged) {
18378092ae7SKarsten Heimrich 			_UpdateSelection();
18478092ae7SKarsten Heimrich 			UnlockLooper();
18578092ae7SKarsten Heimrich 			return;
18678092ae7SKarsten Heimrich 		}
18778092ae7SKarsten Heimrich 
18878092ae7SKarsten Heimrich 		_DrawDays();
18978092ae7SKarsten Heimrich 		_DrawDayHeader();
19078092ae7SKarsten Heimrich 		_DrawWeekHeader();
19178092ae7SKarsten Heimrich 
19278092ae7SKarsten Heimrich 		rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
19378092ae7SKarsten Heimrich 		SetHighColor(tint_color(background, B_DARKEN_3_TINT));
19478092ae7SKarsten Heimrich 		StrokeRect(Bounds());
19578092ae7SKarsten Heimrich 
19678092ae7SKarsten Heimrich 		UnlockLooper();
19778092ae7SKarsten Heimrich 	}
19878092ae7SKarsten Heimrich }
19978092ae7SKarsten Heimrich 
20078092ae7SKarsten Heimrich 
20178092ae7SKarsten Heimrich void
20278092ae7SKarsten Heimrich BCalendarView::DrawDay(BView* owner, BRect frame, const char* text,
20378092ae7SKarsten Heimrich 	bool isSelected, bool isEnabled, bool focus)
20478092ae7SKarsten Heimrich {
20578092ae7SKarsten Heimrich 	_DrawItem(owner, frame, text, isSelected, isEnabled, focus);
20678092ae7SKarsten Heimrich }
20778092ae7SKarsten Heimrich 
20878092ae7SKarsten Heimrich 
20978092ae7SKarsten Heimrich void
21078092ae7SKarsten Heimrich BCalendarView::DrawDayName(BView* owner, BRect frame, const char* text)
21178092ae7SKarsten Heimrich {
21278092ae7SKarsten Heimrich 	// we get the full rect, fake this as the internal function
21378092ae7SKarsten Heimrich 	// shrinks the frame to work properly when drawing a day item
21478092ae7SKarsten Heimrich 	_DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true);
21578092ae7SKarsten Heimrich }
21678092ae7SKarsten Heimrich 
21778092ae7SKarsten Heimrich 
21878092ae7SKarsten Heimrich void
21978092ae7SKarsten Heimrich BCalendarView::DrawWeekNumber(BView* owner, BRect frame, const char* text)
22078092ae7SKarsten Heimrich {
22178092ae7SKarsten Heimrich 	// we get the full rect, fake this as the internal function
22278092ae7SKarsten Heimrich 	// shrinks the frame to work properly when drawing a day item
22378092ae7SKarsten Heimrich 	_DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true);
22478092ae7SKarsten Heimrich }
22578092ae7SKarsten Heimrich 
22678092ae7SKarsten Heimrich 
22778092ae7SKarsten Heimrich uint32
22878092ae7SKarsten Heimrich BCalendarView::SelectionCommand() const
22978092ae7SKarsten Heimrich {
23078092ae7SKarsten Heimrich 	if (SelectionMessage())
23178092ae7SKarsten Heimrich 		return SelectionMessage()->what;
23278092ae7SKarsten Heimrich 
23378092ae7SKarsten Heimrich 	return 0;
23478092ae7SKarsten Heimrich }
23578092ae7SKarsten Heimrich 
23678092ae7SKarsten Heimrich 
23778092ae7SKarsten Heimrich BMessage*
23878092ae7SKarsten Heimrich BCalendarView::SelectionMessage() const
23978092ae7SKarsten Heimrich {
24078092ae7SKarsten Heimrich 	return fSelectionMessage;
24178092ae7SKarsten Heimrich }
24278092ae7SKarsten Heimrich 
24378092ae7SKarsten Heimrich 
24478092ae7SKarsten Heimrich void
24578092ae7SKarsten Heimrich BCalendarView::SetSelectionMessage(BMessage* message)
24678092ae7SKarsten Heimrich {
24778092ae7SKarsten Heimrich 	delete fSelectionMessage;
24878092ae7SKarsten Heimrich 	fSelectionMessage = message;
24978092ae7SKarsten Heimrich }
25078092ae7SKarsten Heimrich 
25178092ae7SKarsten Heimrich 
25278092ae7SKarsten Heimrich uint32
25378092ae7SKarsten Heimrich BCalendarView::InvocationCommand() const
25478092ae7SKarsten Heimrich {
25578092ae7SKarsten Heimrich 	return BInvoker::Command();
25678092ae7SKarsten Heimrich }
25778092ae7SKarsten Heimrich 
25878092ae7SKarsten Heimrich 
25978092ae7SKarsten Heimrich BMessage*
26078092ae7SKarsten Heimrich BCalendarView::InvocationMessage() const
26178092ae7SKarsten Heimrich {
26278092ae7SKarsten Heimrich 	return BInvoker::Message();
26378092ae7SKarsten Heimrich }
26478092ae7SKarsten Heimrich 
26578092ae7SKarsten Heimrich 
26678092ae7SKarsten Heimrich void
26778092ae7SKarsten Heimrich BCalendarView::SetInvocationMessage(BMessage* message)
26878092ae7SKarsten Heimrich {
26978092ae7SKarsten Heimrich 	BInvoker::SetMessage(message);
27078092ae7SKarsten Heimrich }
27178092ae7SKarsten Heimrich 
27278092ae7SKarsten Heimrich 
27378092ae7SKarsten Heimrich void
27478092ae7SKarsten Heimrich BCalendarView::MakeFocus(bool state)
27578092ae7SKarsten Heimrich {
27678092ae7SKarsten Heimrich 	if (IsFocus() == state)
27778092ae7SKarsten Heimrich 		return;
27878092ae7SKarsten Heimrich 
27978092ae7SKarsten Heimrich 	BView::MakeFocus(state);
28078092ae7SKarsten Heimrich 
2811b3303e7SAxel Dörfler 	// TODO: solve this better
28278092ae7SKarsten Heimrich 	fFocusChanged = true;
28378092ae7SKarsten Heimrich 	Draw(_RectOfDay(fFocusedDay));
28478092ae7SKarsten Heimrich 	fFocusChanged = false;
28578092ae7SKarsten Heimrich }
28678092ae7SKarsten Heimrich 
28778092ae7SKarsten Heimrich 
28878092ae7SKarsten Heimrich status_t
28978092ae7SKarsten Heimrich BCalendarView::Invoke(BMessage* message)
29078092ae7SKarsten Heimrich {
29178092ae7SKarsten Heimrich 	bool notify = false;
29278092ae7SKarsten Heimrich 	uint32 kind = InvokeKind(&notify);
29378092ae7SKarsten Heimrich 
29478092ae7SKarsten Heimrich 	BMessage clone(kind);
29578092ae7SKarsten Heimrich 	status_t status = B_BAD_VALUE;
29678092ae7SKarsten Heimrich 
29778092ae7SKarsten Heimrich 	if (!message && !notify)
29878092ae7SKarsten Heimrich 		message = Message();
29978092ae7SKarsten Heimrich 
30078092ae7SKarsten Heimrich 	if (!message) {
30178092ae7SKarsten Heimrich 		if (!IsWatched())
30278092ae7SKarsten Heimrich 			return status;
30378092ae7SKarsten Heimrich 	} else
30478092ae7SKarsten Heimrich 		clone = *message;
30578092ae7SKarsten Heimrich 
30678092ae7SKarsten Heimrich 	clone.AddPointer("source", this);
30778092ae7SKarsten Heimrich 	clone.AddInt64("when", (int64)system_time());
30878092ae7SKarsten Heimrich 	clone.AddMessenger("be:sender", BMessenger(this));
30978092ae7SKarsten Heimrich 
31078092ae7SKarsten Heimrich 	int32 year;
31178092ae7SKarsten Heimrich 	int32 month;
3126846765fSOliver Tappe 	_GetYearMonthForSelection(fSelectedDay, &year, &month);
31378092ae7SKarsten Heimrich 
3146846765fSOliver Tappe 	clone.AddInt32("year", fDate.Year());
3156846765fSOliver Tappe 	clone.AddInt32("month", fDate.Month());
3166846765fSOliver Tappe 	clone.AddInt32("day", fDate.Day());
31778092ae7SKarsten Heimrich 
31878092ae7SKarsten Heimrich 	if (message)
31978092ae7SKarsten Heimrich 		status = BInvoker::Invoke(&clone);
32078092ae7SKarsten Heimrich 
32178092ae7SKarsten Heimrich 	SendNotices(kind, &clone);
32278092ae7SKarsten Heimrich 
32378092ae7SKarsten Heimrich 	return status;
32478092ae7SKarsten Heimrich }
32578092ae7SKarsten Heimrich 
32678092ae7SKarsten Heimrich 
32778092ae7SKarsten Heimrich void
32878092ae7SKarsten Heimrich BCalendarView::MouseDown(BPoint where)
32978092ae7SKarsten Heimrich {
33078092ae7SKarsten Heimrich 	if (!IsFocus()) {
33178092ae7SKarsten Heimrich 		MakeFocus();
33278092ae7SKarsten Heimrich 		Sync();
33378092ae7SKarsten Heimrich 		Window()->UpdateIfNeeded();
33478092ae7SKarsten Heimrich 	}
33578092ae7SKarsten Heimrich 
33678092ae7SKarsten Heimrich 	BRect frame = Bounds();
33778092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
33878092ae7SKarsten Heimrich 		frame.top += frame.Height() / 7 - 1.0;
33978092ae7SKarsten Heimrich 
34078092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible)
34178092ae7SKarsten Heimrich 		frame.left += frame.Width() / 8 - 1.0;
34278092ae7SKarsten Heimrich 
34378092ae7SKarsten Heimrich 	if (!frame.Contains(where))
34478092ae7SKarsten Heimrich 		return;
34578092ae7SKarsten Heimrich 
34678092ae7SKarsten Heimrich 	// try to set to new day
34778092ae7SKarsten Heimrich 	frame = _SetNewSelectedDay(where);
34878092ae7SKarsten Heimrich 
34978092ae7SKarsten Heimrich 	// on success
35078092ae7SKarsten Heimrich 	if (fSelectedDay != fNewSelectedDay) {
35178092ae7SKarsten Heimrich 		// update focus
35278092ae7SKarsten Heimrich 		fFocusChanged = true;
35378092ae7SKarsten Heimrich 		fNewFocusedDay = fNewSelectedDay;
35478092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
35578092ae7SKarsten Heimrich 		fFocusChanged = false;
35678092ae7SKarsten Heimrich 
35778092ae7SKarsten Heimrich 		// update selection
35878092ae7SKarsten Heimrich 		fSelectionChanged = true;
35978092ae7SKarsten Heimrich 		Draw(frame);
36078092ae7SKarsten Heimrich 		Draw(_RectOfDay(fSelectedDay));
36178092ae7SKarsten Heimrich 		fSelectionChanged = false;
36278092ae7SKarsten Heimrich 
36378092ae7SKarsten Heimrich 		// notify that selection changed
36478092ae7SKarsten Heimrich 		InvokeNotify(SelectionMessage(), B_CONTROL_MODIFIED);
36578092ae7SKarsten Heimrich 	}
36678092ae7SKarsten Heimrich 
36778092ae7SKarsten Heimrich 	int32 clicks;
36878092ae7SKarsten Heimrich 	// on double click invoke
36978092ae7SKarsten Heimrich 	BMessage* message = Looper()->CurrentMessage();
37078092ae7SKarsten Heimrich 	if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1)
37178092ae7SKarsten Heimrich 		Invoke();
37278092ae7SKarsten Heimrich }
37378092ae7SKarsten Heimrich 
37478092ae7SKarsten Heimrich 
37578092ae7SKarsten Heimrich void
37678092ae7SKarsten Heimrich BCalendarView::KeyDown(const char* bytes, int32 numBytes)
37778092ae7SKarsten Heimrich {
37878092ae7SKarsten Heimrich 	const int32 kRows = 6;
37978092ae7SKarsten Heimrich 	const int32 kColumns = 7;
38078092ae7SKarsten Heimrich 
38178092ae7SKarsten Heimrich 	int32 row = fFocusedDay.row;
38278092ae7SKarsten Heimrich 	int32 column = fFocusedDay.column;
38378092ae7SKarsten Heimrich 
38478092ae7SKarsten Heimrich 	switch (bytes[0]) {
38578092ae7SKarsten Heimrich 		case B_LEFT_ARROW:
38678092ae7SKarsten Heimrich 			column -= 1;
38778092ae7SKarsten Heimrich 			if (column < 0) {
38878092ae7SKarsten Heimrich 				column = kColumns - 1;
38978092ae7SKarsten Heimrich 				row -= 1;
39078092ae7SKarsten Heimrich 				if (row >= 0)
39178092ae7SKarsten Heimrich 					fFocusChanged = true;
39278092ae7SKarsten Heimrich 			} else
39378092ae7SKarsten Heimrich 				fFocusChanged = true;
3946846765fSOliver Tappe 			break;
39578092ae7SKarsten Heimrich 
39678092ae7SKarsten Heimrich 		case B_RIGHT_ARROW:
39778092ae7SKarsten Heimrich 			column += 1;
39878092ae7SKarsten Heimrich 			if (column == kColumns) {
39978092ae7SKarsten Heimrich 				column = 0;
40078092ae7SKarsten Heimrich 				row += 1;
40178092ae7SKarsten Heimrich 				if (row < kRows)
40278092ae7SKarsten Heimrich 					fFocusChanged = true;
40378092ae7SKarsten Heimrich 			} else
40478092ae7SKarsten Heimrich 				fFocusChanged = true;
4056846765fSOliver Tappe 			break;
40678092ae7SKarsten Heimrich 
40778092ae7SKarsten Heimrich 		case B_UP_ARROW:
40878092ae7SKarsten Heimrich 			row -= 1;
40978092ae7SKarsten Heimrich 			if (row >= 0)
41078092ae7SKarsten Heimrich 				fFocusChanged = true;
4116846765fSOliver Tappe 			break;
41278092ae7SKarsten Heimrich 
41378092ae7SKarsten Heimrich 		case B_DOWN_ARROW:
41478092ae7SKarsten Heimrich 			row += 1;
41578092ae7SKarsten Heimrich 			if (row < kRows)
41678092ae7SKarsten Heimrich 				fFocusChanged = true;
4176846765fSOliver Tappe 			break;
4186846765fSOliver Tappe 
4196846765fSOliver Tappe 		case B_PAGE_UP:
4206846765fSOliver Tappe 		{
4216846765fSOliver Tappe 			BDate date(fDate);
4226846765fSOliver Tappe 			date.AddMonths(-1);
4236846765fSOliver Tappe 			SetDate(date);
4246846765fSOliver Tappe 
4256846765fSOliver Tappe 			Invoke();
4266846765fSOliver Tappe 			break;
4276846765fSOliver Tappe 		}
4286846765fSOliver Tappe 
4296846765fSOliver Tappe 		case B_PAGE_DOWN:
4306846765fSOliver Tappe 		{
4316846765fSOliver Tappe 			BDate date(fDate);
4326846765fSOliver Tappe 			date.AddMonths(1);
4336846765fSOliver Tappe 			SetDate(date);
4346846765fSOliver Tappe 
4356846765fSOliver Tappe 			Invoke();
4366846765fSOliver Tappe 			break;
4376846765fSOliver Tappe 		}
43878092ae7SKarsten Heimrich 
43978092ae7SKarsten Heimrich 		case B_RETURN:
4406846765fSOliver Tappe 		case B_SPACE:
4416846765fSOliver Tappe 		{
44278092ae7SKarsten Heimrich 			fSelectionChanged = true;
44378092ae7SKarsten Heimrich 			BPoint pt = _RectOfDay(fFocusedDay).LeftTop();
44478092ae7SKarsten Heimrich 			Draw(_SetNewSelectedDay(pt + BPoint(4.0, 4.0)));
44578092ae7SKarsten Heimrich 			Draw(_RectOfDay(fSelectedDay));
44678092ae7SKarsten Heimrich 			fSelectionChanged = false;
44778092ae7SKarsten Heimrich 
44878092ae7SKarsten Heimrich 			Invoke();
4496846765fSOliver Tappe 			break;
4506846765fSOliver Tappe 		}
45178092ae7SKarsten Heimrich 
45278092ae7SKarsten Heimrich 		default:
45378092ae7SKarsten Heimrich 			BView::KeyDown(bytes, numBytes);
45478092ae7SKarsten Heimrich 			break;
45578092ae7SKarsten Heimrich 	}
45678092ae7SKarsten Heimrich 
45778092ae7SKarsten Heimrich 	if (fFocusChanged) {
45878092ae7SKarsten Heimrich 		fNewFocusedDay.SetTo(row, column);
45978092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
46078092ae7SKarsten Heimrich 		Draw(_RectOfDay(fNewFocusedDay));
46178092ae7SKarsten Heimrich 		fFocusChanged = false;
46278092ae7SKarsten Heimrich 	}
46378092ae7SKarsten Heimrich }
46478092ae7SKarsten Heimrich 
46578092ae7SKarsten Heimrich 
46678092ae7SKarsten Heimrich void
46778092ae7SKarsten Heimrich BCalendarView::ResizeToPreferred()
46878092ae7SKarsten Heimrich {
46978092ae7SKarsten Heimrich 	float width;
47078092ae7SKarsten Heimrich 	float height;
47178092ae7SKarsten Heimrich 
47278092ae7SKarsten Heimrich 	GetPreferredSize(&width, &height);
47378092ae7SKarsten Heimrich 	BView::ResizeTo(width, height);
47478092ae7SKarsten Heimrich }
47578092ae7SKarsten Heimrich 
47678092ae7SKarsten Heimrich 
47778092ae7SKarsten Heimrich void
47878092ae7SKarsten Heimrich BCalendarView::GetPreferredSize(float* width, float* height)
47978092ae7SKarsten Heimrich {
48078092ae7SKarsten Heimrich 	_GetPreferredSize(width, height);
48178092ae7SKarsten Heimrich }
48278092ae7SKarsten Heimrich 
48378092ae7SKarsten Heimrich 
4842530274dSRyan Leavengood BSize
4852530274dSRyan Leavengood BCalendarView::MaxSize()
4862530274dSRyan Leavengood {
4872530274dSRyan Leavengood 	return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
4882530274dSRyan Leavengood 		BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
4892530274dSRyan Leavengood }
4902530274dSRyan Leavengood 
4912530274dSRyan Leavengood 
4922530274dSRyan Leavengood BSize
4932530274dSRyan Leavengood BCalendarView::MinSize()
4942530274dSRyan Leavengood {
4952530274dSRyan Leavengood 	float width, height;
4962530274dSRyan Leavengood 	_GetPreferredSize(&width, &height);
4976846765fSOliver Tappe 	return BLayoutUtils::ComposeSize(ExplicitMinSize(), BSize(width, height));
4982530274dSRyan Leavengood }
4992530274dSRyan Leavengood 
5002530274dSRyan Leavengood 
5012530274dSRyan Leavengood BSize
5022530274dSRyan Leavengood BCalendarView::PreferredSize()
5032530274dSRyan Leavengood {
5046846765fSOliver Tappe 	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), MinSize());
5052530274dSRyan Leavengood }
5062530274dSRyan Leavengood 
5072530274dSRyan Leavengood 
50878092ae7SKarsten Heimrich int32
50978092ae7SKarsten Heimrich BCalendarView::Day() const
51078092ae7SKarsten Heimrich {
5116846765fSOliver Tappe 	return fDate.Day();
51278092ae7SKarsten Heimrich }
51378092ae7SKarsten Heimrich 
51478092ae7SKarsten Heimrich 
51578092ae7SKarsten Heimrich int32
51678092ae7SKarsten Heimrich BCalendarView::Year() const
51778092ae7SKarsten Heimrich {
51878092ae7SKarsten Heimrich 	int32 year;
5196846765fSOliver Tappe 	_GetYearMonthForSelection(fSelectedDay, &year, NULL);
52078092ae7SKarsten Heimrich 
52178092ae7SKarsten Heimrich 	return year;
52278092ae7SKarsten Heimrich }
52378092ae7SKarsten Heimrich 
52478092ae7SKarsten Heimrich 
52578092ae7SKarsten Heimrich int32
52678092ae7SKarsten Heimrich BCalendarView::Month() const
52778092ae7SKarsten Heimrich {
52878092ae7SKarsten Heimrich 	int32 month;
5296846765fSOliver Tappe 	_GetYearMonthForSelection(fSelectedDay, NULL, &month);
53078092ae7SKarsten Heimrich 
53178092ae7SKarsten Heimrich 	return month;
53278092ae7SKarsten Heimrich }
53378092ae7SKarsten Heimrich 
53478092ae7SKarsten Heimrich 
535afd5ec11SAdrien Destugues bool
536afd5ec11SAdrien Destugues BCalendarView::SetDay(int32 day)
537afd5ec11SAdrien Destugues {
538afd5ec11SAdrien Destugues 	BDate date = Date();
539afd5ec11SAdrien Destugues 	date.SetDay(day);
540afd5ec11SAdrien Destugues 	if (!date.IsValid())
541afd5ec11SAdrien Destugues 		return false;
542afd5ec11SAdrien Destugues 	SetDate(date);
543afd5ec11SAdrien Destugues 	return true;
544afd5ec11SAdrien Destugues }
545afd5ec11SAdrien Destugues 
546afd5ec11SAdrien Destugues 
547afd5ec11SAdrien Destugues bool
548afd5ec11SAdrien Destugues BCalendarView::SetMonth(int32 month)
549afd5ec11SAdrien Destugues {
550afd5ec11SAdrien Destugues 	if (month < 1 || month > 12)
551afd5ec11SAdrien Destugues 		return false;
552afd5ec11SAdrien Destugues 	BDate date = Date();
553afd5ec11SAdrien Destugues 	int32 oldDay = date.Day();
554afd5ec11SAdrien Destugues 
555afd5ec11SAdrien Destugues 	date.SetMonth(month);
556afd5ec11SAdrien Destugues 	date.SetDay(1); // make sure the date is valid
557afd5ec11SAdrien Destugues 
558afd5ec11SAdrien Destugues 	// We must make sure that the day in month fits inside the new month.
559afd5ec11SAdrien Destugues 	if (oldDay > date.DaysInMonth())
560afd5ec11SAdrien Destugues 		date.SetDay(date.DaysInMonth());
561afd5ec11SAdrien Destugues 	else
562afd5ec11SAdrien Destugues 		date.SetDay(oldDay);
563afd5ec11SAdrien Destugues 	SetDate(date);
564afd5ec11SAdrien Destugues 	return true;
565afd5ec11SAdrien Destugues }
566afd5ec11SAdrien Destugues 
567afd5ec11SAdrien Destugues 
568afd5ec11SAdrien Destugues bool
569afd5ec11SAdrien Destugues BCalendarView::SetYear(int32 year)
570afd5ec11SAdrien Destugues {
571afd5ec11SAdrien Destugues 	BDate date = Date();
572afd5ec11SAdrien Destugues 
573afd5ec11SAdrien Destugues 	// This can fail when going from 29 feb. on a leap year to a non-leap year.
574afd5ec11SAdrien Destugues 	if (date.Month() == 2 && date.Day() == 29 && !date.IsLeapYear(year))
575afd5ec11SAdrien Destugues 		date.SetDay(28);
576afd5ec11SAdrien Destugues 
577afd5ec11SAdrien Destugues 	// TODO we should also handle the "hole" at the switch between Julian and
578afd5ec11SAdrien Destugues 	// Gregorian calendars, which will result in an invalid date.
579afd5ec11SAdrien Destugues 
580afd5ec11SAdrien Destugues 	date.SetYear(year);
581afd5ec11SAdrien Destugues 	SetDate(date);
582afd5ec11SAdrien Destugues 	return true;
583afd5ec11SAdrien Destugues }
584afd5ec11SAdrien Destugues 
585afd5ec11SAdrien Destugues 
58678092ae7SKarsten Heimrich BDate
58778092ae7SKarsten Heimrich BCalendarView::Date() const
58878092ae7SKarsten Heimrich {
58978092ae7SKarsten Heimrich 	int32 year;
59078092ae7SKarsten Heimrich 	int32 month;
5916846765fSOliver Tappe 	_GetYearMonthForSelection(fSelectedDay, &year, &month);
5926846765fSOliver Tappe 	return BDate(year, month, fDate.Day());
59378092ae7SKarsten Heimrich }
59478092ae7SKarsten Heimrich 
59578092ae7SKarsten Heimrich 
59678092ae7SKarsten Heimrich bool
59778092ae7SKarsten Heimrich BCalendarView::SetDate(const BDate& date)
59878092ae7SKarsten Heimrich {
599c1ed5d75SKarsten Heimrich 	if (!date.IsValid())
600c1ed5d75SKarsten Heimrich 		return false;
601c1ed5d75SKarsten Heimrich 
6026846765fSOliver Tappe 	if (fDate == date)
60378092ae7SKarsten Heimrich 		return true;
60478092ae7SKarsten Heimrich 
6056846765fSOliver Tappe 	if (fDate.Year() == date.Year() && fDate.Month() == date.Month()) {
6066846765fSOliver Tappe 		fDate = date;
6076846765fSOliver Tappe 
60878092ae7SKarsten Heimrich 		_SetToDay();
60978092ae7SKarsten Heimrich 		// update focus
61078092ae7SKarsten Heimrich 		fFocusChanged = true;
61178092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
61278092ae7SKarsten Heimrich 		fFocusChanged = false;
61378092ae7SKarsten Heimrich 
61478092ae7SKarsten Heimrich 		// update selection
61578092ae7SKarsten Heimrich 		fSelectionChanged = true;
61678092ae7SKarsten Heimrich 		Draw(_RectOfDay(fSelectedDay));
61778092ae7SKarsten Heimrich 		Draw(_RectOfDay(fNewSelectedDay));
61878092ae7SKarsten Heimrich 		fSelectionChanged = false;
61978092ae7SKarsten Heimrich 	} else {
6206846765fSOliver Tappe 		fDate = date;
62178092ae7SKarsten Heimrich 
62278092ae7SKarsten Heimrich 		_SetupDayNumbers();
62378092ae7SKarsten Heimrich 		_SetupWeekNumbers();
62478092ae7SKarsten Heimrich 
62578092ae7SKarsten Heimrich 		BRect frame = Bounds();
62678092ae7SKarsten Heimrich 		if (fDayNameHeaderVisible)
62778092ae7SKarsten Heimrich 			frame.top += frame.Height() / 7 - 1.0;
62878092ae7SKarsten Heimrich 
62978092ae7SKarsten Heimrich 		if (fWeekNumberHeaderVisible)
63078092ae7SKarsten Heimrich 			frame.left += frame.Width() / 8 - 1.0;
63178092ae7SKarsten Heimrich 
63278092ae7SKarsten Heimrich 		Draw(frame.InsetBySelf(4.0, 4.0));
63378092ae7SKarsten Heimrich 	}
63478092ae7SKarsten Heimrich 
63578092ae7SKarsten Heimrich 	return true;
63678092ae7SKarsten Heimrich }
63778092ae7SKarsten Heimrich 
63878092ae7SKarsten Heimrich 
6396846765fSOliver Tappe bool
6406846765fSOliver Tappe BCalendarView::SetDate(int32 year, int32 month, int32 day)
64178092ae7SKarsten Heimrich {
6426846765fSOliver Tappe 	return SetDate(BDate(year, month, day));
6436846765fSOliver Tappe }
6446846765fSOliver Tappe 
6456846765fSOliver Tappe 
6466846765fSOliver Tappe BWeekday
6476846765fSOliver Tappe BCalendarView::StartOfWeek() const
6486846765fSOliver Tappe {
6496846765fSOliver Tappe 	return BWeekday(fStartOfWeek);
65078092ae7SKarsten Heimrich }
65178092ae7SKarsten Heimrich 
65278092ae7SKarsten Heimrich 
65378092ae7SKarsten Heimrich void
6546846765fSOliver Tappe BCalendarView::SetStartOfWeek(BWeekday startOfWeek)
65578092ae7SKarsten Heimrich {
6566846765fSOliver Tappe 	if (fStartOfWeek == (int32)startOfWeek)
65778092ae7SKarsten Heimrich 		return;
65878092ae7SKarsten Heimrich 
6596846765fSOliver Tappe 	fStartOfWeek = (int32)startOfWeek;
66078092ae7SKarsten Heimrich 
66178092ae7SKarsten Heimrich 	_SetupDayNames();
66278092ae7SKarsten Heimrich 	_SetupDayNumbers();
66378092ae7SKarsten Heimrich 	_SetupWeekNumbers();
66478092ae7SKarsten Heimrich 
66578092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
66678092ae7SKarsten Heimrich }
66778092ae7SKarsten Heimrich 
66878092ae7SKarsten Heimrich 
66978092ae7SKarsten Heimrich bool
67078092ae7SKarsten Heimrich BCalendarView::IsDayNameHeaderVisible() const
67178092ae7SKarsten Heimrich {
67278092ae7SKarsten Heimrich 	return fDayNameHeaderVisible;
67378092ae7SKarsten Heimrich }
67478092ae7SKarsten Heimrich 
67578092ae7SKarsten Heimrich 
67678092ae7SKarsten Heimrich void
67778092ae7SKarsten Heimrich BCalendarView::SetDayNameHeaderVisible(bool visible)
67878092ae7SKarsten Heimrich {
67978092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible == visible)
68078092ae7SKarsten Heimrich 		return;
68178092ae7SKarsten Heimrich 
68278092ae7SKarsten Heimrich 	fDayNameHeaderVisible = visible;
68378092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
68478092ae7SKarsten Heimrich }
68578092ae7SKarsten Heimrich 
68678092ae7SKarsten Heimrich 
68778092ae7SKarsten Heimrich bool
68878092ae7SKarsten Heimrich BCalendarView::IsWeekNumberHeaderVisible() const
68978092ae7SKarsten Heimrich {
69078092ae7SKarsten Heimrich 	return fWeekNumberHeaderVisible;
69178092ae7SKarsten Heimrich }
69278092ae7SKarsten Heimrich 
69378092ae7SKarsten Heimrich 
69478092ae7SKarsten Heimrich void
69578092ae7SKarsten Heimrich BCalendarView::SetWeekNumberHeaderVisible(bool visible)
69678092ae7SKarsten Heimrich {
69778092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible == visible)
69878092ae7SKarsten Heimrich 		return;
69978092ae7SKarsten Heimrich 
70078092ae7SKarsten Heimrich 	fWeekNumberHeaderVisible = visible;
70178092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
70278092ae7SKarsten Heimrich }
70378092ae7SKarsten Heimrich 
70478092ae7SKarsten Heimrich 
70578092ae7SKarsten Heimrich void
70678092ae7SKarsten Heimrich BCalendarView::_InitObject()
70778092ae7SKarsten Heimrich {
7086846765fSOliver Tappe 	fDate = BDate::CurrentDate(B_LOCAL_TIME);
7096846765fSOliver Tappe 
7100a925409SAdrien Destugues 	BDateFormat().GetStartOfWeek((BWeekday*)&fStartOfWeek);
71178092ae7SKarsten Heimrich 
71278092ae7SKarsten Heimrich 	_SetupDayNames();
71378092ae7SKarsten Heimrich 	_SetupDayNumbers();
71478092ae7SKarsten Heimrich 	_SetupWeekNumbers();
71578092ae7SKarsten Heimrich }
71678092ae7SKarsten Heimrich 
71778092ae7SKarsten Heimrich 
71878092ae7SKarsten Heimrich void
71978092ae7SKarsten Heimrich BCalendarView::_SetToDay()
72078092ae7SKarsten Heimrich {
7216846765fSOliver Tappe 	BDate date(fDate.Year(), fDate.Month(), 1);
72278092ae7SKarsten Heimrich 	if (!date.IsValid())
72378092ae7SKarsten Heimrich 		return;
72478092ae7SKarsten Heimrich 
7256846765fSOliver Tappe 	const int32 firstDayOffset = (7 + date.DayOfWeek() - fStartOfWeek) % 7;
72678092ae7SKarsten Heimrich 
7276846765fSOliver Tappe 	int32 day = 1 - firstDayOffset;
72878092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
72978092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
7306846765fSOliver Tappe 			if (day == fDate.Day()) {
73178092ae7SKarsten Heimrich 				fNewFocusedDay.SetTo(row, column);
73278092ae7SKarsten Heimrich 				fNewSelectedDay.SetTo(row, column);
73378092ae7SKarsten Heimrich 				return;
73478092ae7SKarsten Heimrich 			}
7356846765fSOliver Tappe 			day++;
73678092ae7SKarsten Heimrich 		}
73778092ae7SKarsten Heimrich 	}
7386846765fSOliver Tappe 
7396846765fSOliver Tappe 	fNewFocusedDay.SetTo(0, 0);
7406846765fSOliver Tappe 	fNewSelectedDay.SetTo(0, 0);
74178092ae7SKarsten Heimrich }
74278092ae7SKarsten Heimrich 
74378092ae7SKarsten Heimrich 
74478092ae7SKarsten Heimrich void
7456846765fSOliver Tappe BCalendarView::_GetYearMonthForSelection(const Selection& selection,
7466846765fSOliver Tappe 	int32* year, int32* month) const
74778092ae7SKarsten Heimrich {
7486846765fSOliver Tappe 	BDate startOfMonth(fDate.Year(), fDate.Month(), 1);
7496846765fSOliver Tappe 	const int32 firstDayOffset
7506846765fSOliver Tappe 		= (7 + startOfMonth.DayOfWeek() - fStartOfWeek) % 7;
7516846765fSOliver Tappe 	const int32 daysInMonth = startOfMonth.DaysInMonth();
75278092ae7SKarsten Heimrich 
7536846765fSOliver Tappe 	BDate date(fDate);
7546846765fSOliver Tappe 	const int32 dayOffset = selection.row * 7 + selection.column;
7556846765fSOliver Tappe 	if (dayOffset < firstDayOffset)
7566846765fSOliver Tappe 		date.AddMonths(-1);
7576846765fSOliver Tappe 	else if (dayOffset >= firstDayOffset + daysInMonth)
7586846765fSOliver Tappe 		date.AddMonths(1);
7596846765fSOliver Tappe 	if (year != NULL)
76078092ae7SKarsten Heimrich 		*year = date.Year();
7616846765fSOliver Tappe 	if (month != NULL)
76278092ae7SKarsten Heimrich 		*month = date.Month();
76378092ae7SKarsten Heimrich }
76478092ae7SKarsten Heimrich 
76578092ae7SKarsten Heimrich 
76678092ae7SKarsten Heimrich void
76778092ae7SKarsten Heimrich BCalendarView::_GetPreferredSize(float* _width, float* _height)
76878092ae7SKarsten Heimrich {
76978092ae7SKarsten Heimrich 	BFont font;
77078092ae7SKarsten Heimrich 	GetFont(&font);
77178092ae7SKarsten Heimrich 	font_height fontHeight;
77278092ae7SKarsten Heimrich 	font.GetHeight(&fontHeight);
77378092ae7SKarsten Heimrich 
77478092ae7SKarsten Heimrich 	const float height = FontHeight(this) + 4.0;
77578092ae7SKarsten Heimrich 
77678092ae7SKarsten Heimrich 	int32 rows = 7;
77778092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
77878092ae7SKarsten Heimrich 		rows = 6;
77978092ae7SKarsten Heimrich 
78078092ae7SKarsten Heimrich 	// height = font height * rows + 8 px border
78178092ae7SKarsten Heimrich 	*_height = height * rows + 8.0;
78278092ae7SKarsten Heimrich 
78378092ae7SKarsten Heimrich 	float width = 0.0;
78478092ae7SKarsten Heimrich 	for (int32 column = 0; column < 7; ++column) {
78578092ae7SKarsten Heimrich 		float tmp = StringWidth(fDayNames[column].String()) + 2.0;
78678092ae7SKarsten Heimrich 		width = tmp > width ? tmp : width;
78778092ae7SKarsten Heimrich 	}
78878092ae7SKarsten Heimrich 
78978092ae7SKarsten Heimrich 	int32 columns = 8;
79078092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
79178092ae7SKarsten Heimrich 		columns = 7;
79278092ae7SKarsten Heimrich 
79378092ae7SKarsten Heimrich 	// width = max width day name * 8 column + 8 px border
79478092ae7SKarsten Heimrich 	*_width = width * columns + 8.0;
79578092ae7SKarsten Heimrich }
79678092ae7SKarsten Heimrich 
79778092ae7SKarsten Heimrich 
79878092ae7SKarsten Heimrich void
79978092ae7SKarsten Heimrich BCalendarView::_SetupDayNames()
80078092ae7SKarsten Heimrich {
8016846765fSOliver Tappe 	for (int32 i = 0; i <= 6; ++i)
8026846765fSOliver Tappe 		fDayNames[i] = fDate.ShortDayName(1 + (fStartOfWeek - 1 + i) % 7);
80378092ae7SKarsten Heimrich }
80478092ae7SKarsten Heimrich 
80578092ae7SKarsten Heimrich 
80678092ae7SKarsten Heimrich void
80778092ae7SKarsten Heimrich BCalendarView::_SetupDayNumbers()
80878092ae7SKarsten Heimrich {
8096846765fSOliver Tappe 	BDate startOfMonth(fDate.Year(), fDate.Month(), 1);
8106846765fSOliver Tappe 	if (!startOfMonth.IsValid())
81178092ae7SKarsten Heimrich 		return;
81278092ae7SKarsten Heimrich 
81378092ae7SKarsten Heimrich 	fFocusedDay.SetTo(0, 0);
81478092ae7SKarsten Heimrich 	fSelectedDay.SetTo(0, 0);
81578092ae7SKarsten Heimrich 	fNewFocusedDay.SetTo(0, 0);
81678092ae7SKarsten Heimrich 
8176846765fSOliver Tappe 	const int32 daysInMonth = startOfMonth.DaysInMonth();
8186846765fSOliver Tappe 	const int32 firstDayOffset
8196846765fSOliver Tappe 		= (7 + startOfMonth.DayOfWeek() - fStartOfWeek) % 7;
82078092ae7SKarsten Heimrich 
82178092ae7SKarsten Heimrich 	// calc the last day one month before
8226846765fSOliver Tappe 	BDate lastDayInMonthBefore(startOfMonth);
8236846765fSOliver Tappe 	lastDayInMonthBefore.AddDays(-1);
8246846765fSOliver Tappe 	const int32 lastDayBefore = lastDayInMonthBefore.DaysInMonth();
82578092ae7SKarsten Heimrich 
82678092ae7SKarsten Heimrich 	int32 counter = 0;
82778092ae7SKarsten Heimrich 	int32 firstDayAfter = 1;
82878092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
82978092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
8306846765fSOliver Tappe 			int32 day = 1 + counter - firstDayOffset;
8316846765fSOliver Tappe 			if (counter < firstDayOffset)
83278092ae7SKarsten Heimrich 				day += lastDayBefore;
8336846765fSOliver Tappe 			else if (counter >= firstDayOffset + daysInMonth)
83478092ae7SKarsten Heimrich 				day = firstDayAfter++;
8356846765fSOliver Tappe 			else if (day == fDate.Day()) {
83678092ae7SKarsten Heimrich 				fFocusedDay.SetTo(row, column);
83778092ae7SKarsten Heimrich 				fSelectedDay.SetTo(row, column);
83878092ae7SKarsten Heimrich 				fNewFocusedDay.SetTo(row, column);
83978092ae7SKarsten Heimrich 			}
84078092ae7SKarsten Heimrich 			counter++;
8416846765fSOliver Tappe 			fDayNumbers[row][column].Truncate(0);
84278092ae7SKarsten Heimrich 			fDayNumbers[row][column] << day;
84378092ae7SKarsten Heimrich 		}
84478092ae7SKarsten Heimrich 	}
84578092ae7SKarsten Heimrich }
84678092ae7SKarsten Heimrich 
8476846765fSOliver Tappe 
84878092ae7SKarsten Heimrich void
84978092ae7SKarsten Heimrich BCalendarView::_SetupWeekNumbers()
85078092ae7SKarsten Heimrich {
8516846765fSOliver Tappe 	BDate date(fDate.Year(), fDate.Month(), 1);
85278092ae7SKarsten Heimrich 	if (!date.IsValid())
85378092ae7SKarsten Heimrich 		return;
85478092ae7SKarsten Heimrich 
855c1ed5d75SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
85678092ae7SKarsten Heimrich 		fWeekNumbers[row].SetTo("");
857f0932941SMichael Pfeiffer 		fWeekNumbers[row] << date.WeekNumber();
858f0932941SMichael Pfeiffer 		date.AddDays(7);
859c1ed5d75SKarsten Heimrich 	}
86078092ae7SKarsten Heimrich }
86178092ae7SKarsten Heimrich 
86278092ae7SKarsten Heimrich 
86378092ae7SKarsten Heimrich void
86487663db4SOliver Tappe BCalendarView::_DrawDay(int32 currRow, int32 currColumn, int32 row,
86587663db4SOliver Tappe 	int32 column, int32 counter, BRect frame, const char* text, bool focus)
86678092ae7SKarsten Heimrich {
8676846765fSOliver Tappe 	BDate startOfMonth(fDate.Year(), fDate.Month(), 1);
8686846765fSOliver Tappe 	const int32 firstDayOffset
8696846765fSOliver Tappe 		= (7 + startOfMonth.DayOfWeek() - fStartOfWeek) % 7;
8706846765fSOliver Tappe 	const int32 daysMonth = startOfMonth.DaysInMonth();
87178092ae7SKarsten Heimrich 
87278092ae7SKarsten Heimrich 	bool enabled = true;
87378092ae7SKarsten Heimrich 	bool selected = false;
87478092ae7SKarsten Heimrich 	// check for the current date
87578092ae7SKarsten Heimrich 	if (currRow == row  && currColumn == column) {
87678092ae7SKarsten Heimrich 		selected = true;	// draw current date selected
8776846765fSOliver Tappe 		if (counter <= firstDayOffset || counter > firstDayOffset + daysMonth) {
87878092ae7SKarsten Heimrich 			enabled = false;	// days of month before or after
87978092ae7SKarsten Heimrich 			selected = false;	// not selected but able to get focus
88078092ae7SKarsten Heimrich 		}
88178092ae7SKarsten Heimrich 	} else {
8826846765fSOliver Tappe 		if (counter <= firstDayOffset || counter > firstDayOffset + daysMonth)
88378092ae7SKarsten Heimrich 			enabled = false;	// days of month before or after
88478092ae7SKarsten Heimrich 	}
88578092ae7SKarsten Heimrich 
88678092ae7SKarsten Heimrich 	DrawDay(this, frame, text, selected, enabled, focus);
88778092ae7SKarsten Heimrich }
88878092ae7SKarsten Heimrich 
88978092ae7SKarsten Heimrich 
89078092ae7SKarsten Heimrich void
89178092ae7SKarsten Heimrich BCalendarView::_DrawDays()
89278092ae7SKarsten Heimrich {
89378092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
89478092ae7SKarsten Heimrich 
89578092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
89678092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
89778092ae7SKarsten Heimrich 
89878092ae7SKarsten Heimrich 	const bool isFocus = IsFocus();
89978092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
90078092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
90178092ae7SKarsten Heimrich 
90278092ae7SKarsten Heimrich 	int32 counter = 0;
90378092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
90478092ae7SKarsten Heimrich 		BRect tmp = frame;
90578092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
90678092ae7SKarsten Heimrich 			counter++;
90778092ae7SKarsten Heimrich 			const char* day = fDayNumbers[row][column].String();
90878092ae7SKarsten Heimrich 			bool focus = isFocus && focusRow == row && focusColumn == column;
90987663db4SOliver Tappe 			_DrawDay(currRow, currColumn, row, column, counter, tmp, day,
91087663db4SOliver Tappe 				focus);
91178092ae7SKarsten Heimrich 
91278092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
91378092ae7SKarsten Heimrich 		}
91478092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
91578092ae7SKarsten Heimrich 	}
91678092ae7SKarsten Heimrich }
91778092ae7SKarsten Heimrich 
91878092ae7SKarsten Heimrich 
91978092ae7SKarsten Heimrich void
92078092ae7SKarsten Heimrich BCalendarView::_DrawFocusRect()
92178092ae7SKarsten Heimrich {
92278092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
92378092ae7SKarsten Heimrich 
92478092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
92578092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
92678092ae7SKarsten Heimrich 
92778092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
92878092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
92978092ae7SKarsten Heimrich 
93078092ae7SKarsten Heimrich 	int32 counter = 0;
93178092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
93278092ae7SKarsten Heimrich 		BRect tmp = frame;
93378092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
93478092ae7SKarsten Heimrich 			counter++;
93578092ae7SKarsten Heimrich 			if (fNewFocusedDay.row == row && fNewFocusedDay.column == column) {
93678092ae7SKarsten Heimrich 				fFocusedDay.SetTo(row, column);
93778092ae7SKarsten Heimrich 
93878092ae7SKarsten Heimrich 				bool focus = IsFocus() && true;
93978092ae7SKarsten Heimrich 				const char* day = fDayNumbers[row][column].String();
94087663db4SOliver Tappe 				_DrawDay(currRow, currColumn, row, column, counter, tmp, day,
94187663db4SOliver Tappe 					focus);
9426846765fSOliver Tappe 			} else if (focusRow == row && focusColumn == column) {
94378092ae7SKarsten Heimrich 				const char* day = fDayNumbers[row][column].String();
94487663db4SOliver Tappe 				_DrawDay(currRow, currColumn, row, column, counter, tmp, day,
94587663db4SOliver Tappe 					false);
94678092ae7SKarsten Heimrich 			}
94778092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
94878092ae7SKarsten Heimrich 		}
94978092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
95078092ae7SKarsten Heimrich 	}
95178092ae7SKarsten Heimrich }
95278092ae7SKarsten Heimrich 
95378092ae7SKarsten Heimrich 
95478092ae7SKarsten Heimrich void
95578092ae7SKarsten Heimrich BCalendarView::_DrawDayHeader()
95678092ae7SKarsten Heimrich {
95778092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
95878092ae7SKarsten Heimrich 		return;
95978092ae7SKarsten Heimrich 
96078092ae7SKarsten Heimrich 	int32 offset = 1;
96178092ae7SKarsten Heimrich 	int32 columns = 8;
96278092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible) {
96378092ae7SKarsten Heimrich 		offset = 0;
96478092ae7SKarsten Heimrich 		columns = 7;
96578092ae7SKarsten Heimrich 	}
96678092ae7SKarsten Heimrich 
96778092ae7SKarsten Heimrich 	BRect frame = Bounds();
96878092ae7SKarsten Heimrich 	frame.right = frame.Width() / columns - 1.0;
96978092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / 7.0 - 2.0;
97078092ae7SKarsten Heimrich 	frame.OffsetBy(4.0, 4.0);
97178092ae7SKarsten Heimrich 
97278092ae7SKarsten Heimrich 	for (int32 i = 0; i < columns; ++i) {
97378092ae7SKarsten Heimrich 		if (i == 0 && fWeekNumberHeaderVisible) {
97478092ae7SKarsten Heimrich 			DrawDayName(this, frame, "");
97578092ae7SKarsten Heimrich 			frame.OffsetBy(frame.Width(), 0.0);
97678092ae7SKarsten Heimrich 			continue;
97778092ae7SKarsten Heimrich 		}
97878092ae7SKarsten Heimrich 		DrawDayName(this, frame, fDayNames[i - offset].String());
97978092ae7SKarsten Heimrich 		frame.OffsetBy(frame.Width(), 0.0);
98078092ae7SKarsten Heimrich 	}
98178092ae7SKarsten Heimrich }
98278092ae7SKarsten Heimrich 
98378092ae7SKarsten Heimrich 
98478092ae7SKarsten Heimrich void
98578092ae7SKarsten Heimrich BCalendarView::_DrawWeekHeader()
98678092ae7SKarsten Heimrich {
98778092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
98878092ae7SKarsten Heimrich 		return;
98978092ae7SKarsten Heimrich 
99078092ae7SKarsten Heimrich 	int32 rows = 7;
99178092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
99278092ae7SKarsten Heimrich 		rows = 6;
99378092ae7SKarsten Heimrich 
99478092ae7SKarsten Heimrich 	BRect frame = Bounds();
99578092ae7SKarsten Heimrich 	frame.right = frame.Width() / 8.0 - 2.0;
99678092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / rows - 1.0;
99778092ae7SKarsten Heimrich 
99878092ae7SKarsten Heimrich 	float offsetY = 4.0;
99978092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
100078092ae7SKarsten Heimrich 		offsetY += frame.Height();
100178092ae7SKarsten Heimrich 
100278092ae7SKarsten Heimrich 	frame.OffsetBy(4.0, offsetY);
100378092ae7SKarsten Heimrich 
100478092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
100578092ae7SKarsten Heimrich 		DrawWeekNumber(this, frame, fWeekNumbers[row].String());
100678092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
100778092ae7SKarsten Heimrich 	}
100878092ae7SKarsten Heimrich }
100978092ae7SKarsten Heimrich 
101078092ae7SKarsten Heimrich 
101178092ae7SKarsten Heimrich void
101278092ae7SKarsten Heimrich BCalendarView::_DrawItem(BView* owner, BRect frame, const char* text,
101378092ae7SKarsten Heimrich 	bool isSelected, bool isEnabled, bool focus)
101478092ae7SKarsten Heimrich {
101578092ae7SKarsten Heimrich 	rgb_color lColor = LowColor();
101678092ae7SKarsten Heimrich 	rgb_color highColor = HighColor();
101778092ae7SKarsten Heimrich 
1018*99e015b4SJanus 	rgb_color textColor = ui_color(B_LIST_ITEM_TEXT_COLOR);
1019*99e015b4SJanus 	float tintDisabled = B_LIGHTEN_2_TINT;
1020*99e015b4SJanus 
1021*99e015b4SJanus 	if (textColor.red + textColor.green + textColor.blue > 125 * 3)
1022*99e015b4SJanus 		tintDisabled  = B_DARKEN_2_TINT;
102378092ae7SKarsten Heimrich 
102478092ae7SKarsten Heimrich 	if (isSelected) {
1025*99e015b4SJanus 		SetHighColor(ui_color(B_LIST_SELECTED_BACKGROUND_COLOR));
1026*99e015b4SJanus 		textColor = ui_color(B_LIST_SELECTED_ITEM_TEXT_COLOR);
102778092ae7SKarsten Heimrich 	} else
1028*99e015b4SJanus 		SetHighColor(ui_color(B_LIST_BACKGROUND_COLOR));
1029*99e015b4SJanus 
1030*99e015b4SJanus 	SetLowColor(HighColor());
103178092ae7SKarsten Heimrich 
103278092ae7SKarsten Heimrich 	FillRect(frame.InsetByCopy(1.0, 1.0));
103378092ae7SKarsten Heimrich 
103478092ae7SKarsten Heimrich 	if (focus) {
103578092ae7SKarsten Heimrich 		SetHighColor(keyboard_navigation_color());
103678092ae7SKarsten Heimrich 		StrokeRect(frame.InsetByCopy(1.0, 1.0));
103778092ae7SKarsten Heimrich 	}
103878092ae7SKarsten Heimrich 
1039*99e015b4SJanus 	SetHighColor(textColor);
104078092ae7SKarsten Heimrich 	if (!isEnabled)
1041*99e015b4SJanus 		SetHighColor(tint_color(textColor, tintDisabled));
104278092ae7SKarsten Heimrich 
104378092ae7SKarsten Heimrich 	float offsetH = frame.Width() / 2.0;
10446846765fSOliver Tappe 	float offsetV = frame.Height() / 2.0 + FontHeight(owner) / 2.0 - 2.0;
104578092ae7SKarsten Heimrich 
10466846765fSOliver Tappe 	DrawString(text, BPoint(frame.right - offsetH - StringWidth(text) / 2.0,
10476846765fSOliver Tappe 			frame.top + offsetV));
104878092ae7SKarsten Heimrich 
104978092ae7SKarsten Heimrich 	SetLowColor(lColor);
105078092ae7SKarsten Heimrich 	SetHighColor(highColor);
105178092ae7SKarsten Heimrich }
105278092ae7SKarsten Heimrich 
105378092ae7SKarsten Heimrich 
105478092ae7SKarsten Heimrich void
105578092ae7SKarsten Heimrich BCalendarView::_UpdateSelection()
105678092ae7SKarsten Heimrich {
105778092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
105878092ae7SKarsten Heimrich 
105978092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
106078092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
106178092ae7SKarsten Heimrich 
106278092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
106378092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
106478092ae7SKarsten Heimrich 
106578092ae7SKarsten Heimrich 	int32 counter = 0;
106678092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
106778092ae7SKarsten Heimrich 		BRect tmp = frame;
106878092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
106978092ae7SKarsten Heimrich 			counter++;
107087663db4SOliver Tappe 			if (fNewSelectedDay.row == row
107187663db4SOliver Tappe 				&& fNewSelectedDay.column == column) {
107278092ae7SKarsten Heimrich 				fSelectedDay.SetTo(row, column);
107378092ae7SKarsten Heimrich 
107478092ae7SKarsten Heimrich 				const char* day = fDayNumbers[row][column].String();
107587663db4SOliver Tappe 				bool focus = IsFocus() && focusRow == row
107687663db4SOliver Tappe 					&& focusColumn == column;
107778092ae7SKarsten Heimrich 				_DrawDay(row, column, row, column, counter, tmp, day, focus);
10786846765fSOliver Tappe 			} else if (currRow == row && currColumn == column) {
107978092ae7SKarsten Heimrich 				const char* day = fDayNumbers[row][column].String();
108087663db4SOliver Tappe 				bool focus = IsFocus() && focusRow == row
108187663db4SOliver Tappe 					&& focusColumn == column;
108278092ae7SKarsten Heimrich 				_DrawDay(currRow, currColumn, -1, -1, counter, tmp, day, focus);
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 
109078092ae7SKarsten Heimrich 
109178092ae7SKarsten Heimrich BRect
109278092ae7SKarsten Heimrich BCalendarView::_FirstCalendarItemFrame() const
109378092ae7SKarsten Heimrich {
109478092ae7SKarsten Heimrich 	int32 rows = 7;
109578092ae7SKarsten Heimrich 	int32 columns = 8;
109678092ae7SKarsten Heimrich 
109778092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
109878092ae7SKarsten Heimrich 		rows = 6;
109978092ae7SKarsten Heimrich 
110078092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
110178092ae7SKarsten Heimrich 		columns = 7;
110278092ae7SKarsten Heimrich 
110378092ae7SKarsten Heimrich 	BRect frame = Bounds();
110478092ae7SKarsten Heimrich 	frame.right = frame.Width() / columns - 1.0;
110578092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / rows - 1.0;
110678092ae7SKarsten Heimrich 
110778092ae7SKarsten Heimrich 	float offsetY = 4.0;
110878092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
110978092ae7SKarsten Heimrich 		offsetY += frame.Height();
111078092ae7SKarsten Heimrich 
111178092ae7SKarsten Heimrich 	float offsetX = 4.0;
111278092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible)
111378092ae7SKarsten Heimrich 		offsetX += frame.Width();
111478092ae7SKarsten Heimrich 
111578092ae7SKarsten Heimrich 	return frame.OffsetBySelf(offsetX, offsetY);
111678092ae7SKarsten Heimrich }
111778092ae7SKarsten Heimrich 
111878092ae7SKarsten Heimrich 
111978092ae7SKarsten Heimrich BRect
112078092ae7SKarsten Heimrich BCalendarView::_SetNewSelectedDay(const BPoint& where)
112178092ae7SKarsten Heimrich {
112278092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
112378092ae7SKarsten Heimrich 
112478092ae7SKarsten Heimrich 	int32 counter = 0;
112578092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
112678092ae7SKarsten Heimrich 		BRect tmp = frame;
112778092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
112878092ae7SKarsten Heimrich 			counter++;
112978092ae7SKarsten Heimrich 			if (tmp.Contains(where)) {
113078092ae7SKarsten Heimrich 				fNewSelectedDay.SetTo(row, column);
11316846765fSOliver Tappe 				int32 year;
11326846765fSOliver Tappe 				int32 month;
11336846765fSOliver Tappe 				_GetYearMonthForSelection(fNewSelectedDay, &year, &month);
11346846765fSOliver Tappe 				if (month == fDate.Month()) {
11356846765fSOliver Tappe 					// only change date if a day in the current month has been
11366846765fSOliver Tappe 					// selected
11376846765fSOliver Tappe 					int32 day = atoi(fDayNumbers[row][column].String());
11386846765fSOliver Tappe 					fDate.SetDate(year, month, day);
11396846765fSOliver Tappe 				}
114078092ae7SKarsten Heimrich 				return tmp;
114178092ae7SKarsten Heimrich 			}
114278092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
114378092ae7SKarsten Heimrich 		}
114478092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
114578092ae7SKarsten Heimrich 	}
114678092ae7SKarsten Heimrich 
114778092ae7SKarsten Heimrich 	return frame;
114878092ae7SKarsten Heimrich }
114978092ae7SKarsten Heimrich 
115078092ae7SKarsten Heimrich 
115178092ae7SKarsten Heimrich BRect
115278092ae7SKarsten Heimrich BCalendarView::_RectOfDay(const Selection& selection) const
115378092ae7SKarsten Heimrich {
115478092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
115578092ae7SKarsten Heimrich 
115678092ae7SKarsten Heimrich 	int32 counter = 0;
115778092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
115878092ae7SKarsten Heimrich 		BRect tmp = frame;
115978092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
116078092ae7SKarsten Heimrich 			counter++;
11616846765fSOliver Tappe 			if (selection.row == row && selection.column == column)
116278092ae7SKarsten Heimrich 				return tmp;
116378092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
116478092ae7SKarsten Heimrich 		}
116578092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
116678092ae7SKarsten Heimrich 	}
116778092ae7SKarsten Heimrich 
116878092ae7SKarsten Heimrich 	return frame;
116978092ae7SKarsten Heimrich }
117078092ae7SKarsten Heimrich 
117178092ae7SKarsten Heimrich 
117278092ae7SKarsten Heimrich }	// namespace BPrivate
1173