1 {
2 *****************************************************************************
3 This file is part of the Lazarus Component Library (LCL)
4
5 See the file COPYING.modifiedLGPL.txt, included in this distribution,
6 for details about the license.
7 *****************************************************************************
8 }
9 unit ButtonPanel;
10
11 {$mode objfpc}{$h+}
12
13 interface
14
15 uses
16 Math, Types, SysUtils, Classes,
17 // LCL
18 LCLType, LMessages, Controls, ExtCtrls, StdCtrls, Buttons, Forms, Graphics, Themes,
19 // LazUtils
20 GraphType;
21
22 type
23 TButtonOrder = (boDefault, boCloseCancelOK, boCloseOKCancel);
24 TPanelButton = (pbOK, pbCancel, pbClose, pbHelp);
25 TPanelButtons = set of TPanelButton;
26
27 const
28 DefShowButtons = [pbOK, pbCancel, pbClose, pbHelp];
29 DefShowGlyphs = [pbOK, pbCancel, pbClose, pbHelp];
30
31 type
32
33 { TPanelBitBtn }
34
35 TPanelBitBtn = class(TCustomBitBtn)
36 public
37 constructor Create(AOwner: TComponent); override;
38 published
39 // Caption is stored only if DefaultCaption = false
40 property Caption stored IsCaptionStored;
41 property DefaultCaption stored True;
42 property Left stored False;
43 property Top stored False;
44 property Width stored False;
45 property Height stored False;
46 property Enabled;
47 property Font;
48 property Glyph;
49 property Name stored True;
50 property PopupMenu;
51 property ShowHint;
52 property OnClick;
53 end;
54
55 { TCustomButtonPanel }
56
57 TCustomButtonPanel = class(TCustomPanel)
58 private
59 FShowBevel: Boolean;
60 FShowButtons: TPanelButtons;
61 FShowGlyphs: TPanelButtons;
62 FBevel: TBevel;
63 FGlyphs: array[TPanelButton] of TBitmap;
64 FButtons: array[TPanelButton] of TPanelBitBtn;
65 FButtonsWidth: Integer;
66 FButtonsHeight: Integer;
67 FButtonOrder: TButtonOrder;
68 FDefaultButton: TPanelButton;
69 FSpacing: TSpacingSize;
70 procedure CreateButton(AButton: TPanelButton);
71 procedure DoDefaultButton;
72 procedure DoShowButtons;
73 procedure DoShowGlyphs;
74 procedure SetButtonOrder(Value: TButtonOrder);
75 procedure SetDefaultButton(Value: TPanelButton);
76 procedure SetShowBevel(AValue: Boolean);
77 procedure SetShowButtons(Value: TPanelButtons);
78 procedure SetShowGlyphs(Value: TPanelButtons);
79 procedure SetSpacing(AValue: TSpacingSize);
80 procedure UpdateBevel;
81 procedure UpdateButtonOrder;
82 procedure UpdateSizes;
83 procedure UpdateButtonLayout;
84 procedure UpdateButtonSize;
IsLastButtonnull85 function IsLastButton(AControl: TControl): boolean;
86 protected
CreateControlBorderSpacingnull87 function CreateControlBorderSpacing: TControlBorderSpacing; override;
CustomAlignInsertBeforenull88 function CustomAlignInsertBefore(AControl1, AControl2: TControl): Boolean; override;
89 procedure CustomAlignPosition(AControl: TControl; var ANewLeft, ANewTop,
90 ANewWidth, ANewHeight: Integer; var AlignRect: TRect;
91 AlignInfo: TAlignInfo); override;
92 procedure CalculatePreferredSize(var PreferredWidth,
93 PreferredHeight: integer; WithThemeSpace: Boolean); override;
94 procedure Loaded; override;
95 procedure Notification(AComponent: TComponent; Operation: TOperation); override;
96 procedure SetAlign(Value: TAlign); override;
97 procedure CMAppShowBtnGlyphChanged(var Message: TLMessage); message CM_APPSHOWBTNGLYPHCHANGED;
98 procedure CMShowingChanged(var Message: TLMessage); message CM_SHOWINGCHANGED;
99 public
100 constructor Create(AOwner: TComponent); override;
101 destructor Destroy; override;
102
103 property Align default alBottom;
104 property AutoSize default True;
105
106 property OKButton: TPanelBitBtn read FButtons[pbOK] default nil;
107 property HelpButton: TPanelBitBtn read FButtons[pbHelp] default nil;
108 property CloseButton: TPanelBitBtn read FButtons[pbClose] default nil;
109 property CancelButton: TPanelBitBtn read FButtons[pbCancel] default nil;
110 property ButtonOrder: TButtonOrder read FButtonOrder write SetButtonOrder default boDefault;
111
112 property DefaultButton: TPanelButton read FDefaultButton write SetDefaultButton default pbOK;
113 property ShowButtons: TPanelButtons read FShowButtons write SetShowButtons default DefShowButtons;
114 property ShowGlyphs: TPanelButtons read FShowGlyphs write SetShowGlyphs default DefShowGlyphs;
115 property ShowBevel: Boolean read FShowBevel write SetShowBevel default True;
116 property Spacing: TSpacingSize read FSpacing write SetSpacing default 6;
117 published
118 end;
119
120 { TButtonPanel }
121
122 TButtonPanel = class(TCustomButtonPanel)
123 published
124 property Align;
125 property Anchors;
126 property AutoSize;
127 property BorderSpacing;
128 property Constraints;
129 property Enabled;
130 property OKButton;
131 property HelpButton;
132 property CloseButton;
133 property CancelButton;
134 property Color;
135 property ButtonOrder;
136 property TabOrder;
137 property DefaultButton;
138 property Spacing;
139 property OnClick;
140 property OnDblClick;
141 property OnDragDrop;
142 property OnEnter;
143 property OnExit;
144 property OnKeyDown;
145 property OnKeyPress;
146 property OnKeyUp;
147 property OnMouseDown;
148 property OnMouseEnter;
149 property OnMouseLeave;
150 property OnMouseMove;
151 property OnMouseUp;
152 property OnMouseWheel;
153 property OnMouseWheelDown;
154 property OnMouseWheelUp;
155 property OnResize;
156 property OnUTF8KeyPress;
157 property ShowButtons;
158 property ShowGlyphs;
159 property ShowBevel;
160 property Visible;
161 end;
162
163 procedure Register;
164
165 implementation
166
167 const
168 DEFAULT_BUTTONPANEL_BORDERSPACING: TControlBorderSpacingDefault = (
169 Left:0; Top:0; Right:0; Bottom:0; Around:6;
170 );
171
172 procedure Register;
173 begin
174 RegisterComponents('Misc', [TButtonPanel]);
175 end;
176
177 { TPanelBitBtn }
178
179 constructor TPanelBitBtn.Create(AOwner: TComponent);
180 begin
181 inherited;
182
183 SetSubComponent(True);
184 end;
185
186 { TCustomButtonPanel }
187
188 procedure TCustomButtonPanel.DoShowButtons;
189 var
190 btn: TPanelButton;
191 aButton: TPanelBitBtn;
192 begin
193 DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TCustomButtonPanel.DoShowButtons'){$ENDIF};
194
195 for btn := Low(btn) to High(btn) do
196 begin
197 if FButtons[btn] = nil
198 then CreateButton(btn);
199 aButton:=FButtons[btn];
200
201 if btn in FShowButtons
202 then begin
203 if csDesigning in ComponentState then
204 aButton.ControlStyle:=aButton.ControlStyle-[csNoDesignVisible];
205 aButton.Visible := True;
206 end
207 else begin
208 if csDesigning in ComponentState then
209 aButton.ControlStyle:=aButton.ControlStyle+[csNoDesignVisible];
210 aButton.Visible := False;
211 end;
212 end;
213
214 UpdateButtonOrder;
215 UpdateButtonLayout;
216 EnableAutoSizing{$IFDEF DebugDisableAutoSizing}('TCustomButtonPanel.DoShowButtons'){$ENDIF};
217 end;
218
219 procedure TCustomButtonPanel.SetShowButtons(Value: TPanelButtons);
220 begin
221 if FShowButtons = Value then
222 Exit;
223
224 FShowButtons := Value;
225 InvalidatePreferredSize;
226 DoShowButtons;
227 end;
228
229 procedure TCustomButtonPanel.DoShowGlyphs;
230 var
231 btn: TPanelButton;
232 begin
233 DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TCustomButtonPanel.DoShowGlyphs'){$ENDIF};
234 for btn := Low(btn) to High(btn) do
235 begin
236 if FButtons[btn] = nil then Continue;
237
238 if btn in FShowGlyphs
239 then begin
240 FButtons[btn].Glyph.Assign(FGlyphs[btn]);
241 end
242 else begin
243 FButtons[btn].Glyph.Assign(nil);
244 end;
245 end;
246 EnableAutoSizing{$IFDEF DebugDisableAutoSizing}('TCustomButtonPanel.DoShowGlyphs'){$ENDIF};
247 end;
248
249 procedure TCustomButtonPanel.SetShowGlyphs(Value: TPanelButtons);
250 begin
251 if FShowGlyphs = Value then Exit;
252 FShowGlyphs := Value;
253 InvalidatePreferredSize;
254 DoShowGlyphs;
255 end;
256
257 procedure TCustomButtonPanel.SetSpacing(AValue: TSpacingSize);
258 begin
259 if FSpacing = AValue then Exit;
260 FSpacing := AValue;
261 InvalidatePreferredSize;
262 ReAlign;
263 end;
264
265 procedure TCustomButtonPanel.UpdateBevel;
266 begin
267 if FBevel = nil then Exit;
268
269 case Align of
270 alTop:
271 begin
272 FBevel.Shape := bsBottomLine;
273 FBevel.Align := alBottom;
274 end;
275 alLeft:
276 begin
277 FBevel.Shape := bsRightLine;
278 FBevel.Align := alRight;
279 end;
280 alRight:
281 begin
282 FBevel.Shape := bsLeftLine;
283 FBevel.Align := alLeft;
284 end
285 else
286 // default to bottom
287 FBevel.Shape := bsTopLine;
288 FBevel.Align := alTop;
289 end;
290
291 if Align in [alLeft, alRight]
292 then FBevel.Width := 2
293 else FBevel.Height := 2;
294 end;
295
296 procedure TCustomButtonPanel.UpdateSizes;
297 var
298 i: Integer;
299 BtnWidth, BtnHeight: Integer;
300 Details: TThemedElementDetails;
301 DefButtonSize: TSize;
302 begin
303 if csDestroying in ComponentState then
304 Exit;
305
306 Details := ThemeServices.GetElementDetails(tbPushButtonNormal);
307 DefButtonSize := ThemeServices.GetDetailSize(Details);
308 FButtonsWidth := DefButtonSize.cx;
309 FButtonsHeight := DefButtonSize.cy;
310
311 for i := 0 to ControlCount - 1 do
312 begin
313 if not (Controls[i] is TCustomButton) then Continue;
314 Controls[i].GetPreferredSize(BtnWidth, BtnHeight, True);
315 if Align in [alTop, alBottom] then
316 Controls[i].Width := BtnWidth;
317 if Align in [alLeft, alRight] then
318 Controls[i].Height := BtnHeight;
319 if BtnWidth > FButtonsWidth then
320 FButtonsWidth := BtnWidth;
321 if BtnHeight > FButtonsHeight then
322 FButtonsHeight := BtnHeight;
323 end;
324 end;
325
326 procedure TCustomButtonPanel.UpdateButtonLayout;
327 var
328 aButton: TPanelBitBtn;
329 btn: TPanelButton;
330 begin
331 for btn := Low(TPanelButton) to High(TPanelButton) do
332 begin
333 aButton:=FButtons[btn];
334 if aButton = nil then Continue;
335 aButton.Align := alCustom;
336 aButton.Default := FDefaultButton = btn;
337 end;
338 end;
339
IsLastButtonnull340 function TCustomButtonPanel.IsLastButton(AControl: TControl): boolean;
341 // returns true if AControl is the right/bottommost of the TPanelBitBtn
342 // Note: pbHelp could be the only button, then it is the last button
343 var
344 i: TPanelButton;
345 begin
346 if not AControl.IsControlVisible then exit(false);
347 if not (AControl is TPanelBitBtn) then exit(false);
348 for i:=low(FButtons) to pred(high(FButtons)) do
349 if (FButtons[i]<>nil) and FButtons[i].IsControlVisible
350 and (FButtons[i].TabOrder>TPanelBitBtn(AControl).TabOrder) then
351 exit(false); // there is a higher one
352 Result:=true;
353 end;
354
355 procedure TCustomButtonPanel.UpdateButtonOrder;
356 const
357 TabOrders: array[TButtonOrder, 0..3] of TPanelButton = (
358 {$IFDEF UNIX}
359 {boDefault } (pbOK, pbCancel, pbClose, pbHelp),
360 {$ELSE}
361 {boDefault } (pbCancel, pbOK, pbClose, pbHelp),
362 {$ENDIF}
363 {boCloseCancelOK} (pbOK, pbCancel, pbClose, pbHelp),
364 {boCloseOKCancel} (pbCancel, pbOK, pbClose, pbHelp)
365 );
366 var
367 i: Integer;
368 begin
369 //set taborder
370 for i := Low(TabOrders[FButtonOrder]) to High(TabOrders[FButtonOrder]) do
371 begin
372 if FButtons[TabOrders[FButtonOrder, i]] = nil then Continue;
373 FButtons[TabOrders[FButtonOrder, i]].TabOrder := High(TabOrders[FButtonOrder]) - i;
374 end;
375 AdjustSize;
376 end;
377
378 procedure TCustomButtonPanel.UpdateButtonSize;
379 var
380 AParent: TCustomDesignControl;
381 Details: TThemedElementDetails;
382 DefButtonSize: TSize;
383 btn: TPanelBitBtn;
384 begin
385 AParent := GetParentDesignControl(Self);
386 if AParent=nil then
387 Exit;
388
389 Details := ThemeServices.GetElementDetails(tbPushButtonNormal);
390 DefButtonSize := ThemeServices.GetDetailSize(Details);
391
392 DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TCustomButtonPanel.UpdateButtonSize'){$ENDIF};
393 try
394 for btn in FButtons do
395 begin
396 if btn = nil then Continue;
397 if Application.Scaled and AParent.Scaled then
398 begin
399 btn.Constraints.MinWidth := MulDiv(DefButtonSize.cx, AParent.PixelsPerInch, ScreenInfo.PixelsPerInchX);
400 btn.Constraints.MinHeight := MulDiv(DefButtonSize.cy, AParent.PixelsPerInch, ScreenInfo.PixelsPerInchY);
401 end else
402 begin
403 btn.Constraints.MinWidth := DefButtonSize.cx;
404 btn.Constraints.MinHeight := DefButtonSize.cy;
405 end;
406 end;
407 finally
408 EnableAutoSizing{$IFDEF DebugDisableAutoSizing}('TCustomButtonPanel.UpdateButtonSize'){$ENDIF};
409 end;
410 end;
411
412 procedure TCustomButtonPanel.SetAlign(Value: TAlign);
413 begin
414 DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TCustomButtonPanel.SetAlign'){$ENDIF};
415 try
416 inherited SetAlign(Value);
417 UpdateButtonLayout;
418 UpdateBevel;
419 UpdateSizes;
420 finally
421 EnableAutoSizing{$IFDEF DebugDisableAutoSizing}('TCustomButtonPanel.SetAlign'){$ENDIF};
422 end;
423 end;
424
425 procedure TCustomButtonPanel.CMAppShowBtnGlyphChanged(var Message: TLMessage);
426 begin
427 NotifyControls(Message.msg);
428 end;
429
430 procedure TCustomButtonPanel.CMShowingChanged(var Message: TLMessage);
431 begin
432 inherited;
433
434 UpdateButtonSize;
435 end;
436
437 procedure TCustomButtonPanel.SetButtonOrder(Value: TButtonOrder);
438 begin
439 if FButtonOrder = Value then Exit;
440 FButtonOrder := Value;
441 UpdateButtonOrder;
442 end;
443
444 procedure TCustomButtonPanel.DoDefaultButton;
445 var
446 btn: TPanelButton;
447 begin
448 for btn := Low(btn) to High(btn) do
449 begin
450 if FButtons[btn] = nil then Continue;
451 FButtons[btn].Default := FDefaultButton = btn;
452 end;
453 end;
454
455 procedure TCustomButtonPanel.SetDefaultButton(Value: TPanelButton);
456 begin
457 if FDefaultButton = Value then
458 Exit;
459
460 FDefaultButton := Value;
461
462 DoDefaultButton;
463 end;
464
465 procedure TCustomButtonPanel.SetShowBevel(AValue: Boolean);
466 begin
467 if FShowBevel = AValue then exit;
468 FShowBevel := AValue;
469
470 if not FShowBevel
471 then begin
472 FreeAndNil(FBevel);
473 Exit;
474 end;
475
476 DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TCustomButtonPanel.SetShowBevel'){$ENDIF};
477 try
478 FBevel := TBevel.Create(Self);
479 FBevel.Parent := Self;
480 FBevel.Name := 'Bevel';
481
482 UpdateBevel;
483 finally
484 EnableAutoSizing{$IFDEF DebugDisableAutoSizing}('TCustomButtonPanel.SetShowBevel'){$ENDIF};
485 end;
486 end;
487
488 procedure TCustomButtonPanel.Loaded;
489 begin
490 inherited;
491 DoShowGlyphs;
492 end;
493
494 procedure TCustomButtonPanel.Notification(AComponent: TComponent;
495 Operation: TOperation);
496 var
497 btn: TPanelButton;
498 begin
499 if Operation=opRemove then
500 begin
501 for btn := Low(btn) to High(btn) do
502 begin
503 if FButtons[btn] <> AComponent then Continue;
504 FButtons[btn] := nil;
505 Exclude(FShowButtons, btn);
506 end;
507 end;
508 inherited Notification(AComponent, Operation);
509 if AComponent is TPanelBitBtn then
510 UpdateSizes;
511 end;
512
513 constructor TCustomButtonPanel.Create(AOwner: TComponent);
514 begin
515 inherited Create(AOwner);
516
517 ControlStyle := ControlStyle + [csOwnedChildrenNotSelectable];
518
519 Align := alBottom;
520 BevelInner := bvNone;
521 BevelOuter := bvNone;
522 Caption := '';
523 ControlStyle := ControlStyle - [csSetCaption];
524 AutoSize := True;
525 FSpacing := 6;
526 ShowBevel := True;
527
528
529 FDefaultButton := pbOK;
530 FButtonOrder := boDefault;
531 FShowButtons := DefShowButtons;
532 FShowGlyphs := DefShowGlyphs;
533
534 // create the buttons
535 DoShowButtons;
536 end;
537
538 procedure TCustomButtonPanel.CreateButton(AButton: TPanelButton);
539 const
540 NAMES: array[TPanelButton] of String = (
541 'OKButton', 'CancelButton', 'CloseButton', 'HelpButton'
542 );
543 KINDS: array[TPanelButton] of TBitBtnKind = (
544 bkOK, bkCancel, bkClose, bkHelp
545 );
546 begin
547 if FButtons[AButton] <> nil then Exit;
548
549 FButtons[AButton] := TPanelBitBtn.Create(Self);
550 with FButtons[AButton] do
551 begin
552 Name := NAMES[AButton];
553 Kind := KINDS[AButton];
554 AutoSize := true;
555 TabOrder := Ord(AButton); //initial order
556 Align := alCustom;
557 if FGlyphs[AButton] = nil
558 then begin
559 // first time
560 FGlyphs[AButton] := TBitmap.Create;
561 FGlyphs[AButton].Assign(Glyph);
562 end;
563 // (re)set the glyph if needed
564 if (AButton in FShowGlyphs)
565 then Glyph.Assign(FGlyphs[AButton])
566 else Glyph.Assign(nil);
567 // set default
568 Default := AButton = FDefaultButton;
569
570 Parent := Self;
571 end;
572 end;
573
CreateControlBorderSpacingnull574 function TCustomButtonPanel.CreateControlBorderSpacing: TControlBorderSpacing;
575 begin
576 Result := TControlBorderSpacing.Create(Self, @DEFAULT_BUTTONPANEL_BORDERSPACING);
577 end;
578
CustomAlignInsertBeforenull579 function TCustomButtonPanel.CustomAlignInsertBefore(AControl1, AControl2: TControl): Boolean;
580 begin
581 // bevel is always the very first
582 if AControl1 = FBevel then Exit(True);
583 if AControl2 = FBevel then Exit(False);
584 // the help button is the second
585 if AControl1 = FButtons[pbHelp] then Exit(True);
586 if AControl2 = FButtons[pbHelp] then Exit(False);
587 // user defined controls comes before the normal buttons
588 if (not (AControl1 is TPanelBitBtn)) and (AControl2 is TPanelBitBtn) then
589 Exit(True)
590 else if (AControl1 is TPanelBitBtn) and (not (AControl2 is TPanelBitBtn)) then
591 Exit(False);
592 // sort for taborder
593 Result := TWinControl(AControl2).TabOrder > TWinControl(AControl1).TabOrder;
594 end;
595
596 procedure TCustomButtonPanel.CustomAlignPosition(AControl: TControl;
597 var ANewLeft, ANewTop, ANewWidth, ANewHeight: Integer; var AlignRect: TRect;
598 AlignInfo: TAlignInfo);
599 var
600 BevelSpacing: TSpacingSize;
601 begin
602 //debugln(['TCustomButtonPanel.CustomAlignPosition ',DbgSName(Self),' AControl=',DbgSName(AControl),' AlignRect=',dbgs(AlignRect),' New=',ANewLeft,',',ANewTop,',',ANewWidth,'x',ANewHeight]);
603 inherited CustomAlignPosition(AControl, ANewLeft, ANewTop, ANewWidth,
604 ANewHeight, AlignRect, AlignInfo);
605
606 if Assigned(FBevel) and FBevel.IsControlVisible then
607 BevelSpacing := Spacing
608 else
609 BevelSpacing := 0;
610
611 if Align in [alLeft,alRight] then
612 begin
613 // put top or bottom
614 ANewLeft:=AlignRect.Left;
615 ANewWidth:=AControl.Constraints.MinMaxWidth(AlignRect.Right-ANewLeft-BevelSpacing);
616 if Align=alRight then
617 inc(ANewLeft,BevelSpacing);
618 if AControl=FButtons[pbHelp] then
619 begin
620 ANewTop:=AlignRect.Top; // no Spacing in front of the first button
621 AlignRect.Top:=Min(AlignRect.Bottom,ANewTop+ANewHeight);
622 end else begin
623 ANewTop:=AlignRect.Bottom-ANewHeight;
624 if not IsLastButton(AControl) then
625 dec(ANewTop,Spacing);
626 AlignRect.Bottom:=Max(AlignRect.Top,ANewTop);
627 end;
628 end else
629 begin
630 // put left or right
631 ANewTop:=AlignRect.Top;
632 ANewHeight:=AControl.Constraints.MinMaxHeight(AlignRect.Bottom-ANewTop-BevelSpacing);
633 if Align=alBottom then
634 inc(ANewTop,BevelSpacing);
635 if AControl=FButtons[pbHelp] then
636 begin
637 // put left
638 ANewLeft:=AlignRect.Left; // no Spacing in front of the first button
639 AlignRect.Left:=Min(AlignRect.Right,ANewLeft+ANewWidth);
640 end else begin
641 // put right
642 ANewLeft:=AlignRect.Right-ANewWidth;
643 if not IsLastButton(AControl) then
644 dec(ANewLeft,Spacing);
645 AlignRect.Right:=Max(AlignRect.Left,ANewLeft);
646 end;
647 end;
648 //debugln(['TCustomButtonPanel.CustomAlignPosition END ',DbgSName(Self),' AControl=',DbgSName(AControl),' AlignRect=',dbgs(AlignRect),' New=',ANewLeft,',',ANewTop,',',ANewWidth,'x',ANewHeight]);
649 end;
650
651 procedure TCustomButtonPanel.CalculatePreferredSize(var PreferredWidth,
652 PreferredHeight: integer; WithThemeSpace: Boolean);
653 var
654 i: Integer;
655 AControl: TControl;
656 MinWidth: Integer;
657 MinHeight: Integer;
658 CtrlPrefWidth, CtrlPrefHeight: integer;
659 begin
660 MinWidth:=0;
661 MinHeight:=0;
662 // add buttons
663 for i:=0 to ControlCount-1 do
664 begin
665 AControl:=Controls[i];
666 if (AControl.Align<>alCustom) or (not AControl.IsControlVisible) then continue;
667 if AControl=FBevel then continue;
668 CtrlPrefWidth:=0;
669 CtrlPrefHeight:=0;
670 AControl.GetPreferredSize(CtrlPrefWidth,CtrlPrefHeight);
671 //debugln(['TCustomButtonPanel.CalculatePreferredSize ',DbgSName(AControl),' ',CtrlPrefHeight]);
672 if Align in [alLeft,alRight] then
673 begin
674 inc(MinHeight,CtrlPrefHeight);
675 if not IsLastButton(AControl) then
676 inc(MinHeight,Spacing);
677 MinWidth:=Max(MinWidth,CtrlPrefWidth);
678 end
679 else begin
680 inc(MinWidth,CtrlPrefWidth);
681 if not IsLastButton(AControl) then
682 inc(MinWidth,Spacing);
683 MinHeight:=Max(MinHeight,CtrlPrefHeight);
684 end;
685 end;
686 // bevel
687 if (FBevel<>nil) and FBevel.IsControlVisible then
688 begin
689 if Align in [alLeft,alRight] then
690 inc(MinWidth,FBevel.Width+Spacing)
691 else
692 inc(MinHeight,FBevel.Height+Spacing);
693 end;
694 PreferredWidth:=MinWidth;
695 PreferredHeight:=MinHeight;
696 //debugln(['TCustomButtonPanel.CalculatePreferredSize ',DbgSName(Self),' ',PreferredWidth,'x',PreferredHeight]);
697 end;
698
699 destructor TCustomButtonPanel.Destroy;
700 var
701 btn: TPanelButton;
702 begin
703 for btn := Low(btn) to High(btn) do
704 FreeAndNil(FGlyphs[btn]);
705 inherited Destroy;
706 end;
707
708 end.
709