Renaming Viewports back to Paths

This commit is contained in:
Terry MacDonald 2020-10-07 20:08:36 +13:00
parent f0088d08e2
commit 8c4604bc58
9 changed files with 258 additions and 58 deletions

View File

@ -63,9 +63,9 @@
<Compile Include="ProfileRepository.cs" />
<Compile Include="TaskBarSettings.cs" />
<Compile Include="TaskBarStuckRectangle.cs" />
<Compile Include="Topology\ProfileViewport.cs" />
<Compile Include="Topology\ProfileViewportHelper.cs" />
<Compile Include="Topology\ProfileViewportTargetDisplay.cs" />
<Compile Include="Topology\Path.cs" />
<Compile Include="Topology\PathHelper.cs" />
<Compile Include="Topology\PathTarget.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources\Language.Designer.cs">
<DependentUpon>Language.resx</DependentUpon>

View File

@ -28,7 +28,7 @@ namespace HeliosPlus.Shared
// ReSharper disable once TooManyArguments
public static RectangleF CalculateViewSize(
ProfileViewport[] paths,
Path[] paths,
bool withPadding = false,
int paddingX = 0,
int paddingY = 0)
@ -71,7 +71,7 @@ namespace HeliosPlus.Shared
return resolution;
}
public static Size NormalizeResolution(ProfileViewport path)
public static Size NormalizeResolution(Path path)
{
var biggest = Size.Empty;
@ -144,7 +144,7 @@ namespace HeliosPlus.Shared
public Bitmap ToTightestBitmap(int width = 256, int height = 0, PixelFormat format = PixelFormat.Format32bppArgb)
{
var viewSize = CalculateViewSize(_profile.Viewports, true, PaddingX, PaddingY);
var viewSize = CalculateViewSize(_profile.Paths, true, PaddingX, PaddingY);
int viewSizeRatio = Convert.ToInt32(viewSize.Width / viewSize.Height);
if (height == 0)
@ -200,7 +200,7 @@ namespace HeliosPlus.Shared
return bitmap;*/
var viewSize = CalculateViewSize(_profile.Viewports, true, PaddingX, PaddingY);
var viewSize = CalculateViewSize(_profile.Paths, true, PaddingX, PaddingY);
var width = bitmap.Width * 0.7f;
var height = width / viewSize.Width * viewSize.Height;
@ -303,7 +303,7 @@ namespace HeliosPlus.Shared
return multiIcon;
}
private void DrawPath(Graphics g, ProfileViewport path)
private void DrawPath(Graphics g, Path path)
{
var res = NormalizeResolution(path);
var rect = new Rectangle(path.Position, res);
@ -325,8 +325,8 @@ namespace HeliosPlus.Shared
// ReSharper disable once TooManyArguments
private void DrawTarget(
Graphics g,
ProfileViewport path,
ProfileViewportTargetDisplay target,
Path path,
PathTarget target,
Rectangle rect,
int row,
int col,
@ -361,7 +361,7 @@ namespace HeliosPlus.Shared
private void DrawView(Graphics g, float width, float height)
{
var viewSize = CalculateViewSize(_profile.Viewports, true, PaddingX, PaddingY);
var viewSize = CalculateViewSize(_profile.Paths, true, PaddingX, PaddingY);
var standPadding = height * 0.005f;
height -= standPadding * 8;
var factor = Math.Min((width - 2 * standPadding - 1) / viewSize.Width,
@ -398,7 +398,7 @@ namespace HeliosPlus.Shared
viewSize.Width, viewSize.Height);
}
foreach (var path in _profile.Viewports)
foreach (var path in _profile.Paths)
{
DrawPath(g, path);
}

View File

@ -160,8 +160,8 @@ namespace HeliosPlus.Shared
public string Name { get; set; }
public Topology.Path[] Viewports { get; set; } = new Topology.Path[0];
public Topology.Path[] Paths { get; set; } = new Topology.Path[0];
[JsonIgnore]
public ProfileIcon ProfileIcon
{
@ -269,7 +269,7 @@ namespace HeliosPlus.Shared
public bool IsValid()
{
if (Viewports != null &&
if (Paths != null &&
ProfileIcon is Bitmap &&
File.Exists(SavedProfileIconCacheFilename) &&
ProfileBitmap is Bitmap &&
@ -292,7 +292,7 @@ namespace HeliosPlus.Shared
// Copy all our profile data over to the other profile
profile.Name = Name;
profile.Viewports = Viewports;
profile.Paths = Paths;
profile.ProfileIcon = ProfileIcon;
profile.SavedProfileIconCacheFilename = SavedProfileIconCacheFilename;
profile.ProfileBitmap = ProfileBitmap;
@ -340,7 +340,7 @@ namespace HeliosPlus.Shared
// We need to exclude the name as the name is solely for saving to disk
// and displaying to the user.
// Two profiles are equal only when they have the same viewport data
if (Viewports.SequenceEqual(other.Viewports))
if (Paths.SequenceEqual(other.Paths))
return true;
else
return false;
@ -352,7 +352,7 @@ namespace HeliosPlus.Shared
{
// Get hash code for the Viewports field if it is not null.
int hashViewports = Viewports == null ? 0 : Viewports.GetHashCode();
int hashViewports = Paths == null ? 0 : Paths.GetHashCode();
//Calculate the hash code for the product.
return hashViewports;
@ -396,7 +396,7 @@ namespace HeliosPlus.Shared
// We need to exclude the name as the name is solely for saving to disk
// and displaying to the user.
// Two profiles are equal only when they have the same viewport data
if (x.Viewports.Equals(y.Viewports))
if (x.Paths.Equals(y.Paths))
return true;
else
return false;
@ -411,7 +411,7 @@ namespace HeliosPlus.Shared
if (Object.ReferenceEquals(profile, null)) return 0;
// Get hash code for the Viewports field if it is not null.
int hashViewports = profile.Viewports == null ? 0 : profile.Viewports.GetHashCode();
int hashViewports = profile.Paths == null ? 0 : profile.Paths.GetHashCode();
//Calculate the hash code for the product.
return hashViewports;

View File

@ -26,7 +26,7 @@ using System.Resources;
using System.Net.NetworkInformation;
using NvAPIWrapper.Mosaic;
using NvAPIWrapper.Native.Mosaic;
using PathInfos = HeliosPlus.Shared.Topology.PathInfo;
using HeliosPlus.Shared.Topology;
namespace HeliosPlus.Shared
@ -359,7 +359,7 @@ namespace HeliosPlus.Shared
ProfileItem activeProfile = new ProfileItem
{
Name = "Current Display Profile",
Viewports = PathInfo.GetActivePaths().Select(info => new Path(info)).ToArray()
Paths = PathInfo.GetActivePaths().Select(info => new HeliosPlus.Shared.Topology.Path(info)).ToArray()
};
activeProfile.ProfileIcon = new ProfileIcon(activeProfile);
@ -460,7 +460,7 @@ namespace HeliosPlus.Shared
ProfileItem myCurrentProfile = new ProfileItem
{
Name = "Current Display Profile",
Viewports = PathInfo.GetActivePaths().Select(info => new Path(info)).ToArray()
Paths = PathInfo.GetActivePaths().Select(info => new HeliosPlus.Shared.Topology.Path(info)).ToArray()
};
_currentProfile = myCurrentProfile;
@ -485,7 +485,7 @@ namespace HeliosPlus.Shared
ProfileItem myCurrentProfile = new ProfileItem
{
Name = "Current Display Profile",
Viewports = PathInfo.GetActivePaths().Select(info => new Path(info)).ToArray()
Paths = PathInfo.GetActivePaths().Select(info => new HeliosPlus.Shared.Topology.Path(info)).ToArray()
};
_currentProfile = myCurrentProfile;
@ -836,7 +836,7 @@ namespace HeliosPlus.Shared
try
{
var surroundTopologies =
profile.Viewports.SelectMany(viewport => viewport.TargetDisplays)
profile.Paths.SelectMany(viewport => viewport.TargetDisplays)
.Select(target => target.SurroundTopology)
.Where(topology => topology != null)
.Select(topology => topology.ToGridTopology())
@ -878,13 +878,23 @@ namespace HeliosPlus.Shared
try
{
// If Nvidia then we need to handle NVidia style
var pathInfos = profile.Viewports.Select(viewport => viewport.ToPathInfo()).Where(info => info != null).ToArray();
var test = new NvAPIWrapper.Display.PathInfo;
var v2obj = test.GetPathInfoV2();
WindowsDisplayAPI.DisplayConfig.PathInfo.ApplyPathInfos(pathInfos, true, true, true);
/*var viewports = profile.Viewports;
foreach (var viewport in viewports)
{
var vpPathInfo = viewport.ToPathInfo();
}*/
var pathInfos = profile.Paths.Select(viewport => viewport.ToPathInfo()).Where(info => info != null).ToArray();
//var PathInfos2 = NvAPIWrapper.Display.PathInfo.GetDisplaysConfig();
/*if (!pathInfos.Any())
{
throw new InvalidOperationException(
@"Display configuration changed since this profile is created. Please re-create this profile.");
}*/
//var PathInfo2 = WindowsDisplayAPI.DisplayConfig.PathInfo.GetActivePaths();
PathInfo.ApplyPathInfos(pathInfos, true, true, true);
return true;
}
catch (Exception ex)

View File

@ -0,0 +1,186 @@
using System;
using System.Drawing;
using System.Linq;
using WindowsDisplayAPI.DisplayConfig;
using WindowsDisplayAPI.Native.DisplayConfig;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Collections.Generic;
namespace HeliosPlus.Shared.Topology
{
public class Path
{
public Path(PathInfo pathInfo)
{
SourceId = pathInfo.DisplaySource.SourceId;
PixelFormat = pathInfo.PixelFormat;
Position = pathInfo.Position;
Resolution = pathInfo.Resolution;
TargetDisplays = pathInfo.TargetsInfo.Select(targetDisplay => new PathTarget(targetDisplay)).ToArray();
}
public Path()
{
}
[JsonConverter(typeof(StringEnumConverter))]
public DisplayConfigPixelFormat PixelFormat { get; set; }
public Point Position { get; set; }
public Size Resolution { get; set; }
public uint SourceId { get; set; }
public PathTarget[] TargetDisplays { get; set; }
public override string ToString()
{
return $"\\\\.\\DISPLAY{SourceId}";
}
public PathInfo ToPathInfo()
{
var targetDisplays = TargetDisplays.Select(target => target.ToPathTargetInfo()).Where(info => info != null).ToArray();
if (targetDisplays.Any())
{
return new PathInfo(new PathDisplaySource(targetDisplays.First().DisplayTarget.Adapter, SourceId), Position,
Resolution, PixelFormat, targetDisplays);
}
return null;
}
// The public override for the Object.Equals
public override bool Equals(object obj)
{
return this.Equals(obj as Path);
}
// Profiles are equal if their contents (except name) are equal
public bool Equals(Path other)
{
// If parameter is null, return false.
if (Object.ReferenceEquals(other, null))
return false;
// Optimization for a common success case.
if (Object.ReferenceEquals(this, other))
return true;
// If run-time types are not exactly the same, return false.
if (this.GetType() != other.GetType())
return false;
// Check whether the Profile Viewport properties are equal
// Two profiles are equal only when they have the same viewport data exactly
if (PixelFormat == other.PixelFormat &&
Position.Equals(other.Position) &&
Resolution.Equals(other.Resolution) &&
SourceId == other.SourceId)
{
// If the above all match, then we need to check the DisplayTargets
foreach (PathTarget targetDisplay in TargetDisplays)
{
if (!other.TargetDisplays.Contains(targetDisplay))
return false;
}
return true;
}
else
return false;
}
// If Equals() returns true for this object compared to another
// then GetHashCode() must return the same value for these objects.
public override int GetHashCode()
{
// Get hash code for the PixelFormat field if it is not null.
int hashPixelFormat = PixelFormat.GetHashCode();
// Get hash code for the Position field if it is not null.
int hashPosition = Position == null ? 0 : Position.GetHashCode();
// Get hash code for the Resolution field if it is not null.
int hashResolution = Resolution == null ? 0 : Resolution.GetHashCode();
// Get hash code for the SourceId field if it is not null.
int hashSourceId = SourceId.GetHashCode();
// Get hash code for the TargetDisplays field if it is not null.
int hashTargetDisplays = TargetDisplays == null ? 0 : TargetDisplays.GetHashCode();
//Calculate the hash code for the product.
return hashPixelFormat ^ hashPosition ^ hashResolution ^ hashSourceId ^ hashTargetDisplays;
}
}
// Custom comparer for the ProfileViewport class
class ProfileViewportComparer : IEqualityComparer<Path>
{
// Products are equal if their names and product numbers are equal.
public bool Equals(Path x, Path y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
// Check whether the Profile Viewport properties are equal
// Two profiles are equal only when they have the same viewport data exactly
if (x.PixelFormat == y.PixelFormat &&
x.Position.Equals(y.Position) &&
x.Resolution.Equals(y.Resolution) &&
x.SourceId == y.SourceId)
{
// If the above all match, then we need to check the DisplayTargets
// If they aren't equal then we need to return false;
if (!x.TargetDisplays.SequenceEqual(y.TargetDisplays))
return false;
else
return true;
/* foreach (ProfileViewportTargetDisplay xTargetDisplay in x.TargetDisplays)
{
if (!y.TargetDisplays.Contains(xTargetDisplay))
return false;
}*/
//return true;
}
else
return false;
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public int GetHashCode(Path profileViewport)
{
// Check whether the object is null
if (Object.ReferenceEquals(profileViewport, null)) return 0;
// Get hash code for the PixelFormat field if it is not null.
int hashPixelFormat = profileViewport.PixelFormat.GetHashCode();
// Get hash code for the Position field if it is not null.
int hashPosition = profileViewport.Position == null ? 0 : profileViewport.Position.GetHashCode();
// Get hash code for the Resolution field if it is not null.
int hashResolution = profileViewport.Resolution == null ? 0 : profileViewport.Resolution.GetHashCode();
// Get hash code for the SourceId field if it is not null.
int hashSourceId = profileViewport.SourceId.GetHashCode();
// Get hash code for the TargetDisplays field if it is not null.
int hashTargetDisplays = profileViewport.TargetDisplays == null ? 0 : profileViewport.TargetDisplays.GetHashCode();
//Calculate the hash code for the product.
return hashPixelFormat ^ hashPosition ^ hashResolution ^ hashSourceId ^ hashTargetDisplays;
}
}
}

View File

@ -2,7 +2,7 @@
namespace HeliosPlus.Shared.Topology
{
internal static class ProfileViewportHelper
internal static class PathHelper
{
public static DisplayConfigRotation ToDisplayConfigRotation(this Rotation rotation)
{

View File

@ -8,9 +8,9 @@ using System.Collections.Generic;
namespace HeliosPlus.Shared.Topology
{
public class ProfileViewportTargetDisplay : IEquatable<ProfileViewportTargetDisplay>
public class PathTarget : IEquatable<PathTarget>
{
public ProfileViewportTargetDisplay(PathTargetInfo targetInfo, SurroundTopology surround = null)
public PathTarget(PathTargetInfo targetInfo, SurroundTopology surround = null)
{
DevicePath = targetInfo.DisplayTarget.DevicePath;
var index = DevicePath.IndexOf("{", StringComparison.InvariantCultureIgnoreCase);
@ -38,7 +38,7 @@ namespace HeliosPlus.Shared.Topology
}
public ProfileViewportTargetDisplay()
public PathTarget()
{
}
@ -74,6 +74,10 @@ namespace HeliosPlus.Shared.Topology
target => target.DevicePath.StartsWith(DevicePath,
StringComparison.InvariantCultureIgnoreCase));
// TODO fix - Trying to allow NVIDIA surround to non-NVIDIA surround move and doesnt work.
/* var targetDevice =
PathDisplayTarget.GetDisplayTargets().FirstOrDefault();*/
if (targetDevice == null)
{
return null;
@ -87,11 +91,11 @@ namespace HeliosPlus.Shared.Topology
// The public override for the Object.Equals
public override bool Equals(object obj)
{
return this.Equals(obj as ProfileViewportTargetDisplay);
return this.Equals(obj as PathTarget);
}
// Profiles are equal if their contents (except name) are equal
public bool Equals(ProfileViewportTargetDisplay other)
public bool Equals(PathTarget other)
{
// If parameter is null, return false.
@ -164,10 +168,10 @@ namespace HeliosPlus.Shared.Topology
}
// Custom comparer for the ProfileViewportTargetDisplay class
class ProfileViewportTargetDisplayComparer : IEqualityComparer<ProfileViewportTargetDisplay>
class ProfileViewportTargetDisplayComparer : IEqualityComparer<PathTarget>
{
// Products are equal if their names and product numbers are equal.
public bool Equals(ProfileViewportTargetDisplay x, ProfileViewportTargetDisplay y)
public bool Equals(PathTarget x, PathTarget y)
{
//Check whether the compared objects reference the same data.
@ -204,7 +208,7 @@ namespace HeliosPlus.Shared.Topology
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public int GetHashCode(ProfileViewportTargetDisplay profileViewport)
public int GetHashCode(PathTarget profileViewport)
{
// Check whether the object is null
if (Object.ReferenceEquals(profileViewport, null)) return 0;

View File

@ -38,7 +38,7 @@ namespace HeliosPlus.Shared.UserControls
}
}
private void DrawPath(Graphics g, ProfileViewport path)
private void DrawPath(Graphics g, Path path)
{
var res = ProfileIcon.NormalizeResolution(path);
var rect = new Rectangle(path.Position, res);
@ -89,7 +89,7 @@ namespace HeliosPlus.Shared.UserControls
return new Size((int) stringSize.Width, (int) stringSize.Height);
}
private void DrawSurroundTopology(Graphics g, ProfileViewportTargetDisplay target, Rectangle rect)
private void DrawSurroundTopology(Graphics g, PathTarget target, Rectangle rect)
{
g.DrawRectangle(Pens.Black, rect);
@ -144,8 +144,8 @@ namespace HeliosPlus.Shared.UserControls
private void DrawTarget(
Graphics g,
ProfileViewport path,
ProfileViewportTargetDisplay target,
Path path,
PathTarget target,
Rectangle rect,
int row,
int col,
@ -220,7 +220,7 @@ namespace HeliosPlus.Shared.UserControls
private void DrawView(Graphics g)
{
var viewSize = ProfileIcon.CalculateViewSize(_profile.Viewports, true, PaddingX, PaddingY);
var viewSize = ProfileIcon.CalculateViewSize(_profile.Paths, true, PaddingX, PaddingY);
var factor = Math.Min(Width / viewSize.Width, Height / viewSize.Height);
g.ScaleTransform(factor, factor);
@ -228,7 +228,7 @@ namespace HeliosPlus.Shared.UserControls
var yOffset = (Height / factor - viewSize.Height) / 2f;
g.TranslateTransform(-viewSize.X + xOffset, -viewSize.Y + yOffset);
foreach (var path in _profile.Viewports)
foreach (var path in _profile.Paths)
{
DrawPath(g, path);
}

View File

@ -30,7 +30,7 @@ namespace HeliosPlus
}
}
public DisplayRepresentation(ProfileViewportTargetDisplay display)
public DisplayRepresentation(PathTarget display)
{
Name = display.DisplayName;
Path = display.DevicePath;
@ -60,7 +60,7 @@ namespace HeliosPlus
if (profile != null)
{
foreach (var target in profile.Viewports.SelectMany(path => path.TargetDisplays))
foreach (var target in profile.Paths.SelectMany(path => path.TargetDisplays))
{
if (displays.All(display => display.Path != target.DevicePath))
{
@ -77,14 +77,14 @@ namespace HeliosPlus
return Display.GetDisplays().FirstOrDefault(display => display.DevicePath.StartsWith(Path));
}
public ProfileViewport GetPathSource(ProfileItem profile)
public Path GetPathSource(ProfileItem profile)
{
return profile.Viewports.FirstOrDefault(path => path.TargetDisplays.Any(target => target.DevicePath == Path));
return profile.Paths.FirstOrDefault(path => path.TargetDisplays.Any(target => target.DevicePath == Path));
}
public ProfileViewportTargetDisplay GetPathTarget(ProfileItem profile)
public PathTarget GetPathTarget(ProfileItem profile)
{
return profile.Viewports.SelectMany(path => path.TargetDisplays).FirstOrDefault(target => target.DevicePath == Path);
return profile.Paths.SelectMany(path => path.TargetDisplays).FirstOrDefault(target => target.DevicePath == Path);
}
public PathDisplayTarget GetTargetInfo()
@ -115,14 +115,14 @@ namespace HeliosPlus
}
}
var p = new ProfileItem {Viewports = new ProfileViewport[1]};
p.Viewports[0] = new ProfileViewport
var p = new ProfileItem {Paths = new Path[1]};
p.Paths[0] = new Path
{
Resolution = resolution,
Position = new Point(),
TargetDisplays = new ProfileViewportTargetDisplay[1]
TargetDisplays = new PathTarget[1]
};
p.Viewports[0].TargetDisplays[0] = new ProfileViewportTargetDisplay {DevicePath = Path};
p.Paths[0].TargetDisplays[0] = new PathTarget {DevicePath = Path};
if (profile != null)
{
@ -130,7 +130,7 @@ namespace HeliosPlus
if (targetPath != null)
{
p.Viewports[0].TargetDisplays[0].SurroundTopology = targetPath.SurroundTopology;
p.Paths[0].TargetDisplays[0].SurroundTopology = targetPath.SurroundTopology;
}
}