Subversion Repositories spacemission

Rev

Blame | Last modification | View Log | RSS feed

  1. unit DXFFBEdit;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  7.   StdCtrls, Spin, DXInput, TypInfo, ExtCtrls, Menus, ComCtrls;
  8.  
  9. type
  10.   TDelphiXFFEditForm = class(TForm)
  11.     ListGroupBox: TGroupBox;
  12.     AddButton: TButton;
  13.     DelButton: TButton;
  14.     EditGroupBox: TGroupBox;
  15.     EffectTypeBox: TComboBox;
  16.     EffectTypeLabel: TLabel;
  17.     ConstantLabel: TLabel;
  18.     ConstantYEdit: TSpinEdit;
  19.     ConstantXEdit: TSpinEdit;
  20.     ConstantXLabel: TLabel;
  21.     ConstantYLabel: TLabel;
  22.     FadeTimeLabel: TLabel;
  23.     FadeTimeEdit: TSpinEdit;
  24.     PeriodLabel: TLabel;
  25.     PeriodEdit: TSpinEdit;
  26.     PeriodLabel2: TLabel;
  27.     PowerLabel: TLabel;
  28.     TimeLabel: TLabel;
  29.     TimeEdit: TSpinEdit;
  30.     TimeLabel2: TLabel;
  31.     AttackTimeEditLabel: TLabel;
  32.     AttackTimeEdit: TSpinEdit;
  33.     RunButton: TButton;
  34.     RunGroupButton: TButton;
  35.     OKButton: TButton;
  36.     CancelButton: TButton;
  37.     DXInput: TDXInput;
  38.     NameEditLabel: TLabel;
  39.     NameEdit: TEdit;
  40.     Bevel1: TBevel;
  41.     StopButton: TButton;
  42.     PopupMenu: TPopupMenu;
  43.     A1: TMenuItem;
  44.     DeleteEffectItem: TMenuItem;
  45.     PowerEdit: TSpinEdit;
  46.     Timer: TTimer;
  47.     Bevel2: TBevel;
  48.     N1: TMenuItem;
  49.     N2: TMenuItem;
  50.     SaveToFileItem: TMenuItem;
  51.     AddFromFileButton: TButton;
  52.     OpenDialog: TOpenDialog;
  53.     SaveDialog: TSaveDialog;
  54.     EffectView: TTreeView;
  55.     ConditionLabel: TLabel;
  56.     ConditionXLabel: TLabel;
  57.     ConditionXEdit: TSpinEdit;
  58.     ConditionYLabel: TLabel;
  59.     ConditionYEdit: TSpinEdit;
  60.     Label1: TLabel;
  61.     Label2: TLabel;
  62.     AttackLevelEdit: TSpinEdit;
  63.     FadeLevelEdit: TSpinEdit;
  64.     Label3: TLabel;
  65.     Label4: TLabel;
  66.     Label5: TLabel;
  67.     Label6: TLabel;
  68.     procedure OKButtonClick(Sender: TObject);
  69.     procedure CancelButtonClick(Sender: TObject);
  70.     procedure EffectViewChange(Sender: TObject; Node: TTreeNode);
  71.     procedure FormShow(Sender: TObject);
  72.     procedure FormCreate(Sender: TObject);
  73.     procedure AddButtonClick(Sender: TObject);
  74.     procedure DelButtonClick(Sender: TObject);
  75.     procedure RunButtonClick(Sender: TObject);
  76.     procedure RunGroupButtonClick(Sender: TObject);
  77.     procedure StopButtonClick(Sender: TObject);
  78.     procedure ChangeEvent(Sender: TObject);
  79.     procedure TimerTimer(Sender: TObject);
  80.     procedure NameEditChange(Sender: TObject);
  81.     procedure EffectViewDragDrop(Sender, Source: TObject; X, Y: Integer);
  82.     procedure EffectViewDragOver(Sender, Source: TObject; X, Y: Integer;
  83.       State: TDragState; var Accept: Boolean);
  84.     procedure AddFromFileButtonClick(Sender: TObject);
  85.     procedure SaveToFileItemClick(Sender: TObject);
  86.     procedure EffectViewEdited(Sender: TObject; Node: TTreeNode;
  87.       var S: String);
  88.     procedure EffectTypeBoxChange(Sender: TObject);
  89.   private
  90.     FChanged: Boolean;
  91.     FSelectEffect: TForceFeedbackEffect;
  92.     FOldStates: TDXInputStates;
  93.     FUpdating: Boolean;
  94.     function AddTree(Parent: TTreeNode; Effect: TForceFeedbackEffect): TTreeNode;
  95.     procedure Save;
  96.   public
  97.     Effects: TForceFeedbackEffects;
  98.   end;
  99.  
  100. var
  101.   DelphiXFFEditForm: TDelphiXFFEditForm;
  102.  
  103. implementation
  104.  
  105. uses DXConsts;
  106.  
  107. {$R *.DFM}
  108.  
  109. procedure TDelphiXFFEditForm.FormCreate(Sender: TObject);
  110. var
  111.   e: TForceFeedbackEffectType;
  112.   s: string;
  113. begin
  114.   for e:=Low(e) to High(e) do
  115.   begin
  116.     if e=etNone then
  117.       s := SNone
  118.     else
  119.       s := GetEnumName(TypeInfo(TForceFeedbackEffectType), Integer(e));
  120.  
  121.     EffectTypeBox.Items.Add(s);
  122.   end;
  123. end;
  124.  
  125. function TDelphiXFFEditForm.AddTree(Parent: TTreeNode; Effect: TForceFeedbackEffect): TTreeNode;
  126. var
  127.   i: Integer;
  128. begin
  129.   Result := EffectView.Items.AddChildObject(Parent, Effect.Name, Effect);
  130.   for i:=0 to Effect.Count-1 do
  131.     AddTree(Result, Effect.Effects[i]);
  132. end;
  133.  
  134. procedure TDelphiXFFEditForm.Save;
  135. begin
  136.   if FChanged then EffectViewChange(nil, nil);
  137. end;
  138.  
  139. procedure TDelphiXFFEditForm.FormShow(Sender: TObject);
  140. begin
  141.   Caption := Format(SFFBEffectEditor, [Effects.Input.ClassName]);
  142.  
  143.   Effects.Input.Enabled := True;
  144.  
  145.   EffectView.Selected := AddTree(nil, Effects);
  146.   if EffectView.Selected<>nil then
  147.     EffectView.Selected.Expanded := True;
  148. end;
  149.  
  150. procedure TDelphiXFFEditForm.OKButtonClick(Sender: TObject);
  151. begin
  152.   Save;
  153.   Tag := 1;
  154.   Close;
  155. end;
  156.  
  157. procedure TDelphiXFFEditForm.CancelButtonClick(Sender: TObject);
  158. begin
  159.   Close;
  160. end;
  161.  
  162. procedure SetControlEnabled(Control: TControl; Value: Boolean);
  163. var
  164.   NewColor: TColor;
  165. begin
  166.   Control.Enabled := Value;
  167.  
  168.   if Value then NewColor := clWindow else NewColor := clBtnFace;
  169.  
  170.   if Control is TComboBox then TComboBox(Control).Color := NewColor;
  171.   if Control is TSpinEdit then TSpinEdit(Control).Color := NewColor;
  172.   if Control is TEdit then TEdit(Control).Color := NewColor;
  173. end;
  174.  
  175. procedure TDelphiXFFEditForm.EffectViewChange(Sender: TObject; Node: TTreeNode);
  176. var
  177.   i: Integer;
  178.   Control: TControl;
  179. begin
  180.   StopButtonClick(nil);
  181.  
  182.   FUpdating := True;
  183.   try
  184.     if FSelectEffect<>nil then
  185.     begin
  186.       if FChanged then
  187.       begin
  188.         with FSelectEffect do
  189.         begin
  190.           Name := NameEdit.Text;
  191.  
  192.           EffectType := etNone;
  193.  
  194.           Power := PowerEdit.Value;
  195.           Time := TimeEdit.Value;
  196.           AttackTime := AttackTimeEdit.Value;
  197.           AttackLevel := AttackLevelEdit.Value;
  198.           FadeTime := FadeTimeEdit.Value;
  199.           FadeLevel := FadeLevelEdit.Value;
  200.           Constant := Point(ConstantXEdit.Value, ConstantYEdit.Value);
  201.           Period := PeriodEdit.Value;
  202.           Condition := Point(ConditionXEdit.Value, ConditionYEdit.Value);
  203.  
  204.           EffectType := TForceFeedbackEffectType(EffectTypeBox.ItemIndex);
  205.         end;
  206.       end;
  207.     end;
  208.  
  209.     FSelectEffect := nil;
  210.     if (EffectView.Selected<>nil) and (EffectView.Selected.Data<>nil) then
  211.       FSelectEffect := EffectView.Selected.Data;
  212.  
  213.     DelButton.Enabled := (FSelectEffect<>nil) and (FSelectEffect.Parent<>nil);
  214.     DeleteEffectItem.Enabled := DelButton.Enabled;
  215.     SaveToFileItem.Enabled := FSelectEffect<>nil;
  216.  
  217.     if FSelectEffect<>nil then
  218.     begin
  219.       for i:=0 to ComponentCount-1 do
  220.         if (Components[i] is TControl) then
  221.         begin
  222.           Control := TControl(Components[i]);
  223.           if Control.Parent=EditGroupBox then
  224.             SetControlEnabled(Control, True);
  225.         end;
  226.     end else
  227.     begin
  228.       for i:=0 to ComponentCount-1 do
  229.         if (Components[i] is TControl) then
  230.         begin
  231.           Control := TControl(Components[i]);
  232.           if Control.Parent=EditGroupBox then
  233.           begin
  234.             SetControlEnabled(Control, False);
  235.             if Control is TEdit then
  236.               TEdit(Control).Text := ''
  237.             else if Control is TSpinEdit then
  238.               TSpinEdit(Control).Value := 0
  239.             else if Control is TComboBox then
  240.               TComboBox(Control).ItemIndex := 0
  241.             else if Control is TCheckBox then
  242.               TCheckBox(Control).Checked := False;
  243.           end;
  244.         end;
  245.     end;
  246.  
  247.     if FSelectEffect<>nil then
  248.     begin
  249.       with FSelectEffect do
  250.       begin
  251.         NameEdit.Text := Name;
  252.  
  253.         EffectTypeBox.ItemIndex := Integer(EffectType);
  254.  
  255.         PowerEdit.Value := Power;
  256.         TimeEdit.Value := Time;
  257.  
  258.         AttackTimeEdit.Value := AttackTime;
  259.         AttackLevelEdit.Value := AttackLevel;
  260.  
  261.         FadeTimeEdit.Value := FadeTime;
  262.         FadeLevelEdit.Value := FadeLevel;
  263.  
  264.         ConstantXEdit.Value := Constant.X;
  265.         ConstantYEdit.Value := Constant.Y;
  266.  
  267.         PeriodEdit.Value := Period;
  268.  
  269.         ConditionXEdit.Value := Condition.X;
  270.         ConditionYEdit.Value := Condition.Y;
  271.       end;
  272.  
  273.       EffectTypeBoxChange(nil);
  274.     end;
  275.   finally
  276.     FUpdating := False;
  277.   end;
  278.  
  279.   FChanged := False;
  280.   FOldStates := [];
  281. end;
  282.  
  283. procedure TDelphiXFFEditForm.AddButtonClick(Sender: TObject);
  284. var
  285.   Effect: TForceFeedbackEffect;
  286.   OwnerEffect: TForceFeedbackEffect;
  287.   i, j: Integer;
  288.   Flag: Boolean;
  289. begin
  290.   if FSelectEffect<>nil then
  291.     OwnerEffect := FSelectEffect
  292.   else
  293.     OwnerEffect := Effects;
  294.  
  295.   {  Unique name making  }
  296.   j := 0;
  297.   repeat
  298.     Flag := True;
  299.     Inc(j);
  300.     for i:=0 to OwnerEffect.Count-1 do
  301.       if AnsiCompareText(OwnerEffect[i].Name, Format('Effect%d', [j]))=0 then
  302.       begin
  303.         Flag := False;
  304.         Break;
  305.       end;
  306.   until Flag;
  307.  
  308.   {  Effect making  }
  309.   Effect := TForceFeedbackEffect.Create(OwnerEffect);
  310.   Effect.Name := Format('Effect%d', [j]);
  311.  
  312.   EffectView.Selected := AddTree(EffectView.Selected, Effect);
  313. end;
  314.  
  315. procedure TDelphiXFFEditForm.DelButtonClick(Sender: TObject);
  316. begin
  317.   FSelectEffect.Free;
  318.   FSelectEffect := nil;
  319.  
  320.   EffectView.Selected.Delete;
  321. end;
  322.  
  323. procedure TDelphiXFFEditForm.RunButtonClick(Sender: TObject);
  324. begin
  325.   if not RunButton.Enabled then Exit;
  326.  
  327.   Save;
  328.  
  329.   if not DXInput.UseDirectInput then
  330.   begin
  331.     Screen.Cursor := crHourGlass;
  332.     try
  333.       DXInput.UseDirectInput := True;
  334.     finally
  335.       Screen.Cursor := crDefault;
  336.     end;
  337.   end;
  338.  
  339.   FSelectEffect.Start;
  340. end;
  341.  
  342. procedure TDelphiXFFEditForm.RunGroupButtonClick(Sender: TObject);
  343. var
  344.   Effect: TForceFeedbackEffect;
  345. begin
  346.   if not RunGroupButton.Enabled then Exit;
  347.  
  348.   Save;
  349.  
  350.   if not DXInput.UseDirectInput then
  351.   begin
  352.     Screen.Cursor := crHourGlass;
  353.     try
  354.       DXInput.UseDirectInput := True;
  355.     finally
  356.       Screen.Cursor := crDefault;
  357.     end;
  358.   end;
  359.  
  360.   Effect := FSelectEffect;
  361.   while (Effect.Parent<>nil) and (Effect.Parent.Parent<>nil) do
  362.     Effect := Effect.Parent;
  363.  
  364.   Effect.Start;
  365. end;
  366.  
  367. procedure TDelphiXFFEditForm.StopButtonClick(Sender: TObject);
  368. begin
  369.   Effects.Stop;
  370.   Effects.UnLoad(True);
  371. end;
  372.  
  373. procedure TDelphiXFFEditForm.ChangeEvent(Sender: TObject);
  374. begin
  375.   if not FUpdating then FChanged := True;
  376. end;
  377.  
  378. procedure TDelphiXFFEditForm.TimerTimer(Sender: TObject);
  379. var
  380.   s: TDXInputStates;
  381. begin
  382.   if not (Effects.Input is TKeyboard) then
  383.   begin
  384.     Effects.Input.Update;
  385.     s := Effects.Input.States;
  386.  
  387.     if (isButton1 in s) and (not (isButton1 in FOldStates)) then
  388.       RunGroupButtonClick(nil)
  389.     else if (isButton2 in s) and (not (isButton2 in FOldStates)) then
  390.       RunButtonClick(nil)
  391.     else if (s*[isButton1, isButton2]=[]) and (FOldStates*[isButton1, isButton2]<>[]) then
  392.       StopButtonClick(nil);
  393.  
  394.     FOldStates := s;
  395.   end;
  396. end;
  397.  
  398. procedure TDelphiXFFEditForm.NameEditChange(Sender: TObject);
  399. begin
  400.   if not FUpdating then
  401.     if EffectView.Selected<>nil then
  402.     begin
  403.       EffectView.Selected.Text := NameEdit.Text;
  404.       FSelectEffect.Name := NameEdit.Text;
  405.     end;
  406. end;
  407.  
  408. procedure TDelphiXFFEditForm.EffectViewDragOver(Sender, Source: TObject; X,
  409.   Y: Integer; State: TDragState; var Accept: Boolean);
  410. var
  411.   Node: TTreeNode;
  412. begin
  413.   Accept := False;
  414.  
  415.   Node := EffectView.GetNodeAt(X, Y);
  416.   if Node=nil then Exit;
  417.  
  418.   if Node=EffectView.Items.GetFirstNode then Exit;
  419.  
  420.   while Node<>nil do
  421.   begin
  422.     if Node=EffectView.Selected then
  423.       Exit;
  424.     Node := Node.Parent;
  425.   end;
  426.  
  427.   Accept := True;
  428. end;
  429.  
  430. procedure TDelphiXFFEditForm.EffectViewDragDrop(Sender, Source: TObject; X,
  431.   Y: Integer);
  432. var
  433.   Node, Node2: TTreeNode;
  434.   Effect: TForceFeedbackEffect;
  435. begin
  436.   Save;
  437.  
  438.   Node := EffectView.GetNodeAt(X, Y);
  439.  
  440.   if Node<>nil then
  441.   begin
  442.     Effect := TObject(EffectView.Selected.Data) as TForceFeedbackEffect;
  443.  
  444.     Node2 := EffectView.Selected;
  445.  
  446.     if X>Node.DisplayRect(True).Right+10 then
  447.     begin
  448.       {  Effect is moved to the child.  }
  449.       Effect.Parent := TObject(Node.Data) as TForceFeedbackEffect;
  450.       EffectView.Selected.MoveTo(Node, naAddChild);
  451.       Effect.Index := EffectView.Selected.Index;
  452.     end else
  453.     begin
  454.       {  Effect is moved to the brother.  }
  455.       Effect.Parent := (TObject(Node.Data) as TForceFeedbackEffect).Parent;
  456.       EffectView.Selected.MoveTo(Node, naInsert);
  457.       Effect.Index := EffectView.Selected.Index;
  458.     end;
  459.  
  460.     EffectView.Selected := Node2;
  461.  
  462.     EffectView.Invalidate;
  463.   end;
  464. end;
  465.  
  466. procedure TDelphiXFFEditForm.AddFromFileButtonClick(Sender: TObject);
  467. var
  468.   i: Integer;
  469.   Effect: TForceFeedbackEffect;
  470. begin
  471.   if not OpenDialog.Execute then Exit;
  472.  
  473.   Save;
  474.  
  475.   for i:=0 to OpenDialog.Files.Count-1 do
  476.   begin
  477.     Effect := TForceFeedbackEffect.Create(Effects);
  478.     try
  479.       Effect.LoadFromFile(OpenDialog.Files[i]);
  480.     except
  481.       Effect.Free;
  482.       raise;
  483.     end;
  484.  
  485.     EffectView.Selected := AddTree(EffectView.Items.GetFirstNode, Effect);
  486.   end;
  487. end;
  488.  
  489. procedure TDelphiXFFEditForm.SaveToFileItemClick(Sender: TObject);
  490. begin
  491.   SaveDialog.FileName := FSelectEffect.Name+'.ffe';
  492.  
  493.   if not SaveDialog.Execute then Exit;
  494.  
  495.   Save;
  496.  
  497.   FSelectEffect.SaveToFile(SaveDialog.FileName);
  498. end;
  499.  
  500. procedure TDelphiXFFEditForm.EffectViewEdited(Sender: TObject;
  501.   Node: TTreeNode; var S: String);
  502. begin
  503.   NameEdit.Text := s;
  504. end;
  505.  
  506. procedure TDelphiXFFEditForm.EffectTypeBoxChange(Sender: TObject);
  507. var
  508.   EffectType: TForceFeedbackEffectType;
  509. begin
  510.   ChangeEvent(Sender);
  511.  
  512.   EffectType := TForceFeedbackEffectType(EffectTypeBox.ItemIndex);
  513.  
  514.   SetControlEnabled(PowerEdit, EffectType<>etNone);
  515.   SetControlEnabled(TimeEdit, EffectType<>etNone);
  516.  
  517.   SetControlEnabled(AttackTimeEdit, EffectType<>etNone);
  518.   SetControlEnabled(AttackLevelEdit, EffectType<>etNone);
  519.  
  520.   SetControlEnabled(FadeTimeEdit, EffectType<>etNone);
  521.   SetControlEnabled(FadeLevelEdit, EffectType<>etNone);
  522.  
  523.   SetControlEnabled(ConstantXEdit, EffectType in [etConstantForce, etPeriodic, etCondition]);
  524.   SetControlEnabled(ConstantYEdit, EffectType in [etConstantForce, etPeriodic, etCondition]);
  525.  
  526.   SetControlEnabled(PeriodEdit, EffectType in [etPeriodic]);
  527.  
  528.   SetControlEnabled(ConditionXEdit, EffectType in [etCondition]);
  529.   SetControlEnabled(ConditionYEdit, EffectType in [etCondition]);
  530. end;
  531.  
  532. end.
  533.