GGroup.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. using System;
  2. using FairyGUI.Utils;
  3. using UnityEngine;
  4. namespace FairyGUI
  5. {
  6. /// <summary>
  7. /// GGroup class.
  8. /// 组对象,对应编辑器里的高级组。
  9. /// </summary>
  10. public class GGroup : GObject
  11. {
  12. GroupLayoutType _layout;
  13. int _lineGap;
  14. int _columnGap;
  15. bool _excludeInvisibles;
  16. bool _autoSizeDisabled;
  17. int _mainGridIndex;
  18. int _mainGridMinSize;
  19. bool _percentReady;
  20. bool _boundsChanged;
  21. int _mainChildIndex;
  22. float _totalSize;
  23. int _numChildren;
  24. internal int _updating;
  25. Action _refreshDelegate;
  26. public GGroup()
  27. {
  28. _mainGridIndex = -1;
  29. _mainChildIndex = -1;
  30. _mainGridMinSize = 50;
  31. _refreshDelegate = EnsureBoundsCorrect;
  32. }
  33. /// <summary>
  34. /// Group layout type.
  35. /// </summary>
  36. public GroupLayoutType layout
  37. {
  38. get { return _layout; }
  39. set
  40. {
  41. if (_layout != value)
  42. {
  43. _layout = value;
  44. SetBoundsChangedFlag();
  45. }
  46. }
  47. }
  48. /// <summary>
  49. ///
  50. /// </summary>
  51. public int lineGap
  52. {
  53. get { return _lineGap; }
  54. set
  55. {
  56. if (_lineGap != value)
  57. {
  58. _lineGap = value;
  59. SetBoundsChangedFlag(true);
  60. }
  61. }
  62. }
  63. /// <summary>
  64. ///
  65. /// </summary>
  66. public int columnGap
  67. {
  68. get { return _columnGap; }
  69. set
  70. {
  71. if (_columnGap != value)
  72. {
  73. _columnGap = value;
  74. SetBoundsChangedFlag(true);
  75. }
  76. }
  77. }
  78. /// <summary>
  79. ///
  80. /// </summary>
  81. public bool excludeInvisibles
  82. {
  83. get { return _excludeInvisibles; }
  84. set
  85. {
  86. if (_excludeInvisibles != value)
  87. {
  88. _excludeInvisibles = value;
  89. SetBoundsChangedFlag();
  90. }
  91. }
  92. }
  93. /// <summary>
  94. ///
  95. /// </summary>
  96. public bool autoSizeDisabled
  97. {
  98. get { return _autoSizeDisabled; }
  99. set
  100. {
  101. if (_autoSizeDisabled != value)
  102. {
  103. _autoSizeDisabled = value;
  104. SetBoundsChangedFlag();
  105. }
  106. }
  107. }
  108. /// <summary>
  109. ///
  110. /// </summary>
  111. public int mainGridMinSize
  112. {
  113. get { return _mainGridMinSize; }
  114. set
  115. {
  116. if (_mainGridMinSize != value)
  117. {
  118. _mainGridMinSize = value;
  119. SetBoundsChangedFlag();
  120. }
  121. }
  122. }
  123. /// <summary>
  124. ///
  125. /// </summary>
  126. public int mainGridIndex
  127. {
  128. get { return _mainGridIndex; }
  129. set
  130. {
  131. if (_mainGridIndex != value)
  132. {
  133. _mainGridIndex = value;
  134. SetBoundsChangedFlag();
  135. }
  136. }
  137. }
  138. /// <summary>
  139. /// Update group bounds.
  140. /// 更新组的包围.
  141. /// </summary>
  142. public void SetBoundsChangedFlag(bool positionChangedOnly = false)
  143. {
  144. if (_updating == 0 && parent != null)
  145. {
  146. if (!positionChangedOnly)
  147. _percentReady = false;
  148. if (!_boundsChanged)
  149. {
  150. _boundsChanged = true;
  151. if (_layout != GroupLayoutType.None)
  152. {
  153. UpdateContext.OnBegin -= _refreshDelegate;
  154. UpdateContext.OnBegin += _refreshDelegate;
  155. }
  156. }
  157. }
  158. }
  159. public void EnsureBoundsCorrect()
  160. {
  161. if (parent == null || !_boundsChanged)
  162. return;
  163. UpdateContext.OnBegin -= _refreshDelegate;
  164. _boundsChanged = false;
  165. if (_autoSizeDisabled)
  166. ResizeChildren(0, 0);
  167. else
  168. {
  169. HandleLayout();
  170. UpdateBounds();
  171. }
  172. }
  173. void UpdateBounds()
  174. {
  175. int cnt = parent.numChildren;
  176. int i;
  177. GObject child;
  178. float ax = int.MaxValue, ay = int.MaxValue;
  179. float ar = int.MinValue, ab = int.MinValue;
  180. float tmp;
  181. bool empty = true;
  182. bool skipInvisibles = _layout != GroupLayoutType.None && _excludeInvisibles;
  183. for (i = 0; i < cnt; i++)
  184. {
  185. child = parent.GetChildAt(i);
  186. if (child.group != this)
  187. continue;
  188. if (skipInvisibles && !child.internalVisible3)
  189. continue;
  190. tmp = child.xMin;
  191. if (tmp < ax)
  192. ax = tmp;
  193. tmp = child.yMin;
  194. if (tmp < ay)
  195. ay = tmp;
  196. tmp = child.xMin + child.width;
  197. if (tmp > ar)
  198. ar = tmp;
  199. tmp = child.yMin + child.height;
  200. if (tmp > ab)
  201. ab = tmp;
  202. empty = false;
  203. }
  204. float w;
  205. float h;
  206. if (!empty)
  207. {
  208. _updating |= 1;
  209. SetXY(ax, ay);
  210. _updating &= 2;
  211. w = ar - ax;
  212. h = ab - ay;
  213. }
  214. else
  215. w = h = 0;
  216. if ((_updating & 2) == 0)
  217. {
  218. _updating |= 2;
  219. SetSize(w, h);
  220. _updating &= 1;
  221. }
  222. else
  223. {
  224. _updating &= 1;
  225. ResizeChildren(_width - w, _height - h);
  226. }
  227. }
  228. void HandleLayout()
  229. {
  230. _updating |= 1;
  231. if (_layout == GroupLayoutType.Horizontal)
  232. {
  233. float curX = this.x;
  234. int cnt = parent.numChildren;
  235. for (int i = 0; i < cnt; i++)
  236. {
  237. GObject child = parent.GetChildAt(i);
  238. if (child.group != this)
  239. continue;
  240. if (_excludeInvisibles && !child.internalVisible3)
  241. continue;
  242. child.xMin = curX;
  243. if (child.width != 0)
  244. curX += child.width + _columnGap;
  245. }
  246. }
  247. else if (_layout == GroupLayoutType.Vertical)
  248. {
  249. float curY = this.y;
  250. int cnt = parent.numChildren;
  251. for (int i = 0; i < cnt; i++)
  252. {
  253. GObject child = parent.GetChildAt(i);
  254. if (child.group != this)
  255. continue;
  256. if (_excludeInvisibles && !child.internalVisible3)
  257. continue;
  258. child.yMin = curY;
  259. if (child.height != 0)
  260. curY += child.height + _lineGap;
  261. }
  262. }
  263. _updating &= 2;
  264. }
  265. internal void MoveChildren(float dx, float dy)
  266. {
  267. if ((_updating & 1) != 0 || parent == null)
  268. return;
  269. _updating |= 1;
  270. int cnt = parent.numChildren;
  271. int i;
  272. GObject child;
  273. for (i = 0; i < cnt; i++)
  274. {
  275. child = parent.GetChildAt(i);
  276. if (child.group == this)
  277. {
  278. child.SetXY(child.x + dx, child.y + dy);
  279. }
  280. }
  281. _updating &= 2;
  282. }
  283. internal void ResizeChildren(float dw, float dh)
  284. {
  285. if (_layout == GroupLayoutType.None || (_updating & 2) != 0 || parent == null)
  286. return;
  287. _updating |= 2;
  288. if (_boundsChanged)
  289. {
  290. _boundsChanged = false;
  291. if (!_autoSizeDisabled)
  292. {
  293. UpdateBounds();
  294. return;
  295. }
  296. }
  297. int cnt = parent.numChildren;
  298. if (!_percentReady)
  299. {
  300. _percentReady = true;
  301. _numChildren = 0;
  302. _totalSize = 0;
  303. _mainChildIndex = -1;
  304. int j = 0;
  305. for (int i = 0; i < cnt; i++)
  306. {
  307. GObject child = parent.GetChildAt(i);
  308. if (child.group != this)
  309. continue;
  310. if (!_excludeInvisibles || child.internalVisible3)
  311. {
  312. if (j == _mainGridIndex)
  313. _mainChildIndex = i;
  314. _numChildren++;
  315. if (_layout == GroupLayoutType.Horizontal)
  316. _totalSize += child.width;
  317. else
  318. _totalSize += child.height;
  319. }
  320. j++;
  321. }
  322. if (_mainChildIndex != -1)
  323. {
  324. if (_layout == GroupLayoutType.Horizontal)
  325. {
  326. GObject child = parent.GetChildAt(_mainChildIndex);
  327. _totalSize += _mainGridMinSize - child.width;
  328. child._sizePercentInGroup = _mainGridMinSize / _totalSize;
  329. }
  330. else
  331. {
  332. GObject child = parent.GetChildAt(_mainChildIndex);
  333. _totalSize += _mainGridMinSize - child.height;
  334. child._sizePercentInGroup = _mainGridMinSize / _totalSize;
  335. }
  336. }
  337. for (int i = 0; i < cnt; i++)
  338. {
  339. GObject child = parent.GetChildAt(i);
  340. if (child.group != this)
  341. continue;
  342. if (i == _mainChildIndex)
  343. continue;
  344. if (_totalSize > 0)
  345. child._sizePercentInGroup = (_layout == GroupLayoutType.Horizontal ? child.width : child.height) / _totalSize;
  346. else
  347. child._sizePercentInGroup = 0;
  348. }
  349. }
  350. float remainSize = 0;
  351. float remainPercent = 1;
  352. bool priorHandled = false;
  353. if (_layout == GroupLayoutType.Horizontal)
  354. {
  355. remainSize = this.width - (_numChildren - 1) * _columnGap;
  356. if (_mainChildIndex != -1 && remainSize >= _totalSize)
  357. {
  358. GObject child = parent.GetChildAt(_mainChildIndex);
  359. child.SetSize(remainSize - (_totalSize - _mainGridMinSize), child._rawHeight + dh, true);
  360. remainSize -= child.width;
  361. remainPercent -= child._sizePercentInGroup;
  362. priorHandled = true;
  363. }
  364. float curX = this.x;
  365. for (int i = 0; i < cnt; i++)
  366. {
  367. GObject child = parent.GetChildAt(i);
  368. if (child.group != this)
  369. continue;
  370. if (_excludeInvisibles && !child.internalVisible3)
  371. {
  372. child.SetSize(child._rawWidth, child._rawHeight + dh, true);
  373. continue;
  374. }
  375. if (!priorHandled || i != _mainChildIndex)
  376. {
  377. child.SetSize(Mathf.Round(child._sizePercentInGroup / remainPercent * remainSize), child._rawHeight + dh, true);
  378. remainPercent -= child._sizePercentInGroup;
  379. remainSize -= child.width;
  380. }
  381. child.xMin = curX;
  382. if (child.width != 0)
  383. curX += child.width + _columnGap;
  384. }
  385. }
  386. else
  387. {
  388. remainSize = this.height - (_numChildren - 1) * _lineGap;
  389. if (_mainChildIndex != -1 && remainSize >= _totalSize)
  390. {
  391. GObject child = parent.GetChildAt(_mainChildIndex);
  392. child.SetSize(child._rawWidth + dw, remainSize - (_totalSize - _mainGridMinSize), true);
  393. remainSize -= child.height;
  394. remainPercent -= child._sizePercentInGroup;
  395. priorHandled = true;
  396. }
  397. float curY = this.y;
  398. for (int i = 0; i < cnt; i++)
  399. {
  400. GObject child = parent.GetChildAt(i);
  401. if (child.group != this)
  402. continue;
  403. if (_excludeInvisibles && !child.internalVisible3)
  404. {
  405. child.SetSize(child._rawWidth + dw, child._rawHeight, true);
  406. continue;
  407. }
  408. if (!priorHandled || i != _mainChildIndex)
  409. {
  410. child.SetSize(child._rawWidth + dw, Mathf.Round(child._sizePercentInGroup / remainPercent * remainSize), true);
  411. remainPercent -= child._sizePercentInGroup;
  412. remainSize -= child.height;
  413. }
  414. child.yMin = curY;
  415. if (child.height != 0)
  416. curY += child.height + _lineGap;
  417. }
  418. }
  419. _updating &= 1;
  420. }
  421. override protected void HandleAlphaChanged()
  422. {
  423. base.HandleAlphaChanged();
  424. if (this.underConstruct || parent == null)
  425. return;
  426. int cnt = parent.numChildren;
  427. float a = this.alpha;
  428. for (int i = 0; i < cnt; i++)
  429. {
  430. GObject child = parent.GetChildAt(i);
  431. if (child.group == this)
  432. child.alpha = a;
  433. }
  434. }
  435. override internal protected void HandleVisibleChanged()
  436. {
  437. if (parent == null)
  438. return;
  439. int cnt = parent.numChildren;
  440. for (int i = 0; i < cnt; i++)
  441. {
  442. GObject child = parent.GetChildAt(i);
  443. if (child.group == this)
  444. child.HandleVisibleChanged();
  445. }
  446. }
  447. override public void Setup_BeforeAdd(ByteBuffer buffer, int beginPos)
  448. {
  449. base.Setup_BeforeAdd(buffer, beginPos);
  450. buffer.Seek(beginPos, 5);
  451. _layout = (GroupLayoutType)buffer.ReadByte();
  452. _lineGap = buffer.ReadInt();
  453. _columnGap = buffer.ReadInt();
  454. if (buffer.version >= 2)
  455. {
  456. _excludeInvisibles = buffer.ReadBool();
  457. _autoSizeDisabled = buffer.ReadBool();
  458. _mainGridIndex = buffer.ReadShort();
  459. }
  460. }
  461. override public void Setup_AfterAdd(ByteBuffer buffer, int beginPos)
  462. {
  463. base.Setup_AfterAdd(buffer, beginPos);
  464. if (!this.visible)
  465. HandleVisibleChanged();
  466. }
  467. }
  468. }