Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conflict highlight for selected row #3951

Merged
merged 1 commit into from Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Core/Relationships/RelationshipResolver.cs
Expand Up @@ -632,7 +632,7 @@ public IEnumerable<CkanModule> Recommendations(HashSet<CkanModule> dependencies)
public IEnumerable<string> ConflictDescriptions
=> conflicts.Where(kvp => kvp.Value == null
// Pick the pair with the least distantly selected one first
|| totalDependers(kvp.Key) < totalDependers(kvp.Value))
|| totalDependers(kvp.Key) <= totalDependers(kvp.Value))
.Select(kvp => string.Format(
Properties.Resources.RelationshipResolverConflictsWith,
conflictingModDescription(kvp.Key, null),
Expand Down
52 changes: 26 additions & 26 deletions GUI/Controls/ManageMods.cs
Expand Up @@ -178,45 +178,44 @@ private void ConflictsUpdated(Dictionary<GUIMod, string> prevConflicts)
Main.Instance.AddStatusMessage("");
}

var inst = Main.Instance.CurrentInstance;
var registry = RegistryManager.Instance(inst, repoData).registry;
if (prevConflicts != null)
{
// Mark old conflicts as non-conflicted
// (rows that are _still_ conflicted will be marked as such in the next loop)
var inst = Main.Instance.CurrentInstance;
foreach (GUIMod guiMod in prevConflicts.Keys)
{
DataGridViewRow row = mainModList.full_list_of_mod_rows[guiMod.Identifier];

foreach (DataGridViewCell cell in row.Cells)
{
cell.ToolTipText = null;
}
var registry = RegistryManager.Instance(Main.Instance.CurrentInstance, repoData).registry;
mainModList.ReapplyLabels(guiMod, false, inst.Name, inst.game, registry);
if (row.Visible)
{
ModGrid.InvalidateRow(row.Index);
}
SetUnsetRowConflicted(guiMod, false, null, inst, registry);
}
}
if (Conflicts != null)
{
// Mark current conflicts as conflicted
foreach (var kvp in Conflicts)
foreach ((GUIMod guiMod, string conflict_text) in Conflicts)
{
GUIMod guiMod = kvp.Key;
DataGridViewRow row = mainModList.full_list_of_mod_rows[guiMod.Identifier];
string conflict_text = kvp.Value;
SetUnsetRowConflicted(guiMod, true, conflict_text, inst, registry);
}
}
}

foreach (DataGridViewCell cell in row.Cells)
{
cell.ToolTipText = conflict_text;
}
row.DefaultCellStyle.BackColor = mainModList.GetRowBackground(guiMod, true, Main.Instance.CurrentInstance.Name);
if (row.Visible)
{
ModGrid.InvalidateRow(row.Index);
}
private void SetUnsetRowConflicted(GUIMod guiMod,
bool conflicted,
string tooltip,
GameInstance inst,
Registry registry)
{
var row = mainModList.ReapplyLabels(guiMod, conflicted,
inst.Name, inst.game, registry);
if (row != null)
{
foreach (DataGridViewCell cell in row.Cells)
{
cell.ToolTipText = tooltip;
}
if (row.Visible)
{
ModGrid.InvalidateRow(row.Index);
}
}
}
Expand Down Expand Up @@ -291,6 +290,7 @@ private void LabelsContextMenuStrip_Opening(object sender, CancelEventArgs e)
LabelsContextMenuStrip.Items.Add(
new ToolStripMenuItem(mlbl.Name, null, labelMenuItem_Click)
{
BackColor = mlbl.Color,
Checked = mlbl.ContainsModule(Main.Instance.CurrentInstance.game, module.Identifier),
CheckOnClick = true,
Tag = mlbl,
Expand Down
41 changes: 24 additions & 17 deletions GUI/Model/ModList.cs
Expand Up @@ -288,13 +288,8 @@ private DataGridViewRow MakeRow(GUIMod mod, List<ModChange> changes, string inst
{
DataGridViewRow item = new DataGridViewRow() {Tag = mod};

Color? myColor = ModuleLabels.LabelsFor(instanceName)
.FirstOrDefault(l => l.ContainsModule(game, mod.Identifier))
?.Color;
if (myColor.HasValue)
{
item.DefaultCellStyle.BackColor = myColor.Value;
}
item.DefaultCellStyle.BackColor = GetRowBackground(mod, false, instanceName, game);
item.DefaultCellStyle.SelectionBackColor = SelectionBlend(item.DefaultCellStyle.BackColor);

ModChange myChange = changes?.FindLast((ModChange ch) => ch.Mod.Equals(mod));

Expand Down Expand Up @@ -380,29 +375,41 @@ private DataGridViewRow MakeRow(GUIMod mod, List<ModChange> changes, string inst
private static string ToGridText(string text)
=> Platform.IsMono ? text.Replace("&", "&&") : text;

public Color GetRowBackground(GUIMod mod, bool conflicted, string instanceName)
=> conflicted ? Color.LightCoral
: full_list_of_mod_rows.ContainsKey(mod.Identifier)
? ModuleLabels.LabelsFor(instanceName)
.FirstOrDefault(l => l.ContainsModule(Main.Instance.CurrentInstance.game, mod.Identifier))
?.Color
?? Color.Empty
: Color.Empty;
public Color GetRowBackground(GUIMod mod, bool conflicted, string instanceName, IGame game)
=> conflicted ? conflictColor
: Util.BlendColors(
ModuleLabels.LabelsFor(instanceName)
.Where(l => l.ContainsModule(game, mod.Identifier))
.Select(l => l.Color)
.ToArray());

private static readonly Color conflictColor = Color.FromArgb(255, 64, 64);

/// <summary>
/// Update the color and visible state of the given row
/// after it has been added to or removed from a label group
/// </summary>
/// <param name="mod">The mod that needs an update</param>
public void ReapplyLabels(GUIMod mod, bool conflicted, string instanceName, IGame game, Registry registry)
public DataGridViewRow ReapplyLabels(GUIMod mod, bool conflicted,
string instanceName, IGame game, Registry registry)
{
if (full_list_of_mod_rows.TryGetValue(mod.Identifier, out DataGridViewRow row))
{
row.DefaultCellStyle.BackColor = GetRowBackground(mod, conflicted, instanceName);
row.DefaultCellStyle.BackColor = GetRowBackground(mod, conflicted, instanceName, game);
row.DefaultCellStyle.SelectionBackColor = SelectionBlend(row.DefaultCellStyle.BackColor);
row.Visible = IsVisible(mod, instanceName, game, registry);
return row;
}
return null;
}

private static Color SelectionBlend(Color c)
=> c == Color.Empty
? SystemColors.Highlight
: SystemColors.Highlight.AlphaBlendWith(selectionAlpha, c);

private const float selectionAlpha = 0.4f;

/// <summary>
/// Returns a version string shorn of any leading epoch as delimited by a single colon
/// </summary>
Expand Down
19 changes: 19 additions & 0 deletions GUI/Util.cs
Expand Up @@ -290,6 +290,25 @@ public static Point ClampedLocationWithMargins(Point location, Size size, Size t
};
}

public static Color BlendColors(Color[] colors)
=> colors.Length < 1 ? Color.Empty
: colors.Length == 1 ? colors[0]
: colors.Aggregate((back, fore) => fore.AlphaBlendWith(1f / colors.Length, back));

public static Color AlphaBlendWith(this Color c1, float alpha, Color c2)
=> AddColors(c1.MultiplyBy(alpha),
c2.MultiplyBy(1f - alpha));

private static Color MultiplyBy(this Color c, float f)
=> Color.FromArgb((int)(f * c.R),
(int)(f * c.G),
(int)(f * c.B));

private static Color AddColors(Color a, Color b)
=> Color.FromArgb(a.R + b.R,
a.G + b.G,
a.B + b.B);

/// <summary>
/// Simple syntactic sugar around Graphics.MeasureString
/// </summary>
Expand Down