mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 23:17:57 +02:00
525 lines
17 KiB
ObjectPascal
525 lines
17 KiB
ObjectPascal
unit DependencyGraphOptions;
|
|
|
|
{$mode objfpc}{$H+}
|
|
{off $DEFINE WITH_RANDOM_SEED} // ONLY applies, after "apply" or "ok" when the graph is redrawn
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Math,
|
|
// LCL
|
|
Forms, Controls, Graphics, Dialogs, ButtonPanel, StdCtrls, ExtCtrls, Spin,
|
|
// LazControls
|
|
LvlGraphCtrl,
|
|
// IdeConfig
|
|
EnvironmentOpts,
|
|
// IDE
|
|
LazarusIDEStrConsts;
|
|
|
|
type
|
|
|
|
{ TLvlGraphOptions }
|
|
|
|
TLvlGraphOptions = class(TIDESubOptions)
|
|
private
|
|
FCaptionPos: TLvlGraphNodeCaptionPosition;
|
|
FEdgeShape: TLvlGraphEdgeShape;
|
|
FEdgeSplit: TLvlGraphEdgeSplitMode;
|
|
FExtraSpacingHoriz: integer;
|
|
FExtraSpacingVert: integer;
|
|
FHighLevels: Boolean;
|
|
FLimitLvlHeighAbs: integer;
|
|
FLimitLvlHeighRel: Single;
|
|
FMinimizeEdges: Boolean;
|
|
FOnLoaded: TNotifyEvent;
|
|
FReduceBackEdges: Boolean;
|
|
FStraightenGraph: Boolean;
|
|
{$IFDEF WITH_RANDOM_SEED}
|
|
FTestRandomSeed: integer;
|
|
{$ENDIF}
|
|
public
|
|
constructor Create;
|
|
procedure ReadFromXml(OnlyDesktop: boolean); override;
|
|
procedure WriteToXml(OnlyDesktop: boolean); override;
|
|
procedure Assign(ASrc: TPersistent); override;
|
|
procedure WriteToGraph(AValue: TLvlGraphControl);
|
|
procedure ReadFromGraph(AValue: TLvlGraphControl);
|
|
published
|
|
property MinimizeEdges: Boolean read FMinimizeEdges write FMinimizeEdges;
|
|
property HighLevels: Boolean read FHighLevels write FHighLevels;
|
|
property ReduceBackEdges: Boolean read FReduceBackEdges write FReduceBackEdges;
|
|
property ExtraSpacingHoriz: integer read FExtraSpacingHoriz write FExtraSpacingHoriz;
|
|
property ExtraSpacingVert: integer read FExtraSpacingVert write FExtraSpacingVert;
|
|
property CaptionPos: TLvlGraphNodeCaptionPosition read FCaptionPos write FCaptionPos;
|
|
property EdgeShape: TLvlGraphEdgeShape read FEdgeShape write FEdgeShape;
|
|
property EdgeSplit: TLvlGraphEdgeSplitMode read FEdgeSplit write FEdgeSplit;
|
|
property StraightenGraph: Boolean read FStraightenGraph write FStraightenGraph;
|
|
property LimitLvlHeighAbs: integer read FLimitLvlHeighAbs write FLimitLvlHeighAbs;
|
|
property LimitLvlHeighRel: Single read FLimitLvlHeighRel write FLimitLvlHeighRel;
|
|
{$IFDEF WITH_RANDOM_SEED}
|
|
property TestRandomSeed: integer read FTestRandomSeed write FTestRandomSeed;
|
|
{$ENDIF}
|
|
|
|
property OnLoaded: TNotifyEvent read FOnLoaded write FOnLoaded;
|
|
end;
|
|
|
|
TApplyOptionsProc = procedure(AnOpts: TLvlGraphOptions; AGraph: TLvlGraph) of object;
|
|
TLvlGraphEdgeSplitModes = set of TLvlGraphEdgeSplitMode;
|
|
|
|
{ TDependencyGraphOptDialog }
|
|
|
|
TDependencyGraphOptDialog = class(TForm)
|
|
ApplyButton: TPanelBitBtn;
|
|
ButtonPanel1: TButtonPanel;
|
|
chkReduceBackEdges: TCheckBox;
|
|
chkStraigtenGraph: TCheckBox;
|
|
chkMinimizeEdges: TCheckBox;
|
|
chkHighEdges: TCheckBox;
|
|
chkCaptionOnTop: TCheckBox;
|
|
dropEdgeShape: TComboBox;
|
|
dropEdgeSplit: TComboBox;
|
|
DummySpaceHolder: TLabel;
|
|
lblExtraSpacing: TLabel;
|
|
Panel11: TPanel;
|
|
Panel12: TPanel;
|
|
spinVertSpacing: TSpinEdit;
|
|
spinHorizSpacing: TSpinEdit;
|
|
spinLvlLimitRel: TFloatSpinEdit;
|
|
lblMaxLevelHeight: TLabel;
|
|
lblEdgeShape: TLabel;
|
|
lblEdgeSplit: TLabel;
|
|
lblSplitCount: TLabel;
|
|
Panel1: TPanel;
|
|
Panel10: TPanel;
|
|
Panel2: TPanel;
|
|
Panel3: TPanel;
|
|
Panel4: TPanel;
|
|
Panel5: TPanel;
|
|
Panel6: TPanel;
|
|
Panel7: TPanel;
|
|
Panel8: TPanel;
|
|
Panel9: TPanel;
|
|
spinLvlLimitAbs: TSpinEdit;
|
|
valSplitCnt: TLabel;
|
|
valLevelCnt: TLabel;
|
|
valCrossCnt: TLabel;
|
|
LblCrossCount: TLabel;
|
|
lblNodeCnt: TLabel;
|
|
valNodeCnt: TLabel;
|
|
lblEdgeCount: TLabel;
|
|
valEdgeCnt: TLabel;
|
|
lblEdgeLen: TLabel;
|
|
valEdgeLen: TLabel;
|
|
LblLevelCount: TLabel;
|
|
OptionsGroup: TGroupBox;
|
|
InfoGroup: TGroupBox;
|
|
ScrollBox1: TScrollBox;
|
|
procedure ApplyButtonClick(Sender: TObject);
|
|
procedure CancelButtonClick(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure OKButtonClick(Sender: TObject);
|
|
private
|
|
{$IFDEF WITH_RANDOM_SEED}
|
|
spinTestRandomSeed: TSpinEdit;
|
|
{$ENDIF}
|
|
FApplyCallback: TApplyOptionsProc;
|
|
FGraph: TLvlGraph;
|
|
FOptions: TLvlGraphOptions;
|
|
FShowInfo: Boolean;
|
|
FShowSplitModes: TLvlGraphEdgeSplitModes;
|
|
FEdgeSplitMap: array[0..ord(high(TLvlGraphEdgeSplitMode))] of TLvlGraphEdgeSplitMode;
|
|
FEdgeRevSplitMap: array[low(TLvlGraphEdgeSplitMode)..high(TLvlGraphEdgeSplitMode)] of integer;
|
|
procedure SetApplyCallback(AValue: TApplyOptionsProc);
|
|
procedure SetGraph(AValue: TLvlGraph);
|
|
procedure SetOptions(AValue: TLvlGraphOptions);
|
|
procedure SetShowInfo(AValue: Boolean);
|
|
procedure SetShowSplitModes(AValue: TLvlGraphEdgeSplitModes);
|
|
procedure PopulateEdgeSplit;
|
|
procedure PopulateEdgeShape;
|
|
procedure WriteToOpts;
|
|
procedure ReadFromOpts;
|
|
procedure UpdateInfo;
|
|
public
|
|
property Options: TLvlGraphOptions read FOptions write SetOptions;
|
|
property Graph: TLvlGraph read FGraph write SetGraph;
|
|
property ApplyCallback: TApplyOptionsProc read FApplyCallback write SetApplyCallback;
|
|
property ShowInfo: Boolean read FShowInfo write SetShowInfo;
|
|
property ShowSplitModes: TLvlGraphEdgeSplitModes read FShowSplitModes write SetShowSplitModes;
|
|
end;
|
|
|
|
function ShowDependencyGraphOptions(AnOpts: TLvlGraphOptions; AGraph: TLvlGraph; ACaption: String;
|
|
AnApplyCallback: TApplyOptionsProc = nil): TModalResult;
|
|
|
|
implementation
|
|
|
|
function ShowDependencyGraphOptions(AnOpts: TLvlGraphOptions; AGraph: TLvlGraph; ACaption: String;
|
|
AnApplyCallback: TApplyOptionsProc = nil): TModalResult;
|
|
var
|
|
Dlg: TDependencyGraphOptDialog;
|
|
begin
|
|
Dlg := TDependencyGraphOptDialog.Create(Application);
|
|
Dlg.Caption := ACaption;
|
|
Dlg.Graph := AGraph;
|
|
Dlg.Options := AnOpts;
|
|
Dlg.ApplyCallback := AnApplyCallback;
|
|
Result := Dlg.ShowModal;
|
|
Dlg.Free;
|
|
end;
|
|
|
|
{$R *.lfm}
|
|
|
|
{ TDependencyGraphOptDialog }
|
|
|
|
procedure TDependencyGraphOptDialog.CancelButtonClick(Sender: TObject);
|
|
begin
|
|
ModalResult := mrCancel;
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.FormCreate(Sender: TObject);
|
|
begin
|
|
FShowInfo := True;
|
|
FShowSplitModes := [lgesSeparate, lgesMergeSource, lgesMergeTarget, lgesMergeHighest];
|
|
|
|
chkMinimizeEdges.Caption := LvlGraphShapeMinimizeEdge;
|
|
chkHighEdges.Caption := LvlGraphShapeCalculateLay;
|
|
chkReduceBackEdges.Caption := LvlGraphReduceBackedges;
|
|
chkStraigtenGraph.Caption := LvlGraphStraightenGraph;
|
|
chkCaptionOnTop.Caption := LvlGraphNamesAboveNode;
|
|
|
|
lblEdgeSplit.Caption := LvlGraphShapeEdgesSplitMo;
|
|
lblEdgeShape.Caption := LvlGraphShapeEdgesShape;
|
|
dropEdgeSplit.Constraints.MinWidth := Max(dropEdgeSplit.Constraints.MinWidth,
|
|
lblEdgeSplit.Width);
|
|
dropEdgeShape.Constraints.MinWidth := Max(dropEdgeShape.Constraints.MinWidth,
|
|
lblEdgeShape.Width);
|
|
|
|
OptionsGroup.Caption := lisOptions;
|
|
InfoGroup.Caption := LvlGraphOptInfo;
|
|
lblNodeCnt.Caption := LvlGraphShapeNodes;
|
|
lblEdgeCount.Caption := LvlGraphOptEdges;
|
|
lblEdgeLen.Caption := LvlGraphOptEdgeLen;
|
|
LblLevelCount.Caption := LvlGraphOptLevels;
|
|
LblCrossCount.Caption := LvlGraphOptCrossings;
|
|
lblSplitCount.Caption := LvlGraphOptSplitpoints;
|
|
lblMaxLevelHeight.Caption := LvlGraphOptLimitHeightOfLvl;
|
|
lblExtraSpacing.Caption := LvlGraphExtraSpacing;
|
|
spinLvlLimitAbs.Hint := Format(LvlGraphOptAbsoluteLimi, [LineEnding]);
|
|
spinLvlLimitRel.Hint := Format(LvlGraphOptLimitRelativ, [LineEnding]);
|
|
spinHorizSpacing.Hint := Format(LvlGraphAddHorizontalSpacing, [LineEnding]);
|
|
spinVertSpacing.Hint := Format(LvlGraphAddVerticalSpacingAr, [LineEnding]);
|
|
|
|
ButtonPanel1.CloseButton.Caption := lisBtnApply;
|
|
|
|
{$IFDEF WITH_RANDOM_SEED}
|
|
spinTestRandomSeed := TSpinEdit.Create(Self);
|
|
spinTestRandomSeed.Parent := OptionsGroup;
|
|
spinTestRandomSeed.Hint := 'Random seed for testing. Set to none zero to activate';
|
|
spinTestRandomSeed.ShowHint := True;
|
|
{$ENDIF}
|
|
|
|
|
|
PopulateEdgeSplit;
|
|
PopulateEdgeShape;
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.OKButtonClick(Sender: TObject);
|
|
begin
|
|
WriteToOpts;
|
|
ModalResult := mrOK;
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.ApplyButtonClick(Sender: TObject);
|
|
begin
|
|
if ApplyCallback <> nil then begin
|
|
WriteToOpts;
|
|
ApplyCallback(Options, Graph);
|
|
ModalResult := mrNone;
|
|
UpdateInfo;
|
|
end;
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.SetApplyCallback(AValue: TApplyOptionsProc);
|
|
begin
|
|
if FApplyCallback = AValue then Exit;
|
|
FApplyCallback := AValue;
|
|
if FApplyCallback <> nil then
|
|
ButtonPanel1.ShowButtons := ButtonPanel1.ShowButtons + [pbClose]
|
|
else
|
|
ButtonPanel1.ShowButtons := ButtonPanel1.ShowButtons - [pbClose];
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.SetGraph(AValue: TLvlGraph);
|
|
begin
|
|
if FGraph = AValue then Exit;
|
|
FGraph := AValue;
|
|
UpdateInfo;
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.SetOptions(AValue: TLvlGraphOptions);
|
|
begin
|
|
if FOptions = AValue then Exit;
|
|
FOptions := AValue;
|
|
ReadFromOpts;
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.SetShowInfo(AValue: Boolean);
|
|
begin
|
|
if FShowInfo = AValue then Exit;
|
|
FShowInfo := AValue;
|
|
UpdateInfo;
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.SetShowSplitModes(
|
|
AValue: TLvlGraphEdgeSplitModes);
|
|
begin
|
|
if FShowSplitModes = AValue then Exit;
|
|
FShowSplitModes := AValue;
|
|
PopulateEdgeSplit;
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.PopulateEdgeSplit;
|
|
var
|
|
i: TLvlGraphEdgeSplitMode;
|
|
j: Integer;
|
|
begin
|
|
dropEdgeSplit.Items.Clear;
|
|
j := 0;
|
|
for i := low(TLvlGraphEdgeSplitMode) to high(TLvlGraphEdgeSplitMode) do begin
|
|
if not (i in FShowSplitModes) then
|
|
continue;
|
|
FEdgeSplitMap[j] := i;
|
|
FEdgeRevSplitMap[i] := j;
|
|
case i of
|
|
lgesNone: dropEdgeSplit.Items.Add(LvlGraphSplitNone);
|
|
lgesSeparate: dropEdgeSplit.Items.Add(LvlGraphSplitSeparate);
|
|
lgesMergeSource: dropEdgeSplit.Items.Add(LvlGraphSplitMergeAtSourc);
|
|
lgesMergeTarget: dropEdgeSplit.Items.Add(LvlGraphSplitMergeAtTarge);
|
|
lgesMergeHighest: dropEdgeSplit.Items.Add(LvlGraphSplitMergeAtHighe);
|
|
else dropEdgeSplit.Items.Add('?');
|
|
end;
|
|
inc(j);
|
|
end;
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.PopulateEdgeShape;
|
|
var
|
|
i: TLvlGraphEdgeShape;
|
|
begin
|
|
dropEdgeShape.Items.Clear;
|
|
for i := low(TLvlGraphEdgeShape) to high(TLvlGraphEdgeShape) do begin
|
|
case i of
|
|
lgesStraight: dropEdgeShape.Items.Add(LvlGraphShapeStraight);
|
|
lgesCurved: dropEdgeShape.Items.Add(LvlGraphShapeCurved);
|
|
else dropEdgeShape.Items.Add('?');
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.WriteToOpts;
|
|
begin
|
|
Options.MinimizeEdges := chkMinimizeEdges.Checked;
|
|
Options.HighLevels := chkHighEdges.Checked;
|
|
Options.ReduceBackEdges := chkReduceBackEdges.Checked;
|
|
Options.StraightenGraph := chkStraigtenGraph.Checked;
|
|
Options.EdgeSplit := FEdgeSplitMap[max(0, dropEdgeSplit.ItemIndex)];
|
|
Options.EdgeShape := TLvlGraphEdgeShape(max(0, dropEdgeShape.ItemIndex));
|
|
if chkCaptionOnTop.Checked then
|
|
Options.CaptionPos := lgncTop
|
|
else
|
|
Options.CaptionPos := lgncBottom;
|
|
Options.ExtraSpacingHoriz := spinHorizSpacing.Value;
|
|
Options.ExtraSpacingVert := spinVertSpacing.Value;
|
|
Options.LimitLvlHeighAbs := spinLvlLimitAbs.Value;
|
|
Options.LimitLvlHeighRel := spinLvlLimitRel.Value;
|
|
{$IFDEF WITH_RANDOM_SEED}
|
|
Options.TestRandomSeed := spinTestRandomSeed.Value;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.ReadFromOpts;
|
|
begin
|
|
chkMinimizeEdges.Checked := Options.MinimizeEdges;
|
|
chkHighEdges.Checked := Options.HighLevels;
|
|
chkReduceBackEdges.Checked := Options.ReduceBackEdges;
|
|
chkStraigtenGraph.Checked := Options.StraightenGraph;
|
|
dropEdgeSplit.ItemIndex := FEdgeRevSplitMap[Options.EdgeSplit];
|
|
dropEdgeShape.ItemIndex := ord(Options.EdgeShape);
|
|
chkCaptionOnTop.Checked := Options.CaptionPos = lgncTop;
|
|
spinHorizSpacing.Value := Options.ExtraSpacingHoriz;
|
|
spinVertSpacing.Value := Options.ExtraSpacingVert;
|
|
spinLvlLimitAbs.Value := Options.LimitLvlHeighAbs;
|
|
spinLvlLimitRel.Value := Options.LimitLvlHeighRel;
|
|
{$IFDEF WITH_RANDOM_SEED}
|
|
spinTestRandomSeed.Value := Options.TestRandomSeed;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TDependencyGraphOptDialog.UpdateInfo;
|
|
function ComputeCrossCount: integer;
|
|
var
|
|
l,i,j,e1,e2: Integer;
|
|
Level: TLvlGraphLevel;
|
|
Node1, Node2, Target1, Target2: TLvlGraphNode;
|
|
begin
|
|
Result:=0;
|
|
for l:=0 to Graph.LevelCount-2 do begin
|
|
Level:=Graph.Levels[l];
|
|
for i:=0 to Level.Count-2 do begin
|
|
Node1:=Level.Nodes[i];
|
|
for j:=i+1 to Level.Count-1 do begin
|
|
Node2:=Level.Nodes[j];
|
|
for e1:=0 to Node1.OutEdgeCount-1 do begin
|
|
Target1:=Node1.OutEdges[e1].Target;
|
|
for e2:=0 to Node2.OutEdgeCount-1 do begin
|
|
Target2:=Node2.OutEdges[e2].Target;
|
|
if Target1.IndexInLevel>Target2.IndexInLevel then
|
|
Result+=1;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
var
|
|
InfoNodeCnt, InfoEdgeCnt, InfoEdgeLen, InfoSplitCnt: Integer;
|
|
i, j: Integer;
|
|
Node: TLvlGraphNode;
|
|
Targets: TLvlGraphNodeArray;
|
|
begin
|
|
InfoGroup.Visible := FGraph <> nil;
|
|
if FGraph = nil then
|
|
exit;
|
|
InfoNodeCnt := 0;
|
|
InfoEdgeCnt := 0;
|
|
InfoEdgeLen := 0;
|
|
InfoSplitCnt := 0;
|
|
for i := 0 to Graph.NodeCount - 1 do begin
|
|
Node := Graph.Nodes[i];
|
|
if not Node.Visible then begin
|
|
if (Node.OutEdgeCount > 1) or (Node.InEdgeCount > 1) then
|
|
InfoSplitCnt := InfoSplitCnt + 1;
|
|
continue;
|
|
end;
|
|
InfoNodeCnt := InfoNodeCnt + 1;
|
|
Targets := Node.GetVisibleTargetNodes;
|
|
InfoEdgeCnt := InfoEdgeCnt + length(Targets);
|
|
for j := 0 to high(Targets) do
|
|
InfoEdgeLen := InfoEdgeLen + abs(Targets[j].Level.Index - Node.Level.Index);
|
|
end;
|
|
valNodeCnt.Caption := IntToStr(InfoNodeCnt);
|
|
valEdgeCnt.Caption := IntToStr(InfoEdgeCnt);
|
|
valEdgeLen.Caption := IntToStr(InfoEdgeLen);
|
|
valLevelCnt.Caption := IntToStr(Graph.LevelCount);
|
|
valCrossCnt.Caption := IntToStr(ComputeCrossCount);
|
|
valSplitCnt.Caption := IntToStr(InfoSplitCnt);
|
|
end;
|
|
|
|
{ TLvlGraphOptions }
|
|
|
|
constructor TLvlGraphOptions.Create;
|
|
begin
|
|
inherited;
|
|
FMinimizeEdges := True;
|
|
FHighLevels := False;
|
|
ReduceBackEdges := True;
|
|
FExtraSpacingVert := 0;
|
|
FExtraSpacingHoriz := 0;
|
|
FCaptionPos := lgncTop;
|
|
FEdgeShape := lgesCurved;
|
|
FEdgeSplit := lgesMergeHighest;
|
|
FStraightenGraph := True;
|
|
FLimitLvlHeighAbs := 0;
|
|
FLimitLvlHeighRel := 1.5;
|
|
end;
|
|
|
|
procedure TLvlGraphOptions.ReadFromXml(OnlyDesktop: boolean);
|
|
var
|
|
Def: TLvlGraphOptions;
|
|
begin
|
|
if OnlyDesktop then Exit; // LvlGraph options are not part of desktop.
|
|
Def := TLvlGraphOptions.Create;
|
|
XMLCfg.ReadObject(TopPath, Self, Def);
|
|
Def.Free;
|
|
if OnLoaded <> nil then
|
|
OnLoaded(Self);
|
|
end;
|
|
|
|
procedure TLvlGraphOptions.WriteToXml(OnlyDesktop: boolean);
|
|
var
|
|
Def: TLvlGraphOptions;
|
|
begin
|
|
if OnlyDesktop then Exit;
|
|
Def := TLvlGraphOptions.Create;
|
|
XMLCfg.WriteObject(TopPath, Self, Def);
|
|
Def.Free;
|
|
end;
|
|
|
|
procedure TLvlGraphOptions.Assign(ASrc: TPersistent);
|
|
begin
|
|
FMinimizeEdges := TLvlGraphOptions(ASrc).FMinimizeEdges;
|
|
FHighLevels := TLvlGraphOptions(ASrc).FHighLevels;
|
|
FReduceBackEdges := TLvlGraphOptions(ASrc).FReduceBackEdges;
|
|
FExtraSpacingVert := TLvlGraphOptions(ASrc).FExtraSpacingVert;
|
|
FExtraSpacingHoriz := TLvlGraphOptions(ASrc).FExtraSpacingHoriz;
|
|
FCaptionPos := TLvlGraphOptions(ASrc).FCaptionPos;
|
|
FEdgeShape := TLvlGraphOptions(ASrc).FEdgeShape;
|
|
FEdgeSplit := TLvlGraphOptions(ASrc).FEdgeSplit;
|
|
FStraightenGraph := TLvlGraphOptions(ASrc).FStraightenGraph;
|
|
FLimitLvlHeighAbs := TLvlGraphOptions(ASrc).FLimitLvlHeighAbs;
|
|
FLimitLvlHeighRel := TLvlGraphOptions(ASrc).FLimitLvlHeighRel;
|
|
end;
|
|
|
|
procedure TLvlGraphOptions.WriteToGraph(AValue: TLvlGraphControl);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if MinimizeEdges then
|
|
AValue.Options := AValue.Options + [lgoMinimizeEdgeLens]
|
|
else
|
|
AValue.Options := AValue.Options - [lgoMinimizeEdgeLens];
|
|
if HighLevels then
|
|
AValue.Options := AValue.Options + [lgoHighLevels]
|
|
else
|
|
AValue.Options := AValue.Options - [lgoHighLevels];
|
|
if ReduceBackEdges then
|
|
AValue.Options := AValue.Options + [lgoReduceBackEdges]
|
|
else
|
|
AValue.Options := AValue.Options - [lgoReduceBackEdges];
|
|
i := ExtraSpacingVert div 2;
|
|
AValue.NodeStyle.GapTop := DefaultLvlGraphNodeGapTop + i;
|
|
AValue.NodeStyle.GapBottom := DefaultLvlGraphNodeGapBottom + ExtraSpacingVert - i;
|
|
AValue.NodeStyle.GapRight := DefaultLvlGraphNodeGapRight + ExtraSpacingHoriz;
|
|
AValue.NodeStyle.CaptionPosition := FCaptionPos;
|
|
AValue.EdgeStyle.SplitMode := EdgeSplit;
|
|
AValue.EdgeStyle.Shape := EdgeShape;
|
|
if StraightenGraph then
|
|
AValue.Options := AValue.Options + [lgoStraightenGraph]
|
|
else
|
|
AValue.Options := AValue.Options - [lgoStraightenGraph];
|
|
AValue.Limits.MaxLevelHeightAbs := LimitLvlHeighAbs;
|
|
AValue.Limits.MaxLevelHeightRel := LimitLvlHeighRel;
|
|
{$IFDEF WITH_RANDOM_SEED}
|
|
if TestRandomSeed <> 0 then
|
|
RandSeed := TestRandomSeed; // graph autolayout should be triggered before anything else uses random
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TLvlGraphOptions.ReadFromGraph(AValue: TLvlGraphControl);
|
|
begin
|
|
MinimizeEdges := lgoMinimizeEdgeLens in AValue.Options;
|
|
HighLevels := lgoHighLevels in AValue.Options;
|
|
ReduceBackEdges := lgoReduceBackEdges in AValue.Options;
|
|
ExtraSpacingVert := AValue.NodeStyle.GapTop - DefaultLvlGraphNodeGapTop
|
|
+ AValue.NodeStyle.GapBottom - DefaultLvlGraphNodeGapBottom;
|
|
ExtraSpacingHoriz := AValue.NodeStyle.GapRight - DefaultLvlGraphNodeGapRight;
|
|
FCaptionPos := AValue.NodeStyle.CaptionPosition;
|
|
EdgeSplit := AValue.EdgeStyle.SplitMode;
|
|
EdgeShape := AValue.EdgeStyle.Shape;
|
|
StraightenGraph := lgoStraightenGraph in AValue.Options;
|
|
LimitLvlHeighAbs := AValue.Limits.MaxLevelHeightAbs;
|
|
LimitLvlHeighRel := AValue.Limits.MaxLevelHeightRel;
|
|
end;
|
|
|
|
end.
|
|
|