📄 datemonth.c
字号:
*
* FUNCTION: DrawRepeatingAppointments
*
* DESCRIPTION: This routine draws appointment indicators for all the
* daily repeating appointments in a month.
*
* PARAMETERS: monthP - month object
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 7/16/96 Initial Revision
* roger 6/25/98 Fix from developer to not always draw the first day mark.
*
***********************************************************************/
static void DrawRepeatingAppointments (MonthPtr monthP)
{
UInt16 count = 0;
UInt16 recordNum;
Int16 x1, x2, y;
DateType temp;
DateType date;
Boolean first;
Boolean last;
MemHandle recordH;
RectangleType dayR;
ApptDBRecordType apptRec;
// Loop through the repeating event looking for daily repeating events.
// 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);
if (apptRec.repeat &&
apptRec.repeat->repeatType == repeatDaily &&
apptRec.repeat->repeatFrequency == 1)
{
date.day = 1;
date.month = monthP->month;
date.year = monthP->year - firstYear;
// if the first day of this daily repeating event is in this month
// then we draw a vertical tick. If it's not (it's in the prior
// month) then don't.
if (DateToInt(apptRec.when->date) >= DateToInt(date))
first = true;
else
first = false;
while (ApptNextRepeat (&apptRec, &date, true))
{
if ((date.month != monthP->month) ||
(date.year != monthP->year - firstYear))
break;
GetDayBounds (monthP, date.day, &dayR);
y = dayR.topLeft.y + dayR.extent.y - repeatIndicatorBottomMargin;
x1 = dayR.topLeft.x;
x2 = dayR.topLeft.x + dayR.extent.x;
last = (DateToInt (date) == DateToInt (apptRec.repeat->repeatEndDate));
if (first)
{
first = false;
WinDrawLine (x1+1, y-1, x1+1, y+1);
x1 += 2;
}
if (last)
{
WinDrawLine (x2-1, y-1, x2-1, y+1);
x2 -= 2;
}
WinDrawGrayLine (x1, y, x2, y);
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++;
}
}
/***********************************************************************
*
* FUNCTION: DrawAppointmentsInMonth
*
* 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 7/16/96 Initial Revision
*
***********************************************************************/
static void DrawAppointmentsInMonth (MonthPtr monthP)
{
if (ShowTimedAppts || ShowUntimedAppts)
DrawTimedAppointments (monthP);
if (ShowDailyRepeatingAppts)
DrawRepeatingAppointments (monthP);
}
/***********************************************************************
*
* FUNCTION: DrawLunarDateText
*
* DESCRIPTION: Draw the Chinese text identifying <gregorianDay>'s
* position in the Chinese lunar month, aligning its
* top left corner with <drawX> and <drawY>.
*
* PARAMETERS: gregorianDay - date number in currently displayed month
* drawX - left side of text
* drawY - top of text
*
* RETURNED: nothing
*
* REVISION HISTORY:
* 2002-10-23 CS New today to support Lunar View.
*
***********************************************************************/
static void DrawLunarDateText (MonthPtr monthP, UInt16 gregorianDay,
Coord drawX, Coord drawY)
{
DateTimeType dateTime;
UInt32 dateSeconds;
UInt16 lunarYear;
UInt16 lunarMonth;
UInt16 lunarDay;
Boolean isLeapMonth;
Char lunarDayStr[kMaxLunarDayStrSize];
MemHandle resH = NULL;
Err tErr = errNone;
WinPushDrawState();
FntSetFont((FontID)chineseNumeralFontID);
dateTime.second = 0;
dateTime.minute = 0;
dateTime.hour = 0;
dateTime.day = gregorianDay;
dateTime.month = monthP->month;
dateTime.year = monthP->year;
dateSeconds = TimDateTimeToSeconds(&dateTime);
tErr = DateSecondsToLunarDate(dateSeconds,
&lunarYear,
&lunarMonth,
&lunarDay,
&isLeapMonth);
if (tErr != errNone)
{
ErrNonFatalDisplay("Error converting seconds to lunar date");
return;
}
if (lunarDay == timFirstChineseLunarDay)
{
if ( (lunarMonth == 11)
|| (lunarMonth == 12))
{
resH = DmGetResource(bitmapRsc,
(lunarMonth == 11) ?
lunarMonth11BitmapID
: lunarMonth12BitmapID);
ErrNonFatalDisplayIf(!resH, "Unable to load lunar month bitmap");
if (resH)
{
WinPaintBitmap(MemHandleLock(resH), drawX, drawY);
MemHandleUnlock(resH);
}
}
else
{
SysStringByIndex( (isLeapMonth) ?
lunarLeapMonthsStrlID
: lunarMonthsStrlID,
lunarMonth,
lunarDayStr,
sizeof(lunarDayStr));
ErrNonFatalDisplayIf(StrLen(lunarDayStr) != 2,
"Lunar day string not 2 characters long");
WinDrawChars(lunarDayStr, StrLen(lunarDayStr), drawX, drawY);
}
}
else
{
SysStringByIndex( lunarDaysStrlID,
lunarDay,
lunarDayStr,
sizeof(lunarDayStr));
ErrNonFatalDisplayIf(StrLen(lunarDayStr) != 2,
"Lunar day string not 2 characters long");
WinDrawChars(lunarDayStr, StrLen(lunarDayStr), drawX, drawY);
}
WinPopDrawState();
} // DrawLunarDateText
/***********************************************************************
*
* FUNCTION: DrawMonth
*
* DESCRIPTION: Draw the month object.
*
* PARAMETERS: monthP - pointer to month object to draw
* selectDay - if true, draw "today" selected if possible
*
* RETURNED: nothing
*
* HISTORY:
* 04/08/96 rsf Created by Roger Flores.
* 08/26/99 kwk Use DateTemplateToAscii to get the DOW first letter.
* 10/18/99 gap Get DOW labels from daysOfWeekInitialsStrID resource and
* use StartDayOfWeek to determine which letter is start day.
* 10/31/99 jmp Eliminate WinInvertRectangle(); draw day as selected instead.
* Also, always call DrawAppointmentsInMonth(), as DrawMonth()
* was always followed by that call -- helps consolidate various
* drawing problems.
* 11/14/99 jmp Updated the drawing such that non-selectable areas of the MonthView
* are in standard Form colors while selectable areas use control-
* style colors. Also, added selectDay argument to allow today's
* date to either by drawn selected or not.
* 2002-10-22 CS Lunar View has slightly different margins for date
* numbers, and doesn't display appointments.
* 2002-10-23 CS Call DrawLunarDateText to draw Chinese lunar date
* text below Gregorian date text.
*
***********************************************************************/
static void DrawMonth (MonthPtr monthP, Boolean selectDay)
{
Int16 drawX, drawY;
Int16 cellWidth, cellHeight;
Int16 charWidth;
Int16 leftMargin, topMargin;
Int16 lineHeight;
Int16 lastDay;
Char dowTemplate[] = "^1s";
Char dayInAscii[3];
UInt16 dow;
UInt16 i;
Int16 x, y;
DateTimeType today;
RectangleType r;
UInt8 dayOfWeek;
Char * dayLabels;
UInt16 labelLength;
Char* label;
WinPushDrawState();
WinSetBackColor(UIColorGetTableEntryIndex(UIFormFill));
WinSetForeColor(UIColorGetTableEntryIndex(UIObjectForeground));
WinSetTextColor(UIColorGetTableEntryIndex(UIObjectForeground));
FntSetFont (boldFont);
// Make sure the "unselectable" parts of the MonthView are
// drawn in the proper colors first.
WinEraseRectangle (&monthP->bounds, 0);
cellWidth = monthP->bounds.extent.x / daysInWeek;
cellHeight = monthP->bounds.extent.y / linesInMonthPlusTitle;
// Get the resource that contains the first letter of each day.
dayLabels = MemHandleLock (DmGetResource (strRsc, daysOfWeekInitialsStrID));
// Calculate length of one item in string */
labelLength = StrLen (dayLabels) / daysInWeek;
// Draw the days of the week labels right justified to the number columns
// Be sure to draw the labels with respect to current setting of StartDayOfWeek. Somes locales
// consider Monday the first day while others use Sunday. There is also a user preference
// selection in Prefs app/Formats panelthat will allow the user to change first day of week.
drawY = monthP->bounds.topLeft.y + (cellHeight - FntLineHeight()) / 2;
for (i = 0; i <= daysInWeek; i++)
{
dayOfWeek = (i + StartDayOfWeek) % daysInWeek;
label = &dayLabels[labelLength * dayOfWeek];
drawX = monthP->bounds.topLeft.x + (cellWidth * i) + ((cellWidth - FntCharsWidth (label, labelLength)) / 2);
WinDrawChars (label, labelLength, drawX, drawY);
}
// Unlock the day of week label resource now that we are done with it.
MemPtrUnlock (dayLabels);
// Set the background color behind the grid in control-style colors since
// the grid is selectable.
WinSetBackColor(UIColorGetTableEntryIndex(UIObjectFill));
RctCopyRectangle(&monthP->bounds, &r);
r.topLeft.y += cellHeight;
r.extent.y -= cellHeight;
WinEraseRectangle (&r, 0);
// Draw the grid. Change the foreground color temporarily to get the right effect,
// and put it back when we're done.
WinSetForeColor(WinRGBToIndex(&colorLine));
x = monthP->bounds.topLeft.x;
y = monthP->bounds.topLeft.y + cellHeight;
for (i = 0; i < daysInWeek + 1; i++)
{
WinDrawLine (x, y, x, y + (cellHeight * maxWeeksInMonth));
x += cellWidth;
}
x = monthP->bounds.topLeft.x;
for (i = 0; i < maxWeeksInMonth + 1; i++)
{
WinDrawLine (x, y, x + (cellWidth * daysInWeek) , y);
y += cellHeight;
}
WinSetForeColor(UIColorGetTableEntryIndex(UIObjectForeground));
// Draw the days of the month.
if (pMonthViewButtonID == MonthLunarViewButton)
{
FntSetFont ((FontID)arabicNumeralFontID);
leftMargin = dateTextLeftMarginLunarView;
topMargin = dateTextTopMarginLunarView;
}
else
{
FntSetFont (stdFont);
leftMargin = dateTextLeftMarginMonthView;
topMargin = dateTextTopMarginMonthView;
}
charWidth = FntCharWidth('0');
dow = FirstDayOfMonth (monthP);
drawX = monthP->bounds.topLeft.x + (dow * cellWidth) + leftMargin;
drawY = monthP->bounds.topLeft.y + cellHeight + topMargin;
lineHeight = FntLineHeight();
lastDay = DaysInMonth(monthP->month, monthP->year);
for (i=1; i <= lastDay; i++, dow++)
{
if (dow == daysInWeek)
{
drawX = monthP->bounds.topLeft.x + leftMargin;
drawY += cellHeight;
dow = 0;
}
StrIToA (dayInAscii, i);
WinDrawChars (dayInAscii,
(i < 10) ? 1 : 2,
// (i < 10) ? drawX + charWidth : drawX,
drawX,
drawY);
if (pMonthViewButtonID == MonthLunarViewButton)
{
DrawLunarDateText(monthP, i, drawX, drawY + lineHeight);
}
drawX += cellWidth;
}
// Display a rectangle around today's day if it's visible.
TimSecondsToDateTime(TimGetSeconds(), &today);
if (TodayIsVisible(monthP, today) && selectDay)
{
GetDaySelectionBounds(monthP, today.day, &r);
MonthDrawInversionEffect (&r, 0);
}
if (pMonthViewButtonID == MonthMonthViewButton)
{
DrawAppointmentsInMonth (monthP);
}
WinPopDrawState ();
}
/***********************************************************************
*
* FUNCTION: MapPointToItem
*
* DESCRIPTION: Return return the item at x, y.
*
* PARAMETERS: x, y - coordinate
* r - the bounds of the item area (not the MTWTFSS area)
*
* RETURNED: item number (doesn't check for invalid bounds!)
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* roger 11/15/94 Initial Revision
*
***********************************************************************/
static Int16 MapPointToItem (Int16 x, Int16 y, RectanglePtr r)
{
Int16 itemNumber;
itemNumber = daysInWeek * (((y - r->topLeft.y) /
(r->extent.y / linesInMonthPlusTitle)) - 1);
itemNumber += ((x - r->topLeft.x) / (r->extent.x / daysInWeek));
return itemNumber;
}
/***********************************************************************
*
* FUNCTION: MonthViewGetMonthPtr
*
* DESCRIPTION: This routine returns a pointer to the month object.
*
* PARAMETERS: nothing
*
* RETURNED: pointer to a MonthType structure
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 4/10/96 Initial Revision
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -