Пример #1
0
        /// <summary>
        /// Enumerates through all descendant with the ability to filter them.
        /// </summary>
        /// <param name="me"><see cref="ISpatialBinding"/></param>
        /// <param name="filter">A filter function that take a descendant as a <see cref="IWindowElement"/>, and the <see cref="BindingPosition"/>.</param>
        /// <returns>An enumeration of all descendants</returns>
        public static IEnumerable<ISpatialBinding> AllDescendants( this ISpatialBinding me, BindingPosition excludes = BindingPosition.None )
        {
            //List<IWindowElement> toExclude = new List<IWindowElement>();

            //if( excludes.HasFlag( BindingPosition.Top ) )
            //    foreach( var e in me.Top.Descendants( me.Window ) ) toExclude.Add( e );
            //if( excludes.HasFlag( BindingPosition.Bottom ) )
            //{
            //    foreach( var e in me.Bottom.Descendants( me.Window ) ) toExclude.Add( e );
            //}
            //if( excludes.HasFlag( BindingPosition.Left ) )
            //    foreach( var e in me.Left.Descendants( me.Window ) ) toExclude.Add( e );
            //if( excludes.HasFlag( BindingPosition.Right ) )
            //    foreach( var e in me.Right.Descendants( me.Window ) ) toExclude.Add( e );

            //return me.AllDescendants().Except( toExclude );

            var v = new List<ISpatialBinding>();
            BrowseExclude( me, v, excludes );
            return v.Except( new[] { me } );
        }
        void FillContainers( IWindowElement master, IWindowElement slave, BindingPosition position )
        {
            UnbindButtonContainer masterContainer;
            UnbindButtonContainer slaveContainer;

            if( !_unbindButtonContainers.TryGetValue( slave, out slaveContainer ) )
            {
                slaveContainer = new UnbindButtonContainer( slave );
                _unbindButtonContainers.Add( slave, slaveContainer );
            }
            if( !_unbindButtonContainers.TryGetValue( master, out masterContainer ) )
            {
                masterContainer = new UnbindButtonContainer( master );
                _unbindButtonContainers.Add( master, masterContainer );
            }

            Debug.Assert( masterContainer.GetUnbindFromPosition( position ) == null );
            Debug.Assert( slaveContainer.GetUnbindFromPosition( GetOppositePosition( position ) ) == null );

            IWindowElement button = InitializeButton( master, slave, position );

            masterContainer.SetButton( button, position );
            slaveContainer.SetButton( button, GetOppositePosition( position ) );

            button.Show();
            EnableUnbindButtons();
        }
        void DoPlaceButtons( IWindowElement button, IWindowElement window, BindingPosition position )
        {
            Debug.Assert( Dispatcher.CurrentDispatcher == NoFocusManager.Default.ExternalDispatcher, "This method should only be called by the ExternalThread." );

            double top = window.Top;
            double height = window.Height;
            double width = window.Width;
            double left = window.Left;

            if( position == BindingPosition.Top )
            {
                button.Window.Top = top - button.Height / 2;
                button.Window.Left = left + width / 2 - button.Width / 2;
            }
            else if( position == BindingPosition.Bottom )
            {
                button.Window.Top = top + height - button.Height / 2;
                button.Window.Left = left + width / 2 - button.Width / 2;
            }
            else if( position == BindingPosition.Right )
            {
                button.Window.Top = top + height / 2 - button.Height / 2;
                button.Window.Left = left + width - button.Width / 2;
            }
            else if( position == BindingPosition.Left )
            {
                button.Window.Top = top + height / 2 - button.Width / 2;
                button.Window.Left = left - button.Height / 2;
            }
        }
        VMUnbindButton CreateVM( IWindowElement window, IWindowElement other, BindingPosition position )
        {
            Debug.Assert( Dispatcher.CurrentDispatcher == NoFocusManager.Default.ExternalDispatcher, "This method should only be called by the ExternalThread." );

            if( position == BindingPosition.None )
                return null;

            Action move = null;

            if( position == BindingPosition.Top )
            {
                move = () =>
                {
                    WindowManager.Service.Move( window, window.Top + 10, window.Left ).Broadcast();
                    WindowManager.Service.Move( other, other.Top - 10, other.Left ).Broadcast();
                };
            }
            else if( position == BindingPosition.Bottom )
            {
                move = () =>
                {
                    WindowManager.Service.Move( window, window.Top - 10, window.Left ).Broadcast();
                    WindowManager.Service.Move( other, other.Top + 10, other.Left ).Broadcast();
                };
            }
            else if( position == BindingPosition.Right )
            {
                move = () =>
                {
                    WindowManager.Service.Move( window, window.Top, window.Left - 10 ).Broadcast();
                    WindowManager.Service.Move( other, other.Top, other.Left + 10 ).Broadcast();
                };
            }
            else if( position == BindingPosition.Left )
            {
                move = () =>
                {
                    WindowManager.Service.Move( window, window.Top, window.Left + 10 ).Broadcast();
                    WindowManager.Service.Move( other, other.Top, other.Left - 10 ).Broadcast();
                };
            }

            return new VMUnbindButton( () =>
            {
                WindowBinder.Service.Unbind( window, other, false );
                move();
                EnableUnbindButtons();
            } );
        }
 void CreateButton( IWindowElement master, IWindowElement slave, BindingPosition position )
 {
     FillContainers( master, slave, position );
 }
 internal static BindingPosition GetOppositePosition( BindingPosition position )
 {
     if( position == BindingPosition.Bottom ) return BindingPosition.Top;
     if( position == BindingPosition.Top ) return BindingPosition.Bottom;
     if( position == BindingPosition.Left ) return BindingPosition.Right;
     if( position == BindingPosition.Right ) return BindingPosition.Left;
     return BindingPosition.None;
 }
Пример #7
0
        public static IEnumerable<IWindowElement> SubTree( this ISpatialBinding me, BindingPosition position )
        {
            var visited = new List<IWindowElement>();
            visited.Add( me.Window );

            if( me.Top != null && position.HasFlag( BindingPosition.Top ) ) Browse( me.Top, visited );
            if( me.Left != null && position.HasFlag( BindingPosition.Left ) ) Browse( me.Left, visited );
            if( me.Bottom != null && position.HasFlag( BindingPosition.Bottom ) ) Browse( me.Bottom, visited );
            if( me.Right != null && position.HasFlag( BindingPosition.Right ) ) Browse( me.Right, visited );

            return visited.Except( new[] { me.Window } );
        }
 public IWindowElement GetUnbindFromPosition( BindingPosition position )
 {
     if( position == BindingPosition.Top ) return TopButton;
     else if( position == BindingPosition.Bottom ) return BottomButton;
     else if( position == BindingPosition.Left ) return LeftButton;
     else if( position == BindingPosition.Right ) return RightButton;
     return null;
 }
        private bool CanBind( IWindowElement target, IWindowElement origin, BindingPosition position, out SpatialBinding targetSpatialBinding, out SpatialBinding originSpatialBinding )
        {
            Debug.Assert( Dispatcher.CurrentDispatcher == Application.Current.Dispatcher, "This method should only be called by the Application Thread." );

            originSpatialBinding = null;
            using( _logger.OpenGroup( LogLevel.Info, "Master binding..." ) )
            {
                if( _spatialBindings.TryGetValue( target, out targetSpatialBinding ) )
                {
                    if( position == BindingPosition.Top && targetSpatialBinding.Top != null )
                    {
                        _logger.Trace( "{0} is already bound to {1} at position {2}.", targetSpatialBinding.Top.Window.Name, target.Name, position );
                        return false;
                    }
                    else if( position == BindingPosition.Left && targetSpatialBinding.Left != null )
                    {
                        _logger.Trace( "{0} is already bound to {1} at position {2}.", targetSpatialBinding.Left.Window.Name, target.Name, position );
                        return false;
                    }
                    else if( position == BindingPosition.Bottom && targetSpatialBinding.Bottom != null )
                    {
                        _logger.Trace( "{0} is already bound to {1} at position {2}.", targetSpatialBinding.Bottom.Window.Name, target.Name, position );
                        return false;
                    }
                    else if( position == BindingPosition.Right && targetSpatialBinding.Right != null )
                    {
                        _logger.Trace( "{0} is already bound to {1} at position {2}.", targetSpatialBinding.Right.Window.Name, target.Name, position );
                        return false;
                    }
                    else _logger.Trace( "{0} already exists in bindings but no window attached at position {1}.", target.Name, position );
                }
                else
                {
                    _logger.Trace( "Fresh new window" );
                }
            }

            using( _logger.OpenGroup( LogLevel.Info, "Slave binding..." ) )
            {
                if( _spatialBindings.TryGetValue( origin, out originSpatialBinding ) )
                {
                    if( position == BindingPosition.Top && originSpatialBinding.Bottom != null )
                    {
                        _logger.Trace( "{0} is already bound to {1} at position {2}.", originSpatialBinding.Bottom.Window.Name, target.Name, position );
                        return false;
                    }
                    else if( position == BindingPosition.Left && originSpatialBinding.Right != null )
                    {
                        _logger.Trace( "{0} is already bound to {1} at position {2}.", originSpatialBinding.Right.Window.Name, target.Name, position );
                        return false;
                    }
                    else if( position == BindingPosition.Bottom && originSpatialBinding.Top != null )
                    {
                        _logger.Trace( "{0} is already bound to {1} at position {2}.", originSpatialBinding.Top.Window.Name, target.Name, position );
                        return false;
                    }
                    else if( position == BindingPosition.Right && originSpatialBinding.Left != null )
                    {
                        _logger.Trace( "{0} is already bound to {1} at position {2}.", originSpatialBinding.Left.Window.Name, target.Name, position );
                        return false;
                    }
                    else _logger.Trace( "{0} already exists in bindings but no window attached at position {1}.", origin.Name, position );
                }
                else
                {
                    _logger.Trace( "Fresh new window" );
                    //spatialBinding = new SpatialBinding( slave );
                }
            }

            return true;
        }
Пример #10
0
        public IBindResult PreviewBind( IWindowElement target, IWindowElement origin, BindingPosition position )
        {
            if( Dispatcher.CurrentDispatcher != Application.Current.Dispatcher ) throw new InvalidOperationException( "This method should only be called by the Application Thread." );

            if( target == null ) throw new ArgumentNullException( "master" );
            if( origin == null ) throw new ArgumentNullException( "slave" );

            SpatialBinding targetSpatialBinding = null;
            SpatialBinding originSpatialBinding = null;

            if( CanBind( target, origin, position, out targetSpatialBinding, out originSpatialBinding ) )
            {
                var binding = new SimpleBinding
                {
                    Target = target,
                    Origin = origin,
                    Position = position
                };

                var evt = new WindowBindedEventArgs
                {
                    Binding = binding,
                    BindingType = BindingEventType.Attach
                };

                if( PreviewBinding != null )
                    PreviewBinding( this, evt );

                return new BindResult( this, binding );
            }
            return NullResult.Default;
        }
Пример #11
0
        public void Bind( IWindowElement master, IWindowElement slave, BindingPosition position, bool saveBinding = false )
        {
            if( Dispatcher.CurrentDispatcher != Application.Current.Dispatcher ) throw new InvalidOperationException( "This method should only be called by the Application Thread." );

            if( master == null ) throw new ArgumentNullException( "master" );
            if( slave == null ) throw new ArgumentNullException( "slave" );

            //Console.WriteLine( "BIND thread id: {0} TimeSpan : {1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.Ticks );

            // Spatial binding point of view
            using( _logger.OpenGroup( LogLevel.Info, "Attaching {0} on {1} at {2}", master.Name, slave.Name, position.ToString() ) )
            {
                SpatialBinding spatialBinding = null;
                SpatialBinding slaveSpatialBinding = null;

                if( CanBind( master, slave, position, out spatialBinding, out slaveSpatialBinding ) )
                {
                    _logger.Trace( "Before binding..." );

                    var binding = new SimpleBinding
                    {
                        Target = master,
                        Origin = slave,
                        Position = position
                    };

                    var evt = new WindowBindingEventArgs
                    {
                        Binding = binding,
                        BindingType = BindingEventType.Attach
                    };

                    if( BeforeBinding != null )
                        BeforeBinding( this, evt );

                    if( evt.Canceled == true )
                    {
                        _logger.Trace( "...canceled. The reason was {0}.", evt.CancelReason ?? "No Reason" );
                    }
                    else
                    {
                        if( spatialBinding == null )
                        {
                            spatialBinding = new SpatialBinding( master );
                            _spatialBindings.Add( master, spatialBinding );
                        }
                        if( slaveSpatialBinding == null )
                        {
                            slaveSpatialBinding = new SpatialBinding( slave );
                            _spatialBindings.Add( slave, slaveSpatialBinding );
                        }

                        Debug.Assert( spatialBinding != null );
                        Debug.Assert( slaveSpatialBinding != null );

                        //TODO : FIXWITHDOCKING

                        if( position == BindingPosition.Top )
                        {
                            spatialBinding.Top = slaveSpatialBinding;
                            slaveSpatialBinding.Bottom = spatialBinding;
                        }
                        if( position == BindingPosition.Left )
                        {
                            spatialBinding.Left = slaveSpatialBinding;
                            slaveSpatialBinding.Right = spatialBinding;
                        }
                        if( position == BindingPosition.Bottom )
                        {
                            spatialBinding.Bottom = slaveSpatialBinding;
                            slaveSpatialBinding.Top = spatialBinding;
                        }
                        if( position == BindingPosition.Right )
                        {
                            spatialBinding.Right = slaveSpatialBinding;
                            slaveSpatialBinding.Left = spatialBinding;
                        }

                        if( saveBinding )
                            _persistantBindings.Add( binding );

                        var evtAfter = new WindowBindedEventArgs
                        {
                            Binding = binding,
                            BindingType = BindingEventType.Attach
                        };

                        _logger.Trace( "After binding..." );
                        if( AfterBinding != null )
                            AfterBinding( this, evtAfter );
                    }
                }
            }
        }
Пример #12
0
 //public HitTestResult( IWindowElement windowElement, IWindowElement matchedWindow, Rect enlargedRectangle, Rect overlapRectangle )
 //{
 //    Target = windowElement;
 //    Origin = matchedWindow;
 //    if( overlapRectangle.Bottom == enlargedRectangle.Bottom && overlapRectangle.Height != enlargedRectangle.Height ) Position = BindingPosition.Top;
 //    else if( overlapRectangle.Top == enlargedRectangle.Top && overlapRectangle.Height != enlargedRectangle.Height ) Position = BindingPosition.Bottom;
 //    else if( overlapRectangle.Right == enlargedRectangle.Right && overlapRectangle.Width != enlargedRectangle.Width ) Position = BindingPosition.Left;
 //    else if( overlapRectangle.Left == enlargedRectangle.Left && overlapRectangle.Width != enlargedRectangle.Width ) Position = BindingPosition.Right;
 //    else Position = BindingPosition.None;
 //}
 public HitTestResult( IWindowElement origin, IWindowElement target, BindingPosition position )
 {
     Target = target;
     Origin = origin;
     Position = position;
 }
Пример #13
0
        private static void BrowseExclude( this ISpatialBinding me, IList<ISpatialBinding> visited, BindingPosition excludes )
        {
            if( !visited.Contains( me ) )
            {
                visited.Add( me );

                if( me.Top != null && !excludes.HasFlag( BindingPosition.Top ) ) BrowseExclude( me.Top, visited, excludes );
                if( me.Left != null && !excludes.HasFlag( BindingPosition.Left ) ) BrowseExclude( me.Left, visited, excludes );
                if( me.Bottom != null && !excludes.HasFlag( BindingPosition.Bottom ) ) BrowseExclude( me.Bottom, visited, excludes );
                if( me.Right != null && !excludes.HasFlag( BindingPosition.Right ) ) BrowseExclude( me.Right, visited, excludes );
            }
        }
Пример #14
0
        WindowElement InitializeButton( IWindowElement window, IWindowElement other, BindingPosition position )
        {
            Debug.Assert( Dispatcher.CurrentDispatcher == NoFocusManager.Default.ExternalDispatcher, "This method should only be called by the ExternalThread." );
            WindowElement button = null;

            button = new WindowElement( new UnbindButtonView()
            {
                DataContext = CreateVM( window, other, position )
            }, "UnbindButton" );

            DoPlaceButtons( button, window, position );

            TopMostService.Service.RegisterTopMostElement( "30", button.Window );

            return button;
        }
Пример #15
0
 public void Add( string target, string origin, BindingPosition position )
 {
     Bindings.Add( new SerializableBinding( target, origin, position ) );
 }
Пример #16
0
 public IWindowElement this[BindingPosition p]
 {
     get
     {
         return GetUnbindFromPosition( p );
     }
     set
     {
         SetButton( value, p );
     }
 }
Пример #17
0
 internal SerializableBinding( string target, string origin, BindingPosition position )
 {
     Target = target;
     Origin = origin;
     Position = position;
 }
Пример #18
0
 public void SetButton( IWindowElement button, BindingPosition position )
 {
     Debug.Assert( position != BindingPosition.None );
     if( position == BindingPosition.Top ) TopButton = button;
     else if( position == BindingPosition.Bottom ) BottomButton = button;
     else if( position == BindingPosition.Left ) LeftButton = button;
     else if( position == BindingPosition.Right ) RightButton = button;
 }
        void ResizingWindow( ISpatialBinding binding, BindingPosition masterPosition = BindingPosition.None )
        {
            Debug.Assert( Dispatcher.CurrentDispatcher == Application.Current.Dispatcher, "This method should only be called by the ExternalThread." );

            IWindowElement reference = binding.Window;
            IWindowElement slave = null;

            if( masterPosition != BindingPosition.Top && binding.Top != null )
            {
                slave = binding.Top.Window;
                if( reference.Height != slave.Height )
                {
                    WindowManager.Resize( slave, reference.Width, slave.Height );
                    ResizingWindow( binding.Top, BindingPosition.Bottom );
                }
                WindowManager.Move( slave, reference.Top - slave.Height, reference.Left );
            }
            if( masterPosition != BindingPosition.Bottom && binding.Bottom != null )
            {
                slave = binding.Bottom.Window;
                if( reference.Height != slave.Height )
                {
                    WindowManager.Resize( slave, reference.Width, slave.Height );
                    ResizingWindow( binding.Bottom, BindingPosition.Top );
                }
                WindowManager.Move( slave, reference.Top + reference.Height, reference.Left );
            }
            if( masterPosition != BindingPosition.Left && binding.Left != null )
            {
                slave = binding.Left.Window;
                if( reference.Width != slave.Width )
                {
                    WindowManager.Resize( slave, slave.Width, reference.Height );
                    ResizingWindow( binding.Left, BindingPosition.Right );
                }
                WindowManager.Move( slave, reference.Top, reference.Left - slave.Width );
            }
            if( masterPosition != BindingPosition.Right && binding.Right != null )
            {
                slave = binding.Right.Window;
                if( reference.Width != slave.Width )
                {
                    WindowManager.Resize( slave, slave.Width, reference.Height );
                    ResizingWindow( binding.Right, BindingPosition.Left );
                }
                WindowManager.Move( slave, reference.Top, reference.Left + reference.Width );
            }
        }