LZScene

Форк
0
/
GLGui.pas 
1298 строк · 35.5 Кб
1
//
2
// This unit is part of the GLScene Engine https://github.com/glscene
3
//
4
{
5
  In GL windows management classes and structures
6

7
  History :  
8
       15/04/11 - Yar - Added TGLGuiLayout.Assign
9
       16/03/11 - Yar - Fixes after emergence of GLMaterialEx
10
       23/08/10 - Yar - Added OpenGLTokens to uses, replaced OpenGL1x functions to OpenGLAdapter
11
       11/06/10 - YP - Link GUI elements to their parent
12
       06/06/10 - Yar - Fixed warnings
13
       30/03/07 - DaStr - Added $I GLScene.inc, cosmetic changes
14
       17/02/07 - DaStr - TGLGuiElement.Create - vectors creation fixed
15
                          Changed some types from TGLCoordinates to TGLCoordinates2
16
                          Removed some empty lines
17
       16/12/05 - DK - Removed GuiSkinEditorFormUnit dependancy
18
       30/11/04 - DB - Fixed memory leaks (thanks dikoe Kenguru)
19
       16/07/03 - EG - TGLBaseGuiObject moved in along with RecursiveVisible mechanism
20
       25/11/02 - EG - TGLGuiLayout.Clear fix (Sternas Stefanos)
21
       06/09/02 - JAJ - Updated and added to CVS..
22
       01/06/02 - JAJ - Base Unit built..
23
  
24
}
25
unit GLGui;
26

27
interface
28

29
{$I GLScene.inc}
30

31
uses
32
  Classes, SysUtils,
33

34
  GLScene, GLBitmapFont, GLMaterial, GLCrossPlatform, OpenGLTokens, GLContext,
35
  GLPersistentClasses, GLVectorGeometry, GLCoordinates, GLBaseClasses;
36

37
type
38

39
  TGLBaseGuiObject = class(TGLBaseSceneObject)
40
  private
41
    FRecursiveVisible: Boolean;
42
    FWidth: Single;
43
    FHeight: Single;
44

45
  protected
46
    // self notification on hide. Also notifies children.
47
    procedure NotifyHide; dynamic;
48
    // child notification on show. Also notifies children.
49
    procedure NotifyShow; dynamic;
50

51
    procedure SetLeft(const Value: TGLFloat);
52
    function GetLeft: TGLFloat;
53
    procedure SetTop(const Value: TGLFloat);
54
    function GetTop: TGLFloat;
55
    procedure SetWidth(const val: Single);
56
    procedure SetHeight(const val: Single);
57
    procedure SetVisible(aValue: Boolean); override;
58

59
  public
60
    constructor Create(AOwner: TComponent); override;
61

62
    procedure AddChild(AChild: TGLBaseSceneObject); override;
63
    procedure Insert(aIndex: Integer; aChild: TGLBaseSceneObject); override;
64

65
    { GuiComponent Width in 3D world units. }
66
    property Width: Single read FWidth write SetWidth;
67
    { GuiComponent Height in 3D world units. }
68
    property Height: Single read FHeight write SetHeight;
69
    { GuiComponent Left in 3D world units. }
70
    property Left: TGLFloat read GetLeft write SetLeft;
71
    { GuiComponent Top in 3D world units. }
72
    property Top: TGLFloat read GetTop write SetTop;
73

74
    property RecursiveVisible: Boolean read FRecursiveVisible;
75
  end;
76

77
  TGUIAlignments = (GLAlTopLeft, GLAlTop, GLAlTopRight, GLAlLeft, GLAlCenter,
78
    GLAlRight, GLAlBottomLeft, GLAlBottom, GLAlBottomRight, GLAlBorder);
79
  TGUIRect = record
80
    X1: TGLFloat;
81
    Y1: TGLFloat;
82
    X2: TGLFloat;
83
    Y2: TGLFloat;
84
    XTiles: TGLFloat;
85
    YTiles: TGLFloat;
86
  end;
87
  TGUIDrawResult = array[TGUIAlignments] of TGUIRect;
88

89
  TGLGuiElementName = string;
90
  TGLGuiElement = class(TCollectionItem)
91
  private
92
    FTopLeft: TGLCoordinates2;
93
    FBottomRight: TGLCoordinates2;
94
    FScale: TGLCoordinates2;
95
    FAlign: TGUIAlignments;
96
    FName: TGLGuiElementName;
97
  protected
98
    function GetDisplayName: string; override;
99
    procedure SetName(const val: TGLGuiElementName);
100
  public
101
    constructor Create(Collection: TCollection); override;
102
    destructor Destroy; override;
103
    procedure AssignTo(Dest: TPersistent); override;
104
  published
105
    property TopLeft: TGLCoordinates2 read FTopLeft write FTopLeft;
106
    property BottomRight: TGLCoordinates2 read FBottomRight write FBottomRight;
107
    property Scale: TGLCoordinates2 read FScale write FScale;
108
    property Align: TGUIAlignments read FAlign write FAlign;
109
    property Name: TGLGuiElementName read FName write SetName;
110
  end;
111

112
  TGLGuiComponent = class;
113

114
  TGLGuiElementList = class(TOwnedCollection)
115
  private
116
    FGuiComponent: TGLGuiComponent;
117
  protected
118
    procedure SetItems(index: Integer; const val: TGLGuiElement);
119
    function GetItems(index: Integer): TGLGuiElement;
120
  public
121
    constructor Create(AOwner: TGLGuiComponent);
122
    procedure AssignTo(Dest: TPersistent); override;
123

124
    function GetOwner: TPersistent; override;
125
    function IndexOf(const Item: TGLGuiElement): Integer;
126
    property Items[index: Integer]: TGLGuiElement read GetItems write SetItems;
127
      default;
128
  end;
129

130
  TGLGuiComponentName = string;
131

132
  TGLGuiComponentList = class;
133
  TGLGuiComponent = class(TCollectionItem)
134
  private
135
    FElements: TGLGuiElementList;
136
    FName: TGLGuiComponentName;
137
  protected
138
    function GetDisplayName: string; override;
139
    procedure SetName(const val: TGLGuiComponentName);
140
  public
141
    constructor Create(Collection: TCollection); override;
142
    destructor Destroy; override;
143
    procedure AssignTo(Dest: TPersistent); override;
144
    procedure RenderToArea(X1, Y1, X2, Y2: TGLFloat; var Res: TGUIDrawResult;
145
      Refresh: Boolean = True; Scale: TGLFloat = 1);
146
    function GetOwnerList: TGLGuiComponentList;
147
    property Owner: TGLGuiComponentList read GetOwnerList;
148
  published
149
    property Elements: TGLGuiElementList read FElements write FElements;
150
    property Name: TGLGuiComponentName read FName write SetName;
151
  end;
152

153
  TGLGuiLayout = class;
154
  TGLGuiComponentList = class(TOwnedCollection)
155
  private
156
    FLayout: TGLGuiLayout;
157
  protected
158
    procedure SetItems(index: Integer; const val: TGLGuiComponent);
159
    function GetItems(index: Integer): TGLGuiComponent;
160
  public
161
    constructor Create(AOwner: TGLGuiLayout);
162

163
    function GetOwner: TPersistent; override;
164
    function FindItem(name: TGLGuiComponentName): TGLGuiComponent;
165
    property Items[index: Integer]: TGLGuiComponent read GetItems write
166
      SetItems; default;
167
  end;
168

169
  TGLGuiLayout = class(TGLUpdateableComponent)
170
  private
171
    FBitmapFont: TGLCustomBitmapFont;
172
    FMaterial: TGLMaterial;
173
    FGuiComponents: TGLGuiComponentList;
174
    FFileName: string;
175
    FGuiComponentList: TList;
176
  protected
177
    procedure Notification(AComponent: TComponent; Operation: TOperation);
178
      override;
179

180
    procedure SetFileName(newName: string);
181
  public
182
    constructor Create(AOwner: TComponent); override;
183
    destructor Destroy; override;
184
    procedure Assign(Source: TPersistent); override;
185

186
    procedure LoadFromStream(Stream: TStream);
187
    procedure LoadFromFile(FN: string);
188

189
    procedure Clear;
190

191
    procedure SaveToStream(Stream: TStream);
192
    procedure SaveToFile(FN: string);
193
    procedure AddGuiComponent(Component: TGLUpdateableComponent);
194
    procedure RemoveGuiComponent(Component: TGLUpdateableComponent);
195

196
    procedure NotifyChange(Sender: TObject); override;
197
  published
198
    property BitmapFont: TGLCustomBitmapFont read FBitmapFont write FBitmapFont;
199
    property Material: TGLMaterial read FMaterial write FMaterial;
200
    property GuiComponents: TGLGuiComponentList read FGuiComponents write
201
      FGuiComponents;
202
    property FileName: string read FFileName write SetFileName;
203
  end;
204

205
const
206
  GuiNullRect: TGUIRect = (X1: 0.0; Y1: 0.0; X2: 0.0; Y2: 0.0; XTiles: 0.0;
207
    YTiles: 0.0);
208

209
function IsInRect(const R: TGUIRect; X, Y: Single): Boolean;
210

211
implementation
212

213
function IsInRect(const R: TGUIRect; X, Y: Single): Boolean;
214

215
begin
216
  Result := (R.X1 <= X) and (R.X2 >= X) and (R.Y1 <= Y) and (R.Y2 >= Y);
217
end;
218

219
// ------------------
220
// ------------------ TGLBaseGuiObject ------------------
221
// ------------------
222

223
// Create
224
//
225

226
constructor TGLBaseGuiObject.Create(AOwner: TComponent);
227
begin
228
  inherited Create(AOwner);
229
  FRecursiveVisible := Visible;
230
end;
231

232
// SetLeft
233
//
234

235
procedure TGLBaseGuiObject.SetLeft(const Value: TGLFloat);
236
var
237
  NewPosX: TGLFloat;
238
  i: integer;
239
  Diff: TGLFloat;
240
begin
241
  if Assigned(Parent) and (Parent is TGLBaseGuiObject) then
242
    NewPosX := (Parent as TGLBaseGuiObject).Position.X + Value
243
  else
244
    NewPosX := Value;
245

246
  if Position.X <> NewPosX then
247
  begin
248
    Diff := NewPosX - Position.X;
249
    Position.X := NewPosX;
250

251
    for i := 0 to Count - 1 do
252
      if Children[i] is TGLBaseGuiObject then
253
      begin
254
        (Children[i] as TGLBaseGuiObject).Left := (Children[i] as
255
          TGLBaseGuiObject).Left + Diff;
256
      end;
257
  end;
258
end;
259

260
// GetLeft
261
//
262

263
function TGLBaseGuiObject.GetLeft: TGLFloat;
264
begin
265
  if Assigned(Parent) and (Parent is TGLBaseGuiObject) then
266
    Result := Position.X - (Parent as TGLBaseGuiObject).Position.X
267
  else
268
    Result := Position.X;
269
end;
270

271
// SetTop
272
//
273

274
procedure TGLBaseGuiObject.SetTop(const Value: TGLFloat);
275
var
276
  NewPosY: TGLFloat;
277
  i: integer;
278
  Diff: TGLFloat;
279
begin
280
  if Assigned(Parent) and (Parent is TGLBaseGuiObject) then
281
    NewPosY := (Parent as TGLBaseGuiObject).Position.Y + Value
282
  else
283
    NewPosY := Value;
284

285
  if Position.Y <> NewPosY then
286
  begin
287
    Diff := NewPosY - Position.Y;
288
    Position.Y := NewPosY;
289

290
    for i := 0 to Count - 1 do
291
      if Children[i] is TGLBaseGuiObject then
292
      begin
293
        (Children[i] as TGLBaseGuiObject).Top := (Children[i] as
294
          TGLBaseGuiObject).Top + Diff;
295
      end;
296
  end;
297
end;
298

299
// GetTop
300
//
301

302
function TGLBaseGuiObject.GetTop: TGLFloat;
303
begin
304
  if Assigned(Parent) and (Parent is TGLBaseGuiObject) then
305
    Result := Position.Y - (Parent as TGLBaseGuiObject).Position.Y
306
  else
307
    Result := Position.Y;
308
end;
309

310
// SetWidth
311
//
312

313
procedure TGLBaseGuiObject.SetWidth(const val: TGLFloat);
314
begin
315
  if FWidth <> val then
316
  begin
317
    FWidth := val;
318
    NotifyChange(Self);
319
  end;
320
end;
321

322
// SetHeight
323
//
324

325
procedure TGLBaseGuiObject.SetHeight(const val: TGLFloat);
326
begin
327
  if FHeight <> val then
328
  begin
329
    FHeight := val;
330
    NotifyChange(Self);
331
  end;
332
end;
333

334
// NotifyHide
335
//
336

337
procedure TGLBaseGuiObject.NotifyHide;
338
var
339
  child: TGLBaseSceneObject;
340
  xc: Integer;
341
begin
342
  if RecursiveVisible then
343
  begin
344
    FRecursiveVisible := False;
345
    for xc := 0 to Count - 1 do
346
    begin
347
      child := Children[xc];
348
      if child is TGLBaseGuiObject then
349
        TGLBaseGuiObject(child).NotifyHide;
350
    end;
351
  end;
352
end;
353

354
// NotifyShow
355
//
356

357
procedure TGLBaseGuiObject.NotifyShow;
358
var
359
  child: TGLBaseSceneObject;
360
  xc: Integer;
361
begin
362
  if not RecursiveVisible then
363
  begin
364
    FRecursiveVisible := True;
365
    for xc := 0 to Count - 1 do
366
    begin
367
      child := Children[xc];
368
      if child is TGLBaseGuiObject then
369
        TGLBaseGuiObject(child).NotifyShow;
370
    end;
371
  end;
372
end;
373

374
// AddChild
375
//
376

377
procedure TGLBaseGuiObject.AddChild(aChild: TGLBaseSceneObject);
378
begin
379
  inherited;
380
  if AChild is TGLBaseGuiObject then
381
  begin
382
    if RecursiveVisible then
383
      TGLBaseGuiObject(AChild).NotifyShow
384
    else
385
      TGLBaseGuiObject(AChild).NotifyHide;
386
  end;
387
end;
388

389
// Insert
390
//
391

392
procedure TGLBaseGuiObject.Insert(aIndex: Integer; aChild: TGLBaseSceneObject);
393
begin
394
  inherited;
395
  if AChild is TGLBaseGuiObject then
396
  begin
397
    if RecursiveVisible then
398
      TGLBaseGuiObject(AChild).NotifyShow
399
    else
400
      TGLBaseGuiObject(AChild).NotifyHide;
401
  end;
402
end;
403

404
// SetVisible
405
//
406

407
procedure TGLBaseGuiObject.SetVisible(aValue: Boolean);
408
begin
409
  if Visible <> aValue then
410
  begin
411
    inherited SetVisible(aValue);
412
    if aValue then
413
    begin
414
      if Parent <> nil then
415
        if Parent is TGLBaseGuiObject then
416
        begin
417
          if TGLBaseGuiObject(Parent).RecursiveVisible then
418
            NotifyShow;
419
        end
420
        else
421
        begin
422
          if Parent.Visible then
423
            NotifyShow;
424
        end;
425
    end
426
    else
427
    begin
428
      if RecursiveVisible then
429
        NotifyHide;
430
    end;
431
  end;
432
end;
433

434
constructor TGLGuiLayout.Create(AOwner: TComponent);
435
begin
436
  FGuiComponentList := TList.Create;
437
  inherited;
438
  FGuiComponents := TGLGuiComponentList.Create(Self);
439
  FMaterial := TGLMaterial.Create(Self);
440
end;
441

442
destructor TGLGuiLayout.Destroy;
443
begin
444
  Clear;
445
  FMaterial.Free;
446
  FGuiComponents.Free;
447
  inherited;
448
  FGuiComponentList.Free;
449
end;
450

451
procedure TGLGuiLayout.SetFileName(newName: string);
452
begin
453
  if newName <> FFileName then
454
  begin
455
    FFileName := newName;
456
    if FileExists(FFileName) then
457
    begin
458
      Clear;
459
      loadFromFile(FFileName);
460
    end;
461
  end;
462
end;
463

464
procedure TGLGuiLayout.LoadFromFile(FN: string);
465
var
466
  Stream: TMemoryStream;
467

468
begin
469
  Stream := TMemoryStream.Create;
470
  try
471
    Stream.LoadFromFile(FN);
472
    LoadFromStream(stream);
473
    FFileName := FN;
474
  finally
475
    stream.Free;
476
  end;
477
end;
478

479
procedure TGLGuiLayout.SaveToFile(FN: string);
480
var
481
  Stream: TMemoryStream;
482
begin
483
  Stream := TMemoryStream.Create;
484
  try
485
    SaveToStream(Stream);
486
    Stream.SaveToFile(FN);
487
    FFileName := FN;
488
  finally
489
    Stream.Free;
490
  end;
491
end;
492

493
procedure TGLGuiLayout.AddGuiComponent(Component: TGLUpdateableComponent);
494
begin
495
  if FGuiComponentList.IndexOf(Component) < 0 then
496
  begin
497
    FreeNotification(Component);
498
    FGuiComponentList.Add(Component);
499
  end;
500
end;
501

502
procedure TGLGuiLayout.RemoveGuiComponent(Component: TGLUpdateableComponent);
503
begin
504
  FGuiComponentList.Remove(Component);
505
  RemoveFreeNotification(Component);
506
end;
507

508
procedure TGLGuiLayout.Assign(Source: TPersistent);
509
var
510
  LLayout: TGLGuiLayout;
511
  LComponent: TGLGuiComponent;
512
  I: Integer;
513
begin
514
  if Source is TGLGuiLayout then
515
  begin
516
    LLayout := TGLGuiLayout(Source);
517
    FBitmapFont := LLayout.FBitmapFont;
518
    FMaterial.Assign(LLayout.Material);
519
    FFileName := LLayout.FFileName;
520
    Clear;
521
    for I := 0 to LLayout.FGuiComponents.Count - 1 do
522
    begin
523
      LComponent := TGLGuiComponent(FGuiComponents.Add);
524
      LLayout.FGuiComponents[I].AssignTo(LComponent);
525
      LComponent.Name := LLayout.FGuiComponents[I].Name;
526
    end;
527
    for I := 0 to FGuiComponentList.Count - 1 do
528
      TGLUpdateAbleComponent(FGuiComponentList[I]).RemoveFreeNotification(Self);
529
    FGuiComponentList.Assign(LLayout.FGuiComponentList);
530
    for I := 0 to FGuiComponentList.Count - 1 do
531
      TGLUpdateAbleComponent(FGuiComponentList[I]).FreeNotification(Self);
532
  end
533
  else
534
    inherited; // Assigned Error
535
end;
536

537
procedure TGLGuiLayout.Clear;
538
var
539
  XC: Integer;
540

541
begin
542
  for XC := FGuiComponents.Count - 1 downto 0 do
543
  begin
544
    FGuiComponents.Delete(XC);
545
  end;
546
  NotifyChange(Self);
547
end;
548

549
procedure TGLGuiLayout.NotifyChange(Sender: TObject);
550
var
551
  XC: Integer;
552
begin
553
  inherited;
554

555
  for XC := FGuiComponentList.Count - 1 downto 0 do
556
    TGLUpdateAbleComponent(FGuiComponentList[XC]).NotifyChange(Self);
557
end;
558

559
procedure TGLGuiLayout.LoadFromStream(Stream: TStream);
560

561
var
562
  TmpComponent: TGLGuiComponent;
563
  XC, YC, ZC: Integer;
564
  TmpElement: TGLGuiElement;
565
  TmpAlignment: TGUIAlignments;
566
  Version: Integer;
567
  Data: TBinaryReader;
568

569
begin
570
  Data := TBinaryReader.Create(Stream);
571
  try
572

573
    Version := Data.ReadInteger;
574
    if Version <> 1 then
575
      Exit;
576

577
    for XC := 0 to Data.ReadInteger - 1 do
578
    begin
579
      TmpComponent := FGuiComponents.Add as TGLGuiComponent;
580
      TmpComponent.FName := Data.ReadString;
581
      for YC := 0 to Data.ReadInteger - 1 do
582
      begin
583
        TmpElement := TmpComponent.FElements.add as TGLGuiElement;
584

585
        TmpElement.FName := Data.ReadString;
586

587
        TmpElement.FTopLeft.X := Data.ReadFloat;
588
        TmpElement.FTopLeft.Y := Data.ReadFloat;
589
        TmpElement.FTopLeft.Z := Data.ReadFloat;
590

591
        TmpElement.FBottomRight.X := Data.ReadFloat;
592
        TmpElement.FBottomRight.Y := Data.ReadFloat;
593
        TmpElement.FBottomRight.Z := Data.ReadFloat;
594

595
        TmpElement.FScale.X := Data.ReadFloat;
596
        TmpElement.FScale.Y := Data.ReadFloat;
597
        TmpElement.FScale.Z := Data.ReadFloat;
598

599
        for ZC := 0 to Data.ReadInteger - 1 do
600
        begin
601
          TmpAlignment := TGUIAlignments(Data.ReadInteger);
602
          TmpElement.FAlign := TmpAlignment;
603
        end;
604
      end;
605
    end;
606
  finally
607
    Data.Free;
608
  end;
609
  NotifyChange(Self);
610
end;
611

612
procedure TGLGuiLayout.SaveToStream(stream: TStream);
613
var
614
  TmpComponent: TGLGuiComponent;
615
  Alignments, XC, YC: Integer;
616
  TmpElement: TGLGuiElement;
617
  TmpAlignment: TGUIAlignments;
618
  Data: TBinaryWriter;
619

620
begin
621
  Data := TBinaryWriter.Create(Stream);
622
  try
623
    Data.WriteInteger(1);
624
    Data.WriteInteger(FGuiComponents.Count);
625
    for XC := 0 to FGuiComponents.Count - 1 do
626
    begin
627
      TmpComponent := FGuiComponents.Items[XC];
628
      Data.WriteString(TmpComponent.FName);
629

630
      Data.WriteInteger(TmpComponent.FElements.Count);
631

632
      for YC := 0 to TmpComponent.FElements.Count - 1 do
633
      begin
634
        TmpElement := TmpComponent.FElements.Items[YC];
635

636
        Data.WriteString(TmpElement.FName);
637

638
        Data.WriteFloat(TmpElement.FTopLeft.X);
639
        Data.WriteFloat(TmpElement.FTopLeft.Y);
640
        Data.WriteFloat(TmpElement.FTopLeft.Z);
641

642
        Data.WriteFloat(TmpElement.FBottomRight.X);
643
        Data.WriteFloat(TmpElement.FBottomRight.Y);
644
        Data.WriteFloat(TmpElement.FBottomRight.Z);
645

646
        Data.WriteFloat(TmpElement.FScale.X);
647
        Data.WriteFloat(TmpElement.FScale.Y);
648
        Data.WriteFloat(TmpElement.FScale.Z);
649

650
        Alignments := 0;
651
        for TmpAlignMent := GLAlTopLeft to GLAlBorder do
652
        begin
653
          if TmpAlignMent = TmpElement.FAlign then
654
            inc(Alignments);
655
        end;
656

657
        Data.WriteInteger(Alignments);
658

659
        for TmpAlignMent := GLAlTopLeft to GLAlBorder do
660
        begin
661
          if TmpAlignMent = TmpElement.FAlign then
662
            Data.WriteInteger(Integer(TmpAlignMent));
663
        end;
664
      end;
665
    end;
666
  finally
667
    Data.Free;
668
  end;
669
end;
670

671
constructor TGLGuiComponentList.Create(AOwner: TGLGuiLayout);
672
begin
673
  inherited Create(AOwner, TGLGuiComponent);
674
  FLayout := AOwner;
675
end;
676

677
function TGLGuiComponentList.GetOwner: TPersistent;
678
begin
679
  Result := FLayout;
680
end;
681

682
procedure TGLGuiComponentList.SetItems(index: Integer; const val:
683
  TGLGuiComponent);
684
begin
685
  inherited Items[index] := val;
686
end;
687

688
function TGLGuiComponentList.FindItem(name: TGLGuiComponentName):
689
  TGLGuiComponent;
690
var
691
  XC: Integer;
692
  gc: TGLGuiComponent;
693
begin
694
  Result := nil;
695
  if Name = '' then
696
    Exit;
697
  for XC := 0 to Count - 1 do
698
  begin
699
    gc := Items[xc];
700
    if gc.FName = Name then
701
    begin
702
      Result := gc;
703
      Break;
704
    end;
705
  end;
706
end;
707

708
function TGLGuiComponentList.GetItems(index: Integer): TGLGuiComponent;
709
begin
710
  Result := TGLGuiComponent(inherited Items[index]);
711
end;
712

713
procedure TGLGuiComponent.RenderToArea(X1, Y1, X2, Y2: TGLFloat; var Res:
714
  TGUIDrawResult; Refresh: Boolean = True; Scale: TGLFloat = 1);
715
var
716
  XC: Integer;
717
  ThisElement: TGLGuiElement;
718
  W, H: TGLFloat;
719
  Len1, Len2: TGLFloat;
720
  Layout: TGLGuiLayout;
721
  LibMaterial: TGLLibMaterial;
722
  Material: TGLMaterial;
723
  TexWidth,
724
    TexHeight: TGLFloat;
725
  AlignCount: TGUIAlignments;
726

727
  procedure Prepare;
728
  begin
729
    Len1 := (ThisElement.FTopLeft.x - ThisElement.FBottomRight.x) *
730
      ThisElement.Scale.X * Scale;
731
    Len2 := (ThisElement.FTopLeft.y - ThisElement.FBottomRight.y) *
732
      ThisElement.Scale.Y * Scale;
733
    if Len1 < 0 then
734
    begin
735
      if Len2 < 0 then
736
      begin
737
        W := -Len1;
738
        H := -Len2;
739
      end
740
      else
741
      begin
742
        W := -Len1;
743
        H := Len2;
744
      end;
745
    end
746
    else
747
    begin
748
      if Len2 < 0 then
749
      begin
750
        W := Len1;
751
        H := -Len2;
752
      end
753
      else
754
      begin
755
        W := Len1;
756
        H := Len2;
757
      end;
758
    end;
759
  end;
760

761
  procedure RenderIt(var ARect: TGuiRect; AElement: TGLGuiElement);
762
  var
763
    XC: TGLFloat;
764
    YC: TGLFloat;
765
    XPos, X2Pos: TGLFloat;
766
    YPos, y2Pos: TGLFloat;
767
    tx1, ty1, tx2, ty2: TGLFloat;
768
    XTileSize, YTileSize: TGLFloat;
769
    tx3, ty3: TGLFloat;
770
    tx, ty: TGLFloat;
771

772
  begin
773
    if (ARect.XTiles = 1) and (ARect.YTiles = 1) then
774
    begin
775
      GL.TexCoord2f(AElement.TopLeft.X / TexWidth, -AElement.TopLeft.Y /
776
        TexHeight);
777
      GL.Vertex2f(ARect.X1, -ARect.Y1);
778

779
      GL.TexCoord2f(AElement.TopLeft.X / TexWidth, -AElement.BottomRight.Y /
780
        TexHeight);
781
      GL.Vertex2f(ARect.X1, -ARect.Y2);
782

783
      GL.TexCoord2f(AElement.BottomRight.X / TexWidth, -AElement.BottomRight.Y /
784
        TexHeight);
785
      GL.Vertex2f(ARect.X2, -ARect.Y2);
786

787
      GL.TexCoord2f(AElement.BottomRight.X / TexWidth, -AElement.TopLeft.Y /
788
        TexHeight);
789
      GL.Vertex2f(ARect.X2, -ARect.Y1);
790
    end
791
    else
792
    begin
793
      XTileSize := (ARect.X2 - ARect.X1) / ARect.XTiles;
794
      YTileSize := (ARect.Y2 - ARect.Y1) / ARect.YTiles;
795
      tx1 := AElement.TopLeft.X / TexWidth;
796
      ty1 := -AElement.TopLeft.Y / TexHeight;
797
      tx2 := AElement.BottomRight.X / TexWidth;
798
      ty2 := -AElement.BottomRight.Y / TexHeight;
799
      tx3 := (AElement.TopLeft.X + (AElement.BottomRight.X - AElement.TopLeft.X)
800
        * Frac(ARect.XTiles)) / TexWidth;
801
      ty3 := -(AElement.TopLeft.y + (AElement.BottomRight.y - AElement.TopLeft.y)
802
        * Frac(ARect.yTiles)) / TexHeight;
803

804
      XC := ARect.XTiles;
805
      XPos := ARect.X1;
806
      tx := tx2;
807
      while XC > 0 do
808
      begin
809
        YC := ARect.YTiles;
810
        YPos := ARect.Y1;
811
        ty := ty2;
812

813
        if XC >= 1 then
814
          X2Pos := XPos + XTileSize
815
        else
816
        begin
817
          X2Pos := ARect.X2;
818
          tx := tx3;
819
        end;
820

821
        while YC > 0 do
822
        begin
823
          if YC >= 1 then
824
            Y2Pos := YPos + YTileSize
825
          else
826
          begin
827
            Y2Pos := ARect.Y2;
828
            ty := ty3;
829
          end;
830

831
          GL.TexCoord2f(tx1, ty1);
832
          GL.Vertex2f(XPos, -YPos);
833

834
          GL.TexCoord2f(tx1, ty);
835
          GL.Vertex2f(XPos, -Y2Pos);
836

837
          GL.TexCoord2f(tx, ty);
838
          GL.Vertex2f(X2Pos, -Y2Pos);
839

840
          GL.TexCoord2f(tx, ty1);
841
          GL.Vertex2f(X2Pos, -YPos);
842
          yc := yc - 1.0;
843
          ypos := Y2Pos;
844
        end;
845
        xc := xc - 1.0;
846
        xpos := X2Pos;
847
      end;
848
    end;
849
  end;
850

851
  procedure RenderBorder(AElement: TGLGuiElement);
852
  var
853
    TmpElement: TGLGuiElement;
854

855
  begin
856
    TmpElement := TGLGuiElement.Create(nil);
857
    TmpElement.FTopLeft.X := ThisElement.FTopLeft.X;
858
    TmpElement.FTopLeft.Y := ThisElement.FTopLeft.Y;
859
    TmpElement.FBottomRight.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
860
    TmpElement.FBottomRight.Y := ThisElement.FTopLeft.Y + ThisElement.Scale.Y;
861
    TmpElement.Scale.SetPoint2D(1, 1);
862
    RenderIt(Res[GLALTopLeft], TmpElement);
863

864
    TmpElement.FTopLeft.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
865
    TmpElement.FBottomRight.X := ThisElement.FBottomRight.X -
866
      ThisElement.Scale.X;
867
    RenderIt(Res[GLALTop], TmpElement);
868

869
    TmpElement.FTopLeft.X := ThisElement.FBottomRight.X - ThisElement.Scale.X;
870
    TmpElement.FBottomRight.X := ThisElement.FBottomRight.X;
871
    RenderIt(Res[GLALTopRight], TmpElement);
872

873
    TmpElement.FTopLeft.Y := ThisElement.FTopLeft.Y + ThisElement.Scale.Y;
874
    TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y -
875
      ThisElement.Scale.Y;
876
    RenderIt(Res[GLALRight], TmpElement);
877

878
    TmpElement.FTopLeft.X := ThisElement.FBottomRight.X - ThisElement.Scale.X;
879
    TmpElement.FTopLeft.Y := ThisElement.FBottomRight.Y - ThisElement.Scale.Y;
880
    TmpElement.FBottomRight.X := ThisElement.FBottomRight.X;
881
    TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y;
882
    RenderIt(Res[GLALBottomRight], TmpElement);
883

884
    TmpElement.FTopLeft.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
885
    TmpElement.FTopLeft.Y := ThisElement.FBottomRight.Y - ThisElement.Scale.Y;
886
    TmpElement.FBottomRight.X := ThisElement.FBottomRight.X -
887
      ThisElement.Scale.X;
888
    TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y;
889
    RenderIt(Res[GLALBottom], TmpElement);
890

891
    TmpElement.FTopLeft.X := ThisElement.FTopLeft.X;
892
    TmpElement.FTopLeft.Y := ThisElement.FBottomRight.Y - ThisElement.Scale.Y;
893
    TmpElement.FBottomRight.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
894
    TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y;
895
    RenderIt(Res[GLALBottomLeft], TmpElement);
896

897
    TmpElement.FTopLeft.X := ThisElement.FTopLeft.X;
898
    TmpElement.FTopLeft.Y := ThisElement.FTopLeft.Y + ThisElement.Scale.Y;
899
    TmpElement.FBottomRight.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
900
    TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y -
901
      ThisElement.Scale.Y;
902
    RenderIt(Res[GLALLeft], TmpElement);
903

904
    TmpElement.FTopLeft.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
905
    TmpElement.FTopLeft.Y := ThisElement.FTopLeft.Y + ThisElement.Scale.Y;
906
    TmpElement.FBottomRight.X := ThisElement.FBottomRight.X -
907
      ThisElement.Scale.X;
908
    TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y -
909
      ThisElement.Scale.Y;
910
    RenderIt(Res[GLALCenter], TmpElement);
911
  end;
912

913
begin
914
  Layout := ((GetOwner as TGLGuiComponentList).GetOwner as TGLGuiLayout);
915
  Material := nil;
916
  if Assigned(Layout.Material.MaterialLibrary)
917
    and (Layout.Material.MaterialLibrary is TGLMaterialLibrary)
918
    and (Layout.Material.LibMaterialName <> '') then
919
  begin
920
    LibMaterial :=
921
      TGLMaterialLibrary(Layout.Material.MaterialLibrary).Materials.GetLibMaterialByName(Layout.Material.LibMaterialName);
922
    if Assigned(LibMaterial) then
923
      Material := LibMaterial.Material;
924
  end;
925
  if not Assigned(Material) then
926
  begin
927
    Material := Layout.Material;
928
  end;
929

930
  if Refresh then
931
  begin
932
    Res[GLALtopLeft].X1 := X1;
933
    Res[GLALtopLeft].Y1 := Y1;
934
    Res[GLALtopLeft].X2 := X1;
935
    Res[GLALtopLeft].Y2 := Y1;
936

937
    Res[GLALtopRight].X1 := X2;
938
    Res[GLALtopRight].Y1 := Y1;
939
    Res[GLALtopRight].X2 := X2;
940
    Res[GLALtopRight].Y2 := Y1;
941

942
    Res[GLALBottomLeft].X1 := X1;
943
    Res[GLALBottomLeft].Y1 := Y2;
944
    Res[GLALBottomLeft].X2 := X1;
945
    Res[GLALBottomLeft].Y2 := Y2;
946

947
    Res[GLALBottomRight].X1 := X2;
948
    Res[GLALBottomRight].Y1 := Y2;
949
    Res[GLALBottomRight].X2 := X2;
950
    Res[GLALBottomRight].Y2 := Y2;
951

952
    for XC := 0 to FElements.Count - 1 do
953
    begin
954
      ThisElement := FElements[XC];
955
      if GLAlBorder = ThisElement.Align then
956
      begin
957
        Res[GLALtopLeft].X1 := X1;
958
        Res[GLALtopLeft].Y1 := Y1;
959
        Res[GLALtopLeft].X2 := X1 + ThisElement.Scale.X * Scale *
960
          ThisElement.Scale.Z;
961
        Res[GLALtopLeft].Y2 := Y1 + ThisElement.Scale.Y * Scale *
962
          ThisElement.Scale.Z;
963

964
        Res[GLALtop].X1 := X1 + ThisElement.Scale.X * Scale *
965
          ThisElement.Scale.Z;
966
        Res[GLALtop].Y1 := Y1;
967
        Res[GLALtop].X2 := X2 - ThisElement.Scale.X * Scale *
968
          ThisElement.Scale.Z;
969
        Res[GLALtop].Y2 := Y1 + ThisElement.Scale.Y * Scale *
970
          ThisElement.Scale.Z;
971

972
        Res[GLALtopRight].X1 := X2 - ThisElement.Scale.X * Scale *
973
          ThisElement.Scale.Z;
974
        Res[GLALtopRight].Y1 := Y1;
975
        Res[GLALtopRight].X2 := X2;
976
        Res[GLALtopRight].Y2 := Y1 + ThisElement.Scale.Y * Scale *
977
          ThisElement.Scale.Z;
978

979
        Res[GLALRight].X1 := X2 - ThisElement.Scale.X * Scale *
980
          ThisElement.Scale.Z;
981
        Res[GLALRight].Y1 := Y1 + ThisElement.Scale.Y * Scale *
982
          ThisElement.Scale.Z;
983
        Res[GLALRight].X2 := X2;
984
        Res[GLALRight].Y2 := Y2 - ThisElement.Scale.Y * Scale *
985
          ThisElement.Scale.Z;
986

987
        Res[GLALBottomRight].X1 := X2 - ThisElement.Scale.X * Scale *
988
          ThisElement.Scale.Z;
989
        Res[GLALBottomRight].Y1 := Y2 - ThisElement.Scale.Y * Scale *
990
          ThisElement.Scale.Z;
991
        Res[GLALBottomRight].X2 := X2;
992
        Res[GLALBottomRight].Y2 := Y2;
993

994
        Res[GLALBottom].X1 := X1 + ThisElement.Scale.X * Scale *
995
          ThisElement.Scale.Z;
996
        Res[GLALBottom].Y1 := Y2 - ThisElement.Scale.Y * Scale *
997
          ThisElement.Scale.Z;
998
        Res[GLALBottom].X2 := X2 - ThisElement.Scale.X * Scale *
999
          ThisElement.Scale.Z;
1000
        Res[GLALBottom].Y2 := Y2;
1001

1002
        Res[GLALBottomLeft].X1 := X1;
1003
        Res[GLALBottomLeft].Y1 := Y2 - ThisElement.Scale.Y * Scale *
1004
          ThisElement.Scale.Z;
1005
        Res[GLALBottomLeft].X2 := X1 + ThisElement.Scale.X * Scale *
1006
          ThisElement.Scale.Z;
1007
        Res[GLALBottomLeft].Y2 := Y2;
1008

1009
        Res[GLALLeft].X1 := X1;
1010
        Res[GLALLeft].Y1 := Y1 + ThisElement.Scale.Y * Scale *
1011
          ThisElement.Scale.Z;
1012
        Res[GLALLeft].X2 := X1 + ThisElement.Scale.X * Scale *
1013
          ThisElement.Scale.Z;
1014
        Res[GLALLeft].Y2 := Y2 - ThisElement.Scale.Y * Scale *
1015
          ThisElement.Scale.Z;
1016

1017
        Res[GLALCenter].X1 := X1 + ThisElement.Scale.X * Scale *
1018
          ThisElement.Scale.Z;
1019
        Res[GLALCenter].Y1 := Y1 + ThisElement.Scale.Y * Scale *
1020
          ThisElement.Scale.Z;
1021
        Res[GLALCenter].X2 := X2 - ThisElement.Scale.X * Scale *
1022
          ThisElement.Scale.Z;
1023
        Res[GLALCenter].Y2 := Y2 - ThisElement.Scale.Y * Scale *
1024
          ThisElement.Scale.Z;
1025
      end;
1026

1027
      if GLALtopLeft = ThisElement.Align then
1028
      begin
1029
        Prepare;
1030
        Res[GLALtopLeft].X1 := X1;
1031
        Res[GLALtopLeft].Y1 := Y1;
1032
        Res[GLALtopLeft].X2 := X1 + W;
1033
        Res[GLALtopLeft].Y2 := Y1 + H;
1034
      end;
1035
      if GLALtopRight = ThisElement.Align then
1036
      begin
1037
        Prepare;
1038
        Res[GLALtopRight].X1 := X2 - W;
1039
        Res[GLALtopRight].Y1 := Y1;
1040
        Res[GLALtopRight].X2 := X2;
1041
        Res[GLALtopRight].Y2 := Y1 + H;
1042
      end;
1043
      if GLALBottomLeft = ThisElement.Align then
1044
      begin
1045
        Prepare;
1046
        Res[GLALBottomLeft].X1 := X1;
1047
        Res[GLALBottomLeft].Y1 := Y2 - H;
1048
        Res[GLALBottomLeft].X2 := X1 + W;
1049
        Res[GLALBottomLeft].Y2 := Y2;
1050
      end;
1051
      if GLALBottomRight = ThisElement.Align then
1052
      begin
1053
        Prepare;
1054
        Res[GLALBottomRight].X1 := X2 - W;
1055
        Res[GLALBottomRight].Y1 := Y2 - H;
1056
        Res[GLALBottomRight].X2 := X2;
1057
        Res[GLALBottomRight].Y2 := Y2;
1058
      end;
1059
    end;
1060

1061
    Res[GLALtop].X1 := Res[GLALtopLeft].X2;
1062
    Res[GLALtop].Y1 := Res[GLALtopRight].Y1;
1063
    Res[GLALtop].X2 := Res[GLALtopRight].X1;
1064
    Res[GLALtop].Y2 := Res[GLALtopLeft].Y2;
1065

1066
    Res[GLALBottom].X1 := Res[GLALBottomLeft].X2;
1067
    Res[GLALBottom].Y1 := Res[GLALBottomLeft].Y1;
1068
    Res[GLALBottom].X2 := Res[GLALBottomRight].X1;
1069
    Res[GLALBottom].Y2 := Res[GLALBottomRight].Y2;
1070

1071
    Res[GLALLeft].X1 := Res[GLALtopLeft].X1;
1072
    Res[GLALLeft].Y1 := Res[GLALtopLeft].Y2;
1073
    Res[GLALLeft].X2 := Res[GLALBottomLeft].X2;
1074
    Res[GLALLeft].Y2 := Res[GLALBottomLeft].Y1;
1075

1076
    Res[GLALRight].X1 := Res[GLALtopRight].X1;
1077
    Res[GLALRight].Y1 := Res[GLALtopRight].Y2;
1078
    Res[GLALRight].X2 := Res[GLALBottomRight].X2;
1079
    Res[GLALRight].Y2 := Res[GLALBottomRight].Y1;
1080

1081
    for XC := 0 to FElements.Count - 1 do
1082
    begin
1083
      ThisElement := FElements[XC];
1084
      if GLALtop = ThisElement.Align then
1085
      begin
1086
        Prepare;
1087
        Res[GLALtop].Y1 := Y1;
1088
        Res[GLALtop].Y2 := Y1 + H;
1089
      end;
1090
      if GLALBottom = ThisElement.Align then
1091
      begin
1092
        Prepare;
1093
        Res[GLALBottom].Y1 := Y2 - H;
1094
        Res[GLALBottom].Y2 := Y2;
1095
      end;
1096
      if GLALLeft = ThisElement.Align then
1097
      begin
1098
        Prepare;
1099
        Res[GLALLeft].X1 := X1;
1100
        Res[GLALLeft].X2 := X1 + W;
1101
      end;
1102
      if GLALRight = ThisElement.Align then
1103
      begin
1104
        Prepare;
1105
        Res[GLALRight].X1 := X2 - W;
1106
        Res[GLALRight].X2 := X2;
1107
      end;
1108
    end;
1109

1110
    Res[GLALCenter].X1 := Res[GLALLeft].X2;
1111
    Res[GLALCenter].Y1 := Res[GLALtop].Y2;
1112
    Res[GLALCenter].X2 := Res[GLALRight].X1;
1113
    Res[GLALCenter].Y2 := Res[GLALBottom].Y1;
1114
  end;
1115

1116
  TexWidth := Material.Texture.TexWidth;
1117
  if TexWidth = 0 then
1118
    TexWidth := Material.Texture.Image.Width;
1119

1120
  TexHeight := Material.Texture.TexHeight;
1121
  if TexHeight = 0 then
1122
    TexHeight := Material.Texture.Image.Height;
1123

1124
  GL.Begin_(GL_QUADS);
1125

1126
  for XC := 0 to FElements.Count - 1 do
1127
  begin
1128
    ThisElement := FElements[XC];
1129
    for AlignCount := GLAlTopLeft to GLAlBottomRight do
1130
      if (AlignCount = ThisElement.Align) then
1131
      begin
1132
        if Refresh then
1133
        begin
1134
          Res[AlignCount].XTiles := ((Res[AlignCount].X2 - Res[AlignCount].X1) /
1135
            (ThisElement.FBottomRight.X - ThisElement.FTopLeft.X)) /
1136
            ThisElement.Scale.X;
1137
          Res[AlignCount].YTiles := ((Res[AlignCount].Y2 - Res[AlignCount].Y1) /
1138
            (ThisElement.FBottomRight.Y - ThisElement.FTopLeft.Y)) /
1139
            ThisElement.Scale.Y;
1140
        end;
1141
        RenderIt(Res[AlignCount], ThisElement);
1142
      end;
1143
    if (GLALBorder = ThisElement.Align) then
1144
    begin
1145
      RenderBorder(ThisElement);
1146
    end;
1147

1148
  end;
1149
  GL.End_;
1150
end;
1151

1152
function TGLGuiComponent.GetOwnerList: TGLGuiComponentList;
1153
begin
1154
  Result := GetOwner as TGLGuiComponentList;
1155
end;
1156

1157
function TGLGuiComponent.GetDisplayName: string;
1158
begin
1159
  Result := FName;
1160
end;
1161

1162
procedure TGLGuiComponent.SetName(const val: TGLGuiComponentName);
1163
begin
1164
  FName := Val;
1165
end;
1166

1167
constructor TGLGuiComponent.Create(Collection: TCollection);
1168
begin
1169
  inherited;
1170
  FElements := TGLGuiElementList.Create(Self);
1171
end;
1172

1173
destructor TGLGuiComponent.Destroy;
1174
begin
1175
  FElements.Free;
1176
  inherited;
1177
end;
1178

1179
constructor TGLGuiElementList.Create(AOwner: TGLGuiComponent);
1180
begin
1181
  inherited Create(AOwner, TGLGuiElement);
1182
  FGuiComponent := AOwner;
1183
end;
1184

1185
function TGLGuiElementList.GetOwner: TPersistent;
1186
begin
1187
  Result := FGuiComponent;
1188
end;
1189

1190
procedure TGLGuiElementList.SetItems(index: Integer; const val: TGLGuiElement);
1191
begin
1192
  inherited Items[index] := val;
1193
end;
1194

1195
function TGLGuiElementList.IndexOf(const Item: TGLGuiElement): Integer;
1196
var
1197
  I: Integer;
1198
begin
1199
  Result := -1;
1200
  if Count <> 0 then
1201
    for I := 0 to Count - 1 do
1202
      if GetItems(I) = Item then
1203
      begin
1204
        Result := I;
1205
        Exit;
1206
      end;
1207
end;
1208

1209
function TGLGuiElementList.GetItems(index: Integer): TGLGuiElement;
1210
begin
1211
  Result := TGLGuiElement(inherited Items[index]);
1212
end;
1213

1214
function TGLGuiElement.GetDisplayName: string;
1215
begin
1216
  Result := FName;
1217
end;
1218

1219
procedure TGLGuiElement.SetName(const val: TGLGuiElementName);
1220
begin
1221
  FName := Val;
1222
end;
1223

1224
constructor TGLGuiElement.Create(Collection: TCollection);
1225
begin
1226
  inherited;
1227
  FTopLeft := TGLCoordinates2.CreateInitialized(Self, NullHmgVector, csPoint2D);
1228
  FBottomRight := TGLCoordinates2.CreateInitialized(Self, NullHmgVector,
1229
    csPoint2D);
1230
  FScale := TGLCoordinates2.CreateInitialized(Self, XYHmgVector, csPoint2D);
1231
end;
1232

1233
destructor TGLGuiElement.Destroy;
1234
begin
1235
  FTopLeft.Free;
1236
  FBottomRight.Free;
1237
  FScale.Free;
1238
  inherited;
1239
end;
1240

1241
procedure TGLGuiLayout.Notification(AComponent: TComponent;
1242
  Operation: TOperation);
1243
begin
1244
  if Operation = opRemove then
1245
  begin
1246
    if AComponent = FBitmapFont then
1247
      BitmapFont := nil
1248
    else
1249
      FGuiComponentList.Remove(AComponent);
1250
  end;
1251
  NotifyChange(Self); // EG : looks suspicious...
1252
  inherited;
1253
end;
1254

1255
procedure TGLGuiComponent.AssignTo(Dest: TPersistent);
1256
begin
1257
  if Dest is TGLGuiComponent then
1258
  begin
1259
    TGLGuiComponent(Dest).Elements.Assign(Elements);
1260
  end
1261
  else
1262
    inherited;
1263
end;
1264

1265
procedure TGLGuiElementList.AssignTo(Dest: TPersistent);
1266
var
1267
  i: Integer;
1268
begin
1269
  if Dest is TGLGuiElementList then
1270
  begin
1271
    for i := 0 to Count - 1 do
1272
    begin
1273
      TGLGuiElementList(Dest).Add.Assign(Items[i]);
1274
    end;
1275
  end
1276
  else
1277
    inherited;
1278
end;
1279

1280
procedure TGLGuiElement.AssignTo(Dest: TPersistent);
1281
var
1282
  element: TGLGuiElement;
1283
begin
1284
  if Dest is TGLGuiElement then
1285
  begin
1286
    element := TGLGuiElement(Dest);
1287

1288
    element.TopLeft.Assign(TopLeft);
1289
    element.BottomRight.Assign(BottomRight);
1290
    element.Scale.Assign(Scale);
1291
    element.Align := Align;
1292
    element.Name := Name;
1293
  end
1294
  else
1295
    inherited;
1296
end;
1297

1298
end.
1299

1300

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

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

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

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