[1240] | 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 | }
|
---|