unit JITStringGrid;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Grids;

type
  TGetTextEvent = procedure (Sender: TObject; ACol, ARow: Longint; var Value: string) of object;
  TGetTextColorEvent = procedure (Sender: TObject; ACol, ARow: Longint; var Color: TColor) of object;

  TJITStringGrid = class(TDrawGrid)
  private
    FOnGetEditText: TGetEditEvent;
    FOnGetText: TGetTextEvent;
    FOnGetTextColor: TGetTextColorEvent;
    FOnGetTextBackColor: TGetTextColorEvent;
    FData: Pointer;
    FRows: Pointer;
    FCols: Pointer;
    FUpdating: Boolean;
    FNeedsUpdating: Boolean;
    FEditUpdate: Integer;
    procedure DisableEditUpdate;
    procedure EnableEditUpdate;
    procedure Initialize;
    procedure Update(ACol, ARow: Integer); reintroduce;
    procedure SetUpdateState(Updating: Boolean);
    function GetCells(ACol, ARow: Integer): string;
    function GetCols(Index: Integer): TStrings;
    function GetObjects(ACol, ARow: Integer): TObject;
    function GetRows(Index: Integer): TStrings;
    procedure SetCells(ACol, ARow: Integer; const Value: string);
    procedure SetCols(Index: Integer; Value: TStrings);
    procedure SetObjects(ACol, ARow: Integer; Value: TObject);
    procedure SetRows(Index: Integer; Value: TStrings);
  protected
    procedure ColumnMoved(FromIndex, ToIndex: Longint); override;
    procedure DrawCell(ACol, ARow: Longint; ARect: TRect;
      AState: TGridDrawState); override;
    function GetEditText(ACol, ARow: Longint): string; override;
    procedure SetEditText(ACol, ARow: Longint; const Value: string); override;
    procedure RowMoved(FromIndex, ToIndex: Longint); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property Cells[ACol, ARow: Integer]: string read GetCells write SetCells;
    property Cols[Index: Integer]: TStrings read GetCols write SetCols;
    property Objects[ACol, ARow: Integer]: TObject read GetObjects write SetObjects;
    property Rows[Index: Integer]: TStrings read GetRows write SetRows;
  published
    property OnGetText: TGetTextEvent read FOnGetText write FOnGetText;
    property OnGetTextColor: TGetTextColorEvent read FOnGetTextColor write FOnGetTextColor;
    property OnGetTextBackColor: TGetTextColorEvent read FOnGetTextBackColor write FOnGetTextBackColor;
  end;

procedure Register;

implementation

constructor TJITStringGrid.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Initialize;
end;

destructor TJITStringGrid.Destroy;
begin
  inherited Destroy;
end;

procedure TJITStringGrid.RowMoved(FromIndex, ToIndex: Longint);
begin
  Invalidate;
  inherited RowMoved(FromIndex, ToIndex);
end;

function TJITStringGrid.GetEditText(ACol, ARow: Longint): string;
begin
  Result := Cells[ACol, ARow];
  if Assigned(FOnGetEditText) then FOnGetEditText(Self, ACol, ARow, Result);
end;

procedure TJITStringGrid.SetEditText(ACol, ARow: Longint; const Value: string);
begin
  DisableEditUpdate;
  try
    if Value <> Cells[ACol, ARow] then Cells[ACol, ARow] := Value;
  finally
    EnableEditUpdate;
  end;
  inherited SetEditText(ACol, ARow, Value);
end;

procedure TJITStringGrid.DrawCell(ACol, ARow: Longint; ARect: TRect;
  AState: TGridDrawState);
var
  Color: TColor;
begin
  if DefaultDrawing then
  begin
    if Assigned(FOnGetTextColor) then
    begin
      FOnGetTextColor(Self, ACol, ARow, Color);
      Canvas.Font.Color := Color;
    end;
    if Assigned(FOnGetTextBackColor) then
    begin
      FOnGetTextBackColor(Self, ACol, ARow, Color);
      Canvas.Brush.Color := Color;
    end;
    Canvas.TextRect(ARect, ARect.Left+2, ARect.Top+2, Cells[ACol, ARow]);
  end;
  inherited DrawCell(ACol, ARow, ARect, AState);
end;

procedure TJITStringGrid.DisableEditUpdate;
begin
  Inc(FEditUpdate);
end;

procedure TJITStringGrid.EnableEditUpdate;
begin
  Dec(FEditUpdate);
end;

procedure TJITStringGrid.ColumnMoved(FromIndex, ToIndex: Longint);
begin
  Invalidate;
  inherited ColumnMoved(FromIndex, ToIndex);
end;

procedure TJITStringGrid.Initialize;
begin
end;

procedure TJITStringGrid.SetUpdateState(Updating: Boolean);
begin
  FUpdating := Updating;
  if not Updating and FNeedsUpdating then
  begin
    Invalidate;
    FNeedsUpdating := False;
  end;
end;

procedure TJITStringGrid.Update(ACol, ARow: Integer);
begin
  if not FUpdating then InvalidateCell(ACol, ARow)
  else FNeedsUpdating := True;
  if (ACol = Col) and (ARow = Row) and (FEditUpdate = 0) then InvalidateEditor;
end;

function TJITStringGrid.GetCells(ACol, ARow: Integer): string;
begin
  if Assigned(FOnGetText) then
    FOnGetText(Self, ACol, ARow, Result)
  else
    Result := '';
end;

function TJITStringGrid.GetCols(Index: Integer): TStrings;
begin
end;

function TJITStringGrid.GetObjects(ACol, ARow: Integer): TObject;
begin
end;

function TJITStringGrid.GetRows(Index: Integer): TStrings;
begin
end;

procedure TJITStringGrid.SetCells(ACol, ARow: Integer; const Value: string);
begin
end;

procedure TJITStringGrid.SetCols(Index: Integer; Value: TStrings);
begin
end;

procedure TJITStringGrid.SetObjects(ACol, ARow: Integer; Value: TObject);
begin
end;

procedure TJITStringGrid.SetRows(Index: Integer; Value: TStrings);
begin
end;

procedure Register;
begin
  RegisterComponents('Additional', [TJITStringGrid]);
end;

end.
