mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
[WIP] Remaking Equals and Contains for Profiles
The existing comparisons didn't work well, and my earlier changes didn't help at all. Decided to recreate them from Microsoft's latest documentation. Nearly completed it but need to finish off SurroundTopoly and do proper testing.
This commit is contained in:
@ -9,6 +9,7 @@ using System.Windows.Forms;
|
||||
using WindowsDisplayAPI.DisplayConfig;
|
||||
using HeliosPlus.Shared.Resources;
|
||||
using Newtonsoft.Json;
|
||||
//using NvAPIWrapper.Display;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.Mosaic;
|
||||
using NvAPIWrapper.Native.Mosaic;
|
||||
@ -16,17 +17,20 @@ using HeliosPlus.Shared.Topology;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using WindowsDisplayAPI;
|
||||
using WindowsDisplayAPI.DisplayConfig;
|
||||
using WindowsDisplayAPI.Native.DisplayConfig;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace HeliosPlus.Shared
|
||||
{
|
||||
public class Profile : IEquatable<Profile>
|
||||
public class Profile
|
||||
{
|
||||
private static Profile _currentProfile;
|
||||
private static List<Profile> _allSavedProfiles = new List<Profile>();
|
||||
private ProfileIcon _profileIcon;
|
||||
private Bitmap _profileBitmap;
|
||||
private static List<Display> _availableDisplays;
|
||||
private static List<UnAttachedDisplay> _unavailableDisplays;
|
||||
|
||||
internal static string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "HeliosPlus");
|
||||
|
||||
@ -122,8 +126,10 @@ namespace HeliosPlus.Shared
|
||||
get
|
||||
{
|
||||
|
||||
// Firstly check which displays are attached to this computer
|
||||
_availableDisplays = Display.GetDisplays().ToList();
|
||||
|
||||
// Firstly check which displays are attached to this computer and are on
|
||||
/* _availableDisplays = Display.GetDisplays().ToList();
|
||||
_unavailableDisplays = UnAttachedDisplay.GetUnAttachedDisplays().ToList();
|
||||
// DevicePath "\\\\?\\DISPLAY#DELD065#5&38860457&0&UID4609#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}"
|
||||
List<string> availableDevicePath = new List<string>();
|
||||
foreach (Display aDisplay in _availableDisplays)
|
||||
@ -136,40 +142,41 @@ namespace HeliosPlus.Shared
|
||||
availableDevicePath.Add(devicePathMatches.Groups[1].Value.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (availableDevicePath.Count > 0)
|
||||
*/
|
||||
/* if (availableDevicePath.Count > 0)
|
||||
{
|
||||
|
||||
int profileDisplaysCount = 0;
|
||||
int profileDisplaysFoundCount = 0;
|
||||
// Then go through the displays in the profile and check they're live
|
||||
foreach (ProfileViewport profileViewport in Viewports)
|
||||
*/
|
||||
List<string> unavailableDeviceNames = new List<string>();
|
||||
// Then go through the displays in the profile and check they're live
|
||||
foreach (ProfileViewport profileViewport in Viewports)
|
||||
{
|
||||
foreach (ProfileViewportTargetDisplay profileViewportTargetDisplay in profileViewport.TargetDisplays)
|
||||
{
|
||||
foreach (ProfileViewportTargetDisplay profileViewportTargetDisplay in profileViewport.TargetDisplays)
|
||||
{
|
||||
profileDisplaysCount++;
|
||||
if (profileViewportTargetDisplay.DevicePath.Equals(availableDevicePath));
|
||||
profileDisplaysFoundCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (profileDisplaysCount == profileDisplaysFoundCount)
|
||||
{
|
||||
// If we found all our profile displays in the available displays!
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
PathTargetInfo viewportTargetInfo = profileViewportTargetDisplay.ToPathTargetInfo();
|
||||
bool isAvailable = viewportTargetInfo.DisplayTarget != null ? viewportTargetInfo.DisplayTarget.IsAvailable : false;
|
||||
if (!viewportTargetInfo.DisplayTarget.IsAvailable)
|
||||
unavailableDeviceNames.Add(profileViewportTargetDisplay.DisplayName);
|
||||
}
|
||||
}
|
||||
|
||||
if (unavailableDeviceNames.Count > 0)
|
||||
{
|
||||
// Darn - there was at least one unavilable displaytarget
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// There were no unavailable DisplayTargets!
|
||||
return true;
|
||||
}
|
||||
/* }
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// This should include the ones not currently enabled.
|
||||
/* // This should include the ones not currently enabled.
|
||||
var displayAdapters = DisplayAdapter.GetDisplayAdapters().ToArray();
|
||||
var displays = Display.GetDisplays().ToArray();
|
||||
|
||||
@ -178,7 +185,13 @@ namespace HeliosPlus.Shared
|
||||
var displayDevices = physicalGPUs[0].GetDisplayDevices().ToArray();
|
||||
return true;
|
||||
|
||||
/*var surroundTopologies =
|
||||
|
||||
GridTopology.ValidateGridTopologies(
|
||||
SurroundTopologies.Select(topology => topology.ToGridTopology()).ToArray(),
|
||||
SetDisplayTopologyFlag.MaximizePerformance);
|
||||
|
||||
// Check if we are using NVIDIA surround in this profile
|
||||
var surroundTopologies =
|
||||
Viewports.SelectMany(path => path.TargetDisplays)
|
||||
.Select(target => target.SurroundTopology)
|
||||
.Where(topology => topology != null).ToArray();
|
||||
@ -296,66 +309,6 @@ namespace HeliosPlus.Shared
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(Profile other)
|
||||
{
|
||||
//if the other profile points to null, it's not equal
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//if the other profile is the same object, it's equal
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//return Paths.All(path => other.Paths.Contains(path));
|
||||
if (Viewports.Length != other.Viewports.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int thisToOtherViewportCount = 0;
|
||||
int otherToThisViewportCount = 0;
|
||||
|
||||
foreach (ProfileViewport myProfileViewport in Viewports)
|
||||
{
|
||||
foreach (ProfileViewport otherProfileViewport in other.Viewports)
|
||||
{
|
||||
if (myProfileViewport.Equals(otherProfileViewport))
|
||||
{
|
||||
thisToOtherViewportCount++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (ProfileViewport otherProfileViewport in other.Viewports)
|
||||
{
|
||||
foreach (ProfileViewport myProfileViewport in Viewports)
|
||||
{
|
||||
if (myProfileViewport.Equals(otherProfileViewport))
|
||||
{
|
||||
otherToThisViewportCount++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (thisToOtherViewportCount == otherToThisViewportCount)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IEnumerable<Profile> LoadAllProfiles()
|
||||
{
|
||||
|
||||
@ -402,7 +355,7 @@ namespace HeliosPlus.Shared
|
||||
loadedProfile.ProfileIcon = new ProfileIcon(loadedProfile);
|
||||
loadedProfile.ProfileBitmap = loadedProfile.ProfileIcon.ToBitmap(128,128);
|
||||
|
||||
if (loadedProfile.Equals(myCurrentProfile)) {
|
||||
if (loadedProfile.IsActive) {
|
||||
_currentProfile = loadedProfile;
|
||||
}
|
||||
|
||||
@ -433,18 +386,6 @@ namespace HeliosPlus.Shared
|
||||
return _allSavedProfiles;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static bool operator ==(Profile left, Profile right)
|
||||
{
|
||||
return Equals(left, right) || left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
public static bool operator !=(Profile left, Profile right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
public static bool IsValidName(string testName)
|
||||
{
|
||||
foreach (Profile loadedProfile in _allSavedProfiles)
|
||||
@ -474,7 +415,11 @@ namespace HeliosPlus.Shared
|
||||
|
||||
public static void RefreshActiveStatus()
|
||||
{
|
||||
//_currentProfile = null;
|
||||
_currentProfile = new Profile
|
||||
{
|
||||
Name = "Current Display Profile",
|
||||
Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
public static bool SaveAllProfiles()
|
||||
@ -541,37 +486,53 @@ namespace HeliosPlus.Shared
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
// The public override for the Object.Equals
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((Profile) obj);
|
||||
return this.Equals(obj as Profile);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
// Profiles are equal if their contents (except name) are equal
|
||||
public bool Equals(Profile 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 profiles' properties are equal
|
||||
// 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.Equals(other.Viewports))
|
||||
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()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (Viewports?.GetHashCode() ?? 0) * 397;
|
||||
}
|
||||
|
||||
// Get hash code for the Viewports field if it is not null.
|
||||
int hashViewports = Viewports == null ? 0 : Viewports.GetHashCode();
|
||||
|
||||
//Calculate the hash code for the product.
|
||||
return hashViewports;
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return (Name ?? Language.UN_TITLED_PROFILE) + (IsActive ? " " + Language._Active_ : "");
|
||||
@ -606,10 +567,12 @@ namespace HeliosPlus.Shared
|
||||
{
|
||||
try
|
||||
{
|
||||
// Wait 20 seconds
|
||||
Thread.Sleep(2000);
|
||||
|
||||
try
|
||||
{
|
||||
// Get an array of the valid NVIDAI surround topologies
|
||||
var surroundTopologies =
|
||||
Viewports.SelectMany(path => path.TargetDisplays)
|
||||
.Select(target => target.SurroundTopology)
|
||||
@ -617,8 +580,11 @@ namespace HeliosPlus.Shared
|
||||
.Select(topology => topology.ToGridTopology())
|
||||
.ToArray();
|
||||
|
||||
// See if we have any surroundTopologies specified!
|
||||
if (surroundTopologies.Length == 0)
|
||||
{
|
||||
// if we do not have surroundTopopligies specified then
|
||||
// Figure out how to lay out the standard windows displays
|
||||
var currentTopologies = GridTopology.GetGridTopologies();
|
||||
|
||||
if (currentTopologies.Any(topology => topology.Rows * topology.Columns > 1))
|
||||
@ -629,10 +595,11 @@ namespace HeliosPlus.Shared
|
||||
.Select(displays => new GridTopology(1, 1, new[] {displays}))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (surroundTopologies.Length > 0)
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we DO have surroundTopopligies specified then
|
||||
// Figure out how to turn them on
|
||||
GridTopology.SetGridTopologies(surroundTopologies, SetDisplayTopologyFlag.MaximizePerformance);
|
||||
}
|
||||
}
|
||||
@ -641,17 +608,25 @@ namespace HeliosPlus.Shared
|
||||
// ignored
|
||||
}
|
||||
|
||||
// Wait 18 seconds
|
||||
Thread.Sleep(18000);
|
||||
var pathInfos = Viewports.Select(path => path.ToPathInfo()).Where(info => info != null).ToArray();
|
||||
|
||||
if (!pathInfos.Any())
|
||||
// Check to see what Viewports we have enabled
|
||||
var ViewportsPathInfo = Viewports.Select(path => path.ToPathInfo()).Where(info => info != null).ToArray();
|
||||
|
||||
// If we don't have any
|
||||
if (!ViewportsPathInfo.Any())
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
@"Display configuration changed since this profile is created. Please re-create this profile.");
|
||||
}
|
||||
|
||||
PathInfo.ApplyPathInfos(pathInfos, true, true, true);
|
||||
// Apply the new screen configuration
|
||||
PathInfo.ApplyPathInfos(ViewportsPathInfo, true, true, true);
|
||||
// Wait 10 seconds
|
||||
Thread.Sleep(10000);
|
||||
|
||||
// Check o see what our current screen profile is now!
|
||||
RefreshActiveStatus();
|
||||
|
||||
return true;
|
||||
@ -665,21 +640,48 @@ namespace HeliosPlus.Shared
|
||||
}
|
||||
}
|
||||
|
||||
public Profile Clone()
|
||||
}
|
||||
|
||||
// Custom comparer for the Profile class
|
||||
// Allows us to use 'Contains'
|
||||
class ProfileComparer : IEqualityComparer<Profile>
|
||||
{
|
||||
// Products are equal if their names and product numbers are equal.
|
||||
public bool Equals(Profile x, Profile y)
|
||||
{
|
||||
try
|
||||
{
|
||||
var serialized = JsonConvert.SerializeObject(this);
|
||||
|
||||
var cloned = JsonConvert.DeserializeObject<Profile>(serialized);
|
||||
cloned.Id = Guid.NewGuid().ToString("B");
|
||||
//Check whether the compared objects reference the same data.
|
||||
if (Object.ReferenceEquals(x, y)) return true;
|
||||
|
||||
return cloned;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
//Check whether any of the compared objects is null.
|
||||
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
|
||||
return false;
|
||||
|
||||
// Check whether the profiles' properties are equal
|
||||
// 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))
|
||||
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(Profile profile)
|
||||
{
|
||||
|
||||
// Check whether the object is null
|
||||
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();
|
||||
|
||||
//Calculate the hash code for the product.
|
||||
return hashViewports;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -5,10 +5,11 @@ using WindowsDisplayAPI.DisplayConfig;
|
||||
using WindowsDisplayAPI.Native.DisplayConfig;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace HeliosPlus.Shared.Topology
|
||||
{
|
||||
public class ProfileViewport : IEquatable<ProfileViewport>
|
||||
public class ProfileViewport
|
||||
{
|
||||
public ProfileViewport(PathInfo pathInfo)
|
||||
{
|
||||
@ -34,116 +35,6 @@ namespace HeliosPlus.Shared.Topology
|
||||
|
||||
public ProfileViewportTargetDisplay[] TargetDisplays { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(ProfileViewport other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PixelFormat == other.PixelFormat &&
|
||||
Position.Equals(other.Position) &&
|
||||
Resolution.Equals(other.Resolution) &&
|
||||
TargetDisplays.Length == other.TargetDisplays.Length)
|
||||
{
|
||||
// TODO fix this so it checks for exact match
|
||||
|
||||
//TargetDisplays.All(target => other.TargetDisplays.Contains(target));
|
||||
int thisToOtherTargetDisplayCount = 0;
|
||||
int otherToThisTargetDisplayCount = 0;
|
||||
|
||||
foreach (ProfileViewportTargetDisplay myProfileViewportTargetDisplay in TargetDisplays)
|
||||
{
|
||||
foreach (ProfileViewportTargetDisplay otherProfileViewportTargetDisplay in other.TargetDisplays)
|
||||
{
|
||||
if (myProfileViewportTargetDisplay.Equals(otherProfileViewportTargetDisplay))
|
||||
{
|
||||
thisToOtherTargetDisplayCount++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (ProfileViewportTargetDisplay otherProfileViewportTargetDisplay in other.TargetDisplays)
|
||||
{
|
||||
foreach (ProfileViewportTargetDisplay myProfileViewportTargetDisplay in TargetDisplays)
|
||||
{
|
||||
if (otherProfileViewportTargetDisplay.Equals(myProfileViewportTargetDisplay))
|
||||
{
|
||||
otherToThisTargetDisplayCount++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (thisToOtherTargetDisplayCount == otherToThisTargetDisplayCount)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static bool operator ==(ProfileViewport left, ProfileViewport right)
|
||||
{
|
||||
return Equals(left, right) || left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
public static bool operator !=(ProfileViewport left, ProfileViewport right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((ProfileViewport) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (int) PixelFormat;
|
||||
hashCode = (hashCode * 397) ^ Position.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ Resolution.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (TargetDisplays?.GetHashCode() ?? 0);
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"\\\\.\\DISPLAY{SourceId}";
|
||||
@ -161,5 +52,130 @@ namespace HeliosPlus.Shared.Topology
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// The public override for the Object.Equals
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return this.Equals(obj as ProfileViewport);
|
||||
}
|
||||
|
||||
// Profiles are equal if their contents (except name) are equal
|
||||
public bool Equals(ProfileViewport 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 (ProfileViewportTargetDisplay 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<ProfileViewport>
|
||||
{
|
||||
// Products are equal if their names and product numbers are equal.
|
||||
public bool Equals(ProfileViewport x, ProfileViewport 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
|
||||
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(ProfileViewport 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ using WindowsDisplayAPI.DisplayConfig;
|
||||
using HeliosPlus.Shared.NVIDIA;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace HeliosPlus.Shared.Topology
|
||||
{
|
||||
@ -58,99 +59,6 @@ namespace HeliosPlus.Shared.Topology
|
||||
|
||||
public SurroundTopology SurroundTopology { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(ProfileViewportTargetDisplay other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (FrequencyInMillihertz.Equals(other.FrequencyInMillihertz) &&
|
||||
Rotation.Equals(other.Rotation) &&
|
||||
Scaling.Equals(other.Scaling) &&
|
||||
ScanLineOrdering.Equals(other.ScanLineOrdering) &&
|
||||
DevicePath.Equals(other.DevicePath))
|
||||
{
|
||||
if (SurroundTopology == null)
|
||||
{
|
||||
if (other.SurroundTopology == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (other.SurroundTopology == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SurroundTopology.Equals(other.SurroundTopology);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool operator ==(ProfileViewportTargetDisplay left, ProfileViewportTargetDisplay right)
|
||||
{
|
||||
return Equals(left, right) || left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
public static bool operator !=(ProfileViewportTargetDisplay left, ProfileViewportTargetDisplay right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((ProfileViewportTargetDisplay) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = FrequencyInMillihertz.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) Rotation;
|
||||
hashCode = (hashCode * 397) ^ (int) Scaling;
|
||||
hashCode = (hashCode * 397) ^ (int) ScanLineOrdering;
|
||||
hashCode = (hashCode * 397) ^ DevicePath.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ SurroundTopology?.GetHashCode() ?? 0;
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
@ -175,5 +83,157 @@ namespace HeliosPlus.Shared.Topology
|
||||
FrequencyInMillihertz, ScanLineOrdering.ToDisplayConfigScanLineOrdering(),
|
||||
Rotation.ToDisplayConfigRotation(), Scaling.ToDisplayConfigScaling());
|
||||
}
|
||||
|
||||
// The public override for the Object.Equals
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return this.Equals(obj as ProfileViewportTargetDisplay);
|
||||
}
|
||||
|
||||
// Profiles are equal if their contents (except name) are equal
|
||||
public bool Equals(ProfileViewportTargetDisplay 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 (FrequencyInMillihertz == other.FrequencyInMillihertz &&
|
||||
Rotation.Equals(other.Rotation) &&
|
||||
Scaling.Equals(other.Scaling) &&
|
||||
ScanLineOrdering.Equals(other.ScanLineOrdering) &&
|
||||
DisplayName.Equals(other.DisplayName) &&
|
||||
DevicePath.Equals(other.DevicePath))
|
||||
{
|
||||
// If the above all match, then we need to check the SurroundTopology matches
|
||||
if (SurroundTopology == null && other.SurroundTopology == null)
|
||||
return true;
|
||||
else if (SurroundTopology != null && other.SurroundTopology == null)
|
||||
return false;
|
||||
else if (SurroundTopology == null && other.SurroundTopology != null)
|
||||
return false;
|
||||
else if (SurroundTopology.Equals(other.SurroundTopology))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
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 FrequencyInMillihertz field if it is not null.
|
||||
int hashFrequencyInMillihertz = FrequencyInMillihertz.GetHashCode();
|
||||
|
||||
// Get hash code for the Position field if it is not null.
|
||||
int hashRotation = Rotation.GetHashCode();
|
||||
|
||||
// Get hash code for the Scaling field if it is not null.
|
||||
int hashScaling = Scaling.GetHashCode();
|
||||
|
||||
// Get hash code for the ScanLineOrdering field if it is not null.
|
||||
int hashScanLineOrdering = ScanLineOrdering.GetHashCode();
|
||||
|
||||
// Get hash code for the hashDisplayName field if it is not null.
|
||||
int hashDisplayName = DisplayName == null ? 0 : DisplayName.GetHashCode();
|
||||
|
||||
// Get hash code for the DevicePath field if it is not null.
|
||||
int hashDevicePath = DevicePath == null ? 0 : DevicePath.GetHashCode();
|
||||
|
||||
// Get hash code for the SurroundTopology field if it is not null.
|
||||
int hashSurroundTopology = SurroundTopology == null ? 0 : SurroundTopology.GetHashCode();
|
||||
|
||||
//Calculate the hash code for the product.
|
||||
return hashFrequencyInMillihertz ^ hashRotation ^ hashScaling ^ hashScanLineOrdering ^
|
||||
hashDisplayName ^ hashDevicePath ^ hashSurroundTopology;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Custom comparer for the ProfileViewportTargetDisplay class
|
||||
class ProfileViewportTargetDisplayComparer : IEqualityComparer<ProfileViewportTargetDisplay>
|
||||
{
|
||||
// Products are equal if their names and product numbers are equal.
|
||||
public bool Equals(ProfileViewportTargetDisplay x, ProfileViewportTargetDisplay 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.FrequencyInMillihertz == y.FrequencyInMillihertz &&
|
||||
x.Rotation.Equals(y.Rotation) &&
|
||||
x.Scaling.Equals(y.Scaling) &&
|
||||
x.ScanLineOrdering.Equals(y.ScanLineOrdering) &&
|
||||
x.DisplayName.Equals(y.DisplayName) &&
|
||||
x.DevicePath.Equals(y.DevicePath))
|
||||
{
|
||||
// If the above all match, then we need to check the SurroundTopology matches
|
||||
if (x.SurroundTopology == null && y.SurroundTopology == null)
|
||||
return true;
|
||||
else if (x.SurroundTopology != null && y.SurroundTopology == null)
|
||||
return false;
|
||||
else if (x.SurroundTopology == null && y.SurroundTopology != null)
|
||||
return false;
|
||||
else if (x.SurroundTopology.Equals(y.SurroundTopology))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
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(ProfileViewportTargetDisplay profileViewport)
|
||||
{
|
||||
// Check whether the object is null
|
||||
if (Object.ReferenceEquals(profileViewport, null)) return 0;
|
||||
|
||||
// Get hash code for the FrequencyInMillihertz field if it is not null.
|
||||
int hashFrequencyInMillihertz = profileViewport.FrequencyInMillihertz.GetHashCode();
|
||||
|
||||
// Get hash code for the Position field if it is not null.
|
||||
int hashRotation = profileViewport.Rotation.GetHashCode();
|
||||
|
||||
// Get hash code for the Scaling field if it is not null.
|
||||
int hashScaling = profileViewport.Scaling.GetHashCode();
|
||||
|
||||
// Get hash code for the ScanLineOrdering field if it is not null.
|
||||
int hashScanLineOrdering = profileViewport.ScanLineOrdering.GetHashCode();
|
||||
|
||||
// Get hash code for the hashDisplayName field if it is not null.
|
||||
int hashDisplayName = profileViewport.DisplayName == null ? 0 : profileViewport.DisplayName.GetHashCode();
|
||||
|
||||
// Get hash code for the DevicePath field if it is not null.
|
||||
int hashDevicePath = profileViewport.DevicePath == null ? 0 : profileViewport.DevicePath.GetHashCode();
|
||||
|
||||
// Get hash code for the SurroundTopology field if it is not null.
|
||||
int hashSurroundTopology = profileViewport.SurroundTopology == null ? 0 : profileViewport.SurroundTopology.GetHashCode();
|
||||
|
||||
//Calculate the hash code for the product.
|
||||
return hashFrequencyInMillihertz ^ hashRotation ^ hashScaling ^ hashScanLineOrdering ^
|
||||
hashDisplayName ^ hashDevicePath ^ hashSurroundTopology;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -32,37 +32,28 @@ namespace HeliosPlus.UIForms
|
||||
|
||||
private void Apply_Click(object sender, EventArgs e)
|
||||
{
|
||||
/* if (dv_profile.Profile != null &&
|
||||
lv_profiles_old.SelectedIndices.Count > 0 &&
|
||||
lv_profiles_old.SelectedItems[0].Tag != null)
|
||||
if (!_selectedProfile.IsPossible)
|
||||
{
|
||||
if (!dv_profile.Profile.IsPossible)
|
||||
{
|
||||
MessageBox.Show(this, Language.This_profile_is_currently_impossible_to_apply,
|
||||
Language.Apply_Profile,
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
MessageBox.Show(this, Language.This_profile_is_currently_impossible_to_apply,
|
||||
Language.Apply_Profile,
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Enabled = false;
|
||||
Visible = false;
|
||||
if (
|
||||
new SplashForm(
|
||||
() =>
|
||||
{
|
||||
Task.Factory.StartNew(() => _selectedProfile.Apply(), TaskCreationOptions.LongRunning);
|
||||
}, 3, 30).ShowDialog(this) !=
|
||||
DialogResult.Cancel)
|
||||
{
|
||||
// nothing to do
|
||||
Console.WriteLine("Applying profile " + _selectedProfile.Name);
|
||||
}
|
||||
|
||||
if (
|
||||
new SplashForm(
|
||||
() =>
|
||||
{
|
||||
Task.Factory.StartNew(() => dv_profile.Profile.Apply(), TaskCreationOptions.LongRunning);
|
||||
}, 3, 30).ShowDialog(this) !=
|
||||
DialogResult.Cancel)
|
||||
{
|
||||
ReloadProfiles();
|
||||
}
|
||||
|
||||
Visible = true;
|
||||
Enabled = true;
|
||||
Activate();
|
||||
}*/
|
||||
Activate();
|
||||
}
|
||||
|
||||
private void Exit_Click(object sender, EventArgs e)
|
||||
@ -186,9 +177,10 @@ namespace HeliosPlus.UIForms
|
||||
// so we need to show the current profile
|
||||
// And finally we need to select the currentProfile, as it's the one we're using now
|
||||
newItem.Selected = true;
|
||||
ChangeSelectedProfile(Profile.CurrentProfile);
|
||||
}
|
||||
}
|
||||
ChangeSelectedProfile(Profile.CurrentProfile);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Reference in New Issue
Block a user