Subversion Repositories spacemission

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 daniel-mar 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.