LZScene

Форк
0
/
FGLSceneEdit.pas 
1514 строк · 44.5 Кб
1
//
2
// This unit is part of the GLScene Engine https://github.com/glscene
3
//
4
{
5
   Scene Editor, for adding + removing scene objects within the Delphi IDE.
6

7
   History :  
8
   05/02/00 - EG - Fixed DragDrop, added root nodes auto-expansion
9
   
10
}
11
unit FGLSceneEdit;
12

13
interface
14

15
{$I GLScene.inc}
16

17
uses
18
  lresources,
19
  lclintf,
20
  {$IFDEF MSWINDOWS}
21
  Registry,
22
  {$ENDIF}
23
  Classes, 
24
  SysUtils,
25
  Controls, 
26
  Forms, 
27
  ComCtrls,
28
  Dialogs, 
29
  Menus, 
30
  ActnList, 
31
  ExtCtrls, 
32
  StdCtrls,
33
  Propedits, 
34
  ComponentEditors,
35

36
  GLXCollection, 
37
  GLScene, 
38
  GLViewer, 
39
  GLSceneRegister, 
40
  GLStrings, 
41
  FInfo, 
42
  OpenGL1x, 
43
  GLCrossPlatform, 
44
  ClipBrd;
45

46

47
const
48
  SCENE_SELECTED=0;
49
  BEHAVIOURS_SELECTED=1;
50
  EFFECTS_SELECTED=2;
51
type
52
  TSetSubItemsEvent = procedure(Sender:TObject) of object;
53

54
  { TGLSceneEditorForm }
55

56
  TGLSceneEditorForm = class(TForm)
57
    MenuItem1: TMenuItem;
58
    ToolBar2: TToolBar;
59
    ToolButton10: TToolButton;
60
    ToolButton11: TToolButton;
61
    ToolButton12: TToolButton;
62
    ToolButton13: TToolButton;
63
    ToolButton14: TToolButton;
64
    ToolButton15: TToolButton;
65
    ToolButton2: TToolButton;
66
    ToolButton3: TToolButton;
67
    ToolButton4: TToolButton;
68
    ToolButton5: TToolButton;
69
    ToolButton6: TToolButton;
70
    ToolButton7: TToolButton;
71
    Tree: TTreeView;
72
    PopupMenu: TPopupMenu;
73
    MIAddCamera: TMenuItem;
74
    MIAddObject: TMenuItem;
75
    N1: TMenuItem;
76
    MIDelObject: TMenuItem;
77
    ToolBar: TToolBar;
78
    ActionList: TActionList;
79
    ToolButton1: TToolButton;
80
    TBAddObjects: TToolButton;
81
    PMToolBar: TPopupMenu;
82
    ACAddCamera: TAction;
83
    ACAddObject: TAction;
84
    ImageList: TImageList;
85
    ACDeleteObject: TAction;
86
    ACMoveUp: TAction;
87
    ACMoveDown: TAction;
88
    N2: TMenuItem;
89
    Moveobjectup1: TMenuItem;
90
    Moveobjectdown1: TMenuItem;
91
    ACSaveScene: TAction;
92
    ACLoadScene: TAction;
93
    OpenDialog: TOpenDialog;
94
    SaveDialog: TSaveDialog;
95
    ToolButton8: TToolButton;
96
    ToolButton9: TToolButton;
97
    ACInfo: TAction;
98
    ACCopy: TAction;
99
    ACCut: TAction;
100
    ACPaste: TAction;
101
    Copy1: TMenuItem;
102
    Paste1: TMenuItem;
103
    Cut1: TMenuItem;
104
    PABehaviours: TPanel;
105
    BehavioursListView: TListView;
106
    Splitter3: TSplitter;
107
    EffectsListView: TListView;
108
    Splitter: TSplitter;
109
    PMBehavioursToolbar: TPopupMenu;
110
    ACAddBehaviour: TAction;
111
    MIAddBehaviour: TMenuItem;
112
    MIAddEffect: TMenuItem;
113
    MIBehaviourSeparator: TMenuItem;
114
    ACDeleteBehaviour: TAction;
115
    BehavioursPopupMenu: TPopupMenu;
116
    Delete1: TMenuItem;
117
    MoveUp1: TMenuItem;
118
    MoveDown1: TMenuItem;
119
    N4: TMenuItem;
120
    Label1: TLabel;
121
    Label2: TLabel;
122
    PMEffectsToolbar: TPopupMenu;
123
    ACAddEffect: TAction;
124
    ToolBar1: TToolBar;
125
    TBAddBehaviours: TToolButton;
126
    TBAddEffects: TToolButton;
127
    TBEffectsPanel: TToolButton;
128
    TBStayOnTop: TToolButton;
129
    ACStayOnTop: TAction;
130
    procedure BehavioursListViewClick(Sender: TObject);
131
    procedure EffectsListViewClick(Sender: TObject);
132
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
133
    procedure FormCreate(Sender: TObject);
134
    procedure ToolButton10Click(Sender: TObject);
135
    procedure ToolButton15Click(Sender: TObject);
136
    procedure TreeEditing(Sender: TObject; Node: TTreeNode; var AllowEdit: Boolean);
137
    procedure TreeDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
138
    procedure TreeDragDrop(Sender, Source: TObject; X, Y: Integer);
139
    procedure TreeChange(Sender: TObject; Node: TTreeNode);
140
    procedure TreeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
141
    procedure TreeEnter(Sender: TObject);
142
    procedure TreeMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
143
    procedure ACAddCameraExecute(Sender: TObject);
144
    procedure ACDeleteObjectExecute(Sender: TObject);
145
    procedure ACMoveUpExecute(Sender: TObject);
146
    procedure ACMoveDownExecute(Sender: TObject);
147
    procedure ACAddObjectExecute(Sender: TObject);
148
    procedure ACSaveSceneExecute(Sender: TObject);
149
    procedure ACLoadSceneExecute(Sender: TObject);
150
    procedure FormDestroy(Sender: TObject);
151
    procedure ACInfoExecute(Sender: TObject);
152
    procedure ACCopyExecute(Sender: TObject);
153
    procedure ACCutExecute(Sender: TObject);
154
    procedure ACPasteExecute(Sender: TObject);
155

156
    procedure ACAddBehaviourExecute(Sender: TObject);
157
    procedure DeleteBaseBehaviour(ListView:TListView);
158
    procedure PMBehavioursToolbarPopup(Sender: TObject);
159
    procedure PMEffectsToolbarPopup(Sender: TObject);
160
    procedure BehavioursListViewSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
161
    procedure ACAddEffectExecute(Sender: TObject);
162
    procedure PopupMenuPopup(Sender: TObject);
163
    procedure TBEffectsPanelClick(Sender: TObject);
164
    procedure TreeKeyDown(Sender: TObject; var Key: Word;
165
      Shift: TShiftState);
166
    procedure ACStayOnTopExecute(Sender: TObject);
167

168
  private
169
    FSelectedItems:Integer; //
170

171
    FScene: TGLScene;
172
    FObjectNode: TTreeNode;
173
    FCurrentDesigner: TComponentEditorDesigner;
174
    FLastMouseDownPos: TPoint;
175
    FObjectList: TStringList;
176
    FXObjectList: TList;
177
    procedure ReadScene;
178
    procedure ResetTree;
179
    // adds the given scene object as well as its children to the tree structure and returns
180
    // the last add node (e.g. for selection)
181
    function AddNodes(ANode: TTreeNode; AObject: TGLBaseSceneObject): TTreeNode;
182
    procedure AddObjectClick(Sender: TObject);
183
    procedure AddBehaviourClick(Sender: TObject);
184
    procedure AddEffectClick(Sender: TObject);
185
    procedure SetObjectsSubItems(parent : TMenuItem);
186
    procedure SetXCollectionSubItems(parent : TMenuItem ; XCollection: TGLXCollection; Event:TSetSubItemsEvent);
187
    procedure SetBehavioursSubItems(parent : TMenuItem; XCollection: TGLXCollection);
188
    procedure SetEffectsSubItems(parent : TMenuItem; XCollection: TGLXCollection);
189
    procedure OnBaseSceneObjectNameChanged(Sender : TObject);
190
    function IsValidClipBoardNode : Boolean;
191
    function IsPastePossible : Boolean;
192
    procedure ShowBehaviours(BaseSceneObject:TGLBaseSceneObject);
193
    procedure ShowEffects(BaseSceneObject:TGLBaseSceneObject);
194
    procedure ShowBehavioursAndEffects(BaseSceneObject:TGLBaseSceneObject);
195
    procedure EnableAndDisableActions();
196
    procedure TreeEdited(Sender: TObject; Node: TTreeNode; var S: String);
197

198
  protected
199
	 procedure Notification(AComponent: TComponent; Operation: TOperation); override;
200

201
  public
202
    procedure SetScene(AScene : TGLScene; ADesigner : TComponentEditorDesigner);
203

204
  end;
205

206
function GLSceneEditorForm : TGLSceneEditorForm;
207
procedure ReleaseGLSceneEditorForm;
208

209
// ------------------------------------------------------------------
210
// ------------------------------------------------------------------
211
// ------------------------------------------------------------------
212
implementation
213
// ------------------------------------------------------------------
214
// ------------------------------------------------------------------
215
// ------------------------------------------------------------------
216

217
resourcestring
218
   cGLSceneEditor = 'GLScene Editor';
219

220
var
221
	vGLSceneEditorForm : TGLSceneEditorForm;
222

223
function GLSceneEditorForm : TGLSceneEditorForm;
224
begin
225
	if not Assigned(vGLSceneEditorForm) then
226
		vGLSceneEditorForm:=TGLSceneEditorForm.Create(nil);
227
	Result:=vGLSceneEditorForm;
228
end;
229

230
procedure ReleaseGLSceneEditorForm;
231
begin
232
	if Assigned(vGLSceneEditorForm) then begin
233
		vGLSceneEditorForm.Free;
234
      vGLSceneEditorForm:=nil;
235
   end;
236
end;
237

238
{$IFDEF MSWINDOWS}
239
const
240
   cRegistryKey = 'Software\GLScene\GLSceneEditor';
241

242
function ReadRegistryInteger(reg : TRegistry; const name : String;
243
                             defaultValue : Integer) : Integer;
244
begin
245
   if reg.ValueExists(name) then
246
      Result:=reg.ReadInteger(name)
247
   else Result:=defaultValue;
248
end;
249
{$ENDIF}
250

251
// FindNodeByData
252
//
253
function FindNodeByData(treeNodes : TTreeNodes; data : Pointer;
254
								baseNode : TTreeNode = nil) : TTreeNode;
255
var
256
	n : TTreeNode;
257
begin
258
	Result:=nil;
259
	if Assigned(baseNode) then begin
260
		n:=baseNode.getFirstChild;
261
		while Assigned(n) do begin
262
			if n.Data=data then begin
263
				Result:=n; Break;
264
			end else	if n.HasChildren then begin
265
				Result:=FindNodeByData(treeNodes, data, n);
266
				if Assigned(Result) then Break;
267
			end;
268
			n:=baseNode.GetNextChild(n);
269
		end;
270
	end else begin
271
		n:=treeNodes.GetFirstNode;
272
		while Assigned(n) do begin
273
			if n.Data=data then begin
274
				Result:=n; Break;
275
			end else	if n.HasChildren then begin
276
				Result:=FindNodeByData(treeNodes, data, n);
277
				if Assigned(Result) then Break;
278
			end;
279
			n:=n.getNextSibling;
280
		end;
281
	end;
282
end;
283

284
//----------------- TGLSceneEditorForm ---------------------------------------------------------------------------------
285

286
// SetScene
287
//
288
procedure TGLSceneEditorForm.SetScene(AScene : TGLScene; ADesigner : TComponentEditorDesigner);
289
begin
290
   if Assigned(FScene) then begin
291
     FScene.RemoveFreeNotification(Self);
292
   end;
293
   FScene:=AScene;
294
   FCurrentDesigner:=ADesigner;
295
   ResetTree;
296
   BehavioursListView.Items.Clear;
297
   EffectsListView.Items.Clear;
298

299
   if Assigned(FScene) then begin
300
      FScene.FreeNotification(Self);
301
      ReadScene;
302
      Caption:=cGLSceneEditor+' : '+FScene.Name;
303
   end else Caption:=cGLSceneEditor;
304
   TreeChange(Self, nil);
305
   if Assigned(FScene) then begin
306
      Tree.Enabled:=true;
307
      BehavioursListView.Enabled:=true;
308
      EffectsListView.Enabled:=true;
309
      ACLoadScene.Enabled:=True;
310
      ACSaveScene.Enabled:=True;
311
      FSelectedItems:=SCENE_SELECTED;
312
      EnableAndDisableActions;
313
   end else begin
314
      Tree.Enabled:=False;
315
      BehavioursListView.Enabled:=False;
316
      EffectsListView.Enabled:=False;
317
      ACLoadScene.Enabled:=False;
318
      ACSaveScene.Enabled:=False;
319
      ACAddCamera.Enabled:=False;
320
      ACAddObject.Enabled:=False;
321
      ACAddBehaviour.Enabled:=False;
322
      ACAddEffect.Enabled:=False;
323
      ACDeleteObject.Enabled:=False;
324
      ACMoveUp.Enabled:=False;
325
      ACMoveDown.Enabled:=False;
326
      ACCut.Enabled:=False;
327
      ACCopy.Enabled:=False;
328
      ACPaste.Enabled:=False;
329
   end;
330

331
   ShowBehavioursAndEffects(nil);
332
end;
333

334
// FormCreate
335
//
336
procedure TGLSceneEditorForm.FormCreate(Sender: TObject);
337
var
338
   CurrentNode: TTreeNode;
339
   {$IFDEF MSWINDOWS}
340
   reg : TRegistry;
341
   {$ENDIF}
342
begin
343
   FObjectList := TStringList.Create;
344
   RegisterGLBaseSceneObjectNameChangeEvent(OnBaseSceneObjectNameChanged);
345
   Tree.Images:=ObjectManager.ObjectIcons;
346
   Tree.Indent:=ObjectManager.ObjectIcons.Width;
347
   with Tree.Items do begin
348
      // first add the scene root
349
      CurrentNode:=Add(nil, glsSceneRoot);
350
      with CurrentNode do begin
351
         ImageIndex:=ObjectManager.SceneRootIndex;
352
         SelectedIndex:=ImageIndex;
353
      end;
354
      // and the root for all objects
355
      FObjectNode:=AddChild(CurrentNode, glsObjectRoot);
356
      with FObjectNode do begin
357
         ImageIndex:=ObjectManager.ObjectRootIndex;
358
         SelectedIndex:=ObjectManager.ObjectRootIndex;
359
      end;
360
   end;
361
   // Build SubMenus
362
   SetObjectsSubItems(MIAddObject);
363
   MIAddObject.SubMenuImages:=ObjectManager.ObjectIcons;
364
   SetObjectsSubItems(PMToolBar.Items);
365
   PMToolBar.Images:=ObjectManager.ObjectIcons;
366

367
   SetBehavioursSubItems(MIAddBehaviour, nil);
368
   SetBehavioursSubItems(PMBehavioursToolBar.Items, nil);
369
   SetEffectsSubItems(MIAddEffect, nil);
370
   SetEffectsSubItems(PMEffectsToolBar.Items, nil);
371

372
   {$IFDEF MSWINDOWS}
373
   reg:=TRegistry.Create;
374
   try
375
      if reg.OpenKey(cRegistryKey, True) then begin
376
         if reg.ValueExists('EffectsPanel') then
377
            TBEffectsPanel.Down:=reg.ReadBool('EffectsPanel');
378
         TBEffectsPanelClick(Self);
379
         Left:=ReadRegistryInteger(reg, 'Left', Left);
380
         Top:=ReadRegistryInteger(reg, 'Top', Top);
381
         Width:=ReadRegistryInteger(reg, 'Width', 250);
382
         Height:=ReadRegistryInteger(reg, 'Height', Height);
383
      end;
384
   finally
385
      reg.Free;
386
   end;
387
   {$ENDIF}
388

389
   // Trigger the event OnEdited manualy
390
   Tree.OnEdited := TreeEdited;
391
end;
392

393
procedure TGLSceneEditorForm.ToolButton10Click(Sender: TObject);
394
begin
395
    Tree.FullExpand;
396
end;
397

398
procedure TGLSceneEditorForm.ToolButton15Click(Sender: TObject);
399
begin
400
    if FObjectNode <> nil then try
401
    Tree.Items.BeginUpdate;
402
    FObjectNode.Collapse(true);
403
    FObjectNode.Expand(false);
404
  finally
405
    Tree.Items.EndUpdate;
406
  end;
407
end;
408

409
// FormClose
410
//
411
procedure TGLSceneEditorForm.FormClose(Sender: TObject;
412
  var CloseAction: TCloseAction);
413
begin
414
    SetScene(nil,nil);
415
    CloseAction :=CloseAction;
416
end;
417

418
// FormDestroy
419
//
420
procedure TGLSceneEditorForm.FormDestroy(Sender: TObject);
421
{$IFDEF MSWINDOWS}
422
var
423
   reg : TRegistry;
424
{$ENDIF}
425
begin
426
  SetScene(nil,nil);
427
  DeRegisterGLBaseSceneObjectNameChangeEvent(OnBaseSceneObjectNameChanged);
428
  FObjectList.Free;
429

430
   {$IFDEF MSWINDOWS}
431
   reg:=TRegistry.Create;
432
   try
433
      if reg.OpenKey(cRegistryKey, True) then begin
434
         reg.WriteBool('EffectsPanel', TBEffectsPanel.Down);
435
         reg.WriteInteger('Left', Left);
436
         reg.WriteInteger('Top', Top);
437
         reg.WriteInteger('Width', Width);
438
         reg.WriteInteger('Height', Height);
439
      end;
440
   finally
441
      reg.Free;
442
   end;
443
   {$ENDIF}
444
end;
445

446
//----------------------------------------------------------------------------------------------------------------------
447

448
procedure TGLSceneEditorForm.ReadScene;
449

450
var
451
  I: Integer;
452

453
begin
454
  Tree.Items.BeginUpdate;
455
  with FScene do
456
  begin
457
    if Assigned(Objects) then
458
	 begin
459
      FObjectNode.Data:=Objects;
460
      with Objects do
461
        for I:=0 to Count - 1 do AddNodes(FObjectNode, Children[I]);
462
      FObjectNode.Expand(False);
463
    end;
464
  end;
465
  Tree.Items.EndUpdate;
466
end;
467

468
//----------------------------------------------------------------------------------------------------------------------
469

470
procedure TGLSceneEditorForm.ResetTree;
471
begin
472
   // delete all subtrees (empty tree)
473
   Tree.Items.BeginUpdate;
474
   try
475
      with FObjectNode do begin
476
         DeleteChildren;
477
			Data:=nil;
478
         Parent.Expand(True);
479
      end;
480
   finally
481
      Tree.Items.EndUpdate;
482
   end;
483
end;
484

485
//----------------------------------------------------------------------------------------------------------------------
486

487
function TGLSceneEditorForm.AddNodes(ANode: TTreeNode; AObject: TGLBaseSceneObject): TTreeNode;
488
var
489
  I: Integer;
490
  CurrentNode: TTreeNode;
491
begin
492
  if IsSubComponent(AObject) then
493
  begin
494
    Result := Tree.Selected;
495
    Exit;
496
  end
497
  else
498
  begin
499
    Result := Tree.Items.AddChildObject(ANode, AObject.Name, AObject);
500
    Result.ImageIndex := ObjectManager.GetImageIndex(TGLSceneObjectClass(AObject.ClassType));
501
    Result.SelectedIndex := Result.ImageIndex;
502
    CurrentNode := Result;
503
    for I := 0 to AObject.Count - 1 do
504
      Result := AddNodes(CurrentNode, AObject[I]);
505
  end;
506
end;
507

508
procedure TGLSceneEditorForm.SetObjectsSubItems(parent : TMenuItem);
509
var
510
   i, j : Integer;
511
   item, currentParent : TMenuItem;
512
   currentCategory : String;
513
   soc : TGLSceneObjectClass;
514
begin
515
   ObjectManager.GetRegisteredSceneObjects(FObjectList);
516

517
   for i:=0 to FObjectList.Count-1 do
518
   begin
519
     if FObjectList[i]<>'' then
520
     begin
521
        with ObjectManager do
522
           currentCategory:=GetCategory(TGLSceneObjectClass(FObjectList.Objects[i]));
523
        if currentCategory='' then
524
           currentParent:=parent
525
        else begin
526
           currentParent:=NewItem(currentCategory, 0, False, True, nil, 0, '');
527
           parent.Add(currentParent);
528
        end;
529

530
        for j := i to FObjectList.Count-1 do
531
        begin
532
          if FObjectList[j]<>'' then
533
            with ObjectManager do
534
            begin
535
               soc:=TGLSceneObjectClass(FObjectList.Objects[j]);
536
               if currentCategory=GetCategory(soc) then
537
               begin
538
                  item := NewItem(FObjectList[j], 0, False, True, AddObjectClick, 0, '');
539
                  item.ImageIndex := GetImageIndex(soc);
540
                  item.GlyphShowMode:= gsmAlways;
541
                  item.Tag := j;
542
                  currentParent.Add(item);
543
                  FObjectList[j] := '';
544
                  if currentCategory='' then
545
                    Break;
546
               end;
547
            end;
548
        end;
549

550
     end;
551
   end;
552
end;
553

554
procedure TGLSceneEditorForm.SetXCollectionSubItems(parent : TMenuItem ; XCollection: TGLXCollection; Event:TSetSubItemsEvent);
555
var
556
	I : Integer;
557
	XCollectionItemClass : TGLXCollectionItemClass;
558
	mi : TMenuItem;
559
begin
560
  parent.Clear;
561
  if Assigned(XCollection) then
562
  begin
563
     FXObjectList := GetXCollectionItemClassesList(XCollection.ItemsClass);
564
     for I:=0 to FXObjectList.Count-1 do begin
565
        XCollectionItemClass:=TGLXCollectionItemClass(FXObjectList[i]);
566
        mi:=TMenuItem.Create(owner);
567
        mi.Caption:=XCollectionItemClass.FriendlyName;
568
        mi.OnClick:=Event;
569
        mi.Tag := I;
570
        if Assigned(XCollection) then
571
          mi.Enabled:=XCollection.CanAdd(XCollectionItemClass)
572
        else
573
          mi.Enabled:=TBAddBehaviours.Enabled;
574
        parent.Add(mi);
575
     end;
576
     FXObjectList.Free;
577
   end;
578
end;
579

580

581
// SetBehavioursSubItems
582
//
583
procedure TGLSceneEditorForm.SetBehavioursSubItems(parent : TMenuItem ; XCollection: TGLXCollection);
584
begin
585
  SetXCollectionSubItems(parent, XCollection, AddBehaviourClick);
586
end;
587

588
// SetEffectsSubItems
589
//
590
procedure TGLSceneEditorForm.SetEffectsSubItems(parent : TMenuItem ; XCollection: TGLXCollection);
591
begin
592
  SetXCollectionSubItems(parent, XCollection, AddEffectClick);
593
end;
594

595

596
procedure TGLSceneEditorForm.AddObjectClick(Sender: TObject);
597
var
598
   AParent, AObject: TGLBaseSceneObject;
599
   I: Integer;
600
   Node: TTreeNode;
601
begin
602
  if Assigned(FCurrentDesigner) then with Tree do
603
    if Assigned(Selected) and (Selected.Level > 0) then
604
    begin
605
       AParent:=TGLBaseSceneObject(Selected.Data);
606
       I := TMenuItem(Sender).Tag;
607
       AObject:=TGLBaseSceneObject(TGLSceneObjectClass(FObjectList.Objects[I]).Create(FScene.Owner));
608
       AObject.Name:=FCurrentDesigner.CreateUniqueComponentName(AObject.ClassName);
609
       TComponent(AObject).DesignInfo:=0;
610
       AParent.AddChild(AObject);
611
       Node:=AddNodes(Selected, AObject);
612
       Node.Selected:=True;
613
       FCurrentDesigner.PropertyEditorHook.PersistentAdded(AObject,True);
614
       FCurrentDesigner.Modified;
615
       FCurrentDesigner.SelectOnlyThisComponent(AObject);
616
    end;
617
end;
618

619
procedure TGLSceneEditorForm.AddBehaviourClick(Sender: TObject);
620
var
621
   I: Integer;
622
   XCollectionItemClass : TGLXCollectionItemClass;
623
   AParent: TGLBaseSceneObject;
624
   XCollectionItem : TGLXCollectionItem;
625
begin
626
  if Assigned(Tree.Selected) then
627
  begin
628
        AParent:=TGLBaseSceneObject(Tree.Selected.Data);
629
        I := (Sender as TMenuItem).Tag;
630

631
        FXObjectList := GetXCollectionItemClassesList(AParent.Behaviours.ItemsClass);
632

633
	XCollectionItemClass:=TGLXCollectionItemClass(FXObjectList[I]);
634
	XCollectionItem:=XCollectionItemClass.Create(AParent.Behaviours);
635
        ShowBehaviours(AParent);
636
       	BehavioursListView.Selected:=BehavioursListView.Items.FindData(XCollectionItem);
637
        GlobalDesignHook.Modified(Sender);
638
        FXObjectList.Free;
639
   end;
640
end;
641

642

643
procedure TGLSceneEditorForm.AddEffectClick(Sender: TObject);
644
var
645
   I: Integer;
646
	XCollectionItemClass : TGLXCollectionItemClass;
647
        AParent: TGLBaseSceneObject;
648
        XCollectionItem : TGLXCollectionItem;
649
begin
650
        if Assigned(Tree.Selected) then
651
        begin
652
        AParent:=TGLBaseSceneObject(Tree.Selected.Data);
653
        I := (Sender as TMenuItem).Tag;
654

655
        FXObjectList := GetXCollectionItemClassesList(AParent.Effects.ItemsClass);
656

657
	XCollectionItemClass:=TGLXCollectionItemClass(FXObjectList[I]);
658
	XCollectionItem:=XCollectionItemClass.Create(AParent.Effects);
659
        ShowEffects(AParent);
660
       	EffectsListView.Selected:=EffectsListView.Items.FindData(XCollectionItem);
661
        GlobalDesignHook.Modified(Sender);
662
        FXObjectList.Free;
663
   end;
664
end;
665

666
procedure TGLSceneEditorForm.TreeDragOver(Sender, Source: TObject; X, Y: Integer;
667
                                          State: TDragState; var Accept: Boolean);
668
var
669
   Target : TTreeNode;
670
begin
671
   Accept:=False;
672
   if Source=Tree then with Tree do begin
673
      Target:=Tree.GetNodeAt(X, Y);  //Tree.DropTarget; buged result=nil
674
      Accept:=Assigned(Target) and (Selected <> Target)
675
                and Assigned(Target.Data) and
676
                (not Target.HasAsParent(Selected));
677
   end;
678
   State:=State;
679
end;
680

681
procedure TGLSceneEditorForm.TreeDragDrop(Sender, Source: TObject; X, Y: Integer);
682
var
683
   SourceNode, DestinationNode: TTreeNode;
684
   SourceObject, DestinationObject: TGLBaseSceneObject;
685
begin
686
    if Assigned(FCurrentDesigner) then
687
    begin
688
      DestinationNode:=Tree.GetNodeAt(X, Y);  //Tree.DropTarget; buged result=nil
689
      if Assigned(DestinationNode) and (Source = Tree) then
690
      begin
691
	 SourceNode:=TTreeView(Source).Selected;
692
         SourceObject:=SourceNode.Data;
693
         DestinationObject:=DestinationNode.Data;
694
         DestinationObject.Insert(0, SourceObject);
695
         SourceNode.MoveTo(DestinationNode, naAddChildFirst);
696
         TreeChange(Self, nil);
697
         FCurrentDesigner.Modified;
698
      end;
699
   end;
700
end;
701

702
// Notification
703
//
704
procedure TGLSceneEditorForm.Notification(AComponent: TComponent; Operation: TOperation);
705
begin
706
   if (FScene=AComponent) and (Operation=opRemove) then begin
707
      FScene:=nil;
708
      SetScene(nil, nil);
709
	end;
710
	inherited;
711
end;
712

713
// OnBaseSceneObjectNameChanged
714
//
715
procedure TGLSceneEditorForm.OnBaseSceneObjectNameChanged(Sender : TObject);
716
var
717
	n : TTreeNode;
718
begin
719
	n:=FindNodeByData(Tree.Items, Sender);
720
	if Assigned(n) then
721
		n.Text:=(Sender as TGLBaseSceneObject).Name;
722
end;
723

724
// TreeChange
725
//
726
procedure TGLSceneEditorForm.TreeChange(Sender: TObject; Node: TTreeNode);
727
var
728
//   selNode : TTreeNode;
729
   BaseSceneObject1:TGLBaseSceneObject;
730
begin
731
   if Assigned(FCurrentDesigner) then begin
732

733
   if Node<>nil then
734
   begin
735
      BaseSceneObject1:=TGLBaseSceneObject(Node.Data);
736
      if BaseSceneObject1<>nil then
737
      begin
738
        ShowBehavioursAndEffects(BaseSceneObject1);
739
      end;
740
   end;
741

742
   EnableAndDisableActions();
743
   end;
744
end;
745

746
// TreeEditing
747
//
748
procedure TGLSceneEditorForm.TreeEditing(Sender: TObject; Node: TTreeNode;
749
                                         var AllowEdit: Boolean);
750
begin
751
   AllowEdit:=(Node.Level>1);
752
end;
753

754
procedure TGLSceneEditorForm.ShowBehaviours(BaseSceneObject:TGLBaseSceneObject);
755
var
756
  i:integer;
757
begin
758
      BehavioursListView.Items.Clear;
759
      BehavioursListView.Items.BeginUpdate;
760
      if Assigned(BaseSceneObject) then
761
      begin
762
      for i:=0 to BaseSceneObject.Behaviours.Count-1 do
763
      begin
764
        with BehavioursListView.Items.Add do
765
        begin
766
          Caption:=IntToStr(i)+' - '+BaseSceneObject.Behaviours[i].Name;
767
          Data:=BaseSceneObject.Behaviours[i];
768
        end;
769
      end;
770
      end;
771
      BehavioursListView.Items.EndUpdate;
772
end;
773

774
procedure TGLSceneEditorForm.ShowEffects(BaseSceneObject:TGLBaseSceneObject);
775
var
776
  i:integer;
777
begin
778
      EffectsListView.Items.Clear;
779
      EffectsListView.Items.BeginUpdate;
780
      if Assigned(BaseSceneObject) then
781
      begin
782
      for i:=0 to BaseSceneObject.Effects.Count-1 do
783
      begin
784
        with EffectsListView.Items.Add do
785
        begin
786
          caption:=IntToStr(i)+' - '+BaseSceneObject.Effects[i].Name;
787
          Data:=BaseSceneObject.Effects[i];
788
        end;
789
      end;
790
      end;
791
      EffectsListView.Items.EndUpdate;
792
end;
793

794

795
procedure TGLSceneEditorForm.ShowBehavioursAndEffects(BaseSceneObject:TGLBaseSceneObject);
796
begin
797
  ShowBehaviours(BaseSceneObject);
798
  ShowEffects(BaseSceneObject);
799
end;
800

801
// TreeEdited
802
//
803

804
procedure TGLSceneEditorForm.TreeEdited(Sender: TObject; Node: TTreeNode; var S: String);
805

806
var
807
  BaseSceneObject1:TGLBaseSceneObject;
808
begin
809
   if Assigned(FCurrentDesigner) then begin
810
      // renaming a node means renaming a scene object
811
      BaseSceneObject1:=TGLBaseSceneObject(Node.Data);
812
      if FScene.FindSceneObject(S)=nil then
813
        BaseSceneObject1.Name:=S
814
      else
815
      begin
816
       // Messagedlg('A component named '+S+' already exists',mtWarning,[mbok],0);
817
        S:=BaseSceneObject1.Name;
818
      end;
819
      ShowBehavioursAndEffects(BaseSceneObject1);
820

821
      FCurrentDesigner.Modified;
822
   end;
823
end;
824

825
// TreeMouseDown
826
//
827
procedure TGLSceneEditorForm.TreeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
828
begin
829
   FLastMouseDownPos:=Point(X, Y);
830
   Button:=Button;
831
   Shift:=Shift;
832
end;
833

834
// TreeMouseMove
835
//
836
procedure TGLSceneEditorForm.TreeMouseMove(Sender: TObject;
837
  Shift: TShiftState; X, Y: Integer);
838
var
839
   node: TTreeNode;
840
begin
841
   if Shift=[ssLeft] then begin
842
      node:=Tree.Selected;
843
      if Assigned(node) and (node.Level>1) then
844
         if (Abs(FLastMouseDownPos.x-x)>4) or (Abs(FLastMouseDownPos.y-y)>4) then
845
            Tree.BeginDrag(False);
846
   end;
847
end;
848

849
// TreeEnter
850
//
851
procedure TGLSceneEditorForm.TreeEnter(Sender: TObject);
852
begin
853
   if Assigned(FCurrentDesigner) and Assigned(Tree.Selected) then
854
      FCurrentDesigner.SelectOnlyThisComponent(TGLBaseSceneObject(Tree.Selected.Data));
855
   FSelectedItems:=SCENE_SELECTED;
856
   EnableAndDisableActions();
857
end;
858

859
// ACAddCameraExecute
860
//
861
procedure TGLSceneEditorForm.ACAddCameraExecute(Sender: TObject);
862
var
863
   AObject: TGLBaseSceneObject;
864
   Node: TTreeNode;
865
begin
866
   if Assigned(FCurrentDesigner) then begin
867
      AObject:=TGLBaseSceneObject(TGLCamera.Create(FCurrentDesigner.Form));
868
      AObject.Name:=FCurrentDesigner.CreateUniqueComponentName(AObject.ClassName);
869
      FScene.Objects.AddChild(AObject);
870
      Node:=AddNodes(FObjectNode, AObject);
871
      Node.Selected:=True;
872
      FCurrentDesigner.PropertyEditorHook.PersistentAdded(AObject,True);
873
      FCurrentDesigner.Modified;
874
      FCurrentDesigner.SelectOnlyThisComponent(AObject);
875
   end;
876
end;
877

878
// ACDeleteObjectExecute
879
//
880
procedure TGLSceneEditorForm.ACDeleteObjectExecute(Sender: TObject);
881
var
882
	anObject : TGLBaseSceneObject;
883
   allowed, keepChildren : Boolean;
884
   confirmMsg : String;
885
   buttons : TMsgDlgButtons;
886
begin
887
   if FSelectedItems=BEHAVIOURS_SELECTED then begin
888
      DeleteBaseBehaviour(BehavioursListView);
889

890
      FCurrentDesigner.SelectOnlyThisComponent(TGLBaseSceneObject(Tree.Selected.data));
891

892
      ShowBehaviours(TGLBaseSceneObject(Tree.Selected.data));
893
   end else if FSelectedItems=EFFECTS_SELECTED then begin
894
      DeleteBaseBehaviour(EffectsListView);
895

896
      FCurrentDesigner.SelectOnlyThisComponent(TGLBaseSceneObject(Tree.Selected.data));
897

898
      ShowEffects(TGLBaseSceneObject(Tree.Selected.data));
899
   end else if FSelectedItems=SCENE_SELECTED then begin
900
      if Assigned(Tree.Selected) and (Tree.Selected.Level > 1) then begin
901
         anObject:=TGLBaseSceneObject(Tree.Selected.Data);
902
         // ask for confirmation
903
         if anObject.Name<>'' then
904
            ConfirmMsg:='Delete '+anObject.Name
905
         else ConfirmMsg:='Delete the marked object';
906
         buttons:=[mbOK, mbCancel];
907
         // are there children to care for?
908
         // mbAll exist only on Windows ...
909
         {.$IFDEF MSWINDOWS}
910
         if (anObject.Count > 0)  and (not anObject.HasSubChildren) then
911
         begin
912
            confirmMsg:=ConfirmMsg+' only or with ALL its children?';
913
            buttons:=[mbAll]+Buttons;
914
         end else confirmMsg:=confirmMsg+'?';
915
         {.$ENDIF}
916
         case MessageDlg(confirmMsg, mtConfirmation, buttons, 0) of
917
           {.$IFDEF MSWINDOWS}
918
            mrAll : begin
919
               keepChildren:=False;
920
               allowed:=True;
921
            end;
922
            {.$ENDIF}
923
            mrOK : begin
924
               keepChildren:=True;
925
               allowed:=True;
926
            end;
927
            mrCancel : begin
928
               allowed:=False;
929
               keepChildren:=True;
930
            end;
931
         else
932
            allowed:=False;
933
            keepChildren:=True;
934
         end;
935
         // deletion allowed?
936
         if allowed then begin
937
            if keepChildren=true then
938
               while Tree.Selected.Count>0 do
939
             Tree.Selected.Items[0].MoveTo(Tree.Selected,naAdd);
940
            //previous line should be "naInsert" if children are to remain in position of parent
941
            // (would require changes to TGLBaseSceneObject.Remove)
942
            Tree.Selected.Free;
943
            GlobalDesignHook.Unselect(anObject);
944
            anObject.Parent.Remove(anObject, keepChildren);
945
            FCurrentDesigner.Modified;
946
            GlobalDesignHook.DeletePersistent(TPersistent(anObject));
947
         end
948
      end;
949
   end;
950
end;
951

952
function FindListViewData(list : TListView; data : Pointer) : TListItem;
953
var
954
   i : Integer;
955
begin
956
   Result:=nil;
957
   for i:=0 to list.Items.Count-1 do
958
      if list.Items[i].Data = data then begin
959
         Result:=list.Items[i];
960
         Break;
961
      end;
962
end;
963

964
// ACMoveUpExecute
965
//
966
procedure TGLSceneEditorForm.ACMoveUpExecute(Sender: TObject);
967
var
968
   node : TTreeNode;
969
   prevData:Pointer;
970
begin
971
  if FSelectedItems=BEHAVIOURS_SELECTED then
972
  begin
973
        PrevData:=BehavioursListView.Selected.Data;
974
        TGLBaseBehaviour(PrevData).MoveUp;
975
        ShowBehaviours(TGLBaseSceneObject(Tree.Selected.Data));
976
        BehavioursListView.Selected:=FindListViewData(BehavioursListView, PrevData);
977
        FCurrentDesigner.Modified;
978
  end
979
  else if FSelectedItems=EFFECTS_SELECTED then
980
  begin
981
        PrevData:=EffectsListView.Selected.Data;
982
        TGLBaseBehaviour(PrevData).MoveUp;
983
        ShowEffects(TGLBaseSceneObject(Tree.Selected.Data));
984
        EffectsListView.Selected:=FindListViewData(EffectsListView, PrevData);
985
        FCurrentDesigner.Modified;
986
  end
987
  else if FSelectedItems=SCENE_SELECTED then
988
  begin
989
   if ACMoveUp.Enabled then begin
990
      node:=Tree.Selected;
991
      if Assigned(node) then begin
992
         node.MoveTo(node.GetPrevSibling, naInsert);
993
         with TGLBaseSceneObject(node.Data) do begin
994
            MoveUp;
995
            Update;
996
         end;
997
         TreeChange(Self, node);
998
         FCurrentDesigner.Modified;
999
      end;
1000
   end;
1001
  end; 
1002
end;
1003

1004
// ACMoveDownExecute
1005
//
1006
procedure TGLSceneEditorForm.ACMoveDownExecute(Sender: TObject);
1007
var
1008
   node : TTreeNode;
1009
   prevData:Pointer;
1010
begin
1011
  if FSelectedItems=BEHAVIOURS_SELECTED then
1012
  begin
1013
        PrevData:=BehavioursListView.Selected.Data;
1014
        TGLBaseBehaviour(PrevData).MoveDown;
1015
        ShowBehaviours(TGLBaseSceneObject(Tree.Selected.Data));
1016
        BehavioursListView.Selected:=FindListViewData(BehavioursListView, PrevData);
1017
        FCurrentDesigner.Modified;
1018
  end
1019
  else if FSelectedItems=EFFECTS_SELECTED then
1020
  begin
1021
        PrevData:=EffectsListView.Selected.Data;
1022
        TGLBaseBehaviour(PrevData).MoveDown;
1023
        ShowEffects(TGLBaseSceneObject(Tree.Selected.Data));
1024
        EffectsListView.Selected:=FindListViewData(EffectsListView, PrevData);
1025
        FCurrentDesigner.Modified;
1026
  end
1027
  else if FSelectedItems=SCENE_SELECTED then
1028
  begin
1029
   if ACMoveDown.Enabled then begin
1030
      node:=Tree.Selected;
1031
      if Assigned(node) then begin
1032
         node.GetNextSibling.MoveTo(node, naInsert);
1033
         with TGLBaseSceneObject(node.Data) do begin
1034
				MoveDown;
1035
            Update;
1036
         end;
1037
			TreeChange(Self, node);
1038
         FCurrentDesigner.Modified;
1039
		end;
1040
	end;
1041
      end;
1042
end;
1043

1044
// ACAddObjectExecute
1045
//
1046
procedure TGLSceneEditorForm.ACAddObjectExecute(Sender: TObject);
1047
begin
1048
  TBAddObjects.CheckMenuDropdown;
1049
end;
1050

1051
procedure TGLSceneEditorForm.ACStayOnTopExecute(Sender: TObject);
1052
begin
1053
  if TBStayOnTop.Down then
1054
    FormStyle := fsStayOnTop
1055
  else
1056
    FormStyle := fsNormal;
1057
end;
1058

1059
// ACSaveSceneExecute
1060
//
1061
procedure TGLSceneEditorForm.ACSaveSceneExecute(Sender: TObject);
1062
begin
1063
	if SaveDialog.Execute then
1064
		FScene.SaveToFile(SaveDialog.FileName);
1065
end;
1066

1067
// ACLoadSceneExecute
1068
//
1069
procedure TGLSceneEditorForm.ACLoadSceneExecute(Sender: TObject);
1070
begin
1071
	if OpenDialog.Execute then begin
1072
		FScene.LoadFromFile(OpenDialog.FileName);
1073
		ResetTree;
1074
		ReadScene;
1075
                ShowBehavioursAndEffects(nil);
1076
	end;
1077
end;
1078

1079
// ACInfoExecute
1080
//
1081
procedure TGLSceneEditorForm.ACInfoExecute(Sender: TObject);
1082
var
1083
	AScene: TGLSceneViewer;
1084
begin
1085
	AScene:=TGLSceneViewer.Create(Self);
1086
	AScene.Name:='GLSceneEditor';
1087
	AScene.Width:=0;
1088
	AScene.Height:=0;
1089
	AScene.Parent:=Self;
1090
	try
1091
		AScene.Buffer.ShowInfo;
1092
	finally
1093
		AScene.Free;
1094
	end;
1095
end;
1096

1097
// IsValidClipBoardNode
1098
//
1099
function TGLSceneEditorForm.IsValidClipBoardNode : Boolean;
1100
var
1101
   selNode : TTreeNode;
1102
begin
1103
   selNode:=Tree.Selected;
1104
   Result:=((selNode<>nil) and (selNode.Parent<>nil)
1105
            and (selNode.Parent.Parent<>nil));
1106
end;
1107

1108
// IsPastePossible
1109
//
1110
function TGLSceneEditorForm.IsPastePossible : Boolean;
1111
{$IFDEF GLS_DELPHI_6_UP}
1112

1113
   function PossibleStream(const S: string): Boolean;
1114
   var
1115
     I: Integer;
1116
   begin
1117
     Result := True;
1118
     for I := 1 to Length(S) - 6 do begin
1119
       if (S[I] in ['O','o']) and (CompareText(Copy(S, I, 6), 'OBJECT') = 0) then Exit;
1120
       if not (S[I] in [' ',#9, #13, #10]) then Break;
1121
     end;
1122
     Result := False;
1123
   end;
1124

1125
var
1126
   selNode : TTreeNode;
1127
	anObject, destination : TGLBaseSceneObject;
1128
   ComponentList: IDesignerSelections;
1129
   TmpContainer : TComponent;
1130
begin
1131
   selNode:=Tree.Selected;
1132

1133
   if (selNode<>nil) and (selNode.Parent<>nil)
1134
      {$IFDEF MSWINDOWS}
1135
      and (ClipBoard.HasFormat(CF_COMPONENT) or (Clipboard.HasFormat(CF_TEXT) and
1136
      PossibleStream(Clipboard.AsText))) {$ENDIF} then
1137
      begin
1138
      TmpContainer := TComponent.Create(self);
1139
      try
1140
         ComponentList := TDesignerSelections.Create;
1141
         PasteComponents(TmpContainer, TmpContainer, ComponentList);
1142
         if (ComponentList.Count>0) and (ComponentList[0] is TGLBaseSceneObject) then begin
1143
            anObject:=TGLBaseSceneObject(ComponentList[0]);
1144
            destination:=TGLBaseSceneObject(selNode.Data);
1145
            Result:=CanPaste(anObject, destination);
1146
         end else Result:=False;
1147
      finally
1148
         TmpContainer.Free;
1149
      end;
1150
   end else Result:=False;
1151
{$ELSE}
1152
begin
1153
   Result:=False;
1154
{$ENDIF}
1155
end;
1156

1157
// CanPaste
1158
//
1159
{$IFDEF GLS_DELPHI_6_UP}
1160
function TGLSceneEditorForm.CanPaste(obj, destination : TGLBaseSceneObject) : Boolean;
1161
begin
1162
   Result:= Assigned(obj) and Assigned(destination);
1163
end;
1164
{$ENDIF}
1165

1166
// ACCopyExecute
1167
//
1168
procedure TGLSceneEditorForm.ACCopyExecute(Sender: TObject);
1169
{$IFDEF GLS_DELPHI_6_UP}
1170
var
1171
   ComponentList: IDesignerSelections;
1172
begin
1173
   ComponentList := TDesignerSelections.Create;
1174
   ComponentList.Add(TGLBaseSceneObject(Tree.Selected.Data));
1175
   CopyComponents(FScene.Owner, ComponentList);
1176
   ACPaste.Enabled:=IsPastePossible;
1177
{$ELSE}
1178
begin
1179
{$ENDIF}
1180
end;
1181

1182
// ACCutExecute
1183
//
1184
procedure TGLSceneEditorForm.ACCutExecute(Sender: TObject);
1185
{$IFDEF GLS_DELPHI_6_UP}
1186
var
1187
  AObject: TGLBaseSceneObject;
1188
  ComponentList: IDesignerSelections;
1189
begin
1190
  if IsValidClipBoardNode then
1191
  begin
1192
    AObject := TGLBaseSceneObject(Tree.Selected.Data);
1193
    ComponentList := TDesignerSelections.Create;
1194
    ComponentList.Add(TGLBaseSceneObject(Tree.Selected.Data));
1195

1196
    CopyComponents(FScene.Owner, ComponentList);
1197
    AObject.Parent.Remove(AObject, False);
1198
    AObject.Free;
1199
    Tree.Selected.Free;
1200
    ACPaste.Enabled:=IsPastePossible;
1201
  end;
1202
{$ELSE}
1203
begin
1204
{$ENDIF}
1205
end;
1206

1207

1208
// ACPasteExecute
1209
//
1210
procedure TGLSceneEditorForm.ACPasteExecute(Sender: TObject);
1211
{$IFDEF GLS_DELPHI_6_UP}
1212
var
1213
   selNode : TTreeNode;
1214
	destination : TGLBaseSceneObject;
1215
   ComponentList: IDesignerSelections;
1216
   t: integer;
1217
begin
1218
   selNode:=Tree.Selected;
1219
   if (selNode<>nil) and (selNode.Parent<>nil) then begin
1220
      destination:=TGLBaseSceneObject(selNode.Data);
1221
      ComponentList := TDesignerSelections.Create;
1222
      PasteComponents(FScene.Owner, destination, ComponentList);
1223
      if (ComponentList.count>0) and (CanPaste(TGLBaseSCeneObject(ComponentList[0]), destination)) then begin
1224
         for t :=0 to ComponentList.Count-1 do
1225
            AddNodes(selNode, TGLBaseSCeneObject(ComponentList[t]) );
1226
         selNode.Expand(False);
1227
      end;
1228
      FCurrentDesigner.Modified;
1229
   end;
1230
{$ELSE}
1231
begin
1232
{$ENDIF}
1233
end;
1234

1235
{$IFDEF GLS_DELPHI_6_UP}
1236
// CopyComponents
1237
//
1238
procedure TGLSceneEditorForm.CopyComponents(Root: TComponent; const Components: IDesignerSelections);
1239
var
1240
  S: TMemoryStream;
1241
  W: TWriter;
1242
  I: Integer;
1243
begin
1244
  S := TMemoryStream.Create;
1245
  try
1246
    W := TWriter.Create(S, 1024);
1247
    try
1248
      W.Root := Root;
1249
      for I := 0 to Components.Count - 1 do
1250
      begin
1251
        W.WriteSignature;
1252
        W.WriteComponent(TComponent(Components[I]));
1253
      end;
1254
      W.WriteListEnd;
1255
    finally
1256
      W.Free;
1257
    end;
1258
    CopyStreamToClipboard(S);
1259
  finally
1260
    S.Free;
1261
  end;
1262
end;
1263

1264
procedure TGLSceneEditorForm.MethodError(Reader: TReader;
1265
      const MethodName: String; var Address: Pointer; var Error: Boolean);
1266
begin
1267
   // error is true because Address is nil in csDesigning
1268
   Error:=false;
1269
end;
1270

1271
procedure TGLSceneEditorForm.PasteComponents(AOwner, AParent: TComponent;const Components: IDesignerSelections);
1272
var
1273
  S: TStream;
1274
  R: TReader;
1275
begin
1276
  S := GetClipboardStream;
1277
  try
1278
    R := TReader.Create(S, 1024);
1279
    try
1280
      R.OnSetName := ReaderSetName;
1281
      R.OnFindMethod := MethodError;
1282
      FPasteOwner := AOwner;
1283
      FPasteSelection := Components;
1284
      R.ReadComponents(AOwner, AParent, ComponentRead);
1285
    finally
1286
      R.Free;
1287
    end;
1288
  finally
1289
    S.Free;
1290
  end;
1291
end;
1292

1293
procedure TGLSceneEditorForm.ReaderSetName(Reader: TReader; Component: TComponent; var Name: string);
1294
begin
1295
  if (Reader.Root = FPasteOwner) and (FPasteOwner.FindComponent(Name) <> nil) then
1296
    Name := UniqueName(Component);
1297
end;
1298

1299
function TGLSceneEditorForm.UniqueName(Component: TComponent): string;
1300
begin
1301
  Result := FCurrentDesigner.CreateUniqueComponentName(Component.ClassName);
1302
end;
1303

1304
procedure TGLSceneEditorForm.ComponentRead(Component: TComponent);
1305
begin
1306
   FPasteSelection.Add(Component);
1307
end;
1308
{$ENDIF}
1309

1310
procedure TGLSceneEditorForm.BehavioursListViewClick(Sender: TObject);
1311
begin
1312
   if Assigned(FCurrentDesigner) and Assigned(BehavioursListView.Selected) then
1313
      GlobalDesignHook.SelectOnlyThis(TGLBaseBehaviour(BehavioursListView.Selected.Data));
1314
   FSelectedItems:=BEHAVIOURS_SELECTED;
1315
   EnableAndDisableActions();
1316
end;
1317

1318
procedure TGLSceneEditorForm.EffectsListViewClick(Sender: TObject);
1319
begin
1320
   if Assigned(FCurrentDesigner) and Assigned(EffectsListView.Selected) then
1321
      GlobalDesignHook.SelectOnlyThis(TGLXCollectionItem(EffectsListView.Selected.Data));
1322
   FSelectedItems:=EFFECTS_SELECTED;
1323
   EnableAndDisableActions();
1324
end;
1325

1326
procedure TGLSceneEditorForm.ACAddBehaviourExecute(Sender: TObject);
1327
begin
1328
  TBAddBehaviours.CheckMenuDropdown
1329
end;
1330

1331
procedure TGLSceneEditorForm.DeleteBaseBehaviour(ListView:TListView);
1332
begin
1333
  if ListView.Selected<>nil then
1334
  begin
1335

1336
      GlobalDesignHook.SelectOnlyThis(nil);
1337

1338
      TGLXCollectionItem(ListView.Selected.Data).Free;
1339
      ListView.Selected.Free;
1340
     // ListViewChange(Self, nil, ctState);
1341
     FCurrentDesigner.Modified;
1342
      ShowBehavioursAndEffects(TGLBaseSceneObject(Tree.Selected.Data));
1343
  end;
1344
end;
1345

1346
procedure TGLSceneEditorForm.PMBehavioursToolbarPopup(Sender: TObject);
1347
var
1348
  object1:TGLBaseSceneObject;
1349
begin
1350
   if (Tree.Selected)<>nil then
1351
   begin
1352
     object1:=TGLBaseSceneObject(Tree.Selected.Data);
1353
     SetBehavioursSubItems(PMBehavioursToolbar.Items, object1.Behaviours);
1354
   end;
1355
end;
1356

1357
procedure TGLSceneEditorForm.PMEffectsToolbarPopup(Sender: TObject);
1358
var
1359
  object1:TGLBaseSceneObject;
1360
begin
1361
   if (Tree.Selected)<>nil then
1362
   begin
1363
     object1:=TGLBaseSceneObject(Tree.Selected.Data);
1364
     SetEffectsSubItems(PMEffectsToolbar.Items, object1.Effects);
1365
   end;
1366
end;
1367

1368

1369
procedure TGLSceneEditorForm.BehavioursListViewSelectItem(Sender: TObject;
1370
  Item: TListItem; Selected: Boolean);
1371
begin
1372
  EnableAndDisableActions();
1373
  Item := Item;
1374
  Selected:=Selected;
1375
end;
1376

1377
procedure TGLSceneEditorForm.ACAddEffectExecute(Sender: TObject);
1378
begin
1379
   TBAddEffects.CheckMenuDropdown;
1380
end;
1381

1382
procedure TGLSceneEditorForm.EnableAndDisableActions();
1383
var
1384
  SelNode:TTreeNode;
1385
begin
1386
  if FSelectedItems=SCENE_SELECTED then
1387
  begin
1388
      selNode:=Tree.Selected;
1389
      // select in Delphi IDE
1390
      if Assigned(selNode) then
1391
      begin
1392
         if Assigned(selNode.Data) then
1393
            FCurrentDesigner.SelectOnlyThisComponent(TGLBaseSceneObject(selNode.Data))
1394
         else FCurrentDesigner.SelectOnlyThisComponent(FScene);
1395
         // enablings
1396
         ACAddCamera.Enabled:=((selNode=FObjectNode) or selNode.HasAsParent(FObjectNode));
1397
         ACAddObject.Enabled:=((selNode=FObjectNode) or selNode.HasAsParent(FObjectNode));
1398
         ACAddBehaviour.Enabled:=(selNode.HasAsParent(FObjectNode));
1399
         ACAddEffect.Enabled:=(selNode.HasAsParent(FObjectNode));
1400
         ACDeleteObject.Enabled:=(selNode.Level>1);
1401
         ACMoveUp.Enabled:=((selNode.Index>0)and(selNode.Level>1));
1402
         ACMoveDown.Enabled:=((selNode.GetNextSibling<>nil)and(selNode.Level>1));
1403
         ACCut.Enabled:=IsValidClipBoardNode;
1404
         ACPaste.Enabled:=IsPastePossible;
1405

1406
      end
1407
      else
1408
      begin
1409
         ACAddCamera.Enabled:=False;
1410
         ACAddObject.Enabled:=False;
1411
         ACAddBehaviour.Enabled:=False;
1412
         ACAddEffect.Enabled:=False;
1413
         ACDeleteObject.Enabled:=False;
1414
         ACMoveUp.Enabled:=False;
1415
         ACMoveDown.Enabled:=False;
1416
         ACCut.Enabled:=False;
1417
         ACPaste.Enabled:=False;
1418
      end;
1419
//   end;
1420
   ACCopy.Enabled:=ACCut.Enabled;
1421

1422
  end
1423
  else if FSelectedItems=BEHAVIOURS_SELECTED then
1424
  begin
1425
    if (BehavioursListView.Selected<>nil) then
1426
    begin
1427
         GlobalDesignHook.SelectOnlyThis(TGLBaseBehaviour(BehavioursListView.Selected.Data));
1428
         //Writeln('BehavioursListView.Selected.data=',hexStr(BehavioursListView.Selected.data));
1429
         ACDeleteObject.Enabled:=True;
1430
         ACMoveUp.Enabled:=(BehavioursListView.Selected.Index>0);
1431
         ACMoveDown.Enabled:=(BehavioursListView.Selected.Index<BehavioursListView.Selected.Owner.Count-1);
1432
         ACCut.Enabled:=False;
1433
         ACCopy.Enabled:=false;
1434
         ACPaste.Enabled:=False;
1435
    end
1436
      else
1437
      begin
1438
         ACDeleteObject.Enabled:=false;
1439
         ACMoveUp.Enabled:=false;
1440
         ACMoveDown.Enabled:=false;
1441
         ACCut.Enabled:=false;
1442
         ACCopy.Enabled:=false;
1443
         ACPaste.Enabled:=false;
1444
      end;
1445
  end
1446
  else if FSelectedItems=EFFECTS_SELECTED then
1447
  begin
1448
    if (EffectsListView.Selected<>nil)then
1449
    begin
1450
         GlobalDesignHook.SelectOnlyThis(TGLXCollectionItem(EffectsListView.Selected.Data));
1451
         ACDeleteObject.Enabled:=True;
1452
         ACMoveUp.Enabled:=(EffectsListView.Selected.Index>0);
1453
         ACMoveDown.Enabled:=(EffectsListView.Selected.Index<EffectsListView.Selected.Owner.Count-1);
1454
         ACCut.Enabled:=False;
1455
         ACCopy.Enabled:=false;
1456
         ACPaste.Enabled:=False;
1457
    end
1458
      else
1459
      begin
1460
         ACDeleteObject.Enabled:=false;
1461
         ACMoveUp.Enabled:=false;
1462
         ACMoveDown.Enabled:=false;
1463
         ACCut.Enabled:=false;
1464
         ACCopy.Enabled:=false;
1465
         ACPaste.Enabled:=false;
1466
      end;
1467
  end;
1468

1469
end;
1470

1471
procedure TGLSceneEditorForm.PopupMenuPopup(Sender: TObject);
1472
var
1473
   obj : TObject;
1474
   sceneObj : TGLBaseSceneObject;
1475
begin
1476
   if (Tree.Selected)<>nil then begin
1477
      obj:=TObject(Tree.Selected.Data);
1478
      if Assigned(obj) and (obj is TGLBaseSceneObject) then begin
1479
         sceneObj:=TGLBaseSceneObject(obj);
1480
         SetBehavioursSubItems(MIAddBehaviour, sceneObj.Behaviours);
1481
         SetEffectsSubItems(MIAddEffect, sceneObj.Effects);
1482
      end else begin
1483
         SetBehavioursSubItems(MIAddBehaviour, nil);
1484
         SetEffectsSubItems(MIAddEffect, nil);
1485
      end;
1486
   end;
1487
end;
1488

1489
procedure TGLSceneEditorForm.TBEffectsPanelClick(Sender: TObject);
1490
begin
1491
   PABehaviours.Visible:=TBEffectsPanel.Down;
1492
   Splitter.Visible:=TBEffectsPanel.Down;
1493
   if PABehaviours.Visible then
1494
      Width:=Width+PABehaviours.Width
1495
   else Width:=Width-PABehaviours.Width;
1496
end;
1497

1498
procedure TGLSceneEditorForm.TreeKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
1499
begin
1500
  if (Key = glKey_DELETE) and not Tree.IsEditing then begin
1501
    Key := 0;
1502
    ACDeleteObject.Execute;
1503
  end;
1504
  Shift:=Shift;
1505
end;
1506

1507
initialization
1508

1509
  {$I FGLSceneEdit.lrs}
1510

1511
finalization
1512
  ReleaseGLSceneEditorForm;
1513

1514
end.
1515

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.