fix color profile issues, add lock/unlock power off/on, add GPU OC settings to new UI

This commit is contained in:
Vincent Maas committed 2024-10-20 11:18:02 +02:00
1 parent 6f4b1e9779
commit 5c62273b33
100 files changed
+11273 -10560

No files matched your search

+27 -27
View File
@@ -5,39 +5,39 @@ namespace ColorControl.UI;
public static class Blazor
{
public static void Start(Config? config = null)
{
var builder = WebApplication.CreateBuilder();
public static void Start(Config? config = null)
{
var builder = WebApplication.CreateBuilder();
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddSingleton<AppState>(new AppState { SelectedTheme = (config?.UseDarkMode ?? true) ? "dark" : "light" });
builder.Services.AddTransient<RpcUiClientService>();
builder.Services.AddTransient<JSHelper>();
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<NotificationService>();
builder.WebHost.ConfigureKestrel(o => o.ListenAnyIP(config?.UiPort > 0 ? config.UiPort : 5000));
builder.Services.AddSingleton<AppState>(new AppState { SelectedTheme = (config?.UseDarkMode ?? true) ? "dark" : "light" });
builder.Services.AddTransient<RpcUiClientService>();
builder.Services.AddTransient<JSHelper>();
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<NotificationService>();
builder.WebHost.ConfigureKestrel(o => o.ListenAnyIP(config?.UiPort > 0 ? config.UiPort : 5000));
var app = builder.Build();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<Components.App>()
.AddInteractiveServerRenderMode();
app.MapRazorComponents<Components.App>()
.AddInteractiveServerRenderMode();
app.Run();
}
app.Run();
}
}
+3
View File
@@ -41,6 +41,9 @@
<Content Update="Components\Pages\LG\LgExecuteActionModal.razor">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
<Content Update="Components\Pages\Nvidia\NvidiaGpuSettings.razor">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
<Content Update="Components\Pages\Samsung\SamsungSummary.razor">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
@@ -1,8 +1,7 @@
@using ColorControl.Shared.Contracts
@using ColorControl.UI.Services;
@using ColorControl.UI.Services
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@@ -4,7 +4,7 @@
@inject AppState AppState
@inject NavigationManager _navigationManager;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
<div class="top-row px-4 pt-3 text-end">
@* <button type="button" class="btn btn-primary me-2" @onclick="ChangeTheme">@ThemeTransitionName</button> *@
@@ -15,7 +15,7 @@
private string ThemeTransitionName = "Dark";
protected override async Task OnInitializedAsync()
protected override void OnInitialized()
{
ThemeTransitionName = AppState.SelectedTheme == "light" ? "Dark theme" : "Light theme";
}
@@ -4,7 +4,7 @@
@using ColorControl.Shared.Common;
@using ColorControl.UI.Services
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@@ -4,7 +4,7 @@
@using ColorControl.Shared.Common;
@using ColorControl.UI.Components.Pages.Generic
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
<div class="modal" id="settingsModal" tabindex="-1" @onfocus="OnFocus">
@@ -8,7 +8,7 @@
@using ColorControl.UI.Generics
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject ProtectedLocalStorage _localStorage
@@ -99,7 +99,7 @@ else
<div class="list-group">
@foreach (var preset in Presets)
{
<a class="list-group-item list-group-item-action" @onclick="() => PresetOnClick(preset)" @onclick:preventDefault @onclick:stopPropagation>
<span class="list-group-item list-group-item-action" @onclick="() => PresetOnClick(preset)" @onclick:preventDefault @onclick:stopPropagation>
<div class="d-flex align-items-start justify-content-between">
<div>
<h5 class="mb-1">
@@ -128,7 +128,7 @@ else
</div>
<p class="mb-1">@preset.DisplayConfig.Resolution.ToString() @@ @preset.DisplayConfig.RefreshRate.ToString()Hz @(preset.applyColorData ? preset.colorDepth : "")</p>
<small class="text-muted">@preset.shortcut</small>
</a>
</span>
}
</div>
</div>
@@ -165,19 +165,19 @@ else
await _rpcClientService.CallAsync<bool>("AmdService", "ApplyPresetWithId", preset.id);
}
private async Task PresetOnEditClick(AmdPreset preset)
private void PresetOnEditClick(AmdPreset preset)
{
CurrentPreset = preset;
}
private async Task PresetOnCloneClick(AmdPreset preset)
private void PresetOnCloneClick(AmdPreset preset)
{
CurrentPreset = new AmdPreset(preset);
CurrentPreset.name = preset.name;
CurrentPreset.SetCloneValues();
}
private async Task PresetOnDeleteClick(AmdPreset preset)
private void PresetOnDeleteClick(AmdPreset preset)
{
CurrentPreset = preset;
}
@@ -194,12 +194,12 @@ else
StateHasChanged();
}
private async Task DisplayPresetOnClick(AmdPreset preset)
private void DisplayPresetOnClick(AmdPreset preset)
{
CurrentPreset = preset;
}
private async Task AddPresetOnClick()
private void AddPresetOnClick()
{
CurrentPreset = new AmdPreset();
}
@@ -7,7 +7,7 @@
@using MHC2Gen
@using Microsoft.JSInterop;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject JSHelper jsHelper;
@@ -260,6 +260,13 @@
</form>
</div>
<div class="modal-footer">
@if (DisplayInfo?.IsAdvancedColorSupported == true && ColorProfile != null)
{
<input class="form-check-input" type="checkbox" @bind="ColorProfile.IsHDRProfile" id="associateAsHdrProfile">
<label class="form-check-label" for="associateAsHdrProfile">
Associate as HDR profile
</label>
}
<button type="submit" class="btn btn-primary" @onclick="InstallOnClick" disabled="@(ColorProfile == null)">Install and set as default</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" @onclick="CloseOnClick">Close</button>
<button type="submit" class="btn btn-primary" @onclick="ApplyClick" disabled="@(ColorProfile == null)">Save</button>
@@ -290,11 +297,10 @@
private string WasValidated = "";
private bool IsVisible;
private DisplayPrimariesSource DisplayPrimariesSource;
private bool IsInstalled;
protected override async Task OnParametersSetAsync()
{
if (ColorProfileName == null)
if (ColorProfileName == null || !IsVisible)
{
return;
}
@@ -305,7 +311,7 @@
}
else
{
ColorProfile = await _rpcClientService.CallAsync<ColorProfileDto>("ColorProfileService", "GetColorProfile", ColorProfileName, DisplayInfo?.IsHdrSupportedAndEnabled ?? false);
ColorProfile = await _rpcClientService.CallAsync<ColorProfileDto>("ColorProfileService", "GetColorProfile", ColorProfileName, DisplayInfo?.DeviceName);
}
if (ColorProfile != null)
@@ -386,8 +392,6 @@
ColorProfile.UpdatePrimariesAndLuminance(CurrentColorInfo);
var result = await _rpcClientService.CallAsync<bool>("ColorProfileService", "InstallAndActivateColorProfile", ColorProfile, DisplayInfo.DeviceName);
IsInstalled = true;
}
private async Task CloseOnClick()
@@ -7,7 +7,7 @@
@using ColorControl.UI.Generics
@using ColorControl.UI.Services
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject JSHelper jsHelper;
@@ -18,7 +18,7 @@
<ConfirmModal Title="Delete color profile" Message="Are you sure you want to delete the color profile?" OnConfirm="ColorProfileOnDeleteConfirmed" />
<ConfirmModal ModalId="disassociateConfirmModal" Title="Disassociate color profile" Message="Are you sure you want to disassociate the color profile from the selected display?" OnConfirm="ColorProfileOnDisassociateConfirmed" />
<ConfirmModal ModalId="associateConfirmModal" Title="Associate color profile" Message="Are you sure you want to associate the color profile with the selected display?" OnConfirm="ColorProfileOnAssociateConfirmed" />
<ConfirmModal ModalId="associateConfirmModal" ExtraFields="AssociateFields" Title="Associate color profile" Message="Are you sure you want to associate the color profile with the selected display?" OnConfirm="ColorProfileOnAssociateConfirmed" />
<h2>Displays</h2>
@@ -44,22 +44,7 @@ else
}
</select>
</div>
@* <div class="col-lg-6 mb-3">
<div class="card h-100">
<div class="card-header d-flex align-items-baseline">
<span>
@display.DisplayName @@ @display.AdapterName
</span>
</div>
<div class="card-body">
<small class="text-body">@display.DevicePath</small>
<small class="text-muted">EDID? @display.DisplayColors.Any(dc => dc.DisplayPrimariesSource == MHC2Gen.DisplayPrimariesSource.EDID)</small>
</div>
</div>
</div>
*@ }
}
</div>
}
@@ -70,7 +55,7 @@ else
else
{
<div class="mb-2 d-flex align-items-center">
<h2>Display Associated Color profiles (@(SelectedDisplay.IsHdrSupportedAndEnabled ? "HDR" : "SDR"))</h2>
<h2>Display Associated Color profiles</h2>
<div class="d-flex ms-auto">
<button type="button" class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => AddColorProfileOnClick()">
Add
@@ -88,37 +73,49 @@ else
<div class="list-group">
@foreach (var colorProfile in SelectedDisplay.ColorProfiles)
{
<a class="list-group-item list-group-item-action" @onclick="() => SetColorProfileOnClick(colorProfile)" @onclick:preventDefault @onclick:stopPropagation>
<span class="list-group-item list-group-item-action" @onclick="() => SetColorProfileOnClick(colorProfile)" @onclick:preventDefault @onclick:stopPropagation>
<div class="d-flex align-items-start justify-content-between">
<div>
<h5 class="mb-1">
@colorProfile
@if (colorProfile == SelectedDisplay?.DefaultColorProfile)
@if (colorProfile.IsHDRProfile)
{
<span class="ms-2 badge text-bg-warning" title="Active color profile">Active</span>
<span class="me-2 badge text-bg-info" title="HDR profile">HDR</span>
}
else
{
<span class="me-2 badge text-bg-secondary" title="SDR profile">SDR</span>
}
@colorProfile.Name
@if (colorProfile.IsHDRProfile && colorProfile.Name == SelectedDisplay?.DefaultHdrColorProfile)
{
<span class="ms-2 badge text-bg-warning" title="Active HDR color profile">Active HDR</span>
}
else if (!colorProfile.IsHDRProfile && colorProfile.Name == SelectedDisplay?.DefaultSdrColorProfile)
{
<span class="ms-2 badge text-bg-warning" title="Active SDR color profile">Active SDR</span>
}
</h5>
</div>
<span class="d-none d-lg-block">
<button class="btn btn-warning btn-sm" data-bs-toggle="modal" data-bs-target="#disassociateConfirmModal" @onclick="() => SelectedColorProfileName = colorProfile" @onclick:preventDefault @onclick:stopPropagation>Disassociate</button>
<button class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#confirmModal" @onclick="() => DeleteColorProfileOnClick(colorProfile)" @onclick:preventDefault @onclick:stopPropagation>Delete</button>
<button class="btn btn-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => CloneColorProfileOnClick(colorProfile)" @onclick:preventDefault @onclick:stopPropagation>Clone</button>
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => EditColorProfileOnClick(colorProfile)" @onclick:preventDefault @onclick:stopPropagation>Edit</button>
<button class="btn btn-warning btn-sm" data-bs-toggle="modal" data-bs-target="#disassociateConfirmModal" @onclick="() => SelectedColorProfile = colorProfile" @onclick:preventDefault @onclick:stopPropagation>Disassociate</button>
<button class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#confirmModal" @onclick="() => DeleteColorProfileOnClick(colorProfile.Name)" @onclick:preventDefault @onclick:stopPropagation>Delete</button>
<button class="btn btn-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => CloneColorProfileOnClick(colorProfile.Name)" @onclick:preventDefault @onclick:stopPropagation>Clone</button>
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => EditColorProfileOnClick(colorProfile.Name)" @onclick:preventDefault @onclick:stopPropagation>Edit</button>
</span>
<div class="d-lg-none" @onclick:preventDefault @onclick:stopPropagation>
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-three-dots-vertical"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#disassociateConfirmModal" @onclick="() => SelectedColorProfileName = colorProfile">Disassociate</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#confirmModal" @onclick="() => DeleteColorProfileOnClick(colorProfile)">Delete</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => CloneColorProfileOnClick(colorProfile)">Clone</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => EditColorProfileOnClick(colorProfile)">Edit</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#disassociateConfirmModal" @onclick="() => SelectedColorProfileName = colorProfile.Name">Disassociate</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#confirmModal" @onclick="() => DeleteColorProfileOnClick(colorProfile.Name)">Delete</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => CloneColorProfileOnClick(colorProfile.Name)">Clone</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => EditColorProfileOnClick(colorProfile.Name)">Edit</a></li>
</ul>
</div>
</div>
</a>
</span>
}
</div>
}
@@ -149,7 +146,7 @@ else
</div>
<span class="d-none d-lg-block">
<button class="btn btn-warning btn-sm" data-bs-toggle="modal" data-bs-target="#associateConfirmModal" @onclick="() => SelectedColorProfileName = colorProfile" @onclick:preventDefault @onclick:stopPropagation>Associate</button>
<button class="btn btn-warning btn-sm" data-bs-toggle="modal" data-bs-target="#associateConfirmModal" @onclick="() => AssociateColorProfileOnClick(colorProfile)" @onclick:preventDefault @onclick:stopPropagation>Associate</button>
<button class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#confirmModal" @onclick="() => DeleteColorProfileOnClick(colorProfile)" @onclick:preventDefault @onclick:stopPropagation>Delete</button>
<button class="btn btn-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => CloneColorProfileOnClick(colorProfile)" @onclick:preventDefault @onclick:stopPropagation>Clone</button>
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => EditColorProfileOnClick(colorProfile)" @onclick:preventDefault @onclick:stopPropagation>Edit</button>
@@ -159,7 +156,7 @@ else
<i class="bi bi-three-dots-vertical"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#associateConfirmModal" @onclick="() => SelectedColorProfileName = colorProfile">Associate</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#associateConfirmModal" @onclick="() => AssociateColorProfileOnClick(colorProfile)">Associate</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#confirmModal" @onclick="() => DeleteColorProfileOnClick(colorProfile)">Delete</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => CloneColorProfileOnClick(colorProfile)">Clone</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#colorProfileModal" @onclick="() => EditColorProfileOnClick(colorProfile)">Edit</a></li>
@@ -179,19 +176,19 @@ else
private DisplayInfoDto? SelectedDisplay;
private List<DisplayInfoDto>? Displays;
private string? SelectedColorProfileName;
private ColorProfileDto? SelectedColorProfile;
private bool UseAsTemplate;
private List<string>? ColorProfileNames;
private List<FieldDefinition>? AssociateFields;
private FieldDefinition AskHdrAssociationField = new FieldDefinition { Label = "Associate as HDR profile", FieldType = FieldType.CheckBox, Value = false };
protected override async Task OnInitializedAsync()
{
await RefreshDisplays();
}
protected override async Task OnAfterRenderAsync(bool firstTime)
{
}
private async Task AddColorProfileOnClick()
private void AddColorProfileOnClick()
{
SelectedColorProfileName = "";
}
@@ -203,26 +200,47 @@ else
await jsHelper.OpenModal("colorProfileModal");
}
private async Task SetColorProfileOnClick(string colorProfile)
private async Task SetColorProfileOnClick(ColorProfileDto colorProfile)
{
if (SelectedDisplay == null)
{
return;
}
var result = await _rpcClientService.CallAsync<bool>("ColorProfileService", "SetDisplayDefaultColorProfile", SelectedDisplay.DeviceName, colorProfile, Type.Missing, SelectedDisplay.IsHdrSupportedAndEnabled);
var result = await _rpcClientService.CallAsync<bool>("ColorProfileService", "SetDisplayDefaultColorProfile", SelectedDisplay.DeviceName, colorProfile.Name, Type.Missing, colorProfile.IsHDRProfile);
if (result)
{
SelectedDisplay.DefaultColorProfile = colorProfile;
if (colorProfile.IsHDRProfile)
{
SelectedDisplay.DefaultHdrColorProfile = colorProfile.Name;
}
else
{
SelectedDisplay.DefaultSdrColorProfile = colorProfile.Name;
}
}
}
private async Task DeleteColorProfileOnClick(string colorProfile)
private void AssociateColorProfileOnClick(string colorProfile)
{
SelectedColorProfileName = colorProfile;
if (SelectedDisplay?.IsAdvancedColorSupported == true)
{
AskHdrAssociationField.Value = false;
AssociateFields = [AskHdrAssociationField];
}
else
{
AssociateFields = null;
}
}
private void DeleteColorProfileOnClick(string colorProfile)
{
SelectedColorProfileName = colorProfile;
}
private async Task CloneColorProfileOnClick(string colorProfile)
private void CloneColorProfileOnClick(string colorProfile)
{
UseAsTemplate = true;
SelectedColorProfileName = colorProfile;
@@ -245,14 +263,14 @@ else
private async Task ColorProfileOnDisassociateConfirmed()
{
if (SelectedColorProfileName == null || SelectedDisplay == null)
if (SelectedColorProfile == null || SelectedDisplay == null)
{
return;
}
await _rpcClientService.CallAsync<bool>("ColorProfileService", "RemoveDisplayColorProfile", SelectedDisplay.DeviceName, SelectedColorProfileName, SelectedDisplay.IsHdrSupportedAndEnabled);
await _rpcClientService.CallAsync<bool>("ColorProfileService", "RemoveDisplayColorProfile", SelectedDisplay.DeviceName, SelectedColorProfile.Name, SelectedColorProfile.IsHDRProfile);
SelectedColorProfileName = null;
SelectedColorProfile = null;
await RefreshDisplays();
StateHasChanged();
@@ -265,7 +283,7 @@ else
return;
}
await _rpcClientService.CallAsync<bool>("ColorProfileService", "AddDisplayColorProfile", SelectedDisplay.DeviceName, SelectedColorProfileName, false, SelectedDisplay.IsHdrSupportedAndEnabled);
await _rpcClientService.CallAsync<bool>("ColorProfileService", "AddDisplayColorProfile", SelectedDisplay.DeviceName, SelectedColorProfileName, false, AskHdrAssociationField.BoolValue);
SelectedColorProfileName = null;
@@ -273,9 +291,16 @@ else
StateHasChanged();
}
private void SelectedDisplayChanged()
private async Task SelectedDisplayChanged()
{
SelectedDisplay = Displays?.FirstOrDefault(d => d.DisplayId == SelectedDisplayId);
ColorProfileNames = await _rpcClientService.CallAsync<List<string>>("ColorProfileService", "GetAllColorProfileNames");
if (SelectedDisplay != null)
{
ColorProfileNames = ColorProfileNames?.Except(SelectedDisplay.ColorProfiles.Select(p => p.Name)).ToList();
}
}
private async Task AfterColorProfileSaved(ColorProfileDto colorProfile)
@@ -288,14 +313,11 @@ else
{
Displays = await _rpcClientService.CallAsync<List<DisplayInfoDto>>("ColorProfileService", "GetDisplayInfos");
ColorProfileNames = await _rpcClientService.CallAsync<List<string>>("ColorProfileService", "GetAllColorProfileNames");
if (Displays?.Any() == true)
{
SelectedDisplay = Displays.FirstOrDefault(d => d.DisplayId == SelectedDisplayId) ?? Displays.First();
SelectedDisplayId = SelectedDisplay.DisplayId;
ColorProfileNames = ColorProfileNames?.Except(SelectedDisplay.ColorProfiles).ToList();
SelectedDisplayId = (Displays.FirstOrDefault(d => d.DisplayId == SelectedDisplayId) ?? Displays.First()).DisplayId;
}
await SelectedDisplayChanged();
}
}
@@ -6,7 +6,7 @@
@using NvAPIWrapper.Native.Display
@using ColorControl.Shared.Common
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@@ -5,7 +5,7 @@
@using ColorControl.Shared.Common;
@using ColorControl.UI.Components.Pages.Generic
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
<div class="modal" id="settingsModal" tabindex="-1">
@@ -8,7 +8,7 @@
@using ColorControl.UI.Generics
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject ProtectedLocalStorage _localStorage
@@ -59,7 +59,7 @@ else
<div class="list-group">
@foreach (var preset in Presets)
{
<a class="list-group-item list-group-item-action" @onclick="() => PresetOnClick(preset)">
<span class="list-group-item list-group-item-action" @onclick="() => PresetOnClick(preset)">
<div class="d-flex align-items-start justify-content-between">
<div>
<h5 class="mb-1">
@@ -86,7 +86,7 @@ else
</ul>
</div>
</div>
</a>
</span>
}
</div>
</div>
@@ -120,18 +120,18 @@ else
await _rpcClientService.CallAsync<bool>("GameService", "ApplyPresetWithId", preset.id);
}
private async Task PresetOnEditClick(GamePreset preset)
private void PresetOnEditClick(GamePreset preset)
{
CurrentPreset = preset;
}
private async Task PresetOnCloneClick(GamePreset preset)
private void PresetOnCloneClick(GamePreset preset)
{
CurrentPreset = new GamePreset(preset);
CurrentPreset.SetCloneValues();
}
private async Task PresetOnDeleteClick(GamePreset preset)
private void PresetOnDeleteClick(GamePreset preset)
{
CurrentPreset = preset;
}
@@ -148,7 +148,7 @@ else
StateHasChanged();
}
private async Task AddPresetOnClick()
private void AddPresetOnClick()
{
CurrentPreset = new GamePreset();
}
@@ -2,7 +2,7 @@
@using ColorControl.UI.Services;
@using ColorControl.Shared.Common;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
<FieldsModal ModalId="@ModalId" Fields="Fields" Title="@Title" OnConfirm="ConfirmClick"></FieldsModal>
@@ -19,13 +19,21 @@
[Parameter]
public string ModalId { get; set; } = "confirmModal";
[Parameter]
public List<FieldDefinition>? ExtraFields { get; set; }
public List<FieldDefinition>? Fields { get; set; }
protected override async Task OnParametersSetAsync()
protected override void OnParametersSet()
{
if (Message != null)
{
Fields = [new FieldDefinition { FieldType = FieldType.Label, Label = Message }];
if (ExtraFields != null)
{
Fields.AddRange(ExtraFields);
}
}
}
@@ -2,7 +2,7 @@
@using ColorControl.UI.Services;
@using ColorControl.Shared.Common;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject NavigationManager _navigationManager;
@@ -2,7 +2,7 @@
@using ColorControl.UI.Services;
@using ColorControl.Shared.Common;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject NavigationManager _navigationManager;
@@ -120,7 +120,7 @@
}
}
private async Task OnClose(MouseEventArgs e)
private void OnClose(MouseEventArgs e)
{
IsVisible = false;
}
@@ -4,7 +4,7 @@
@using ColorControl.Shared.Common;
@using ColorControl.UI.Services
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject JSHelper jsHelper;
@inject NotificationService notificationService;
@@ -13,7 +13,7 @@
@if (Notifications?.Any() == true)
{
<div aria-live="polite" aria-atomic="true" class="position-relative">
<div class="toast-container bottom-0 end-0 p-3">
<div class="toast-container position-fixed bottom-0 end-0 p-3">
@foreach (var notification in Notifications)
{
@@ -48,7 +48,7 @@
@code {
private List<NotificationDto> Notifications { get; } = [];
protected override async Task OnAfterRenderAsync(bool firstRender)
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
@@ -77,7 +77,7 @@
notification.ShownAt = DateTime.UtcNow;
}
private async Task NotificationOnClick(NotificationDto notification)
private void NotificationOnClick(NotificationDto notification)
{
if (notification.InternalUrl != null)
{
@@ -3,7 +3,7 @@
@using ColorControl.UI.Services;
@using ColorControl.Shared.Common;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@if (Label != null)
{
@@ -222,7 +222,7 @@
private List<FieldDefinition>? ActionFields;
protected override async Task OnParametersSetAsync()
protected override void OnParametersSet()
{
if (Steps != null)
{
@@ -369,7 +369,7 @@
await EmitSteps();
}
private async Task RawTextOnChange(ChangeEventArgs e)
private void RawTextOnChange(ChangeEventArgs e)
{
RawText = e.Value?.ToString();
}
@@ -3,7 +3,7 @@
@using ColorControl.UI.Services;
@using ColorControl.Shared.Common;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@if (Triggers != null)
{
+1 -1
View File
@@ -6,7 +6,7 @@
@using ColorControl.UI.Generics
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
+1 -1
View File
@@ -3,7 +3,7 @@
@using ColorControl.Shared.Common;
@using ColorControl.UI.Services;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@@ -4,7 +4,7 @@
@using NvAPIWrapper.Native.Display
@using ColorControl.Shared.Common
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@@ -143,6 +143,14 @@
<input class="form-check-input" type="checkbox" role="switch" id="checkWindowsPowerOff" @bind="Device.Options.PowerOffByWindows">
<label class="form-check-label" for="checkWindowsPowerOff">Use Windows power settings to power off</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="checkPowerOnAfterSessionUnlock" @bind="Device.Options.PowerOnAfterSessionUnlock">
<label class="form-check-label" for="checkPowerOnAfterSessionUnlock">Power on when unlocking the pc</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="checkPowerOffAfterSessionLock" @bind="Device.Options.PowerOffAfterSessionLock">
<label class="form-check-label" for="checkPowerOffAfterSessionLock">Power off when locking the pc</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="checkUseSecureConnection" @bind="Device.Options.UseSecureConnection">
<label class="form-check-label" for="checkUseSecureConnection">Use secure connection</label>
@@ -177,7 +185,7 @@
private bool? IsTestConnectionSuccessful;
protected override async Task OnParametersSetAsync()
protected override void OnParametersSet()
{
if (_device != Device)
{
@@ -4,7 +4,7 @@
@using ColorControl.Shared.Common;
@using ColorControl.UI.Components.Pages.Generic
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@@ -28,7 +28,7 @@
private FieldDefinition? Field;
private FieldDefinition? DeviceField;
protected override async Task OnParametersSetAsync()
protected override void OnParametersSet()
{
if (Action == null)
{
@@ -6,7 +6,7 @@
@using ColorControl.Shared.Common
@using static ColorControl.UI.Components.Pages.Generic.StepsInput<ColorControl.Shared.Contracts.LG.LgPreset>
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@@ -114,7 +114,7 @@
private string WasValidated = "";
private bool IsVisible;
protected override async Task OnParametersSetAsync()
protected override void OnParametersSet()
{
if (PresetParam == null)
{
@@ -4,7 +4,7 @@
@using ColorControl.Shared.Common;
@using ColorControl.UI.Components.Pages.Generic
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
<FieldsModal Title="Lg settings" ConfirmCaption="Save" ModalId="settingsModal" Fields="Fields" OnConfirm="ApplyClick" OnShow="ModalOnShow"></FieldsModal>
@@ -9,7 +9,7 @@
@using ColorControl.UI.Generics
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject ProtectedLocalStorage _localStorage
@@ -162,7 +162,7 @@ else
<div class="list-group">
@foreach (var preset in Presets)
{
<a class="list-group-item list-group-item-action" @onclick="() => PresetOnClick(preset)" @onclick:preventDefault @onclick:stopPropagation>
<span class="list-group-item list-group-item-action" @onclick="() => PresetOnClick(preset)" @onclick:preventDefault @onclick:stopPropagation>
<div class="d-flex align-items-start justify-content-between">
<div>
<h5 class="mb-1">@preset.name <small class="text-muted">@GetDeviceName(preset)</small></h5>
@@ -188,7 +188,7 @@ else
</ul>
</div>
</div>
</a>
</span>
}
</div>
</div>
@@ -248,18 +248,18 @@ else
await _rpcClientService.CallAsync<bool>("LgService", "ApplyPresetWithId", preset.id);
}
private async Task PresetOnEditClick(LgPreset preset)
private void PresetOnEditClick(LgPreset preset)
{
CurrentPreset = preset;
}
private async Task PresetOnCloneClick(LgPreset preset)
private void PresetOnCloneClick(LgPreset preset)
{
CurrentPreset = new LgPreset(preset);
CurrentPreset.SetCloneValues();
}
private async Task PresetOnDeleteClick(LgPreset preset)
private void PresetOnDeleteClick(LgPreset preset)
{
CurrentPreset = preset;
}
@@ -276,17 +276,17 @@ else
StateHasChanged();
}
private async Task DeviceOnClick(LgDeviceDto device)
private void DeviceOnClick(LgDeviceDto device)
{
CurrentDevice = device;
}
private async Task AddDeviceOnClick()
private void AddDeviceOnClick()
{
CurrentDevice = new LgDeviceDto { IsCustom = true };
}
private async Task AddPresetOnClick()
private void AddPresetOnClick()
{
CurrentPreset = new LgPreset();
}
@@ -320,7 +320,7 @@ else
StateHasChanged();
}
private async Task ActionOnclick(InvokableActionDto<LgPreset> action)
private void ActionOnclick(InvokableActionDto<LgPreset> action)
{
CurrentInvokableAction = action;
}
@@ -3,7 +3,7 @@
@using ColorControl.Shared.Contracts
@using ColorControl.UI.Services;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@@ -147,6 +147,7 @@ else
"WARN" => "warning",
"ERROR" => "danger",
"FATAL" => "secondary",
_ => "info"
};
public bool Show(NLog.LogLevel level) => LogLevel >= level;
@@ -200,7 +201,7 @@ else
await _rpcClientService.CallAsync<bool>("LoggingService", "SetLogLevel", value);
}
private async Task LogLevelFilterInput(ChangeEventArgs e)
private void LogLevelFilterInput(ChangeEventArgs e)
{
var value = e.Value as string ?? NLog.LogLevel.Debug.Name;
logLevelFilter = NLog.LogLevel.FromString(value);
@@ -4,7 +4,7 @@
@using NvAPIWrapper.Native.Display
@using ColorControl.Shared.Common;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@@ -4,11 +4,10 @@
@using NvAPIWrapper.Native.Display
@using ColorControl.Shared.Common;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@inject NavigationManager _navigationManager;
@inject JSHelper jsHelper;
<div class="modal modal-lg" id="driverSettingsModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" @onfocus="OnFocus">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered">
@@ -104,7 +103,7 @@
else
{
<button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#presetModal" @onclick="() => IsVisible = false">Close</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#presetModal" @onclick="ApplyClick">Save</button>
<button type="button" class="btn btn-primary" @onclick="ApplyClick">Save</button>
}
</div>
</div>
@@ -215,6 +214,9 @@
{
Preset.UpdateDriverSettings(changedSettings);
await jsHelper.CloseModal("driverSettingsModal");
await jsHelper.OpenModal("presetModal");
return;
}
@@ -0,0 +1,195 @@
@using ColorControl.Shared.Contracts
@using ColorControl.Shared.Contracts.NVIDIA
@using ColorControl.UI.Services;
@using NvAPIWrapper.Native.Display
@using ColorControl.Shared.Common;
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject JSHelper jsHelper;
<div class="modal modal-lg" id="gpuSettingsModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" @onfocus="OnFocus">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">@(Preset != null ? $"GPU settings for {Preset.IdOrName}" : $"GPU settings for {GpuInfo?.Name ?? "?"}")</h5>
@if (Preset == null)
{
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" @onclick="() => IsVisible = false"></button>
}
else
{
<button type="button" class="btn-close" data-bs-toggle="modal" data-bs-target="#presetModal" aria-label="Close" @onclick="() => IsVisible = false"></button>
}
</div>
<div class="modal-body">
<form class="row g-1">
@if (OverclockSettings != null && GpuInfos?.Any() == true)
{
<div class="mb-2">
<label class="form-label" for="gpu">GPU</label>
<select class="form-select" id="gpu" @bind="OverclockSettings.PCIIdentifier">
@foreach (var gpu in GpuInfos)
{
<option value="@gpu.PCIIdentifier">@gpu.Name</option>
}
</select>
</div>
}
@if (OverclockSettings != null && GpuInfo != null)
{
<div class="mb-2">
<label class="form-label" for="ocType">Overclock method</label>
<select class="form-select" id="ocType" @bind="OverclockSettings.Type">
@foreach (var ocType in Enum.GetValues<NvGpuOcType>())
{
<option value="@ocType.ToString()">@ocType.GetDescription()</option>
}
</select>
</div>
@if (OverclockSettings.Type is NvGpuOcType.Curve or NvGpuOcType.Offset)
{
<div class="mb-2">
<label class="form-label" for="coreOffset">Core offset in MHz: @OverclockSettings.GraphicsOffsetMHz.ToSignedUnitString() (Min: @GpuInfo.MinCoreDeltaInMHz.ToSignedUnitString(), Max: @GpuInfo.MaxCoreDeltaInMHz.ToSignedUnitString())</label>
<input class="form-range" type="range" step="@GpuInfo.MinCoreStepInMHz" min="@GpuInfo.CorrectedMinCoreDeltaInMHz" max="@GpuInfo.MaxCoreDeltaInMHz" @bind="OverclockSettings.GraphicsOffsetMHz" id="coreOffset">
</div>
<div class="mb-2">
<label class="form-label" for="memoryOffset">Memory offset in MHz: @OverclockSettings.MemoryOffsetMHz.ToSignedUnitString() (Min: @GpuInfo.MinMemoryDeltaInMHz.ToSignedUnitString(), Max: @GpuInfo.MaxMemoryDeltaInMHz.ToSignedUnitString())</label>
<input class="form-range" type="range" step="1" min="@GpuInfo.MinMemoryDeltaInMHz" max="@GpuInfo.MaxMemoryDeltaInMHz" @bind="OverclockSettings.MemoryOffsetMHz" id="memoryOffset">
</div>
}
@if (OverclockSettings.Type is NvGpuOcType.Curve or NvGpuOcType.BoostLock)
{
<div class="mb-2">
<label class="form-label" for="maxCoreFrequency">Maximum core frequency MHz: @OverclockSettings.MaximumFrequencyMHz.ToUnitString() (Min: @GpuInfo.MinCurveFrequencyInMHz.ToUnitString(), Max: @GpuInfo.MaxCurveFrequencyInMHz.ToUnitString())</label>
<input class="form-range" type="range" step="@GpuInfo.MinCoreStepInMHz" min="@GpuInfo.MinCurveFrequencyInMHz" max="@GpuInfo.MaxCurveFrequencyInMHz" @bind="OverclockSettings.MaximumFrequencyMHz" id="maxCoreFrequency">
<div id="maxCoreFrequencyHelp" class="form-text">Setting this value to anything else than '0' will limit the maximum frequency of the curve.</div>
</div>
<div class="mb-2">
<label class="form-label" for="maxCoreVoltage">Maximum core voltage in millivolt: @OverclockSettings.MaximumVoltageMv.ToUnitString("mv") (Min: @GpuInfo.MinCurveVoltageInMv.ToUnitString("mv"), Max: @GpuInfo.MaxCurveVoltageInMv.ToUnitString("mv"))</label>
<input class="form-range" type="range" step="5" min="@GpuInfo.MinCurveVoltageInMv" max="@GpuInfo.MaxCurveVoltageInMv" @bind="OverclockSettings.MaximumVoltageMv" id="maxCoreVoltage">
<div id="maxCoreFrequencyHelp" class="form-text">Setting this value to anything else than '0' will limit the maximum voltage (and also the frequency) of the curve.</div>
</div>
}
@if (OverclockSettings.Type != NvGpuOcType.None)
{
<div class="mb-2">
<label class="form-label" for="voltageBoost">Voltage boost in %: @OverclockSettings.VoltageBoostPercent.ToUnitString("%")</label>
<input class="form-range" type="range" step="1" min="0" max="100" @bind="OverclockSettings.VoltageBoostPercent" id="voltageBoost">
</div>
@if (GpuInfo.DefaultPowerInMilliWatts > 0 && GpuInfo.MaxPowerInMilliWatts > 0 && GpuInfo.MinPowerInMilliWatts > 0 && GpuInfo.MaxPowerInMilliWatts > GpuInfo.MinPowerInMilliWatts)
{
<div class="mb-2">
<label class="form-label" for="powerLimitWatts">Power limit in watts: @(((uint)(OverclockSettings.PowerPCM / 100000f * GpuInfo.DefaultPowerInMilliWatts)).ToKiloUnitString(units: "W")) (@OverclockSettings.PowerPCM.ToKiloUnitString(units: "%")) (Min: @GpuInfo.MinPowerInMilliWatts.ToKiloUnitString(units: "W"), Max: @GpuInfo.MaxPowerInMilliWatts.ToKiloUnitString(units: "W"))</label>
<input class="form-range" type="range" step="1" min="@GpuInfo.MinimumPowerInPCM" max="@GpuInfo.MaximumPowerInPCM" @bind="OverclockSettings.PowerPCM" id="powerLimitWatts">
</div>
}
else
{
<div class="mb-2">
<label class="form-label" for="powerLimitPercentage">Power limit in percentage: @OverclockSettings.PowerPCM.ToKiloUnitString(units: "%") (Min: @GpuInfo.MinimumPowerInPCM.ToKiloUnitString(units: "%"), Max: @GpuInfo.MaximumPowerInPCM.ToKiloUnitString(units: "%")</label>
<input class="form-range" type="range" step="1" min="@GpuInfo.MinimumPowerInPCM" max="@GpuInfo.MaximumPowerInPCM" @bind="OverclockSettings.PowerPCM" id="powerLimitPercentage">
</div>
}
}
}
</form>
</div>
<div class="modal-footer">
@if (Preset == null)
{
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" @onclick="() => IsVisible = false">Close</button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" @onclick="ApplyClick">Apply</button>
}
else
{
<button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#presetModal" @onclick="() => IsVisible = false">Close</button>
<button type="button" class="btn btn-primary" @onclick="ApplyClick">Save</button>
}
</div>
</div>
</div>
</div>
@code {
[Parameter]
public NvGpuOcSettings? OverclockSettings { get; set; }
[Parameter]
public NvGpuInfoDto? GpuInfo { get; set; }
private NvPreset? _preset;
[Parameter]
public NvPreset? Preset { get; set; }
[Parameter]
public Func<NvGpuInfoDto, Task>? AfterApply { get; set; }
private List<NvGpuInfoDto>? GpuInfos;
private bool IsVisible { get; set; }
protected override async Task OnParametersSetAsync()
{
if (_preset != Preset)
{
_preset = Preset;
}
if (GpuInfo == null)
{
GpuInfos = await _rpcClientService.CallAsync<List<NvGpuInfoDto>>("NvService", "GetGpuInfos");
GpuInfo = GpuInfos?.FirstOrDefault();
}
if (Preset != null)
{
OverclockSettings = Preset.ocSettings.FirstOrDefault();
}
if (GpuInfo != null && OverclockSettings == null)
{
OverclockSettings = GpuInfo.OverclockSettings;
}
}
private async Task ApplyClick(MouseEventArgs e)
{
if (OverclockSettings == null)
{
return;
}
if (Preset != null)
{
Preset.UpdateOverclockingSetting(OverclockSettings);
await jsHelper.CloseModal("gpuSettingsModal");
await jsHelper.OpenModal("presetModal");
return;
}
var result = await _rpcClientService.CallAsync<bool>("NvService", "ApplyOverclocking", new List<NvGpuOcSettings> { OverclockSettings });
if (AfterApply != null && GpuInfo != null)
{
await AfterApply.Invoke(GpuInfo);
}
}
private void OnFocus(FocusEventArgs e)
{
if (!IsVisible)
{
IsVisible = true;
}
}
}
@@ -1,11 +1,12 @@
@using ColorControl.Shared.Contracts
@using ColorControl.Shared.Contracts.DisplayInfo
@using ColorControl.Shared.Contracts.NVIDIA
@using ColorControl.UI.Services;
@using ColorControl.UI.Components.Pages.Generic
@using NvAPIWrapper.Native.Display
@using ColorControl.Shared.Common;
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@@ -281,7 +282,7 @@
<div id="driverSettings" class="accordion-collapse collapse" data-bs-parent="#presetAccordion">
<div class="accordion-body">
<div class="mb-3">
<button class="btn btn-secondary btn-sm" type="button" data-bs-target="#driverSettingsModal" data-bs-toggle="modal" @onclick="DriverSettingsOnClick">Open driver settings</button>
<button class="btn btn-secondary btn-sm me-1" type="button" data-bs-target="#driverSettingsModal" data-bs-toggle="modal" @onclick="DriverSettingsOnClick">Open driver settings</button>
<span>@Preset.driverSettings.Count settings configured</span>
</div>
</div>
@@ -460,7 +461,7 @@
</div>
}
@if (ColorProfileNames?.Any() == true)
@if (ColorProfiles?.Any() == true)
{
<div class="accordion-item">
<h2 class="accordion-header">
@@ -480,9 +481,9 @@
<label class="form-label" for="colorProfile">Color profile</label>
<select class="form-select" id="colorProfile" @bind="Preset.ColorProfileSettings.ProfileName">
<option value="">Not selected</option>
@foreach (var colorProfile in ColorProfileNames)
@foreach (var colorProfile in ColorProfiles)
{
<option value="@colorProfile">@colorProfile</option>
<option value="@colorProfile.Name">@colorProfile</option>
}
</select>
</div>
@@ -501,6 +502,42 @@
</div>
}
@if (ShowOverclocking)
{
<div class="accordion-item">
<h2 class="accordion-header">
<span class="d-flex align-items-baseline">
@if (!Preset.IsDisplayPreset)
{
<input class="form-check-input me-1" style="font-size: 1rem" title="Apply these settings" type="checkbox" @bind="Preset.applyOverclocking" id="applyOverclocking">
}
<button class="accordion-button collapsed py-2 @(Preset.applyOverclocking ? "text-warning fw-bold" : "")" type="button" data-bs-toggle="collapse" data-bs-target="#overclocking">
Overclocking
</button>
</span>
</h2>
<div id="overclocking" class="accordion-collapse collapse" data-bs-parent="#presetAccordion">
<div class="accordion-body">
<div class="mb-3">
<button class="btn btn-secondary btn-sm me-1" type="button" data-bs-target="#gpuSettingsModal" data-bs-toggle="modal" @onclick="GpuSettingsOnClick">Open GPU settings</button>
@if (Preset.ocSettings.Any())
{
<span>Overclocking settings configured:</span>
@foreach (var ocSetting in Preset.ocSettings)
{
<div>@ocSetting.ToString()</div>
}
}
else
{
<span>No overclocking settings configured</span>
}
</div>
</div>
</div>
</div>
}
</div>
}
</form>
@@ -525,6 +562,9 @@
[Parameter]
public Func<NvPreset, Task>? SetDriverSettingsPreset { get; set; }
[Parameter]
public Func<NvPreset, Task>? SetGpuSettingsPreset { get; set; }
private string? selectedActiveResolution;
private string? selectedVirtualResolution;
private string? selectedRefreshRate;
@@ -532,15 +572,17 @@
private List<VirtualResolution>? resolutions;
private List<Rational>? refreshRates;
private List<NvPreset>? displayPresets;
private List<string>? ColorProfileNames;
private List<ColorProfileDto>? ColorProfiles;
private string WasValidated = "";
private bool IsVisible;
private bool IsDriverSettingsOpened;
private bool IsGpuSettingsOpened;
private bool ShowOverclocking;
protected override async Task OnParametersSetAsync()
{
if (IsDriverSettingsOpened && Preset != null)
if ((IsDriverSettingsOpened || IsGpuSettingsOpened) && Preset != null)
{
return;
}
@@ -564,8 +606,10 @@
if (Preset != null)
{
ColorProfileNames = await _rpcClientService.CallAsync<List<string>>("ColorProfileService", "GetDisplayColorProfiles", deviceName);
ColorProfiles = await _rpcClientService.CallAsync<List<ColorProfileDto>>("ColorProfileService", "GetAllDisplayColorProfiles", deviceName);
}
ShowOverclocking = true;
}
protected override void OnAfterRender(bool firstRender)
@@ -641,10 +685,20 @@
Preset!.applyHdmiSettings = true;
}
private async Task DriverSettingsOnClick(MouseEventArgs e)
private Task DriverSettingsOnClick(MouseEventArgs e)
{
IsDriverSettingsOpened = true;
SetDriverSettingsPreset?.Invoke(Preset!);
return Task.CompletedTask;
}
private Task GpuSettingsOnClick(MouseEventArgs e)
{
IsGpuSettingsOpened = true;
SetGpuSettingsPreset?.Invoke(Preset!);
return Task.CompletedTask;
}
private void ModalOnFocus(FocusEventArgs e)
@@ -654,6 +708,11 @@
IsDriverSettingsOpened = false;
StateHasChanged();
}
if (IsVisible && IsGpuSettingsOpened)
{
IsGpuSettingsOpened = false;
StateHasChanged();
}
if (!IsVisible)
{
@@ -4,7 +4,7 @@
@using ColorControl.Shared.Common;
@using ColorControl.UI.Components.Pages.Generic
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
<div class="modal" id="settingsModal" tabindex="-1" @onfocus="OnFocus">
@@ -26,7 +26,7 @@
<div class="form-check">
<input class="form-check-input" type="checkbox" @bind="Config.ShowOverclocking" id="showOverclocking">
<label class="form-check-label" for="showOverclocking">
Show overclocking
Show and allow overclocking
</label>
</div>
<div class="form-check">
@@ -8,7 +8,7 @@
@using ColorControl.UI.Generics
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject ProtectedLocalStorage _localStorage
@@ -18,6 +18,7 @@
<NvidiaSettings />
<NvidiaDithering Visible="DitheringVisible" />
<NvidiaDriverSettings Preset="CurrentDriverSettingsPreset" />
<NvidiaGpuSettings Preset="CurrentGpuSettingsPreset" GpuInfo="CurrentGpuInfo" />
<div class="d-flex align-items-center">
<h1>NVIDIA controller</h1>
@@ -39,7 +40,7 @@
<h2>Displays</h2>
<NvidiaPreset PresetParam="CurrentPreset" AfterApply="AfterPresetApplied" SetDriverSettingsPreset="SetDriverSettingsPreset" />
<NvidiaPreset PresetParam="CurrentPreset" AfterApply="AfterPresetApplied" SetDriverSettingsPreset="SetDriverSettingsPreset" SetGpuSettingsPreset="SetGpuSettingsPreset" />
<ConfirmModal Title="Delete preset" Message="Are you sure you want to delete the preset?" OnConfirm="PresetOnDeleteConfirmed" />
@if (DisplayPresets == null)
@@ -117,11 +118,20 @@ else
<span>
@gpuInfo.Name
</span>
@if (NvConfig?.ShowOverclocking == true)
{
<div class="d-flex ms-auto">
<button type="button" class="btn btn-sm btn-primary ms-2" data-bs-toggle="modal" data-bs-target="#gpuSettingsModal" @onclick="() => GpuSettingsOnClick(gpuInfo)">
Settings
</button>
</div>
}
</div>
<div class="card-body">
<small class="text-body">GPU: @gpuInfo.GpuFrequencyInKhz.ToUnitString() @@ @gpuInfo.VoltageInMv mV, @Utils.ToUnitString(values: [gpuInfo.GpuTemperature, gpuInfo.HotSpotTemperature])</small>
<small class="text-body">Memory: @gpuInfo.GpuFrequencyInKhz.ToUnitString(), @Utils.ToUnitString(values: [gpuInfo.MemoryTemperature])</small>
<small class="text-muted">Power: @(gpuInfo.PowerInWatts)W</small>
<small class="text-body">GPU: @gpuInfo.GpuFrequencyInKhz.ToKiloUnitString() @@ @gpuInfo.VoltageInMv mV, @Utils.ToUnitString(values: [gpuInfo.GpuTemperature, gpuInfo.HotSpotTemperature])</small>
<small class="text-body">Memory: @gpuInfo.GpuFrequencyInKhz.ToKiloUnitString(), @Utils.ToUnitString(values: [gpuInfo.MemoryTemperature])</small>
<small class="text-body">Power: @(gpuInfo.PowerInWatts)W</small>
<small class="text-body"><br/>Overclock info: @gpuInfo.OverclockSettings</small>
</div>
</div>
</div>
@@ -241,15 +251,19 @@ else
private List<NvPreset>? Presets;
private List<NvPreset>? DisplayPresets;
private List<NvGpuInfoDto>? GpuInfos;
private NvServiceConfig? NvConfig;
private NvPreset? CurrentPreset;
private NvPreset? CurrentDriverSettingsPreset;
private NvPreset? CurrentGpuSettingsPreset;
private NvGpuInfoDto? CurrentGpuInfo;
private bool DitheringVisible;
private PresetOrder PresetOrder;
protected override async Task OnInitializedAsync()
{
NvConfig = await _rpcClientService.CallAsync<NvServiceConfig>("NvService", "GetConfig");
await RefreshPresets();
DisplayPresets = await _rpcClientService.CallAsync<List<NvPreset>>("NvService", "GetDisplayPresets");
GpuInfos = await _rpcClientService.CallAsync<List<NvGpuInfoDto>>("NvService", "GetGpuInfos");
@@ -271,19 +285,19 @@ else
await _rpcClientService.CallAsync<bool>("NvService", "ApplyPresetWithId", preset.id);
}
private async Task PresetOnEditClick(NvPreset preset)
private void PresetOnEditClick(NvPreset preset)
{
CurrentPreset = preset;
}
private async Task PresetOnCloneClick(NvPreset preset)
private void PresetOnCloneClick(NvPreset preset)
{
CurrentPreset = new NvPreset(preset);
CurrentPreset.name = preset.name;
CurrentPreset.SetCloneValues();
}
private async Task PresetOnDeleteClick(NvPreset preset)
private void PresetOnDeleteClick(NvPreset preset)
{
CurrentPreset = preset;
}
@@ -300,12 +314,12 @@ else
StateHasChanged();
}
private async Task DisplayPresetOnClick(NvPreset preset)
private void DisplayPresetOnClick(NvPreset preset)
{
CurrentPreset = preset;
}
private async Task AddPresetOnClick()
private void AddPresetOnClick()
{
CurrentPreset = new NvPreset();
}
@@ -323,10 +337,26 @@ else
StateHasChanged();
}
private async Task SetDriverSettingsPreset(NvPreset preset)
private Task SetDriverSettingsPreset(NvPreset preset)
{
CurrentDriverSettingsPreset = preset;
StateHasChanged();
return Task.CompletedTask;
}
private Task SetGpuSettingsPreset(NvPreset preset)
{
CurrentGpuSettingsPreset = preset;
StateHasChanged();
return Task.CompletedTask;
}
private void GpuSettingsOnClick(NvGpuInfoDto gpuInfo)
{
CurrentGpuInfo = gpuInfo;
CurrentGpuSettingsPreset = null;
}
private async Task PresetOrderChanged()
@@ -5,7 +5,7 @@
@using ColorControl.Shared.Common;
@using ColorControl.UI.Components.Pages.Generic
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@@ -4,7 +4,7 @@
@using NvAPIWrapper.Native.Display
@using ColorControl.Shared.Common
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@@ -143,6 +143,14 @@
<input class="form-check-input" type="checkbox" role="switch" id="checkWindowsPowerOff" @bind="Device.Options.PowerOffByWindows">
<label class="form-check-label" for="checkWindowsPowerOff">Use Windows power settings to power off</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="checkPowerOnAfterSessionUnlock" @bind="Device.Options.PowerOnAfterSessionUnlock">
<label class="form-check-label" for="checkPowerOnAfterSessionUnlock">Power on when unlocking the pc</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="checkPowerOffAfterSessionLock" @bind="Device.Options.PowerOffAfterSessionLock">
<label class="form-check-label" for="checkPowerOffAfterSessionLock">Power off when locking the pc</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="checkUseSecureConnection" @bind="Device.Options.UseSecureConnection">
<label class="form-check-label" for="checkUseSecureConnection">Use secure connection</label>
@@ -179,7 +187,7 @@
private string WasValidated = "";
private bool IsVisible;
protected override async Task OnParametersSetAsync()
protected override void OnParametersSet()
{
if (_device != Device)
{
@@ -6,7 +6,7 @@
@using ColorControl.Shared.Common
@using static ColorControl.UI.Components.Pages.Generic.StepsInput<ColorControl.Shared.Contracts.Samsung.SamsungPreset>
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject AppState AppState
@@ -114,7 +114,7 @@
private string WasValidated = "";
private bool IsVisible;
protected override async Task OnParametersSetAsync()
protected override void OnParametersSet()
{
if (PresetParam == null)
{
@@ -4,7 +4,7 @@
@using ColorControl.Shared.Common;
@using ColorControl.UI.Components.Pages.Generic
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
<FieldsModal ModalId="serviceMenuModal" Title="@Title" ConfirmCaption="@ConfirmCaption" SecondaryCaption="@SecondaryCaption"
@@ -23,7 +23,7 @@
private Func<Task>? NextAction;
private Func<Task>? SecondaryAction;
protected override async Task OnInitializedAsync()
protected override void OnInitialized()
{
// NextAction = FirstStepExit;
// Title = "Access Service Menu";
@@ -31,7 +31,7 @@
// Fields = [AddField("Service Menu Access Type", ServiceMenuType.FactoryMenu, subLabel: "Both types will not reset your settings. 'FactoryMenu' is recommended for 2024 series but will also work for older ones. Click 'Next >' to continue or 'X' to stop")];
}
protected async Task OnShow()
protected Task OnShow()
{
NextAction = FirstStepExit;
Title = "Access Service Menu";
@@ -50,6 +50,8 @@
}
StateHasChanged();
return Task.CompletedTask;
}
private async Task NextClick()
@@ -98,12 +100,16 @@
ConfirmCaption = "Next >";
SecondaryCaption = "Skip";
SecondaryAction = FactoryMenuSecondStepEnterWithoutExecute;
Fields = [AddField("Service Menu - Advanced", null, FieldType.Label, "If the service menu opened and you want to access the Advanced settings, click 'Next >' or click 'Skip' to skip")];
Fields =
[
AddField("Service Menu - Advanced", null, FieldType.Label, "If the service menu opened and you want to access the Advanced settings, click 'Next >' or click 'Skip' to skip"),
AddField("Advanced Unlock Type", AdvancedUnlockType.TV, subLabel: "Select the desired unlock type for the Advanced section. If the target is a TV choose TV, otherwise choose Monitor")
];
StateHasChanged();
}
protected async Task FactoryMenuSecondStepEnterWithoutExecute()
protected Task FactoryMenuSecondStepEnterWithoutExecute()
{
NextAction = FactoryMenuSecondStepExit;
Title = "Exit Service Menu";
@@ -113,11 +119,27 @@
Fields = [AddField("Exit Service Menu Type", ExitServiceMenuType.Exit, subLabel: "Choose how to exit the service menu. You can either reboot the TV or just exit the service menu (if, for example, no changes have been made)")];
StateHasChanged();
return Task.CompletedTask;
}
protected async Task FactoryMenuSecondStepEnter()
{
await ExecutePreset(SamsungFactoryMenuPresets.PresetAdvanced);
if (Fields == null)
{
return;
}
var unlockType = Fields.First(f => f.ValueType == typeof(AdvancedUnlockType)).ValueAsEnum<AdvancedUnlockType>();
if (unlockType == AdvancedUnlockType.TV)
{
await ExecutePreset(SamsungFactoryMenuPresets.PresetAdvanced);
}
else
{
await ExecutePreset(SamsungFactoryMenuPresets.PresetAdvancedMonitor);
}
await FactoryMenuSecondStepEnterWithoutExecute();
}
@@ -4,7 +4,7 @@
@using ColorControl.Shared.Common;
@using ColorControl.UI.Components.Pages.Generic
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
<FieldsModal Title="Samsung settings" ConfirmCaption="Save" ModalId="settingsModal" Fields="Fields" OnConfirm="ApplyClick" OnShow="ModalOnShow"></FieldsModal>
@@ -9,7 +9,7 @@
@using ColorControl.UI.Generics
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@rendermode InteractiveServer
@rendermode Constants.RenderMode
@inject RpcUiClientService _rpcClientService
@inject ProtectedLocalStorage _localStorage
@@ -160,7 +160,7 @@ else
<div class="list-group">
@foreach (var preset in Presets)
{
<a class="list-group-item list-group-item-action" @onclick="() => PresetOnClick(preset)" @onclick:preventDefault @onclick:stopPropagation>
<span class="list-group-item list-group-item-action" @onclick="() => PresetOnClick(preset)" @onclick:preventDefault @onclick:stopPropagation>
<div class="d-flex align-items-start justify-content-between">
<div>
<h5 class="mb-1">@preset.name <small class="text-muted">@GetDeviceName(preset)</small></h5>
@@ -186,7 +186,7 @@ else
</ul>
</div>
</div>
</a>
</span>
}
</div>
</div>
@@ -229,18 +229,18 @@ else
await _rpcClientService.CallAsync<bool>("SamsungService", "ApplyPresetWithId", preset.id);
}
private async Task PresetOnEditClick(SamsungPreset preset)
private void PresetOnEditClick(SamsungPreset preset)
{
CurrentPreset = preset;
}
private async Task PresetOnCloneClick(SamsungPreset preset)
private void PresetOnCloneClick(SamsungPreset preset)
{
CurrentPreset = new SamsungPreset(preset);
CurrentPreset.SetCloneValues();
}
private async Task PresetOnDeleteClick(SamsungPreset preset)
private void PresetOnDeleteClick(SamsungPreset preset)
{
CurrentPreset = preset;
}
@@ -257,17 +257,17 @@ else
StateHasChanged();
}
private async Task DeviceOnClick(SamsungDeviceDto device)
private void DeviceOnClick(SamsungDeviceDto device)
{
CurrentDevice = device;
}
private async Task AddDeviceOnClick()
private void AddDeviceOnClick()
{
CurrentDevice = new SamsungDeviceDto { IsCustom = true };
}
private async Task AddPresetOnClick()
private void AddPresetOnClick()
{
CurrentPreset = new SamsungPreset();
}
+15 -8
View File
@@ -1,11 +1,18 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
public static class Constants
{
public const string Primary = "primary";
public const string Secondary = "secondary";
public const string Success = "success";
public const string Danger = "danger";
public const string Warning = "warning";
public const string Info = "info";
public const string Light = "light";
public const string Dark = "dark";
public const string Primary = "primary";
public const string Secondary = "secondary";
public const string Success = "success";
public const string Danger = "danger";
public const string Warning = "warning";
public const string Info = "info";
public const string Light = "light";
public const string Dark = "dark";
public static IComponentRenderMode RenderMode = new InteractiveServerRenderMode(prerender: false);
}
+24 -16
View File
@@ -2,25 +2,33 @@
public class NotificationService
{
public event Func<NotificationDto, Task>? OnNotification;
public event Func<NotificationDto, Task>? OnNotification;
private List<NotificationDto> _scheduledNotifications = new();
private List<NotificationDto> _scheduledNotifications = new();
public void SendNotification(NotificationDto notification)
{
var now = DateTime.UtcNow;
if (notification.ScheduledAt == null || notification.ScheduledAt <= now)
{
OnNotification?.Invoke(notification);
public void SendNotification(NotificationDto notification)
{
var now = DateTime.UtcNow;
if (notification.ScheduledAt == null || notification.ScheduledAt <= now)
{
OnNotification?.Invoke(notification);
return;
}
return;
}
Task.Run(async () =>
{
await Task.Delay(notification.ScheduledAt.Value - now);
Task.Run(async () =>
{
await Task.Delay(notification.ScheduledAt.Value - now);
OnNotification?.Invoke(notification);
});
}
OnNotification?.Invoke(notification);
});
}
public async Task SendNotificationDirect(NotificationDto notification)
{
if (OnNotification != null)
{
await OnNotification.Invoke(notification);
}
}
}
@@ -14,7 +14,7 @@ public class RpcUiClientService(NotificationService notificationService)
{
public string? LastErrorMessage { get; private set; }
public async Task<T> CallAsync<T>(string serviceName, string method, params object[] arguments)
public async Task<T> CallAsync<T>(string serviceName, string method, params object?[] arguments)
{
var rpcMessage = new SvcRpcMessage
{
@@ -28,7 +28,7 @@ public class RpcUiClientService(NotificationService notificationService)
return await SendRpcMessageAsync<T>(rpcMessage, timeout, pipeName: PipeUtils.MainPipe);
}
public async Task<T> CallWithOptionsAsync<T>(string serviceName, string method, RpcUiClientOptions options, params object[] arguments)
public async Task<T> CallWithOptionsAsync<T>(string serviceName, string method, RpcUiClientOptions options, params object?[] arguments)
{
var rpcMessage = new SvcRpcMessage
{
@@ -73,7 +73,7 @@ public class RpcUiClientService(NotificationService notificationService)
{
LastErrorMessage = resultMessage?.ErrorMessage ?? "Unknown communication error";
notificationService.SendNotification(new NotificationDto(LastErrorMessage, Constants.Danger));
await notificationService.SendNotificationDirect(new NotificationDto(LastErrorMessage, Constants.Danger));
return default;
}