3
{ fpc/Lazarus demo of TStringGrid and the associated cell/button types.
5
Copyright (C) 2013 Windsurfer contact via fpc/Lazarus forum
7
This library is free software; you can redistribute it and/or modify it
8
under the terms of the GNU Library General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or (at your
10
option) any later version with the following modification:
12
As a special exception, the copyright holders of this library give you
13
permission to link this library with independent modules to produce an
14
executable, regardless of the license terms of these independent modules,and
15
to copy and distribute the resulting executable under terms of your choice,
16
provided that you also meet, for each linked independent module, the terms
17
and conditions of the license of that module. An independent module is a
18
module which is not derived from or based on this library. If you modify
19
this library, you may extend this exception to your version of the library,
20
but you are not obligated to do so. If you do not wish to do so, delete this
21
exception statement from your version.
23
This program is distributed in the hope that it will be useful, but WITHOUT
24
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
28
You should have received a copy of the GNU Library General Public License
29
along with this library; if not, write to the Free Software Foundation,
30
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Grids,
45
CalculatorDialog1: TCalculatorDialog;
46
ColorDialog1: TColorDialog;
52
StringGrid1: TStringGrid;
53
procedure Edit1Change(Sender: TObject);
54
procedure FormCreate(Sender: TObject);
55
procedure StringGrid1ButtonClick(Sender: TObject; aCol, aRow: integer);
56
procedure StringGrid1CheckboxToggled(Sender: TObject; aCol, aRow: integer;
57
aState: TCheckboxState);
58
procedure StringGrid1DrawCell(Sender: TObject; aCol, aRow: integer;
59
aRect: TRect; aState: TGridDrawState);
60
procedure StringGrid1GetCellHint(Sender: TObject; ACol, ARow: integer;
61
var HintText: string);
62
procedure StringGrid1GetCheckboxState(Sender: TObject; ACol, ARow: integer;
63
var Value: TCheckboxState);
64
procedure StringGrid1GetEditMask(Sender: TObject; ACol, ARow: integer;
66
procedure StringGrid1SetEditText(Sender: TObject; ACol, ARow: integer;
68
procedure StringGrid1ValidateEntry(Sender: TObject; aCol, aRow: integer;
69
const OldValue: string; var NewValue: string);
82
CheckBox: TCheckBoxState;
93
//The cbsButton can call the DrawCell event and change the colour immediately
94
//the ColorDialog closes. The cbsEllipsis can only call the DrawCell event when
95
//focus moves to another cell.
96
//In Grids.pas it can be seen that cbsEllipsis calls TButtonCellEditor, but
97
//cbsButton calls both TButtonCellEditor and TStringEditor.
98
//Changing the ButtonStyle of Column 'Button' from cbsButton to cbsEllipsis will
102
ayMyInput: array of TMyInput; //All status information is written to and read
103
//from here. This is not strictly necesary, but allows a real program to destroy
104
//the form and keep the information.
106
procedure TForm1.FormCreate(Sender: TObject);
110
SetLength(ayMyInput, StringGrid1.RowCount - 1); //grid and array count from 0
111
// Ensure button column is correct colour. Otherwise, DrawCell event will paint it black.
112
for I := 0 to length(ayMyInput) - 1 do
113
ayMyInput[I].Button := clWindow; //TColor
114
for I := 0 to length(ayMyInput) - 1 do
115
ayMyInput[I].CheckBox := cbUnChecked; //TCheckBoxState
117
for I := 0 to length(ayMyInput) - 1 do
119
ayMyInput[I].None := 'Not editable'; //'None' can only be changed in program
120
StringGrid1.Cells[6, I + 1] := ayMyInput[I].None;
123
Edit1.Text := ayMyInput[0].None;
124
StringGrid1.Options := StringGrid1.Options + [goCellHints];
125
StringGrid1.ShowHint := True;
126
StringGrid1.Columns.Items[7].PickList.Add('Giraffe'); //Add an item progamatically
127
//The others are added in the Object Inspector
128
Application.HintPause := 1;
131
procedure TForm1.StringGrid1GetEditMask(Sender: TObject; ACol, ARow: integer;
134
//'!' = delete leading blanks. '0' = position must be a number.
135
//'1' = keep formatting symbols. '_' = trailing '0'.
136
//Does not limit fields to 23:59:59.
137
//Use ValidateEntry and Copy()to check and change each character as the cell is exited.
138
if (ARow > 0) and (ACol = 1) then
139
Value := '!00:00:00;1;_';
142
procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol, ARow: integer;
143
const Value: string);
144
begin //Capture text from columns 0 and 1 to ayMyInput.Auto and .EditMask
145
//SetEditText works for each keystroke
148
ayMyInput[aRow - 1].Auto := StringGrid1.Cells[ACol, ARow]
149
else if (ACol = 1) then
150
ayMyInput[aRow - 1].EditMask := StringGrid1.Cells[ACol, ARow];
152
Label4.Caption := Value; //Show text as it is typed
155
procedure TForm1.StringGrid1ValidateEntry(Sender: TObject; aCol, aRow: integer;
156
const OldValue: string; var NewValue: string);
158
//Constrain to '23:59:59'.
159
//This only takes effect on leaving cell.
160
if (aRow > 0) and (aCol = 1) then
162
if Copy(NewValue, 1, 1) > '2' then
164
if Copy(NewValue, 2, 1) > '3' then
166
if Copy(NewValue, 4, 1) > '5' then
168
if Copy(NewValue, 7, 1) > '5' then
173
procedure TForm1.StringGrid1ButtonClick(Sender: TObject; aCol, aRow: integer);
175
//For these columns there is no manual entry into the cell,
176
//so use ButtonClick event
178
if (aCol = 2) and ColorDialog1.Execute then //Button
180
ayMyInput[aRow - 1].Button := Colordialog1.Color; //store cell colour in array
181
StringGrid1.Invalidate; //Could also use 'Repaint' te force DrawCell event
184
if (aCol = 3) then //ButtonColumn
186
StringGrid1.Options := StringGrid1.Options - [goEditing];
187
//Prevent write to previous cell
188
ayMyInput[aRow - 1].ButtonColumn := IntToStr(aCol) + ',' + IntToStr(aRow);
190
StringGrid1.Cells[aCol, aRow] := ayMyInput[aRow - 1].ButtonColumn;
191
StringGrid1.Options := StringGrid1.Options + [goEditing]; //Turn cell editing back on
194
if (aCol = 5) and CalculatorDialog1.Execute then //Ellipsis
196
// Click 'tick' sign on calculator to get result
197
ayMyInput[aRow - 1].Ellipsis := FloattoStr(Calculatordialog1.Value);
199
StringGrid1.Cells[aCol, aRow] := ayMyInput[aRow - 1].Ellipsis;
203
procedure TForm1.StringGrid1CheckboxToggled(Sender: TObject;
204
aCol, aRow: integer; aState: TCheckboxState);
206
if (ARow > 0) and (ACol = 4) then
207
ayMyInput[ARow - 1].CheckBox := aState;
210
procedure TForm1.StringGrid1GetCheckboxState(Sender: TObject;
211
ACol, ARow: integer; var Value: TCheckboxState);
213
if (ARow > 0) and (ACol = 4) then
214
Value := ayMyInput[ARow - 1].CheckBox;
217
procedure TForm1.Edit1Change(Sender: TObject);
221
for I := 1 to StringGrid1.RowCount - 1 do //'None' can only be changed in program
223
ayMyInput[I - 1].None := Edit1.Text;
224
StringGrid1.Cells[6, I] := ayMyInput[I - 1].None;
228
procedure TForm1.StringGrid1DrawCell(Sender: TObject; aCol, aRow: integer;
229
aRect: TRect; aState: TGridDrawState);
231
//Note in Col 2 'Button' the Repaint event takes place before the focus changes
234
if (aRow > 0) then //Use DrawCell to paint rectangle
236
begin //Get colour from array
237
stringgrid1.canvas.Brush.Color := ayMyInput[aRow - 1].Button;
238
stringgrid1.canvas.FillRect(aRect); //Paint Cell
242
procedure TForm1.StringGrid1GetCellHint(Sender: TObject; ACol, ARow: integer;
243
var HintText: string);
246
0: HintText := 'Button style cbsAuto sting grid column' +
247
sLineBreak + ' - enter any text.';
248
1: HintText := 'Button style cbsAuto, with basic Editmask for Time format.' +
249
sLineBreak + 'Uses ValidateEntry as cell is exited to enforce max of ''23:59:59''';
250
2: HintText := 'Button style cbsButton that shows colour dialog' +
251
sLineBreak + ' and changes cell colour.';
252
3: HintText := 'Button style cbsButtonColumn that shows cell position.';
253
4: HintText := 'Button style cbsCheckbox that toggles ''check'' mark.';
254
5: HintText := 'Button style cbsEllipsis that opens calculator.' +
255
sLineBreak + 'Click ''tick'' on calculator to send value to cell.';
256
6: HintText := 'Button style cbsNone that cannot be changed manually.' +
257
sLineBreak + 'Change Edit box contents to change displayed text.';
258
7: HintText := 'Button style cbsPicklist that offers a choice from' +
259
sLineBreak + 'a list set in the Object Inspector.';