PageRenderTime 53ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/shared/com/societyGames/flashForms/Window.as

http://flashforms.googlecode.com/
ActionScript | 485 lines | 428 code | 46 blank | 11 comment | 43 complexity | 4c83dedb4bca0c90a26fd4de4fb671de MD5 | raw file
  1. package com.societyGames.flashForms
  2. {
  3. import flash.display.DisplayObject;
  4. import flash.display.Sprite;
  5. import flash.events.MouseEvent;
  6. import flash.geom.Point;
  7. import flash.geom.Rectangle;
  8. public class Window extends SingleChildContainer
  9. {
  10. private var _desiredWidth:Number;
  11. private var _desiredHeight:Number;
  12. private var _body:Sprite;
  13. private var _borderTop:Number;
  14. private var _borderLeft:Number;
  15. private var _borderBottom:Number;
  16. private var _borderRight:Number;
  17. private var _borderMoveTop:Number;
  18. private var _dragBounds:Rectangle;
  19. private var _dragType:DragType;
  20. private var _isLocked:Boolean; //Tracks whether mouse cursor is locked.
  21. private var _lastMouseX:Number;
  22. private var _lastMouseY:Number;
  23. private var _allowResize:Boolean = true;
  24. private var _header:DisplayObject;
  25. public function Window(body:Sprite, borderLeft:Number, borderRight:Number, borderTop:Number, borderBottom:Number, borderMoveTop:Number)
  26. {
  27. this._body = body;
  28. this._borderLeft = borderLeft;
  29. this._borderRight = borderRight;
  30. this._borderTop = borderTop;
  31. this._borderBottom = borderBottom;
  32. this._borderMoveTop = borderMoveTop;
  33. this._body.y = 0;
  34. this.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
  35. this.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
  36. this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
  37. this.addChild(this._body);
  38. this._desiredWidth = width;
  39. this._desiredHeight = height;
  40. }
  41. public override function set width(value:Number):void
  42. {
  43. if (value != this._desiredWidth)
  44. {
  45. this._desiredWidth = value;
  46. this._body.width = this._desiredWidth;
  47. recalculateChildWidth();
  48. recalculateHeaderWidth();
  49. }
  50. }
  51. public override function set height(value:Number):void
  52. {
  53. if (value != this._desiredHeight)
  54. {
  55. this._desiredHeight = value;
  56. this._body.height = this._desiredHeight;
  57. recalculateChildHeight();
  58. recalculateHeaderHeight();
  59. }
  60. }
  61. public override function set child(value:DisplayObject):void
  62. {
  63. super.child = value;
  64. this._child.x = this._borderLeft;
  65. this._child.y = this._borderTop + this._borderMoveTop;
  66. recalculateChildWidth();
  67. recalculateChildHeight();
  68. }
  69. //Whether you can drag the window larger or smaller.
  70. public function get allowResize():Boolean
  71. {
  72. return this._allowResize;
  73. }
  74. //Whether you can drag the window larger or smaller.
  75. public function set allowResize(value:Boolean):void
  76. {
  77. this._allowResize = value;
  78. }
  79. //Set space for the child.
  80. public function set innerWidth(value:Number):void
  81. {
  82. width = value + _borderLeft + _borderRight;
  83. }
  84. //Get space for the child.
  85. public function get innerWidth():Number
  86. {
  87. return _desiredWidth - (_borderLeft + _borderRight);
  88. }
  89. //Set space for the child.
  90. public function set innerHeight(value:Number):void
  91. {
  92. height = value + _borderTop + _borderMoveTop + _borderBottom;
  93. }
  94. //Get space for the child.
  95. public function get innerHeight():Number
  96. {
  97. return _desiredHeight - (_borderTop + _borderMoveTop + _borderBottom);
  98. }
  99. public function set header(value:DisplayObject):void
  100. {
  101. this._header = value;
  102. this._header.x = this._borderLeft;
  103. this._header.y = this._borderTop;
  104. this.addChild(this._header);
  105. recalculateHeaderWidth();
  106. recalculateHeaderHeight();
  107. }
  108. public function set dragBounds(value:Rectangle):void
  109. {
  110. this._dragBounds = value;
  111. }
  112. private function recalculateChildWidth():void
  113. {
  114. if (this._child != null)
  115. {
  116. this._child.width = _borderLeft + _borderRight > this._desiredWidth ? 0 : this._desiredWidth - (_borderLeft + _borderRight);
  117. }
  118. }
  119. private function recalculateChildHeight():void
  120. {
  121. if (this._child != null)
  122. {
  123. this._child.height = _borderTop + _borderMoveTop + _borderBottom > this._desiredHeight ? 0 : this._desiredHeight - (_borderTop + _borderMoveTop + _borderBottom);
  124. }
  125. }
  126. private function recalculateHeaderWidth():void
  127. {
  128. if (this._header != null)
  129. {
  130. this._header.width = _borderLeft + _borderRight > this._desiredWidth ? Math.max(0, this._desiredWidth - _borderLeft) : this._desiredWidth - (_borderLeft + _borderRight);
  131. }
  132. }
  133. private function recalculateHeaderHeight():void
  134. {
  135. if (this._header != null)
  136. {
  137. this._header.height = _borderTop + _borderMoveTop > this._desiredHeight ? Math.max(0, this._desiredHeight - _borderTop) : _borderMoveTop;
  138. }
  139. }
  140. private function mouseMoveHandler(event:MouseEvent = null):void
  141. {
  142. var newDragType:DragType = null;
  143. if (this._allowResize)
  144. {
  145. //In the left border
  146. if (this.mouseX < this._borderLeft && this.mouseX > 0)
  147. {
  148. if (this.mouseY < this._borderTop)
  149. {
  150. newDragType = DragType.LeftTop;
  151. }
  152. else if (this.mouseY > this._desiredHeight - this._borderBottom)
  153. {
  154. newDragType = DragType.LeftBottom;
  155. }
  156. else
  157. {
  158. newDragType = DragType.Left;
  159. }
  160. }
  161. //In the right border
  162. else if (this.mouseX > this._desiredWidth - this._borderRight && this.mouseX < this._desiredWidth)
  163. {
  164. if (this.mouseY < this._borderTop)
  165. {
  166. newDragType = DragType.RightTop;
  167. }
  168. else if (this.mouseY > this._desiredHeight - this._borderBottom)
  169. {
  170. newDragType = DragType.RightBottom;
  171. }
  172. else
  173. {
  174. newDragType = DragType.Right;
  175. }
  176. }
  177. //In the top
  178. else if (this.mouseY < this._borderTop)
  179. {
  180. newDragType = DragType.Top;
  181. }
  182. //In the bottom
  183. else if (this.mouseY > this._desiredHeight - this._borderBottom && this.mouseY < this._desiredHeight)
  184. {
  185. newDragType = DragType.Bottom;
  186. }
  187. } //End if allow resize.
  188. //In the move area
  189. if (this.mouseY < this._borderTop + this._borderMoveTop && this.mouseY > this._borderTop)
  190. {
  191. newDragType = DragType.Move;
  192. }
  193. showDragType(newDragType, false);
  194. }
  195. private function rollOutHandler(event:MouseEvent):void
  196. {
  197. showDragType(null, false);
  198. }
  199. private function showDragType(dragType:DragType, shouldLock:Boolean):void
  200. {
  201. if (this._dragType != dragType || this._isLocked != shouldLock)
  202. {
  203. this._dragType = dragType;
  204. this._isLocked = shouldLock;
  205. if (this._isLocked)
  206. {
  207. switch (this._dragType)
  208. {
  209. case null:
  210. case DragType.Move:
  211. MouseCursor.instance.unlockCursor(this);
  212. break;
  213. case DragType.Left:
  214. case DragType.Right:
  215. MouseCursor.instance.lockCursor(Cursors.leftRightCursor, this, -Cursors.leftRightCursor.width / 2, -Cursors.leftRightCursor.height / 2);
  216. break;
  217. case DragType.Top:
  218. case DragType.Bottom:
  219. MouseCursor.instance.lockCursor(Cursors.upDownCursor, this, -Cursors.upDownCursor.width / 2, -Cursors.upDownCursor.height / 2);
  220. break;
  221. case DragType.RightTop:
  222. case DragType.LeftBottom:
  223. MouseCursor.instance.lockCursor(Cursors.leftDownCursor, this, -Cursors.upDownCursor.width / 2, -Cursors.upDownCursor.height / 2);
  224. break;
  225. case DragType.LeftTop:
  226. case DragType.RightBottom:
  227. MouseCursor.instance.lockCursor(Cursors.rightDownCursor, this, -Cursors.upDownCursor.width / 2, -Cursors.upDownCursor.height / 2);
  228. break;
  229. }
  230. }
  231. else
  232. {
  233. switch (this._dragType)
  234. {
  235. case null:
  236. case DragType.Move:
  237. MouseCursor.instance.unsetCursor(this);
  238. break;
  239. case DragType.Left:
  240. case DragType.Right:
  241. MouseCursor.instance.setCursor(Cursors.leftRightCursor, this, -Cursors.leftRightCursor.width / 2, -Cursors.leftRightCursor.height / 2);
  242. break;
  243. case DragType.Top:
  244. case DragType.Bottom:
  245. MouseCursor.instance.setCursor(Cursors.upDownCursor, this, -Cursors.upDownCursor.width / 2, -Cursors.upDownCursor.height / 2);
  246. break;
  247. case DragType.RightTop:
  248. case DragType.LeftBottom:
  249. MouseCursor.instance.setCursor(Cursors.leftDownCursor, this, -Cursors.upDownCursor.width / 2, -Cursors.upDownCursor.height / 2);
  250. break;
  251. case DragType.LeftTop:
  252. case DragType.RightBottom:
  253. MouseCursor.instance.setCursor(Cursors.rightDownCursor, this, -Cursors.rightDownCursor.width / 2, -Cursors.rightDownCursor.height / 2);
  254. break;
  255. }
  256. }
  257. }
  258. }
  259. private function lockDragType():void
  260. {
  261. showDragType(this._dragType, true);
  262. }
  263. private function unlockDragType():void
  264. {
  265. MouseCursor.instance.unlockCursor(this);
  266. }
  267. private function mouseDownHandler(event:MouseEvent):void
  268. {
  269. this.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
  270. this.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
  271. this.removeEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
  272. this.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  273. if (this._dragType != null)
  274. {
  275. this._lastMouseX = this.mouseX;
  276. this._lastMouseY = this.mouseY;
  277. }
  278. switch (this._dragType)
  279. {
  280. case DragType.Move:
  281. this.startDrag();
  282. break;
  283. case DragType.LeftTop:
  284. this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveLeftTopHandler);
  285. break;
  286. case DragType.LeftBottom:
  287. this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveLeftBottomHandler);
  288. break;
  289. case DragType.RightTop:
  290. this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveRightTopHandler);
  291. break;
  292. case DragType.RightBottom:
  293. this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveRightBottomHandler);
  294. break;
  295. case DragType.Left:
  296. this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveLeftHandler);
  297. break;
  298. case DragType.Right:
  299. this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveRightHandler);
  300. break;
  301. case DragType.Bottom:
  302. this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveBottomHandler);
  303. break;
  304. case DragType.Top:
  305. this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveTopHandler);
  306. break;
  307. }
  308. lockDragType();
  309. }
  310. private function mouseUpHandler(event:MouseEvent):void
  311. {
  312. this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
  313. this.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
  314. this.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
  315. this.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  316. switch (this._dragType)
  317. {
  318. case DragType.Move:
  319. this.stopDrag();
  320. break;
  321. case DragType.LeftTop:
  322. this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveLeftTopHandler);
  323. break;
  324. case DragType.LeftBottom:
  325. this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveLeftBottomHandler);
  326. break;
  327. case DragType.RightTop:
  328. this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveRightTopHandler);
  329. break;
  330. case DragType.RightBottom:
  331. this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveRightBottomHandler);
  332. break;
  333. case DragType.Left:
  334. this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveLeftHandler);
  335. break;
  336. case DragType.Right:
  337. this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveRightHandler);
  338. break;
  339. case DragType.Bottom:
  340. this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveBottomHandler);
  341. break;
  342. case DragType.Top:
  343. this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveTopHandler);
  344. break;
  345. }
  346. unlockDragType();
  347. if (this.hitTestPoint(event.stageX, event.stageY, true))
  348. {
  349. mouseMoveHandler(); //Refresh the cursor in case we got dragged over something valid.
  350. }
  351. }
  352. private function clampWidthDelta(dx:Number):Number
  353. {
  354. return this._desiredWidth + dx < (this._borderLeft + this._borderRight) ? this._desiredWidth - (this._borderLeft + this._borderRight) : dx;
  355. }
  356. private function clampHeightDelta(dy:Number):Number
  357. {
  358. return (this._desiredHeight + dy) < (this._borderTop + this._borderMoveTop + this._borderBottom)
  359. ? this._desiredHeight - (this._borderTop + this._borderMoveTop + this._borderBottom)
  360. : dy;
  361. }
  362. private function mouseMoveLeftTopHandler(event:MouseEvent):void
  363. {
  364. var dx:Number = clampWidthDelta(this._lastMouseX - this.mouseX);
  365. this.width = this._desiredWidth + dx;
  366. this.x = int(this.x - dx);
  367. var dy:Number = clampHeightDelta(this._lastMouseY - this.mouseY);
  368. this.height = this._desiredHeight + dy;
  369. this.y = int(this.y - dy);
  370. this._lastMouseX = this.mouseX;
  371. this._lastMouseY = this.mouseY;
  372. }
  373. private function mouseMoveLeftBottomHandler(event:MouseEvent):void
  374. {
  375. var dx:Number = clampWidthDelta(this._lastMouseX - this.mouseX);
  376. this.width = this._desiredWidth + dx;
  377. this.x = int(this.x - dx);
  378. this.height = this._desiredHeight + clampHeightDelta(this.mouseY - this._lastMouseY);
  379. this._lastMouseX = this.mouseX;
  380. this._lastMouseY = this.mouseY;
  381. }
  382. private function mouseMoveRightTopHandler(event:MouseEvent):void
  383. {
  384. this.width = this._desiredWidth + clampWidthDelta(this.mouseX - this._lastMouseX);
  385. var dy:Number = clampHeightDelta(this._lastMouseY - this.mouseY);
  386. this.height = this._desiredHeight + dy;
  387. this.y = int(this.y - dy);
  388. this._lastMouseX = this.mouseX;
  389. this._lastMouseY = this.mouseY;
  390. }
  391. private function mouseMoveRightBottomHandler(event:MouseEvent):void
  392. {
  393. this.width = this._desiredWidth + clampWidthDelta(this.mouseX - this._lastMouseX);
  394. this.height = this._desiredHeight + clampHeightDelta(this.mouseY - this._lastMouseY);
  395. this._lastMouseX = this.mouseX;
  396. this._lastMouseY = this.mouseY;
  397. }
  398. private function mouseMoveLeftHandler(event:MouseEvent):void
  399. {
  400. var dx:Number = clampWidthDelta(this._lastMouseX - this.mouseX);
  401. this.width = this._desiredWidth + dx;
  402. this.x = int(this.x - dx);
  403. this._lastMouseX = this.mouseX;
  404. this._lastMouseY = this.mouseY;
  405. }
  406. private function mouseMoveRightHandler(event:MouseEvent):void
  407. {
  408. this.width = this._desiredWidth + clampWidthDelta(this.mouseX - this._lastMouseX);
  409. this._lastMouseX = this.mouseX;
  410. this._lastMouseY = this.mouseY;
  411. }
  412. private function mouseMoveTopHandler(event:MouseEvent):void
  413. {
  414. var dy:Number = clampHeightDelta(this._lastMouseY - this.mouseY);
  415. this.height = this._desiredHeight + dy;
  416. this.y = int(this.y - dy);
  417. this._lastMouseX = this.mouseX;
  418. this._lastMouseY = this.mouseY;
  419. }
  420. private function mouseMoveBottomHandler(event:MouseEvent):void
  421. {
  422. this.height = this._desiredHeight + clampHeightDelta(this.mouseY - this._lastMouseY);
  423. this._lastMouseX = this.mouseX;
  424. this._lastMouseY = this.mouseY;
  425. }
  426. }
  427. }
  428. class DragType
  429. {
  430. public static const Move:DragType = new DragType();
  431. public static const Top:DragType = new DragType();
  432. public static const Left:DragType = new DragType();
  433. public static const Right:DragType = new DragType();
  434. public static const LeftBottom:DragType = new DragType();
  435. public static const LeftTop:DragType = new DragType();
  436. public static const RightBottom:DragType = new DragType();
  437. public static const RightTop:DragType = new DragType();
  438. public static const Bottom:DragType = new DragType();
  439. }