Browse Source

Move Inference settings to sub page

pull/324/head
Ionite 12 months ago
parent
commit
9ae2fb9d05
No known key found for this signature in database
  1. 90
      StabilityMatrix.Avalonia/Languages/Resources.Designer.cs
  2. 30
      StabilityMatrix.Avalonia/Languages/Resources.resx
  3. 215
      StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs
  4. 168
      StabilityMatrix.Avalonia/ViewModels/Settings/MainSettingsViewModel.cs
  5. 2
      StabilityMatrix.Avalonia/ViewModels/SettingsViewModel.cs
  6. 148
      StabilityMatrix.Avalonia/Views/Settings/InferenceSettingsPage.axaml
  7. 114
      StabilityMatrix.Avalonia/Views/Settings/MainSettingsPage.axaml
  8. 3
      StabilityMatrix.Avalonia/Views/SettingsPage.axaml

90
StabilityMatrix.Avalonia/Languages/Resources.Designer.cs generated

@ -662,6 +662,15 @@ namespace StabilityMatrix.Avalonia.Languages {
} }
} }
/// <summary>
/// Looks up a localized string similar to Auto Completion.
/// </summary>
public static string Label_AutoCompletion {
get {
return ResourceManager.GetString("Label_AutoCompletion", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Automatically scroll to end of console output. /// Looks up a localized string similar to Automatically scroll to end of console output.
/// </summary> /// </summary>
@ -797,6 +806,15 @@ namespace StabilityMatrix.Avalonia.Languages {
} }
} }
/// <summary>
/// Looks up a localized string similar to Replace underscores with spaces when inserting completions.
/// </summary>
public static string Label_CompletionReplaceUnderscoresWithSpaces {
get {
return ResourceManager.GetString("Label_CompletionReplaceUnderscoresWithSpaces", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Confirm Delete. /// Looks up a localized string similar to Confirm Delete.
/// </summary> /// </summary>
@ -1094,6 +1112,15 @@ namespace StabilityMatrix.Avalonia.Languages {
} }
} }
/// <summary>
/// Looks up a localized string similar to General.
/// </summary>
public static string Label_General {
get {
return ResourceManager.GetString("Label_General", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Height. /// Looks up a localized string similar to Height.
/// </summary> /// </summary>
@ -1112,6 +1139,15 @@ namespace StabilityMatrix.Avalonia.Languages {
} }
} }
/// <summary>
/// Looks up a localized string similar to Image Viewer.
/// </summary>
public static string Label_ImageViewer {
get {
return ResourceManager.GetString("Label_ImageViewer", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Import with Metadata. /// Looks up a localized string similar to Import with Metadata.
/// </summary> /// </summary>
@ -1148,6 +1184,15 @@ namespace StabilityMatrix.Avalonia.Languages {
} }
} }
/// <summary>
/// Looks up a localized string similar to Inference.
/// </summary>
public static string Label_Inference {
get {
return ResourceManager.GetString("Label_Inference", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Inner exception. /// Looks up a localized string similar to Inner exception.
/// </summary> /// </summary>
@ -1418,6 +1463,15 @@ namespace StabilityMatrix.Avalonia.Languages {
} }
} }
/// <summary>
/// Looks up a localized string similar to Output Image Files.
/// </summary>
public static string Label_OutputImageFiles {
get {
return ResourceManager.GetString("Label_OutputImageFiles", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Output Browser. /// Looks up a localized string similar to Output Browser.
/// </summary> /// </summary>
@ -1535,6 +1589,42 @@ namespace StabilityMatrix.Avalonia.Languages {
} }
} }
/// <summary>
/// Looks up a localized string similar to Prompt.
/// </summary>
public static string Label_Prompt {
get {
return ResourceManager.GetString("Label_Prompt", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Prompt Tags.
/// </summary>
public static string Label_PromptTags {
get {
return ResourceManager.GetString("Label_PromptTags", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Tags file to use for suggesting completions (Supports the a1111-sd-webui-tagcomplete .csv format).
/// </summary>
public static string Label_PromptTagsDescription {
get {
return ResourceManager.GetString("Label_PromptTagsDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Import Prompt tags.
/// </summary>
public static string Label_PromptTagsImport {
get {
return ResourceManager.GetString("Label_PromptTagsImport", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Python Packages. /// Looks up a localized string similar to Python Packages.
/// </summary> /// </summary>

30
StabilityMatrix.Avalonia/Languages/Resources.resx

@ -813,4 +813,34 @@
<data name="TeachingTip_MoreCheckpointCategories" xml:space="preserve"> <data name="TeachingTip_MoreCheckpointCategories" xml:space="preserve">
<value>Additional folders such as IPAdapters and TextualInversions (embeddings) can be enabled here</value> <value>Additional folders such as IPAdapters and TextualInversions (embeddings) can be enabled here</value>
</data> </data>
<data name="Label_General" xml:space="preserve">
<value>General</value><comment>A general settings category</comment>
</data>
<data name="Label_Inference" xml:space="preserve">
<value>Inference</value><comment>The Inference feature page</comment>
</data>
<data name="Label_Prompt" xml:space="preserve">
<value>Prompt</value><comment>A settings category for Inference generation prompts</comment>
</data>
<data name="Label_OutputImageFiles" xml:space="preserve">
<value>Output Image Files</value>
</data>
<data name="Label_ImageViewer" xml:space="preserve">
<value>Image Viewer</value>
</data>
<data name="Label_AutoCompletion" xml:space="preserve">
<value>Auto Completion</value>
</data>
<data name="Label_CompletionReplaceUnderscoresWithSpaces" xml:space="preserve">
<value>Replace underscores with spaces when inserting completions</value>
</data>
<data name="Label_PromptTags" xml:space="preserve">
<value>Prompt Tags</value><comment>Tags for image generation prompts</comment>
</data>
<data name="Label_PromptTagsImport" xml:space="preserve">
<value>Import Prompt tags</value>
</data>
<data name="Label_PromptTagsDescription" xml:space="preserve">
<value>Tags file to use for suggesting completions (Supports the a1111-sd-webui-tagcomplete .csv format)</value>
</data>
</root> </root>

215
StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs

@ -1,7 +1,28 @@
using FluentAvalonia.UI.Controls; using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Controls.Notifications;
using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DynamicData.Binding;
using FluentAvalonia.UI.Controls;
using NLog;
using StabilityMatrix.Avalonia.Extensions;
using StabilityMatrix.Avalonia.Models.Inference;
using StabilityMatrix.Avalonia.Models.TagCompletion;
using StabilityMatrix.Avalonia.Services;
using StabilityMatrix.Avalonia.ViewModels.Base; using StabilityMatrix.Avalonia.ViewModels.Base;
using StabilityMatrix.Avalonia.Views.Settings; using StabilityMatrix.Avalonia.Views.Settings;
using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Attributes;
using StabilityMatrix.Core.Helper;
using StabilityMatrix.Core.Models.FileInterfaces;
using StabilityMatrix.Core.Python;
using StabilityMatrix.Core.Services;
using Symbol = FluentIcons.Common.Symbol; using Symbol = FluentIcons.Common.Symbol;
using SymbolIconSource = FluentIcons.FluentAvalonia.SymbolIconSource; using SymbolIconSource = FluentIcons.FluentAvalonia.SymbolIconSource;
@ -9,12 +30,202 @@ namespace StabilityMatrix.Avalonia.ViewModels.Settings;
[View(typeof(InferenceSettingsPage))] [View(typeof(InferenceSettingsPage))]
[Singleton, ManagedService] [Singleton, ManagedService]
public class InferenceSettingsViewModel : PageViewModelBase public partial class InferenceSettingsViewModel : PageViewModelBase
{ {
private readonly INotificationService notificationService;
private readonly ISettingsManager settingsManager;
private readonly ICompletionProvider completionProvider;
/// <inheritdoc /> /// <inheritdoc />
public override string Title => "Inference"; public override string Title => "Inference";
/// <inheritdoc /> /// <inheritdoc />
public override IconSource IconSource => public override IconSource IconSource =>
new SymbolIconSource { Symbol = Symbol.Settings, IsFilled = true }; new SymbolIconSource { Symbol = Symbol.Settings, IsFilled = true };
[ObservableProperty]
private bool isPromptCompletionEnabled = true;
[ObservableProperty]
private IReadOnlyList<string> availableTagCompletionCsvs = Array.Empty<string>();
[ObservableProperty]
private string? selectedTagCompletionCsv;
[ObservableProperty]
private bool isCompletionRemoveUnderscoresEnabled = true;
[ObservableProperty]
[CustomValidation(typeof(InferenceSettingsViewModel), nameof(ValidateOutputImageFileNameFormat))]
private string? outputImageFileNameFormat;
[ObservableProperty]
private string? outputImageFileNameFormatSample;
public IEnumerable<FileNameFormatVar> OutputImageFileNameFormatVars =>
FileNameFormatProvider
.GetSample()
.Substitutions.Select(
kv =>
new FileNameFormatVar
{
Variable = $"{{{kv.Key}}}",
Example = kv.Value.Invoke()
}
);
[ObservableProperty]
private bool isImageViewerPixelGridEnabled = true;
public InferenceSettingsViewModel(INotificationService notificationService, IPrerequisiteHelper prerequisiteHelper, IPyRunner pyRunner, ServiceManager<ViewModelBase> dialogFactory, ICompletionProvider completionProvider, ITrackedDownloadService trackedDownloadService, IModelIndexService modelIndexService, INavigationService<SettingsViewModel> settingsNavigationService, IAccountsService accountsService, ISettingsManager settingsManager)
{
this.settingsManager = settingsManager;
this.notificationService = notificationService;
this.completionProvider = completionProvider;
settingsManager.RelayPropertyFor(
this,
vm => vm.SelectedTagCompletionCsv,
settings => settings.TagCompletionCsv
);
settingsManager.RelayPropertyFor(
this,
vm => vm.IsPromptCompletionEnabled,
settings => settings.IsPromptCompletionEnabled,
true
);
settingsManager.RelayPropertyFor(
this,
vm => vm.IsCompletionRemoveUnderscoresEnabled,
settings => settings.IsCompletionRemoveUnderscoresEnabled,
true
);
this.WhenPropertyChanged(vm => vm.OutputImageFileNameFormat)
.Throttle(TimeSpan.FromMilliseconds(50))
.Subscribe(formatProperty =>
{
var provider = FileNameFormatProvider.GetSample();
var template = formatProperty.Value ?? string.Empty;
if (
!string.IsNullOrEmpty(template)
&& provider.Validate(template) == ValidationResult.Success
)
{
var format = FileNameFormat.Parse(template, provider);
OutputImageFileNameFormatSample = format.GetFileName() + ".png";
}
else
{
// Use default format if empty
var defaultFormat = FileNameFormat.Parse(
FileNameFormat.DefaultTemplate,
provider
);
OutputImageFileNameFormatSample = defaultFormat.GetFileName() + ".png";
}
});
settingsManager.RelayPropertyFor(
this,
vm => vm.OutputImageFileNameFormat,
settings => settings.InferenceOutputImageFileNameFormat,
true
);
settingsManager.RelayPropertyFor(
this,
vm => vm.IsImageViewerPixelGridEnabled,
settings => settings.IsImageViewerPixelGridEnabled,
true
);
ImportTagCsvCommand.WithNotificationErrorHandler(notificationService, LogLevel.Warn);
}
/// <summary>
/// Validator for <see cref="OutputImageFileNameFormat"/>
/// </summary>
public static ValidationResult ValidateOutputImageFileNameFormat(
string? format,
ValidationContext context
)
{
return FileNameFormatProvider.GetSample().Validate(format ?? string.Empty);
}
/// <inheritdoc />
public override void OnLoaded()
{
base.OnLoaded();
UpdateAvailableTagCompletionCsvs();
}
#region Commands
[RelayCommand(FlowExceptionsToTaskScheduler = true)]
private async Task ImportTagCsv()
{
var storage = App.StorageProvider;
var files = await storage.OpenFilePickerAsync(
new FilePickerOpenOptions
{
FileTypeFilter = new List<FilePickerFileType>
{
new("CSV")
{
Patterns = ["*.csv"]
}
}
}
);
if (files.Count == 0)
return;
var sourceFile = new FilePath(files[0].TryGetLocalPath()!);
var tagsDir = settingsManager.TagsDirectory;
tagsDir.Create();
// Copy to tags directory
var targetFile = tagsDir.JoinFile(sourceFile.Name);
await sourceFile.CopyToAsync(targetFile);
// Update index
UpdateAvailableTagCompletionCsvs();
// Trigger load
completionProvider.BackgroundLoadFromFile(targetFile, true);
notificationService.Show(
$"Imported {sourceFile.Name}",
$"The {sourceFile.Name} file has been imported.",
NotificationType.Success
);
}
#endregion
private void UpdateAvailableTagCompletionCsvs()
{
if (!settingsManager.IsLibraryDirSet)
return;
if (settingsManager.TagsDirectory is not { Exists: true } tagsDir)
return;
var csvFiles = tagsDir.Info.EnumerateFiles("*.csv");
AvailableTagCompletionCsvs = csvFiles.Select(f => f.Name).ToImmutableArray();
// Set selected to current if exists
var settingsCsv = settingsManager.Settings.TagCompletionCsv;
if (settingsCsv is not null && AvailableTagCompletionCsvs.Contains(settingsCsv))
{
SelectedTagCompletionCsv = settingsCsv;
}
}
} }

168
StabilityMatrix.Avalonia/ViewModels/Settings/MainSettingsViewModel.cs

@ -102,41 +102,6 @@ public partial class MainSettingsViewModel : PageViewModelBase
[ObservableProperty] [ObservableProperty]
private bool removeSymlinksOnShutdown; private bool removeSymlinksOnShutdown;
// Inference UI section
[ObservableProperty]
private bool isPromptCompletionEnabled = true;
[ObservableProperty]
private IReadOnlyList<string> availableTagCompletionCsvs = Array.Empty<string>();
[ObservableProperty]
private string? selectedTagCompletionCsv;
[ObservableProperty]
private bool isCompletionRemoveUnderscoresEnabled = true;
[ObservableProperty]
[CustomValidation(typeof(MainSettingsViewModel), nameof(ValidateOutputImageFileNameFormat))]
private string? outputImageFileNameFormat;
[ObservableProperty]
private string? outputImageFileNameFormatSample;
public IEnumerable<FileNameFormatVar> OutputImageFileNameFormatVars =>
FileNameFormatProvider
.GetSample()
.Substitutions.Select(
kv =>
new FileNameFormatVar
{
Variable = $"{{{kv.Key}}}",
Example = kv.Value.Invoke()
}
);
[ObservableProperty]
private bool isImageViewerPixelGridEnabled = true;
// Integrations section // Integrations section
[ObservableProperty] [ObservableProperty]
private bool isDiscordRichPresenceEnabled; private bool isDiscordRichPresenceEnabled;
@ -217,71 +182,10 @@ public partial class MainSettingsViewModel : PageViewModelBase
settings => settings.AnimationScale settings => settings.AnimationScale
); );
settingsManager.RelayPropertyFor(
this,
vm => vm.SelectedTagCompletionCsv,
settings => settings.TagCompletionCsv
);
settingsManager.RelayPropertyFor(
this,
vm => vm.IsPromptCompletionEnabled,
settings => settings.IsPromptCompletionEnabled,
true
);
settingsManager.RelayPropertyFor(
this,
vm => vm.IsCompletionRemoveUnderscoresEnabled,
settings => settings.IsCompletionRemoveUnderscoresEnabled,
true
);
this.WhenPropertyChanged(vm => vm.OutputImageFileNameFormat)
.Throttle(TimeSpan.FromMilliseconds(50))
.Subscribe(formatProperty =>
{
var provider = FileNameFormatProvider.GetSample();
var template = formatProperty.Value ?? string.Empty;
if (
!string.IsNullOrEmpty(template)
&& provider.Validate(template) == ValidationResult.Success
)
{
var format = FileNameFormat.Parse(template, provider);
OutputImageFileNameFormatSample = format.GetFileName() + ".png";
}
else
{
// Use default format if empty
var defaultFormat = FileNameFormat.Parse(
FileNameFormat.DefaultTemplate,
provider
);
OutputImageFileNameFormatSample = defaultFormat.GetFileName() + ".png";
}
});
settingsManager.RelayPropertyFor(
this,
vm => vm.OutputImageFileNameFormat,
settings => settings.InferenceOutputImageFileNameFormat,
true
);
settingsManager.RelayPropertyFor(
this,
vm => vm.IsImageViewerPixelGridEnabled,
settings => settings.IsImageViewerPixelGridEnabled,
true
);
DebugThrowAsyncExceptionCommand.WithNotificationErrorHandler( DebugThrowAsyncExceptionCommand.WithNotificationErrorHandler(
notificationService, notificationService,
LogLevel.Warn LogLevel.Warn
); );
ImportTagCsvCommand.WithNotificationErrorHandler(notificationService, LogLevel.Warn);
} }
/// <inheritdoc /> /// <inheritdoc />
@ -291,20 +195,10 @@ public partial class MainSettingsViewModel : PageViewModelBase
await notificationService.TryAsync(completionProvider.Setup()); await notificationService.TryAsync(completionProvider.Setup());
UpdateAvailableTagCompletionCsvs();
// Start accounts update // Start accounts update
accountsService.RefreshAsync().SafeFireAndForget(); accountsService.RefreshAsync().SafeFireAndForget();
} }
public static ValidationResult ValidateOutputImageFileNameFormat(
string? format,
ValidationContext context
)
{
return FileNameFormatProvider.GetSample().Validate(format ?? string.Empty);
}
partial void OnSelectedThemeChanged(string? value) partial void OnSelectedThemeChanged(string? value)
{ {
// In case design / tests // In case design / tests
@ -453,68 +347,6 @@ public partial class MainSettingsViewModel : PageViewModelBase
#endregion #endregion
#region Inference UI
private void UpdateAvailableTagCompletionCsvs()
{
if (!settingsManager.IsLibraryDirSet)
return;
var tagsDir = settingsManager.TagsDirectory;
if (!tagsDir.Exists)
return;
var csvFiles = tagsDir.Info.EnumerateFiles("*.csv");
AvailableTagCompletionCsvs = csvFiles.Select(f => f.Name).ToImmutableArray();
// Set selected to current if exists
var settingsCsv = settingsManager.Settings.TagCompletionCsv;
if (settingsCsv is not null && AvailableTagCompletionCsvs.Contains(settingsCsv))
{
SelectedTagCompletionCsv = settingsCsv;
}
}
[RelayCommand(FlowExceptionsToTaskScheduler = true)]
private async Task ImportTagCsv()
{
var storage = App.StorageProvider;
var files = await storage.OpenFilePickerAsync(
new FilePickerOpenOptions
{
FileTypeFilter = new List<FilePickerFileType>
{
new("CSV") { Patterns = new[] { "*.csv" }, }
}
}
);
if (files.Count == 0)
return;
var sourceFile = new FilePath(files[0].TryGetLocalPath()!);
var tagsDir = settingsManager.TagsDirectory;
tagsDir.Create();
// Copy to tags directory
var targetFile = tagsDir.JoinFile(sourceFile.Name);
await sourceFile.CopyToAsync(targetFile);
// Update index
UpdateAvailableTagCompletionCsvs();
// Trigger load
completionProvider.BackgroundLoadFromFile(targetFile, true);
notificationService.Show(
$"Imported {sourceFile.Name}",
$"The {sourceFile.Name} file has been imported.",
NotificationType.Success
);
}
#endregion
#region System #region System
/// <summary> /// <summary>

2
StabilityMatrix.Avalonia/ViewModels/SettingsViewModel.cs

@ -24,7 +24,7 @@ public partial class SettingsViewModel : PageViewModelBase
public IReadOnlyList<PageViewModelBase> SubPages { get; } public IReadOnlyList<PageViewModelBase> SubPages { get; }
[ObservableProperty] [ObservableProperty]
private ObservableCollection<PageViewModelBase> currentPagePath = new(); private ObservableCollection<PageViewModelBase> currentPagePath = [];
[ObservableProperty] [ObservableProperty]
private PageViewModelBase? currentPage; private PageViewModelBase? currentPage;

148
StabilityMatrix.Avalonia/Views/Settings/InferenceSettingsPage.axaml

@ -4,66 +4,144 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:StabilityMatrix.Avalonia.Controls" xmlns:controls="clr-namespace:StabilityMatrix.Avalonia.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fluentIcons="clr-namespace:FluentIcons.FluentAvalonia;assembly=FluentIcons.FluentAvalonia"
xmlns:inference="clr-namespace:StabilityMatrix.Avalonia.Models.Inference"
xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages" xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mocks="clr-namespace:StabilityMatrix.Avalonia.DesignData" xmlns:mocks="clr-namespace:StabilityMatrix.Avalonia.DesignData"
xmlns:sg="clr-namespace:SpacedGridControl.Avalonia;assembly=SpacedGridControl.Avalonia"
xmlns:system="clr-namespace:System;assembly=System.Runtime" xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:ui="using:FluentAvalonia.UI.Controls" xmlns:ui="using:FluentAvalonia.UI.Controls"
xmlns:vm="clr-namespace:StabilityMatrix.Avalonia.ViewModels" xmlns:vm="clr-namespace:StabilityMatrix.Avalonia.ViewModels"
xmlns:vmSettings="clr-namespace:StabilityMatrix.Avalonia.ViewModels.Settings" xmlns:vmSettings="clr-namespace:StabilityMatrix.Avalonia.ViewModels.Settings"
d:DataContext="{x:Static mocks:DesignData.InferenceSettingsViewModel}" d:DataContext="{x:Static mocks:DesignData.InferenceSettingsViewModel}"
d:DesignHeight="450" d:DesignHeight="650"
d:DesignWidth="800" d:DesignWidth="900"
x:DataType="vmSettings:InferenceSettingsViewModel" x:DataType="vmSettings:InferenceSettingsViewModel"
mc:Ignorable="d"> mc:Ignorable="d">
<controls:UserControlBase.Styles>
<Style Selector="sg|SpacedGrid &gt; ui|SettingsExpander">
<Setter Property="Margin" Value="8,0" />
</Style>
</controls:UserControlBase.Styles>
<ScrollViewer VerticalScrollBarVisibility="Auto"> <ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Margin="8,16" Spacing="8"> <StackPanel Margin="8,16" Spacing="8">
<!-- Theme -->
<Grid RowDefinitions="Auto,*,*,*"> <!-- Prompt -->
<sg:SpacedGrid RowDefinitions="Auto,*" RowSpacing="4">
<TextBlock <TextBlock
Margin="0,0,0,8" Margin="0,0,0,4"
FontWeight="Medium" FontWeight="Medium"
Text="Stuff" /> Text="{x:Static lang:Resources.Label_Prompt}" />
<!-- Auto Completion -->
<ui:SettingsExpander <ui:SettingsExpander
Grid.Row="1" Grid.Row="1"
Margin="8,0,8,4" Margin="8,0"
Header="{x:Static lang:Resources.Label_Theme}" Header="{x:Static lang:Resources.Label_AutoCompletion}">
IconSource="WeatherMoon">
<ui:SettingsExpander.Footer> <ui:SettingsExpander.IconSource>
<ComboBox MinWidth="100" /> <controls:FASymbolIconSource Symbol="fa-solid fa-wand-magic-sparkles" />
</ui:SettingsExpander.Footer> </ui:SettingsExpander.IconSource>
</ui:SettingsExpander>
<ui:SettingsExpander
Grid.Row="2"
Margin="8,0,8,4"
Header="{x:Static lang:Resources.Label_Language}"
IconSource="Character">
<ui:SettingsExpander.Footer> <ui:SettingsExpander.Footer>
<ComboBox MinWidth="100" /> <ToggleSwitch IsChecked="{Binding IsPromptCompletionEnabled}" />
</ui:SettingsExpander.Footer> </ui:SettingsExpander.Footer>
<!-- Tag csv selection -->
<ui:SettingsExpanderItem
Content="{x:Static lang:Resources.Label_PromptTags}"
Description="{x:Static lang:Resources.Label_PromptTagsDescription}"
IconSource="Tag"
IsEnabled="{Binding IsPromptCompletionEnabled}">
<ui:SettingsExpanderItem.Footer>
<ui:FAComboBox ItemsSource="{Binding AvailableTagCompletionCsvs}" SelectedItem="{Binding SelectedTagCompletionCsv}" />
</ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem>
<!-- Tag csv import -->
<ui:SettingsExpanderItem
Content="{x:Static lang:Resources.Label_PromptTagsImport}"
IconSource="Add"
IsEnabled="{Binding IsPromptCompletionEnabled}">
<ui:SettingsExpanderItem.Footer>
<Button Command="{Binding ImportTagCsvCommand}" Content="Import" />
</ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem>
<!-- Remove underscores -->
<ui:SettingsExpanderItem
Content="{x:Static lang:Resources.Label_CompletionReplaceUnderscoresWithSpaces}"
IconSource="Underline"
IsEnabled="{Binding IsPromptCompletionEnabled}">
<ui:SettingsExpanderItem.Footer>
<CheckBox Margin="8" IsChecked="{Binding IsCompletionRemoveUnderscoresEnabled}" />
</ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem>
</ui:SettingsExpander> </ui:SettingsExpander>
<ui:SettingsExpander </sg:SpacedGrid>
Grid.Row="3"
Margin="8,0,8,4"
Header="Inference"
IconSource="Code" />
</Grid>
<!-- Checkpoints Manager Options --> <!-- General -->
<Grid RowDefinitions="auto,*,Auto"> <sg:SpacedGrid RowDefinitions="Auto,*,*" RowSpacing="4">
<TextBlock <TextBlock
Margin="0,0,0,8" Margin="0,0,0,4"
FontWeight="Medium" FontWeight="Medium"
Text="Other stuff" /> Text="{x:Static lang:Resources.Label_General}" />
<!-- Image Viewer -->
<ui:SettingsExpander <ui:SettingsExpander
Grid.Row="1" Grid.Row="1"
Margin="8,0" Header="{x:Static lang:Resources.Label_ImageViewer}"
IconSource="Folder"> IconSource="Image"
<ui:SettingsExpander.Footer> IsExpanded="True">
<CheckBox Margin="8" />
</ui:SettingsExpander.Footer> <!-- Pixel grid -->
<ui:SettingsExpanderItem Content="Show pixel grid at high zoom levels" IconSource="ViewAll">
<ui:SettingsExpanderItem.Footer>
<CheckBox Margin="8" IsChecked="{Binding IsImageViewerPixelGridEnabled}" />
</ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem>
</ui:SettingsExpander>
<!-- Output Image Files -->
<ui:SettingsExpander
Grid.Row="2"
Header="{x:Static lang:Resources.Label_OutputImageFiles}"
IsExpanded="True">
<ui:SettingsExpander.IconSource>
<fluentIcons:SymbolIconSource Symbol="TabDesktopImage" />
</ui:SettingsExpander.IconSource>
<!-- File name pattern -->
<ui:SettingsExpanderItem
Content="File name pattern"
Description="{Binding OutputImageFileNameFormatSample}"
IconSource="Rename">
<ui:SettingsExpanderItem.Footer>
<TextBox
Name="OutputImageFileNameFormatTextBox"
MinWidth="150"
FontFamily="Cascadia Code,Consolas,Menlo,Monospace"
FontSize="13"
Text="{Binding OutputImageFileNameFormat}"
Watermark="{x:Static inference:FileNameFormat.DefaultTemplate}" />
</ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem>
</ui:SettingsExpander> </ui:SettingsExpander>
</Grid>
<ui:TeachingTip
Title="Format Variables"
Grid.Row="2"
IsOpen="{Binding #OutputImageFileNameFormatTextBox.IsFocused}"
PreferredPlacement="Top"
Target="{Binding #OutputImageFileNameFormatTextBox, Mode=OneWay}">
<DataGrid AutoGenerateColumns="True" ItemsSource="{Binding OutputImageFileNameFormatVars}" />
<!--<mdxaml:MarkdownScrollViewer
Markdown="{Binding OutputImageFileNameFormatGuideMarkdown}"/>-->
</ui:TeachingTip>
</sg:SpacedGrid>
</StackPanel> </StackPanel>
</ScrollViewer> </ScrollViewer>
</controls:UserControlBase> </controls:UserControlBase>

114
StabilityMatrix.Avalonia/Views/Settings/MainSettingsPage.axaml

@ -105,111 +105,29 @@
</ui:SettingsExpander> </ui:SettingsExpander>
</Grid> </Grid>
<!-- Inference UI --> <!-- General -->
<Grid Margin="0,8,0,0" RowDefinitions="auto,*,*,*"> <sg:SpacedGrid RowDefinitions="Auto,*" RowSpacing="4">
<TextBlock <TextBlock
Margin="0,0,0,8" Margin="0,0,0,4"
FontWeight="Medium" FontWeight="Medium"
Text="Inference" /> Text="{x:Static lang:Resources.Label_General}" />
<!-- Auto Completion --> <!-- Link to Inference Sub-Settings -->
<ui:SettingsExpander <ui:SettingsExpander
Grid.Row="1" Grid.Row="1"
Margin="8,0,8,4" Margin="8,0"
Header="Prompt Auto Completion"> ActionIconSource="ChevronRight"
<ui:SettingsExpander.IconSource> Command="{Binding NavigateToSubPageCommand}"
<controls:FASymbolIconSource Symbol="fa-solid fa-wand-magic-sparkles" /> CommandParameter="{x:Type vmSettings:InferenceSettingsViewModel}"
</ui:SettingsExpander.IconSource> Header="{x:Static lang:Resources.Label_Inference}"
IsClickEnabled="True">
<!-- Enable toggle -->
<ui:SettingsExpanderItem Content="Enable">
<ui:SettingsExpanderItem.Footer>
<ToggleSwitch IsChecked="{Binding IsPromptCompletionEnabled}" />
</ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem>
<!-- Tag csv selection -->
<ui:SettingsExpanderItem
Content="Tag Source"
Description="Tags to use for completion in .csv format (Compatible with a1111-sd-webui-tagcomplete)"
IconSource="Tag"
IsEnabled="{Binding IsPromptCompletionEnabled}">
<ui:SettingsExpanderItem.Footer>
<ui:FAComboBox ItemsSource="{Binding AvailableTagCompletionCsvs}" SelectedItem="{Binding SelectedTagCompletionCsv}" />
</ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem>
<!-- Tag csv import -->
<ui:SettingsExpanderItem
Content="Import Tag Source .csv"
IconSource="Add"
IsEnabled="{Binding IsPromptCompletionEnabled}">
<ui:SettingsExpanderItem.Footer>
<Button Command="{Binding ImportTagCsvCommand}" Content="Import" />
</ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem>
<!-- Remove underscores -->
<ui:SettingsExpanderItem
Content="Replace underscores with spaces when inserting completions"
IconSource="Underline"
IsEnabled="{Binding IsPromptCompletionEnabled}">
<ui:SettingsExpanderItem.Footer>
<CheckBox Margin="8" IsChecked="{Binding IsCompletionRemoveUnderscoresEnabled}" />
</ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem>
</ui:SettingsExpander>
<!-- Image Viewer -->
<ui:SettingsExpander
Grid.Row="2"
Margin="8,0,8,4"
Header="Image Viewer"
IconSource="Image">
<!-- Pixel grid -->
<ui:SettingsExpanderItem Content="Show pixel grid at high zoom levels" IconSource="ViewAll">
<ui:SettingsExpanderItem.Footer>
<CheckBox Margin="8" IsChecked="{Binding IsImageViewerPixelGridEnabled}" />
</ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem>
</ui:SettingsExpander>
<!-- Output Image Files -->
<ui:SettingsExpander
Grid.Row="3"
Margin="8,0,8,4"
Header="Output Image Files">
<ui:SettingsExpander.IconSource> <ui:SettingsExpander.IconSource>
<fluentIcons:SymbolIconSource Symbol="TabDesktopImage" /> <fluentIcons:SymbolIconSource
FontSize="10"
IsFilled="True"
Symbol="AppGeneric" />
</ui:SettingsExpander.IconSource> </ui:SettingsExpander.IconSource>
<!-- File name pattern -->
<ui:SettingsExpanderItem
Content="File name pattern"
Description="{Binding OutputImageFileNameFormatSample}"
IconSource="Rename">
<ui:SettingsExpanderItem.Footer>
<TextBox
Name="OutputImageFileNameFormatTextBox"
MinWidth="150"
FontFamily="Cascadia Code,Consolas,Menlo,Monospace"
FontSize="13"
Text="{Binding OutputImageFileNameFormat}"
Watermark="{x:Static inference:FileNameFormat.DefaultTemplate}" />
</ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem>
</ui:SettingsExpander> </ui:SettingsExpander>
</sg:SpacedGrid>
<ui:TeachingTip
Title="Format Variables"
Grid.Row="3"
IsOpen="{Binding #OutputImageFileNameFormatTextBox.IsFocused}"
PreferredPlacement="Top"
Target="{Binding #OutputImageFileNameFormatTextBox, Mode=OneWay}">
<DataGrid AutoGenerateColumns="True" ItemsSource="{Binding OutputImageFileNameFormatVars}" />
<!--<mdxaml:MarkdownScrollViewer
Markdown="{Binding OutputImageFileNameFormatGuideMarkdown}"/>-->
</ui:TeachingTip>
</Grid>
<!-- Environment Options --> <!-- Environment Options -->
<Grid RowDefinitions="Auto, Auto, Auto"> <Grid RowDefinitions="Auto, Auto, Auto">

3
StabilityMatrix.Avalonia/Views/SettingsPage.axaml

@ -19,10 +19,13 @@
mc:Ignorable="d"> mc:Ignorable="d">
<controls:UserControlBase.Resources> <controls:UserControlBase.Resources>
<!-- Override styles for BreadcrumbBar -->
<!-- ReSharper disable Xaml.RedundantResource -->
<x:Double x:Key="BreadcrumbBarItemThemeFontSize">24</x:Double> <x:Double x:Key="BreadcrumbBarItemThemeFontSize">24</x:Double>
<x:Double x:Key="BreadcrumbBarChevronFontSize">17</x:Double> <x:Double x:Key="BreadcrumbBarChevronFontSize">17</x:Double>
<Thickness x:Key="BreadcrumbBarChevronPadding">6,3</Thickness> <Thickness x:Key="BreadcrumbBarChevronPadding">6,3</Thickness>
<FontWeight x:Key="BreadcrumbBarItemFontWeight">Medium</FontWeight> <FontWeight x:Key="BreadcrumbBarItemFontWeight">Medium</FontWeight>
<!-- ReSharper restore Xaml.RedundantResource -->
</controls:UserControlBase.Resources> </controls:UserControlBase.Resources>
<Grid RowDefinitions="Auto,*"> <Grid RowDefinitions="Auto,*">

Loading…
Cancel
Save