From 2ff41ccea4c3d3884d1766e1b88f8f74c2878138 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Fri, 13 Oct 2023 09:33:12 +0000 Subject: [PATCH] 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 --- .../spktoolbar/SpkToolbar/spkt_Buttons.pas | 2 +- .../spktoolbar/SpkToolbar/spkt_Pane.pas | 117 ++++++++++++++---- 2 files changed, 95 insertions(+), 24 deletions(-) diff --git a/components/spktoolbar/SpkToolbar/spkt_Buttons.pas b/components/spktoolbar/SpkToolbar/spkt_Buttons.pas index 835eadf72..4acb4c332 100644 --- a/components/spktoolbar/SpkToolbar/spkt_Buttons.pas +++ b/components/spktoolbar/SpkToolbar/spkt_Buttons.pas @@ -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; diff --git a/components/spktoolbar/SpkToolbar/spkt_Pane.pas b/components/spktoolbar/SpkToolbar/spkt_Pane.pas index 75c471adc..30f602df5 100644 --- a/components/spktoolbar/SpkToolbar/spkt_Pane.pas +++ b/components/spktoolbar/SpkToolbar/spkt_Pane.pas @@ -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,29 +775,55 @@ begin begin tmpRect.Top := PaneFullRowTopPadding; tmpRect.Bottom := tmpRect.Top + PaneFullRowHeight - 1; - tmpRect.Left := LastX; - tmpRect.Right := LastX + ItemWidth - 1; - - LastX := tmpRect.Right + 1; - if LastX > MaxRowX then - MaxRowX := LastX; + 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 > EndRowX then + EndRowX := LastX; + end; end else begin if ItemGroupBehaviour in [gbContinuesGroup, gbEndsGroup] then begin - tmpRect.Left := LastX; - tmpRect.Right := tmpRect.Left + ItemWidth - 1; + 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 i>0 then - tmpRect.Left := LastX + PaneGroupSpacer - else - tmpRect.Left := LastX; - tmpRect.Right := tmpRect.Left + ItemWidth - 1; + 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'} @@ -825,18 +859,37 @@ begin end; {$ENDREGION} - LastX := tmpRect.right + 1; - if LastX > MaxRowX then - MaxRowX:=LastX; + if isRTL then + begin + LastX := tmpRect.Left - 1; + if LastX < EndRowX then + EndRowX := LastX; + end else + begin + LastX := tmpRect.right + 1; + 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;