📄 adstmach.pas
字号:
{ tell the state to deactivate }
DoDeactivate;
{ generate the appropriate events }
if Assigned(FOnStateChange) then
FOnStateChange(Self, FCurrentState, NextState);
if (Assigned (LiveDataSource)) and
(FCurrentState.Conditions[M.wParam].OutputOnActivate <> '') then
LiveDataSource.Output (FCurrentState.Conditions[M.wParam].OutputOnActivate);
{ activate the next state }
DoActivate(NextState);
end;
function TApdCustomStateMachine.GetComPort : TApdCustomComPort;
begin
if LiveDataSource is TApdStateComPortSource then
Result := TApdStateComPortSource (LiveDataSource).ComPort
else if Assigned (FDefaultDataSource) then
Result := FDefaultDataSource.ComPort
else
Result := nil;
end;
function TApdCustomStateMachine.GetData: Pointer;
begin
Result := FData;
end;
function TApdCustomStateMachine.GetDataSource : TApdStateCustomDataSource;
begin
if Assigned (FDataSource) then
Result := FDataSource
else
Result := nil;
end;
function TApdCustomStateMachine.GetDataSize: Integer;
begin
Result := FDataSize;
end;
function TApdCustomStateMachine.GetDataString: string;
begin
Result := FDataString;
end;
function TApdCustomStateMachine.GetLiveDataSource : TApdStateCustomDataSource;
begin
if Assigned (FDataSource) then
Result := FDataSource
else
Result := FDefaultDataSource;
end;
function TApdCustomStateMachine.GetPaused;
begin
if Assigned (LiveDataSource) then
Result := LiveDataSource.Paused
else
Result := FDefaultDataSource.Paused;
end;
function TApdCustomStateMachine.GetStateNames: TStringList;
var
I : Integer;
begin
Result := TStringList.Create;
for I := 0 to pred(Owner.ComponentCount) do
if Owner.Components[I] is TApdCustomState then
if TApdCustomState(Owner.Components[I]).FStateMachine = Self then
Result.Add(TApdCustomState(Owner.Components[I]).Name);
end;
procedure TApdCustomStateMachine.Loaded;
begin
inherited;
end;
procedure TApdCustomStateMachine.MouseDown (Button : TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i : Integer;
Point : TPoint;
State : TApdCustomState;
AddType : TApdConnectAddType;
begin
if Button = mbLeft then begin
Point.x := X;
Point.y := Y;
if (Point.x < Left) or (Point.x > Left + Width) or
(Point.y < Top) or (Point.y > Top + Height) then
Exit;
for i := 0 to pred (ControlCount) do begin
if Controls[i] is TApdCustomState then begin
State := TApdCustomState(Controls[i]);
if (Point.x >= State.Left) and
(Point.x <= State.Left + State.Width) and
(Point.y >= State.Top) and
(Point.y <= State.Top + State.Height) then
Exit;
end;
end;
if (ssShift in Shift) then
AddType := atAdd
else if (ssCtrl in Shift) then
AddType := atSub
else
AddType := atNone;
ConnectoidAtPoint (AddType, Point);
end;
inherited MouseDown (Button, Shift, X, Y);
end;
procedure TApdCustomStateMachine.Notification (AComponent : TComponent;
Operation : TOperation);
begin
inherited Notification (AComponent, Operation);
if (Operation = opRemove) then begin
{See if our com port is going away}
if (AComponent = ComPort) then
ComPort := nil
else if (AComponent = FDataSource) then
FDataSource := nil
else if (AComponent = FStartState) then
FStartState := nil
else if (AComponent = FTerminalState) then
FTerminalState := nil;
end else if (Operation = opInsert) then begin
{Check for a com port being installed}
if not Assigned (ComPort) and
(AComponent is TApdCustomComPort) then
ComPort := TApdCustomComPort (AComponent);
end;
end;
procedure TApdCustomStateMachine.StateMachinePaint;
var
R : TRect;
I, C : Integer;
State : TApdCustomState;
HintText : string;
begin
HintText := '';
{get the display dimensions}
R := GetClientRect;
{ clear the existing display }
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := Color;
Canvas.FillRect(R);
Canvas.Brush.Style := bsClear;
Canvas.Pen.Color := clActiveBorder;
Canvas.TextRect(R, 2, 2, Caption);
{ draw the connectoids }
for I := 0 to pred(ControlCount) do begin
if Controls[I] is TApdCustomState then begin
State := TApdCustomState(Controls[I]);
if State.Conditions.Count > 0 then begin
for C := 0 to pred(State.Conditions.Count) do
if State.Conditions[C].NextState <> nil then begin
RenderConnectoid (State.Conditions[C].Connectoid,
State, State.Conditions[C].NextState);
if (State.Conditions[C].Connectoid.FSelected) and
((csDesigning in ComponentState) or
(ccsHint in ConnectoidClickStyle)) then
HintText := HintText + State.Name + ' -> ' +
State.Conditions[C].NextState.Name + ' ';
end;
end;
end;
end;
{ tell the states to draw themselves }
for I := 0 to pred(ControlCount) do begin
if Controls[I] is TApdCustomState then
TApdCustomState(Controls[I]).Paint;
end;
{ Display Hint Text }
if HintText <> '' then begin
Canvas.Pen.Color := clBlack;
Canvas.Pen.Width := 1;
Canvas.Brush.Color := $00bfffff;
Canvas.Font.Color := clBlack;
Canvas.Rectangle (3, 3,
Canvas.TextWidth (HintText) + 7,
Canvas.TextHeight (HintText) + 7);
Canvas.TextOut (5, 5, HintText);
Canvas.Brush.Color := clWhite;
end;
end;
procedure TApdCustomStateMachine.PaintWindow(DC: HDC);
var
R : TRect;
begin
Canvas.Handle := DC;
try
R := ClientRect;
InvalidateRect(Canvas.Handle, @R, True);
StateMachinePaint;
finally
Canvas.Handle := 0;
end;
end;
procedure TApdCustomStateMachine.Pause;
begin
if Assigned (LiveDataSource) then
LiveDataSource.Pause;
FDefaultDataSource.Pause;
end;
procedure TApdCustomStateMachine.RenderConnectoid (
Connectoid : TApdStateConnectoid;
State, DestState : TApdCustomState);
var
StartAt : TPoint;
EndAt : TPoint;
MidPoint : TPoint;
MinPoint : TPoint;
MaxPoint : TPoint;
OldColor : TColor;
begin
if Assigned(Connectoid) and Assigned(DestState) and
(Connectoid <> nil) and (DestState <> nil) then begin
StartAt.x := State.Left + (State.Width div 2);
StartAt.y := State.Top + (State.Height div 2);
EndAt.x := DestState.Left + (DestState.Width div 2);
EndAt.y := DestState.Top + (DestState.Height div 2);
if StartAt.x > EndAt.x then begin
MinPoint.x := EndAt.x;
MaxPoint.x := StartAt.x;
end else begin
MinPoint.x := StartAt.x;
MaxPoint.x := EndAt.x;
end;
if StartAt.y > EndAt.y then begin
MinPoint.y := EndAt.y;
MaxPoint.y := StartAt.y;
end else begin
MinPoint.y := StartAt.y;
MaxPoint.y := EndAt.y;
end;
MidPoint.x := (MaxPoint.x - MinPoint.x) div 2 + MinPoint.x;
MidPoint.y := (MaxPoint.y - MinPoint.y) div 2 + MinPoint.y;
OldColor := Canvas.Pen.Color;
Canvas.Font.Assign (Connectoid.Font);
if (Connectoid.FSelected) and
((csDesigning in ComponentState) or
(ccsHighlight in ConnectoidClickStyle)) then begin
if Connectoid.Color = clRed then
Canvas.Pen.Color := clFuchsia
else
Canvas.Pen.Color := clRed;
Canvas.Font.Color := clRed;
end else
Canvas.Pen.Color := Connectoid.Color;
Canvas.Pen.Width := Connectoid.Width;
if DestState = State then begin
Dec (StartAt.x, 8);
Canvas.Ellipse (State.Left + State.Width - 14, State.Top - 6,
State.Left + State.Width - 8, State.Top);
Canvas.Ellipse (State.Left + State.Width + 12, State.Top - 12,
State.Left + State.Width - 12, State.Top + 12);
{ Draw Arrow }
Canvas.MoveTo (DestState.Left + DestState.Width, State.Top + 10);
Canvas.LineTo (DestState.Left + DestState.Width + 4, State.Top + 6);
Canvas.MoveTo (DestState.Left + DestState.Width, State.Top + 10);
Canvas.LineTo (DestState.Left + DestState.Width + 4, State.Top + 14);
Canvas.TextOut(State.Left + State.Width -
Canvas.TextWidth (Connectoid.Caption) div 2,
State.Top - 14 - Canvas.TextHeight (Connectoid.Caption),
Connectoid.Caption);
end else if (DestState.Top > State.Top + State.Height) then begin
Dec (StartAt.x, 8);
Dec (EndAt.x, 8);
Dec (MidPoint.y, 4);
{ Draw Start }
Canvas.Ellipse (StartAt.x - 3, State.Top + State.Height + 6,
StartAt.x + 3, State.Top + State.Height);
{ Draw Connectoid }
Canvas.MoveTo (StartAt.x, StartAt.y);
Canvas.LineTo (StartAt.x, MidPoint.y);
Canvas.LineTo (EndAt.x, MidPoint.y);
Canvas.LineTo (EndAt.x, EndAt.y);
{ Draw Arrow }
Canvas.MoveTo (EndAt.x, DestState.Top);
Canvas.LineTo (EndAt.x - 4, DestState.Top - 4);
Canvas.MoveTo (EndAt.x, DestState.Top);
Canvas.LineTo (EndAt.x + 4, DestState.Top - 4);
if EndAt.x > StartAt.x then
Canvas.TextOut(StartAt.x + 2,
MidPoint.y - Canvas.TextHeight (Connectoid.Caption) - 2,
Connectoid.Caption)
else
Canvas.TextOut(StartAt.x - 2 - Canvas.TextWidth (Connectoid.Caption),
MidPoint.y - Canvas.TextHeight (Connectoid.Caption) - 2,
Connectoid.Caption)
end else if (DestState.Top + DestState.Height < State.Top) then begin
Inc (StartAt.x, 8);
Inc (EndAt.x, 8);
Inc (MidPoint.y, 4);
{ Draw Start }
Canvas.Ellipse (StartAt.x - 3, State.Top - 6,
StartAt.x + 3, State.Top);
{ Draw Connectoid }
Canvas.MoveTo (StartAt.x, StartAt.y);
Canvas.LineTo (StartAt.x, MidPoint.y);
Canvas.LineTo (EndAt.x, MidPoint.y);
Canvas.LineTo (EndAt.x, EndAt.y);
{ Draw Arrow }
Canvas.MoveTo (EndAt.x, DestState.Top + DestState.Height);
Canvas.LineTo (EndAt.x - 4, DestState.Top + DestState.Height + 4);
Canvas.MoveTo (EndAt.x, DestState.Top + DestState.Height);
Canvas.LineTo (EndAt.x + 4, DestState.Top + DestState.Height + 4);
if EndAt.x >= StartAt.x then
Canvas.TextOut(StartAt.x + 2,
MidPoint.y + 2,
Connectoid.Caption)
else
Canvas.TextOut(StartAt.x - 2 - Canvas.TextWidth (Connectoid.Caption),
MidPoint.y + 2,
Connectoid.Caption)
end else if (DestState.Left > State.Left + State.Width) then begin
Dec (StartAt.y, 8);
Dec (EndAt.y, 8);
Dec (MidPoint.x, 4);
{ Draw Start }
Canvas.Ellipse (State.Left + State.Width, StartAt.y - 3,
State.Left + State.Width + 6, StartAt.y + 3);
{ Draw Connectoid }
Canvas.MoveTo (StartAt.x, StartAt.y);
Canvas.LineTo (MidPoint.x, StartAt.y);
Canvas.LineTo (MidPoint.x, EndAt.y);
Canvas.LineTo (EndAt.x, EndAt.y);
{ Draw Arrow }
Canvas.MoveTo (DestState.Left, EndAt.y);
Canvas.LineTo (DestState.Left - 4, EndAt.y - 4);
Canvas.MoveTo (DestState.Left, EndAt.y);
Canvas.LineTo (DestState.Left - 4, EndAt.y + 4);
if EndAt.y >= StartAt.y then
Canvas.TextOut(State.Left + State.Width + 10,
StartAt.y - Canvas.TextHeight (Connectoid.Caption) - 2,
Connectoid.Caption)
else
Canvas.TextOut(DestState.Left - Canvas.TextWidth (Connectoid.Caption) - 2,
EndAt.y - Canvas.TextHeight (Connectoid.Caption) - 2,
Connectoid.Caption)
end else if (DestState.Left + DestState.Width < State.Left) then begin
Inc (St
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -