static void ForEachEventListenerBubbleUp <T>(T e, HitChain hitPointChain, EventListenerAction <T> listenerAction)
            where T : UIEventArgs
        {
            HitInfo hitInfo;

            for (int i = hitPointChain.Count - 1; i >= 0; --i)
            {
                hitInfo = hitPointChain.GetHitInfo(i);
                if (hitInfo.HitElemAsRenderElement.GetController() is IUIEventListener listener)
                {
                    if (e.SourceHitElement == null)
                    {
                        e.SetSourceHitObject(listener);
                    }

                    Point p = hitInfo.point;
                    e.SetLocation(p.X, p.Y);
                    e.SetCurrentContextElement(listener);
                    if (listenerAction(e, listener))
                    {
                        return;
                    }
                }
            }
        }
예제 #2
0
        static void ForEachEventListenerBubbleUp(UIEventArgs e, HitChain hitPointChain, EventListenerAction listenerAction)
        {
            HitInfo hitInfo;

            for (int i = hitPointChain.Count - 1; i >= 0; --i)
            {
                hitInfo = hitPointChain.GetHitInfo(i);
                IUIEventListener listener = hitInfo.hitElement.GetController() as IUIEventListener;
                if (listener != null)
                {
                    if (e.SourceHitElement == null)
                    {
                        e.SourceHitElement = listener;
                    }

                    var hitPoint = hitInfo.point;
                    e.SetLocation(hitPoint.X, hitPoint.Y);
                    e.CurrentContextElement = listener;
                    if (listenerAction(listener))
                    {
                        return;
                    }
                }
            }
        }
예제 #3
0
        static void SetEventOrigin(UIEventArgs e, HitChain hitChain)
        {
            int count = hitChain.Count;

            if (count > 0)
            {
                var hitInfo = hitChain.GetHitInfo(count - 1);
                e.ExactHitObject = hitInfo.hitElement;
            }
        }
예제 #4
0
        static RenderElement HitTestOnPreviousChain(HitChain hitPointChain, HitChain previousChain, int x, int y)
        {
#if DEBUG
            if (hitPointChain == previousChain)
            {
                throw new NotSupportedException();
            }
#endif

            if (previousChain.Count > 0)
            {
                previousChain.SetStartTestPoint(x, y);
                //test on prev chain top to bottom
                int j = previousChain.Count;

                for (int i = 0; i < j; ++i)
                {
                    HitInfo       hitInfo = previousChain.GetHitInfo(i);
                    RenderElement elem    = hitInfo.hitElement;
                    if (elem != null && elem.VisibleAndHasParent)
                    {
                        if (elem.Contains(hitInfo.point))
                        {
                            RenderElement found = elem.FindUnderlyingSiblingAtPoint(hitInfo.point);
                            if (found == null)
                            {
                                Point leftTop = elem.Location;
                                hitPointChain.OffsetTestPoint(leftTop.X, leftTop.Y);
                                hitPointChain.AddHitObject(elem);
                                //add to chain
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            //---------------------------------
            if (hitPointChain.Count > 0)
            {
                var commonElement = hitPointChain.GetHitInfo(hitPointChain.Count - 1).hitElement;
                hitPointChain.RemoveCurrentHit();
                return(commonElement);
            }
            else
            {
                return(null);
            }
        }
        static void SetEventOrigin(UIEventArgs e, HitChain hitChain)
        {
            int count = hitChain.Count;

            if (count > 0)
            {
                e.SetExactHitObject(hitChain.GetHitInfo(count - 1).HitElemAsRenderElement);
            }
            else
            {
                e.SetExactHitObject(null);
            }
        }
 static void ForEachOnlyEventPortalBubbleUp <T>(T e, HitChain hitPointChain, EventPortalAction <T> eventPortalAction)
     where T : UIEventArgs
 {
     for (int i = hitPointChain.Count - 1; i >= 0; --i)
     {
         HitInfo hitPoint      = hitPointChain.GetHitInfo(i);
         object  currentHitObj = hitPoint.HitElemAsRenderElement.GetController();
         if (currentHitObj is IEventPortal eventPortal)
         {
             Point p = hitPoint.point;
             e.SetCurrentContextElement(currentHitObj as IUIEventListener);
             e.SetLocation(p.X, p.Y);
             if (eventPortalAction(e, eventPortal))
             {
                 return;
             }
         }
     }
 }
예제 #7
0
 static void ForEachOnlyEventPortalBubbleUp(UIEventArgs e, HitChain hitPointChain, EventPortalAction eventPortalAction)
 {
     for (int i = hitPointChain.Count - 1; i >= 0; --i)
     {
         HitInfo      hitPoint          = hitPointChain.GetHitInfo(i);
         object       currentHitElement = hitPoint.hitElement.GetController();
         IEventPortal eventPortal       = currentHitElement as IEventPortal;
         if (eventPortal != null)
         {
             var ppp = hitPoint.point;
             e.CurrentContextElement = currentHitElement as IUIEventListener;
             e.SetLocation(ppp.X, ppp.Y);
             if (eventPortalAction(eventPortal))
             {
                 return;
             }
         }
     }
 }
        //        static RenderElement HitTestOnPreviousChain(HitChain hitPointChain, HitChain previousChain, int x, int y)
        //        {
        //#if DEBUG
        //            if (hitPointChain == previousChain)
        //            {
        //                throw new NotSupportedException();
        //            }
        //#endif

        //            if (previousChain.Count > 0)
        //            {
        //                previousChain.SetStartTestPoint(x, y);
        //                //test on prev chain top to bottom
        //                int j = previousChain.Count;
        //                for (int i = 0; i < j; ++i)
        //                {
        //                    HitInfo hitInfo = previousChain.GetHitInfo(i);
        //                    RenderElement elem = hitInfo.HitElemAsRenderElement;
        //                    if (elem != null && elem.VisibleAndHasParent)
        //                    {
        //                        if (elem.Contains(hitInfo.point))
        //                        {
        //                            RenderElement found = elem.FindUnderlyingSiblingAtPoint(hitInfo.point);
        //                            if (found == null)
        //                            {
        //                                Point leftTop = elem.Location;
        //                                hitPointChain.OffsetTestPoint(leftTop.X, leftTop.Y);
        //                                hitPointChain.AddHitObject(elem);
        //                                //add to chain
        //                            }
        //                            else
        //                            {
        //                                break;
        //                            }
        //                        }
        //                    }
        //                    else
        //                    {
        //                        break;
        //                    }
        //                }
        //            }
        //            //---------------------------------
        //            if (hitPointChain.Count > 0)
        //            {
        //                var commonElement = hitPointChain.GetHitInfo(hitPointChain.Count - 1).HitElemAsRenderElement;
        //                hitPointChain.RemoveCurrentHit();
        //                return commonElement;
        //            }
        //            else
        //            {
        //                return null;
        //            }
        //        }


        void HitTestCoreWithPrevChainHint(HitChain hitChain, HitChain previousChain, int x, int y)
        {
            //---------------------------------
            //test on previous chain first , find common element
            hitChain.Reset();
            hitChain.SetStartTestPoint(x, y);
#if DEBUG
            hitChain.dbugHitPhase = _dbugHitChainPhase;
#endif
            //if (this.dbugId > 0 && isDragging && previousChain.Count > 1)
            //{

            //}

            //RenderElement commonElement = HitTestOnPreviousChain(hitPointChain, previousChain, x, y);

            //temp fix
            //TODO: fix bug on HitTestOnPreviousChain()
            RenderElement commonElement = _topRenderElement;
            commonElement.HitTestCore(hitChain);

            //remove disable elements
            //if (hitPointChain.dbugHitPhase == dbugHitChainPhase.MouseDown)
            //{
            int j = hitChain.Count;
            for (int i = 0; i < j; ++i)
            {
                HitInfo       info    = hitChain.GetHitInfo(i);
                RenderElement renderE = info.HitElemAsRenderElement;
                if (renderE != null && renderE.GetController() is IUIEventListener ui && !ui.Enabled)
                {
                    HitChain.UnsafeClear(hitChain);
                    break;//stop loop and exit
                }
            }
            //}
        }
        void IEventPortal.PortalMouseDown(UIMouseDownEventArgs e)
        {
#if DEBUG
            if (this.dbugRootGraphics != null && this.dbugRootGraphics.dbugEnableGraphicInvalidateTrace)
            {
                this.dbugRootGraphics.dbugGraphicInvalidateTracer.WriteInfo("================");
                this.dbugRootGraphics.dbugGraphicInvalidateTracer.WriteInfo("MOUSEDOWN");
                this.dbugRootGraphics.dbugGraphicInvalidateTracer.WriteInfo("================");
            }
            dbugMsgChainVersion = 1;
            int local_msgVersion = 1;
#endif
            HitChain hitPointChain = GetFreeHitChain();
#if DEBUG
            _dbugHitChainPhase = dbugHitChainPhase.MouseDown;
#endif
            HitTestCoreWithPrevChainHint(hitPointChain, _previousChain, e.X, e.Y);

            if (hitPointChain.Count > 0)
            {
                //------------------------------
                //1. origin object
                SetEventOrigin(e, hitPointChain);
                //------------------------------

                _currentMouseDown = null;
                //portal
                ForEachOnlyEventPortalBubbleUp(e, hitPointChain, (e1, portal) =>
                {
                    //please ensure=> no local var/pararmeter capture inside lambda
                    portal.PortalMouseDown(e1);
                    //*****
                    _currentMouseDown = e1.CurrentContextElement;
                    return(true);
                });
                //------------------------------
                //use events
                if (!e.CancelBubbling)
                {
                    _currentMouseDown = null; //clear
                    e.SetCurrentContextElement(null);

                    ForEachEventListenerBubbleUp(e, hitPointChain, (e1, listener) =>
                    {
                        //please ensure=> no local var/pararmeter capture inside lambda
                        if (listener.BypassAllMouseEvents)
                        {
                            return(false);
                        }
                        _currentMouseDown = listener;

                        listener.ListenMouseDown(e1);

                        //-------------------------------------------------------
                        //auto begin monitor mouse press
                        _mousePressMonitor.AddMousePressInformation(e1);
                        _mousePressMonitor.SetMonitoredElement(listener);
                        //-------------------------------------------------------
                        bool cancelMouseBubbling = e1.CancelBubbling;
                        if (_prevMouseDownElement != null &&
                            _prevMouseDownElement != listener)
                        {
                            _prevMouseDownElement.ListenLostMouseFocus(_mouseLostFocusArgs);
                            _prevMouseDownElement = null;//clear
                        }
                        //-------------------------------------------------------
                        //retrun true to stop this loop (no further bubble up)
                        //return false to bubble this to upper control
                        return(e1.CancelBubbling || !listener.BypassAllMouseEvents);
                    });

                    if (_currentMouseDown == null)
                    {
                        _mousePressMonitor.Reset();
                    }
                }

                if (_prevMouseDownElement != _currentMouseDown &&
                    _prevMouseDownElement != null)
                {
                    //TODO: review here, auto or manual
                    _prevMouseDownElement.ListenLostMouseFocus(_mouseLostFocusArgs);
                    _prevMouseDownElement = null;
                }
            }
            //---------------------------------------------------------------

#if DEBUG
            RootGraphic dbug_visualroot = this.dbugRootGraphics;
            if (dbug_visualroot != null && dbug_visualroot.dbug_RecordHitChain)
            {
                dbug_visualroot.dbug_rootHitChainMsg.Clear();
                HitInfo hitInfo;
                for (int tt = hitPointChain.Count - 1; tt >= 0; --tt)
                {
                    hitInfo = hitPointChain.GetHitInfo(tt);
                    RenderElement ve = hitInfo.HitElemAsRenderElement;
                    if (ve != null)
                    {
                        ve.dbug_WriteOwnerLayerInfo(dbug_visualroot, tt);
                        ve.dbug_WriteOwnerLineInfo(dbug_visualroot, tt);
                        string hit_info = new string('.', tt) + " [" + tt + "] "
                                          + "(" + hitInfo.point.X + "," + hitInfo.point.Y + ") "
                                          + ve.dbug_FullElementDescription();
                        dbug_visualroot.dbug_rootHitChainMsg.AddLast(new dbugLayoutMsg(ve, hit_info));
                    }
                }
            }
#endif

            SwapHitChain(hitPointChain);

            e.StopPropagation(); //TODO: review this again
#if DEBUG
            if (local_msgVersion != dbugMsgChainVersion)
            {
                return;
            }
            dbug_visualroot.dbugHitTracker.Write("stop-mousedown");
            dbug_visualroot.dbugHitTracker.Play = false;
#endif
        }
예제 #10
0
        void IEventPortal.PortalMouseDown(UIMouseEventArgs e)
        {
#if DEBUG
            if (this.dbugRootGraphics.dbugEnableGraphicInvalidateTrace)
            {
                this.dbugRootGraphics.dbugGraphicInvalidateTracer.WriteInfo("================");
                this.dbugRootGraphics.dbugGraphicInvalidateTracer.WriteInfo("MOUSEDOWN");
                this.dbugRootGraphics.dbugGraphicInvalidateTracer.WriteInfo("================");
            }
            dbugMsgChainVersion = 1;
            int local_msgVersion = 1;
#endif


            HitChain hitPointChain = GetFreeHitChain();
            HitTestCoreWithPrevChainHint(hitPointChain, this._previousChain, e.X, e.Y);
            int           hitCount   = hitPointChain.Count;
            RenderElement hitElement = hitPointChain.TopMostElement;
            if (hitCount > 0)
            {
                //------------------------------
                //1. origin object
                SetEventOrigin(e, hitPointChain);
                //------------------------------
                var prevMouseDownElement          = e.PreviousMouseDown;
                IUIEventListener currentMouseDown = null;
                //portal
                ForEachOnlyEventPortalBubbleUp(e, hitPointChain, (portal) =>
                {
                    portal.PortalMouseDown(e);
                    //*****
                    currentMouseDown = e.CurrentContextElement;
                    return(true);
                });
                //------------------------------
                //use events
                if (!e.CancelBubbling)
                {
                    e.CurrentContextElement = currentMouseDown = null; //clear
                    ForEachEventListenerBubbleUp(e, hitPointChain, (listener) =>
                    {
                        currentMouseDown = listener;
                        listener.ListenMouseDown(e);
                        //-------------------------------------------------------
                        bool cancelMouseBubbling = e.CancelBubbling;
                        if (prevMouseDownElement != null &&
                            prevMouseDownElement != listener)
                        {
                            prevMouseDownElement.ListenLostMouseFocus(e);
                            prevMouseDownElement = null;//clear
                        }
                        //-------------------------------------------------------
                        return(e.CancelBubbling || !listener.BypassAllMouseEvents);
                    });
                }

                if (prevMouseDownElement != currentMouseDown &&
                    prevMouseDownElement != null)
                {
                    prevMouseDownElement.ListenLostMouseFocus(e);
                    prevMouseDownElement = null;
                }
            }
            //---------------------------------------------------------------

#if DEBUG
            RootGraphic visualroot = this.dbugRootGraphics;
            if (visualroot.dbug_RecordHitChain)
            {
                visualroot.dbug_rootHitChainMsg.Clear();
                HitInfo hitInfo;
                for (int tt = hitPointChain.Count - 1; tt >= 0; --tt)
                {
                    hitInfo = hitPointChain.GetHitInfo(tt);
                    RenderElement ve = hitInfo.hitElement;
                    if (ve != null)
                    {
                        ve.dbug_WriteOwnerLayerInfo(visualroot, tt);
                        ve.dbug_WriteOwnerLineInfo(visualroot, tt);
                        string hit_info = new string('.', tt) + " [" + tt + "] "
                                          + "(" + hitInfo.point.X + "," + hitInfo.point.Y + ") "
                                          + ve.dbug_FullElementDescription();
                        visualroot.dbug_rootHitChainMsg.AddLast(new dbugLayoutMsg(ve, hit_info));
                    }
                }
            }
#endif
            SwapHitChain(hitPointChain);
            e.StopPropagation();
#if DEBUG
            if (local_msgVersion != dbugMsgChainVersion)
            {
                return;
            }
            visualroot.dbugHitTracker.Write("stop-mousedown");
            visualroot.dbugHitTracker.Play = false;
#endif
        }