Example #1
0
        /// <summary>
        /// Dependency property event once the focused mdi child has changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        private static void ActiveMdiChildValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var mdiContainer = (MdiContainer) sender;
            MdiChild newChild = (MdiChild) e.NewValue,
                     oldChild = (MdiChild) e.OldValue;

            if (newChild == null || newChild == oldChild)
                return;

            if (oldChild != null && oldChild.WindowState == WindowState.Maximized)
                newChild.WindowState = WindowState.Maximized;

            int maxZindex = 0;
            for (int i = 0; i < mdiContainer.Children.Count; i++)
            {
                int zindex = Panel.GetZIndex(mdiContainer.Children[i]);
                if (zindex > maxZindex)
                    maxZindex = zindex;
                if (mdiContainer.Children[i] != newChild)
                    mdiContainer.Children[i].Focused = false;
                else
                    newChild.Focused = true;
            }

            Panel.SetZIndex(newChild, maxZindex + 1);

            if (mdiContainer.MdiChildTitleChanged != null)
                mdiContainer.MdiChildTitleChanged(mdiContainer, new RoutedEventArgs());
        }
        public void AddChild(Behaviors.Bot bot)
        {
            var child = new MdiChild();
            child.Title = "Bot";
            child.Content = new BotControl(bot);

            child.Closed += OnChildClosed;

            MdiContainer.Children.Add(child);
        }
Example #3
0
        /// <summary>
        /// Handles the SizeChanged event of the MdiContainer control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param>
        private void MdiContainer_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (Children.Count == 0)
                return;

            for (int i = 0; i < Children.Count; i++)
            {
                MdiChild mdiChild = Children[i];
                if (mdiChild.WindowState == WindowState.Maximized)
                {
                    mdiChild.Width = ActualWidth;
                    mdiChild.Height = ActualHeight;
                }
                if (mdiChild.WindowState == WindowState.Minimized)
                {
                    mdiChild.Position = new Point(mdiChild.Position.X, mdiChild.Position.Y + e.NewSize.Height - e.PreviousSize.Height);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Handles the CollectionChanged event of the Children control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Collections.Specialized.NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
        private void Children_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    {
                        MdiChild mdiChild = Children[e.NewStartingIndex],
                                 topChild = ActiveMdiChild;

                        if (topChild != null && topChild.WindowState == WindowState.Maximized)
                            mdiChild.Loaded += (s, a) => mdiChild.WindowState = WindowState.Maximized;
                        mdiChild.Loaded += (s, a) => ActiveMdiChild = mdiChild;

                        if (mdiChild.Position.X < 0 || mdiChild.Position.Y < 0)
                            mdiChild.Position = new Point(m_windowOffset, m_windowOffset);
                        m_windowCanvas.Children.Add(mdiChild);

                        m_windowOffset += WindowOffset;
                        if (m_windowOffset + mdiChild.Width > ActualWidth)
                            m_windowOffset = 0;
                        if (m_windowOffset + mdiChild.Height > ActualHeight)
                            m_windowOffset = 0;
                    }
                    break;
                case NotifyCollectionChangedAction.Remove:
                    {
                        var oldChild = (MdiChild) e.OldItems[0];
                        m_windowCanvas.Children.Remove(oldChild);
                        MdiChild newChild = GetTopChild();

                        ActiveMdiChild = newChild;
                        if (newChild != null && oldChild.WindowState == WindowState.Maximized)
                            newChild.WindowState = WindowState.Maximized;
                    }
                    break;
                case NotifyCollectionChangedAction.Reset:
                    m_windowCanvas.Children.Clear();
                    break;
            }
            InvalidateSize();
        }
Example #5
0
        /// <summary>
        /// Invalidates the size checking to see if the furthest
        /// child point exceeds the current height and width.
        /// </summary>
        internal void InvalidateSize()
        {
            var largestPoint = new Point(0, 0);

            for (int i = 0; i < Children.Count; i++)
            {
                MdiChild mdiChild = Children[i];

                var farPosition = new Point(mdiChild.Position.X + mdiChild.Width, mdiChild.Position.Y + mdiChild.Height);

                if (farPosition.X > largestPoint.X)
                    largestPoint.X = farPosition.X;

                if (farPosition.Y > largestPoint.Y)
                    largestPoint.Y = farPosition.Y;
            }

            if (m_windowCanvas.Width != largestPoint.X)
                m_windowCanvas.Width = largestPoint.X;

            if (m_windowCanvas.Height != largestPoint.Y)
                m_windowCanvas.Height = largestPoint.Y;
        }
Example #6
0
        /// <summary>
        /// Dependency property event once the MDI layout value has changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        private static void MdiLayoutValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var mdiContainer = (MdiContainer) sender;
            var value = (MdiLayout) e.NewValue;

            if (value == MdiLayout.ArrangeIcons ||
                mdiContainer.Children.Count < 1)
                return;

            // 1. WindowState.Maximized -> WindowState.Normal
            List<MdiChild> minimizedWindows = new List<MdiChild>(),
                           normalWindows = new List<MdiChild>();
            foreach (MdiChild mdiChild in mdiContainer.Children)
                switch (mdiChild.WindowState)
                {
                    case WindowState.Minimized:
                        minimizedWindows.Add(mdiChild);
                        break;
                    case WindowState.Maximized:
                        mdiChild.WindowState = WindowState.Normal;
                        normalWindows.Add(mdiChild);
                        break;
                    default:
                        normalWindows.Add(mdiChild);
                        break;
                }

            minimizedWindows.Sort(new MdiChildComparer());
            normalWindows.Sort(new MdiChildComparer());

            // 2. Arrange minimized windows
            double containerHeight = mdiContainer.InnerHeight;
            for (int i = 0; i < minimizedWindows.Count; i++)
            {
                MdiChild mdiChild = minimizedWindows[i];
                int capacity = Convert.ToInt32(mdiContainer.ActualWidth)/MdiChild.MinimizedWidth,
                    row = i/capacity + 1,
                    col = i%capacity;
                containerHeight = mdiContainer.InnerHeight - MdiChild.MinimizedHeight*row;
                double newLeft = MdiChild.MinimizedWidth*col;
                mdiChild.Position = new Point(newLeft, containerHeight);
            }

            // 3. Resize & arrange normal windows
            switch (value)
            {
                case MdiLayout.Cascade:
                    {
                        double newWidth = mdiContainer.ActualWidth*0.58,
                               // should be non-linear formula here
                               newHeight = containerHeight*0.67,
                               windowOffset = 0;
                        foreach (MdiChild mdiChild in normalWindows)
                        {
                            if (mdiChild.Resizable)
                            {
                                mdiChild.Width = newWidth;
                                mdiChild.Height = newHeight;
                            }
                            mdiChild.Position = new Point(windowOffset, windowOffset);

                            windowOffset += WindowOffset;
                            if (windowOffset + mdiChild.Width > mdiContainer.ActualWidth)
                                windowOffset = 0;
                            if (windowOffset + mdiChild.Height > containerHeight)
                                windowOffset = 0;
                        }
                    }
                    break;
                case MdiLayout.TileHorizontal:
                    {
                        int cols = (int) Math.Sqrt(normalWindows.Count),
                            rows = normalWindows.Count/cols;

                        var col_count = new List<int>(); // windows per column
                        for (int i = 0; i < cols; i++)
                        {
                            if (normalWindows.Count%cols > cols - i - 1)
                                col_count.Add(rows + 1);
                            else
                                col_count.Add(rows);
                        }

                        double newWidth = mdiContainer.ActualWidth/cols,
                               newHeight = containerHeight/col_count[0],
                               offsetTop = 0,
                               offsetLeft = 0;

                        for (int i = 0, col_index = 0, prev_count = 0; i < normalWindows.Count; i++)
                        {
                            if (i >= prev_count + col_count[col_index])
                            {
                                prev_count += col_count[col_index++];
                                offsetLeft += newWidth;
                                offsetTop = 0;
                                newHeight = containerHeight/col_count[col_index];
                            }

                            MdiChild mdiChild = normalWindows[i];
                            if (mdiChild.Resizable)
                            {
                                mdiChild.Width = newWidth;
                                mdiChild.Height = newHeight;
                            }
                            mdiChild.Position = new Point(offsetLeft, offsetTop);
                            offsetTop += newHeight;
                        }
                    }
                    break;
                case MdiLayout.TileVertical:
                    {
                        int rows = (int) Math.Sqrt(normalWindows.Count),
                            cols = normalWindows.Count/rows;

                        var col_count = new List<int>(); // windows per column
                        for (int i = 0; i < cols; i++)
                        {
                            if (normalWindows.Count%cols > cols - i - 1)
                                col_count.Add(rows + 1);
                            else
                                col_count.Add(rows);
                        }

                        double newWidth = mdiContainer.ActualWidth/cols,
                               newHeight = containerHeight/col_count[0],
                               offsetTop = 0,
                               offsetLeft = 0;

                        for (int i = 0, col_index = 0, prev_count = 0; i < normalWindows.Count; i++)
                        {
                            if (i >= prev_count + col_count[col_index])
                            {
                                prev_count += col_count[col_index++];
                                offsetLeft += newWidth;
                                offsetTop = 0;
                                newHeight = containerHeight/col_count[col_index];
                            }

                            MdiChild mdiChild = normalWindows[i];
                            if (mdiChild.Resizable)
                            {
                                mdiChild.Width = newWidth;
                                mdiChild.Height = newHeight;
                            }
                            mdiChild.Position = new Point(offsetLeft, offsetTop);
                            offsetTop += newHeight;
                        }
                    }
                    break;
            }
            mdiContainer.InvalidateSize();
            mdiContainer.MdiLayout = MdiLayout.ArrangeIcons;
        }
Example #7
0
        /// <summary>
        /// Dependency property event once the windows state value has changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        private static void WindowStateValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var          mdiChild     = (MdiChild)sender;
            MdiContainer mdiContainer = mdiChild.Container;

            var previousWindowState = (WindowState)e.OldValue;
            var windowState         = (WindowState)e.NewValue;

            if (mdiChild.Container == null ||
                previousWindowState == windowState)
            {
                return;
            }

            if (previousWindowState == WindowState.Maximized)
            {
                if (mdiContainer.ActiveMdiChild.WindowState != WindowState.Maximized)
                {
                    for (int i = 0; i < mdiContainer.Children.Count; i++)
                    {
                        if (mdiContainer.Children[i] != mdiChild &&
                            mdiContainer.Children[i].WindowState == WindowState.Maximized &&
                            mdiContainer.Children[i].MaximizeBox)
                        {
                            mdiContainer.Children[i].WindowState = WindowState.Normal;
                        }
                    }

                    var sv = (ScrollViewer)((Grid)mdiContainer.Content).Children[1];
                    sv.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
                    sv.VerticalScrollBarVisibility   = ScrollBarVisibility.Auto;
                }

                mdiChild.Buttons.Children.Clear();
                mdiChild.Buttons = null;
                mdiChild.buttonsPanel.Children.Add(mdiChild.minimizeButton);
                mdiChild.buttonsPanel.Children.Add(mdiChild.maximizeButton);
                mdiChild.buttonsPanel.Children.Add(mdiChild.closeButton);
            }

            if (previousWindowState == WindowState.Minimized)
            {
                mdiChild.minimizedPosition = mdiChild.Position;
            }

            switch (windowState)
            {
            case WindowState.Normal:
            {
                mdiChild.Position = new Point(mdiChild.originalDimension.X, mdiChild.originalDimension.Y);
                mdiChild.Width    = mdiChild.originalDimension.Width;
                mdiChild.Height   = mdiChild.originalDimension.Height;
            }
            break;

            case WindowState.Minimized:
            {
                if (previousWindowState == WindowState.Normal)
                {
                    mdiChild.originalDimension = new Rect(mdiChild.Position.X, mdiChild.Position.Y, mdiChild.ActualWidth, mdiChild.ActualHeight);
                }

                double newLeft, newTop;
                if (mdiChild.minimizedPosition.X >= 0 || mdiChild.minimizedPosition.Y >= 0)
                {
                    newLeft = mdiChild.minimizedPosition.X;
                    newTop  = mdiChild.minimizedPosition.Y;
                }
                else
                {
                    var minimizedWindows = new List <Rect>();
                    for (int i = 0; i < mdiContainer.Children.Count; i++)
                    {
                        MdiChild child = mdiContainer.Children[i];
                        if (child != mdiChild &&
                            child.WindowState == WindowState.Minimized)
                        {
                            minimizedWindows.Add(new Rect(child.Position.X, mdiContainer.InnerHeight - child.Position.Y, child.Width, child.Height));
                        }
                    }
                    Rect newWindowPlace;
                    bool occupied = true;
                    int  count    = 0,
                         capacity = Convert.ToInt32(mdiContainer.ActualWidth) / MinimizedWidth;
                    do
                    {
                        int row = count / capacity + 1,
                            col = count % capacity;
                        newTop  = MinimizedHeight * row;
                        newLeft = MinimizedWidth * col;

                        newWindowPlace = new Rect(newLeft, newTop, MinimizedWidth, MinimizedHeight);
                        occupied       = false;
                        foreach (Rect rect in minimizedWindows)
                        {
                            Rect intersection = rect;
                            intersection.Intersect(newWindowPlace);
                            if (intersection != Rect.Empty && intersection.Width > 0 && intersection.Height > 0)
                            {
                                occupied = true;
                                break;
                            }
                        }
                        count++;

                        // TODO: handle negative Canvas coordinates somehow.
                        if (newTop < 0)
                        {
                            // ugly workaround for now.
                            newTop   = 0;
                            occupied = false;
                        }
                    } while (occupied);

                    newTop = mdiContainer.InnerHeight - newTop;
                }

                mdiChild.Position = new Point(newLeft, newTop);

                mdiChild.Width  = MinimizedWidth;
                mdiChild.Height = MinimizedHeight;
            }
            break;

            case WindowState.Maximized:
            {
                if (previousWindowState == WindowState.Normal)
                {
                    mdiChild.originalDimension = new Rect(mdiChild.Position.X, mdiChild.Position.Y, mdiChild.ActualWidth, mdiChild.ActualHeight);
                }
                mdiChild.NonMaximizedState = previousWindowState;

                mdiChild.buttonsPanel.Children.Clear();
                var sp = new StackPanel {
                    Orientation = Orientation.Horizontal
                };
                sp.Children.Add(mdiChild.minimizeButton);
                sp.Children.Add(mdiChild.maximizeButton);
                sp.Children.Add(mdiChild.closeButton);
                mdiChild.Buttons = sp;

                mdiChild.Position = new Point(0, 0);
                mdiChild.Width    = mdiContainer.ActualWidth;
                mdiChild.Height   = mdiContainer.InnerHeight - 2;       // ContentBorder.BorderThickness="1" in template

                var sv = (ScrollViewer)((Grid)mdiContainer.Content).Children[1];
                sv.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                sv.VerticalScrollBarVisibility   = ScrollBarVisibility.Hidden;
            }
            break;
            }
            if (mdiContainer.ActiveMdiChild == mdiChild)
            {
                mdiContainer.Buttons = mdiChild.Buttons;
            }
            mdiContainer.InvalidateSize();
        }