⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jvqsimlogic.pas

📁 East make Tray Icon in delphi
💻 PAS
📖 第 1 页 / 共 5 页
字号:
        begin
          Left := nc.X - D;
          Width := -nw + D + D;
        end
        else
          Width := nw;
        nh := nc.Y - FConAnchor.Y;
        // adjust BR new hot position
        if (nw < D) and (not (nh < D)) then
        begin
          case FConHot of
            jcpBR:
              FConPos := jcpBL;
            jcpTL:
              FConPos := jcpTR;
          end;
          FShape := jcsTRBL;
        end
        else
        if (nw < D) and (nh < D) then
        begin
          case FConHot of
            jcpBR:
              FConPos := jcpTL;
            jcpTL:
              FConPos := jcpBR;
          end;
          FShape := jcsTLBR;
        end
        else
        if (not nw < D) and (nh < D) then
        begin
          case FConHot of
            jcpBR:
              FConPos := jcpTR;
            jcpTL:
              FConPos := jcpBL;
          end;
          FShape := jcsTRBL;
        end
        else
        begin
          case FConHot of
            jcpBR:
              FConPos := jcpBR;
            jcpTL:
              FConPos := jcpTL;
          end;
          FShape := jcsTLBR;
        end;
        // end of adjust BR new hot
        if nh < D then
        begin
          Top := FConAnchor.Y + nh - D;
          Height := -nh + D + D;
        end
        else
          Height := nh;
      end;
    jcmBL:
      begin
        nw := FConAnchor.X - nc.X;
        if nw < D then
        begin
          Left := FConAnchor.X - D;
          Width := -nw + D + D;
        end
        else
        begin
          Left := FConAnchor.X - nw;
          Width := nw;
        end;
        nh := nc.Y - FConAnchor.Y;
        // adjust BL new hot position
        if (nw < D) and (not (nh < D)) then
        begin
          case FConHot of
            jcpBL:
              FConPos := jcpBR;
            jcpTR:
              FConPos := jcpTL;
          end;
          FShape := jcsTLBR;
        end
        else
        if (nw < D) and (nh < D) then
        begin
          case FConHot of
            jcpBL:
              FConPos := jcpTR;
            jcpTR:
              FConPos := jcpBL;
          end;
          FShape := jcsTRBL;
        end
        else
        if (not nw < D) and (nh < D) then
        begin
          case FConHot of
            jcpBL:
              FConPos := jcpTL;
            jcpTR:
              FConPos := jcpBR;
          end;
          FShape := jcsTLBR;
        end
        else
        begin
          case FConHot of
            jcpBL:
              FConPos := jcpBL;
            jcpTR:
              FConPos := jcpTR;
          end;
          FShape := jcsTRBL;
        end;
        // end of adjust BL new hot
        if nh < D then
        begin
          Top := FConAnchor.Y + nh - D;
          Height := -nh + D + D;
        end
        else
          Height := nh;
      end;
  end;
end;

procedure TJvSIMConnector.Connect;
var
  Pi, Po: TPoint;
  R: TRect;
  D, d2, xw, yh: Integer;
  Wc: TWinControl;
  Vi: Boolean;
  sBut: TJvSimButton;
  sLog: TJvLogic;
  sLight: TJvSimLight;
  sRev: TJvSimReverse;
  pl: TPoint;

  // convert a corner point to a Parent point

  function ParentPoint(X, Y: Integer): TPoint;
  var
    P: TPoint;
  begin
    P := Point(X, Y);
    P := ClientToScreen(P);
    Result := Wc.ScreenToClient(P);
  end;

  function GetVi: Boolean;
  var
    J: Integer;
  begin
    Result := True;
    for J := 0 to Wc.ControlCount - 1 do
    begin
      if Wc.Controls[J] is TJvSimButton then
      begin
        R := Wc.Controls[J].BoundsRect;
        InflateRect(R, D, 0);
        if PtInRect(R, Pi) then
        begin
          sBut := TJvSimButton(Wc.Controls[J]);
          Vi := sBut.Down;
          Exit;
        end;
      end
      else
      if Wc.Controls[J] is TJvSimReverse then
      begin
        R := Wc.Controls[J].BoundsRect;
        InflateRect(R, D, D);
        if PtInRect(R, Pi) then
        begin
          sRev := TJvSimReverse(Wc.Controls[J]);
          // now check if P is the output area
          pl := sRev.Gates[1].Pos;
          R := Rect(sRev.Left + pl.X, sRev.Top - D, sRev.Left + pl.X + 12, sRev.Top + pl.Y + 12);
          if PtInRect(R, Pi) and sRev.Gates[1].Active then
          begin // output
            Vi := sRev.Output1;
            Exit;
          end;
          pl := sRev.Gates[2].Pos;
          R := Rect(sRev.Left - D, sRev.Top + pl.Y, sRev.Left + pl.X + 12, sRev.Top + pl.Y + 12);
          if PtInRect(R, Pi) and sRev.Gates[2].Active then
          begin // output
            Vi := sRev.Output2;
            Exit;
          end;
          pl := sRev.Gates[3].Pos;
          R := Rect(sRev.Left + pl.X, sRev.Top + pl.Y, sRev.Left + pl.X + 12, sRev.Top + sRev.Height + D);
          if PtInRect(R, Pi) and sRev.Gates[3].Active then
          begin // output
            Vi := sRev.Output3;
            Exit;
          end;
        end;
      end
      else
      if Wc.Controls[J] is TJvLogic then
      begin
        R := Wc.Controls[J].BoundsRect;
        InflateRect(R, D, 0);
        if PtInRect(R, Pi) then
        begin
          sLog := TJvLogic(Wc.Controls[J]);
          // now check if P is in one of the 3 output area's
          R := Rect(sLog.Left + 33, sLog.Top, sLog.Left + sLog.Width + FConSize, sLog.Top + 22);
          if PtInRect(R, Pi) and sLog.Gates[3].Active then
          begin // output is gate 3
            Vi := sLog.Output1;
            Exit;
          end;
          R := Rect(sLog.Left + 33, sLog.Top + 23, sLog.Left + sLog.Width + FConSize, sLog.Top + 44);
          if PtInRect(R, Pi) and sLog.Gates[4].Active then
          begin // output is gate 4
            Vi := sLog.Output2;
            Exit;
          end;
          R := Rect(sLog.Left + 33, sLog.Top + 45, sLog.Left + sLog.Width + FConSize, sLog.Top + 64);
          if PtInRect(R, Pi) and sLog.Gates[5].Active then
          begin // output is gate 5
            Vi := sLog.Output3;
            Exit;
          end;
        end;
      end;
    end;
    Result := False;
  end;

  procedure SetVo;
  var
    J: Integer;
  begin
    for J := 0 to Wc.ControlCount - 1 do
    begin
      if (Wc.Controls[J] is TJvSimLight) then
      begin
        R := Wc.Controls[J].BoundsRect;
        InflateRect(R, D, 0);
        if PtInRect(R, Po) then
        begin
          sLight := TJvSimLight(Wc.Controls[J]);
          sLight.Lit := Vi;
          Exit;
        end;
      end
      else
      if Wc.Controls[J] is TJvSimReverse then
      begin
        R := Wc.Controls[J].BoundsRect;
        InflateRect(R, D, 0);
        if PtInRect(R, Po) then
        begin
          sRev := TJvSimReverse(Wc.Controls[J]);
          // now check if P is in the input area
          pl := sRev.Gates[0].Pos;
          R := Rect(sRev.Left + pl.X, sRev.Top + pl.Y, sRev.Left + sRev.Width + D, sRev.Top + pl.Y + 12);
          if PtInRect(R, Po) and sRev.Gates[0].Active then
          begin // input
            sRev.Input1 := Vi;
            Exit;
          end;
        end;
      end
      else
      if Wc.Controls[J] is TJvLogic then
      begin
        R := Wc.Controls[J].BoundsRect;
        InflateRect(R, D, 0);
        if PtInRect(R, Po) then
        begin
          sLog := TJvLogic(Wc.Controls[J]);
          // now check if P is in one of the 3 input area's
          R := Rect(sLog.Left - D, sLog.Top, sLog.Left + 32, sLog.Top + 22);
          if PtInRect(R, Po) and sLog.Gates[0].Active then
          begin // input is gate 0
            sLog.Input1 := Vi;
            Exit;
          end;
          R := Rect(sLog.Left - D, sLog.Top + 23, sLog.Left + 32, sLog.Top + 44);
          if PtInRect(R, Po) and sLog.Gates[1].Active then
          begin // input is gate 1
            sLog.Input2 := Vi;
            Exit;
          end;
          R := Rect(sLog.Left - D, sLog.Top + 45, sLog.Left + 32, sLog.Top + 64);
          if PtInRect(R, Po) and sLog.Gates[2].Active then
          begin // input is gate 2
            sLog.Input3 := Vi;
            Exit;
          end;
        end;
      end;
    end;
  end;

begin
  // connect input and output using the FConPos
  d2 := FConSize div 2;
  D := FConSize;
  xw := Width - 1;
  yh := Height - 1;
  Wc := Parent;
  case FConPos of
    jcpTL:
      begin
        Pi := ParentPoint(d2, d2);
        Po := ParentPoint(xw - d2, yh - d2);
      end;
    jcpTR:
      begin
        Pi := ParentPoint(xw - d2, d2);
        Po := ParentPoint(d2, yh - d2);
      end;
    jcpBR:
      begin
        Pi := ParentPoint(xw - d2, yh - d2);
        Po := ParentPoint(d2, d2);
      end;
    jcpBL:
      begin
        Pi := ParentPoint(d2, yh - d2);
        Po := ParentPoint(xw - d2, d2);
      end;
  end;
  // get input Vi
  if GetVi then
    SetVo;
end;

procedure TJvSIMConnector.Disconnect;
var
  Pi, Po: TPoint;
  R: TRect;
  D, d2, xw, yh: Integer;
  Wc: TWinControl;
  sLog: TJvLogic;
  sLight: TJvSimLight;

  // convert a corner point to a Parent point

  function ParentPoint(X, Y: Integer): TPoint;
  var
    P: TPoint;
  begin
    P := Point(X, Y);
    P := ClientToScreen(P);
    Result := Wc.ScreenToClient(P);
  end;

  procedure SetVo;
  var
    J: Integer;
  begin
    for J := 0 to Wc.ControlCount - 1 do
    begin
      if Wc.Controls[J] is TJvSimLight then
      begin
        R := Wc.Controls[J].BoundsRect;
        InflateRect(R, D, 0);
        if PtInRect(R, Po) then
        begin
          sLight := TJvSimLight(Wc.Controls[J]);
          FDisCon := sLight;
          //sLight.Lit:=False;
          Exit;
        end;
      end
      else
      if Wc.Controls[J] is TJvLogic then
      begin
        R := Wc.Controls[J].BoundsRect;
        InflateRect(R, D, 0);
        if PtInRect(R, Po) then
        begin
          sLog := TJvLogic(Wc.Controls[J]);
          // now check if P is in one of the 3 input area's
          R := Rect(sLog.Left - D, sLog.Top, sLog.Left + 32, sLog.Top + 22);
          if PtInRect(R, Po) and sLog.Gates[0].Active then
          begin // input is gate 0
            FDisCon := sLog;
            FDisConI := 1;
            //            sLog.Input1:=False;
            Exit;
          end;
          R := Rect(sLog.Left - D, sLog.Top + 23, sLog.Left + 32, sLog.Top + 44);
          if PtInRect(R, Po) and sLog.Gates[1].Active then
          begin // input is gate 1
            FDisCon := sLog;
            FDisConI := 2;
            //            sLog.Input2:=False;
            Exit;
          end;
          R := Rect(sLog.Left - D, sLog.Top + 45, sLog.Left + 32, sLog.Top + 64);
          if PtInRect(R, Po) and sLog.Gates[2].Active then
          begin // input is gate 2
            FDisCon := sLog;
            FDisConI := 3;
            //            sLog.Input3:=False;
            Exit;
          end;
        end;
      end;
    end;
  end;

begin
  // connect input and output using the FConPos
  FDisCon := nil;
  FDisConI := 0;
  d2 := FConSize div 2;
  D := FConSize;
  xw := Width - 1;
  yh := Height - 1;
  Wc := Parent;
  case FConPos of
    jcpTL:
      begin
        Pi := ParentPoint(d2, d2);
        Po := ParentPoint(xw - d2, yh - d2);
      end;
    jcpTR:
      begin
        Pi := ParentPoint(xw - d2, d2);
        Po := ParentPoint(d2, yh - d2);
      end;
    jcpBR:
      begin
        Pi := ParentPoint(xw - d2, yh - d2);
        Po := ParentPoint(d2, d2);
      end;
    jcpBL:
      begin
        Pi := ParentPoint(d2, yh - d2);
        Po := ParentPoint(xw - d2, d2);
      end;
  end;
  // clear logic inputs and lights
  SetVo;
end;

//=== { TJvLogic } ===========================================================

constructor TJvLogic.Create(AOwner: TComponent);
var
  I: Integer;
begin
  inherited Create(AOwner);
  Width := 65;
  Height := 65;
  // initialize Gates
  FGates[0].Pos := Point(1, 10);
  FGates[1].Pos := Point(1, 28);
  FGates[2].Pos := Point(1, 46);
  FGates[3].Pos := Point(52, 10);
  FGates[4].Pos := Point(52, 28);
  FGates[5].Pos := Point(52, 46);
  for I := 0 to 5 do
    FGates[I].State := False;
  for I := 0 to 2 do
  begin
    FGates[I].Style := jgsDI;
    FGates[I + 3].Style := jgsDO;
  end;
  FLogicFunc := jlfAND;
  FGates[0].Active := True;
  FGates[1].Active := False;
  FGates[2].Active := True;
  FGates[3].Active := False;
  FGates[4].Active := True;
  FGates[5].Active := False;
  FConnectors := TList.Create;
end;

destructor TJvLogic.Destroy;
begin
  FConnectors.Free;
  inherited Destroy;
end;

function TJvLogic.GetGate(Index: Integer): TJvGate;
begin
  Result := FGates[Index];
end;

procedure TJvLogic.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
var
  R: TRect;
begin
  FDoMove := False;
  FDoStyle := False;
  FStyleDown := False;
  FMdp := Point(X, Y);
  R := ClientRect;
  InflateRect(R, -15, -15);
  FDoStyle := PtInRect(R, FMdp);
  FDoMove := not FDoStyle;
  FOldp := Point(X, Y);
  if FDoMove then
    AnchorConnectors;
  if FDoStyle then
  begin
    FStyleDown := True;
    Invalidate;
  end;
end;

procedure TJvLogic.MouseMove(Shift: TShiftState; X, Y: Integer);
var
  P: TPoint;
begin

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -