PageRenderTime 88ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/com/bit101/components/ColorChooser.as

https://github.com/jenrios/Elastic-Lists
ActionScript | 355 lines | 235 code | 49 blank | 71 comment | 13 complexity | 58cd64ed16767bec7956732466e89968 MD5 | raw file
  1. /**
  2. * ColorChooser.as
  3. * Keith Peters
  4. * version 0.9.1
  5. *
  6. * A Color Chooser component, allowing textual input, a default gradient, or custom image.
  7. *
  8. * Copyright (c) 2010 Keith Peters
  9. *
  10. * popup color choosing code by Rashid Ghassempouri
  11. *
  12. * Permission is hereby granted, free of charge, to any person obtaining a copy
  13. * of this software and associated documentation files (the "Software"), to deal
  14. * in the Software without restriction, including without limitation the rights
  15. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  16. * copies of the Software, and to permit persons to whom the Software is
  17. * furnished to do so, subject to the following conditions:
  18. *
  19. * The above copyright notice and this permission notice shall be included in
  20. * all copies or substantial portions of the Software.
  21. *
  22. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  23. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  24. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  25. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  26. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  27. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  28. * THE SOFTWARE.
  29. */
  30. package com.bit101.components
  31. {
  32. import flash.display.Bitmap;
  33. import flash.display.BitmapData;
  34. import flash.display.BlendMode;
  35. import flash.display.DisplayObject;
  36. import flash.display.DisplayObjectContainer;
  37. import flash.display.GradientType;
  38. import flash.display.Graphics;
  39. import flash.display.InterpolationMethod;
  40. import flash.display.SpreadMethod;
  41. import flash.display.Sprite;
  42. import flash.display.Stage;
  43. import flash.events.Event;
  44. import flash.events.MouseEvent;
  45. import flash.geom.Matrix;
  46. import flash.geom.Point;
  47. public class ColorChooser extends Component
  48. {
  49. public static const TOP:String = "top";
  50. public static const BOTTOM:String = "bottom";
  51. private var _colors:BitmapData;
  52. private var _colorsContainer:Sprite;
  53. private var _defaultModelColors:Array=[0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF, 0xFF0000,0xFFFFFF,0x000000];
  54. private var _input:InputText;
  55. private var _model:DisplayObject;
  56. private var _oldColorChoice:uint = _value;
  57. private var _popupAlign:String = BOTTOM;
  58. private var _stage:Stage;
  59. private var _swatch:Sprite;
  60. private var _tmpColorChoice:uint = _value;
  61. private var _usePopup:Boolean = false;
  62. private var _value:uint = 0xff0000;
  63. /**
  64. * Constructor
  65. * @param parent The parent DisplayObjectContainer on which to add this ColorChooser.
  66. * @param xpos The x position to place this component.
  67. * @param ypos The y position to place this component.
  68. * @param value The initial color value of this component.
  69. * @param defaultHandler The event handling function to handle the default event for this component (change in this case).
  70. */
  71. public function ColorChooser(parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number = 0, value:uint = 0xff0000, defaultHandler:Function = null)
  72. {
  73. _oldColorChoice = _tmpColorChoice = _value = value;
  74. super(parent, xpos, ypos);
  75. if(defaultHandler != null)
  76. {
  77. addEventListener(Event.CHANGE, defaultHandler);
  78. }
  79. }
  80. /**
  81. * Initializes the component.
  82. */
  83. override protected function init():void
  84. {
  85. super.init();
  86. _width = 65;
  87. _height = 15;
  88. value = _value;
  89. }
  90. override protected function addChildren():void
  91. {
  92. _input = new InputText();
  93. _input.width = 45;
  94. _input.restrict = "0123456789ABCDEFabcdef";
  95. _input.maxChars = 6;
  96. addChild(_input);
  97. _input.addEventListener(Event.CHANGE, onChange);
  98. _swatch = new Sprite();
  99. _swatch.x = 50;
  100. _swatch.filters = [getShadow(2, true)];
  101. addChild(_swatch);
  102. _colorsContainer = new Sprite();
  103. _colorsContainer.addEventListener(Event.ADDED_TO_STAGE, onColorsAddedToStage);
  104. _colorsContainer.addEventListener(Event.REMOVED_FROM_STAGE, onColorsRemovedFromStage);
  105. _model = getDefaultModel();
  106. drawColors(_model);
  107. }
  108. ///////////////////////////////////
  109. // public methods
  110. ///////////////////////////////////
  111. /**
  112. * Draws the visual ui of the component.
  113. */
  114. override public function draw():void
  115. {
  116. super.draw();
  117. _swatch.graphics.clear();
  118. _swatch.graphics.beginFill(_value);
  119. _swatch.graphics.drawRect(0, 0, 16, 16);
  120. _swatch.graphics.endFill();
  121. }
  122. ///////////////////////////////////
  123. // event handlers
  124. ///////////////////////////////////
  125. /**
  126. * Internal change handler.
  127. * @param event The Event passed by the system.
  128. */
  129. protected function onChange(event:Event):void
  130. {
  131. event.stopImmediatePropagation();
  132. _value = parseInt("0x" + _input.text, 16);
  133. _input.text = _input.text.toUpperCase();
  134. _oldColorChoice = value;
  135. invalidate();
  136. dispatchEvent(new Event(Event.CHANGE));
  137. }
  138. ///////////////////////////////////
  139. // getter/setters
  140. ///////////////////////////////////
  141. /**
  142. * Gets / sets the color value of this ColorChooser.
  143. */
  144. public function set value(n:uint):void
  145. {
  146. var str:String = n.toString(16).toUpperCase();
  147. while(str.length < 6)
  148. {
  149. str = "0" + str;
  150. }
  151. _input.text = str;
  152. _value = parseInt("0x" + _input.text, 16);
  153. invalidate();
  154. }
  155. public function get value():uint
  156. {
  157. return _value;
  158. }
  159. ///////////////////////////////////
  160. // COLOR PICKER MODE SUPPORT
  161. ///////////////////////////////////}
  162. public function get model():DisplayObject { return _model; }
  163. public function set model(value:DisplayObject):void
  164. {
  165. _model = value;
  166. if (_model!=null) {
  167. drawColors(_model);
  168. if (!usePopup) usePopup = true;
  169. } else {
  170. _model = getDefaultModel();
  171. drawColors(_model);
  172. usePopup = false;
  173. }
  174. }
  175. private function drawColors(d:DisplayObject):void{
  176. _colors = new BitmapData(d.width, d.height);
  177. _colors.draw(d);
  178. while (_colorsContainer.numChildren) _colorsContainer.removeChildAt(0);
  179. _colorsContainer.addChild(new Bitmap(_colors));
  180. placeColors();
  181. }
  182. public function get popupAlign():String { return _popupAlign; }
  183. public function set popupAlign(value:String):void {
  184. _popupAlign = value;
  185. placeColors();
  186. }
  187. public function get usePopup():Boolean { return _usePopup; }
  188. public function set usePopup(value:Boolean):void {
  189. _usePopup = value;
  190. _swatch.buttonMode = true;
  191. _colorsContainer.buttonMode = true;
  192. _colorsContainer.addEventListener(MouseEvent.MOUSE_MOVE, browseColorChoice);
  193. _colorsContainer.addEventListener(MouseEvent.MOUSE_OUT, backToColorChoice);
  194. _colorsContainer.addEventListener(MouseEvent.CLICK, setColorChoice);
  195. _swatch.addEventListener(MouseEvent.CLICK, onSwatchClick);
  196. if (!_usePopup) {
  197. _swatch.buttonMode = false;
  198. _colorsContainer.buttonMode = false;
  199. _colorsContainer.removeEventListener(MouseEvent.MOUSE_MOVE, browseColorChoice);
  200. _colorsContainer.removeEventListener(MouseEvent.MOUSE_OUT, backToColorChoice);
  201. _colorsContainer.removeEventListener(MouseEvent.CLICK, setColorChoice);
  202. _swatch.removeEventListener(MouseEvent.CLICK, onSwatchClick);
  203. }
  204. }
  205. /**
  206. * The color picker mode Handlers
  207. */
  208. private function onColorsRemovedFromStage(e:Event):void {
  209. _stage.removeEventListener(MouseEvent.CLICK, onStageClick);
  210. }
  211. private function onColorsAddedToStage(e:Event):void {
  212. _stage = stage;
  213. _stage.addEventListener(MouseEvent.CLICK, onStageClick);
  214. }
  215. private function onStageClick(e:MouseEvent):void {
  216. displayColors();
  217. }
  218. private function onSwatchClick(event:MouseEvent):void
  219. {
  220. event.stopImmediatePropagation();
  221. displayColors();
  222. }
  223. private function backToColorChoice(e:MouseEvent):void
  224. {
  225. value = _oldColorChoice;
  226. }
  227. private function setColorChoice(e:MouseEvent):void {
  228. value = _colors.getPixel(_colorsContainer.mouseX, _colorsContainer.mouseY);
  229. _oldColorChoice = value;
  230. dispatchEvent(new Event(Event.CHANGE));
  231. displayColors();
  232. }
  233. private function browseColorChoice(e:MouseEvent):void
  234. {
  235. _tmpColorChoice = _colors.getPixel(_colorsContainer.mouseX, _colorsContainer.mouseY);
  236. value = _tmpColorChoice;
  237. }
  238. /**
  239. * The color picker mode Display functions
  240. */
  241. private function displayColors():void
  242. {
  243. placeColors();
  244. if (_colorsContainer.parent) _colorsContainer.parent.removeChild(_colorsContainer);
  245. else stage.addChild(_colorsContainer);
  246. }
  247. private function placeColors():void{
  248. var point:Point = new Point(x, y);
  249. if(parent) point = parent.localToGlobal(point);
  250. switch (_popupAlign)
  251. {
  252. case TOP :
  253. _colorsContainer.x = point.x;
  254. _colorsContainer.y = point.y - _colorsContainer.height - 4;
  255. break;
  256. case BOTTOM :
  257. _colorsContainer.x = point.x;
  258. _colorsContainer.y = point.y + 22;
  259. break;
  260. default:
  261. _colorsContainer.x = point.x;
  262. _colorsContainer.y = point.y + 22;
  263. break;
  264. }
  265. }
  266. /**
  267. * Create the default gradient Model
  268. */
  269. private function getDefaultModel():Sprite {
  270. var w:Number = 100;
  271. var h:Number = 100;
  272. var bmd:BitmapData = new BitmapData(w, h);
  273. var g1:Sprite = getGradientSprite(w, h, _defaultModelColors);
  274. bmd.draw(g1);
  275. var blendmodes:Array = [BlendMode.MULTIPLY,BlendMode.ADD];
  276. var nb:int = blendmodes.length;
  277. var g2:Sprite = getGradientSprite(h/nb, w, [0xFFFFFF, 0x000000]);
  278. for (var i:int = 0; i < nb; i++) {
  279. var blendmode:String = blendmodes[i];
  280. var m:Matrix = new Matrix();
  281. m.rotate(-Math.PI / 2);
  282. m.translate(0, h / nb * i + h/nb);
  283. bmd.draw(g2, m, null,blendmode);
  284. }
  285. var s:Sprite = new Sprite();
  286. var bm:Bitmap = new Bitmap(bmd);
  287. s.addChild(bm);
  288. return(s);
  289. }
  290. private function getGradientSprite(w:Number, h:Number, ca:Array):Sprite
  291. {
  292. var gc:Array = ca;
  293. var gs:Sprite = new Sprite();
  294. var g:Graphics = gs.graphics;
  295. var gn:int = gc.length;
  296. var ga:Array = [];
  297. var gr:Array = [];
  298. var gm:Matrix = new Matrix(); gm.createGradientBox(w, h, 0, 0, 0);
  299. for (var i:int = 0; i < gn; i++) { ga.push(1); gr.push(0x00 + 0xFF / (gn - 1) * i); }
  300. g.beginGradientFill(GradientType.LINEAR, gc, ga, gr, gm, SpreadMethod.PAD,InterpolationMethod.RGB);
  301. g.drawRect(0, 0, w, h);
  302. g.endFill();
  303. return(gs);
  304. }
  305. }
  306. }