mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 02:36:23 +02:00
cody: lvlgraph: hidden nodes
git-svn-id: trunk@40392 -
This commit is contained in:
parent
77e410ec98
commit
97a6467b74
@ -253,6 +253,7 @@ type
|
|||||||
FOutWeight: single;
|
FOutWeight: single;
|
||||||
FPrevSelected: TLvlGraphNode;
|
FPrevSelected: TLvlGraphNode;
|
||||||
FSelected: boolean;
|
FSelected: boolean;
|
||||||
|
FVisible: boolean;
|
||||||
function GetInEdges(Index: integer): TLvlGraphEdge;
|
function GetInEdges(Index: integer): TLvlGraphEdge;
|
||||||
function GetOutEdges(Index: integer): TLvlGraphEdge;
|
function GetOutEdges(Index: integer): TLvlGraphEdge;
|
||||||
procedure SetCaption(AValue: string);
|
procedure SetCaption(AValue: string);
|
||||||
@ -261,6 +262,7 @@ type
|
|||||||
procedure SetDrawSize(AValue: integer);
|
procedure SetDrawSize(AValue: integer);
|
||||||
procedure SetLevel(AValue: TLvlGraphLevel);
|
procedure SetLevel(AValue: TLvlGraphLevel);
|
||||||
procedure SetSelected(AValue: boolean);
|
procedure SetSelected(AValue: boolean);
|
||||||
|
procedure SetVisible(AValue: boolean);
|
||||||
procedure UnbindLevel;
|
procedure UnbindLevel;
|
||||||
procedure SelectionChanged;
|
procedure SelectionChanged;
|
||||||
public
|
public
|
||||||
@ -271,6 +273,7 @@ type
|
|||||||
procedure Invalidate;
|
procedure Invalidate;
|
||||||
property Color: TFPColor read FColor write SetColor;
|
property Color: TFPColor read FColor write SetColor;
|
||||||
property Caption: string read FCaption write SetCaption;
|
property Caption: string read FCaption write SetCaption;
|
||||||
|
property Visible: boolean read FVisible write SetVisible;
|
||||||
property Graph: TLvlGraph read FGraph;
|
property Graph: TLvlGraph read FGraph;
|
||||||
function IndexOfInEdge(Source: TLvlGraphNode): integer;
|
function IndexOfInEdge(Source: TLvlGraphNode): integer;
|
||||||
function FindInEdge(Source: TLvlGraphNode): TLvlGraphEdge;
|
function FindInEdge(Source: TLvlGraphNode): TLvlGraphEdge;
|
||||||
@ -400,7 +403,8 @@ type
|
|||||||
property LevelClass: TLvlGraphLevelClass read FLevelClass;
|
property LevelClass: TLvlGraphLevelClass read FLevelClass;
|
||||||
|
|
||||||
procedure CreateTopologicalLevels; // create levels from edges
|
procedure CreateTopologicalLevels; // create levels from edges
|
||||||
procedure ScaleNodeDrawSizes(NodeGapAbove, NodeGapBelow, HardMaxTotal, HardMinOneNode, SoftMaxTotal, SoftMinOneNode: integer);
|
procedure ScaleNodeDrawSizes(NodeGapAbove, NodeGapBelow,
|
||||||
|
HardMaxTotal, HardMinOneNode, SoftMaxTotal, SoftMinOneNode: integer);
|
||||||
procedure SetAllNodeDrawSizes(PixelPerWeight: single = 1.0; MinWeight: single = 0.0);
|
procedure SetAllNodeDrawSizes(PixelPerWeight: single = 1.0; MinWeight: single = 0.0);
|
||||||
procedure MarkBackEdges;
|
procedure MarkBackEdges;
|
||||||
procedure MinimizeCrossings; // set all Node.Position to minimize crossings
|
procedure MinimizeCrossings; // set all Node.Position to minimize crossings
|
||||||
@ -417,6 +421,7 @@ type
|
|||||||
type
|
type
|
||||||
TLvlGraphCtrlOption = (
|
TLvlGraphCtrlOption = (
|
||||||
lgoAutoLayout, // automatic graph layout after graph was changed
|
lgoAutoLayout, // automatic graph layout after graph was changed
|
||||||
|
lgoAutoSplitLongEdges, // split long edges over multiple levels
|
||||||
lgoHighlightNodeUnderMouse, // when mouse over node highlight node and its edges
|
lgoHighlightNodeUnderMouse, // when mouse over node highlight node and its edges
|
||||||
lgoMouseSelects
|
lgoMouseSelects
|
||||||
);
|
);
|
||||||
@ -1001,6 +1006,7 @@ var
|
|||||||
Edge: TLvlGraphEdge;
|
Edge: TLvlGraphEdge;
|
||||||
TargetNode: TLvlGraphNode;
|
TargetNode: TLvlGraphNode;
|
||||||
NodeHighlighted: Boolean;
|
NodeHighlighted: Boolean;
|
||||||
|
x1, y1, x2, y2: Integer;
|
||||||
begin
|
begin
|
||||||
for i:=0 to Graph.LevelCount-1 do begin
|
for i:=0 to Graph.LevelCount-1 do begin
|
||||||
Level:=Graph.Levels[i];
|
Level:=Graph.Levels[i];
|
||||||
@ -1011,23 +1017,35 @@ begin
|
|||||||
TargetNode:=Edge.Target;
|
TargetNode:=Edge.Target;
|
||||||
NodeHighlighted:=(Node=NodeUnderMouse) or (TargetNode=NodeUnderMouse);
|
NodeHighlighted:=(Node=NodeUnderMouse) or (TargetNode=NodeUnderMouse);
|
||||||
if NodeHighlighted<>Highlighted then continue;
|
if NodeHighlighted<>Highlighted then continue;
|
||||||
|
x1:=Level.DrawPosition+ScrollLeft;
|
||||||
|
y1:=Node.DrawCenter-ScrollTop;
|
||||||
|
x2:=TargetNode.Level.DrawPosition-ScrollLeft;
|
||||||
|
y2:=TargetNode.DrawCenter-ScrollTop;
|
||||||
if TargetNode.Level.Index>Level.Index then begin
|
if TargetNode.Level.Index>Level.Index then begin
|
||||||
// normal dependency
|
// normal dependency
|
||||||
|
// => draw line from right of Node to left of TargetNode
|
||||||
|
if Node.Visible then
|
||||||
|
x1+=NodeStyle.Width
|
||||||
|
else
|
||||||
|
x1+=NodeStyle.Width div 2;
|
||||||
|
if not TargetNode.Visible then
|
||||||
|
x2+=NodeStyle.Width div 2;
|
||||||
if NodeHighlighted then
|
if NodeHighlighted then
|
||||||
Canvas.Pen.Color:=clGray
|
Canvas.Pen.Color:=clGray
|
||||||
else
|
else
|
||||||
Canvas.Pen.Color:=clSilver;
|
Canvas.Pen.Color:=clSilver;
|
||||||
Canvas.Line(Level.DrawPosition+NodeStyle.Width-ScrollLeft,
|
Canvas.Line(x1,y1,x2,y2);
|
||||||
Node.DrawCenter-ScrollTop,
|
|
||||||
TargetNode.Level.DrawPosition-ScrollLeft,
|
|
||||||
TargetNode.DrawCenter-ScrollTop);
|
|
||||||
end else begin
|
end else begin
|
||||||
// cycle dependency
|
// cycle dependency
|
||||||
|
// => draw line from left of Node to right of TargetNode
|
||||||
|
if not Node.Visible then
|
||||||
|
x1+=NodeStyle.Width div 2;
|
||||||
|
if TargetNode.Visible then
|
||||||
|
x2+=NodeStyle.Width div 2
|
||||||
|
else
|
||||||
|
x2+=NodeStyle.Width div 2;
|
||||||
Canvas.Pen.Color:=clRed;
|
Canvas.Pen.Color:=clRed;
|
||||||
Canvas.Line(Level.DrawPosition-ScrollLeft,
|
Canvas.Line(x1,y1,x2+NodeStyle.Width,y2);
|
||||||
Node.DrawCenter-ScrollTop,
|
|
||||||
TargetNode.Level.DrawPosition+NodeStyle.Width-ScrollLeft,
|
|
||||||
TargetNode.DrawCenter-ScrollTop);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1054,7 +1072,7 @@ begin
|
|||||||
Level:=Graph.Levels[i];
|
Level:=Graph.Levels[i];
|
||||||
for j:=0 to Level.Count-1 do begin
|
for j:=0 to Level.Count-1 do begin
|
||||||
Node:=Level.Nodes[j];
|
Node:=Level.Nodes[j];
|
||||||
if Node.Caption='' then continue;
|
if (Node.Caption='') or (not Node.Visible) then continue;
|
||||||
TxtW:=Canvas.TextWidth(Node.Caption);
|
TxtW:=Canvas.TextWidth(Node.Caption);
|
||||||
case NodeStyle.CaptionPosition of
|
case NodeStyle.CaptionPosition of
|
||||||
lgncLeft,lgncRight: p.y:=Node.DrawCenter-(TxtH div 2);
|
lgncLeft,lgncRight: p.y:=Node.DrawCenter-(TxtH div 2);
|
||||||
@ -1091,6 +1109,7 @@ begin
|
|||||||
Level:=Graph.Levels[i];
|
Level:=Graph.Levels[i];
|
||||||
for j:=0 to Level.Count-1 do begin
|
for j:=0 to Level.Count-1 do begin
|
||||||
Node:=Level.Nodes[j];
|
Node:=Level.Nodes[j];
|
||||||
|
if not Node.Visible then continue;
|
||||||
//debugln(['TCustomLvlGraphControl.Paint ',Node.Caption,' ',dbgs(FPColorToTColor(Node.Color)),' Level.DrawPosition=',Level.DrawPosition,' Node.DrawPosition=',Node.DrawPosition,' ',Node.DrawPositionEnd]);
|
//debugln(['TCustomLvlGraphControl.Paint ',Node.Caption,' ',dbgs(FPColorToTColor(Node.Color)),' Level.DrawPosition=',Level.DrawPosition,' Node.DrawPosition=',Node.DrawPosition,' ',Node.DrawPositionEnd]);
|
||||||
Canvas.Brush.Color:=FPColorToTColor(Node.Color);
|
Canvas.Brush.Color:=FPColorToTColor(Node.Color);
|
||||||
Canvas.Pen.Color:=Darker(Canvas.Brush.Color);
|
Canvas.Pen.Color:=Darker(Canvas.Brush.Color);
|
||||||
@ -1218,6 +1237,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomLvlGraphControl.AutoLayoutLevels(TxtH: LongInt);
|
procedure TCustomLvlGraphControl.AutoLayoutLevels(TxtH: LongInt);
|
||||||
|
// compute all Levels.DrawPosition
|
||||||
var
|
var
|
||||||
j: Integer;
|
j: Integer;
|
||||||
p: Integer;
|
p: Integer;
|
||||||
@ -1233,6 +1253,7 @@ begin
|
|||||||
LevelTxtWidths[i]:=Max(NodeStyle.Width,Canvas.TextWidth('NodeX'));
|
LevelTxtWidths[i]:=Max(NodeStyle.Width,Canvas.TextWidth('NodeX'));
|
||||||
Level:=Graph.Levels[i];
|
Level:=Graph.Levels[i];
|
||||||
for j:=0 to Level.Count-1 do
|
for j:=0 to Level.Count-1 do
|
||||||
|
if Level[j].Visible then
|
||||||
LevelTxtWidths[i]:=Max(LevelTxtWidths[i], Canvas.TextWidth(Level[j].Caption));
|
LevelTxtWidths[i]:=Max(LevelTxtWidths[i], Canvas.TextWidth(Level[j].Caption));
|
||||||
|
|
||||||
if i=0 then begin
|
if i=0 then begin
|
||||||
@ -1492,6 +1513,7 @@ begin
|
|||||||
if (X<Level.DrawPosition) or (X>=Level.DrawPosition+NodeStyle.Width) then continue;
|
if (X<Level.DrawPosition) or (X>=Level.DrawPosition+NodeStyle.Width) then continue;
|
||||||
for n:=Level.Count-1 downto 0 do begin
|
for n:=Level.Count-1 downto 0 do begin
|
||||||
Node:=Level.Nodes[n];
|
Node:=Level.Nodes[n];
|
||||||
|
if not Node.Visible then continue;
|
||||||
if (Y<Node.DrawPosition) or (Y>=Node.DrawPositionEnd) then continue;
|
if (Y<Node.DrawPosition) or (Y>=Node.DrawPositionEnd) then continue;
|
||||||
exit(Node);
|
exit(Node);
|
||||||
end;
|
end;
|
||||||
@ -1860,7 +1882,8 @@ end;
|
|||||||
|
|
||||||
procedure TLvlGraph.ScaleNodeDrawSizes(NodeGapAbove, NodeGapBelow,
|
procedure TLvlGraph.ScaleNodeDrawSizes(NodeGapAbove, NodeGapBelow,
|
||||||
HardMaxTotal, HardMinOneNode, SoftMaxTotal, SoftMinOneNode: integer);
|
HardMaxTotal, HardMinOneNode, SoftMaxTotal, SoftMinOneNode: integer);
|
||||||
{ NodeGap: minimum space between nodes
|
{ NodeGapAbove: minimum space above each node
|
||||||
|
NodeGapBelow: minimum space below each node
|
||||||
HardMaxTotal: maximum size of largest level
|
HardMaxTotal: maximum size of largest level
|
||||||
HardMinOneNode: minimum size of a node
|
HardMinOneNode: minimum size of a node
|
||||||
SoftMaxTotal: preferred maximum size of the largest level, total can be bigger
|
SoftMaxTotal: preferred maximum size of the largest level, total can be bigger
|
||||||
@ -1880,6 +1903,7 @@ var
|
|||||||
MinPixelPerWeight, PrefMinPixelPerWeight: single;
|
MinPixelPerWeight, PrefMinPixelPerWeight: single;
|
||||||
DrawHeight: integer;
|
DrawHeight: integer;
|
||||||
PixelPerWeight, MaxPixelPerWeight, PrefMaxPixelPerWeight: single;
|
PixelPerWeight, MaxPixelPerWeight, PrefMaxPixelPerWeight: single;
|
||||||
|
Gap: Integer;
|
||||||
begin
|
begin
|
||||||
//debugln(['TLvlGraph.ScaleNodeDrawSizes',
|
//debugln(['TLvlGraph.ScaleNodeDrawSizes',
|
||||||
// ' NodeGapAbove=',NodeGapAbove,' NodeGapBelow=',NodeGapBelow,
|
// ' NodeGapAbove=',NodeGapAbove,' NodeGapBelow=',NodeGapBelow,
|
||||||
@ -1919,14 +1943,23 @@ begin
|
|||||||
for i:=0 to LevelCount-1 do begin
|
for i:=0 to LevelCount-1 do begin
|
||||||
Level:=Levels[i];
|
Level:=Levels[i];
|
||||||
// LvlWeight = how much weight to draw
|
// LvlWeight = how much weight to draw
|
||||||
LvlWeight:=Level.GetTotalInOutWeights;
|
|
||||||
if LvlWeight=0.0 then continue;
|
|
||||||
// DrawHeight - how much pixel left to draw the weight
|
// DrawHeight - how much pixel left to draw the weight
|
||||||
DrawHeight:=Max(1,HardMaxTotal-(Level.Count*(NodeGapAbove+NodeGapBelow)));
|
LvlWeight:=0.0;
|
||||||
|
Gap:=0;
|
||||||
|
DrawHeight:=HardMaxTotal;
|
||||||
|
for j:=0 to Level.Count-1 do begin
|
||||||
|
LvlWeight+=Max(Node.InWeight,Node.OutWeight);
|
||||||
|
if Node.Visible then
|
||||||
|
Gap+=NodeGapAbove+NodeGapBelow
|
||||||
|
else
|
||||||
|
Gap+=1;
|
||||||
|
end;
|
||||||
|
if LvlWeight=0.0 then continue;
|
||||||
|
DrawHeight:=Max(1,HardMaxTotal-Gap);
|
||||||
PixelPerWeight:=single(DrawHeight)/LvlWeight;
|
PixelPerWeight:=single(DrawHeight)/LvlWeight;
|
||||||
if (MaxPixelPerWeight=0.0) or (MaxPixelPerWeight>PixelPerWeight) then
|
if (MaxPixelPerWeight=0.0) or (MaxPixelPerWeight>PixelPerWeight) then
|
||||||
MaxPixelPerWeight:=PixelPerWeight;
|
MaxPixelPerWeight:=PixelPerWeight;
|
||||||
DrawHeight:=Max(1,SoftMaxTotal-(Level.Count*(NodeGapAbove+NodeGapBelow)));
|
DrawHeight:=Max(1,SoftMaxTotal-Gap);
|
||||||
PixelPerWeight:=single(DrawHeight)/LvlWeight;
|
PixelPerWeight:=single(DrawHeight)/LvlWeight;
|
||||||
if (PrefMaxPixelPerWeight=0.0) or (PrefMaxPixelPerWeight>PixelPerWeight) then
|
if (PrefMaxPixelPerWeight=0.0) or (PrefMaxPixelPerWeight>PixelPerWeight) then
|
||||||
PrefMaxPixelPerWeight:=PixelPerWeight;
|
PrefMaxPixelPerWeight:=PixelPerWeight;
|
||||||
@ -2006,8 +2039,10 @@ begin
|
|||||||
Node:=TLvlGraphNode(AVLNode.Data);
|
Node:=TLvlGraphNode(AVLNode.Data);
|
||||||
if Last=nil then
|
if Last=nil then
|
||||||
Node.DrawPosition:=MinPos+NodeGapAbove
|
Node.DrawPosition:=MinPos+NodeGapAbove
|
||||||
|
else if Node.Visible then
|
||||||
|
Node.DrawPosition:=Max(Node.DrawPosition,Last.DrawPositionEnd+NodeGapBelow+NodeGapAbove)
|
||||||
else
|
else
|
||||||
Node.DrawPosition:=Max(Node.DrawPosition,Last.DrawPositionEnd+NodeGapBelow+NodeGapAbove);
|
Node.DrawPosition:=Max(Node.DrawPosition,Last.DrawPositionEnd+1);
|
||||||
Last:=Node;
|
Last:=Node;
|
||||||
AVLNode:=Tree.FindSuccessor(AVLNode);
|
AVLNode:=Tree.FindSuccessor(AVLNode);
|
||||||
end;
|
end;
|
||||||
@ -2249,6 +2284,13 @@ begin
|
|||||||
SelectionChanged;
|
SelectionChanged;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TLvlGraphNode.SetVisible(AValue: boolean);
|
||||||
|
begin
|
||||||
|
if FVisible=AValue then Exit;
|
||||||
|
FVisible:=AValue;
|
||||||
|
Invalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TLvlGraphNode.UnbindLevel;
|
procedure TLvlGraphNode.UnbindLevel;
|
||||||
begin
|
begin
|
||||||
if FLevel<>nil then
|
if FLevel<>nil then
|
||||||
@ -2275,6 +2317,7 @@ begin
|
|||||||
FInEdges:=TFPList.Create;
|
FInEdges:=TFPList.Create;
|
||||||
FOutEdges:=TFPList.Create;
|
FOutEdges:=TFPList.Create;
|
||||||
FDrawSize:=1;
|
FDrawSize:=1;
|
||||||
|
FVisible:=true;
|
||||||
Level:=TheLevel;
|
Level:=TheLevel;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user