Skip to content

Commit 3eb481b

Browse files
author
David Khristepher Santos
committed
Add Volume controls to Preview
Add ability to pause/play the video by clicking on it Pause preview video if popup is active
1 parent 8df86f8 commit 3eb481b

9 files changed

Lines changed: 238 additions & 17 deletions

File tree

Diffusion.Toolkit/Configuration/Settings.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public Settings()
7373
//{
7474
// RecurseFolders = true;
7575
//}
76-
76+
Volume = 1.0f;
7777
Instance = this;
7878
}
7979

@@ -468,6 +468,12 @@ public bool LoopVideo
468468
set => UpdateValue(ref field, value);
469469
}
470470

471+
public float Volume
472+
{
473+
get;
474+
set => UpdateValue(ref field, value);
475+
}
476+
471477
public TagsMode TagsMode
472478
{
473479
get;

Diffusion.Toolkit/Controls/PreviewPane.xaml

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,13 @@
6464
<MediaElement
6565
DataContext="{Binding Image, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
6666
Source="{Binding Path}"
67-
LoadedBehavior="Play"
67+
LoadedBehavior="Manual"
6868
Loaded="Player_OnLoaded"
69+
MediaOpened="MediaElement_OnMediaOpened"
6970
MediaEnded="Player_OnMediaEnded"
71+
MouseDown="Player_OnMouseDown"
7072
SpeedRatio="1"
73+
Volume="{Binding MainModel.Settings.Volume, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
7174
></MediaElement>
7275
</DataTemplate>
7376
</ResourceDictionary>
@@ -253,7 +256,99 @@
253256
</Style.Triggers>
254257
</Style>
255258
</fa:ImageAwesome.Resources>
259+
</fa:ImageAwesome>
260+
</Button>
261+
262+
</Grid>
263+
<Grid Background="{x:Null}">
256264

265+
<Grid.RowDefinitions>
266+
<RowDefinition/>
267+
<RowDefinition Height="100"/>
268+
<RowDefinition Height="50"/>
269+
<RowDefinition>
270+
<RowDefinition.Style>
271+
<Style TargetType="{x:Type RowDefinition}">
272+
<Setter Property="Height" Value="0"></Setter>
273+
<Style.Triggers>
274+
<DataTrigger Binding="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource iflessThan}, ConverterParameter=570}" Value="True">
275+
<Setter Property="Height" Value="50"/>
276+
</DataTrigger>
277+
</Style.Triggers>
278+
</Style>
279+
</RowDefinition.Style>
280+
</RowDefinition>
281+
</Grid.RowDefinitions>
282+
<Grid.ColumnDefinitions>
283+
<ColumnDefinition/>
284+
<ColumnDefinition Width="24"/>
285+
<ColumnDefinition Width="32"/>
286+
<ColumnDefinition Width="32"/>
287+
</Grid.ColumnDefinitions>
288+
<Slider Grid.Row="1" Grid.Column="2" Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Center" Background="Transparent"
289+
Minimum="0"
290+
Maximum="1.0"
291+
Value="{Binding Volume}"
292+
Visibility="{Binding ShowVolume, Converter={StaticResource boolToVis}}"
293+
>
294+
</Slider>
295+
<Button Grid.Row="2" Grid.Column="1" ToolTip="Loop Video" Click="Loop_Click" DataContext="{Binding Image, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
296+
<Button.Style>
297+
<Style TargetType="Button" BasedOn="{StaticResource StaticButton}">
298+
<Style.Triggers>
299+
<DataTrigger Binding="{Binding Type}" Value="{x:Static common:ImageType.Image}">
300+
<Setter Property="Visibility" Value="Hidden" />
301+
</DataTrigger>
302+
<DataTrigger Binding="{Binding Type}" Value="{x:Static common:ImageType.Video}">
303+
<Setter Property="Visibility" Value="Visible" />
304+
</DataTrigger>
305+
</Style.Triggers>
306+
</Style>
307+
</Button.Style>
308+
<fa:ImageAwesome Margin="0,4,0,0" Height="18" Icon="Repeat" Foreground="{DynamicResource ForegroundBrush}">
309+
<fa:ImageAwesome.Resources>
310+
<Style TargetType="fa:ImageAwesome">
311+
<Setter Property="Opacity" Value="0.5"></Setter>
312+
<Style.Triggers>
313+
<Trigger Property="IsMouseOver" Value="True">
314+
<Setter Property="Opacity" Value="1.0"></Setter>
315+
</Trigger>
316+
<DataTrigger Binding="{Binding MainModel.Settings.LoopVideo, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" Value="True" >
317+
<Setter Property="Opacity" Value="1.0"></Setter>
318+
</DataTrigger>
319+
320+
</Style.Triggers>
321+
</Style>
322+
</fa:ImageAwesome.Resources>
323+
</fa:ImageAwesome>
324+
</Button>
325+
<Button Grid.Row="2" Grid.Column="2" ToolTip="Volume" Click="Volume_Click" DataContext="{Binding Image, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
326+
<Button.Style>
327+
<Style TargetType="Button" BasedOn="{StaticResource StaticButton}">
328+
<Style.Triggers>
329+
<DataTrigger Binding="{Binding Type}" Value="{x:Static common:ImageType.Image}">
330+
<Setter Property="Visibility" Value="Hidden" />
331+
</DataTrigger>
332+
<DataTrigger Binding="{Binding Type}" Value="{x:Static common:ImageType.Video}">
333+
<Setter Property="Visibility" Value="Visible" />
334+
</DataTrigger>
335+
</Style.Triggers>
336+
</Style>
337+
</Button.Style>
338+
<fa:ImageAwesome Margin="0,4,0,0" Height="18" Icon="VolumeOff" Foreground="{DynamicResource ForegroundBrush}">
339+
<fa:ImageAwesome.Resources>
340+
<Style TargetType="fa:ImageAwesome">
341+
<Setter Property="Opacity" Value="0.5"></Setter>
342+
<Style.Triggers>
343+
<Trigger Property="IsMouseOver" Value="True">
344+
<Setter Property="Opacity" Value="1.0"></Setter>
345+
</Trigger>
346+
<DataTrigger Binding="{Binding ShowVolume, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" Value="True" >
347+
<Setter Property="Opacity" Value="1.0"></Setter>
348+
</DataTrigger>
349+
</Style.Triggers>
350+
</Style>
351+
</fa:ImageAwesome.Resources>
257352
</fa:ImageAwesome>
258353
</Button>
259354
</Grid>

Diffusion.Toolkit/Controls/PreviewPane.xaml.cs

Lines changed: 117 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
using System.IO;
1313
using System.Linq;
1414
using System.Net;
15+
using System.Runtime.CompilerServices;
1516
using System.Threading;
17+
using System.Threading.Tasks;
1618
using System.Windows;
1719
using System.Windows.Controls;
1820
using System.Windows.Input;
@@ -27,7 +29,7 @@ namespace Diffusion.Toolkit.Controls
2729
/// <summary>
2830
/// Interaction logic for PreviewPane.xaml
2931
/// </summary>
30-
public partial class PreviewPane : UserControl
32+
public partial class PreviewPane : UserControl, INotifyPropertyChanged
3133
{
3234
public static readonly DependencyProperty IsLoadingProperty =
3335
DependencyProperty.Register(
@@ -60,6 +62,17 @@ public partial class PreviewPane : UserControl
6062
propertyChangedCallback: PropertyChangedCallback)
6163
);
6264

65+
public static readonly DependencyProperty VolumeProperty =
66+
DependencyProperty.Register(
67+
name: nameof(Volume),
68+
propertyType: typeof(double),
69+
ownerType: typeof(PreviewPane),
70+
typeMetadata: new FrameworkPropertyMetadata(
71+
defaultValue: 1.0d,
72+
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
73+
propertyChangedCallback: PropertyChangedCallback)
74+
);
75+
6376
private int? originalRating;
6477

6578
private static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
@@ -90,8 +103,11 @@ private static void PropertyChangedCallback(DependencyObject d, DependencyProper
90103

91104
//if (model.Type == ImageType.Video)
92105
//{
93-
// preview.Player.Source = new Uri(model.Path, UriKind.Absolute);
94-
// preview.Player.Play();
106+
// if (preview is not { IsPopout: false, MainModel.IsPreviewOpen: true })
107+
// {
108+
// preview.isPlaying = true;
109+
// preview.Player?.Play();
110+
// }
95111
//}
96112
}
97113
}
@@ -139,6 +155,18 @@ public ImageViewModel? Image
139155
set => SetValue(ImageProperty, value);
140156
}
141157

158+
public double Volume
159+
{
160+
get => (double)GetValue(VolumeProperty);
161+
set => SetValue(VolumeProperty, value);
162+
}
163+
164+
public bool ShowVolume
165+
{
166+
get;
167+
set => SetField(ref field, value);
168+
}
169+
142170
public ICommand CopyPathCommand { get; set; }
143171

144172

@@ -537,13 +565,20 @@ private void Player_OnLoaded(object sender, RoutedEventArgs e)
537565
_scrollDragger = null;
538566

539567
Player = (MediaElement)sender;
568+
569+
isPlaying = true;
570+
Player?.Play();
540571
}
541572

542573
private void Player_OnMediaEnded(object sender, RoutedEventArgs e)
543574
{
575+
isEnded = true;
576+
isPlaying = false;
544577
if (ServiceLocator.Settings.LoopVideo)
545578
{
546579
Player?.Position = TimeSpan.FromMilliseconds(1);
580+
isEnded = false;
581+
isPlaying = true;
547582
}
548583
}
549584

@@ -558,5 +593,84 @@ private void ScrollViewer_OnLoaded(object sender, RoutedEventArgs e)
558593

559594
SetFocus();
560595
}
596+
597+
public event PropertyChangedEventHandler? PropertyChanged;
598+
599+
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
600+
{
601+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
602+
}
603+
604+
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
605+
{
606+
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
607+
field = value;
608+
OnPropertyChanged(propertyName);
609+
return true;
610+
}
611+
612+
private void Volume_Click(object sender, RoutedEventArgs e)
613+
{
614+
ShowVolume = !ShowVolume;
615+
e.Handled = true;
616+
}
617+
618+
private bool isPlaying = true;
619+
private bool isEnded = false;
620+
621+
private void Player_OnMouseDown(object sender, MouseButtonEventArgs e)
622+
{
623+
if (isPlaying)
624+
{
625+
Player?.Pause();
626+
}
627+
else
628+
{
629+
if (isEnded)
630+
{
631+
Player?.Position = TimeSpan.FromMilliseconds(1);
632+
isEnded = false;
633+
}
634+
Player?.Play();
635+
}
636+
isPlaying = !isPlaying;
637+
e.Handled = true;
638+
}
639+
640+
private void Loop_Click(object sender, RoutedEventArgs e)
641+
{
642+
MainModel.Settings.LoopVideo = !MainModel.Settings.LoopVideo;
643+
}
644+
645+
public void Pause()
646+
{
647+
isPlaying = false;
648+
Player?.Pause();
649+
}
650+
651+
private void MediaElement_OnMediaOpened(object sender, RoutedEventArgs e)
652+
{
653+
if (Image.Type == ImageType.Video)
654+
{
655+
if (IsPopout || !MainModel.IsPreviewOpen)
656+
{
657+
isPlaying = true;
658+
Player?.Play();
659+
}
660+
else if (!IsPopout && MainModel.IsPreviewOpen)
661+
{
662+
isPlaying = true;
663+
Player?.Play();
664+
Task.Delay(10).ContinueWith((t) =>
665+
{
666+
Dispatcher.Invoke(() =>
667+
{
668+
isPlaying = false;
669+
Player?.Stop();
670+
});
671+
});
672+
}
673+
}
674+
}
561675
}
562676
}

Diffusion.Toolkit/MainWindow.xaml.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,13 +362,15 @@ private void PopoutPreview(bool hidePreview, bool maximized, bool fullscreen)
362362

363363
_previewWindow.Closed += (sender, args) =>
364364
{
365+
_model.IsPreviewOpen = false;
365366
_search.OnCurrentImageChange = null;
366367
_search.ThumbnailListView.FocusCurrentItem();
367368
_previewWindow = null;
368369
_search.NavigationCompleted -= SearchOnNavigationCompleted;
369370
};
370371
_previewWindow.SetCurrentImage(_search.CurrentImage);
371372

373+
372374
_search.NavigationCompleted += SearchOnNavigationCompleted;
373375

374376
_search.OnCurrentImageChange = (image) =>
@@ -422,6 +424,8 @@ void UpdatePreviewWindowState()
422424
_previewWindow.Show();
423425
}
424426

427+
_model.IsPreviewOpen = true;
428+
_search.PreviewPane.Pause();
425429
}
426430
else
427431
{

Diffusion.Toolkit/Models/MainModel.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,5 @@ public ThumbnailViewMode ThumbnailViewMode
768768
public ICommand ToggleThumbnailViewModeCommand { get; set; }
769769
public ICommand FocusSearch { get; set; }
770770
public ICommand RefreshFolderCommand { get; set; }
771-
772-
771+
public bool IsPreviewOpen { get; set; }
773772
}

Diffusion.Toolkit/Pages/Search.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,7 @@
10071007
PreviewKeyUp="PreviewPane_OnPreviewKeyUp"
10081008
PreviewKeyDown="PreviewPane_OnPreviewKeyDown"
10091009
MouseDoubleClick="PreviewPane_OnMouseDoubleClick"
1010+
Volume="{Binding MainModel.Settings.Volume}"
10101011
Drop="PreviewPane_OnDrop"></controls:PreviewPane>
10111012

10121013
<Grid x:Name="PreviewPaneGrid" Background="{x:Null}">

Diffusion.Toolkit/Preview.xaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@
6464
x:Name="PreviewPane"
6565
AllowDrop="True"
6666
Loaded="PreviewPane_OnLoaded"
67-
Drop="PreviewPane_OnDrop"></controls:PreviewPane>
67+
Drop="PreviewPane_OnDrop"
68+
Volume="{Binding MainModel.Settings.Volume}"
69+
></controls:PreviewPane>
6870

6971

7072
<Grid Background="{x:Null}">
@@ -130,10 +132,11 @@
130132
<Grid.ColumnDefinitions>
131133
<ColumnDefinition/>
132134
<ColumnDefinition Width="60"/>
135+
<ColumnDefinition Width="70"/>
133136
</Grid.ColumnDefinitions>
134137
<Grid.RowDefinitions>
135138
<RowDefinition/>
136-
<RowDefinition Height="60"/>
139+
<RowDefinition Height="28"/>
137140
</Grid.RowDefinitions>
138141

139142
<Button Style="{DynamicResource BorderlessButton}" Grid.Row="1" Grid.Column="1" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Command="{Binding CurrentImage.ToggleParameters}">

Diffusion.Toolkit/Release Notes/Opening.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# What is Diffusion Toolkit?
22

3-
Are you tired of dragging your images into PNG-Info to see the metadata? Annoyed at how slow navigating through Explorer is to view your images? Want to organize your images without having to move them around to different folders? Wish you could easily search for images using metadata?
3+
Are you tired of dragging your images into PNG-Info to see the metadata? Who even uses A1111 anymore? Annoyed at how slow navigating through Explorer is to view your images? Want to organize your images without having to move them around to different folders? Wish you could easily search for images using metadata?
44

5-
Diffusion Toolkit (https://github.com/RupertAvery/DiffusionToolkit) is an image metadata-indexer and viewer for AI-generated images. It aims to help you organize, search and sort your ever-growing collection of best quality 4k masterpieces.
5+
Diffusion Toolkit (https://github.com/RupertAvery/DiffusionToolkit) is metadata-indexer and media viewer for AI-generated images.
6+
7+
It aims to help you organize, search and sort your ever-growing collection of best quality 4k masterpieces.
68

79
# Installation
810

0 commit comments

Comments
 (0)