| 1 | unit UCoolBar;
|
|---|
| 2 |
|
|---|
| 3 | {$mode delphi}{$H+}
|
|---|
| 4 |
|
|---|
| 5 | interface
|
|---|
| 6 |
|
|---|
| 7 | uses
|
|---|
| 8 | Classes, SysUtils, Controls, SpecializedList, Dialogs, ComCtrls, Forms;
|
|---|
| 9 |
|
|---|
| 10 | type
|
|---|
| 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 |
|
|---|
| 65 | procedure Register;
|
|---|
| 66 |
|
|---|
| 67 |
|
|---|
| 68 | implementation
|
|---|
| 69 |
|
|---|
| 70 | procedure Register;
|
|---|
| 71 | begin
|
|---|
| 72 | RegisterComponents('Samples', [TCoolBar]);
|
|---|
| 73 | end;
|
|---|
| 74 |
|
|---|
| 75 | { TCoolBand }
|
|---|
| 76 |
|
|---|
| 77 | procedure TCoolBand.SetControl(AValue: TControl);
|
|---|
| 78 | begin
|
|---|
| 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;
|
|---|
| 86 | end;
|
|---|
| 87 |
|
|---|
| 88 | procedure TCoolBand.SetText(AValue: string);
|
|---|
| 89 | begin
|
|---|
| 90 | if FText = AValue then Exit;
|
|---|
| 91 | FText := AValue;
|
|---|
| 92 | end;
|
|---|
| 93 |
|
|---|
| 94 | procedure TCoolBand.SetVisible(AValue: Boolean);
|
|---|
| 95 | begin
|
|---|
| 96 | if FVisible = AValue then Exit;
|
|---|
| 97 | FVisible := AValue;
|
|---|
| 98 | if Assigned(Control) then Visible := FVisible;
|
|---|
| 99 | end;
|
|---|
| 100 |
|
|---|
| 101 | procedure TCoolBand.ControlVisibleChange(Sender: TObject);
|
|---|
| 102 | begin
|
|---|
| 103 | FVisible := Control.Visible;
|
|---|
| 104 | end;
|
|---|
| 105 |
|
|---|
| 106 | { TCoolBar }
|
|---|
| 107 |
|
|---|
| 108 | function TCoolBar.GetBand(Index: Integer): TCoolBand;
|
|---|
| 109 | begin
|
|---|
| 110 | Result := TCoolBand(FBands[Index]);
|
|---|
| 111 | end;
|
|---|
| 112 |
|
|---|
| 113 | procedure TCoolBar.SetBand(Index: Integer; AValue: TCoolBand);
|
|---|
| 114 | begin
|
|---|
| 115 | FBands[Index] := AValue;
|
|---|
| 116 | end;
|
|---|
| 117 |
|
|---|
| 118 | procedure TCoolBar.BandsUpdate(Sender: TObject);
|
|---|
| 119 | begin
|
|---|
| 120 | Arrange;
|
|---|
| 121 | end;
|
|---|
| 122 |
|
|---|
| 123 | procedure TCoolBar.AsyncResize(Param: PtrInt);
|
|---|
| 124 | begin
|
|---|
| 125 | Arrange;
|
|---|
| 126 | end;
|
|---|
| 127 |
|
|---|
| 128 | procedure TCoolBar.ControlResize(Sender: TObject);
|
|---|
| 129 | begin
|
|---|
| 130 | Application.QueueAsyncCall(AsyncResize, 0);
|
|---|
| 131 | end;
|
|---|
| 132 |
|
|---|
| 133 | procedure TCoolBar.SetRowSize(AValue: Integer);
|
|---|
| 134 | begin
|
|---|
| 135 | if FRowSize = AValue then Exit;
|
|---|
| 136 | FRowSize := AValue;
|
|---|
| 137 | Arrange;
|
|---|
| 138 | end;
|
|---|
| 139 |
|
|---|
| 140 | procedure TCoolBar.Paint;
|
|---|
| 141 | begin
|
|---|
| 142 | inherited Paint;
|
|---|
| 143 | end;
|
|---|
| 144 |
|
|---|
| 145 | procedure TCoolBar.InsertControl(AControl: TControl; Index: integer);
|
|---|
| 146 | var
|
|---|
| 147 | NewBand: TCoolBand;
|
|---|
| 148 | begin
|
|---|
| 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;
|
|---|
| 157 | end;
|
|---|
| 158 |
|
|---|
| 159 | procedure TCoolBar.RemoveControl(AControl: TControl);
|
|---|
| 160 | var
|
|---|
| 161 | Band: TCoolBand;
|
|---|
| 162 | begin
|
|---|
| 163 | Band := SearchBand(AControl);
|
|---|
| 164 | FBands.Remove(Band);
|
|---|
| 165 | AControl.OnResize := nil;
|
|---|
| 166 | inherited RemoveControl(AControl);
|
|---|
| 167 | Arrange;
|
|---|
| 168 | end;
|
|---|
| 169 |
|
|---|
| 170 | function TCoolBar.SearchBand(Control: TControl): TCoolBand;
|
|---|
| 171 | var
|
|---|
| 172 | I: Integer;
|
|---|
| 173 | begin
|
|---|
| 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;
|
|---|
| 178 | end;
|
|---|
| 179 |
|
|---|
| 180 | procedure TCoolBar.Resize;
|
|---|
| 181 | begin
|
|---|
| 182 | inherited Resize;
|
|---|
| 183 | //if not DisableResize then Arrange;
|
|---|
| 184 | end;
|
|---|
| 185 |
|
|---|
| 186 | constructor TCoolBar.Create(TheOwner: TComponent);
|
|---|
| 187 | begin
|
|---|
| 188 | inherited;
|
|---|
| 189 | FBands := TListObject.Create;
|
|---|
| 190 | FBands.OnUpdate := BandsUpdate;
|
|---|
| 191 | FRowSize := 24;
|
|---|
| 192 | Align := alTop;
|
|---|
| 193 | ControlStyle := ControlStyle + [csAcceptsControls];
|
|---|
| 194 | Arrange;
|
|---|
| 195 | end;
|
|---|
| 196 |
|
|---|
| 197 | destructor TCoolBar.Destroy;
|
|---|
| 198 | begin
|
|---|
| 199 | FreeAndNil(FBands);
|
|---|
| 200 | inherited;
|
|---|
| 201 | end;
|
|---|
| 202 |
|
|---|
| 203 | procedure TCoolBar.Arrange;
|
|---|
| 204 | var
|
|---|
| 205 | X, Y: Integer;
|
|---|
| 206 | I: Integer;
|
|---|
| 207 | NewHeight: Integer;
|
|---|
| 208 | begin
|
|---|
| 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;
|
|---|
| 246 | end;
|
|---|
| 247 |
|
|---|
| 248 | end.
|
|---|
| 249 |
|
|---|