GXS.Gui.pas 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245
  1. //
  2. // The graphics engine GLXEngine. The unit of GXScene for Delphi
  3. //
  4. unit GXS.Gui;
  5. (* In GL windows management classes and structures *)
  6. interface
  7. {$I Stage.Defines.inc}
  8. uses
  9. Winapi.OpenGL,
  10. Winapi.OpenGLext,
  11. System.Classes,
  12. System.SysUtils,
  13. Stage.VectorTypes,
  14. GXS.Scene,
  15. GXS.BitmapFont,
  16. GXS.Material,
  17. GXS.Context,
  18. GXS.PersistentClasses,
  19. Stage.VectorGeometry,
  20. GXS.Coordinates,
  21. GXS.BaseClasses;
  22. type
  23. TgxBaseGuiObject = class(TgxBaseSceneObject)
  24. private
  25. FRecursiveVisible: Boolean;
  26. FWidth: Single;
  27. FHeight: Single;
  28. protected
  29. // self notification on hide. Also notifies children.
  30. procedure NotifyHide; virtual;
  31. // child notification on show. Also notifies children.
  32. procedure NotifyShow; virtual;
  33. procedure SetLeft(const Value: Single);
  34. function GetLeft: Single;
  35. procedure SetTop(const Value: Single);
  36. function GetTop: Single;
  37. procedure SetWidth(const val: Single);
  38. procedure SetHeight(const val: Single);
  39. procedure SetVisible(aValue: Boolean); override;
  40. public
  41. constructor Create(AOwner: TComponent); override;
  42. procedure AddChild(AChild: TgxBaseSceneObject); override;
  43. procedure Insert(aIndex: Integer; aChild: TgxBaseSceneObject); override;
  44. // GuiComponent Width in 3D world units.
  45. property Width: Single read FWidth write SetWidth;
  46. // GuiComponent Height in 3D world units.
  47. property Height: Single read FHeight write SetHeight;
  48. // GuiComponent Left in 3D world units.
  49. property Left: Single read GetLeft write SetLeft;
  50. // GuiComponent Top in 3D world units.
  51. property Top: Single read GetTop write SetTop;
  52. property RecursiveVisible: Boolean read FRecursiveVisible;
  53. end;
  54. TGUIAlignments = (GLAlTopLeft, GLAlTop, GLAlTopRight, GLAlLeft, GLAlCenter,
  55. GLAlRight, GLAlBottomLeft, GLAlBottom, GLAlBottomRight, GLAlBorder);
  56. TGUIRect = record
  57. X1: Single;
  58. Y1: Single;
  59. X2: Single;
  60. Y2: Single;
  61. XTiles: Single;
  62. YTiles: Single;
  63. end;
  64. TGUIDrawResult = array[TGUIAlignments] of TGUIRect;
  65. TgxGuiElementName = string;
  66. TgxGuiElement = class(TCollectionItem)
  67. private
  68. FTopLeft: TgxCoordinates2;
  69. FBottomRight: TgxCoordinates2;
  70. FScale: TgxCoordinates2;
  71. FAlign: TGUIAlignments;
  72. FName: TgxGuiElementName;
  73. protected
  74. function GetDisplayName: string; override;
  75. procedure SetName(const val: TgxGuiElementName);
  76. public
  77. constructor Create(Collection: TCollection); override;
  78. destructor Destroy; override;
  79. procedure AssignTo(Dest: TPersistent); override;
  80. published
  81. property TopLeft: TgxCoordinates2 read FTopLeft write FTopLeft;
  82. property BottomRight: TgxCoordinates2 read FBottomRight write FBottomRight;
  83. property Scale: TgxCoordinates2 read FScale write FScale;
  84. property Align: TGUIAlignments read FAlign write FAlign;
  85. property Name: TgxGuiElementName read FName write SetName;
  86. end;
  87. TgxGuiComponent = class;
  88. TgxGuiElementList = class(TOwnedCollection)
  89. private
  90. FGuiComponent: TgxGuiComponent;
  91. protected
  92. procedure SetItems(index: Integer; const val: TgxGuiElement);
  93. function GetItems(index: Integer): TgxGuiElement;
  94. public
  95. constructor Create(AOwner: TgxGuiComponent);
  96. procedure AssignTo(Dest: TPersistent); override;
  97. function GetOwner: TPersistent; override;
  98. function IndexOf(const Item: TgxGuiElement): Integer;
  99. property Items[index: Integer]: TgxGuiElement read GetItems write SetItems;
  100. default;
  101. end;
  102. TgxGuiComponentName = string;
  103. TgxGuiComponentList = class;
  104. TgxGuiComponent = class(TCollectionItem)
  105. private
  106. FElements: TgxGuiElementList;
  107. FName: TgxGuiComponentName;
  108. protected
  109. function GetDisplayName: string; override;
  110. procedure SetName(const val: TgxGuiComponentName);
  111. public
  112. constructor Create(Collection: TCollection); override;
  113. destructor Destroy; override;
  114. procedure AssignTo(Dest: TPersistent); override;
  115. procedure RenderToArea(X1, Y1, X2, Y2: Single; var Res: TGUIDrawResult;
  116. Refresh: Boolean = True; Scale: Single = 1);
  117. function GetOwnerList: TgxGuiComponentList;
  118. property Owner: TgxGuiComponentList read GetOwnerList;
  119. published
  120. property Elements: TgxGuiElementList read FElements write FElements;
  121. property Name: TgxGuiComponentName read FName write SetName;
  122. end;
  123. TgxGuiLayout = class;
  124. TgxGuiComponentList = class(TOwnedCollection)
  125. private
  126. FLayout: TgxGuiLayout;
  127. protected
  128. procedure SetItems(index: Integer; const val: TgxGuiComponent);
  129. function GetItems(index: Integer): TgxGuiComponent;
  130. public
  131. constructor Create(AOwner: TgxGuiLayout);
  132. function GetOwner: TPersistent; override;
  133. function FindItem(name: TgxGuiComponentName): TgxGuiComponent;
  134. property Items[index: Integer]: TgxGuiComponent read GetItems write
  135. SetItems; default;
  136. end;
  137. TgxGuiLayout = class(TgxUpdateAbleComponent)
  138. private
  139. FBitmapFont: TgxCustomBitmapFont;
  140. FMaterial: TgxMaterial;
  141. FGuiComponents: TgxGuiComponentList;
  142. FFileName: string;
  143. FGuiComponentList: TList;
  144. protected
  145. procedure Notification(AComponent: TComponent; Operation: TOperation);
  146. override;
  147. procedure SetFileName(newName: string);
  148. public
  149. constructor Create(AOwner: TComponent); override;
  150. destructor Destroy; override;
  151. procedure Assign(Source: TPersistent); override;
  152. procedure LoadFromStream(Stream: TStream);
  153. procedure LoadFromFile(FN: string);
  154. procedure Clear;
  155. procedure SaveToStream(Stream: TStream);
  156. procedure SaveToFile(FN: string);
  157. procedure AddGuiComponent(Component: TgxUpdateAbleComponent);
  158. procedure RemoveGuiComponent(Component: TgxUpdateAbleComponent);
  159. procedure NotifyChange(Sender: TObject); override;
  160. published
  161. property BitmapFont: TgxCustomBitmapFont read FBitmapFont write FBitmapFont;
  162. property Material: TgxMaterial read FMaterial write FMaterial;
  163. property GuiComponents: TgxGuiComponentList read FGuiComponents write
  164. FGuiComponents;
  165. property FileName: string read FFileName write SetFileName;
  166. end;
  167. const
  168. GuiNullRect: TGUIRect = (X1: 0.0; Y1: 0.0; X2: 0.0; Y2: 0.0; XTiles: 0.0;
  169. YTiles: 0.0);
  170. function IsInRect(const R: TGUIRect; X, Y: Single): Boolean;
  171. //-----------------------------------
  172. implementation
  173. //-----------------------------------
  174. function IsInRect(const R: TGUIRect; X, Y: Single): Boolean;
  175. begin
  176. Result := (R.X1 <= X) and (R.X2 >= X) and (R.Y1 <= Y) and (R.Y2 >= Y);
  177. end;
  178. // ------------------
  179. // ------------------ TgxBaseGuiObject ------------------
  180. // ------------------
  181. constructor TgxBaseGuiObject.Create(AOwner: TComponent);
  182. begin
  183. inherited Create(AOwner);
  184. FRecursiveVisible := Visible;
  185. end;
  186. procedure TgxBaseGuiObject.SetLeft(const Value: Single);
  187. var
  188. NewPosX: Single;
  189. i: integer;
  190. Diff: Single;
  191. begin
  192. if Assigned(Parent) and (Parent is TgxBaseGuiObject) then
  193. NewPosX := (Parent as TgxBaseGuiObject).Position.X + Value
  194. else
  195. NewPosX := Value;
  196. if Position.X <> NewPosX then
  197. begin
  198. Diff := NewPosX - Position.X;
  199. Position.X := NewPosX;
  200. for i := 0 to Count - 1 do
  201. if Children[i] is TgxBaseGuiObject then
  202. begin
  203. (Children[i] as TgxBaseGuiObject).Left := (Children[i] as
  204. TgxBaseGuiObject).Left + Diff;
  205. end;
  206. end;
  207. end;
  208. function TgxBaseGuiObject.GetLeft: Single;
  209. begin
  210. if Assigned(Parent) and (Parent is TgxBaseGuiObject) then
  211. Result := Position.X - (Parent as TgxBaseGuiObject).Position.X
  212. else
  213. Result := Position.X;
  214. end;
  215. procedure TgxBaseGuiObject.SetTop(const Value: Single);
  216. var
  217. NewPosY: Single;
  218. i: integer;
  219. Diff: Single;
  220. begin
  221. if Assigned(Parent) and (Parent is TgxBaseGuiObject) then
  222. NewPosY := (Parent as TgxBaseGuiObject).Position.Y + Value
  223. else
  224. NewPosY := Value;
  225. if Position.Y <> NewPosY then
  226. begin
  227. Diff := NewPosY - Position.Y;
  228. Position.Y := NewPosY;
  229. for i := 0 to Count - 1 do
  230. if Children[i] is TgxBaseGuiObject then
  231. begin
  232. (Children[i] as TgxBaseGuiObject).Top := (Children[i] as
  233. TgxBaseGuiObject).Top + Diff;
  234. end;
  235. end;
  236. end;
  237. function TgxBaseGuiObject.GetTop: Single;
  238. begin
  239. if Assigned(Parent) and (Parent is TgxBaseGuiObject) then
  240. Result := Position.Y - (Parent as TgxBaseGuiObject).Position.Y
  241. else
  242. Result := Position.Y;
  243. end;
  244. procedure TgxBaseGuiObject.SetWidth(const val: Single);
  245. begin
  246. if FWidth <> val then
  247. begin
  248. FWidth := val;
  249. NotifyChange(Self);
  250. end;
  251. end;
  252. procedure TgxBaseGuiObject.SetHeight(const val: Single);
  253. begin
  254. if FHeight <> val then
  255. begin
  256. FHeight := val;
  257. NotifyChange(Self);
  258. end;
  259. end;
  260. procedure TgxBaseGuiObject.NotifyHide;
  261. var
  262. child: TgxBaseSceneObject;
  263. xc: Integer;
  264. begin
  265. if RecursiveVisible then
  266. begin
  267. FRecursiveVisible := False;
  268. for xc := 0 to Count - 1 do
  269. begin
  270. child := Children[xc];
  271. if child is TgxBaseGuiObject then
  272. TgxBaseGuiObject(child).NotifyHide;
  273. end;
  274. end;
  275. end;
  276. procedure TgxBaseGuiObject.NotifyShow;
  277. var
  278. child: TgxBaseSceneObject;
  279. xc: Integer;
  280. begin
  281. if not RecursiveVisible then
  282. begin
  283. FRecursiveVisible := True;
  284. for xc := 0 to Count - 1 do
  285. begin
  286. child := Children[xc];
  287. if child is TgxBaseGuiObject then
  288. TgxBaseGuiObject(child).NotifyShow;
  289. end;
  290. end;
  291. end;
  292. procedure TgxBaseGuiObject.AddChild(aChild: TgxBaseSceneObject);
  293. begin
  294. inherited;
  295. if AChild is TgxBaseGuiObject then
  296. begin
  297. if RecursiveVisible then
  298. TgxBaseGuiObject(AChild).NotifyShow
  299. else
  300. TgxBaseGuiObject(AChild).NotifyHide;
  301. end;
  302. end;
  303. procedure TgxBaseGuiObject.Insert(aIndex: Integer; aChild: TgxBaseSceneObject);
  304. begin
  305. inherited;
  306. if AChild is TgxBaseGuiObject then
  307. begin
  308. if RecursiveVisible then
  309. TgxBaseGuiObject(AChild).NotifyShow
  310. else
  311. TgxBaseGuiObject(AChild).NotifyHide;
  312. end;
  313. end;
  314. procedure TgxBaseGuiObject.SetVisible(aValue: Boolean);
  315. begin
  316. if Visible <> aValue then
  317. begin
  318. inherited SetVisible(aValue);
  319. if aValue then
  320. begin
  321. if Parent <> nil then
  322. if Parent is TgxBaseGuiObject then
  323. begin
  324. if TgxBaseGuiObject(Parent).RecursiveVisible then
  325. NotifyShow;
  326. end
  327. else
  328. begin
  329. if Parent.Visible then
  330. NotifyShow;
  331. end;
  332. end
  333. else
  334. begin
  335. if RecursiveVisible then
  336. NotifyHide;
  337. end;
  338. end;
  339. end;
  340. constructor TgxGuiLayout.Create(AOwner: TComponent);
  341. begin
  342. FGuiComponentList := TList.Create;
  343. inherited;
  344. FGuiComponents := TgxGuiComponentList.Create(Self);
  345. FMaterial := TgxMaterial.Create(Self);
  346. end;
  347. destructor TgxGuiLayout.Destroy;
  348. begin
  349. Clear;
  350. FMaterial.Free;
  351. FGuiComponents.Free;
  352. inherited;
  353. FGuiComponentList.Free;
  354. end;
  355. procedure TgxGuiLayout.SetFileName(newName: string);
  356. begin
  357. if newName <> FFileName then
  358. begin
  359. FFileName := newName;
  360. if FileExists(FFileName) then
  361. begin
  362. Clear;
  363. loadFromFile(FFileName);
  364. end;
  365. end;
  366. end;
  367. procedure TgxGuiLayout.LoadFromFile(FN: string);
  368. var
  369. Stream: TMemoryStream;
  370. begin
  371. Stream := TMemoryStream.Create;
  372. try
  373. Stream.LoadFromFile(FN);
  374. LoadFromStream(stream);
  375. FFileName := FN;
  376. finally
  377. stream.Free;
  378. end;
  379. end;
  380. procedure TgxGuiLayout.SaveToFile(FN: string);
  381. var
  382. Stream: TMemoryStream;
  383. begin
  384. Stream := TMemoryStream.Create;
  385. try
  386. SaveToStream(Stream);
  387. Stream.SaveToFile(FN);
  388. FFileName := FN;
  389. finally
  390. Stream.Free;
  391. end;
  392. end;
  393. procedure TgxGuiLayout.AddGuiComponent(Component: TgxUpdateAbleComponent);
  394. begin
  395. if FGuiComponentList.IndexOf(Component) < 0 then
  396. begin
  397. FreeNotification(Component);
  398. FGuiComponentList.Add(Component);
  399. end;
  400. end;
  401. procedure TgxGuiLayout.RemoveGuiComponent(Component: TgxUpdateAbleComponent);
  402. begin
  403. FGuiComponentList.Remove(Component);
  404. RemoveFreeNotification(Component);
  405. end;
  406. procedure TgxGuiLayout.Assign(Source: TPersistent);
  407. var
  408. LLayout: TgxGuiLayout;
  409. LComponent: TgxGuiComponent;
  410. I: Integer;
  411. begin
  412. if Source is TgxGuiLayout then
  413. begin
  414. LLayout := TgxGuiLayout(Source);
  415. FBitmapFont := LLayout.FBitmapFont;
  416. FMaterial.Assign(LLayout.Material);
  417. FFileName := LLayout.FFileName;
  418. Clear;
  419. for I := 0 to LLayout.FGuiComponents.Count - 1 do
  420. begin
  421. LComponent := TgxGuiComponent(FGuiComponents.Add);
  422. LLayout.FGuiComponents[I].AssignTo(LComponent);
  423. LComponent.Name := LLayout.FGuiComponents[I].Name;
  424. end;
  425. for I := 0 to FGuiComponentList.Count - 1 do
  426. TgxUpdateAbleComponent(FGuiComponentList[I]).RemoveFreeNotification(Self);
  427. FGuiComponentList.Assign(LLayout.FGuiComponentList);
  428. for I := 0 to FGuiComponentList.Count - 1 do
  429. TgxUpdateAbleComponent(FGuiComponentList[I]).FreeNotification(Self);
  430. end
  431. else
  432. inherited; // Assign Error
  433. end;
  434. procedure TgxGuiLayout.Clear;
  435. var
  436. XC: Integer;
  437. begin
  438. for XC := FGuiComponents.Count - 1 downto 0 do
  439. begin
  440. FGuiComponents.Delete(XC);
  441. end;
  442. NotifyChange(Self);
  443. end;
  444. procedure TgxGuiLayout.NotifyChange(Sender: TObject);
  445. var
  446. XC: Integer;
  447. begin
  448. inherited;
  449. for XC := FGuiComponentList.Count - 1 downto 0 do
  450. TgxUpdateAbleComponent(FGuiComponentList[XC]).NotifyChange(Self);
  451. end;
  452. procedure TgxGuiLayout.LoadFromStream(Stream: TStream);
  453. var
  454. TmpComponent: TgxGuiComponent;
  455. XC, YC, ZC: Integer;
  456. TmpElement: TgxGuiElement;
  457. TmpAlignment: TGUIAlignments;
  458. Version: Integer;
  459. Data: TgxBinaryReader;
  460. begin
  461. Data := TgxBinaryReader.Create(Stream);
  462. try
  463. Version := Data.ReadInteger;
  464. if Version <> 1 then
  465. Exit;
  466. for XC := 0 to Data.ReadInteger - 1 do
  467. begin
  468. TmpComponent := FGuiComponents.Add as TgxGuiComponent;
  469. TmpComponent.FName := Data.ReadString;
  470. for YC := 0 to Data.ReadInteger - 1 do
  471. begin
  472. TmpElement := TmpComponent.FElements.add as TgxGuiElement;
  473. TmpElement.FName := Data.ReadString;
  474. TmpElement.FTopLeft.X := Data.ReadFloat;
  475. TmpElement.FTopLeft.Y := Data.ReadFloat;
  476. TmpElement.FTopLeft.Z := Data.ReadFloat;
  477. TmpElement.FBottomRight.X := Data.ReadFloat;
  478. TmpElement.FBottomRight.Y := Data.ReadFloat;
  479. TmpElement.FBottomRight.Z := Data.ReadFloat;
  480. TmpElement.FScale.X := Data.ReadFloat;
  481. TmpElement.FScale.Y := Data.ReadFloat;
  482. TmpElement.FScale.Z := Data.ReadFloat;
  483. for ZC := 0 to Data.ReadInteger - 1 do
  484. begin
  485. TmpAlignment := TGUIAlignments(Data.ReadInteger);
  486. TmpElement.FAlign := TmpAlignment;
  487. end;
  488. end;
  489. end;
  490. finally
  491. Data.Free;
  492. end;
  493. NotifyChange(Self);
  494. end;
  495. procedure TgxGuiLayout.SaveToStream(stream: TStream);
  496. var
  497. TmpComponent: TgxGuiComponent;
  498. Alignments, XC, YC: Integer;
  499. TmpElement: TgxGuiElement;
  500. TmpAlignment: TGUIAlignments;
  501. Data: TgxBinaryWriter;
  502. begin
  503. Data := TgxBinaryWriter.Create(Stream);
  504. try
  505. Data.WriteInteger(1);
  506. Data.WriteInteger(FGuiComponents.Count);
  507. for XC := 0 to FGuiComponents.Count - 1 do
  508. begin
  509. TmpComponent := FGuiComponents.Items[XC];
  510. Data.WriteString(TmpComponent.FName);
  511. Data.WriteInteger(TmpComponent.FElements.Count);
  512. for YC := 0 to TmpComponent.FElements.Count - 1 do
  513. begin
  514. TmpElement := TmpComponent.FElements.Items[YC];
  515. Data.WriteString(TmpElement.FName);
  516. Data.WriteFloat(TmpElement.FTopLeft.X);
  517. Data.WriteFloat(TmpElement.FTopLeft.Y);
  518. Data.WriteFloat(TmpElement.FTopLeft.Z);
  519. Data.WriteFloat(TmpElement.FBottomRight.X);
  520. Data.WriteFloat(TmpElement.FBottomRight.Y);
  521. Data.WriteFloat(TmpElement.FBottomRight.Z);
  522. Data.WriteFloat(TmpElement.FScale.X);
  523. Data.WriteFloat(TmpElement.FScale.Y);
  524. Data.WriteFloat(TmpElement.FScale.Z);
  525. Alignments := 0;
  526. for TmpAlignMent := GLAlTopLeft to GLAlBorder do
  527. begin
  528. if TmpAlignMent = TmpElement.FAlign then
  529. inc(Alignments);
  530. end;
  531. Data.WriteInteger(Alignments);
  532. for TmpAlignMent := GLAlTopLeft to GLAlBorder do
  533. begin
  534. if TmpAlignMent = TmpElement.FAlign then
  535. Data.WriteInteger(Integer(TmpAlignMent));
  536. end;
  537. end;
  538. end;
  539. finally
  540. Data.Free;
  541. end;
  542. end;
  543. constructor TgxGuiComponentList.Create(AOwner: TgxGuiLayout);
  544. begin
  545. inherited Create(AOwner, TgxGuiComponent);
  546. FLayout := AOwner;
  547. end;
  548. function TgxGuiComponentList.GetOwner: TPersistent;
  549. begin
  550. Result := FLayout;
  551. end;
  552. procedure TgxGuiComponentList.SetItems(index: Integer; const val:
  553. TgxGuiComponent);
  554. begin
  555. inherited Items[index] := val;
  556. end;
  557. function TgxGuiComponentList.FindItem(name: TgxGuiComponentName):
  558. TgxGuiComponent;
  559. var
  560. XC: Integer;
  561. gc: TgxGuiComponent;
  562. begin
  563. Result := nil;
  564. if Name = '' then
  565. Exit;
  566. for XC := 0 to Count - 1 do
  567. begin
  568. gc := Items[xc];
  569. if gc.FName = Name then
  570. begin
  571. Result := gc;
  572. Break;
  573. end;
  574. end;
  575. end;
  576. function TgxGuiComponentList.GetItems(index: Integer): TgxGuiComponent;
  577. begin
  578. Result := TgxGuiComponent(inherited Items[index]);
  579. end;
  580. procedure TgxGuiComponent.RenderToArea(X1, Y1, X2, Y2: Single; var Res:
  581. TGUIDrawResult; Refresh: Boolean = True; Scale: Single = 1);
  582. var
  583. XC: Integer;
  584. ThisElement: TgxGuiElement;
  585. W, H: Single;
  586. Len1, Len2: Single;
  587. Layout: TgxGuiLayout;
  588. LibMaterial: TgxLibMaterial;
  589. Material: TgxMaterial;
  590. TexWidth,
  591. TexHeight: Single;
  592. AlignCount: TGUIAlignments;
  593. procedure Prepare;
  594. begin
  595. Len1 := (ThisElement.FTopLeft.x - ThisElement.FBottomRight.x) *
  596. ThisElement.Scale.X * Scale;
  597. Len2 := (ThisElement.FTopLeft.y - ThisElement.FBottomRight.y) *
  598. ThisElement.Scale.Y * Scale;
  599. if Len1 < 0 then
  600. begin
  601. if Len2 < 0 then
  602. begin
  603. W := -Len1;
  604. H := -Len2;
  605. end
  606. else
  607. begin
  608. W := -Len1;
  609. H := Len2;
  610. end;
  611. end
  612. else
  613. begin
  614. if Len2 < 0 then
  615. begin
  616. W := Len1;
  617. H := -Len2;
  618. end
  619. else
  620. begin
  621. W := Len1;
  622. H := Len2;
  623. end;
  624. end;
  625. end;
  626. procedure RenderIt(var ARect: TGuiRect; AElement: TgxGuiElement);
  627. var
  628. XC: Single;
  629. YC: Single;
  630. XPos, X2Pos: Single;
  631. YPos, y2Pos: Single;
  632. tx1, ty1, tx2, ty2: Single;
  633. XTileSize, YTileSize: Single;
  634. tx3, ty3: Single;
  635. tx, ty: Single;
  636. begin
  637. if (ARect.XTiles = 1) and (ARect.YTiles = 1) then
  638. begin
  639. glTexCoord2f(AElement.TopLeft.X / TexWidth, -AElement.TopLeft.Y /
  640. TexHeight);
  641. glVertex2f(ARect.X1, -ARect.Y1);
  642. glTexCoord2f(AElement.TopLeft.X / TexWidth, -AElement.BottomRight.Y /
  643. TexHeight);
  644. glVertex2f(ARect.X1, -ARect.Y2);
  645. glTexCoord2f(AElement.BottomRight.X / TexWidth, -AElement.BottomRight.Y /
  646. TexHeight);
  647. glVertex2f(ARect.X2, -ARect.Y2);
  648. glTexCoord2f(AElement.BottomRight.X / TexWidth, -AElement.TopLeft.Y /
  649. TexHeight);
  650. glVertex2f(ARect.X2, -ARect.Y1);
  651. end
  652. else
  653. begin
  654. XTileSize := (ARect.X2 - ARect.X1) / ARect.XTiles;
  655. YTileSize := (ARect.Y2 - ARect.Y1) / ARect.YTiles;
  656. tx1 := AElement.TopLeft.X / TexWidth;
  657. ty1 := -AElement.TopLeft.Y / TexHeight;
  658. tx2 := AElement.BottomRight.X / TexWidth;
  659. ty2 := -AElement.BottomRight.Y / TexHeight;
  660. tx3 := (AElement.TopLeft.X + (AElement.BottomRight.X - AElement.TopLeft.X)
  661. * Frac(ARect.XTiles)) / TexWidth;
  662. ty3 := -(AElement.TopLeft.y + (AElement.BottomRight.y - AElement.TopLeft.y)
  663. * Frac(ARect.yTiles)) / TexHeight;
  664. XC := ARect.XTiles;
  665. XPos := ARect.X1;
  666. tx := tx2;
  667. while XC > 0 do
  668. begin
  669. YC := ARect.YTiles;
  670. YPos := ARect.Y1;
  671. ty := ty2;
  672. if XC >= 1 then
  673. X2Pos := XPos + XTileSize
  674. else
  675. begin
  676. X2Pos := ARect.X2;
  677. tx := tx3;
  678. end;
  679. while YC > 0 do
  680. begin
  681. if YC >= 1 then
  682. Y2Pos := YPos + YTileSize
  683. else
  684. begin
  685. Y2Pos := ARect.Y2;
  686. ty := ty3;
  687. end;
  688. glTexCoord2f(tx1, ty1);
  689. glVertex2f(XPos, -YPos);
  690. glTexCoord2f(tx1, ty);
  691. glVertex2f(XPos, -Y2Pos);
  692. glTexCoord2f(tx, ty);
  693. glVertex2f(X2Pos, -Y2Pos);
  694. glTexCoord2f(tx, ty1);
  695. glVertex2f(X2Pos, -YPos);
  696. yc := yc - 1.0;
  697. ypos := Y2Pos;
  698. end;
  699. xc := xc - 1.0;
  700. xpos := X2Pos;
  701. end;
  702. end;
  703. end;
  704. procedure RenderBorder(AElement: TgxGuiElement);
  705. var
  706. TmpElement: TgxGuiElement;
  707. begin
  708. TmpElement := TgxGuiElement.Create(nil);
  709. TmpElement.FTopLeft.X := ThisElement.FTopLeft.X;
  710. TmpElement.FTopLeft.Y := ThisElement.FTopLeft.Y;
  711. TmpElement.FBottomRight.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
  712. TmpElement.FBottomRight.Y := ThisElement.FTopLeft.Y + ThisElement.Scale.Y;
  713. TmpElement.Scale.SetPoint2D(1, 1);
  714. RenderIt(Res[GLALTopLeft], TmpElement);
  715. TmpElement.FTopLeft.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
  716. TmpElement.FBottomRight.X := ThisElement.FBottomRight.X -
  717. ThisElement.Scale.X;
  718. RenderIt(Res[GLALTop], TmpElement);
  719. TmpElement.FTopLeft.X := ThisElement.FBottomRight.X - ThisElement.Scale.X;
  720. TmpElement.FBottomRight.X := ThisElement.FBottomRight.X;
  721. RenderIt(Res[GLALTopRight], TmpElement);
  722. TmpElement.FTopLeft.Y := ThisElement.FTopLeft.Y + ThisElement.Scale.Y;
  723. TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y -
  724. ThisElement.Scale.Y;
  725. RenderIt(Res[GLALRight], TmpElement);
  726. TmpElement.FTopLeft.X := ThisElement.FBottomRight.X - ThisElement.Scale.X;
  727. TmpElement.FTopLeft.Y := ThisElement.FBottomRight.Y - ThisElement.Scale.Y;
  728. TmpElement.FBottomRight.X := ThisElement.FBottomRight.X;
  729. TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y;
  730. RenderIt(Res[GLALBottomRight], TmpElement);
  731. TmpElement.FTopLeft.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
  732. TmpElement.FTopLeft.Y := ThisElement.FBottomRight.Y - ThisElement.Scale.Y;
  733. TmpElement.FBottomRight.X := ThisElement.FBottomRight.X -
  734. ThisElement.Scale.X;
  735. TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y;
  736. RenderIt(Res[GLALBottom], TmpElement);
  737. TmpElement.FTopLeft.X := ThisElement.FTopLeft.X;
  738. TmpElement.FTopLeft.Y := ThisElement.FBottomRight.Y - ThisElement.Scale.Y;
  739. TmpElement.FBottomRight.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
  740. TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y;
  741. RenderIt(Res[GLALBottomLeft], TmpElement);
  742. TmpElement.FTopLeft.X := ThisElement.FTopLeft.X;
  743. TmpElement.FTopLeft.Y := ThisElement.FTopLeft.Y + ThisElement.Scale.Y;
  744. TmpElement.FBottomRight.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
  745. TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y -
  746. ThisElement.Scale.Y;
  747. RenderIt(Res[GLALLeft], TmpElement);
  748. TmpElement.FTopLeft.X := ThisElement.FTopLeft.X + ThisElement.Scale.X;
  749. TmpElement.FTopLeft.Y := ThisElement.FTopLeft.Y + ThisElement.Scale.Y;
  750. TmpElement.FBottomRight.X := ThisElement.FBottomRight.X -
  751. ThisElement.Scale.X;
  752. TmpElement.FBottomRight.Y := ThisElement.FBottomRight.Y -
  753. ThisElement.Scale.Y;
  754. RenderIt(Res[GLALCenter], TmpElement);
  755. end;
  756. begin
  757. Layout := ((GetOwner as TgxGuiComponentList).GetOwner as TgxGuiLayout);
  758. Material := nil;
  759. if Assigned(Layout.Material.MaterialLibrary)
  760. and (Layout.Material.MaterialLibrary is TgxMaterialLibrary)
  761. and (Layout.Material.LibMaterialName <> '') then
  762. begin
  763. LibMaterial :=
  764. TgxMaterialLibrary(Layout.Material.MaterialLibrary).Materials.GetLibMaterialByName(Layout.Material.LibMaterialName);
  765. if Assigned(LibMaterial) then
  766. Material := LibMaterial.Material;
  767. end;
  768. if not Assigned(Material) then
  769. begin
  770. Material := Layout.Material;
  771. end;
  772. if Refresh then
  773. begin
  774. Res[GLALtopLeft].X1 := X1;
  775. Res[GLALtopLeft].Y1 := Y1;
  776. Res[GLALtopLeft].X2 := X1;
  777. Res[GLALtopLeft].Y2 := Y1;
  778. Res[GLALtopRight].X1 := X2;
  779. Res[GLALtopRight].Y1 := Y1;
  780. Res[GLALtopRight].X2 := X2;
  781. Res[GLALtopRight].Y2 := Y1;
  782. Res[GLALBottomLeft].X1 := X1;
  783. Res[GLALBottomLeft].Y1 := Y2;
  784. Res[GLALBottomLeft].X2 := X1;
  785. Res[GLALBottomLeft].Y2 := Y2;
  786. Res[GLALBottomRight].X1 := X2;
  787. Res[GLALBottomRight].Y1 := Y2;
  788. Res[GLALBottomRight].X2 := X2;
  789. Res[GLALBottomRight].Y2 := Y2;
  790. for XC := 0 to FElements.Count - 1 do
  791. begin
  792. ThisElement := FElements[XC];
  793. if GLAlBorder = ThisElement.Align then
  794. begin
  795. Res[GLALtopLeft].X1 := X1;
  796. Res[GLALtopLeft].Y1 := Y1;
  797. Res[GLALtopLeft].X2 := X1 + ThisElement.Scale.X * Scale *
  798. ThisElement.Scale.Z;
  799. Res[GLALtopLeft].Y2 := Y1 + ThisElement.Scale.Y * Scale *
  800. ThisElement.Scale.Z;
  801. Res[GLALtop].X1 := X1 + ThisElement.Scale.X * Scale *
  802. ThisElement.Scale.Z;
  803. Res[GLALtop].Y1 := Y1;
  804. Res[GLALtop].X2 := X2 - ThisElement.Scale.X * Scale *
  805. ThisElement.Scale.Z;
  806. Res[GLALtop].Y2 := Y1 + ThisElement.Scale.Y * Scale *
  807. ThisElement.Scale.Z;
  808. Res[GLALtopRight].X1 := X2 - ThisElement.Scale.X * Scale *
  809. ThisElement.Scale.Z;
  810. Res[GLALtopRight].Y1 := Y1;
  811. Res[GLALtopRight].X2 := X2;
  812. Res[GLALtopRight].Y2 := Y1 + ThisElement.Scale.Y * Scale *
  813. ThisElement.Scale.Z;
  814. Res[GLALRight].X1 := X2 - ThisElement.Scale.X * Scale *
  815. ThisElement.Scale.Z;
  816. Res[GLALRight].Y1 := Y1 + ThisElement.Scale.Y * Scale *
  817. ThisElement.Scale.Z;
  818. Res[GLALRight].X2 := X2;
  819. Res[GLALRight].Y2 := Y2 - ThisElement.Scale.Y * Scale *
  820. ThisElement.Scale.Z;
  821. Res[GLALBottomRight].X1 := X2 - ThisElement.Scale.X * Scale *
  822. ThisElement.Scale.Z;
  823. Res[GLALBottomRight].Y1 := Y2 - ThisElement.Scale.Y * Scale *
  824. ThisElement.Scale.Z;
  825. Res[GLALBottomRight].X2 := X2;
  826. Res[GLALBottomRight].Y2 := Y2;
  827. Res[GLALBottom].X1 := X1 + ThisElement.Scale.X * Scale *
  828. ThisElement.Scale.Z;
  829. Res[GLALBottom].Y1 := Y2 - ThisElement.Scale.Y * Scale *
  830. ThisElement.Scale.Z;
  831. Res[GLALBottom].X2 := X2 - ThisElement.Scale.X * Scale *
  832. ThisElement.Scale.Z;
  833. Res[GLALBottom].Y2 := Y2;
  834. Res[GLALBottomLeft].X1 := X1;
  835. Res[GLALBottomLeft].Y1 := Y2 - ThisElement.Scale.Y * Scale *
  836. ThisElement.Scale.Z;
  837. Res[GLALBottomLeft].X2 := X1 + ThisElement.Scale.X * Scale *
  838. ThisElement.Scale.Z;
  839. Res[GLALBottomLeft].Y2 := Y2;
  840. Res[GLALLeft].X1 := X1;
  841. Res[GLALLeft].Y1 := Y1 + ThisElement.Scale.Y * Scale *
  842. ThisElement.Scale.Z;
  843. Res[GLALLeft].X2 := X1 + ThisElement.Scale.X * Scale *
  844. ThisElement.Scale.Z;
  845. Res[GLALLeft].Y2 := Y2 - ThisElement.Scale.Y * Scale *
  846. ThisElement.Scale.Z;
  847. Res[GLALCenter].X1 := X1 + ThisElement.Scale.X * Scale *
  848. ThisElement.Scale.Z;
  849. Res[GLALCenter].Y1 := Y1 + ThisElement.Scale.Y * Scale *
  850. ThisElement.Scale.Z;
  851. Res[GLALCenter].X2 := X2 - ThisElement.Scale.X * Scale *
  852. ThisElement.Scale.Z;
  853. Res[GLALCenter].Y2 := Y2 - ThisElement.Scale.Y * Scale *
  854. ThisElement.Scale.Z;
  855. end;
  856. if GLALtopLeft = ThisElement.Align then
  857. begin
  858. Prepare;
  859. Res[GLALtopLeft].X1 := X1;
  860. Res[GLALtopLeft].Y1 := Y1;
  861. Res[GLALtopLeft].X2 := X1 + W;
  862. Res[GLALtopLeft].Y2 := Y1 + H;
  863. end;
  864. if GLALtopRight = ThisElement.Align then
  865. begin
  866. Prepare;
  867. Res[GLALtopRight].X1 := X2 - W;
  868. Res[GLALtopRight].Y1 := Y1;
  869. Res[GLALtopRight].X2 := X2;
  870. Res[GLALtopRight].Y2 := Y1 + H;
  871. end;
  872. if GLALBottomLeft = ThisElement.Align then
  873. begin
  874. Prepare;
  875. Res[GLALBottomLeft].X1 := X1;
  876. Res[GLALBottomLeft].Y1 := Y2 - H;
  877. Res[GLALBottomLeft].X2 := X1 + W;
  878. Res[GLALBottomLeft].Y2 := Y2;
  879. end;
  880. if GLALBottomRight = ThisElement.Align then
  881. begin
  882. Prepare;
  883. Res[GLALBottomRight].X1 := X2 - W;
  884. Res[GLALBottomRight].Y1 := Y2 - H;
  885. Res[GLALBottomRight].X2 := X2;
  886. Res[GLALBottomRight].Y2 := Y2;
  887. end;
  888. end;
  889. Res[GLALtop].X1 := Res[GLALtopLeft].X2;
  890. Res[GLALtop].Y1 := Res[GLALtopRight].Y1;
  891. Res[GLALtop].X2 := Res[GLALtopRight].X1;
  892. Res[GLALtop].Y2 := Res[GLALtopLeft].Y2;
  893. Res[GLALBottom].X1 := Res[GLALBottomLeft].X2;
  894. Res[GLALBottom].Y1 := Res[GLALBottomLeft].Y1;
  895. Res[GLALBottom].X2 := Res[GLALBottomRight].X1;
  896. Res[GLALBottom].Y2 := Res[GLALBottomRight].Y2;
  897. Res[GLALLeft].X1 := Res[GLALtopLeft].X1;
  898. Res[GLALLeft].Y1 := Res[GLALtopLeft].Y2;
  899. Res[GLALLeft].X2 := Res[GLALBottomLeft].X2;
  900. Res[GLALLeft].Y2 := Res[GLALBottomLeft].Y1;
  901. Res[GLALRight].X1 := Res[GLALtopRight].X1;
  902. Res[GLALRight].Y1 := Res[GLALtopRight].Y2;
  903. Res[GLALRight].X2 := Res[GLALBottomRight].X2;
  904. Res[GLALRight].Y2 := Res[GLALBottomRight].Y1;
  905. for XC := 0 to FElements.Count - 1 do
  906. begin
  907. ThisElement := FElements[XC];
  908. if GLALtop = ThisElement.Align then
  909. begin
  910. Prepare;
  911. Res[GLALtop].Y1 := Y1;
  912. Res[GLALtop].Y2 := Y1 + H;
  913. end;
  914. if GLALBottom = ThisElement.Align then
  915. begin
  916. Prepare;
  917. Res[GLALBottom].Y1 := Y2 - H;
  918. Res[GLALBottom].Y2 := Y2;
  919. end;
  920. if GLALLeft = ThisElement.Align then
  921. begin
  922. Prepare;
  923. Res[GLALLeft].X1 := X1;
  924. Res[GLALLeft].X2 := X1 + W;
  925. end;
  926. if GLALRight = ThisElement.Align then
  927. begin
  928. Prepare;
  929. Res[GLALRight].X1 := X2 - W;
  930. Res[GLALRight].X2 := X2;
  931. end;
  932. end;
  933. Res[GLALCenter].X1 := Res[GLALLeft].X2;
  934. Res[GLALCenter].Y1 := Res[GLALtop].Y2;
  935. Res[GLALCenter].X2 := Res[GLALRight].X1;
  936. Res[GLALCenter].Y2 := Res[GLALBottom].Y1;
  937. end;
  938. TexWidth := Material.Texture.TexWidth;
  939. if TexWidth = 0 then
  940. TexWidth := Material.Texture.Image.Width;
  941. TexHeight := Material.Texture.TexHeight;
  942. if TexHeight = 0 then
  943. TexHeight := Material.Texture.Image.Height;
  944. glBegin(GL_QUADS);
  945. for XC := 0 to FElements.Count - 1 do
  946. begin
  947. ThisElement := FElements[XC];
  948. for AlignCount := GLAlTopLeft to GLAlBottomRight do
  949. if (AlignCount = ThisElement.Align) then
  950. begin
  951. if Refresh then
  952. begin
  953. Res[AlignCount].XTiles := ((Res[AlignCount].X2 - Res[AlignCount].X1) /
  954. (ThisElement.FBottomRight.X - ThisElement.FTopLeft.X)) /
  955. ThisElement.Scale.X;
  956. Res[AlignCount].YTiles := ((Res[AlignCount].Y2 - Res[AlignCount].Y1) /
  957. (ThisElement.FBottomRight.Y - ThisElement.FTopLeft.Y)) /
  958. ThisElement.Scale.Y;
  959. end;
  960. RenderIt(Res[AlignCount], ThisElement);
  961. end;
  962. if (GLALBorder = ThisElement.Align) then
  963. begin
  964. RenderBorder(ThisElement);
  965. end;
  966. end;
  967. glEnd;
  968. end;
  969. function TgxGuiComponent.GetOwnerList: TgxGuiComponentList;
  970. begin
  971. Result := GetOwner as TgxGuiComponentList;
  972. end;
  973. function TgxGuiComponent.GetDisplayName: string;
  974. begin
  975. Result := FName;
  976. end;
  977. procedure TgxGuiComponent.SetName(const val: TgxGuiComponentName);
  978. begin
  979. FName := Val;
  980. end;
  981. constructor TgxGuiComponent.Create(Collection: TCollection);
  982. begin
  983. inherited;
  984. FElements := TgxGuiElementList.Create(Self);
  985. end;
  986. destructor TgxGuiComponent.Destroy;
  987. begin
  988. FElements.Free;
  989. inherited;
  990. end;
  991. constructor TgxGuiElementList.Create(AOwner: TgxGuiComponent);
  992. begin
  993. inherited Create(AOwner, TgxGuiElement);
  994. FGuiComponent := AOwner;
  995. end;
  996. function TgxGuiElementList.GetOwner: TPersistent;
  997. begin
  998. Result := FGuiComponent;
  999. end;
  1000. procedure TgxGuiElementList.SetItems(index: Integer; const val: TgxGuiElement);
  1001. begin
  1002. inherited Items[index] := val;
  1003. end;
  1004. function TgxGuiElementList.IndexOf(const Item: TgxGuiElement): Integer;
  1005. var
  1006. I: Integer;
  1007. begin
  1008. Result := -1;
  1009. if Count <> 0 then
  1010. for I := 0 to Count - 1 do
  1011. if GetItems(I) = Item then
  1012. begin
  1013. Result := I;
  1014. Exit;
  1015. end;
  1016. end;
  1017. function TgxGuiElementList.GetItems(index: Integer): TgxGuiElement;
  1018. begin
  1019. Result := TgxGuiElement(inherited Items[index]);
  1020. end;
  1021. function TgxGuiElement.GetDisplayName: string;
  1022. begin
  1023. Result := FName;
  1024. end;
  1025. procedure TgxGuiElement.SetName(const val: TgxGuiElementName);
  1026. begin
  1027. FName := Val;
  1028. end;
  1029. constructor TgxGuiElement.Create(Collection: TCollection);
  1030. begin
  1031. inherited;
  1032. FTopLeft := TgxCoordinates2.CreateInitialized(Self, NullHmgVector, csPoint2D);
  1033. FBottomRight := TgxCoordinates2.CreateInitialized(Self, NullHmgVector,
  1034. csPoint2D);
  1035. FScale := TgxCoordinates2.CreateInitialized(Self, XYHmgVector, csPoint2D);
  1036. end;
  1037. destructor TgxGuiElement.Destroy;
  1038. begin
  1039. FTopLeft.Free;
  1040. FBottomRight.Free;
  1041. FScale.Free;
  1042. inherited;
  1043. end;
  1044. procedure TgxGuiLayout.Notification(AComponent: TComponent;
  1045. Operation: TOperation);
  1046. begin
  1047. if Operation = opRemove then
  1048. begin
  1049. if AComponent = FBitmapFont then
  1050. BitmapFont := nil
  1051. else
  1052. FGuiComponentList.Remove(AComponent);
  1053. end;
  1054. NotifyChange(Self); // EG : looks suspicious...
  1055. inherited;
  1056. end;
  1057. procedure TgxGuiComponent.AssignTo(Dest: TPersistent);
  1058. begin
  1059. if Dest is TgxGuiComponent then
  1060. begin
  1061. TgxGuiComponent(Dest).Elements.Assign(Elements);
  1062. end
  1063. else
  1064. inherited;
  1065. end;
  1066. procedure TgxGuiElementList.AssignTo(Dest: TPersistent);
  1067. var
  1068. i: Integer;
  1069. begin
  1070. if Dest is TgxGuiElementList then
  1071. begin
  1072. for i := 0 to Count - 1 do
  1073. begin
  1074. TgxGuiElementList(Dest).Add.Assign(Items[i]);
  1075. end;
  1076. end
  1077. else
  1078. inherited;
  1079. end;
  1080. procedure TgxGuiElement.AssignTo(Dest: TPersistent);
  1081. var
  1082. element: TgxGuiElement;
  1083. begin
  1084. if Dest is TgxGuiElement then
  1085. begin
  1086. element := TgxGuiElement(Dest);
  1087. element.TopLeft.Assign(TopLeft);
  1088. element.BottomRight.Assign(BottomRight);
  1089. element.Scale.Assign(Scale);
  1090. element.Align := Align;
  1091. element.Name := Name;
  1092. end
  1093. else
  1094. inherited;
  1095. end;
  1096. end.