lazarus/examples/gridexamples/merged_cells/mainform.pas

170 lines
4.8 KiB
ObjectPascal

unit mainform;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
Grids, mcGrid;
type
{ TForm1 }
TForm1 = class(TForm)
ImageList1: TImageList;
procedure FormCreate(Sender: TObject);
private
Grid: TMCStringGrid;
procedure DrawCellTextHandler(Sender: TObject; ACol, ARow: Integer;
ARect: TRect; AState: TGridDrawState; AText: String; var Handled: Boolean);
procedure MergeCellsHandler(Sender: TObject; ACol, ARow: Integer;
var ALeft, ATop, ARight, ABottom: Integer);
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
// Create an instance of TStringGridEx at runtime for testing
Grid := TMCStringGrid.Create(Self);
Grid.Parent := self;
Grid.Align := alClient;
Grid.RowCount := 20;
Grid.ColCount := 10;
Grid.Cells[1, 0] := 'Merged';
Grid.Cells[3, 0] := 'Single';
Grid.Cells[1, 1] := 'combined';
Grid.Cells[3, 1] := 'abc';
Grid.Cells[4, 1] := 'bold';
Grid.Cells[5, 1] := 'Image';
Grid.Cells[2, 7] := 'Image';
Grid.Cells[2, 3] := 'This is a long text' + LineEnding + 'with line break.';
Grid.Cells[0, 2] := 'Vertical text';
Grid.Cells[0, 6] := 'Centered';
Grid.OnDrawCellText := @DrawCellTextHandler;
Grid.OnMergeCells := @MergeCellsHandler;
Grid.Options := Grid.Options + [goColSpanning, goEditing, goDrawFocusSelected];
if Grid.DefaultRowHeight < ImageList1.Height + 4 then
Grid.DefaultRowHeight := ImageList1.Height + 4
end;
{ This event handler takes care of painting the cell text. Normally it is not
needed for merged cells, but it implements here vertical text direction,
line breaks etc. }
procedure TForm1.DrawCellTextHandler(Sender: TObject; ACol, ARow: Integer;
ARect: TRect; AState: TGridDrawState; AText: String; var Handled: Boolean);
var
ts: TTextStyle;
x, y: Integer;
bmp: TBitmap;
begin
Handled := True;
if (ACol in [2..4]) and (ARow in [3..5]) then
begin
// Word-wrapped text
ts := Grid.Canvas.TextStyle;
ts.SingleLine := false;
ts.Wordbreak := true;
x := ARect.Left + constCellPadding;
y := ARect.Top + constCellPadding;
Grid.Canvas.TextRect(ARect, x, y, AText, ts);
end else
if (ACol = 0) and (ARow in [2..5]) then
begin
// Vertical text
Grid.Canvas.Font.Orientation := 900;
x := (ARect.Left + ARect.Right - Grid.Canvas.TextHeight('Tg')) div 2;
y := ARect.Bottom - constCellPadding;
Grid.Canvas.TextOut(x, y, AText);
Grid.Canvas.Font.Orientation := 0;
end else
if (ACol = 0) and (ARow = 6) then
begin
// Centered text
ts := Grid.Canvas.TextStyle;
ts.Alignment := taCenter;
ts.Layout := tlCenter;
x := (ARect.Left + ARect.Right) div 2;
y := (ARect.Top + ARect.Bottom) div 2;
Grid.Canvas.TextRect(ARect, x, y, AText, ts);
end else
if (ACol = 4) and (ARow = 1) then
begin
// Bold text
Grid.Canvas.Font.Style := [fsBold];
x := ARect.Left + constCellPadding;
y := ARect.Top + constCellPadding;
Grid.Canvas.TextOut(x, y, AText);
Grid.Canvas.Font.Style := [];
end else
if (ACol = 5) and (ARow = 1) then
begin
// Cell with image
bmp := TBitmap.Create;
try
ImageList1.GetBitmap(0, bmp);
x := ARect.Left + constCellPadding;
y := (ARect.Top + ARect.Bottom - bmp.Height) div 2;
Grid.Canvas.Draw(x, y, bmp);
inc(x, bmp.Width + constCellpadding);
y := ARect.Top + constCellPadding;
Grid.Canvas.TextOut(x, y, AText);
finally
bmp.Free;
end;
end else
Handled := false;
end;
{ This is the event handler defining the merged block. In this example we
assume that the cells defined by columns 2..3 and rows 3..5 are will be merged }
procedure TForm1.MergeCellsHandler(Sender: TObject; ACol, ARow: Integer;
var ALeft, ATop, ARight, ABottom: Integer);
begin
// Define a merged block which is a single row heigh
if (ACol in [1..2]) and (ARow = 1) then begin
ALeft := 1;
ARight := 2;
end else
// Define a merged block covering several columns and rows (for the word-wrap text)
if (ACol in [2..3]) and (ARow in [3..5]) then begin
ALeft := 2;
ARight := 3;
Atop := 3;
ABottom := 5;
end;
// Define a merged block in the column headers
if (ACol in [1..2]) and (ARow = 0) then begin
ALeft := 1;
ARight := 2;
end else
// Define a merged block in the row headers (for the vertical text)
if (ACol = 0) and (ARow in [2..5]) then begin
ATop := 2;
ABottom := 5;
end else
// Merge the next two cells adjacent to cell with text 'Image'
if (ACol > 1) and (Grid.Cells[ACol-1, ARow] = 'Image') then begin
ALeft := ACol;
ARight := ALeft + 1;
end else
if (ACol > 2) and (Grid.Cells[ACol-2, ARow] = 'Image') then begin
ALeft := ACol - 1;
ARight := ALeft + 1;
end;
end;
end.