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