tvplanit: More refactoring of TVpContactGridPainter

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8525 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2022-10-08 14:34:02 +00:00
parent 3da97ca4d6
commit 03cc304f83

View File

@ -15,6 +15,8 @@ type
FContactGrid: TVpContactGrid; FContactGrid: TVpContactGrid;
FLabelWidth: Integer; FLabelWidth: Integer;
FScaledTextMargin: Integer; FScaledTextMargin: Integer;
FAnchorMargin: Integer;
FTextColWidth: Integer;
// local variables of the original TVpContactGrid method // local variables of the original TVpContactGrid method
// PhoneLblWidth: Integer; // PhoneLblWidth: Integer;
@ -32,6 +34,11 @@ type
function CalcHeaderRect(ABitmap: TBitmap): TRect; function CalcHeaderRect(ABitmap: TBitmap): TRect;
function CalcInitialAnchor(ABitmap: TBitmap): TPoint; function CalcInitialAnchor(ABitmap: TBitmap): TPoint;
function CalcLabelWidth(ABitmap: TBitmap): Integer; 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 protected
procedure Clear; procedure Clear;
@ -103,19 +110,14 @@ begin
end; end;
function TVpContactGridPainter.CalcInitialAnchor(ABitmap: TBitmap): TPoint; function TVpContactGridPainter.CalcInitialAnchor(ABitmap: TBitmap): TPoint;
var
anchorMargin: Integer;
px2: Integer;
begin begin
px2 := round(Scale*2);
anchorMargin := px2 + FScaledTextMargin * 2;
case Angle of case Angle of
ra0, ra90: ra0, ra90:
Result := Point(anchorMargin, anchorMargin); Result := Point(FAnchorMargin, FAnchorMargin);
ra180: ra180:
Result := Point(WidthOf(RenderIn) - ABitmap.Width - anchorMargin, ABitmap.Height - anchorMargin); Result := Point(WidthOf(RenderIn) - ABitmap.Width - FAnchorMargin, ABitmap.Height - FAnchorMargin);
ra270: ra270:
Result := Point(anchorMargin, HeightOf(RenderIn) - ABitmap.Height - anchorMargin); Result := Point(FAnchorMargin, HeightOf(RenderIn) - ABitmap.Height - FAnchorMargin);
end; end;
end; end;
@ -139,6 +141,34 @@ begin
end; end;
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; procedure TVpContactGridPainter.Clear;
var var
I: Integer; I: Integer;
@ -376,18 +406,12 @@ function TVpContactGridPainter.DrawContactRows(ABitmap: TBitmap;
var ACol, ARecsInCol: Integer; var AContactRec: TVpContactRec): Boolean; var ACol, ARecsInCol: Integer; var AContactRec: TVpContactRec): Boolean;
var var
s: String; s: String;
px2: Integer; spacing: Integer;
textColWidth: Integer; textColWidth: Integer;
newCol: Boolean; newCol: Boolean;
begin begin
Result := true; 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 // Set font and colors for the contact data
ABitmap.Canvas.Font.Assign(FContactGrid.Font); ABitmap.Canvas.Font.Assign(FContactGrid.Font);
ABitmap.Canvas.Font.PixelsPerInch := RenderCanvas.Font.PixelsPerInch; 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, // 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 } // then slide over to the top of the next column }
newCol := false; newCol := (ARecsInCol > 0) and NewColumnNeeded(AWholeRect, Anchor);
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;
if newCol then if newCol then
begin 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. // in the 1st column and reset it for the new column.
if ACol = 1 then if ACol = 1 then
TVpContactGridOpener(FContactGrid).cgCol1RecCount := ARecsInCol; TVpContactGridOpener(FContactGrid).cgCol1RecCount := ARecsInCol;
@ -489,11 +478,12 @@ begin
inc(ARecsInCol); inc(ARecsInCol);
// Add some spacing between records // Add some spacing between records
spacing := FScaledTextMargin * 2;
case Angle of case Angle of
ra0 : AWholeRect.Bottom := AWholeRect.Bottom + FScaledTextMargin * 2; ra0 : AWholeRect.Bottom := AWholeRect.Bottom + spacing;
ra90 : AWholeRect.Left := AWholeRect.Left - FScaledTextMargin * 2; ra90 : AWholeRect.Left := AWholeRect.Left - spacing;
ra180 : AWholeRect.Top := AWholeRect.Top - FScaledTextMargin * 2; ra180 : AWholeRect.Top := AWholeRect.Top - spacing;
ra270 : AWholeRect.Right := AWholeRect.Right + FScaledTextMargin * 2; ra270 : AWholeRect.Right := AWholeRect.Right + spacing;
end; end;
// Move data rectangles to the position at which they will appear on // Move data rectangles to the position at which they will appear on
@ -514,8 +504,7 @@ end;
procedure TVpContactGridPainter.DrawContacts; procedure TVpContactGridPainter.DrawContacts;
var var
Anchor: TPoint; Anchor: TPoint;
I, W: Integer; I: Integer;
Str: string;
TmpBmp: TBitmap; TmpBmp: TBitmap;
contact: TVpContact; contact: TVpContact;
Col, RecsInCol: Integer; Col, RecsInCol: Integer;
@ -524,8 +513,7 @@ var
CR: TVpContactRec; CR: TVpContactRec;
HeadRect: TRect = (Left:0; Top:0; Right:0; Bottom:0); HeadRect: TRect = (Left:0; Top:0; Right:0; Bottom:0);
contactCount: Integer; contactCount: Integer;
anchorMargin: Integer; px4: Integer; // Scaled 4 pixels
px2, px4: Integer; // Scaled 2, 4 pixels
begin begin
// If the component is sufficiently small then no sense in painting it // If the component is sufficiently small then no sense in painting it
if (FContactGrid.Height < 20) then if (FContactGrid.Height < 20) then
@ -543,7 +531,6 @@ begin
oldCol1RecCount := TVpContactGridOpener(FContactGrid).cgCol1RecCount; oldCol1RecCount := TVpContactGridOpener(FContactGrid).cgCol1RecCount;
TVpContactGridOpener(FContactGrid).FVisibleContacts := 0; TVpContactGridOpener(FContactGrid).FVisibleContacts := 0;
TVpContactGridOpener(FContactGrid).cgCol1RecCount := 0; TVpContactGridOpener(FContactGrid).cgCol1RecCount := 0;
px2 := Round(2 * Scale);
px4 := Round(4 * Scale); px4 := Round(4 * Scale);
// Create a temporary bitmap for painting the contact items // Create a temporary bitmap for painting the contact items
@ -557,6 +544,9 @@ begin
TmpBmp.Width := RealHeight - FScaledTextMargin * 2; TmpBmp.Width := RealHeight - FScaledTextMargin * 2;
end; end;
// Calculate the width of each contact column (without spacers)
FTextColWidth := CalcTextColWidth(TmpBmp);
// Calculate max label width // Calculate max label width
FLabelWidth := CalcLabelWidth(TmpBmp); FLabelWidth := CalcLabelWidth(TmpBmp);
@ -793,6 +783,41 @@ begin
end; end;
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. } { Copy the drawn contact record from the bitmap to the rendering canvas. }
procedure TVpContactGridPainter.PaintContactBitmap(ABitmap: TBitmap; procedure TVpContactGridPainter.PaintContactBitmap(ABitmap: TBitmap;
AContact: TVpContact; Anchor: TPoint; AWholeRect: TRect); AContact: TVpContact; Anchor: TPoint; AWholeRect: TRect);
@ -804,26 +829,30 @@ var
begin begin
// Calculate the destination rectangle on the rendering canvas. // Calculate the destination rectangle on the rendering canvas.
case Angle of case Angle of
ra0 : R := Rect(Anchor.X + AWholeRect.Left + RenderIn.Left, ra0:
Anchor.Y + AWholeRect.Top + RenderIn.Top, R := Rect(Anchor.X + AWholeRect.Left + RenderIn.Left,
Anchor.X + ABitmap.Width + RenderIn.Left, Anchor.Y + AWholeRect.Top + RenderIn.Top,
Anchor.Y + AWholeRect.Bottom + 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, ra90:
AWholeRect.Right + RenderIn.Left - Anchor.X, R := Rect(AWholeRect.Left + RenderIn.Left - Anchor.X,
Anchor.Y + AWholeRect.Bottom + RenderIn.Top Anchor.Y + AWholeRect.Top + RenderIn.Top,
); AWholeRect.Right + RenderIn.Left - Anchor.X,
ra180 : R := Rect(Anchor.X + AWholeRect.Left + RenderIn.Left, Anchor.Y + AWholeRect.Bottom + RenderIn.Top
Anchor.Y - HeightOf(AWholeRect) + RenderIn.Top, );
Anchor.X + ABitmap.Width + RenderIn.Left, ra180:
Anchor.Y + RenderIn.Top R := Rect(Anchor.X + AWholeRect.Left + RenderIn.Left,
); Anchor.Y - HeightOf(AWholeRect) + RenderIn.Top,
ra270 : R := Rect(Anchor.X + RenderIn.Left, Anchor.X + ABitmap.Width + RenderIn.Left,
Anchor.Y + RenderIn.Top, Anchor.Y + RenderIn.Top
Anchor.X + RenderIn.Left + WidthOf(AWholeRect), );
Anchor.Y + RenderIn.Top + HeightOf(AWholeRect) ra270:
); R := Rect(Anchor.X + RenderIn.Left,
Anchor.Y + RenderIn.Top,
Anchor.X + RenderIn.Left + WidthOf(AWholeRect),
Anchor.Y + RenderIn.Top + HeightOf(AWholeRect)
);
end; end;
// Copy the auxiliary contact bitmap from AWholeRect to R into the // Copy the auxiliary contact bitmap from AWholeRect to R into the
@ -893,11 +922,14 @@ begin
end; end;
procedure TVpContactGridPainter.SetMeasurements; procedure TVpContactGridPainter.SetMeasurements;
const
MARGIN = 2;
var var
numCols: Integer; numCols: Integer;
begin begin
inherited; inherited;
FScaledTextMargin := round(FContactGrid.TextMargin * Scale); FScaledTextMargin := round(FContactGrid.TextMargin * Scale);
FAnchorMargin := round(Scale * MARGIN) + FScaledTextMargin * 2;
numCols := FContactGrid.PrintNumColumns; numCols := FContactGrid.PrintNumColumns;
if DisplayOnly and (numCols > 0) then if DisplayOnly and (numCols > 0) then