FPReport Custom elements

From Lazarus wiki
Jump to navigationJump to search

FPReport contains support for 4 basic reporting elements:

  • Memo
  • Shape
  • Image
  • Checkbox

While these will get you a long way, sometimes something extra is needed.

On this page we explain how to create a new element.

We'll take the sample TReportPolygon as an example.

Create a new element class

Any printable element must descend from TFPReportElement. It must expose published properties which allow the user to control behaviour of the element.

TReportPolygon = class(TFPReportElement)
Published
  Property Corners : Cardinal Read FCorners Write SetCorners;
  Property LineWidth : Cardinal Read FLineWidth Write SetCLineWidth;
  Property Color : TFPReportColor Read FColor Write FColor;
  // In degrees
  Property RotateAngle : Double Read FRotateAngle Write FRotateAngle;
end;

The element itself must only know how to read/write its properties from/to a report streamer, and how to copy properties to another instance.

Copying properties to another instance is done in the usual fashion, using the Assign method:

procedure TReportPolygon.Assign(Source: TPersistent);

Var
  P : TReportPolygon;

begin
  if (Source is TReportPolygon) then
    begin
    P:=Source as TReportPolygon;
    Corners:=P.Corners;
    Color:=P.Color;
    LineWidth:=P.LineWidth;
    RotateAngle:=P.RotateAngle;
    end;
  inherited Assign(Source);
end;

Writing properties to the streamer can be done in the WriteElement method, or the DoWriteLocalProperties method:

procedure TReportPolygon.DoWriteLocalProperties(AWriter: TFPReportStreamer;
  AOriginal: TFPReportElement);

Var
  P : TReportPolygon;

begin
  inherited DoWriteLocalProperties(AWriter, AOriginal);
  if AOriginal is TReportPolygon then
    begin
    P:=AOriginal as TReportPolygon;
    AWriter.WriteIntegerDiff('Color', Color, P.Color);
    AWriter.WriteIntegerDiff('Corners',Corners,P.Color);
    AWriter.WriteIntegerDiff('LineWidth',LineWidth,P.LineWidth);
    AWriter.WriteFloatDiff('RotateAngle',RotateAngle,P.RotateAngle);
    end
  else
    begin
    AWriter.WriteInteger('Color', Color);
    AWriter.WriteInteger('Corners',Corners);
    AWriter.WriteInteger('LineWidth',LineWidth);
    AWriter.WriteFloat('RotateAngle',RotateAngle);
    end;
end;

The AOriginal is meant for a rendered element, do be able to write only properties that differ from the original element, to keep the stream minimal in size (similar to the default clause in a published property declaration).