www.pudn.com > DelphiX_for7.zip > DXFFBEdit.pas


unit DXFFBEdit; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  StdCtrls, Spin, DXInput, TypInfo, ExtCtrls, Menus, ComCtrls; 
 
type 
  TDelphiXFFEditForm = class(TForm) 
    ListGroupBox: TGroupBox; 
    AddButton: TButton; 
    DelButton: TButton; 
    EditGroupBox: TGroupBox; 
    EffectTypeBox: TComboBox; 
    EffectTypeLabel: TLabel; 
    ConstantLabel: TLabel; 
    ConstantYEdit: TSpinEdit; 
    ConstantXEdit: TSpinEdit; 
    ConstantXLabel: TLabel; 
    ConstantYLabel: TLabel; 
    FadeTimeLabel: TLabel; 
    FadeTimeEdit: TSpinEdit; 
    PeriodLabel: TLabel; 
    PeriodEdit: TSpinEdit; 
    PeriodLabel2: TLabel; 
    PowerLabel: TLabel; 
    TimeLabel: TLabel; 
    TimeEdit: TSpinEdit; 
    TimeLabel2: TLabel; 
    AttackTimeEditLabel: TLabel; 
    AttackTimeEdit: TSpinEdit; 
    RunButton: TButton; 
    RunGroupButton: TButton; 
    OKButton: TButton; 
    CancelButton: TButton; 
    DXInput: TDXInput; 
    NameEditLabel: TLabel; 
    NameEdit: TEdit; 
    Bevel1: TBevel; 
    StopButton: TButton; 
    PopupMenu: TPopupMenu; 
    A1: TMenuItem; 
    DeleteEffectItem: TMenuItem; 
    PowerEdit: TSpinEdit; 
    Timer: TTimer; 
    Bevel2: TBevel; 
    N1: TMenuItem; 
    N2: TMenuItem; 
    SaveToFileItem: TMenuItem; 
    AddFromFileButton: TButton; 
    OpenDialog: TOpenDialog; 
    SaveDialog: TSaveDialog; 
    EffectView: TTreeView; 
    ConditionLabel: TLabel; 
    ConditionXLabel: TLabel; 
    ConditionXEdit: TSpinEdit; 
    ConditionYLabel: TLabel; 
    ConditionYEdit: TSpinEdit; 
    Label1: TLabel; 
    Label2: TLabel; 
    AttackLevelEdit: TSpinEdit; 
    FadeLevelEdit: TSpinEdit; 
    Label3: TLabel; 
    Label4: TLabel; 
    Label5: TLabel; 
    Label6: TLabel; 
    procedure OKButtonClick(Sender: TObject); 
    procedure CancelButtonClick(Sender: TObject); 
    procedure EffectViewChange(Sender: TObject; Node: TTreeNode); 
    procedure FormShow(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    procedure AddButtonClick(Sender: TObject); 
    procedure DelButtonClick(Sender: TObject); 
    procedure RunButtonClick(Sender: TObject); 
    procedure RunGroupButtonClick(Sender: TObject); 
    procedure StopButtonClick(Sender: TObject); 
    procedure ChangeEvent(Sender: TObject); 
    procedure TimerTimer(Sender: TObject); 
    procedure NameEditChange(Sender: TObject); 
    procedure EffectViewDragDrop(Sender, Source: TObject; X, Y: Integer); 
    procedure EffectViewDragOver(Sender, Source: TObject; X, Y: Integer; 
      State: TDragState; var Accept: Boolean); 
    procedure AddFromFileButtonClick(Sender: TObject); 
    procedure SaveToFileItemClick(Sender: TObject); 
    procedure EffectViewEdited(Sender: TObject; Node: TTreeNode; 
      var S: String); 
    procedure EffectTypeBoxChange(Sender: TObject); 
  private 
    FChanged: Boolean; 
    FSelectEffect: TForceFeedbackEffect; 
    FOldStates: TDXInputStates; 
    FUpdating: Boolean; 
    function AddTree(Parent: TTreeNode; Effect: TForceFeedbackEffect): TTreeNode; 
    procedure Save; 
  public 
    Effects: TForceFeedbackEffects; 
  end; 
 
var 
  DelphiXFFEditForm: TDelphiXFFEditForm; 
 
implementation 
 
uses DXConsts; 
 
{$R *.DFM} 
 
procedure TDelphiXFFEditForm.FormCreate(Sender: TObject); 
var 
  e: TForceFeedbackEffectType; 
  s: string; 
begin 
  for e:=Low(e) to High(e) do 
  begin 
    if e=etNone then 
      s := SNone 
    else 
      s := GetEnumName(TypeInfo(TForceFeedbackEffectType), Integer(e)); 
 
    EffectTypeBox.Items.Add(s); 
  end; 
end; 
 
function TDelphiXFFEditForm.AddTree(Parent: TTreeNode; Effect: TForceFeedbackEffect): TTreeNode; 
var 
  i: Integer; 
begin 
  Result := EffectView.Items.AddChildObject(Parent, Effect.Name, Effect); 
  for i:=0 to Effect.Count-1 do 
    AddTree(Result, Effect.Effects[i]); 
end; 
 
procedure TDelphiXFFEditForm.Save; 
begin 
  if FChanged then EffectViewChange(nil, nil); 
end; 
 
procedure TDelphiXFFEditForm.FormShow(Sender: TObject); 
begin 
  Caption := Format(SFFBEffectEditor, [Effects.Input.ClassName]); 
 
  Effects.Input.Enabled := True; 
 
  EffectView.Selected := AddTree(nil, Effects); 
  if EffectView.Selected<>nil then 
    EffectView.Selected.Expanded := True; 
end; 
 
procedure TDelphiXFFEditForm.OKButtonClick(Sender: TObject); 
begin 
  Save; 
  Tag := 1; 
  Close; 
end; 
 
procedure TDelphiXFFEditForm.CancelButtonClick(Sender: TObject); 
begin 
  Close; 
end; 
 
procedure SetControlEnabled(Control: TControl; Value: Boolean); 
var 
  NewColor: TColor; 
begin 
  Control.Enabled := Value; 
 
  if Value then NewColor := clWindow else NewColor := clBtnFace; 
 
  if Control is TComboBox then TComboBox(Control).Color := NewColor; 
  if Control is TSpinEdit then TSpinEdit(Control).Color := NewColor; 
  if Control is TEdit then TEdit(Control).Color := NewColor; 
end; 
 
procedure TDelphiXFFEditForm.EffectViewChange(Sender: TObject; Node: TTreeNode); 
var 
  i: Integer; 
  Control: TControl; 
begin 
  StopButtonClick(nil); 
 
  FUpdating := True; 
  try 
    if FSelectEffect<>nil then 
    begin 
      if FChanged then 
      begin 
        with FSelectEffect do 
        begin 
          Name := NameEdit.Text; 
 
          EffectType := etNone; 
 
          Power := PowerEdit.Value; 
          Time := TimeEdit.Value; 
          AttackTime := AttackTimeEdit.Value; 
          AttackLevel := AttackLevelEdit.Value; 
          FadeTime := FadeTimeEdit.Value; 
          FadeLevel := FadeLevelEdit.Value; 
          Constant := Point(ConstantXEdit.Value, ConstantYEdit.Value); 
          Period := PeriodEdit.Value; 
          Condition := Point(ConditionXEdit.Value, ConditionYEdit.Value); 
 
          EffectType := TForceFeedbackEffectType(EffectTypeBox.ItemIndex); 
        end; 
      end; 
    end; 
 
    FSelectEffect := nil; 
    if (EffectView.Selected<>nil) and (EffectView.Selected.Data<>nil) then 
      FSelectEffect := EffectView.Selected.Data; 
 
    DelButton.Enabled := (FSelectEffect<>nil) and (FSelectEffect.Parent<>nil); 
    DeleteEffectItem.Enabled := DelButton.Enabled; 
    SaveToFileItem.Enabled := FSelectEffect<>nil; 
 
    if FSelectEffect<>nil then 
    begin 
      for i:=0 to ComponentCount-1 do 
        if (Components[i] is TControl) then 
        begin 
          Control := TControl(Components[i]); 
          if Control.Parent=EditGroupBox then 
            SetControlEnabled(Control, True); 
        end; 
    end else 
    begin 
      for i:=0 to ComponentCount-1 do 
        if (Components[i] is TControl) then 
        begin 
          Control := TControl(Components[i]); 
          if Control.Parent=EditGroupBox then 
          begin 
            SetControlEnabled(Control, False); 
            if Control is TEdit then 
              TEdit(Control).Text := '' 
            else if Control is TSpinEdit then 
              TSpinEdit(Control).Value := 0 
            else if Control is TComboBox then 
              TComboBox(Control).ItemIndex := 0 
            else if Control is TCheckBox then 
              TCheckBox(Control).Checked := False; 
          end; 
        end; 
    end; 
 
    if FSelectEffect<>nil then 
    begin 
      with FSelectEffect do 
      begin 
        NameEdit.Text := Name; 
 
        EffectTypeBox.ItemIndex := Integer(EffectType); 
 
        PowerEdit.Value := Power; 
        TimeEdit.Value := Time; 
 
        AttackTimeEdit.Value := AttackTime; 
        AttackLevelEdit.Value := AttackLevel; 
 
        FadeTimeEdit.Value := FadeTime; 
        FadeLevelEdit.Value := FadeLevel; 
 
        ConstantXEdit.Value := Constant.X; 
        ConstantYEdit.Value := Constant.Y; 
 
        PeriodEdit.Value := Period; 
 
        ConditionXEdit.Value := Condition.X; 
        ConditionYEdit.Value := Condition.Y; 
      end; 
 
      EffectTypeBoxChange(nil); 
    end; 
  finally 
    FUpdating := False; 
  end; 
 
  FChanged := False; 
  FOldStates := []; 
end; 
 
procedure TDelphiXFFEditForm.AddButtonClick(Sender: TObject); 
var 
  Effect: TForceFeedbackEffect; 
  OwnerEffect: TForceFeedbackEffect; 
  i, j: Integer; 
  Flag: Boolean; 
begin 
  if FSelectEffect<>nil then 
    OwnerEffect := FSelectEffect 
  else 
    OwnerEffect := Effects; 
 
  {  Unique name making  } 
  j := 0; 
  repeat 
    Flag := True; 
    Inc(j); 
    for i:=0 to OwnerEffect.Count-1 do 
      if AnsiCompareText(OwnerEffect[i].Name, Format('Effect%d', [j]))=0 then 
      begin 
        Flag := False; 
        Break; 
      end; 
  until Flag; 
 
  {  Effect making  } 
  Effect := TForceFeedbackEffect.Create(OwnerEffect); 
  Effect.Name := Format('Effect%d', [j]); 
 
  EffectView.Selected := AddTree(EffectView.Selected, Effect); 
end; 
 
procedure TDelphiXFFEditForm.DelButtonClick(Sender: TObject); 
begin 
  FSelectEffect.Free; 
  FSelectEffect := nil; 
 
  EffectView.Selected.Delete; 
end; 
 
procedure TDelphiXFFEditForm.RunButtonClick(Sender: TObject); 
begin 
  if not RunButton.Enabled then Exit; 
 
  Save; 
 
  if not DXInput.UseDirectInput then 
  begin 
    Screen.Cursor := crHourGlass; 
    try 
      DXInput.UseDirectInput := True; 
    finally 
      Screen.Cursor := crDefault; 
    end; 
  end; 
 
  FSelectEffect.Start; 
end; 
 
procedure TDelphiXFFEditForm.RunGroupButtonClick(Sender: TObject); 
var 
  Effect: TForceFeedbackEffect; 
begin 
  if not RunGroupButton.Enabled then Exit; 
 
  Save; 
 
  if not DXInput.UseDirectInput then 
  begin 
    Screen.Cursor := crHourGlass; 
    try 
      DXInput.UseDirectInput := True; 
    finally 
      Screen.Cursor := crDefault; 
    end; 
  end; 
 
  Effect := FSelectEffect; 
  while (Effect.Parent<>nil) and (Effect.Parent.Parent<>nil) do 
    Effect := Effect.Parent; 
 
  Effect.Start; 
end; 
 
procedure TDelphiXFFEditForm.StopButtonClick(Sender: TObject); 
begin 
  Effects.Stop; 
  Effects.UnLoad(True); 
end; 
 
procedure TDelphiXFFEditForm.ChangeEvent(Sender: TObject); 
begin 
  if not FUpdating then FChanged := True; 
end; 
 
procedure TDelphiXFFEditForm.TimerTimer(Sender: TObject); 
var 
  s: TDXInputStates; 
begin 
  if not (Effects.Input is TKeyboard) then 
  begin 
    Effects.Input.Update; 
    s := Effects.Input.States; 
 
    if (isButton1 in s) and (not (isButton1 in FOldStates)) then 
      RunGroupButtonClick(nil) 
    else if (isButton2 in s) and (not (isButton2 in FOldStates)) then 
      RunButtonClick(nil) 
    else if (s*[isButton1, isButton2]=[]) and (FOldStates*[isButton1, isButton2]<>[]) then 
      StopButtonClick(nil); 
 
    FOldStates := s; 
  end; 
end; 
 
procedure TDelphiXFFEditForm.NameEditChange(Sender: TObject); 
begin 
  if not FUpdating then 
    if EffectView.Selected<>nil then 
    begin 
      EffectView.Selected.Text := NameEdit.Text; 
      FSelectEffect.Name := NameEdit.Text; 
    end; 
end; 
 
procedure TDelphiXFFEditForm.EffectViewDragOver(Sender, Source: TObject; X, 
  Y: Integer; State: TDragState; var Accept: Boolean); 
var 
  Node: TTreeNode; 
begin 
  Accept := False; 
 
  Node := EffectView.GetNodeAt(X, Y); 
  if Node=nil then Exit; 
 
  if Node=EffectView.Items.GetFirstNode then Exit; 
 
  while Node<>nil do 
  begin 
    if Node=EffectView.Selected then 
      Exit; 
    Node := Node.Parent; 
  end; 
 
  Accept := True; 
end; 
 
procedure TDelphiXFFEditForm.EffectViewDragDrop(Sender, Source: TObject; X, 
  Y: Integer); 
var 
  Node, Node2: TTreeNode; 
  Effect: TForceFeedbackEffect; 
begin 
  Save; 
 
  Node := EffectView.GetNodeAt(X, Y); 
 
  if Node<>nil then 
  begin 
    Effect := TObject(EffectView.Selected.Data) as TForceFeedbackEffect; 
 
    Node2 := EffectView.Selected; 
 
    if X>Node.DisplayRect(True).Right+10 then 
    begin 
      {  Effect is moved to the child.  } 
      Effect.Parent := TObject(Node.Data) as TForceFeedbackEffect; 
      EffectView.Selected.MoveTo(Node, naAddChild); 
      Effect.Index := EffectView.Selected.Index; 
    end else 
    begin 
      {  Effect is moved to the brother.  } 
      Effect.Parent := (TObject(Node.Data) as TForceFeedbackEffect).Parent; 
      EffectView.Selected.MoveTo(Node, naInsert); 
      Effect.Index := EffectView.Selected.Index; 
    end; 
 
    EffectView.Selected := Node2; 
 
    EffectView.Invalidate; 
  end; 
end; 
 
procedure TDelphiXFFEditForm.AddFromFileButtonClick(Sender: TObject); 
var 
  i: Integer; 
  Effect: TForceFeedbackEffect; 
begin 
  if not OpenDialog.Execute then Exit; 
 
  Save; 
 
  for i:=0 to OpenDialog.Files.Count-1 do 
  begin 
    Effect := TForceFeedbackEffect.Create(Effects); 
    try 
      Effect.LoadFromFile(OpenDialog.Files[i]); 
    except 
      Effect.Free; 
      raise; 
    end; 
 
    EffectView.Selected := AddTree(EffectView.Items.GetFirstNode, Effect); 
  end; 
end; 
 
procedure TDelphiXFFEditForm.SaveToFileItemClick(Sender: TObject); 
begin 
  SaveDialog.FileName := FSelectEffect.Name+'.ffe'; 
 
  if not SaveDialog.Execute then Exit; 
 
  Save; 
 
  FSelectEffect.SaveToFile(SaveDialog.FileName); 
end; 
 
procedure TDelphiXFFEditForm.EffectViewEdited(Sender: TObject; 
  Node: TTreeNode; var S: String); 
begin 
  NameEdit.Text := s; 
end; 
 
procedure TDelphiXFFEditForm.EffectTypeBoxChange(Sender: TObject); 
var 
  EffectType: TForceFeedbackEffectType; 
begin 
  ChangeEvent(Sender); 
 
  EffectType := TForceFeedbackEffectType(EffectTypeBox.ItemIndex); 
 
  SetControlEnabled(PowerEdit, EffectType<>etNone); 
  SetControlEnabled(TimeEdit, EffectType<>etNone); 
 
  SetControlEnabled(AttackTimeEdit, EffectType<>etNone); 
  SetControlEnabled(AttackLevelEdit, EffectType<>etNone); 
 
  SetControlEnabled(FadeTimeEdit, EffectType<>etNone); 
  SetControlEnabled(FadeLevelEdit, EffectType<>etNone); 
 
  SetControlEnabled(ConstantXEdit, EffectType in [etConstantForce, etPeriodic, etCondition]); 
  SetControlEnabled(ConstantYEdit, EffectType in [etConstantForce, etPeriodic, etCondition]); 
 
  SetControlEnabled(PeriodEdit, EffectType in [etPeriodic]); 
 
  SetControlEnabled(ConditionXEdit, EffectType in [etCondition]); 
  SetControlEnabled(ConditionYEdit, EffectType in [etCondition]); 
end; 
 
end.