📄 d_lmddiagram.pas
字号:
LItem := TLMDDiagram(Source).SelectedItem.DisplayName
else
LItem := 'nil';
Memo1.Lines.Add(Format('Panel1.OnDragDrop: %s (Item: %s) -> %s (X: %d, Y: %d)',
[LSource, LItem, Panel1.Name, X, Y]));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
LMDDiagram1.Items.Add;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if LMDDiagram1.SelectedItem <> nil then
LMDDiagram1.SelectedItem.Free;
if LMDDiagram1.SelectedLink <> nil then
LMDDiagram1.SelectedLink.Free;
end;
procedure TForm1.LMDDiagram1DragOver(Sender, Source: TObject; X,
Y: Integer; State: TDragState; var Accept: Boolean);
begin
if (Source = LMDDiagram1) and (LMDDiagram1.SelectedItem <> nil) and
(LMDDiagram1.ItemAtPos(X, Y) <> nil) and
(LMDDiagram1.SelectedItem <> LMDDiagram1.ItemAtPos(X, Y)) then
Accept := True
else
Accept := False;
end;
procedure TForm1.LMDDiagram1DragDrop(Sender, Source: TObject; X,
Y: Integer);
begin
if (Source = LMDDiagram1) and (LMDDiagram1.SelectedItem <> nil) and
(LMDDiagram1.ItemAtPos(X, Y) <> nil) and
(LMDDiagram1.SelectedItem <> LMDDiagram1.ItemAtPos(X, Y)) then
with TLMDDiagramLink(LMDDiagram1.Links.Add) do
begin
BeginItemName := LMDDiagram1.SelectedItem.Name;
EndItemName := LMDDiagram1.ItemAtPos(X, Y).Name;
end;
end;
procedure TForm1.LMDDiagram1KeyPress(Sender: TObject; var Key: Char);
begin
if CheckBox9.Checked then
Memo1.Lines.Add(Format('OnKeyPress: (Key: "%s")', [Key]));
end;
procedure TForm1.LMDDiagram1PaintItem(Sender: TObject;
APanel: TLMDDiagramItemPanel);
var
LI: Integer;
LRect: TRect;
begin
APanel.Canvas.Pen.Color := clBtnShadow;
APanel.Canvas.MoveTo(10, 0);
APanel.Canvas.LineTo(10, APanel.ClientHeight - 10);
LI := 10;
while LI < APanel.ClientHeight - 10 do
begin
APanel.Canvas.MoveTo(8, LI);
APanel.Canvas.LineTo(13, LI);
Inc(LI, 10);
end;
APanel.Canvas.MoveTo(10, APanel.ClientHeight - 10);
APanel.Canvas.LineTo(APanel.ClientWidth, APanel.ClientHeight - 10);
LI := 10;
while LI < APanel.ClientWidth - 10 do
begin
APanel.Canvas.MoveTo(LI, APanel.ClientHeight - 8);
APanel.Canvas.LineTo(LI, APanel.ClientHeight - 13);
Inc(LI, 10);
end;
APanel.Canvas.Pen.Color := clRed;
APanel.Canvas.MoveTo(10, APanel.ClientHeight - 10);
for LI := 10 to APanel.ClientWidth - 1 do
APanel.Canvas.LineTo(LI, APanel.ClientHeight - (LI - 10) * (LI - 10) div 70 - 10);
APanel.Canvas.TextOut(20, 5, 'y = F(x)');
if APanel.Focused then
begin
LRect := APanel.ClientRect;
InflateRect(LRect, -2, -2);
APanel.Canvas.DrawFocusRect(LRect);
end;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
LMDDiagram1.CustomDrawItems := CheckBox1.Checked;
end;
procedure TForm1.CheckBox2Click(Sender: TObject);
begin
LMDDiagram1.CustomDrawLinks := CheckBox2.Checked;
end;
procedure TForm1.LMDDiagram1CreateLinkDrawInfo(Sender: TObject;
ALink: TLMDDiagramLink; var ADrawInfo: TLMDLinkDrawInfo);
begin
// Create TCustomLinkDrawInfo object and fill it with information
// for drawing link. This information must be enough for drawing link.
// Later this information will be used to draw the ALink object.
// You must not use any other information (except represented in the ADrawInfo),
// including ALink properties for drawing link and custom
// ADrawInfo object must not contains references to other objects.
// You must not offset any coordinates using diagram HScrollPos and VScrollPos
// properties.
if (ALink.BeginItem <> nil) and (ALink.EndItem <> nil) and
(ALink.BeginItem.Visible) and (ALink.EndItem.Visible) and ALink.Visible then
begin
ADrawInfo := TCustomLinkDrawInfo.Create;
with TCustomLinkDrawInfo(ADrawInfo) do
begin
BeginP := Point(ALink.BeginItem.Left + ALink.BeginItem.Width div 2,
ALink.BeginItem.Top - 10);
EndP := Point(ALink.EndItem.Left + ALink.EndItem.Width div 2,
ALink.EndItem.Top - 10);
Color := ALink.Color;
Selected := ALink.Selected;
end;
end;
end;
procedure TForm1.LMDDiagram1IsEqualDrawInfos(Sender: TObject; ADrawInfo1,
ADrawInfo2: TLMDLinkDrawInfo; var AIsEqual: Boolean);
begin
// Compare draw infos. This is used to optimize links drawing.
AIsEqual :=
(TCustomLinkDrawInfo(ADrawInfo1).BeginP.X = TCustomLinkDrawInfo(ADrawInfo2).BeginP.X) and
(TCustomLinkDrawInfo(ADrawInfo1).BeginP.Y = TCustomLinkDrawInfo(ADrawInfo2).BeginP.Y) and
(TCustomLinkDrawInfo(ADrawInfo1).EndP.X = TCustomLinkDrawInfo(ADrawInfo2).EndP.X) and
(TCustomLinkDrawInfo(ADrawInfo1).EndP.Y = TCustomLinkDrawInfo(ADrawInfo2).EndP.Y) and
(TCustomLinkDrawInfo(ADrawInfo1).Color = TCustomLinkDrawInfo(ADrawInfo2).Color) and
(TCustomLinkDrawInfo(ADrawInfo1).Selected = TCustomLinkDrawInfo(ADrawInfo2).Selected);
end;
procedure TForm1.LMDDiagram1IsOnLink(Sender: TObject;
ADrawInfo: TLMDLinkDrawInfo; AX, AY: Integer; var AIsOnLink: Boolean);
const
LR = 3;
var
LXMin, LXMax, LYMin, LYMax: Integer;
LA, LB, LA_2, LB_2, LC_2: Double;
LP, LP1, LP2: TPoint;
LDI: TCustomLinkDrawInfo;
begin
// Check if the Point(AX, AY) is on Line(ADrawInfo.BeginP; ADrawInfo.EndP)
// or near this line (e.g. the circle with (AX, AY) center and LR radius
// intersects the Line). This is used when user clicks diagram to selecting
// links and in the LinkAtPos function.
LDI := ADrawInfo as TCustomLinkDrawInfo;
LP := Point(AX, AY);
LP1 := LDI.BeginP;
Dec(LP1.X, LMDDiagram1.HScrollPos);
Dec(LP1.Y, LMDDiagram1.VScrollPos);
LP2 := LDI.EndP;
Dec(LP2.X, LMDDiagram1.HScrollPos);
Dec(LP2.Y, LMDDiagram1.VScrollPos);
{ Calc Min and Max }
if LP1.X < LP2.X then
begin
LXMin := LP1.X;
LXMax := LP2.X;
end
else
begin
LXMin := LP2.X;
LXMax := LP1.X;
end;
if LP1.Y < LP2.Y then
begin
LYMin := LP1.Y;
LYMax := LP2.Y;
end
else
begin
LYMin := LP2.Y;
LYMax := LP1.Y;
end;
{ Check }
AIsOnLink := (LP.Y - LR <= LYMax) and (LP.Y + LR >= LYMin) and
(LP.X - LR <= LXMax) and (LP.X + LR >= LXMin);
if AIsOnLink and not ((LXMin = LXMax) or (LYMin = LYMax)) then
begin
LA := (LP1.Y - LP2.Y) / (LP1.X - LP2.X);
LB := LP1.Y - LA * LP1.X;
LA_2 := 1 + LA * LA;
LB_2 := 2 * LA * LB - 2 * LP.X - 2 * LA * LP.Y;
LC_2 := LP.X * LP.X + LB * LB - 2 * LB * LP.Y + LP.Y * LP.Y - LR * LR;
if (LB_2 * LB_2 - 4 * LA_2 * LC_2) < 0 then AIsOnLink := False;
end;
end;
procedure TForm1.LMDDiagram1PaintLink(Sender: TObject;
ADrawInfo: TLMDLinkDrawInfo; AClear: Boolean);
var
LXOffset, LYOffset: Integer;
LDI: TCustomLinkDrawInfo;
begin
// Paint link using ADrawInfo draw info object. You mast not use any other
// information in this procedure to paint link!
// AClear parameter is determined whether the link must be eraised from diagram
// (AClear = True) or normal painting is expected (AClear = False)
// You must use diagram HScrollPos and VScrollPos properties to offset
// coordinates represented in the ADrawInfo object.
LDI := ADrawInfo as TCustomLinkDrawInfo;
if AClear then
begin
LMDDiagram1.Canvas.Pen.Color := Color;
LMDDiagram1.Canvas.Brush.Color := Color;
end
else
begin
LMDDiagram1.Canvas.Pen.Color := LDI.Color;
LMDDiagram1.Canvas.Brush.Color := LDI.Color;
end;
LXOffset := -LMDDiagram1.HScrollPos;
LYOffset := -LMDDiagram1.VScrollPos;
LMDDiagram1.Canvas.Ellipse(Rect(
LDI.BeginP.X + LXOffset - 2,
LDI.BeginP.Y + LYOffset - 2,
LDI.BeginP.X + LXOffset + 2,
LDI.BeginP.Y + LYOffset + 2));
LMDDiagram1.Canvas.Ellipse(Rect(
LDI.EndP.X + LXOffset - 2,
LDI.EndP.Y + LYOffset - 2,
LDI.EndP.X + LXOffset + 2,
LDI.EndP.Y + LYOffset + 2));
if LDI.Selected then
LMDDiagram1.Canvas.Pen.Width := 2
else
LMDDiagram1.Canvas.Pen.Width := 1;
LMDDiagram1.Canvas.Polyline([
Point(
LDI.BeginP.X + LXOffset,
LDI.BeginP.Y + LYOffset),
Point(
LDI.EndP.X + LXOffset,
LDI.EndP.Y + LYOffset)
]);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -