Blog
All Blog Posts | Next Post | Previous PostAttractive Scalable Images in your Diagram with Delphi, WEB Core and Lazarus
Wednesday, October 19, 2022
With TMS FNC Blox you have the ability to create high-quality diagrams and flowcharts with the help of some quick and easy selection tools.
In the previous blogpost we've created our own custom blocks to use as a component in a logic scheme. In this blogpost and video we will use a vector based svg image to get the visual level of our diagram to a higher level.
October 27, Webinar: Visually create and execute workflows in Delphi apps
In this webinar, Bruno will go over the basics on how to get started with TMS FNC Blox, but will gradually advance to a more complex program where we will follow the steps of our diagram in real-time and execute actions based on the type of block.
If this sounds like an interesting feature you could use in your applications, you can register here.
Custom Blocks with SVG image
As Holger mentions in the video, the advantage to use svg images, is that you can scale the block as you want and you will not lose any quality of your image.
In the previous blogpost, we saw that we'll need to create our custom blocks first.
uses FMX.TMSFNCBloxControl, FMX.TMSFNCBloxCoreBlock; type TSolarPanelBlock = class(TTMSFNCBloxBlock) public constructor Create; override; procedure GetBlockPath(APath: TTMSFNCBloxPath; ADrawer: TTMSFNCBloxBlockDrawer); override; end; TConverterBlock = class(TTMSFNCBloxBlock) public constructor Create; override; procedure GetBlockPath(APath: TTMSFNCBloxPath; ADrawer: TTMSFNCBloxBlockDrawer); override; end;
Although we don't draw the block path ourselves this time, we will need to override the method to clear the path.
procedure TConverterBlock.GetBlockPath(APath: TTMSFNCBloxPath; ADrawer: TTMSFNCBloxBlockDrawer); begin inherited; APath.Reset; end;
constructor TSolarPanelBlock.Create; begin inherited; Restrictions := Restrictions + [crKeepRatio]; Picture.LoadFromFile('..\..\solar-panel.svg'); LinkPointStyle := lptNone; LinkPoints.Clear; LinkPoints.AddLink(2, (OriginalRect.Bottom - OriginalRect.Top)/2, aoLeft); LinkPoints.AddLink((OriginalRect.Right - OriginalRect.Left) - 2, (OriginalRect.Bottom - OriginalRect.Top) / 2, aoRight); end; constructor TConverterBlock.Create; begin inherited; Width := 100; Height := 100; Restrictions := Restrictions + [crKeepRatio]; Picture.LoadFromFile('..\..\electric-meter.svg'); LinkPointStyle := lptNone; LinkPoints.Clear; LinkPoints.AddLink((OriginalRect.Right - OriginalRect.Left) / 2, 0, aoUp); LinkPoints.AddLink(0, (OriginalRect.Bottom - OriginalRect.Top) / 2, aoLeft); LinkPoints.AddLink(OriginalRect.Right - OriginalRect.Left, (OriginalRect.Bottom - OriginalRect.Top) / 2, aoRight); end;
The LinkPointStyle defines how we see the linkpoints in the diagram. By default these are small crosses, but for this application we don't want to see them, so we set it to None.
To have the full source code to the demonstration application, the code for the build-up of the diagram is added as well. It is a lot of code, but we want to show the solar panels in the middle, so this needed some tweaking.
Another thing we wanted to add was that the line was one smooth line. Therefor we need the code in the for-loop to select which linkpoint to use as a source and target.
If you would use these blocks and lines a lot, you can always add more custom properties in the constructor to have less code in the creation of the diagram.
uses FMX.TMSFNCBloxCoreLinkPoint, FMX.TMSFNCBloxCoreLine, FMX.TMSFNCBloxCoreTypes; procedure TSolarBloxDemoForm.FormCreate(Sender: TObject); var sp, psp: TSolarPanelBlock; c: TConverterBlock; x, y, I: Integer; l: TTMSFNCBloxSideLine; begin TMSFNCBloxControl1.BeginUpdate; x := Round(TMSFNCBloxControl1.Width / 4); y := Round(TMSFNCBloxControl1.Height / 6); for I := 0 to 5 do begin sp := TSolarPanelBlock.Create; sp.Width := 80; sp.Height := 80; sp.FontSize := 16; sp.Text := (Random(100) + 30).ToString + 'W'; sp.VertAlign := vaBottom; sp.Top := ((I div 3) + 1) * y; if I < 3 then sp.Left := (I mod 3) * x + TMSFNCBloxControl1.Width / 5 else sp.Left := (2 - I mod 3) * x + TMSFNCBloxControl1.Width / 5; TMSFNCBloxControl1.Blox.Add(sp); if (I > 0) and (psp <> nil) then begin l := TTMSFNCBloxSideLine.Create; l.Stroke.Color := gcOrange; l.Stroke.Width := 3; if I < 3 then begin l.SourceLinkPoint.AnchorLink := psp.LinkPoints[1]; l.TargetLinkPoint.AnchorLink := sp.LinkPoints[0]; end else if I = 3 then begin l.SourceLinkPoint.AnchorLink := psp.LinkPoints[1]; l.TargetLinkPoint.AnchorLink := sp.LinkPoints[1]; end else begin l.SourceLinkPoint.AnchorLink := psp.LinkPoints[0]; l.TargetLinkPoint.AnchorLink := sp.LinkPoints[1]; end; TMSFNCBloxControl1.Blox.Add(l); end; psp := sp; end; c := TConverterBlock.Create; c.Top := (4 * y); c.Left := (TMSFNCBloxControl1.Width - c.Width)/2; c.FontSize := 16; c.FontStyle := [xsBold]; c.TextColor := gcDarkslateblue; c.Text := '3.2 kW' + #10#13 ; c.VertAlign := vaCenter; TMSFNCBloxControl1.Blox.Add(c); l := TTMSFNCBloxSideLine.Create; l.SourceLinkPoint.AnchorLink := sp.LinkPoints[0]; l.TargetLinkPoint.AnchorLink := c.LinkPoints[0]; l.Stroke.Color := gcOrange; l.Stroke.Width := 3; TMSFNCBloxControl1.Blox.Add(l); TMSFNCBloxControl1.EndUpdate; end;
Gjalt Vanhouwaert
This blog post has received 2 comments.
https://www.tmssoftware.com/site/blog.asp?post=751
Bruno Fierens
All Blog Posts | Next Post | Previous Post
Glasier Jonathan