xref: /haiku/src/kits/shared/CalendarView.cpp (revision 87663db420980bdfe50101b6d067dea5e4ded7b2)
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 
3878092ae7SKarsten Heimrich BCalendarView::BCalendarView(BRect frame, const char *name,
3978092ae7SKarsten Heimrich 		uint32 resizeMask, uint32 flags)
401b3303e7SAxel Dörfler 	:
411b3303e7SAxel Dörfler 	BView(frame, name, resizeMask, flags),
4278092ae7SKarsten Heimrich 	BInvoker(),
4378092ae7SKarsten Heimrich 	fSelectionMessage(NULL),
4478092ae7SKarsten Heimrich 	fDay(0),
4578092ae7SKarsten Heimrich 	fYear(0),
4678092ae7SKarsten Heimrich 	fMonth(0),
4778092ae7SKarsten Heimrich 	fFocusChanged(false),
4878092ae7SKarsten Heimrich 	fSelectionChanged(false),
4978092ae7SKarsten Heimrich 	fWeekStart(B_WEEK_START_SUNDAY),
5078092ae7SKarsten Heimrich 	fDayNameHeaderVisible(true),
5178092ae7SKarsten Heimrich 	fWeekNumberHeaderVisible(true)
5278092ae7SKarsten Heimrich {
5378092ae7SKarsten Heimrich 	_InitObject();
5478092ae7SKarsten Heimrich }
5578092ae7SKarsten Heimrich 
5678092ae7SKarsten Heimrich 
5778092ae7SKarsten Heimrich BCalendarView::BCalendarView(BRect frame, const char *name, week_start start,
5878092ae7SKarsten Heimrich 		uint32 resizeMask, uint32 flags)
591b3303e7SAxel Dörfler 	:
601b3303e7SAxel Dörfler 	BView(frame, name, resizeMask, flags),
6178092ae7SKarsten Heimrich 	BInvoker(),
6278092ae7SKarsten Heimrich 	fSelectionMessage(NULL),
6378092ae7SKarsten Heimrich 	fDay(0),
6478092ae7SKarsten Heimrich 	fYear(0),
6578092ae7SKarsten Heimrich 	fMonth(0),
6678092ae7SKarsten Heimrich 	fFocusChanged(false),
6778092ae7SKarsten Heimrich 	fSelectionChanged(false),
6878092ae7SKarsten Heimrich 	fWeekStart(start),
6978092ae7SKarsten Heimrich 	fDayNameHeaderVisible(true),
7078092ae7SKarsten Heimrich 	fWeekNumberHeaderVisible(true)
7178092ae7SKarsten Heimrich {
7278092ae7SKarsten Heimrich 	_InitObject();
7378092ae7SKarsten Heimrich }
7478092ae7SKarsten Heimrich 
7578092ae7SKarsten Heimrich 
762530274dSRyan Leavengood BCalendarView::BCalendarView(const char* name, uint32 flags)
772530274dSRyan Leavengood 	:
782530274dSRyan Leavengood 	BView(name, flags),
792530274dSRyan Leavengood 	BInvoker(),
802530274dSRyan Leavengood 	fSelectionMessage(NULL),
812530274dSRyan Leavengood 	fDay(0),
822530274dSRyan Leavengood 	fYear(0),
832530274dSRyan Leavengood 	fMonth(0),
842530274dSRyan Leavengood 	fFocusChanged(false),
852530274dSRyan Leavengood 	fSelectionChanged(false),
862530274dSRyan Leavengood 	fWeekStart(B_WEEK_START_SUNDAY),
872530274dSRyan Leavengood 	fDayNameHeaderVisible(true),
882530274dSRyan Leavengood 	fWeekNumberHeaderVisible(true)
892530274dSRyan Leavengood {
902530274dSRyan Leavengood 	_InitObject();
912530274dSRyan Leavengood }
922530274dSRyan Leavengood 
932530274dSRyan Leavengood 
941e07062bSOliver Tappe BCalendarView::BCalendarView(const char* name, week_start start,
951e07062bSOliver Tappe 	uint32 flags)
961e07062bSOliver Tappe 	:
971e07062bSOliver Tappe 	BView(name, flags),
981e07062bSOliver Tappe 	BInvoker(),
991e07062bSOliver Tappe 	fSelectionMessage(NULL),
1001e07062bSOliver Tappe 	fDay(0),
1011e07062bSOliver Tappe 	fYear(0),
1021e07062bSOliver Tappe 	fMonth(0),
1031e07062bSOliver Tappe 	fFocusChanged(false),
1041e07062bSOliver Tappe 	fSelectionChanged(false),
1051e07062bSOliver Tappe 	fWeekStart(start),
1061e07062bSOliver Tappe 	fDayNameHeaderVisible(true),
1071e07062bSOliver Tappe 	fWeekNumberHeaderVisible(true)
1081e07062bSOliver Tappe {
1091e07062bSOliver Tappe 	_InitObject();
1101e07062bSOliver Tappe }
1111e07062bSOliver Tappe 
1121e07062bSOliver Tappe 
11378092ae7SKarsten Heimrich BCalendarView::~BCalendarView()
11478092ae7SKarsten Heimrich {
11578092ae7SKarsten Heimrich 	SetSelectionMessage(NULL);
11678092ae7SKarsten Heimrich }
11778092ae7SKarsten Heimrich 
11878092ae7SKarsten Heimrich 
11978092ae7SKarsten Heimrich BCalendarView::BCalendarView(BMessage *archive)
1201b3303e7SAxel Dörfler 	:
1211b3303e7SAxel Dörfler 	BView(archive),
12278092ae7SKarsten Heimrich 	BInvoker(),
12378092ae7SKarsten Heimrich 	fSelectionMessage(NULL),
12478092ae7SKarsten Heimrich 	fDay(0),
12578092ae7SKarsten Heimrich 	fYear(0),
12678092ae7SKarsten Heimrich 	fMonth(0),
12778092ae7SKarsten Heimrich 	fFocusChanged(false),
12878092ae7SKarsten Heimrich 	fSelectionChanged(false),
12978092ae7SKarsten Heimrich 	fWeekStart(B_WEEK_START_SUNDAY),
13078092ae7SKarsten Heimrich 	fDayNameHeaderVisible(true),
13178092ae7SKarsten Heimrich 	fWeekNumberHeaderVisible(true)
13278092ae7SKarsten Heimrich {
13378092ae7SKarsten Heimrich 	if (archive->HasMessage("_invokeMsg")) {
13478092ae7SKarsten Heimrich 		BMessage *invokationMessage = new BMessage;
13578092ae7SKarsten Heimrich 		archive->FindMessage("_invokeMsg", invokationMessage);
13678092ae7SKarsten Heimrich 		SetInvocationMessage(invokationMessage);
13778092ae7SKarsten Heimrich 	}
13878092ae7SKarsten Heimrich 
13978092ae7SKarsten Heimrich 	if (archive->HasMessage("_selectMsg")) {
14078092ae7SKarsten Heimrich 		BMessage *selectionMessage = new BMessage;
14178092ae7SKarsten Heimrich 		archive->FindMessage("selectMsg", selectionMessage);
14278092ae7SKarsten Heimrich 		SetSelectionMessage(selectionMessage);
14378092ae7SKarsten Heimrich 	}
14478092ae7SKarsten Heimrich 
14578092ae7SKarsten Heimrich 	if (archive->FindInt32("_day", &fDay) != B_OK
14678092ae7SKarsten Heimrich 		|| archive->FindInt32("_month", &fMonth) != B_OK
14778092ae7SKarsten Heimrich 		|| archive->FindInt32("_year", &fYear) != B_OK) {
14878092ae7SKarsten Heimrich 		BDate date = BDate::CurrentDate(B_LOCAL_TIME);
1499bee8e93SKarsten Heimrich 		date.GetDate(&fYear, &fMonth, &fDay);
15078092ae7SKarsten Heimrich 	}
15178092ae7SKarsten Heimrich 
15278092ae7SKarsten Heimrich 	int32 start;
15378092ae7SKarsten Heimrich 	if (archive->FindInt32("_weekStart", &start) == B_OK)
15478092ae7SKarsten Heimrich 		fWeekStart = week_start(start);
15578092ae7SKarsten Heimrich 
15678092ae7SKarsten Heimrich 	if (archive->FindBool("_dayHeader", &fDayNameHeaderVisible) != B_OK)
15778092ae7SKarsten Heimrich 		fDayNameHeaderVisible = true;
15878092ae7SKarsten Heimrich 
15978092ae7SKarsten Heimrich 	if (archive->FindBool("_weekHeader", &fWeekNumberHeaderVisible) != B_OK)
16078092ae7SKarsten Heimrich 		fWeekNumberHeaderVisible = true;
16178092ae7SKarsten Heimrich 
16278092ae7SKarsten Heimrich 	_SetupDayNames();
16378092ae7SKarsten Heimrich 	_SetupDayNumbers();
16478092ae7SKarsten Heimrich 	_SetupWeekNumbers();
16578092ae7SKarsten Heimrich }
16678092ae7SKarsten Heimrich 
16778092ae7SKarsten Heimrich 
16878092ae7SKarsten Heimrich BArchivable*
16978092ae7SKarsten Heimrich BCalendarView::Instantiate(BMessage *archive)
17078092ae7SKarsten Heimrich {
17178092ae7SKarsten Heimrich 	if (validate_instantiation(archive, "BCalendarView"))
17278092ae7SKarsten Heimrich 		return new BCalendarView(archive);
17378092ae7SKarsten Heimrich 
17478092ae7SKarsten Heimrich 	return NULL;
17578092ae7SKarsten Heimrich }
17678092ae7SKarsten Heimrich 
17778092ae7SKarsten Heimrich 
17878092ae7SKarsten Heimrich status_t
17978092ae7SKarsten Heimrich BCalendarView::Archive(BMessage *archive, bool deep) const
18078092ae7SKarsten Heimrich {
18178092ae7SKarsten Heimrich 	status_t status = BView::Archive(archive, deep);
18278092ae7SKarsten Heimrich 
18378092ae7SKarsten Heimrich 	if (status == B_OK && InvocationMessage())
18478092ae7SKarsten Heimrich 		status = archive->AddMessage("_invokeMsg", InvocationMessage());
18578092ae7SKarsten Heimrich 
18678092ae7SKarsten Heimrich 	if (status == B_OK && SelectionMessage())
18778092ae7SKarsten Heimrich 		status = archive->AddMessage("_selectMsg", SelectionMessage());
18878092ae7SKarsten Heimrich 
18978092ae7SKarsten Heimrich 	if (status == B_OK)
19078092ae7SKarsten Heimrich 		status = archive->AddInt32("_day", fDay);
19178092ae7SKarsten Heimrich 
19278092ae7SKarsten Heimrich 	if (status == B_OK)
19378092ae7SKarsten Heimrich 		status = archive->AddInt32("_month", fMonth);
19478092ae7SKarsten Heimrich 
19578092ae7SKarsten Heimrich 	if (status == B_OK)
19678092ae7SKarsten Heimrich 		status = archive->AddInt32("_year", fYear);
19778092ae7SKarsten Heimrich 
19878092ae7SKarsten Heimrich 	if (status == B_OK)
19978092ae7SKarsten Heimrich 		status = archive->AddInt32("_weekStart", int32(fWeekStart));
20078092ae7SKarsten Heimrich 
20178092ae7SKarsten Heimrich 	if (status == B_OK)
20278092ae7SKarsten Heimrich 		status = archive->AddBool("_dayHeader", fDayNameHeaderVisible);
20378092ae7SKarsten Heimrich 
20478092ae7SKarsten Heimrich 	if (status == B_OK)
20578092ae7SKarsten Heimrich 		status = archive->AddBool("_weekHeader", fWeekNumberHeaderVisible);
20678092ae7SKarsten Heimrich 
20778092ae7SKarsten Heimrich 	return status;
20878092ae7SKarsten Heimrich }
20978092ae7SKarsten Heimrich 
21078092ae7SKarsten Heimrich 
21178092ae7SKarsten Heimrich void
21278092ae7SKarsten Heimrich BCalendarView::AttachedToWindow()
21378092ae7SKarsten Heimrich {
21478092ae7SKarsten Heimrich 	BView::AttachedToWindow();
21578092ae7SKarsten Heimrich 
21678092ae7SKarsten Heimrich 	if (!Messenger().IsValid())
21778092ae7SKarsten Heimrich 		SetTarget(Window(), NULL);
21878092ae7SKarsten Heimrich }
21978092ae7SKarsten Heimrich 
22078092ae7SKarsten Heimrich 
22178092ae7SKarsten Heimrich void
22278092ae7SKarsten Heimrich BCalendarView::DetachedFromWindow()
22378092ae7SKarsten Heimrich {
22478092ae7SKarsten Heimrich 	BView::DetachedFromWindow();
22578092ae7SKarsten Heimrich }
22678092ae7SKarsten Heimrich 
22778092ae7SKarsten Heimrich 
22878092ae7SKarsten Heimrich void
22978092ae7SKarsten Heimrich BCalendarView::AllAttached()
23078092ae7SKarsten Heimrich {
23178092ae7SKarsten Heimrich 	BView::AllAttached();
23278092ae7SKarsten Heimrich }
23378092ae7SKarsten Heimrich 
23478092ae7SKarsten Heimrich 
23578092ae7SKarsten Heimrich void
23678092ae7SKarsten Heimrich BCalendarView::AllDetached()
23778092ae7SKarsten Heimrich {
23878092ae7SKarsten Heimrich 	BView::AllDetached();
23978092ae7SKarsten Heimrich }
24078092ae7SKarsten Heimrich 
24178092ae7SKarsten Heimrich 
24278092ae7SKarsten Heimrich void
24378092ae7SKarsten Heimrich BCalendarView::FrameMoved(BPoint newPosition)
24478092ae7SKarsten Heimrich {
24578092ae7SKarsten Heimrich 	BView::FrameMoved(newPosition);
24678092ae7SKarsten Heimrich }
24778092ae7SKarsten Heimrich 
24878092ae7SKarsten Heimrich 
24978092ae7SKarsten Heimrich void
25078092ae7SKarsten Heimrich BCalendarView::FrameResized(float width, float height)
25178092ae7SKarsten Heimrich {
25278092ae7SKarsten Heimrich 	Invalidate(Bounds());
25378092ae7SKarsten Heimrich }
25478092ae7SKarsten Heimrich 
25578092ae7SKarsten Heimrich 
25678092ae7SKarsten Heimrich void
25778092ae7SKarsten Heimrich BCalendarView::Draw(BRect updateRect)
25878092ae7SKarsten Heimrich {
25978092ae7SKarsten Heimrich 	if (LockLooper()) {
26078092ae7SKarsten Heimrich 		if (fFocusChanged) {
26178092ae7SKarsten Heimrich 			_DrawFocusRect();
26278092ae7SKarsten Heimrich 			UnlockLooper();
26378092ae7SKarsten Heimrich 			return;
26478092ae7SKarsten Heimrich 		}
26578092ae7SKarsten Heimrich 
26678092ae7SKarsten Heimrich 		if (fSelectionChanged) {
26778092ae7SKarsten Heimrich 			_UpdateSelection();
26878092ae7SKarsten Heimrich 			UnlockLooper();
26978092ae7SKarsten Heimrich 			return;
27078092ae7SKarsten Heimrich 		}
27178092ae7SKarsten Heimrich 
27278092ae7SKarsten Heimrich 		_DrawDays();
27378092ae7SKarsten Heimrich 		_DrawDayHeader();
27478092ae7SKarsten Heimrich 		_DrawWeekHeader();
27578092ae7SKarsten Heimrich 
27678092ae7SKarsten Heimrich 		rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
27778092ae7SKarsten Heimrich 		SetHighColor(tint_color(background, B_DARKEN_3_TINT));
27878092ae7SKarsten Heimrich 		StrokeRect(Bounds());
27978092ae7SKarsten Heimrich 
28078092ae7SKarsten Heimrich 		UnlockLooper();
28178092ae7SKarsten Heimrich 	}
28278092ae7SKarsten Heimrich }
28378092ae7SKarsten Heimrich 
28478092ae7SKarsten Heimrich 
28578092ae7SKarsten Heimrich void
28678092ae7SKarsten Heimrich BCalendarView::DrawDay(BView *owner, BRect frame, const char *text,
28778092ae7SKarsten Heimrich 	bool isSelected, bool isEnabled, bool focus)
28878092ae7SKarsten Heimrich {
28978092ae7SKarsten Heimrich 	_DrawItem(owner, frame, text, isSelected, isEnabled, focus);
29078092ae7SKarsten Heimrich }
29178092ae7SKarsten Heimrich 
29278092ae7SKarsten Heimrich 
29378092ae7SKarsten Heimrich void
29478092ae7SKarsten Heimrich BCalendarView::DrawDayName(BView *owner, BRect frame, const char *text)
29578092ae7SKarsten Heimrich {
29678092ae7SKarsten Heimrich 	// we get the full rect, fake this as the internal function
29778092ae7SKarsten Heimrich 	// shrinks the frame to work properly when drawing a day item
29878092ae7SKarsten Heimrich 	_DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true);
29978092ae7SKarsten Heimrich }
30078092ae7SKarsten Heimrich 
30178092ae7SKarsten Heimrich 
30278092ae7SKarsten Heimrich void
30378092ae7SKarsten Heimrich BCalendarView::DrawWeekNumber(BView *owner, BRect frame, const char *text)
30478092ae7SKarsten Heimrich {
30578092ae7SKarsten Heimrich 	// we get the full rect, fake this as the internal function
30678092ae7SKarsten Heimrich 	// shrinks the frame to work properly when drawing a day item
30778092ae7SKarsten Heimrich 	_DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true);
30878092ae7SKarsten Heimrich }
30978092ae7SKarsten Heimrich 
31078092ae7SKarsten Heimrich 
31178092ae7SKarsten Heimrich void
31278092ae7SKarsten Heimrich BCalendarView::MessageReceived(BMessage *message)
31378092ae7SKarsten Heimrich {
31478092ae7SKarsten Heimrich 	BView::MessageReceived(message);
31578092ae7SKarsten Heimrich }
31678092ae7SKarsten Heimrich 
31778092ae7SKarsten Heimrich 
31878092ae7SKarsten Heimrich uint32
31978092ae7SKarsten Heimrich BCalendarView::SelectionCommand() const
32078092ae7SKarsten Heimrich {
32178092ae7SKarsten Heimrich 	if (SelectionMessage())
32278092ae7SKarsten Heimrich 		return SelectionMessage()->what;
32378092ae7SKarsten Heimrich 
32478092ae7SKarsten Heimrich 	return 0;
32578092ae7SKarsten Heimrich }
32678092ae7SKarsten Heimrich 
32778092ae7SKarsten Heimrich 
32878092ae7SKarsten Heimrich BMessage*
32978092ae7SKarsten Heimrich BCalendarView::SelectionMessage() const
33078092ae7SKarsten Heimrich {
33178092ae7SKarsten Heimrich 	return fSelectionMessage;
33278092ae7SKarsten Heimrich }
33378092ae7SKarsten Heimrich 
33478092ae7SKarsten Heimrich 
33578092ae7SKarsten Heimrich void
33678092ae7SKarsten Heimrich BCalendarView::SetSelectionMessage(BMessage *message)
33778092ae7SKarsten Heimrich {
33878092ae7SKarsten Heimrich 	delete fSelectionMessage;
33978092ae7SKarsten Heimrich 	fSelectionMessage = message;
34078092ae7SKarsten Heimrich }
34178092ae7SKarsten Heimrich 
34278092ae7SKarsten Heimrich 
34378092ae7SKarsten Heimrich uint32
34478092ae7SKarsten Heimrich BCalendarView::InvocationCommand() const
34578092ae7SKarsten Heimrich {
34678092ae7SKarsten Heimrich 	return BInvoker::Command();
34778092ae7SKarsten Heimrich }
34878092ae7SKarsten Heimrich 
34978092ae7SKarsten Heimrich 
35078092ae7SKarsten Heimrich BMessage*
35178092ae7SKarsten Heimrich BCalendarView::InvocationMessage() const
35278092ae7SKarsten Heimrich {
35378092ae7SKarsten Heimrich 	return BInvoker::Message();
35478092ae7SKarsten Heimrich }
35578092ae7SKarsten Heimrich 
35678092ae7SKarsten Heimrich 
35778092ae7SKarsten Heimrich void
35878092ae7SKarsten Heimrich BCalendarView::SetInvocationMessage(BMessage *message)
35978092ae7SKarsten Heimrich {
36078092ae7SKarsten Heimrich 	BInvoker::SetMessage(message);
36178092ae7SKarsten Heimrich }
36278092ae7SKarsten Heimrich 
36378092ae7SKarsten Heimrich 
36478092ae7SKarsten Heimrich void
36578092ae7SKarsten Heimrich BCalendarView::WindowActivated(bool state)
36678092ae7SKarsten Heimrich {
36778092ae7SKarsten Heimrich 	BView::WindowActivated(state);
36878092ae7SKarsten Heimrich }
36978092ae7SKarsten Heimrich 
37078092ae7SKarsten Heimrich 
37178092ae7SKarsten Heimrich void
37278092ae7SKarsten Heimrich BCalendarView::MakeFocus(bool state)
37378092ae7SKarsten Heimrich {
37478092ae7SKarsten Heimrich 	if (IsFocus() == state)
37578092ae7SKarsten Heimrich 		return;
37678092ae7SKarsten Heimrich 
37778092ae7SKarsten Heimrich 	BView::MakeFocus(state);
37878092ae7SKarsten Heimrich 
3791b3303e7SAxel Dörfler 	// TODO: solve this better
38078092ae7SKarsten Heimrich 	fFocusChanged = true;
38178092ae7SKarsten Heimrich 	Draw(_RectOfDay(fFocusedDay));
38278092ae7SKarsten Heimrich 	fFocusChanged = false;
38378092ae7SKarsten Heimrich }
38478092ae7SKarsten Heimrich 
38578092ae7SKarsten Heimrich 
38678092ae7SKarsten Heimrich status_t
38778092ae7SKarsten Heimrich BCalendarView::Invoke(BMessage *message)
38878092ae7SKarsten Heimrich {
38978092ae7SKarsten Heimrich 	bool notify = false;
39078092ae7SKarsten Heimrich 	uint32 kind = InvokeKind(&notify);
39178092ae7SKarsten Heimrich 
39278092ae7SKarsten Heimrich 	BMessage clone(kind);
39378092ae7SKarsten Heimrich 	status_t status = B_BAD_VALUE;
39478092ae7SKarsten Heimrich 
39578092ae7SKarsten Heimrich 	if (!message && !notify)
39678092ae7SKarsten Heimrich 		message = Message();
39778092ae7SKarsten Heimrich 
39878092ae7SKarsten Heimrich 	if (!message) {
39978092ae7SKarsten Heimrich 		if (!IsWatched())
40078092ae7SKarsten Heimrich 			return status;
40178092ae7SKarsten Heimrich 	} else
40278092ae7SKarsten Heimrich 		clone = *message;
40378092ae7SKarsten Heimrich 
40478092ae7SKarsten Heimrich 	clone.AddPointer("source", this);
40578092ae7SKarsten Heimrich 	clone.AddInt64("when", (int64)system_time());
40678092ae7SKarsten Heimrich 	clone.AddMessenger("be:sender", BMessenger(this));
40778092ae7SKarsten Heimrich 
40878092ae7SKarsten Heimrich 	int32 year;
40978092ae7SKarsten Heimrich 	int32 month;
41078092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
41178092ae7SKarsten Heimrich 
41278092ae7SKarsten Heimrich 	clone.AddInt32("year", year);
41378092ae7SKarsten Heimrich 	clone.AddInt32("month", month);
41478092ae7SKarsten Heimrich 	clone.AddInt32("day", fDay);
41578092ae7SKarsten Heimrich 
41678092ae7SKarsten Heimrich 	if (message)
41778092ae7SKarsten Heimrich 		status = BInvoker::Invoke(&clone);
41878092ae7SKarsten Heimrich 
41978092ae7SKarsten Heimrich 	SendNotices(kind, &clone);
42078092ae7SKarsten Heimrich 
42178092ae7SKarsten Heimrich 	return status;
42278092ae7SKarsten Heimrich }
42378092ae7SKarsten Heimrich 
42478092ae7SKarsten Heimrich 
42578092ae7SKarsten Heimrich void
42678092ae7SKarsten Heimrich BCalendarView::MouseUp(BPoint point)
42778092ae7SKarsten Heimrich {
42878092ae7SKarsten Heimrich 	BView::MouseUp(point);
42978092ae7SKarsten Heimrich }
43078092ae7SKarsten Heimrich 
43178092ae7SKarsten Heimrich 
43278092ae7SKarsten Heimrich void
43378092ae7SKarsten Heimrich BCalendarView::MouseDown(BPoint where)
43478092ae7SKarsten Heimrich {
43578092ae7SKarsten Heimrich 	if (!IsFocus()) {
43678092ae7SKarsten Heimrich 		MakeFocus();
43778092ae7SKarsten Heimrich 		Sync();
43878092ae7SKarsten Heimrich 		Window()->UpdateIfNeeded();
43978092ae7SKarsten Heimrich 	}
44078092ae7SKarsten Heimrich 
44178092ae7SKarsten Heimrich 	BRect frame = Bounds();
44278092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
44378092ae7SKarsten Heimrich 		frame.top += frame.Height() / 7 - 1.0;
44478092ae7SKarsten Heimrich 
44578092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible)
44678092ae7SKarsten Heimrich 		frame.left += frame.Width() / 8 - 1.0;
44778092ae7SKarsten Heimrich 
44878092ae7SKarsten Heimrich 	if (!frame.Contains(where))
44978092ae7SKarsten Heimrich 		return;
45078092ae7SKarsten Heimrich 
45178092ae7SKarsten Heimrich 	// try to set to new day
45278092ae7SKarsten Heimrich 	frame = _SetNewSelectedDay(where);
45378092ae7SKarsten Heimrich 
45478092ae7SKarsten Heimrich 	// on success
45578092ae7SKarsten Heimrich 	if (fSelectedDay != fNewSelectedDay) {
45678092ae7SKarsten Heimrich 		// update focus
45778092ae7SKarsten Heimrich 		fFocusChanged = true;
45878092ae7SKarsten Heimrich 		fNewFocusedDay = fNewSelectedDay;
45978092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
46078092ae7SKarsten Heimrich 		fFocusChanged = false;
46178092ae7SKarsten Heimrich 
46278092ae7SKarsten Heimrich 		// update selection
46378092ae7SKarsten Heimrich 		fSelectionChanged = true;
46478092ae7SKarsten Heimrich 		Draw(frame);
46578092ae7SKarsten Heimrich 		Draw(_RectOfDay(fSelectedDay));
46678092ae7SKarsten Heimrich 		fSelectionChanged = false;
46778092ae7SKarsten Heimrich 
46878092ae7SKarsten Heimrich 		// notify that selection changed
46978092ae7SKarsten Heimrich 		InvokeNotify(SelectionMessage(), B_CONTROL_MODIFIED);
47078092ae7SKarsten Heimrich 	}
47178092ae7SKarsten Heimrich 
47278092ae7SKarsten Heimrich 	int32 clicks;
47378092ae7SKarsten Heimrich 	// on double click invoke
47478092ae7SKarsten Heimrich 	BMessage *message = Looper()->CurrentMessage();
47578092ae7SKarsten Heimrich 	if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1)
47678092ae7SKarsten Heimrich 		Invoke();
47778092ae7SKarsten Heimrich }
47878092ae7SKarsten Heimrich 
47978092ae7SKarsten Heimrich 
48078092ae7SKarsten Heimrich void
481*87663db4SOliver Tappe BCalendarView::MouseMoved(BPoint point, uint32 code,
482*87663db4SOliver Tappe 	const BMessage *dragMessage)
48378092ae7SKarsten Heimrich {
48478092ae7SKarsten Heimrich 	BView::MouseMoved(point, code, dragMessage);
48578092ae7SKarsten Heimrich }
48678092ae7SKarsten Heimrich 
48778092ae7SKarsten Heimrich 
48878092ae7SKarsten Heimrich void
48978092ae7SKarsten Heimrich BCalendarView::KeyDown(const char *bytes, int32 numBytes)
49078092ae7SKarsten Heimrich {
49178092ae7SKarsten Heimrich 	const int32 kRows = 6;
49278092ae7SKarsten Heimrich 	const int32 kColumns = 7;
49378092ae7SKarsten Heimrich 
49478092ae7SKarsten Heimrich 	int32 row = fFocusedDay.row;
49578092ae7SKarsten Heimrich 	int32 column = fFocusedDay.column;
49678092ae7SKarsten Heimrich 
49778092ae7SKarsten Heimrich 	switch (bytes[0]) {
49878092ae7SKarsten Heimrich 		case B_LEFT_ARROW:
49978092ae7SKarsten Heimrich 		{
50078092ae7SKarsten Heimrich 			column -= 1;
50178092ae7SKarsten Heimrich 			if (column < 0) {
50278092ae7SKarsten Heimrich 				column = kColumns -1;
50378092ae7SKarsten Heimrich 				row -= 1;
50478092ae7SKarsten Heimrich 				if (row >= 0)
50578092ae7SKarsten Heimrich 					fFocusChanged = true;
50678092ae7SKarsten Heimrich 			} else
50778092ae7SKarsten Heimrich 				fFocusChanged = true;
50878092ae7SKarsten Heimrich 		}	break;
50978092ae7SKarsten Heimrich 
51078092ae7SKarsten Heimrich 		case B_RIGHT_ARROW:
51178092ae7SKarsten Heimrich 		{
51278092ae7SKarsten Heimrich 			column += 1;
51378092ae7SKarsten Heimrich 			if (column == kColumns) {
51478092ae7SKarsten Heimrich 				column = 0;
51578092ae7SKarsten Heimrich 				row += 1;
51678092ae7SKarsten Heimrich 				if (row < kRows)
51778092ae7SKarsten Heimrich 					fFocusChanged = true;
51878092ae7SKarsten Heimrich 			} else
51978092ae7SKarsten Heimrich 				fFocusChanged = true;
52078092ae7SKarsten Heimrich 		}	break;
52178092ae7SKarsten Heimrich 
52278092ae7SKarsten Heimrich 		case B_UP_ARROW:
52378092ae7SKarsten Heimrich 		{
52478092ae7SKarsten Heimrich 			row -= 1;
52578092ae7SKarsten Heimrich 			if (row >= 0)
52678092ae7SKarsten Heimrich 				fFocusChanged = true;
52778092ae7SKarsten Heimrich 		}	break;
52878092ae7SKarsten Heimrich 
52978092ae7SKarsten Heimrich 		case B_DOWN_ARROW:
53078092ae7SKarsten Heimrich 		{
53178092ae7SKarsten Heimrich 			row += 1;
53278092ae7SKarsten Heimrich 			if (row < kRows)
53378092ae7SKarsten Heimrich 				fFocusChanged = true;
53478092ae7SKarsten Heimrich 		}	break;
53578092ae7SKarsten Heimrich 
53678092ae7SKarsten Heimrich 		case B_RETURN:
53778092ae7SKarsten Heimrich 		case B_SPACE: {
53878092ae7SKarsten Heimrich 			fSelectionChanged = true;
53978092ae7SKarsten Heimrich 			BPoint pt = _RectOfDay(fFocusedDay).LeftTop();
54078092ae7SKarsten Heimrich 			Draw(_SetNewSelectedDay(pt + BPoint(4.0, 4.0)));
54178092ae7SKarsten Heimrich 			Draw(_RectOfDay(fSelectedDay));
54278092ae7SKarsten Heimrich 			fSelectionChanged = false;
54378092ae7SKarsten Heimrich 
54478092ae7SKarsten Heimrich 			Invoke();
54578092ae7SKarsten Heimrich 		}	break;
54678092ae7SKarsten Heimrich 
54778092ae7SKarsten Heimrich 		default:
54878092ae7SKarsten Heimrich 			BView::KeyDown(bytes, numBytes);
54978092ae7SKarsten Heimrich 			break;
55078092ae7SKarsten Heimrich 	}
55178092ae7SKarsten Heimrich 
55278092ae7SKarsten Heimrich 	if (fFocusChanged) {
55378092ae7SKarsten Heimrich 		fNewFocusedDay.SetTo(row, column);
55478092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
55578092ae7SKarsten Heimrich 		Draw(_RectOfDay(fNewFocusedDay));
55678092ae7SKarsten Heimrich 		fFocusChanged = false;
55778092ae7SKarsten Heimrich 	}
55878092ae7SKarsten Heimrich }
55978092ae7SKarsten Heimrich 
56078092ae7SKarsten Heimrich 
56178092ae7SKarsten Heimrich BHandler*
56278092ae7SKarsten Heimrich BCalendarView::ResolveSpecifier(BMessage *message, int32 index,
56378092ae7SKarsten Heimrich 	BMessage *specifier, int32 form, const char *property)
56478092ae7SKarsten Heimrich {
56578092ae7SKarsten Heimrich 	return BView::ResolveSpecifier(message, index, specifier, form, property);
56678092ae7SKarsten Heimrich }
56778092ae7SKarsten Heimrich 
56878092ae7SKarsten Heimrich 
56978092ae7SKarsten Heimrich status_t
57078092ae7SKarsten Heimrich BCalendarView::GetSupportedSuites(BMessage *data)
57178092ae7SKarsten Heimrich {
57278092ae7SKarsten Heimrich 	return BView::GetSupportedSuites(data);
57378092ae7SKarsten Heimrich }
57478092ae7SKarsten Heimrich 
57578092ae7SKarsten Heimrich 
57678092ae7SKarsten Heimrich status_t
57778092ae7SKarsten Heimrich BCalendarView::Perform(perform_code code, void *arg)
57878092ae7SKarsten Heimrich {
57978092ae7SKarsten Heimrich 	return BView::Perform(code, arg);
58078092ae7SKarsten Heimrich }
58178092ae7SKarsten Heimrich 
58278092ae7SKarsten Heimrich 
58378092ae7SKarsten Heimrich void
58478092ae7SKarsten Heimrich BCalendarView::ResizeToPreferred()
58578092ae7SKarsten Heimrich {
58678092ae7SKarsten Heimrich 	float width;
58778092ae7SKarsten Heimrich 	float height;
58878092ae7SKarsten Heimrich 
58978092ae7SKarsten Heimrich 	GetPreferredSize(&width, &height);
59078092ae7SKarsten Heimrich 	BView::ResizeTo(width, height);
59178092ae7SKarsten Heimrich }
59278092ae7SKarsten Heimrich 
59378092ae7SKarsten Heimrich 
59478092ae7SKarsten Heimrich void
59578092ae7SKarsten Heimrich BCalendarView::GetPreferredSize(float *width, float *height)
59678092ae7SKarsten Heimrich {
59778092ae7SKarsten Heimrich 	_GetPreferredSize(width, height);
59878092ae7SKarsten Heimrich }
59978092ae7SKarsten Heimrich 
60078092ae7SKarsten Heimrich 
6012530274dSRyan Leavengood BSize
6022530274dSRyan Leavengood BCalendarView::MaxSize()
6032530274dSRyan Leavengood {
6042530274dSRyan Leavengood 	return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
6052530274dSRyan Leavengood 		BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
6062530274dSRyan Leavengood }
6072530274dSRyan Leavengood 
6082530274dSRyan Leavengood 
6092530274dSRyan Leavengood BSize
6102530274dSRyan Leavengood BCalendarView::MinSize()
6112530274dSRyan Leavengood {
6122530274dSRyan Leavengood 	float width, height;
6132530274dSRyan Leavengood 	_GetPreferredSize(&width, &height);
6142530274dSRyan Leavengood 	return BLayoutUtils::ComposeSize(ExplicitMinSize(),
6152530274dSRyan Leavengood 		BSize(width, height));
6162530274dSRyan Leavengood }
6172530274dSRyan Leavengood 
6182530274dSRyan Leavengood 
6192530274dSRyan Leavengood BSize
6202530274dSRyan Leavengood BCalendarView::PreferredSize()
6212530274dSRyan Leavengood {
6222530274dSRyan Leavengood 	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
6232530274dSRyan Leavengood 		MinSize());
6242530274dSRyan Leavengood }
6252530274dSRyan Leavengood 
6262530274dSRyan Leavengood 
62778092ae7SKarsten Heimrich int32
62878092ae7SKarsten Heimrich BCalendarView::Day() const
62978092ae7SKarsten Heimrich {
63078092ae7SKarsten Heimrich 	return fDay;
63178092ae7SKarsten Heimrich }
63278092ae7SKarsten Heimrich 
63378092ae7SKarsten Heimrich 
63478092ae7SKarsten Heimrich int32
63578092ae7SKarsten Heimrich BCalendarView::Year() const
63678092ae7SKarsten Heimrich {
63778092ae7SKarsten Heimrich 	int32 year;
63878092ae7SKarsten Heimrich 	int32 month;
63978092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
64078092ae7SKarsten Heimrich 
64178092ae7SKarsten Heimrich 	return year;
64278092ae7SKarsten Heimrich }
64378092ae7SKarsten Heimrich 
64478092ae7SKarsten Heimrich 
64578092ae7SKarsten Heimrich int32
64678092ae7SKarsten Heimrich BCalendarView::Month() const
64778092ae7SKarsten Heimrich {
64878092ae7SKarsten Heimrich 	int32 year;
64978092ae7SKarsten Heimrich 	int32 month;
65078092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
65178092ae7SKarsten Heimrich 
65278092ae7SKarsten Heimrich 	return month;
65378092ae7SKarsten Heimrich }
65478092ae7SKarsten Heimrich 
65578092ae7SKarsten Heimrich 
65678092ae7SKarsten Heimrich BDate
65778092ae7SKarsten Heimrich BCalendarView::Date() const
65878092ae7SKarsten Heimrich {
65978092ae7SKarsten Heimrich 	int32 year;
66078092ae7SKarsten Heimrich 	int32 month;
66178092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
66278092ae7SKarsten Heimrich 	return BDate(year, month, fDay);
66378092ae7SKarsten Heimrich }
66478092ae7SKarsten Heimrich 
66578092ae7SKarsten Heimrich 
66678092ae7SKarsten Heimrich bool
66778092ae7SKarsten Heimrich BCalendarView::SetDate(const BDate &date)
66878092ae7SKarsten Heimrich {
669c1ed5d75SKarsten Heimrich 	if (!date.IsValid())
670c1ed5d75SKarsten Heimrich 		return false;
671c1ed5d75SKarsten Heimrich 
67278092ae7SKarsten Heimrich 	return SetDate(date.Year(), date.Month(), date.Day());
67378092ae7SKarsten Heimrich }
67478092ae7SKarsten Heimrich 
67578092ae7SKarsten Heimrich 
67678092ae7SKarsten Heimrich bool
67778092ae7SKarsten Heimrich BCalendarView::SetDate(int32 year, int32 month, int32 day)
67878092ae7SKarsten Heimrich {
67978092ae7SKarsten Heimrich 	if (!BDate(year, month, day).IsValid())
68078092ae7SKarsten Heimrich 		return false;
68178092ae7SKarsten Heimrich 
68278092ae7SKarsten Heimrich 	if (fYear == year && fMonth == month && fDay == day)
68378092ae7SKarsten Heimrich 		return true;
68478092ae7SKarsten Heimrich 
68578092ae7SKarsten Heimrich 	fDay = day;
68678092ae7SKarsten Heimrich 	if (fYear == year && fMonth == month) {
68778092ae7SKarsten Heimrich 		_SetToDay();
68878092ae7SKarsten Heimrich 		// update focus
68978092ae7SKarsten Heimrich 		fFocusChanged = true;
69078092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
69178092ae7SKarsten Heimrich 		fFocusChanged = false;
69278092ae7SKarsten Heimrich 
69378092ae7SKarsten Heimrich 		// update selection
69478092ae7SKarsten Heimrich 		fSelectionChanged = true;
69578092ae7SKarsten Heimrich 		Draw(_RectOfDay(fSelectedDay));
69678092ae7SKarsten Heimrich 		Draw(_RectOfDay(fNewSelectedDay));
69778092ae7SKarsten Heimrich 		fSelectionChanged = false;
69878092ae7SKarsten Heimrich 	} else {
69978092ae7SKarsten Heimrich 		fYear = year;
70078092ae7SKarsten Heimrich 		fMonth = month;
70178092ae7SKarsten Heimrich 
70278092ae7SKarsten Heimrich 		_SetupDayNumbers();
70378092ae7SKarsten Heimrich 		_SetupWeekNumbers();
70478092ae7SKarsten Heimrich 
70578092ae7SKarsten Heimrich 		BRect frame = Bounds();
70678092ae7SKarsten Heimrich 		if (fDayNameHeaderVisible)
70778092ae7SKarsten Heimrich 			frame.top += frame.Height() / 7 - 1.0;
70878092ae7SKarsten Heimrich 
70978092ae7SKarsten Heimrich 		if (fWeekNumberHeaderVisible)
71078092ae7SKarsten Heimrich 			frame.left += frame.Width() / 8 - 1.0;
71178092ae7SKarsten Heimrich 
71278092ae7SKarsten Heimrich 		Draw(frame.InsetBySelf(4.0, 4.0));
71378092ae7SKarsten Heimrich 	}
71478092ae7SKarsten Heimrich 
71578092ae7SKarsten Heimrich 	return true;
71678092ae7SKarsten Heimrich }
71778092ae7SKarsten Heimrich 
71878092ae7SKarsten Heimrich 
71978092ae7SKarsten Heimrich week_start
72078092ae7SKarsten Heimrich BCalendarView::WeekStart() const
72178092ae7SKarsten Heimrich {
72278092ae7SKarsten Heimrich 	return fWeekStart;
72378092ae7SKarsten Heimrich }
72478092ae7SKarsten Heimrich 
72578092ae7SKarsten Heimrich 
72678092ae7SKarsten Heimrich void
72778092ae7SKarsten Heimrich BCalendarView::SetWeekStart(week_start start)
72878092ae7SKarsten Heimrich {
72978092ae7SKarsten Heimrich 	if (fWeekStart == start)
73078092ae7SKarsten Heimrich 		return;
73178092ae7SKarsten Heimrich 
73278092ae7SKarsten Heimrich 	fWeekStart = start;
73378092ae7SKarsten Heimrich 
73478092ae7SKarsten Heimrich 	_SetupDayNames();
73578092ae7SKarsten Heimrich 	_SetupDayNumbers();
73678092ae7SKarsten Heimrich 	_SetupWeekNumbers();
73778092ae7SKarsten Heimrich 
73878092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
73978092ae7SKarsten Heimrich }
74078092ae7SKarsten Heimrich 
74178092ae7SKarsten Heimrich 
74278092ae7SKarsten Heimrich bool
74378092ae7SKarsten Heimrich BCalendarView::IsDayNameHeaderVisible() const
74478092ae7SKarsten Heimrich {
74578092ae7SKarsten Heimrich 	return fDayNameHeaderVisible;
74678092ae7SKarsten Heimrich }
74778092ae7SKarsten Heimrich 
74878092ae7SKarsten Heimrich 
74978092ae7SKarsten Heimrich void
75078092ae7SKarsten Heimrich BCalendarView::SetDayNameHeaderVisible(bool visible)
75178092ae7SKarsten Heimrich {
75278092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible == visible)
75378092ae7SKarsten Heimrich 		return;
75478092ae7SKarsten Heimrich 
75578092ae7SKarsten Heimrich 	fDayNameHeaderVisible = visible;
75678092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
75778092ae7SKarsten Heimrich }
75878092ae7SKarsten Heimrich 
75978092ae7SKarsten Heimrich 
76078092ae7SKarsten Heimrich bool
76178092ae7SKarsten Heimrich BCalendarView::IsWeekNumberHeaderVisible() const
76278092ae7SKarsten Heimrich {
76378092ae7SKarsten Heimrich 	return fWeekNumberHeaderVisible;
76478092ae7SKarsten Heimrich }
76578092ae7SKarsten Heimrich 
76678092ae7SKarsten Heimrich 
76778092ae7SKarsten Heimrich void
76878092ae7SKarsten Heimrich BCalendarView::SetWeekNumberHeaderVisible(bool visible)
76978092ae7SKarsten Heimrich {
77078092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible == visible)
77178092ae7SKarsten Heimrich 		return;
77278092ae7SKarsten Heimrich 
77378092ae7SKarsten Heimrich 	fWeekNumberHeaderVisible = visible;
77478092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
77578092ae7SKarsten Heimrich }
77678092ae7SKarsten Heimrich 
77778092ae7SKarsten Heimrich 
77878092ae7SKarsten Heimrich void
77978092ae7SKarsten Heimrich BCalendarView::_InitObject()
78078092ae7SKarsten Heimrich {
78178092ae7SKarsten Heimrich 	BDate date = BDate::CurrentDate(B_LOCAL_TIME);
7829bee8e93SKarsten Heimrich 	date.GetDate(&fYear, &fMonth, &fDay);
78378092ae7SKarsten Heimrich 
78478092ae7SKarsten Heimrich 	_SetupDayNames();
78578092ae7SKarsten Heimrich 	_SetupDayNumbers();
78678092ae7SKarsten Heimrich 	_SetupWeekNumbers();
78778092ae7SKarsten Heimrich }
78878092ae7SKarsten Heimrich 
78978092ae7SKarsten Heimrich 
79078092ae7SKarsten Heimrich void
79178092ae7SKarsten Heimrich BCalendarView::_SetToDay()
79278092ae7SKarsten Heimrich {
79378092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
79478092ae7SKarsten Heimrich 	if (!date.IsValid())
79578092ae7SKarsten Heimrich 		return;
79678092ae7SKarsten Heimrich 
79778092ae7SKarsten Heimrich 	fNewFocusedDay.SetTo(0, 0);
79878092ae7SKarsten Heimrich 	fNewSelectedDay.SetTo(0, 0);
79978092ae7SKarsten Heimrich 
80078092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
80178092ae7SKarsten Heimrich 
80278092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
80378092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
80478092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
80578092ae7SKarsten Heimrich 
80678092ae7SKarsten Heimrich 	int32 counter = 0;
80778092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
80878092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
80978092ae7SKarsten Heimrich 			int32 day = counter - (firstDay - 1);
810*87663db4SOliver Tappe 			if (counter >= firstDay
811*87663db4SOliver Tappe 				&& counter <= dayCountCurrent + firstDay - 1) {
81278092ae7SKarsten Heimrich 				if (day == fDay) {
81378092ae7SKarsten Heimrich 					fNewFocusedDay.SetTo(row, column);
81478092ae7SKarsten Heimrich 					fNewSelectedDay.SetTo(row, column);
81578092ae7SKarsten Heimrich 					return;
81678092ae7SKarsten Heimrich 				}
81778092ae7SKarsten Heimrich 			}
81878092ae7SKarsten Heimrich 			counter++;
81978092ae7SKarsten Heimrich 		}
82078092ae7SKarsten Heimrich 	}
82178092ae7SKarsten Heimrich }
82278092ae7SKarsten Heimrich 
82378092ae7SKarsten Heimrich 
82478092ae7SKarsten Heimrich void
82578092ae7SKarsten Heimrich BCalendarView::_GetYearMonth(int32 *year, int32 *month) const
82678092ae7SKarsten Heimrich {
82778092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
82878092ae7SKarsten Heimrich 
82978092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
83078092ae7SKarsten Heimrich 
83178092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
83278092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
83378092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
83478092ae7SKarsten Heimrich 
83578092ae7SKarsten Heimrich 	// set the date to one month before
83678092ae7SKarsten Heimrich 	if (date.Month() == 1)
83778092ae7SKarsten Heimrich 		date.SetDate(date.Year() -1, 12, fDay);
83878092ae7SKarsten Heimrich 	else
83978092ae7SKarsten Heimrich 		date.SetDate(date.Year(), date.Month() - 1, fDay);
84078092ae7SKarsten Heimrich 
84178092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
84278092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
84378092ae7SKarsten Heimrich 
84478092ae7SKarsten Heimrich 	*year = fYear;
84578092ae7SKarsten Heimrich 	*month = fMonth;
84678092ae7SKarsten Heimrich 
84778092ae7SKarsten Heimrich 	int32 counter = 0;
84878092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
84978092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
850*87663db4SOliver Tappe 			if (counter < firstDay
851*87663db4SOliver Tappe 				|| counter > dayCountCurrent + firstDay - 1) {
85278092ae7SKarsten Heimrich 				if (counter - firstDay < 0) {
85378092ae7SKarsten Heimrich 					if (row == currRow && column == currColumn) {
85478092ae7SKarsten Heimrich 						*year = date.Year();
85578092ae7SKarsten Heimrich 						*month = date.Month();
85678092ae7SKarsten Heimrich 						break;
85778092ae7SKarsten Heimrich 					}
85878092ae7SKarsten Heimrich 				} else {
85978092ae7SKarsten Heimrich 					if (row == currRow && column == currColumn) {
86078092ae7SKarsten Heimrich 						*year = fYear;
86178092ae7SKarsten Heimrich 						*month = fMonth +1;
86278092ae7SKarsten Heimrich 						if (fMonth == 12) {
86378092ae7SKarsten Heimrich 							*year = fYear +1;
86478092ae7SKarsten Heimrich 							*month = 1;
86578092ae7SKarsten Heimrich 						}
86678092ae7SKarsten Heimrich 						break;
86778092ae7SKarsten Heimrich 					}
86878092ae7SKarsten Heimrich 				}
86978092ae7SKarsten Heimrich 			} else {
87078092ae7SKarsten Heimrich 				if (row == currRow && column == currColumn)
87178092ae7SKarsten Heimrich 					break;
87278092ae7SKarsten Heimrich 			}
87378092ae7SKarsten Heimrich 			counter++;
87478092ae7SKarsten Heimrich 		}
87578092ae7SKarsten Heimrich 	}
87678092ae7SKarsten Heimrich }
87778092ae7SKarsten Heimrich 
87878092ae7SKarsten Heimrich 
87978092ae7SKarsten Heimrich void
88078092ae7SKarsten Heimrich BCalendarView::_GetPreferredSize(float *_width, float *_height)
88178092ae7SKarsten Heimrich {
88278092ae7SKarsten Heimrich 	BFont font;
88378092ae7SKarsten Heimrich 	GetFont(&font);
88478092ae7SKarsten Heimrich 	font_height fontHeight;
88578092ae7SKarsten Heimrich 	font.GetHeight(&fontHeight);
88678092ae7SKarsten Heimrich 
88778092ae7SKarsten Heimrich 	const float height = FontHeight(this) + 4.0;
88878092ae7SKarsten Heimrich 
88978092ae7SKarsten Heimrich 	int32 rows = 7;
89078092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
89178092ae7SKarsten Heimrich 		rows = 6;
89278092ae7SKarsten Heimrich 
89378092ae7SKarsten Heimrich 	// height = font height * rows + 8 px border
89478092ae7SKarsten Heimrich 	*_height = height * rows + 8.0;
89578092ae7SKarsten Heimrich 
89678092ae7SKarsten Heimrich 	float width = 0.0;
89778092ae7SKarsten Heimrich 	for (int32 column = 0; column < 7; ++column) {
89878092ae7SKarsten Heimrich 		float tmp = StringWidth(fDayNames[column].String()) + 2.0;
89978092ae7SKarsten Heimrich 		width = tmp > width ? tmp : width;
90078092ae7SKarsten Heimrich 	}
90178092ae7SKarsten Heimrich 
90278092ae7SKarsten Heimrich 	int32 columns = 8;
90378092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
90478092ae7SKarsten Heimrich 		columns = 7;
90578092ae7SKarsten Heimrich 
90678092ae7SKarsten Heimrich 	// width = max width day name * 8 column + 8 px border
90778092ae7SKarsten Heimrich 	*_width = width * columns + 8.0;
90878092ae7SKarsten Heimrich }
90978092ae7SKarsten Heimrich 
91078092ae7SKarsten Heimrich 
91178092ae7SKarsten Heimrich void
91278092ae7SKarsten Heimrich BCalendarView::_SetupDayNames()
91378092ae7SKarsten Heimrich {
91478092ae7SKarsten Heimrich 	const BDate date(fYear, fMonth, fDay);
91578092ae7SKarsten Heimrich 	if (!date.IsValid())
91678092ae7SKarsten Heimrich 		return;
91778092ae7SKarsten Heimrich 
91878092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY) {
91978092ae7SKarsten Heimrich 		for (int32 i = 1; i <= 7; ++i) {
92078092ae7SKarsten Heimrich 			fDayNames[i -1] = date.ShortDayName(i);
92178092ae7SKarsten Heimrich 		}
92278092ae7SKarsten Heimrich 	} else {
92378092ae7SKarsten Heimrich 		fDayNames[0] = date.ShortDayName(7);
92478092ae7SKarsten Heimrich 		for (int32 i = 1; i < 7; ++i) {
92578092ae7SKarsten Heimrich 			fDayNames[i] = date.ShortDayName(i);
92678092ae7SKarsten Heimrich 		}
92778092ae7SKarsten Heimrich 	}
92878092ae7SKarsten Heimrich }
92978092ae7SKarsten Heimrich 
93078092ae7SKarsten Heimrich 
93178092ae7SKarsten Heimrich void
93278092ae7SKarsten Heimrich BCalendarView::_SetupDayNumbers()
93378092ae7SKarsten Heimrich {
93478092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
93578092ae7SKarsten Heimrich 	if (!date.IsValid())
93678092ae7SKarsten Heimrich 		return;
93778092ae7SKarsten Heimrich 
93878092ae7SKarsten Heimrich 	fFocusedDay.SetTo(0, 0);
93978092ae7SKarsten Heimrich 	fSelectedDay.SetTo(0, 0);
94078092ae7SKarsten Heimrich 	fNewFocusedDay.SetTo(0, 0);
94178092ae7SKarsten Heimrich 
94278092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
94378092ae7SKarsten Heimrich 
94478092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
94578092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
94678092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
94778092ae7SKarsten Heimrich 
94878092ae7SKarsten Heimrich 	// calc the last day one month before
94978092ae7SKarsten Heimrich 	if (date.Month() == 1)
950c8b61804SAxel Dörfler 		date.SetDate(date.Year() -1, 12, 1);
95178092ae7SKarsten Heimrich 	else
952c8b61804SAxel Dörfler 		date.SetDate(date.Year(), date.Month() - 1, 1);
95378092ae7SKarsten Heimrich 	const int32 lastDayBefore = date.DaysInMonth();
95478092ae7SKarsten Heimrich 
95578092ae7SKarsten Heimrich 	int32 counter = 0;
95678092ae7SKarsten Heimrich 	int32 firstDayAfter = 1;
95778092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
95878092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
95978092ae7SKarsten Heimrich 			int32 day = counter - (firstDay - 1);
960*87663db4SOliver Tappe 			if (counter < firstDay
961*87663db4SOliver Tappe 				|| counter > dayCountCurrent + firstDay - 1) {
96278092ae7SKarsten Heimrich 				if (counter - firstDay < 0)
96378092ae7SKarsten Heimrich 					day += lastDayBefore;
96478092ae7SKarsten Heimrich 				else
96578092ae7SKarsten Heimrich 					day = firstDayAfter++;
96678092ae7SKarsten Heimrich 			} else {
96778092ae7SKarsten Heimrich 				if (day == fDay) {
96878092ae7SKarsten Heimrich 					fFocusedDay.SetTo(row, column);
96978092ae7SKarsten Heimrich 					fSelectedDay.SetTo(row, column);
97078092ae7SKarsten Heimrich 					fNewFocusedDay.SetTo(row, column);
97178092ae7SKarsten Heimrich 				}
97278092ae7SKarsten Heimrich 			}
97378092ae7SKarsten Heimrich 			counter++;
97478092ae7SKarsten Heimrich 			fDayNumbers[row][column].SetTo("");
97578092ae7SKarsten Heimrich 			fDayNumbers[row][column] << day;
97678092ae7SKarsten Heimrich 		}
97778092ae7SKarsten Heimrich 	}
97878092ae7SKarsten Heimrich }
97978092ae7SKarsten Heimrich 
98078092ae7SKarsten Heimrich void
98178092ae7SKarsten Heimrich BCalendarView::_SetupWeekNumbers()
98278092ae7SKarsten Heimrich {
983c1ed5d75SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
98478092ae7SKarsten Heimrich 	if (!date.IsValid())
98578092ae7SKarsten Heimrich 		return;
98678092ae7SKarsten Heimrich 
987f0932941SMichael Pfeiffer 	// date on Thursday determines week number (ISO 8601)
9884352fc91SMichael Pfeiffer 	int dayOfWeek = date.DayOfWeek();
9894352fc91SMichael Pfeiffer 	// adjust weekday if Monday is week start,
9904352fc91SMichael Pfeiffer 	// then Sunday is last day in week
9914352fc91SMichael Pfeiffer 	if (fWeekStart == B_WEEK_START_MONDAY && dayOfWeek == 0)
9924352fc91SMichael Pfeiffer 			dayOfWeek = 7;
9934352fc91SMichael Pfeiffer 	date.AddDays(4 - dayOfWeek);
99478092ae7SKarsten Heimrich 
995c1ed5d75SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
99678092ae7SKarsten Heimrich 		fWeekNumbers[row].SetTo("");
997f0932941SMichael Pfeiffer 		fWeekNumbers[row] << date.WeekNumber();
998f0932941SMichael Pfeiffer 		date.AddDays(7);
999c1ed5d75SKarsten Heimrich 	}
100078092ae7SKarsten Heimrich }
100178092ae7SKarsten Heimrich 
100278092ae7SKarsten Heimrich 
100378092ae7SKarsten Heimrich void
1004*87663db4SOliver Tappe BCalendarView::_DrawDay(int32 currRow, int32 currColumn, int32 row,
1005*87663db4SOliver Tappe 	int32 column, int32 counter, BRect frame, const char *text, bool focus)
100678092ae7SKarsten Heimrich {
100778092ae7SKarsten Heimrich 	const BDate date(fYear, fMonth, 1);
100878092ae7SKarsten Heimrich 	const int32 daysMonth = date.DaysInMonth();
100978092ae7SKarsten Heimrich 
101078092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
101178092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
101278092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
101378092ae7SKarsten Heimrich 
101478092ae7SKarsten Heimrich 	bool enabled = true;
101578092ae7SKarsten Heimrich 	bool selected = false;
101678092ae7SKarsten Heimrich 	// check for the current date
101778092ae7SKarsten Heimrich 	if (currRow == row  && currColumn == column) {
101878092ae7SKarsten Heimrich 		selected = true;	// draw current date selected
101978092ae7SKarsten Heimrich 		if (counter <= firstDay || counter > firstDay + daysMonth) {
102078092ae7SKarsten Heimrich 			enabled = false;	// days of month before or after
102178092ae7SKarsten Heimrich 			selected = false;	// not selected but able to get focus
102278092ae7SKarsten Heimrich 		}
102378092ae7SKarsten Heimrich 	} else {
102478092ae7SKarsten Heimrich 		if (counter <= firstDay || counter > firstDay + daysMonth)
102578092ae7SKarsten Heimrich 			enabled = false;	// days of month before or after
102678092ae7SKarsten Heimrich 	}
102778092ae7SKarsten Heimrich 
102878092ae7SKarsten Heimrich 	DrawDay(this, frame, text, selected, enabled, focus);
102978092ae7SKarsten Heimrich }
103078092ae7SKarsten Heimrich 
103178092ae7SKarsten Heimrich 
103278092ae7SKarsten Heimrich void
103378092ae7SKarsten Heimrich BCalendarView::_DrawDays()
103478092ae7SKarsten Heimrich {
103578092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
103678092ae7SKarsten Heimrich 
103778092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
103878092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
103978092ae7SKarsten Heimrich 
104078092ae7SKarsten Heimrich 	const bool isFocus = IsFocus();
104178092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
104278092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
104378092ae7SKarsten Heimrich 
104478092ae7SKarsten Heimrich 	int32 counter = 0;
104578092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
104678092ae7SKarsten Heimrich 		BRect tmp = frame;
104778092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
104878092ae7SKarsten Heimrich 			counter++;
104978092ae7SKarsten Heimrich 			const char *day = fDayNumbers[row][column].String();
105078092ae7SKarsten Heimrich 			bool focus = isFocus && focusRow == row && focusColumn == column;
1051*87663db4SOliver Tappe 			_DrawDay(currRow, currColumn, row, column, counter, tmp, day,
1052*87663db4SOliver Tappe 				focus);
105378092ae7SKarsten Heimrich 
105478092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
105578092ae7SKarsten Heimrich 		}
105678092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
105778092ae7SKarsten Heimrich 	}
105878092ae7SKarsten Heimrich }
105978092ae7SKarsten Heimrich 
106078092ae7SKarsten Heimrich 
106178092ae7SKarsten Heimrich void
106278092ae7SKarsten Heimrich BCalendarView::_DrawFocusRect()
106378092ae7SKarsten Heimrich {
106478092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
106578092ae7SKarsten Heimrich 
106678092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
106778092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
106878092ae7SKarsten Heimrich 
106978092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
107078092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
107178092ae7SKarsten Heimrich 
107278092ae7SKarsten Heimrich 	int32 counter = 0;
107378092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
107478092ae7SKarsten Heimrich 		BRect tmp = frame;
107578092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
107678092ae7SKarsten Heimrich 			counter++;
107778092ae7SKarsten Heimrich 			if (fNewFocusedDay.row == row && fNewFocusedDay.column == column) {
107878092ae7SKarsten Heimrich 				fFocusedDay.SetTo(row, column);
107978092ae7SKarsten Heimrich 
108078092ae7SKarsten Heimrich 				bool focus = IsFocus() && true;
108178092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
1082*87663db4SOliver Tappe 				_DrawDay(currRow, currColumn, row, column, counter, tmp, day,
1083*87663db4SOliver Tappe 					focus);
108478092ae7SKarsten Heimrich 			}
108578092ae7SKarsten Heimrich 			else if (focusRow == row && focusColumn == column) {
108678092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
1087*87663db4SOliver Tappe 				_DrawDay(currRow, currColumn, row, column, counter, tmp, day,
1088*87663db4SOliver Tappe 					false);
108978092ae7SKarsten Heimrich 			}
109078092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
109178092ae7SKarsten Heimrich 		}
109278092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
109378092ae7SKarsten Heimrich 	}
109478092ae7SKarsten Heimrich }
109578092ae7SKarsten Heimrich 
109678092ae7SKarsten Heimrich 
109778092ae7SKarsten Heimrich void
109878092ae7SKarsten Heimrich BCalendarView::_DrawDayHeader()
109978092ae7SKarsten Heimrich {
110078092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
110178092ae7SKarsten Heimrich 		return;
110278092ae7SKarsten Heimrich 
110378092ae7SKarsten Heimrich 	int32 offset = 1;
110478092ae7SKarsten Heimrich 	int32 columns = 8;
110578092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible) {
110678092ae7SKarsten Heimrich 		offset = 0;
110778092ae7SKarsten Heimrich 		columns = 7;
110878092ae7SKarsten Heimrich 	}
110978092ae7SKarsten Heimrich 
111078092ae7SKarsten Heimrich 	BRect frame = Bounds();
111178092ae7SKarsten Heimrich 	frame.right = frame.Width() / columns - 1.0;
111278092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / 7.0 - 2.0;
111378092ae7SKarsten Heimrich 	frame.OffsetBy(4.0, 4.0);
111478092ae7SKarsten Heimrich 
111578092ae7SKarsten Heimrich 	for (int32 i = 0; i < columns; ++i) {
111678092ae7SKarsten Heimrich 		if (i == 0 && fWeekNumberHeaderVisible) {
111778092ae7SKarsten Heimrich 			DrawDayName(this, frame, "");
111878092ae7SKarsten Heimrich 			frame.OffsetBy(frame.Width(), 0.0);
111978092ae7SKarsten Heimrich 			continue;
112078092ae7SKarsten Heimrich 		}
112178092ae7SKarsten Heimrich 		DrawDayName(this, frame, fDayNames[i - offset].String());
112278092ae7SKarsten Heimrich 		frame.OffsetBy(frame.Width(), 0.0);
112378092ae7SKarsten Heimrich 	}
112478092ae7SKarsten Heimrich }
112578092ae7SKarsten Heimrich 
112678092ae7SKarsten Heimrich 
112778092ae7SKarsten Heimrich void
112878092ae7SKarsten Heimrich BCalendarView::_DrawWeekHeader()
112978092ae7SKarsten Heimrich {
113078092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
113178092ae7SKarsten Heimrich 		return;
113278092ae7SKarsten Heimrich 
113378092ae7SKarsten Heimrich 	int32 rows = 7;
113478092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
113578092ae7SKarsten Heimrich 		rows = 6;
113678092ae7SKarsten Heimrich 
113778092ae7SKarsten Heimrich 	BRect frame = Bounds();
113878092ae7SKarsten Heimrich 	frame.right = frame.Width() / 8.0 - 2.0;
113978092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / rows - 1.0;
114078092ae7SKarsten Heimrich 
114178092ae7SKarsten Heimrich 	float offsetY = 4.0;
114278092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
114378092ae7SKarsten Heimrich 		offsetY += frame.Height();
114478092ae7SKarsten Heimrich 
114578092ae7SKarsten Heimrich 	frame.OffsetBy(4.0, offsetY);
114678092ae7SKarsten Heimrich 
114778092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
114878092ae7SKarsten Heimrich 		DrawWeekNumber(this, frame, fWeekNumbers[row].String());
114978092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
115078092ae7SKarsten Heimrich 	}
115178092ae7SKarsten Heimrich }
115278092ae7SKarsten Heimrich 
115378092ae7SKarsten Heimrich 
115478092ae7SKarsten Heimrich void
115578092ae7SKarsten Heimrich BCalendarView::_DrawItem(BView *owner, BRect frame, const char *text,
115678092ae7SKarsten Heimrich 	bool isSelected, bool isEnabled, bool focus)
115778092ae7SKarsten Heimrich {
115878092ae7SKarsten Heimrich 	rgb_color lColor = LowColor();
115978092ae7SKarsten Heimrich 	rgb_color highColor = HighColor();
116078092ae7SKarsten Heimrich 
116178092ae7SKarsten Heimrich 	rgb_color lowColor = { 255, 255, 255, 255 };
116278092ae7SKarsten Heimrich 
116378092ae7SKarsten Heimrich 	if (isSelected) {
116478092ae7SKarsten Heimrich 		SetHighColor(tint_color(lowColor, B_DARKEN_2_TINT));
116578092ae7SKarsten Heimrich 		SetLowColor(HighColor());
116678092ae7SKarsten Heimrich 	} else
116778092ae7SKarsten Heimrich 		SetHighColor(lowColor);
116878092ae7SKarsten Heimrich 
116978092ae7SKarsten Heimrich 	FillRect(frame.InsetByCopy(1.0, 1.0));
117078092ae7SKarsten Heimrich 
117178092ae7SKarsten Heimrich 	if (focus) {
117278092ae7SKarsten Heimrich 		SetHighColor(keyboard_navigation_color());
117378092ae7SKarsten Heimrich 		StrokeRect(frame.InsetByCopy(1.0, 1.0));
117478092ae7SKarsten Heimrich 	}
117578092ae7SKarsten Heimrich 
117678092ae7SKarsten Heimrich 	rgb_color black = { 0, 0, 0, 255 };
117778092ae7SKarsten Heimrich 	SetHighColor(black);
117878092ae7SKarsten Heimrich 	if (!isEnabled)
117978092ae7SKarsten Heimrich 		SetHighColor(tint_color(black, B_LIGHTEN_2_TINT));
118078092ae7SKarsten Heimrich 
118178092ae7SKarsten Heimrich 	float offsetH = frame.Width() / 2.0;
118278092ae7SKarsten Heimrich 	float offsetV = (frame.Height() / 2.0) + (FontHeight(owner) / 2.0) - 2.0;
118378092ae7SKarsten Heimrich 
118478092ae7SKarsten Heimrich 	DrawString(text, BPoint(frame.right - offsetH
118578092ae7SKarsten Heimrich 		- (StringWidth(text) / 2.0), frame.top + offsetV));
118678092ae7SKarsten Heimrich 
118778092ae7SKarsten Heimrich 	SetLowColor(lColor);
118878092ae7SKarsten Heimrich 	SetHighColor(highColor);
118978092ae7SKarsten Heimrich }
119078092ae7SKarsten Heimrich 
119178092ae7SKarsten Heimrich 
119278092ae7SKarsten Heimrich void
119378092ae7SKarsten Heimrich BCalendarView::_UpdateSelection()
119478092ae7SKarsten Heimrich {
119578092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
119678092ae7SKarsten Heimrich 
119778092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
119878092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
119978092ae7SKarsten Heimrich 
120078092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
120178092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
120278092ae7SKarsten Heimrich 
120378092ae7SKarsten Heimrich 	int32 counter = 0;
120478092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
120578092ae7SKarsten Heimrich 		BRect tmp = frame;
120678092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
120778092ae7SKarsten Heimrich 			counter++;
1208*87663db4SOliver Tappe 			if (fNewSelectedDay.row == row
1209*87663db4SOliver Tappe 				&& fNewSelectedDay.column == column) {
121078092ae7SKarsten Heimrich 				fSelectedDay.SetTo(row, column);
121178092ae7SKarsten Heimrich 
121278092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
1213*87663db4SOliver Tappe 				bool focus = IsFocus() && focusRow == row
1214*87663db4SOliver Tappe 					&& focusColumn == column;
121578092ae7SKarsten Heimrich 				_DrawDay(row, column, row, column, counter, tmp, day, focus);
121678092ae7SKarsten Heimrich 			}
121778092ae7SKarsten Heimrich 			else if (currRow == row && currColumn == column) {
121878092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
1219*87663db4SOliver Tappe 				bool focus = IsFocus() && focusRow == row
1220*87663db4SOliver Tappe 					&& focusColumn == column;
122178092ae7SKarsten Heimrich 				_DrawDay(currRow, currColumn, -1, -1, counter, tmp, day, focus);
122278092ae7SKarsten Heimrich 			}
122378092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
122478092ae7SKarsten Heimrich 		}
122578092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
122678092ae7SKarsten Heimrich 	}
122778092ae7SKarsten Heimrich }
122878092ae7SKarsten Heimrich 
122978092ae7SKarsten Heimrich 
123078092ae7SKarsten Heimrich BRect
123178092ae7SKarsten Heimrich BCalendarView::_FirstCalendarItemFrame() const
123278092ae7SKarsten Heimrich {
123378092ae7SKarsten Heimrich 	int32 rows = 7;
123478092ae7SKarsten Heimrich 	int32 columns = 8;
123578092ae7SKarsten Heimrich 
123678092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
123778092ae7SKarsten Heimrich 		rows = 6;
123878092ae7SKarsten Heimrich 
123978092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
124078092ae7SKarsten Heimrich 		columns = 7;
124178092ae7SKarsten Heimrich 
124278092ae7SKarsten Heimrich 	BRect frame = Bounds();
124378092ae7SKarsten Heimrich 	frame.right = frame.Width() / columns - 1.0;
124478092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / rows - 1.0;
124578092ae7SKarsten Heimrich 
124678092ae7SKarsten Heimrich 	float offsetY = 4.0;
124778092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
124878092ae7SKarsten Heimrich 		offsetY += frame.Height();
124978092ae7SKarsten Heimrich 
125078092ae7SKarsten Heimrich 	float offsetX = 4.0;
125178092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible)
125278092ae7SKarsten Heimrich 		offsetX += frame.Width();
125378092ae7SKarsten Heimrich 
125478092ae7SKarsten Heimrich 	return frame.OffsetBySelf(offsetX, offsetY);
125578092ae7SKarsten Heimrich }
125678092ae7SKarsten Heimrich 
125778092ae7SKarsten Heimrich 
125878092ae7SKarsten Heimrich BRect
125978092ae7SKarsten Heimrich BCalendarView::_SetNewSelectedDay(const BPoint &where)
126078092ae7SKarsten Heimrich {
126178092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
126278092ae7SKarsten Heimrich 
126378092ae7SKarsten Heimrich 	int32 counter = 0;
126478092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
126578092ae7SKarsten Heimrich 		BRect tmp = frame;
126678092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
126778092ae7SKarsten Heimrich 			counter++;
126878092ae7SKarsten Heimrich 			if (tmp.Contains(where)) {
126978092ae7SKarsten Heimrich 				fNewSelectedDay.SetTo(row, column);
127078092ae7SKarsten Heimrich 				fDay = atoi(fDayNumbers[row][column].String());
127178092ae7SKarsten Heimrich 				return tmp;
127278092ae7SKarsten Heimrich 			}
127378092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
127478092ae7SKarsten Heimrich 		}
127578092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
127678092ae7SKarsten Heimrich 	}
127778092ae7SKarsten Heimrich 
127878092ae7SKarsten Heimrich 	return frame;
127978092ae7SKarsten Heimrich }
128078092ae7SKarsten Heimrich 
128178092ae7SKarsten Heimrich 
128278092ae7SKarsten Heimrich BRect
128378092ae7SKarsten Heimrich BCalendarView::_RectOfDay(const Selection &selection) const
128478092ae7SKarsten Heimrich {
128578092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
128678092ae7SKarsten Heimrich 
128778092ae7SKarsten Heimrich 	int32 counter = 0;
128878092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
128978092ae7SKarsten Heimrich 		BRect tmp = frame;
129078092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
129178092ae7SKarsten Heimrich 			counter++;
129278092ae7SKarsten Heimrich 			if (selection.row == row && selection.column == column) {
129378092ae7SKarsten Heimrich 				return tmp;
129478092ae7SKarsten Heimrich 			}
129578092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
129678092ae7SKarsten Heimrich 		}
129778092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
129878092ae7SKarsten Heimrich 	}
129978092ae7SKarsten Heimrich 
130078092ae7SKarsten Heimrich 	return frame;
130178092ae7SKarsten Heimrich }
130278092ae7SKarsten Heimrich 
130378092ae7SKarsten Heimrich 
130478092ae7SKarsten Heimrich }	// namespace BPrivate
1305