📄 datemonth.c
字号:
/******************************************************************************
*
* Copyright (c) 1995-2003 PalmSource, Inc. All rights reserved.
*
* File: DateMonth.c
*
* Release: Palm OS 5 SDK (68K) R3.
*
* Description:
* This is the Datebook application's month view module.
*
*****************************************************************************/
#include <PalmOS.h>
#include <PalmUtils.h>
#include "DateLunar.h" // For DateSupportsLunarCalendar, etc.
#include "Datebook.h"
extern void PrintApptRecord (DmOpenRef dbP, UInt16 index);
/***********************************************************************
*
* Internal Constants
*
***********************************************************************/
#define linesInMonthPlusTitle 7
#define maxWeeksInMonth 6
#define kMaxLunarDayStrSize 8
// Day number's margins
#define dateTextLeftMarginMonthView 3
#define dateTextTopMarginMonthView 1
#define dateTextLeftMarginLunarView 2
#define dateTextTopMarginLunarView 1
// Event indicators
#define lunchStartTime 0x0b1e // 11:30 am
#define lunchMidTime 0x0c0f // 12:15 pm
#define lunchEndTime 0xd00 // 1:00 pm
#define timeIndicatorWidth 2
#define timeIndicatorTopMargin 3
#define timeIndicatorRightMargin 2
#define untimeIndicatorTopMargin 13
#define untimeIndicatorRightMargin 5
#define repeatIndicatorBottomMargin 2
#define morningHeight 4
#define lunchHeight 3
#define afternoonHeight 4
#define drawDaySelected true
#define dontDrawDaySelected false
#define TodayIsVisible(monthP,today) ((monthP->month == today.month) && (monthP->year == today.year))
/***********************************************************************
*
* Internal Structutes
*
***********************************************************************/
typedef struct {
RectangleType bounds;
Int16 month; // month displayed
Int16 year; // year displayed
DateTimeType selected;
} MonthType;
typedef MonthType * MonthPtr;
/***********************************************************************
*
* Global variables (see DateGlobals.c)
*
***********************************************************************/
extern UInt16 pMonthViewButtonID; // Controls which view to implement
/***********************************************************************
*
* FUNCTION: FirstDayOfMonth
*
* DESCRIPTION: This routine returns the day-of-the-week, adjusted by the
* preference setting that specifies the first day-of-
* the-week. If the date passed is a Tuesday and the
* start day of week is Monday, this routine will return
* a value of one.
*
* PARAMETERS: monthP - pointer to MontnType structure
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 4/8/96 Initial Revision
*
***********************************************************************/
static UInt16 FirstDayOfMonth (MonthPtr monthP)
{
return (DayOfWeek (monthP->month, 1, monthP->year) -
StartDayOfWeek + daysInWeek) % daysInWeek;
}
/***********************************************************************
*
* FUNCTION: MonthDrawInversionEffect
*
* DESCRIPTION: This routine does an inversion effect by swapping colors
* this is NOT undoable by calling it a second time, rather
* it just applies a selected look on top of already
* rendered data. (It's kind of a hack.)
*
* PARAMETERS: rP - pointer to a rectangle to 'invert'
* cornerDiam - corner diameter
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* bob 10/28/99 Initial revision
* jmp 11/14/99 Modified for use with Datebook's MonthView (i.e., backcolor
* changed to UIObjectFill).
*
***********************************************************************/
static void MonthDrawInversionEffect (const RectangleType *rP, UInt16 cornerDiam)
{
WinPushDrawState();
WinSetDrawMode(winSwap);
WinSetPatternType (blackPattern);
WinSetBackColor(UIColorGetTableEntryIndex(UIObjectFill));
WinSetForeColor(UIColorGetTableEntryIndex(UIObjectSelectedFill));
WinPaintRectangle(rP, cornerDiam);
if (UIColorGetTableEntryIndex(UIObjectSelectedFill) != UIColorGetTableEntryIndex(UIObjectForeground)) {
WinSetBackColor(UIColorGetTableEntryIndex(UIObjectForeground));
WinSetForeColor(UIColorGetTableEntryIndex(UIObjectSelectedForeground));
WinPaintRectangle(rP, cornerDiam);
}
WinPopDrawState();
}
/***********************************************************************
*
* FUNCTION: GetDayBounds
*
* DESCRIPTION: This routine returns the bounds of the specified day
*
* PARAMETERS: monthP - pointer to month object
* day - day of month
* r - returned: bounds of the day
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 4/10/96 Initial Revision
*
***********************************************************************/
static void GetDayBounds (MonthPtr monthP, UInt16 day, RectanglePtr r)
{
UInt16 cell;
Int16 cellWidth;
Int16 cellHeight;
cell = day - 1 + FirstDayOfMonth (monthP);
cellWidth = monthP->bounds.extent.x / daysInWeek;
cellHeight = monthP->bounds.extent.y / linesInMonthPlusTitle;
r->topLeft.x = monthP->bounds.topLeft.x + (cell % daysInWeek) * cellWidth;
r->topLeft.y = monthP->bounds.topLeft.y + ((cell / daysInWeek) + 1) * cellHeight;
r->extent.x = cellWidth;
r->extent.y = cellHeight;
}
/***********************************************************************
*
* FUNCTION: GetDaySelectionBounds
*
* DESCRIPTION: This routine returns the selection bounds of the specified day
*
* PARAMETERS: monthP - pointer to month object
* day - day of month
* r - returned: bounds of the day selection
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* jmp 11/14/99 Initial Revision
* jmp 11/30/99 Grrr... swapped meaning of "cell" and "day" and
* broke selection of Sunday vs. Monday start-of-week
* selection. Fixed that!
* 2002-10-22 CS Lunar View has slightly different margins for date
* numbers.
* CS Make sure we set the font before calling FntCharWidth,
* FntLineHeight, etc.
*
***********************************************************************/
static void GetDaySelectionBounds(MonthPtr monthP, UInt16 day, RectanglePtr r)
{
UInt16 cell;
Int16 cellWidth;
Int16 cellHeight;
Int16 charWidth;
Int16 leftMargin;
Int16 topMargin;
WinPushDrawState();
if (pMonthViewButtonID == MonthLunarViewButton)
{
FntSetFont ((FontID)arabicNumeralFontID);
leftMargin = dateTextLeftMarginLunarView;
topMargin = dateTextTopMarginLunarView;
}
else
{
FntSetFont (stdFont);
leftMargin = dateTextLeftMarginMonthView;
topMargin = dateTextTopMarginMonthView;
}
cell = day - 1 + FirstDayOfMonth (monthP);
cellWidth = monthP->bounds.extent.x / daysInWeek;
cellHeight = monthP->bounds.extent.y / linesInMonthPlusTitle;
charWidth = FntCharWidth('0');
if (pMonthViewButtonID == MonthLunarViewButton)
{
r->topLeft.x = monthP->bounds.topLeft.x + ((cell % daysInWeek) * cellWidth) + 1;
r->topLeft.y = monthP->bounds.topLeft.y + (((cell / daysInWeek) + 1) * cellHeight) + 1;
r->extent.x = ((day < 10) ? charWidth : charWidth * 2) + leftMargin - 1;
r->extent.y = FntLineHeight () + (topMargin * 2) - 1;
}
else
{
r->topLeft.x = monthP->bounds.topLeft.x + (cell % daysInWeek) * cellWidth;
r->topLeft.y = monthP->bounds.topLeft.y + ((cell / daysInWeek) + 1) * cellHeight;
r->extent.x = ((day < 10) ? charWidth : charWidth * 2) + (leftMargin * 2);
r->extent.y = FntLineHeight () + (topMargin * 2);
RctInsetRectangle (r, 1);
}
WinPopDrawState ();
}
/***********************************************************************
*
* FUNCTION: DrawAppointment
*
* DESCRIPTION: This routine draw an appointment indicator.
*
* PARAMETERS: dayR - bounds of the day's drawing region
* start - appointment's start time
* end - appointment's end time
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 4/8/96 Initial Revision
*
***********************************************************************/
static void DrawAppointment (RectanglePtr dayR, TimeType start, TimeType end)
{
Int16 x, y;
RectangleType r;
// Draw the indicator for an untimed appointment.
if (TimeToInt(start) == apptNoTime)
{
x = dayR->topLeft.x + untimeIndicatorRightMargin;
y = dayR->topLeft.y + untimeIndicatorTopMargin;
WinDrawLine (x - 1, y, x + 1, y);
WinDrawLine (x, y - 1, x, y + 1);
return;
}
// Draw the indicator for an timed appointment.
x = dayR->topLeft.x + dayR->extent.x - timeIndicatorWidth -
timeIndicatorRightMargin;
y = dayR->topLeft.y + timeIndicatorTopMargin;
// Draw indicator for a morning appointment.
if (TimeToInt(start) < lunchStartTime)
{
r.topLeft.x = x;
r.topLeft.y = y;
r.extent.x = timeIndicatorWidth;
r.extent.y = morningHeight;
WinDrawRectangle (&r, 0);
}
// Draw indicator for a lunch appointment.
if ((TimeToInt(start) >= lunchStartTime && TimeToInt(start) < lunchEndTime) ||
(TimeToInt(start) < lunchStartTime && TimeToInt(end) > lunchMidTime))
{
r.topLeft.x = x;
r.topLeft.y = y + morningHeight + 1;
r.extent.x = timeIndicatorWidth;
r.extent.y = lunchHeight;
WinDrawRectangle (&r, 0);
}
// Draw indicator for a afternoon appointment.
if (TimeToInt(start) >= lunchEndTime ||
(TimeToInt(start) < lunchEndTime && TimeToInt(end) > lunchEndTime))
{
r.topLeft.x = x;
r.topLeft.y = y + morningHeight + lunchHeight + 2;
r.extent.x = timeIndicatorWidth;
r.extent.y = afternoonHeight;
WinDrawRectangle (&r, 0);
}
}
/***********************************************************************
*
* FUNCTION: DrawTimedAppointments
*
* DESCRIPTION: This routine draws appointment indicators for all the
* appointment in a month.
*
* PARAMETERS: monthP - month object
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 4/10/96 Initial Revision
*
***********************************************************************/
static void DrawTimedAppointments (MonthPtr monthP)
{
UInt16 recordNum;
DateType temp;
DateType date;
Boolean untimed;
Boolean sameMonth;
MemHandle recordH;
RectangleType dayR;
ApptDBRecordType apptRec;
date.day = 1;
date.month = monthP->month;
date.year = monthP->year - firstYear;
// Find the first non-repeating appointment of the day.
ApptFindFirst (ApptDB, date, &recordNum);
while (true)
{
recordH = DmQueryNextInCategory (ApptDB, &recordNum, dmAllCategories);
if (! recordH) break;
ApptGetRecord (ApptDB, recordNum, &apptRec, &recordH);
// Check if the appointment is on the same month
sameMonth = (apptRec.when->date.month == monthP->month) &&
(apptRec.when->date.year == monthP->year - firstYear);
untimed = TimeToInt(apptRec.when->startTime) == apptNoTime;
if (sameMonth &&
((ShowUntimedAppts && untimed) || (ShowTimedAppts && (! untimed))))
{
GetDayBounds (monthP, apptRec.when->date.day, &dayR);
DrawAppointment (&dayR, apptRec.when->startTime,
apptRec.when->endTime);
}
MemHandleUnlock (recordH);
if (! sameMonth) break;
// Get the next record.
recordNum++;
}
// Add the repeating appointments to the list. Repeating appointments
// are stored at the beginning of the database.
recordNum = 0;
while (true)
{
recordH = DmQueryNextInCategory (ApptDB, &recordNum, dmAllCategories);
if (! recordH) break;
ApptGetRecord (ApptDB, recordNum, &apptRec, &recordH);
untimed = TimeToInt(apptRec.when->startTime) == apptNoTime;
if (apptRec.repeat &&
((ShowUntimedAppts && untimed) || (ShowTimedAppts && (! untimed))))
{
date.day = 1;
date.month = monthP->month;
date.year = monthP->year - firstYear;
while (ApptNextRepeat (&apptRec, &date, true))
{
if ((date.month != monthP->month) ||
(date.year != monthP->year - firstYear))
break;
GetDayBounds (monthP, date.day, &dayR);
DrawAppointment (&dayR, apptRec.when->startTime,
apptRec.when->endTime);
temp = date;
DateAdjust (&date, 1);
if (DateToInt (temp) == DateToInt (date)) break;
}
}
MemHandleUnlock (recordH);
// If the record has no repeating info we've reached the end of the
// repeating appointments.
if (! apptRec.repeat) break;
recordNum++;
}
}
/***********************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -