Files
PowerToys/src/modules/fancyzones/editor/FancyZonesEditor/CanvasZone.xaml.cs
gokcekantarci a94b3eec39 .NET 8 Upgrade Silenced Errors Fix (#30469)
* [Dev][Build] .NET 8 Upgrade Silenced errors first fix.

* [Dev][Build] .NET 8 Upgrade Silenced errors. CA1859

* [Dev][Build] .NET 8 Upgrade Silenced errors. CA1854.

* [Dev][Build] .NET 8 Upgrade Silenced errors. CA1860

* [Dev][Build] .NET 8 Upgrade Silenced errors. CA1861

* [Dev][Build] .NET 8 Upgrade Silenced errors. CA1862

* [Dev][Build] .NET 8 Upgrade Silenced errors. CA1863

* [Dev][Build] .NET 8 Upgrade Silenced errors. CA1864

* [Dev][Build] .NET 8 Upgrade Silenced errors. CA1865

* [Dev][Build] .NET 8 Upgrade Silenced errors. CA2208

* [Dev][Build] .NET 8 Upgrade Silenced errors. CS9191

* [Dev][Build] .NET 8 Upgrade Silenced errors. Spell check

* [Dev][Build] .NET 8 Upgrade Silenced errors. Spell check

* [Dev][Build] .NET 8 Upgrade Silenced errors.
- CompositeFormat variables used more than once in the same file were assigned to a single variable.
- GetProcessesByName logic fix.
- String comparion fix.
- ArgumentOutOfRangeException message change.

* [Dev][Build] .NET 8 Upgrade Silenced errors.
- Null check added.
- static readonly CompositeFormat added for all fields.
2023-12-28 13:37:13 +03:00

541 lines
20 KiB
C#

// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using FancyZonesEditor.Models;
namespace FancyZonesEditor
{
/// <summary>
/// Once you've "Commit"ted the starter grid, then the Zones within the grid come to life for you to be able to further subdivide them
/// using splitters
/// </summary>
public partial class CanvasZone : UserControl
{
private readonly int defaultMoveAmount = 10;
private readonly int smallMoveAmount = 1;
public CanvasZone()
{
InitializeComponent();
Canvas.SetZIndex(this, zIndex++);
SizeChanged += CanvasZone_SizeChanged;
}
private void CanvasZone_SizeChanged(object sender, SizeChangedEventArgs e)
{
// using current culture as this is end user facing
WidthLabel.Text = Width.ToString(CultureInfo.CurrentCulture);
HeightLabel.Text = Height.ToString(CultureInfo.CurrentCulture);
}
private CanvasLayoutModel model;
private int zoneIndex;
public enum ResizeMode
{
BottomEdge,
TopEdge,
BothEdges,
}
private abstract class SnappyHelperBase
{
public int ScreenW { get; private set; }
protected List<int> Snaps { get; private set; }
protected int MinValue { get; private set; }
protected int MaxValue { get; private set; }
public int Position { get; protected set; }
public ResizeMode Mode { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="SnappyHelperBase"/> class.
/// Just pass it the canvas arguments. Use mode
/// to tell it which edges of the existing masks to use when building its list
/// of snap points, and generally which edges to track. There will be two
/// SnappyHelpers, one for X-coordinates and one for
/// Y-coordinates, they work independently but share the same logic.
/// </summary>
/// <param name="zones">The list of rectangles describing all zones</param>
/// <param name="zoneIndex">The index of the zone to track</param>
/// <param name="isX"> Whether this is the X or Y SnappyHelper</param>
/// <param name="mode"> One of the three modes of operation (for example: tracking left/right/both edges)</param>
/// <param name="screenAxisOrigin"> The origin (left/top) of the screen in this (X or Y) dimension</param>
/// <param name="screenAxisSize"> The size of the screen in this (X or Y) dimension</param>
public SnappyHelperBase(IList<Int32Rect> zones, int zoneIndex, bool isX, ResizeMode mode, int screenAxisOrigin, int screenAxisSize)
{
int zonePosition = isX ? zones[zoneIndex].X : zones[zoneIndex].Y;
int zoneAxisSize = isX ? zones[zoneIndex].Width : zones[zoneIndex].Height;
int minAxisSize = isX ? MinZoneWidth : MinZoneHeight;
List<int> keyPositions = new List<int>();
for (int i = 0; i < zones.Count; ++i)
{
if (i != zoneIndex)
{
int ithZonePosition = isX ? zones[i].X : zones[i].Y;
int ithZoneAxisSize = isX ? zones[i].Width : zones[i].Height;
keyPositions.Add(ithZonePosition);
keyPositions.Add(ithZonePosition + ithZoneAxisSize);
if (mode == ResizeMode.BothEdges)
{
keyPositions.Add(ithZonePosition - zoneAxisSize);
keyPositions.Add(ithZonePosition + ithZoneAxisSize - zoneAxisSize);
}
}
}
foreach (Rect singleMonitor in App.Overlay.WorkAreas)
{
int monitorPositionLow = (int)(isX ? singleMonitor.Left : singleMonitor.Top);
int monitorPositionHigh = (int)(isX ? singleMonitor.Right : singleMonitor.Bottom);
keyPositions.Add(monitorPositionLow - screenAxisOrigin);
keyPositions.Add(monitorPositionHigh - screenAxisOrigin);
if (mode == ResizeMode.BothEdges)
{
keyPositions.Add(monitorPositionLow - screenAxisOrigin - zoneAxisSize);
keyPositions.Add(monitorPositionHigh - screenAxisOrigin - zoneAxisSize);
}
}
// Remove duplicates and sort
keyPositions.Sort();
Snaps = new List<int>();
if (keyPositions.Count > 0)
{
Snaps.Add(keyPositions[0]);
for (int i = 1; i < keyPositions.Count; ++i)
{
if (keyPositions[i] != keyPositions[i - 1])
{
Snaps.Add(keyPositions[i]);
}
}
}
switch (mode)
{
case ResizeMode.BottomEdge:
// We're dragging the low edge, don't go below zero
MinValue = 0;
// It can't make the zone smaller than minAxisSize
MaxValue = zonePosition + zoneAxisSize - minAxisSize;
Position = zonePosition;
break;
case ResizeMode.TopEdge:
// We're dragging the high edge, don't make the zone smaller than minAxisSize
MinValue = zonePosition + minAxisSize;
// Don't go off the screen
MaxValue = screenAxisSize;
Position = zonePosition + zoneAxisSize;
break;
case ResizeMode.BothEdges:
// We're moving the window, don't move it below zero
MinValue = 0;
// Don't go off the screen (this time the lower edge is tracked)
MaxValue = screenAxisSize - zoneAxisSize;
Position = zonePosition;
break;
}
Mode = mode;
this.ScreenW = screenAxisSize;
}
public abstract void Move(int delta);
}
private sealed class SnappyHelperMagnetic : SnappyHelperBase
{
private List<int> magnetZoneSizes;
private int freePosition;
private int MagnetZoneMaxSize
{
get => (int)(0.08 * ScreenW);
}
public SnappyHelperMagnetic(IList<Int32Rect> zones, int zoneIndex, bool isX, ResizeMode mode, int screenAxisOrigin, int screenAxisSize)
: base(zones, zoneIndex, isX, mode, screenAxisOrigin, screenAxisSize)
{
freePosition = Position;
magnetZoneSizes = new List<int>();
for (int i = 0; i < Snaps.Count; ++i)
{
int previous = i == 0 ? 0 : Snaps[i - 1];
int next = i == Snaps.Count - 1 ? ScreenW : Snaps[i + 1];
magnetZoneSizes.Add(Math.Min(Snaps[i] - previous, Math.Min(next - Snaps[i], MagnetZoneMaxSize)) / 2);
}
}
public override void Move(int delta)
{
freePosition = Position + delta;
int snapId = -1;
for (int i = 0; i < Snaps.Count; ++i)
{
if (Math.Abs(freePosition - Snaps[i]) <= magnetZoneSizes[i])
{
snapId = i;
break;
}
}
if (snapId == -1)
{
Position = freePosition;
}
else
{
int deadZoneWidth = (magnetZoneSizes[snapId] + 1) / 2;
if (Math.Abs(freePosition - Snaps[snapId]) <= deadZoneWidth)
{
Position = Snaps[snapId];
}
else if (freePosition < Snaps[snapId])
{
Position = freePosition + (freePosition - (Snaps[snapId] - magnetZoneSizes[snapId]));
}
else
{
Position = freePosition - ((Snaps[snapId] + magnetZoneSizes[snapId]) - freePosition);
}
}
Position = Math.Max(Math.Min(MaxValue, Position), MinValue);
}
}
private sealed class SnappyHelperNonMagnetic : SnappyHelperBase
{
public SnappyHelperNonMagnetic(IList<Int32Rect> zones, int zoneIndex, bool isX, ResizeMode mode, int screenAxisOrigin, int screenAxisSize)
: base(zones, zoneIndex, isX, mode, screenAxisOrigin, screenAxisSize)
{
}
public override void Move(int delta)
{
var pos = Position + delta;
Position = Math.Max(Math.Min(MaxValue, pos), MinValue);
}
}
private SnappyHelperBase snappyX;
private SnappyHelperBase snappyY;
private SnappyHelperMagnetic NewMagneticSnapper(bool isX, ResizeMode mode)
{
Rect workingArea = App.Overlay.WorkArea;
int screenAxisOrigin = (int)(isX ? workingArea.Left : workingArea.Top);
int screenAxisSize = (int)(isX ? workingArea.Width : workingArea.Height);
return new SnappyHelperMagnetic(Model.Zones, ZoneIndex, isX, mode, screenAxisOrigin, screenAxisSize);
}
private SnappyHelperNonMagnetic NewNonMagneticSnapper(bool isX, ResizeMode mode)
{
Rect workingArea = App.Overlay.WorkArea;
int screenAxisOrigin = (int)(isX ? workingArea.Left : workingArea.Top);
int screenAxisSize = (int)(isX ? workingArea.Width : workingArea.Height);
return new SnappyHelperNonMagnetic(Model.Zones, ZoneIndex, isX, mode, screenAxisOrigin, screenAxisSize);
}
private void UpdateFromSnappyHelpers()
{
if (ZoneIndex >= Model.Zones.Count)
{
return;
}
Int32Rect rect = Model.Zones[ZoneIndex];
if (snappyX != null)
{
if (snappyX.Mode == ResizeMode.BottomEdge)
{
int changeX = snappyX.Position - rect.X;
rect.X += changeX;
rect.Width -= changeX;
}
else if (snappyX.Mode == ResizeMode.TopEdge)
{
rect.Width = snappyX.Position - rect.X;
}
else
{
int changeX = snappyX.Position - rect.X;
rect.X += changeX;
}
Canvas.SetLeft(this, rect.X);
Width = rect.Width;
}
if (snappyY != null)
{
if (snappyY.Mode == ResizeMode.BottomEdge)
{
int changeY = snappyY.Position - rect.Y;
rect.Y += changeY;
rect.Height -= changeY;
}
else if (snappyY.Mode == ResizeMode.TopEdge)
{
rect.Height = snappyY.Position - rect.Y;
}
else
{
int changeY = snappyY.Position - rect.Y;
rect.Y += changeY;
}
Canvas.SetTop(this, rect.Y);
Height = rect.Height;
}
Model.Zones[ZoneIndex] = rect;
}
private static int zIndex;
private const int MinZoneWidth = 64;
private const int MinZoneHeight = 72;
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
Canvas.SetZIndex(this, zIndex++);
base.OnPreviewMouseDown(e);
}
private void UniversalDragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (snappyX != null)
{
snappyX.Move((int)e.HorizontalChange);
}
if (snappyY != null)
{
snappyY.Move((int)e.VerticalChange);
}
UpdateFromSnappyHelpers();
}
// Corner dragging
private void Caption_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
snappyX = NewMagneticSnapper(true, ResizeMode.BothEdges);
snappyY = NewMagneticSnapper(false, ResizeMode.BothEdges);
}
public CanvasLayoutModel Model { get => model; set => model = value; }
public int ZoneIndex { get => zoneIndex; set => zoneIndex = value; }
public void FocusZone()
{
Keyboard.Focus(RootBorder);
}
private void NWResize_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
snappyX = NewMagneticSnapper(true, ResizeMode.BottomEdge);
snappyY = NewMagneticSnapper(false, ResizeMode.BottomEdge);
}
private void NEResize_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
snappyX = NewMagneticSnapper(true, ResizeMode.TopEdge);
snappyY = NewMagneticSnapper(false, ResizeMode.BottomEdge);
}
private void SWResize_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
snappyX = NewMagneticSnapper(true, ResizeMode.BottomEdge);
snappyY = NewMagneticSnapper(false, ResizeMode.TopEdge);
}
private void SEResize_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
snappyX = NewMagneticSnapper(true, ResizeMode.TopEdge);
snappyY = NewMagneticSnapper(false, ResizeMode.TopEdge);
}
// Edge dragging
private void NResize_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
snappyX = null;
snappyY = NewMagneticSnapper(false, ResizeMode.BottomEdge);
}
private void SResize_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
snappyX = null;
snappyY = NewMagneticSnapper(false, ResizeMode.TopEdge);
}
private void WResize_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
snappyX = NewMagneticSnapper(true, ResizeMode.BottomEdge);
snappyY = null;
}
private void EResize_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
snappyX = NewMagneticSnapper(true, ResizeMode.TopEdge);
snappyY = null;
}
private void OnClose(object sender, RoutedEventArgs e)
{
RemoveZone();
}
private void RemoveZone()
{
((Panel)Parent).Children.Remove(this);
Model.RemoveZoneAt(ZoneIndex);
}
private void Border_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Tab)
{
return;
}
e.Handled = true;
if (e.Key == Key.Delete)
{
RemoveZone();
return;
}
var moveValue = IsCtrlKeyDown() ? smallMoveAmount : defaultMoveAmount;
if (IsShiftKeyDown())
{
moveValue = Math.Max(1, moveValue / 2);
}
if (e.Key == Key.Right)
{
if (IsShiftKeyDown())
{
// Make the zone larger (width)
MoveZoneX(moveValue, ResizeMode.TopEdge, ResizeMode.BottomEdge);
MoveZoneX(-moveValue, ResizeMode.BottomEdge, ResizeMode.BottomEdge);
}
else
{
// Move zone right
MoveZoneX(moveValue, ResizeMode.BothEdges, ResizeMode.BothEdges);
}
}
else if (e.Key == Key.Left)
{
if (IsShiftKeyDown())
{
// Make the zone smaller (width)
MoveZoneX(-moveValue, ResizeMode.TopEdge, ResizeMode.BottomEdge);
MoveZoneX(moveValue, ResizeMode.BottomEdge, ResizeMode.BottomEdge);
}
else
{
// Move zone left
MoveZoneX(-moveValue, ResizeMode.BothEdges, ResizeMode.BothEdges);
}
}
else if (e.Key == Key.Up)
{
if (IsShiftKeyDown())
{
// Make the zone larger (height)
MoveZoneY(moveValue, ResizeMode.TopEdge, ResizeMode.BottomEdge);
MoveZoneY(-moveValue, ResizeMode.BottomEdge, ResizeMode.BottomEdge);
}
else
{
// Move zone up
MoveZoneY(-moveValue, ResizeMode.BothEdges, ResizeMode.BothEdges);
}
}
else if (e.Key == Key.Down)
{
if (IsShiftKeyDown())
{
// Make the zone smaller (height)
MoveZoneY(-moveValue, ResizeMode.TopEdge, ResizeMode.BottomEdge);
MoveZoneY(moveValue, ResizeMode.BottomEdge, ResizeMode.BottomEdge);
}
else
{
// Move zone down
MoveZoneY(moveValue, ResizeMode.BothEdges, ResizeMode.BothEdges);
}
}
}
private void MoveZoneX(int value, ResizeMode top, ResizeMode bottom)
{
snappyX = NewNonMagneticSnapper(true, top);
snappyY = NewNonMagneticSnapper(false, bottom);
snappyX.Move(value);
UpdateFromSnappyHelpers();
}
private void MoveZoneY(int value, ResizeMode top, ResizeMode bottom)
{
snappyX = NewNonMagneticSnapper(true, bottom);
snappyY = NewNonMagneticSnapper(false, top);
snappyY.Move(value);
UpdateFromSnappyHelpers();
}
private bool IsShiftKeyDown()
{
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{
return true;
}
else
{
return false;
}
}
private bool IsCtrlKeyDown()
{
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{
return true;
}
else
{
return false;
}
}
private void Border_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
// Set (keyboard)focus on this zone when click
Border selectedBorder = sender as Border;
selectedBorder.Focus();
Keyboard.Focus(selectedBorder);
}
}
}