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();
|
||||
}
|
||||
|
||||
@ -28,11 +28,6 @@ public interface ICoreService : IArtemisService, IDisposable
|
||||
/// </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();
|
||||
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()
|
||||
|
||||
@ -55,7 +55,6 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi
|
||||
_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)
|
||||
|
||||
@ -25,7 +25,8 @@
|
||||
<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"/>
|
||||
<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" />
|
||||
|
||||
@ -34,7 +35,8 @@
|
||||
<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"/>
|
||||
<ToggleSwitch IsChecked="{CompiledBinding !UIShowOnStartup.Value}" IsEnabled="{CompiledBinding UIAutoRun.Value}" MinWidth="0" Margin="0 -10" OnContent="Yes"
|
||||
OffContent="No" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
@ -100,9 +102,7 @@
|
||||
<StackPanel>
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock>
|
||||
Web server port
|
||||
</TextBlock>
|
||||
<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>
|
||||
@ -110,6 +110,21 @@
|
||||
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">
|
||||
<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>
|
||||
@ -138,7 +153,7 @@
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsChecked="{CompiledBinding UICheckForUpdates.Value}" MinWidth="0" />
|
||||
<ToggleSwitch IsChecked="{CompiledBinding UICheckForUpdates.Value}" MinWidth="0" OnContent="Yes" OffContent="No" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
@ -153,7 +168,7 @@
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsEnabled="{CompiledBinding UICheckForUpdates.Value}" IsChecked="{CompiledBinding UIAutoUpdate.Value}" MinWidth="0" />
|
||||
<ToggleSwitch IsEnabled="{CompiledBinding UICheckForUpdates.Value}" IsChecked="{CompiledBinding UIAutoUpdate.Value}" MinWidth="0" OnContent="Yes" OffContent="No" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
@ -191,7 +206,7 @@
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleSwitch IsChecked="{CompiledBinding ProfileEditorShowDataModelValues.Value}" MinWidth="0" />
|
||||
<ToggleSwitch IsChecked="{CompiledBinding ProfileEditorShowDataModelValues.Value}" MinWidth="0" OnContent="Yes" OffContent="No" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Classes="card-separator" />
|
||||
|
||||
@ -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