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); } }
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); } }
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); }
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); } }
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); }
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); }