Skip to content

Commit

Permalink
Support dynamic themes for ConsoleUI
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Jan 23, 2021
1 parent be42c4c commit ee772f4
Show file tree
Hide file tree
Showing 39 changed files with 748 additions and 523 deletions.
8 changes: 5 additions & 3 deletions Cmdline/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ private static int RunSimpleAction(Options cmdline, CommonOptions options, strin
return Gui(manager, (GuiOptions)options, args);

case "consoleui":
return ConsoleUi(manager, options, args);
return ConsoleUi(manager, (ConsoleUIOptions)options, args);

case "prompt":
return new Prompt().RunCommand(manager, cmdline.options);
Expand Down Expand Up @@ -277,11 +277,13 @@ private static int Gui(GameInstanceManager manager, GuiOptions options, string[]
return Exit.OK;
}

private static int ConsoleUi(GameInstanceManager manager, CommonOptions opts, string[] args)
private static int ConsoleUi(GameInstanceManager manager, ConsoleUIOptions opts, string[] args)
{
// Debug/verbose output just messes up the screen
LogManager.GetRepository().Threshold = Level.Warn;
return CKAN.ConsoleUI.ConsoleUI.Main_(args, manager, opts.Debug);
return CKAN.ConsoleUI.ConsoleUI.Main_(args, manager,
opts.Theme ?? Environment.GetEnvironmentVariable("CKAN_CONSOLEUI_THEME") ?? "default",
opts.Debug);
}

private static int Version(IUser user)
Expand Down
6 changes: 5 additions & 1 deletion Cmdline/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,11 @@ internal class GuiOptions : InstanceSpecificOptions
public bool ShowConsole { get; set; }
}

internal class ConsoleUIOptions : InstanceSpecificOptions { }
internal class ConsoleUIOptions : InstanceSpecificOptions
{
[Option("theme", HelpText = "Name of color scheme to use, falls back to environment variable CKAN_CONSOLEUI_THEME")]
public string Theme { get; set; }
}

internal class UpdateOptions : InstanceSpecificOptions
{
Expand Down
12 changes: 6 additions & 6 deletions ConsoleUI/AuthTokenAddDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public AuthTokenAddDialog() : base()
AddObject(new ConsoleLabel(
l + 2, t + 2, l + 2 + labelW,
() => "Host:",
() => ConsoleTheme.Current.PopupBg,
() => ConsoleTheme.Current.PopupFg
th => th.PopupBg,
th => th.PopupFg
));

hostEntry = new ConsoleField(
Expand All @@ -42,8 +42,8 @@ public AuthTokenAddDialog() : base()
AddObject(new ConsoleLabel(
l + 2, t + 4, l + 2 + labelW,
() => "Token:",
() => ConsoleTheme.Current.PopupBg,
() => ConsoleTheme.Current.PopupFg
th => th.PopupBg,
th => th.PopupFg
));

tokenEntry = new ConsoleField(
Expand All @@ -54,10 +54,10 @@ public AuthTokenAddDialog() : base()
AddObject(tokenEntry);

AddTip("Esc", "Cancel");
AddBinding(Keys.Escape, (object sender) => false);
AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => false);

AddTip("Enter", "Accept", validKey);
AddBinding(Keys.Enter, (object sender) => {
AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => {
if (validKey()) {
ServiceLocator.Container.Resolve<IConfiguration>().SetAuthToken(hostEntry.Value, tokenEntry.Value);
return false;
Expand Down
16 changes: 8 additions & 8 deletions ConsoleUI/AuthTokenListScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,23 @@ public AuthTokenScreen() : base()
3, -1, -1,
() => "NOTE: These values are private! Do not share screenshots of this screen!",
null,
() => ConsoleTheme.Current.AlertFrameFg
th => th.AlertFrameFg
));

AddTip("Esc", "Back");
AddBinding(Keys.Escape, (object sender) => false);
AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => false);

tokenList.AddTip("A", "Add");
tokenList.AddBinding(Keys.A, (object sender) => {
tokenList.AddBinding(Keys.A, (object sender, ConsoleTheme theme) => {
AuthTokenAddDialog ad = new AuthTokenAddDialog();
ad.Run();
DrawBackground();
ad.Run(theme);
DrawBackground(theme);
tokenList.SetData(new List<string>(ServiceLocator.Container.Resolve<IConfiguration>().GetAuthTokenHosts()));
return true;
});

tokenList.AddTip("R", "Remove", () => tokenList.Selection != null);
tokenList.AddBinding(Keys.R, (object sender) => {
tokenList.AddBinding(Keys.R, (object sender, ConsoleTheme theme) => {
if (tokenList.Selection != null) {
ServiceLocator.Container.Resolve<IConfiguration>().SetAuthToken(tokenList.Selection, null);
tokenList.SetData(new List<string>(ServiceLocator.Container.Resolve<IConfiguration>().GetAuthTokenHosts()));
Expand All @@ -97,9 +97,9 @@ protected override string CenterHeader()
return "Authentication Tokens";
}

private bool openGitHubURL()
private bool openGitHubURL(ConsoleTheme theme)
{
ModInfoScreen.LaunchURL(githubTokenURL);
ModInfoScreen.LaunchURL(theme, githubTokenURL);
return true;
}

Expand Down
11 changes: 6 additions & 5 deletions ConsoleUI/CompatibleVersionDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public CompatibleVersionDialog(IGame game) : base()
);
AddObject(choices);
choices.AddTip("Enter", "Select version");
choices.AddBinding(Keys.Enter, (object sender) => {
choices.AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => {
choice = choices.Selection;
return false;
});
Expand All @@ -52,7 +52,7 @@ public CompatibleVersionDialog(IGame game) : base()
};
AddObject(manualEntry);
manualEntry.AddTip("Enter", "Accept value", () => GameVersion.TryParse(manualEntry.Value, out choice));
manualEntry.AddBinding(Keys.Enter, (object sender) => {
manualEntry.AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => {
if (GameVersion.TryParse(manualEntry.Value, out choice)) {
// Good value, done running
return false;
Expand All @@ -63,7 +63,7 @@ public CompatibleVersionDialog(IGame game) : base()
});

AddTip("Esc", "Cancel");
AddBinding(Keys.Escape, (object sender) => {
AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => {
choice = null;
return false;
});
Expand All @@ -75,12 +75,13 @@ public CompatibleVersionDialog(IGame game) : base()
/// Display the dialog and handle its interaction
/// </summary>
/// <param name="process">Function to control the dialog, default is normal user interaction</param>
/// <param name="theme">The visual theme to use to draw the dialog</param>
/// <returns>
/// Row user selected
/// </returns>
public new GameVersion Run(Action process = null)
public new GameVersion Run(ConsoleTheme theme, Action<ConsoleTheme> process = null)
{
base.Run(process);
base.Run(theme, process);
return choice;
}

Expand Down
53 changes: 30 additions & 23 deletions ConsoleUI/ConsoleCKAN.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,41 @@ public class ConsoleCKAN {
/// Starts with a splash screen, then instance selection if no default,
/// then list of mods.
/// </summary>
public ConsoleCKAN(GameInstanceManager mgr, bool debug)
public ConsoleCKAN(GameInstanceManager mgr, string themeName, bool debug)
{
// GameInstanceManager only uses its IUser object to construct game instance objects,
// which only use it to inform the user about the creation of the CKAN/ folder.
// These aren't really intended to be displayed, so the manager
// can keep a NullUser reference forever.
GameInstanceManager manager = mgr ?? new GameInstanceManager(new NullUser());
if (Toolkit.ConsoleTheme.Themes.TryGetValue(themeName, out ConsoleTheme theme))
{
// GameInstanceManager only uses its IUser object to construct game instance objects,
// which only use it to inform the user about the creation of the CKAN/ folder.
// These aren't really intended to be displayed, so the manager
// can keep a NullUser reference forever.
GameInstanceManager manager = mgr ?? new GameInstanceManager(new NullUser());

// The splash screen returns true when it's safe to run the rest of the app.
// This can be blocked by a lock file, for example.
if (new SplashScreen(manager).Run()) {
// The splash screen returns true when it's safe to run the rest of the app.
// This can be blocked by a lock file, for example.
if (new SplashScreen(manager).Run(theme)) {

if (manager.CurrentInstance == null) {
if (manager.Instances.Count == 0) {
// No instances, add one
new GameInstanceAddScreen(manager).Run();
// Set instance to current if they added one
manager.GetPreferredInstance();
} else {
// Multiple instances, no default, pick one
new GameInstanceListScreen(manager).Run();
if (manager.CurrentInstance == null) {
if (manager.Instances.Count == 0) {
// No instances, add one
new GameInstanceAddScreen(manager).Run(theme);
// Set instance to current if they added one
manager.GetPreferredInstance();
} else {
// Multiple instances, no default, pick one
new GameInstanceListScreen(manager).Run(theme);
}
}
if (manager.CurrentInstance != null) {
new ModListScreen(manager, debug).Run(theme);
}
}
if (manager.CurrentInstance != null) {
new ModListScreen(manager, debug).Run();
}

new ExitScreen().Run();
new ExitScreen().Run(theme);
}
}
else
{
System.Console.WriteLine("No such theme: {0}", themeName);
}
}

Expand Down
14 changes: 7 additions & 7 deletions ConsoleUI/DependencyScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ public DependencyScreen(GameInstanceManager mgr, ChangePlan cp, HashSet<string>
1, 0, ListSortDirection.Descending
);
dependencyList.AddTip("+", "Toggle");
dependencyList.AddBinding(Keys.Plus, (object sender) => {
dependencyList.AddBinding(Keys.Plus, (object sender, ConsoleTheme theme) => {
ChangePlan.toggleContains(accepted, dependencyList.Selection.module);
return true;
});

dependencyList.AddTip("Ctrl+A", "Select all");
dependencyList.AddBinding(Keys.CtrlA, (object sender) => {
dependencyList.AddBinding(Keys.CtrlA, (object sender, ConsoleTheme theme) => {
foreach (var kvp in dependencies) {
if (!accepted.Contains(kvp.Key)) {
ChangePlan.toggleContains(accepted, kvp.Key);
Expand All @@ -80,15 +80,15 @@ public DependencyScreen(GameInstanceManager mgr, ChangePlan cp, HashSet<string>
});

dependencyList.AddTip("Ctrl+D", "Deselect all", () => accepted.Count > 0);
dependencyList.AddBinding(Keys.CtrlD, (object sender) => {
dependencyList.AddBinding(Keys.CtrlD, (object sender, ConsoleTheme theme) => {
accepted.Clear();
return true;
});

dependencyList.AddTip("Enter", "Details");
dependencyList.AddBinding(Keys.Enter, (object sender) => {
dependencyList.AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => {
if (dependencyList.Selection != null) {
LaunchSubScreen(new ModInfoScreen(
LaunchSubScreen(theme, new ModInfoScreen(
manager, plan,
dependencyList.Selection.module,
debug
Expand All @@ -100,7 +100,7 @@ public DependencyScreen(GameInstanceManager mgr, ChangePlan cp, HashSet<string>
AddObject(dependencyList);

AddTip("Esc", "Cancel");
AddBinding(Keys.Escape, (object sender) => {
AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => {
// Add everything to rejected
foreach (var kvp in dependencies) {
rejected.Add(kvp.Key.identifier);
Expand All @@ -109,7 +109,7 @@ public DependencyScreen(GameInstanceManager mgr, ChangePlan cp, HashSet<string>
});

AddTip("F9", "Accept");
AddBinding(Keys.F9, (object sender) => {
AddBinding(Keys.F9, (object sender, ConsoleTheme theme) => {
foreach (CkanModule mod in accepted) {
plan.Install.Add(mod);
}
Expand Down
7 changes: 4 additions & 3 deletions ConsoleUI/DownloadImportDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,24 @@ public static class DownloadImportDialog {
/// <summary>
/// Let the user choose some zip files, then import them to the mod cache.
/// </summary>
/// <param name="theme">The visual theme to use to draw the dialog</param>
/// <param name="gameInst">Game instance to import into</param>
/// <param name="cache">Cache object to import into</param>
/// <param name="cp">Change plan object for marking things to be installed</param>
public static void ImportDownloads(GameInstance gameInst, NetModuleCache cache, ChangePlan cp)
public static void ImportDownloads(ConsoleTheme theme, GameInstance gameInst, NetModuleCache cache, ChangePlan cp)
{
ConsoleFileMultiSelectDialog cfmsd = new ConsoleFileMultiSelectDialog(
"Import Downloads",
FindDownloadsPath(gameInst),
"*.zip",
"Import"
);
HashSet<FileInfo> files = cfmsd.Run();
HashSet<FileInfo> files = cfmsd.Run(theme);

if (files.Count > 0) {
ProgressScreen ps = new ProgressScreen("Importing Downloads", "Calculating...");
ModuleInstaller inst = ModuleInstaller.GetInstance(gameInst, cache, ps);
ps.Run(() => inst.ImportFiles(files, ps,
ps.Run(theme, (ConsoleTheme th) => inst.ImportFiles(files, ps,
(CkanModule mod) => cp.Install.Add(mod), RegistryManager.Instance(gameInst).registry));
// Don't let the installer re-use old screen references
inst.User = null;
Expand Down
Loading

0 comments on commit ee772f4

Please sign in to comment.