SpkToolbar: Support RTL layout of buttons within panes.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8956 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2023-10-13 09:33:12 +00:00
parent d3bbef0991
commit 2ff41ccea4
2 changed files with 95 additions and 24 deletions

View File

@ -1807,7 +1807,7 @@ begin
fontColor := TColorTools.ColorToGrayscale(fontColor);
// Text
if FShowCaption then
if FShowCaption and (FCaption <> '') then
begin
ABuffer.Canvas.Font.Assign(FAppearance.Element.CaptionFont);
ABuffer.Canvas.Font.Color := fontColor;

View File

@ -74,6 +74,7 @@ type
// *** Generating a layout of elements ***
function GenerateLayout: TSpkPaneItemsLayout;
function IsRightToLeft: Boolean;
// *** Designtime and LFM support ***
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
@ -100,6 +101,8 @@ type
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetRootComponent: TComponent;
// *** Mouse support ***
procedure MouseLeave;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
@ -645,11 +648,13 @@ var
ItemSize: TSpkItemSize;
ForceNewColumn: boolean;
LastX: integer;
MaxRowX: integer;
EndRowX: integer;
ColumnX: integer;
rows: Integer;
sgn: Integer;
ItemWidth: Integer;
tmpRect: T2DIntRect;
isRTL: Boolean;
begin
Result.Rects := Default(T2DIntRectArray);
@ -659,6 +664,9 @@ begin
if FItems.Count = 0 then
exit;
isRTL := IsRightToLeft;
sgn := IfThen(isRTL, -1, +1);
// Note: the algorithm is structured in such a way that three of them,
// CurrentColumn, CurrentRow and CurrentItem, point to an element that
// is not yet present (just after the recently added element).
@ -735,19 +743,19 @@ begin
Result.Rects[i].Create(-1, -1, -1, -1);
{$ENDIF}
MaxRowX := 0;
EndRowX := 0;
// Now, we iterate through the layout, fixing the recit.
for c := 0 to High(Layout) do
begin
if c>0 then
begin
LastX := MaxRowX + PaneColumnSpacer;
MaxRowX := LastX;
LastX := EndRowX + sgn * PaneColumnSpacer;
EndRowX := LastX;
end
else
begin
LastX := MaxRowX;
LastX := EndRowX;
end;
ColumnX := LastX;
@ -767,30 +775,56 @@ begin
begin
tmpRect.Top := PaneFullRowTopPadding;
tmpRect.Bottom := tmpRect.Top + PaneFullRowHeight - 1;
if isRTL then
begin
tmpRect.Right := LastX;
tmpRect.Left := LastX - ItemWidth + 1;
LastX := tmpRect.Left - 1;
if lastX < EndRowX then
EndRowX := LastX;
end else
begin
tmpRect.Left := LastX;
tmpRect.Right := LastX + ItemWidth - 1;
LastX := tmpRect.Right + 1;
if LastX > MaxRowX then
MaxRowX := LastX;
if LastX > EndRowX then
EndRowX := LastX;
end;
end
else
begin
if ItemGroupBehaviour in [gbContinuesGroup, gbEndsGroup] then
begin
if isRTL then
begin
tmpRect.Right := LastX;
tmpRect.Left := tmpRect.Right - ItemWidth + 1;
end else
begin
tmpRect.Left := LastX;
tmpRect.Right := tmpRect.Left + ItemWidth - 1;
end;
end
else
begin
// If the element is not the first one, it must be offset by
// the margin from the previous one
if isRTL then
begin
if i > 0 then
tmpRect.Right := LastX - PaneGroupSpacer
else
tmpRect.Right := LastX;
tmpRect.Left := tmpRect.Right - ItemWidth + 1;
end else
begin
if i>0 then
tmpRect.Left := LastX + PaneGroupSpacer
else
tmpRect.Left := LastX;
tmpRect.Right := tmpRect.Left + ItemWidth - 1;
end;
end;
{$REGION 'Calculation of tmpRect.top and bottom'}
case rows of
@ -825,18 +859,37 @@ begin
end;
{$ENDREGION}
if isRTL then
begin
LastX := tmpRect.Left - 1;
if LastX < EndRowX then
EndRowX := LastX;
end else
begin
LastX := tmpRect.right + 1;
if LastX > MaxRowX then
MaxRowX:=LastX;
if LastX > EndRowX then
EndRowX := LastX;
end;
end;
Result.Rects[Layout[c][r][i]] := tmpRect;
end;
end;
end;
// At this point, MaxRowX points to the first pixel behind the most
// At this point, EndRowX points to the first pixel behind the most
// right-hand element - ergo is equal to the width of the entire layout.
Result.Width := MaxRowX;
// (In case of Right-to-left EndRowX points to the first pixel BEFORE the
// most left-hand element)
Result.Width := abs(EndRowX);
// In case of RTL we must move the rects to the right of the pane;
// they have negative x coordinates so far.
if isRTL then
for c := 0 to High(Layout) do
for r := 0 to High(Layout[c]) do
for i := 0 to High(Layout[c, r]) do
Result.Rects[Layout[c,r,i]].Move(Result.Width, 0);
end;
procedure TSpkPane.GetChildren(Proc: TGetChildProc; Root: TComponent);
@ -848,6 +901,19 @@ begin
Proc(FItems.Items[i]);
end;
function TSpkPane.GetRootComponent: TComponent;
var
tab: TSpkBaseItem;
begin
Result := nil;
if Collection <> nil then
tab := TSpkBaseItem(Collection.RootComponent)
else
exit;
if (tab <> nil) and (tab.Collection <> nil) then
Result := tab.Collection.RootComponent;
end;
function TSpkPane.GetWidth: integer;
var
tmpBitmap: TBitmap;
@ -886,6 +952,11 @@ begin
Result := Max(PaneCaptionWidth, PaneElementsWidth);
end;
function TSpkPane.IsRightToLeft: Boolean;
begin
Result := (GetRootComponent as TControl).IsRightToLeft;
end;
procedure TSpkPane.Loaded;
begin
inherited;