1 | /**
|
---|
2 | * Autoscroll screen if component to be focused is offscreen to make it visible.
|
---|
3 | * created by: jtorreno 2008.05.08
|
---|
4 | */
|
---|
5 |
|
---|
6 | package gov.va.med.edp.util
|
---|
7 | {
|
---|
8 | import flash.display.DisplayObjectContainer;
|
---|
9 | import flash.display.InteractiveObject;
|
---|
10 | import flash.events.FocusEvent;
|
---|
11 | import flash.geom.Point;
|
---|
12 | import flash.geom.Rectangle;
|
---|
13 |
|
---|
14 | import mx.core.Container;
|
---|
15 | import mx.core.EdgeMetrics;
|
---|
16 | import mx.managers.IFocusManager;
|
---|
17 |
|
---|
18 | [Bindable]
|
---|
19 | public class AutoScrollView
|
---|
20 | {
|
---|
21 |
|
---|
22 | private static var focusMgr:IFocusManager;
|
---|
23 |
|
---|
24 | /**
|
---|
25 | * Function: setupFocusViewportWatcher()
|
---|
26 | * Parameters:
|
---|
27 | * dispObj:DisplayObjectContainer - focused object container
|
---|
28 | * focusManager:IFocusManager - Focus manager
|
---|
29 | * Description:
|
---|
30 | * Set up the event listener for the focusIn event
|
---|
31 | * Date: 2008.05.08
|
---|
32 | *
|
---|
33 | **/
|
---|
34 | public static function setupFocusViewportWatcher(
|
---|
35 | dispObj:DisplayObjectContainer, focusManager:IFocusManager):void {
|
---|
36 |
|
---|
37 | focusMgr = focusManager;
|
---|
38 | dispObj.addEventListener("focusIn", makeFocusedItemVisible);
|
---|
39 | }
|
---|
40 |
|
---|
41 | /**
|
---|
42 | * Function: makeFocusedItemVisible()
|
---|
43 | * Parameters:
|
---|
44 | * event:FocusEvent get focus event
|
---|
45 | * Description:
|
---|
46 | * Set up the event listener for the focusIn event
|
---|
47 | * Date: 2008.05.08
|
---|
48 | *
|
---|
49 | **/
|
---|
50 | private static function makeFocusedItemVisible(event:FocusEvent):void {
|
---|
51 | // Target is the actual object that has focus.
|
---|
52 | var target:InteractiveObject = null;
|
---|
53 | // OriginalTarget is the component that has focus as some
|
---|
54 | // component actually delegate true focus to an internal object.
|
---|
55 | var originalTarget:InteractiveObject = null;
|
---|
56 |
|
---|
57 | if ((event != null) && (event.target != null)) {
|
---|
58 |
|
---|
59 | target = InteractiveObject(event.target);
|
---|
60 | originalTarget = InteractiveObject(focusMgr.findFocusManagerComponent(target));
|
---|
61 |
|
---|
62 | // The viewable portion of a container
|
---|
63 | var viewport:Rectangle = new Rectangle();
|
---|
64 |
|
---|
65 | if ((target != null) && (originalTarget != null)) {
|
---|
66 | do {
|
---|
67 | // Cycle through all parents looking for containers.
|
---|
68 | if ((target.parent is Container) && (target.parent != null)) {
|
---|
69 | var viewportChanged:Boolean = false;
|
---|
70 | var c:Container = target.parent as Container;
|
---|
71 |
|
---|
72 | // Get the viewable area in the container.
|
---|
73 | var vm:EdgeMetrics = c.viewMetrics;
|
---|
74 | viewport.x = vm.left;
|
---|
75 | viewport.y = vm.top;
|
---|
76 | viewport.width =
|
---|
77 | c.width / c.scaleX - vm.left - vm.right;
|
---|
78 | viewport.height =
|
---|
79 | c.height / c.scaleY - vm.top - vm.bottom;
|
---|
80 |
|
---|
81 | // Calculate the position of the target in the container.
|
---|
82 | var topLeft:Point = new Point(0, 0);
|
---|
83 | var bottomRight:Point =
|
---|
84 | new Point(originalTarget.width, originalTarget.height);
|
---|
85 | topLeft = originalTarget.localToGlobal(topLeft);
|
---|
86 | topLeft = c.globalToLocal(topLeft);
|
---|
87 | bottomRight = originalTarget.localToGlobal(bottomRight);
|
---|
88 | bottomRight = c.globalToLocal(bottomRight);
|
---|
89 |
|
---|
90 | // Figure out if we have to move the scroll bars.
|
---|
91 | // If the scroll bar moves, the position of the component
|
---|
92 | // moves as well. This algorithm makes sure the top
|
---|
93 | // left of the component is visible if the component is
|
---|
94 | // bigger than the viewport.
|
---|
95 | var delta:Number;
|
---|
96 |
|
---|
97 | if (bottomRight.x > viewport.right) {
|
---|
98 | delta = bottomRight.x - viewport.right;
|
---|
99 | c.horizontalScrollPosition += delta;
|
---|
100 | topLeft.x -= delta;
|
---|
101 | viewportChanged = true;
|
---|
102 | }
|
---|
103 |
|
---|
104 | if (topLeft.x < viewport.left) {
|
---|
105 | // leave it a few pixels in from the left
|
---|
106 | c.horizontalScrollPosition -=
|
---|
107 | viewport.left - topLeft.x + 2;
|
---|
108 | viewportChanged = true;
|
---|
109 | }
|
---|
110 |
|
---|
111 | if (bottomRight.y > viewport.bottom) {
|
---|
112 | delta = bottomRight.y - viewport.bottom;
|
---|
113 | c.verticalScrollPosition += delta;
|
---|
114 | topLeft.y -= delta;
|
---|
115 | viewportChanged = true;
|
---|
116 | }
|
---|
117 |
|
---|
118 | if (topLeft.y < viewport.top) {
|
---|
119 | // leave it a few pixels down from the top
|
---|
120 | c.verticalScrollPosition -=
|
---|
121 | viewport.top - topLeft.y + 2;
|
---|
122 | viewportChanged = true;
|
---|
123 | }
|
---|
124 |
|
---|
125 | // You must the validateNow() method to get the
|
---|
126 | // container to move the component before working
|
---|
127 | // on the next parent.
|
---|
128 | // Otherwise, your calculations will be incorrect.
|
---|
129 | if (viewportChanged) {
|
---|
130 | c.validateNow();
|
---|
131 | }
|
---|
132 | }
|
---|
133 |
|
---|
134 | target = target.parent;
|
---|
135 |
|
---|
136 | } while ((target != originalTarget) && (target.parent != null)
|
---|
137 | && (target.parent as Container));
|
---|
138 | }
|
---|
139 | }
|
---|
140 | }
|
---|
141 | }
|
---|
142 | }
|
---|