Function and operator implementations

The function implementations are described here in the order they appear in GMCGraphics.C.

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);
      }

GetGeometricBounds

This function overrides the
MGraphic::GetGeometricBounds function.

      TGRect                  
      AMonthGraphic::GetGeometricBounds () const
      {
          TGRect bounds(TGPoint::kOrigin,fSize);
          TGArea tbounds (bounds);
          
          tbounds.TransformBy (fTransform);
              
          return tbounds.GetBounds ();
      }

GetLooseFitBounds function

This function overrides the
MGraphic::GetLooseFitBounds function.

      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 ();
      }

Draw function

This funciton calls HandleDraw.

      void
      AMonthGraphic::Draw( TGrafPort& port ) const
      {
          ( ( AMonthGraphic * ) this ) -> HandleDraw( port );
      }

HandleDraw function

The HandleDraw function is called by the Draw function. It draws the day numbers and any other shading specific to the days. Areas of Improvement: The MoveForward and MoveBackward methods could do the drawing into an offscreen buffer. Here we would just blast bits to the screen that should make the display appear to be a lot faster than it is now.

      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;
      }


[Contents] [Previous] [Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.

Generated with WebMaker