Multi-Platform Package Manager for Stable Diffusion
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

520 lines
28 KiB

<Page
Loaded="CheckpointManagerPage_OnLoaded"
d:DataContext="{d:DesignInstance Type=designData:MockCheckpointManagerViewModel,
IsDesignTimeCreatable=True}"
d:DesignHeight="650"
d:DesignWidth="1000"
mc:Ignorable="d"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
x:Class="StabilityMatrix.CheckpointManagerPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:controls="clr-namespace:StabilityMatrix.Controls"
xmlns:converters="clr-namespace:StabilityMatrix.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:designData="clr-namespace:StabilityMatrix.DesignData"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:ci="clr-namespace:StabilityMatrix.Interactions"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:viewModels="clr-namespace:StabilityMatrix.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:models="clr-namespace:StabilityMatrix.Models">
<Page.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<converters:StringNullOrEmptyToVisibilityConverter x:Key="StringNullOrEmptyToVisibilityConverter" />
<converters:BooleanToHiddenVisibleConverter x:Key="BoolToHiddenVisibleConverter" />
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
<converters:ValueConverterGroup x:Key="InvertAndVisibleOrHidden">
<converters:BoolNegationConverter />
<converters:BooleanToHiddenVisibleConverter />
</converters:ValueConverterGroup>
<converters:ValueConverterGroup x:Key="InvertBoolToVisibilityConverter">
<converters:BoolNegationConverter />
<BooleanToVisibilityConverter />
</converters:ValueConverterGroup>
<DropShadowEffect
BlurRadius="8"
Color="#FF000000"
Direction="0"
Opacity="0.2"
ShadowDepth="0"
x:Key="TextDropShadowEffect" />
<!-- Template for a single badge -->
<DataTemplate DataType="{x:Type system:String}" x:Key="BadgeTemplate">
<ui:Card
Height="18"
Margin="4,0,0,0"
Padding="3"
Visibility="{Binding Converter={StaticResource StringNullOrEmptyToVisibilityConverter}, FallbackValue=Collapsed}"
Width="40">
<TextBlock
FontSize="10"
FontWeight="Medium"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
HorizontalAlignment="Center"
Text="{Binding}"
VerticalAlignment="Center" />
</ui:Card>
</DataTemplate>
<DataTemplate DataType="{x:Type models:CheckpointFile}" x:Key="CheckpointFileDataTemplate">
<Border
Background="Transparent"
BorderThickness="0"
Margin="8">
<i:Interaction.Behaviors>
<i:MouseDragElementBehavior />
</i:Interaction.Behaviors>
<ui:Card Width="260">
<ui:Card.ContextMenu>
<ContextMenu>
<!-- ReSharper disable once Xaml.RedundantResource -->
<MenuItem Command="{Binding RenameCommand}" Header="Rename" />
<!-- ReSharper disable once Xaml.RedundantResource -->
<MenuItem Command="{Binding DeleteCommand}" Header="Delete" />
<!-- ReSharper disable once Xaml.RedundantResource -->
<MenuItem Header="Open on CivitAI"
Command="{Binding OpenOnCivitAiCommand}"
Visibility="{Binding IsConnectedModel, Converter={StaticResource BoolToVisibilityConverter}}"/>
</ContextMenu>
</ui:Card.ContextMenu>
<Grid>
<!-- Main contents, hidden when IsLoading is true -->
<StackPanel MinHeight="70">
<ui:Image
CornerRadius="4"
Margin="0,0,0,8"
Source="{Binding PreviewImage}"
Stretch="Uniform"
Visibility="Collapsed" />
<Grid Name="ModelInfoGrid" Visibility="{Binding IsLoading, Converter={StaticResource InvertAndVisibleOrHidden}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="0.1*" />
</Grid.RowDefinitions>
<StackPanel
Grid.ColumnSpan="4"
HorizontalAlignment="Left"
IsEnabled="True"
Margin="4"
Orientation="Vertical"
ToolTipService.BetweenShowDelay="100"
ToolTipService.InitialShowDelay="300">
<!-- Tooltip for title and version -->
<StackPanel.ToolTip>
<ToolTip Padding="8">
<VirtualizingStackPanel>
<!-- Title -->
<TextBlock
FontSize="14"
FontWeight="Medium"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
HorizontalAlignment="Left"
Margin="0,0,0,4"
Text="{Binding Title}"
TextWrapping="WrapWithOverflow" />
<!-- Version -->
<TextBlock
FontSize="13"
Foreground="{DynamicResource TextFillColorTertiaryBrush}"
HorizontalAlignment="Left"
Margin="0,0,0,4"
Text="{Binding ConnectedModel.VersionName, FallbackValue=''}"
TextWrapping="WrapWithOverflow"
Visibility="{Binding IsConnectedModel, Converter={StaticResource BoolToVisibilityConverter}}" />
<!-- Image -->
<ui:Image
CornerRadius="4"
Margin="0,0,0,4"
Source="{Binding PreviewImage}"
Stretch="Uniform"
Visibility="{Binding IsConnectedModel, Converter={StaticResource BoolToVisibilityConverter}}" />
</VirtualizingStackPanel>
</ToolTip>
</StackPanel.ToolTip>
<TextBlock
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
HorizontalAlignment="Left"
IsEnabled="True"
MaxWidth="150"
Text="{Binding Title}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
<TextBlock
FontSize="13"
Foreground="{DynamicResource TextFillColorTertiaryBrush}"
HorizontalAlignment="Left"
IsEnabled="True"
Text="{Binding ConnectedModel.VersionName, FallbackValue=''}"
TextWrapping="WrapWithOverflow"
Visibility="{Binding IsConnectedModel, Converter={StaticResource BoolToVisibilityConverter}}" />
</StackPanel>
<Grid Grid.Column="4" Grid.Row="0">
<Button
Background="Transparent"
BorderBrush="Transparent"
FontSize="20"
HorizontalAlignment="Right"
IsEnabled="True"
MaxHeight="48"
MaxWidth="64"
Padding="0"
ToolTip="Connected Model"
VerticalAlignment="Top"
Visibility="{Binding IsConnectedModel, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<ui:SymbolIcon
FontSize="12"
Foreground="LightGreen"
Symbol="CloudCheckmark24"
ToolTip="Connected Model" />
</Button>
<Button
Background="Transparent"
BorderBrush="Transparent"
FontSize="20"
HorizontalAlignment="Right"
IsEnabled="True"
MaxHeight="48"
MaxWidth="64"
Padding="0"
ToolTip="Local Model"
VerticalAlignment="Top"
Visibility="{Binding IsConnectedModel, Mode=OneWay, Converter={StaticResource InvertBoolToVisibilityConverter}}">
<ui:SymbolIcon
FontSize="12"
Foreground="DimGray"
Symbol="CloudOff24"
ToolTip="Local Model" />
</Button>
<ui:Button
Background="Transparent"
BorderBrush="Transparent"
FontSize="20"
HorizontalAlignment="Right"
IsEnabled="False"
MaxHeight="48"
MaxWidth="64"
Padding="0"
VerticalAlignment="Top"
Visibility="Collapsed">
<ui:Button.Icon>
<ui:SymbolIcon
FontSize="12"
Foreground="OrangeRed"
Symbol="CloudArrowUp24"
ToolTip="Update Available" />
</ui:Button.Icon>
</ui:Button>
</Grid>
<TextBlock
FontSize="11"
Foreground="{DynamicResource TextFillColorTertiaryBrush}"
Grid.Column="0"
Grid.ColumnSpan="3"
Grid.Row="1"
IsEnabled="True"
Margin="4,4"
Text="{Binding FileName}"
TextTrimming="CharacterEllipsis"
ToolTip="{Binding FileName}"
VerticalAlignment="Bottom" />
<ItemsControl
Grid.Column="3"
Grid.ColumnSpan="2"
Grid.Row="1"
ItemTemplate="{StaticResource BadgeTemplate}"
ItemsSource="{Binding Badges}"
VerticalAlignment="Bottom">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
HorizontalAlignment="Right"
Orientation="Horizontal"
VerticalAlignment="Bottom" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</StackPanel>
<!-- Progress ring -->
<ui:ProgressRing
Grid.Row="0"
Height="32"
HorizontalAlignment="Center"
IsEnabled="{Binding IsLoading}"
IsIndeterminate="True"
Padding="0"
VerticalAlignment="Center"
Visibility="{Binding IsLoading, Converter={StaticResource BooleanToVisibilityConverter}}"
Width="32" />
</Grid>
</ui:Card>
</Border>
</DataTemplate>
<DataTemplate DataType="{x:Type models:CheckpointFolder}" x:Key="CheckpointFolderGridDataTemplate">
<Expander
AllowDrop="True"
Header="{Binding Title}"
IsExpanded="True"
Margin="8"
Padding="8,8,8,8"
Visibility="{Binding IsCategoryEnabled, Converter={StaticResource BoolToVisibilityConverter}, FallbackValue=Visible}">
<Expander.ContextMenu>
<ContextMenu>
<!-- ReSharper disable once Xaml.RedundantResource -->
<MenuItem Header="Show in Explorer"
Command="{Binding ShowInExplorerCommand}"
CommandParameter="{Binding DirectoryPath}"/>
</ContextMenu>
</Expander.ContextMenu>
<StackPanel Orientation="Vertical">
<!-- Subfolders -->
<StackPanel Orientation="Vertical">
<ItemsControl
HorizontalAlignment="Stretch"
ItemTemplate="{DynamicResource CheckpointFolderGridDataTemplate}"
ItemsSource="{Binding SubFolders, Mode=OneWay}"
Margin="8,0,8,8" />
</StackPanel>
<!-- Files -->
<Grid>
<i:Interaction.Triggers>
<ci:EventTriggerWithoutPropagation EventName="PreviewDragEnter">
<i:InvokeCommandAction Command="{Binding OnPreviewDragEnterCommand}" />
</ci:EventTriggerWithoutPropagation>
<ci:EventTriggerWithoutPropagation EventName="PreviewDragLeave">
<i:InvokeCommandAction Command="{Binding OnPreviewDragLeaveCommand}" />
</ci:EventTriggerWithoutPropagation>
<ci:EventTriggerWithoutPropagation EventName="PreviewDrop">
<i:InvokeCommandAction Command="{Binding PreviewDropCommand}" PassEventArgsToCommand="True" />
</ci:EventTriggerWithoutPropagation>
</i:Interaction.Triggers>
<ui:VirtualizingItemsControl
ItemTemplate="{StaticResource CheckpointFileDataTemplate}"
ItemsSource="{Binding CheckpointFiles}"
Padding="5"
PreviewMouseWheel="VirtualizingGridView_OnPreviewMouseWheel" />
<Border
CornerRadius="8"
Grid.RowSpan="4"
IsEnabled="False"
Name="OnDragBlurBorder"
Visibility="{Binding IsDragBlurEnabled, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}">
<Border.Background>
<SolidColorBrush Color="#EE202020" />
</Border.Background>
</Border>
<Border
BorderThickness="1,1,1,1"
CornerRadius="8"
Grid.RowSpan="4"
IsEnabled="False"
Name="OnDragDashBorder"
Visibility="{Binding IsCurrentDragTarget, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}">
<Border.BorderBrush>
<DrawingBrush
TileMode="Tile"
Viewport="0,0,8,8"
ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="White">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,50,50" />
<RectangleGeometry Rect="50,50,50,50" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Border.BorderBrush>
</Border>
<VirtualizingStackPanel
Margin="0,8"
Orientation="Vertical"
VerticalAlignment="Center">
<TextBlock
Effect="{StaticResource TextDropShadowEffect}"
FontSize="24"
HorizontalAlignment="Center"
Name="OnDragText"
Text="Drop a file here to import"
VerticalAlignment="Center"
Visibility="{Binding IsCurrentDragTarget, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Visible}" />
<TextBlock
Effect="{StaticResource TextDropShadowEffect}"
FontSize="18"
HorizontalAlignment="Center"
Name="ImportProgressText"
Text="{Binding Progress.Text, FallbackValue=Importing checkpoint.safetensors}"
VerticalAlignment="Center"
Visibility="{Binding Progress.TextVisibility}" />
<ProgressBar
Effect="{StaticResource TextDropShadowEffect}"
HorizontalAlignment="Stretch"
IsIndeterminate="{Binding Progress.IsIndeterminate, FallbackValue=False}"
Margin="64,8"
Name="ImportProgressBar"
VerticalAlignment="Center"
Visibility="{Binding Progress.ProgressVisibility, FallbackValue=Visible}"
controls:ProgressBarSmoother.SmoothValue="{Binding Progress.Value, FallbackValue=20}" />
</VirtualizingStackPanel>
</Grid>
</StackPanel>
</Expander>
</DataTemplate>
<DataTemplate DataType="{x:Type models:CheckpointFolder}" x:Key="CheckpointFolderDataTemplate">
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource CheckpointFolderGridDataTemplate}" />
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
<!-- Template for dropdown category checkbox item -->
<DataTemplate DataType="{x:Type models:CheckpointFolder}" x:Key="CategoryItemTemplate">
<CheckBox Content="{Binding Title}" IsChecked="{Binding IsCategoryEnabled, Mode=TwoWay}" />
</DataTemplate>
<!-- Template for dropdown box -->
<ControlTemplate TargetType="{x:Type ComboBoxItem}" x:Key="CategoryDropDownStyle">
<Grid>
<Border
CornerRadius="{TemplateBinding Border.CornerRadius}"
Margin="{TemplateBinding Margin}"
Name="ContentBorder"
Padding="0"
SnapsToDevicePixels="True"
VerticalAlignment="Stretch">
<Grid>
<Rectangle
Height="16"
HorizontalAlignment="Left"
Margin="0"
RadiusX="2"
RadiusY="2"
VerticalAlignment="Center"
Visibility="Collapsed"
Width="3"
x:Name="ActiveRectangle">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource SystemAccentColorSecondary}" />
</Rectangle.Fill>
</Rectangle>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Setup grid rows -->
<StackPanel
Grid.Column="0"
Margin="10,0,0,0"
VerticalAlignment="Top"
d:DataContext="{d:DesignInstance Type=models:CheckpointFolder,
IsDesignTimeCreatable=True}">
<CheckBox Content="{Binding TitleWithFilesCount}" IsChecked="{Binding IsCategoryEnabled, Mode=TwoWay}" />
</StackPanel>
</Grid>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Page.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.1*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Top settings bar -->
<ui:ToggleSwitch
Content="Import as Connected"
Grid.Column="0"
IsChecked="{Binding IsImportAsConnected}"
Margin="24,8"
ToolTip="Search for connected metadata on new local imports" />
<StackPanel
Grid.Column="1"
Grid.Row="0"
HorizontalAlignment="Right"
Margin="16,0"
Orientation="Horizontal">
<ui:Button
VerticalAlignment="Stretch"
Command="{Binding OpenModelsFolderCommand}"
Height="46"
Margin="8,0">
<ui:Button.Icon>
<ui:SymbolIcon Symbol="FolderOpen24"/>
</ui:Button.Icon>
<ui:Button.Content>
<TextBlock Text="Open Models Folder"/>
</ui:Button.Content>
</ui:Button>
<ComboBox
HorizontalAlignment="Right"
ItemsSource="{Binding CheckpointFolders}"
MinWidth="180"
SelectedIndex="0">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="Template" Value="{StaticResource CategoryDropDownStyle}" />
</Style>
</ComboBox.ItemContainerStyle>
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type models:CheckpointFolder}">
<StackPanel Margin="10,0,0,0" VerticalAlignment="Top">
<TextBlock Margin="0,5,0,5" Text="Categories" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
<!-- Main view with model cards -->
<ui:DynamicScrollViewer
CanContentScroll="True"
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="1"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<Grid>
<StackPanel Orientation="Vertical">
<ItemsControl
HorizontalAlignment="Stretch"
ItemTemplate="{StaticResource CheckpointFolderGridDataTemplate}"
ItemsSource="{Binding CheckpointFolders, Mode=OneWay}"
Margin="8,0,8,8" />
</StackPanel>
</Grid>
</ui:DynamicScrollViewer>
</Grid>
</Page>