1 | Unit CustomRadioGroup;
|
---|
2 |
|
---|
3 | // TCustomRadioGroup is not really based on TCustomRadioGroup it replaces it
|
---|
4 | // the only change is a tiny bug fix to make setting itemindex work without
|
---|
5 | // the control being shown (as when it is on an initially concealed notebook page)
|
---|
6 | Interface
|
---|
7 |
|
---|
8 | Uses
|
---|
9 | Classes, Forms, StdCtrls;
|
---|
10 |
|
---|
11 | {Declare new class}
|
---|
12 | Type
|
---|
13 |
|
---|
14 | TCustomRadioGroup=Class(TGroupBox)
|
---|
15 | Private
|
---|
16 | FItems:TStrings;
|
---|
17 | FRadios:TList;
|
---|
18 | FItemIndex:LongInt;
|
---|
19 | FColumns:LongInt;
|
---|
20 | FOnClick:TNotifyEvent;
|
---|
21 | Procedure SetItemIndex(Value:LongInt);
|
---|
22 | Procedure SetColumns(Value:LongInt);
|
---|
23 | Procedure SetItems(Value:TStrings);
|
---|
24 | Procedure SetRadioCount(Value:LongInt);
|
---|
25 | Function GetItemsEnabled(Index:LongInt):Boolean;
|
---|
26 | Procedure SetItemsEnabled(Index:LongInt;Value:Boolean);
|
---|
27 | Procedure UpdateRadios;
|
---|
28 | Procedure ArrangeRadios;
|
---|
29 | Procedure EvItemsChange(Sender:TObject);
|
---|
30 | Procedure EvRadioClick(Sender:TObject);
|
---|
31 | Protected
|
---|
32 | Procedure SetupComponent;Override;
|
---|
33 | Procedure SetupShow;Override;
|
---|
34 | Procedure Resize;Override;
|
---|
35 | Procedure FontChange;Override;
|
---|
36 | Procedure Click;Virtual;
|
---|
37 | Procedure ItemIndexChange;Virtual;
|
---|
38 | Public
|
---|
39 | Destructor Destroy;Override;
|
---|
40 | Procedure ReadSCUResource(Const ResName:TResourceName;Var Data;DataLen:LongInt);Override;
|
---|
41 | Function WriteSCUResource(Stream:TResourceStream):Boolean;Override;
|
---|
42 | Property ItemsEnabled[Index:LongInt]:Boolean Read GetItemsEnabled Write SetItemsEnabled;
|
---|
43 | Property XAlign;
|
---|
44 | Property XStretch;
|
---|
45 | Property YAlign;
|
---|
46 | Property YStretch;
|
---|
47 | Published
|
---|
48 | Property Align;
|
---|
49 | Property Caption;
|
---|
50 | Property Color;
|
---|
51 | Property Columns:LongInt Read FColumns Write SetColumns;
|
---|
52 | Property DragCursor;
|
---|
53 | Property DragMode;
|
---|
54 | Property Enabled;
|
---|
55 | Property Font;
|
---|
56 | Property ItemIndex:LongInt Read FItemIndex Write SetItemIndex;
|
---|
57 | Property Items:TStrings Read FItems Write SetItems;
|
---|
58 | Property ParentColor;
|
---|
59 | Property ParentPenColor;
|
---|
60 | Property ParentFont;
|
---|
61 | Property ParentShowHint;
|
---|
62 | Property PenColor;
|
---|
63 | Property ShowHint;
|
---|
64 | Property TabOrder;
|
---|
65 | Property TabStop;
|
---|
66 | Property Visible;
|
---|
67 | Property ZOrder;
|
---|
68 |
|
---|
69 | Property OnCanDrag;
|
---|
70 | Property OnClick:TNotifyEvent Read FOnClick Write FOnClick;
|
---|
71 | Property OnDragDrop;
|
---|
72 | Property OnDragOver;
|
---|
73 | Property OnEndDrag;
|
---|
74 | Property OnEnter;
|
---|
75 | Property OnExit;
|
---|
76 | Property OnFontChange;
|
---|
77 | Property OnSetupShow;
|
---|
78 | Property OnStartDrag;
|
---|
79 | End;
|
---|
80 |
|
---|
81 | {Define components to export}
|
---|
82 | {You may define a page of the component palette and a component bitmap file}
|
---|
83 | Exports
|
---|
84 | TCustomRadioGroup,'User','CustomRadioGroup.bmp';
|
---|
85 |
|
---|
86 | Implementation
|
---|
87 |
|
---|
88 | Uses
|
---|
89 | Buttons, SysUtils;
|
---|
90 |
|
---|
91 | Procedure TCustomRadioGroup.SetupComponent;
|
---|
92 | Begin
|
---|
93 | Inherited SetupComponent;
|
---|
94 |
|
---|
95 | Name := 'RadioGroup';
|
---|
96 | Caption := Name;
|
---|
97 |
|
---|
98 | FRadios:= TList.Create;
|
---|
99 | FItems := TStringList.Create;
|
---|
100 | TStringList(FItems).OnChange := EvItemsChange;
|
---|
101 | FItemIndex := -1;
|
---|
102 | FColumns := 1;
|
---|
103 | End;
|
---|
104 |
|
---|
105 |
|
---|
106 | Procedure TCustomRadioGroup.SetupShow;
|
---|
107 | Begin
|
---|
108 | Inherited SetupShow;
|
---|
109 |
|
---|
110 | UpdateRadios;
|
---|
111 | SetItemIndex(FItemIndex);
|
---|
112 | ArrangeRadios;
|
---|
113 | End;
|
---|
114 |
|
---|
115 |
|
---|
116 | Destructor TCustomRadioGroup.Destroy;
|
---|
117 | Begin
|
---|
118 | SetRadioCount(0);
|
---|
119 | FRadios.Destroy;
|
---|
120 | FRadios := Nil;
|
---|
121 | TStringList(FItems).OnChange := Nil;
|
---|
122 | FItems.Destroy;
|
---|
123 | FItems := Nil;
|
---|
124 |
|
---|
125 | Inherited Destroy;
|
---|
126 | End;
|
---|
127 |
|
---|
128 |
|
---|
129 | Procedure TCustomRadioGroup.Resize;
|
---|
130 | Begin
|
---|
131 | Inherited Resize;
|
---|
132 |
|
---|
133 | ArrangeRadios;
|
---|
134 | End;
|
---|
135 |
|
---|
136 |
|
---|
137 | Procedure TCustomRadioGroup.FontChange;
|
---|
138 | Var I:LongInt;
|
---|
139 | Radio:TRadioButton;
|
---|
140 | Begin
|
---|
141 | Inherited FontChange;
|
---|
142 |
|
---|
143 | For I := 0 To FRadios.Count-1 Do
|
---|
144 | Begin
|
---|
145 | Radio := TRadioButton(FRadios.Items[I]);
|
---|
146 | Radio.Font := Font;
|
---|
147 | End;
|
---|
148 | ArrangeRadios;
|
---|
149 | End;
|
---|
150 |
|
---|
151 |
|
---|
152 | Procedure TCustomRadioGroup.Click;
|
---|
153 | Begin
|
---|
154 | If FOnClick <> Nil Then FOnClick(Self);
|
---|
155 | End;
|
---|
156 |
|
---|
157 |
|
---|
158 | Procedure TCustomRadioGroup.SetItemIndex(Value:LongInt);
|
---|
159 | Begin
|
---|
160 | If ComponentState * [csReading] <> [] Then
|
---|
161 | Begin
|
---|
162 | FItemIndex := Value;
|
---|
163 | Exit;
|
---|
164 | End;
|
---|
165 |
|
---|
166 | // Bug fix over SPCC: create radios so we can set the item index
|
---|
167 | // Thanks Martin Vieregg <vrb@compuserve.com>
|
---|
168 | SetRadioCount(FItems.Count);
|
---|
169 |
|
---|
170 | If Value < 0 Then Value := -1;
|
---|
171 | If Value >= FRadios.Count Then Value := FRadios.Count-1;
|
---|
172 |
|
---|
173 | {deselect old because New Value can be < 0}
|
---|
174 | If (FItemIndex >= 0) And (FItemIndex < FRadios.Count)
|
---|
175 | Then TRadioButton(FRadios[FItemIndex]).Checked := False;
|
---|
176 |
|
---|
177 | FItemIndex := Value;
|
---|
178 | If FItemIndex >= 0 {Select New}
|
---|
179 | Then TRadioButton(FRadios[FItemIndex]).Checked := True;
|
---|
180 |
|
---|
181 | ItemIndexChange;
|
---|
182 | End;
|
---|
183 |
|
---|
184 |
|
---|
185 | Procedure TCustomRadioGroup.ItemIndexChange;
|
---|
186 | Begin
|
---|
187 | End;
|
---|
188 |
|
---|
189 |
|
---|
190 | Procedure TCustomRadioGroup.SetColumns(Value:LongInt);
|
---|
191 | Begin
|
---|
192 | If Value <= 0 Then Value := 1;
|
---|
193 | If FColumns <> Value Then
|
---|
194 | Begin
|
---|
195 | FColumns := Value;
|
---|
196 | ArrangeRadios;
|
---|
197 | End;
|
---|
198 | End;
|
---|
199 |
|
---|
200 |
|
---|
201 | Procedure TCustomRadioGroup.SetItems(Value:TStrings);
|
---|
202 | Begin
|
---|
203 | If Value <> FItems Then FItems.Assign(Value);
|
---|
204 | End;
|
---|
205 |
|
---|
206 |
|
---|
207 | Procedure TCustomRadioGroup.SetRadioCount(Value:LongInt);
|
---|
208 | Var Radio:TRadioButton;
|
---|
209 | Begin
|
---|
210 | While FRadios.Count < Value Do
|
---|
211 | Begin
|
---|
212 | Radio:= TRadioButton.Create(Self);
|
---|
213 | Include(Radio.ComponentState, csDetail);
|
---|
214 | Radio.Font := Font;
|
---|
215 | Radio.OnClick := EvRadioClick;
|
---|
216 | FRadios.Add(Radio);
|
---|
217 | End;
|
---|
218 | While FRadios.Count > Value Do
|
---|
219 | Begin
|
---|
220 | Radio := TRadioButton(FRadios.Last);
|
---|
221 | FRadios.Remove(Radio);
|
---|
222 | Radio.Destroy;
|
---|
223 | End;
|
---|
224 | End;
|
---|
225 |
|
---|
226 |
|
---|
227 | Function TCustomRadioGroup.GetItemsEnabled(Index:LongInt):Boolean;
|
---|
228 | Var Radio:TRadioButton;
|
---|
229 | Begin
|
---|
230 | Radio := TRadioButton(FRadios.Items[Index]);
|
---|
231 | Result := Radio.Enabled;
|
---|
232 | End;
|
---|
233 |
|
---|
234 |
|
---|
235 | Procedure TCustomRadioGroup.SetItemsEnabled(Index:LongInt;Value:Boolean);
|
---|
236 | Var Radio:TRadioButton;
|
---|
237 | Begin
|
---|
238 | Radio := TRadioButton(FRadios.Items[Index]);
|
---|
239 | Radio.Enabled := Value;
|
---|
240 | End;
|
---|
241 |
|
---|
242 |
|
---|
243 | Procedure TCustomRadioGroup.UpdateRadios;
|
---|
244 | Var I:LongInt;
|
---|
245 | Radio:TRadioButton;
|
---|
246 | Begin
|
---|
247 | SetRadioCount(FItems.Count);
|
---|
248 | For I := 0 To FItems.Count- 1 Do
|
---|
249 | Begin
|
---|
250 | Radio := TRadioButton(FRadios.Items[I]);
|
---|
251 | Radio.Caption := FItems[I];
|
---|
252 | End;
|
---|
253 | SetItemIndex(FItemIndex);
|
---|
254 | ArrangeRadios;
|
---|
255 | End;
|
---|
256 |
|
---|
257 |
|
---|
258 | Procedure TCustomRadioGroup.ArrangeRadios;
|
---|
259 | Const Margin=10;
|
---|
260 | Var I:LongInt;
|
---|
261 | Radio:TRadioButton;
|
---|
262 | RadioWidth:LongInt;
|
---|
263 | RadioHeight:LongInt;
|
---|
264 | RadiosPerColumn:LongInt;
|
---|
265 | XPos,YPos:LongInt;
|
---|
266 | rc:TRect;
|
---|
267 | Begin
|
---|
268 | If Handle = 0 Then Exit;
|
---|
269 | If FRadios.Count = 0 Then Exit;
|
---|
270 |
|
---|
271 | rc := ClientRect;
|
---|
272 | Inc(rc.Left,Margin);
|
---|
273 | Inc(rc.Bottom,Margin);
|
---|
274 | Dec(rc.Right,Margin);
|
---|
275 | Dec(rc.Top,Margin+Font.Height);
|
---|
276 |
|
---|
277 | RadiosPerColumn := (FRadios.Count + FColumns - 1) Div FColumns;
|
---|
278 | RadioWidth := (rc.Right - rc.Left) Div FColumns;
|
---|
279 | RadioHeight := (rc.Top - rc.Bottom) Div RadiosPerColumn;
|
---|
280 |
|
---|
281 | XPos := rc.Left;
|
---|
282 | YPos := rc.Top - RadioHeight;
|
---|
283 | For I := 0 To FRadios.Count-1 Do
|
---|
284 | Begin
|
---|
285 | Radio := TRadioButton(FRadios[I]);
|
---|
286 | Radio.SetWindowPos(XPos,YPos,RadioWidth,RadioHeight);
|
---|
287 | If Radio.parent = Nil Then Radio.parent := Self;
|
---|
288 |
|
---|
289 | If ((I+1) Mod RadiosPerColumn) = 0 Then
|
---|
290 | Begin
|
---|
291 | YPos := rc.Top - RadioHeight;
|
---|
292 | Inc(XPos,RadioWidth);
|
---|
293 | End
|
---|
294 | Else Dec(YPos,RadioHeight);
|
---|
295 | End;
|
---|
296 | End;
|
---|
297 |
|
---|
298 |
|
---|
299 | {$HINTS OFF}
|
---|
300 | Procedure TCustomRadioGroup.EvItemsChange(Sender:TObject);
|
---|
301 | Begin
|
---|
302 | If ComponentState * [csReading] = [] Then
|
---|
303 | Begin
|
---|
304 | UpdateRadios;
|
---|
305 | End;
|
---|
306 | End;
|
---|
307 | {$HINTS ON}
|
---|
308 |
|
---|
309 |
|
---|
310 | Procedure TCustomRadioGroup.EvRadioClick(Sender:TObject);
|
---|
311 | Begin
|
---|
312 | FItemIndex := FRadios.IndexOf(Sender);
|
---|
313 | ItemIndexChange;
|
---|
314 | Click;
|
---|
315 | End;
|
---|
316 |
|
---|
317 |
|
---|
318 | Function TCustomRadioGroup.WriteSCUResource(Stream:TResourceStream):Boolean;
|
---|
319 | Var aText:PChar;
|
---|
320 | Begin
|
---|
321 | Result := Inherited WriteSCUResource(Stream);
|
---|
322 | If Not Result Then Exit;
|
---|
323 |
|
---|
324 | aText := Items.GetText;
|
---|
325 | If aText <> Nil Then
|
---|
326 | Begin
|
---|
327 | Result := Stream.NewResourceEntry(rnItems,aText^,Length(aText^)+1);
|
---|
328 | StrDispose(aText);
|
---|
329 | End;
|
---|
330 | End;
|
---|
331 |
|
---|
332 |
|
---|
333 | Procedure TCustomRadioGroup.ReadSCUResource(Const ResName:TResourceName;Var Data;DataLen:LongInt);
|
---|
334 | Var aText:PChar;
|
---|
335 | Begin
|
---|
336 | If ResName = rnItems Then
|
---|
337 | Begin
|
---|
338 | aText := @Data;
|
---|
339 | Items.SetText(aText);
|
---|
340 | End
|
---|
341 | Else Inherited ReadSCUResource(ResName,Data,DataLen)
|
---|
342 | End;
|
---|
343 |
|
---|
344 | Initialization
|
---|
345 | {Register classes}
|
---|
346 | RegisterClasses([TCustomRadioGroup]);
|
---|
347 | End.
|
---|
348 |
|
---|