注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

神魔破杜梓的叨叨堂

Programming every day!

 
 
 

日志

 
 
 
 

AutoScrollManager Class: 当鼠标左键被按下,在某一区域内移动时,让滚动条自动滚动  

2008-08-01 09:17:41|  分类: My Tech |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
原文来自ntt.cc
Problem Summary: In a flex project, I need to insert an object to a object list which is derived from Container component. However, the list has fixed width and height, and the items of the list are too many to display one-time. So i have to scroll the list to the proper position then drag the object from a panel and insert it. I need a convenient way to complete this. I worte an AutoScrollManager utility to help myself.

Solution Summary: I add an event listener to the stage object of container’s systemManager object. It’s used to find the proper Container during the run-time because the container cannot trigger the MouseMove event while I am dragging the object from the panel. It is covered by what I am dragging. I have to find the proper container according to the Mouse coordinates. The function findContainer helps me a lot. Despite of this big problem, there is nothing hard to deal with.

Demo(DownloadDownload Full Project):

Press the left button of your mouse and do not release it. Move your mouse pointer inside the panel arbitrary. When the pointer moves around the texts, the scroll-bars scroll automatically.

Description: The AutoScrollManager provide two static functions to enable or disable auto-scrolling, addAutoScroll and removeAutoScroll, you should pass the target Container component to these functions. With the addAutoScroll function, there are another two parameters: scrollSpeed and bound. scrollSpeed determine the speed the scroll-bars scrolling. The bound is based on the model below:

clip_image002

viewMetrics is defined by the container self. Detailed info you will find in the flex SDK document.

* Returns an object that has four properties: <code>left</code>,

* <code>top</code>, <code>right</code>, and <code>bottom</code>.

* The value of each property equals the thickness of the chrome

* (visual elements) around the edge of the container.

Scroll bars appear when they are required.

Bound is defined by user. It is used to specify a particular area where the scroll bars scrolling automatically while the mouse is moving in it.

In this AutoScrollManger class , when the mouse is moving in the area of viewMetrics or Bound, the scroll bars scroll.

Codes:

  1. <?xml version=”1.0encoding=”utf-8?>
  2.  
  3. <mx:Application
  4.  
  5. xmlns:mx=”http://www.adobe.com/2006/mxml
  6.  
  7. layout=”absolute
  8.  
  9. xmlns:local=”*”
  10.  
  11. height=”200
  12.  
  13. width=”200
  14.  
  15. creationComplete=”initApp();”>
  16.  
  17. <mx:XML id=”myDataxmlns="">
  18.  
  19. <root>
  20.  
  21. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  22.  
  23. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  24.  
  25. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  26.  
  27. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  28.  
  29. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  30.  
  31. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  32.  
  33. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  34.  
  35. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  36.  
  37. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  38.  
  39. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  40.  
  41. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  42.  
  43. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  44.  
  45. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  46.  
  47. <item name=”asdfghjklasdfghjklasdfghjklasdfghjklasdfghjklasdfghjkl/>
  48.  
  49. </root>
  50.  
  51. </mx:XML>
  52.  
  53. <mx:Script>
  54.  
  55. <![CDATA[
  56.  
  57. private function initApp():void
  58.  
  59. {
  60.  
  61. AutoScrollingManager.addAutoScroll(myPan);
  62.  
  63. }
  64.  
  65. ]]>
  66.  
  67. </mx:Script>
  68.  
  69. <mx:Panel id=”myPanwidth=”{application.width}” height=”{application.height}”>
  70.  
  71. <mx:VBox width=”100%” height=”100%”>
  72.  
  73. <mx:Repeater id=”myRepdataProvider=”{myData.item}”>
  74.  
  75. <mx:Label text=”{myRep.currentItem.@name}”/>
  76.  
  77. </mx:Repeater>
  78.  
  79. </mx:VBox>
  80.  
  81. </mx:Panel>
  82.  
  83. </mx:Application>

Following is AutoScrollManager Class:

  1. import flash.display.Stage;
  2. import flash.events.Event;
  3. import flash.events.MouseEvent;
  4. import flash.geom.Point;
  5. import flash.utils.Dictionary;
  6. import mx.core.Container;
  7. import mx.core.EdgeMetrics;
  8.  
  9. public class AutoScrollingManager
  10. {
  11.  
  12. private static var managers:Dictionary = new Dictionary();
  13.  
  14. public var scrollSpeed:int = 10;
  15.  
  16. public var scrollFunction:Function = horizontalScroll;
  17.  
  18. private var _bound:EdgeMetrics;
  19.  
  20. public var bound:EdgeMetrics = new EdgeMetrics(20,20,20,20);
  21.  
  22. public static function addAutoScroll(container:Container,scrollSpeed:int = 10,bound:EdgeMetrics = null):void
  23. {
  24.  
  25. var manager:AutoScrollingManager = new AutoScrollingManager();
  26.  
  27. manager.scrollSpeed = scrollSpeed;
  28.  
  29. if(bound)manager.bound = bound;
  30.  
  31. managers[container] = manager;
  32.  
  33. container.systemManager.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
  34.  
  35. container.systemManager.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
  36.  
  37. }
  38.  
  39. public static function removeAutoScroll(container:Container):void
  40. {
  41.  
  42. container.systemManager.removeEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
  43.  
  44. container.systemManager.removeEventListener(MouseEvent.MOUSE_UP,onMouseUp);
  45.  
  46. if(managers[container])
  47. {
  48.  
  49. container.systemManager.removeEventListener(Event.ENTER_FRAME,managers[container].scrollFunction);
  50.  
  51. managers[container] = null;
  52.  
  53. }
  54.  
  55. }
  56.  
  57. private static function onMouseMove(event:MouseEvent):void
  58. {
  59.  
  60. var pt:Point = new Point(event.localX,event.localY);
  61.  
  62. var container:Container = findContainer(pt,event.currentTarget.stage);
  63.  
  64. if(!container)
  65.  
  66. return;
  67.  
  68. var manager:AutoScrollingManager = managers[container];
  69.  
  70. if(!event.buttonDown)
  71. {
  72.  
  73. container.systemManager.removeEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  74.  
  75. return;
  76.  
  77. }
  78.  
  79. var vm:EdgeMetrics = container.viewMetrics;
  80.  
  81. var _bound:EdgeMetrics = new EdgeMetrics();
  82.  
  83. _bound.bottom = manager.bound.bottom;
  84.  
  85. _bound.left = manager.bound.left;
  86.  
  87. _bound.right = manager.bound.right;
  88.  
  89. _bound.top = manager.bound.top;
  90.  
  91. if(container.horizontalScrollBar)_bound.bottom += container.horizontalScrollBar.height;
  92.  
  93. if(container.verticalScrollBar)_bound.right += container.verticalScrollBar.width;
  94.  
  95. if(vm.bottom!=0) _bound.bottom += vm.bottom;
  96.  
  97. if(vm.left!=0) _bound.left += vm.left;
  98.  
  99. if(vm.right!=0) _bound.right += vm.right;
  100.  
  101. if(vm.top!=0) _bound.top += vm.top;
  102.  
  103. pt = event.target.localToGlobal(pt);
  104. pt = container.globalToLocal(pt);
  105.  
  106. var insideLeftTopCorner:Boolean;
  107. var insideLeftBottomCorner:Boolean ;
  108. var insideRightTopCorner:Boolean;
  109. var insideRightBottomCorner:Boolean ;
  110.  
  111. insideLeftTopCorner = pt.x < _bound.left && pt.y < _bound.top;
  112. insideLeftBottomCorner = pt.x < _bound.left && pt.y > container.height - _bound.bottom;
  113. insideRightTopCorner = pt.x > container.width - _bound.right && pt.y < _bound.top;
  114.  
  115. insideRightBottomCorner = pt.x > container.width - _bound.right&& pt.y > container.height - _bound.bottom;
  116.  
  117. if(insideLeftTopCorner||insideLeftBottomCorner||insideRightTopCorner||insideRightBottomCorner)
  118. {
  119.  
  120. container.systemManager.removeEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  121.  
  122. return;
  123.  
  124. }
  125.  
  126. if(container.horizontalScrollBar)
  127. {
  128.  
  129. if(pt.y > container.height - container.horizontalScrollBar.height - vm.bottom)
  130. {
  131. return;
  132. }
  133.  
  134. manager.scrollFunction = horizontalScroll;
  135.  
  136. if(pt.x < _bound.left)
  137. {
  138. if( container.horizontalScrollPosition!=0)
  139. {
  140. container.systemManager.removeEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  141. container.systemManager.addEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  142. manager.scrollSpeed = Math.abs(manager.scrollSpeed)*-1;
  143. }
  144. }
  145. else if((pt.x > container.width-_bound.right && pt.x < container.width - (container.verticalScrollBar?container.verticalScrollBar.width:0) - vm.right) || pt.x > container.width - vm.right)
  146. {
  147. if(container.horizontalScrollPosition!=container.maxHorizontalScrollPosition)
  148. {
  149. container.systemManager.removeEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  150. container.systemManager.addEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  151. manager.scrollSpeed = Math.abs(manager.scrollSpeed);
  152. }
  153.  
  154. }
  155. else
  156. {
  157. container.systemManager.removeEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  158. }
  159.  
  160. }
  161.  
  162. if(container.verticalScrollBar)
  163. {
  164. if(pt.x > container.width - container.verticalScrollBar.width - vm.right)
  165. {
  166. return;
  167. }
  168.  
  169. manager.scrollFunction = verticalScroll;
  170.  
  171. if(pt.y < _bound.top)
  172. {
  173. if(container.verticalScrollPosition!=0)
  174. {
  175. container.systemManager.removeEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  176. container.systemManager.addEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  177. manager.scrollSpeed = Math.abs(manager.scrollSpeed)*-1;
  178. }
  179. }
  180.  
  181. else if((pt.y > container.height - _bound.bottom && pt.y < container.height - (container.horizontalScrollBar?container.horizontalScrollBar.height:0) - vm.bottom) || pt.y > container.height - vm.bottom)
  182. {
  183. if(container.verticalScrollPosition!=container.maxVerticalScrollPosition)
  184. {
  185. container.systemManager.removeEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  186. container.systemManager.addEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  187. manager.scrollSpeed = Math.abs(manager.scrollSpeed);
  188. }
  189. }
  190. else
  191. {
  192. container.systemManager.removeEventListener(Event.ENTER_FRAME,manager.scrollFunction);
  193. }
  194. }
  195. }
  196.  
  197. private static function onMouseUp(event:MouseEvent):void
  198. {
  199. event.currentTarget.removeEventListener(Event.ENTER_FRAME,horizontalScroll);
  200. event.currentTarget.removeEventListener(Event.ENTER_FRAME,verticalScroll);
  201. }
  202.  
  203. private static function horizontalScroll(event:Event):void
  204. {
  205. var pt:Point = new Point(event.currentTarget.stage.mouseX,event.currentTarget.stage.mouseY);
  206. var container:Container = findContainer(pt,event.currentTarget.stage);
  207.  
  208. if(!container)
  209. return;
  210.  
  211. container.horizontalScrollPosition += managers[container].scrollSpeed;
  212. }
  213.  
  214. private static function verticalScroll(event:Event):void
  215. {
  216. var pt:Point = new Point(event.currentTarget.stage.mouseX,event.currentTarget.stage.mouseY);
  217. var container:Container = findContainer(pt,event.currentTarget.stage);
  218.  
  219. if(!container)
  220. return;
  221.  
  222. container.verticalScrollPosition += managers[container].scrollSpeed;
  223. }
  224.  
  225. private static function findContainer(pt:Point,stage:Stage):Container
  226. {
  227. var objects:Array = stage.getObjectsUnderPoint(pt);
  228.  
  229. for each(var object:Object in objects)
  230. {
  231. var result:Object = doFind(object);
  232.  
  233. if(result!=null)
  234. {
  235. return Container(result);
  236. }
  237. }
  238. return null;
  239. }
  240.  
  241. private static function doFind(object:Object):Container
  242. {
  243. if(object.parent && object.parent is Container)
  244. {
  245. if(managers[object.parent] != null)
  246. {
  247. return object.parent;
  248. }
  249. else
  250. {
  251. return doFind(object.parent);
  252. }
  253. }
  254. return null;
  255. }
  256. }

 
  评论这张
 
阅读(575)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017