LCL: Add BiDiMode support for TCoolBar. Issue #26875, patch from Vojtech Cihak.

git-svn-id: trunk@46581 -
This commit is contained in:
juha 2014-10-17 17:09:54 +00:00
parent eb2e358f20
commit 7f23c55be1
2 changed files with 372 additions and 230 deletions

View File

@ -2270,12 +2270,14 @@ type
FMinWidth: Integer; FMinWidth: Integer;
FParentBitmap: Boolean; FParentBitmap: Boolean;
FParentColor: Boolean; FParentColor: Boolean;
FRealLeft: Integer;
FRealWidth: Integer;
FText: TTranslateString; FText: TTranslateString;
FVisible: Boolean; FVisible: Boolean;
FWidth: Integer; FWidth: Integer;
FLeft: Integer; FLeft: Integer;
FTop: Integer; FTop: Integer;
FRealWidth: Integer; function GetRight: Integer;
function IsBitmapStored: Boolean; function IsBitmapStored: Boolean;
function IsColorStored: Boolean; function IsColorStored: Boolean;
function GetVisible: Boolean; function GetVisible: Boolean;
@ -2298,13 +2300,15 @@ type
cDefMinHeight = 25; cDefMinHeight = 25;
cDefMinWidth = 100; cDefMinWidth = 100;
cDefWidth = 180; cDefWidth = 180;
cHorSpacing = 7; cHorSpacing = 5;
cVertSpacing = 3; cVertSpacing = 3;
protected protected
FControlLeft: Integer; FControlLeft: Integer;
FControlTop: Integer; FControlTop: Integer;
FTextWidth: Integer;
function CalcPreferredHeight: Integer; function CalcPreferredHeight: Integer;
function CalcPrefferedWidth: Integer; function CalcPrefferedWidth: Integer;
procedure CalcTextWidth;
function GetDisplayName: string; override; function GetDisplayName: string; override;
public public
constructor Create(aCollection: TCollection); override; constructor Create(aCollection: TCollection); override;
@ -2312,6 +2316,9 @@ type
procedure InvalidateCoolBar(Sender: TObject); procedure InvalidateCoolBar(Sender: TObject);
procedure Assign(aSource: TPersistent); override; procedure Assign(aSource: TPersistent); override;
property Height: Integer read FHeight; property Height: Integer read FHeight;
property Left: Integer read FLeft;
property Right: Integer read GetRight;
property Top: Integer read FTop;
published published
property Bitmap: TBitmap read FBitmap write SetBitmap stored IsBitmapStored; property Bitmap: TBitmap read FBitmap write SetBitmap stored IsBitmapStored;
property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsNone; property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsNone;
@ -2337,7 +2344,7 @@ type
private private
FCoolBar: TCustomCoolBar; FCoolBar: TCustomCoolBar;
function GetItem(Index: Integer): TCoolBand; function GetItem(Index: Integer): TCoolBand;
procedure SetItem(Index: Integer; aValue: TCoolBand); procedure SetItem(Index: Integer; Value: TCoolBand);
protected protected
function GetOwner: TPersistent; override; function GetOwner: TPersistent; override;
procedure Update(aItem: TCollectionItem); override; procedure Update(aItem: TCollectionItem); override;
@ -2371,51 +2378,61 @@ type
FVertical: Boolean; FVertical: Boolean;
FOnChange: TNotifyEvent; FOnChange: TNotifyEvent;
function GetAlign: TAlign; function GetAlign: TAlign;
function RowEndHelper(ALeft, AVisInd: Integer): Boolean; function RowEndHelper(ALeft, AVisibleIdx: Integer): Boolean;
procedure SetBandBorderStyle(AValue: TBorderStyle); procedure SetBandBorderStyle(AValue: TBorderStyle);
procedure SetBands(AValue: TCoolBands); procedure SetBands(AValue: TCoolBands);
procedure SetBitmap(aValue: TBitmap); procedure SetBitmap(AValue: TBitmap);
procedure SetGrabStyle(AValue: TGrabStyle); procedure SetGrabStyle(AValue: TGrabStyle);
procedure SetGrabWidth(AValue: Integer); procedure SetGrabWidth(AValue: Integer);
procedure SetImages(AValue: TCustomImageList); procedure SetImages(AValue: TCustomImageList);
procedure SetShowText(AValue: Boolean); procedure SetShowText(AValue: Boolean);
procedure SetVertical(aValue: Boolean); procedure SetVertical(AValue: Boolean);
protected const protected const
cBorderWidth = 2;
cDefGrabStyle = gsDouble; cDefGrabStyle = gsDouble;
cDefGrabWidth = 10; cDefGrabWidth = 10;
cDivider: SmallInt = 2;
cGrabIndent: SmallInt = 2;
protected protected
FVisiBands: array of TCoolBand; FBorderEdges: TEdgeBorders;
FDefCursor: TCursor; FBorderLeft, FBorderTop, FBorderRight, FBorderBottom: SmallInt;
FBorderWidth: SmallInt;
FCursorBkgnd: TCursor;
FDragBand: TDragBand; FDragBand: TDragBand;
FDraggedBandIndex: Integer; // -1 .. space below the last row; other negative .. invalid area FDraggedBandIndex: Integer; // -1 .. space below the last row; other negative .. invalid area
FDragInitPos: Integer; // Initial mouse X - position (for resizing Bands) FDragInitPos: Integer; // Initial mouse X - position (for resizing Bands)
FLockCursor: Boolean;
FRightToLeft: Boolean;
FTextHeight: Integer; FTextHeight: Integer;
FVisiBands: array of TCoolBand;
procedure AlignControls(AControl: TControl; var RemainingClientRect: TRect); override; procedure AlignControls(AControl: TControl; var RemainingClientRect: TRect); override;
procedure BitmapOrImageListChange(Sender: TObject); procedure BitmapOrImageListChange(Sender: TObject);
procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer; procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;
{%H-}WithThemeSpace: Boolean); override; {%H-}WithThemeSpace: Boolean); override;
procedure CalculateAndAlign; procedure CalculateAndAlign;
function CalculateRealIndex(AVisibleIndex: Integer): Integer; function CalculateRealIndex(AVisibleIndex: Integer): Integer;
procedure DoFontChanged; procedure ChangeCursor(ABand, AGrabber: Boolean);
procedure CMBiDiModeChanged(var Message: TLMessage); message CM_BIDIMODECHANGED;
procedure CreateWnd; override; procedure CreateWnd; override;
procedure DoFontChanged;
procedure DrawTiledBitmap(ARect: TRect; ABitmap: TBitmap); procedure DrawTiledBitmap(ARect: TRect; ABitmap: TBitmap);
procedure FontChanged(Sender: TObject); override; procedure FontChanged(Sender: TObject); override;
function IsFirstAtRow(ABand: Integer): Boolean;
function IsRowEnd(ALeft, AVisibleIndex: Integer): Boolean; function IsRowEnd(ALeft, AVisibleIndex: Integer): Boolean;
procedure Loaded; override; procedure Loaded; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseEnter; override;
procedure MouseLeave; override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure Paint; override; procedure Paint; override;
procedure SetAlign(aValue: TAlign); reintroduce; procedure SetAlign(aValue: TAlign); reintroduce;
procedure SetAutoSize(Value: Boolean); override;
procedure SetCursor(Value: TCursor); override;
procedure WMSize(var Message: TLMSize); message LM_SIZE; procedure WMSize(var Message: TLMSize); message LM_SIZE;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
procedure EndUpdate; override; procedure EndUpdate; override;
procedure Invalidate; override;
procedure MouseToBandPos(X, Y: Integer; out ABand: Integer; out AGrabber: Boolean); procedure MouseToBandPos(X, Y: Integer; out ABand: Integer; out AGrabber: Boolean);
procedure InsertControl(AControl: TControl; Index: integer); override; procedure InsertControl(AControl: TControl; Index: integer); override;
procedure RemoveControl(AControl: TControl); override; procedure RemoveControl(AControl: TControl); override;

View File

@ -19,7 +19,7 @@ constructor TCoolBand.Create(aCollection: TCollection);
begin begin
FBreak := True; FBreak := True;
FColor := clDefault; FColor := clDefault;
FControl := nil; FControl := Nil;
FFixedBackground := True; FFixedBackground := True;
FImageIndex := -1; FImageIndex := -1;
FMinHeight := cDefMinHeight; FMinHeight := cDefMinHeight;
@ -28,7 +28,6 @@ begin
FParentColor := True; FParentColor := True;
FVisible := True; FVisible := True;
FWidth := cDefWidth; FWidth := cDefWidth;
inherited Create(aCollection); inherited Create(aCollection);
Assert(aCollection is TCoolBands, 'TCoolBand.Create: aCollection is not TCoolBands'); Assert(aCollection is TCoolBands, 'TCoolBand.Create: aCollection is not TCoolBands');
FCoolBar := TCoolBands(aCollection).FCoolBar; FCoolBar := TCoolBands(aCollection).FCoolBar;
@ -72,30 +71,39 @@ end;
function TCoolBand.CalcPreferredHeight: Integer; function TCoolBand.CalcPreferredHeight: Integer;
begin begin
Result := FMinHeight; Result := FMinHeight;
if assigned(FControl) then if Assigned(FControl) then
Result := max(Result, FControl.Height+2*cVertSpacing); Result := max(Result, FControl.Height+2*cVertSpacing);
if FCoolBar.FShowText then if FCoolBar.FShowText then
Result := max(Result, FCoolBar.FTextHeight+2*cVertSpacing); Result := max(Result, FCoolBar.FTextHeight+2*cVertSpacing);
if assigned(FCoolBar.Images) and (ImageIndex >= 0) then if Assigned(FCoolBar.Images) and (ImageIndex >= 0) then
Result := max(Result, FCoolBar.Images.Height+2*cVertSpacing); Result := max(Result, FCoolBar.Images.Height+2*cVertSpacing);
//DebugLn('CalcPreferredHeight ', CalcPreferredHeight);
end; end;
function TCoolBand.CalcPrefferedWidth: Integer; function TCoolBand.CalcPrefferedWidth: Integer;
begin begin
Result := FCoolBar.GrabWidth+2*cHorSpacing; Result := FCoolBar.GrabWidth+2*cHorSpacing;
if assigned(Control) then if Assigned(Control) then inc(Result, Control.Width+cHorSpacing);
inc(Result, Control.Width+cHorSpacing); if (FText <> '') and FCoolBar.FShowText then inc(Result, FTextWidth+cHorSpacing);
if (FText <> '') and FCoolBar.FShowText then
inc(Result, FCoolBar.Canvas.TextWidth(FText)+cHorSpacing);
Result := max(FMinWidth, Result); Result := max(FMinWidth, Result);
end; end;
procedure TCoolBand.CalcTextWidth;
begin
FTextWidth := FCoolBar.Canvas.TextWidth(FText);
end;
function TCoolBand.GetDisplayName: string; function TCoolBand.GetDisplayName: string;
begin begin
Result := Text; Result := Text;
if Result = '' then Result := ClassName; if Result = '' then Result := ClassName;
end; end;
function TCoolBand.GetRight: Integer;
begin
Result := FLeft+FWidth;
end;
function TCoolBand.IsBitmapStored: Boolean; function TCoolBand.IsBitmapStored: Boolean;
begin begin
Result := not ParentBitmap; Result := not ParentBitmap;
@ -149,21 +157,14 @@ procedure TCoolBand.SetControl(AValue: TControl);
var aBand: TCoolBand; var aBand: TCoolBand;
begin begin
if FControl = AValue then Exit; if FControl = AValue then Exit;
FCoolBar.BeginUpdate; FControl := AValue;
try if Assigned(AValue) then begin
if assigned(AValue) then AValue.Align := alNone;
begin aBand := TCoolBands(Collection).FindBand(AValue);
AValue.Align := alNone; if Assigned(aBand) and (aBand <> Self) then aBand.SetControl(Nil); //remove old association
aBand := TCoolBands(Collection).FindBand(AValue); AValue.Parent := FCoolBar;
if assigned(aBand) and (aBand <> Self) then
aBand.SetControl(Nil); // Remove old association
AValue.Parent := FCoolBar;
end;
FControl := AValue;
Changed(True);
finally
FCoolBar.EndUpdate;
end; end;
Changed(True);
end; end;
procedure TCoolBand.SetFixedBackground(AValue: Boolean); procedure TCoolBand.SetFixedBackground(AValue: Boolean);
@ -217,8 +218,9 @@ end;
procedure TCoolBand.SetText(const AValue: TTranslateString); procedure TCoolBand.SetText(const AValue: TTranslateString);
begin begin
if AValue = FText then exit; if AValue = FText then Exit;
FText := AValue; FText := AValue;
CalcTextWidth;
Changed(True); Changed(True);
end; end;
@ -226,7 +228,7 @@ procedure TCoolBand.SetVisible(AValue: Boolean);
begin begin
if FVisible = AValue then Exit; if FVisible = AValue then Exit;
FVisible := AValue; FVisible := AValue;
if assigned(FControl) then FControl.Visible := AValue; if Assigned(FControl) then FControl.Visible := AValue;
Changed(True); Changed(True);
end; end;
@ -255,35 +257,26 @@ end;
function TCoolBands.FindBand(AControl: TControl): TCoolBand; function TCoolBands.FindBand(AControl: TControl): TCoolBand;
var i: Integer; var i: Integer;
begin begin
Result := nil; Result := Nil;
for i := 0 to Count-1 do for i := 0 to Count-1 do
if GetItem(i).FControl = AControl then if GetItem(i).FControl = AControl then Exit(GetItem(i));
Exit(GetItem(i));
end; end;
procedure TCoolBands.Notify(aItem: TCollectionItem; aAction: TCollectionNotification); procedure TCoolBands.Notify(aItem: TCollectionItem; aAction: TCollectionNotification);
begin begin
inherited Notify(aItem, aAction); inherited Notify(aItem, aAction);
case aAction of if aAction = cnAdded then begin
cnAdded: begin //DebugLn('TCoolBands.Notify: aAction = cnAdded');
//DebugLn('TCoolBands.Notify: aAction = cnAdded'); TCoolBand(aItem).FCoolBar := FCoolBar;
TCoolBand(aItem).FCoolBar:=FCoolBar;
end;
cnExtracting: begin
//DebugLn('TCoolBands.Notify: aAction = cnExtracting');
end;
cnDeleting: begin
//DebugLn('TCoolBands.Notify: aAction = cnDeleting');
end;
end; end;
end; end;
procedure TCoolBands.Update(aItem: TCollectionItem); procedure TCoolBands.Update(aItem: TCollectionItem);
begin begin
inherited Update(aItem); inherited Update(aItem);
if assigned(FCoolBar) then begin if Assigned(FCoolBar) then begin
//DebugLn('Bands.Update calls CalcAndAlign'); //DebugLn('Bands.Update calls CalcAndAlign');
if not assigned(aItem) then FCoolBar.CalculateAndAlign; if not Assigned(aItem) then FCoolBar.CalculateAndAlign;
FCoolBar.Invalidate; FCoolBar.Invalidate;
end; end;
end; end;
@ -298,27 +291,33 @@ begin
Result := FCoolBar; Result := FCoolBar;
end; end;
procedure TCoolBands.SetItem(Index: Integer; aValue: TCoolBand); procedure TCoolBands.SetItem(Index: Integer; Value: TCoolBand);
begin begin
inherited SetItem(Index, aValue); inherited SetItem(Index, Value);
end; end;
{ TCustomCoolBar } { TCustomCoolBar }
constructor TCustomCoolBar.Create(AOwner: TComponent); constructor TCustomCoolBar.Create(AOwner: TComponent);
begin begin
FBands := TCoolBands.Create(Self);
inherited Create(AOwner); inherited Create(AOwner);
ControlStyle := ControlStyle - [csSetCaption] ControlStyle := ControlStyle-[csSetCaption]
+ [csAcceptsControls, csNoFocus, csOpaque, csParentBackground, csReplicatable]; +[csAcceptsControls, csNoFocus, csOpaque, csParentBackground, csReplicatable];
Align := alTop; Align := alTop;
Height := 75; Height := 75;
ParentColor := True; ParentColor := True;
ParentFont := True; ParentFont := True;
FBandBorderStyle := bsSingle; FBandBorderStyle := bsSingle;
FBandMaximize := bmClick; FBandMaximize := bmClick;
FBands := TCoolBands.Create(Self);
FBitmap := TBitmap.Create; FBitmap := TBitmap.Create;
FBitmap.OnChange:=@BitmapOrImageListChange; FBitmap.OnChange := @BitmapOrImageListChange;
FBorderEdges := EdgeBorders;
FBorderLeft := 2;
FBorderTop := 2;
FBorderRight := 2;
FBorderBottom := 2;
FBorderWidth := 2;
FGrabStyle := cDefGrabStyle; FGrabStyle := cDefGrabStyle;
FGrabWidth := cDefGrabWidth; FGrabWidth := cDefGrabWidth;
FImageChangeLink := TChangeLink.Create; FImageChangeLink := TChangeLink.Create;
@ -349,6 +348,12 @@ begin
Vertical := (aValue in [alLeft, alRight]); Vertical := (aValue in [alLeft, alRight]);
end; end;
procedure TCustomCoolBar.SetAutoSize(Value: Boolean);
begin
inherited SetAutoSize(Value);
if Value then CalculateAndAlign;
end;
procedure TCustomCoolBar.SetBandBorderStyle(AValue: TBorderStyle); procedure TCustomCoolBar.SetBandBorderStyle(AValue: TBorderStyle);
begin begin
if FBandBorderStyle = AValue then Exit; if FBandBorderStyle = AValue then Exit;
@ -361,9 +366,15 @@ begin
FBands.Assign(AValue); FBands.Assign(AValue);
end; end;
procedure TCustomCoolBar.SetBitmap(aValue: TBitmap); procedure TCustomCoolBar.SetBitmap(AValue: TBitmap);
begin begin
FBitmap.Assign(aValue); FBitmap.Assign(AValue);
end;
procedure TCustomCoolBar.SetCursor(Value: TCursor);
begin
inherited SetCursor(Value);
if not FLockCursor then FCursorBkgnd:=Value;
end; end;
procedure TCustomCoolBar.SetGrabStyle(AValue: TGrabStyle); procedure TCustomCoolBar.SetGrabStyle(AValue: TGrabStyle);
@ -402,24 +413,32 @@ begin
Invalidate; Invalidate;
end; end;
procedure TCustomCoolBar.SetVertical(aValue: Boolean); procedure TCustomCoolBar.SetVertical(AValue: Boolean);
begin begin
if FVertical = aValue then Exit; if FVertical = aValue then Exit;
FVertical := aValue; FVertical := AValue;
Invalidate; Invalidate;
end; end;
procedure TCustomCoolBar.AlignControls(AControl: TControl; var RemainingClientRect: TRect); procedure TCustomCoolBar.AlignControls(AControl: TControl; var RemainingClientRect: TRect);
var i: Integer; var i: Integer;
begin begin
if wcfAligningControls in FWinControlFlags then exit;
//DebugLn('AlignControls'); //DebugLn('AlignControls');
for i:=0 to Bands.Count-1 do for i:=0 to Bands.Count-1 do
if assigned(Bands[i].FControl) then begin if Assigned(Bands[i].FControl) then begin
Bands[i].FControl.Align:=alNone; Bands[i].FControl.Align:=alNone;
Bands[i].FControl.BorderSpacing.Around:=0; Bands[i].FControl.BorderSpacing.Around:=0;
Bands[i].FControl.Anchors:=[akLeft, akTop]; if not FRightToLeft then begin
Bands[i].FControl.AnchorParallel(akLeft, Bands[i].FControlLeft, self); Bands[i].FControl.Anchors:=[akTop, akLeft];
Bands[i].FControl.AnchorParallel(akTop, Bands[i].FControlTop, self); Bands[i].FControl.AnchorParallel(akLeft, Bands[i].FControlLeft, Self);
end else begin
Bands[i].FControl.Anchors:=[akTop, akRight];
Bands[i].FControl.AnchorParallel(akRight,
Width-Bands[i].FControlLeft-Bands[i].FControl.Width-FBorderLeft-FBorderRight, Self);
end;
if Bands[i].FControl.Top <> (Bands[i].FControlTop+FBorderTop) then
Bands[i].FControl.AnchorParallel(akTop, Bands[i].FControlTop, Self);
end; end;
inherited AlignControls(AControl, RemainingClientRect); inherited AlignControls(AControl, RemainingClientRect);
end; end;
@ -430,7 +449,7 @@ begin
end; end;
procedure TCustomCoolBar.CalculateAndAlign; procedure TCustomCoolBar.CalculateAndAlign;
var i, x, y, aCountM1, aHeight, aLeft, aStartIndex, aTop, aWidth: Integer; var i, x, xHelp, y, aBorder, aCountM1, aHeight, aLeft, aStartIndex, aTop, aWidth: Integer;
aRowEnd: Boolean; aRowEnd: Boolean;
begin begin
if (FUpdateCount > 0) or ([csLoading, csDestroying] * ComponentState <> []) then exit; if (FUpdateCount > 0) or ([csLoading, csDestroying] * ComponentState <> []) then exit;
@ -447,18 +466,29 @@ begin
inc(x); inc(x);
end; end;
aCountM1 := x-1; aCountM1 := x-1;
//Do not use FBands from this point, only FVisiBands if not FRightToLeft then
aBorder := FBorderLeft
else
aBorder := FBorderRight;
//do not use FBands from this point, only FVisiBands
aHeight := 0; aHeight := 0;
aStartIndex := 0; aStartIndex := 0;
aRowEnd := True; aRowEnd := True;
if AutoSize and (aCountM1 >= 0) then DisableAutoSizing; if AutoSize then begin
for i := 0 to aCountM1 do if aCountM1 >= 0 then DisableAutoSizing;
begin inc(FUpdateCount);
if (FVisiBands[i].Break or Vertical) or aRowEnd then aLeft := cBorderWidth; InvalidatePreferredSize;
AdjustSize;
if aCountM1 >= 0 then EnableAutoSizing;
dec(FUpdateCount);
end;
for i := 0 to aCountM1 do begin
if (FVisiBands[i].Break or Vertical) or aRowEnd then aLeft := aBorder; //TODO
aHeight := Max(aHeight, FVisiBands[i].CalcPreferredHeight); aHeight := Max(aHeight, FVisiBands[i].CalcPreferredHeight);
aRowEnd := (i = aCountM1);
inc(aLeft, FVisiBands[i].Width); inc(aLeft, FVisiBands[i].Width);
aRowEnd := (i = aCountM1) or ( (i < aCountM1) and RowEndHelper(ALeft, i) ); aRowEnd := aRowEnd or ((i < aCountM1) and RowEndHelper(ALeft, i));
//Set all Bands in row to uniform height //set all Bands in row to uniform height
if aRowEnd then begin if aRowEnd then begin
for y := aStartIndex to i do for y := aStartIndex to i do
FVisiBands[y].FHeight := aHeight; FVisiBands[y].FHeight := aHeight;
@ -466,44 +496,52 @@ begin
aStartIndex := i+1; aStartIndex := i+1;
end; end;
end; end;
aTop := cBorderWidth; aTop := FBorderTop;
aRowEnd := True; aRowEnd := True;
for i := 0 to aCountM1 do include(FWinControlFlags, wcfAligningControls);
begin for i := 0 to aCountM1 do begin
if aRowEnd or (FVisiBands[i].Break or Vertical) then aLeft := cBorderWidth; if aRowEnd or (FVisiBands[i].Break or Vertical) then aLeft := aBorder;
FVisiBands[i].FLeft := aLeft; if not FRightToLeft then
FVisiBands[i].FLeft := aLeft
else
FVisiBands[i].FLeft := Width-aLeft-FVisiBands[i].Width;
FVisiBands[i].FRealLeft := FVisiBands[i].FLeft;
FVisiBands[i].FTop := aTop; FVisiBands[i].FTop := aTop;
if assigned(FVisiBands[i].Control) then begin if Assigned(FVisiBands[i].Control) then begin
x := 2+GrabWidth+TCoolBand.cHorSpacing; x := cGrabIndent+GrabWidth+TCoolBand.cHorSpacing;
xHelp := x;
if (FVisiBands[i].Text<>'') and FShowText then if (FVisiBands[i].Text<>'') and FShowText then
inc(x, Canvas.TextWidth(FVisiBands[i].Text)+TCoolBand.cHorSpacing); inc(x, Canvas.TextWidth(FVisiBands[i].Text)+TCoolBand.cHorSpacing);
if assigned(FImages) and (FVisiBands[i].ImageIndex >=0) then if Assigned(FImages) and (FVisiBands[i].ImageIndex >=0) then
inc(x, FImages.Width+TCoolBand.cHorSpacing); inc(x, FImages.Width+TCoolBand.cHorSpacing);
aWidth := FVisiBands[i].Width-x-TCoolBand.cHorSpacing-cBorderWidth; if x = xHelp then inc(x, TCoolBand.cHorSpacing);
inc(x, aLeft); aWidth := FVisiBands[i].Width-x-TCoolBand.cHorSpacing-cDivider;
y := aTop+(FVisiBands[i].FHeight-FVisiBands[i].Control.Height) div 2; y := aTop+(FVisiBands[i].FHeight-FVisiBands[i].Control.Height) div 2;
FVisiBands[i].Control.Width:=aWidth; if not FRightToLeft then begin
FVisiBands[i].FControlLeft:=x-cBorderWidth; inc(x, aLeft);
FVisiBands[i].FControlTop:=y-cBorderWidth; FVisiBands[i].Control.Left := x;
ReAlign; FVisiBands[i].FControlLeft := x-aBorder;
end else begin
x := FVisiBands[i].FLeft+cDivider+TCoolBand.cHorSpacing;
FVisiBands[i].Control.Left := x;
FVisiBands[i].FControlLeft := x-FBorderLeft;
end;
FVisiBands[i].FControlTop := y-FBorderTop;
FVisiBands[i].Control.Top := FVisiBands[i].FControlTop+FBorderTop;
FVisiBands[i].Control.Width := aWidth;
end; end;
x := FVisiBands[i].Width; x := FVisiBands[i].Width;
inc(aLeft, x); inc(aLeft, x);
aRowEnd := IsRowEnd(aLeft, i); aRowEnd := IsRowEnd(aLeft, i);
if aRowEnd or (i = aCountM1) then if aRowEnd or (i = aCountM1) then begin
FVisiBands[i].FRealWidth := x+ClientWidth-aLeft-cBorderWidth FVisiBands[i].FRealWidth := x+Width-aLeft-FBorderRight;
else if FRightToLeft then FVisiBands[i].FRealLeft := FBorderLeft;
end else
FVisiBands[i].FRealWidth := x; FVisiBands[i].FRealWidth := x;
if aRowEnd then if aRowEnd then
inc(aTop, FVisiBands[i].FHeight+cBorderWidth); inc(aTop, FVisiBands[i].FHeight+cDivider);
end;
if AutoSize then begin
inc(FUpdateCount);
InvalidatePreferredSize;
AdjustSize;
if aCountM1 >= 0 then EnableAutoSizing;
dec(FUpdateCount);
end; end;
exclude(FWinControlFlags, wcfAligningControls);
end; end;
procedure TCustomCoolBar.CalculatePreferredSize(var PreferredWidth, PreferredHeight: Integer; procedure TCustomCoolBar.CalculatePreferredSize(var PreferredWidth, PreferredHeight: Integer;
@ -512,15 +550,16 @@ var i, aCountM1, aPrefWidth: Integer;
begin begin
aCountM1 := length(FVisiBands)-1; aCountM1 := length(FVisiBands)-1;
if aCountM1 >= 0 then if aCountM1 >= 0 then
PreferredHeight := FVisiBands[aCountM1].FTop+FVisiBands[aCountM1].FHeight+2 PreferredHeight := FVisiBands[aCountM1].FTop+FVisiBands[aCountM1].FHeight+FBorderBottom
else else
PreferredHeight := TCoolBand.cDefMinHeight+4; PreferredHeight := TCoolBand.cDefMinHeight+FBorderTop+FBorderBottom;
if not FVertical then if not FVertical then
PreferredWidth := 0 PreferredWidth := 0
else begin else begin
aPrefWidth := TCoolBand.cDefMinHeight+4; //min. Width is ~ 25 pixels aPrefWidth := TCoolBand.cDefMinHeight; //min. Width is ~ 25 pixels
for i := 0 to aCountM1 do for i := 0 to aCountM1 do
aPrefWidth := max(aPrefWidth, FVisiBands[i].Width); aPrefWidth := max(aPrefWidth, FVisiBands[i].Width);
inc(aPrefWidth, FBorderLeft+FBorderRight);
PreferredWidth := aPrefWidth; PreferredWidth := aPrefWidth;
end; end;
end; end;
@ -530,8 +569,7 @@ var i, aInvisibles, aVisibles: Integer;
begin begin
aInvisibles := 0; aInvisibles := 0;
aVisibles := 0; aVisibles := 0;
for i:=0 to FBands.Count-1 do for i:=0 to FBands.Count-1 do begin
begin
if not FBands[i].Visible then if not FBands[i].Visible then
inc(aInvisibles) inc(aInvisibles)
else else
@ -541,13 +579,41 @@ begin
Result := AVisibleIndex+aInvisibles; Result := AVisibleIndex+aInvisibles;
end; end;
procedure TCustomCoolBar.ChangeCursor(ABand, AGrabber: Boolean);
begin
FLockCursor := True;
if ABand then begin
if not AGrabber then
Cursor := crDrag
else
Cursor := crHSplit;
end else
Cursor := FCursorBkgnd;
FLockCursor := False;
end;
procedure TCustomCoolBar.CMBiDiModeChanged(var Message: TLMessage);
begin
inherited CMBiDiModeChanged(Message);
FRightToLeft := IsRightToLeft;
CalculateAndAlign;
end;
procedure TCustomCoolBar.CreateWnd; procedure TCustomCoolBar.CreateWnd;
begin begin
inherited CreateWnd; inherited CreateWnd;
FDefCursor := Cursor; FCursorBkgnd := Cursor;
DoFontChanged; DoFontChanged;
end; end;
procedure TCustomCoolBar.DoFontChanged;
var i: Integer;
begin
FTextHeight := Canvas.TextHeight('Žy|');
for i := 0 to FBands.Count-1 do
FBands[i].CalcTextWidth;
end;
procedure TCustomCoolBar.DrawTiledBitmap(ARect: TRect; ABitmap: TBitmap); procedure TCustomCoolBar.DrawTiledBitmap(ARect: TRect; ABitmap: TBitmap);
var i, j, x, y, aWidth, aHeight: Integer; var i, j, x, y, aWidth, aHeight: Integer;
begin begin
@ -565,17 +631,16 @@ begin
Canvas.Clipping := False; Canvas.Clipping := False;
end; end;
procedure TCustomCoolBar.DoFontChanged;
begin
FTextHeight := Canvas.TextHeight('Žy|');
end;
procedure TCustomCoolBar.EndUpdate; procedure TCustomCoolBar.EndUpdate;
begin begin
inherited EndUpdate; inherited EndUpdate;
//DebugLn('EndUpdate calls CalculateAndAlign'); //DebugLn('EndUpdate calls CalculateAndAlign');
CalculateAndAlign; if FUpdateCount = 0 then begin
Invalidate; DisableAutoSizing;
CalculateAndAlign;
EnableAutoSizing;
Invalidate;
end;
end; end;
procedure TCustomCoolBar.FontChanged(Sender: TObject); procedure TCustomCoolBar.FontChanged(Sender: TObject);
@ -586,10 +651,61 @@ begin
CalculateAndAlign; CalculateAndAlign;
end; end;
function TCustomCoolBar.RowEndHelper(ALeft, AVisInd: Integer): Boolean; procedure TCustomCoolBar.InsertControl(AControl: TControl; Index: integer);
var aBand: TCoolBand;
begin begin
Result := FVisiBands[AVisInd+1].Break or Vertical inherited InsertControl(AControl, Index);
or (ALeft+FVisiBands[AVisInd+1].Width > ClientWidth); //DebugLn('TCustomCoolBar.InsertControl '+inttostr(FUpdateCount));
if (AControl is TWinControl) and not (csLoading in ComponentState) then begin
aBand := Bands.FindBand(AControl);
if aBand = Nil then begin
//DebugLn('TCoolBar.InsertControl: Adding band for Comp=' + AControl.Name + ', class=' + AControl.ClassName);
BeginUpdate;
aBand := FBands.Add;
aBand.Control := AControl;
aBand.Width := aBand.CalcPrefferedWidth;
EndUpdate;
end;
end;
end;
procedure TCustomCoolBar.Invalidate;
var aBorderWidth: Integer;
begin
aBorderWidth := 0;
if EdgeOuter <> esNone then inc(aBorderWidth);
if EdgeInner <> esNone then inc(aBorderWidth);
if (FBorderWidth <> aBorderWidth) or (FBorderEdges <> EdgeBorders) then begin
FBorderWidth := aBorderWidth;
FBorderEdges := EdgeBorders;
if ebLeft in EdgeBorders then
FBorderLeft := aBorderWidth
else
FBorderLeft := 0;
if ebTop in EdgeBorders then
FBorderTop := aBorderWidth
else
FBorderTop := 0;
if ebRight in EdgeBorders then
FBorderRight := aBorderWidth
else
FBorderRight := 0;
if ebBottom in EdgeBorders then
FBorderBottom := aBorderWidth
else
FBorderBottom := 0;
CalculateAndAlign;
//DebugLn('Change BorderEdge');
end;
inherited Invalidate;
end;
function TCustomCoolBar.IsFirstAtRow(ABand: Integer): Boolean;
begin
if not FRightToLeft then
Result := (FVisiBands[ABand].FLeft = FBorderLeft)
else
Result := (FVisiBands[ABand].Right = Width-FBorderRight);
end; end;
function TCustomCoolBar.IsRowEnd(ALeft, AVisibleIndex: Integer): Boolean; function TCustomCoolBar.IsRowEnd(ALeft, AVisibleIndex: Integer): Boolean;
@ -597,40 +713,6 @@ begin
Result := (AVisibleIndex < length(FVisiBands)-1) and RowEndHelper(ALeft, AVisibleIndex); Result := (AVisibleIndex < length(FVisiBands)-1) and RowEndHelper(ALeft, AVisibleIndex);
end; end;
procedure TCustomCoolBar.InsertControl(AControl: TControl; Index: integer);
var aBand: TCoolBand;
begin
inherited InsertControl(AControl, Index);
//DebugLn('TCustomCoolBar.InsertControl');
if (FUpdateCount = 0) and (AControl is TWinControl) and
not (csLoading in ComponentState) then
begin
aBand := Bands.FindBand(AControl);
if aBand = Nil then
begin
//DebugLn('TCoolBar.InsertControl: Adding band for Comp=' + AControl.Name + ', class=' + AControl.ClassName);
BeginUpdate;
aBand := FBands.Add;
aBand.Control := AControl;
aBand.Width := aBand.CalcPrefferedWidth;
EndUpdate;
end;
end;
end;
procedure TCustomCoolBar.RemoveControl(AControl: TControl);
var aBand: TCoolBand;
begin
inherited RemoveControl(AControl);
aBand := Bands.FindBand(AControl);
if assigned(aBand) then begin
//DebugLn('TCoolBar.RemoveControl: Comp=' + AControl.Name + ', class=' + AControl.ClassName);
aBand.FControl := nil;
CalculateAndAlign;
Invalidate;
end;
end;
procedure TCustomCoolBar.Loaded; procedure TCustomCoolBar.Loaded;
begin begin
inherited Loaded; inherited Loaded;
@ -645,50 +727,44 @@ begin
inherited MouseDown(Button, Shift, X, Y); inherited MouseDown(Button, Shift, X, Y);
MouseToBandPos(X, Y, aBand, aGrabber); MouseToBandPos(X, Y, aBand, aGrabber);
FDraggedBandIndex := aBand; FDraggedBandIndex := aBand;
if aBand >= 0 then begin //Hit any Band if aBand >= 0 then begin //hit any Band
if not aGrabber or (FVisiBands[aBand].FLeft = cBorderWidth) if not aGrabber or IsFirstAtRow(aBand)
or FFixedSize or FVisiBands[aBand-1].FFixedSize then begin or FFixedSize or FVisiBands[aBand-1].FFixedSize then begin
if not FFixedOrder then begin //Move Band if not FFixedOrder then FDragBand := dbMove; //move Band
FDragBand := dbMove; end else begin //resize Band
Cursor := crDrag;
end;
end else begin //Resize Band
if not FFixedSize and not FVisiBands[aBand-1].FFixedSize then begin if not FFixedSize and not FVisiBands[aBand-1].FFixedSize then begin
FDragBand := dbResize; FDragBand := dbResize;
FDragInitPos := X-FVisiBands[aBand-1].FWidth-FVisiBands[aBand-1].FLeft; if not FRightToLeft then
FDragInitPos := X-FVisiBands[aBand-1].FWidth-FVisiBands[aBand-1].FLeft
else
FDragInitPos := FVisiBands[aBand-1].FLeft-X;
end; end;
end; end;
end; end;
end; end;
procedure TCustomCoolBar.MouseEnter;
begin
inherited MouseEnter;
FDefCursor := Cursor;
end;
procedure TCustomCoolBar.MouseLeave;
begin
inherited MouseLeave;
Cursor := FDefCursor;
end;
procedure TCustomCoolBar.MouseMove(Shift: TShiftState; X, Y: Integer); procedure TCustomCoolBar.MouseMove(Shift: TShiftState; X, Y: Integer);
var aBand: Integer; var aBand: Integer;
aGrabber: Boolean; aGrabber: Boolean;
begin begin
inherited MouseMove(Shift, X, Y); inherited MouseMove(Shift, X, Y);
if (FDragBand = dbNone) and not FFixedSize then begin if length(FVisiBands) > 1 then begin
MouseToBandPos(X, Y, aBand, aGrabber); if (FDragBand = dbNone) and not FFixedSize then begin
if (aBand >= 1) and not FVisiBands[aBand-1].FFixedSize then begin MouseToBandPos(X, Y, aBand, aGrabber);
if aGrabber and (aBand > 0) and (FVisiBands[aBand].FLeft > cBorderWidth) then if aBand >= 0 then begin
Cursor := crHSplit if aGrabber and (aBand > 0) and not IsFirstAtRow(aBand) then
else ChangeCursor(True, True)
Cursor := FDefCursor; else
end; if length(FVisiBands) > 1 then ChangeCursor(True, False);
end else end else
if FDragBand = dbResize then begin ChangeCursor(False, False);
FVisiBands[FDraggedBandIndex-1].Width := X-FDragInitPos-FVisiBands[FDraggedBandIndex-1].FLeft; end else
if FDragBand = dbResize then begin
if not FRightToLeft then
FVisiBands[FDraggedBandIndex-1].Width := X-FDragInitPos-FVisiBands[FDraggedBandIndex-1].FLeft
else
FVisiBands[FDraggedBandIndex-1].Width := -X-FDragInitPos+FVisiBands[FDraggedBandIndex-1].FLeft+FVisiBands[FDraggedBandIndex-1].FWidth;
end;
end; end;
end; end;
@ -699,21 +775,22 @@ begin
AGrabber := False; AGrabber := False;
aCountM1 := length(FVisiBands)-1; aCountM1 := length(FVisiBands)-1;
if aCountM1 >= 0 then begin if aCountM1 >= 0 then begin
if Y > (FVisiBands[aCountM1].FTop+FVisiBands[aCountM1].FHeight+cBorderWidth) then if Y > (FVisiBands[aCountM1].Top+FVisiBands[aCountM1].Height+cDivider) then
ABand := -1 // new row, i.e. free space below the last row ABand := -1 //new row, i.e. free space below the last row
else else
for i := 0 to aCountM1 do for i := 0 to aCountM1 do begin
begin aLeft := FVisiBands[i].FRealLeft;
aLeft := FVisiBands[i].FLeft;
aTop := FVisiBands[i].FTop; aTop := FVisiBands[i].FTop;
if PtInRect(Rect(aLeft, aTop, aLeft+FVisiBands[i].FRealWidth, if PtInRect(Rect(aLeft, aTop, aLeft+FVisiBands[i].FRealWidth,
aTop+FVisiBands[i].FHeight), Point(X, Y)) then aTop+FVisiBands[i].FHeight), Point(X, Y)) then begin
begin
ABand := i; ABand := i;
//DebugLn('Mouse over Band ', i); //DebugLn('Mouse over Band ', i);
AGrabber := (X <= (aLeft+GrabWidth+1)); if not FRightToLeft then
AGrabber := (X <= (aLeft+GrabWidth+1))
else
AGrabber := (X >= (FVisiBands[i].FLeft+FVisiBands[i].Width-GrabWidth-1));
//DebugLn('Grabber '+BoolToStr(AGrabber), ' hit', ' not hit'); //DebugLn('Grabber '+BoolToStr(AGrabber), ' hit', ' not hit');
exit; // EXIT! exit; //Exit!
end; end;
end; end;
end; end;
@ -734,13 +811,14 @@ begin
if (FVisiBands[FDraggedBandIndex].Break or Vertical) if (FVisiBands[FDraggedBandIndex].Break or Vertical)
and (FDraggedBandIndex < (length(FVisiBands)-1)) and (FDraggedBandIndex < (length(FVisiBands)-1))
then FVisiBands[FDraggedBandIndex+1].FBreak := True; then FVisiBands[FDraggedBandIndex+1].FBreak := True;
if (X > (FVisiBands[aBand].FLeft+FVisiBands[aBand].Width)) then begin //beyond the last band in row if (not FRightToLeft and (X > (FVisiBands[aBand].FLeft+FVisiBands[aBand].Width)))
or (FRightToLeft and (X < FVisiBands[aBand].FLeft)) then begin //beyond the last band in row
FVisiBands[FDraggedBandIndex].FBreak := False; FVisiBands[FDraggedBandIndex].FBreak := False;
if FDraggedBandIndex > aBand then if FDraggedBandIndex > aBand then
FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand+1) FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand+1)
else else
FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand); FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand);
if FDraggedBandIndex = (aBand+1) then needRecalc := True; needRecalc := (FDraggedBandIndex = (aBand+1));
end else begin //on another Band end else begin //on another Band
FVisiBands[FDraggedBandIndex].FBreak := FVisiBands[aBand].Break; FVisiBands[FDraggedBandIndex].FBreak := FVisiBands[aBand].Break;
if FDraggedBandIndex > aBand then begin //move up or left if FDraggedBandIndex > aBand then begin //move up or left
@ -752,17 +830,31 @@ begin
FVisiBands[FDraggedBandIndex].FBreak := False; FVisiBands[FDraggedBandIndex].FBreak := False;
FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand); FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand);
end else begin //other row end else begin //other row
if (not FVertical) and (FVisiBands[FDraggedBandIndex].FLeft > cBorderWidth) then if not FRightToLeft then begin
FVisiBands[aBand].FBreak := False; if (not FVertical) and (FVisiBands[FDraggedBandIndex].Left > FBorderLeft) then
if (FVisiBands[FDraggedBandIndex].FLeft = cBorderWidth) FVisiBands[aBand].FBreak := False;
and (FVisiBands[aBand].FLeft = cBorderWidth) if (FVisiBands[FDraggedBandIndex].FLeft = FBorderLeft)
and (FVertical or ((aBand-FDraggedBandIndex) = 1) and (FVisiBands[aBand].FLeft = FBorderLeft)
or (length(FVisiBands) = (aBand+1)) and (FVertical or ((aBand-FDraggedBandIndex) = 1)
or (FVisiBands[aBand+1].FLeft = cBorderWidth)) then or (length(FVisiBands) = (aBand+1))
FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand) or (FVisiBands[aBand+1].FLeft = FBorderLeft)) then
else FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand)
FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand-1); else
if FDraggedBandIndex = (aBand-1) then needRecalc := True; FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand-1);
end else begin
if (not FVertical) and
(FVisiBands[FDraggedBandIndex].Right < (Width-FBorderRight)) then
FVisiBands[aBand].FBreak := False;
if (FVisiBands[FDraggedBandIndex].Right = (Width-FBorderRight))
and (FVisiBands[aBand].Right = (Width-FBorderRight))
and (FVertical or ((aBand-FDraggedBandIndex) = 1)
or (length(FVisiBands) = (aBand+1))
or (FVisiBands[aBand+1].FLeft = FBorderLeft)) then
FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand)
else
FVisiBands[FDraggedBandIndex].Index := CalculateRealIndex(aBand-1);
end;
needRecalc := (FDraggedBandIndex = (aBand-1));
end; end;
end else begin //new row end else begin //new row
FVisiBands[FDraggedBandIndex].FBreak := True; FVisiBands[FDraggedBandIndex].FBreak := True;
@ -781,10 +873,7 @@ begin
end; end;
end; end;
end; end;
if FDragBand > dbNone then begin FDragBand := dbNone;
Cursor := FDefCursor;
FDragBand := dbNone;
end;
end; end;
procedure TCustomCoolBar.Notification(AComponent: TComponent; Operation: TOperation); procedure TCustomCoolBar.Notification(AComponent: TComponent; Operation: TOperation);
@ -793,7 +882,7 @@ begin
if csDestroying in ComponentState then Exit; if csDestroying in ComponentState then Exit;
if Operation = opRemove then begin if Operation = opRemove then begin
//DebugLn('TCoolBar.Notification: Operation = opRemove'); //DebugLn('TCoolBar.Notification: Operation = opRemove');
if AComponent = FImages then Images := nil; if AComponent = FImages then Images := Nil;
end; end;
end; end;
@ -874,16 +963,16 @@ const arBevel: array[False..True] of TColor = (clBtnShadow, clBtnHighlight);
begin begin
//DebugLn('PaintSeparator'); //DebugLn('PaintSeparator');
Canvas.Pen.Color := arBevel[aRaisedBevel]; Canvas.Pen.Color := arBevel[aRaisedBevel];
Canvas.Line(1, Y, ClientWidth-2, Y); Canvas.Line(FBorderLeft, Y, Width-FBorderRight, Y);
inc(Y); inc(Y);
Canvas.Pen.Color := arBevel[not aRaisedBevel]; Canvas.Pen.Color := arBevel[not aRaisedBevel];
Canvas.Line(2, Y, ClientWidth-2, Y); Canvas.Line(FBorderLeft, Y, Width-FBorderRight, Y);
end; end;
begin begin
inherited Paint; inherited Paint;
//DebugLn('TCoolBar.Paint'); //DebugLn('TCoolBar.Paint');
//Draw Bitmap Background //draw Bitmap Background
if FBitmap.Width > 0 then DrawTiledBitmap(ClientRect, FBitmap); if FBitmap.Width > 0 then DrawTiledBitmap(ClientRect, FBitmap);
aCountM1 := length(FVisiBands)-1; aCountM1 := length(FVisiBands)-1;
if aCountM1 >= 0 then begin if aCountM1 >= 0 then begin
@ -894,20 +983,19 @@ begin
gsGripper: aGrabDetails := ThemeServices.GetElementDetails(trGripper); gsGripper: aGrabDetails := ThemeServices.GetElementDetails(trGripper);
gsButton: aGrabDetails := ThemeServices.GetElementDetails(tbPushButtonDisabled); gsButton: aGrabDetails := ThemeServices.GetElementDetails(tbPushButtonDisabled);
end; end;
if FShowText or assigned(FImages) then begin if FShowText or Assigned(FImages) then begin
if IsEnabled then if IsEnabled then
aDetails := ThemeServices.GetElementDetails(tbPushButtonNormal) aDetails := ThemeServices.GetElementDetails(tbPushButtonNormal)
else else
aDetails := ThemeServices.GetElementDetails(tbPushButtonDisabled); aDetails := ThemeServices.GetElementDetails(tbPushButtonDisabled);
aFlags := DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX; aFlags := DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX;
if IsRightToLeft then aFlags := aFlags or DT_RTLREADING; if FRightToLeft then aFlags := aFlags or DT_RTLREADING;
end; end;
for i := 0 to aCountM1 do for i := 0 to aCountM1 do begin
begin
aLeft := FVisiBands[i].FLeft; aLeft := FVisiBands[i].FLeft;
aTop := FVisiBands[i].FTop; aTop := FVisiBands[i].FTop;
aRect := Rect(aLeft, aTop, aLeft+FVisiBands[i].FRealWidth+1, aTop+FVisiBands[i].FHeight); aRect := Rect(aLeft, aTop, aLeft+FVisiBands[i].FRealWidth+1, aTop+FVisiBands[i].FHeight);
//Paint Band Background //paint Band Background
if FVisiBands[i].Bitmap.Width > 0 then begin if FVisiBands[i].Bitmap.Width > 0 then begin
DrawTiledBitmap(aRect, FVisiBands[i].Bitmap); DrawTiledBitmap(aRect, FVisiBands[i].Bitmap);
end else begin end else begin
@ -922,44 +1010,81 @@ begin
end; end;
end; end;
end; end;
//Paint a Grabber //paint a Grabber
x := aLeft+2; if not FRightToLeft then
x := aLeft+cGrabIndent
else
x := aLeft+FVisiBands[i].Width-GrabWidth-cGrabIndent;
PaintGrabber(Rect(x, aTop+2, x+GrabWidth-1, aTop+FVisiBands[i].FHeight-3)); PaintGrabber(Rect(x, aTop+2, x+GrabWidth-1, aTop+FVisiBands[i].FHeight-3));
//Paint Image if not FRightToLeft then
x := aLeft+GrabWidth+2+TCoolBand.cHorSpacing; x := x+GrabWidth+TCoolBand.cHorSpacing
if assigned(FImages) and (FVisiBands[i].ImageIndex >= 0) then begin else
x := x-TCoolBand.cHorSpacing;
//paint Image
if Assigned(FImages) and (FVisiBands[i].ImageIndex >= 0) then begin
if FRightToLeft then dec(x, FImages.Width);
ThemeServices.DrawIcon(Canvas, aDetails, ThemeServices.DrawIcon(Canvas, aDetails,
Point(x, aTop+(FVisiBands[i].FHeight-FImages.Height) div 2), Point(x, aTop+(FVisiBands[i].FHeight-FImages.Height) div 2),
FImages, FVisiBands[i].ImageIndex); FImages, FVisiBands[i].ImageIndex);
inc(x, FImages.Width+TCoolBand.cHorSpacing); if not FRightToLeft then
inc(x, FImages.Width+TCoolBand.cHorSpacing)
else
dec(x, TCoolBand.cHorSpacing);
end; end;
//Paint Text //paint Text
if FShowText then begin if FShowText then begin
aRect := Rect(x, aTop, x+FVisiBands[i].Width, aTop+FVisiBands[i].FHeight); if FRightToLeft then dec(x, FVisiBands[i].FTextWidth);
aRect := Rect(x, aTop, x+FVisiBands[i].FTextWidth, aTop+FVisiBands[i].FHeight);
ThemeServices.DrawText(Canvas, aDetails, FVisiBands[i].Text, aRect, aFlags, 0); ThemeServices.DrawText(Canvas, aDetails, FVisiBands[i].Text, aRect, aFlags, 0);
end; end;
// Paint a Separator border below the row of bands ____ //paint a Separator border below the row of bands ____
x := aLeft;
inc(aLeft, FVisiBands[i].Width); inc(aLeft, FVisiBands[i].Width);
aRowEnd := IsRowEnd(aLeft, i); if not FRightToLeft then
aRowEnd := IsRowEnd(aLeft, i)
else
aRowEnd := IsRowEnd(Width-x, i);
if (aRowEnd or ((i = aCountM1) and not AutoSize) or (Align in [alLeft, alRight])) if (aRowEnd or ((i = aCountM1) and not AutoSize) or (Align in [alLeft, alRight]))
and (FBandBorderStyle = bsSingle) and (FBandBorderStyle = bsSingle)
then PaintSeparator(aTop+FVisiBands[i].FHeight); then PaintSeparator(aTop+FVisiBands[i].FHeight);
if not aRowEnd and (i < aCountM1) and (FBandBorderStyle = bsSingle) then begin if not aRowEnd and (i < aCountM1) and (FBandBorderStyle = bsSingle) then begin
//Paint Divider | //paint Divider |
if not FRightToLeft then x := aLeft-cDivider;
Canvas.Pen.Color := arBevel[not aRaisedBevel]; Canvas.Pen.Color := arBevel[not aRaisedBevel];
Canvas.Line(aLeft-1, aTop+1, aLeft-1, aTop+FVisiBands[i].FHeight-1); Canvas.Line(x+1, aTop+1, x+1, aTop+FVisiBands[i].FHeight-1);
Canvas.Pen.Color := arBevel[aRaisedBevel]; Canvas.Pen.Color := arBevel[aRaisedBevel];
Canvas.Line(aLeft-2, aTop+1, aLeft-2, aTop+FVisiBands[i].FHeight-1); Canvas.Line(x, aTop+1, x, aTop+FVisiBands[i].FHeight-1);
end; end;
end; end;
end; end;
end; end;
procedure TCustomCoolBar.RemoveControl(AControl: TControl);
var aBand: TCoolBand;
begin
inherited RemoveControl(AControl);
aBand := Bands.FindBand(AControl);
if Assigned(aBand) then begin
//DebugLn('TCoolBar.RemoveControl: Comp=' + AControl.Name + ', class=' + AControl.ClassName);
aBand.FControl := Nil;
CalculateAndAlign;
Invalidate;
end;
end;
function TCustomCoolBar.RowEndHelper(ALeft, AVisibleIdx: Integer): Boolean;
begin
Result := FVisiBands[AVisibleIdx+1].Break or Vertical
or (ALeft+FVisiBands[AVisibleIdx+1].Width-cDivider >= Width);
end;
procedure TCustomCoolBar.WMSize(var Message: TLMSize); procedure TCustomCoolBar.WMSize(var Message: TLMSize);
begin begin
//DebugLn('WMSize'); //DebugLn('WMSize');
inherited WMSize(Message); inherited WMSize(Message);
CalculateAndAlign; if not Autosize then begin
Invalidate; //Required by GTK2 CalculateAndAlign;
Invalidate; //required by GTK2
end;
end; end;