diff --git a/components/tvplanit/source/vpcontactgridpainter.pas b/components/tvplanit/source/vpcontactgridpainter.pas index 55263b155..fd5b1e0bb 100644 --- a/components/tvplanit/source/vpcontactgridpainter.pas +++ b/components/tvplanit/source/vpcontactgridpainter.pas @@ -15,6 +15,8 @@ type FContactGrid: TVpContactGrid; FLabelWidth: Integer; FScaledTextMargin: Integer; + FAnchorMargin: Integer; + FTextColWidth: Integer; // local variables of the original TVpContactGrid method // PhoneLblWidth: Integer; @@ -32,6 +34,11 @@ type function CalcHeaderRect(ABitmap: TBitmap): TRect; function CalcInitialAnchor(ABitmap: TBitmap): TPoint; function CalcLabelWidth(ABitmap: TBitmap): Integer; + procedure CalcNextColumnAnchor(ABitmap: TBitmap; const AWholeRect: TRect; + var Anchor: TPoint); + function CalcTextColWidth(ABitmap: TBitmap): Integer; + function NewColumnNeeded(AWholeRect: TRect; Anchor: TPoint): Boolean; + function NewPageNeeded(Anchor: TPoint): Boolean; protected procedure Clear; @@ -103,19 +110,14 @@ begin end; function TVpContactGridPainter.CalcInitialAnchor(ABitmap: TBitmap): TPoint; -var - anchorMargin: Integer; - px2: Integer; begin - px2 := round(Scale*2); - anchorMargin := px2 + FScaledTextMargin * 2; case Angle of ra0, ra90: - Result := Point(anchorMargin, anchorMargin); + Result := Point(FAnchorMargin, FAnchorMargin); ra180: - Result := Point(WidthOf(RenderIn) - ABitmap.Width - anchorMargin, ABitmap.Height - anchorMargin); + Result := Point(WidthOf(RenderIn) - ABitmap.Width - FAnchorMargin, ABitmap.Height - FAnchorMargin); ra270: - Result := Point(anchorMargin, HeightOf(RenderIn) - ABitmap.Height - anchorMargin); + Result := Point(FAnchorMargin, HeightOf(RenderIn) - ABitmap.Height - FAnchorMargin); end; end; @@ -139,6 +141,34 @@ begin end; end; +{ Calculates the anchor for the next column. AWholeRect is the rectangle of + the last contact drawn in the previous column. } +procedure TVpContactGridPainter.CalcNextColumnAnchor(ABitmap: TBitmap; + const AWholeRect: TRect; var Anchor: TPoint); +var + colDist: Integer; +begin + colDist := FContactGrid.BarWidth + 1 + FScaledTextMargin * 3; // wp: why? + case Angle of + ra0: + Anchor := Point(Anchor.x + AWholeRect.Right + colDist, FAnchorMargin); + ra90: + Anchor := Point(FAnchorMargin, Anchor.y + AWholeRect.Bottom + colDist); + ra180: + Anchor := Point(Anchor.x - (AWholeRect.Right + colDist), ABitmap.Height - FAnchorMargin); + ra270: + Anchor := Point(FAnchorMargin, Anchor.y - (AWholeRect.Bottom + colDist)); + end; +end; + +function TVpContactGridPainter.CalcTextColWidth(ABitmap: TBitmap): Integer; +begin + case Angle of + ra0, ra180: Result := ABitmap.Width; + ra90, ra270: Result := ABitmap.Height; + end; +end; + procedure TVpContactGridPainter.Clear; var I: Integer; @@ -376,18 +406,12 @@ function TVpContactGridPainter.DrawContactRows(ABitmap: TBitmap; var ACol, ARecsInCol: Integer; var AContactRec: TVpContactRec): Boolean; var s: String; - px2: Integer; + spacing: Integer; textColWidth: Integer; newCol: Boolean; begin Result := true; - case Angle of - ra0, ra180: textColWidth := ABitmap.Width; - ra90, ra270: textColWidth := ABitmap.Height; - end; - px2 := Round(2 * Scale); // Size of two scaled pixels. - // Set font and colors for the contact data ABitmap.Canvas.Font.Assign(FContactGrid.Font); ABitmap.Canvas.Font.PixelsPerInch := RenderCanvas.Font.PixelsPerInch; @@ -432,52 +456,17 @@ begin // If this record is too big to fit in the remaining area of this column, // then slide over to the top of the next column } - newCol := false; - if ARecsInCol > 0 then - case Angle of - ra0: - if (RenderIn.Top + Anchor.y + AWholeRect.Bottom >= RenderIn.Bottom - FScaledTextMargin * 3) then - begin - newCol := true; - Anchor := Point( - Anchor.x + AWholeRect.Right + FContactGrid.BarWidth + 1 + FScaledTextMargin * 3, - px2 + FScaledTextMargin * 2 - ); - if DisplayOnly and (Anchor.X + textColWidth >= RenderIn.Right) then - Result := false; - end; - ra90: - if (Anchor.x + RenderIn.Left + WidthOf(AWholeRect) > RenderIn.Right - FScaledTextMargin * 3) then - begin - newCol := true; - Anchor.x := px2 + FScaledTextMargin * 2; - Anchor.y := Anchor.y + AWholeRect.Bottom + FContactGrid.BarWidth + 1 + FScaledTextMargin * 3; - if DisplayOnly and (Anchor.y + textColWidth >= RenderIn.Bottom) then - Result := false; - end; - ra180: - if (Anchor.y + RenderIn.Top - HeightOf(AWholeRect) <= RenderIn.Top + FScaledTextMargin * 3) then - begin - newCol := true; - Anchor.x := Anchor.x - (AWholeRect.Right + FContactGrid.BarWidth + 1 + FScaledTextMargin * 3); - Anchor.y := ABitmap.Height - px2 - FScaledTextMargin * 2; - if DisplayOnly and (Anchor.x + textColWidth < RenderIn.Left) then - Result := false; - end; - ra270: - if (Anchor.x + RenderIn.Left + WidthOf(AWholeRect) >= RenderIn.Right - FScaledTextMargin * 3) then - begin - newCol := true; - Anchor.x := px2 + FScaledTextMargin * 2; - Anchor.y := Anchor.y - (AWholeRect.Bottom + FContactGrid.BarWidth + 1 + FScaledTextMargin * 3); - if DisplayOnly and (Anchor.y + textColWidth <= RenderIn.Top) then - Result := false; - end; - end; - + newCol := (ARecsInCol > 0) and NewColumnNeeded(AWholeRect, Anchor); if newCol then begin - // New columns: Increment the column counter. Store the counter of records + CalcNextColumnAnchor(ABitmap, AWholeRect, Anchor); + if DisplayOnly and NewPageNeeded(Anchor) then + begin + Result := false; // to do: fix creating a new page + exit; + end; + + // New columns Increment the column counter. Store the counter of records // in the 1st column and reset it for the new column. if ACol = 1 then TVpContactGridOpener(FContactGrid).cgCol1RecCount := ARecsInCol; @@ -489,11 +478,12 @@ begin inc(ARecsInCol); // Add some spacing between records + spacing := FScaledTextMargin * 2; case Angle of - ra0 : AWholeRect.Bottom := AWholeRect.Bottom + FScaledTextMargin * 2; - ra90 : AWholeRect.Left := AWholeRect.Left - FScaledTextMargin * 2; - ra180 : AWholeRect.Top := AWholeRect.Top - FScaledTextMargin * 2; - ra270 : AWholeRect.Right := AWholeRect.Right + FScaledTextMargin * 2; + ra0 : AWholeRect.Bottom := AWholeRect.Bottom + spacing; + ra90 : AWholeRect.Left := AWholeRect.Left - spacing; + ra180 : AWholeRect.Top := AWholeRect.Top - spacing; + ra270 : AWholeRect.Right := AWholeRect.Right + spacing; end; // Move data rectangles to the position at which they will appear on @@ -514,8 +504,7 @@ end; procedure TVpContactGridPainter.DrawContacts; var Anchor: TPoint; - I, W: Integer; - Str: string; + I: Integer; TmpBmp: TBitmap; contact: TVpContact; Col, RecsInCol: Integer; @@ -524,8 +513,7 @@ var CR: TVpContactRec; HeadRect: TRect = (Left:0; Top:0; Right:0; Bottom:0); contactCount: Integer; - anchorMargin: Integer; - px2, px4: Integer; // Scaled 2, 4 pixels + px4: Integer; // Scaled 4 pixels begin // If the component is sufficiently small then no sense in painting it if (FContactGrid.Height < 20) then @@ -543,7 +531,6 @@ begin oldCol1RecCount := TVpContactGridOpener(FContactGrid).cgCol1RecCount; TVpContactGridOpener(FContactGrid).FVisibleContacts := 0; TVpContactGridOpener(FContactGrid).cgCol1RecCount := 0; - px2 := Round(2 * Scale); px4 := Round(4 * Scale); // Create a temporary bitmap for painting the contact items @@ -557,6 +544,9 @@ begin TmpBmp.Width := RealHeight - FScaledTextMargin * 2; end; + // Calculate the width of each contact column (without spacers) + FTextColWidth := CalcTextColWidth(TmpBmp); + // Calculate max label width FLabelWidth := CalcLabelWidth(TmpBmp); @@ -793,6 +783,41 @@ begin end; end; +{ Determines whether the contact rectange AWholeRect execeeds the page height + and a new column should be started. } +function TVpContactGridPainter.NewColumnNeeded(AWholeRect: TRect; + Anchor: TPoint): Boolean; +var + bottomMargin: Integer; +begin + bottomMargin := FScaledTextMargin * 2; + case Angle of + ra0: + Result := (RenderIn.Top + Anchor.y + AWholeRect.Bottom >= RenderIn.Bottom - bottomMargin); + ra90: + Result := (Anchor.x + RenderIn.Left + WidthOf(AWholeRect) > RenderIn.Right - bottomMargin); + ra180: + Result := (Anchor.y + RenderIn.Top - HeightOf(AWholeRect) <= RenderIn.Top + bottomMargin); + ra270: + Result := (Anchor.x + RenderIn.Left + WidthOf(AWholeRect) >= RenderIn.Right - bottomMargin); + end; +end; + +{ Determines whether the new anchor is outside the current page. } +function TVpContactGridPainter.NewPageNeeded(Anchor: TPoint): Boolean; +begin + case Angle of + ra0: + Result := (Anchor.X + FTextColWidth >= RenderIn.Right); + ra90: + Result := (Anchor.y + FTextColWidth >= RenderIn.Bottom); + ra180: + Result := (Anchor.x + FTextColWidth < RenderIn.Left); + ra270: + Result := (Anchor.y + FTextColWidth <= RenderIn.Top); + end; +end; + { Copy the drawn contact record from the bitmap to the rendering canvas. } procedure TVpContactGridPainter.PaintContactBitmap(ABitmap: TBitmap; AContact: TVpContact; Anchor: TPoint; AWholeRect: TRect); @@ -804,26 +829,30 @@ var begin // Calculate the destination rectangle on the rendering canvas. case Angle of - ra0 : R := Rect(Anchor.X + AWholeRect.Left + RenderIn.Left, - Anchor.Y + AWholeRect.Top + RenderIn.Top, - Anchor.X + ABitmap.Width + RenderIn.Left, - Anchor.Y + AWholeRect.Bottom + RenderIn.Top - ); - ra90 : R := Rect(AWholeRect.Left + RenderIn.Left - Anchor.X, - Anchor.Y + AWholeRect.Top + RenderIn.Top, - AWholeRect.Right + RenderIn.Left - Anchor.X, - Anchor.Y + AWholeRect.Bottom + RenderIn.Top - ); - ra180 : R := Rect(Anchor.X + AWholeRect.Left + RenderIn.Left, - Anchor.Y - HeightOf(AWholeRect) + RenderIn.Top, - Anchor.X + ABitmap.Width + RenderIn.Left, - Anchor.Y + RenderIn.Top - ); - ra270 : R := Rect(Anchor.X + RenderIn.Left, - Anchor.Y + RenderIn.Top, - Anchor.X + RenderIn.Left + WidthOf(AWholeRect), - Anchor.Y + RenderIn.Top + HeightOf(AWholeRect) - ); + ra0: + R := Rect(Anchor.X + AWholeRect.Left + RenderIn.Left, + Anchor.Y + AWholeRect.Top + RenderIn.Top, + Anchor.X + ABitmap.Width + RenderIn.Left, + Anchor.Y + AWholeRect.Bottom + RenderIn.Top + ); + ra90: + R := Rect(AWholeRect.Left + RenderIn.Left - Anchor.X, + Anchor.Y + AWholeRect.Top + RenderIn.Top, + AWholeRect.Right + RenderIn.Left - Anchor.X, + Anchor.Y + AWholeRect.Bottom + RenderIn.Top + ); + ra180: + R := Rect(Anchor.X + AWholeRect.Left + RenderIn.Left, + Anchor.Y - HeightOf(AWholeRect) + RenderIn.Top, + Anchor.X + ABitmap.Width + RenderIn.Left, + Anchor.Y + RenderIn.Top + ); + ra270: + R := Rect(Anchor.X + RenderIn.Left, + Anchor.Y + RenderIn.Top, + Anchor.X + RenderIn.Left + WidthOf(AWholeRect), + Anchor.Y + RenderIn.Top + HeightOf(AWholeRect) + ); end; // Copy the auxiliary contact bitmap from AWholeRect to R into the @@ -893,11 +922,14 @@ begin end; procedure TVpContactGridPainter.SetMeasurements; +const + MARGIN = 2; var numCols: Integer; begin inherited; FScaledTextMargin := round(FContactGrid.TextMargin * Scale); + FAnchorMargin := round(Scale * MARGIN) + FScaledTextMargin * 2; numCols := FContactGrid.PrintNumColumns; if DisplayOnly and (numCols > 0) then