Пример #1
0
        public static MinimisedEdges ToMinimisedEdge(this DockEdges dockPosition)
        {
            switch (dockPosition)
            {
            case DockEdges.Left: return(MinimisedEdges.Left);

            case DockEdges.Bottom: return(MinimisedEdges.Bottom);

            case DockEdges.Right: return(MinimisedEdges.Right);

            default: return(MinimisedEdges.Top);
            }
        }
Пример #2
0
        public static AppBarEdge ToAppBarEdge(this DockEdges dockPosition)
        {
            switch (dockPosition)
            {
            case DockEdges.Left: return(AppBarEdge.Left);

            case DockEdges.Bottom: return(AppBarEdge.Bottom);

            case DockEdges.Right: return(AppBarEdge.Right);

            default: return(AppBarEdge.Top);
            }
        }
Пример #3
0
        private Rect CalculateDockSizeAndPositionInPx(DockEdges position, DockSizes size)
        {
            Log.InfoFormat("CalculateDockSizeAndPositionInPx called with position:{0}, size:{1}", position, size);

            double x, y, width, height;
            var thicknessAsPercentage = size == DockSizes.Full
                ? getFullDockThicknessAsPercentageOfScreen() / 100
                : (getFullDockThicknessAsPercentageOfScreen() * getCollapsedDockThicknessAsPercentageOfFullDockThickness()) / 10000; //Percentage of a percentage

            switch (position)
            {
                case DockEdges.Top:
                    x = screenBoundsInPx.X;
                    y = screenBoundsInPx.Y;
                    width = screenBoundsInPx.Width;
                    height = screenBoundsInPx.Height * thicknessAsPercentage;
                    break;

                case DockEdges.Bottom:
                    x = screenBoundsInPx.X;
                    y = screenBoundsInPx.Y + screenBoundsInPx.Height - (screenBoundsInPx.Height * thicknessAsPercentage);
                    width = screenBoundsInPx.Width;
                    height = screenBoundsInPx.Height * thicknessAsPercentage;
                    break;

                case DockEdges.Left:
                    x = screenBoundsInPx.X;
                    y = screenBoundsInPx.Y;
                    width = screenBoundsInPx.Width * thicknessAsPercentage;
                    height = screenBoundsInPx.Height;
                    break;

                default: //case DockEdges.Right:
                    x = screenBoundsInPx.X + screenBoundsInPx.Width - (screenBoundsInPx.Width * thicknessAsPercentage);
                    y = screenBoundsInPx.Y;
                    width = screenBoundsInPx.Width * thicknessAsPercentage;
                    height = screenBoundsInPx.Height;
                    break;
            }

            return new Rect(x, y, width, height);
        }
Пример #4
0
        private void SetAppBarSizeAndPosition(DockEdges dockPosition, Rect sizeAndPosition, bool isInitialising = false)
        {
            Log.InfoFormat("SetAppBarSizeAndPosition called with dockPosition:{0}, sizeAndPosition.Top:{1}, sizeAndPosition.Bottom:{2}, sizeAndPosition.Left:{3}, sizeAndPosition.Right:{4}",
                    dockPosition, sizeAndPosition.Top, sizeAndPosition.Bottom, sizeAndPosition.Left, sizeAndPosition.Right);
            Log.InfoFormat("Screen bounds in px - Top:{0}, Left:{1}, Width:{2}, Height:{3}", screenBoundsInPx.Top, screenBoundsInPx.Left, screenBoundsInPx.Width, screenBoundsInPx.Height);

            if (getWindowState() != WindowStates.Docked) return;

            var barData = new APPBARDATA();
            barData.cbSize = Marshal.SizeOf(barData);
            barData.hWnd = windowHandle;
            barData.uEdge = dockPosition.ToAppBarEdge();
            barData.rc.Left = (int)Math.Round(sizeAndPosition.Left);
            barData.rc.Top = (int)Math.Round(sizeAndPosition.Top);
            barData.rc.Right = (int)Math.Round(sizeAndPosition.Right);
            barData.rc.Bottom = (int)Math.Round(sizeAndPosition.Bottom);

            //Submit a query for the proposed dock size and position, which might be updated
            PInvoke.SHAppBarMessage(AppBarMessages.QueryPos, ref barData);

            Log.InfoFormat("QueryPos returned barData.rc.Top:{0}, barData.rc.Bottom:{1}, barData.rc.Left:{2}, barData.rc.Right:{3}",
                    barData.rc.Top, barData.rc.Bottom, barData.rc.Left, barData.rc.Right);

            //Compensate for lost thickness due to other app bars
            switch (dockPosition)
            {
                case DockEdges.Top:
                    barData.rc.Bottom += barData.rc.Top - (int) Math.Round(sizeAndPosition.Top);
                    break;
                case DockEdges.Bottom:
                    barData.rc.Top -= (int)Math.Round(sizeAndPosition.Bottom) - barData.rc.Bottom;
                    break;
                case DockEdges.Left:
                    barData.rc.Right += barData.rc.Left - (int)Math.Round(sizeAndPosition.Left);
                    break;
                case DockEdges.Right:
                    barData.rc.Left -= (int)Math.Round(sizeAndPosition.Right) - barData.rc.Right;
                    break;
            }

            Log.InfoFormat("Rect values adjusted (to compensate for other app bars) to barData.rc.Top:{0}, barData.rc.Bottom:{1}, barData.rc.Left:{2}, barData.rc.Right:{3}",
                    barData.rc.Top, barData.rc.Bottom, barData.rc.Left, barData.rc.Right);

            //Then set the dock size and position, using the potentially updated barData
            PInvoke.SHAppBarMessage(AppBarMessages.SetPos, ref barData);

            Log.InfoFormat("SetPos returned barData.rc.Top:{0}, barData.rc.Bottom:{1}, barData.rc.Left:{2}, barData.rc.Right:{3}",
                    barData.rc.Top, barData.rc.Bottom, barData.rc.Left, barData.rc.Right);

            var finalDockLeftInDp = barData.rc.Left/Graphics.DipScalingFactorX;
            var finalDockTopInDp = barData.rc.Top / Graphics.DipScalingFactorY;
            var finalDockWidthInDp = (barData.rc.Right - barData.rc.Left) / Graphics.DipScalingFactorX;
            var finalDockHeightInDp = (barData.rc.Bottom - barData.rc.Top) / Graphics.DipScalingFactorY;

            Log.InfoFormat("finalDockLeftInDp:{0}, finalDockTopInDp:{1}, finalDockWidthInDp:{2}, finalDockHeightInDp:{3}", finalDockLeftInDp, finalDockTopInDp, finalDockWidthInDp, finalDockHeightInDp);
            Log.InfoFormat("Screen bounds in dp - Top:{0}, Left:{1}, Width:{2}, Height:{3}", screenBoundsInDp.Top, screenBoundsInDp.Left, screenBoundsInDp.Width, screenBoundsInDp.Height);

            if (finalDockLeftInDp < 0 ||
                finalDockTopInDp < 0 ||
                finalDockWidthInDp <= 0 ||
                finalDockHeightInDp <= 0 ||
                (finalDockLeftInDp + finalDockWidthInDp) > screenBoundsInDp.Right ||
                (finalDockTopInDp + finalDockHeightInDp) > screenBoundsInDp.Bottom)
            {
                Log.Error("Final dock size and/or position is invalid - reverting to floating size and position");
                UnRegisterAppBar();
                saveWindowState(WindowStates.Floating);
                savePreviousWindowState(WindowStates.Floating);
                PublishError(this, new ApplicationException("There was a problem positioning OptiKey - reverting to floating position"));
            }
            else if (!isInitialising)
            {
                //Apply final size and position to the window. This is dispatched with ApplicationIdle priority
                //as WPF will send a resize after a new appbar is added. We need to apply the received size & position after this happens.
                //RECT values are in pixels so I need to scale back to DIPs for WPF.
                var rect = new Rect(finalDockLeftInDp, finalDockTopInDp, finalDockWidthInDp, finalDockHeightInDp);
                window.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new ApplySizeAndPositionDelegate(ApplyAndPersistSizeAndPosition), rect);
            }
        }
Пример #5
0
        private Rect CalculateMinimisedSizeAndPosition(DockEdges position)
        {
            double x, y;
            var thicknessAsPercentage = (getFullDockThicknessAsPercentageOfScreen() * getCollapsedDockThicknessAsPercentageOfFullDockThickness()) / 10000; //Percentage of a percentage
            var height = screenBoundsInPx.Height * thicknessAsPercentage;
            var width = screenBoundsInPx.Width * thicknessAsPercentage;

            var minimisedEdge = getMinimisedPosition();
            switch (minimisedEdge == MinimisedEdges.SameAsDockedPosition ? getDockPosition().ToMinimisedEdge() : minimisedEdge)
            {
                case MinimisedEdges.Top:
                    if (screenBoundsInDp.Height > screenBoundsInDp.Width)
                    {
                        //Ensure the minimise button's long edge is against the docked edge,
                        //so swap width and height if aspect ratio is taller than it is wide
                        var temp = width;
                        width = height;
                        height = temp;
                    }
                    x = screenBoundsInDp.Left + (screenBoundsInDp.Width / 2) - (width / 2);
                    y = screenBoundsInDp.Top;
                    break;

                case MinimisedEdges.Bottom:
                    if (screenBoundsInDp.Height > screenBoundsInDp.Width)
                    {
                        //Ensure the minimise button's long edge is against the docked edge,
                        //so swap width and height if aspect ratio is taller than it is wide
                        var temp = width;
                        width = height;
                        height = temp;
                    }
                    x = screenBoundsInDp.Left + (screenBoundsInDp.Width / 2) - (width / 2);
                    y = screenBoundsInDp.Bottom - height;
                    break;

                case MinimisedEdges.Left:
                    if (screenBoundsInDp.Width > screenBoundsInDp.Height)
                    {
                        //Ensure the minimise button's long edge is against the docked edge,
                        //so swap width and height if aspect ratio is wider than it is high
                        var temp = width;
                        width = height;
                        height = temp;
                    }
                    x = screenBoundsInDp.Left;
                    y = screenBoundsInDp.Top + (screenBoundsInDp.Height / 2) - (height / 2);
                    break;

                default: //case DockEdges.Right:
                    if (screenBoundsInDp.Width > screenBoundsInDp.Height)
                    {
                        //Ensure the minimise button's long edge is against the docked edge,
                        //so swap width and height if aspect ratio is wider than it is high
                        var temp = width;
                        width = height;
                        height = temp;
                    }
                    x = screenBoundsInDp.Right - width;
                    y = screenBoundsInDp.Top + (screenBoundsInDp.Height / 2) - (height / 2);
                    break;
            }

            return new Rect(x, y, width, height);
        }
Пример #6
0
        private void SetAppBarSizeAndPosition(DockEdges dockPosition, Rect sizeAndPosition)
        {
            if (getWindowState() != WindowStates.Docked) return;

            var barData = new APPBARDATA();
            barData.cbSize = Marshal.SizeOf(barData);
            barData.hWnd = windowHandle;
            barData.uEdge = dockPosition.ToAppBarEdge();
            barData.rc.Left = (int)Math.Round(sizeAndPosition.Left);
            barData.rc.Top = (int)Math.Round(sizeAndPosition.Top);
            barData.rc.Right = (int)Math.Round(sizeAndPosition.Right);
            barData.rc.Bottom = (int)Math.Round(sizeAndPosition.Bottom);

            //Submit a query for the proposed dock size and position, which might be updated
            PInvoke.SHAppBarMessage(AppBarMessages.QueryPos, ref barData);

            //Compensate for lost thickness due to other app bars
            switch (dockPosition)
            {
                case DockEdges.Top:
                    barData.rc.Bottom += barData.rc.Top - (int) Math.Round(sizeAndPosition.Top);
                    break;
                case DockEdges.Bottom:
                    barData.rc.Top -= (int)Math.Round(sizeAndPosition.Bottom) - barData.rc.Bottom;
                    break;
                case DockEdges.Left:
                    barData.rc.Right += barData.rc.Left - (int)Math.Round(sizeAndPosition.Left);
                    break;
                case DockEdges.Right:
                    barData.rc.Left -= (int)Math.Round(sizeAndPosition.Right) - barData.rc.Right;
                    break;
            }

            //Then set the dock size and position, using the potentially updated barData
            PInvoke.SHAppBarMessage(AppBarMessages.SetPos, ref barData);

            //Extract the final size and position and apply to the window. This is dispatched with ApplicationIdle priority
            //as WPF will send a resize after a new appbar is added. We need to apply the received size & position after this happens.
            //RECT values are in pixels so I need to scale back to DIPs for WPF.
            var rect = new Rect(
                barData.rc.Left / Graphics.DipScalingFactorX,
                barData.rc.Top / Graphics.DipScalingFactorY,
                (barData.rc.Right - barData.rc.Left) / Graphics.DipScalingFactorX,
                (barData.rc.Bottom - barData.rc.Top) / Graphics.DipScalingFactorY);
            window.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new ApplySizeAndPositionDelegate(ApplyAndPersistSizeAndPosition), rect);
        }