xref: /haiku/src/kits/shared/CalendarView.cpp (revision 78092ae789179f1b5199224109b17898f68a9f9a)
1*78092ae7SKarsten Heimrich /*
2*78092ae7SKarsten Heimrich  * Copyright 2007-2008, Haiku, Inc. All Rights Reserved.
3*78092ae7SKarsten Heimrich  * Distributed under the terms of the MIT License.
4*78092ae7SKarsten Heimrich  *
5*78092ae7SKarsten Heimrich  * Authors:
6*78092ae7SKarsten Heimrich  *		Julun <host.haiku@gmx.de>
7*78092ae7SKarsten Heimrich  */
8*78092ae7SKarsten Heimrich 
9*78092ae7SKarsten Heimrich #include "CalendarView.h"
10*78092ae7SKarsten Heimrich 
11*78092ae7SKarsten Heimrich 
12*78092ae7SKarsten Heimrich #include <Window.h>
13*78092ae7SKarsten Heimrich 
14*78092ae7SKarsten Heimrich 
15*78092ae7SKarsten Heimrich #include <stdlib.h>
16*78092ae7SKarsten Heimrich 
17*78092ae7SKarsten Heimrich 
18*78092ae7SKarsten Heimrich namespace BPrivate {
19*78092ae7SKarsten Heimrich 
20*78092ae7SKarsten Heimrich 
21*78092ae7SKarsten Heimrich namespace {
22*78092ae7SKarsten Heimrich 	float
23*78092ae7SKarsten Heimrich 	FontHeight(const BView *view)
24*78092ae7SKarsten Heimrich 	{
25*78092ae7SKarsten Heimrich 		if (!view)
26*78092ae7SKarsten Heimrich 			return 0.0;
27*78092ae7SKarsten Heimrich 
28*78092ae7SKarsten Heimrich 		BFont font;
29*78092ae7SKarsten Heimrich 		view->GetFont(&font);
30*78092ae7SKarsten Heimrich 		font_height fheight;
31*78092ae7SKarsten Heimrich 		font.GetHeight(&fheight);
32*78092ae7SKarsten Heimrich 		return ceilf(fheight.ascent + fheight.descent + fheight.leading);
33*78092ae7SKarsten Heimrich 	}
34*78092ae7SKarsten Heimrich }
35*78092ae7SKarsten Heimrich 
36*78092ae7SKarsten Heimrich 
37*78092ae7SKarsten Heimrich BCalendarView::BCalendarView(BRect frame, const char *name,
38*78092ae7SKarsten Heimrich 		uint32 resizeMask, uint32 flags)
39*78092ae7SKarsten Heimrich 	: BView(frame, name, resizeMask, flags),
40*78092ae7SKarsten Heimrich 	  BInvoker(),
41*78092ae7SKarsten Heimrich 	  fSelectionMessage(NULL),
42*78092ae7SKarsten Heimrich 	  fDay(0),
43*78092ae7SKarsten Heimrich 	  fYear(0),
44*78092ae7SKarsten Heimrich 	  fMonth(0),
45*78092ae7SKarsten Heimrich 	  fFocusChanged(false),
46*78092ae7SKarsten Heimrich 	  fSelectionChanged(false),
47*78092ae7SKarsten Heimrich 	  fWeekStart(B_WEEK_START_SUNDAY),
48*78092ae7SKarsten Heimrich 	  fDayNameHeaderVisible(true),
49*78092ae7SKarsten Heimrich 	  fWeekNumberHeaderVisible(true)
50*78092ae7SKarsten Heimrich {
51*78092ae7SKarsten Heimrich 	_InitObject();
52*78092ae7SKarsten Heimrich }
53*78092ae7SKarsten Heimrich 
54*78092ae7SKarsten Heimrich 
55*78092ae7SKarsten Heimrich BCalendarView::BCalendarView(BRect frame, const char *name, week_start start,
56*78092ae7SKarsten Heimrich 		uint32 resizeMask, uint32 flags)
57*78092ae7SKarsten Heimrich 	: BView(frame, name, resizeMask, flags),
58*78092ae7SKarsten Heimrich 	  BInvoker(),
59*78092ae7SKarsten Heimrich 	  fSelectionMessage(NULL),
60*78092ae7SKarsten Heimrich 	  fDay(0),
61*78092ae7SKarsten Heimrich 	  fYear(0),
62*78092ae7SKarsten Heimrich 	  fMonth(0),
63*78092ae7SKarsten Heimrich 	  fFocusChanged(false),
64*78092ae7SKarsten Heimrich 	  fSelectionChanged(false),
65*78092ae7SKarsten Heimrich 	  fWeekStart(start),
66*78092ae7SKarsten Heimrich 	  fDayNameHeaderVisible(true),
67*78092ae7SKarsten Heimrich 	  fWeekNumberHeaderVisible(true)
68*78092ae7SKarsten Heimrich {
69*78092ae7SKarsten Heimrich 	_InitObject();
70*78092ae7SKarsten Heimrich }
71*78092ae7SKarsten Heimrich 
72*78092ae7SKarsten Heimrich 
73*78092ae7SKarsten Heimrich BCalendarView::~BCalendarView()
74*78092ae7SKarsten Heimrich {
75*78092ae7SKarsten Heimrich 	SetSelectionMessage(NULL);
76*78092ae7SKarsten Heimrich }
77*78092ae7SKarsten Heimrich 
78*78092ae7SKarsten Heimrich 
79*78092ae7SKarsten Heimrich BCalendarView::BCalendarView(BMessage *archive)
80*78092ae7SKarsten Heimrich 	: BView(archive),
81*78092ae7SKarsten Heimrich 	  BInvoker(),
82*78092ae7SKarsten Heimrich 	  fSelectionMessage(NULL),
83*78092ae7SKarsten Heimrich 	  fDay(0),
84*78092ae7SKarsten Heimrich 	  fYear(0),
85*78092ae7SKarsten Heimrich 	  fMonth(0),
86*78092ae7SKarsten Heimrich 	  fFocusChanged(false),
87*78092ae7SKarsten Heimrich 	  fSelectionChanged(false),
88*78092ae7SKarsten Heimrich 	  fWeekStart(B_WEEK_START_SUNDAY),
89*78092ae7SKarsten Heimrich 	  fDayNameHeaderVisible(true),
90*78092ae7SKarsten Heimrich 	  fWeekNumberHeaderVisible(true)
91*78092ae7SKarsten Heimrich {
92*78092ae7SKarsten Heimrich 	if (archive->HasMessage("_invokeMsg")) {
93*78092ae7SKarsten Heimrich 		BMessage *invokationMessage = new BMessage;
94*78092ae7SKarsten Heimrich 		archive->FindMessage("_invokeMsg", invokationMessage);
95*78092ae7SKarsten Heimrich 		SetInvocationMessage(invokationMessage);
96*78092ae7SKarsten Heimrich 	}
97*78092ae7SKarsten Heimrich 
98*78092ae7SKarsten Heimrich 	if (archive->HasMessage("_selectMsg")) {
99*78092ae7SKarsten Heimrich 		BMessage *selectionMessage = new BMessage;
100*78092ae7SKarsten Heimrich 		archive->FindMessage("selectMsg", selectionMessage);
101*78092ae7SKarsten Heimrich 		SetSelectionMessage(selectionMessage);
102*78092ae7SKarsten Heimrich 	}
103*78092ae7SKarsten Heimrich 
104*78092ae7SKarsten Heimrich 	if (archive->FindInt32("_day", &fDay) != B_OK
105*78092ae7SKarsten Heimrich 		|| archive->FindInt32("_month", &fMonth) != B_OK
106*78092ae7SKarsten Heimrich 		|| archive->FindInt32("_year", &fYear) != B_OK) {
107*78092ae7SKarsten Heimrich 			BDate date = BDate::CurrentDate(B_LOCAL_TIME);
108*78092ae7SKarsten Heimrich 			fDay = date.Day();
109*78092ae7SKarsten Heimrich 			fMonth = date.Month();
110*78092ae7SKarsten Heimrich 			fYear = date.Year();
111*78092ae7SKarsten Heimrich 	}
112*78092ae7SKarsten Heimrich 
113*78092ae7SKarsten Heimrich 	int32 start;
114*78092ae7SKarsten Heimrich 	if (archive->FindInt32("_weekStart", &start) == B_OK)
115*78092ae7SKarsten Heimrich 		fWeekStart = week_start(start);
116*78092ae7SKarsten Heimrich 
117*78092ae7SKarsten Heimrich 	if (archive->FindBool("_dayHeader", &fDayNameHeaderVisible) != B_OK)
118*78092ae7SKarsten Heimrich 		fDayNameHeaderVisible = true;
119*78092ae7SKarsten Heimrich 
120*78092ae7SKarsten Heimrich 	if (archive->FindBool("_weekHeader", &fWeekNumberHeaderVisible) != B_OK)
121*78092ae7SKarsten Heimrich 		fWeekNumberHeaderVisible = true;
122*78092ae7SKarsten Heimrich 
123*78092ae7SKarsten Heimrich 	_SetupDayNames();
124*78092ae7SKarsten Heimrich 	_SetupDayNumbers();
125*78092ae7SKarsten Heimrich 	_SetupWeekNumbers();
126*78092ae7SKarsten Heimrich }
127*78092ae7SKarsten Heimrich 
128*78092ae7SKarsten Heimrich 
129*78092ae7SKarsten Heimrich BArchivable*
130*78092ae7SKarsten Heimrich BCalendarView::Instantiate(BMessage *archive)
131*78092ae7SKarsten Heimrich {
132*78092ae7SKarsten Heimrich 	if (validate_instantiation(archive, "BCalendarView"))
133*78092ae7SKarsten Heimrich 		return new BCalendarView(archive);
134*78092ae7SKarsten Heimrich 
135*78092ae7SKarsten Heimrich 	return NULL;
136*78092ae7SKarsten Heimrich }
137*78092ae7SKarsten Heimrich 
138*78092ae7SKarsten Heimrich 
139*78092ae7SKarsten Heimrich status_t
140*78092ae7SKarsten Heimrich BCalendarView::Archive(BMessage *archive, bool deep) const
141*78092ae7SKarsten Heimrich {
142*78092ae7SKarsten Heimrich 	status_t status = BView::Archive(archive, deep);
143*78092ae7SKarsten Heimrich 
144*78092ae7SKarsten Heimrich 	if (status == B_OK && InvocationMessage())
145*78092ae7SKarsten Heimrich 		status = archive->AddMessage("_invokeMsg", InvocationMessage());
146*78092ae7SKarsten Heimrich 
147*78092ae7SKarsten Heimrich 	if (status == B_OK && SelectionMessage())
148*78092ae7SKarsten Heimrich 		status = archive->AddMessage("_selectMsg", SelectionMessage());
149*78092ae7SKarsten Heimrich 
150*78092ae7SKarsten Heimrich 	if (status == B_OK)
151*78092ae7SKarsten Heimrich 		status = archive->AddInt32("_day", fDay);
152*78092ae7SKarsten Heimrich 
153*78092ae7SKarsten Heimrich 	if (status == B_OK)
154*78092ae7SKarsten Heimrich 		status = archive->AddInt32("_month", fMonth);
155*78092ae7SKarsten Heimrich 
156*78092ae7SKarsten Heimrich 	if (status == B_OK)
157*78092ae7SKarsten Heimrich 		status = archive->AddInt32("_year", fYear);
158*78092ae7SKarsten Heimrich 
159*78092ae7SKarsten Heimrich 	if (status == B_OK)
160*78092ae7SKarsten Heimrich 		status = archive->AddInt32("_weekStart", int32(fWeekStart));
161*78092ae7SKarsten Heimrich 
162*78092ae7SKarsten Heimrich 	if (status == B_OK)
163*78092ae7SKarsten Heimrich 		status = archive->AddBool("_dayHeader", fDayNameHeaderVisible);
164*78092ae7SKarsten Heimrich 
165*78092ae7SKarsten Heimrich 	if (status == B_OK)
166*78092ae7SKarsten Heimrich 		status = archive->AddBool("_weekHeader", fWeekNumberHeaderVisible);
167*78092ae7SKarsten Heimrich 
168*78092ae7SKarsten Heimrich 	return status;
169*78092ae7SKarsten Heimrich }
170*78092ae7SKarsten Heimrich 
171*78092ae7SKarsten Heimrich 
172*78092ae7SKarsten Heimrich void
173*78092ae7SKarsten Heimrich BCalendarView::AttachedToWindow()
174*78092ae7SKarsten Heimrich {
175*78092ae7SKarsten Heimrich 	BView::AttachedToWindow();
176*78092ae7SKarsten Heimrich 
177*78092ae7SKarsten Heimrich 	if (!Messenger().IsValid())
178*78092ae7SKarsten Heimrich 		SetTarget(Window(), NULL);
179*78092ae7SKarsten Heimrich }
180*78092ae7SKarsten Heimrich 
181*78092ae7SKarsten Heimrich 
182*78092ae7SKarsten Heimrich void
183*78092ae7SKarsten Heimrich BCalendarView::DetachedFromWindow()
184*78092ae7SKarsten Heimrich {
185*78092ae7SKarsten Heimrich 	BView::DetachedFromWindow();
186*78092ae7SKarsten Heimrich }
187*78092ae7SKarsten Heimrich 
188*78092ae7SKarsten Heimrich 
189*78092ae7SKarsten Heimrich void
190*78092ae7SKarsten Heimrich BCalendarView::AllAttached()
191*78092ae7SKarsten Heimrich {
192*78092ae7SKarsten Heimrich 	BView::AllAttached();
193*78092ae7SKarsten Heimrich }
194*78092ae7SKarsten Heimrich 
195*78092ae7SKarsten Heimrich 
196*78092ae7SKarsten Heimrich void
197*78092ae7SKarsten Heimrich BCalendarView::AllDetached()
198*78092ae7SKarsten Heimrich {
199*78092ae7SKarsten Heimrich 	BView::AllDetached();
200*78092ae7SKarsten Heimrich }
201*78092ae7SKarsten Heimrich 
202*78092ae7SKarsten Heimrich 
203*78092ae7SKarsten Heimrich void
204*78092ae7SKarsten Heimrich BCalendarView::FrameMoved(BPoint newPosition)
205*78092ae7SKarsten Heimrich {
206*78092ae7SKarsten Heimrich 	BView::FrameMoved(newPosition);
207*78092ae7SKarsten Heimrich }
208*78092ae7SKarsten Heimrich 
209*78092ae7SKarsten Heimrich 
210*78092ae7SKarsten Heimrich void
211*78092ae7SKarsten Heimrich BCalendarView::FrameResized(float width, float height)
212*78092ae7SKarsten Heimrich {
213*78092ae7SKarsten Heimrich 	Invalidate(Bounds());
214*78092ae7SKarsten Heimrich }
215*78092ae7SKarsten Heimrich 
216*78092ae7SKarsten Heimrich 
217*78092ae7SKarsten Heimrich void
218*78092ae7SKarsten Heimrich BCalendarView::Draw(BRect updateRect)
219*78092ae7SKarsten Heimrich {
220*78092ae7SKarsten Heimrich 	if (LockLooper()) {
221*78092ae7SKarsten Heimrich 		if (fFocusChanged) {
222*78092ae7SKarsten Heimrich 			_DrawFocusRect();
223*78092ae7SKarsten Heimrich 			UnlockLooper();
224*78092ae7SKarsten Heimrich 			return;
225*78092ae7SKarsten Heimrich 		}
226*78092ae7SKarsten Heimrich 
227*78092ae7SKarsten Heimrich 		if (fSelectionChanged) {
228*78092ae7SKarsten Heimrich 			_UpdateSelection();
229*78092ae7SKarsten Heimrich 			UnlockLooper();
230*78092ae7SKarsten Heimrich 			return;
231*78092ae7SKarsten Heimrich 		}
232*78092ae7SKarsten Heimrich 
233*78092ae7SKarsten Heimrich 		_DrawDays();
234*78092ae7SKarsten Heimrich 		_DrawDayHeader();
235*78092ae7SKarsten Heimrich 		_DrawWeekHeader();
236*78092ae7SKarsten Heimrich 
237*78092ae7SKarsten Heimrich 		rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
238*78092ae7SKarsten Heimrich 		SetHighColor(tint_color(background, B_DARKEN_3_TINT));
239*78092ae7SKarsten Heimrich 		StrokeRect(Bounds());
240*78092ae7SKarsten Heimrich 
241*78092ae7SKarsten Heimrich 		UnlockLooper();
242*78092ae7SKarsten Heimrich 	}
243*78092ae7SKarsten Heimrich }
244*78092ae7SKarsten Heimrich 
245*78092ae7SKarsten Heimrich 
246*78092ae7SKarsten Heimrich void
247*78092ae7SKarsten Heimrich BCalendarView::DrawDay(BView *owner, BRect frame, const char *text,
248*78092ae7SKarsten Heimrich 	bool isSelected, bool isEnabled, bool focus)
249*78092ae7SKarsten Heimrich {
250*78092ae7SKarsten Heimrich 	_DrawItem(owner, frame, text, isSelected, isEnabled, focus);
251*78092ae7SKarsten Heimrich }
252*78092ae7SKarsten Heimrich 
253*78092ae7SKarsten Heimrich 
254*78092ae7SKarsten Heimrich void
255*78092ae7SKarsten Heimrich BCalendarView::DrawDayName(BView *owner, BRect frame, const char *text)
256*78092ae7SKarsten Heimrich {
257*78092ae7SKarsten Heimrich 	// we get the full rect, fake this as the internal function
258*78092ae7SKarsten Heimrich 	// shrinks the frame to work properly when drawing a day item
259*78092ae7SKarsten Heimrich 	_DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true);
260*78092ae7SKarsten Heimrich }
261*78092ae7SKarsten Heimrich 
262*78092ae7SKarsten Heimrich 
263*78092ae7SKarsten Heimrich void
264*78092ae7SKarsten Heimrich BCalendarView::DrawWeekNumber(BView *owner, BRect frame, const char *text)
265*78092ae7SKarsten Heimrich {
266*78092ae7SKarsten Heimrich 	// we get the full rect, fake this as the internal function
267*78092ae7SKarsten Heimrich 	// shrinks the frame to work properly when drawing a day item
268*78092ae7SKarsten Heimrich 	_DrawItem(owner, frame.InsetByCopy(-1.0, -1.0), text, true);
269*78092ae7SKarsten Heimrich }
270*78092ae7SKarsten Heimrich 
271*78092ae7SKarsten Heimrich 
272*78092ae7SKarsten Heimrich void
273*78092ae7SKarsten Heimrich BCalendarView::MessageReceived(BMessage *message)
274*78092ae7SKarsten Heimrich {
275*78092ae7SKarsten Heimrich 	BView::MessageReceived(message);
276*78092ae7SKarsten Heimrich }
277*78092ae7SKarsten Heimrich 
278*78092ae7SKarsten Heimrich 
279*78092ae7SKarsten Heimrich uint32
280*78092ae7SKarsten Heimrich BCalendarView::SelectionCommand() const
281*78092ae7SKarsten Heimrich {
282*78092ae7SKarsten Heimrich 	if (SelectionMessage())
283*78092ae7SKarsten Heimrich 		return SelectionMessage()->what;
284*78092ae7SKarsten Heimrich 
285*78092ae7SKarsten Heimrich 	return 0;
286*78092ae7SKarsten Heimrich }
287*78092ae7SKarsten Heimrich 
288*78092ae7SKarsten Heimrich 
289*78092ae7SKarsten Heimrich BMessage*
290*78092ae7SKarsten Heimrich BCalendarView::SelectionMessage() const
291*78092ae7SKarsten Heimrich {
292*78092ae7SKarsten Heimrich 	return fSelectionMessage;
293*78092ae7SKarsten Heimrich }
294*78092ae7SKarsten Heimrich 
295*78092ae7SKarsten Heimrich 
296*78092ae7SKarsten Heimrich void
297*78092ae7SKarsten Heimrich BCalendarView::SetSelectionMessage(BMessage *message)
298*78092ae7SKarsten Heimrich {
299*78092ae7SKarsten Heimrich 	delete fSelectionMessage;
300*78092ae7SKarsten Heimrich 	fSelectionMessage = message;
301*78092ae7SKarsten Heimrich }
302*78092ae7SKarsten Heimrich 
303*78092ae7SKarsten Heimrich 
304*78092ae7SKarsten Heimrich uint32
305*78092ae7SKarsten Heimrich BCalendarView::InvocationCommand() const
306*78092ae7SKarsten Heimrich {
307*78092ae7SKarsten Heimrich 	return BInvoker::Command();
308*78092ae7SKarsten Heimrich }
309*78092ae7SKarsten Heimrich 
310*78092ae7SKarsten Heimrich 
311*78092ae7SKarsten Heimrich BMessage*
312*78092ae7SKarsten Heimrich BCalendarView::InvocationMessage() const
313*78092ae7SKarsten Heimrich {
314*78092ae7SKarsten Heimrich 	return BInvoker::Message();
315*78092ae7SKarsten Heimrich }
316*78092ae7SKarsten Heimrich 
317*78092ae7SKarsten Heimrich 
318*78092ae7SKarsten Heimrich void
319*78092ae7SKarsten Heimrich BCalendarView::SetInvocationMessage(BMessage *message)
320*78092ae7SKarsten Heimrich {
321*78092ae7SKarsten Heimrich 	BInvoker::SetMessage(message);
322*78092ae7SKarsten Heimrich }
323*78092ae7SKarsten Heimrich 
324*78092ae7SKarsten Heimrich 
325*78092ae7SKarsten Heimrich void
326*78092ae7SKarsten Heimrich BCalendarView::WindowActivated(bool state)
327*78092ae7SKarsten Heimrich {
328*78092ae7SKarsten Heimrich 	BView::WindowActivated(state);
329*78092ae7SKarsten Heimrich }
330*78092ae7SKarsten Heimrich 
331*78092ae7SKarsten Heimrich 
332*78092ae7SKarsten Heimrich void
333*78092ae7SKarsten Heimrich BCalendarView::MakeFocus(bool state)
334*78092ae7SKarsten Heimrich {
335*78092ae7SKarsten Heimrich 	if (IsFocus() == state)
336*78092ae7SKarsten Heimrich 		return;
337*78092ae7SKarsten Heimrich 
338*78092ae7SKarsten Heimrich 	BView::MakeFocus(state);
339*78092ae7SKarsten Heimrich 
340*78092ae7SKarsten Heimrich 	fFocusChanged = true;
341*78092ae7SKarsten Heimrich 	Draw(_RectOfDay(fFocusedDay));
342*78092ae7SKarsten Heimrich 	fFocusChanged = false;
343*78092ae7SKarsten Heimrich }
344*78092ae7SKarsten Heimrich 
345*78092ae7SKarsten Heimrich 
346*78092ae7SKarsten Heimrich status_t
347*78092ae7SKarsten Heimrich BCalendarView::Invoke(BMessage *message)
348*78092ae7SKarsten Heimrich {
349*78092ae7SKarsten Heimrich 	bool notify = false;
350*78092ae7SKarsten Heimrich 	uint32 kind = InvokeKind(&notify);
351*78092ae7SKarsten Heimrich 
352*78092ae7SKarsten Heimrich 	BMessage clone(kind);
353*78092ae7SKarsten Heimrich 	status_t status = B_BAD_VALUE;
354*78092ae7SKarsten Heimrich 
355*78092ae7SKarsten Heimrich 	if (!message && !notify)
356*78092ae7SKarsten Heimrich 		message = Message();
357*78092ae7SKarsten Heimrich 
358*78092ae7SKarsten Heimrich 	if (!message) {
359*78092ae7SKarsten Heimrich 		if (!IsWatched())
360*78092ae7SKarsten Heimrich 			return status;
361*78092ae7SKarsten Heimrich 	} else
362*78092ae7SKarsten Heimrich 		clone = *message;
363*78092ae7SKarsten Heimrich 
364*78092ae7SKarsten Heimrich 	clone.AddPointer("source", this);
365*78092ae7SKarsten Heimrich 	clone.AddInt64("when", (int64)system_time());
366*78092ae7SKarsten Heimrich 	clone.AddMessenger("be:sender", BMessenger(this));
367*78092ae7SKarsten Heimrich 
368*78092ae7SKarsten Heimrich 	int32 year;
369*78092ae7SKarsten Heimrich 	int32 month;
370*78092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
371*78092ae7SKarsten Heimrich 
372*78092ae7SKarsten Heimrich 	clone.AddInt32("year", year);
373*78092ae7SKarsten Heimrich 	clone.AddInt32("month", month);
374*78092ae7SKarsten Heimrich 	clone.AddInt32("day", fDay);
375*78092ae7SKarsten Heimrich 
376*78092ae7SKarsten Heimrich 	if (message)
377*78092ae7SKarsten Heimrich 		status = BInvoker::Invoke(&clone);
378*78092ae7SKarsten Heimrich 
379*78092ae7SKarsten Heimrich 	SendNotices(kind, &clone);
380*78092ae7SKarsten Heimrich 
381*78092ae7SKarsten Heimrich 	return status;
382*78092ae7SKarsten Heimrich }
383*78092ae7SKarsten Heimrich 
384*78092ae7SKarsten Heimrich 
385*78092ae7SKarsten Heimrich void
386*78092ae7SKarsten Heimrich BCalendarView::MouseUp(BPoint point)
387*78092ae7SKarsten Heimrich {
388*78092ae7SKarsten Heimrich 	BView::MouseUp(point);
389*78092ae7SKarsten Heimrich }
390*78092ae7SKarsten Heimrich 
391*78092ae7SKarsten Heimrich 
392*78092ae7SKarsten Heimrich void
393*78092ae7SKarsten Heimrich BCalendarView::MouseDown(BPoint where)
394*78092ae7SKarsten Heimrich {
395*78092ae7SKarsten Heimrich 	if (!IsFocus()) {
396*78092ae7SKarsten Heimrich 		MakeFocus();
397*78092ae7SKarsten Heimrich 		Sync();
398*78092ae7SKarsten Heimrich 		Window()->UpdateIfNeeded();
399*78092ae7SKarsten Heimrich 	}
400*78092ae7SKarsten Heimrich 
401*78092ae7SKarsten Heimrich 	BRect frame = Bounds();
402*78092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
403*78092ae7SKarsten Heimrich 		frame.top += frame.Height() / 7 - 1.0;
404*78092ae7SKarsten Heimrich 
405*78092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible)
406*78092ae7SKarsten Heimrich 		frame.left += frame.Width() / 8 - 1.0;
407*78092ae7SKarsten Heimrich 
408*78092ae7SKarsten Heimrich 	if (!frame.Contains(where))
409*78092ae7SKarsten Heimrich 		return;
410*78092ae7SKarsten Heimrich 
411*78092ae7SKarsten Heimrich 	// try to set to new day
412*78092ae7SKarsten Heimrich 	frame = _SetNewSelectedDay(where);
413*78092ae7SKarsten Heimrich 
414*78092ae7SKarsten Heimrich 	// on success
415*78092ae7SKarsten Heimrich 	if (fSelectedDay != fNewSelectedDay) {
416*78092ae7SKarsten Heimrich 		// update focus
417*78092ae7SKarsten Heimrich 		fFocusChanged = true;
418*78092ae7SKarsten Heimrich 		fNewFocusedDay = fNewSelectedDay;
419*78092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
420*78092ae7SKarsten Heimrich 		fFocusChanged = false;
421*78092ae7SKarsten Heimrich 
422*78092ae7SKarsten Heimrich 		// update selection
423*78092ae7SKarsten Heimrich 		fSelectionChanged = true;
424*78092ae7SKarsten Heimrich 		Draw(frame);
425*78092ae7SKarsten Heimrich 		Draw(_RectOfDay(fSelectedDay));
426*78092ae7SKarsten Heimrich 		fSelectionChanged = false;
427*78092ae7SKarsten Heimrich 
428*78092ae7SKarsten Heimrich 		// notify that selection changed
429*78092ae7SKarsten Heimrich 		InvokeNotify(SelectionMessage(), B_CONTROL_MODIFIED);
430*78092ae7SKarsten Heimrich 	}
431*78092ae7SKarsten Heimrich 
432*78092ae7SKarsten Heimrich 	int32 clicks;
433*78092ae7SKarsten Heimrich 	// on double click invoke
434*78092ae7SKarsten Heimrich 	BMessage *message = Looper()->CurrentMessage();
435*78092ae7SKarsten Heimrich 	if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1)
436*78092ae7SKarsten Heimrich 		Invoke();
437*78092ae7SKarsten Heimrich }
438*78092ae7SKarsten Heimrich 
439*78092ae7SKarsten Heimrich 
440*78092ae7SKarsten Heimrich void
441*78092ae7SKarsten Heimrich BCalendarView::MouseMoved(BPoint point, uint32 code, const BMessage *dragMessage)
442*78092ae7SKarsten Heimrich {
443*78092ae7SKarsten Heimrich 	BView::MouseMoved(point, code, dragMessage);
444*78092ae7SKarsten Heimrich }
445*78092ae7SKarsten Heimrich 
446*78092ae7SKarsten Heimrich 
447*78092ae7SKarsten Heimrich void
448*78092ae7SKarsten Heimrich BCalendarView::KeyDown(const char *bytes, int32 numBytes)
449*78092ae7SKarsten Heimrich {
450*78092ae7SKarsten Heimrich 	const int32 kRows = 6;
451*78092ae7SKarsten Heimrich 	const int32 kColumns = 7;
452*78092ae7SKarsten Heimrich 
453*78092ae7SKarsten Heimrich 	int32 row = fFocusedDay.row;
454*78092ae7SKarsten Heimrich 	int32 column = fFocusedDay.column;
455*78092ae7SKarsten Heimrich 
456*78092ae7SKarsten Heimrich 	switch (bytes[0]) {
457*78092ae7SKarsten Heimrich 		case B_LEFT_ARROW:
458*78092ae7SKarsten Heimrich 		{
459*78092ae7SKarsten Heimrich 			column -= 1;
460*78092ae7SKarsten Heimrich 			if (column < 0) {
461*78092ae7SKarsten Heimrich 				column = kColumns -1;
462*78092ae7SKarsten Heimrich 				row -= 1;
463*78092ae7SKarsten Heimrich 				if (row >= 0)
464*78092ae7SKarsten Heimrich 					fFocusChanged = true;
465*78092ae7SKarsten Heimrich 			} else
466*78092ae7SKarsten Heimrich 				fFocusChanged = true;
467*78092ae7SKarsten Heimrich 		}	break;
468*78092ae7SKarsten Heimrich 
469*78092ae7SKarsten Heimrich 		case B_RIGHT_ARROW:
470*78092ae7SKarsten Heimrich 		{
471*78092ae7SKarsten Heimrich 			column += 1;
472*78092ae7SKarsten Heimrich 			if (column == kColumns) {
473*78092ae7SKarsten Heimrich 				column = 0;
474*78092ae7SKarsten Heimrich 				row += 1;
475*78092ae7SKarsten Heimrich 				if (row < kRows)
476*78092ae7SKarsten Heimrich 					fFocusChanged = true;
477*78092ae7SKarsten Heimrich 			} else
478*78092ae7SKarsten Heimrich 				fFocusChanged = true;
479*78092ae7SKarsten Heimrich 		}	break;
480*78092ae7SKarsten Heimrich 
481*78092ae7SKarsten Heimrich 		case B_UP_ARROW:
482*78092ae7SKarsten Heimrich 		{
483*78092ae7SKarsten Heimrich 			row -= 1;
484*78092ae7SKarsten Heimrich 			if (row >= 0)
485*78092ae7SKarsten Heimrich 				fFocusChanged = true;
486*78092ae7SKarsten Heimrich 		}	break;
487*78092ae7SKarsten Heimrich 
488*78092ae7SKarsten Heimrich 		case B_DOWN_ARROW:
489*78092ae7SKarsten Heimrich 		{
490*78092ae7SKarsten Heimrich 			row += 1;
491*78092ae7SKarsten Heimrich 			if (row < kRows)
492*78092ae7SKarsten Heimrich 				fFocusChanged = true;
493*78092ae7SKarsten Heimrich 		}	break;
494*78092ae7SKarsten Heimrich 
495*78092ae7SKarsten Heimrich 		case B_RETURN:
496*78092ae7SKarsten Heimrich 		case B_SPACE: {
497*78092ae7SKarsten Heimrich 			fSelectionChanged = true;
498*78092ae7SKarsten Heimrich 			BPoint pt = _RectOfDay(fFocusedDay).LeftTop();
499*78092ae7SKarsten Heimrich 			Draw(_SetNewSelectedDay(pt + BPoint(4.0, 4.0)));
500*78092ae7SKarsten Heimrich 			Draw(_RectOfDay(fSelectedDay));
501*78092ae7SKarsten Heimrich 			fSelectionChanged = false;
502*78092ae7SKarsten Heimrich 
503*78092ae7SKarsten Heimrich 			Invoke();
504*78092ae7SKarsten Heimrich 		}	break;
505*78092ae7SKarsten Heimrich 
506*78092ae7SKarsten Heimrich 		default:
507*78092ae7SKarsten Heimrich 			BView::KeyDown(bytes, numBytes);
508*78092ae7SKarsten Heimrich 			break;
509*78092ae7SKarsten Heimrich 	}
510*78092ae7SKarsten Heimrich 
511*78092ae7SKarsten Heimrich 	if (fFocusChanged) {
512*78092ae7SKarsten Heimrich 		fNewFocusedDay.SetTo(row, column);
513*78092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
514*78092ae7SKarsten Heimrich 		Draw(_RectOfDay(fNewFocusedDay));
515*78092ae7SKarsten Heimrich 		fFocusChanged = false;
516*78092ae7SKarsten Heimrich 	}
517*78092ae7SKarsten Heimrich }
518*78092ae7SKarsten Heimrich 
519*78092ae7SKarsten Heimrich 
520*78092ae7SKarsten Heimrich BHandler*
521*78092ae7SKarsten Heimrich BCalendarView::ResolveSpecifier(BMessage *message, int32 index,
522*78092ae7SKarsten Heimrich 	BMessage *specifier, int32 form, const char *property)
523*78092ae7SKarsten Heimrich {
524*78092ae7SKarsten Heimrich 	return BView::ResolveSpecifier(message, index, specifier, form, property);
525*78092ae7SKarsten Heimrich }
526*78092ae7SKarsten Heimrich 
527*78092ae7SKarsten Heimrich 
528*78092ae7SKarsten Heimrich status_t
529*78092ae7SKarsten Heimrich BCalendarView::GetSupportedSuites(BMessage *data)
530*78092ae7SKarsten Heimrich {
531*78092ae7SKarsten Heimrich 	return BView::GetSupportedSuites(data);
532*78092ae7SKarsten Heimrich }
533*78092ae7SKarsten Heimrich 
534*78092ae7SKarsten Heimrich 
535*78092ae7SKarsten Heimrich status_t
536*78092ae7SKarsten Heimrich BCalendarView::Perform(perform_code code, void *arg)
537*78092ae7SKarsten Heimrich {
538*78092ae7SKarsten Heimrich 	return BView::Perform(code, arg);
539*78092ae7SKarsten Heimrich }
540*78092ae7SKarsten Heimrich 
541*78092ae7SKarsten Heimrich 
542*78092ae7SKarsten Heimrich void
543*78092ae7SKarsten Heimrich BCalendarView::ResizeToPreferred()
544*78092ae7SKarsten Heimrich {
545*78092ae7SKarsten Heimrich 	float width;
546*78092ae7SKarsten Heimrich 	float height;
547*78092ae7SKarsten Heimrich 
548*78092ae7SKarsten Heimrich 	GetPreferredSize(&width, &height);
549*78092ae7SKarsten Heimrich 	BView::ResizeTo(width, height);
550*78092ae7SKarsten Heimrich }
551*78092ae7SKarsten Heimrich 
552*78092ae7SKarsten Heimrich 
553*78092ae7SKarsten Heimrich void
554*78092ae7SKarsten Heimrich BCalendarView::GetPreferredSize(float *width, float *height)
555*78092ae7SKarsten Heimrich {
556*78092ae7SKarsten Heimrich 	_GetPreferredSize(width, height);
557*78092ae7SKarsten Heimrich }
558*78092ae7SKarsten Heimrich 
559*78092ae7SKarsten Heimrich 
560*78092ae7SKarsten Heimrich int32
561*78092ae7SKarsten Heimrich BCalendarView::Day() const
562*78092ae7SKarsten Heimrich {
563*78092ae7SKarsten Heimrich 	return fDay;
564*78092ae7SKarsten Heimrich }
565*78092ae7SKarsten Heimrich 
566*78092ae7SKarsten Heimrich 
567*78092ae7SKarsten Heimrich int32
568*78092ae7SKarsten Heimrich BCalendarView::Year() const
569*78092ae7SKarsten Heimrich {
570*78092ae7SKarsten Heimrich 	int32 year;
571*78092ae7SKarsten Heimrich 	int32 month;
572*78092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
573*78092ae7SKarsten Heimrich 
574*78092ae7SKarsten Heimrich 	return year;
575*78092ae7SKarsten Heimrich }
576*78092ae7SKarsten Heimrich 
577*78092ae7SKarsten Heimrich 
578*78092ae7SKarsten Heimrich int32
579*78092ae7SKarsten Heimrich BCalendarView::Month() const
580*78092ae7SKarsten Heimrich {
581*78092ae7SKarsten Heimrich 	int32 year;
582*78092ae7SKarsten Heimrich 	int32 month;
583*78092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
584*78092ae7SKarsten Heimrich 
585*78092ae7SKarsten Heimrich 	return month;
586*78092ae7SKarsten Heimrich }
587*78092ae7SKarsten Heimrich 
588*78092ae7SKarsten Heimrich 
589*78092ae7SKarsten Heimrich BDate
590*78092ae7SKarsten Heimrich BCalendarView::Date() const
591*78092ae7SKarsten Heimrich {
592*78092ae7SKarsten Heimrich 	int32 year;
593*78092ae7SKarsten Heimrich 	int32 month;
594*78092ae7SKarsten Heimrich 	_GetYearMonth(&year, &month);
595*78092ae7SKarsten Heimrich 	return BDate(year, month, fDay);
596*78092ae7SKarsten Heimrich }
597*78092ae7SKarsten Heimrich 
598*78092ae7SKarsten Heimrich 
599*78092ae7SKarsten Heimrich bool
600*78092ae7SKarsten Heimrich BCalendarView::SetDate(const BDate &date)
601*78092ae7SKarsten Heimrich {
602*78092ae7SKarsten Heimrich 	return SetDate(date.Year(), date.Month(), date.Day());
603*78092ae7SKarsten Heimrich }
604*78092ae7SKarsten Heimrich 
605*78092ae7SKarsten Heimrich 
606*78092ae7SKarsten Heimrich bool
607*78092ae7SKarsten Heimrich BCalendarView::SetDate(int32 year, int32 month, int32 day)
608*78092ae7SKarsten Heimrich {
609*78092ae7SKarsten Heimrich 	if (!BDate(year, month, day).IsValid())
610*78092ae7SKarsten Heimrich 		return false;
611*78092ae7SKarsten Heimrich 
612*78092ae7SKarsten Heimrich 	if (fYear == year && fMonth == month && fDay == day)
613*78092ae7SKarsten Heimrich 		return true;
614*78092ae7SKarsten Heimrich 
615*78092ae7SKarsten Heimrich 	fDay = day;
616*78092ae7SKarsten Heimrich 	if (fYear == year && fMonth == month) {
617*78092ae7SKarsten Heimrich 		_SetToDay();
618*78092ae7SKarsten Heimrich 		// update focus
619*78092ae7SKarsten Heimrich 		fFocusChanged = true;
620*78092ae7SKarsten Heimrich 		Draw(_RectOfDay(fFocusedDay));
621*78092ae7SKarsten Heimrich 		fFocusChanged = false;
622*78092ae7SKarsten Heimrich 
623*78092ae7SKarsten Heimrich 		// update selection
624*78092ae7SKarsten Heimrich 		fSelectionChanged = true;
625*78092ae7SKarsten Heimrich 		Draw(_RectOfDay(fSelectedDay));
626*78092ae7SKarsten Heimrich 		Draw(_RectOfDay(fNewSelectedDay));
627*78092ae7SKarsten Heimrich 		fSelectionChanged = false;
628*78092ae7SKarsten Heimrich 	} else {
629*78092ae7SKarsten Heimrich 		fYear = year;
630*78092ae7SKarsten Heimrich 		fMonth = month;
631*78092ae7SKarsten Heimrich 
632*78092ae7SKarsten Heimrich 		_SetupDayNumbers();
633*78092ae7SKarsten Heimrich 		_SetupWeekNumbers();
634*78092ae7SKarsten Heimrich 
635*78092ae7SKarsten Heimrich 		BRect frame = Bounds();
636*78092ae7SKarsten Heimrich 		if (fDayNameHeaderVisible)
637*78092ae7SKarsten Heimrich 			frame.top += frame.Height() / 7 - 1.0;
638*78092ae7SKarsten Heimrich 
639*78092ae7SKarsten Heimrich 		if (fWeekNumberHeaderVisible)
640*78092ae7SKarsten Heimrich 			frame.left += frame.Width() / 8 - 1.0;
641*78092ae7SKarsten Heimrich 
642*78092ae7SKarsten Heimrich 		Draw(frame.InsetBySelf(4.0, 4.0));
643*78092ae7SKarsten Heimrich 	}
644*78092ae7SKarsten Heimrich 
645*78092ae7SKarsten Heimrich 	return true;
646*78092ae7SKarsten Heimrich }
647*78092ae7SKarsten Heimrich 
648*78092ae7SKarsten Heimrich 
649*78092ae7SKarsten Heimrich week_start
650*78092ae7SKarsten Heimrich BCalendarView::WeekStart() const
651*78092ae7SKarsten Heimrich {
652*78092ae7SKarsten Heimrich 	return fWeekStart;
653*78092ae7SKarsten Heimrich }
654*78092ae7SKarsten Heimrich 
655*78092ae7SKarsten Heimrich 
656*78092ae7SKarsten Heimrich void
657*78092ae7SKarsten Heimrich BCalendarView::SetWeekStart(week_start start)
658*78092ae7SKarsten Heimrich {
659*78092ae7SKarsten Heimrich 	if (fWeekStart == start)
660*78092ae7SKarsten Heimrich 		return;
661*78092ae7SKarsten Heimrich 
662*78092ae7SKarsten Heimrich 	fWeekStart = start;
663*78092ae7SKarsten Heimrich 
664*78092ae7SKarsten Heimrich 	_SetupDayNames();
665*78092ae7SKarsten Heimrich 	_SetupDayNumbers();
666*78092ae7SKarsten Heimrich 	_SetupWeekNumbers();
667*78092ae7SKarsten Heimrich 
668*78092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
669*78092ae7SKarsten Heimrich }
670*78092ae7SKarsten Heimrich 
671*78092ae7SKarsten Heimrich 
672*78092ae7SKarsten Heimrich bool
673*78092ae7SKarsten Heimrich BCalendarView::IsDayNameHeaderVisible() const
674*78092ae7SKarsten Heimrich {
675*78092ae7SKarsten Heimrich 	return fDayNameHeaderVisible;
676*78092ae7SKarsten Heimrich }
677*78092ae7SKarsten Heimrich 
678*78092ae7SKarsten Heimrich 
679*78092ae7SKarsten Heimrich void
680*78092ae7SKarsten Heimrich BCalendarView::SetDayNameHeaderVisible(bool visible)
681*78092ae7SKarsten Heimrich {
682*78092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible == visible)
683*78092ae7SKarsten Heimrich 		return;
684*78092ae7SKarsten Heimrich 
685*78092ae7SKarsten Heimrich 	fDayNameHeaderVisible = visible;
686*78092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
687*78092ae7SKarsten Heimrich }
688*78092ae7SKarsten Heimrich 
689*78092ae7SKarsten Heimrich 
690*78092ae7SKarsten Heimrich bool
691*78092ae7SKarsten Heimrich BCalendarView::IsWeekNumberHeaderVisible() const
692*78092ae7SKarsten Heimrich {
693*78092ae7SKarsten Heimrich 	return fWeekNumberHeaderVisible;
694*78092ae7SKarsten Heimrich }
695*78092ae7SKarsten Heimrich 
696*78092ae7SKarsten Heimrich 
697*78092ae7SKarsten Heimrich void
698*78092ae7SKarsten Heimrich BCalendarView::SetWeekNumberHeaderVisible(bool visible)
699*78092ae7SKarsten Heimrich {
700*78092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible == visible)
701*78092ae7SKarsten Heimrich 		return;
702*78092ae7SKarsten Heimrich 
703*78092ae7SKarsten Heimrich 	fWeekNumberHeaderVisible = visible;
704*78092ae7SKarsten Heimrich 	Invalidate(Bounds().InsetBySelf(1.0, 1.0));
705*78092ae7SKarsten Heimrich }
706*78092ae7SKarsten Heimrich 
707*78092ae7SKarsten Heimrich 
708*78092ae7SKarsten Heimrich void
709*78092ae7SKarsten Heimrich BCalendarView::_InitObject()
710*78092ae7SKarsten Heimrich {
711*78092ae7SKarsten Heimrich 	BDate date = BDate::CurrentDate(B_LOCAL_TIME);
712*78092ae7SKarsten Heimrich 	fDay = date.Day();
713*78092ae7SKarsten Heimrich 	fYear = date.Year();
714*78092ae7SKarsten Heimrich 	fMonth = date.Month();
715*78092ae7SKarsten Heimrich 
716*78092ae7SKarsten Heimrich 	_SetupDayNames();
717*78092ae7SKarsten Heimrich 	_SetupDayNumbers();
718*78092ae7SKarsten Heimrich 	_SetupWeekNumbers();
719*78092ae7SKarsten Heimrich }
720*78092ae7SKarsten Heimrich 
721*78092ae7SKarsten Heimrich 
722*78092ae7SKarsten Heimrich void
723*78092ae7SKarsten Heimrich BCalendarView::_SetToDay()
724*78092ae7SKarsten Heimrich {
725*78092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
726*78092ae7SKarsten Heimrich 	if (!date.IsValid())
727*78092ae7SKarsten Heimrich 		return;
728*78092ae7SKarsten Heimrich 
729*78092ae7SKarsten Heimrich 	fNewFocusedDay.SetTo(0, 0);
730*78092ae7SKarsten Heimrich 	fNewSelectedDay.SetTo(0, 0);
731*78092ae7SKarsten Heimrich 
732*78092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
733*78092ae7SKarsten Heimrich 
734*78092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
735*78092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
736*78092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
737*78092ae7SKarsten Heimrich 
738*78092ae7SKarsten Heimrich 	int32 counter = 0;
739*78092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
740*78092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
741*78092ae7SKarsten Heimrich 			int32 day = counter - (firstDay - 1);
742*78092ae7SKarsten Heimrich 			if (counter >= firstDay && counter <= dayCountCurrent + firstDay - 1) {
743*78092ae7SKarsten Heimrich 				if (day == fDay) {
744*78092ae7SKarsten Heimrich 					fNewFocusedDay.SetTo(row, column);
745*78092ae7SKarsten Heimrich 					fNewSelectedDay.SetTo(row, column);
746*78092ae7SKarsten Heimrich 					return;
747*78092ae7SKarsten Heimrich 				}
748*78092ae7SKarsten Heimrich 			}
749*78092ae7SKarsten Heimrich 			counter++;
750*78092ae7SKarsten Heimrich 		}
751*78092ae7SKarsten Heimrich 	}
752*78092ae7SKarsten Heimrich }
753*78092ae7SKarsten Heimrich 
754*78092ae7SKarsten Heimrich 
755*78092ae7SKarsten Heimrich void
756*78092ae7SKarsten Heimrich BCalendarView::_GetYearMonth(int32 *year, int32 *month) const
757*78092ae7SKarsten Heimrich {
758*78092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
759*78092ae7SKarsten Heimrich 
760*78092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
761*78092ae7SKarsten Heimrich 
762*78092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
763*78092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
764*78092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
765*78092ae7SKarsten Heimrich 
766*78092ae7SKarsten Heimrich 	// set the date to one month before
767*78092ae7SKarsten Heimrich 	if (date.Month() == 1)
768*78092ae7SKarsten Heimrich 		date.SetDate(date.Year() -1, 12, fDay);
769*78092ae7SKarsten Heimrich 	else
770*78092ae7SKarsten Heimrich 		date.SetDate(date.Year(), date.Month() - 1, fDay);
771*78092ae7SKarsten Heimrich 
772*78092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
773*78092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
774*78092ae7SKarsten Heimrich 
775*78092ae7SKarsten Heimrich 	*year = fYear;
776*78092ae7SKarsten Heimrich 	*month = fMonth;
777*78092ae7SKarsten Heimrich 
778*78092ae7SKarsten Heimrich 	int32 counter = 0;
779*78092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
780*78092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
781*78092ae7SKarsten Heimrich 			if (counter < firstDay || counter > dayCountCurrent + firstDay - 1) {
782*78092ae7SKarsten Heimrich 				if (counter - firstDay < 0) {
783*78092ae7SKarsten Heimrich 					if (row == currRow && column == currColumn) {
784*78092ae7SKarsten Heimrich 						*year = date.Year();
785*78092ae7SKarsten Heimrich 						*month = date.Month();
786*78092ae7SKarsten Heimrich 						break;
787*78092ae7SKarsten Heimrich 					}
788*78092ae7SKarsten Heimrich 				} else {
789*78092ae7SKarsten Heimrich 					if (row == currRow && column == currColumn) {
790*78092ae7SKarsten Heimrich 						*year = fYear;
791*78092ae7SKarsten Heimrich 						*month = fMonth +1;
792*78092ae7SKarsten Heimrich 						if (fMonth == 12) {
793*78092ae7SKarsten Heimrich 							*year = fYear +1;
794*78092ae7SKarsten Heimrich 							*month = 1;
795*78092ae7SKarsten Heimrich 						}
796*78092ae7SKarsten Heimrich 						break;
797*78092ae7SKarsten Heimrich 					}
798*78092ae7SKarsten Heimrich 				}
799*78092ae7SKarsten Heimrich 			} else {
800*78092ae7SKarsten Heimrich 				if (row == currRow && column == currColumn)
801*78092ae7SKarsten Heimrich 					break;
802*78092ae7SKarsten Heimrich 			}
803*78092ae7SKarsten Heimrich 			counter++;
804*78092ae7SKarsten Heimrich 		}
805*78092ae7SKarsten Heimrich 	}
806*78092ae7SKarsten Heimrich }
807*78092ae7SKarsten Heimrich 
808*78092ae7SKarsten Heimrich 
809*78092ae7SKarsten Heimrich void
810*78092ae7SKarsten Heimrich BCalendarView::_GetPreferredSize(float *_width, float *_height)
811*78092ae7SKarsten Heimrich {
812*78092ae7SKarsten Heimrich 	BFont font;
813*78092ae7SKarsten Heimrich 	GetFont(&font);
814*78092ae7SKarsten Heimrich 	font_height fontHeight;
815*78092ae7SKarsten Heimrich 	font.GetHeight(&fontHeight);
816*78092ae7SKarsten Heimrich 
817*78092ae7SKarsten Heimrich 	const float height = FontHeight(this) + 4.0;
818*78092ae7SKarsten Heimrich 
819*78092ae7SKarsten Heimrich 	int32 rows = 7;
820*78092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
821*78092ae7SKarsten Heimrich 		rows = 6;
822*78092ae7SKarsten Heimrich 
823*78092ae7SKarsten Heimrich 	// height = font height * rows + 8 px border
824*78092ae7SKarsten Heimrich 	*_height = height * rows + 8.0;
825*78092ae7SKarsten Heimrich 
826*78092ae7SKarsten Heimrich 	float width = 0.0;
827*78092ae7SKarsten Heimrich 	for (int32 column = 0; column < 7; ++column) {
828*78092ae7SKarsten Heimrich 		float tmp = StringWidth(fDayNames[column].String()) + 2.0;
829*78092ae7SKarsten Heimrich 		width = tmp > width ? tmp : width;
830*78092ae7SKarsten Heimrich 	}
831*78092ae7SKarsten Heimrich 
832*78092ae7SKarsten Heimrich 	int32 columns = 8;
833*78092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
834*78092ae7SKarsten Heimrich 		columns = 7;
835*78092ae7SKarsten Heimrich 
836*78092ae7SKarsten Heimrich 	// width = max width day name * 8 column + 8 px border
837*78092ae7SKarsten Heimrich 	*_width = width * columns + 8.0;
838*78092ae7SKarsten Heimrich }
839*78092ae7SKarsten Heimrich 
840*78092ae7SKarsten Heimrich 
841*78092ae7SKarsten Heimrich void
842*78092ae7SKarsten Heimrich BCalendarView::_SetupDayNames()
843*78092ae7SKarsten Heimrich {
844*78092ae7SKarsten Heimrich 	const BDate date(fYear, fMonth, fDay);
845*78092ae7SKarsten Heimrich 	if (!date.IsValid())
846*78092ae7SKarsten Heimrich 		return;
847*78092ae7SKarsten Heimrich 
848*78092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY) {
849*78092ae7SKarsten Heimrich 		for (int32 i = 1; i <= 7; ++i) {
850*78092ae7SKarsten Heimrich 			fDayNames[i -1] = date.ShortDayName(i);
851*78092ae7SKarsten Heimrich 		}
852*78092ae7SKarsten Heimrich 	} else {
853*78092ae7SKarsten Heimrich 		fDayNames[0] = date.ShortDayName(7);
854*78092ae7SKarsten Heimrich 		for (int32 i = 1; i < 7; ++i) {
855*78092ae7SKarsten Heimrich 			fDayNames[i] = date.ShortDayName(i);
856*78092ae7SKarsten Heimrich 		}
857*78092ae7SKarsten Heimrich 	}
858*78092ae7SKarsten Heimrich }
859*78092ae7SKarsten Heimrich 
860*78092ae7SKarsten Heimrich 
861*78092ae7SKarsten Heimrich void
862*78092ae7SKarsten Heimrich BCalendarView::_SetupDayNumbers()
863*78092ae7SKarsten Heimrich {
864*78092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, 1);
865*78092ae7SKarsten Heimrich 	if (!date.IsValid())
866*78092ae7SKarsten Heimrich 		return;
867*78092ae7SKarsten Heimrich 
868*78092ae7SKarsten Heimrich 	fFocusedDay.SetTo(0, 0);
869*78092ae7SKarsten Heimrich 	fSelectedDay.SetTo(0, 0);
870*78092ae7SKarsten Heimrich 	fNewFocusedDay.SetTo(0, 0);
871*78092ae7SKarsten Heimrich 
872*78092ae7SKarsten Heimrich 	const int32 dayCountCurrent = date.DaysInMonth();
873*78092ae7SKarsten Heimrich 
874*78092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
875*78092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
876*78092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
877*78092ae7SKarsten Heimrich 
878*78092ae7SKarsten Heimrich 	// calc the last day one month before
879*78092ae7SKarsten Heimrich 	if (date.Month() == 1)
880*78092ae7SKarsten Heimrich 		date.SetDate(date.Year() -1, 12, fDay);
881*78092ae7SKarsten Heimrich 	else
882*78092ae7SKarsten Heimrich 		date.SetDate(date.Year(), date.Month() - 1, fDay);
883*78092ae7SKarsten Heimrich 	const int32 lastDayBefore = date.DaysInMonth();
884*78092ae7SKarsten Heimrich 
885*78092ae7SKarsten Heimrich 	int32 counter = 0;
886*78092ae7SKarsten Heimrich 	int32 firstDayAfter = 1;
887*78092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
888*78092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
889*78092ae7SKarsten Heimrich 			int32 day = counter - (firstDay - 1);
890*78092ae7SKarsten Heimrich 			if (counter < firstDay || counter > dayCountCurrent + firstDay - 1) {
891*78092ae7SKarsten Heimrich 				if (counter - firstDay < 0)
892*78092ae7SKarsten Heimrich 					day += lastDayBefore;
893*78092ae7SKarsten Heimrich 				else
894*78092ae7SKarsten Heimrich 					day = firstDayAfter++;
895*78092ae7SKarsten Heimrich 			} else {
896*78092ae7SKarsten Heimrich 				if (day == fDay) {
897*78092ae7SKarsten Heimrich 					fFocusedDay.SetTo(row, column);
898*78092ae7SKarsten Heimrich 					fSelectedDay.SetTo(row, column);
899*78092ae7SKarsten Heimrich 					fNewFocusedDay.SetTo(row, column);
900*78092ae7SKarsten Heimrich 				}
901*78092ae7SKarsten Heimrich 			}
902*78092ae7SKarsten Heimrich 			counter++;
903*78092ae7SKarsten Heimrich 			fDayNumbers[row][column].SetTo("");
904*78092ae7SKarsten Heimrich 			fDayNumbers[row][column] << day;
905*78092ae7SKarsten Heimrich 		}
906*78092ae7SKarsten Heimrich 	}
907*78092ae7SKarsten Heimrich }
908*78092ae7SKarsten Heimrich 
909*78092ae7SKarsten Heimrich 
910*78092ae7SKarsten Heimrich void
911*78092ae7SKarsten Heimrich BCalendarView::_SetupWeekNumbers()
912*78092ae7SKarsten Heimrich {
913*78092ae7SKarsten Heimrich 	BDate date(fYear, fMonth, fDay);
914*78092ae7SKarsten Heimrich 	if (!date.IsValid())
915*78092ae7SKarsten Heimrich 		return;
916*78092ae7SKarsten Heimrich 
917*78092ae7SKarsten Heimrich 	date.SetDate(fYear, fMonth, 1);
918*78092ae7SKarsten Heimrich 	fWeekNumbers[0].SetTo("");
919*78092ae7SKarsten Heimrich 	fWeekNumbers[0] << date.WeekNumber();
920*78092ae7SKarsten Heimrich 
921*78092ae7SKarsten Heimrich 	for (int32 row = 1; row < 5; ++row) {
922*78092ae7SKarsten Heimrich 		date.SetDate(fYear, fMonth, date.Day() + 7);
923*78092ae7SKarsten Heimrich 		fWeekNumbers[row].SetTo("");
924*78092ae7SKarsten Heimrich 		fWeekNumbers[row] << date.WeekNumber();
925*78092ae7SKarsten Heimrich 	}
926*78092ae7SKarsten Heimrich 
927*78092ae7SKarsten Heimrich 	if (fMonth == 12)
928*78092ae7SKarsten Heimrich 		date.SetDate(fYear + 1, 1, 5);
929*78092ae7SKarsten Heimrich 	else
930*78092ae7SKarsten Heimrich 		date.SetDate(fYear, fMonth + 1, 7);
931*78092ae7SKarsten Heimrich 
932*78092ae7SKarsten Heimrich 	fWeekNumbers[5].SetTo("");
933*78092ae7SKarsten Heimrich 	fWeekNumbers[5] << date.WeekNumber();
934*78092ae7SKarsten Heimrich }
935*78092ae7SKarsten Heimrich 
936*78092ae7SKarsten Heimrich 
937*78092ae7SKarsten Heimrich void
938*78092ae7SKarsten Heimrich BCalendarView::_DrawDay(int32 currRow, int32 currColumn, int32 row, int32 column,
939*78092ae7SKarsten Heimrich 	int32 counter, BRect frame, const char *text, bool focus)
940*78092ae7SKarsten Heimrich {
941*78092ae7SKarsten Heimrich 	const BDate date(fYear, fMonth, 1);
942*78092ae7SKarsten Heimrich 	const int32 daysMonth = date.DaysInMonth();
943*78092ae7SKarsten Heimrich 
944*78092ae7SKarsten Heimrich 	int32 firstDay = date.DayOfWeek();
945*78092ae7SKarsten Heimrich 	if (fWeekStart == B_WEEK_START_MONDAY)
946*78092ae7SKarsten Heimrich 		firstDay = ((firstDay - 1) < 0) ? 6 : firstDay -1;
947*78092ae7SKarsten Heimrich 
948*78092ae7SKarsten Heimrich 	bool enabled = true;
949*78092ae7SKarsten Heimrich 	bool selected = false;
950*78092ae7SKarsten Heimrich 	// check for the current date
951*78092ae7SKarsten Heimrich 	if (currRow == row  && currColumn == column) {
952*78092ae7SKarsten Heimrich 		selected = true;	// draw current date selected
953*78092ae7SKarsten Heimrich 		if (counter <= firstDay || counter > firstDay + daysMonth) {
954*78092ae7SKarsten Heimrich 			enabled = false;	// days of month before or after
955*78092ae7SKarsten Heimrich 			selected = false;	// not selected but able to get focus
956*78092ae7SKarsten Heimrich 		}
957*78092ae7SKarsten Heimrich 	} else {
958*78092ae7SKarsten Heimrich 		if (counter <= firstDay || counter > firstDay + daysMonth)
959*78092ae7SKarsten Heimrich 			enabled = false;	// days of month before or after
960*78092ae7SKarsten Heimrich 	}
961*78092ae7SKarsten Heimrich 
962*78092ae7SKarsten Heimrich 	DrawDay(this, frame, text, selected, enabled, focus);
963*78092ae7SKarsten Heimrich }
964*78092ae7SKarsten Heimrich 
965*78092ae7SKarsten Heimrich 
966*78092ae7SKarsten Heimrich void
967*78092ae7SKarsten Heimrich BCalendarView::_DrawDays()
968*78092ae7SKarsten Heimrich {
969*78092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
970*78092ae7SKarsten Heimrich 
971*78092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
972*78092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
973*78092ae7SKarsten Heimrich 
974*78092ae7SKarsten Heimrich 	const bool isFocus = IsFocus();
975*78092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
976*78092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
977*78092ae7SKarsten Heimrich 
978*78092ae7SKarsten Heimrich 	int32 counter = 0;
979*78092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
980*78092ae7SKarsten Heimrich 		BRect tmp = frame;
981*78092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
982*78092ae7SKarsten Heimrich 			counter++;
983*78092ae7SKarsten Heimrich 			const char *day = fDayNumbers[row][column].String();
984*78092ae7SKarsten Heimrich 			bool focus = isFocus && focusRow == row && focusColumn == column;
985*78092ae7SKarsten Heimrich 			_DrawDay(currRow, currColumn, row, column, counter, tmp, day, focus);
986*78092ae7SKarsten Heimrich 
987*78092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
988*78092ae7SKarsten Heimrich 		}
989*78092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
990*78092ae7SKarsten Heimrich 	}
991*78092ae7SKarsten Heimrich }
992*78092ae7SKarsten Heimrich 
993*78092ae7SKarsten Heimrich 
994*78092ae7SKarsten Heimrich void
995*78092ae7SKarsten Heimrich BCalendarView::_DrawFocusRect()
996*78092ae7SKarsten Heimrich {
997*78092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
998*78092ae7SKarsten Heimrich 
999*78092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
1000*78092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
1001*78092ae7SKarsten Heimrich 
1002*78092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
1003*78092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
1004*78092ae7SKarsten Heimrich 
1005*78092ae7SKarsten Heimrich 	int32 counter = 0;
1006*78092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
1007*78092ae7SKarsten Heimrich 		BRect tmp = frame;
1008*78092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
1009*78092ae7SKarsten Heimrich 			counter++;
1010*78092ae7SKarsten Heimrich 			if (fNewFocusedDay.row == row && fNewFocusedDay.column == column) {
1011*78092ae7SKarsten Heimrich 				fFocusedDay.SetTo(row, column);
1012*78092ae7SKarsten Heimrich 
1013*78092ae7SKarsten Heimrich 				bool focus = IsFocus() && true;
1014*78092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
1015*78092ae7SKarsten Heimrich 				_DrawDay(currRow, currColumn, row, column, counter, tmp, day, focus);
1016*78092ae7SKarsten Heimrich 			}
1017*78092ae7SKarsten Heimrich 			else if (focusRow == row && focusColumn == column) {
1018*78092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
1019*78092ae7SKarsten Heimrich 				_DrawDay(currRow, currColumn, row, column, counter, tmp, day, false);
1020*78092ae7SKarsten Heimrich 			}
1021*78092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
1022*78092ae7SKarsten Heimrich 		}
1023*78092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
1024*78092ae7SKarsten Heimrich 	}
1025*78092ae7SKarsten Heimrich }
1026*78092ae7SKarsten Heimrich 
1027*78092ae7SKarsten Heimrich 
1028*78092ae7SKarsten Heimrich void
1029*78092ae7SKarsten Heimrich BCalendarView::_DrawDayHeader()
1030*78092ae7SKarsten Heimrich {
1031*78092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
1032*78092ae7SKarsten Heimrich 		return;
1033*78092ae7SKarsten Heimrich 
1034*78092ae7SKarsten Heimrich 	int32 offset = 1;
1035*78092ae7SKarsten Heimrich 	int32 columns = 8;
1036*78092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible) {
1037*78092ae7SKarsten Heimrich 		offset = 0;
1038*78092ae7SKarsten Heimrich 		columns = 7;
1039*78092ae7SKarsten Heimrich 	}
1040*78092ae7SKarsten Heimrich 
1041*78092ae7SKarsten Heimrich 	BRect frame = Bounds();
1042*78092ae7SKarsten Heimrich 	frame.right = frame.Width() / columns - 1.0;
1043*78092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / 7.0 - 2.0;
1044*78092ae7SKarsten Heimrich 	frame.OffsetBy(4.0, 4.0);
1045*78092ae7SKarsten Heimrich 
1046*78092ae7SKarsten Heimrich 	for (int32 i = 0; i < columns; ++i) {
1047*78092ae7SKarsten Heimrich 		if (i == 0 && fWeekNumberHeaderVisible) {
1048*78092ae7SKarsten Heimrich 			DrawDayName(this, frame, "");
1049*78092ae7SKarsten Heimrich 			frame.OffsetBy(frame.Width(), 0.0);
1050*78092ae7SKarsten Heimrich 			continue;
1051*78092ae7SKarsten Heimrich 		}
1052*78092ae7SKarsten Heimrich 		DrawDayName(this, frame, fDayNames[i - offset].String());
1053*78092ae7SKarsten Heimrich 		frame.OffsetBy(frame.Width(), 0.0);
1054*78092ae7SKarsten Heimrich 	}
1055*78092ae7SKarsten Heimrich }
1056*78092ae7SKarsten Heimrich 
1057*78092ae7SKarsten Heimrich 
1058*78092ae7SKarsten Heimrich void
1059*78092ae7SKarsten Heimrich BCalendarView::_DrawWeekHeader()
1060*78092ae7SKarsten Heimrich {
1061*78092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
1062*78092ae7SKarsten Heimrich 		return;
1063*78092ae7SKarsten Heimrich 
1064*78092ae7SKarsten Heimrich 	int32 rows = 7;
1065*78092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
1066*78092ae7SKarsten Heimrich 		rows = 6;
1067*78092ae7SKarsten Heimrich 
1068*78092ae7SKarsten Heimrich 	BRect frame = Bounds();
1069*78092ae7SKarsten Heimrich 	frame.right = frame.Width() / 8.0 - 2.0;
1070*78092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / rows - 1.0;
1071*78092ae7SKarsten Heimrich 
1072*78092ae7SKarsten Heimrich 	float offsetY = 4.0;
1073*78092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
1074*78092ae7SKarsten Heimrich 		offsetY += frame.Height();
1075*78092ae7SKarsten Heimrich 
1076*78092ae7SKarsten Heimrich 	frame.OffsetBy(4.0, offsetY);
1077*78092ae7SKarsten Heimrich 
1078*78092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
1079*78092ae7SKarsten Heimrich 		DrawWeekNumber(this, frame, fWeekNumbers[row].String());
1080*78092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
1081*78092ae7SKarsten Heimrich 	}
1082*78092ae7SKarsten Heimrich }
1083*78092ae7SKarsten Heimrich 
1084*78092ae7SKarsten Heimrich 
1085*78092ae7SKarsten Heimrich void
1086*78092ae7SKarsten Heimrich BCalendarView::_DrawItem(BView *owner, BRect frame, const char *text,
1087*78092ae7SKarsten Heimrich 	bool isSelected, bool isEnabled, bool focus)
1088*78092ae7SKarsten Heimrich {
1089*78092ae7SKarsten Heimrich 	rgb_color lColor = LowColor();
1090*78092ae7SKarsten Heimrich 	rgb_color highColor = HighColor();
1091*78092ae7SKarsten Heimrich 
1092*78092ae7SKarsten Heimrich 	rgb_color lowColor = { 255, 255, 255, 255 };
1093*78092ae7SKarsten Heimrich 
1094*78092ae7SKarsten Heimrich 	if (isSelected) {
1095*78092ae7SKarsten Heimrich 		SetHighColor(tint_color(lowColor, B_DARKEN_2_TINT));
1096*78092ae7SKarsten Heimrich 		SetLowColor(HighColor());
1097*78092ae7SKarsten Heimrich 	} else
1098*78092ae7SKarsten Heimrich 		SetHighColor(lowColor);
1099*78092ae7SKarsten Heimrich 
1100*78092ae7SKarsten Heimrich 	FillRect(frame.InsetByCopy(1.0, 1.0));
1101*78092ae7SKarsten Heimrich 
1102*78092ae7SKarsten Heimrich 	if (focus) {
1103*78092ae7SKarsten Heimrich 		SetHighColor(keyboard_navigation_color());
1104*78092ae7SKarsten Heimrich 		StrokeRect(frame.InsetByCopy(1.0, 1.0));
1105*78092ae7SKarsten Heimrich 	}
1106*78092ae7SKarsten Heimrich 
1107*78092ae7SKarsten Heimrich 	rgb_color black = { 0, 0, 0, 255 };
1108*78092ae7SKarsten Heimrich 	SetHighColor(black);
1109*78092ae7SKarsten Heimrich 	if (!isEnabled)
1110*78092ae7SKarsten Heimrich 		SetHighColor(tint_color(black, B_LIGHTEN_2_TINT));
1111*78092ae7SKarsten Heimrich 
1112*78092ae7SKarsten Heimrich 	float offsetH = frame.Width() / 2.0;
1113*78092ae7SKarsten Heimrich 	float offsetV = (frame.Height() / 2.0) + (FontHeight(owner) / 2.0) - 2.0;
1114*78092ae7SKarsten Heimrich 
1115*78092ae7SKarsten Heimrich 	DrawString(text, BPoint(frame.right - offsetH
1116*78092ae7SKarsten Heimrich 		- (StringWidth(text) / 2.0), frame.top + offsetV));
1117*78092ae7SKarsten Heimrich 
1118*78092ae7SKarsten Heimrich 	SetLowColor(lColor);
1119*78092ae7SKarsten Heimrich 	SetHighColor(highColor);
1120*78092ae7SKarsten Heimrich }
1121*78092ae7SKarsten Heimrich 
1122*78092ae7SKarsten Heimrich 
1123*78092ae7SKarsten Heimrich void
1124*78092ae7SKarsten Heimrich BCalendarView::_UpdateSelection()
1125*78092ae7SKarsten Heimrich {
1126*78092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
1127*78092ae7SKarsten Heimrich 
1128*78092ae7SKarsten Heimrich 	const int32 currRow = fSelectedDay.row;
1129*78092ae7SKarsten Heimrich 	const int32 currColumn = fSelectedDay.column;
1130*78092ae7SKarsten Heimrich 
1131*78092ae7SKarsten Heimrich 	const int32 focusRow = fFocusedDay.row;
1132*78092ae7SKarsten Heimrich 	const int32 focusColumn = fFocusedDay.column;
1133*78092ae7SKarsten Heimrich 
1134*78092ae7SKarsten Heimrich 	int32 counter = 0;
1135*78092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
1136*78092ae7SKarsten Heimrich 		BRect tmp = frame;
1137*78092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
1138*78092ae7SKarsten Heimrich 			counter++;
1139*78092ae7SKarsten Heimrich 			if (fNewSelectedDay.row == row && fNewSelectedDay.column == column) {
1140*78092ae7SKarsten Heimrich 				fSelectedDay.SetTo(row, column);
1141*78092ae7SKarsten Heimrich 
1142*78092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
1143*78092ae7SKarsten Heimrich 				bool focus = IsFocus() && focusRow == row && focusColumn == column;
1144*78092ae7SKarsten Heimrich 				_DrawDay(row, column, row, column, counter, tmp, day, focus);
1145*78092ae7SKarsten Heimrich 			}
1146*78092ae7SKarsten Heimrich 			else if (currRow == row && currColumn == column) {
1147*78092ae7SKarsten Heimrich 				const char *day = fDayNumbers[row][column].String();
1148*78092ae7SKarsten Heimrich 				bool focus = IsFocus() && focusRow == row && focusColumn == column;
1149*78092ae7SKarsten Heimrich 				_DrawDay(currRow, currColumn, -1, -1, counter, tmp, day, focus);
1150*78092ae7SKarsten Heimrich 			}
1151*78092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
1152*78092ae7SKarsten Heimrich 		}
1153*78092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
1154*78092ae7SKarsten Heimrich 	}
1155*78092ae7SKarsten Heimrich }
1156*78092ae7SKarsten Heimrich 
1157*78092ae7SKarsten Heimrich 
1158*78092ae7SKarsten Heimrich BRect
1159*78092ae7SKarsten Heimrich BCalendarView::_FirstCalendarItemFrame() const
1160*78092ae7SKarsten Heimrich {
1161*78092ae7SKarsten Heimrich 	int32 rows = 7;
1162*78092ae7SKarsten Heimrich 	int32 columns = 8;
1163*78092ae7SKarsten Heimrich 
1164*78092ae7SKarsten Heimrich 	if (!fDayNameHeaderVisible)
1165*78092ae7SKarsten Heimrich 		rows = 6;
1166*78092ae7SKarsten Heimrich 
1167*78092ae7SKarsten Heimrich 	if (!fWeekNumberHeaderVisible)
1168*78092ae7SKarsten Heimrich 		columns = 7;
1169*78092ae7SKarsten Heimrich 
1170*78092ae7SKarsten Heimrich 	BRect frame = Bounds();
1171*78092ae7SKarsten Heimrich 	frame.right = frame.Width() / columns - 1.0;
1172*78092ae7SKarsten Heimrich 	frame.bottom = frame.Height() / rows - 1.0;
1173*78092ae7SKarsten Heimrich 
1174*78092ae7SKarsten Heimrich 	float offsetY = 4.0;
1175*78092ae7SKarsten Heimrich 	if (fDayNameHeaderVisible)
1176*78092ae7SKarsten Heimrich 		offsetY += frame.Height();
1177*78092ae7SKarsten Heimrich 
1178*78092ae7SKarsten Heimrich 	float offsetX = 4.0;
1179*78092ae7SKarsten Heimrich 	if (fWeekNumberHeaderVisible)
1180*78092ae7SKarsten Heimrich 		offsetX += frame.Width();
1181*78092ae7SKarsten Heimrich 
1182*78092ae7SKarsten Heimrich 	return frame.OffsetBySelf(offsetX, offsetY);
1183*78092ae7SKarsten Heimrich }
1184*78092ae7SKarsten Heimrich 
1185*78092ae7SKarsten Heimrich 
1186*78092ae7SKarsten Heimrich BRect
1187*78092ae7SKarsten Heimrich BCalendarView::_SetNewSelectedDay(const BPoint &where)
1188*78092ae7SKarsten Heimrich {
1189*78092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
1190*78092ae7SKarsten Heimrich 
1191*78092ae7SKarsten Heimrich 	int32 counter = 0;
1192*78092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
1193*78092ae7SKarsten Heimrich 		BRect tmp = frame;
1194*78092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
1195*78092ae7SKarsten Heimrich 			counter++;
1196*78092ae7SKarsten Heimrich 			if (tmp.Contains(where)) {
1197*78092ae7SKarsten Heimrich 				fNewSelectedDay.SetTo(row, column);
1198*78092ae7SKarsten Heimrich 				fDay = atoi(fDayNumbers[row][column].String());
1199*78092ae7SKarsten Heimrich 				return tmp;
1200*78092ae7SKarsten Heimrich 			}
1201*78092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
1202*78092ae7SKarsten Heimrich 		}
1203*78092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
1204*78092ae7SKarsten Heimrich 	}
1205*78092ae7SKarsten Heimrich 
1206*78092ae7SKarsten Heimrich 	return frame;
1207*78092ae7SKarsten Heimrich }
1208*78092ae7SKarsten Heimrich 
1209*78092ae7SKarsten Heimrich 
1210*78092ae7SKarsten Heimrich BRect
1211*78092ae7SKarsten Heimrich BCalendarView::_RectOfDay(const Selection &selection) const
1212*78092ae7SKarsten Heimrich {
1213*78092ae7SKarsten Heimrich 	BRect frame = _FirstCalendarItemFrame();
1214*78092ae7SKarsten Heimrich 
1215*78092ae7SKarsten Heimrich 	int32 counter = 0;
1216*78092ae7SKarsten Heimrich 	for (int32 row = 0; row < 6; ++row) {
1217*78092ae7SKarsten Heimrich 		BRect tmp = frame;
1218*78092ae7SKarsten Heimrich 		for (int32 column = 0; column < 7; ++column) {
1219*78092ae7SKarsten Heimrich 			counter++;
1220*78092ae7SKarsten Heimrich 			if (selection.row == row && selection.column == column) {
1221*78092ae7SKarsten Heimrich 				return tmp;
1222*78092ae7SKarsten Heimrich 			}
1223*78092ae7SKarsten Heimrich 			tmp.OffsetBy(tmp.Width(), 0.0);
1224*78092ae7SKarsten Heimrich 		}
1225*78092ae7SKarsten Heimrich 		frame.OffsetBy(0.0, frame.Height());
1226*78092ae7SKarsten Heimrich 	}
1227*78092ae7SKarsten Heimrich 
1228*78092ae7SKarsten Heimrich 	return frame;
1229*78092ae7SKarsten Heimrich }
1230*78092ae7SKarsten Heimrich 
1231*78092ae7SKarsten Heimrich 
1232*78092ae7SKarsten Heimrich }	// namespace BPrivate
1233