// Decompiled with JetBrains decompiler // Type: ZuneUI.WindowSnapSimulator // Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 // MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 // Assembly location: C:\Program Files\Zune\ZuneShell.dll using Microsoft.Iris; using Microsoft.Zune.Util; using System; using System.Collections.Generic; using System.ComponentModel; namespace ZuneUI { public class WindowSnapSimulator : SingletonModelItem { private const float c_hotspotPercentage = 0.015f; private Window _window; private bool _isInitialized; private List _monitors; private IHotspot _currentHotspot; private bool _isSnapping; public void Phase3Init() => this.Initialize(); private void Initialize() { if (this.IsInitialized) return; this.InitializeMonitors(); this._window = Application.Window; this._window.PropertyChanged += new PropertyChangedEventHandler(this.OnWindowPropertyChanged); Win7ShellManager.Instance.OnMonitorChange += new MonitorChangeHandler(this.OnMonitorChangeDetected); if (OSVersion.IsWin7()) Win7ShellManager.Instance.OnWindowPositionKeyPress += new WindowPositionKeyPressHandler(this.OnWin7KeypressDetected); Shell defaultInstance = (Shell)ZuneShell.DefaultInstance; if (defaultInstance.NormalWindowSize == null) defaultInstance.NormalWindowSize = new Size(this._window.ClientSize.Width, this._window.ClientSize.Height); if (defaultInstance.NormalWindowPosition == null) defaultInstance.NormalWindowPosition = new Point(this._window.Position.X, this._window.Position.Y); this.IsInitialized = true; this.UpdateIsSnapping(); } private void InitializeMonitors() { this._monitors = new List(); foreach (MonitorSize detectMonitor in new MonitorDetector().DetectMonitors()) { Monitor monitor = new Monitor(detectMonitor); int width = Math.Max((monitor.Right - monitor.Left + 1) / 2, Shell.MinimumWindowWidth); int height = Math.Max(monitor.Bottom - monitor.Top + 1, Shell.MinimumWindowHeight); monitor.LeftSnap.Position = new WindowPosition(monitor.Left, monitor.Top); monitor.LeftSnap.Size = new WindowSize(width, height); monitor.RightSnap.Position = new WindowPosition(monitor.Right - width, monitor.Top); monitor.RightSnap.Size = new WindowSize(width, height); this._monitors.Add(monitor); } this._monitors.Sort(); foreach (Monitor monitor in this._monitors) monitor.InitializeHotspots(this._monitors, 0.015f); } public bool IsSnapping { get => this._isSnapping; private set { if (this._isSnapping == value) return; this._isSnapping = value; this.FirePropertyChanged(nameof(IsSnapping)); } } private bool IsInitialized { get => this._isInitialized; set => this._isInitialized = value; } public void ShiftUp() { if (!this.IsInitialized || this._window.WindowState != WindowState.Normal) return; if (this.IsSnapping) this.Unsnap(this.GetWindowMonitor()); this._window.WindowState = WindowState.Maximized; } public void ShiftDown() { if (!this.IsInitialized) return; switch (this._window.WindowState) { case WindowState.Normal: if (this.IsSnapping) { this.Unsnap(); break; } this._window.WindowState = WindowState.Minimized; break; case WindowState.Maximized: this._window.WindowState = WindowState.Normal; break; } } public void ShiftLeft() { if (!this.IsInitialized) return; if (this._window.WindowState == WindowState.Maximized) this._window.WindowState = WindowState.Normal; Monitor windowMonitor = this.GetWindowMonitor(); switch (this.GetWindowSnappedness(windowMonitor)) { case WindowSnappedness.Unsnapped: this.Snap(windowMonitor.LeftSnap); break; case WindowSnappedness.Left: this.Snap(this.FindPreviousMonitor(windowMonitor).RightSnap); break; case WindowSnappedness.Right: this.Unsnap(windowMonitor); break; } } public void ShiftRight() { if (!this.IsInitialized) return; if (this._window.WindowState == WindowState.Maximized) this._window.WindowState = WindowState.Normal; Monitor windowMonitor = this.GetWindowMonitor(); switch (this.GetWindowSnappedness(windowMonitor)) { case WindowSnappedness.Unsnapped: this.Snap(windowMonitor.RightSnap); break; case WindowSnappedness.Left: this.Unsnap(windowMonitor); break; case WindowSnappedness.Right: this.Snap(this.FindNextMonitor(windowMonitor).LeftSnap); break; } } public void ShiftMonitorLeft() { if (!this.IsInitialized) return; Monitor windowMonitor = this.GetWindowMonitor(); WindowSnappedness windowSnappedness = this.GetWindowSnappedness(windowMonitor); Monitor destinationMonitor = null; if (!OSVersion.IsWin7()) destinationMonitor = this.FindPreviousMonitor(windowMonitor); switch (windowSnappedness) { case WindowSnappedness.Unsnapped: if (OSVersion.IsWin7()) break; this.MoveWindowToMonitor(windowMonitor, this._window.Position, destinationMonitor); break; case WindowSnappedness.Left: if (OSVersion.IsWin7()) { this.Snap(windowMonitor.LeftSnap); break; } this.Snap(destinationMonitor.LeftSnap); break; case WindowSnappedness.Right: if (OSVersion.IsWin7()) { this.Snap(windowMonitor.RightSnap); break; } this.Snap(destinationMonitor.RightSnap); break; } } public void ShiftMonitorRight() { if (!this.IsInitialized) return; Monitor windowMonitor = this.GetWindowMonitor(); WindowSnappedness windowSnappedness = this.GetWindowSnappedness(windowMonitor); Monitor destinationMonitor = null; if (!OSVersion.IsWin7()) destinationMonitor = this.FindNextMonitor(windowMonitor); switch (windowSnappedness) { case WindowSnappedness.Unsnapped: if (OSVersion.IsWin7()) break; this.MoveWindowToMonitor(windowMonitor, this._window.Position, destinationMonitor); break; case WindowSnappedness.Left: if (OSVersion.IsWin7()) { this.Snap(windowMonitor.LeftSnap); break; } this.Snap(destinationMonitor.LeftSnap); break; case WindowSnappedness.Right: if (OSVersion.IsWin7()) { this.Snap(windowMonitor.RightSnap); break; } this.Snap(destinationMonitor.RightSnap); break; } } public void Unsnap() { if (!this.IsSnapping || !this.IsInitialized) return; this.Unsnap(this.GetWindowMonitor()); } public void DragBegun() { if (this.IsInitialized) { int x = 0; int y = 0; MousePosition.GetCursorScreenPosition(out x, out y); this._currentHotspot = this.GetWindowMonitor(x, y).GetHotspotForCursor(x, y); } else this._currentHotspot = null; } public bool ReactToDrag() { IHotspot hotspot = null; if (this.IsInitialized) { int x = 0; int y = 0; MousePosition.GetCursorScreenPosition(out x, out y); hotspot = this.GetWindowMonitor(x, y).GetHotspotForCursor(x, y); if (hotspot != this._currentHotspot) { if (this.IsSnapping) this.Unsnap(); if (this._window.WindowState == WindowState.Maximized) this._window.WindowState = WindowState.Normal; this._currentHotspot = hotspot; hotspot?.Snap(); } } return hotspot != null; } public void DragEnded() => this._currentHotspot = null; public void SetWindowPosition(int left, int top, int width, int height) { this.Initialize(); Monitor windowMonitor = this.GetWindowMonitor(left + width / 2, top + height / 2); if (windowMonitor != null) { if (width > windowMonitor.Right - windowMonitor.Left) width = windowMonitor.Right - windowMonitor.Left; if (height > windowMonitor.Bottom - windowMonitor.Top) height = windowMonitor.Bottom - windowMonitor.Top; if (left < windowMonitor.Left) left = windowMonitor.Left; else if (left + width > windowMonitor.Right) left = windowMonitor.Right - width; if (top < windowMonitor.Top) top = windowMonitor.Top; else if (top + height > windowMonitor.Bottom) top = windowMonitor.Bottom - height; } this._window.Position = new WindowPosition(left, top); this._window.ClientSize = new WindowSize(width, height); } private void Snap(WindowPlacement placement) { if (!this.IsInitialized) return; this._window.Position = placement.Position; this._window.ClientSize = placement.Size; } private void Unsnap(Monitor monitor) { if (!this.IsSnapping || !this.IsInitialized) return; Shell defaultInstance = (Shell)ZuneShell.DefaultInstance; WindowPosition windowPosition = new WindowPosition(defaultInstance.NormalWindowPosition.X, defaultInstance.NormalWindowPosition.Y); WindowSize size = new WindowSize(defaultInstance.NormalWindowSize.Width, defaultInstance.NormalWindowSize.Height); Monitor windowMonitor = this.GetWindowMonitor(windowPosition, size); if (monitor == windowMonitor) this._window.Position = windowPosition; else this.MoveWindowToMonitor(windowMonitor, windowPosition, monitor); this._window.ClientSize = size; } private void MoveWindowToMonitor( Monitor currentMonitor, WindowPosition currentPosition, Monitor destinationMonitor) { int num1 = destinationMonitor.Left - currentMonitor.Left; int num2 = destinationMonitor.Top - currentMonitor.Top; this._window.Position = new WindowPosition(currentPosition.X + num1, currentPosition.Y + num2); } private Monitor FindNextMonitor( Monitor monitor) { int index = this._monitors.IndexOf(monitor) + 1; if (index >= this._monitors.Count) index = 0; return this._monitors[index]; } private Monitor FindPreviousMonitor( Monitor monitor) { int index = this._monitors.IndexOf(monitor) - 1; if (index < 0) index = this._monitors.Count - 1; return this._monitors[index]; } private WindowSnappedness GetWindowSnappedness( Monitor monitor) { WindowSnappedness windowSnappedness = WindowSnappedness.Ineligible; if (this.IsInitialized && this._window.WindowState != WindowState.Maximized && this._window.WindowState != WindowState.Minimized) windowSnappedness = !(this._window.Position == monitor.LeftSnap.Position) || !(this._window.ClientSize == monitor.LeftSnap.Size) ? (!(this._window.Position == monitor.RightSnap.Position) || !(this._window.ClientSize == monitor.RightSnap.Size) ? WindowSnappedness.Unsnapped : WindowSnappedness.Right) : WindowSnappedness.Left; return windowSnappedness; } private Monitor GetWindowMonitor() => this.GetWindowMonitor(this._window.Position, this._window.ClientSize); private Monitor GetWindowMonitor( WindowPlacement placement) { return this.GetWindowMonitor(placement.Position, placement.Size); } private Monitor GetWindowMonitor( WindowPosition position, WindowSize size) { return this.GetWindowMonitor(position.X + size.Width / 2, position.Y + size.Height / 2); } private Monitor GetWindowMonitor(int x, int y) { Monitor monitor1 = null; if (this.IsInitialized) { if (this._monitors.Count > 1) { int num1 = int.MaxValue; foreach (Monitor monitor2 in this._monitors) { int num2 = 0; int num3 = 0; if (x < monitor2.Left) num2 = monitor2.Left - x; else if (x > monitor2.Right) num2 = x - monitor2.Right; if (y < monitor2.Top) num3 = monitor2.Top - y; else if (y > monitor2.Bottom) num3 = y - monitor2.Bottom; int num4 = num2 + num3; if (num4 < num1) { monitor1 = monitor2; num1 = num4; } } } else monitor1 = this._monitors[0]; } return monitor1; } private void UpdateIsSnapping() { bool flag = false; if (this._window.WindowState == WindowState.Normal) { switch (this.GetWindowSnappedness(this.GetWindowMonitor())) { case WindowSnappedness.Left: case WindowSnappedness.Right: flag = true; break; } } this.IsSnapping = flag; } private void OnWindowPropertyChanged(object sender, PropertyChangedEventArgs args) { if (!(args.PropertyName == "Position") && !(args.PropertyName == "ClientSize") && !(args.PropertyName == "WindowState")) return; this.UpdateIsSnapping(); } private void OnWin7KeypressDetected(WindowPositionKeys key) => Application.DeferredInvoke(delegate { switch (key) { case WindowPositionKeys.eWindowPositionKeyLeft: this.ShiftLeft(); break; case WindowPositionKeys.eWindowPositionKeyRight: this.ShiftRight(); break; case WindowPositionKeys.eWindowPositionKeyDown: if (this._window.WindowState != WindowState.Maximized) break; this.ShiftDown(); break; case WindowPositionKeys.eWindowPositionKeyShiftLeft: this.ShiftMonitorLeft(); break; case WindowPositionKeys.eWindowPositionKeyShiftRight: this.ShiftMonitorRight(); break; } }, null); private void OnMonitorChangeDetected() => Application.DeferredInvoke(delegate { this.Unsnap(); this.InitializeMonitors(); }, null); private enum WindowSnappedness { Unsnapped, Left, Right, Ineligible, } private class WindowPlacement { private WindowPosition _position; private WindowSize _size; public WindowPosition Position { get => this._position; set => this._position = value; } public WindowSize Size { get => this._size; set => this._size = value; } } private class Monitor : IComparable { private MonitorSize _dimensions; private WindowPlacement _leftSnap; private WindowPlacement _rightSnap; private int _hotspotSize; private IHotspot _topHotspot; private IHotspot _leftHotspot; private IHotspot _rightHotspot; public Monitor(MonitorSize dimensions) { this._dimensions = dimensions; this.LeftSnap = new WindowPlacement(); this.RightSnap = new WindowPlacement(); } public int Left => this._dimensions.WorkArea.Left; public int Right => this._dimensions.WorkArea.Right; public int Top => this._dimensions.WorkArea.Top; public int Bottom => this._dimensions.WorkArea.Bottom; public WindowPlacement LeftSnap { get => this._leftSnap; private set => this._leftSnap = value; } public WindowPlacement RightSnap { get => this._rightSnap; private set => this._rightSnap = value; } public void InitializeHotspots( List monitorList, float hotspotSizePercentage) { this._hotspotSize = (int)((this.Right - this.Left + 1 + (this.Bottom - this.Top + 1)) / 2 * (double)hotspotSizePercentage); bool flag1 = true; bool flag2 = true; bool flag3 = true; foreach (Monitor monitor in monitorList) { RECT totalArea = monitor._dimensions.TotalArea; if (totalArea.Top + 1 == this.Top) flag1 = false; if (totalArea.Right + 1 == this.Left) flag2 = false; if (totalArea.Left - 1 == this.Right) flag3 = false; } if (flag1) this._topHotspot = new MaximizeHotspot(); if (flag2) this._leftHotspot = new PlacementHotspot(this.LeftSnap); if (!flag3) return; this._rightHotspot = new PlacementHotspot(this.RightSnap); } public IHotspot GetHotspotForCursor( int cursorX, int cursorY) { IHotspot hotspot = null; if (cursorY <= this.Top + this._hotspotSize && this._topHotspot != null) hotspot = this._topHotspot; else if (cursorX <= this.Left + this._hotspotSize) hotspot = this._leftHotspot; else if (cursorX >= this.Right - this._hotspotSize) hotspot = this._rightHotspot; return hotspot; } public int CompareTo(Monitor other) { int num = this.Top.CompareTo(other.Top); return num == 0 ? this.Left.CompareTo(other.Left) : num; } } private interface IHotspot { void Snap(); } private class MaximizeHotspot : IHotspot { public void Snap() => Instance.ShiftUp(); } private class PlacementHotspot : IHotspot { private WindowPlacement _placement; public PlacementHotspot(WindowPlacement placement) => this._placement = placement; public void Snap() => Instance.Snap(this._placement); } } }