Seperated favourites from sources, added gif playback preview

This commit is contained in:
Ebbe Baß
2026-08-19 15:16:57 +02:00
parent b1ffb3924a
commit 62a257b538
7 changed files with 209 additions and 135 deletions
+45 -61
View File
@@ -4,6 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:EbbesMemeClipboard.ViewModels"
xmlns:models="clr-namespace:EbbesMemeClipboard.Models"
xmlns:gif="clr-namespace:XamlAnimatedGif;assembly=XamlAnimatedGif"
Title="Meme Clipboard"
Width="420" Height="520"
WindowStyle="None"
@@ -98,7 +99,13 @@
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
</ContextMenu>
</Button.ContextMenu>
<Image Source="{Binding Thumbnail}" Stretch="Uniform" Margin="5"/>
<!-- Source is the static first frame; the gif attached properties take over only when
preview playback is enabled (both stay null otherwise). -->
<Image Stretch="Uniform" Margin="5"
Source="{Binding Thumbnail}"
gif:AnimationBehavior.SourceUri="{Binding AnimationUri}"
gif:AnimationBehavior.SourceStream="{Binding AnimationStream}"
gif:AnimationBehavior.RepeatBehavior="Forever"/>
</Button>
<!-- Star overlay: marks favourites at a glance without needing a second grid. -->
@@ -133,18 +140,27 @@
</Grid>
</Border>
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,4,0,8">
<Button Content="Local"
<Grid Grid.Row="1" Margin="0,4,0,8">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<Button Content="Local"
Style="{StaticResource TabButtonStyle}"
Tag="{Binding IsLocalSource}"
Command="{Binding SelectSourceCommand}"
CommandParameter="{x:Static models:MemeSource.Local}"/>
<Button Content="Giphy" Margin="6,0,0,0"
Style="{StaticResource TabButtonStyle}"
Tag="{Binding IsGiphySource}"
Command="{Binding SelectSourceCommand}"
CommandParameter="{x:Static models:MemeSource.Giphy}"/>
</StackPanel>
<!-- Right-aligned and separated from the source tabs on purpose: it filters
the active source rather than being a source of its own. -->
<Button Content="&#9733; Favourites" HorizontalAlignment="Right"
Style="{StaticResource TabButtonStyle}"
Tag="{Binding IsLocalSource}"
Command="{Binding SelectSourceCommand}"
CommandParameter="{x:Static models:MemeSource.Local}"/>
<Button Content="Giphy" Margin="6,0,0,0"
Style="{StaticResource TabButtonStyle}"
Tag="{Binding IsGiphySource}"
Command="{Binding SelectSourceCommand}"
CommandParameter="{x:Static models:MemeSource.Giphy}"/>
</StackPanel>
Tag="{Binding ShowingFavorites}"
Command="{Binding ToggleFavoritesViewCommand}"
ToolTip="Show only your favourites from this source"/>
</Grid>
<Grid Grid.Row="2" Margin="0,0,0,10">
<Grid.ColumnDefinitions>
@@ -182,61 +198,29 @@
<Button Grid.Column="1" Content="+" Width="36" Height="36" Margin="8,0,0,0"
FontSize="18" Style="{StaticResource FlatButtonStyle}"
Command="{Binding ImportFilesCommand}"
Visibility="{Binding IsLocalSource, Converter={StaticResource BoolToVisibility}}"
Visibility="{Binding CanImport, Converter={StaticResource BoolToVisibility}}"
ToolTip="Add memes"/>
</Grid>
<ScrollViewer Grid.Row="3" VerticalScrollBarVisibility="Auto" Padding="0,0,4,0"
ScrollChanged="ResultsScrollViewer_OnScrollChanged">
<StackPanel>
<!-- Favourites for the active source. Scrolls with the content rather than
being pinned, so it doesn't permanently eat height in a 520px window. -->
<StackPanel Visibility="{Binding HasFavorites, Converter={StaticResource BoolToVisibility}}">
<TextBlock Text="★ Favourites" Foreground="#9A9CA3" FontSize="11"
FontWeight="SemiBold" Margin="4,0,0,4"/>
<ItemsControl ItemsSource="{Binding Favorites}"
ItemTemplate="{StaticResource MemeTileTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<Border Height="1" Background="#3A3B3E" Margin="4,10,4,10"/>
</StackPanel>
<Grid>
<TextBlock Text="{Binding EmptyStateText}"
Foreground="#7B7D85" FontSize="13"
HorizontalAlignment="Center" VerticalAlignment="Center"
TextWrapping="Wrap" TextAlignment="Center" Width="260"
Margin="0,40,0,0"
Visibility="{Binding ShowEmptyState, Converter={StaticResource BoolToVisibility}}"/>
<Grid>
<TextBlock Text="No memes yet. Click +, drag files in, or paste with Ctrl+V."
Foreground="#7B7D85" FontSize="13"
HorizontalAlignment="Center" VerticalAlignment="Center"
TextWrapping="Wrap" TextAlignment="Center" Width="260"
Margin="0,40,0,0">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Items.Count}" Value="0"/>
<Condition Binding="{Binding IsLocalSource}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Visible"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<ItemsControl ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource MemeTileTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</StackPanel>
<ItemsControl ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource MemeTileTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</ScrollViewer>
<Grid Grid.Row="4" Margin="2,8,0,0">
@@ -37,6 +37,11 @@
<CheckBox Content="Start automatically when Windows starts" Foreground="White"
IsChecked="{Binding AutostartEnabled}"/>
<TextBlock Text="Previews" Foreground="White" FontSize="14" FontWeight="Bold" Margin="0,24,0,8"/>
<CheckBox Content="Play GIF previews in the picker" Foreground="White"
IsChecked="{Binding PlayGifPreviews}"/>
<TextBlock Text="Animates GIF thumbnails instead of showing a still frame. Uses more CPU and memory, especially with lots of Giphy results."
Foreground="#7B7D85" FontSize="10" TextWrapping="Wrap" Margin="20,4,0,0"/>
<TextBlock Text="Giphy" Foreground="White" FontSize="14" FontWeight="Bold" Margin="0,24,0,8"/>
<Border Background="#2B2D31" CornerRadius="6">
<TextBox Text="{Binding GiphyApiKey, UpdateSourceTrigger=PropertyChanged}"