LZScene

Форк
0
/
GLSceneEditLCL.pas 
1547 строк · 47.2 Кб
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
   02/01/15 - PW - Fixed for Lazarus 1.2.6
9
   20/05/10 - Yar - Fixes for Linux x64
10
   18/05/10 - Yar - Fixed for Lazarus-0.9.29-25483 (thanks Predator)
11
   26/03/10 - Yar - Added Expand and Collapse buttons, fix for Unix-based systems
12
                       (thanks to Rustam Asmandiarov aka Predator)
13
   14/03/09 - DanB - Removed Cameras node, instead cameras are now placed into scene
14
   19/03/08 - mrqzzz - Little change to "stay on top" (references self, not GLSceneEditorForm )
15
   17/03/08 - mrqzzz - By dAlex: Added "stay on top" button
16
   12/07/07 - DaStr - Improved cross-platform compatibility
17
                         (BugTrackerID=1684432)
18
   29/03/07 - DaStr - Renamed LINUX to KYLIX (BugTrackerID=1681585)
19
   25/03/07 - DaStr - Abstracted IsSubComponent for Delphi5 compatibility
20
   17/03/07 - DaStr - Dropped Kylix support in favor of FPC (BugTrackerID=1681585)
21
   07/02/07 - DaStr - TGLSceneEditorForm.ACDeleteObjectExecute bugfixed
22
                         TGLSceneEditorForm.AddNodes - removed warning
23
                          (all for proper Subcomponent support)
24
   20/01/07 - DaStr - TGLSceneEditorForm.ACCutExecute bugfixed
25
   19/12/06 - DaStr - TGLSceneEditorForm.AddNodes bugfixed - SubComponents are
26
                          no longer displayed in the Editor (BugTraker ID = 1585913)
27
   24/06/06 - PvD - Fixed bug with DELETE key when editing name in Treeview
28
   03/07/04 - LR - Updated for Linux
29
   18/12/04 - PhP - Added support for deleting objects/effects/behaviours by pressing "Delete"
30
   03/07/04 - LR - Make change for Linux
31
   14/12/03 - EG - Paste fix (Mrqzzz)
32
   31/06/03 - EG - Cosmetic changes, form position/state now saved to the registry
33
   21/06/03 - DanB - Added behaviours/effects listviews
34
   22/01/02 - EG - Fixed controls state after drag/drop (Anton Zhuchkov)
35
   06/08/00 - EG - Added basic Clipboard support
36
   14/05/00 - EG - Added workaround for VCL DesignInfo bug (thx Nelson Chu)
37
   28/04/00 - EG - Fixed new objects not being immediately reco by IDE
38
   26/04/00 - EG - Added support for objects categories
39
   17/04/00 - EG - Added access to TInfoForm
40
   16/04/00 - EG - Fixed occasionnal crash when rebuilding GLScene dpk
41
                      while GLSceneEdit is visible
42
   10/04/00 - EG - Minor Create/Release change
43
   24/03/00 - EG - Fixed SetScene not updating enablings
44
   13/03/00 - EG - Object names (ie. node text) is now properly adjusted
45
                      when a GLScene object is renamed,
46
                      Added Load/Save whole scene
47
   07/02/00 - EG - Fixed notification logic
48
   06/02/00 - EG - DragDrop now starts after moving the mouse a little,
49
                      Form is now auto-creating, fixed Notification,
50
                      Added actionlist and moveUp/moveDown
51
   05/02/00 - EG - Fixed DragDrop, added root nodes auto-expansion
52
   
53
}
54
unit GLSceneEditLCL;
55

56
interface
57

58
{$I GLScene.inc}
59

60
uses
61
  lresources,
62
  lclintf,
63
  {$IFDEF MSWINDOWS}
64
  Registry,
65
  {$ENDIF}
66
  GLXCollection, GLScene, Classes, SysUtils,
67
  Controls, Forms, ComCtrls,
68
  Dialogs, Menus, ActnList, ExtCtrls, StdCtrls,
69
  propedits, componenteditors,
70

71
  GLViewer, 
72
  GLSceneRegisterLCL, 
73
  GLStrings, 
74
  FInfoLCL, 
75
  OpenGL1x, 
76
  GLCrossPlatform, 
77
  ClipBrd;
78

79

80
const
81
  SCENE_SELECTED=0;
82
  BEHAVIOURS_SELECTED=1;
83
  EFFECTS_SELECTED=2;
84
type
85
  TSetSubItemsEvent = procedure(Sender:TObject) of object;
86

87
  { TGLSceneEditorForm }
88

89
  TGLSceneEditorForm = class(TForm)
90
    MenuItem1: TMenuItem;
91
    ToolBar2: TToolBar;
92
    ToolButton10: TToolButton;
93
    ToolButton11: TToolButton;
94
    ToolButton12: TToolButton;
95
    ToolButton13: TToolButton;
96
    ToolButton14: TToolButton;
97
    ToolButton15: TToolButton;
98
    ToolButton2: TToolButton;
99
    ToolButton3: TToolButton;
100
    ToolButton4: TToolButton;
101
    ToolButton5: TToolButton;
102
    ToolButton6: TToolButton;
103
    ToolButton7: TToolButton;
104
    Tree: TTreeView;
105
    PopupMenu: TPopupMenu;
106
    MIAddCamera: TMenuItem;
107
    MIAddObject: TMenuItem;
108
    N1: TMenuItem;
109
    MIDelObject: TMenuItem;
110
    ToolBar: TToolBar;
111
    ActionList: TActionList;
112
    ToolButton1: TToolButton;
113
    TBAddObjects: TToolButton;
114
    PMToolBar: TPopupMenu;
115
    ACAddCamera: TAction;
116
    ACAddObject: TAction;
117
    ImageList: TImageList;
118
    ACDeleteObject: TAction;
119
    ACMoveUp: TAction;
120
    ACMoveDown: TAction;
121
    N2: TMenuItem;
122
    Moveobjectup1: TMenuItem;
123
    Moveobjectdown1: TMenuItem;
124
    ACSaveScene: TAction;
125
    ACLoadScene: TAction;
126
    OpenDialog: TOpenDialog;
127
    SaveDialog: TSaveDialog;
128
    ToolButton8: TToolButton;
129
    ToolButton9: TToolButton;
130
    ACInfo: TAction;
131
    ACCopy: TAction;
132
    ACCut: TAction;
133
    ACPaste: TAction;
134
    Copy1: TMenuItem;
135
    Paste1: TMenuItem;
136
    Cut1: TMenuItem;
137
    PABehaviours: TPanel;
138
    BehavioursListView: TListView;
139
    Splitter3: TSplitter;
140
    EffectsListView: TListView;
141
    Splitter: TSplitter;
142
    PMBehavioursToolbar: TPopupMenu;
143
    ACAddBehaviour: TAction;
144
    MIAddBehaviour: TMenuItem;
145
    MIAddEffect: TMenuItem;
146
    MIBehaviourSeparator: TMenuItem;
147
    ACDeleteBehaviour: TAction;
148
    BehavioursPopupMenu: TPopupMenu;
149
    Delete1: TMenuItem;
150
    MoveUp1: TMenuItem;
151
    MoveDown1: TMenuItem;
152
    N4: TMenuItem;
153
    Label1: TLabel;
154
    Label2: TLabel;
155
    PMEffectsToolbar: TPopupMenu;
156
    ACAddEffect: TAction;
157
    ToolBar1: TToolBar;
158
    TBAddBehaviours: TToolButton;
159
    TBAddEffects: TToolButton;
160
    TBEffectsPanel: TToolButton;
161
    TBStayOnTop: TToolButton;
162
    ACStayOnTop: TAction;
163
    procedure BehavioursListViewClick(Sender: TObject);
164
    procedure EffectsListViewClick(Sender: TObject);
165
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
166
    procedure FormCreate(Sender: TObject);
167
    procedure ToolButton10Click(Sender: TObject);
168
    procedure ToolButton15Click(Sender: TObject);
169
    procedure TreeEditing(Sender: TObject; Node: TTreeNode; var AllowEdit: Boolean);
170
    procedure TreeDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
171
    procedure TreeDragDrop(Sender, Source: TObject; X, Y: Integer);
172
    procedure TreeChange(Sender: TObject; Node: TTreeNode);
173
    procedure TreeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
174
    procedure TreeEnter(Sender: TObject);
175
    procedure TreeMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
176
    procedure ACAddCameraExecute(Sender: TObject);
177
    procedure ACDeleteObjectExecute(Sender: TObject);
178
    procedure ACMoveUpExecute(Sender: TObject);
179
    procedure ACMoveDownExecute(Sender: TObject);
180
    procedure ACAddObjectExecute(Sender: TObject);
181
    procedure ACSaveSceneExecute(Sender: TObject);
182
    procedure ACLoadSceneExecute(Sender: TObject);
183
    procedure FormDestroy(Sender: TObject);
184
    procedure ACInfoExecute(Sender: TObject);
185
    procedure ACCopyExecute(Sender: TObject);
186
    procedure ACCutExecute(Sender: TObject);
187
    procedure ACPasteExecute(Sender: TObject);
188

189
    procedure ACAddBehaviourExecute(Sender: TObject);
190
    procedure DeleteBaseBehaviour(ListView:TListView);
191
    procedure PMBehavioursToolbarPopup(Sender: TObject);
192
    procedure PMEffectsToolbarPopup(Sender: TObject);
193
    procedure BehavioursListViewSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
194
    procedure ACAddEffectExecute(Sender: TObject);
195
    procedure PopupMenuPopup(Sender: TObject);
196
    procedure TBEffectsPanelClick(Sender: TObject);
197
    procedure TreeKeyDown(Sender: TObject; var Key: Word;
198
      Shift: TShiftState);
199
    procedure ACStayOnTopExecute(Sender: TObject);
200

201
  private
202
    FSelectedItems:Integer; //
203

204
    FScene: TGLScene;
205
    FObjectNode: TTreeNode;
206
    FCurrentDesigner: TComponentEditorDesigner;
207
    FLastMouseDownPos: TPoint;
208
    FObjectList: TStringList;
209
    FXObjectList: TList;
210
    procedure ReadScene;
211
    procedure ResetTree;
212
    // adds the given scene object as well as its children to the tree structure and returns
213
    // the last add node (e.g. for selection)
214
    function AddNodes(ANode: TTreeNode; AObject: TGLBaseSceneObject): TTreeNode;
215
    procedure AddObjectClick(Sender: TObject);
216
    procedure AddBehaviourClick(Sender: TObject);
217
    procedure AddEffectClick(Sender: TObject);
218
    procedure SetObjectsSubItems(parent : TMenuItem);
219
    procedure SetXCollectionSubItems(parent : TMenuItem ; XCollection: TGLXCollection; Event:TSetSubItemsEvent);
220
    procedure SetBehavioursSubItems(parent : TMenuItem; XCollection: TGLXCollection);
221
    procedure SetEffectsSubItems(parent : TMenuItem; XCollection: TGLXCollection);
222
    procedure OnBaseSceneObjectNameChanged(Sender : TObject);
223
    function IsValidClipBoardNode : Boolean;
224
    function IsPastePossible : Boolean;
225
    procedure ShowBehaviours(BaseSceneObject:TGLBaseSceneObject);
226
    procedure ShowEffects(BaseSceneObject:TGLBaseSceneObject);
227
    procedure ShowBehavioursAndEffects(BaseSceneObject:TGLBaseSceneObject);
228
    procedure EnableAndDisableActions();
229
    procedure TreeEdited(Sender: TObject; Node: TTreeNode; var S: String);
230

231
  protected
232
	 procedure Notification(AComponent: TComponent; Operation: TOperation); override;
233

234
  public
235
    procedure SetScene(AScene : TGLScene; ADesigner : TComponentEditorDesigner);
236

237
  end;
238

239
function GLSceneEditorForm : TGLSceneEditorForm;
240
procedure ReleaseGLSceneEditorForm;
241

242
// ------------------------------------------------------------------
243
// ------------------------------------------------------------------
244
// ------------------------------------------------------------------
245
implementation
246
// ------------------------------------------------------------------
247
// ------------------------------------------------------------------
248
// ------------------------------------------------------------------
249

250
resourcestring
251
   cGLSceneEditor = 'GLScene Editor';
252

253
var
254
	vGLSceneEditorForm : TGLSceneEditorForm;
255

256
function GLSceneEditorForm : TGLSceneEditorForm;
257
begin
258
	if not Assigned(vGLSceneEditorForm) then
259
		vGLSceneEditorForm:=TGLSceneEditorForm.Create(nil);
260
	Result:=vGLSceneEditorForm;
261
end;
262

263
procedure ReleaseGLSceneEditorForm;
264
begin
265
	if Assigned(vGLSceneEditorForm) then begin
266
		vGLSceneEditorForm.Free;
267
      vGLSceneEditorForm:=nil;
268
   end;
269
end;
270

271
{$IFDEF MSWINDOWS}
272
const
273
   cRegistryKey = 'Software\GLScene\GLSceneEditor';
274

275
function ReadRegistryInteger(reg : TRegistry; const name : String;
276
                             defaultValue : Integer) : Integer;
277
begin
278
   if reg.ValueExists(name) then
279
      Result:=reg.ReadInteger(name)
280
   else Result:=defaultValue;
281
end;
282
{$ENDIF}
283

284
// FindNodeByData
285
//
286
function FindNodeByData(treeNodes : TTreeNodes; data : Pointer;
287
								baseNode : TTreeNode = nil) : TTreeNode;
288
var
289
	n : TTreeNode;
290
begin
291
	Result:=nil;
292
	if Assigned(baseNode) then begin
293
		n:=baseNode.getFirstChild;
294
		while Assigned(n) do begin
295
			if n.Data=data then begin
296
				Result:=n; Break;
297
			end else	if n.HasChildren then begin
298
				Result:=FindNodeByData(treeNodes, data, n);
299
				if Assigned(Result) then Break;
300
			end;
301
			n:=baseNode.GetNextChild(n);
302
		end;
303
	end else begin
304
		n:=treeNodes.GetFirstNode;
305
		while Assigned(n) do begin
306
			if n.Data=data then begin
307
				Result:=n; Break;
308
			end else	if n.HasChildren then begin
309
				Result:=FindNodeByData(treeNodes, data, n);
310
				if Assigned(Result) then Break;
311
			end;
312
			n:=n.getNextSibling;
313
		end;
314
	end;
315
end;
316

317
//----------------- TGLSceneEditorForm ---------------------------------------------------------------------------------
318

319
// SetScene
320
//
321
procedure TGLSceneEditorForm.SetScene(AScene : TGLScene; ADesigner : TComponentEditorDesigner);
322
begin
323
   if Assigned(FScene) then begin
324
     FScene.RemoveFreeNotification(Self);
325
   end;
326
   FScene:=AScene;
327
   FCurrentDesigner:=ADesigner;
328
   ResetTree;
329
   BehavioursListView.Items.Clear;
330
   EffectsListView.Items.Clear;
331

332
   if Assigned(FScene) then begin
333
      FScene.FreeNotification(Self);
334
      ReadScene;
335
      Caption:=cGLSceneEditor+' : '+FScene.Name;
336
   end else Caption:=cGLSceneEditor;
337
   TreeChange(Self, nil);
338
   if Assigned(FScene) then begin
339
      Tree.Enabled:=true;
340
      BehavioursListView.Enabled:=true;
341
      EffectsListView.Enabled:=true;
342
      ACLoadScene.Enabled:=True;
343
      ACSaveScene.Enabled:=True;
344
      FSelectedItems:=SCENE_SELECTED;
345
      EnableAndDisableActions;
346
   end else begin
347
      Tree.Enabled:=False;
348
      BehavioursListView.Enabled:=False;
349
      EffectsListView.Enabled:=False;
350
      ACLoadScene.Enabled:=False;
351
      ACSaveScene.Enabled:=False;
352
      ACAddCamera.Enabled:=False;
353
      ACAddObject.Enabled:=False;
354
      ACAddBehaviour.Enabled:=False;
355
      ACAddEffect.Enabled:=False;
356
      ACDeleteObject.Enabled:=False;
357
      ACMoveUp.Enabled:=False;
358
      ACMoveDown.Enabled:=False;
359
      ACCut.Enabled:=False;
360
      ACCopy.Enabled:=False;
361
      ACPaste.Enabled:=False;
362
   end;
363

364
   ShowBehavioursAndEffects(nil);
365
end;
366

367
// FormCreate
368
//
369
procedure TGLSceneEditorForm.FormCreate(Sender: TObject);
370
var
371
   CurrentNode: TTreeNode;
372
   {$IFDEF MSWINDOWS}
373
   reg : TRegistry;
374
   {$ENDIF}
375
begin
376
   FObjectList := TStringList.Create;
377
   RegisterGLBaseSceneObjectNameChangeEvent(OnBaseSceneObjectNameChanged);
378
   Tree.Images:=ObjectManager.ObjectIcons;
379
   Tree.Indent:=ObjectManager.ObjectIcons.Width;
380
   with Tree.Items do begin
381
      // first add the scene root
382
      CurrentNode:=Add(nil, glsSceneRoot);
383
      with CurrentNode do begin
384
         ImageIndex:=ObjectManager.SceneRootIndex;
385
         SelectedIndex:=ImageIndex;
386
      end;
387
      // and the root for all objects
388
      FObjectNode:=AddChild(CurrentNode, glsObjectRoot);
389
      with FObjectNode do begin
390
         ImageIndex:=ObjectManager.ObjectRootIndex;
391
         SelectedIndex:=ObjectManager.ObjectRootIndex;
392
      end;
393
   end;
394
   // Build SubMenus
395
   SetObjectsSubItems(MIAddObject);
396
   MIAddObject.SubMenuImages:=ObjectManager.ObjectIcons;
397
   SetObjectsSubItems(PMToolBar.Items);
398
   PMToolBar.Images:=ObjectManager.ObjectIcons;
399

400
   SetBehavioursSubItems(MIAddBehaviour, nil);
401
   SetBehavioursSubItems(PMBehavioursToolBar.Items, nil);
402
   SetEffectsSubItems(MIAddEffect, nil);
403
   SetEffectsSubItems(PMEffectsToolBar.Items, nil);
404

405
   {$IFDEF MSWINDOWS}
406
   reg:=TRegistry.Create;
407
   try
408
      if reg.OpenKey(cRegistryKey, True) then begin
409
         if reg.ValueExists('EffectsPanel') then
410
            TBEffectsPanel.Down:=reg.ReadBool('EffectsPanel');
411
         TBEffectsPanelClick(Self);
412
         Left:=ReadRegistryInteger(reg, 'Left', Left);
413
         Top:=ReadRegistryInteger(reg, 'Top', Top);
414
         Width:=ReadRegistryInteger(reg, 'Width', 250);
415
         Height:=ReadRegistryInteger(reg, 'Height', Height);
416
      end;
417
   finally
418
      reg.Free;
419
   end;
420
   {$ENDIF}
421

422
   // Trigger the event OnEdited manualy
423
   Tree.OnEdited := TreeEdited;
424
end;
425

426
procedure TGLSceneEditorForm.ToolButton10Click(Sender: TObject);
427
begin
428
    Tree.FullExpand;
429
end;
430

431
procedure TGLSceneEditorForm.ToolButton15Click(Sender: TObject);
432
begin
433
    if FObjectNode <> nil then try
434
    Tree.Items.BeginUpdate;
435
    FObjectNode.Collapse(true);
436
    FObjectNode.Expand(false);
437
  finally
438
    Tree.Items.EndUpdate;
439
  end;
440
end;
441

442
// FormClose
443
//
444
procedure TGLSceneEditorForm.FormClose(Sender: TObject;
445
  var CloseAction: TCloseAction);
446
begin
447
    SetScene(nil,nil);
448
    CloseAction :=CloseAction;
449
end;
450

451
// FormDestroy
452
//
453
procedure TGLSceneEditorForm.FormDestroy(Sender: TObject);
454
{$IFDEF MSWINDOWS}
455
var
456
   reg : TRegistry;
457
{$ENDIF}
458
begin
459
  SetScene(nil,nil);
460
  DeRegisterGLBaseSceneObjectNameChangeEvent(OnBaseSceneObjectNameChanged);
461
  FObjectList.Free;
462

463
   {$IFDEF MSWINDOWS}
464
   reg:=TRegistry.Create;
465
   try
466
      if reg.OpenKey(cRegistryKey, True) then begin
467
         reg.WriteBool('EffectsPanel', TBEffectsPanel.Down);
468
         reg.WriteInteger('Left', Left);
469
         reg.WriteInteger('Top', Top);
470
         reg.WriteInteger('Width', Width);
471
         reg.WriteInteger('Height', Height);
472
      end;
473
   finally
474
      reg.Free;
475
   end;
476
   {$ENDIF}
477
end;
478

479
//----------------------------------------------------------------------------------------------------------------------
480

481
procedure TGLSceneEditorForm.ReadScene;
482

483
var
484
  I: Integer;
485

486
begin
487
  Tree.Items.BeginUpdate;
488
  with FScene do
489
  begin
490
    if Assigned(Objects) then
491
	 begin
492
      FObjectNode.Data:=Objects;
493
      with Objects do
494
        for I:=0 to Count - 1 do AddNodes(FObjectNode, Children[I]);
495
      FObjectNode.Expand(False);
496
    end;
497
  end;
498
  Tree.Items.EndUpdate;
499
end;
500

501
//----------------------------------------------------------------------------------------------------------------------
502

503
procedure TGLSceneEditorForm.ResetTree;
504
begin
505
   // delete all subtrees (empty tree)
506
   Tree.Items.BeginUpdate;
507
   try
508
      with FObjectNode do begin
509
         DeleteChildren;
510
			Data:=nil;
511
         Parent.Expand(True);
512
      end;
513
   finally
514
      Tree.Items.EndUpdate;
515
   end;
516
end;
517

518
//----------------------------------------------------------------------------------------------------------------------
519

520
function TGLSceneEditorForm.AddNodes(ANode: TTreeNode; AObject: TGLBaseSceneObject): TTreeNode;
521
var
522
  I: Integer;
523
  CurrentNode: TTreeNode;
524
begin
525
  if IsSubComponent(AObject) then
526
  begin
527
    Result := Tree.Selected;
528
    Exit;
529
  end
530
  else
531
  begin
532
    Result := Tree.Items.AddChildObject(ANode, AObject.Name, AObject);
533
    Result.ImageIndex := ObjectManager.GetImageIndex(TGLSceneObjectClass(AObject.ClassType));
534
    Result.SelectedIndex := Result.ImageIndex;
535
    CurrentNode := Result;
536
    for I := 0 to AObject.Count - 1 do
537
      Result := AddNodes(CurrentNode, AObject[I]);
538
  end;
539
end;
540

541
procedure TGLSceneEditorForm.SetObjectsSubItems(parent : TMenuItem);
542
var
543
   i, j : Integer;
544
   item, currentParent : TMenuItem;
545
   currentCategory : String;
546
   soc : TGLSceneObjectClass;
547
begin
548
   ObjectManager.GetRegisteredSceneObjects(FObjectList);
549

550
   for i:=0 to FObjectList.Count-1 do
551
   begin
552
     if FObjectList[i]<>'' then
553
     begin
554
        with ObjectManager do
555
           currentCategory:=GetCategory(TGLSceneObjectClass(FObjectList.Objects[i]));
556
        if currentCategory='' then
557
           currentParent:=parent
558
        else begin
559
           currentParent:=NewItem(currentCategory, 0, False, True, nil, 0, '');
560
           parent.Add(currentParent);
561
        end;
562

563
        for j := i to FObjectList.Count-1 do
564
        begin
565
          if FObjectList[j]<>'' then
566
            with ObjectManager do
567
            begin
568
               soc:=TGLSceneObjectClass(FObjectList.Objects[j]);
569
               if currentCategory=GetCategory(soc) then
570
               begin
571
                  item := NewItem(FObjectList[j], 0, False, True, AddObjectClick, 0, '');
572
                  item.ImageIndex := GetImageIndex(soc);
573
                  item.GlyphShowMode:= gsmAlways;
574
                  item.Tag := j;
575
                  currentParent.Add(item);
576
                  FObjectList[j] := '';
577
                  if currentCategory='' then
578
                    Break;
579
               end;
580
            end;
581
        end;
582

583
     end;
584
   end;
585
end;
586

587
procedure TGLSceneEditorForm.SetXCollectionSubItems(parent : TMenuItem ; XCollection: TGLXCollection; Event:TSetSubItemsEvent);
588
var
589
	I : Integer;
590
	XCollectionItemClass : TGLXCollectionItemClass;
591
	mi : TMenuItem;
592
begin
593
  parent.Clear;
594
  if Assigned(XCollection) then
595
  begin
596
     FXObjectList := GetXCollectionItemClassesList(XCollection.ItemsClass);
597
     for I:=0 to FXObjectList.Count-1 do begin
598
        XCollectionItemClass:=TGLXCollectionItemClass(FXObjectList[i]);
599
        mi:=TMenuItem.Create(owner);
600
        mi.Caption:=XCollectionItemClass.FriendlyName;
601
        mi.OnClick:=Event;
602
        mi.Tag := I;
603
        if Assigned(XCollection) then
604
          mi.Enabled:=XCollection.CanAdd(XCollectionItemClass)
605
        else
606
          mi.Enabled:=TBAddBehaviours.Enabled;
607
        parent.Add(mi);
608
     end;
609
     FXObjectList.Free;
610
   end;
611
end;
612

613

614
// SetBehavioursSubItems
615
//
616
procedure TGLSceneEditorForm.SetBehavioursSubItems(parent : TMenuItem ; XCollection: TGLXCollection);
617
begin
618
  SetXCollectionSubItems(parent, GLXCollection, AddBehaviourClick);
619
end;
620

621
// SetEffectsSubItems
622
//
623
procedure TGLSceneEditorForm.SetEffectsSubItems(parent : TMenuItem ; XCollection: TGLXCollection);
624
begin
625
  SetXCollectionSubItems(parent, GLXCollection, AddEffectClick);
626
end;
627

628

629
procedure TGLSceneEditorForm.AddObjectClick(Sender: TObject);
630
var
631
   AParent, AObject: TGLBaseSceneObject;
632
   I: Integer;
633
   Node: TTreeNode;
634
begin
635
  if Assigned(FCurrentDesigner) then with Tree do
636
    if Assigned(Selected) and (Selected.Level > 0) then
637
    begin
638
       AParent:=TGLBaseSceneObject(Selected.Data);
639
       I := TMenuItem(Sender).Tag;
640
       AObject:=TGLBaseSceneObject(TGLSceneObjectClass(FObjectList.Objects[I]).Create(FScene.Owner));
641
       AObject.Name:=FCurrentDesigner.CreateUniqueComponentName(AObject.ClassName);
642
       TComponent(AObject).DesignInfo:=0;
643
       AParent.AddChild(AObject);
644
       Node:=AddNodes(Selected, AObject);
645
       Node.Selected:=True;
646
       FCurrentDesigner.PropertyEditorHook.PersistentAdded(AObject,True);
647
       FCurrentDesigner.Modified;
648
       FCurrentDesigner.SelectOnlyThisComponent(AObject);
649
    end;
650
end;
651

652
procedure TGLSceneEditorForm.AddBehaviourClick(Sender: TObject);
653
var
654
   I: Integer;
655
   XCollectionItemClass : TGLXCollectionItemClass;
656
   AParent: TGLBaseSceneObject;
657
   XCollectionItem : TGLXCollectionItem;
658
begin
659
  if Assigned(Tree.Selected) then
660
  begin
661
        AParent:=TGLBaseSceneObject(Tree.Selected.Data);
662
        I := (Sender as TMenuItem).Tag;
663

664
        FXObjectList := GetXCollectionItemClassesList(AParent.Behaviours.ItemsClass);
665

666
	XCollectionItemClass:=TGLXCollectionItemClass(FXObjectList[I]);
667
	XCollectionItem:=XCollectionItemClass.Create(AParent.Behaviours);
668
        ShowBehaviours(AParent);
669
       	BehavioursListView.Selected:=BehavioursListView.Items.FindData(XCollectionItem);
670
        GlobalDesignHook.Modified(Sender);
671
        FXObjectList.Free;
672
   end;
673
end;
674

675

676
procedure TGLSceneEditorForm.AddEffectClick(Sender: TObject);
677
var
678
   I: Integer;
679
	XCollectionItemClass : TGLXCollectionItemClass;
680
        AParent: TGLBaseSceneObject;
681
        XCollectionItem : TGLXCollectionItem;
682
begin
683
        if Assigned(Tree.Selected) then
684
        begin
685
        AParent:=TGLBaseSceneObject(Tree.Selected.Data);
686
        I := (Sender as TMenuItem).Tag;
687

688
        FXObjectList := GetXCollectionItemClassesList(AParent.Effects.ItemsClass);
689

690
	XCollectionItemClass:=TGLXCollectionItemClass(FXObjectList[I]);
691
	XCollectionItem:=XCollectionItemClass.Create(AParent.Effects);
692
        ShowEffects(AParent);
693
       	EffectsListView.Selected:=EffectsListView.Items.FindData(XCollectionItem);
694
        GlobalDesignHook.Modified(Sender);
695
        FXObjectList.Free;
696
   end;
697
end;
698

699
procedure TGLSceneEditorForm.TreeDragOver(Sender, Source: TObject; X, Y: Integer;
700
                                          State: TDragState; var Accept: Boolean);
701
var
702
   Target : TTreeNode;
703
begin
704
   Accept:=False;
705
   if Source=Tree then with Tree do begin
706
      Target:=Tree.GetNodeAt(X, Y);  //Tree.DropTarget; buged result=nil
707
      Accept:=Assigned(Target) and (Selected <> Target)
708
                and Assigned(Target.Data) and
709
                (not Target.HasAsParent(Selected));
710
   end;
711
   State:=State;
712
end;
713

714
procedure TGLSceneEditorForm.TreeDragDrop(Sender, Source: TObject; X, Y: Integer);
715
var
716
   SourceNode, DestinationNode: TTreeNode;
717
   SourceObject, DestinationObject: TGLBaseSceneObject;
718
begin
719
    if Assigned(FCurrentDesigner) then
720
    begin
721
      DestinationNode:=Tree.GetNodeAt(X, Y);  //Tree.DropTarget; buged result=nil
722
      if Assigned(DestinationNode) and (Source = Tree) then
723
      begin
724
	 SourceNode:=TTreeView(Source).Selected;
725
         SourceObject:=SourceNode.Data;
726
         DestinationObject:=DestinationNode.Data;
727
         DestinationObject.Insert(0, SourceObject);
728
         SourceNode.MoveTo(DestinationNode, naAddChildFirst);
729
         TreeChange(Self, nil);
730
         FCurrentDesigner.Modified;
731
      end;
732
   end;
733
end;
734

735
// Notification
736
//
737
procedure TGLSceneEditorForm.Notification(AComponent: TComponent; Operation: TOperation);
738
begin
739
   if (FScene=AComponent) and (Operation=opRemove) then begin
740
      FScene:=nil;
741
      SetScene(nil, nil);
742
	end;
743
	inherited;
744
end;
745

746
// OnBaseSceneObjectNameChanged
747
//
748
procedure TGLSceneEditorForm.OnBaseSceneObjectNameChanged(Sender : TObject);
749
var
750
	n : TTreeNode;
751
begin
752
	n:=FindNodeByData(Tree.Items, Sender);
753
	if Assigned(n) then
754
		n.Text:=(Sender as TGLBaseSceneObject).Name;
755
end;
756

757
// TreeChange
758
//
759
procedure TGLSceneEditorForm.TreeChange(Sender: TObject; Node: TTreeNode);
760
var
761
//   selNode : TTreeNode;
762
   BaseSceneObject1:TGLBaseSceneObject;
763
begin
764
   if Assigned(FCurrentDesigner) then begin
765

766
   if Node<>nil then
767
   begin
768
      BaseSceneObject1:=TGLBaseSceneObject(Node.Data);
769
      if BaseSceneObject1<>nil then
770
      begin
771
        ShowBehavioursAndEffects(BaseSceneObject1);
772
      end;
773
   end;
774

775
   EnableAndDisableActions();
776
   end;
777
end;
778

779
// TreeEditing
780
//
781
procedure TGLSceneEditorForm.TreeEditing(Sender: TObject; Node: TTreeNode;
782
                                         var AllowEdit: Boolean);
783
begin
784
   AllowEdit:=(Node.Level>1);
785
end;
786

787
procedure TGLSceneEditorForm.ShowBehaviours(BaseSceneObject:TGLBaseSceneObject);
788
var
789
  i:integer;
790
begin
791
      BehavioursListView.Items.Clear;
792
      BehavioursListView.Items.BeginUpdate;
793
      if Assigned(BaseSceneObject) then
794
      begin
795
      for i:=0 to BaseSceneObject.Behaviours.Count-1 do
796
      begin
797
        with BehavioursListView.Items.Add do
798
        begin
799
          Caption:=IntToStr(i)+' - '+BaseSceneObject.Behaviours[i].Name;
800
          Data:=BaseSceneObject.Behaviours[i];
801
        end;
802
      end;
803
      end;
804
      BehavioursListView.Items.EndUpdate;
805
end;
806

807
procedure TGLSceneEditorForm.ShowEffects(BaseSceneObject:TGLBaseSceneObject);
808
var
809
  i:integer;
810
begin
811
      EffectsListView.Items.Clear;
812
      EffectsListView.Items.BeginUpdate;
813
      if Assigned(BaseSceneObject) then
814
      begin
815
      for i:=0 to BaseSceneObject.Effects.Count-1 do
816
      begin
817
        with EffectsListView.Items.Add do
818
        begin
819
          caption:=IntToStr(i)+' - '+BaseSceneObject.Effects[i].Name;
820
          Data:=BaseSceneObject.Effects[i];
821
        end;
822
      end;
823
      end;
824
      EffectsListView.Items.EndUpdate;
825
end;
826

827

828
procedure TGLSceneEditorForm.ShowBehavioursAndEffects(BaseSceneObject:TGLBaseSceneObject);
829
begin
830
  ShowBehaviours(BaseSceneObject);
831
  ShowEffects(BaseSceneObject);
832
end;
833

834
// TreeEdited
835
//
836

837
procedure TGLSceneEditorForm.TreeEdited(Sender: TObject; Node: TTreeNode; var S: String);
838

839
var
840
  BaseSceneObject1:TGLBaseSceneObject;
841
begin
842
   if Assigned(FCurrentDesigner) then begin
843
      // renaming a node means renaming a scene object
844
      BaseSceneObject1:=TGLBaseSceneObject(Node.Data);
845
      if FScene.FindSceneObject(S)=nil then
846
        BaseSceneObject1.Name:=S
847
      else
848
      begin
849
       // Messagedlg('A component named '+S+' already exists',mtWarning,[mbok],0);
850
        S:=BaseSceneObject1.Name;
851
      end;
852
      ShowBehavioursAndEffects(BaseSceneObject1);
853

854
      FCurrentDesigner.Modified;
855
   end;
856
end;
857

858
// TreeMouseDown
859
//
860
procedure TGLSceneEditorForm.TreeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
861
begin
862
   FLastMouseDownPos:=Point(X, Y);
863
   Button:=Button;
864
   Shift:=Shift;
865
end;
866

867
// TreeMouseMove
868
//
869
procedure TGLSceneEditorForm.TreeMouseMove(Sender: TObject;
870
  Shift: TShiftState; X, Y: Integer);
871
var
872
   node: TTreeNode;
873
begin
874
   if Shift=[ssLeft] then begin
875
      node:=Tree.Selected;
876
      if Assigned(node) and (node.Level>1) then
877
         if (Abs(FLastMouseDownPos.x-x)>4) or (Abs(FLastMouseDownPos.y-y)>4) then
878
            Tree.BeginDrag(False);
879
   end;
880
end;
881

882
// TreeEnter
883
//
884
procedure TGLSceneEditorForm.TreeEnter(Sender: TObject);
885
begin
886
   if Assigned(FCurrentDesigner) and Assigned(Tree.Selected) then
887
      FCurrentDesigner.SelectOnlyThisComponent(TGLBaseSceneObject(Tree.Selected.Data));
888
   FSelectedItems:=SCENE_SELECTED;
889
   EnableAndDisableActions();
890
end;
891

892
// ACAddCameraExecute
893
//
894
procedure TGLSceneEditorForm.ACAddCameraExecute(Sender: TObject);
895
var
896
   AObject: TGLBaseSceneObject;
897
   Node: TTreeNode;
898
begin
899
   if Assigned(FCurrentDesigner) then begin
900
      AObject:=TGLBaseSceneObject(TGLCamera.Create(FCurrentDesigner.Form));
901
      AObject.Name:=FCurrentDesigner.CreateUniqueComponentName(AObject.ClassName);
902
      FScene.Objects.AddChild(AObject);
903
      Node:=AddNodes(FObjectNode, AObject);
904
      Node.Selected:=True;
905
      FCurrentDesigner.PropertyEditorHook.PersistentAdded(AObject,True);
906
      FCurrentDesigner.Modified;
907
      FCurrentDesigner.SelectOnlyThisComponent(AObject);
908
   end;
909
end;
910

911
// ACDeleteObjectExecute
912
//
913
procedure TGLSceneEditorForm.ACDeleteObjectExecute(Sender: TObject);
914
var
915
	anObject : TGLBaseSceneObject;
916
   allowed, keepChildren : Boolean;
917
   confirmMsg : String;
918
   buttons : TMsgDlgButtons;
919
begin
920
   if FSelectedItems=BEHAVIOURS_SELECTED then begin
921
      DeleteBaseBehaviour(BehavioursListView);
922

923
      FCurrentDesigner.SelectOnlyThisComponent(TGLBaseSceneObject(Tree.Selected.data));
924

925
      ShowBehaviours(TGLBaseSceneObject(Tree.Selected.data));
926
   end else if FSelectedItems=EFFECTS_SELECTED then begin
927
      DeleteBaseBehaviour(EffectsListView);
928

929
      FCurrentDesigner.SelectOnlyThisComponent(TGLBaseSceneObject(Tree.Selected.data));
930

931
      ShowEffects(TGLBaseSceneObject(Tree.Selected.data));
932
   end else if FSelectedItems=SCENE_SELECTED then begin
933
      if Assigned(Tree.Selected) and (Tree.Selected.Level > 1) then begin
934
         anObject:=TGLBaseSceneObject(Tree.Selected.Data);
935
         // ask for confirmation
936
         if anObject.Name<>'' then
937
            ConfirmMsg:='Delete '+anObject.Name
938
         else ConfirmMsg:='Delete the marked object';
939
         buttons:=[mbOK, mbCancel];
940
         // are there children to care for?
941
         // mbAll exist only on Windows ...
942
         {.$IFDEF MSWINDOWS}
943
         if (anObject.Count > 0)  and (not anObject.HasSubChildren) then
944
         begin
945
            confirmMsg:=ConfirmMsg+' only or with ALL its children?';
946
            buttons:=[mbAll]+Buttons;
947
         end else confirmMsg:=confirmMsg+'?';
948
         {.$ENDIF}
949
         case MessageDlg(confirmMsg, mtConfirmation, buttons, 0) of
950
           {.$IFDEF MSWINDOWS}
951
            mrAll : begin
952
               keepChildren:=False;
953
               allowed:=True;
954
            end;
955
            {.$ENDIF}
956
            mrOK : begin
957
               keepChildren:=True;
958
               allowed:=True;
959
            end;
960
            mrCancel : begin
961
               allowed:=False;
962
               keepChildren:=True;
963
            end;
964
         else
965
            allowed:=False;
966
            keepChildren:=True;
967
         end;
968
         // deletion allowed?
969
         if allowed then begin
970
            if keepChildren=true then
971
               while Tree.Selected.Count>0 do
972
             Tree.Selected.Items[0].MoveTo(Tree.Selected,naAdd);
973
            //previous line should be "naInsert" if children are to remain in position of parent
974
            // (would require changes to TGLBaseSceneObject.Remove)
975
            Tree.Selected.Free;
976
            GlobalDesignHook.Unselect(anObject);
977
            anObject.Parent.Remove(anObject, keepChildren);
978
            FCurrentDesigner.Modified;
979
            GlobalDesignHook.DeletePersistent(TPersistent(anObject));
980
         end
981
      end;
982
   end;
983
end;
984

985
function FindListViewData(list : TListView; data : Pointer) : TListItem;
986
var
987
   i : Integer;
988
begin
989
   Result:=nil;
990
   for i:=0 to list.Items.Count-1 do
991
      if list.Items[i].Data = data then begin
992
         Result:=list.Items[i];
993
         Break;
994
      end;
995
end;
996

997
// ACMoveUpExecute
998
//
999
procedure TGLSceneEditorForm.ACMoveUpExecute(Sender: TObject);
1000
var
1001
   node : TTreeNode;
1002
   prevData:Pointer;
1003
begin
1004
  if FSelectedItems=BEHAVIOURS_SELECTED then
1005
  begin
1006
        PrevData:=BehavioursListView.Selected.Data;
1007
        TGLBaseBehaviour(PrevData).MoveUp;
1008
        ShowBehaviours(TGLBaseSceneObject(Tree.Selected.Data));
1009
        BehavioursListView.Selected:=FindListViewData(BehavioursListView, PrevData);
1010
        FCurrentDesigner.Modified;
1011
  end
1012
  else if FSelectedItems=EFFECTS_SELECTED then
1013
  begin
1014
        PrevData:=EffectsListView.Selected.Data;
1015
        TGLBaseBehaviour(PrevData).MoveUp;
1016
        ShowEffects(TGLBaseSceneObject(Tree.Selected.Data));
1017
        EffectsListView.Selected:=FindListViewData(EffectsListView, PrevData);
1018
        FCurrentDesigner.Modified;
1019
  end
1020
  else if FSelectedItems=SCENE_SELECTED then
1021
  begin
1022
   if ACMoveUp.Enabled then begin
1023
      node:=Tree.Selected;
1024
      if Assigned(node) then begin
1025
         node.MoveTo(node.GetPrevSibling, naInsert);
1026
         with TGLBaseSceneObject(node.Data) do begin
1027
            MoveUp;
1028
            Update;
1029
         end;
1030
         TreeChange(Self, node);
1031
         FCurrentDesigner.Modified;
1032
      end;
1033
   end;
1034
  end; 
1035
end;
1036

1037
// ACMoveDownExecute
1038
//
1039
procedure TGLSceneEditorForm.ACMoveDownExecute(Sender: TObject);
1040
var
1041
   node : TTreeNode;
1042
   prevData:Pointer;
1043
begin
1044
  if FSelectedItems=BEHAVIOURS_SELECTED then
1045
  begin
1046
        PrevData:=BehavioursListView.Selected.Data;
1047
        TGLBaseBehaviour(PrevData).MoveDown;
1048
        ShowBehaviours(TGLBaseSceneObject(Tree.Selected.Data));
1049
        BehavioursListView.Selected:=FindListViewData(BehavioursListView, PrevData);
1050
        FCurrentDesigner.Modified;
1051
  end
1052
  else if FSelectedItems=EFFECTS_SELECTED then
1053
  begin
1054
        PrevData:=EffectsListView.Selected.Data;
1055
        TGLBaseBehaviour(PrevData).MoveDown;
1056
        ShowEffects(TGLBaseSceneObject(Tree.Selected.Data));
1057
        EffectsListView.Selected:=FindListViewData(EffectsListView, PrevData);
1058
        FCurrentDesigner.Modified;
1059
  end
1060
  else if FSelectedItems=SCENE_SELECTED then
1061
  begin
1062
   if ACMoveDown.Enabled then begin
1063
      node:=Tree.Selected;
1064
      if Assigned(node) then begin
1065
         node.GetNextSibling.MoveTo(node, naInsert);
1066
         with TGLBaseSceneObject(node.Data) do begin
1067
				MoveDown;
1068
            Update;
1069
         end;
1070
			TreeChange(Self, node);
1071
         FCurrentDesigner.Modified;
1072
		end;
1073
	end;
1074
      end;
1075
end;
1076

1077
// ACAddObjectExecute
1078
//
1079
procedure TGLSceneEditorForm.ACAddObjectExecute(Sender: TObject);
1080
begin
1081
  TBAddObjects.CheckMenuDropdown;
1082
end;
1083

1084
procedure TGLSceneEditorForm.ACStayOnTopExecute(Sender: TObject);
1085
begin
1086
  if TBStayOnTop.Down then
1087
    FormStyle := fsStayOnTop
1088
  else
1089
    FormStyle := fsNormal;
1090
end;
1091

1092
// ACSaveSceneExecute
1093
//
1094
procedure TGLSceneEditorForm.ACSaveSceneExecute(Sender: TObject);
1095
begin
1096
	if SaveDialog.Execute then
1097
		FScene.SaveToFile(SaveDialog.FileName);
1098
end;
1099

1100
// ACLoadSceneExecute
1101
//
1102
procedure TGLSceneEditorForm.ACLoadSceneExecute(Sender: TObject);
1103
begin
1104
	if OpenDialog.Execute then begin
1105
		FScene.LoadFromFile(OpenDialog.FileName);
1106
		ResetTree;
1107
		ReadScene;
1108
                ShowBehavioursAndEffects(nil);
1109
	end;
1110
end;
1111

1112
// ACInfoExecute
1113
//
1114
procedure TGLSceneEditorForm.ACInfoExecute(Sender: TObject);
1115
var
1116
	AScene: TGLSceneViewer;
1117
begin
1118
	AScene:=TGLSceneViewer.Create(Self);
1119
	AScene.Name:='GLSceneEditor';
1120
	AScene.Width:=0;
1121
	AScene.Height:=0;
1122
	AScene.Parent:=Self;
1123
	try
1124
		AScene.Buffer.ShowInfo;
1125
	finally
1126
		AScene.Free;
1127
	end;
1128
end;
1129

1130
// IsValidClipBoardNode
1131
//
1132
function TGLSceneEditorForm.IsValidClipBoardNode : Boolean;
1133
var
1134
   selNode : TTreeNode;
1135
begin
1136
   selNode:=Tree.Selected;
1137
   Result:=((selNode<>nil) and (selNode.Parent<>nil)
1138
            and (selNode.Parent.Parent<>nil));
1139
end;
1140

1141
// IsPastePossible
1142
//
1143
function TGLSceneEditorForm.IsPastePossible : Boolean;
1144
{$IFDEF GLS_DELPHI_6_UP}
1145

1146
   function PossibleStream(const S: string): Boolean;
1147
   var
1148
     I: Integer;
1149
   begin
1150
     Result := True;
1151
     for I := 1 to Length(S) - 6 do begin
1152
       if (S[I] in ['O','o']) and (CompareText(Copy(S, I, 6), 'OBJECT') = 0) then Exit;
1153
       if not (S[I] in [' ',#9, #13, #10]) then Break;
1154
     end;
1155
     Result := False;
1156
   end;
1157

1158
var
1159
   selNode : TTreeNode;
1160
	anObject, destination : TGLBaseSceneObject;
1161
   ComponentList: IDesignerSelections;
1162
   TmpContainer : TComponent;
1163
begin
1164
   selNode:=Tree.Selected;
1165

1166
   if (selNode<>nil) and (selNode.Parent<>nil)
1167
      {$IFDEF MSWINDOWS}
1168
      and (ClipBoard.HasFormat(CF_COMPONENT) or (Clipboard.HasFormat(CF_TEXT) and
1169
      PossibleStream(Clipboard.AsText))) {$ENDIF} then
1170
      begin
1171
      TmpContainer := TComponent.Create(self);
1172
      try
1173
         ComponentList := TDesignerSelections.Create;
1174
         PasteComponents(TmpContainer, TmpContainer, ComponentList);
1175
         if (ComponentList.Count>0) and (ComponentList[0] is TGLBaseSceneObject) then begin
1176
            anObject:=TGLBaseSceneObject(ComponentList[0]);
1177
            destination:=TGLBaseSceneObject(selNode.Data);
1178
            Result:=CanPaste(anObject, destination);
1179
         end else Result:=False;
1180
      finally
1181
         TmpContainer.Free;
1182
      end;
1183
   end else Result:=False;
1184
{$ELSE}
1185
begin
1186
   Result:=False;
1187
{$ENDIF}
1188
end;
1189

1190
// CanPaste
1191
//
1192
{$IFDEF GLS_DELPHI_6_UP}
1193
function TGLSceneEditorForm.CanPaste(obj, destination : TGLBaseSceneObject) : Boolean;
1194
begin
1195
   Result:= Assigned(obj) and Assigned(destination);
1196
end;
1197
{$ENDIF}
1198

1199
// ACCopyExecute
1200
//
1201
procedure TGLSceneEditorForm.ACCopyExecute(Sender: TObject);
1202
{$IFDEF GLS_DELPHI_6_UP}
1203
var
1204
   ComponentList: IDesignerSelections;
1205
begin
1206
   ComponentList := TDesignerSelections.Create;
1207
   ComponentList.Add(TGLBaseSceneObject(Tree.Selected.Data));
1208
   CopyComponents(FScene.Owner, ComponentList);
1209
   ACPaste.Enabled:=IsPastePossible;
1210
{$ELSE}
1211
begin
1212
{$ENDIF}
1213
end;
1214

1215
// ACCutExecute
1216
//
1217
procedure TGLSceneEditorForm.ACCutExecute(Sender: TObject);
1218
{$IFDEF GLS_DELPHI_6_UP}
1219
var
1220
  AObject: TGLBaseSceneObject;
1221
  ComponentList: IDesignerSelections;
1222
begin
1223
  if IsValidClipBoardNode then
1224
  begin
1225
    AObject := TGLBaseSceneObject(Tree.Selected.Data);
1226
    ComponentList := TDesignerSelections.Create;
1227
    ComponentList.Add(TGLBaseSceneObject(Tree.Selected.Data));
1228

1229
    CopyComponents(FScene.Owner, ComponentList);
1230
    AObject.Parent.Remove(AObject, False);
1231
    AObject.Free;
1232
    Tree.Selected.Free;
1233
    ACPaste.Enabled:=IsPastePossible;
1234
  end;
1235
{$ELSE}
1236
begin
1237
{$ENDIF}
1238
end;
1239

1240

1241
// ACPasteExecute
1242
//
1243
procedure TGLSceneEditorForm.ACPasteExecute(Sender: TObject);
1244
{$IFDEF GLS_DELPHI_6_UP}
1245
var
1246
   selNode : TTreeNode;
1247
	destination : TGLBaseSceneObject;
1248
   ComponentList: IDesignerSelections;
1249
   t: integer;
1250
begin
1251
   selNode:=Tree.Selected;
1252
   if (selNode<>nil) and (selNode.Parent<>nil) then begin
1253
      destination:=TGLBaseSceneObject(selNode.Data);
1254
      ComponentList := TDesignerSelections.Create;
1255
      PasteComponents(FScene.Owner, destination, ComponentList);
1256
      if (ComponentList.count>0) and (CanPaste(TGLBaseSCeneObject(ComponentList[0]), destination)) then begin
1257
         for t :=0 to ComponentList.Count-1 do
1258
            AddNodes(selNode, TGLBaseSCeneObject(ComponentList[t]) );
1259
         selNode.Expand(False);
1260
      end;
1261
      FCurrentDesigner.Modified;
1262
   end;
1263
{$ELSE}
1264
begin
1265
{$ENDIF}
1266
end;
1267

1268
{$IFDEF GLS_DELPHI_6_UP}
1269
// CopyComponents
1270
//
1271
procedure TGLSceneEditorForm.CopyComponents(Root: TComponent; const Components: IDesignerSelections);
1272
var
1273
  S: TMemoryStream;
1274
  W: TWriter;
1275
  I: Integer;
1276
begin
1277
  S := TMemoryStream.Create;
1278
  try
1279
    W := TWriter.Create(S, 1024);
1280
    try
1281
      W.Root := Root;
1282
      for I := 0 to Components.Count - 1 do
1283
      begin
1284
        W.WriteSignature;
1285
        W.WriteComponent(TComponent(Components[I]));
1286
      end;
1287
      W.WriteListEnd;
1288
    finally
1289
      W.Free;
1290
    end;
1291
    CopyStreamToClipboard(S);
1292
  finally
1293
    S.Free;
1294
  end;
1295
end;
1296

1297
procedure TGLSceneEditorForm.MethodError(Reader: TReader;
1298
      const MethodName: String; var Address: Pointer; var Error: Boolean);
1299
begin
1300
   // error is true because Address is nil in csDesigning
1301
   Error:=false;
1302
end;
1303

1304
procedure TGLSceneEditorForm.PasteComponents(AOwner, AParent: TComponent;const Components: IDesignerSelections);
1305
var
1306
  S: TStream;
1307
  R: TReader;
1308
begin
1309
  S := GetClipboardStream;
1310
  try
1311
    R := TReader.Create(S, 1024);
1312
    try
1313
      R.OnSetName := ReaderSetName;
1314
      R.OnFindMethod := MethodError;
1315
      FPasteOwner := AOwner;
1316
      FPasteSelection := Components;
1317
      R.ReadComponents(AOwner, AParent, ComponentRead);
1318
    finally
1319
      R.Free;
1320
    end;
1321
  finally
1322
    S.Free;
1323
  end;
1324
end;
1325

1326
procedure TGLSceneEditorForm.ReaderSetName(Reader: TReader; Component: TComponent; var Name: string);
1327
begin
1328
  if (Reader.Root = FPasteOwner) and (FPasteOwner.FindComponent(Name) <> nil) then
1329
    Name := UniqueName(Component);
1330
end;
1331

1332
function TGLSceneEditorForm.UniqueName(Component: TComponent): string;
1333
begin
1334
  Result := FCurrentDesigner.CreateUniqueComponentName(Component.ClassName);
1335
end;
1336

1337
procedure TGLSceneEditorForm.ComponentRead(Component: TComponent);
1338
begin
1339
   FPasteSelection.Add(Component);
1340
end;
1341
{$ENDIF}
1342

1343
procedure TGLSceneEditorForm.BehavioursListViewClick(Sender: TObject);
1344
begin
1345
   if Assigned(FCurrentDesigner) and Assigned(BehavioursListView.Selected) then
1346
      GlobalDesignHook.SelectOnlyThis(TGLBaseBehaviour(BehavioursListView.Selected.Data));
1347
   FSelectedItems:=BEHAVIOURS_SELECTED;
1348
   EnableAndDisableActions();
1349
end;
1350

1351
procedure TGLSceneEditorForm.EffectsListViewClick(Sender: TObject);
1352
begin
1353
   if Assigned(FCurrentDesigner) and Assigned(EffectsListView.Selected) then
1354
      GlobalDesignHook.SelectOnlyThis(TGLXCollectionItem(EffectsListView.Selected.Data));
1355
   FSelectedItems:=EFFECTS_SELECTED;
1356
   EnableAndDisableActions();
1357
end;
1358

1359
procedure TGLSceneEditorForm.ACAddBehaviourExecute(Sender: TObject);
1360
begin
1361
  TBAddBehaviours.CheckMenuDropdown
1362
end;
1363

1364
procedure TGLSceneEditorForm.DeleteBaseBehaviour(ListView:TListView);
1365
begin
1366
  if ListView.Selected<>nil then
1367
  begin
1368

1369
      GlobalDesignHook.SelectOnlyThis(nil);
1370

1371
      TGLXCollectionItem(ListView.Selected.Data).Free;
1372
      ListView.Selected.Free;
1373
     // ListViewChange(Self, nil, ctState);
1374
     FCurrentDesigner.Modified;
1375
      ShowBehavioursAndEffects(TGLBaseSceneObject(Tree.Selected.Data));
1376
  end;
1377
end;
1378

1379
procedure TGLSceneEditorForm.PMBehavioursToolbarPopup(Sender: TObject);
1380
var
1381
  object1:TGLBaseSceneObject;
1382
begin
1383
   if (Tree.Selected)<>nil then
1384
   begin
1385
     object1:=TGLBaseSceneObject(Tree.Selected.Data);
1386
     SetBehavioursSubItems(PMBehavioursToolbar.Items, object1.Behaviours);
1387
   end;
1388
end;
1389

1390
procedure TGLSceneEditorForm.PMEffectsToolbarPopup(Sender: TObject);
1391
var
1392
  object1:TGLBaseSceneObject;
1393
begin
1394
   if (Tree.Selected)<>nil then
1395
   begin
1396
     object1:=TGLBaseSceneObject(Tree.Selected.Data);
1397
     SetEffectsSubItems(PMEffectsToolbar.Items, object1.Effects);
1398
   end;
1399
end;
1400

1401

1402
procedure TGLSceneEditorForm.BehavioursListViewSelectItem(Sender: TObject;
1403
  Item: TListItem; Selected: Boolean);
1404
begin
1405
  EnableAndDisableActions();
1406
  Item := Item;
1407
  Selected:=Selected;
1408
end;
1409

1410
procedure TGLSceneEditorForm.ACAddEffectExecute(Sender: TObject);
1411
begin
1412
   TBAddEffects.CheckMenuDropdown;
1413
end;
1414

1415
procedure TGLSceneEditorForm.EnableAndDisableActions();
1416
var
1417
  SelNode:TTreeNode;
1418
begin
1419
  if FSelectedItems=SCENE_SELECTED then
1420
  begin
1421
      selNode:=Tree.Selected;
1422
      // select in Delphi IDE
1423
      if Assigned(selNode) then
1424
      begin
1425
         if Assigned(selNode.Data) then
1426
            FCurrentDesigner.SelectOnlyThisComponent(TGLBaseSceneObject(selNode.Data))
1427
         else FCurrentDesigner.SelectOnlyThisComponent(FScene);
1428
         // enablings
1429
         ACAddCamera.Enabled:=((selNode=FObjectNode) or selNode.HasAsParent(FObjectNode));
1430
         ACAddObject.Enabled:=((selNode=FObjectNode) or selNode.HasAsParent(FObjectNode));
1431
         ACAddBehaviour.Enabled:=(selNode.HasAsParent(FObjectNode));
1432
         ACAddEffect.Enabled:=(selNode.HasAsParent(FObjectNode));
1433
         ACDeleteObject.Enabled:=(selNode.Level>1);
1434
         ACMoveUp.Enabled:=((selNode.Index>0)and(selNode.Level>1));
1435
         ACMoveDown.Enabled:=((selNode.GetNextSibling<>nil)and(selNode.Level>1));
1436
         ACCut.Enabled:=IsValidClipBoardNode;
1437
         ACPaste.Enabled:=IsPastePossible;
1438

1439
      end
1440
      else
1441
      begin
1442
         ACAddCamera.Enabled:=False;
1443
         ACAddObject.Enabled:=False;
1444
         ACAddBehaviour.Enabled:=False;
1445
         ACAddEffect.Enabled:=False;
1446
         ACDeleteObject.Enabled:=False;
1447
         ACMoveUp.Enabled:=False;
1448
         ACMoveDown.Enabled:=False;
1449
         ACCut.Enabled:=False;
1450
         ACPaste.Enabled:=False;
1451
      end;
1452
//   end;
1453
   ACCopy.Enabled:=ACCut.Enabled;
1454

1455
  end
1456
  else if FSelectedItems=BEHAVIOURS_SELECTED then
1457
  begin
1458
    if (BehavioursListView.Selected<>nil) then
1459
    begin
1460
         GlobalDesignHook.SelectOnlyThis(TGLBaseBehaviour(BehavioursListView.Selected.Data));
1461
         //Writeln('BehavioursListView.Selected.data=',hexStr(BehavioursListView.Selected.data));
1462
         ACDeleteObject.Enabled:=True;
1463
         ACMoveUp.Enabled:=(BehavioursListView.Selected.Index>0);
1464
         ACMoveDown.Enabled:=(BehavioursListView.Selected.Index<BehavioursListView.Selected.Owner.Count-1);
1465
         ACCut.Enabled:=False;
1466
         ACCopy.Enabled:=false;
1467
         ACPaste.Enabled:=False;
1468
    end
1469
      else
1470
      begin
1471
         ACDeleteObject.Enabled:=false;
1472
         ACMoveUp.Enabled:=false;
1473
         ACMoveDown.Enabled:=false;
1474
         ACCut.Enabled:=false;
1475
         ACCopy.Enabled:=false;
1476
         ACPaste.Enabled:=false;
1477
      end;
1478
  end
1479
  else if FSelectedItems=EFFECTS_SELECTED then
1480
  begin
1481
    if (EffectsListView.Selected<>nil)then
1482
    begin
1483
         GlobalDesignHook.SelectOnlyThis(TGLXCollectionItem(EffectsListView.Selected.Data));
1484
         ACDeleteObject.Enabled:=True;
1485
         ACMoveUp.Enabled:=(EffectsListView.Selected.Index>0);
1486
         ACMoveDown.Enabled:=(EffectsListView.Selected.Index<EffectsListView.Selected.Owner.Count-1);
1487
         ACCut.Enabled:=False;
1488
         ACCopy.Enabled:=false;
1489
         ACPaste.Enabled:=False;
1490
    end
1491
      else
1492
      begin
1493
         ACDeleteObject.Enabled:=false;
1494
         ACMoveUp.Enabled:=false;
1495
         ACMoveDown.Enabled:=false;
1496
         ACCut.Enabled:=false;
1497
         ACCopy.Enabled:=false;
1498
         ACPaste.Enabled:=false;
1499
      end;
1500
  end;
1501

1502
end;
1503

1504
procedure TGLSceneEditorForm.PopupMenuPopup(Sender: TObject);
1505
var
1506
   obj : TObject;
1507
   sceneObj : TGLBaseSceneObject;
1508
begin
1509
   if (Tree.Selected)<>nil then begin
1510
      obj:=TObject(Tree.Selected.Data);
1511
      if Assigned(obj) and (obj is TGLBaseSceneObject) then begin
1512
         sceneObj:=TGLBaseSceneObject(obj);
1513
         SetBehavioursSubItems(MIAddBehaviour, sceneObj.Behaviours);
1514
         SetEffectsSubItems(MIAddEffect, sceneObj.Effects);
1515
      end else begin
1516
         SetBehavioursSubItems(MIAddBehaviour, nil);
1517
         SetEffectsSubItems(MIAddEffect, nil);
1518
      end;
1519
   end;
1520
end;
1521

1522
procedure TGLSceneEditorForm.TBEffectsPanelClick(Sender: TObject);
1523
begin
1524
   PABehaviours.Visible:=TBEffectsPanel.Down;
1525
   Splitter.Visible:=TBEffectsPanel.Down;
1526
   if PABehaviours.Visible then
1527
      Width:=Width+PABehaviours.Width
1528
   else Width:=Width-PABehaviours.Width;
1529
end;
1530

1531
procedure TGLSceneEditorForm.TreeKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
1532
begin
1533
  if (Key = glKey_DELETE) and not Tree.IsEditing then begin
1534
    Key := 0;
1535
    ACDeleteObject.Execute;
1536
  end;
1537
  Shift:=Shift;
1538
end;
1539

1540
initialization
1541

1542
  {$I GLSceneEditLCL.lrs}
1543

1544
finalization
1545
  ReleaseGLSceneEditorForm;
1546

1547
end.
1548

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

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

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

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