From 43abf2a3cc1e8467a969c20789adad242528c23d Mon Sep 17 00:00:00 2001 From: graemeg Date: Thu, 23 Aug 2007 13:26:22 +0000 Subject: * Grid cells in disabled state are not painting in 3D text effect. * Minor changes to TfpgCustomGrid to make it more flexible for descendants * Rewrote the TfpgCustomStringGrid basing the design on TfpgCustomGrid * Extended the GridTest example to exercise both grids. --- examples/gui/gridtest/gridtest.lpr | 25 ++-- src/gui/gui_basegrid.pas | 4 +- src/gui/gui_customgrid.pas | 32 +++- src/gui/gui_grid.pas | 296 +++++++++++++------------------------ 4 files changed, 146 insertions(+), 211 deletions(-) diff --git a/examples/gui/gridtest/gridtest.lpr b/examples/gui/gridtest/gridtest.lpr index 66802e7c..a5f1d731 100644 --- a/examples/gui/gridtest/gridtest.lpr +++ b/examples/gui/gridtest/gridtest.lpr @@ -46,21 +46,25 @@ type procedure TMainForm.chkDisabledChange(Sender: TObject); begin grdMain.Enabled := not chkDisabled.Checked; + stringgrid.Enabled := grdMain.Enabled; end; procedure TMainForm.chkRowSelectChange(Sender: TObject); begin grdMain.RowSelect := chkRowSelect.Checked; + stringgrid.RowSelect := grdMain.RowSelect; end; procedure TMainForm.chkShowHeaderChange(Sender: TObject); begin grdMain.ShowHeader := chkShowHeader.Checked; + stringgrid.ShowHeader := grdMain.ShowHeader; end; procedure TMainForm.chkShowGridChange(Sender: TObject); begin grdMain.ShowGrid := chkShowGrid.Checked; + stringgrid.ShowGrid := grdMain.ShowGrid; end; procedure TMainForm.btnQuitClick(Sender: TObject); @@ -100,20 +104,21 @@ begin for c := 1 to grdMain.ColumnCount do grdMain.Columns[c-1].Title := 'Title ' + IntToStr(c); - tsTab2 := pagecontrol.AppendTabSheet('String Grid'); stringgrid := TfpgStringGrid.Create(tsTab2); stringgrid.SetPosition(10, 10, Width-50, 250); - stringgrid.ColumnCount := 2; - stringgrid.RowCount := 5; - stringgrid.Cells[2, 1] := 'hello'; - stringgrid.Cells[5, 2] := 'hello'; + // change row and column count to something different that the default + stringgrid.ColumnCount := 2; + stringgrid.RowCount := 3; + // add and change a column + stringgrid.AddColumn('Extra', 100); + stringgrid.ColumnWidth[3] := 150; + // changes header text in different ways stringgrid.ColumnTitle[1] := 'Column 1'; -// stringgrid.Columns[1].Title := 'Column 1'; -// stringgrid.Columns[2].Title := 'Col2'; - //for r := 1 to stringgrid.RowCount do - //for c := 1 to stringgrid.ColumnCount do - //stringgrid.Cells[r, c] := IntToStr(r) + ',' + IntToStr(c); + stringgrid.Columns[2].Title := 'Col 2'; + // add some text + stringgrid.Cells[2, 3] := 'Hello'; + stringgrid.Cells[3, 1] := '(r1,c3)'; // stringgrid.Anchors := [anLeft, anTop, anRight, anBottom]; pagecontrol.ActivePageIndex := 0; diff --git a/src/gui/gui_basegrid.pas b/src/gui/gui_basegrid.pas index 6f793ff7..79dec0ed 100644 --- a/src/gui/gui_basegrid.pas +++ b/src/gui/gui_basegrid.pas @@ -204,7 +204,9 @@ begin s := 'c(' + IntToStr(ARow) + ',' + IntToStr(ACol) + ')'; if (ARow = 5) and (ACol = 2) then s := 'Here lives Graeme!'; - fpgStyle.DrawString(Canvas, ARect.Left+1, ARect.Top+1, s, Enabled); + if not Enabled then + Canvas.SetTextColor(clShadow1); + Canvas.DrawString(ARect.Left+1, ARect.Top+1, s); end; procedure TfpgBaseGrid.DrawHeader(ACol: integer; ARect: TfpgRect; AFlags: integer); diff --git a/src/gui/gui_customgrid.pas b/src/gui/gui_customgrid.pas index 05a7a5a7..47cd2e9f 100644 --- a/src/gui/gui_customgrid.pas +++ b/src/gui/gui_customgrid.pas @@ -5,6 +5,7 @@ unit gui_customgrid; { TODO: * Column text alignment needs to be implemented. Currently always Centre. + * AlternateColor for rows need to be implemented. } {.$Define DEBUG} @@ -35,11 +36,13 @@ type TfpgCustomGrid = class(TfpgBaseGrid) - private - function GetColumns(AIndex: integer): TfpgGridColumn; protected FRowCount: integer; FColumns: TList; + function GetColumns(AIndex: integer): TfpgGridColumn; virtual; + procedure DoDeleteColumn(ACol: integer); virtual; + procedure DoSetRowCount(AValue: integer); virtual; + function DoCreateColumnClass: TfpgGridColumn; virtual; function GetColumnCount: integer; override; procedure SetColumnCount(const AValue: integer); virtual; function GetRowCount: integer; override; @@ -50,10 +53,11 @@ type property RowCount: integer read GetRowCount write SetRowCount; property ColumnCount: integer read GetColumnCount write SetColumnCount; property Columns[AIndex: integer]: TfpgGridColumn read GetColumns; +// property AlternateColor: TColor read FAlternateColor write SetAlternateColor stored IsAltColorStored; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; - function AddColumn(ATitle: string; AWidth: integer): TfpgGridColumn; + function AddColumn(ATitle: string; AWidth: integer): TfpgGridColumn; virtual; end; @@ -83,6 +87,22 @@ begin Result := TfpgGridColumn(FColumns[AIndex]); end; +procedure TfpgCustomGrid.DoDeleteColumn(ACol: integer); +begin + TfpgGridColumn(FColumns.Items[ACol-1]).Free; + FColumns.Delete(ACol-1); +end; + +procedure TfpgCustomGrid.DoSetRowCount(AValue: integer); +begin + // do nothing +end; + +function TfpgCustomGrid.DoCreateColumnClass: TfpgGridColumn; +begin + Result := TfpgGridColumn.Create; +end; + function TfpgCustomGrid.GetColumnCount: integer; begin Result := FColumns.Count; @@ -109,8 +129,7 @@ begin begin while n > AValue do begin - TfpgGridColumn(FColumns.Items[n-1]).Free; - FColumns.Delete(n-1); + DoDeleteColumn(n); dec(n); end; end; @@ -127,6 +146,7 @@ begin begin FocusRow := FRowCount; end; + DoSetRowCount(AValue); // could be implemented by descendants RePaint; end; @@ -182,7 +202,7 @@ end; function TfpgCustomGrid.AddColumn(ATitle: string; AWidth: integer): TfpgGridColumn; begin - Result := TfpgGridColumn.Create; + Result := DoCreateColumnClass; Result.Title := ATitle; Result.Width := AWidth; FColumns.Add(Result); diff --git a/src/gui/gui_grid.pas b/src/gui/gui_grid.pas index aa0a471a..6ec363b6 100644 --- a/src/gui/gui_grid.pas +++ b/src/gui/gui_grid.pas @@ -2,6 +2,13 @@ unit gui_grid; {$mode objfpc}{$H+} +{ + TODO: + * TCustomStringGrid: Objects property needs to be implemented. + * TCustomStringGrid: Col[] and Row[] properties need to be implemented. + The return TStrings with all text inserted.gui_grid +} + interface uses @@ -122,37 +129,34 @@ type end; - TfpgStringGrid = class(TfpgBaseGrid) + TfpgCustomStringGrid = class(TfpgCustomGrid) private - FDoPaint: boolean; // used in destructor - FColumns: TList; - FDefaultColumnWidth: TfpgCoord; - FRowCount: integer; - FColumnCount: integer; - function GetCell(ARow, ACol: Longword): string; - function GetColumnCount: integer; + function GetCell(ACol, ARow: LongWord): string; function GetColumnTitle(ACol: integer): string; - function GetColumns(AIndex: integer): TfpgStringColumn; - function GetRowCount: integer; - procedure SetCell(ARow, ACol: Longword; const AValue: string); - procedure SetColumnCount(const AValue: integer); + function GetColumnWidth(ACol: integer): integer; + procedure SetCell(ACol, ARow: LongWord; const AValue: string); procedure SetColumnTitle(ACol: integer; const AValue: string); - procedure SetRowCount(const AValue: integer); + procedure SetColumnWidth(ACol: integer; const AValue: integer); protected + function GetColumns(AIndex: integer): TfpgStringColumn; reintroduce; + procedure DoDeleteColumn(ACol: integer); override; + procedure DoSetRowCount(AValue: integer); override; + function DoCreateColumnClass: TfpgStringColumn; reintroduce; override; procedure DrawCell(ARow, ACol: integer; ARect: TfpgRect; AFlags: integer); override; - function GetHeaderText(ACol: integer): string; override; - function GetColumnWidth(ACol: integer): integer; override; - procedure SetColumnWidth(ACol: integer; const AValue: integer); override; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - property Cells[ARow, ACol: Longword]: string read GetCell write SetCell; - property RowCount: integer read GetRowCount write SetRowCount; - property ColumnCount: integer read GetColumnCount write SetColumnCount; property Columns[AIndex: integer]: TfpgStringColumn read GetColumns; + public + function AddColumn(ATitle: string; AWidth: integer): TfpgStringColumn; reintroduce; override; + property Cells[ACol, ARow: LongWord]: string read GetCell write SetCell; +// property Objects[ACol, ARow: Integer]: TObject read GetObjects write SetObjects; property ColumnTitle[ACol: integer]: string read GetColumnTitle write SetColumnTitle; property ColumnWidth[ACol: integer]: integer read GetColumnWidth write SetColumnWidth; +// property Cols[index: Integer]: TStrings read GetCols write SetCols; +// property Rows[index: Integer]: TStrings read GetRows write SetRows; + end; + + TfpgStringGrid = class(TfpgCustomStringGrid) published + property Columns; property DefaultColWidth; property DefaultRowHeight; property Font; @@ -161,17 +165,18 @@ type property FocusCol; property FocusRow; property RowSelect; -// property ColumnCount; -// property RowCount; + property ColumnCount; + property RowCount; property ShowHeader; property ShowGrid; property HeaderHeight; property ColResizing; -// property ColumnWidth; + property ColumnWidth; property OnFocusChange; property OnRowChange; property OnDoubleClick; end; + implementation @@ -618,7 +623,6 @@ constructor TfpgStringColumn.Create; begin inherited Create; FCells := TStringList.Create; -// writeln(Classname, ' .Create'); end; destructor TfpgStringColumn.Destroy; @@ -627,214 +631,118 @@ begin inherited Destroy; end; +{ TfpgCustomStringGrid } -{ TfpgStringGrid } - -function TfpgStringGrid.GetCell(ARow, ACol: Longword): string; -var - diff: integer; +function TfpgCustomStringGrid.GetCell(ACol, ARow: LongWord): string; begin - if ACol > FColumns.Count - 1 then - result := '' - else - begin - diff := (TfpgStringColumn(FColumns[ACol]).Cells.Count - 1) - integer(ARow); - if diff < 0 then - result := '' - else - result := TfpgStringColumn(FColumns[ACol]).Cells[ARow]; - end; + if ACol > ColumnCount then + Exit; //==> + if ARow > RowCount then + Exit; //==> + Result := TfpgStringColumn(FColumns.Items[ACol-1]).Cells[ARow-1]; end; -function TfpgStringGrid.GetColumnCount: integer; +function TfpgCustomStringGrid.GetColumnTitle(ACol: integer): string; begin - result := FColumnCount; + if ACol > ColumnCount then + Exit; //==> + Result := TfpgStringColumn(FColumns.Items[ACol-1]).Title; end; -function TfpgStringGrid.GetColumnTitle(ACol: integer): string; +function TfpgCustomStringGrid.GetColumnWidth(ACol: integer): integer; begin - if FColumns.Count - 1 < ACol then - result := '' - else - result := TfpgStringColumn(FColumns[ACol]).Title; + if ACol > ColumnCount then + Exit; //==> + Result := TfpgStringColumn(FColumns.Items[ACol-1]).Width; end; -function TfpgStringGrid.GetColumns(AIndex: integer): TfpgStringColumn; +procedure TfpgCustomStringGrid.SetCell(ACol, ARow: LongWord; + const AValue: string); begin - if (AIndex < 0) or (AIndex > FColumns.Count-1) then - Result := nil - else - Result := TfpgStringColumn(FColumns[AIndex]); + if ACol > ColumnCount then + Exit; //==> + if ARow > RowCount then + Exit; //==> + if TfpgStringColumn(FColumns.Items[ACol-1]).Cells[ARow-1] <> AValue then + begin + TfpgStringColumn(FColumns.Items[ACol-1]).Cells[ARow-1] := AValue; + RePaint; + end; end; -function TfpgStringGrid.GetRowCount: integer; +procedure TfpgCustomStringGrid.SetColumnTitle(ACol: integer; const AValue: string); begin - result := FRowCount; + if ACol > ColumnCount then + Exit; //==> + TfpgStringColumn(FColumns.Items[ACol-1]).Title := AValue; + RePaint; end; -procedure TfpgStringGrid.SetCell(ARow, ACol: Longword; const AValue: string); -var - aCalc: integer; - TmpCol: TfpgStringColumn; - i: Longword; +procedure TfpgCustomStringGrid.SetColumnWidth(ACol: integer; const AValue: integer); begin - aCalc := ACol - FColumns.Count + 1; - if aCalc > 0 then - begin - for i := 1 to aCalc do - begin - TmpCol := TfpgStringColumn.Create; - TmpCol.Width := DefaultColWidth; - FColumns.Add(TmpCol); - end; - end; - aCalc := ARow - TfpgStringColumn(FColumns[ACol]).Cells.Count + 1; - if aCalc > 0 then - begin - for i := 1 to aCalc do - TfpgStringColumn(FColumns[ACol]).Cells.Append(''); - end; - TfpgStringColumn(FColumns[ACol]).Cells[ARow] := AValue; - if ACol > FColumnCount - 1 then - FColumnCount := ACol + 1; - if ARow > FRowCount - 1 then - FRowCount := ARow + 1; + if ACol > ColumnCount then + Exit; //==> + TfpgStringColumn(FColumns.Items[ACol-1]).Width := AValue; + RePaint; end; -procedure TfpgStringGrid.SetColumnCount(const AValue: integer); -var - i: integer; - aCalc: integer; +function TfpgCustomStringGrid.GetColumns(AIndex: integer): TfpgStringColumn; begin - if AValue <> FColumnCount then - begin - if AValue < FColumnCount then - begin - aCalc := FColumns.Count - AValue; - if aCalc > 0 then - begin - for i := 1 to aCalc do - begin - TfpgStringColumn(FColumns[i]).Destroy; - FColumns.Delete(FColumns.Count-1); - end; - end; - end; - FColumnCount := AValue; - if FDoPaint then - RePaint; - end; + if (AIndex < 1) or (AIndex > ColumnCount) then + Result := nil + else + Result := TfpgStringColumn(FColumns.Items[AIndex-1]); end; -procedure TfpgStringGrid.SetColumnTitle(ACol: integer; const AValue: string); -var - aCalc: integer; +procedure TfpgCustomStringGrid.DoDeleteColumn(ACol: integer); begin - aCalc := ACol - FColumns.Count + 1; - if aCalc > 0 then - Cells[ACol, 0] := ''; - if AValue <> TfpgStringColumn(FColumns[ACol]).Title then - begin - if ACol+1 > FColumnCount then - FColumnCount := ACol + 1; - TfpgStringColumn(FColumns[ACol]).Title := aValue; - RePaint; - end; + TfpgStringColumn(FColumns.Items[ACol-1]).Free; + FColumns.Delete(ACol-1); end; -procedure TfpgStringGrid.SetRowCount(const AValue: integer); +procedure TfpgCustomStringGrid.DoSetRowCount(AValue: integer); var - i, i1: integer; - aCalc: integer; - SL: TStringList; + diff: integer; + c: integer; begin - if AValue <> FRowCount then + inherited DoSetRowCount(AValue); + if FColumns.Count = 0 then + Exit; //==> + + diff := AValue - TfpgStringColumn(FColumns.Items[0]).Cells.Count; + if diff > 0 then // We need to add rows begin - if AValue < FRowCount then - begin - for i := 0 to FColumns.Count - 1 do - begin - aCalc := TfpgStringColumn(FColumns[i]).Cells.Count - AValue; - if aCalc > 0 then - begin - sl := TfpgStringColumn(FColumns[i]).Cells; - for i1 := 1 to aCalc do - sl.Delete(sl.Count-1); - end; - end; - end; - FRowCount := aValue; - if FDoPaint then - RePaint; + for c := 0 to FColumns.Count - 1 do + begin + while TfpgStringColumn(FColumns[c]).Cells.Count <> AValue do + TfpgStringColumn(FColumns[c]).Cells.Append(''); + end; end; end; -procedure TfpgStringGrid.DrawCell(ARow, ACol: integer; ARect: TfpgRect; AFlags: integer); -var - s: string; +function TfpgCustomStringGrid.DoCreateColumnClass: TfpgStringColumn; begin -// inherited DrawCell(ARow, ACol, ARect, AFlags); - s := Cells[ACol-1, ARow-1]; - if s <> '' then - Canvas.DrawString(aRect.Left + 1, aRect.top + 1, s); + Result := TfpgStringColumn.Create; end; -function TfpgStringGrid.GetHeaderText(ACol: integer): string; +procedure TfpgCustomStringGrid.DrawCell(ARow, ACol: integer; ARect: TfpgRect; + AFlags: integer); begin - Result := ColumnTitle[ACol-1]; -end; - -function TfpgStringGrid.GetColumnWidth(ACol: integer): integer; -begin - if ACol > FColumns.Count - 1 then - result := DefaultColWidth - else - result := TfpgStringColumn(FColumns[ACol]).Width; -end; - -procedure TfpgStringGrid.SetColumnWidth(ACol: integer; const AValue: integer); -var - aCalc: integer; - i: integer; - TmpCol: TfpgStringColumn; -begin - aCalc := ACol - FColumns.Count; - if aCalc > 0 then - begin - for i := 1 to aCalc do - begin - TmpCol := TfpgStringColumn.Create; - TmpCol.Width := DefaultColWidth; - TmpCol.Cells := TStringList.Create; - FColumns.Add(TmpCol); - end; - end; - if TfpgStringColumn(FColumns[ACol]).Width <> AValue then + if Cells[ACol, ARow] <> '' then begin - TfpgStringColumn(FColumns[ACol]).Width := AValue; - RePaint; + if not Enabled then + Canvas.SetTextColor(clShadow1); + Canvas.DrawString(ARect.Left+1, ARect.Top+1, Cells[ACol, ARow]); end; end; -constructor TfpgStringGrid.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - FDoPaint := True; - FColumns := TList.Create; - FColumnCount := 0; - FRowCount := 0; - DefaultColWidth := 100; - ColumnCount := 5; - RowCount := 5; -end; - -destructor TfpgStringGrid.Destroy; +function TfpgCustomStringGrid.AddColumn(ATitle: string; AWidth: integer): TfpgStringColumn; +var + r: integer; begin - FDoPaint := False; - ColumnCount := 0; - RowCount := 0; - FColumns.Free; - inherited Destroy; + Result := TfpgStringColumn(inherited AddColumn(ATitle, AWidth)); + for r := 1 to RowCount do + Result.Cells.Append(''); end; end. -- cgit v1.2.3-70-g09d2