Init function
The Init function is called by the constructor. It provides private fields with values, sets up the date, initializes the calendar with the date, gets the day and month text to be displayed, and sets the initial size of the calendar.
Copyright © Taligent, Inc. 1995
void
AMonthGraphic::Init()
{
GridMargin = 4.0;
GridTopLeft = TGPoint( 11.0, 43.0 );
GridCellSize = TGPoint( 34.0,28.0 );
GridBottomRight = TGPoint(GridTopLeft.fX+( 7*GridCellSize.fX ),
GridTopLeft.fY+( 6*GridCellSize.fY ) );
GridRect = TGRect( GridTopLeft, GridBottomRight );
// Get today's date
time_t seconds = time( NULL );
struct tm *mytime = localtime( &seconds );
fStartDate.SetField( TCalendar::kDayInMonth,mytime->tm_mday );
fStartDate.SetField( TCalendar::kMonthInYear, mytime->tm_mon+1 );
fStartDate.SetField( TCalendar::kYearInEra,mytime->tm_year+1900 );
// Set the calendar to start on the first of the month
fCalendar.SetField(TCalendar::kDayInMonth,1);
// Get the correct text for the day of the week and month to be displayed
long value = fCalendar.GetField( TCalendar::kMonthInYear );
if (value > 12 || value < 0) value = 1;
const char *monthname = GMCmonthnames[ value ];
char datestring[64]={0};
sprintf(datestring,"%s - %ld",monthname, fCalendar.GetField(
TCalendar::kYearInEra ) );
fdateLabel = new TTextDisplay (TStandardText(datestring));
fdateLabel->SetColor (TTextColorStyle::GetBlack());
fdateLabel->SetOrigin(TGPoint (14.0,26.0));
fdateLabel->SetPointSize(TFontPointSizeStyle(fMonthFontSize));
// Create day of week labels for each column
fColumn0Label = CreateDayLabel( 0 );
fColumn1Label = CreateDayLabel( 1 );
fColumn2Label = CreateDayLabel( 2 );
fColumn3Label = CreateDayLabel( 3 );
fColumn4Label = CreateDayLabel( 4 );
fColumn5Label = CreateDayLabel( 5 );
fColumn6Label = CreateDayLabel( 6 );
//Fill the initial text array
for ( long counter = 0; counter < 32; counter++ )
{
char daystring[12]={0};
sprintf( daystring, %d, counter );
GDayTextArray[counter] = new TTextDisplay( TStandardText( daystring ) );
( GDayTextArray[counter] )->SetPointSize( TFontPointSizeStyle( fNumberFontSize ) );
}
// Set initial size of calendar
SetSize(fSize);
}
Copy operator
The Copy operator allows AMonthGraphic to be created from another AMonthGraphic.
AMonthGraphic&
AMonthGraphic::operator=(const AMonthGraphic& other)
{
if (&other != this)
{
MGraphic::operator=( other );
fSize = other.fSize;
Init();
}
return *this;
}
Streaming operators
The streaming operators get used if the class is extended to stream out data. The streaming operators detect data that was streamed out by an older version of the class instance to stream that data in correctly.
TStream&
AMonthGraphic::operator>>=(TStream& toStream) const
{
WriteVersion(toStream);
MGraphic::operator>>=(toStream);
fSize >>= toStream;
return toStream;
}
TStream&
AMonthGraphic::operator<<=(TStream& fromStream)
{
VersionInfo version = ReadVersion(fromStream);
if (version == kOriginalVersion)
{
MGraphic::operator<<=(fromStream);
fSize <<= fromStream;
Init();
}
return fromStream;
}
SetSize function
This function is called by Init to set the initial size of the calendar. This function is also called whenever the window is resized.
void AMonthGraphic::SetSize(const TGPoint &size)
{
fSize = size;
Invalidate();
}
Invalidate
This function is called by SetSize so that the window will redraw whenever it has been resized. The day of week labels are recalculated according to the new size of the window.
void AMonthGraphic::Invalidate()
{
CalculateParameters();
CalculateDayLabels();
// Make the view draw itself
fImageNeedsUpdate = TRUE;
}
SetDate function
This function is called whenever the value stored in the model changes. It gets the date to display from the model and then invalidates so that the window is redraws.
void
AMonthGraphic::SetDate( const TGregorianCalendar& newCalendar)
{
// Make the view draw itself
fImageNeedsUpdate = TRUE;
fCalendar = newCalendar;
// Re-calculate the month label
CalculateDayLabels();
// Invalidate the view so it gets drawn
Invalidate();
}
CalibrateFontSizes
This function is called by CalculateFontSizes as part of the font size calculations.
void AMonthGraphic::CalibrateFontSizes(const long sizeIndex)
{
// If the new index is the same as the old, do nothing
if (sizeIndex == fSizeIndex)
return;
switch (sizeIndex)
{
case 100:
fNumberFontSize = 8.0;
fMonthFontSize = 10.0;
break;
case 140:
fNumberFontSize = 9.0;
fMonthFontSize = 12.0;
break;
case 378:
fNumberFontSize = 10.0;
fMonthFontSize = 14.0;
break;
case 500:
fNumberFontSize = 12.0;
fMonthFontSize = 18.0;
break;
default:
fNumberFontSize = 18.0;
fMonthFontSize = 24.0;
break;
}
// Set the point size of the number displays
for (long counter=0; counter < 32; counter++)
{
GDayTextArray[counter]->SetPointSize(TFontPointSizeStyle(fNumberFontSize));
}
fSizeIndex = sizeIndex;
}
CalcuateFontSizes function
This function is called by CalculateParameters.
void
AMonthGraphic::CalculateFontSizes()
{
TGRect bounds = GetLooseFitBounds();
long sizeIndex = 100;
if (bounds.GetWidth() < 100.0)
{
sizeIndex = 100;
}
else if (bounds.GetWidth() < 140.0)
{
sizeIndex = 140;
}
else if (bounds.GetWidth() < 378.0)
{
sizeIndex = 378;
}
else if ( bounds.GetWidth90 < 500.0 )
{
sizeIndex = 500;
}
else
{
sizeIndex = 1000;
}
CalibrateFontSizes( sizeIndex );
}
CalculateParameters function
This function calculates the font sizes, and recalculates the grid sizes based on the clipped size of the view. This code shrinks the calendar to display within the window size.
void
AMonthGraphic::CalculateParameters()
{
CalculateFontSizes();
TGRect bounds = GetLooseFitBounds();
GridTopLeft = TGPoint(GridMargin, fMonthFontSize+fNumberFontSize+GridMargin*3);
GridCellSize = TGPoint((bounds.GetWidth()-GridMargin*2)/7,
((bounds.GetHeight()-GridMargin*2-GridTopLeft.fY)/6));
GridBottomRight = TGPoint(GridTopLeft.fX+(7*GridCellSize.fX),
GridTopLeft.fY+(6*GridCellSize.fY));
GridRect = TGRect(GridTopLeft, GridBottomRight);
}
CalculateColumnLabel function
This function centers and calculates the size of single-line column labels when the window is resized.
void
AMonthGraphic::CalculateColumnLabel(TTextDisplay &theLabel, int theColumn)
{
TSingleLineOrientation orientation;
TGPoint origin( theColumn*GridCellSize.fX + ( GridCellSize.fX/2 ) + GridTopLeft.fX,
GridTopLeft.fY - 3.0 );
orientation.SetSegmentPlacement( TSingleLineOrientation::kMiddle );
theLabel.SetText(TStandardText(fDayNameArray[theColumn]));
theLabel.SetOrigin( TGPoint ( theColumn*GridCellSize.fX +
GridTopLeft.fX,GridTopLeft.fY - 3.0 ) );
theLabel.SetPointSize(TFontPointSizeStyle(fNumberFontSize));
theLabel.SetLineOrientation( orientation );
}
CreateDayLabels function
This function calculates the day labels based on the size of the width of the columns.
void
AMonthGraphic::CalculateDayLabels()
{
char **daynameArray;
char **monthnameArray;
// determine the array to use for weekday names based on the width of the columns.
if (GridCellSize.fX < 20.0)
{
fDayNameArray = GMCsingledaynames;
monthnameArray = GMCshortmonthnames;
} else if (GridCellSize.fX < 54.0)
{
fDayNameArray = GMCshortdaynames;
monthnameArray = GMCshortmonthnames;
} else
{
fDayNameArray = GMCdaynames;
monthnameArray = GMCmonthnames;
}
// Create and assign a name for the month label
const char *monthname = GMCmonthnames[fCalendar.GetField(TCalendar::kMonthInYear )];
char datestring[64]={0};
sprintf(datestring,"%s - %ld",monthname, fCalendar.GetField(
TCalendar::kYearInEra ) );
fdateLabel->SetText(TStandardText(datestring));
fdateLabel->SetOrigin(TGPoint (14.0,fMonthFontSize + GridMargin));
fdateLabel->SetPointSize(TFontPointSizeStyle(fMonthFontSize));
// Set up the day headings
CalculateColumnLabel(*fColumn0Label, 0);
CalculateColumnLabel(*fColumn1Label, 1);
CalculateColumnLabel(*fColumn2Label, 2);
CalculateColumnLabel(*fColumn3Label, 3);
CalculateColumnLabel(*fColumn4Label, 4);
CalculateColumnLabel(*fColumn5Label, 5);
CalculateColumnLabel(*fColumn6Label, 6);
}
CreateDayLabel function
This function determines the array to use for week names based on the column width. If the columns are less than 58 characters wide, short names are used.
TTextDisplay *AMonthGraphic::CreateDayLabel(const int column)
{
char **daynameArray;
if (GridCellSize.fX < 54.0)
daynameArray = GMCshortdaynames;
else
daynameArray = GMCdaynames;
TTextDisplay *newLabel = new TTextDisplay(TStandardText( daynameArray[column] ) );
newLabel->SetColor( TTextColorStyle::GetBlack() );
newLabel->SetOrigin( TGPoint ( column*GridCellSize.fX +GridTopLeft.fX,40.0 ) );
newLabel->SetPointSize( TFontPointSizeStyle( fNumberFontSize ) );
return newLabel;
}
TransformBy function
This function overrides the MGraphic::TransformBy function.
void AMonthGraphic::TransformBy (const TGrafMatrix& tform) { fTransform.ConcatWith (tform); }
TGRect AMonthGraphic::GetGeometricBounds () const { TGRect bounds(TGPoint::kOrigin,fSize); TGArea tbounds (bounds); tbounds.TransformBy (fTransform); return tbounds.GetBounds (); }
TGRect AMonthGraphic::GetLooseFitBounds () const { TGRect bounds( TGPoint::kOrigin,fSize ); const TGrafBundle *b = GetBundle (); if ( b ) { const TPen *pen = b->GetFramePen (); if ( pen ) { GCoordinate penAdjust = pen->GetPenWidth (); bounds.Inset( TGPoint (-penAdjust/2.,-penAdjust/2.) ); } } TGArea tbounds (bounds); tbounds.TransformBy (fTransform); return tbounds.GetBounds (); }
void AMonthGraphic::Draw( TGrafPort& port ) const { ( ( AMonthGraphic * ) this ) -> HandleDraw( port ); }
void AMonthGraphic::Draw(TGrafPort &port) const { TLinkedModelMatrixPort matrixPort (&port, fTransform); TLinkedBundlePort bundlePort (&matrixPort, GetBundle()); // Recalculate gid sizes based on the clipped size of the view. // The calendar can be shrunk to fit within the size of the view. TGRect clipRect = GetLooseFitBounds(); ((AMonthGraphic *)this)->UpdateView(bundlePort); //Create a bundle that uses a light background fill and a solid pen width of 1.0 TGrafBundle grafBundle1(khoneydew, kblack); grafBundle1.AdoptFramePen( new TSolidPen( 1.0, TPen::kInsetFrame ) ); port.Draw( clipRect, grafBundle1 ); // Draw the outline that holds the grid TGrafBundle grafBundle2(kwhite, kblack); grafBundle2.AdoptFramePen(new TSolidPen(1.0, TPen::kInsetFrame)); port.Draw(GridRect, grafBundle2); // Draw the text label for the month fdateLabel->Draw(port); // Draw the day labels fColumn0Label->Draw(port); fColumn1Label->Draw(port); fColumn2Label->Draw(port); fColumn3Label->Draw(port); fColumn4Label->Draw(port); fColumn5Label->Draw(port); fColumn6Label->Draw(port); // Draw the vertical lines in the grid. GCoordinate xStart = GridTopLeft.fX+1.0; GCoordinate xEnd = GridBottomRight.fX-1.0; GCoordinate yStart = GridTopLeft.fY+1.0; GCoordinate yEnd = GridBottomRight.fY-1.0; TGrafBundle lineBundle(kgray85, kgray85); lineBundle.AdoptFramePen(new TSolidPen(1.0, TPen::kCenterFrame)); int counter = 0; //Create the canonical vertical line TGLine verticalLine( TGPoint( 0,0 ), TGPoint( 0, yEnd-yStart ) ) ; Copyright © Taligent, Inc. 1995 // If the cell height is greater than 12.0, draw the vertical lines if (GridCellSize.fY > 15.0) { for (counter = 1; counter < 7; counter++) { TLinkedModelMatrixPort transPort( &port, TGrafMatrix( TGPoint( xStart + ( counter*GridCellSize.fZ ) -2, yStart ))); transport.Draw( verticalLine, lineBundle ); } } // Draw the 5 horizontal lines in the grid. TGLine horizontalLine( TGPoint( 0,0 ) ), TGPoint( xEnd-xStart, 0 ) ); for (counter = 1; counter < 6; counter++) { TLinkedModelMatrixPort transPort( &port, TGrafMatrix( TGPoint( xStart, yStart+( counter*GridCellSize.fY ) ) ) ); transport.Draw( horizontalLine, lineBundle ); } // Get the day of the week of the first day in the month int dow = (int)fCalendar.GetField(TCalendar::kDayInWeek); // Get the number of days in the month long maxDays = GMCDaysInMonth( (int)fCalendar.GetField( TCalendar::kMonthInYear ), (int)fCalendar.GetField(TCalendar::kYearInEra)); int currentRow = 0; int currentColumn = 0; // Draw the values of the current selection int dayctr = 0; int tempDow = dow; // Go through each day of the month and determine the cell it should display in, // put a number in the top-left corner of the cell. TTextDisplay numberText; for (dayctr = 0; dayctr < dim; dayctr++) { // Add a extra to the font height GCoordinate columnX = tempDow * GridCellSize.fX + GridTopLeft.fX + 2.0; GCoordinate rowY = currentRow * GridCellSize.fY + GridTopLeft.fY + 1.0 + fNumberFontSize; TLinkedModelMatrixPort matrixPort( &port ), TGrafMatrix( TGPoint( columnX, rowY ))); // If the day and month correspond to doday's date, draw the day in blue if ((dayctr+1 == fStartDate.GetField(TCalendar::kDayInMonth)) && (fCalendar.GetField(TCalendar::kMonthInYear) == fStartDate.GetField(TCalendar::kMonthInYear)) && (fCalendar.GetField(TCalendar::kYearInEra) == fStartDate.GetField(TCalendar::kYearInEra) == fStartDate.GetField( TCalendar::kYearInEra ) ) ) { TGrafBundle aBundle(TRGBColor(1,0,0),TRGBColor(1,0,0)); TLinkedBundlePort bundlePort (&matrixPort, &aBundle); GDayTextArray[dayctr+1]->Draw(bundlePort); } elseif ((tempDow == 0) || (tempDow == 6)) { // If the day is a weekend day, then draw it in blue TGrafBundle aBundle(new TColorPaint(TRGBColor(1,1,1)), TAttributeState::kFillAndFrame); TLinkedBundlePort bundlePort (&matrixPort, &aBundle); GDayTextArray[dayctr+1]->Draw(bundlePort); } else { GDayTextArray[dayctr+1]->Draw(matrixPort); } // Increment the day of the week. // If it is already saturday == 6, reset the day to sunday == 0 if (tempDow == 6) { tempDow = 0; currentRow++; }else tempDow++; } fImageNeedsUpdate = FALSE; }