/libs/gui/hug/HUGListBox.hx

http://na-agent.googlecode.com/ · Haxe · 408 lines · 303 code · 69 blank · 36 comment · 53 complexity · 846f7e934c201d52a70272c411fab9fb MD5 · raw file

  1. package gui.hug;
  2. import flash.display.DisplayObject;
  3. import flash.display.DisplayObjectContainer;
  4. import flash.display.Sprite;
  5. import flash.display.Stage;
  6. import flash.events.KeyboardEvent;
  7. import flash.events.MouseEvent;
  8. import flash.events.Event;
  9. import flash.display.MovieClip;
  10. import flash.text.TextField;
  11. import gui.hug.priv.HUGBorder;
  12. /**
  13. * @author Alexey Kharkov
  14. */
  15. class HUGListBox extends HUGSprite
  16. {
  17. private var items:Array<Dynamic>; //private var items:Array<HUGComboItem>;
  18. private var cur:HUGComboItem; // Currently active item
  19. private var hl:HUGComboItem; // Highlighted item
  20. private var w:Float; // width
  21. private var sel:HUGSprite; // Highlighting rectangle
  22. private var sb:HUGScrollBar;
  23. public var owner:HUGComboBox;
  24. private var enMouse:Bool;
  25. static public inline var ITEM_H:UInt = 19;
  26. static public inline var W:UInt = 16; // ScrollBar width
  27. static public inline var ITEMS_COUNT_TO_SCROLL:UInt = 12;
  28. public function new( x:Int, y:Int, w:Int )
  29. {
  30. super();
  31. this.x = x;
  32. this.y = y;
  33. this.w = w;
  34. enMouse = true;
  35. items = new Array();
  36. //Dbg.init( this );
  37. //mouseEnabled = false;
  38. buttonMode = true;
  39. // Selection rects
  40. sel = new HUGSprite();
  41. Utils.rect( sel, 0, 1, w, ITEM_H - 1, Utils.SEL_BG_COL, Utils.SEL_BG_BORDER_COL );
  42. //drawSel( w );
  43. sel.mouseEnabled = false;
  44. addChild( sel );
  45. sel.mask = maskRect();
  46. // Scroll bar
  47. sb = new HUGScrollBar( w - W, 0, ITEM_H * ITEMS_COUNT_TO_SCROLL - 1 );
  48. sb.visible = false;
  49. sb.addEventListener( Event.SCROLL, onScroll );
  50. addChild( sb );
  51. // Keys control
  52. addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
  53. //
  54. drawBg();
  55. addEventListener( MouseEvent.ROLL_OVER, onOver );
  56. addEventListener( MouseEvent.ROLL_OUT, onOut );
  57. addEventListener( MouseEvent.MOUSE_WHEEL, onWheel );
  58. }
  59. public function clear()
  60. {
  61. cur = null;
  62. items = new Array();
  63. clearLayout();
  64. // Reset Selection Rect
  65. //drawSel( w );
  66. // Reset ScrollBar
  67. sb.init( 0, ITEMS_COUNT_TO_SCROLL );
  68. sb.setScrollPosition(0);
  69. sb.visible = false;
  70. }
  71. public function addItemsArray( arr:Array<Dynamic> )
  72. {
  73. for (i in 0...arr.length)
  74. addItemHelper( arr[i] );
  75. upd();
  76. }
  77. public function addItem( s:String )
  78. {
  79. addItemHelper( s );
  80. upd();
  81. }
  82. public function replaceItemAt( key:Int, s:String )
  83. {
  84. if(key < getLength()) {
  85. var idx:Int = key;
  86. var item: HUGComboItem = new HUGComboItem( this, s, idx, w );
  87. item.y = idx * ITEM_H - 1;
  88. if ( idx == 0 )
  89. {
  90. cur = item;
  91. hl = item;
  92. setItemActive( item );
  93. }
  94. items[key] = item;
  95. reDraw();
  96. }
  97. }
  98. public function getSelectedIndex():Int
  99. {
  100. return (cur != null) ? cur.idx : 0;
  101. }
  102. /*public function getItem(index : Int) : String
  103. {
  104. return items[index].txt.text;
  105. }
  106. */
  107. public function setSelectedIndex( idx:Int )
  108. {
  109. if ( idx >= 0 && idx < getLength() )
  110. {
  111. onItemClick( items[idx], false );
  112. scrollToCur();
  113. }
  114. }
  115. public function getLength():Int
  116. {
  117. return items.length;
  118. }
  119. public function getWidth(): Float
  120. {
  121. return w;
  122. }
  123. public function getHeight():Float
  124. {
  125. return Math.min(getLength(), ITEMS_COUNT_TO_SCROLL) * ITEM_H;
  126. }
  127. // ---------------------------------------------------------------------------- internal methods.
  128. public function setItemActive( item: Dynamic )
  129. {
  130. if ( hl != null )
  131. hl.txt.textColor = 0;
  132. hl = item;
  133. sel.y = item.y;
  134. item.txt.textColor = 0xffffff;
  135. }
  136. public function onItemClick( item: Dynamic, b:Bool )
  137. {
  138. cur = item;
  139. setItemActive( item );
  140. if ( owner == null )
  141. dispatchEvent( new Event( Event.CHANGE ) );
  142. else
  143. owner.onItemClick( item, b );
  144. }
  145. public function reset()
  146. {
  147. setItemActive( cur );
  148. scrollToCur();
  149. }
  150. public function getSelY():Float
  151. {
  152. return sel.y;
  153. }
  154. // ---------------------------------------------------------------------------- private methods.
  155. private function addItemHelper( s:String )
  156. {
  157. var idx:Int = getLength();
  158. var item: HUGComboItem = new HUGComboItem( this, s, idx, w );
  159. item.y = idx * ITEM_H - 1;
  160. if ( idx == 0 )
  161. {
  162. cur = item;
  163. hl = item;
  164. setItemActive( item );
  165. }
  166. items.push( item );
  167. }
  168. private function upd()
  169. {
  170. drawBg();
  171. if ( getLength() > ITEMS_COUNT_TO_SCROLL )
  172. {
  173. sb.init( getLength() - ITEMS_COUNT_TO_SCROLL, ITEMS_COUNT_TO_SCROLL );
  174. sb.setScrollPosition(0);
  175. sb.visible = true;
  176. //if ( getLength() == 1 + ITEMS_COUNT_TO_SCROLL )
  177. //{
  178. //drawSel( w - W - 1 );
  179. //}
  180. } else
  181. reDraw();
  182. }
  183. private function scrollToCur()
  184. {
  185. if ( cur.y < 0 || cur.y >= ITEMS_COUNT_TO_SCROLL * ITEM_H - 1 )
  186. {
  187. sb.setScrollPosition(cur.idx - ITEMS_COUNT_TO_SCROLL / 3);
  188. reDraw();
  189. }
  190. }
  191. private function scrollToBounds( item:HUGComboItem )
  192. {
  193. if ( item.y < 0 )
  194. {
  195. sb.setScrollPosition(item.idx);
  196. } else
  197. if ( item.y >= ITEMS_COUNT_TO_SCROLL * ITEM_H - 1 )
  198. {
  199. sb.setScrollPosition(item.idx - ITEMS_COUNT_TO_SCROLL + 1);
  200. }
  201. reDraw();
  202. }
  203. private function maskRect():HUGSprite
  204. {
  205. var ss:HUGSprite = new HUGSprite();
  206. Utils.fillRect( ss, 0, 0, w + 1, ITEMS_COUNT_TO_SCROLL * ITEM_H + 1, 0 );
  207. addChild( ss );
  208. return ss;
  209. }
  210. private function drawBg()
  211. {
  212. graphics.clear();
  213. var h:Float = Math.min(getLength(), ITEMS_COUNT_TO_SCROLL) * ITEM_H - 1;
  214. Utils.rect( this, 0, 0, w, h, 0xffffff, 0xcccccc, (owner == null) ? 1 : 0.92 );
  215. if ( owner != null )
  216. {
  217. Utils.horLine( this, 0, w, 0, 0xadadad );
  218. Utils.horLine( this, 0, w, h, 0xadadad, 0.95 );
  219. Utils.horLine( this, 0, w, h + 1, 0xadadad, 0.5 );
  220. Utils.horLine( this, 0, w, h + 2, 0xadadad, 0.2 );
  221. }
  222. }
  223. //private function drawSel( ww:uint ):void
  224. //{
  225. // sel.graphics.clear();
  226. // Utils.rect( sel, 0, 1, ww, ITEM_H - 1, Utils.SEL_BG_COL, Utils.SEL_BG_BORDER_COL );
  227. //}
  228. private function reDraw()
  229. {
  230. //removeEventListener( MouseEvent.ROLL_OVER, onOver );
  231. //removeEventListener( MouseEvent.ROLL_OUT, onOut );
  232. clearLayout();
  233. var yy:UInt = -ITEM_H * Math.round( sb.getScrollPosition() );
  234. for (i in 0...items.length)
  235. {
  236. items[i].y = yy - 1;
  237. yy += ITEM_H;
  238. if ( items[i].y > -ITEM_H && items[i].y < height )
  239. {
  240. addChild( items[i] );
  241. items[i].mask = maskRect();
  242. }
  243. }
  244. setChildIndex( sb, numChildren - 1 );
  245. setItemActive( hl );
  246. //addEventListener( MouseEvent.ROLL_OVER, onOver );
  247. //addEventListener( MouseEvent.ROLL_OUT, onOut );
  248. }
  249. private function clearLayout()
  250. {
  251. while ( numChildren > 2 ) // the first two children are "sel" and "sel mask"
  252. removeChildAt( numChildren - 1 );
  253. addChild( sb );
  254. }
  255. private function mouseInside():Bool
  256. {
  257. return mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height;
  258. }
  259. // ----------------------------------------------------------------------- Event handlers
  260. private function onKeyDown( e:KeyboardEvent )
  261. {
  262. if ( owner != null )
  263. return;
  264. enMouse = false;
  265. if ( e.keyCode == 38 )
  266. {
  267. if ( getSelectedIndex() > 0 )
  268. {
  269. onItemClick( items[getSelectedIndex() - 1], false );
  270. scrollToBounds( cur );
  271. hl.graphics.clear();
  272. }
  273. } else
  274. if ( e.keyCode == 40 )
  275. {
  276. if ( getSelectedIndex() < getLength() - 1 )
  277. {
  278. onItemClick( items[getSelectedIndex() + 1], false );
  279. scrollToBounds( cur );
  280. hl.graphics.clear();
  281. }
  282. }
  283. addEventListener( MouseEvent.MOUSE_MOVE, helpListener );
  284. }
  285. public function onComboKeyDown( e:KeyboardEvent )
  286. {
  287. enMouse = false;
  288. if ( e.keyCode == 13 )
  289. {
  290. onItemClick( hl, true );
  291. } else
  292. if ( e.keyCode == 38 )
  293. {
  294. if ( hl.idx > 0 )
  295. {
  296. setItemActive( items[hl.idx - 1] );
  297. scrollToBounds( hl );
  298. }
  299. } else
  300. if ( e.keyCode == 40 )
  301. {
  302. if ( hl.idx < getLength() - 1 )
  303. {
  304. setItemActive( items[hl.idx + 1] );
  305. scrollToBounds( hl );
  306. }
  307. }
  308. addEventListener( MouseEvent.MOUSE_MOVE, helpListener );
  309. }
  310. private function helpListener(e: MouseEvent) {
  311. enMouse = true;
  312. }
  313. private function onOver( e:MouseEvent )
  314. {
  315. //Dbg.log( "onOver( " + mouseX + ", " + mouseY + " ), " + x + ", " + y + " - " + (x+width) + ", " + (y+height) + " hitTest " + mouseInside() );
  316. if ( e.target == this && owner == null )
  317. {
  318. MouseWheel.capture();
  319. }
  320. }
  321. private function onOut( e:MouseEvent )
  322. {
  323. //Dbg.log( "onOut( " + mouseX + ", " + mouseY + " ), " + x + ", " + y + " - " + (x+width) + ", " + (y+height) + " hitTest " + mouseInside() );
  324. if ( e.target == this && owner == null && !mouseInside() )
  325. {
  326. MouseWheel.release();
  327. }
  328. }
  329. private function onScroll( e:Event )
  330. {
  331. reDraw();
  332. }
  333. private function onWheel( e:MouseEvent )
  334. {
  335. enMouse = true;
  336. sb.setScrollPosition(sb.getScrollPosition() - e.delta);
  337. reDraw();
  338. }
  339. }