GComponent.cs 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using FairyGUI.Utils;
  5. #if FAIRYGUI_TOLUA
  6. using LuaInterface;
  7. #endif
  8. namespace FairyGUI
  9. {
  10. /// <summary>
  11. /// Component
  12. /// </summary>
  13. public class GComponent : GObject
  14. {
  15. /// <summary>
  16. /// Root container.
  17. /// </summary>
  18. public Container rootContainer { get; private set; }
  19. /// <summary>
  20. /// Content container. If the component is not clipped, then container==rootContainer.
  21. /// </summary>
  22. public Container container { get; protected set; }
  23. /// <summary>
  24. /// ScrollPane of the component. If the component is not scrollable, the value is null.
  25. /// </summary>
  26. public ScrollPane scrollPane { get; private set; }
  27. internal List<GObject> _children;
  28. internal List<Controller> _controllers;
  29. internal List<Transition> _transitions;
  30. internal bool _buildingDisplayList;
  31. protected Margin _margin;
  32. protected bool _trackBounds;
  33. protected bool _boundsChanged;
  34. protected ChildrenRenderOrder _childrenRenderOrder;
  35. protected int _apexIndex;
  36. internal Vector2 _alignOffset;
  37. Vector2 _clipSoftness;
  38. int _sortingChildCount;
  39. Action _buildDelegate;
  40. Controller _applyingController;
  41. EventListener _onDrop;
  42. public GComponent()
  43. {
  44. _children = new List<GObject>();
  45. _controllers = new List<Controller>();
  46. _transitions = new List<Transition>();
  47. _margin = new Margin();
  48. _buildDelegate = BuildNativeDisplayList;
  49. }
  50. override protected void CreateDisplayObject()
  51. {
  52. rootContainer = new Container("GComponent");
  53. rootContainer.gOwner = this;
  54. rootContainer.onUpdate += OnUpdate;
  55. container = rootContainer;
  56. displayObject = rootContainer;
  57. }
  58. override public void Dispose()
  59. {
  60. int cnt = _transitions.Count;
  61. for (int i = 0; i < cnt; ++i)
  62. {
  63. Transition trans = _transitions[i];
  64. trans.Dispose();
  65. }
  66. cnt = _controllers.Count;
  67. for (int i = 0; i < cnt; ++i)
  68. {
  69. Controller c = _controllers[i];
  70. c.Dispose();
  71. }
  72. if (scrollPane != null)
  73. scrollPane.Dispose();
  74. base.Dispose(); //Dispose native tree first, avoid DisplayObject.RemoveFromParent call
  75. cnt = _children.Count;
  76. for (int i = cnt - 1; i >= 0; --i)
  77. {
  78. GObject obj = _children[i];
  79. obj.InternalSetParent(null); //Avoid GObject.RemoveParent call
  80. obj.Dispose();
  81. }
  82. #if FAIRYGUI_TOLUA
  83. if (_peerTable != null)
  84. {
  85. _peerTable.Dispose();
  86. _peerTable = null;
  87. }
  88. #endif
  89. #if FAIRYGUI_PUERTS
  90. if (__onDispose != null)
  91. __onDispose();
  92. __onConstruct = null;
  93. __onDispose = null;
  94. #endif
  95. }
  96. /// <summary>
  97. /// Dispatched when an object was dragged and dropped to this component.
  98. /// </summary>
  99. public EventListener onDrop
  100. {
  101. get { return _onDrop ?? (_onDrop = new EventListener(this, "onDrop")); }
  102. }
  103. /// <summary>
  104. /// Draw call optimization switch.
  105. /// </summary>
  106. public bool fairyBatching
  107. {
  108. get { return rootContainer.fairyBatching; }
  109. set { rootContainer.fairyBatching = value; }
  110. }
  111. /// <summary>
  112. ///
  113. /// </summary>
  114. /// <param name="childChanged"></param>
  115. public void InvalidateBatchingState(bool childChanged)
  116. {
  117. if (childChanged)
  118. container.InvalidateBatchingState(childChanged);
  119. else
  120. rootContainer.InvalidateBatchingState();
  121. }
  122. /// <summary>
  123. /// If true, mouse/touch events cannot pass through the empty area of the component. Default is true.
  124. /// </summary>
  125. public bool opaque
  126. {
  127. get { return rootContainer.opaque; }
  128. set { rootContainer.opaque = value; }
  129. }
  130. /// <summary>
  131. ///
  132. /// </summary>
  133. /// <value></value>
  134. public Margin margin
  135. {
  136. get { return _margin; }
  137. set
  138. {
  139. _margin = value;
  140. if (rootContainer.clipRect != null && scrollPane == null) //如果scrollPane不为空,则HandleSizeChanged里面的处理会促使ScrollPane处理
  141. container.SetXY(_margin.left + _alignOffset.x, _margin.top + _alignOffset.y);
  142. HandleSizeChanged();
  143. }
  144. }
  145. /// <summary>
  146. ///
  147. /// </summary>
  148. public ChildrenRenderOrder childrenRenderOrder
  149. {
  150. get { return _childrenRenderOrder; }
  151. set
  152. {
  153. if (_childrenRenderOrder != value)
  154. {
  155. _childrenRenderOrder = value;
  156. BuildNativeDisplayList();
  157. }
  158. }
  159. }
  160. /// <summary>
  161. ///
  162. /// </summary>
  163. public int apexIndex
  164. {
  165. get { return _apexIndex; }
  166. set
  167. {
  168. if (_apexIndex != value)
  169. {
  170. _apexIndex = value;
  171. if (_childrenRenderOrder == ChildrenRenderOrder.Arch)
  172. BuildNativeDisplayList();
  173. }
  174. }
  175. }
  176. /// <summary>
  177. /// If true, children can be navigated by TAB from first to last, and repeat
  178. /// </summary>
  179. public bool tabStopChildren
  180. {
  181. get { return rootContainer.tabStopChildren; }
  182. set { rootContainer.tabStopChildren = value; }
  183. }
  184. /// <summary>
  185. /// Add a child to the component. It will be at the frontmost position.
  186. /// </summary>
  187. /// <param name="child">A child object</param>
  188. /// <returns>GObject</returns>
  189. public GObject AddChild(GObject child)
  190. {
  191. AddChildAt(child, _children.Count);
  192. return child;
  193. }
  194. /// <summary>
  195. /// Adds a child to the component at a certain index.
  196. /// </summary>
  197. /// <param name="child">A child object</param>
  198. /// <param name="index">Index</param>
  199. /// <returns>GObject</returns>
  200. virtual public GObject AddChildAt(GObject child, int index)
  201. {
  202. if (index >= 0 && index <= _children.Count)
  203. {
  204. if (child.parent == this)
  205. {
  206. SetChildIndex(child, index);
  207. }
  208. else
  209. {
  210. child.RemoveFromParent();
  211. child.InternalSetParent(this);
  212. int cnt = _children.Count;
  213. if (child.sortingOrder != 0)
  214. {
  215. _sortingChildCount++;
  216. index = GetInsertPosForSortingChild(child);
  217. }
  218. else if (_sortingChildCount > 0)
  219. {
  220. if (index > (cnt - _sortingChildCount))
  221. index = cnt - _sortingChildCount;
  222. }
  223. if (index == cnt)
  224. _children.Add(child);
  225. else
  226. _children.Insert(index, child);
  227. ChildStateChanged(child);
  228. SetBoundsChangedFlag();
  229. }
  230. return child;
  231. }
  232. else
  233. {
  234. throw new Exception("Invalid child index: " + index + ">" + _children.Count);
  235. }
  236. }
  237. int GetInsertPosForSortingChild(GObject target)
  238. {
  239. int cnt = _children.Count;
  240. int i;
  241. for (i = 0; i < cnt; i++)
  242. {
  243. GObject child = _children[i];
  244. if (child == target)
  245. continue;
  246. if (target.sortingOrder < child.sortingOrder)
  247. break;
  248. }
  249. return i;
  250. }
  251. /// <summary>
  252. /// Removes a child from the component. If the object is not a child, nothing happens.
  253. /// </summary>
  254. /// <param name="child">A child object</param>
  255. /// <returns>GObject</returns>
  256. public GObject RemoveChild(GObject child)
  257. {
  258. return RemoveChild(child, false);
  259. }
  260. /// <summary>
  261. /// Removes a child from the component. If the object is not a child, nothing happens.
  262. /// </summary>
  263. /// <param name="child">A child object</param>
  264. /// <param name="dispose">If true, the child will be disposed right away.</param>
  265. /// <returns>GObject</returns>
  266. public GObject RemoveChild(GObject child, bool dispose)
  267. {
  268. int childIndex = _children.IndexOf(child);
  269. if (childIndex != -1)
  270. {
  271. RemoveChildAt(childIndex, dispose);
  272. }
  273. return child;
  274. }
  275. /// <summary>
  276. /// Removes a child at a certain index. Children above the child will move down.
  277. /// </summary>
  278. /// <param name="index">Index</param>
  279. /// <returns>GObject</returns>
  280. public GObject RemoveChildAt(int index)
  281. {
  282. return RemoveChildAt(index, false);
  283. }
  284. /// <summary>
  285. /// Removes a child at a certain index. Children above the child will move down.
  286. /// </summary>
  287. /// <param name="index">Index</param>
  288. /// <param name="dispose">If true, the child will be disposed right away.</param>
  289. /// <returns>GObject</returns>
  290. virtual public GObject RemoveChildAt(int index, bool dispose)
  291. {
  292. if (index >= 0 && index < numChildren)
  293. {
  294. GObject child = _children[index];
  295. child.InternalSetParent(null);
  296. if (child.sortingOrder != 0)
  297. _sortingChildCount--;
  298. _children.RemoveAt(index);
  299. child.group = null;
  300. if (child.inContainer)
  301. {
  302. container.RemoveChild(child.displayObject);
  303. if (_childrenRenderOrder == ChildrenRenderOrder.Arch)
  304. {
  305. UpdateContext.OnBegin -= _buildDelegate;
  306. UpdateContext.OnBegin += _buildDelegate;
  307. }
  308. }
  309. if (dispose)
  310. child.Dispose();
  311. SetBoundsChangedFlag();
  312. return child;
  313. }
  314. else
  315. throw new Exception("Invalid child index: " + index + ">" + numChildren);
  316. }
  317. /// <summary>
  318. /// Remove all children.
  319. /// </summary>
  320. public void RemoveChildren()
  321. {
  322. RemoveChildren(0, -1, false);
  323. }
  324. /// <summary>
  325. /// Removes a range of children from the container (endIndex included).
  326. /// </summary>
  327. /// <param name="beginIndex">Begin index.</param>
  328. /// <param name="endIndex">End index.(Included).</param>
  329. /// <param name="dispose">If true, the child will be disposed right away.</param>
  330. public void RemoveChildren(int beginIndex, int endIndex, bool dispose)
  331. {
  332. if (endIndex < 0 || endIndex >= numChildren)
  333. endIndex = numChildren - 1;
  334. for (int i = beginIndex; i <= endIndex; ++i)
  335. RemoveChildAt(beginIndex, dispose);
  336. }
  337. /// <summary>
  338. /// Returns a child object at a certain index. If index out of bounds, exception raised.
  339. /// </summary>
  340. /// <param name="index">Index</param>
  341. /// <returns>A child object.</returns>
  342. public GObject GetChildAt(int index)
  343. {
  344. if (index >= 0 && index < numChildren)
  345. return _children[index];
  346. else
  347. throw new Exception("Invalid child index: " + index + ">" + numChildren);
  348. }
  349. /// <summary>
  350. /// Returns a child object with a certain name.
  351. /// </summary>
  352. /// <param name="name">Name</param>
  353. /// <returns>A child object. Null if not found.</returns>
  354. public GObject GetChild(string name)
  355. {
  356. int cnt = _children.Count;
  357. for (int i = 0; i < cnt; ++i)
  358. {
  359. if (_children[i].name == name)
  360. return _children[i];
  361. }
  362. return null;
  363. }
  364. public GObject GetChildByPath(string path)
  365. {
  366. string[] arr = path.Split('.');
  367. int cnt = arr.Length;
  368. GComponent gcom = this;
  369. GObject obj = null;
  370. for (int i = 0; i < cnt; ++i)
  371. {
  372. obj = gcom.GetChild(arr[i]);
  373. if (obj == null)
  374. break;
  375. if (i != cnt - 1)
  376. {
  377. if (!(obj is GComponent))
  378. {
  379. obj = null;
  380. break;
  381. }
  382. else
  383. gcom = (GComponent)obj;
  384. }
  385. }
  386. return obj;
  387. }
  388. /// <summary>
  389. /// Returns a visible child object with a certain name.
  390. /// </summary>
  391. /// <param name="name">Name</param>
  392. /// <returns>A child object. Null if not found.</returns>
  393. public GObject GetVisibleChild(string name)
  394. {
  395. int cnt = _children.Count;
  396. for (int i = 0; i < cnt; ++i)
  397. {
  398. GObject child = _children[i];
  399. if (child.internalVisible && child.internalVisible2 && child.name == name)
  400. return child;
  401. }
  402. return null;
  403. }
  404. /// <summary>
  405. /// Returns a child object belong to a group with a certain name.
  406. /// </summary>
  407. /// <param name="group">A group object</param>
  408. /// <param name="name">Name</param>
  409. /// <returns>A child object. Null if not found.</returns>
  410. public GObject GetChildInGroup(GGroup group, string name)
  411. {
  412. int cnt = _children.Count;
  413. for (int i = 0; i < cnt; ++i)
  414. {
  415. GObject child = _children[i];
  416. if (child.group == group && child.name == name)
  417. return child;
  418. }
  419. return null;
  420. }
  421. internal GObject GetChildById(string id)
  422. {
  423. int cnt = _children.Count;
  424. for (int i = 0; i < cnt; ++i)
  425. {
  426. if (_children[i].id == id)
  427. return _children[i];
  428. }
  429. return null;
  430. }
  431. /// <summary>
  432. /// Returns a copy of all children with an array.
  433. /// </summary>
  434. /// <returns>An array contains all children</returns>
  435. public GObject[] GetChildren()
  436. {
  437. return _children.ToArray();
  438. }
  439. /// <summary>
  440. /// Returns the index of a child within the container, or "-1" if it is not found.
  441. /// </summary>
  442. /// <param name="child">A child object</param>
  443. /// <returns>Index of the child. -1 If not found.</returns>
  444. public int GetChildIndex(GObject child)
  445. {
  446. return _children.IndexOf(child);
  447. }
  448. /// <summary>
  449. /// Moves a child to a certain index. Children at and after the replaced position move up.
  450. /// </summary>
  451. /// <param name="child">A Child</param>
  452. /// <param name="index">Index</param>
  453. public void SetChildIndex(GObject child, int index)
  454. {
  455. int oldIndex = _children.IndexOf(child);
  456. if (oldIndex == -1)
  457. throw new ArgumentException("Not a child of this container");
  458. if (child.sortingOrder != 0) //no effect
  459. return;
  460. if (_sortingChildCount > 0)
  461. {
  462. int cnt = _children.Count;
  463. if (index > (cnt - _sortingChildCount - 1))
  464. index = cnt - _sortingChildCount - 1;
  465. }
  466. _SetChildIndex(child, oldIndex, index);
  467. }
  468. /// <summary>
  469. /// Moves a child to a certain position which is in front of the child previously at given index.
  470. /// 与SetChildIndex不同的是,如果child原来在index的前面,那么child插入的位置是index-1,即保证排在原来占据index的对象的前面。
  471. /// </summary>
  472. /// <param name="child"></param>
  473. /// <param name="index"></param>
  474. public int SetChildIndexBefore(GObject child, int index)
  475. {
  476. int oldIndex = _children.IndexOf(child);
  477. if (oldIndex == -1)
  478. throw new ArgumentException("Not a child of this container");
  479. if (child.sortingOrder != 0) //no effect
  480. return oldIndex;
  481. int cnt = _children.Count;
  482. if (_sortingChildCount > 0)
  483. {
  484. if (index > (cnt - _sortingChildCount - 1))
  485. index = cnt - _sortingChildCount - 1;
  486. }
  487. if (oldIndex < index)
  488. return _SetChildIndex(child, oldIndex, index - 1);
  489. else
  490. return _SetChildIndex(child, oldIndex, index);
  491. }
  492. int _SetChildIndex(GObject child, int oldIndex, int index)
  493. {
  494. int cnt = _children.Count;
  495. if (index > cnt)
  496. index = cnt;
  497. if (oldIndex == index)
  498. return oldIndex;
  499. _children.RemoveAt(oldIndex);
  500. if (index >= cnt)
  501. _children.Add(child);
  502. else
  503. _children.Insert(index, child);
  504. if (child.inContainer)
  505. {
  506. int displayIndex = 0;
  507. if (_childrenRenderOrder == ChildrenRenderOrder.Ascent)
  508. {
  509. for (int i = 0; i < index; i++)
  510. {
  511. GObject g = _children[i];
  512. if (g.inContainer)
  513. displayIndex++;
  514. }
  515. container.SetChildIndex(child.displayObject, displayIndex);
  516. }
  517. else if (_childrenRenderOrder == ChildrenRenderOrder.Descent)
  518. {
  519. for (int i = cnt - 1; i > index; i--)
  520. {
  521. GObject g = _children[i];
  522. if (g.inContainer)
  523. displayIndex++;
  524. }
  525. container.SetChildIndex(child.displayObject, displayIndex);
  526. }
  527. else
  528. {
  529. UpdateContext.OnBegin -= _buildDelegate;
  530. UpdateContext.OnBegin += _buildDelegate;
  531. }
  532. SetBoundsChangedFlag();
  533. }
  534. return index;
  535. }
  536. /// <summary>
  537. /// Swaps the indexes of two children.
  538. /// </summary>
  539. /// <param name="child1">A child object</param>
  540. /// <param name="child2">A child object</param>
  541. public void SwapChildren(GObject child1, GObject child2)
  542. {
  543. int index1 = _children.IndexOf(child1);
  544. int index2 = _children.IndexOf(child2);
  545. if (index1 == -1 || index2 == -1)
  546. throw new Exception("Not a child of this container");
  547. SwapChildrenAt(index1, index2);
  548. }
  549. /// <summary>
  550. /// Swaps the indexes of two children.
  551. /// </summary>
  552. /// <param name="index1">index of first child</param>
  553. /// <param name="index2">index of second child</param>
  554. public void SwapChildrenAt(int index1, int index2)
  555. {
  556. GObject child1 = _children[index1];
  557. GObject child2 = _children[index2];
  558. SetChildIndex(child1, index2);
  559. SetChildIndex(child2, index1);
  560. }
  561. /// <summary>
  562. /// The number of children of this component.
  563. /// </summary>
  564. public int numChildren
  565. {
  566. get { return _children.Count; }
  567. }
  568. /// <summary>
  569. ///
  570. /// </summary>
  571. /// <param name="obj"></param>
  572. /// <returns></returns>
  573. public bool IsAncestorOf(GObject obj)
  574. {
  575. if (obj == null)
  576. return false;
  577. GComponent p = obj.parent;
  578. while (p != null)
  579. {
  580. if (p == this)
  581. return true;
  582. p = p.parent;
  583. }
  584. return false;
  585. }
  586. /// <summary>
  587. ///
  588. /// </summary>
  589. /// <param name="objs"></param>
  590. public void ChangeChildrenOrder(IList<GObject> objs)
  591. {
  592. int cnt = objs.Count;
  593. for (int i = 0; i < cnt; i++)
  594. {
  595. GObject obj = objs[i];
  596. if (obj.parent != this)
  597. throw new Exception("Not a child of this container");
  598. _children[i] = obj;
  599. }
  600. BuildNativeDisplayList();
  601. SetBoundsChangedFlag();
  602. }
  603. /// <summary>
  604. /// Adds a controller to the container.
  605. /// </summary>
  606. /// <param name="controller">Controller object</param>
  607. public void AddController(Controller controller)
  608. {
  609. _controllers.Add(controller);
  610. controller.parent = this;
  611. ApplyController(controller);
  612. }
  613. /// <summary>
  614. /// Returns a controller object at a certain index.
  615. /// </summary>
  616. /// <param name="index">Index</param>
  617. /// <returns>Controller object.</returns>
  618. public Controller GetControllerAt(int index)
  619. {
  620. return _controllers[index];
  621. }
  622. /// <summary>
  623. /// Returns a controller object with a certain name.
  624. /// </summary>
  625. /// <param name="name">Name</param>
  626. /// <returns>Controller object. Null if not found.</returns>
  627. public Controller GetController(string name)
  628. {
  629. int cnt = _controllers.Count;
  630. for (int i = 0; i < cnt; ++i)
  631. {
  632. Controller c = _controllers[i];
  633. if (c.name == name)
  634. return c;
  635. }
  636. return null;
  637. }
  638. /// <summary>
  639. /// Removes a controller from the container.
  640. /// </summary>
  641. /// <param name="c">Controller object.</param>
  642. public void RemoveController(Controller c)
  643. {
  644. int index = _controllers.IndexOf(c);
  645. if (index == -1)
  646. throw new Exception("controller not exists: " + c.name);
  647. c.parent = null;
  648. _controllers.RemoveAt(index);
  649. int cnt = _children.Count;
  650. for (int i = 0; i < cnt; ++i)
  651. {
  652. GObject child = _children[i];
  653. child.HandleControllerChanged(c);
  654. }
  655. }
  656. /// <summary>
  657. /// Returns controller list.
  658. /// </summary>
  659. /// <returns>Controller list</returns>
  660. public List<Controller> Controllers
  661. {
  662. get { return _controllers; }
  663. }
  664. /// <summary>
  665. /// Returns a transition object at a certain index.
  666. /// </summary>
  667. /// <param name="index">Index</param>
  668. /// <returns>transition object.</returns>
  669. public Transition GetTransitionAt(int index)
  670. {
  671. return _transitions[index];
  672. }
  673. /// <summary>
  674. /// Returns a transition object at a certain name.
  675. /// </summary>
  676. /// <param name="name">Name</param>
  677. /// <returns>Transition Object</returns>
  678. public Transition GetTransition(string name)
  679. {
  680. int cnt = _transitions.Count;
  681. for (int i = 0; i < cnt; ++i)
  682. {
  683. Transition trans = _transitions[i];
  684. if (trans.name == name)
  685. return trans;
  686. }
  687. return null;
  688. }
  689. /// <summary>
  690. /// Returns transition list.
  691. /// </summary>
  692. /// <returns>Transition list</returns>
  693. public List<Transition> Transitions
  694. {
  695. get { return _transitions; }
  696. }
  697. internal void ChildStateChanged(GObject child)
  698. {
  699. if (_buildingDisplayList)
  700. return;
  701. int cnt = _children.Count;
  702. if (child is GGroup)
  703. {
  704. for (int i = 0; i < cnt; ++i)
  705. {
  706. GObject g = _children[i];
  707. if (g.group == child)
  708. ChildStateChanged(g);
  709. }
  710. return;
  711. }
  712. if (child.displayObject == null)
  713. return;
  714. if (child.internalVisible)
  715. {
  716. if (child.displayObject.parent == null)
  717. {
  718. if (_childrenRenderOrder == ChildrenRenderOrder.Ascent)
  719. {
  720. int index = 0;
  721. for (int i = 0; i < cnt; i++)
  722. {
  723. GObject g = _children[i];
  724. if (g == child)
  725. break;
  726. if (g.displayObject != null && g.displayObject.parent != null)
  727. index++;
  728. }
  729. container.AddChildAt(child.displayObject, index);
  730. }
  731. else if (_childrenRenderOrder == ChildrenRenderOrder.Descent)
  732. {
  733. int index = 0;
  734. for (int i = cnt - 1; i >= 0; i--)
  735. {
  736. GObject g = _children[i];
  737. if (g == child)
  738. break;
  739. if (g.displayObject != null && g.displayObject.parent != null)
  740. index++;
  741. }
  742. container.AddChildAt(child.displayObject, index);
  743. }
  744. else
  745. {
  746. container.AddChild(child.displayObject);
  747. UpdateContext.OnBegin -= _buildDelegate;
  748. UpdateContext.OnBegin += _buildDelegate;
  749. }
  750. }
  751. }
  752. else
  753. {
  754. if (child.displayObject.parent != null)
  755. {
  756. container.RemoveChild(child.displayObject);
  757. if (_childrenRenderOrder == ChildrenRenderOrder.Arch)
  758. {
  759. UpdateContext.OnBegin -= _buildDelegate;
  760. UpdateContext.OnBegin += _buildDelegate;
  761. }
  762. }
  763. }
  764. }
  765. void BuildNativeDisplayList()
  766. {
  767. if (displayObject == null || displayObject.isDisposed)
  768. return;
  769. int cnt = _children.Count;
  770. if (cnt == 0)
  771. return;
  772. switch (_childrenRenderOrder)
  773. {
  774. case ChildrenRenderOrder.Ascent:
  775. {
  776. for (int i = 0; i < cnt; i++)
  777. {
  778. GObject child = _children[i];
  779. if (child.displayObject != null && child.internalVisible)
  780. container.AddChild(child.displayObject);
  781. }
  782. }
  783. break;
  784. case ChildrenRenderOrder.Descent:
  785. {
  786. for (int i = cnt - 1; i >= 0; i--)
  787. {
  788. GObject child = _children[i];
  789. if (child.displayObject != null && child.internalVisible)
  790. container.AddChild(child.displayObject);
  791. }
  792. }
  793. break;
  794. case ChildrenRenderOrder.Arch:
  795. {
  796. int apex = Mathf.Clamp(_apexIndex, 0, cnt);
  797. for (int i = 0; i < apex; i++)
  798. {
  799. GObject child = _children[i];
  800. if (child.displayObject != null && child.internalVisible)
  801. container.AddChild(child.displayObject);
  802. }
  803. for (int i = cnt - 1; i >= apex; i--)
  804. {
  805. GObject child = _children[i];
  806. if (child.displayObject != null && child.internalVisible)
  807. container.AddChild(child.displayObject);
  808. }
  809. }
  810. break;
  811. }
  812. }
  813. internal void ApplyController(Controller c)
  814. {
  815. _applyingController = c;
  816. int cnt = _children.Count;
  817. for (int i = 0; i < cnt; ++i)
  818. {
  819. GObject child = _children[i];
  820. child.HandleControllerChanged(c);
  821. }
  822. _applyingController = null;
  823. c.RunActions();
  824. }
  825. void ApplyAllControllers()
  826. {
  827. int cnt = _controllers.Count;
  828. for (int i = 0; i < cnt; ++i)
  829. {
  830. Controller controller = _controllers[i];
  831. ApplyController(controller);
  832. }
  833. }
  834. internal void AdjustRadioGroupDepth(GObject obj, Controller c)
  835. {
  836. int cnt = _children.Count;
  837. int i;
  838. GObject child;
  839. int myIndex = -1, maxIndex = -1;
  840. for (i = 0; i < cnt; i++)
  841. {
  842. child = _children[i];
  843. if (child == obj)
  844. {
  845. myIndex = i;
  846. }
  847. else if ((child is GButton)
  848. && ((GButton)child).relatedController == c)
  849. {
  850. if (i > maxIndex)
  851. maxIndex = i;
  852. }
  853. }
  854. if (myIndex < maxIndex)
  855. {
  856. if (_applyingController != null)
  857. _children[maxIndex].HandleControllerChanged(_applyingController);
  858. this.SwapChildrenAt(myIndex, maxIndex);
  859. }
  860. }
  861. /// <summary>
  862. /// If clipping softness is set, clipped containers will have soft border effect.
  863. /// </summary>
  864. public Vector2 clipSoftness
  865. {
  866. get { return _clipSoftness; }
  867. set
  868. {
  869. _clipSoftness = value;
  870. if (scrollPane != null)
  871. scrollPane.UpdateClipSoft();
  872. else if (_clipSoftness.x > 0 || _clipSoftness.y > 0)
  873. rootContainer.clipSoftness = new Vector4(value.x, value.y, value.x, value.y);
  874. else
  875. rootContainer.clipSoftness = null;
  876. }
  877. }
  878. /// <summary>
  879. /// The mask of the component.
  880. /// </summary>
  881. public DisplayObject mask
  882. {
  883. get { return container.mask; }
  884. set
  885. {
  886. container.mask = value;
  887. if (value != null && value.parent != container)
  888. container.AddChild(value);
  889. }
  890. }
  891. /// <summary>
  892. ///
  893. /// </summary>
  894. public bool reversedMask
  895. {
  896. get { return container.reversedMask; }
  897. set { container.reversedMask = value; }
  898. }
  899. /// <summary>
  900. ///
  901. /// </summary>
  902. public string baseUserData
  903. {
  904. get
  905. {
  906. ByteBuffer buffer = packageItem.rawData;
  907. buffer.Seek(0, 4);
  908. return buffer.ReadS();
  909. }
  910. }
  911. /// <summary>
  912. /// Test if a child is in view.
  913. /// </summary>
  914. /// <param name="child">A child object</param>
  915. /// <returns>True if in view</returns>
  916. public bool IsChildInView(GObject child)
  917. {
  918. if (scrollPane != null)
  919. {
  920. return scrollPane.IsChildInView(child);
  921. }
  922. else if (rootContainer.clipRect != null)
  923. {
  924. return child.x + child.width >= 0 && child.x <= this.width
  925. && child.y + child.height >= 0 && child.y <= this.height;
  926. }
  927. else
  928. return true;
  929. }
  930. virtual public int GetFirstChildInView()
  931. {
  932. int cnt = _children.Count;
  933. for (int i = 0; i < cnt; ++i)
  934. {
  935. GObject child = _children[i];
  936. if (IsChildInView(child))
  937. return i;
  938. }
  939. return -1;
  940. }
  941. protected void SetupScroll(ByteBuffer buffer)
  942. {
  943. if (rootContainer == container)
  944. {
  945. container = new Container();
  946. rootContainer.AddChild(container);
  947. }
  948. scrollPane = new ScrollPane(this);
  949. scrollPane.Setup(buffer);
  950. }
  951. protected void SetupOverflow(OverflowType overflow)
  952. {
  953. if (overflow == OverflowType.Hidden)
  954. {
  955. if (rootContainer == container)
  956. {
  957. container = new Container();
  958. rootContainer.AddChild(container);
  959. }
  960. UpdateClipRect();
  961. container.SetXY(_margin.left, _margin.top);
  962. }
  963. else if (_margin.left != 0 || _margin.top != 0)
  964. {
  965. if (rootContainer == container)
  966. {
  967. container = new Container();
  968. rootContainer.AddChild(container);
  969. }
  970. container.SetXY(_margin.left, _margin.top);
  971. }
  972. }
  973. void UpdateClipRect()
  974. {
  975. if (scrollPane == null)
  976. {
  977. float w = this.width - (_margin.left + _margin.right);
  978. float h = this.height - (_margin.top + _margin.bottom);
  979. rootContainer.clipRect = new Rect(_margin.left, _margin.top, w, h);
  980. }
  981. else
  982. rootContainer.clipRect = new Rect(0, 0, this.width, this.height);
  983. }
  984. override protected void HandleSizeChanged()
  985. {
  986. base.HandleSizeChanged();
  987. if (scrollPane != null)
  988. scrollPane.OnOwnerSizeChanged();
  989. if (rootContainer.clipRect != null)
  990. UpdateClipRect();
  991. }
  992. override protected void HandleGrayedChanged()
  993. {
  994. Controller cc = GetController("grayed");
  995. if (cc != null)
  996. cc.selectedIndex = this.grayed ? 1 : 0;
  997. else
  998. base.HandleGrayedChanged();
  999. }
  1000. override public void HandleControllerChanged(Controller c)
  1001. {
  1002. base.HandleControllerChanged(c);
  1003. if (scrollPane != null)
  1004. scrollPane.HandleControllerChanged(c);
  1005. }
  1006. /// <summary>
  1007. /// Notify the component the bounds should recaculate.
  1008. /// </summary>
  1009. public void SetBoundsChangedFlag()
  1010. {
  1011. if (scrollPane == null && !_trackBounds)
  1012. return;
  1013. _boundsChanged = true;
  1014. }
  1015. /// <summary>
  1016. /// Make sure the bounds of the component is correct.
  1017. /// Bounds of the component is not updated on every changed. For example, you add a new child to the list, children in the list will be rearranged in next frame.
  1018. /// If you want to access the correct child position immediatelly, call this function first.
  1019. /// </summary>
  1020. public void EnsureBoundsCorrect()
  1021. {
  1022. if (_boundsChanged)
  1023. UpdateBounds();
  1024. }
  1025. virtual protected void UpdateBounds()
  1026. {
  1027. float ax, ay, aw, ah;
  1028. if (_children.Count > 0)
  1029. {
  1030. ax = int.MaxValue;
  1031. ay = int.MaxValue;
  1032. float ar = int.MinValue, ab = int.MinValue;
  1033. float tmp;
  1034. int cnt = _children.Count;
  1035. for (int i = 0; i < cnt; ++i)
  1036. {
  1037. GObject child = _children[i];
  1038. tmp = child.x;
  1039. if (tmp < ax)
  1040. ax = tmp;
  1041. tmp = child.y;
  1042. if (tmp < ay)
  1043. ay = tmp;
  1044. tmp = child.x + child.actualWidth;
  1045. if (tmp > ar)
  1046. ar = tmp;
  1047. tmp = child.y + child.actualHeight;
  1048. if (tmp > ab)
  1049. ab = tmp;
  1050. }
  1051. aw = ar - ax;
  1052. ah = ab - ay;
  1053. }
  1054. else
  1055. {
  1056. ax = 0;
  1057. ay = 0;
  1058. aw = 0;
  1059. ah = 0;
  1060. }
  1061. SetBounds(ax, ay, aw, ah);
  1062. }
  1063. protected void SetBounds(float ax, float ay, float aw, float ah)
  1064. {
  1065. _boundsChanged = false;
  1066. if (scrollPane != null)
  1067. scrollPane.SetContentSize(Mathf.RoundToInt(ax + aw), Mathf.RoundToInt(ay + ah));
  1068. }
  1069. /// <summary>
  1070. /// Viwe port width of the container.
  1071. /// </summary>
  1072. public float viewWidth
  1073. {
  1074. get
  1075. {
  1076. if (scrollPane != null)
  1077. return scrollPane.viewWidth;
  1078. else
  1079. return this.width - _margin.left - _margin.right;
  1080. }
  1081. set
  1082. {
  1083. if (scrollPane != null)
  1084. scrollPane.viewWidth = value;
  1085. else
  1086. this.width = value + _margin.left + _margin.right;
  1087. }
  1088. }
  1089. /// <summary>
  1090. /// View port height of the container.
  1091. /// </summary>
  1092. public float viewHeight
  1093. {
  1094. get
  1095. {
  1096. if (scrollPane != null)
  1097. return scrollPane.viewHeight;
  1098. else
  1099. return this.height - _margin.top - _margin.bottom;
  1100. }
  1101. set
  1102. {
  1103. if (scrollPane != null)
  1104. scrollPane.viewHeight = value;
  1105. else
  1106. this.height = value + _margin.top + _margin.bottom;
  1107. }
  1108. }
  1109. public void GetSnappingPosition(ref float xValue, ref float yValue)
  1110. {
  1111. GetSnappingPositionWithDir(ref xValue, ref yValue, 0, 0);
  1112. }
  1113. protected bool ShouldSnapToNext(float dir, float delta, float size)
  1114. {
  1115. return dir < 0 && delta > UIConfig.defaultScrollSnappingThreshold * size
  1116. || dir > 0 && delta > (1 - UIConfig.defaultScrollSnappingThreshold) * size
  1117. || dir == 0 && delta > size / 2;
  1118. }
  1119. /**
  1120. * dir正数表示右移或者下移,负数表示左移或者上移
  1121. */
  1122. virtual public void GetSnappingPositionWithDir(ref float xValue, ref float yValue, float xDir, float yDir)
  1123. {
  1124. int cnt = _children.Count;
  1125. if (cnt == 0)
  1126. return;
  1127. EnsureBoundsCorrect();
  1128. GObject obj = null;
  1129. int i = 0;
  1130. if (yValue != 0)
  1131. {
  1132. for (; i < cnt; i++)
  1133. {
  1134. obj = _children[i];
  1135. if (yValue < obj.y)
  1136. {
  1137. if (i == 0)
  1138. {
  1139. yValue = 0;
  1140. break;
  1141. }
  1142. else
  1143. {
  1144. GObject prev = _children[i - 1];
  1145. if (ShouldSnapToNext(yDir, yValue - prev.y, prev.height))
  1146. yValue = obj.y;
  1147. else
  1148. yValue = prev.y;
  1149. break;
  1150. }
  1151. }
  1152. }
  1153. if (i == cnt)
  1154. yValue = obj.y;
  1155. }
  1156. if (xValue != 0)
  1157. {
  1158. if (i > 0)
  1159. i--;
  1160. for (; i < cnt; i++)
  1161. {
  1162. obj = _children[i];
  1163. if (xValue < obj.x)
  1164. {
  1165. if (i == 0)
  1166. {
  1167. xValue = 0;
  1168. break;
  1169. }
  1170. else
  1171. {
  1172. GObject prev = _children[i - 1];
  1173. if (ShouldSnapToNext(xDir, xValue - prev.x, prev.width))
  1174. xValue = obj.x;
  1175. else
  1176. xValue = prev.x;
  1177. break;
  1178. }
  1179. }
  1180. }
  1181. if (i == cnt)
  1182. xValue = obj.x;
  1183. }
  1184. }
  1185. internal void ChildSortingOrderChanged(GObject child, int oldValue, int newValue)
  1186. {
  1187. if (newValue == 0)
  1188. {
  1189. _sortingChildCount--;
  1190. SetChildIndex(child, _children.Count);
  1191. }
  1192. else
  1193. {
  1194. if (oldValue == 0)
  1195. _sortingChildCount++;
  1196. int oldIndex = _children.IndexOf(child);
  1197. int index = GetInsertPosForSortingChild(child);
  1198. if (oldIndex < index)
  1199. _SetChildIndex(child, oldIndex, index - 1);
  1200. else
  1201. _SetChildIndex(child, oldIndex, index);
  1202. }
  1203. }
  1204. /// <summary>
  1205. /// 每帧调用的一个回调。如果你要override,请记住以下两点:
  1206. /// 1、记得调用base.onUpdate;
  1207. /// 2、不要在方法里进行任何会更改显示列表的操作,例如AddChild、RemoveChild、visible等。
  1208. /// </summary>
  1209. virtual protected void OnUpdate()
  1210. {
  1211. if (_boundsChanged)
  1212. UpdateBounds();
  1213. }
  1214. override public void ConstructFromResource()
  1215. {
  1216. ConstructFromResource(null, 0);
  1217. }
  1218. internal void ConstructFromResource(List<GObject> objectPool, int poolIndex)
  1219. {
  1220. this.gameObjectName = packageItem.name;
  1221. PackageItem contentItem = packageItem.getBranch();
  1222. if (!contentItem.translated)
  1223. {
  1224. contentItem.translated = true;
  1225. TranslationHelper.TranslateComponent(contentItem);
  1226. }
  1227. ByteBuffer buffer = contentItem.rawData;
  1228. buffer.Seek(0, 0);
  1229. underConstruct = true;
  1230. sourceWidth = buffer.ReadInt();
  1231. sourceHeight = buffer.ReadInt();
  1232. initWidth = sourceWidth;
  1233. initHeight = sourceHeight;
  1234. SetSize(sourceWidth, sourceHeight);
  1235. if (buffer.ReadBool())
  1236. {
  1237. minWidth = buffer.ReadInt();
  1238. maxWidth = buffer.ReadInt();
  1239. minHeight = buffer.ReadInt();
  1240. maxHeight = buffer.ReadInt();
  1241. }
  1242. if (buffer.ReadBool())
  1243. {
  1244. float f1 = buffer.ReadFloat();
  1245. float f2 = buffer.ReadFloat();
  1246. SetPivot(f1, f2, buffer.ReadBool());
  1247. }
  1248. if (buffer.ReadBool())
  1249. {
  1250. _margin.top = buffer.ReadInt();
  1251. _margin.bottom = buffer.ReadInt();
  1252. _margin.left = buffer.ReadInt();
  1253. _margin.right = buffer.ReadInt();
  1254. }
  1255. OverflowType overflow = (OverflowType)buffer.ReadByte();
  1256. if (overflow == OverflowType.Scroll)
  1257. {
  1258. int savedPos = buffer.position;
  1259. buffer.Seek(0, 7);
  1260. SetupScroll(buffer);
  1261. buffer.position = savedPos;
  1262. }
  1263. else
  1264. SetupOverflow(overflow);
  1265. if (buffer.ReadBool())
  1266. {
  1267. int i1 = buffer.ReadInt();
  1268. int i2 = buffer.ReadInt();
  1269. this.clipSoftness = new Vector2(i1, i2);
  1270. }
  1271. _buildingDisplayList = true;
  1272. buffer.Seek(0, 1);
  1273. int controllerCount = buffer.ReadShort();
  1274. for (int i = 0; i < controllerCount; i++)
  1275. {
  1276. int nextPos = buffer.ReadUshort();
  1277. nextPos += buffer.position;
  1278. Controller controller = new Controller();
  1279. _controllers.Add(controller);
  1280. controller.parent = this;
  1281. controller.Setup(buffer);
  1282. buffer.position = nextPos;
  1283. }
  1284. buffer.Seek(0, 2);
  1285. GObject child;
  1286. int childCount = buffer.ReadShort();
  1287. for (int i = 0; i < childCount; i++)
  1288. {
  1289. int dataLen = buffer.ReadShort();
  1290. int curPos = buffer.position;
  1291. if (objectPool != null)
  1292. child = objectPool[poolIndex + i];
  1293. else
  1294. {
  1295. buffer.Seek(curPos, 0);
  1296. ObjectType type = (ObjectType)buffer.ReadByte();
  1297. string src = buffer.ReadS();
  1298. string pkgId = buffer.ReadS();
  1299. PackageItem pi = null;
  1300. if (src != null)
  1301. {
  1302. UIPackage pkg;
  1303. if (pkgId != null)
  1304. pkg = UIPackage.GetById(pkgId);
  1305. else
  1306. pkg = contentItem.owner;
  1307. pi = pkg != null ? pkg.GetItem(src) : null;
  1308. }
  1309. if (pi != null)
  1310. {
  1311. child = UIObjectFactory.NewObject(pi);
  1312. child.ConstructFromResource();
  1313. }
  1314. else
  1315. child = UIObjectFactory.NewObject(type);
  1316. }
  1317. child.underConstruct = true;
  1318. child.Setup_BeforeAdd(buffer, curPos);
  1319. child.InternalSetParent(this);
  1320. _children.Add(child);
  1321. buffer.position = curPos + dataLen;
  1322. }
  1323. buffer.Seek(0, 3);
  1324. this.relations.Setup(buffer, true);
  1325. buffer.Seek(0, 2);
  1326. buffer.Skip(2);
  1327. for (int i = 0; i < childCount; i++)
  1328. {
  1329. int nextPos = buffer.ReadUshort();
  1330. nextPos += buffer.position;
  1331. buffer.Seek(buffer.position, 3);
  1332. _children[i].relations.Setup(buffer, false);
  1333. buffer.position = nextPos;
  1334. }
  1335. buffer.Seek(0, 2);
  1336. buffer.Skip(2);
  1337. for (int i = 0; i < childCount; i++)
  1338. {
  1339. int nextPos = buffer.ReadUshort();
  1340. nextPos += buffer.position;
  1341. child = _children[i];
  1342. child.Setup_AfterAdd(buffer, buffer.position);
  1343. child.underConstruct = false;
  1344. if (child.displayObject != null)
  1345. child.displayObject.cachedTransform.SetParent(this.displayObject.cachedTransform, false);
  1346. buffer.position = nextPos;
  1347. }
  1348. buffer.Seek(0, 4);
  1349. buffer.Skip(2); //customData
  1350. this.opaque = buffer.ReadBool();
  1351. int maskId = buffer.ReadShort();
  1352. if (maskId != -1)
  1353. {
  1354. container.mask = GetChildAt(maskId).displayObject;
  1355. if (buffer.ReadBool())
  1356. container.reversedMask = true;
  1357. }
  1358. {
  1359. string hitTestId = buffer.ReadS();
  1360. int i1 = buffer.ReadInt();
  1361. int i2 = buffer.ReadInt();
  1362. if (hitTestId != null)
  1363. {
  1364. PackageItem pi = contentItem.owner.GetItem(hitTestId);
  1365. if (pi != null && pi.pixelHitTestData != null)
  1366. rootContainer.hitArea = new PixelHitTest(pi.pixelHitTestData, i1, i2, sourceWidth, sourceHeight);
  1367. }
  1368. else if (i1 != 0 && i2 != -1)
  1369. {
  1370. rootContainer.hitArea = new ShapeHitTest(this.GetChildAt(i2).displayObject);
  1371. }
  1372. }
  1373. if (buffer.version >= 5)
  1374. {
  1375. string str = buffer.ReadS();
  1376. if (!string.IsNullOrEmpty(str))
  1377. this.onAddedToStage.Add(() => __playSound(str, 1));
  1378. string str2 = buffer.ReadS();
  1379. if (!string.IsNullOrEmpty(str2))
  1380. this.onRemovedFromStage.Add(() => __playSound(str2, 1));
  1381. }
  1382. buffer.Seek(0, 5);
  1383. int transitionCount = buffer.ReadShort();
  1384. for (int i = 0; i < transitionCount; i++)
  1385. {
  1386. int nextPos = buffer.ReadUshort();
  1387. nextPos += buffer.position;
  1388. Transition trans = new Transition(this);
  1389. trans.Setup(buffer);
  1390. _transitions.Add(trans);
  1391. buffer.position = nextPos;
  1392. }
  1393. if (_transitions.Count > 0)
  1394. {
  1395. this.onAddedToStage.Add(__addedToStage);
  1396. this.onRemovedFromStage.Add(__removedFromStage);
  1397. }
  1398. ApplyAllControllers();
  1399. _buildingDisplayList = false;
  1400. underConstruct = false;
  1401. BuildNativeDisplayList();
  1402. SetBoundsChangedFlag();
  1403. if (contentItem.objectType != ObjectType.Component)
  1404. ConstructExtension(buffer);
  1405. ConstructFromXML(null);
  1406. #if FAIRYGUI_TOLUA
  1407. CallLua("ctor");
  1408. #endif
  1409. #if FAIRYGUI_PUERTS
  1410. if (__onConstruct != null)
  1411. __onConstruct();
  1412. #endif
  1413. }
  1414. virtual protected void ConstructExtension(ByteBuffer buffer)
  1415. {
  1416. }
  1417. /// <summary>
  1418. /// Method for extensions to override
  1419. /// </summary>
  1420. /// <param name="xml"></param>
  1421. virtual public void ConstructFromXML(XML xml)
  1422. {
  1423. }
  1424. public override void Setup_AfterAdd(ByteBuffer buffer, int beginPos)
  1425. {
  1426. base.Setup_AfterAdd(buffer, beginPos);
  1427. buffer.Seek(beginPos, 4);
  1428. int pageController = buffer.ReadShort();
  1429. if (pageController != -1 && scrollPane != null && scrollPane.pageMode)
  1430. scrollPane.pageController = parent.GetControllerAt(pageController);
  1431. int cnt = buffer.ReadShort();
  1432. for (int i = 0; i < cnt; i++)
  1433. {
  1434. Controller cc = GetController(buffer.ReadS());
  1435. string pageId = buffer.ReadS();
  1436. if (cc != null)
  1437. cc.selectedPageId = pageId;
  1438. }
  1439. if (buffer.version >= 2)
  1440. {
  1441. cnt = buffer.ReadShort();
  1442. for (int i = 0; i < cnt; i++)
  1443. {
  1444. string target = buffer.ReadS();
  1445. int propertyId = buffer.ReadShort();
  1446. string value = buffer.ReadS();
  1447. GObject obj = this.GetChildByPath(target);
  1448. if (obj != null)
  1449. {
  1450. if (propertyId == 0)
  1451. obj.text = value;
  1452. else if (propertyId == 1)
  1453. obj.icon = value;
  1454. }
  1455. }
  1456. }
  1457. }
  1458. void __playSound(string soundRes, float volumeScale)
  1459. {
  1460. NAudioClip sound = UIPackage.GetItemAssetByURL(soundRes) as NAudioClip;
  1461. if (sound != null && sound.nativeClip != null)
  1462. Stage.inst.PlayOneShotSound(sound.nativeClip, volumeScale);
  1463. }
  1464. void __addedToStage()
  1465. {
  1466. int cnt = _transitions.Count;
  1467. for (int i = 0; i < cnt; ++i)
  1468. _transitions[i].OnOwnerAddedToStage();
  1469. }
  1470. void __removedFromStage()
  1471. {
  1472. int cnt = _transitions.Count;
  1473. for (int i = 0; i < cnt; ++i)
  1474. _transitions[i].OnOwnerRemovedFromStage();
  1475. }
  1476. #if FAIRYGUI_TOLUA
  1477. internal LuaTable _peerTable;
  1478. public void SetLuaPeer(LuaTable peerTable)
  1479. {
  1480. _peerTable = peerTable;
  1481. }
  1482. [NoToLua]
  1483. public bool CallLua(string funcName)
  1484. {
  1485. if (_peerTable != null)
  1486. {
  1487. LuaFunction ctor = _peerTable.GetLuaFunction(funcName);
  1488. if (ctor != null)
  1489. {
  1490. try
  1491. {
  1492. ctor.Call(this);
  1493. }
  1494. catch (Exception err)
  1495. {
  1496. Debug.LogError(err);
  1497. }
  1498. ctor.Dispose();
  1499. return true;
  1500. }
  1501. }
  1502. return false;
  1503. }
  1504. #endif
  1505. #if FAIRYGUI_PUERTS
  1506. public Action __onConstruct;
  1507. public Action __onDispose;
  1508. #endif
  1509. }
  1510. }