PageRenderTime 25ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/as3/net/inctm/components/Slider.as

http://duffy.googlecode.com/
ActionScript | 365 lines | 222 code | 38 blank | 105 comment | 18 complexity | 2775ed284761a46bcb37d3833dcac485 MD5 | raw file
  1. /**
  2. * Slider.as
  3. * Keith Peters
  4. * version 0.97
  5. *
  6. * A Horizontal Slider component for choosing values.
  7. *
  8. * Copyright (c) 2009 Keith Peters
  9. *
  10. * Permission is hereby granted, free of charge, to any person obtaining a copy
  11. * of this software and associated documentation files (the "Software"), to deal
  12. * in the Software without restriction, including without limitation the rights
  13. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14. * copies of the Software, and to permit persons to whom the Software is
  15. * furnished to do so, subject to the following conditions:
  16. *
  17. * The above copyright notice and this permission notice shall be included in
  18. * all copies or substantial portions of the Software.
  19. *
  20. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26. * THE SOFTWARE.
  27. */
  28. package net.inctm.components
  29. {
  30. import flash.display.DisplayObjectContainer;
  31. import flash.display.Sprite;
  32. import flash.events.Event;
  33. import flash.events.MouseEvent;
  34. import flash.geom.Rectangle;
  35. public class Slider extends Component
  36. {
  37. protected var _handle:Sprite;
  38. protected var _back:Sprite;
  39. protected var _backClick:Boolean = true;
  40. protected var _value:Number = 0;
  41. protected var _max:Number = 100;
  42. protected var _min:Number = 0;
  43. protected var _orientation:String;
  44. protected var _tick:Number = 1;
  45. public static const HORIZONTAL:String = "horizontal";
  46. public static const VERTICAL:String = "vertical";
  47. public var scrollerSize:int = 15;
  48. /**
  49. * Constructor
  50. * @param orientation Whether the slider will be horizontal or vertical.
  51. * @param parent The parent DisplayObjectContainer on which to add this Slider.
  52. * @param xpos The x position to place this component.
  53. * @param ypos The y position to place this component.
  54. * @param defaultHandler The event handling function to handle the default event for this component (change in this case).
  55. */
  56. public function Slider(orientation:String = Slider.HORIZONTAL, parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number = 0, defaultHandler:Function = null)
  57. {
  58. _orientation = orientation;
  59. super(parent, xpos, ypos);
  60. if(defaultHandler != null)
  61. {
  62. addEventListener(Event.CHANGE, defaultHandler);
  63. }
  64. }
  65. /**
  66. * Initializes the component.
  67. */
  68. override protected function init():void
  69. {
  70. super.init();
  71. if(_orientation == HORIZONTAL)
  72. {
  73. setSize(100, 10);
  74. }
  75. else
  76. {
  77. setSize(10, 100);
  78. }
  79. }
  80. /**
  81. * Creates and adds the child display objects of this component.
  82. */
  83. override protected function addChildren():void
  84. {
  85. _back = new Sprite();
  86. //_back.filters = [getShadow(2, true)];
  87. addChild(_back);
  88. _handle = new Sprite();
  89. //_handle.filters = [getShadow(1)];
  90. _handle.addEventListener(MouseEvent.MOUSE_DOWN, onDrag);
  91. _handle.buttonMode = true;
  92. _handle.useHandCursor = true;
  93. addChild(_handle);
  94. }
  95. /**
  96. * Draws the back of the slider.
  97. */
  98. protected function drawBack():void
  99. {
  100. _back.graphics.clear();
  101. _back.graphics.beginFill(Style.BACKGROUND);
  102. _back.graphics.drawRect(0, 0, _width, _height);
  103. _back.graphics.endFill();
  104. if(_backClick)
  105. {
  106. _back.addEventListener(MouseEvent.MOUSE_DOWN, onBackClick);
  107. }
  108. else
  109. {
  110. _back.removeEventListener(MouseEvent.MOUSE_DOWN, onBackClick);
  111. }
  112. }
  113. /**
  114. * Draws the handle of the slider.
  115. */
  116. protected function drawHandle():void
  117. {
  118. _handle.graphics.clear();
  119. _handle.graphics.beginFill(Style.BUTTON_FACE);
  120. if(_orientation == HORIZONTAL)
  121. {
  122. _handle.graphics.drawRect(0, 0, scrollerSize, _height);
  123. }
  124. else
  125. {
  126. _handle.graphics.drawRect(0, 0, _width, scrollerSize);
  127. }
  128. _handle.graphics.endFill();
  129. positionHandle();
  130. }
  131. /**
  132. * Adjusts value to be within minimum and maximum.
  133. */
  134. protected function correctValue():void
  135. {
  136. if(_max > _min)
  137. {
  138. _value = Math.min(_value, _max);
  139. _value = Math.max(_value, _min);
  140. }
  141. else
  142. {
  143. _value = Math.max(_value, _max);
  144. _value = Math.min(_value, _min);
  145. }
  146. }
  147. /**
  148. * Adjusts position of handle when value, maximum or minimum have changed.
  149. * TODO: Should also be called when slider is resized.
  150. */
  151. protected function positionHandle():void
  152. {
  153. var range:Number;
  154. if(_orientation == HORIZONTAL)
  155. {
  156. range = _width - _handle.width;
  157. _handle.x = (_value - _min) / (_max - _min) * range;
  158. }
  159. else
  160. {
  161. range = _height - _handle.height;
  162. _handle.y = _height - _handle.height - (_value - _min) / (_max - _min) * range;
  163. }
  164. }
  165. ///////////////////////////////////
  166. // public methods
  167. ///////////////////////////////////
  168. /**
  169. * Draws the visual ui of the component.
  170. */
  171. override public function draw():void
  172. {
  173. super.draw();
  174. drawBack();
  175. drawHandle();
  176. }
  177. /**
  178. * Convenience method to set the three main parameters in one shot.
  179. * @param min The minimum value of the slider.
  180. * @param max The maximum value of the slider.
  181. * @param value The value of the slider.
  182. */
  183. public function setSliderParams(min:Number, max:Number, value:Number):void
  184. {
  185. this.minimum = min;
  186. this.maximum = max;
  187. this.value = value;
  188. }
  189. ///////////////////////////////////
  190. // event handlers
  191. ///////////////////////////////////
  192. /**
  193. * Handler called when user clicks the background of the slider, causing the handle to move to that point. Only active if backClick is true.
  194. * @param event The MouseEvent passed by the system.
  195. */
  196. protected function onBackClick(event:MouseEvent):void
  197. {
  198. if(_orientation == HORIZONTAL)
  199. {
  200. _handle.x = mouseX - _height / 2;
  201. _handle.x = Math.max(_handle.x, 0);
  202. _handle.x = Math.min(_handle.x, _width - _height);
  203. _value = _handle.x / (width - _height) * (_max - _min) + _min;
  204. }
  205. else
  206. {
  207. _handle.y = mouseY - _width / 2;
  208. _handle.y = Math.max(_handle.y, 0);
  209. _handle.y = Math.min(_handle.y, _height - _width);
  210. _value = (_height - _width - _handle.y) / (height - _width) * (_max - _min) + _min;
  211. }
  212. dispatchEvent(new Event(Event.CHANGE));
  213. }
  214. /**
  215. * Internal mouseDown handler. Starts dragging the handle.
  216. * @param event The MouseEvent passed by the system.
  217. */
  218. protected function onDrag(event:MouseEvent):void
  219. {
  220. stage.addEventListener(MouseEvent.MOUSE_UP, onDrop);
  221. stage.addEventListener(MouseEvent.MOUSE_MOVE, onSlide);
  222. if(_orientation == HORIZONTAL)
  223. {
  224. _handle.startDrag(false, new Rectangle(0, 0, _back.width - _handle.width, 0));
  225. }
  226. else
  227. {
  228. _handle.startDrag(false, new Rectangle(0, 0, 0, _back.height - _handle.height));
  229. }
  230. }
  231. /**
  232. * Internal mouseUp handler. Stops dragging the handle.
  233. * @param event The MouseEvent passed by the system.
  234. */
  235. protected function onDrop(event:MouseEvent):void
  236. {
  237. stage.removeEventListener(MouseEvent.MOUSE_UP, onDrop);
  238. stage.removeEventListener(MouseEvent.MOUSE_MOVE, onSlide);
  239. stopDrag();
  240. }
  241. /**
  242. * Internal mouseMove handler for when the handle is being moved.
  243. * @param event The MouseEvent passed by the system.
  244. */
  245. protected function onSlide(event:MouseEvent):void
  246. {
  247. var oldValue:Number = _value;
  248. if(_orientation == HORIZONTAL)
  249. {
  250. _value = _handle.x / (width - _height) * (_max - _min) + _min;
  251. }
  252. else
  253. {
  254. _value = (_height - _width - _handle.y) / (height - _width) * (_max - _min) + _min;
  255. }
  256. if(_value != oldValue)
  257. {
  258. dispatchEvent(new Event(Event.CHANGE));
  259. }
  260. }
  261. ///////////////////////////////////
  262. // getter/setters
  263. ///////////////////////////////////
  264. /**
  265. * Sets / gets whether or not a click on the background of the slider will move the handler to that position.
  266. */
  267. public function set backClick(b:Boolean):void
  268. {
  269. _backClick = b;
  270. invalidate();
  271. }
  272. public function get backClick():Boolean
  273. {
  274. return _backClick;
  275. }
  276. /**
  277. * Sets / gets the current value of this slider.
  278. */
  279. public function set value(v:Number):void
  280. {
  281. _value = v;
  282. correctValue();
  283. positionHandle();
  284. }
  285. public function get value():Number
  286. {
  287. return Math.round(_value / _tick) * _tick;
  288. }
  289. /**
  290. * Gets / sets the maximum value of this slider.
  291. */
  292. public function set maximum(m:Number):void
  293. {
  294. _max = m;
  295. correctValue();
  296. positionHandle();
  297. }
  298. public function get maximum():Number
  299. {
  300. return _max;
  301. }
  302. /**
  303. * Gets / sets the minimum value of this slider.
  304. */
  305. public function set minimum(m:Number):void
  306. {
  307. _min = m;
  308. correctValue();
  309. positionHandle();
  310. }
  311. public function get minimum():Number
  312. {
  313. return _min;
  314. }
  315. /**
  316. * Gets / sets the tick value of this slider. This round the value to the nearest multiple of this number.
  317. */
  318. public function set tick(t:Number):void
  319. {
  320. _tick = t;
  321. }
  322. public function get tick():Number
  323. {
  324. return _tick;
  325. }
  326. }
  327. }