xref: /haiku/src/kits/shared/CalendarView.cpp (revision 1e07062b408258cd82f9590761e8d0fc4ce33765)
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 
94*1e07062bSOliver Tappe BCalendarView::BCalendarView(const char* name, week_start start,
95*1e07062bSOliver Tappe 	uint32 flags)
96*1e07062bSOliver Tappe 	:
97*1e07062bSOliver Tappe 	BView(name, flags),
98*1e07062bSOliver Tappe 	BInvoker(),
99*1e07062bSOliver Tappe 	fSelectionMessage(NULL),
100*1e07062bSOliver Tappe 	fDay(0),
101*1e07062bSOliver Tappe 	fYear(0),
102*1e07062bSOliver Tappe 	fMonth(0),
103*1e07062bSOliver Tappe 	fFocusChanged(false),
104*1e07062bSOliver Tappe 	fSelectionChanged(false),
105*1e07062bSOliver Tappe 	fWeekStart(start),
106*1e07062bSOliver Tappe 	fDayNameHeaderVisible(true),
107*1e07062bSOliver Tappe 	fWeekNumberHeaderVisible(true)
108*1e07062bSOliver Tappe {
109*1e07062bSOliver Tappe 	_InitObject();
110*1e07062bSOliver Tappe }
111*1e07062bSOliver Tappe 
112*1e07062bSOliver 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
48178092ae7SKarsten Heimrich BCalendarView::MouseMoved(BPoint point, uint32 code, const BMessage *dragMessage)
48278092ae7SKarsten Heimrich {
48378092ae7SKarsten Heimrich 	BView::MouseMoved(point, code, dragMessage);
48478092ae7SKarsten Heimrich }
48578092ae7SKarsten Heimrich 
48678092ae7SKarsten Heimrich 
48778092ae7SKarsten Heimrich void
48878092ae7SKarsten Heimrich BCalendarView::KeyDown(const char *bytes, int32 numBytes)
48978092ae7SKarsten Heimrich {
49078092ae7SKarsten Heimrich 	const int32 kRows = 6;
49178092ae7SKarsten Heimrich 	const int32 kColumns = 7;
49278092ae7SKarsten Heimrich 
49378092ae7SKarsten Heimrich 	int32 row = fFocusedDay.row;
49478092ae7SKarsten Heimrich 	int32 column = fFocusedDay.column;
49578092ae7SKarsten Heimrich 
49678092ae7SKarsten Heimrich 	switch (bytes[0]) {
49778092ae7SKarsten Heimrich 		case B_LEFT_ARROW:
49878092ae7SKarsten Heimrich 		{
49978092ae7SKarsten Heimrich 			column -= 1;
50078092ae7SKarsten Heimrich 			if (column < 0) {
50178092ae7SKarsten Heimrich 				column = kColumns -1;
50278092ae7SKarsten Heimrich 				row -= 1;
50378092ae7SKarsten Heimrich 				if (row >= 0)
50478092ae7SKarsten Heimrich 					fFocusChanged = true;
50578092ae7SKarsten Heimrich 			} else
50678092ae7SKarsten Heimrich 				fFocusChanged = true;
50778092ae7SKarsten Heimrich 		}	break;
50878092ae7SKarsten Heimrich 
50978092ae7SKarsten Heimrich 		case B_RIGHT_ARROW:
51078092ae7SKarsten Heimrich 		{
51178092ae7SKarsten Heimrich 			column += 1;
51278092ae7SKarsten Heimrich 			if (column == kColumns) {
51378092ae7SKarsten Heimrich 				column = 0;
51478092ae7SKarsten Heimrich 				row += 1;
51578092ae7SKarsten Heimrich 				if (row < kRows)
51678092ae7SKarsten Heimrich 					fFocusChanged = true;
51778092ae7SKarsten Heimrich 			} else
51878092ae7SKarsten Heimrich 				fFocusChanged = true;
51978092ae7SKarsten Heimrich 		}	break;
52078092ae7SKarsten Heimrich 
52178092ae7SKarsten Heimrich 		case B_UP_ARROW:
52278092ae7SKarsten Heimrich 		{
52378092ae7SKarsten Heimrich 			row -= 1;
52478092ae7SKarsten Heimrich 			if (row >= 0)
52578092ae7SKarsten Heimrich 				fFocusChanged = true;
52678092ae7SKarsten Heimrich 		}	break;
52778092ae7SKarsten Heimrich 
52878092ae7SKarsten Heimrich 		case B_DOWN_ARROW:
52978092ae7SKarsten Heimrich 		{
53078092ae7SKarsten Heimrich 			row += 1;
53178092ae7SKarsten Heimrich 			if (row < kRows)
53278092ae7SKarsten Heimrich 				fFocusChanged = true;
53378092ae7SKarsten Heimrich 		}	break;
53478092ae7SKarsten Heimrich 
53578092ae7SKarsten Heimrich 		case B_RETURN:
53678092ae7SKarsten Heimrich 		case B_SPACE: {
53778092ae7SKarsten Heimrich 			fSelectionChanged = true;
53878092ae7SKarsten Heimrich 			BPoint pt = _RectOfDay(fFocusedDay).LeftTop();
53978092ae7SKarsten Heimrich 			Draw(_SetNewSelectedDay(pt + BPoint(4.0, 4.0)));
54078092ae7SKarsten Heimrich 			Draw(_RectOfDay(fSelectedDay));
54178092ae7SKarsten Heimrich 			fSelectionChanged = false;
54278092ae7SKarsten Heimrich 
54378092ae7SKarsten Heimrich 			Invoke();
54478092ae7SKarsten Heimrich 		}	break;
54578092ae7SKarsten Heimrich 
54678092ae7SKarsten Heimrich 		default:
54778092ae7SKarsten Heimrich 			BView::KeyDown(bytes, numBytes);
54878092ae7SKarsten Heimrich 			break;
54978092ae7SKarsten Heimrich 	}
55078092ae7SKarsten Heimrich 
55178092ae7SKarsten Heimrich 	if (fFocusChanged) {
55278092ae7SKarsten Heimrich 		fNewFocusedDay.SetTo(row, column);
55378092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
55478092ae7SKarsten Heimrich 		Draw(_RectOfDay(fNewFocusedDay));
55578092ae7SKarsten Heimrich 		fFocusChanged = false;
55678092ae7SKarsten Heimrich 	}
55778092ae7SKarsten Heimrich }
55878092ae7SKarsten Heimrich 
55978092ae7SKarsten Heimrich 
56078092ae7SKarsten Heimrich BHandler*
56178092ae7SKarsten Heimrich BCalendarView::ResolveSpecifier(BMessage *message, int32 index,
56278092ae7SKarsten Heimrich 	BMessage *specifier, int32 form, const char *property)
56378092ae7SKarsten Heimrich {
56478092ae7SKarsten Heimrich 	return BView::ResolveSpecifier(message, index, specifier, form, property);
56578092ae7SKarsten Heimrich }
56678092ae7SKarsten Heimrich 
56778092ae7SKarsten Heimrich 
56878092ae7SKarsten Heimrich status_t
56978092ae7SKarsten Heimrich BCalendarView::GetSupportedSuites(BMessage *data)
57078092ae7SKarsten Heimrich {
57178092ae7SKarsten Heimrich 	return BView::GetSupportedSuites(data);
57278092ae7SKarsten Heimrich }
57378092ae7SKarsten Heimrich 
57478092ae7SKarsten Heimrich 
57578092ae7SKarsten Heimrich status_t
57678092ae7SKarsten Heimrich BCalendarView::Perform(perform_code code, void *arg)
57778092ae7SKarsten Heimrich {
57878092ae7SKarsten Heimrich 	return BView::Perform(code, arg);
57978092ae7SKarsten Heimrich }
58078092ae7SKarsten Heimrich 
58178092ae7SKarsten Heimrich 
58278092ae7SKarsten Heimrich void
58378092ae7SKarsten Heimrich BCalendarView::ResizeToPreferred()
58478092ae7SKarsten Heimrich {
58578092ae7SKarsten Heimrich 	float width;
58678092ae7SKarsten Heimrich 	float height;
58778092ae7SKarsten Heimrich 
58878092ae7SKarsten Heimrich 	GetPreferredSize(&width, &height);
58978092ae7SKarsten Heimrich 	BView::ResizeTo(width, height);
59078092ae7SKarsten Heimrich }
59178092ae7SKarsten Heimrich 
59278092ae7SKarsten Heimrich 
59378092ae7SKarsten Heimrich void
59478092ae7SKarsten Heimrich BCalendarView::GetPreferredSize(float *width, float *height)
59578092ae7SKarsten Heimrich {
59678092ae7SKarsten Heimrich 	_GetPreferredSize(width, height);
59778092ae7SKarsten Heimrich }
59878092ae7SKarsten Heimrich 
59978092ae7SKarsten Heimrich 
6002530274dSRyan Leavengood BSize
6012530274dSRyan Leavengood BCalendarView::MaxSize()
6022530274dSRyan Leavengood {
6032530274dSRyan Leavengood 	return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
6042530274dSRyan Leavengood 		BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
6052530274dSRyan Leavengood }
6062530274dSRyan Leavengood 
6072530274dSRyan Leavengood 
6082530274dSRyan Leavengood BSize
6092530274dSRyan Leavengood BCalendarView::MinSize()
6102530274dSRyan Leavengood {
6112530274dSRyan Leavengood 	float width, height;
6122530274dSRyan Leavengood 	_GetPreferredSize(&width, &height);
6132530274dSRyan Leavengood 	return BLayoutUtils::ComposeSize(ExplicitMinSize(),
6142530274dSRyan Leavengood 		BSize(width, height));
6152530274dSRyan Leavengood }
6162530274dSRyan Leavengood 
6172530274dSRyan Leavengood 
6182530274dSRyan Leavengood BSize
6192530274dSRyan Leavengood BCalendarView::PreferredSize()
6202530274dSRyan Leavengood {
6212530274dSRyan Leavengood 	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
6222530274dSRyan Leavengood 		MinSize());
6232530274dSRyan Leavengood }
6242530274dSRyan Leavengood 
6252530274dSRyan Leavengood 
62678092ae7SKarsten Heimrich int32
62778092ae7SKarsten Heimrich BCalendarView::Day() const
62878092ae7SKarsten Heimrich {
62978092ae7SKarsten Heimrich 	return fDay;
63078092ae7SKarsten Heimrich }
63178092ae7SKarsten Heimrich 
63278092ae7SKarsten Heimrich 
63378092ae7SKarsten Heimrich int32
63478092ae7SKarsten Heimrich BCalendarView::Year() const
63578092ae7SKarsten Heimrich {
63678092ae7SKarsten Heimrich 	int32 year;
63778092ae7SKarsten Heimrich 	int32 month;
63878092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
63978092ae7SKarsten Heimrich 
64078092ae7SKarsten Heimrich 	return year;
64178092ae7SKarsten Heimrich }
64278092ae7SKarsten Heimrich 
64378092ae7SKarsten Heimrich 
64478092ae7SKarsten Heimrich int32
64578092ae7SKarsten Heimrich BCalendarView::Month() const
64678092ae7SKarsten Heimrich {
64778092ae7SKarsten Heimrich 	int32 year;
64878092ae7SKarsten Heimrich 	int32 month;
64978092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
65078092ae7SKarsten Heimrich 
65178092ae7SKarsten Heimrich 	return month;
65278092ae7SKarsten Heimrich }
65378092ae7SKarsten Heimrich 
65478092ae7SKarsten Heimrich 
65578092ae7SKarsten Heimrich BDate
65678092ae7SKarsten Heimrich BCalendarView::Date() const
65778092ae7SKarsten Heimrich {
65878092ae7SKarsten Heimrich 	int32 year;
65978092ae7SKarsten Heimrich 	int32 month;
66078092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
66178092ae7SKarsten Heimrich 	return BDate(year, month, fDay);
66278092ae7SKarsten Heimrich }
66378092ae7SKarsten Heimrich 
66478092ae7SKarsten Heimrich 
66578092ae7SKarsten Heimrich bool
66678092ae7SKarsten Heimrich BCalendarView::SetDate(const BDate &date)
66778092ae7SKarsten Heimrich {
668c1ed5d75SKarsten Heimrich 	if (!date.IsValid())
669c1ed5d75SKarsten Heimrich 		return false;
670c1ed5d75SKarsten Heimrich 
67178092ae7SKarsten Heimrich 	return SetDate(date.Year(), date.Month(), date.Day());
67278092ae7SKarsten Heimrich }
67378092ae7SKarsten Heimrich 
67478092ae7SKarsten Heimrich 
67578092ae7SKarsten Heimrich bool
67678092ae7SKarsten Heimrich BCalendarView::SetDate(int32 year, int32 month, int32 day)
67778092ae7SKarsten Heimrich {
67878092ae7SKarsten Heimrich 	if (!BDate(year, month, day).IsValid())
67978092ae7SKarsten Heimrich 		return false;
68078092ae7SKarsten Heimrich 
68178092ae7SKarsten Heimrich 	if (fYear == year && fMonth == month && fDay == day)
68278092ae7SKarsten Heimrich 		return true;
68378092ae7SKarsten Heimrich 
68478092ae7SKarsten Heimrich 	fDay = day;
68578092ae7SKarsten Heimrich 	if (fYear == year && fMonth == month) {
68678092ae7SKarsten Heimrich 		_SetToDay();
68778092ae7SKarsten Heimrich 		// update focus
68878092ae7SKarsten Heimrich 		fFocusChanged = true;
68978092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
69078092ae7SKarsten Heimrich 		fFocusChanged = false;
69178092ae7SKarsten Heimrich 
69278092ae7SKarsten Heimrich 		// update selection
69378092ae7SKarsten Heimrich 		fSelectionChanged = true;
69478092ae7SKarsten Heimrich 		Draw(_RectOfDay(fSelectedDay));
69578092ae7SKarsten Heimrich 		Draw(_RectOfDay(fNewSelectedDay));
69678092ae7SKarsten Heimrich 		fSelectionChanged = false;
69778092ae7SKarsten Heimrich 	} else {
69878092ae7SKarsten Heimrich 		fYear = year;
69978092ae7SKarsten Heimrich 		fMonth = month;
70078092ae7SKarsten Heimrich 
70178092ae7SKarsten Heimrich 		_SetupDayNumbers();
70278092ae7SKarsten Heimrich 		_SetupWeekNumbers();
70378092ae7SKarsten Heimrich 
70478092ae7SKarsten Heimrich 		BRect frame = Bounds();
70578092ae7SKarsten Heimrich 		if (fDayNameHeaderVisible)
70678092ae7SKarsten Heimrich 			frame.top += frame.Height() / 7 - 1.0;
70778092ae7SKarsten Heimrich 
70878092ae7SKarsten Heimrich 		if (fWeekNumberHeaderVisible)
70978092ae7SKarsten Heimrich 			frame.left += frame.Width() / 8 - 1.0;
71078092ae7SKarsten Heimrich 
71178092ae7SKarsten Heimrich 		Draw(frame.InsetBySelf(4.0, 4.0));
71278092ae7SKarsten Heimrich 	}
71378092ae7SKarsten Heimrich 
71478092ae7SKarsten Heimrich 	return true;
71578092ae7SKarsten Heimrich }
71678092ae7SKarsten Heimrich 
71778092ae7SKarsten Heimrich 
71878092ae7SKarsten Heimrich week_start
71978092ae7SKarsten Heimrich BCalendarView::WeekStart() const
72078092ae7SKarsten Heimrich {
72178092ae7SKarsten Heimrich 	return fWeekStart;
72278092ae7SKarsten Heimrich }
72378092ae7SKarsten Heimrich 
72478092ae7SKarsten Heimrich 
72578092ae7SKarsten Heimrich void
72678092ae7SKarsten Heimrich BCalendarView::SetWeekStart(week_start start)
72778092ae7SKarsten Heimrich {
72878092ae7SKarsten Heimrich 	if (fWeekStart == start)
72978092ae7SKarsten Heimrich 		return;
73078092ae7SKarsten Heimrich 
73178092ae7SKarsten Heimrich 	fWeekStart = start;
73278092ae7SKarsten Heimrich 
73378092ae7SKarsten Heimrich 	_SetupDayNames();
73478092ae7SKarsten Heimrich 	_SetupDayNumbers();
73578092ae7SKarsten Heimrich 	_SetupWeekNumbers();
73678092ae7SKarsten Heimrich 
73778092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
73878092ae7SKarsten Heimrich }
73978092ae7SKarsten Heimrich 
74078092ae7SKarsten Heimrich 
74178092ae7SKarsten Heimrich bool
74278092ae7SKarsten Heimrich BCalendarView::IsDayNameHeaderVisible() const
74378092ae7SKarsten Heimrich {
74478092ae7SKarsten Heimrich 	return fDayNameHeaderVisible;
74578092ae7SKarsten Heimrich }
74678092ae7SKarsten Heimrich 
74778092ae7SKarsten Heimrich 
74878092ae7SKarsten Heimrich void
74978092ae7SKarsten Heimrich BCalendarView::SetDayNameHeaderVisible(bool visible)
75078092ae7SKarsten Heimrich {
75178092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible == visible)
75278092ae7SKarsten Heimrich 		return;
75378092ae7SKarsten Heimrich 
75478092ae7SKarsten Heimrich 	fDayNameHeaderVisible = visible;
75578092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
75678092ae7SKarsten Heimrich }
75778092ae7SKarsten Heimrich 
75878092ae7SKarsten Heimrich 
75978092ae7SKarsten Heimrich bool
76078092ae7SKarsten Heimrich BCalendarView::IsWeekNumberHeaderVisible() const
76178092ae7SKarsten Heimrich {
76278092ae7SKarsten Heimrich 	return fWeekNumberHeaderVisible;
76378092ae7SKarsten Heimrich }
76478092ae7SKarsten Heimrich 
76578092ae7SKarsten Heimrich 
76678092ae7SKarsten Heimrich void
76778092ae7SKarsten Heimrich BCalendarView::SetWeekNumberHeaderVisible(bool visible)
76878092ae7SKarsten Heimrich {
76978092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible == visible)
77078092ae7SKarsten Heimrich 		return;
77178092ae7SKarsten Heimrich 
77278092ae7SKarsten Heimrich 	fWeekNumberHeaderVisible = visible;
77378092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
77478092ae7SKarsten Heimrich }
77578092ae7SKarsten Heimrich 
77678092ae7SKarsten Heimrich 
77778092ae7SKarsten Heimrich void
77878092ae7SKarsten Heimrich BCalendarView::_InitObject()
77978092ae7SKarsten Heimrich {
78078092ae7SKarsten Heimrich 	BDate date = BDate::CurrentDate(B_LOCAL_TIME);
7819bee8e93SKarsten Heimrich 	date.GetDate(&fYear, &fMonth, &fDay);
78278092ae7SKarsten Heimrich 
78378092ae7SKarsten Heimrich 	_SetupDayNames();
78478092ae7SKarsten Heimrich 	_SetupDayNumbers();
78578092ae7SKarsten Heimrich 	_SetupWeekNumbers();
78678092ae7SKarsten Heimrich }
78778092ae7SKarsten Heimrich 
78878092ae7SKarsten Heimrich 
78978092ae7SKarsten Heimrich void
79078092ae7SKarsten Heimrich BCalendarView::_SetToDay()
79178092ae7SKarsten Heimrich {
79278092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
79378092ae7SKarsten Heimrich 	if (!date.IsValid())
79478092ae7SKarsten Heimrich 		return;
79578092ae7SKarsten Heimrich 
79678092ae7SKarsten Heimrich 	fNewFocusedDay.SetTo(0, 0);
79778092ae7SKarsten Heimrich 	fNewSelectedDay.SetTo(0, 0);
79878092ae7SKarsten Heimrich 
79978092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
80078092ae7SKarsten Heimrich 
80178092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
80278092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
80378092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
80478092ae7SKarsten Heimrich 
80578092ae7SKarsten Heimrich 	int32 counter = 0;
80678092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
80778092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
80878092ae7SKarsten Heimrich 			int32 day = counter - (firstDay - 1);
80978092ae7SKarsten Heimrich 			if (counter >= firstDay && counter <= dayCountCurrent + firstDay - 1) {
81078092ae7SKarsten Heimrich 				if (day == fDay) {
81178092ae7SKarsten Heimrich 					fNewFocusedDay.SetTo(row, column);
81278092ae7SKarsten Heimrich 					fNewSelectedDay.SetTo(row, column);
81378092ae7SKarsten Heimrich 					return;
81478092ae7SKarsten Heimrich 				}
81578092ae7SKarsten Heimrich 			}
81678092ae7SKarsten Heimrich 			counter++;
81778092ae7SKarsten Heimrich 		}
81878092ae7SKarsten Heimrich 	}
81978092ae7SKarsten Heimrich }
82078092ae7SKarsten Heimrich 
82178092ae7SKarsten Heimrich 
82278092ae7SKarsten Heimrich void
82378092ae7SKarsten Heimrich BCalendarView::_GetYearMonth(int32 *year, int32 *month) const
82478092ae7SKarsten Heimrich {
82578092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
82678092ae7SKarsten Heimrich 
82778092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
82878092ae7SKarsten Heimrich 
82978092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
83078092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
83178092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
83278092ae7SKarsten Heimrich 
83378092ae7SKarsten Heimrich 	// set the date to one month before
83478092ae7SKarsten Heimrich 	if (date.Month() == 1)
83578092ae7SKarsten Heimrich 		date.SetDate(date.Year() -1, 12, fDay);
83678092ae7SKarsten Heimrich 	else
83778092ae7SKarsten Heimrich 		date.SetDate(date.Year(), date.Month() - 1, fDay);
83878092ae7SKarsten Heimrich 
83978092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
84078092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
84178092ae7SKarsten Heimrich 
84278092ae7SKarsten Heimrich 	*year = fYear;
84378092ae7SKarsten Heimrich 	*month = fMonth;
84478092ae7SKarsten Heimrich 
84578092ae7SKarsten Heimrich 	int32 counter = 0;
84678092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
84778092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
84878092ae7SKarsten Heimrich 			if (counter < firstDay || counter > dayCountCurrent + firstDay - 1) {
84978092ae7SKarsten Heimrich 				if (counter - firstDay < 0) {
85078092ae7SKarsten Heimrich 					if (row == currRow && column == currColumn) {
85178092ae7SKarsten Heimrich 						*year = date.Year();
85278092ae7SKarsten Heimrich 						*month = date.Month();
85378092ae7SKarsten Heimrich 						break;
85478092ae7SKarsten Heimrich 					}
85578092ae7SKarsten Heimrich 				} else {
85678092ae7SKarsten Heimrich 					if (row == currRow && column == currColumn) {
85778092ae7SKarsten Heimrich 						*year = fYear;
85878092ae7SKarsten Heimrich 						*month = fMonth +1;
85978092ae7SKarsten Heimrich 						if (fMonth == 12) {
86078092ae7SKarsten Heimrich 							*year = fYear +1;
86178092ae7SKarsten Heimrich 							*month = 1;
86278092ae7SKarsten Heimrich 						}
86378092ae7SKarsten Heimrich 						break;
86478092ae7SKarsten Heimrich 					}
86578092ae7SKarsten Heimrich 				}
86678092ae7SKarsten Heimrich 			} else {
86778092ae7SKarsten Heimrich 				if (row == currRow && column == currColumn)
86878092ae7SKarsten Heimrich 					break;
86978092ae7SKarsten Heimrich 			}
87078092ae7SKarsten Heimrich 			counter++;
87178092ae7SKarsten Heimrich 		}
87278092ae7SKarsten Heimrich 	}
87378092ae7SKarsten Heimrich }
87478092ae7SKarsten Heimrich 
87578092ae7SKarsten Heimrich 
87678092ae7SKarsten Heimrich void
87778092ae7SKarsten Heimrich BCalendarView::_GetPreferredSize(float *_width, float *_height)
87878092ae7SKarsten Heimrich {
87978092ae7SKarsten Heimrich 	BFont font;
88078092ae7SKarsten Heimrich 	GetFont(&font);
88178092ae7SKarsten Heimrich 	font_height fontHeight;
88278092ae7SKarsten Heimrich 	font.GetHeight(&fontHeight);
88378092ae7SKarsten Heimrich 
88478092ae7SKarsten Heimrich 	const float height = FontHeight(this) + 4.0;
88578092ae7SKarsten Heimrich 
88678092ae7SKarsten Heimrich 	int32 rows = 7;
88778092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
88878092ae7SKarsten Heimrich 		rows = 6;
88978092ae7SKarsten Heimrich 
89078092ae7SKarsten Heimrich 	// height = font height * rows + 8 px border
89178092ae7SKarsten Heimrich 	*_height = height * rows + 8.0;
89278092ae7SKarsten Heimrich 
89378092ae7SKarsten Heimrich 	float width = 0.0;
89478092ae7SKarsten Heimrich 	for (int32 column = 0; column < 7; ++column) {
89578092ae7SKarsten Heimrich 		float tmp = StringWidth(fDayNames[column].String()) + 2.0;
89678092ae7SKarsten Heimrich 		width = tmp > width ? tmp : width;
89778092ae7SKarsten Heimrich 	}
89878092ae7SKarsten Heimrich 
89978092ae7SKarsten Heimrich 	int32 columns = 8;
90078092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
90178092ae7SKarsten Heimrich 		columns = 7;
90278092ae7SKarsten Heimrich 
90378092ae7SKarsten Heimrich 	// width = max width day name * 8 column + 8 px border
90478092ae7SKarsten Heimrich 	*_width = width * columns + 8.0;
90578092ae7SKarsten Heimrich }
90678092ae7SKarsten Heimrich 
90778092ae7SKarsten Heimrich 
90878092ae7SKarsten Heimrich void
90978092ae7SKarsten Heimrich BCalendarView::_SetupDayNames()
91078092ae7SKarsten Heimrich {
91178092ae7SKarsten Heimrich 	const BDate date(fYear, fMonth, fDay);
91278092ae7SKarsten Heimrich 	if (!date.IsValid())
91378092ae7SKarsten Heimrich 		return;
91478092ae7SKarsten Heimrich 
91578092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY) {
91678092ae7SKarsten Heimrich 		for (int32 i = 1; i <= 7; ++i) {
91778092ae7SKarsten Heimrich 			fDayNames[i -1] = date.ShortDayName(i);
91878092ae7SKarsten Heimrich 		}
91978092ae7SKarsten Heimrich 	} else {
92078092ae7SKarsten Heimrich 		fDayNames[0] = date.ShortDayName(7);
92178092ae7SKarsten Heimrich 		for (int32 i = 1; i < 7; ++i) {
92278092ae7SKarsten Heimrich 			fDayNames[i] = date.ShortDayName(i);
92378092ae7SKarsten Heimrich 		}
92478092ae7SKarsten Heimrich 	}
92578092ae7SKarsten Heimrich }
92678092ae7SKarsten Heimrich 
92778092ae7SKarsten Heimrich 
92878092ae7SKarsten Heimrich void
92978092ae7SKarsten Heimrich BCalendarView::_SetupDayNumbers()
93078092ae7SKarsten Heimrich {
93178092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
93278092ae7SKarsten Heimrich 	if (!date.IsValid())
93378092ae7SKarsten Heimrich 		return;
93478092ae7SKarsten Heimrich 
93578092ae7SKarsten Heimrich 	fFocusedDay.SetTo(0, 0);
93678092ae7SKarsten Heimrich 	fSelectedDay.SetTo(0, 0);
93778092ae7SKarsten Heimrich 	fNewFocusedDay.SetTo(0, 0);
93878092ae7SKarsten Heimrich 
93978092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
94078092ae7SKarsten Heimrich 
94178092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
94278092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
94378092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
94478092ae7SKarsten Heimrich 
94578092ae7SKarsten Heimrich 	// calc the last day one month before
94678092ae7SKarsten Heimrich 	if (date.Month() == 1)
947c8b61804SAxel Dörfler 		date.SetDate(date.Year() -1, 12, 1);
94878092ae7SKarsten Heimrich 	else
949c8b61804SAxel Dörfler 		date.SetDate(date.Year(), date.Month() - 1, 1);
95078092ae7SKarsten Heimrich 	const int32 lastDayBefore = date.DaysInMonth();
95178092ae7SKarsten Heimrich 
95278092ae7SKarsten Heimrich 	int32 counter = 0;
95378092ae7SKarsten Heimrich 	int32 firstDayAfter = 1;
95478092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
95578092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
95678092ae7SKarsten Heimrich 			int32 day = counter - (firstDay - 1);
95778092ae7SKarsten Heimrich 			if (counter < firstDay || counter > dayCountCurrent + firstDay - 1) {
95878092ae7SKarsten Heimrich 				if (counter - firstDay < 0)
95978092ae7SKarsten Heimrich 					day += lastDayBefore;
96078092ae7SKarsten Heimrich 				else
96178092ae7SKarsten Heimrich 					day = firstDayAfter++;
96278092ae7SKarsten Heimrich 			} else {
96378092ae7SKarsten Heimrich 				if (day == fDay) {
96478092ae7SKarsten Heimrich 					fFocusedDay.SetTo(row, column);
96578092ae7SKarsten Heimrich 					fSelectedDay.SetTo(row, column);
96678092ae7SKarsten Heimrich 					fNewFocusedDay.SetTo(row, column);
96778092ae7SKarsten Heimrich 				}
96878092ae7SKarsten Heimrich 			}
96978092ae7SKarsten Heimrich 			counter++;
97078092ae7SKarsten Heimrich 			fDayNumbers[row][column].SetTo("");
97178092ae7SKarsten Heimrich 			fDayNumbers[row][column] << day;
97278092ae7SKarsten Heimrich 		}
97378092ae7SKarsten Heimrich 	}
97478092ae7SKarsten Heimrich }
97578092ae7SKarsten Heimrich 
97678092ae7SKarsten Heimrich void
97778092ae7SKarsten Heimrich BCalendarView::_SetupWeekNumbers()
97878092ae7SKarsten Heimrich {
979c1ed5d75SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
98078092ae7SKarsten Heimrich 	if (!date.IsValid())
98178092ae7SKarsten Heimrich 		return;
98278092ae7SKarsten Heimrich 
983f0932941SMichael Pfeiffer 	// date on Thursday determines week number (ISO 8601)
9844352fc91SMichael Pfeiffer 	int dayOfWeek = date.DayOfWeek();
9854352fc91SMichael Pfeiffer 	// adjust weekday if Monday is week start,
9864352fc91SMichael Pfeiffer 	// then Sunday is last day in week
9874352fc91SMichael Pfeiffer 	if (fWeekStart == B_WEEK_START_MONDAY && dayOfWeek == 0)
9884352fc91SMichael Pfeiffer 			dayOfWeek = 7;
9894352fc91SMichael Pfeiffer 	date.AddDays(4 - dayOfWeek);
99078092ae7SKarsten Heimrich 
991c1ed5d75SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
99278092ae7SKarsten Heimrich 		fWeekNumbers[row].SetTo("");
993f0932941SMichael Pfeiffer 		fWeekNumbers[row] << date.WeekNumber();
994f0932941SMichael Pfeiffer 		date.AddDays(7);
995c1ed5d75SKarsten Heimrich 	}
99678092ae7SKarsten Heimrich }
99778092ae7SKarsten Heimrich 
99878092ae7SKarsten Heimrich 
99978092ae7SKarsten Heimrich void
100078092ae7SKarsten Heimrich BCalendarView::_DrawDay(int32 currRow, int32 currColumn, int32 row, int32 column,
100178092ae7SKarsten Heimrich 	int32 counter, BRect frame, const char *text, bool focus)
100278092ae7SKarsten Heimrich {
100378092ae7SKarsten Heimrich 	const BDate date(fYear, fMonth, 1);
100478092ae7SKarsten Heimrich 	const int32 daysMonth = date.DaysInMonth();
100578092ae7SKarsten Heimrich 
100678092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
100778092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
100878092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
100978092ae7SKarsten Heimrich 
101078092ae7SKarsten Heimrich 	bool enabled = true;
101178092ae7SKarsten Heimrich 	bool selected = false;
101278092ae7SKarsten Heimrich 	// check for the current date
101378092ae7SKarsten Heimrich 	if (currRow == row  && currColumn == column) {
101478092ae7SKarsten Heimrich 		selected = true;	// draw current date selected
101578092ae7SKarsten Heimrich 		if (counter <= firstDay || counter > firstDay + daysMonth) {
101678092ae7SKarsten Heimrich 			enabled = false;	// days of month before or after
101778092ae7SKarsten Heimrich 			selected = false;	// not selected but able to get focus
101878092ae7SKarsten Heimrich 		}
101978092ae7SKarsten Heimrich 	} else {
102078092ae7SKarsten Heimrich 		if (counter <= firstDay || counter > firstDay + daysMonth)
102178092ae7SKarsten Heimrich 			enabled = false;	// days of month before or after
102278092ae7SKarsten Heimrich 	}
102378092ae7SKarsten Heimrich 
102478092ae7SKarsten Heimrich 	DrawDay(this, frame, text, selected, enabled, focus);
102578092ae7SKarsten Heimrich }
102678092ae7SKarsten Heimrich 
102778092ae7SKarsten Heimrich 
102878092ae7SKarsten Heimrich void
102978092ae7SKarsten Heimrich BCalendarView::_DrawDays()
103078092ae7SKarsten Heimrich {
103178092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
103278092ae7SKarsten Heimrich 
103378092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
103478092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
103578092ae7SKarsten Heimrich 
103678092ae7SKarsten Heimrich 	const bool isFocus = IsFocus();
103778092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
103878092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
103978092ae7SKarsten Heimrich 
104078092ae7SKarsten Heimrich 	int32 counter = 0;
104178092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
104278092ae7SKarsten Heimrich 		BRect tmp = frame;
104378092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
104478092ae7SKarsten Heimrich 			counter++;
104578092ae7SKarsten Heimrich 			const char *day = fDayNumbers[row][column].String();
104678092ae7SKarsten Heimrich 			bool focus = isFocus && focusRow == row && focusColumn == column;
104778092ae7SKarsten Heimrich 			_DrawDay(currRow, currColumn, row, column, counter, tmp, day, focus);
104878092ae7SKarsten Heimrich 
104978092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
105078092ae7SKarsten Heimrich 		}
105178092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
105278092ae7SKarsten Heimrich 	}
105378092ae7SKarsten Heimrich }
105478092ae7SKarsten Heimrich 
105578092ae7SKarsten Heimrich 
105678092ae7SKarsten Heimrich void
105778092ae7SKarsten Heimrich BCalendarView::_DrawFocusRect()
105878092ae7SKarsten Heimrich {
105978092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
106078092ae7SKarsten Heimrich 
106178092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
106278092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
106378092ae7SKarsten Heimrich 
106478092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
106578092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
106678092ae7SKarsten Heimrich 
106778092ae7SKarsten Heimrich 	int32 counter = 0;
106878092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
106978092ae7SKarsten Heimrich 		BRect tmp = frame;
107078092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
107178092ae7SKarsten Heimrich 			counter++;
107278092ae7SKarsten Heimrich 			if (fNewFocusedDay.row == row && fNewFocusedDay.column == column) {
107378092ae7SKarsten Heimrich 				fFocusedDay.SetTo(row, column);
107478092ae7SKarsten Heimrich 
107578092ae7SKarsten Heimrich 				bool focus = IsFocus() && true;
107678092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
107778092ae7SKarsten Heimrich 				_DrawDay(currRow, currColumn, row, column, counter, tmp, day, focus);
107878092ae7SKarsten Heimrich 			}
107978092ae7SKarsten Heimrich 			else if (focusRow == row && focusColumn == column) {
108078092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
108178092ae7SKarsten Heimrich 				_DrawDay(currRow, currColumn, row, column, counter, tmp, day, false);
108278092ae7SKarsten Heimrich 			}
108378092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
108478092ae7SKarsten Heimrich 		}
108578092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
108678092ae7SKarsten Heimrich 	}
108778092ae7SKarsten Heimrich }
108878092ae7SKarsten Heimrich 
108978092ae7SKarsten Heimrich 
109078092ae7SKarsten Heimrich void
109178092ae7SKarsten Heimrich BCalendarView::_DrawDayHeader()
109278092ae7SKarsten Heimrich {
109378092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
109478092ae7SKarsten Heimrich 		return;
109578092ae7SKarsten Heimrich 
109678092ae7SKarsten Heimrich 	int32 offset = 1;
109778092ae7SKarsten Heimrich 	int32 columns = 8;
109878092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible) {
109978092ae7SKarsten Heimrich 		offset = 0;
110078092ae7SKarsten Heimrich 		columns = 7;
110178092ae7SKarsten Heimrich 	}
110278092ae7SKarsten Heimrich 
110378092ae7SKarsten Heimrich 	BRect frame = Bounds();
110478092ae7SKarsten Heimrich 	frame.right = frame.Width() / columns - 1.0;
110578092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / 7.0 - 2.0;
110678092ae7SKarsten Heimrich 	frame.OffsetBy(4.0, 4.0);
110778092ae7SKarsten Heimrich 
110878092ae7SKarsten Heimrich 	for (int32 i = 0; i < columns; ++i) {
110978092ae7SKarsten Heimrich 		if (i == 0 && fWeekNumberHeaderVisible) {
111078092ae7SKarsten Heimrich 			DrawDayName(this, frame, "");
111178092ae7SKarsten Heimrich 			frame.OffsetBy(frame.Width(), 0.0);
111278092ae7SKarsten Heimrich 			continue;
111378092ae7SKarsten Heimrich 		}
111478092ae7SKarsten Heimrich 		DrawDayName(this, frame, fDayNames[i - offset].String());
111578092ae7SKarsten Heimrich 		frame.OffsetBy(frame.Width(), 0.0);
111678092ae7SKarsten Heimrich 	}
111778092ae7SKarsten Heimrich }
111878092ae7SKarsten Heimrich 
111978092ae7SKarsten Heimrich 
112078092ae7SKarsten Heimrich void
112178092ae7SKarsten Heimrich BCalendarView::_DrawWeekHeader()
112278092ae7SKarsten Heimrich {
112378092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
112478092ae7SKarsten Heimrich 		return;
112578092ae7SKarsten Heimrich 
112678092ae7SKarsten Heimrich 	int32 rows = 7;
112778092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
112878092ae7SKarsten Heimrich 		rows = 6;
112978092ae7SKarsten Heimrich 
113078092ae7SKarsten Heimrich 	BRect frame = Bounds();
113178092ae7SKarsten Heimrich 	frame.right = frame.Width() / 8.0 - 2.0;
113278092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / rows - 1.0;
113378092ae7SKarsten Heimrich 
113478092ae7SKarsten Heimrich 	float offsetY = 4.0;
113578092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
113678092ae7SKarsten Heimrich 		offsetY += frame.Height();
113778092ae7SKarsten Heimrich 
113878092ae7SKarsten Heimrich 	frame.OffsetBy(4.0, offsetY);
113978092ae7SKarsten Heimrich 
114078092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
114178092ae7SKarsten Heimrich 		DrawWeekNumber(this, frame, fWeekNumbers[row].String());
114278092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
114378092ae7SKarsten Heimrich 	}
114478092ae7SKarsten Heimrich }
114578092ae7SKarsten Heimrich 
114678092ae7SKarsten Heimrich 
114778092ae7SKarsten Heimrich void
114878092ae7SKarsten Heimrich BCalendarView::_DrawItem(BView *owner, BRect frame, const char *text,
114978092ae7SKarsten Heimrich 	bool isSelected, bool isEnabled, bool focus)
115078092ae7SKarsten Heimrich {
115178092ae7SKarsten Heimrich 	rgb_color lColor = LowColor();
115278092ae7SKarsten Heimrich 	rgb_color highColor = HighColor();
115378092ae7SKarsten Heimrich 
115478092ae7SKarsten Heimrich 	rgb_color lowColor = { 255, 255, 255, 255 };
115578092ae7SKarsten Heimrich 
115678092ae7SKarsten Heimrich 	if (isSelected) {
115778092ae7SKarsten Heimrich 		SetHighColor(tint_color(lowColor, B_DARKEN_2_TINT));
115878092ae7SKarsten Heimrich 		SetLowColor(HighColor());
115978092ae7SKarsten Heimrich 	} else
116078092ae7SKarsten Heimrich 		SetHighColor(lowColor);
116178092ae7SKarsten Heimrich 
116278092ae7SKarsten Heimrich 	FillRect(frame.InsetByCopy(1.0, 1.0));
116378092ae7SKarsten Heimrich 
116478092ae7SKarsten Heimrich 	if (focus) {
116578092ae7SKarsten Heimrich 		SetHighColor(keyboard_navigation_color());
116678092ae7SKarsten Heimrich 		StrokeRect(frame.InsetByCopy(1.0, 1.0));
116778092ae7SKarsten Heimrich 	}
116878092ae7SKarsten Heimrich 
116978092ae7SKarsten Heimrich 	rgb_color black = { 0, 0, 0, 255 };
117078092ae7SKarsten Heimrich 	SetHighColor(black);
117178092ae7SKarsten Heimrich 	if (!isEnabled)
117278092ae7SKarsten Heimrich 		SetHighColor(tint_color(black, B_LIGHTEN_2_TINT));
117378092ae7SKarsten Heimrich 
117478092ae7SKarsten Heimrich 	float offsetH = frame.Width() / 2.0;
117578092ae7SKarsten Heimrich 	float offsetV = (frame.Height() / 2.0) + (FontHeight(owner) / 2.0) - 2.0;
117678092ae7SKarsten Heimrich 
117778092ae7SKarsten Heimrich 	DrawString(text, BPoint(frame.right - offsetH
117878092ae7SKarsten Heimrich 		- (StringWidth(text) / 2.0), frame.top + offsetV));
117978092ae7SKarsten Heimrich 
118078092ae7SKarsten Heimrich 	SetLowColor(lColor);
118178092ae7SKarsten Heimrich 	SetHighColor(highColor);
118278092ae7SKarsten Heimrich }
118378092ae7SKarsten Heimrich 
118478092ae7SKarsten Heimrich 
118578092ae7SKarsten Heimrich void
118678092ae7SKarsten Heimrich BCalendarView::_UpdateSelection()
118778092ae7SKarsten Heimrich {
118878092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
118978092ae7SKarsten Heimrich 
119078092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
119178092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
119278092ae7SKarsten Heimrich 
119378092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
119478092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
119578092ae7SKarsten Heimrich 
119678092ae7SKarsten Heimrich 	int32 counter = 0;
119778092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
119878092ae7SKarsten Heimrich 		BRect tmp = frame;
119978092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
120078092ae7SKarsten Heimrich 			counter++;
120178092ae7SKarsten Heimrich 			if (fNewSelectedDay.row == row && fNewSelectedDay.column == column) {
120278092ae7SKarsten Heimrich 				fSelectedDay.SetTo(row, column);
120378092ae7SKarsten Heimrich 
120478092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
120578092ae7SKarsten Heimrich 				bool focus = IsFocus() && focusRow == row && focusColumn == column;
120678092ae7SKarsten Heimrich 				_DrawDay(row, column, row, column, counter, tmp, day, focus);
120778092ae7SKarsten Heimrich 			}
120878092ae7SKarsten Heimrich 			else if (currRow == row && currColumn == column) {
120978092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
121078092ae7SKarsten Heimrich 				bool focus = IsFocus() && focusRow == row && focusColumn == column;
121178092ae7SKarsten Heimrich 				_DrawDay(currRow, currColumn, -1, -1, counter, tmp, day, focus);
121278092ae7SKarsten Heimrich 			}
121378092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
121478092ae7SKarsten Heimrich 		}
121578092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
121678092ae7SKarsten Heimrich 	}
121778092ae7SKarsten Heimrich }
121878092ae7SKarsten Heimrich 
121978092ae7SKarsten Heimrich 
122078092ae7SKarsten Heimrich BRect
122178092ae7SKarsten Heimrich BCalendarView::_FirstCalendarItemFrame() const
122278092ae7SKarsten Heimrich {
122378092ae7SKarsten Heimrich 	int32 rows = 7;
122478092ae7SKarsten Heimrich 	int32 columns = 8;
122578092ae7SKarsten Heimrich 
122678092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
122778092ae7SKarsten Heimrich 		rows = 6;
122878092ae7SKarsten Heimrich 
122978092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
123078092ae7SKarsten Heimrich 		columns = 7;
123178092ae7SKarsten Heimrich 
123278092ae7SKarsten Heimrich 	BRect frame = Bounds();
123378092ae7SKarsten Heimrich 	frame.right = frame.Width() / columns - 1.0;
123478092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / rows - 1.0;
123578092ae7SKarsten Heimrich 
123678092ae7SKarsten Heimrich 	float offsetY = 4.0;
123778092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
123878092ae7SKarsten Heimrich 		offsetY += frame.Height();
123978092ae7SKarsten Heimrich 
124078092ae7SKarsten Heimrich 	float offsetX = 4.0;
124178092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible)
124278092ae7SKarsten Heimrich 		offsetX += frame.Width();
124378092ae7SKarsten Heimrich 
124478092ae7SKarsten Heimrich 	return frame.OffsetBySelf(offsetX, offsetY);
124578092ae7SKarsten Heimrich }
124678092ae7SKarsten Heimrich 
124778092ae7SKarsten Heimrich 
124878092ae7SKarsten Heimrich BRect
124978092ae7SKarsten Heimrich BCalendarView::_SetNewSelectedDay(const BPoint &where)
125078092ae7SKarsten Heimrich {
125178092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
125278092ae7SKarsten Heimrich 
125378092ae7SKarsten Heimrich 	int32 counter = 0;
125478092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
125578092ae7SKarsten Heimrich 		BRect tmp = frame;
125678092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
125778092ae7SKarsten Heimrich 			counter++;
125878092ae7SKarsten Heimrich 			if (tmp.Contains(where)) {
125978092ae7SKarsten Heimrich 				fNewSelectedDay.SetTo(row, column);
126078092ae7SKarsten Heimrich 				fDay = atoi(fDayNumbers[row][column].String());
126178092ae7SKarsten Heimrich 				return tmp;
126278092ae7SKarsten Heimrich 			}
126378092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
126478092ae7SKarsten Heimrich 		}
126578092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
126678092ae7SKarsten Heimrich 	}
126778092ae7SKarsten Heimrich 
126878092ae7SKarsten Heimrich 	return frame;
126978092ae7SKarsten Heimrich }
127078092ae7SKarsten Heimrich 
127178092ae7SKarsten Heimrich 
127278092ae7SKarsten Heimrich BRect
127378092ae7SKarsten Heimrich BCalendarView::_RectOfDay(const Selection &selection) const
127478092ae7SKarsten Heimrich {
127578092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
127678092ae7SKarsten Heimrich 
127778092ae7SKarsten Heimrich 	int32 counter = 0;
127878092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
127978092ae7SKarsten Heimrich 		BRect tmp = frame;
128078092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
128178092ae7SKarsten Heimrich 			counter++;
128278092ae7SKarsten Heimrich 			if (selection.row == row && selection.column == column) {
128378092ae7SKarsten Heimrich 				return tmp;
128478092ae7SKarsten Heimrich 			}
128578092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
128678092ae7SKarsten Heimrich 		}
128778092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
128878092ae7SKarsten Heimrich 	}
128978092ae7SKarsten Heimrich 
129078092ae7SKarsten Heimrich 	return frame;
129178092ae7SKarsten Heimrich }
129278092ae7SKarsten Heimrich 
129378092ae7SKarsten Heimrich 
129478092ae7SKarsten Heimrich }	// namespace BPrivate
1295