public AppBarApi(WindowMovement windowMovement) { this.windowMovement = windowMovement; this.callbackMessage = WinApi.RegisterWindowMessage("MorphicAppBarMessage"); this.windowMovement.Ready += (sender, args) => { // Remove it from alt+tab // int style = (int) WinApi.GetWindowLong(this.WindowHandle, WinApi.GWL_EXSTYLE); // style |= WinApi.WS_EX_TOOLWINDOW; // WinApi.SetWindowLong(this.WindowHandle, WinApi.GWL_EXSTYLE, (IntPtr) style); }; }
public AppBar(Window window, WindowMovement windowMovement) { if (!(window is IAppBarWindow)) { throw new ArgumentException($"The window must implement {nameof(IAppBarWindow)}.", nameof(window)); } this.window = window; this.windowMovement = windowMovement; this.api = new AppBarApi(this.windowMovement); // Make the window draggable. this.window.PreviewMouseDown += this.OnPreviewMouseDown; this.window.PreviewMouseMove += this.OnPreviewMouseMove; this.windowMovement.MoveComplete += this.OnMoveComplete; this.windowMovement.Moving += this.OnMoving; this.window.Closed += (sender, args) => this.ApplyAppBar(Edge.None); }
/// <summary> /// Called when the window is being moved, to re-adjust the window in-flight. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void OnMoving(object?sender, WindowMovement.MovementEventArgs args) { args.Handled = true; if (args.IsFirst) { if (this.AppBarEdge == Edge.None) { this.floatingSize = args.Rect.Size; } else { // Un-dock the window so it can be moved. this.ApplyAppBar(Edge.None); // Revert to the original size args.Rect.Size = this.floatingSize; // If the window is not under the cursor, move it so the cursor is in the centre. if (args.Rect.X > args.Cursor.X || args.Rect.Right < args.Cursor.X) { args.Rect.X = args.Cursor.X - args.Rect.Width / 2; } if (args.Rect.Y > args.Cursor.Y || args.Rect.Bottom < args.Cursor.Y) { args.Rect.Y = args.Cursor.Y - args.Rect.Height / 2; } // Make it look like the window was this size when the move started. args.InitialRect = args.NewInitialRect = args.Rect; } } // Like magnifier, if the mouse pointer is on the edge then make the window an app bar on that edge. Point mouse = WindowMovement.GetCursorPos(); Rect workArea = this.windowMovement.GetWorkArea(new Point(mouse.X, mouse.Y)); if (this.EnableDocking) { // See what edge the mouse is near (or beyond) Rect mouseRect = new Rect( Math.Clamp(mouse.X, workArea.Left, workArea.Right), Math.Clamp(mouse.Y, workArea.Top, workArea.Bottom), 0, 0); Edge lastEdge = this.AppBarEdge; this.AppBarEdge = NearEdges(workArea, mouseRect, 5).First(); if (lastEdge != this.AppBarEdge) { this.OnEdgeChanged(this.AppBarEdge, true); } } // Reposition the window to fit the edge. switch (this.AppBarEdge) { case Edge.Left: case Edge.Right: args.Rect.Height = workArea.Height; args.Rect.Width = this.GetGoodSize(new Size(50, args.Rect.Height), Orientation.Vertical, true).Width; args.Rect.Y = workArea.Top; if (this.AppBarEdge == Edge.Left) { args.Rect.X = workArea.X; } else { args.Rect.X = workArea.Right - args.Rect.Width; } this.window.SizeToContent = SizeToContent.Width; break; case Edge.Top: case Edge.Bottom: args.Rect.Width = workArea.Width; args.Rect.Height = this.GetGoodSize(new Size(args.Rect.Width, 50), Orientation.Horizontal, true).Height; args.Rect.X = workArea.X; if (this.AppBarEdge == Edge.Top) { args.Rect.Y = workArea.Y; } else { args.Rect.Y = workArea.Bottom - args.Rect.Height; } this.window.SizeToContent = SizeToContent.Height; break; case Edge.None: args.Rect = args.SupposedRect; // Snap to an edge if (this.SnapToEdges) { this.SnapToEdge(this.windowMovement.GetWorkArea(), ref args.Rect, 20); } this.window.SizeToContent = SizeToContent.WidthAndHeight; break; } }