xref: /haiku/src/kits/shared/CalendarView.cpp (revision 1b3303e7ee6ccc024028e39340cff35043a8523c)
178092ae7SKarsten Heimrich /*
2*1b3303e7SAxel Dörfler  * Copyright 2007-2009, 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 
9*1b3303e7SAxel Dörfler 
1078092ae7SKarsten Heimrich #include "CalendarView.h"
1178092ae7SKarsten Heimrich 
12*1b3303e7SAxel Dörfler #include <stdlib.h>
1378092ae7SKarsten Heimrich 
1478092ae7SKarsten Heimrich #include <Window.h>
1578092ae7SKarsten Heimrich 
1678092ae7SKarsten Heimrich 
1778092ae7SKarsten Heimrich namespace BPrivate {
1878092ae7SKarsten Heimrich 
1978092ae7SKarsten Heimrich namespace {
20*1b3303e7SAxel Dörfler 
2178092ae7SKarsten Heimrich 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 }
33*1b3303e7SAxel Dörfler 
34*1b3303e7SAxel Dörfler }	// private namespace
3578092ae7SKarsten Heimrich 
3678092ae7SKarsten Heimrich 
3778092ae7SKarsten Heimrich BCalendarView::BCalendarView(BRect frame, const char *name,
3878092ae7SKarsten Heimrich 		uint32 resizeMask, uint32 flags)
39*1b3303e7SAxel Dörfler 	:
40*1b3303e7SAxel Dörfler 	BView(frame, name, resizeMask, flags),
4178092ae7SKarsten Heimrich 	BInvoker(),
4278092ae7SKarsten Heimrich 	fSelectionMessage(NULL),
4378092ae7SKarsten Heimrich 	fDay(0),
4478092ae7SKarsten Heimrich 	fYear(0),
4578092ae7SKarsten Heimrich 	fMonth(0),
4678092ae7SKarsten Heimrich 	fFocusChanged(false),
4778092ae7SKarsten Heimrich 	fSelectionChanged(false),
4878092ae7SKarsten Heimrich 	fWeekStart(B_WEEK_START_SUNDAY),
4978092ae7SKarsten Heimrich 	fDayNameHeaderVisible(true),
5078092ae7SKarsten Heimrich 	fWeekNumberHeaderVisible(true)
5178092ae7SKarsten Heimrich {
5278092ae7SKarsten Heimrich 	_InitObject();
5378092ae7SKarsten Heimrich }
5478092ae7SKarsten Heimrich 
5578092ae7SKarsten Heimrich 
5678092ae7SKarsten Heimrich BCalendarView::BCalendarView(BRect frame, const char *name, week_start start,
5778092ae7SKarsten Heimrich 		uint32 resizeMask, uint32 flags)
58*1b3303e7SAxel Dörfler 	:
59*1b3303e7SAxel Dörfler 	BView(frame, name, resizeMask, flags),
6078092ae7SKarsten Heimrich 	BInvoker(),
6178092ae7SKarsten Heimrich 	fSelectionMessage(NULL),
6278092ae7SKarsten Heimrich 	fDay(0),
6378092ae7SKarsten Heimrich 	fYear(0),
6478092ae7SKarsten Heimrich 	fMonth(0),
6578092ae7SKarsten Heimrich 	fFocusChanged(false),
6678092ae7SKarsten Heimrich 	fSelectionChanged(false),
6778092ae7SKarsten Heimrich 	fWeekStart(start),
6878092ae7SKarsten Heimrich 	fDayNameHeaderVisible(true),
6978092ae7SKarsten Heimrich 	fWeekNumberHeaderVisible(true)
7078092ae7SKarsten Heimrich {
7178092ae7SKarsten Heimrich 	_InitObject();
7278092ae7SKarsten Heimrich }
7378092ae7SKarsten Heimrich 
7478092ae7SKarsten Heimrich 
7578092ae7SKarsten Heimrich BCalendarView::~BCalendarView()
7678092ae7SKarsten Heimrich {
7778092ae7SKarsten Heimrich 	SetSelectionMessage(NULL);
7878092ae7SKarsten Heimrich }
7978092ae7SKarsten Heimrich 
8078092ae7SKarsten Heimrich 
8178092ae7SKarsten Heimrich BCalendarView::BCalendarView(BMessage *archive)
82*1b3303e7SAxel Dörfler 	:
83*1b3303e7SAxel Dörfler 	BView(archive),
8478092ae7SKarsten Heimrich 	BInvoker(),
8578092ae7SKarsten Heimrich 	fSelectionMessage(NULL),
8678092ae7SKarsten Heimrich 	fDay(0),
8778092ae7SKarsten Heimrich 	fYear(0),
8878092ae7SKarsten Heimrich 	fMonth(0),
8978092ae7SKarsten Heimrich 	fFocusChanged(false),
9078092ae7SKarsten Heimrich 	fSelectionChanged(false),
9178092ae7SKarsten Heimrich 	fWeekStart(B_WEEK_START_SUNDAY),
9278092ae7SKarsten Heimrich 	fDayNameHeaderVisible(true),
9378092ae7SKarsten Heimrich 	fWeekNumberHeaderVisible(true)
9478092ae7SKarsten Heimrich {
9578092ae7SKarsten Heimrich 	if (archive->HasMessage("_invokeMsg")) {
9678092ae7SKarsten Heimrich 		BMessage *invokationMessage = new BMessage;
9778092ae7SKarsten Heimrich 		archive->FindMessage("_invokeMsg", invokationMessage);
9878092ae7SKarsten Heimrich 		SetInvocationMessage(invokationMessage);
9978092ae7SKarsten Heimrich 	}
10078092ae7SKarsten Heimrich 
10178092ae7SKarsten Heimrich 	if (archive->HasMessage("_selectMsg")) {
10278092ae7SKarsten Heimrich 		BMessage *selectionMessage = new BMessage;
10378092ae7SKarsten Heimrich 		archive->FindMessage("selectMsg", selectionMessage);
10478092ae7SKarsten Heimrich 		SetSelectionMessage(selectionMessage);
10578092ae7SKarsten Heimrich 	}
10678092ae7SKarsten Heimrich 
10778092ae7SKarsten Heimrich 	if (archive->FindInt32("_day", &fDay) != B_OK
10878092ae7SKarsten Heimrich 		|| archive->FindInt32("_month", &fMonth) != B_OK
10978092ae7SKarsten Heimrich 		|| archive->FindInt32("_year", &fYear) != B_OK) {
11078092ae7SKarsten Heimrich 		BDate date = BDate::CurrentDate(B_LOCAL_TIME);
1119bee8e93SKarsten Heimrich 		date.GetDate(&fYear, &fMonth, &fDay);
11278092ae7SKarsten Heimrich 	}
11378092ae7SKarsten Heimrich 
11478092ae7SKarsten Heimrich 	int32 start;
11578092ae7SKarsten Heimrich 	if (archive->FindInt32("_weekStart", &start) == B_OK)
11678092ae7SKarsten Heimrich 		fWeekStart = week_start(start);
11778092ae7SKarsten Heimrich 
11878092ae7SKarsten Heimrich 	if (archive->FindBool("_dayHeader", &fDayNameHeaderVisible) != B_OK)
11978092ae7SKarsten Heimrich 		fDayNameHeaderVisible = true;
12078092ae7SKarsten Heimrich 
12178092ae7SKarsten Heimrich 	if (archive->FindBool("_weekHeader", &fWeekNumberHeaderVisible) != B_OK)
12278092ae7SKarsten Heimrich 		fWeekNumberHeaderVisible = true;
12378092ae7SKarsten Heimrich 
12478092ae7SKarsten Heimrich 	_SetupDayNames();
12578092ae7SKarsten Heimrich 	_SetupDayNumbers();
12678092ae7SKarsten Heimrich 	_SetupWeekNumbers();
12778092ae7SKarsten Heimrich }
12878092ae7SKarsten Heimrich 
12978092ae7SKarsten Heimrich 
13078092ae7SKarsten Heimrich BArchivable*
13178092ae7SKarsten Heimrich BCalendarView::Instantiate(BMessage *archive)
13278092ae7SKarsten Heimrich {
13378092ae7SKarsten Heimrich 	if (validate_instantiation(archive, "BCalendarView"))
13478092ae7SKarsten Heimrich 		return new BCalendarView(archive);
13578092ae7SKarsten Heimrich 
13678092ae7SKarsten Heimrich 	return NULL;
13778092ae7SKarsten Heimrich }
13878092ae7SKarsten Heimrich 
13978092ae7SKarsten Heimrich 
14078092ae7SKarsten Heimrich status_t
14178092ae7SKarsten Heimrich BCalendarView::Archive(BMessage *archive, bool deep) const
14278092ae7SKarsten Heimrich {
14378092ae7SKarsten Heimrich 	status_t status = BView::Archive(archive, deep);
14478092ae7SKarsten Heimrich 
14578092ae7SKarsten Heimrich 	if (status == B_OK && InvocationMessage())
14678092ae7SKarsten Heimrich 		status = archive->AddMessage("_invokeMsg", InvocationMessage());
14778092ae7SKarsten Heimrich 
14878092ae7SKarsten Heimrich 	if (status == B_OK && SelectionMessage())
14978092ae7SKarsten Heimrich 		status = archive->AddMessage("_selectMsg", SelectionMessage());
15078092ae7SKarsten Heimrich 
15178092ae7SKarsten Heimrich 	if (status == B_OK)
15278092ae7SKarsten Heimrich 		status = archive->AddInt32("_day", fDay);
15378092ae7SKarsten Heimrich 
15478092ae7SKarsten Heimrich 	if (status == B_OK)
15578092ae7SKarsten Heimrich 		status = archive->AddInt32("_month", fMonth);
15678092ae7SKarsten Heimrich 
15778092ae7SKarsten Heimrich 	if (status == B_OK)
15878092ae7SKarsten Heimrich 		status = archive->AddInt32("_year", fYear);
15978092ae7SKarsten Heimrich 
16078092ae7SKarsten Heimrich 	if (status == B_OK)
16178092ae7SKarsten Heimrich 		status = archive->AddInt32("_weekStart", int32(fWeekStart));
16278092ae7SKarsten Heimrich 
16378092ae7SKarsten Heimrich 	if (status == B_OK)
16478092ae7SKarsten Heimrich 		status = archive->AddBool("_dayHeader", fDayNameHeaderVisible);
16578092ae7SKarsten Heimrich 
16678092ae7SKarsten Heimrich 	if (status == B_OK)
16778092ae7SKarsten Heimrich 		status = archive->AddBool("_weekHeader", fWeekNumberHeaderVisible);
16878092ae7SKarsten Heimrich 
16978092ae7SKarsten Heimrich 	return status;
17078092ae7SKarsten Heimrich }
17178092ae7SKarsten Heimrich 
17278092ae7SKarsten Heimrich 
17378092ae7SKarsten Heimrich void
17478092ae7SKarsten Heimrich BCalendarView::AttachedToWindow()
17578092ae7SKarsten Heimrich {
17678092ae7SKarsten Heimrich 	BView::AttachedToWindow();
17778092ae7SKarsten Heimrich 
17878092ae7SKarsten Heimrich 	if (!Messenger().IsValid())
17978092ae7SKarsten Heimrich 		SetTarget(Window(), NULL);
18078092ae7SKarsten Heimrich }
18178092ae7SKarsten Heimrich 
18278092ae7SKarsten Heimrich 
18378092ae7SKarsten Heimrich void
18478092ae7SKarsten Heimrich BCalendarView::DetachedFromWindow()
18578092ae7SKarsten Heimrich {
18678092ae7SKarsten Heimrich 	BView::DetachedFromWindow();
18778092ae7SKarsten Heimrich }
18878092ae7SKarsten Heimrich 
18978092ae7SKarsten Heimrich 
19078092ae7SKarsten Heimrich void
19178092ae7SKarsten Heimrich BCalendarView::AllAttached()
19278092ae7SKarsten Heimrich {
19378092ae7SKarsten Heimrich 	BView::AllAttached();
19478092ae7SKarsten Heimrich }
19578092ae7SKarsten Heimrich 
19678092ae7SKarsten Heimrich 
19778092ae7SKarsten Heimrich void
19878092ae7SKarsten Heimrich BCalendarView::AllDetached()
19978092ae7SKarsten Heimrich {
20078092ae7SKarsten Heimrich 	BView::AllDetached();
20178092ae7SKarsten Heimrich }
20278092ae7SKarsten Heimrich 
20378092ae7SKarsten Heimrich 
20478092ae7SKarsten Heimrich void
20578092ae7SKarsten Heimrich BCalendarView::FrameMoved(BPoint newPosition)
20678092ae7SKarsten Heimrich {
20778092ae7SKarsten Heimrich 	BView::FrameMoved(newPosition);
20878092ae7SKarsten Heimrich }
20978092ae7SKarsten Heimrich 
21078092ae7SKarsten Heimrich 
21178092ae7SKarsten Heimrich void
21278092ae7SKarsten Heimrich BCalendarView::FrameResized(float width, float height)
21378092ae7SKarsten Heimrich {
21478092ae7SKarsten Heimrich 	Invalidate(Bounds());
21578092ae7SKarsten Heimrich }
21678092ae7SKarsten Heimrich 
21778092ae7SKarsten Heimrich 
21878092ae7SKarsten Heimrich void
21978092ae7SKarsten Heimrich BCalendarView::Draw(BRect updateRect)
22078092ae7SKarsten Heimrich {
22178092ae7SKarsten Heimrich 	if (LockLooper()) {
22278092ae7SKarsten Heimrich 		if (fFocusChanged) {
22378092ae7SKarsten Heimrich 			_DrawFocusRect();
22478092ae7SKarsten Heimrich 			UnlockLooper();
22578092ae7SKarsten Heimrich 			return;
22678092ae7SKarsten Heimrich 		}
22778092ae7SKarsten Heimrich 
22878092ae7SKarsten Heimrich 		if (fSelectionChanged) {
22978092ae7SKarsten Heimrich 			_UpdateSelection();
23078092ae7SKarsten Heimrich 			UnlockLooper();
23178092ae7SKarsten Heimrich 			return;
23278092ae7SKarsten Heimrich 		}
23378092ae7SKarsten Heimrich 
23478092ae7SKarsten Heimrich 		_DrawDays();
23578092ae7SKarsten Heimrich 		_DrawDayHeader();
23678092ae7SKarsten Heimrich 		_DrawWeekHeader();
23778092ae7SKarsten Heimrich 
23878092ae7SKarsten Heimrich 		rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
23978092ae7SKarsten Heimrich 		SetHighColor(tint_color(background, B_DARKEN_3_TINT));
24078092ae7SKarsten Heimrich 		StrokeRect(Bounds());
24178092ae7SKarsten Heimrich 
24278092ae7SKarsten Heimrich 		UnlockLooper();
24378092ae7SKarsten Heimrich 	}
24478092ae7SKarsten Heimrich }
24578092ae7SKarsten Heimrich 
24678092ae7SKarsten Heimrich 
24778092ae7SKarsten Heimrich void
24878092ae7SKarsten Heimrich BCalendarView::DrawDay(BView *owner, BRect frame, const char *text,
24978092ae7SKarsten Heimrich 	bool isSelected, bool isEnabled, bool focus)
25078092ae7SKarsten Heimrich {
25178092ae7SKarsten Heimrich 	_DrawItem(owner, frame, text, isSelected, isEnabled, focus);
25278092ae7SKarsten Heimrich }
25378092ae7SKarsten Heimrich 
25478092ae7SKarsten Heimrich 
25578092ae7SKarsten Heimrich void
25678092ae7SKarsten Heimrich BCalendarView::DrawDayName(BView *owner, BRect frame, const char *text)
25778092ae7SKarsten Heimrich {
25878092ae7SKarsten Heimrich 	// we get the full rect, fake this as the internal function
25978092ae7SKarsten Heimrich 	// shrinks the frame to work properly when drawing a day item
26078092ae7SKarsten Heimrich 	_DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true);
26178092ae7SKarsten Heimrich }
26278092ae7SKarsten Heimrich 
26378092ae7SKarsten Heimrich 
26478092ae7SKarsten Heimrich void
26578092ae7SKarsten Heimrich BCalendarView::DrawWeekNumber(BView *owner, BRect frame, const char *text)
26678092ae7SKarsten Heimrich {
26778092ae7SKarsten Heimrich 	// we get the full rect, fake this as the internal function
26878092ae7SKarsten Heimrich 	// shrinks the frame to work properly when drawing a day item
26978092ae7SKarsten Heimrich 	_DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true);
27078092ae7SKarsten Heimrich }
27178092ae7SKarsten Heimrich 
27278092ae7SKarsten Heimrich 
27378092ae7SKarsten Heimrich void
27478092ae7SKarsten Heimrich BCalendarView::MessageReceived(BMessage *message)
27578092ae7SKarsten Heimrich {
27678092ae7SKarsten Heimrich 	BView::MessageReceived(message);
27778092ae7SKarsten Heimrich }
27878092ae7SKarsten Heimrich 
27978092ae7SKarsten Heimrich 
28078092ae7SKarsten Heimrich uint32
28178092ae7SKarsten Heimrich BCalendarView::SelectionCommand() const
28278092ae7SKarsten Heimrich {
28378092ae7SKarsten Heimrich 	if (SelectionMessage())
28478092ae7SKarsten Heimrich 		return SelectionMessage()->what;
28578092ae7SKarsten Heimrich 
28678092ae7SKarsten Heimrich 	return 0;
28778092ae7SKarsten Heimrich }
28878092ae7SKarsten Heimrich 
28978092ae7SKarsten Heimrich 
29078092ae7SKarsten Heimrich BMessage*
29178092ae7SKarsten Heimrich BCalendarView::SelectionMessage() const
29278092ae7SKarsten Heimrich {
29378092ae7SKarsten Heimrich 	return fSelectionMessage;
29478092ae7SKarsten Heimrich }
29578092ae7SKarsten Heimrich 
29678092ae7SKarsten Heimrich 
29778092ae7SKarsten Heimrich void
29878092ae7SKarsten Heimrich BCalendarView::SetSelectionMessage(BMessage *message)
29978092ae7SKarsten Heimrich {
30078092ae7SKarsten Heimrich 	delete fSelectionMessage;
30178092ae7SKarsten Heimrich 	fSelectionMessage = message;
30278092ae7SKarsten Heimrich }
30378092ae7SKarsten Heimrich 
30478092ae7SKarsten Heimrich 
30578092ae7SKarsten Heimrich uint32
30678092ae7SKarsten Heimrich BCalendarView::InvocationCommand() const
30778092ae7SKarsten Heimrich {
30878092ae7SKarsten Heimrich 	return BInvoker::Command();
30978092ae7SKarsten Heimrich }
31078092ae7SKarsten Heimrich 
31178092ae7SKarsten Heimrich 
31278092ae7SKarsten Heimrich BMessage*
31378092ae7SKarsten Heimrich BCalendarView::InvocationMessage() const
31478092ae7SKarsten Heimrich {
31578092ae7SKarsten Heimrich 	return BInvoker::Message();
31678092ae7SKarsten Heimrich }
31778092ae7SKarsten Heimrich 
31878092ae7SKarsten Heimrich 
31978092ae7SKarsten Heimrich void
32078092ae7SKarsten Heimrich BCalendarView::SetInvocationMessage(BMessage *message)
32178092ae7SKarsten Heimrich {
32278092ae7SKarsten Heimrich 	BInvoker::SetMessage(message);
32378092ae7SKarsten Heimrich }
32478092ae7SKarsten Heimrich 
32578092ae7SKarsten Heimrich 
32678092ae7SKarsten Heimrich void
32778092ae7SKarsten Heimrich BCalendarView::WindowActivated(bool state)
32878092ae7SKarsten Heimrich {
32978092ae7SKarsten Heimrich 	BView::WindowActivated(state);
33078092ae7SKarsten Heimrich }
33178092ae7SKarsten Heimrich 
33278092ae7SKarsten Heimrich 
33378092ae7SKarsten Heimrich void
33478092ae7SKarsten Heimrich BCalendarView::MakeFocus(bool state)
33578092ae7SKarsten Heimrich {
33678092ae7SKarsten Heimrich 	if (IsFocus() == state)
33778092ae7SKarsten Heimrich 		return;
33878092ae7SKarsten Heimrich 
33978092ae7SKarsten Heimrich 	BView::MakeFocus(state);
34078092ae7SKarsten Heimrich 
341*1b3303e7SAxel Dörfler 	// TODO: solve this better
34278092ae7SKarsten Heimrich 	fFocusChanged = true;
34378092ae7SKarsten Heimrich 	Draw(_RectOfDay(fFocusedDay));
34478092ae7SKarsten Heimrich 	fFocusChanged = false;
34578092ae7SKarsten Heimrich }
34678092ae7SKarsten Heimrich 
34778092ae7SKarsten Heimrich 
34878092ae7SKarsten Heimrich status_t
34978092ae7SKarsten Heimrich BCalendarView::Invoke(BMessage *message)
35078092ae7SKarsten Heimrich {
35178092ae7SKarsten Heimrich 	bool notify = false;
35278092ae7SKarsten Heimrich 	uint32 kind = InvokeKind(&notify);
35378092ae7SKarsten Heimrich 
35478092ae7SKarsten Heimrich 	BMessage clone(kind);
35578092ae7SKarsten Heimrich 	status_t status = B_BAD_VALUE;
35678092ae7SKarsten Heimrich 
35778092ae7SKarsten Heimrich 	if (!message && !notify)
35878092ae7SKarsten Heimrich 		message = Message();
35978092ae7SKarsten Heimrich 
36078092ae7SKarsten Heimrich 	if (!message) {
36178092ae7SKarsten Heimrich 		if (!IsWatched())
36278092ae7SKarsten Heimrich 			return status;
36378092ae7SKarsten Heimrich 	} else
36478092ae7SKarsten Heimrich 		clone = *message;
36578092ae7SKarsten Heimrich 
36678092ae7SKarsten Heimrich 	clone.AddPointer("source", this);
36778092ae7SKarsten Heimrich 	clone.AddInt64("when", (int64)system_time());
36878092ae7SKarsten Heimrich 	clone.AddMessenger("be:sender", BMessenger(this));
36978092ae7SKarsten Heimrich 
37078092ae7SKarsten Heimrich 	int32 year;
37178092ae7SKarsten Heimrich 	int32 month;
37278092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
37378092ae7SKarsten Heimrich 
37478092ae7SKarsten Heimrich 	clone.AddInt32("year", year);
37578092ae7SKarsten Heimrich 	clone.AddInt32("month", month);
37678092ae7SKarsten Heimrich 	clone.AddInt32("day", fDay);
37778092ae7SKarsten Heimrich 
37878092ae7SKarsten Heimrich 	if (message)
37978092ae7SKarsten Heimrich 		status = BInvoker::Invoke(&clone);
38078092ae7SKarsten Heimrich 
38178092ae7SKarsten Heimrich 	SendNotices(kind, &clone);
38278092ae7SKarsten Heimrich 
38378092ae7SKarsten Heimrich 	return status;
38478092ae7SKarsten Heimrich }
38578092ae7SKarsten Heimrich 
38678092ae7SKarsten Heimrich 
38778092ae7SKarsten Heimrich void
38878092ae7SKarsten Heimrich BCalendarView::MouseUp(BPoint point)
38978092ae7SKarsten Heimrich {
39078092ae7SKarsten Heimrich 	BView::MouseUp(point);
39178092ae7SKarsten Heimrich }
39278092ae7SKarsten Heimrich 
39378092ae7SKarsten Heimrich 
39478092ae7SKarsten Heimrich void
39578092ae7SKarsten Heimrich BCalendarView::MouseDown(BPoint where)
39678092ae7SKarsten Heimrich {
39778092ae7SKarsten Heimrich 	if (!IsFocus()) {
39878092ae7SKarsten Heimrich 		MakeFocus();
39978092ae7SKarsten Heimrich 		Sync();
40078092ae7SKarsten Heimrich 		Window()->UpdateIfNeeded();
40178092ae7SKarsten Heimrich 	}
40278092ae7SKarsten Heimrich 
40378092ae7SKarsten Heimrich 	BRect frame = Bounds();
40478092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
40578092ae7SKarsten Heimrich 		frame.top += frame.Height() / 7 - 1.0;
40678092ae7SKarsten Heimrich 
40778092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible)
40878092ae7SKarsten Heimrich 		frame.left += frame.Width() / 8 - 1.0;
40978092ae7SKarsten Heimrich 
41078092ae7SKarsten Heimrich 	if (!frame.Contains(where))
41178092ae7SKarsten Heimrich 		return;
41278092ae7SKarsten Heimrich 
41378092ae7SKarsten Heimrich 	// try to set to new day
41478092ae7SKarsten Heimrich 	frame = _SetNewSelectedDay(where);
41578092ae7SKarsten Heimrich 
41678092ae7SKarsten Heimrich 	// on success
41778092ae7SKarsten Heimrich 	if (fSelectedDay != fNewSelectedDay) {
41878092ae7SKarsten Heimrich 		// update focus
41978092ae7SKarsten Heimrich 		fFocusChanged = true;
42078092ae7SKarsten Heimrich 		fNewFocusedDay = fNewSelectedDay;
42178092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
42278092ae7SKarsten Heimrich 		fFocusChanged = false;
42378092ae7SKarsten Heimrich 
42478092ae7SKarsten Heimrich 		// update selection
42578092ae7SKarsten Heimrich 		fSelectionChanged = true;
42678092ae7SKarsten Heimrich 		Draw(frame);
42778092ae7SKarsten Heimrich 		Draw(_RectOfDay(fSelectedDay));
42878092ae7SKarsten Heimrich 		fSelectionChanged = false;
42978092ae7SKarsten Heimrich 
43078092ae7SKarsten Heimrich 		// notify that selection changed
43178092ae7SKarsten Heimrich 		InvokeNotify(SelectionMessage(), B_CONTROL_MODIFIED);
43278092ae7SKarsten Heimrich 	}
43378092ae7SKarsten Heimrich 
43478092ae7SKarsten Heimrich 	int32 clicks;
43578092ae7SKarsten Heimrich 	// on double click invoke
43678092ae7SKarsten Heimrich 	BMessage *message = Looper()->CurrentMessage();
43778092ae7SKarsten Heimrich 	if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1)
43878092ae7SKarsten Heimrich 		Invoke();
43978092ae7SKarsten Heimrich }
44078092ae7SKarsten Heimrich 
44178092ae7SKarsten Heimrich 
44278092ae7SKarsten Heimrich void
44378092ae7SKarsten Heimrich BCalendarView::MouseMoved(BPoint point, uint32 code, const BMessage *dragMessage)
44478092ae7SKarsten Heimrich {
44578092ae7SKarsten Heimrich 	BView::MouseMoved(point, code, dragMessage);
44678092ae7SKarsten Heimrich }
44778092ae7SKarsten Heimrich 
44878092ae7SKarsten Heimrich 
44978092ae7SKarsten Heimrich void
45078092ae7SKarsten Heimrich BCalendarView::KeyDown(const char *bytes, int32 numBytes)
45178092ae7SKarsten Heimrich {
45278092ae7SKarsten Heimrich 	const int32 kRows = 6;
45378092ae7SKarsten Heimrich 	const int32 kColumns = 7;
45478092ae7SKarsten Heimrich 
45578092ae7SKarsten Heimrich 	int32 row = fFocusedDay.row;
45678092ae7SKarsten Heimrich 	int32 column = fFocusedDay.column;
45778092ae7SKarsten Heimrich 
45878092ae7SKarsten Heimrich 	switch (bytes[0]) {
45978092ae7SKarsten Heimrich 		case B_LEFT_ARROW:
46078092ae7SKarsten Heimrich 		{
46178092ae7SKarsten Heimrich 			column -= 1;
46278092ae7SKarsten Heimrich 			if (column < 0) {
46378092ae7SKarsten Heimrich 				column = kColumns -1;
46478092ae7SKarsten Heimrich 				row -= 1;
46578092ae7SKarsten Heimrich 				if (row >= 0)
46678092ae7SKarsten Heimrich 					fFocusChanged = true;
46778092ae7SKarsten Heimrich 			} else
46878092ae7SKarsten Heimrich 				fFocusChanged = true;
46978092ae7SKarsten Heimrich 		}	break;
47078092ae7SKarsten Heimrich 
47178092ae7SKarsten Heimrich 		case B_RIGHT_ARROW:
47278092ae7SKarsten Heimrich 		{
47378092ae7SKarsten Heimrich 			column += 1;
47478092ae7SKarsten Heimrich 			if (column == kColumns) {
47578092ae7SKarsten Heimrich 				column = 0;
47678092ae7SKarsten Heimrich 				row += 1;
47778092ae7SKarsten Heimrich 				if (row < kRows)
47878092ae7SKarsten Heimrich 					fFocusChanged = true;
47978092ae7SKarsten Heimrich 			} else
48078092ae7SKarsten Heimrich 				fFocusChanged = true;
48178092ae7SKarsten Heimrich 		}	break;
48278092ae7SKarsten Heimrich 
48378092ae7SKarsten Heimrich 		case B_UP_ARROW:
48478092ae7SKarsten Heimrich 		{
48578092ae7SKarsten Heimrich 			row -= 1;
48678092ae7SKarsten Heimrich 			if (row >= 0)
48778092ae7SKarsten Heimrich 				fFocusChanged = true;
48878092ae7SKarsten Heimrich 		}	break;
48978092ae7SKarsten Heimrich 
49078092ae7SKarsten Heimrich 		case B_DOWN_ARROW:
49178092ae7SKarsten Heimrich 		{
49278092ae7SKarsten Heimrich 			row += 1;
49378092ae7SKarsten Heimrich 			if (row < kRows)
49478092ae7SKarsten Heimrich 				fFocusChanged = true;
49578092ae7SKarsten Heimrich 		}	break;
49678092ae7SKarsten Heimrich 
49778092ae7SKarsten Heimrich 		case B_RETURN:
49878092ae7SKarsten Heimrich 		case B_SPACE: {
49978092ae7SKarsten Heimrich 			fSelectionChanged = true;
50078092ae7SKarsten Heimrich 			BPoint pt = _RectOfDay(fFocusedDay).LeftTop();
50178092ae7SKarsten Heimrich 			Draw(_SetNewSelectedDay(pt + BPoint(4.0, 4.0)));
50278092ae7SKarsten Heimrich 			Draw(_RectOfDay(fSelectedDay));
50378092ae7SKarsten Heimrich 			fSelectionChanged = false;
50478092ae7SKarsten Heimrich 
50578092ae7SKarsten Heimrich 			Invoke();
50678092ae7SKarsten Heimrich 		}	break;
50778092ae7SKarsten Heimrich 
50878092ae7SKarsten Heimrich 		default:
50978092ae7SKarsten Heimrich 			BView::KeyDown(bytes, numBytes);
51078092ae7SKarsten Heimrich 			break;
51178092ae7SKarsten Heimrich 	}
51278092ae7SKarsten Heimrich 
51378092ae7SKarsten Heimrich 	if (fFocusChanged) {
51478092ae7SKarsten Heimrich 		fNewFocusedDay.SetTo(row, column);
51578092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
51678092ae7SKarsten Heimrich 		Draw(_RectOfDay(fNewFocusedDay));
51778092ae7SKarsten Heimrich 		fFocusChanged = false;
51878092ae7SKarsten Heimrich 	}
51978092ae7SKarsten Heimrich }
52078092ae7SKarsten Heimrich 
52178092ae7SKarsten Heimrich 
52278092ae7SKarsten Heimrich BHandler*
52378092ae7SKarsten Heimrich BCalendarView::ResolveSpecifier(BMessage *message, int32 index,
52478092ae7SKarsten Heimrich 	BMessage *specifier, int32 form, const char *property)
52578092ae7SKarsten Heimrich {
52678092ae7SKarsten Heimrich 	return BView::ResolveSpecifier(message, index, specifier, form, property);
52778092ae7SKarsten Heimrich }
52878092ae7SKarsten Heimrich 
52978092ae7SKarsten Heimrich 
53078092ae7SKarsten Heimrich status_t
53178092ae7SKarsten Heimrich BCalendarView::GetSupportedSuites(BMessage *data)
53278092ae7SKarsten Heimrich {
53378092ae7SKarsten Heimrich 	return BView::GetSupportedSuites(data);
53478092ae7SKarsten Heimrich }
53578092ae7SKarsten Heimrich 
53678092ae7SKarsten Heimrich 
53778092ae7SKarsten Heimrich status_t
53878092ae7SKarsten Heimrich BCalendarView::Perform(perform_code code, void *arg)
53978092ae7SKarsten Heimrich {
54078092ae7SKarsten Heimrich 	return BView::Perform(code, arg);
54178092ae7SKarsten Heimrich }
54278092ae7SKarsten Heimrich 
54378092ae7SKarsten Heimrich 
54478092ae7SKarsten Heimrich void
54578092ae7SKarsten Heimrich BCalendarView::ResizeToPreferred()
54678092ae7SKarsten Heimrich {
54778092ae7SKarsten Heimrich 	float width;
54878092ae7SKarsten Heimrich 	float height;
54978092ae7SKarsten Heimrich 
55078092ae7SKarsten Heimrich 	GetPreferredSize(&width, &height);
55178092ae7SKarsten Heimrich 	BView::ResizeTo(width, height);
55278092ae7SKarsten Heimrich }
55378092ae7SKarsten Heimrich 
55478092ae7SKarsten Heimrich 
55578092ae7SKarsten Heimrich void
55678092ae7SKarsten Heimrich BCalendarView::GetPreferredSize(float *width, float *height)
55778092ae7SKarsten Heimrich {
55878092ae7SKarsten Heimrich 	_GetPreferredSize(width, height);
55978092ae7SKarsten Heimrich }
56078092ae7SKarsten Heimrich 
56178092ae7SKarsten Heimrich 
56278092ae7SKarsten Heimrich int32
56378092ae7SKarsten Heimrich BCalendarView::Day() const
56478092ae7SKarsten Heimrich {
56578092ae7SKarsten Heimrich 	return fDay;
56678092ae7SKarsten Heimrich }
56778092ae7SKarsten Heimrich 
56878092ae7SKarsten Heimrich 
56978092ae7SKarsten Heimrich int32
57078092ae7SKarsten Heimrich BCalendarView::Year() const
57178092ae7SKarsten Heimrich {
57278092ae7SKarsten Heimrich 	int32 year;
57378092ae7SKarsten Heimrich 	int32 month;
57478092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
57578092ae7SKarsten Heimrich 
57678092ae7SKarsten Heimrich 	return year;
57778092ae7SKarsten Heimrich }
57878092ae7SKarsten Heimrich 
57978092ae7SKarsten Heimrich 
58078092ae7SKarsten Heimrich int32
58178092ae7SKarsten Heimrich BCalendarView::Month() const
58278092ae7SKarsten Heimrich {
58378092ae7SKarsten Heimrich 	int32 year;
58478092ae7SKarsten Heimrich 	int32 month;
58578092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
58678092ae7SKarsten Heimrich 
58778092ae7SKarsten Heimrich 	return month;
58878092ae7SKarsten Heimrich }
58978092ae7SKarsten Heimrich 
59078092ae7SKarsten Heimrich 
59178092ae7SKarsten Heimrich BDate
59278092ae7SKarsten Heimrich BCalendarView::Date() const
59378092ae7SKarsten Heimrich {
59478092ae7SKarsten Heimrich 	int32 year;
59578092ae7SKarsten Heimrich 	int32 month;
59678092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
59778092ae7SKarsten Heimrich 	return BDate(year, month, fDay);
59878092ae7SKarsten Heimrich }
59978092ae7SKarsten Heimrich 
60078092ae7SKarsten Heimrich 
60178092ae7SKarsten Heimrich bool
60278092ae7SKarsten Heimrich BCalendarView::SetDate(const BDate &date)
60378092ae7SKarsten Heimrich {
604c1ed5d75SKarsten Heimrich 	if (!date.IsValid())
605c1ed5d75SKarsten Heimrich 		return false;
606c1ed5d75SKarsten Heimrich 
60778092ae7SKarsten Heimrich 	return SetDate(date.Year(), date.Month(), date.Day());
60878092ae7SKarsten Heimrich }
60978092ae7SKarsten Heimrich 
61078092ae7SKarsten Heimrich 
61178092ae7SKarsten Heimrich bool
61278092ae7SKarsten Heimrich BCalendarView::SetDate(int32 year, int32 month, int32 day)
61378092ae7SKarsten Heimrich {
61478092ae7SKarsten Heimrich 	if (!BDate(year, month, day).IsValid())
61578092ae7SKarsten Heimrich 		return false;
61678092ae7SKarsten Heimrich 
61778092ae7SKarsten Heimrich 	if (fYear == year && fMonth == month && fDay == day)
61878092ae7SKarsten Heimrich 		return true;
61978092ae7SKarsten Heimrich 
62078092ae7SKarsten Heimrich 	fDay = day;
62178092ae7SKarsten Heimrich 	if (fYear == year && fMonth == month) {
62278092ae7SKarsten Heimrich 		_SetToDay();
62378092ae7SKarsten Heimrich 		// update focus
62478092ae7SKarsten Heimrich 		fFocusChanged = true;
62578092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
62678092ae7SKarsten Heimrich 		fFocusChanged = false;
62778092ae7SKarsten Heimrich 
62878092ae7SKarsten Heimrich 		// update selection
62978092ae7SKarsten Heimrich 		fSelectionChanged = true;
63078092ae7SKarsten Heimrich 		Draw(_RectOfDay(fSelectedDay));
63178092ae7SKarsten Heimrich 		Draw(_RectOfDay(fNewSelectedDay));
63278092ae7SKarsten Heimrich 		fSelectionChanged = false;
63378092ae7SKarsten Heimrich 	} else {
63478092ae7SKarsten Heimrich 		fYear = year;
63578092ae7SKarsten Heimrich 		fMonth = month;
63678092ae7SKarsten Heimrich 
63778092ae7SKarsten Heimrich 		_SetupDayNumbers();
63878092ae7SKarsten Heimrich 		_SetupWeekNumbers();
63978092ae7SKarsten Heimrich 
64078092ae7SKarsten Heimrich 		BRect frame = Bounds();
64178092ae7SKarsten Heimrich 		if (fDayNameHeaderVisible)
64278092ae7SKarsten Heimrich 			frame.top += frame.Height() / 7 - 1.0;
64378092ae7SKarsten Heimrich 
64478092ae7SKarsten Heimrich 		if (fWeekNumberHeaderVisible)
64578092ae7SKarsten Heimrich 			frame.left += frame.Width() / 8 - 1.0;
64678092ae7SKarsten Heimrich 
64778092ae7SKarsten Heimrich 		Draw(frame.InsetBySelf(4.0, 4.0));
64878092ae7SKarsten Heimrich 	}
64978092ae7SKarsten Heimrich 
65078092ae7SKarsten Heimrich 	return true;
65178092ae7SKarsten Heimrich }
65278092ae7SKarsten Heimrich 
65378092ae7SKarsten Heimrich 
65478092ae7SKarsten Heimrich week_start
65578092ae7SKarsten Heimrich BCalendarView::WeekStart() const
65678092ae7SKarsten Heimrich {
65778092ae7SKarsten Heimrich 	return fWeekStart;
65878092ae7SKarsten Heimrich }
65978092ae7SKarsten Heimrich 
66078092ae7SKarsten Heimrich 
66178092ae7SKarsten Heimrich void
66278092ae7SKarsten Heimrich BCalendarView::SetWeekStart(week_start start)
66378092ae7SKarsten Heimrich {
66478092ae7SKarsten Heimrich 	if (fWeekStart == start)
66578092ae7SKarsten Heimrich 		return;
66678092ae7SKarsten Heimrich 
66778092ae7SKarsten Heimrich 	fWeekStart = start;
66878092ae7SKarsten Heimrich 
66978092ae7SKarsten Heimrich 	_SetupDayNames();
67078092ae7SKarsten Heimrich 	_SetupDayNumbers();
67178092ae7SKarsten Heimrich 	_SetupWeekNumbers();
67278092ae7SKarsten Heimrich 
67378092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
67478092ae7SKarsten Heimrich }
67578092ae7SKarsten Heimrich 
67678092ae7SKarsten Heimrich 
67778092ae7SKarsten Heimrich bool
67878092ae7SKarsten Heimrich BCalendarView::IsDayNameHeaderVisible() const
67978092ae7SKarsten Heimrich {
68078092ae7SKarsten Heimrich 	return fDayNameHeaderVisible;
68178092ae7SKarsten Heimrich }
68278092ae7SKarsten Heimrich 
68378092ae7SKarsten Heimrich 
68478092ae7SKarsten Heimrich void
68578092ae7SKarsten Heimrich BCalendarView::SetDayNameHeaderVisible(bool visible)
68678092ae7SKarsten Heimrich {
68778092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible == visible)
68878092ae7SKarsten Heimrich 		return;
68978092ae7SKarsten Heimrich 
69078092ae7SKarsten Heimrich 	fDayNameHeaderVisible = visible;
69178092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
69278092ae7SKarsten Heimrich }
69378092ae7SKarsten Heimrich 
69478092ae7SKarsten Heimrich 
69578092ae7SKarsten Heimrich bool
69678092ae7SKarsten Heimrich BCalendarView::IsWeekNumberHeaderVisible() const
69778092ae7SKarsten Heimrich {
69878092ae7SKarsten Heimrich 	return fWeekNumberHeaderVisible;
69978092ae7SKarsten Heimrich }
70078092ae7SKarsten Heimrich 
70178092ae7SKarsten Heimrich 
70278092ae7SKarsten Heimrich void
70378092ae7SKarsten Heimrich BCalendarView::SetWeekNumberHeaderVisible(bool visible)
70478092ae7SKarsten Heimrich {
70578092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible == visible)
70678092ae7SKarsten Heimrich 		return;
70778092ae7SKarsten Heimrich 
70878092ae7SKarsten Heimrich 	fWeekNumberHeaderVisible = visible;
70978092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
71078092ae7SKarsten Heimrich }
71178092ae7SKarsten Heimrich 
71278092ae7SKarsten Heimrich 
71378092ae7SKarsten Heimrich void
71478092ae7SKarsten Heimrich BCalendarView::_InitObject()
71578092ae7SKarsten Heimrich {
71678092ae7SKarsten Heimrich 	BDate date = BDate::CurrentDate(B_LOCAL_TIME);
7179bee8e93SKarsten Heimrich 	date.GetDate(&fYear, &fMonth, &fDay);
71878092ae7SKarsten Heimrich 
71978092ae7SKarsten Heimrich 	_SetupDayNames();
72078092ae7SKarsten Heimrich 	_SetupDayNumbers();
72178092ae7SKarsten Heimrich 	_SetupWeekNumbers();
72278092ae7SKarsten Heimrich }
72378092ae7SKarsten Heimrich 
72478092ae7SKarsten Heimrich 
72578092ae7SKarsten Heimrich void
72678092ae7SKarsten Heimrich BCalendarView::_SetToDay()
72778092ae7SKarsten Heimrich {
72878092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
72978092ae7SKarsten Heimrich 	if (!date.IsValid())
73078092ae7SKarsten Heimrich 		return;
73178092ae7SKarsten Heimrich 
73278092ae7SKarsten Heimrich 	fNewFocusedDay.SetTo(0, 0);
73378092ae7SKarsten Heimrich 	fNewSelectedDay.SetTo(0, 0);
73478092ae7SKarsten Heimrich 
73578092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
73678092ae7SKarsten Heimrich 
73778092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
73878092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
73978092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
74078092ae7SKarsten Heimrich 
74178092ae7SKarsten Heimrich 	int32 counter = 0;
74278092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
74378092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
74478092ae7SKarsten Heimrich 			int32 day = counter - (firstDay - 1);
74578092ae7SKarsten Heimrich 			if (counter >= firstDay && counter <= dayCountCurrent + firstDay - 1) {
74678092ae7SKarsten Heimrich 				if (day == fDay) {
74778092ae7SKarsten Heimrich 					fNewFocusedDay.SetTo(row, column);
74878092ae7SKarsten Heimrich 					fNewSelectedDay.SetTo(row, column);
74978092ae7SKarsten Heimrich 					return;
75078092ae7SKarsten Heimrich 				}
75178092ae7SKarsten Heimrich 			}
75278092ae7SKarsten Heimrich 			counter++;
75378092ae7SKarsten Heimrich 		}
75478092ae7SKarsten Heimrich 	}
75578092ae7SKarsten Heimrich }
75678092ae7SKarsten Heimrich 
75778092ae7SKarsten Heimrich 
75878092ae7SKarsten Heimrich void
75978092ae7SKarsten Heimrich BCalendarView::_GetYearMonth(int32 *year, int32 *month) const
76078092ae7SKarsten Heimrich {
76178092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
76278092ae7SKarsten Heimrich 
76378092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
76478092ae7SKarsten Heimrich 
76578092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
76678092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
76778092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
76878092ae7SKarsten Heimrich 
76978092ae7SKarsten Heimrich 	// set the date to one month before
77078092ae7SKarsten Heimrich 	if (date.Month() == 1)
77178092ae7SKarsten Heimrich 		date.SetDate(date.Year() -1, 12, fDay);
77278092ae7SKarsten Heimrich 	else
77378092ae7SKarsten Heimrich 		date.SetDate(date.Year(), date.Month() - 1, fDay);
77478092ae7SKarsten Heimrich 
77578092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
77678092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
77778092ae7SKarsten Heimrich 
77878092ae7SKarsten Heimrich 	*year = fYear;
77978092ae7SKarsten Heimrich 	*month = fMonth;
78078092ae7SKarsten Heimrich 
78178092ae7SKarsten Heimrich 	int32 counter = 0;
78278092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
78378092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
78478092ae7SKarsten Heimrich 			if (counter < firstDay || counter > dayCountCurrent + firstDay - 1) {
78578092ae7SKarsten Heimrich 				if (counter - firstDay < 0) {
78678092ae7SKarsten Heimrich 					if (row == currRow && column == currColumn) {
78778092ae7SKarsten Heimrich 						*year = date.Year();
78878092ae7SKarsten Heimrich 						*month = date.Month();
78978092ae7SKarsten Heimrich 						break;
79078092ae7SKarsten Heimrich 					}
79178092ae7SKarsten Heimrich 				} else {
79278092ae7SKarsten Heimrich 					if (row == currRow && column == currColumn) {
79378092ae7SKarsten Heimrich 						*year = fYear;
79478092ae7SKarsten Heimrich 						*month = fMonth +1;
79578092ae7SKarsten Heimrich 						if (fMonth == 12) {
79678092ae7SKarsten Heimrich 							*year = fYear +1;
79778092ae7SKarsten Heimrich 							*month = 1;
79878092ae7SKarsten Heimrich 						}
79978092ae7SKarsten Heimrich 						break;
80078092ae7SKarsten Heimrich 					}
80178092ae7SKarsten Heimrich 				}
80278092ae7SKarsten Heimrich 			} else {
80378092ae7SKarsten Heimrich 				if (row == currRow && column == currColumn)
80478092ae7SKarsten Heimrich 					break;
80578092ae7SKarsten Heimrich 			}
80678092ae7SKarsten Heimrich 			counter++;
80778092ae7SKarsten Heimrich 		}
80878092ae7SKarsten Heimrich 	}
80978092ae7SKarsten Heimrich }
81078092ae7SKarsten Heimrich 
81178092ae7SKarsten Heimrich 
81278092ae7SKarsten Heimrich void
81378092ae7SKarsten Heimrich BCalendarView::_GetPreferredSize(float *_width, float *_height)
81478092ae7SKarsten Heimrich {
81578092ae7SKarsten Heimrich 	BFont font;
81678092ae7SKarsten Heimrich 	GetFont(&font);
81778092ae7SKarsten Heimrich 	font_height fontHeight;
81878092ae7SKarsten Heimrich 	font.GetHeight(&fontHeight);
81978092ae7SKarsten Heimrich 
82078092ae7SKarsten Heimrich 	const float height = FontHeight(this) + 4.0;
82178092ae7SKarsten Heimrich 
82278092ae7SKarsten Heimrich 	int32 rows = 7;
82378092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
82478092ae7SKarsten Heimrich 		rows = 6;
82578092ae7SKarsten Heimrich 
82678092ae7SKarsten Heimrich 	// height = font height * rows + 8 px border
82778092ae7SKarsten Heimrich 	*_height = height * rows + 8.0;
82878092ae7SKarsten Heimrich 
82978092ae7SKarsten Heimrich 	float width = 0.0;
83078092ae7SKarsten Heimrich 	for (int32 column = 0; column < 7; ++column) {
83178092ae7SKarsten Heimrich 		float tmp = StringWidth(fDayNames[column].String()) + 2.0;
83278092ae7SKarsten Heimrich 		width = tmp > width ? tmp : width;
83378092ae7SKarsten Heimrich 	}
83478092ae7SKarsten Heimrich 
83578092ae7SKarsten Heimrich 	int32 columns = 8;
83678092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
83778092ae7SKarsten Heimrich 		columns = 7;
83878092ae7SKarsten Heimrich 
83978092ae7SKarsten Heimrich 	// width = max width day name * 8 column + 8 px border
84078092ae7SKarsten Heimrich 	*_width = width * columns + 8.0;
84178092ae7SKarsten Heimrich }
84278092ae7SKarsten Heimrich 
84378092ae7SKarsten Heimrich 
84478092ae7SKarsten Heimrich void
84578092ae7SKarsten Heimrich BCalendarView::_SetupDayNames()
84678092ae7SKarsten Heimrich {
84778092ae7SKarsten Heimrich 	const BDate date(fYear, fMonth, fDay);
84878092ae7SKarsten Heimrich 	if (!date.IsValid())
84978092ae7SKarsten Heimrich 		return;
85078092ae7SKarsten Heimrich 
85178092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY) {
85278092ae7SKarsten Heimrich 		for (int32 i = 1; i <= 7; ++i) {
85378092ae7SKarsten Heimrich 			fDayNames[i -1] = date.ShortDayName(i);
85478092ae7SKarsten Heimrich 		}
85578092ae7SKarsten Heimrich 	} else {
85678092ae7SKarsten Heimrich 		fDayNames[0] = date.ShortDayName(7);
85778092ae7SKarsten Heimrich 		for (int32 i = 1; i < 7; ++i) {
85878092ae7SKarsten Heimrich 			fDayNames[i] = date.ShortDayName(i);
85978092ae7SKarsten Heimrich 		}
86078092ae7SKarsten Heimrich 	}
86178092ae7SKarsten Heimrich }
86278092ae7SKarsten Heimrich 
86378092ae7SKarsten Heimrich 
86478092ae7SKarsten Heimrich void
86578092ae7SKarsten Heimrich BCalendarView::_SetupDayNumbers()
86678092ae7SKarsten Heimrich {
86778092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
86878092ae7SKarsten Heimrich 	if (!date.IsValid())
86978092ae7SKarsten Heimrich 		return;
87078092ae7SKarsten Heimrich 
87178092ae7SKarsten Heimrich 	fFocusedDay.SetTo(0, 0);
87278092ae7SKarsten Heimrich 	fSelectedDay.SetTo(0, 0);
87378092ae7SKarsten Heimrich 	fNewFocusedDay.SetTo(0, 0);
87478092ae7SKarsten Heimrich 
87578092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
87678092ae7SKarsten Heimrich 
87778092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
87878092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
87978092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
88078092ae7SKarsten Heimrich 
88178092ae7SKarsten Heimrich 	// calc the last day one month before
88278092ae7SKarsten Heimrich 	if (date.Month() == 1)
88378092ae7SKarsten Heimrich 		date.SetDate(date.Year() -1, 12, fDay);
88478092ae7SKarsten Heimrich 	else
88578092ae7SKarsten Heimrich 		date.SetDate(date.Year(), date.Month() - 1, fDay);
88678092ae7SKarsten Heimrich 	const int32 lastDayBefore = date.DaysInMonth();
88778092ae7SKarsten Heimrich 
88878092ae7SKarsten Heimrich 	int32 counter = 0;
88978092ae7SKarsten Heimrich 	int32 firstDayAfter = 1;
89078092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
89178092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
89278092ae7SKarsten Heimrich 			int32 day = counter - (firstDay - 1);
89378092ae7SKarsten Heimrich 			if (counter < firstDay || counter > dayCountCurrent + firstDay - 1) {
89478092ae7SKarsten Heimrich 				if (counter - firstDay < 0)
89578092ae7SKarsten Heimrich 					day += lastDayBefore;
89678092ae7SKarsten Heimrich 				else
89778092ae7SKarsten Heimrich 					day = firstDayAfter++;
89878092ae7SKarsten Heimrich 			} else {
89978092ae7SKarsten Heimrich 				if (day == fDay) {
90078092ae7SKarsten Heimrich 					fFocusedDay.SetTo(row, column);
90178092ae7SKarsten Heimrich 					fSelectedDay.SetTo(row, column);
90278092ae7SKarsten Heimrich 					fNewFocusedDay.SetTo(row, column);
90378092ae7SKarsten Heimrich 				}
90478092ae7SKarsten Heimrich 			}
90578092ae7SKarsten Heimrich 			counter++;
90678092ae7SKarsten Heimrich 			fDayNumbers[row][column].SetTo("");
90778092ae7SKarsten Heimrich 			fDayNumbers[row][column] << day;
90878092ae7SKarsten Heimrich 		}
90978092ae7SKarsten Heimrich 	}
91078092ae7SKarsten Heimrich }
91178092ae7SKarsten Heimrich 
91278092ae7SKarsten Heimrich void
91378092ae7SKarsten Heimrich BCalendarView::_SetupWeekNumbers()
91478092ae7SKarsten Heimrich {
915c1ed5d75SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
91678092ae7SKarsten Heimrich 	if (!date.IsValid())
91778092ae7SKarsten Heimrich 		return;
91878092ae7SKarsten Heimrich 
919f0932941SMichael Pfeiffer 	// date on Thursday determines week number (ISO 8601)
9204352fc91SMichael Pfeiffer 	int dayOfWeek = date.DayOfWeek();
9214352fc91SMichael Pfeiffer 	// adjust weekday if Monday is week start,
9224352fc91SMichael Pfeiffer 	// then Sunday is last day in week
9234352fc91SMichael Pfeiffer 	if (fWeekStart == B_WEEK_START_MONDAY && dayOfWeek == 0)
9244352fc91SMichael Pfeiffer 			dayOfWeek = 7;
9254352fc91SMichael Pfeiffer 	date.AddDays(4 - dayOfWeek);
92678092ae7SKarsten Heimrich 
927c1ed5d75SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
92878092ae7SKarsten Heimrich 		fWeekNumbers[row].SetTo("");
929f0932941SMichael Pfeiffer 		fWeekNumbers[row] << date.WeekNumber();
930f0932941SMichael Pfeiffer 		date.AddDays(7);
931c1ed5d75SKarsten Heimrich 	}
93278092ae7SKarsten Heimrich }
93378092ae7SKarsten Heimrich 
93478092ae7SKarsten Heimrich 
93578092ae7SKarsten Heimrich void
93678092ae7SKarsten Heimrich BCalendarView::_DrawDay(int32 currRow, int32 currColumn, int32 row, int32 column,
93778092ae7SKarsten Heimrich 	int32 counter, BRect frame, const char *text, bool focus)
93878092ae7SKarsten Heimrich {
93978092ae7SKarsten Heimrich 	const BDate date(fYear, fMonth, 1);
94078092ae7SKarsten Heimrich 	const int32 daysMonth = date.DaysInMonth();
94178092ae7SKarsten Heimrich 
94278092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
94378092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
94478092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
94578092ae7SKarsten Heimrich 
94678092ae7SKarsten Heimrich 	bool enabled = true;
94778092ae7SKarsten Heimrich 	bool selected = false;
94878092ae7SKarsten Heimrich 	// check for the current date
94978092ae7SKarsten Heimrich 	if (currRow == row  && currColumn == column) {
95078092ae7SKarsten Heimrich 		selected = true;	// draw current date selected
95178092ae7SKarsten Heimrich 		if (counter <= firstDay || counter > firstDay + daysMonth) {
95278092ae7SKarsten Heimrich 			enabled = false;	// days of month before or after
95378092ae7SKarsten Heimrich 			selected = false;	// not selected but able to get focus
95478092ae7SKarsten Heimrich 		}
95578092ae7SKarsten Heimrich 	} else {
95678092ae7SKarsten Heimrich 		if (counter <= firstDay || counter > firstDay + daysMonth)
95778092ae7SKarsten Heimrich 			enabled = false;	// days of month before or after
95878092ae7SKarsten Heimrich 	}
95978092ae7SKarsten Heimrich 
96078092ae7SKarsten Heimrich 	DrawDay(this, frame, text, selected, enabled, focus);
96178092ae7SKarsten Heimrich }
96278092ae7SKarsten Heimrich 
96378092ae7SKarsten Heimrich 
96478092ae7SKarsten Heimrich void
96578092ae7SKarsten Heimrich BCalendarView::_DrawDays()
96678092ae7SKarsten Heimrich {
96778092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
96878092ae7SKarsten Heimrich 
96978092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
97078092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
97178092ae7SKarsten Heimrich 
97278092ae7SKarsten Heimrich 	const bool isFocus = IsFocus();
97378092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
97478092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
97578092ae7SKarsten Heimrich 
97678092ae7SKarsten Heimrich 	int32 counter = 0;
97778092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
97878092ae7SKarsten Heimrich 		BRect tmp = frame;
97978092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
98078092ae7SKarsten Heimrich 			counter++;
98178092ae7SKarsten Heimrich 			const char *day = fDayNumbers[row][column].String();
98278092ae7SKarsten Heimrich 			bool focus = isFocus && focusRow == row && focusColumn == column;
98378092ae7SKarsten Heimrich 			_DrawDay(currRow, currColumn, row, column, counter, tmp, day, focus);
98478092ae7SKarsten Heimrich 
98578092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
98678092ae7SKarsten Heimrich 		}
98778092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
98878092ae7SKarsten Heimrich 	}
98978092ae7SKarsten Heimrich }
99078092ae7SKarsten Heimrich 
99178092ae7SKarsten Heimrich 
99278092ae7SKarsten Heimrich void
99378092ae7SKarsten Heimrich BCalendarView::_DrawFocusRect()
99478092ae7SKarsten Heimrich {
99578092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
99678092ae7SKarsten Heimrich 
99778092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
99878092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
99978092ae7SKarsten Heimrich 
100078092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
100178092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
100278092ae7SKarsten Heimrich 
100378092ae7SKarsten Heimrich 	int32 counter = 0;
100478092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
100578092ae7SKarsten Heimrich 		BRect tmp = frame;
100678092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
100778092ae7SKarsten Heimrich 			counter++;
100878092ae7SKarsten Heimrich 			if (fNewFocusedDay.row == row && fNewFocusedDay.column == column) {
100978092ae7SKarsten Heimrich 				fFocusedDay.SetTo(row, column);
101078092ae7SKarsten Heimrich 
101178092ae7SKarsten Heimrich 				bool focus = IsFocus() && true;
101278092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
101378092ae7SKarsten Heimrich 				_DrawDay(currRow, currColumn, row, column, counter, tmp, day, focus);
101478092ae7SKarsten Heimrich 			}
101578092ae7SKarsten Heimrich 			else if (focusRow == row && focusColumn == column) {
101678092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
101778092ae7SKarsten Heimrich 				_DrawDay(currRow, currColumn, row, column, counter, tmp, day, false);
101878092ae7SKarsten Heimrich 			}
101978092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
102078092ae7SKarsten Heimrich 		}
102178092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
102278092ae7SKarsten Heimrich 	}
102378092ae7SKarsten Heimrich }
102478092ae7SKarsten Heimrich 
102578092ae7SKarsten Heimrich 
102678092ae7SKarsten Heimrich void
102778092ae7SKarsten Heimrich BCalendarView::_DrawDayHeader()
102878092ae7SKarsten Heimrich {
102978092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
103078092ae7SKarsten Heimrich 		return;
103178092ae7SKarsten Heimrich 
103278092ae7SKarsten Heimrich 	int32 offset = 1;
103378092ae7SKarsten Heimrich 	int32 columns = 8;
103478092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible) {
103578092ae7SKarsten Heimrich 		offset = 0;
103678092ae7SKarsten Heimrich 		columns = 7;
103778092ae7SKarsten Heimrich 	}
103878092ae7SKarsten Heimrich 
103978092ae7SKarsten Heimrich 	BRect frame = Bounds();
104078092ae7SKarsten Heimrich 	frame.right = frame.Width() / columns - 1.0;
104178092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / 7.0 - 2.0;
104278092ae7SKarsten Heimrich 	frame.OffsetBy(4.0, 4.0);
104378092ae7SKarsten Heimrich 
104478092ae7SKarsten Heimrich 	for (int32 i = 0; i < columns; ++i) {
104578092ae7SKarsten Heimrich 		if (i == 0 && fWeekNumberHeaderVisible) {
104678092ae7SKarsten Heimrich 			DrawDayName(this, frame, "");
104778092ae7SKarsten Heimrich 			frame.OffsetBy(frame.Width(), 0.0);
104878092ae7SKarsten Heimrich 			continue;
104978092ae7SKarsten Heimrich 		}
105078092ae7SKarsten Heimrich 		DrawDayName(this, frame, fDayNames[i - offset].String());
105178092ae7SKarsten Heimrich 		frame.OffsetBy(frame.Width(), 0.0);
105278092ae7SKarsten Heimrich 	}
105378092ae7SKarsten Heimrich }
105478092ae7SKarsten Heimrich 
105578092ae7SKarsten Heimrich 
105678092ae7SKarsten Heimrich void
105778092ae7SKarsten Heimrich BCalendarView::_DrawWeekHeader()
105878092ae7SKarsten Heimrich {
105978092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
106078092ae7SKarsten Heimrich 		return;
106178092ae7SKarsten Heimrich 
106278092ae7SKarsten Heimrich 	int32 rows = 7;
106378092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
106478092ae7SKarsten Heimrich 		rows = 6;
106578092ae7SKarsten Heimrich 
106678092ae7SKarsten Heimrich 	BRect frame = Bounds();
106778092ae7SKarsten Heimrich 	frame.right = frame.Width() / 8.0 - 2.0;
106878092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / rows - 1.0;
106978092ae7SKarsten Heimrich 
107078092ae7SKarsten Heimrich 	float offsetY = 4.0;
107178092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
107278092ae7SKarsten Heimrich 		offsetY += frame.Height();
107378092ae7SKarsten Heimrich 
107478092ae7SKarsten Heimrich 	frame.OffsetBy(4.0, offsetY);
107578092ae7SKarsten Heimrich 
107678092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
107778092ae7SKarsten Heimrich 		DrawWeekNumber(this, frame, fWeekNumbers[row].String());
107878092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
107978092ae7SKarsten Heimrich 	}
108078092ae7SKarsten Heimrich }
108178092ae7SKarsten Heimrich 
108278092ae7SKarsten Heimrich 
108378092ae7SKarsten Heimrich void
108478092ae7SKarsten Heimrich BCalendarView::_DrawItem(BView *owner, BRect frame, const char *text,
108578092ae7SKarsten Heimrich 	bool isSelected, bool isEnabled, bool focus)
108678092ae7SKarsten Heimrich {
108778092ae7SKarsten Heimrich 	rgb_color lColor = LowColor();
108878092ae7SKarsten Heimrich 	rgb_color highColor = HighColor();
108978092ae7SKarsten Heimrich 
109078092ae7SKarsten Heimrich 	rgb_color lowColor = { 255, 255, 255, 255 };
109178092ae7SKarsten Heimrich 
109278092ae7SKarsten Heimrich 	if (isSelected) {
109378092ae7SKarsten Heimrich 		SetHighColor(tint_color(lowColor, B_DARKEN_2_TINT));
109478092ae7SKarsten Heimrich 		SetLowColor(HighColor());
109578092ae7SKarsten Heimrich 	} else
109678092ae7SKarsten Heimrich 		SetHighColor(lowColor);
109778092ae7SKarsten Heimrich 
109878092ae7SKarsten Heimrich 	FillRect(frame.InsetByCopy(1.0, 1.0));
109978092ae7SKarsten Heimrich 
110078092ae7SKarsten Heimrich 	if (focus) {
110178092ae7SKarsten Heimrich 		SetHighColor(keyboard_navigation_color());
110278092ae7SKarsten Heimrich 		StrokeRect(frame.InsetByCopy(1.0, 1.0));
110378092ae7SKarsten Heimrich 	}
110478092ae7SKarsten Heimrich 
110578092ae7SKarsten Heimrich 	rgb_color black = { 0, 0, 0, 255 };
110678092ae7SKarsten Heimrich 	SetHighColor(black);
110778092ae7SKarsten Heimrich 	if (!isEnabled)
110878092ae7SKarsten Heimrich 		SetHighColor(tint_color(black, B_LIGHTEN_2_TINT));
110978092ae7SKarsten Heimrich 
111078092ae7SKarsten Heimrich 	float offsetH = frame.Width() / 2.0;
111178092ae7SKarsten Heimrich 	float offsetV = (frame.Height() / 2.0) + (FontHeight(owner) / 2.0) - 2.0;
111278092ae7SKarsten Heimrich 
111378092ae7SKarsten Heimrich 	DrawString(text, BPoint(frame.right - offsetH
111478092ae7SKarsten Heimrich 		- (StringWidth(text) / 2.0), frame.top + offsetV));
111578092ae7SKarsten Heimrich 
111678092ae7SKarsten Heimrich 	SetLowColor(lColor);
111778092ae7SKarsten Heimrich 	SetHighColor(highColor);
111878092ae7SKarsten Heimrich }
111978092ae7SKarsten Heimrich 
112078092ae7SKarsten Heimrich 
112178092ae7SKarsten Heimrich void
112278092ae7SKarsten Heimrich BCalendarView::_UpdateSelection()
112378092ae7SKarsten Heimrich {
112478092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
112578092ae7SKarsten Heimrich 
112678092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
112778092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
112878092ae7SKarsten Heimrich 
112978092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
113078092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
113178092ae7SKarsten Heimrich 
113278092ae7SKarsten Heimrich 	int32 counter = 0;
113378092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
113478092ae7SKarsten Heimrich 		BRect tmp = frame;
113578092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
113678092ae7SKarsten Heimrich 			counter++;
113778092ae7SKarsten Heimrich 			if (fNewSelectedDay.row == row && fNewSelectedDay.column == column) {
113878092ae7SKarsten Heimrich 				fSelectedDay.SetTo(row, column);
113978092ae7SKarsten Heimrich 
114078092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
114178092ae7SKarsten Heimrich 				bool focus = IsFocus() && focusRow == row && focusColumn == column;
114278092ae7SKarsten Heimrich 				_DrawDay(row, column, row, column, counter, tmp, day, focus);
114378092ae7SKarsten Heimrich 			}
114478092ae7SKarsten Heimrich 			else if (currRow == row && currColumn == column) {
114578092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
114678092ae7SKarsten Heimrich 				bool focus = IsFocus() && focusRow == row && focusColumn == column;
114778092ae7SKarsten Heimrich 				_DrawDay(currRow, currColumn, -1, -1, counter, tmp, day, focus);
114878092ae7SKarsten Heimrich 			}
114978092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
115078092ae7SKarsten Heimrich 		}
115178092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
115278092ae7SKarsten Heimrich 	}
115378092ae7SKarsten Heimrich }
115478092ae7SKarsten Heimrich 
115578092ae7SKarsten Heimrich 
115678092ae7SKarsten Heimrich BRect
115778092ae7SKarsten Heimrich BCalendarView::_FirstCalendarItemFrame() const
115878092ae7SKarsten Heimrich {
115978092ae7SKarsten Heimrich 	int32 rows = 7;
116078092ae7SKarsten Heimrich 	int32 columns = 8;
116178092ae7SKarsten Heimrich 
116278092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
116378092ae7SKarsten Heimrich 		rows = 6;
116478092ae7SKarsten Heimrich 
116578092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
116678092ae7SKarsten Heimrich 		columns = 7;
116778092ae7SKarsten Heimrich 
116878092ae7SKarsten Heimrich 	BRect frame = Bounds();
116978092ae7SKarsten Heimrich 	frame.right = frame.Width() / columns - 1.0;
117078092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / rows - 1.0;
117178092ae7SKarsten Heimrich 
117278092ae7SKarsten Heimrich 	float offsetY = 4.0;
117378092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
117478092ae7SKarsten Heimrich 		offsetY += frame.Height();
117578092ae7SKarsten Heimrich 
117678092ae7SKarsten Heimrich 	float offsetX = 4.0;
117778092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible)
117878092ae7SKarsten Heimrich 		offsetX += frame.Width();
117978092ae7SKarsten Heimrich 
118078092ae7SKarsten Heimrich 	return frame.OffsetBySelf(offsetX, offsetY);
118178092ae7SKarsten Heimrich }
118278092ae7SKarsten Heimrich 
118378092ae7SKarsten Heimrich 
118478092ae7SKarsten Heimrich BRect
118578092ae7SKarsten Heimrich BCalendarView::_SetNewSelectedDay(const BPoint &where)
118678092ae7SKarsten Heimrich {
118778092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
118878092ae7SKarsten Heimrich 
118978092ae7SKarsten Heimrich 	int32 counter = 0;
119078092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
119178092ae7SKarsten Heimrich 		BRect tmp = frame;
119278092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
119378092ae7SKarsten Heimrich 			counter++;
119478092ae7SKarsten Heimrich 			if (tmp.Contains(where)) {
119578092ae7SKarsten Heimrich 				fNewSelectedDay.SetTo(row, column);
119678092ae7SKarsten Heimrich 				fDay = atoi(fDayNumbers[row][column].String());
119778092ae7SKarsten Heimrich 				return tmp;
119878092ae7SKarsten Heimrich 			}
119978092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
120078092ae7SKarsten Heimrich 		}
120178092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
120278092ae7SKarsten Heimrich 	}
120378092ae7SKarsten Heimrich 
120478092ae7SKarsten Heimrich 	return frame;
120578092ae7SKarsten Heimrich }
120678092ae7SKarsten Heimrich 
120778092ae7SKarsten Heimrich 
120878092ae7SKarsten Heimrich BRect
120978092ae7SKarsten Heimrich BCalendarView::_RectOfDay(const Selection &selection) const
121078092ae7SKarsten Heimrich {
121178092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
121278092ae7SKarsten Heimrich 
121378092ae7SKarsten Heimrich 	int32 counter = 0;
121478092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
121578092ae7SKarsten Heimrich 		BRect tmp = frame;
121678092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
121778092ae7SKarsten Heimrich 			counter++;
121878092ae7SKarsten Heimrich 			if (selection.row == row && selection.column == column) {
121978092ae7SKarsten Heimrich 				return tmp;
122078092ae7SKarsten Heimrich 			}
122178092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
122278092ae7SKarsten Heimrich 		}
122378092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
122478092ae7SKarsten Heimrich 	}
122578092ae7SKarsten Heimrich 
122678092ae7SKarsten Heimrich 	return frame;
122778092ae7SKarsten Heimrich }
122878092ae7SKarsten Heimrich 
122978092ae7SKarsten Heimrich 
123078092ae7SKarsten Heimrich }	// namespace BPrivate
1231