Browse Source

base: moved rendered scrollbars to TFresnelElement

mattias 5 months ago
parent
commit
efdc9b25a5
2 changed files with 77 additions and 42 deletions
  1. 49 2
      src/base/fresnel.dom.pas
  2. 28 40
      src/base/fresnel.renderer.pas

+ 49 - 2
src/base/fresnel.dom.pas

@@ -1239,6 +1239,24 @@ type
     Procedure Render(aRenderer : IFresnelRenderer);
   end;
 
+  { TFresnelScrollBar }
+
+  TFresnelScrollBar = class
+  private
+    FElement: TFresnelElement;
+    FHorizontal: boolean;
+  public
+    Box: TFresnelRect;
+    Position: TFresnelLength; // ScrollLeft/Top
+    Size: TFresnelLength; // ScrollWidth/Height
+    Page: TFresnelLength; // ClientWidth/Height
+    Color: TFPColor;
+    constructor Create(TheElement: TFresnelElement; aHorizontal: boolean);
+    destructor Destroy; override;
+    property Element: TFresnelElement read FElement;
+    property Horizontal: boolean read FHorizontal;
+  end;
+
   { TFresnelFontDesc - font descriptor }
 
   TFresnelFontDesc = record
@@ -1309,6 +1327,8 @@ type
     FRendered: boolean;
     FRenderedBorderBox: TFresnelRect;
     FRenderedContentBox: TFresnelRect;
+    FScrollBarHorizontal: TFresnelScrollBar;
+    FScrollBarVertical: TFresnelScrollBar;
     FScrollLeft: TFresnelLength;
     FScrollTop: TFresnelLength;
     FStates: TStates;
@@ -1512,6 +1532,8 @@ type
     property ScrollTop: TFresnelLength read FScrollTop write SetScrollTop;
     property ScrollWidth: TFresnelLength read GetScrollWidth;
     property ScrollHeight: TFresnelLength read GetScrollHeight;
+    property ScrollBarHorizontal: TFresnelScrollBar read FScrollBarHorizontal;
+    property ScrollBarVertical: TFresnelScrollBar read FScrollBarVertical;
     // Renderer
     function GetBorderBoxOnViewport: TFresnelRect; virtual;
     function GetRenderedPaddingBox: TFresnelRect;
@@ -6534,13 +6556,36 @@ begin
   FNodes.Sort(Compare,Context,SortBase.DefaultSortingAlgorithm);
 end;
 {$ELSE}
-procedure TFresnelLayoutNode.SortNodes(
-  const Compare: TListSortCompare);
+procedure TFresnelLayoutNode.SortNodes(const Compare: TListSortCompare);
 begin
   FNodes.Sort(Compare);
 end;
 {$ENDIF}
 
+{ TFresnelScrollBar }
+
+constructor TFresnelScrollBar.Create(TheElement: TFresnelElement; aHorizontal: boolean);
+begin
+  FElement:=TheElement;
+  FHorizontal:=aHorizontal;
+  if Horizontal then
+    FElement.FScrollBarHorizontal:=Self
+  else
+    FElement.FScrollBarVertical:=Self;
+end;
+
+destructor TFresnelScrollBar.Destroy;
+begin
+  if FElement<>nil then
+  begin
+    if FHorizontal then
+      FElement.FScrollBarHorizontal:=nil
+    else
+      FElement.FScrollBarVertical:=nil;
+  end;
+  inherited Destroy;
+end;
+
 { TFresnelFontDesc }
 
 function TFresnelFontDesc.Compare(const Desc: TFresnelFontDesc): integer;
@@ -9327,6 +9372,8 @@ procedure TFresnelElement.Clear;
 var
   i: Integer;
 begin
+  FScrollBarHorizontal.Free; // auto nil
+  FScrollBarVertical.Free; // auto nil
   FreeAndNil(FStyleElement);
   FreeAndNil(FCSSValues);
   FCSSClasses.Clear;

+ 28 - 40
src/base/fresnel.renderer.pas

@@ -63,21 +63,6 @@ type
         property Renderer : TFresnelRenderer read FRenderer;
       end;
 
-      { TScrollBar }
-
-      TScrollBar = class
-      private
-        FRenderer : TFresnelRenderer;
-      public
-        Box: TFresnelRect;
-        Horizontal: boolean;
-        Position: TFresnelLength; // ScrollLeft/Top
-        Size: TFresnelLength; // ScrollWidth/Height
-        Page: TFresnelLength; // ClientWidth/Height
-        Color: TFPColor;
-        constructor Create(aRenderer: TFresnelRenderer);
-        property Renderer: TFresnelRenderer read FRenderer;
-      end;
   protected
     // Not in IFresnelRenderer
     // Create backend-specific TBorderAndBackground if needed
@@ -88,9 +73,9 @@ type
     procedure DrawElBackground(El: TFresnelElement; Params: TBorderAndBackground); virtual;
     // Draw the border of the element. This is called after drawing the background. Not called if PrepareBackgroundBorder returned False.
     procedure DrawElBorder(El: TFresnelElement; Params: TBorderAndBackground); virtual;
-    function CreateScrollBar : TScrollBar; virtual;
+    function CreateScrollBar(El: TFresnelElement; Horizontal: boolean): TFresnelScrollBar; virtual;
     // Draw the scrollbars of the element. Called after drawing content.
-    procedure DrawScrollBar(El: TFresnelElement; aBar: TScrollBar); virtual;
+    procedure DrawScrollBar(aBar: TFresnelScrollBar); virtual;
     procedure DrawScrollBarCorner(El: TFresnelElement; const r: TFresnelRect); virtual;
     procedure DrawScrollBars(El: TFresnelElement); virtual;
     // Draw an element
@@ -513,13 +498,15 @@ begin
   end;
 end;
 
-function TFresnelRenderer.CreateScrollBar: TScrollBar;
+function TFresnelRenderer.CreateScrollBar(El: TFresnelElement; Horizontal: boolean
+  ): TFresnelScrollBar;
 begin
-  Result:=TScrollBar.Create(Self);
+  Result:=TFresnelScrollBar.Create(El,Horizontal);
 end;
 
-procedure TFresnelRenderer.DrawScrollBar(El: TFresnelElement; aBar: TScrollBar);
+procedure TFresnelRenderer.DrawScrollBar(aBar: TFresnelScrollBar);
 var
+  El: TFresnelElement;
   TrackColor, ThumbColor: TFPColor;
   FromPos, ToPos, l: TFresnelLength;
   r: TFresnelRect;
@@ -527,6 +514,7 @@ var
   ThumbR: TFresnelRoundRect;
   c: TFresnelCSSCorner;
 begin
+  El:=aBar.Element;
   r:=aBar.Box;
 
   // draw track
@@ -594,7 +582,7 @@ var
   LNode: TUsedLayoutNode;
   BarWidth, BarHeight: TFresnelLength;
   r, aPaddingBox: TFresnelRect;
-  aScrollbar: TScrollBar;
+  aScrollbar: TFresnelScrollBar;
   IsLeft, HasVertBar, HasHorzBar: Boolean;
 begin
   LNode:=TUsedLayoutNode(El.LayoutNode);
@@ -619,6 +607,7 @@ begin
   aPaddingBox:=El.GetRenderedPaddingBox;
   //writeln('TFresnelRenderer.DrawScrollBars ',El.Name,' PaddingBox=',aPaddingBox.ToString);
 
+  aScrollbar:=El.ScrollBarVertical;
   if HasVertBar then
   begin
     r:=aPaddingBox;
@@ -629,11 +618,12 @@ begin
     if HasHorzBar then
       r.Bottom:=Max(r.Top,r.Bottom-BarHeight);
 
-    if not r.IsEmpty then
-    begin
-      aScrollbar:=CreateScrollBar;
+    if r.IsEmpty then
+      aScrollbar.Free
+    else begin
+      if aScrollbar=nil then
+        aScrollbar:=CreateScrollBar(El,false);
       try
-        aScrollbar.Horizontal:=false;
         aScrollbar.Size:=LNode.ScrollHeight;
         aScrollbar.Position:=El.ScrollTop;
         aScrollbar.Page:=El.ClientHeight;
@@ -643,12 +633,15 @@ begin
         {$IFDEF VerboseFresnelScrolling}
         writeln('TFresnelRenderer.DrawScrollBars ',El.Name,' ScrollHeight=',FloatToCSSStr(El.ScrollHeight),' ClientHeight',FloatToCSSStr(El.ClientHeight),' ScrollTop=',FloatToCSSStr(El.ScrollTop)+' BarWidth='+FloatToCSSStr(BarWidth)+' r='+r.ToString);
         {$ENDIF}
-        DrawScrollBar(El,aScrollbar);
+        DrawScrollBar(aScrollbar);
       finally
         aScrollbar.Free;
       end;
     end;
-  end;
+  end else if aScrollbar<>nil then
+    aScrollbar.Free;
+
+  aScrollbar:=El.ScrollBarHorizontal;
   if HasHorzBar then
   begin
     r:=aPaddingBox;
@@ -661,11 +654,12 @@ begin
         r.Right:=r.Right-BarWidth;
     end;
 
-    if not r.IsEmpty then
-    begin
-      aScrollbar:=CreateScrollBar;
+    if r.IsEmpty then
+      aScrollbar.Free
+    else begin
+      if aScrollbar=nil then
+        aScrollbar:=CreateScrollBar(El,true);
       try
-        aScrollbar.Horizontal:=true;
         aScrollbar.Size:=LNode.ScrollWidth;
         aScrollbar.Position:=El.ScrollLeft;
         aScrollbar.Page:=El.ClientWidth;
@@ -675,12 +669,13 @@ begin
         {$IFDEF VerboseFresnelScrolling}
         writeln('TFresnelRenderer.DrawScrollBars ',El.Name,' ScrollWidth=',FloatToCSSStr(El.ScrollWidth),' ClientWidth=',FloatToCSSStr(El.ClientWidth),' ScrollLeft=',FloatToCSSStr(El.ScrollLeft)+' BarHeight='+FloatToCSSStr(BarHeight));
         {$ENDIF}
-        DrawScrollBar(El,aScrollbar);
+        DrawScrollBar(aScrollbar);
       finally
         aScrollbar.Free;
       end;
     end;
-  end;
+  end else if aScrollbar<>nil then
+    aScrollbar.Free;
 
   if HasVertBar and HasHorzBar then
   begin
@@ -954,12 +949,5 @@ begin
   Result:=FHasRadius;
 end;
 
-{ TFresnelRenderer.TScrollBar }
-
-constructor TFresnelRenderer.TScrollBar.Create(aRenderer: TFresnelRenderer);
-begin
-  FRenderer:=aRenderer;
-end;
-
 end.