PageRenderTime 32ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/arctic/ArcticBlock.hx

http://arctic.googlecode.com/
Haxe | 553 lines | 219 code | 57 blank | 277 comment | 26 complexity | ae0165c4ca2aeb7f0ce6ba7f1c1e589e MD5 | raw file
  1. package arctic;
  2. import arctic.ArcticMC;
  3. // We introduce an alias for MovieClip which works in both Flash 8 & 9. See also ArcticMC.hx
  4. #if flash9
  5. typedef ArcticMovieClip = flash.display.Sprite;
  6. #elseif flash
  7. typedef ArcticMovieClip = flash.MovieClip
  8. #elseif neko
  9. typedef ArcticMovieClip = neash.display.MovieClip
  10. #end
  11. /**
  12. * Arctic is an embedded Domain Specific Language for making user interfaces.
  13. * A user interface is built from ArcticBlocks. Read this file to learn which
  14. * blocks are available.
  15. */
  16. enum ArcticBlock {
  17. /**
  18. * Draw a solid background behind the given block.
  19. * Alpha is an optional transparency from 0.0 to 100.0.
  20. * roundRadius > 0 makes the background rounded at the corners.
  21. */
  22. Background(color : Null<Int>, block : ArcticBlock, ?alpha : Null<Float>, ?roundRadius : Null<Float>);
  23. /**
  24. * Draw a gradient background behind the given block.
  25. * colors is an array of colors in the gradient.
  26. * xOffset & yOffset are percentage offsets from the center of the block, so an offset of 0.5, -0.5 means
  27. * to put the center of the gradient in the top, right corner.
  28. * Alpha is an array of optional transparencies from 0 to 100.0. It has to have as many entries as the color array.
  29. * roundRadius > 0 makes the gradient rounded at the corners.
  30. * rotation - the amount to rotate, in radians (the default value is 0).
  31. * ratios - an array with numbers from 0 to 255 defining how to "distribute" the gradient colors.
  32. */
  33. GradientBackground(type : String, colors : Array<Int>, xOffset : Float, yOffset : Float, block : ArcticBlock, ?alpha : Array<Float>, ?roundRadius : Null<Float>, ?rotation: Null<Float>, ?ratios: Array<Int>);
  34. /// Add some space around the block
  35. Border(x : Float, y : Float, block : ArcticBlock);
  36. /**
  37. * A text (in the subset of HTML which Flash understands).
  38. * If wordWrap is true, the text will grow in the width and height as much as possible,
  39. * and the text inside word wrap according to how much width is available. Notice that
  40. * layout of word-wrapping text can be unreliable when combined with Align or other
  41. * layout elements because of limitations of the layout algorithm used. In this cases,
  42. * the result will become much more predictable when you wrap the Text block with a
  43. * ConstrainWidth block:
  44. *
  45. * ConstrainWidth(0, width, Text(text, null, true))
  46. *
  47. * If wordWrap is false, the text will always have the same size, and only break lines
  48. * if <br/> tags exist in the text.
  49. * selectable defines whether user can select & copy contents.
  50. */
  51. Text(html : String, ?embeddedFont : Null<Bool>, ?wordWrap : Null<Bool>, ?selectable: Null<Bool>, ?format : ArcticTextFormat);
  52. /**
  53. * An input text. Text Font/Size/Color can be specified along with initial text content in the subset of HTML which Flash understands.
  54. * The validator callback is called on each change. You can use this callback to extract the contents of the text input.
  55. * Width and height, being set to null, cause text field to resize dynamically in the relevant direction (and call refresh(false) upon it)
  56. * All fields of the style parameter is copied verbatim to the textinput object. This allows you to customize the text input in
  57. * all detail, but it's up to you to make sure this works in both Flash 8 & 9. ( { wordWrap: true, multiline: true } as style is portable.)
  58. * The onInit parameter is called on construction and returns a function textFn( TextInputModel ) : TextInputModel which
  59. * can be used to change the contents of the TextInput (html and text), force it to have focus, change selection and cursor position,
  60. * and will return current TextInput status in each of these dimensions.
  61. * When changing, pass the values you don't want to change as null. If you only want to get status, you can pass null for the entire structure
  62. */
  63. TextInput(html : String, width : Null<Float>, height : Null<Float>, ?validator : String -> Bool, ?style : Dynamic, ?maxChars : Null<Int>, ?numeric : Null<Bool>, ?bgColor : Null<Int>, ?focus : Null<Bool>, ?embeddedFont : Null<Bool>, ?onInit : (TextInputModel -> TextInputModel) -> Void, ?onInitEvents: (TextInputEvents -> Void) -> Void);
  64. /**
  65. * A static picture loaded from a URL. It is your responsibility to set the scaling such that the picture has the stated size.
  66. * Notice that the width & height should be the size of this block, not the original size of the picture. If crop is true,
  67. * the picture will be cropped the number of pixels in all edges.
  68. * A negative value for scaling enabled automatic scaling to fit an image into (width, height) specified
  69. */
  70. Picture(url : String, width : Float, height : Float, scaling : Float, ?resource : Null<Bool>, ?crop : Int, ?cache : Bool, ?cbSizeDiff : Float -> Float -> Void);
  71. /**
  72. * A button - when mouse is above, we change to hover look. Notice block and hover should have the exact same size.
  73. * When the button is clicked, onClick is called. If onClickExtended is supplied, it is called with the x and y
  74. * coordinates, plus a bool signifying whether the mouse button is pressed (true) or released (false).
  75. * onClickExtended is called even if the click or released is outside the button, and the final bool tells
  76. * whether the click is inside the button or not.
  77. * On button release, onClick is called before onClickExtended.
  78. * hover can be null, in which case the button does not change look when hovered.
  79. */
  80. Button(block : ArcticBlock, hover : ArcticBlock, onClick : Void -> Void, ?onClickExtended : Float -> Float -> Bool -> Bool-> Void);
  81. /**
  82. * Toggle button (selected/unselected).
  83. * Though technically the ArcticBlock can be of any type, the most appropriate ones are Text & Picture.
  84. * Notice that the selected and unselected blocks should have the exact same size, because we do not
  85. * do a relayout when the state is changed. The onInit method is called when the view is constructed
  86. * with the state we have. This can be used to implement connected radio button groups - like Arctic.makeTextChoice
  87. * and Arctic.makeRadioButtonGroup do. This can also be used to implement check boxes - see Arctic.makeCheckbox.
  88. */
  89. ToggleButton(selected : ArcticBlock, unselected : ArcticBlock, initialState : Bool, onChange : Bool -> Void, ?onInit : (Bool -> Void) -> Void);
  90. /**
  91. * The ArcticBlock will be constrained to the dimensions given - in terms of layout only.
  92. * To crop a clip, use the Crop block.
  93. * If the minimumWidth is negative, the absolute value is reserved for layout purposes
  94. * even if there is not extra space from the environment. However, the block is not
  95. * artificially grown in case there was enough space to begin with.
  96. */
  97. ConstrainWidth(minimumWidth : Float, maximumWidth : Float, block : ArcticBlock);
  98. /**
  99. * The ArcticBlock will be constrained to the dimensions given - in terms of layout only.
  100. * To crop a clip, use the Crop block.
  101. * If the minimumHeight is negative, the absolute value is reserved for layout purposes
  102. * even if there is not extra space from the environment. However, the block is not
  103. * artificially grown in case there was enough space to begin with.
  104. */
  105. ConstrainHeight(minimumHeight : Float, maximumHeight : Float, block : ArcticBlock);
  106. /**
  107. * Clip the block to a certain size
  108. */
  109. Crop(x : Float, y : Float, width : Null<Float>, height : Null<Float>, block : ArcticBlock);
  110. /**
  111. * Filler is greedy empty space, that eats space when put in a LineStack or ColumnStack.
  112. * This can be used to implement left alignment, centering, and similar layout strategies.
  113. */
  114. Filler;
  115. /**
  116. * A block of the given size - can be empty
  117. */
  118. Fixed(width : Null<Float>, height : Null<Float>);
  119. /**
  120. * Align a block.
  121. * xpos: 0=left align, 0.5 = center horizontally, 1=right align, -1 = width to fit, -2 = use width of child
  122. * ypos: 0=top align, 0.5 = center vertically, 1=bottom align, -1 = height to fit, -2 = use height of child
  123. */
  124. Align(xpos : Float, ypos : Float, block : ArcticBlock);
  125. /**
  126. * Columns are blocks put next to each other horizontally. The height is the maximum
  127. * height of the blocks. If there is an unconstrained filler in the column stack (recursively)
  128. * this block will use all available width.
  129. */
  130. ColumnStack(columns: Array<ArcticBlock>, ?useIntegerFillings: Bool, ?rowAlign : Float);
  131. /**
  132. * A bunch of blocks stacked on top of each other. The width is the maximum width
  133. * of the blocks. If you want to make sure the very top of a specific block is visible,
  134. * pass the index number of the block in the array as second parameter. Notice there
  135. * is no guarantee that all of the entry is visible. If you do not need a scrollbar,
  136. * no matter how high the LineStack is, then pass false as the last parameter. The default
  137. * is to automatically add a scrollbar if needed.
  138. */
  139. LineStack(blocks: Array<ArcticBlock>, ?ensureVisibleIndex: Null<Int>, ?useScrollbar : Bool, ?useIntegerFillings: Bool, ?lineAlign : Float);
  140. /**
  141. * A 2-d grid of block. For now, this does not support resizing or horizontal scrollbar.
  142. * Vertical scrollbar will be added automatically if the opposite is not specified
  143. */
  144. Grid(blocks: Array<Array<ArcticBlock>>, ?disableScrollbar: Bool, ?oddRowColor: Int, ?evenRowColor: Int, ?borderSize : Float, ?borderColor : Null<Int>);
  145. //TODO: may be it should be removed from ArcticBlock enum?
  146. TableCell(block : ArcticBlock, ?rowSpan : Int, ?colSpan : Int, ?topBorder : Int, ?rightBorder : Int, ?bottomBorder : Int, ?leftBorder : Int);
  147. Table(cells : Array<ArcticBlock>, nRows : Int, nCols : Int, borderColor : Null<Int>);
  148. /**
  149. * Places the first block at the top-left corner, then the next block will be placed to the right.
  150. * The layout continues placing blocks along the x axis until a block reaches the bestWidth, then
  151. * the layout will begin placing blocks at the next row.
  152. * Best width is choosen from [lowerWidth * maxWidth ... maxWidth] by minimizing of block area.
  153. * eolFiller: optional block, which will be placed into the end of each row if there is some
  154. * free space
  155. * If maxWidth is null, the block will grow and use all available width.
  156. * lowerWidth should be in [0 ... 1] range. By default its value is 0.45
  157. * lineAlign defines blocks alignment in the row. [Top ... Bottom] corresponds to [0 ... 1] range.
  158. * rowAlign defines left-to-right justification of each row. Should be in [0 ... 1] range.
  159. * rowIndent defines first line indentation. Negative value indents subsequent lines.
  160. */
  161. Wrap(blocks: Array<ArcticBlock>, ?maxWidth: Float, ?xspacing: Null<Float>, ?yspacing: Null<Float>, ?eolFiller: ArcticBlock, ?lowerWidth : Float, ?lineAlign : Float, ?rowAlign : Float, ?rowIndent : Float );
  162. /// Add a scrollbar if necessary
  163. ScrollBar(block : ArcticBlock);
  164. /**
  165. * Make a block dragable by the mouse in the given directions.
  166. * If stayWithinSize is true, the movement is constrained to the available area
  167. * of the block (and this block becomes size greedy in the directions we allow motion in).
  168. * This block can be used to make many things, including dialogs. Use the wrapper
  169. * Arctic.makeDragable if you want to preserve the dragged distance across canvas resizes.
  170. */
  171. Dragable(stayWithinBlock : Bool, sideMotionAllowed : Bool, upDownMotionAllowed : Bool, block : ArcticBlock,
  172. onDrag : DragInfo -> Void, ?onInit : DragInfo -> (Float -> Float -> Void) -> Void, ?onStopDrag: Void -> Void);
  173. /**
  174. * Set the cursor shape to a block when the mouse is within the given block.
  175. * If you want the cursor block to be in ADDITION to the normal cursor, set
  176. * keepNormalCursor to true. This is useful for tooltips, see Arctic.makeTooltip.
  177. * Per default, the normal cursor is hidden when the custom cursor is visible.
  178. * If showFullCursor is true and cursor block juts out base clip on the right side,
  179. * cursor block will be placed a bit left to mouse cursor (but its left-upper corner
  180. * will be still visible). Same for bottom side.
  181. */
  182. Cursor(block : ArcticBlock, cursor : ArcticBlock, ?keepNormalCursor : Null<Bool>, ?showFullCursor : Null<Bool> );
  183. /**
  184. * Translate a block in some direction - notice layout does not take this offset
  185. * into account.
  186. */
  187. Offset(xOffset : Float, yOffset : Float, block : ArcticBlock);
  188. /**
  189. * Place a block on top of another block (overlay). The size is the maximum of the
  190. * two blocks in each dimension.
  191. */
  192. OnTop(base : ArcticBlock, overlay : ArcticBlock);
  193. #if flash9
  194. OnTopView(base : ArcticBlock, overlay : ArcticBlock);
  195. #end
  196. /// A state-full block which can be updated from the outside with a new block. See MutableBlock below for more info
  197. Mutable( state : MutableBlock );
  198. /**
  199. * A choice block that allows you to choose one of an array of blocks. At any time,
  200. * just one of these blocks is visible (the initial one is selected by 'current'). The
  201. * block will cache the views of the other, invisible blocks, so that switching to another
  202. * block is fast. The onInit function is a function that is called on construction with a
  203. * function which allows you to switch between the different blocks.
  204. *
  205. * Example:
  206. *
  207. * var switchFn : Int -> Void;
  208. * var getSwitchFn = function (fn) { switchFn = fn; };
  209. * var gui = Switch( [ block0, block1, block2 ], 0, getSwitchFn);
  210. * ...
  211. * // Switch to block 1
  212. * switchFn(1);
  213. *
  214. * See Arctic.makeSwitch for an simple wrapper that helps do this.
  215. */
  216. Switch(blocks : Array<ArcticBlock>, current : Int, onInit : (Int -> Void) -> Void);
  217. /**
  218. * Name this block so that we can get to it, and update it using ArcticView.update
  219. * and ArcticView.getRawMovieClip. Has no visual effect besides this.
  220. */
  221. Id(name : String, block : ArcticBlock);
  222. /**
  223. * A custom block. This is an escape mechanism which allows you to extend Arctic
  224. * with your own basic blocks. Parameters:
  225. *
  226. * data: an optional payload.
  227. * buildFunc: This is called with the optional data payload as first parameter,
  228. * the build mode requested (see enum below), the parent MovieClip where the
  229. * block should be put or drawn, and the available height and width for the
  230. * element. The final parameter is any existing MovieClip. This is useful in
  231. * Reuse mode, where the code should update the looks of this MovieClip.
  232. *
  233. * The buildFunc should return parentMc as clip in Create mode, existingMC in
  234. * Reuse mode, and null in Metrics mode. (Therefore, this could be omitted
  235. * from the API, but for now, I'll let it be like be like this to avoid
  236. * introducing new types.)
  237. *
  238. * The function should return the metrics for the block. The different build modes
  239. * should be consistent in the metrics - otherwise, layout bugs can occur.
  240. *
  241. * Notice that you have to build the custom blocks such that their work with
  242. * both Flash 8 and 9. See ArcticMC for helper functions that makes this simpler.
  243. */
  244. CustomBlock( data : Dynamic, buildFunc : Dynamic -> BuildMode -> ArcticMovieClip -> Float -> Float -> ArcticMovieClip -> Metrics );
  245. /**
  246. * Draws a frame around the given block. Alpha is optional between 0 and 100.
  247. */
  248. Frame(thickness: Float, color: Int, block: ArcticBlock, ?roundRadius: Null<Float>, ?alpha: Null<Float>, ?xspacing: Null<Float>, ?yspacing: Null<Float>);
  249. /**
  250. * Apply a filter on the block. Notice that the filter effect is not considered as part of the block
  251. * in terms of size.
  252. */
  253. Filter(filter : Filter, block : ArcticBlock);
  254. /**
  255. * Captures mouse wheel movements in the given block
  256. */
  257. MouseWheel(block : ArcticBlock, onMouseWheel : Float -> Void);
  258. /**
  259. * A masking block - a block is masked by another block
  260. */
  261. Mask(block : ArcticBlock, mask : ArcticBlock);
  262. /**
  263. * Scale a block - original size is 1.0. The scaling can be constrained to maxScale.
  264. * If childGrowth is 1.0, the child gets all available space for layout. Default is 0.
  265. */
  266. Scale(block : ArcticBlock, ? maxScale : Float, ? alignX : Float, ? alignY : Float, ?childGrowth : Float);
  267. /**
  268. * Transform a block
  269. */
  270. Transform(block : ArcticBlock, scaleX : Float, scaleY : Float);
  271. #if flash9
  272. /// Rotates a block. The angle is in degrees. If keepOrigin is true, we do not translate or enlarge the result accordingly
  273. Rotate(block : ArcticBlock, ?angle : Float, ?keepOrigin : Bool);
  274. #end
  275. /// An animation block
  276. Animate(animator : Animator);
  277. Cached(block : ArcticBlock);
  278. UnCached(block : ArcticBlock);
  279. /// Special block which is useful for debugging
  280. DebugBlock(id : String, block : ArcticBlock);
  281. }
  282. /// The structure used by CustomBlocks to tell arctic of dimensions and requested resizing behaviour
  283. typedef Metrics = { clip: ArcticMovieClip, width : Float, height : Float, growWidth : Bool, growHeight : Bool }
  284. /// What the build function should do
  285. enum BuildMode {
  286. /// Create a new movieclip for the block
  287. Create;
  288. /// Reuse an existing movieclip, but update that to reflect the block
  289. Reuse;
  290. /// Do not create or change any movieclips - just calculate metrics
  291. Metrics;
  292. /// Destroy, removing movieClip and event listeners.
  293. Destroy;
  294. }
  295. /// Information returned about draggable blocks
  296. typedef DragInfo = {
  297. // How much we have moved so far in pixels?
  298. x : Float,
  299. y : Float,
  300. // How wide/high is the drag handle?
  301. width : Float,
  302. height : Float,
  303. // How much room is available for dragging in pixels?
  304. totalWidth : Float,
  305. totalHeight : Float
  306. }
  307. /**
  308. * TextInputModel is an aux structure to manipulate get and set status of text inputs - see below
  309. * Note: when setting status, leave the parameters you don't want to change as null
  310. * Selection takes precedence over cursor position when setting
  311. */
  312. typedef TextInputModel = {
  313. var html: Null<String>;
  314. var text: Null<String>;
  315. var focus: Null<Bool>;
  316. var selStart: Null<Int>;
  317. var selEnd: Null<Int>;
  318. var cursorPos: Null<Int>;
  319. var disabled: Null<Bool>;
  320. var cursorX: Null<Float>;
  321. }
  322. /**
  323. * TextInputEvents is an aux structure to manipulate manipulate input events
  324. */
  325. typedef TextInputEvents = {
  326. var onChange: Void -> Void;
  327. var onSetFocus: Void -> Void;
  328. var onKillFocus: Void -> Void;
  329. var onPress: Void -> Void;
  330. var onRelease: Void -> Void;
  331. #if flash9
  332. var onKeyDown: UInt -> Void;
  333. var onKeyUp: UInt -> Void;
  334. #else
  335. var onKeyDown: Int -> Void;
  336. var onKeyUp: Int -> Void;
  337. #end
  338. var onCaretPosChanged: Void -> Void;
  339. }
  340. enum Filter {
  341. #if flash9
  342. Bevel(?distance : Float, ?angle : Float, ?highlightColor : UInt, ?highlightAlpha : Float, ?shadowColor : UInt, ?shadowAlpha : Float, ?blurX : Float, ?blurY : Float, ?strength : Float, ?quality : Int, ?type : String, ?knockout : Bool);
  343. Blur(?blurX : Float, ?blurY : Float, ?quality : Int);
  344. ColorMatrix(?matrix : Array<Float>);
  345. Convolution(?matrixX : Float, ?matrixY : Float, ?matrix : Array<Dynamic>, ?divisor : Float, ?bias : Float, ?preserveAlpha : Bool, ?clamp : Bool, ?color : UInt, ?alpha : Float);
  346. DropShadow(?distance : Float, ?angle : Float, ?color : UInt, ?alpha : Float, ?blurX : Float, ?blurY : Float/*, ?strength : Float, ?quality : Int, ?inner : Bool, ?knockout : Bool, ?hideObject : Bool*/);
  347. // DropShadow(?distance : Float, ?angle : Float, ?color : UInt, ?alpha : Float);
  348. Glow(?color : UInt, ?alpha : Float, ?blurX : Float, ?blurY : Float, ?strength : Float, ?quality : Int, ?inner : Bool, ?knockout : Bool);
  349. GradientBevel(?distance : Float, ?angle : Float, ?colors : Array<Dynamic>, ?alphas : Array<Dynamic>, ?ratios : Array<Dynamic>, ?blurX : Float, ?blurY : Float, ?strength : Float, ?quality : Int, ?type : String, ?knockout : Bool);
  350. GradientGlow(?distance : Float, ?angle : Float, ?colors : Array<Dynamic>, ?alphas : Array<Dynamic>, ?ratios : Array<Dynamic>, ?blurX : Float, ?blurY : Float, ?strength : Float, ?quality : Int, ?type : String, ?knockout : Bool);
  351. #else
  352. Bevel(?distance : Float, ?angle : Float, ?highlightColor : Float, ?highlightAlpha : Float, ?shadowColor : Float, ?shadowAlpha : Float, ?blurX : Float, ?blurY : Float, ?strength : Float, ?quality : Float, ?type : String, ?knockout : Bool);
  353. Blur(?blurX : Float, ?blurY : Float, ?quality : Int);
  354. ColorMatrix(?matrix : Array<Float>);
  355. Convolution(?matrixX : Float, ?matrixY : Float, ?matrix : Array<Dynamic>, ?divisor : Float, ?bias : Float, ?preserveAlpha : Bool, ?clamp : Bool, ?color : Int, ?alpha : Float);
  356. // DropShadow(?distance : Float, ?angle : Float, ?color : Float, ?alpha : Float, ?blurX : Float, ?blurY : Float, ?strength : Float, ?quality : Float, ?inner : Bool, ?knockout : Bool, ?hideObject : Bool);
  357. DropShadow(?distance : Float, ?angle : Float, ?color : Float, ?alpha : Float);
  358. Glow(?color : Int, ?alpha : Float, ?blurX : Float, ?blurY : Float, ?strength : Float, ?quality : Int, ?inner : Bool, ?knockout : Bool);
  359. GradientBevel(?distance : Float, ?angle : Float, ?colors : Array<Dynamic>, ?alphas : Array<Dynamic>, ?ratios : Array<Dynamic>, ?blurX : Float, ?blurY : Float, ?strength : Float, ?quality : Int, ?type : String, ?knockout : Bool);
  360. GradientGlow(?distance : Float, ?angle : Float, ?colors : Array<Dynamic>, ?alphas : Array<Dynamic>, ?ratios : Array<Dynamic>, ?blurX : Float, ?blurY : Float, ?strength : Float, ?quality : Int, ?type : String, ?knockout : Bool);
  361. #end
  362. }
  363. /**
  364. * A MutableBlock object encapsulates a block which can be updated later.
  365. * Just assign a new ArcticBlock to the block member variable, and the display will be updated
  366. * automatically. See the Mutable ArcticBlock above.
  367. * This has also been wrapped as an easy-to-use state block. See ArcticState for more info
  368. * on this.
  369. * Example:
  370. * var mutable = new MutableBlock(Text("My block"));
  371. * var gui = Mutable(mutable);
  372. * var dialog = new ArcticDialogUi(gui).open();
  373. * ...
  374. * // Automatically update the block
  375. * mutable.block = Text("New text");
  376. */
  377. class MutableBlock {
  378. public function new(initialBlock : ArcticBlock) {
  379. myBlock = initialBlock;
  380. arcticUpdater = null;
  381. }
  382. public var block(get, set) : ArcticBlock;
  383. private var myBlock : ArcticBlock;
  384. private function get() : ArcticBlock {
  385. return myBlock;
  386. }
  387. private function set(block : ArcticBlock) : ArcticBlock {
  388. var oldBlock = myBlock;
  389. /* Hm, this is not possible, since enums can not be compared
  390. if (block == oldBlock) {
  391. return block;
  392. }
  393. */
  394. myBlock = block;
  395. update(oldBlock);
  396. return myBlock;
  397. }
  398. /// For safety, provide an explicit way to update the view (should never be necessary)
  399. public function update(?oldBlock : ArcticBlock) {
  400. if (arcticUpdater != null) {
  401. arcticUpdater(oldBlock, block, availableWidth, availableHeight);
  402. }
  403. }
  404. public function destroy() {
  405. if (arcticUpdater != null) {
  406. arcticUpdater(myBlock, null, availableWidth, availableHeight);
  407. }
  408. }
  409. /// Updated by ArcticView.build
  410. public var arcticUpdater(null, default) : ArcticBlock -> ArcticBlock -> Float -> Float -> Void;
  411. public var availableWidth(null, default) : Float;
  412. public var availableHeight(null, default) : Float;
  413. }
  414. /**
  415. * Example of creating an animation in Arctic:
  416. * var animator = new Animator( arctic.Text("Test") );
  417. * var gui = LineStack( Animate(animator) );
  418. * ...
  419. * // To start an animation that takes 5 seconds:
  420. * animator.animate(5.0, [ Alpha(Animators.line( 0.0, 1.0 )), ScaleX(Animators.line(10.0, 0.0)) ] );
  421. */
  422. class Animator {
  423. public function new(block0 : ArcticBlock, ?doneFn0 : Void -> Void) {
  424. block = block0;
  425. doneFn = doneFn0;
  426. startTime = 0.0;
  427. }
  428. /// External interface used to start an animation
  429. public function animate(duration0 : Float, animations0 : Array<AnimateComponent>) {
  430. #if flash9
  431. if (startTime != 0.0) {
  432. clearHandler();
  433. }
  434. reciprocDuration = 0.001 / duration0;
  435. animations = animations0;
  436. startTime = flash.Lib.getTimer();
  437. endTime = startTime + duration0;
  438. clip.addEventListener(flash.events.Event.ENTER_FRAME, enterFrame);
  439. #end
  440. }
  441. private function enterFrame( e ) : Void {
  442. #if flash9
  443. var t = flash.Lib.getTimer() - startTime;
  444. t = t * reciprocDuration;
  445. if (t >= 1.0) {
  446. clearHandler();
  447. t = 1.0;
  448. }
  449. for (a in animations) {
  450. switch (a) {
  451. /// Hm, this should be recursive
  452. case Alpha( f ): var a = f(t); if (a != clip.alpha) clip.alpha = a;
  453. case X( f ): var x = f(t); if (x != clip.x) clip.x = x;
  454. case Y( f ): var y = f(t); if (y != clip.y) clip.y = y;
  455. case ScaleX( f ): var sx = f(t); if (sx != clip.scaleX) clip.scaleX = sx;
  456. case ScaleY( f ): var sy = f(t); if (sy != clip.scaleY) clip.scaleY = sy;
  457. case Rotation( f ): var r = f(t); if (r != clip.rotation) clip.rotation = r;
  458. }
  459. }
  460. if (t >= 1.0 && doneFn != null) {
  461. doneFn();
  462. }
  463. #end
  464. }
  465. /// Called by ArcticView.build
  466. public function registerClip(clip0 : ArcticMovieClip) {
  467. clip = clip0;
  468. }
  469. private function clearHandler() {
  470. if (clip != null) {
  471. #if flash9
  472. clip.removeEventListener(flash.events.Event.ENTER_FRAME, enterFrame);
  473. #end
  474. }
  475. }
  476. /// Called by ArcticView.build on destroy phase
  477. public function destroy() {
  478. clearHandler();
  479. clip = null;
  480. }
  481. public var block : ArcticBlock;
  482. private var doneFn : Void -> Void;
  483. private var clip : ArcticMovieClip;
  484. private var startTime : Float;
  485. private var endTime : Float;
  486. private var reciprocDuration : Float;
  487. private var animations : Array<AnimateComponent>;
  488. }
  489. enum AnimateComponent {
  490. Alpha( f : Float -> Float);
  491. X( f : Float -> Float);
  492. Y( f : Float -> Float);
  493. ScaleX( f : Float -> Float);
  494. ScaleY( f : Float -> Float);
  495. Rotation( f : Float -> Float);
  496. }