예제 #1
0
        //private void RemoveHandler(Event e)
        //{
        //    DisplayObject popup = e.Target as DisplayObject;
        //    if (null != popup)
        //    {
        //        popup.RemoveEventListener(MouseEvent.MOUSE_DOWN_OUTSIDE, RemoveHandler);
        //        popup.RemoveEventListener(MouseEvent.MOUSE_WHEEL_OUTSIDE, RemoveHandler);
        //        TerminatePopup(popup);
        //    }
        //    if (_popups.Count == 0 && SystemManager.Instance.HasEventListener(ResizeEvent.RESIZE))
        //        SystemManager.Instance.RemoveEventListener(ResizeEvent.RESIZE, RemoveHandler);
        //}

        //private static void TerminatePopup(DisplayObject popup)
        //{
        //    //Debug.Log("TerminatePopup");

        //    var dlm = popup as DisplayListMember;

        //    if (null != dlm)
        //    {
        //        Instance.RemovePopup(dlm);
        //        // TODO: SystemManager.Instance.RemoveEventListener(ResizeEvent.RESIZE, ...);
        //        dlm.Dispose();
        //    }
        //}

        #endregion

        #region Add

        /// <summary>
        /// Adds a popup to popup stage
        /// </summary>
        /// <param name="popup">A popup to add</param>
        /// <param name="options">Popup options</param>
        public void AddPopup(DisplayListMember popup, params PopupOption[] options)
        {
            Event e = new Event(OPENING, popup, false, true); // cancelable

            DispatchEvent(e);

            if (e.Canceled)
            {
                return;
            }

            if (IsDefaultPrevented(OPENING))
            {
                return;
            }

            if (_popups.Contains(popup))
            {
                return;
            }
#if DEBUG
            if (DebugMode)
            {
                Debug.Log("AddPopup");
            }
#endif

            DisplayObjectContainer parent = null;
            bool  modal      = true;
            bool  centered   = true;
            bool  keepCenter = false;
            bool  removeOnMouseDownOutside  = false;
            bool  removeOnMouseWheelOutside = false;
            bool  removeOnScreenResize      = false;
            bool  autoFocus           = true;
            bool  focusPreviousOnHide = true;
            Stage stage = _stage;

            bool visibleFlag = popup.Visible;
            popup.Visible = false;

            int len = options.Length;
            for (int i = 0; i < len; i++)
            {
                PopupOption option = options[i];
                switch (option.Type)
                {
                case PopupOptionType.Parent:
                    parent = (DisplayObjectContainer)option.Value;
                    break;

                case PopupOptionType.Modal:
                    modal = (bool)option.Value;
                    break;

                case PopupOptionType.Centered:
                    centered = (bool)option.Value;
                    break;

                case PopupOptionType.KeepCenter:
                    keepCenter = (bool)option.Value;
                    break;

                case PopupOptionType.RemoveOnMouseDownOutside:
                    removeOnMouseDownOutside = (bool)option.Value;
                    break;

                case PopupOptionType.RemoveOnMouseWheelOutside:
                    removeOnMouseWheelOutside = (bool)option.Value;
                    break;

                case PopupOptionType.RemoveOnScreenResize:
                    removeOnScreenResize = (bool)option.Value;
                    break;

                case PopupOptionType.AutoFocus:
                    autoFocus = (bool)option.Value;
                    break;

                case PopupOptionType.FocusPreviousOnHide:
                    focusPreviousOnHide = (bool)option.Value;
                    break;

                case PopupOptionType.Stage:
                    //Debug.Log("Exotic stage: " + option.Value);
                    stage = (Stage)option.Value;
                    break;

                default:
                    throw new Exception("Unknown option");
                }
            }

            _popups.Add(popup);

            if (null == parent)
            {
                parent = stage;
            }

            DisplayListMember overlay   = null;
            Group             popupRoot = null;

            InvalidationManagerClient imc = popup as InvalidationManagerClient;
            Component comp = popup as Component;
            if (null != comp)
            {
                comp.IsPopUp = true;
            }

            if (modal)
            {
                overlay = (DisplayListMember)Activator.CreateInstance(ModalOverlayType);
                overlay.AddEventListener(MouseEvent.MOUSE_DOWN, OnOverlayMouseDown);

                // we are packing both the overlay and the popup to into an aditional container
                popupRoot = new Group();
                stage.AddChild(popupRoot);

                // BUG BUG BUG! If we do _stage.AddChild(popupRoot); AFTER the children are added, we get a null exception
                // this is the major problem when adding children, started appearing since 10.1.2012
                // solved. This had to to with the creationcomplete method, which has to be run after the complete invalidation pass

                popupRoot.AddChild(overlay);
                popupRoot.AddChild(popup);

                // popup has been added to popup stage
                // invalidation methods have been called upon the addition
                // now we want to run measure (to validate dimensions)
                // because we want to center the popup
                // now, the absolute layout won't do it on his own
                //overlay.Bounds = (Rectangle)parent.Bounds.Clone();

                overlay.Width  = PopupManagerStage.Instance.Width;
                overlay.Height = PopupManagerStage.Instance.Height;

                /*var client = overlay as InvalidationManagerClient;
                 * if (client != null)
                 * {
                 *  /*var imc2 = client;
                 *  imc2.SetActualSize(
                 *      PopupManagerStage.Instance.Width,
                 *      PopupManagerStage.Instance.Height/*,
                 *      Math.Max(imc2.GetExplicitOrMeasuredWidth(), imc2.MinWidth),
                 *      Math.Max(imc2.GetExplicitOrMeasuredHeight(), imc2.MinHeight)#2#
                 *  );#1#
                 *  client.Width = PopupManagerStage.Instance.Width;
                 *  client.Height = PopupManagerStage.Instance.Height;
                 *  //imc2.InvalidateTransform();
                 * }
                 * else
                 * {
                 *  overlay.X = parent.X;
                 *  overlay.Y = parent.Y;
                 *  /*overlay.X = parent.X;
                 *  overlay.Y = parent.Y;#1#
                 * }*/
            }
            else
            {
                stage.AddChild(popup);
            }

            if (null != imc)
            {
                //InvalidationManager.Instance.ValidateClient(imc, true);
                imc.ValidateNow();
                //Debug.Log(string.Format("imc.Width:{0}, imc.Height:{1}", imc.Width, imc.Height));
                //Debug.Log(string.Format("imc.GetExplicitOrMeasuredWidth():{0}, imc.GetExplicitOrMeasuredHeight():{1}", imc.GetExplicitOrMeasuredWidth(), imc.GetExplicitOrMeasuredHeight()));
                //imc.SetActualSize(imc.GetExplicitOrMeasuredWidth(), imc.GetExplicitOrMeasuredHeight());

                imc.SetActualSize(
                    Math.Min(Math.Max(imc.GetExplicitOrMeasuredWidth(), imc.MinWidth), imc.MaxWidth),
                    Math.Min(Math.Max(imc.GetExplicitOrMeasuredHeight(), imc.MinHeight), imc.MaxHeight)
                    );
            }

            var descriptor = new PopupDescriptor(parent, overlay, popupRoot)
            {
                Popup      = popup,
                PopupRoot  = modal ? popupRoot : popup,
                Owner      = parent,
                Modal      = modal,
                Centered   = centered,
                KeepCenter = keepCenter,
                RemoveOnMouseDownOutside  = removeOnMouseDownOutside,
                RemoveOnMouseWheelOutside = removeOnMouseWheelOutside,
                RemoveOnScreenResize      = removeOnScreenResize,
                FocusPreviousOnHide       = focusPreviousOnHide,
                Stage = stage
            };

            _descriptors.Add(popup, descriptor);

            if (centered)
            {
                CenterPopUp(popup);
            }

            InteractiveComponent ic = popup as InteractiveComponent;
            if (autoFocus && null != ic)
            {
                ic.SetFocus(); // TEMP disabled, 2.1.2012.
                //FocusManager.Instance.SetFocus(ic);

                /*ic.Defer(delegate
                 * {
                 *  //ic.SetFocus();
                 *  FocusManager.Instance.SetFocus(ic);
                 * }, 1);*/
            }


            // connect if not connected
            if (_descriptors.Count > 0)
            {
                SystemManager.Instance.ResizeSignal.Connect(ResizeSlot);
                SystemManager.Instance.MouseDownSignal.Connect(MouseDownSlot);
                SystemManager.Instance.RightMouseDownSignal.Connect(MouseDownSlot);
                SystemManager.Instance.MiddleMouseDownSignal.Connect(MouseDownSlot);
                SystemManager.Instance.MouseWheelSignal.Connect(MouseWheelSlot);

                // subscribe to stage to see if some component has been mouse-downed
                // NOTE: some components (i.e. window close button) could cancel the event, this is by design

                // note: it is safe ta call it multiple times, it is checked internally
                stage.AddEventListener(MouseEvent.MOUSE_DOWN, MouseDownHandler);
            }
            else
            {
                SystemManager.Instance.ResizeSignal.Disconnect(ResizeSlot);
                SystemManager.Instance.MouseDownSignal.Disconnect(MouseDownSlot);
                SystemManager.Instance.RightMouseDownSignal.Disconnect(MouseDownSlot);
                SystemManager.Instance.MiddleMouseDownSignal.Disconnect(MouseDownSlot);
                SystemManager.Instance.MouseWheelSignal.Disconnect(MouseWheelSlot);

                //MouseEventDispatcher.Instance.RemoveEventListener(MouseEvent.MOUSE_DOWN, MouseDownHandler);
                stage.RemoveEventListener(MouseEvent.MOUSE_DOWN, MouseDownHandler);
            }

            // NOTE: This is needed when having effects because of the flicker (?):
            //descriptor.PopupRoot.SkipRender(100);

            // bring the popup root to front
            descriptor.PopupRoot.BringToFront();

            popup.Visible = visibleFlag;

            DispatchEvent(new Event(OPEN, popup));
        }