BoundingBox.ts 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. import {ArgumentOutOfRangeException} from "../Exceptions";
  2. import {PointF_2D} from "../../Common/DataObjects/PointF_2D";
  3. import {SizeF_2D} from "../../Common/DataObjects/SizeF_2D";
  4. import {RectangleF_2D} from "../../Common/DataObjects/RectangleF_2D";
  5. export class BoundingBox {
  6. protected isSymbol: boolean = false;
  7. protected relativePositionHasBeenSet: boolean;
  8. protected xBordersHaveBeenSet: boolean;
  9. protected yBordersHaveBeenSet: boolean;
  10. protected absolutePosition: PointF_2D = new PointF_2D();
  11. protected relativePosition: PointF_2D = new PointF_2D();
  12. protected size: SizeF_2D = new SizeF_2D();
  13. protected marginSize: SizeF_2D;
  14. protected upperLeftCorner: PointF_2D;
  15. protected upperLeftMarginCorner: PointF_2D;
  16. protected borderLeft: number;
  17. protected borderRight: number;
  18. protected borderTop: number;
  19. protected borderBottom: number;
  20. protected borderMarginLeft: number;
  21. protected borderMarginRight: number;
  22. protected borderMarginTop: number;
  23. protected borderMarginBottom: number;
  24. protected boundingRectangle: RectangleF_2D;
  25. protected boundingMarginRectangle: RectangleF_2D;
  26. protected childElements: List<BoundingBox> = new List<BoundingBox>();
  27. protected parent: BoundingBox;
  28. protected dataObject: Object;
  29. constructor(dataObject: Object) {
  30. this.dataObject = dataObject;
  31. this.xBordersHaveBeenSet = false;
  32. this.yBordersHaveBeenSet = false;
  33. }
  34. constructor(parent: BoundingBox, dataObject: Object) {
  35. this(dataObject);
  36. this.parent = parent;
  37. }
  38. public get RelativePositionHasBeenSet(): boolean {
  39. return this.relativePositionHasBeenSet;
  40. }
  41. public get XBordersHaveBeenSet(): boolean {
  42. return this.xBordersHaveBeenSet;
  43. }
  44. public set XBordersHaveBeenSet(value: boolean) {
  45. this.xBordersHaveBeenSet = value;
  46. }
  47. public get YBordersHaveBeenSet(): boolean {
  48. return this.yBordersHaveBeenSet;
  49. }
  50. public set YBordersHaveBeenSet(value: boolean) {
  51. this.yBordersHaveBeenSet = value;
  52. }
  53. public get AbsolutePosition(): PointF_2D {
  54. return this.absolutePosition;
  55. }
  56. public set AbsolutePosition(value: PointF_2D) {
  57. this.absolutePosition = value;
  58. }
  59. public get RelativePosition(): PointF_2D {
  60. return this.relativePosition;
  61. }
  62. public set RelativePosition(value: PointF_2D) {
  63. this.relativePosition = value;
  64. this.relativePositionHasBeenSet = true;
  65. }
  66. public get Size(): SizeF_2D {
  67. return this.size;
  68. }
  69. public set Size(value: SizeF_2D) {
  70. this.size = value;
  71. }
  72. public get MarginSize(): SizeF_2D {
  73. return this.marginSize;
  74. }
  75. public get UpperLeftCorner(): PointF_2D {
  76. return this.upperLeftCorner;
  77. }
  78. public get UpperLeftMarginCorner(): PointF_2D {
  79. return this.upperLeftMarginCorner;
  80. }
  81. public get BorderLeft(): number {
  82. return this.borderLeft;
  83. }
  84. public set BorderLeft(value: number) {
  85. this.borderLeft = value;
  86. this.calculateRectangle();
  87. }
  88. public get BorderRight(): number {
  89. return this.borderRight;
  90. }
  91. public set BorderRight(value: number) {
  92. this.borderRight = value;
  93. this.calculateRectangle();
  94. }
  95. public get BorderTop(): number {
  96. return this.borderTop;
  97. }
  98. public set BorderTop(value: number) {
  99. this.borderTop = value;
  100. this.calculateRectangle();
  101. }
  102. public get BorderBottom(): number {
  103. return this.borderBottom;
  104. }
  105. public set BorderBottom(value: number) {
  106. this.borderBottom = value;
  107. this.calculateRectangle();
  108. }
  109. public get BorderMarginLeft(): number {
  110. return this.borderMarginLeft;
  111. }
  112. public set BorderMarginLeft(value: number) {
  113. this.borderMarginLeft = value;
  114. this.calculateMarginRectangle();
  115. }
  116. public get BorderMarginRight(): number {
  117. return this.borderMarginRight;
  118. }
  119. public set BorderMarginRight(value: number) {
  120. this.borderMarginRight = value;
  121. this.calculateMarginRectangle();
  122. }
  123. public get BorderMarginTop(): number {
  124. return this.borderMarginTop;
  125. }
  126. public set BorderMarginTop(value: number) {
  127. this.borderMarginTop = value;
  128. this.calculateMarginRectangle();
  129. }
  130. public get BorderMarginBottom(): number {
  131. return this.borderMarginBottom;
  132. }
  133. public set BorderMarginBottom(value: number) {
  134. this.borderMarginBottom = value;
  135. this.calculateMarginRectangle();
  136. }
  137. public get BoundingRectangle(): RectangleF_2D {
  138. return this.boundingRectangle;
  139. }
  140. public get BoundingMarginRectangle(): RectangleF_2D {
  141. return this.boundingMarginRectangle;
  142. }
  143. public get ChildElements(): List<BoundingBox> {
  144. return this.childElements;
  145. }
  146. public set ChildElements(value: List<BoundingBox>) {
  147. this.childElements = value;
  148. }
  149. public get Parent(): BoundingBox {
  150. return this.parent;
  151. }
  152. public set Parent(value: BoundingBox) {
  153. this.parent = value;
  154. }
  155. public get DataObject(): Object {
  156. return this.dataObject;
  157. }
  158. public setAbsolutePositionFromParent(): void {
  159. if (this.parent != null) {
  160. this.absolutePosition.X = this.parent.AbsolutePosition.X + this.relativePosition.X;
  161. this.absolutePosition.Y = this.parent.AbsolutePosition.Y + this.relativePosition.Y;
  162. }
  163. else {
  164. this.absolutePosition = this.relativePosition;
  165. }
  166. }
  167. public calculateAbsolutePositionsRecursiveWithoutTopelement(): void {
  168. this.absolutePosition.X = 0.0;
  169. this.absolutePosition.Y = 0.0;
  170. for (var idx: number = 0, len = this.ChildElements.Count; idx < len; ++idx) {
  171. var child: BoundingBox = this.ChildElements[idx];
  172. child.calculateAbsolutePositionsRecursive(this.absolutePosition.X, this.absolutePosition.Y);
  173. }
  174. }
  175. public calculateAbsolutePositionsRecursive(x: number, y: number): void {
  176. this.absolutePosition.X = this.relativePosition.X + x;
  177. this.absolutePosition.Y = this.relativePosition.Y + y;
  178. for (var idx: number = 0, len = this.ChildElements.Count; idx < len; ++idx) {
  179. var child: BoundingBox = this.ChildElements[idx];
  180. child.calculateAbsolutePositionsRecursive(this.absolutePosition.X, this.absolutePosition.Y);
  181. }
  182. }
  183. public calculateBoundingBox(): void {
  184. if (this.childElements.Count == 0)
  185. return
  186. for (var idx: number = 0, len = this.ChildElements.Count; idx < len; ++idx) {
  187. var childElement: BoundingBox = this.ChildElements[idx];
  188. childElement.calculateBoundingBox();
  189. }
  190. var minLeft: number = number.MaxValue;
  191. var maxRight: number = number.MinValue;
  192. var minTop: number = number.MaxValue;
  193. var maxBottom: number = number.MinValue;
  194. var minMarginLeft: number = number.MaxValue;
  195. var maxMarginRight: number = number.MinValue;
  196. var minMarginTop: number = number.MaxValue;
  197. var maxMarginBottom: number = number.MinValue;
  198. if (this.isSymbol) {
  199. minLeft = this.borderLeft;
  200. maxRight = this.borderRight;
  201. minTop = this.borderTop;
  202. maxBottom = this.borderBottom;
  203. minMarginLeft = this.borderMarginLeft;
  204. maxMarginRight = this.borderMarginRight;
  205. minMarginTop = this.borderMarginTop;
  206. maxMarginBottom = this.borderMarginBottom;
  207. }
  208. for (var idx: number = 0, len = this.ChildElements.Count; idx < len; ++idx) {
  209. var childElement: BoundingBox = this.ChildElements[idx];
  210. minLeft = Math.Min(minLeft, childElement.relativePosition.X + childElement.borderLeft);
  211. maxRight = Math.Max(maxRight, childElement.relativePosition.X + childElement.borderRight);
  212. minTop = Math.Min(minTop, childElement.relativePosition.Y + childElement.borderTop);
  213. maxBottom = Math.Max(maxBottom, childElement.relativePosition.Y + childElement.borderBottom);
  214. minMarginLeft = Math.Min(minMarginLeft, childElement.relativePosition.X + childElement.borderMarginLeft);
  215. maxMarginRight = Math.Max(maxMarginRight,
  216. childElement.relativePosition.X + childElement.borderMarginRight);
  217. minMarginTop = Math.Min(minMarginTop, childElement.relativePosition.Y + childElement.borderMarginTop);
  218. maxMarginBottom = Math.Max(maxMarginBottom,
  219. childElement.relativePosition.Y + childElement.borderMarginBottom);
  220. }
  221. this.borderLeft = minLeft;
  222. this.borderRight = maxRight;
  223. this.borderTop = minTop;
  224. this.borderBottom = maxBottom;
  225. this.borderMarginLeft = minMarginLeft;
  226. this.borderMarginRight = maxMarginRight;
  227. this.borderMarginTop = minMarginTop;
  228. this.borderMarginBottom = maxMarginBottom;
  229. this.calculateRectangle();
  230. this.calculateMarginRectangle();
  231. this.xBordersHaveBeenSet = true;
  232. this.yBordersHaveBeenSet = true;
  233. }
  234. public calculateTopBottomBorders(): void {
  235. if (this.childElements.Count == 0)
  236. return
  237. for (var idx: number = 0, len = this.ChildElements.Count; idx < len; ++idx) {
  238. var childElement: BoundingBox = this.ChildElements[idx];
  239. childElement.calculateTopBottomBorders();
  240. }
  241. var minTop: number = number.MaxValue;
  242. var maxBottom: number = number.MinValue;
  243. var minMarginTop: number = number.MaxValue;
  244. var maxMarginBottom: number = number.MinValue;
  245. if (this.yBordersHaveBeenSet) {
  246. minTop = this.borderTop;
  247. maxBottom = this.borderBottom;
  248. minMarginTop = this.borderMarginTop;
  249. maxMarginBottom = this.borderMarginBottom;
  250. }
  251. for (var idx: number = 0, len = this.ChildElements.Count; idx < len; ++idx) {
  252. var childElement: BoundingBox = this.ChildElements[idx];
  253. minTop = Math.Min(minTop, childElement.relativePosition.Y + childElement.borderTop);
  254. maxBottom = Math.Max(maxBottom, childElement.relativePosition.Y + childElement.borderBottom);
  255. minMarginTop = Math.Min(minMarginTop, childElement.relativePosition.Y + childElement.borderMarginTop);
  256. maxMarginBottom = Math.Max(maxMarginBottom,
  257. childElement.relativePosition.Y + childElement.borderMarginBottom);
  258. }
  259. this.borderTop = minTop;
  260. this.borderBottom = maxBottom;
  261. this.borderMarginTop = minMarginTop;
  262. this.borderMarginBottom = maxMarginBottom;
  263. this.calculateRectangle();
  264. this.calculateMarginRectangle();
  265. }
  266. public computeNonOverlappingPositionWithMargin(placementPsi: BoundingBox, direction: ColDirEnum): void {
  267. this.computeNonOverlappingPositionWithMargin(placementPsi, direction, new PointF_2D(0.0, 0.0));
  268. }
  269. public computeNonOverlappingPositionWithMargin(placementPsi: BoundingBox, direction: ColDirEnum, position: PointF_2D): void {
  270. this.RelativePosition = new PointF_2D(position.X, position.Y);
  271. this.setAbsolutePositionFromParent();
  272. var currentPosition: number = 0.0;
  273. var hasBeenMoved: boolean = false;
  274. do {
  275. switch (direction) {
  276. case ColDirEnum.Left:
  277. case ColDirEnum.Right:
  278. currentPosition = this.relativePosition.X;
  279. placementPsi.calculateMarginPositionAlongDirection(this, direction);
  280. hasBeenMoved = Math.Abs(currentPosition - this.relativePosition.X) > 0.001;
  281. break;
  282. case ColDirEnum.Up:
  283. case ColDirEnum.Down:
  284. currentPosition = this.relativePosition.Y;
  285. placementPsi.calculateMarginPositionAlongDirection(this, direction);
  286. hasBeenMoved = Math.Abs(currentPosition - this.relativePosition.Y) > 0.001;
  287. break;
  288. default:
  289. throw new ArgumentOutOfRangeException("direction");
  290. }
  291. }
  292. while (hasBeenMoved);
  293. }
  294. public collisionDetection(psi: BoundingBox): boolean {
  295. var overlapWidth: number = Math.Min(this.AbsolutePosition.X + this.borderRight, psi.absolutePosition.X + psi.borderRight) - Math.Max(this.AbsolutePosition.X + this.borderLeft, psi.absolutePosition.X + psi.borderLeft);
  296. var overlapHeight: number = Math.Min(this.AbsolutePosition.Y + this.borderBottom, psi.absolutePosition.Y + psi.borderBottom) - Math.Max(this.AbsolutePosition.Y + this.borderTop, psi.absolutePosition.Y + psi.borderTop);
  297. if (overlapWidth > 0 && overlapHeight > 0)
  298. return true;
  299. return false;
  300. }
  301. public liesInsideBorders(psi: BoundingBox): boolean {
  302. var leftBorderInside: boolean = (this.AbsolutePosition.X + this.borderLeft) <= (psi.absolutePosition.X + psi.borderLeft) && (psi.absolutePosition.X + psi.borderLeft) <= (this.AbsolutePosition.X + this.borderRight);
  303. var rightBorderInside: boolean = (this.AbsolutePosition.X + this.borderLeft) <= (psi.absolutePosition.X + psi.borderRight) && (psi.absolutePosition.X + psi.borderRight) <= (this.AbsolutePosition.X + this.borderRight);
  304. if (leftBorderInside && rightBorderInside) {
  305. var topBorderInside: boolean = (this.AbsolutePosition.Y + this.borderTop) <= (psi.absolutePosition.Y + psi.borderTop) && (psi.absolutePosition.Y + psi.borderTop) <= (this.AbsolutePosition.Y + this.borderBottom);
  306. var bottomBorderInside: boolean = (this.AbsolutePosition.Y + this.borderTop) <= (psi.absolutePosition.Y + psi.borderBottom) && (psi.absolutePosition.Y + psi.borderBottom) <= (this.AbsolutePosition.Y + this.borderBottom);
  307. if (topBorderInside && bottomBorderInside) {
  308. return true;
  309. }
  310. }
  311. return false;
  312. }
  313. public liesInsideBorders(psi: BoundingBox, leftBorderInside: boolean, rightBorderInside: boolean,
  314. topBorderInside: boolean, bottomBorderInside: boolean): boolean {
  315. leftBorderInside = (this.AbsolutePosition.X + this.borderLeft) <= (psi.absolutePosition.X + psi.borderLeft) && (psi.absolutePosition.X + psi.borderLeft) <= (this.AbsolutePosition.X + this.borderRight);
  316. rightBorderInside = (this.AbsolutePosition.X + this.borderLeft) <= (psi.absolutePosition.X + psi.borderRight) && (psi.absolutePosition.X + psi.borderRight) <= (this.AbsolutePosition.X + this.borderRight);
  317. topBorderInside = (this.AbsolutePosition.Y + this.borderTop) <= (psi.absolutePosition.Y + psi.borderTop) && (psi.absolutePosition.Y + psi.borderTop) <= (this.AbsolutePosition.Y + this.borderBottom);
  318. bottomBorderInside = (this.AbsolutePosition.Y + this.borderTop) <= (psi.absolutePosition.Y + psi.borderBottom) && (psi.absolutePosition.Y + psi.borderBottom) <= (this.AbsolutePosition.Y + this.borderBottom);
  319. return topBorderInside && bottomBorderInside && leftBorderInside && rightBorderInside;
  320. }
  321. public liesInsideBorders(position: PointF_2D): boolean {
  322. var xInside: boolean = (this.AbsolutePosition.X + this.borderLeft) <= position.X && position.X <= (this.AbsolutePosition.X + this.borderRight);
  323. if (xInside) {
  324. var yInside: boolean = (this.AbsolutePosition.Y + this.borderTop) <= position.Y && position.Y <= (this.AbsolutePosition.Y + this.borderBottom);
  325. if (yInside) {
  326. return true;
  327. }
  328. }
  329. return false;
  330. }
  331. public marginCollisionDetection(psi: BoundingBox): boolean {
  332. var overlapWidth: number = Math.Min(this.AbsolutePosition.X + this.borderMarginRight, psi.absolutePosition.X + psi.borderMarginRight) - Math.Max(this.AbsolutePosition.X + this.borderMarginLeft, psi.absolutePosition.X + psi.borderMarginLeft);
  333. var overlapHeight: number = Math.Min(this.AbsolutePosition.Y + this.borderMarginBottom, psi.absolutePosition.Y + psi.borderMarginBottom) - Math.Max(this.AbsolutePosition.Y + this.borderMarginTop, psi.absolutePosition.Y + psi.borderMarginTop);
  334. if (overlapWidth > 0 && overlapHeight > 0)
  335. return true;
  336. return false;
  337. }
  338. public liesInsideMargins(psi: BoundingBox): boolean {
  339. var leftMarginInside: boolean = (this.AbsolutePosition.X + this.borderMarginLeft) <= (psi.absolutePosition.X + psi.borderMarginLeft) && (psi.absolutePosition.X + psi.borderMarginLeft) <= (this.AbsolutePosition.X + this.borderMarginRight);
  340. var rightMarginInside: boolean = (this.AbsolutePosition.X + this.borderMarginLeft) <= (psi.absolutePosition.X + psi.borderMarginRight) && (psi.absolutePosition.X + psi.borderMarginRight) <= (this.AbsolutePosition.X + this.borderMarginRight);
  341. if (leftMarginInside && rightMarginInside) {
  342. var topMarginInside: boolean = (this.AbsolutePosition.Y + this.borderMarginTop) <= (psi.absolutePosition.Y + psi.borderMarginTop) && (psi.absolutePosition.Y + psi.borderMarginTop) <= (this.AbsolutePosition.Y + this.borderMarginBottom);
  343. var bottomMarginInside: boolean = (this.AbsolutePosition.Y + this.borderMarginTop) <= (psi.absolutePosition.Y + psi.borderMarginBottom) && (psi.absolutePosition.Y + psi.borderMarginBottom) <= (this.AbsolutePosition.Y + this.borderMarginBottom);
  344. if (topMarginInside && bottomMarginInside) {
  345. return true;
  346. }
  347. }
  348. return false;
  349. }
  350. public liesInsideMargins(position: PointF_2D): boolean {
  351. var xInside: boolean = (this.AbsolutePosition.X + this.borderMarginLeft) <= position.X && position.X <= (this.AbsolutePosition.X + this.borderMarginRight);
  352. if (xInside) {
  353. var yInside: boolean = (this.AbsolutePosition.Y + this.borderMarginTop) <= position.Y && position.Y <= (this.AbsolutePosition.Y + this.borderMarginBottom);
  354. if (yInside) {
  355. return true;
  356. }
  357. }
  358. return false;
  359. }
  360. public computeNonOverlappingPosition(placementPsi: BoundingBox, direction: ColDirEnum, margin: number): void {
  361. this.computeNonOverlappingPosition(placementPsi, direction, new PointF_2D(0.0, 0.0));
  362. }
  363. public computeNonOverlappingPosition(placementPsi: BoundingBox, direction: ColDirEnum, position: PointF_2D): void {
  364. this.RelativePosition = new PointF_2D(position.X, position.Y);
  365. this.setAbsolutePositionFromParent();
  366. var currentPosition: number = 0.0f;
  367. var hasBeenMoved: boolean = false;
  368. do {
  369. switch (direction) {
  370. case ColDirEnum.Left:
  371. case ColDirEnum.Right:
  372. currentPosition = this.relativePosition.X;
  373. placementPsi.calculatePositionAlongDirection(this, direction);
  374. hasBeenMoved = Math.Abs(currentPosition - this.relativePosition.X) > 0.0001;
  375. break;
  376. case ColDirEnum.Up:
  377. case ColDirEnum.Down:
  378. currentPosition = this.relativePosition.Y;
  379. placementPsi.calculatePositionAlongDirection(this, direction);
  380. hasBeenMoved = Math.Abs(currentPosition - this.relativePosition.Y) > 0.0001;
  381. break;
  382. default:
  383. throw new ArgumentOutOfRangeException("direction");
  384. }
  385. }
  386. while (hasBeenMoved);
  387. }
  388. public getClickedObjectOfType<T>(clickPosition: PointF_2D): T {
  389. var obj: Object = this.dataObject;
  390. if (this.liesInsideBorders(clickPosition) && (obj instanceof T))
  391. return __as__<T>(obj, T);
  392. for (var idx: number = 0, len = this.childElements.Count; idx < len; ++idx) {
  393. var psi: BoundingBox = this.childElements[idx];
  394. var innerObject: Object = psi.getClickedObjectOfType<T>(clickPosition);
  395. if (innerObject != null)
  396. return __as__<T>(innerObject, T);
  397. }
  398. return null;
  399. }
  400. public getObjectsInRegion<T>(region: BoundingBox): IEnumerable<T> {
  401. return getObjectsInRegion<T>(region, true);
  402. }
  403. public getObjectsInRegion<T>(region: BoundingBox, liesInside: boolean): IEnumerable<T> {
  404. if (this.dataObject instanceof T) {
  405. if (liesInside) {
  406. if (region.liesInsideBorders(this))
  407. return __init(new List<T>(), { __as__<T>(this.dataObject, T) });
  408. }
  409. else {
  410. if (region.collisionDetection(this))
  411. return __init(new List<T>(), { __as__<T>(this.dataObject, T) });
  412. }
  413. }
  414. return this.childElements.SelectMany(psi => psi.getObjectsInRegion<T>(region, liesInside));
  415. }
  416. protected calculateRectangle(): void
  417. {
  418. this.upperLeftCorner = new PointF_2D(this.borderLeft, this.borderTop);
  419. this.size = new SizeF_2D(this.borderRight - this.borderLeft, this.borderBottom - this.borderTop);
  420. this.boundingRectangle = new RectangleF_2D(this.upperLeftCorner, this.size);
  421. }
  422. protected calculateMarginRectangle(): void
  423. {
  424. this.upperLeftMarginCorner = new PointF_2D(this.borderMarginLeft, this.borderMarginTop);
  425. this.marginSize = new SizeF_2D(this.borderMarginRight - this.borderMarginLeft, this.borderMarginBottom - this.borderMarginTop);
  426. this.boundingMarginRectangle = new RectangleF_2D(this.upperLeftMarginCorner, this.marginSize);
  427. }
  428. private calculateMarginPositionAlongDirection(toBePlaced:BoundingBox, direction:ColDirEnum): void
  429. {
  430. if(this == toBePlaced)
  431. {
  432. return
  433. }
  434. if (this.isSymbol && this.marginCollisionDetection(toBePlaced)) {
  435. var shiftDistance: number = 0;
  436. switch (direction) {
  437. case ColDirEnum.Left:
  438. shiftDistance = (this.absolutePosition.X + this.borderMarginLeft) - (toBePlaced.absolutePosition.X + toBePlaced.borderMarginRight);
  439. toBePlaced.relativePosition.X += shiftDistance;
  440. toBePlaced.absolutePosition.X += shiftDistance;
  441. return
  442. case ColDirEnum.Right:
  443. shiftDistance = (this.absolutePosition.X + this.borderMarginRight) - (toBePlaced.absolutePosition.X + toBePlaced.borderMarginLeft);
  444. toBePlaced.relativePosition.X += shiftDistance;
  445. toBePlaced.absolutePosition.X += shiftDistance;
  446. return
  447. case ColDirEnum.Up:
  448. shiftDistance = (this.absolutePosition.Y + this.borderMarginTop) - (toBePlaced.absolutePosition.Y + toBePlaced.borderMarginBottom);
  449. toBePlaced.relativePosition.Y += shiftDistance;
  450. toBePlaced.absolutePosition.Y += shiftDistance;
  451. return
  452. case ColDirEnum.Down:
  453. shiftDistance = (this.absolutePosition.Y + this.borderMarginBottom) - (toBePlaced.absolutePosition.Y + toBePlaced.borderMarginTop);
  454. toBePlaced.relativePosition.Y += shiftDistance;
  455. toBePlaced.absolutePosition.Y += shiftDistance;
  456. return
  457. default:
  458. throw new ArgumentOutOfRangeException("direction");
  459. }
  460. }
  461. for (var idx: number = 0, len = this.ChildElements.Count; idx < len; ++idx) {
  462. var childElement: BoundingBox = this.ChildElements[idx];
  463. childElement.calculateMarginPositionAlongDirection(toBePlaced, direction);
  464. }
  465. }
  466. private calculatePositionAlongDirection(toBePlaced:BoundingBox, direction:ColDirEnum): void
  467. {
  468. if(this == toBePlaced)
  469. {
  470. return
  471. }
  472. if (this.isSymbol && this.collisionDetection(toBePlaced)) {
  473. var shiftDistance: number;
  474. switch (direction) {
  475. case ColDirEnum.Left:
  476. shiftDistance = (this.absolutePosition.X + this.borderLeft) - (toBePlaced.absolutePosition.X + toBePlaced.borderRight);
  477. toBePlaced.relativePosition.X += shiftDistance;
  478. toBePlaced.absolutePosition.X += shiftDistance;
  479. return
  480. case ColDirEnum.Right:
  481. shiftDistance = (this.absolutePosition.X + this.borderRight) - (toBePlaced.absolutePosition.X + toBePlaced.borderLeft);
  482. toBePlaced.relativePosition.X += shiftDistance;
  483. toBePlaced.absolutePosition.X += shiftDistance;
  484. return
  485. case ColDirEnum.Up:
  486. shiftDistance = (this.absolutePosition.Y + this.borderTop) - (toBePlaced.absolutePosition.Y + toBePlaced.borderBottom);
  487. toBePlaced.relativePosition.Y += shiftDistance;
  488. toBePlaced.absolutePosition.Y += shiftDistance;
  489. return
  490. case ColDirEnum.Down:
  491. shiftDistance = (this.absolutePosition.Y + this.borderBottom) - (toBePlaced.absolutePosition.Y + toBePlaced.borderTop);
  492. toBePlaced.relativePosition.Y += shiftDistance;
  493. toBePlaced.absolutePosition.Y += shiftDistance;
  494. return
  495. default:
  496. throw new ArgumentOutOfRangeException("direction");
  497. }
  498. }
  499. for (var idx: number = 0, len = this.ChildElements.Count; idx < len; ++idx) {
  500. var childElement: BoundingBox = this.ChildElements[idx];
  501. childElement.calculatePositionAlongDirection(toBePlaced, direction);
  502. }
  503. }
  504. }
  505. export enum ColDirEnum {
  506. Left = 0,
  507. Right = 1,
  508. Up = 2,
  509. Down = 3
  510. }