source: CoolBar/UCoolBar.pas

Last change on this file was 436, checked in by chronos, 12 years ago
  • Modified: Better handlig of TCoolBar resize.
File size: 6.0 KB
Line 
1unit UCoolBar;
2
3{$mode delphi}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils, Controls, SpecializedList, Dialogs, ComCtrls, Forms;
9
10type
11 TCoolBar = class;
12
13 { TCoolBand }
14
15 TCoolBand = class
16 private
17 FControl: TControl;
18 FCoolBar: TCoolBar;
19 FText: string;
20 FVisible: Boolean;
21 procedure SetControl(AValue: TControl);
22 procedure SetText(AValue: string);
23 procedure SetVisible(AValue: Boolean);
24 procedure ControlVisibleChange(Sender: TObject);
25 published
26 property Text: string read FText write SetText;
27 property Visible: Boolean read FVisible write SetVisible;
28 property CoolBar: TCoolBar read FCoolBar;
29 property Control: TControl read FControl write SetControl;
30 end;
31
32 { TCoolBar }
33
34 TCoolBar = class(TCustomControl)
35 private
36 FBands: TListObject;
37 FRowSize: Integer;
38 DisableResize: Boolean;
39 function GetBand(Index: Integer): TCoolBand;
40 procedure SetBand(Index: Integer; AValue: TCoolBand);
41 procedure BandsUpdate(Sender: TObject);
42 procedure AsyncResize(Param: PtrInt);
43 procedure ControlResize(Sender: TObject);
44 procedure SetRowSize(AValue: Integer);
45 function SearchBand(Control: TControl): TCoolBand;
46 protected
47 procedure Paint; override;
48 procedure Resize; override;
49 public
50 procedure InsertControl(AControl: TControl; Index: integer); override;
51 procedure RemoveControl(AControl: TControl); override;
52 constructor Create(TheOwner: TComponent); override;
53 destructor Destroy; override;
54 procedure Arrange;
55 property Bands: TListObject read FBands;
56 property BandsIndex[Index: Integer]: TCoolBand read GetBand write SetBand;
57 published
58 property PopupMenu;
59 property Align;
60 property Color;
61 property RowSize: Integer read FRowSize write SetRowSize;
62 property OnResize;
63 end;
64
65procedure Register;
66
67
68implementation
69
70procedure Register;
71begin
72 RegisterComponents('Samples', [TCoolBar]);
73end;
74
75{ TCoolBand }
76
77procedure TCoolBand.SetControl(AValue: TControl);
78begin
79 if FControl = AValue then Exit;
80 FControl := AValue;
81 if Assigned(AValue) then begin
82 AValue.Parent := CoolBar;
83 AValue.AddHandlerOnVisibleChanged(ControlVisibleChange);
84 end else AValue.RemoveHandlerOnVisibleChanged(ControlVisibleChange);
85 CoolBar.Arrange;
86end;
87
88procedure TCoolBand.SetText(AValue: string);
89begin
90 if FText = AValue then Exit;
91 FText := AValue;
92end;
93
94procedure TCoolBand.SetVisible(AValue: Boolean);
95begin
96 if FVisible = AValue then Exit;
97 FVisible := AValue;
98 if Assigned(Control) then Visible := FVisible;
99end;
100
101procedure TCoolBand.ControlVisibleChange(Sender: TObject);
102begin
103 FVisible := Control.Visible;
104end;
105
106{ TCoolBar }
107
108function TCoolBar.GetBand(Index: Integer): TCoolBand;
109begin
110 Result := TCoolBand(FBands[Index]);
111end;
112
113procedure TCoolBar.SetBand(Index: Integer; AValue: TCoolBand);
114begin
115 FBands[Index] := AValue;
116end;
117
118procedure TCoolBar.BandsUpdate(Sender: TObject);
119begin
120 Arrange;
121end;
122
123procedure TCoolBar.AsyncResize(Param: PtrInt);
124begin
125 Arrange;
126end;
127
128procedure TCoolBar.ControlResize(Sender: TObject);
129begin
130 Application.QueueAsyncCall(AsyncResize, 0);
131end;
132
133procedure TCoolBar.SetRowSize(AValue: Integer);
134begin
135 if FRowSize = AValue then Exit;
136 FRowSize := AValue;
137 Arrange;
138end;
139
140procedure TCoolBar.Paint;
141begin
142 inherited Paint;
143end;
144
145procedure TCoolBar.InsertControl(AControl: TControl; Index: integer);
146var
147 NewBand: TCoolBand;
148begin
149 inherited InsertControl(AControl, Index);
150 AControl.Align := alCustom;
151 NewBand := TCoolBand.Create;
152 NewBand.FCoolBar := Self;
153 NewBand.Control := AControl;
154 NewBand.Control.OnResize := ControlResize;
155 FBands.Insert(Index, NewBand);
156 Arrange;
157end;
158
159procedure TCoolBar.RemoveControl(AControl: TControl);
160var
161 Band: TCoolBand;
162begin
163 Band := SearchBand(AControl);
164 FBands.Remove(Band);
165 AControl.OnResize := nil;
166 inherited RemoveControl(AControl);
167 Arrange;
168end;
169
170function TCoolBar.SearchBand(Control: TControl): TCoolBand;
171var
172 I: Integer;
173begin
174 I := 0;
175 while (I < FBands.Count) and (TCoolBand(FBands[I]).Control <> Control) do Inc(I);
176 if I < FBands.Count then Result := TCoolBand(FBands[I])
177 else Result := nil;
178end;
179
180procedure TCoolBar.Resize;
181begin
182 inherited Resize;
183 //if not DisableResize then Arrange;
184end;
185
186constructor TCoolBar.Create(TheOwner: TComponent);
187begin
188 inherited;
189 FBands := TListObject.Create;
190 FBands.OnUpdate := BandsUpdate;
191 FRowSize := 24;
192 Align := alTop;
193 ControlStyle := ControlStyle + [csAcceptsControls];
194 Arrange;
195end;
196
197destructor TCoolBar.Destroy;
198begin
199 FreeAndNil(FBands);
200 inherited;
201end;
202
203procedure TCoolBar.Arrange;
204var
205 X, Y: Integer;
206 I: Integer;
207 NewHeight: Integer;
208begin
209 try
210 DisableResize := True;
211 X := 0;
212 Y := 0;
213 for I := 0 to FBands.Count - 1 do
214 with TCoolBand(FBands[I]) do begin
215 if Assigned(Control) and Control.Visible then begin
216 if (CoolBar.Width - X) > Control.Width then begin
217 // Place CoolBand right to the previous
218 if (Control.Left <> X) or (Control.Top <> Y) or
219 (Control.Width <> Control.Width) or (Control.Height <> RowSize) then
220 Control.SetBounds(X, Y, Control.Width, RowSize);
221 Inc(X, Control.Width);
222 end else begin
223 // CoolBand do not fit in gap, place to next row
224 if I > 0 then begin
225 // Enlarge previous band
226 with TCoolBand(FBands[I - 1]).Control do begin
227 SetBounds(Left, Top, CoolBar.Width - Left, Height);
228 end;
229 end;
230 Inc(Y, RowSize);
231 X := 0;
232 if (Control.Left <> X) or (Control.Top <> Y) or
233 (Control.Width <> Control.Width) or (Control.Height <> RowSize) then
234 Control.SetBounds(X, Y, Control.Width, RowSize);
235 Inc(X, Control.Width);
236 end;
237 end;
238 end;
239 Y := Y + RowSize;
240 if Y > RowSize then NewHeight := Y
241 else NewHeight := RowSize;
242 if NewHeight <> Height then Height := NewHeight;
243 finally
244 DisableResize := False;
245 end;
246end;
247
248end.
249
Note: See TracBrowser for help on using the repository browser.