Sfoglia il codice sorgente

inspector: longhands

mattias 19 ore fa
parent
commit
fd2248b46e

+ 141 - 43
src/base/fresnel.cssstyleinspector.pas

@@ -15,14 +15,23 @@ unit Fresnel.CSSStyleInspector;
 interface
 
 uses
-  Classes, SysUtils, FPImage, fpCSSTree, fpCSSResParser, fpCSSResolver,
+  Classes, SysUtils, Math, FPImage, fpCSSTree, fpCSSResParser, fpCSSResolver,
   Fresnel.DOM, Fresnel.Classes, Fresnel.Controls, Fresnel.Events, FCL.Events;
 
 type
 
-  { TCSSInspBoxModell }
+  { TCSSInspDropArrow }
 
-  TCSSInspBoxModell = class(TDiv)
+  TCSSInspDropArrow = class(TSpan)
+  protected
+    procedure DoRender(aRenderer: IFresnelRenderer); override;
+  public
+    procedure ComputeCSSLayoutFinished; override;
+  end;
+
+  { TCSSInspBoxModel }
+
+  TCSSInspBoxModel = class(TDiv)
   private
     FBorderColor: TFPColor;
     FContentColor: TFPColor;
@@ -49,7 +58,7 @@ type
 
   TCSSStyleInspector = class(TDiv)
   private
-    FBoxModellDiv: TCSSInspBoxModell;
+    FBoxModelDiv: TCSSInspBoxModel;
     FRulesDiv: TDiv;
     FLock: integer;
     FInspectNeeded: boolean;
@@ -61,8 +70,11 @@ type
     procedure ShowNothingSelected;
     procedure UpdateRule(Row: integer; Selectors, Origin: TCSSString; RuleEl: TCSSRuleElement);
     procedure UpdateDeclaration(RuleDiv: TDiv; Row: integer; DeclEl: TCSSDeclarationElement);
-    function UpdateDeclaration(DeclDiv: TDIv; DeclEl: TCSSDeclarationElement; var Index: integer): boolean;
-    procedure UpdateLabel(DeclDiv: TDiv; Index: integer; aClass, aCaption: string);
+    function UpdateDeclaration(DeclDiv: TDiv; DeclEl: TCSSDeclarationElement; var Index: integer): boolean;
+    procedure UpdateLongHand(AttrID: TCSSNumericalID; aValue: string; DeclDiv: TDiv; Index: integer);
+    function UpdateElement(DeclDiv: TDiv; Index: integer; ElClass: TFresnelElementClass; const aCSSClass: string): TFresnelElement;
+    procedure UpdateLabel(DeclDiv: TDiv; Index: integer; const aClass, aCaption: string);
+    procedure UpdateArrow(DeclDiv: TDiv; Index: integer; const aClass: string);
     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
   public
     const
@@ -77,10 +89,12 @@ type
       DeclDivClass = 'CSSStyleInspDecl';
       DeclKeyLabelClass = 'CSSStyleInspKey';
       DeclColonLabelClass = 'CSSStyleInspColon';
+      DeclDropArrowLabelClass = 'CSSStyleInspDropArrow';
       DeclValueLabelClass = 'CSSStyleInspValue';
       DeclSemicolonLabelClass = 'CSSStyleInspSemicolon';
+      DeclLonghandDivClass = 'CSSStyleInspLonghand';
       SkippedClass = 'CSSStyleInspSkipped';
-      BoxModellDivClass = 'CSSStyleInspBoxModell';
+      BoxModelDivClass = 'CSSStyleInspBoxModel';
       //
       ElementStyleCaption = 'Element.Style';
   public
@@ -91,28 +105,59 @@ type
     procedure EndUpdate;
     property Target: TFresnelElement read FTarget write SetTarget;
     property RulesDiv: TDiv read FRulesDiv;
-    property BoxModellDiv: TCSSInspBoxModell read FBoxModellDiv;
+    property BoxModellDiv: TCSSInspBoxModel read FBoxModelDiv;
   end;
 
 implementation
 
-{ TCSSInspBoxModell }
+{ TCSSInspDropArrow }
 
-procedure TCSSInspBoxModell.SetMarginColor(AValue: TFPColor);
+procedure TCSSInspDropArrow.DoRender(aRenderer: IFresnelRenderer);
+var
+  R: TFresnelRect;
+  Points: TFresnelPointArray;
+  w, h: TFresnelLength;
+begin
+  R:=UsedContentBox;
+  writeln('AAA3 TCSSInspDropArrow.Render ',R.ToString);
+
+  h:=Min(R.Width,R.Height);
+  w:=h*0.66;
+
+  SetLength(Points,3);
+  Points[0].X:=R.Left+(r.Width-w)/2;
+  Points[0].Y:=R.Top+(r.Height-h)/2;
+  Points[1].X:=Points[0].X+w;
+  Points[1].Y:=(R.Top+R.Bottom)/2;
+  Points[2].X:=Points[0].X;
+  Points[2].Y:=R.Bottom-(r.Height-h)/2;
+
+  aRenderer.Polygon(colWhite,@Points[0],3);
+end;
+
+procedure TCSSInspDropArrow.ComputeCSSLayoutFinished;
+begin
+  inherited ComputeCSSLayoutFinished;
+  writeln('TCSSInspDropArrow.ComputeCSSLayoutFinished ',UsedBorderBox.ToString);
+end;
+
+{ TCSSInspBoxModel }
+
+procedure TCSSInspBoxModel.SetMarginColor(AValue: TFPColor);
 begin
   if FMarginColor=AValue then Exit;
   FMarginColor:=AValue;
   Invalidate;
 end;
 
-procedure TCSSInspBoxModell.SetPaddingColor(AValue: TFPColor);
+procedure TCSSInspBoxModel.SetPaddingColor(AValue: TFPColor);
 begin
   if FPaddingColor=AValue then Exit;
   FPaddingColor:=AValue;
   Invalidate;
 end;
 
-function TCSSInspBoxModell.FloatToCaption(f: TFresnelLength): string;
+function TCSSInspBoxModel.FloatToCaption(f: TFresnelLength): string;
 var
   p, EndP: SizeInt;
 begin
@@ -129,21 +174,21 @@ begin
   end;
 end;
 
-procedure TCSSInspBoxModell.SetBorderColor(AValue: TFPColor);
+procedure TCSSInspBoxModel.SetBorderColor(AValue: TFPColor);
 begin
   if FBorderColor=AValue then Exit;
   FBorderColor:=AValue;
   Invalidate;
 end;
 
-procedure TCSSInspBoxModell.SetContentColor(AValue: TFPColor);
+procedure TCSSInspBoxModel.SetContentColor(AValue: TFPColor);
 begin
   if FContentColor=AValue then Exit;
   FContentColor:=AValue;
   Invalidate;
 end;
 
-procedure TCSSInspBoxModell.DoRender(aRenderer: IFresnelRenderer);
+procedure TCSSInspBoxModel.DoRender(aRenderer: IFresnelRenderer);
 var
   MarginRect, BorderRect, PaddingRect, ContentRect: TFresnelRect;
   L, T, W, cx, cy: TFresnelLength;
@@ -170,7 +215,7 @@ begin
   L:=UsedClientBox.Left;
   T:=UsedClientBox.Top;
   W:=UsedClientBox.Width;
-  writeln('TFresnelBoxModell.DoRender ',UsedClientBox.ToString);
+  //writeln('TFresnelBoxModell.DoRender ',UsedClientBox.ToString);
   F:=Font;
   Size0:=F.TextSize('0');
   TextCol:=colWhite;
@@ -257,7 +302,7 @@ begin
   aRenderer.TextOut(cx-MarginBottomSize.X*0.5,MarginRect.Bottom-Size0.Y*1.2,F,TextCol,MarginBottomCaption);
 end;
 
-constructor TCSSInspBoxModell.Create(AOwner: TComponent);
+constructor TCSSInspBoxModel.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
   FMarginColor:=FPColor($bbbb,$bbbb,0);
@@ -476,13 +521,9 @@ end;
 procedure TCSSStyleInspector.UpdateDeclaration(RuleDiv: TDiv; Row: integer;
   DeclEl: TCSSDeclarationElement);
 var
-  KeyEl: TCSSElement;
-  ResolvedKeyEl: TCSSResolvedIdentifierElement;
   ValueTxt, KeyTxt, ValueCaption: String;
   i, Index: Integer;
   DeclDiv: TDiv;
-  KeyData: TCSSAttributeKeyData;
-  TargetResolver: TCSSResolver;
 begin
   // add or update div
   if Row<RuleDiv.NodeCount-1 then // -1 for the footer
@@ -527,7 +568,7 @@ begin
     DeclDiv.Nodes[DeclDiv.NodeCount-1].Free;
 end;
 
-function TCSSStyleInspector.UpdateDeclaration(DeclDiv: TDIv;
+function TCSSStyleInspector.UpdateDeclaration(DeclDiv: TDiv;
   DeclEl: TCSSDeclarationElement; var Index: integer): boolean;
 var
   KeyEl: TCSSElement;
@@ -538,6 +579,8 @@ var
   ValueTxt, ValueCaption: String;
   i: Integer;
   KeyTxt: TCSSString;
+  AttrIDs: TCSSNumericalIDArray;
+  Values: TCSSStringArray;
 begin
   Result:=false;
   if (DeclEl.KeyCount<>1) then
@@ -578,49 +621,102 @@ begin
   UpdateLabel(DeclDiv,Index,DeclColonLabelClass,':');
   inc(Index);
 
-
+  if length(Desc.CompProps)>0 then
+  begin
+    // shorthand
+    UpdateArrow(DeclDiv,Index,DeclDropArrowLabelClass);
+    inc(Index);
+  end;
 
   UpdateLabel(DeclDiv,Index,DeclValueLabelClass,ValueCaption);
   inc(Index);
   UpdateLabel(DeclDiv,Index,DeclSemicolonLabelClass,';');
   inc(Index);
 
+  if (length(Desc.CompProps)>0) and Assigned(Desc.OnSplitShorthand) then
+  begin
+    // shorthand: add longhands
+    TargetResolver.InitParseAttr(Desc,nil,ValueTxt);
+    AttrIDs:=[];
+    Values:=[];
+    Desc.OnSplitShorthand(TargetResolver,AttrIDs,Values);
+
+    for i:=0 to length(AttrIDs)-1 do
+    begin
+      UpdateLongHand(AttrIDs[i],Values[i],DeclDiv,Index);
+      inc(Index);
+    end;
+  end;
+
   // todo: split shorthands
   // todo: check if overriden
 end;
 
-procedure TCSSStyleInspector.UpdateLabel(DeclDiv: TDiv; Index: integer; aClass, aCaption: string);
+procedure TCSSStyleInspector.UpdateLongHand(AttrID: TCSSNumericalID;
+  aValue: string; DeclDiv: TDiv; Index: integer);
+var
+  LHDiv: TDiv;
+  SubIndex: Integer;
+  Desc: TCSSAttributeDesc;
+begin
+  Desc:=Target.Resolver.GetAttributeDesc(AttrID);
+
+  LHDiv:=TDiv(UpdateElement(DeclDiv,Index,TDiv,DeclLonghandDivClass));
+  SubIndex:=0;
+  UpdateLabel(LHDiv,SubIndex,DeclKeyLabelClass,Desc.Name);
+  inc(SubIndex);
+  UpdateLabel(LHDiv,SubIndex,DeclColonLabelClass,':');
+  inc(SubIndex);
+  UpdateLabel(LHDiv,SubIndex,DeclValueLabelClass,aValue);
+  inc(SubIndex);
+  UpdateLabel(LHDiv,SubIndex,DeclSemicolonLabelClass,';');
+  inc(SubIndex);
+end;
+
+function TCSSStyleInspector.UpdateElement(DeclDiv: TDiv; Index: integer;
+  ElClass: TFresnelElementClass; const aCSSClass: string): TFresnelElement;
 var
-  aLabel: TLabel;
   El: TFresnelElement;
 begin
-  //writeln('TCSSStyleInspector.UpdateLabel ',Index,' "',aClass,'" "',aCaption,'"');
   if Index=DeclDiv.NodeCount then
   begin
     // add
-    aLabel:=TLabel.Create(Self);
-    aLabel.CSSClasses.Text:=aClass;
-    aLabel.Caption:=aCaption;
-    aLabel.Parent:=DeclDiv;
+    Result:=ElClass.Create(Self);
+    Result.CSSClasses.Text:=aCSSClass;
+    Result.Parent:=DeclDiv;
   end else begin
     // update
     El:=DeclDiv.Nodes[Index];
-    if El is TLabel then
+    if El is ElClass then
     begin
-      // update label
-      aLabel:=TLabel(El);
-      aLabel.CSSClasses.Text:=aClass;
-      aLabel.Caption:=aCaption;
+      // update
+      Result:=El;
+      Result.CSSClasses.Text:=aCSSClass;
     end else begin
-      // insert label
-      aLabel:=TLabel.Create(Self);
-      aLabel.CSSClasses.Text:=aClass;
-      aLabel.Caption:=aCaption;
-      DeclDiv.InsertBefore(aLabel,El);
+      // insert
+      Result:=ElClass.Create(Self);
+      Result.CSSClasses.Text:=aCSSClass;
+      DeclDiv.InsertBefore(Result,El);
     end;
   end;
 end;
 
+procedure TCSSStyleInspector.UpdateLabel(DeclDiv: TDiv; Index: integer;
+  const aClass, aCaption: string);
+var
+  aLabel: TLabel;
+begin
+  aLabel:=TLabel(UpdateElement(DeclDiv,Index,TLabel,aClass));
+  aLabel.Caption:=aCaption;
+end;
+
+procedure TCSSStyleInspector.UpdateArrow(DeclDiv: TDiv; Index: integer;
+  const aClass: string);
+begin
+  writeln('AAA2 TCSSStyleInspector.UpdateArrow ');
+  UpdateElement(DeclDiv,Index,TCSSInspDropArrow,aClass);
+end;
+
 procedure TCSSStyleInspector.Notification(AComponent: TComponent; Operation: TOperation);
 begin
   inherited Notification(AComponent, Operation);
@@ -641,9 +737,9 @@ begin
     Parent:=Self;
   end;
 
-  FBoxModellDiv:=TCSSInspBoxModell.Create(Self);
+  FBoxModelDiv:=TCSSInspBoxModel.Create(Self);
   with BoxModellDiv do begin
-    CSSClasses.Text:=BoxModellDivClass;
+    CSSClasses.Text:=BoxModelDivClass;
     Parent:=Self;
   end;
 
@@ -666,10 +762,12 @@ begin
     +'.'+DeclDivClass+' { margin-left: 2ch; }'+LineEnding
     +'.'+DeclKeyLabelClass+' { color: cyan; }'+LineEnding
     +'.'+DeclColonLabelClass+' { margin-right: 1ch; }'+LineEnding
+    +'.'+DeclDropArrowLabelClass+' { display: inline block; width: 0.8em; height: 0.8em; }'+LineEnding
     +'.'+DeclValueLabelClass+' { color: #d8e; }'+LineEnding
     //+'.'+DeclSemicolonLabelClass+' { font-weight: bold; }'+LineEnding
+    +'.'+DeclLonghandDivClass+' { margin-left: 2ch; }'+LineEnding
     +'.'+SkippedClass+' { color: #aaa; }'+LineEnding
-    +'.'+BoxModellDivClass+' { color: #fff; font-size: 10px; background-color: #222; padding: 6px; height: 12em; }'+LineEnding
+    +'.'+BoxModelDivClass+' { color: #fff; font-size: 10px; background-color: #222; padding: 6px; height: 12em; }'+LineEnding
     ;
 end;
 

+ 1 - 0
src/base/fresnel.dom.pas

@@ -1224,6 +1224,7 @@ type
   IFresnelRenderer = Interface ['{06738575-BE7F-4EA5-A4D0-3E26A5441BFD}']
     procedure FillRect(const aColor: TFPColor; const aRect: TFresnelRect);
     procedure Line(const aColor: TFPColor; const x1, y1, x2, y2: TFresnelLength);
+    procedure Polygon(const aColor: TFPColor; const p: PFresnelPoint; Count: integer);
     procedure TextOut(const aLeft, aTop: TFresnelLength; const aFont: IFresnelFont; const aColor: TFPColor; const aText: string);
     procedure AddTextShadow(const aOffsetX, aOffsetY: TFresnelLength; const aColor: TFPColor; const aRadius: TFresnelLength);
     procedure ClearTextShadows;

+ 0 - 2
src/base/fresnel.renderer.pas

@@ -1039,8 +1039,6 @@ begin
 
   aBorderBox:=El.UsedBorderBox;
 
-  FLLog(etDebug,'TFresnelRenderer.DrawElement %s %s',[El.GetPath,aBorderBox.ToString]);
-
   //writeln('TFresnelRenderer.DrawElement ',El.Name,' BorderBox=',El.UsedBorderBox.ToString,' ContentBox=',El.UsedContentBox.ToString,' Origin=',Origin.ToString);
 
   if El<>El.Viewport then