mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Core - Moved startup arguments from CoreService to Constants
Web server - Added setting to disable the web server Web server - Added --disable-webserver startup argument to disable the web server UI - Fixed Artemis not bringing existing instances to foreground if already running
This commit is contained in:
parent
87b87a9145
commit
928d9711af
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Artemis.Core.JsonConverters;
|
||||
@ -90,6 +91,11 @@ public static class Constants
|
||||
/// </summary>
|
||||
public static readonly Plugin CorePlugin = new(CorePluginInfo, new DirectoryInfo(ApplicationFolder), null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the startup arguments provided to the application
|
||||
/// </summary>
|
||||
public static ReadOnlyCollection<string> StartupArguments { get; set; } = null!;
|
||||
|
||||
internal static readonly CorePluginFeature CorePluginFeature = new() {Plugin = CorePlugin, Profiler = CorePlugin.GetProfiler("Feature - Core")};
|
||||
internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new() {Plugin = CorePlugin, Profiler = CorePlugin.GetProfiler("Feature - Effect Placeholder")};
|
||||
|
||||
|
||||
@ -58,7 +58,6 @@ internal class CoreService : ICoreService
|
||||
_scriptingService = scriptingService;
|
||||
_loggingLevel = settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Debug);
|
||||
_frameStopWatch = new Stopwatch();
|
||||
StartupArguments = new List<string>();
|
||||
|
||||
_rgbService.Surface.Updating += SurfaceOnUpdating;
|
||||
_loggingLevel.SettingChanged += (sender, args) => ApplyLoggingLevel();
|
||||
@ -78,7 +77,7 @@ internal class CoreService : ICoreService
|
||||
|
||||
private void ApplyLoggingLevel()
|
||||
{
|
||||
string? argument = StartupArguments.FirstOrDefault(a => a.StartsWith("--logging"));
|
||||
string? argument = Constants.StartupArguments.FirstOrDefault(a => a.StartsWith("--logging"));
|
||||
if (argument != null)
|
||||
{
|
||||
// Parse the provided log level
|
||||
@ -194,7 +193,6 @@ internal class CoreService : ICoreService
|
||||
public int FrameRate { get; private set; }
|
||||
public TimeSpan FrameTime { get; private set; }
|
||||
public bool ProfileRenderingDisabled { get; set; }
|
||||
public List<string> StartupArguments { get; set; }
|
||||
public bool IsElevated { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
@ -217,7 +215,7 @@ internal class CoreService : ICoreService
|
||||
Constants.BuildInfo.BuildNumber,
|
||||
Constants.BuildInfo.SourceBranch
|
||||
);
|
||||
_logger.Information("Startup arguments: {args}", StartupArguments);
|
||||
_logger.Information("Startup arguments: {args}", Constants.StartupArguments);
|
||||
_logger.Information("Elevated permissions: {perms}", IsElevated);
|
||||
_logger.Information("Stopwatch high resolution: {perms}", Stopwatch.IsHighResolution);
|
||||
|
||||
@ -230,9 +228,9 @@ internal class CoreService : ICoreService
|
||||
|
||||
// Initialize the services
|
||||
_pluginManagementService.CopyBuiltInPlugins();
|
||||
_pluginManagementService.LoadPlugins(StartupArguments, IsElevated);
|
||||
_pluginManagementService.LoadPlugins(IsElevated);
|
||||
|
||||
_rgbService.ApplyPreferredGraphicsContext(StartupArguments.Contains("--force-software-render"));
|
||||
_rgbService.ApplyPreferredGraphicsContext(Constants.StartupArguments.Contains("--force-software-render"));
|
||||
_rgbService.SetRenderPaused(false);
|
||||
OnInitialized();
|
||||
}
|
||||
|
||||
@ -27,12 +27,7 @@ public interface ICoreService : IArtemisService, IDisposable
|
||||
/// Gets or sets whether profiles are rendered each frame by calling their Render method
|
||||
/// </summary>
|
||||
bool ProfileRenderingDisabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a list of startup arguments
|
||||
/// </summary>
|
||||
List<string> StartupArguments { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether Artemis is running in an elevated environment (admin permissions)
|
||||
/// </summary>
|
||||
|
||||
@ -26,7 +26,7 @@ public interface IPluginManagementService : IArtemisService, IDisposable
|
||||
/// <summary>
|
||||
/// Loads all installed plugins. If plugins already loaded this will reload them all
|
||||
/// </summary>
|
||||
void LoadPlugins(List<string> startupArguments, bool isElevated);
|
||||
void LoadPlugins(bool isElevated);
|
||||
|
||||
/// <summary>
|
||||
/// Unloads all installed plugins.
|
||||
|
||||
@ -203,17 +203,17 @@ internal class PluginManagementService : IPluginManagementService
|
||||
|
||||
#region Plugins
|
||||
|
||||
public void LoadPlugins(List<string> startupArguments, bool isElevated)
|
||||
public void LoadPlugins(bool isElevated)
|
||||
{
|
||||
if (startupArguments.Contains("--no-plugins"))
|
||||
if (Constants.StartupArguments.Contains("--no-plugins"))
|
||||
{
|
||||
_logger.Warning("Artemis launched with --no-plugins, skipping the loading of plugins");
|
||||
return;
|
||||
}
|
||||
|
||||
bool ignorePluginLock = startupArguments.Contains("--ignore-plugin-lock");
|
||||
bool stayElevated = startupArguments.Contains("--force-elevation");
|
||||
bool droppedAdmin = startupArguments.Contains("--dropped-admin");
|
||||
bool ignorePluginLock = Constants.StartupArguments.Contains("--ignore-plugin-lock");
|
||||
bool stayElevated = Constants.StartupArguments.Contains("--force-elevation");
|
||||
bool droppedAdmin = Constants.StartupArguments.Contains("--dropped-admin");
|
||||
if (LoadingPlugins)
|
||||
throw new ArtemisCoreException("Cannot load plugins while a previous load hasn't been completed yet.");
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.Modules;
|
||||
using EmbedIO;
|
||||
@ -17,15 +18,19 @@ internal class WebServerService : IWebServerService, IDisposable
|
||||
private readonly List<WebApiControllerRegistration> _controllers;
|
||||
private readonly ILogger _logger;
|
||||
private readonly List<WebModuleRegistration> _modules;
|
||||
private readonly PluginSetting<bool> _webServerEnabledSetting;
|
||||
private readonly PluginSetting<int> _webServerPortSetting;
|
||||
private CancellationTokenSource? _cts;
|
||||
|
||||
public WebServerService(ILogger logger, ISettingsService settingsService, IPluginManagementService pluginManagementService)
|
||||
public WebServerService(ILogger logger, ICoreService coreService, ISettingsService settingsService, IPluginManagementService pluginManagementService)
|
||||
{
|
||||
_logger = logger;
|
||||
_controllers = new List<WebApiControllerRegistration>();
|
||||
_modules = new List<WebModuleRegistration>();
|
||||
|
||||
_webServerEnabledSetting = settingsService.GetSetting("WebServer.Enabled", true);
|
||||
_webServerPortSetting = settingsService.GetSetting("WebServer.Port", 9696);
|
||||
_webServerEnabledSetting.SettingChanged += WebServerEnabledSettingOnSettingChanged;
|
||||
_webServerPortSetting.SettingChanged += WebServerPortSettingOnSettingChanged;
|
||||
pluginManagementService.PluginFeatureDisabled += PluginManagementServiceOnPluginFeatureDisabled;
|
||||
|
||||
@ -33,9 +38,9 @@ internal class WebServerService : IWebServerService, IDisposable
|
||||
StartWebServer();
|
||||
}
|
||||
|
||||
protected virtual void OnWebServerStarting()
|
||||
private void WebServerEnabledSettingOnSettingChanged(object? sender, EventArgs e)
|
||||
{
|
||||
WebServerStarting?.Invoke(this, EventArgs.Empty);
|
||||
StartWebServer();
|
||||
}
|
||||
|
||||
private void WebServerPortSettingOnSettingChanged(object? sender, EventArgs e)
|
||||
@ -72,14 +77,23 @@ internal class WebServerService : IWebServerService, IDisposable
|
||||
public WebServer? Server { get; private set; }
|
||||
public PluginsModule PluginsModule { get; }
|
||||
|
||||
public event EventHandler? WebServerStarting;
|
||||
|
||||
#region Web server managament
|
||||
|
||||
private WebServer CreateWebServer()
|
||||
{
|
||||
Server?.Dispose();
|
||||
Server = null;
|
||||
if (Server != null)
|
||||
{
|
||||
if (_cts != null)
|
||||
{
|
||||
_cts.Cancel();
|
||||
_cts = null;
|
||||
}
|
||||
|
||||
Server.Dispose();
|
||||
OnWebServerStopped();
|
||||
Server = null;
|
||||
}
|
||||
|
||||
WebApiModule apiModule = new("/", JsonNetSerializer);
|
||||
PluginsModule.ServerUrl = $"http://localhost:{_webServerPortSetting.Value}/";
|
||||
@ -112,8 +126,20 @@ internal class WebServerService : IWebServerService, IDisposable
|
||||
private void StartWebServer()
|
||||
{
|
||||
Server = CreateWebServer();
|
||||
|
||||
if (!_webServerEnabledSetting.Value)
|
||||
return;
|
||||
|
||||
if (Constants.StartupArguments.Contains("--disable-webserver"))
|
||||
{
|
||||
_logger.Warning("Artemis launched with --disable-webserver, not enabling the webserver");
|
||||
return;
|
||||
}
|
||||
|
||||
OnWebServerStarting();
|
||||
Server.Start();
|
||||
_cts = new CancellationTokenSource();
|
||||
Server.Start(_cts.Token);
|
||||
OnWebServerStarted();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -276,4 +302,27 @@ internal class WebServerService : IWebServerService, IDisposable
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
protected virtual void OnWebServerStopped()
|
||||
{
|
||||
WebServerStopped?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
protected virtual void OnWebServerStarting()
|
||||
{
|
||||
WebServerStarting?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
protected virtual void OnWebServerStarted()
|
||||
{
|
||||
WebServerStarted?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public event EventHandler? WebServerStopped;
|
||||
public event EventHandler? WebServerStarting;
|
||||
public event EventHandler? WebServerStarted;
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -1,3 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Windows.Ninject;
|
||||
using Artemis.UI.Windows.Providers.Input;
|
||||
@ -13,14 +21,23 @@ namespace Artemis.UI.Windows;
|
||||
|
||||
public class App : Application
|
||||
{
|
||||
private StandardKernel? _kernel;
|
||||
private bool _shutDown;
|
||||
|
||||
// ReSharper disable NotAccessedField.Local
|
||||
private ApplicationStateManager? _applicationStateManager;
|
||||
private Mutex? _artemisMutex;
|
||||
// ReSharper restore NotAccessedField.Local
|
||||
|
||||
private StandardKernel? _kernel;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
// If Artemis is already running, bring it to foreground and stop this process
|
||||
if (FocusExistingInstance())
|
||||
{
|
||||
_shutDown = true;
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
_kernel = ArtemisBootstrapper.Bootstrap(this, new WindowsModule());
|
||||
Program.CreateLogger(_kernel);
|
||||
RxApp.MainThreadScheduler = AvaloniaScheduler.Instance;
|
||||
@ -29,7 +46,7 @@ public class App : Application
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop || Design.IsDesignMode)
|
||||
if (ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop || Design.IsDesignMode || _shutDown)
|
||||
return;
|
||||
|
||||
ArtemisBootstrapper.Initialize();
|
||||
@ -42,4 +59,55 @@ public class App : Application
|
||||
IInputService inputService = standardKernel.Get<IInputService>();
|
||||
inputService.AddInputProvider(standardKernel.Get<WindowsInputProvider>());
|
||||
}
|
||||
|
||||
private bool FocusExistingInstance()
|
||||
{
|
||||
_artemisMutex = new Mutex(true, "Artemis-3c24b502-64e6-4587-84bf-9072970e535f", out bool createdNew);
|
||||
return !createdNew && RemoteFocus();
|
||||
}
|
||||
|
||||
private bool RemoteFocus()
|
||||
{
|
||||
// At this point we cannot read the database yet to retrieve the web server port.
|
||||
// Instead use the method external applications should use as well.
|
||||
if (!File.Exists(Path.Combine(Constants.DataFolder, "webserver.txt")))
|
||||
{
|
||||
KillOtherInstances();
|
||||
return false;
|
||||
}
|
||||
|
||||
string url = File.ReadAllText(Path.Combine(Constants.DataFolder, "webserver.txt"));
|
||||
using HttpClient client = new();
|
||||
try
|
||||
{
|
||||
CancellationTokenSource cts = new();
|
||||
cts.CancelAfter(2000);
|
||||
|
||||
HttpResponseMessage httpResponseMessage = client.Send(new HttpRequestMessage(HttpMethod.Post, url + "remote/bring-to-foreground"), cts.Token);
|
||||
httpResponseMessage.EnsureSuccessStatusCode();
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
KillOtherInstances();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void KillOtherInstances()
|
||||
{
|
||||
// Kill everything else heh
|
||||
List<Process> processes = Process.GetProcessesByName("Artemis.UI.Windows").Where(p => p.Id != Process.GetCurrentProcess().Id).ToList();
|
||||
foreach (Process process in processes)
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Kill(true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,12 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.UI.Windows.Utilities;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
@ -19,14 +16,8 @@ namespace Artemis.UI.Windows;
|
||||
|
||||
public class ApplicationStateManager
|
||||
{
|
||||
private readonly IWindowService _windowService;
|
||||
|
||||
// ReSharper disable once NotAccessedField.Local - Kept in scope to ensure it does not get released
|
||||
private Mutex? _artemisMutex;
|
||||
|
||||
public ApplicationStateManager(IKernel kernel, string[] startupArguments)
|
||||
{
|
||||
_windowService = kernel.Get<IWindowService>();
|
||||
StartupArguments = startupArguments;
|
||||
IsElevated = new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
|
||||
|
||||
@ -51,72 +42,6 @@ public class ApplicationStateManager
|
||||
public string[] StartupArguments { get; }
|
||||
public bool IsElevated { get; }
|
||||
|
||||
public bool FocusExistingInstance()
|
||||
{
|
||||
_artemisMutex = new Mutex(true, "Artemis-3c24b502-64e6-4587-84bf-9072970e535f", out bool createdNew);
|
||||
if (createdNew)
|
||||
return false;
|
||||
|
||||
return RemoteFocus();
|
||||
}
|
||||
|
||||
public void DisplayException(Exception e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_windowService.ShowExceptionDialog("An unhandled exception occured", e);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored, we tried
|
||||
}
|
||||
}
|
||||
|
||||
private bool RemoteFocus()
|
||||
{
|
||||
// At this point we cannot read the database yet to retrieve the web server port.
|
||||
// Instead use the method external applications should use as well.
|
||||
if (!File.Exists(Path.Combine(Constants.DataFolder, "webserver.txt")))
|
||||
{
|
||||
KillOtherInstances();
|
||||
return false;
|
||||
}
|
||||
|
||||
string url = File.ReadAllText(Path.Combine(Constants.DataFolder, "webserver.txt"));
|
||||
using HttpClient client = new();
|
||||
try
|
||||
{
|
||||
CancellationTokenSource cts = new();
|
||||
cts.CancelAfter(2000);
|
||||
|
||||
HttpResponseMessage httpResponseMessage = client.Send(new HttpRequestMessage(HttpMethod.Post, url + "remote/bring-to-foreground"), cts.Token);
|
||||
httpResponseMessage.EnsureSuccessStatusCode();
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
KillOtherInstances();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void KillOtherInstances()
|
||||
{
|
||||
// Kill everything else heh
|
||||
List<Process> processes = Process.GetProcessesByName("Artemis.UI.Windows").Where(p => p.Id != Process.GetCurrentProcess().Id).ToList();
|
||||
foreach (Process process in processes)
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Kill(true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UtilitiesOnRestartRequested(object? sender, RestartEventArgs e)
|
||||
{
|
||||
List<string> argsList = new();
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Ninject;
|
||||
@ -52,6 +55,8 @@ public static class ArtemisBootstrapper
|
||||
if (_application.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
|
||||
return;
|
||||
|
||||
Constants.StartupArguments = new ReadOnlyCollection<string>(new List<string>(desktop.Args));
|
||||
|
||||
// Don't shut down when the last window closes, we might still be active in the tray
|
||||
desktop.ShutdownMode = ShutdownMode.OnExplicitShutdown;
|
||||
// Create the root view model that drives the UI
|
||||
|
||||
@ -47,12 +47,12 @@ public class MainWindow : ReactiveCoreWindow<RootViewModel>
|
||||
|
||||
private void OnActivated(object? sender, EventArgs e)
|
||||
{
|
||||
ViewModel.Focused();
|
||||
ViewModel?.Focused();
|
||||
}
|
||||
|
||||
private void OnDeactivated(object? sender, EventArgs e)
|
||||
{
|
||||
ViewModel.Unfocused();
|
||||
ViewModel?.Unfocused();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
|
||||
@ -54,8 +54,7 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi
|
||||
_defaultTitleBarViewModel = defaultTitleBarViewModel;
|
||||
_sidebarVmFactory = sidebarVmFactory;
|
||||
_lifeTime = (IClassicDesktopStyleApplicationLifetime) Application.Current!.ApplicationLifetime!;
|
||||
|
||||
coreService.StartupArguments = _lifeTime.Args.ToList();
|
||||
|
||||
mainWindowService.ConfigureMainWindowProvider(this);
|
||||
|
||||
DisplayAccordingToSettings();
|
||||
@ -99,8 +98,8 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi
|
||||
|
||||
private void DisplayAccordingToSettings()
|
||||
{
|
||||
bool autoRunning = _coreService.StartupArguments.Contains("--autorun");
|
||||
bool minimized = _coreService.StartupArguments.Contains("--minimized");
|
||||
bool autoRunning = Constants.StartupArguments.Contains("--autorun");
|
||||
bool minimized = Constants.StartupArguments.Contains("--minimized");
|
||||
bool showOnAutoRun = _settingsService.GetSetting("UI.ShowOnStartup", true).Value;
|
||||
|
||||
if ((autoRunning && !showOnAutoRun) || minimized)
|
||||
|
||||
@ -13,364 +13,379 @@
|
||||
x:DataType="settings:GeneralTabViewModel">
|
||||
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Margin="15" MaxWidth="1000">
|
||||
<!-- General settings -->
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
General
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<StackPanel IsVisible="{CompiledBinding IsAutoRunSupported}">
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>Auto-run on startup</TextBlock>
|
||||
</StackPanel>
|
||||
<ToggleSwitch Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" IsChecked="{CompiledBinding UIAutoRun.Value}" MinWidth="0" Margin="0 -10"/>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
<StackPanel Margin="15" MaxWidth="1000">
|
||||
<!-- General settings -->
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
General
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<StackPanel IsVisible="{CompiledBinding IsAutoRunSupported}">
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>Auto-run on startup</TextBlock>
|
||||
</StackPanel>
|
||||
<ToggleSwitch Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" IsChecked="{CompiledBinding UIAutoRun.Value}" MinWidth="0" Margin="0 -10" OnContent="Yes"
|
||||
OffContent="No" />
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>Hide window on auto-run</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsChecked="{CompiledBinding !UIShowOnStartup.Value}" IsEnabled="{CompiledBinding UIAutoRun.Value}" MinWidth="0" Margin="0 -10"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>Hide window on auto-run</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsChecked="{CompiledBinding !UIShowOnStartup.Value}" IsEnabled="{CompiledBinding UIAutoRun.Value}" MinWidth="0" Margin="0 -10" OnContent="Yes"
|
||||
OffContent="No" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>Startup delay</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Set the amount of seconds to wait before auto-running Artemis.
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
If some devices don't work because Artemis starts before the manufacturer's software, try increasing this value.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal">
|
||||
<controls:NumberBox IsEnabled="{CompiledBinding UIAutoRun.Value}" Width="120">
|
||||
<Interaction.Behaviors>
|
||||
<behaviors:LostFocusNumberBoxBindingBehavior Value="{CompiledBinding UIAutoRunDelay.Value}"/>
|
||||
</Interaction.Behaviors>
|
||||
</controls:NumberBox>
|
||||
<TextBlock VerticalAlignment="Center" TextAlignment="Right" Width="30">sec</TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
</StackPanel>
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Log level
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Sets the logging level, a higher logging level will result in more log files.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<shared:EnumComboBox Width="150" Value="{CompiledBinding CoreLoggingLevel.Value}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>Startup delay</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Set the amount of seconds to wait before auto-running Artemis.
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
If some devices don't work because Artemis starts before the manufacturer's software, try increasing this value.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal">
|
||||
<controls:NumberBox IsEnabled="{CompiledBinding UIAutoRun.Value}" Width="120">
|
||||
<Interaction.Behaviors>
|
||||
<behaviors:LostFocusNumberBoxBindingBehavior Value="{CompiledBinding UIAutoRunDelay.Value}" />
|
||||
</Interaction.Behaviors>
|
||||
</controls:NumberBox>
|
||||
<TextBlock VerticalAlignment="Center" TextAlignment="Right" Width="30">sec</TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
</StackPanel>
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" VerticalAlignment="Center">
|
||||
<TextBlock>
|
||||
Logs
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle">
|
||||
Opens the directory where logs are stored.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Button Command="{CompiledBinding ShowLogs}" Width="150" Content="Show logs" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Log level
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Sets the logging level, a higher logging level will result in more log files.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<shared:EnumComboBox Width="150" Value="{CompiledBinding CoreLoggingLevel.Value}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<!-- Web server settings -->
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
Web server
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Web server port
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Artemis runs a local web server that can be used to externally interact with the application.
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
This web server can only be accessed by applications running on your own computer, e.g. supported games.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<controls:NumberBox Width="150">
|
||||
<Interaction.Behaviors>
|
||||
<behaviors:LostFocusNumberBoxBindingBehavior Value="{CompiledBinding WebServerPort.Value}"/>
|
||||
</Interaction.Behaviors>
|
||||
</controls:NumberBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" VerticalAlignment="Center">
|
||||
<TextBlock>
|
||||
Logs
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle">
|
||||
Opens the directory where logs are stored.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Button Command="{CompiledBinding ShowLogs}" Width="150" Content="Show logs" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Update settings -->
|
||||
<StackPanel IsVisible="{CompiledBinding IsUpdatingSupported}">
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
Updating
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Check for updates
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
If enabled, we'll check for updates on startup and periodically while running.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsChecked="{CompiledBinding UICheckForUpdates.Value}" MinWidth="0" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Auto-install updates
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
If enabled, new updates will automatically be installed.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsEnabled="{CompiledBinding UICheckForUpdates.Value}" IsChecked="{CompiledBinding UIAutoUpdate.Value}" MinWidth="0" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
<!-- Web server settings -->
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
Web server
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>Enable web server</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Artemis runs a local web server that can be used to externally interact with the application.
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
This web server can only be accessed by applications running on your own computer, e.g. supported games.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsChecked="{CompiledBinding WebServerEnabled.Value}" OnContent="Yes" OffContent="No" MinWidth="0" Margin="0 -10" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" VerticalAlignment="Center">
|
||||
<TextBlock>
|
||||
Update
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle">
|
||||
Use the button on the right to check for updates now.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Button Command="{CompiledBinding CheckForUpdate}" Width="150" Content="Check now" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Web server port
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
If the webserver does not work you can try changing the port to one that is available.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<controls:NumberBox Width="150">
|
||||
<Interaction.Behaviors>
|
||||
<behaviors:LostFocusNumberBoxBindingBehavior Value="{CompiledBinding WebServerPort.Value}" />
|
||||
</Interaction.Behaviors>
|
||||
</controls:NumberBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Profile editor settings -->
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
Profile editor
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Show condition data model values
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
While selecting a condition target, show the current values of the data model.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsChecked="{CompiledBinding ProfileEditorShowDataModelValues.Value}" MinWidth="0" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
<!-- Update settings -->
|
||||
<StackPanel IsVisible="{CompiledBinding IsUpdatingSupported}">
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
Updating
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Check for updates
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
If enabled, we'll check for updates on startup and periodically while running.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsChecked="{CompiledBinding UICheckForUpdates.Value}" MinWidth="0" OnContent="Yes" OffContent="No" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Default brush
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Sets the default brush that is applied to new layers
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<StackPanel.Styles>
|
||||
<Style Selector="ComboBox.brush /template/ ContentControl#ContentPresenter">
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate DataType="{x:Type layerBrushes:LayerBrushDescriptor}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<avalonia:MaterialIcon Kind="{CompiledBinding Icon}" Height="20" Width="20" VerticalAlignment="Center" Margin="0 0 5 0"/>
|
||||
<TextBlock Text="{CompiledBinding DisplayName}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</StackPanel.Styles>
|
||||
<ComboBox Classes="brush"
|
||||
Width="200"
|
||||
HorizontalAlignment="Left"
|
||||
Items="{CompiledBinding LayerBrushDescriptors}"
|
||||
SelectedItem="{CompiledBinding SelectedLayerBrushDescriptor}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type layerBrushes:LayerBrushDescriptor}">
|
||||
<Grid ColumnDefinitions="30,*" RowDefinitions="Auto,Auto">
|
||||
<avalonia:MaterialIcon Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Kind="{CompiledBinding Icon}"
|
||||
Height="20"
|
||||
Width="20"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" Text="{CompiledBinding DisplayName}" TextWrapping="Wrap" MaxWidth="350" />
|
||||
<TextBlock Classes="subtitle" Grid.Row="1" Grid.Column="1" Text="{CompiledBinding Description}" TextWrapping="Wrap" MaxWidth="350" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Auto-install updates
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
If enabled, new updates will automatically be installed.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsEnabled="{CompiledBinding UICheckForUpdates.Value}" IsChecked="{CompiledBinding UIAutoUpdate.Value}" MinWidth="0" OnContent="Yes" OffContent="No" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<!-- Rendering settings -->
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
Rendering
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Preferred render method
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Software-based rendering is done purely on the CPU while Vulkan uses GPU-acceleration.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ComboBox Width="150"
|
||||
SelectedItem="{CompiledBinding CorePreferredGraphicsContext.Value}"
|
||||
Items="{CompiledBinding GraphicsContexts}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" VerticalAlignment="Center">
|
||||
<TextBlock>
|
||||
Update
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle">
|
||||
Use the button on the right to check for updates now.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Button Command="{CompiledBinding CheckForUpdate}" Width="150" Content="Check now" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Render scale
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Sets the resolution Artemis renders at, higher scale means more CPU-usage, especially on large surfaces.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ComboBox Width="150"
|
||||
SelectedItem="{CompiledBinding SelectedRenderScale}"
|
||||
Items="{CompiledBinding RenderScales}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{CompiledBinding Display}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
<!-- Profile editor settings -->
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
Profile editor
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Show condition data model values
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
While selecting a condition target, show the current values of the data model.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsChecked="{CompiledBinding ProfileEditorShowDataModelValues.Value}" MinWidth="0" OnContent="Yes" OffContent="No" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Target frame rate
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Sets the FPS Artemis tries to render at, higher FPS means more CPU-usage but smoother animations.
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
The options past 45 FPS are mostly useless unless you are using a custom device.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ComboBox Width="150"
|
||||
SelectedItem="{CompiledBinding SelectedTargetFrameRate}"
|
||||
Items="{CompiledBinding TargetFrameRates}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{CompiledBinding Display}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Default brush
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Sets the default brush that is applied to new layers
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<StackPanel.Styles>
|
||||
<Style Selector="ComboBox.brush /template/ ContentControl#ContentPresenter">
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate DataType="{x:Type layerBrushes:LayerBrushDescriptor}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<avalonia:MaterialIcon Kind="{CompiledBinding Icon}" Height="20" Width="20" VerticalAlignment="Center" Margin="0 0 5 0" />
|
||||
<TextBlock Text="{CompiledBinding DisplayName}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</StackPanel.Styles>
|
||||
<ComboBox Classes="brush"
|
||||
Width="200"
|
||||
HorizontalAlignment="Left"
|
||||
Items="{CompiledBinding LayerBrushDescriptors}"
|
||||
SelectedItem="{CompiledBinding SelectedLayerBrushDescriptor}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type layerBrushes:LayerBrushDescriptor}">
|
||||
<Grid ColumnDefinitions="30,*" RowDefinitions="Auto,Auto">
|
||||
<avalonia:MaterialIcon Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Kind="{CompiledBinding Icon}"
|
||||
Height="20"
|
||||
Width="20"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" Text="{CompiledBinding DisplayName}" TextWrapping="Wrap" MaxWidth="350" />
|
||||
<TextBlock Classes="subtitle" Grid.Row="1" Grid.Column="1" Text="{CompiledBinding Description}" TextWrapping="Wrap" MaxWidth="350" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Tools -->
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
Tools
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" VerticalAlignment="Center">
|
||||
<TextBlock>
|
||||
Setup wizard
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle">
|
||||
Opens the startup wizard usually shown when Artemis first starts.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Button Command="{CompiledBinding ShowSetupWizard}" Width="150" Content="Show wizard" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
<!-- Rendering settings -->
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
Rendering
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Preferred render method
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Software-based rendering is done purely on the CPU while Vulkan uses GPU-acceleration.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ComboBox Width="150"
|
||||
SelectedItem="{CompiledBinding CorePreferredGraphicsContext.Value}"
|
||||
Items="{CompiledBinding GraphicsContexts}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" VerticalAlignment="Center">
|
||||
<TextBlock>
|
||||
Debugger
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle">
|
||||
Use the debugger to see the raw image Artemis is rendering on the surface.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Button Command="{CompiledBinding ShowDebugger}" Width="150" Content="Show debugger" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Render scale
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Sets the resolution Artemis renders at, higher scale means more CPU-usage, especially on large surfaces.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ComboBox Width="150"
|
||||
SelectedItem="{CompiledBinding SelectedRenderScale}"
|
||||
Items="{CompiledBinding RenderScales}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{CompiledBinding Display}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" VerticalAlignment="Center">
|
||||
<TextBlock>
|
||||
Application files
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle">
|
||||
Opens the directory where application files like plugins and settings are stored.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Button Command="{CompiledBinding ShowDataFolder}" Width="150" Content="Show app files" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Target frame rate
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
Sets the FPS Artemis tries to render at, higher FPS means more CPU-usage but smoother animations.
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle" TextWrapping="Wrap">
|
||||
The options past 45 FPS are mostly useless unless you are using a custom device.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ComboBox Width="150"
|
||||
SelectedItem="{CompiledBinding SelectedTargetFrameRate}"
|
||||
Items="{CompiledBinding TargetFrameRates}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{CompiledBinding Display}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Tools -->
|
||||
<TextBlock Classes="h4" Margin="0 15">
|
||||
Tools
|
||||
</TextBlock>
|
||||
<Border Classes="card" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" VerticalAlignment="Center">
|
||||
<TextBlock>
|
||||
Setup wizard
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle">
|
||||
Opens the startup wizard usually shown when Artemis first starts.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Button Command="{CompiledBinding ShowSetupWizard}" Width="150" Content="Show wizard" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" VerticalAlignment="Center">
|
||||
<TextBlock>
|
||||
Debugger
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle">
|
||||
Use the debugger to see the raw image Artemis is rendering on the surface.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Button Command="{CompiledBinding ShowDebugger}" Width="150" Content="Show debugger" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" VerticalAlignment="Center">
|
||||
<TextBlock>
|
||||
Application files
|
||||
</TextBlock>
|
||||
<TextBlock Classes="subtitle">
|
||||
Opens the directory where application files like plugins and settings are stored.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Button Command="{CompiledBinding ShowDataFolder}" Width="150" Content="Show app files" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
</UserControl>
|
||||
@ -149,6 +149,7 @@ public class GeneralTabViewModel : ActivatableViewModelBase
|
||||
public PluginSetting<string> CorePreferredGraphicsContext => _settingsService.GetSetting("Core.PreferredGraphicsContext", "Software");
|
||||
public PluginSetting<double> CoreRenderScale => _settingsService.GetSetting("Core.RenderScale", 0.25);
|
||||
public PluginSetting<int> CoreTargetFrameRate => _settingsService.GetSetting("Core.TargetFrameRate", 30);
|
||||
public PluginSetting<bool> WebServerEnabled => _settingsService.GetSetting("WebServer.Enabled", true);
|
||||
public PluginSetting<int> WebServerPort => _settingsService.GetSetting("WebServer.Port", 9696);
|
||||
|
||||
private void ExecuteShowLogs()
|
||||
|
||||
@ -17,7 +17,7 @@ public class SaturateNode : Node
|
||||
#region Constructors
|
||||
|
||||
public SaturateNode()
|
||||
: base("Clamp", "Clamps the value to be in between 0 and 1")
|
||||
: base("Saturate", "Clamps the value to be in between 0 and 1")
|
||||
{
|
||||
Value = CreateInputPin<Numeric>();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user