|
@@ -5,15 +5,41 @@ unit Fresnel.CSSStyleInspector;
|
|
|
interface
|
|
|
|
|
|
uses
|
|
|
- Classes, SysUtils, fpCSSTree, fpCSSResParser, fpCSSResolver, Fresnel.DOM, Fresnel.Classes,
|
|
|
- Fresnel.Controls, Fresnel.Events, FCL.Events;
|
|
|
+ Classes, SysUtils, FPImage, fpCSSTree, fpCSSResParser, fpCSSResolver,
|
|
|
+ Fresnel.DOM, Fresnel.Classes, Fresnel.Controls, Fresnel.Events, FCL.Events;
|
|
|
|
|
|
type
|
|
|
|
|
|
+ { TCSSInspBoxModell }
|
|
|
+
|
|
|
+ TCSSInspBoxModell = class(TDiv)
|
|
|
+ private
|
|
|
+ FBorderColor: TFPColor;
|
|
|
+ FContentColor: TFPColor;
|
|
|
+ FMarginColor: TFPColor;
|
|
|
+ FPaddingColor: TFPColor;
|
|
|
+ FTarget: TFresnelElement;
|
|
|
+ procedure SetBorderColor(AValue: TFPColor);
|
|
|
+ procedure SetContentColor(AValue: TFPColor);
|
|
|
+ procedure SetMarginColor(AValue: TFPColor);
|
|
|
+ procedure SetPaddingColor(AValue: TFPColor);
|
|
|
+ protected
|
|
|
+ function FloatToCaption(f: TFresnelLength): string; virtual;
|
|
|
+ procedure DoRender(aRenderer: IFresnelRenderer); override;
|
|
|
+ public
|
|
|
+ constructor Create(AOwner: TComponent); override;
|
|
|
+ property MarginColor: TFPColor read FMarginColor write SetMarginColor;
|
|
|
+ property BorderColor: TFPColor read FBorderColor write SetBorderColor;
|
|
|
+ property PaddingColor: TFPColor read FPaddingColor write SetPaddingColor;
|
|
|
+ property ContentColor: TFPColor read FContentColor write SetContentColor;
|
|
|
+ property Target: TFresnelElement read FTarget write FTarget;
|
|
|
+ end;
|
|
|
+
|
|
|
{ TCSSStyleInspector }
|
|
|
|
|
|
TCSSStyleInspector = class(TDiv)
|
|
|
private
|
|
|
+ FBoxModellDiv: TCSSInspBoxModell;
|
|
|
FRulesDiv: TDiv;
|
|
|
FLock: integer;
|
|
|
FInspectNeeded: boolean;
|
|
@@ -42,6 +68,7 @@ type
|
|
|
DeclColonLabelClass = 'CSSStyleInspColon';
|
|
|
DeclValueLabelClass = 'CSSStyleInspValue';
|
|
|
SkippedClass = 'CSSStyleInspSkipped';
|
|
|
+ BoxModellDivClass = 'CSSStyleInspBoxModell';
|
|
|
//
|
|
|
ElementStyleCaption = 'Element.Style';
|
|
|
public
|
|
@@ -52,10 +79,181 @@ type
|
|
|
procedure EndUpdate;
|
|
|
property Target: TFresnelElement read FTarget write SetTarget;
|
|
|
property RulesDiv: TDiv read FRulesDiv;
|
|
|
+ property BoxModellDiv: TCSSInspBoxModell read FBoxModellDiv;
|
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
|
|
+{ TCSSInspBoxModell }
|
|
|
+
|
|
|
+procedure TCSSInspBoxModell.SetMarginColor(AValue: TFPColor);
|
|
|
+begin
|
|
|
+ if FMarginColor=AValue then Exit;
|
|
|
+ FMarginColor:=AValue;
|
|
|
+ Invalidate;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TCSSInspBoxModell.SetPaddingColor(AValue: TFPColor);
|
|
|
+begin
|
|
|
+ if FPaddingColor=AValue then Exit;
|
|
|
+ FPaddingColor:=AValue;
|
|
|
+ Invalidate;
|
|
|
+end;
|
|
|
+
|
|
|
+function TCSSInspBoxModell.FloatToCaption(f: TFresnelLength): string;
|
|
|
+var
|
|
|
+ p, EndP: SizeInt;
|
|
|
+begin
|
|
|
+ Result:=FloatToStr(f,FresnelCSSFormatSettings);
|
|
|
+ p:=Pos(FresnelCSSFormatSettings.DecimalSeparator,Result);
|
|
|
+ if p>0 then
|
|
|
+ begin
|
|
|
+ inc(p);
|
|
|
+ EndP:=p;
|
|
|
+ while (EndP<length(Result)) and (Result[EndP] in ['0'..'9']) do
|
|
|
+ inc(EndP);
|
|
|
+ if EndP>p+1 then
|
|
|
+ System.Delete(Result,p+1,EndP-p-1);
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TCSSInspBoxModell.SetBorderColor(AValue: TFPColor);
|
|
|
+begin
|
|
|
+ if FBorderColor=AValue then Exit;
|
|
|
+ FBorderColor:=AValue;
|
|
|
+ Invalidate;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TCSSInspBoxModell.SetContentColor(AValue: TFPColor);
|
|
|
+begin
|
|
|
+ if FContentColor=AValue then Exit;
|
|
|
+ FContentColor:=AValue;
|
|
|
+ Invalidate;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TCSSInspBoxModell.DoRender(aRenderer: IFresnelRenderer);
|
|
|
+var
|
|
|
+ MarginRect, BorderRect, PaddingRect, ContentRect: TFresnelRect;
|
|
|
+ L, T, W, cx, cy: TFresnelLength;
|
|
|
+ Size0, MarginLeftSize, MarginRightSize, BorderLeftSize,
|
|
|
+ BorderRightSize, PaddingLeftSize, PaddingRightSize,
|
|
|
+ MarginTopSize, MarginBottomSize,
|
|
|
+ BorderTopSize, BorderBottomSize, PaddingTopSize,
|
|
|
+ PaddingBottomSize, ContentCaptionSize: TFresnelPoint;
|
|
|
+ F: IFresnelFont;
|
|
|
+ TextCol: TFPColor;
|
|
|
+ ContentCaption, MarginLeftCaption, MarginRightCaption,
|
|
|
+ MarginTopCaption, MarginBottomCaption, BorderBottomCaption,
|
|
|
+ BorderRightCaption, BorderTopCaption, BorderLeftCaption,
|
|
|
+ PaddingLeftCaption, PaddingRightCaption, PaddingTopCaption,
|
|
|
+ PaddingBottomCaption: String;
|
|
|
+ LNode: TFresnelLayoutNode;
|
|
|
+begin
|
|
|
+ inherited DoRender(aRenderer);
|
|
|
+ if Target=nil then exit;
|
|
|
+ LNode:=Target.LayoutNode;
|
|
|
+ if LNode=nil then exit;
|
|
|
+ if LNode.SkipLayout then exit;
|
|
|
+
|
|
|
+ L:=UsedClientBox.Left;
|
|
|
+ T:=UsedClientBox.Top;
|
|
|
+ W:=UsedClientBox.Width;
|
|
|
+ writeln('TFresnelBoxModell.DoRender ',UsedClientBox.ToString);
|
|
|
+ F:=Font;
|
|
|
+ Size0:=F.TextSize('0');
|
|
|
+ TextCol:=colWhite;
|
|
|
+ ContentCaption:=FloatToCaption(Target.UsedContentBox.Width)
|
|
|
+ +'x'+FloatToCaption(Target.UsedContentBox.Height);
|
|
|
+
|
|
|
+ MarginLeftCaption:=FloatToCaption(LNode.MarginLeft);
|
|
|
+ MarginLeftSize:=F.TextSize(MarginLeftCaption);
|
|
|
+ MarginRightCaption:=FloatToCaption(LNode.MarginRight);
|
|
|
+ MarginRightSize:=F.TextSize(MarginRightCaption);
|
|
|
+ MarginTopCaption:=FloatToCaption(LNode.MarginTop);
|
|
|
+ MarginTopSize:=F.TextSize(MarginTopCaption);
|
|
|
+ MarginBottomCaption:=FloatToCaption(LNode.MarginBottom);
|
|
|
+ MarginBottomSize:=F.TextSize(MarginBottomCaption);
|
|
|
+ BorderLeftCaption:=FloatToCaption(LNode.BorderLeft);
|
|
|
+ BorderLeftSize:=F.TextSize(BorderLeftCaption);
|
|
|
+ BorderRightCaption:=FloatToCaption(LNode.BorderRight);
|
|
|
+ BorderRightSize:=F.TextSize(BorderRightCaption);
|
|
|
+ BorderTopCaption:=FloatToCaption(LNode.BorderTop);
|
|
|
+ BorderTopSize:=F.TextSize(BorderTopCaption);
|
|
|
+ BorderBottomCaption:=FloatToCaption(LNode.BorderBottom);
|
|
|
+ BorderBottomSize:=F.TextSize(BorderBottomCaption);
|
|
|
+ PaddingLeftCaption:=FloatToCaption(LNode.PaddingLeft);
|
|
|
+ PaddingLeftSize:=F.TextSize(PaddingLeftCaption);
|
|
|
+ PaddingRightCaption:=FloatToCaption(LNode.PaddingRight);
|
|
|
+ PaddingRightSize:=F.TextSize(PaddingRightCaption);
|
|
|
+ PaddingTopCaption:=FloatToCaption(LNode.PaddingTop);
|
|
|
+ PaddingTopSize:=F.TextSize(PaddingTopCaption);
|
|
|
+ PaddingBottomCaption:=FloatToCaption(LNode.PaddingBottom);
|
|
|
+ PaddingBottomSize:=F.TextSize(PaddingBottomCaption);
|
|
|
+ ContentCaptionSize:=F.TextSize(ContentCaption);
|
|
|
+
|
|
|
+ MarginRect.Left:=L+W*0.15;
|
|
|
+ MarginRect.Right:=L+W*0.85;
|
|
|
+ MarginRect.Top:=T+Size0.Y*1.5;
|
|
|
+ MarginRect.Bottom:=T+Size0.Y*12;
|
|
|
+ aRenderer.FillRect(MarginColor,MarginRect);
|
|
|
+
|
|
|
+ BorderRect.Left:=MarginRect.Left+MarginLeftSize.X+Size0.X;
|
|
|
+ BorderRect.Right:=MarginRect.Right-MarginRightSize.X-Size0.X;
|
|
|
+ BorderRect.Top:=MarginRect.Top+Size0.Y*1.5;
|
|
|
+ BorderRect.Bottom:=MarginRect.Bottom-Size0.Y*1.5;
|
|
|
+ aRenderer.FillRect(BorderColor,BorderRect);
|
|
|
+
|
|
|
+ PaddingRect.Left:=BorderRect.Left+BorderLeftSize.X+Size0.X;
|
|
|
+ PaddingRect.Right:=BorderRect.Right-BorderRightSize.X-Size0.X;
|
|
|
+ PaddingRect.Top:=BorderRect.Top+Size0.Y*1.5;
|
|
|
+ PaddingRect.Bottom:=BorderRect.Bottom-Size0.Y*1.5;
|
|
|
+ aRenderer.FillRect(PaddingColor,PaddingRect);
|
|
|
+
|
|
|
+ ContentRect.Left:=PaddingRect.Left+PaddingLeftSize.X+Size0.X*1.5;
|
|
|
+ ContentRect.Right:=PaddingRect.Right-PaddingRightSize.X-Size0.X*1.5;
|
|
|
+ ContentRect.Top:=PaddingRect.Top+Size0.Y*1.5;
|
|
|
+ ContentRect.Bottom:=PaddingRect.Bottom-Size0.Y*1.5;
|
|
|
+ aRenderer.FillRect(ContentColor,ContentRect);
|
|
|
+
|
|
|
+ cx:=L+W*0.5;
|
|
|
+ cy:=(ContentRect.Top+ContentRect.Bottom)*0.5;
|
|
|
+
|
|
|
+ // captions
|
|
|
+ aRenderer.TextOut(L+Size0.X,T+Size0.Y*0.3,F,TextCol,'Box Model');
|
|
|
+ aRenderer.TextOut(MarginRect.Left+Size0.X,MarginRect.Top+Size0.Y*0.3,F,TextCol,'margin');
|
|
|
+ aRenderer.TextOut(BorderRect.Left+Size0.X,BorderRect.Top+Size0.Y*0.3,F,TextCol,'border');
|
|
|
+ aRenderer.TextOut(PaddingRect.Left+Size0.X,PaddingRect.Top+Size0.Y*0.3,
|
|
|
+ F,TextCol,'padding');
|
|
|
+ aRenderer.TextOut(ContentRect.Left+(ContentRect.Width-ContentCaptionSize.X)*0.5,
|
|
|
+ cy-ContentCaptionSize.Y*0.5,F,TextCol,ContentCaption);
|
|
|
+
|
|
|
+ // values
|
|
|
+ aRenderer.TextOut(MarginRect.Left+Size0.X*0.5,cy-Size0.Y*0.5,F,TextCol,MarginLeftCaption);
|
|
|
+ aRenderer.TextOut(BorderRect.Left+Size0.X*0.5,cy-Size0.Y*0.5,F,TextCol,BorderLeftCaption);
|
|
|
+ aRenderer.TextOut(PaddingRect.Left+Size0.X*0.5,cy-Size0.Y*0.5,F,TextCol,PaddingLeftCaption);
|
|
|
+
|
|
|
+ aRenderer.TextOut(ContentRect.Right+Size0.X*0.5,cy-Size0.Y*0.5,F,TextCol,PaddingRightCaption);
|
|
|
+ aRenderer.TextOut(PaddingRect.Right+Size0.X*0.5,cy-Size0.Y*0.5,F,TextCol,BorderRightCaption);
|
|
|
+ aRenderer.TextOut(BorderRect.Right+Size0.X*0.5,cy-Size0.Y*0.5,F,TextCol,MarginRightCaption);
|
|
|
+
|
|
|
+ aRenderer.TextOut(cx-MarginTopSize.X*0.5,MarginRect.Top+Size0.Y*0.2,F,TextCol,MarginTopCaption);
|
|
|
+ aRenderer.TextOut(cx-BorderTopSize.X*0.5,BorderRect.Top+Size0.Y*0.2,F,TextCol,BorderTopCaption);
|
|
|
+ aRenderer.TextOut(cx-PaddingTopSize.X*0.5,PaddingRect.Top+Size0.Y*0.2,F,TextCol,PaddingTopCaption);
|
|
|
+
|
|
|
+ aRenderer.TextOut(cx-PaddingBottomSize.X*0.5,PaddingRect.Bottom-Size0.Y*1.2,F,TextCol,PaddingBottomCaption);
|
|
|
+ aRenderer.TextOut(cx-BorderBottomSize.X*0.5,BorderRect.Bottom-Size0.Y*1.2,F,TextCol,BorderBottomCaption);
|
|
|
+ aRenderer.TextOut(cx-MarginBottomSize.X*0.5,MarginRect.Bottom-Size0.Y*1.2,F,TextCol,MarginBottomCaption);
|
|
|
+end;
|
|
|
+
|
|
|
+constructor TCSSInspBoxModell.Create(AOwner: TComponent);
|
|
|
+begin
|
|
|
+ inherited Create(AOwner);
|
|
|
+ FMarginColor:=FPColor($bbbb,$bbbb,0);
|
|
|
+ FBorderColor:=FPColor($3333,$3333,$3333);
|
|
|
+ FPaddingColor:=FPColor($bbbb,$8080,$bbbb);
|
|
|
+ FContentColor:=FPColor(0,$8080,$bbbb);
|
|
|
+end;
|
|
|
+
|
|
|
{ TCSSStyleInspector }
|
|
|
|
|
|
procedure TCSSStyleInspector.SetTarget(const AValue: TFresnelElement);
|
|
@@ -66,6 +264,8 @@ begin
|
|
|
if FTarget<>nil then
|
|
|
RemoveFreeNotification(FTarget);
|
|
|
FTarget:=AValue;
|
|
|
+ if BoxModellDiv<>nil then
|
|
|
+ BoxModellDiv.Target:=Target;
|
|
|
if FTarget<>nil then
|
|
|
begin
|
|
|
if (FTarget=Self) or Contains(FTarget) then
|
|
@@ -402,6 +602,12 @@ begin
|
|
|
Parent:=Self;
|
|
|
end;
|
|
|
|
|
|
+ FBoxModellDiv:=TCSSInspBoxModell.Create(Self);
|
|
|
+ with BoxModellDiv do begin
|
|
|
+ CSSClasses.Text:=BoxModellDivClass;
|
|
|
+ Parent:=Self;
|
|
|
+ end;
|
|
|
+
|
|
|
Inspect;
|
|
|
end;
|
|
|
|
|
@@ -422,6 +628,7 @@ begin
|
|
|
+'.'+DeclKeyLabelClass+' { color: cyan; }'+LineEnding
|
|
|
+'.'+DeclColonLabelClass+' { margin-right: 1ch; }'+LineEnding
|
|
|
+'.'+SkippedClass+' { color: #aaa; }'+LineEnding
|
|
|
+ +'.'+BoxModellDivClass+' { color: #fff; font-size: 10px; background-color: #222; padding: 6px; }'+LineEnding
|
|
|
;
|
|
|
end;
|
|
|
|