Skip to content

Commit

Permalink
Merge #4163 Don't hide other providing mods for installed, make insta…
Browse files Browse the repository at this point in the history
…lled bold
  • Loading branch information
HebaruSan committed Aug 18, 2024
2 parents b6c0b9b + d4d288c commit 912af73
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 40 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ All notable changes to this project will be documented in this file.
- [GUI] Search by licenses (#4148 by: HebaruSan)
- [CLI] Make `ckan compat add` take multiple versions, add `clear` and `set` (#4151 by: HebaruSan)
- [GUI] Add mod support links to Help menu (#4154 by: HebaruSan)
- [GUI] Don't hide other providing mods for installed, make installed bold (#4163 by: HebaruSan)

### Bugfixes

Expand Down
36 changes: 23 additions & 13 deletions GUI/Controls/ModInfoTabs/Relationships.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

100 changes: 73 additions & 27 deletions GUI/Controls/ModInfoTabs/Relationships.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,15 @@ private void _UpdateModDependencyGraph(CkanModule module)
};
DependsGraphTree.Nodes.Add(root);
AddChildren(registry, root);
DependsGraphTree.EndUpdate();
root.Expand();
// Expand virtual depends nodes
foreach (var node in root.Nodes.OfType<TreeNode>()
.Where(nd => nd.Nodes.Count > 0
&& nd.ImageIndex == (int)RelationshipType.Depends + 1))
{
node.Expand();
}
DependsGraphTree.EndUpdate();
}

private void BeforeExpand(object sender, TreeViewCancelEventArgs args)
Expand Down Expand Up @@ -270,43 +277,62 @@ private IEnumerable<TreeNode> ForwardRelationships(IRegistryQuerier registry, Ck
// Then give up and note the name without a module
?? nonindexedNode(dependency, relationship))));

private TreeNode findDependencyShallow(IRegistryQuerier registry, RelationshipDescriptor relDescr, RelationshipType relationship, GameVersionCriteria crit)
private TreeNode findDependencyShallow(IRegistryQuerier registry,
RelationshipDescriptor relDescr,
RelationshipType relationship,
GameVersionCriteria crit)
{
var childNodes = relDescr.LatestAvailableWithProvides(
registry, crit,
// Ignore conflicts with installed mods
new List<CkanModule>())
.Select(dep => indexedNode(registry, dep, relationship, relDescr, crit))
.ToList();

// Check if this dependency is installed
if (relDescr.MatchesAny(registry.InstalledModules.Select(im => im.Module).ToList(),
registry.InstalledDlls.ToHashSet(),
// Maybe it's a DLC?
registry.InstalledDlc,
out CkanModule matched))
{
return matched != null
? indexedNode(registry, matched, relationship, relDescr, crit)
: nonModuleNode(relDescr, null, relationship);
if (matched == null)
{
childNodes.Add(nonModuleNode(relDescr, null, relationship));
}
else
{
var newNode = indexedNode(registry, matched, relationship, relDescr, crit);
if (childNodes.FindIndex(nd => (nd.Tag as CkanModule)?.identifier == matched.identifier)
is int index && index != -1)
{
// Replace the latest provider with the installed version
childNodes[index] = newNode;
}
else
{
childNodes.Add(newNode);
}
}
}

// Find modules that satisfy this dependency
List<CkanModule> dependencyModules = relDescr.LatestAvailableWithProvides(
registry, crit,
// Ignore conflicts with installed mods
new List<CkanModule>());
if (dependencyModules.Count == 0)
if (childNodes.Count == 0)
{
// Nothing found, don't return a node
return null;
}
else if (dependencyModules.Count == 1
&& relDescr.ContainsAny(new string[] { dependencyModules[0].identifier }))
else if (childNodes.Count == 1
&& childNodes[0].Tag is CkanModule module
&& relDescr.ContainsAny(new string[] { module.identifier }))
{
// Only one exact match module, return a simple node
return indexedNode(registry, dependencyModules[0], relationship, relDescr, crit);
return childNodes[0];
}
else
{
// Several found or not same id, return a "provides" node
return providesNode(relDescr.ToString(),
relationship,
dependencyModules.Select(dep => indexedNode(
registry, dep, relationship, relDescr, crit)));
return providesNode(relDescr.ToString(), relationship,
childNodes.ToArray());
}
}

Expand All @@ -326,18 +352,27 @@ private IEnumerable<TreeNode> ReverseRelationships(IRegistryQuerier registry, Ck
.Select(r => indexedNode(registry, otherMod, relationship, r, crit)))));
}

private TreeNode providesNode(string identifier, RelationshipType relationship, IEnumerable<TreeNode> children)
private TreeNode providesNode(string identifier,
RelationshipType relationship,
TreeNode[] children)
{
int icon = (int)relationship + 1;
return new TreeNode(string.Format(Properties.Resources.ModInfoVirtual, identifier), icon, icon, children.ToArray())
var node = new TreeNode(string.Format(Properties.Resources.ModInfoVirtual,
identifier),
icon, icon, children)
{
Name = identifier,
ToolTipText = relationship.Localize(),
ForeColor = SystemColors.GrayText,
};
return node;
}

private TreeNode indexedNode(IRegistryQuerier registry, CkanModule module, RelationshipType relationship, RelationshipDescriptor relDescr, GameVersionCriteria crit)
private TreeNode indexedNode(IRegistryQuerier registry,
CkanModule module,
RelationshipType relationship,
RelationshipDescriptor relDescr,
GameVersionCriteria crit)
{
int icon = (int)relationship + 1;
bool missingDLC = module.IsDLC && !registry.InstalledDlc.ContainsKey(module.identifier);
Expand All @@ -350,26 +385,37 @@ private TreeNode indexedNode(IRegistryQuerier registry, CkanModule module, Relat
ToolTipText = $"{relationship.Localize()} {relDescr}",
Tag = module,
ForeColor = (compatible && !missingDLC)
? SystemColors.WindowText
: Color.Red,
? SystemColors.WindowText
: Color.Red,
NodeFont = new Font(DependsGraphTree.Font,
registry.IsInstalled(module.identifier, false)
? FontStyle.Bold
: FontStyle.Regular),
};
}

private TreeNode nonModuleNode(RelationshipDescriptor relDescr, ModuleVersion version, RelationshipType relationship)
private TreeNode nonModuleNode(RelationshipDescriptor relDescr,
ModuleVersion version,
RelationshipType relationship)
{
int icon = (int)relationship + 1;
return new TreeNode($"{relDescr} {version}", icon, icon)
{
Name = relDescr.ToString(),
ToolTipText = relationship.Localize()
ToolTipText = relationship.Localize(),
NodeFont = new Font(DependsGraphTree.Font,
FontStyle.Bold),
};
}

private TreeNode nonindexedNode(RelationshipDescriptor relDescr, RelationshipType relationship)
private TreeNode nonindexedNode(RelationshipDescriptor relDescr,
RelationshipType relationship)
{
// Completely nonexistent dependency, e.g. "AJE"
int icon = (int)relationship + 1;
return new TreeNode(string.Format(Properties.Resources.ModInfoNotIndexed, relDescr.ToString()), icon, icon)
return new TreeNode(string.Format(Properties.Resources.ModInfoNotIndexed,
relDescr.ToString()),
icon, icon)
{
Name = relDescr.ToString(),
ToolTipText = relationship.Localize(),
Expand Down
1 change: 1 addition & 0 deletions GUI/Controls/ModInfoTabs/Relationships.resx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="LegendInstalledLabel.Text" xml:space="preserve"><value>Installed</value></data>
<data name="LegendProvidesLabel.Text" xml:space="preserve"><value>Provides</value></data>
<data name="LegendDependsLabel.Text" xml:space="preserve"><value>Depends</value></data>
<data name="LegendRecommendsLabel.Text" xml:space="preserve"><value>Recommends</value></data>
Expand Down

0 comments on commit 912af73

Please sign in to comment.