Added Giphy support, Favourites
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:EbbesMemeClipboard.ViewModels"
|
||||
xmlns:models="clr-namespace:EbbesMemeClipboard.Models"
|
||||
Title="Meme Clipboard"
|
||||
Width="420" Height="520"
|
||||
WindowStyle="None"
|
||||
@@ -20,6 +21,8 @@
|
||||
ContextMenuOpening="PickerWindow_OnContextMenuOpening"
|
||||
ContextMenuClosing="PickerWindow_OnContextMenuClosing">
|
||||
<Window.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVisibility"/>
|
||||
|
||||
<Style x:Key="FlatButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#2B2D31"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
@@ -43,25 +46,105 @@
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Tag carries "is this tab active", so one style can drive both tab buttons. -->
|
||||
<Style x:Key="TabButtonStyle" TargetType="Button">
|
||||
<Setter Property="Foreground" Value="#9A9CA3"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Padding" Value="14,6"/>
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border x:Name="Bd" Background="{TemplateBinding Background}" CornerRadius="6" SnapsToDevicePixels="True">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{TemplateBinding Padding}"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="Bd" Property="Background" Value="#2B2D31"/>
|
||||
</Trigger>
|
||||
<DataTrigger Binding="{Binding Tag, RelativeSource={RelativeSource Self}}" Value="True">
|
||||
<Setter TargetName="Bd" Property="Background" Value="#3A3D42"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</DataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Shared by the favourites row and the main grid so both behave identically. -->
|
||||
<DataTemplate x:Key="MemeTileTemplate" DataType="{x:Type vm:MemeTileViewModel}">
|
||||
<Grid Width="88" Height="88" Margin="4">
|
||||
<Button Padding="0"
|
||||
Style="{StaticResource FlatButtonStyle}"
|
||||
Command="{Binding DataContext.SelectItemCommand, ElementName=RootWindow}"
|
||||
CommandParameter="{Binding}"
|
||||
Tag="{Binding DataContext, ElementName=RootWindow}"
|
||||
ToolTip="{Binding DisplayName}">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="{Binding PlacementTarget.DataContext.FavoriteActionLabel, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
||||
Command="{Binding PlacementTarget.Tag.ToggleFavoriteCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
|
||||
<Separator/>
|
||||
<MenuItem Header="Remove"
|
||||
IsEnabled="{Binding PlacementTarget.DataContext.IsLocal, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
||||
Command="{Binding PlacementTarget.Tag.RemoveItemCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Image Source="{Binding Thumbnail}" Stretch="Uniform" Width="80" Height="80"/>
|
||||
</Button>
|
||||
|
||||
<!-- Star overlay: marks favourites at a glance without needing a second grid. -->
|
||||
<TextBlock Text="★" FontSize="13" Foreground="#FFC72C"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Top"
|
||||
Margin="0,4,6,0" IsHitTestVisible="False"
|
||||
Visibility="{Binding IsFavorite, Converter={StaticResource BoolToVisibility}}"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</Window.Resources>
|
||||
|
||||
<Border Background="#F0202225" CornerRadius="10" BorderBrush="#3A3B3E" BorderThickness="1">
|
||||
<Grid Margin="12">
|
||||
<Grid Margin="12,8,12,12">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="16"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.Row="0" Background="Transparent" Cursor="SizeAll"
|
||||
<!-- Title bar: doubles as the drag surface. -->
|
||||
<Border Grid.Row="0" Background="Transparent" Cursor="SizeAll" Height="26"
|
||||
MouseLeftButtonDown="DragHandle_OnMouseLeftButtonDown"
|
||||
ToolTip="Drag to move">
|
||||
<Border Width="36" Height="4" CornerRadius="2" Background="#4A4C52"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
<Grid>
|
||||
<TextBlock Text="Meme Clipboard" Foreground="White" FontSize="13"
|
||||
FontWeight="SemiBold" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left"/>
|
||||
<Border Width="36" Height="4" CornerRadius="2" Background="#4A4C52"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Grid Grid.Row="1" Margin="0,4,0,10">
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,4,0,8">
|
||||
<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>
|
||||
|
||||
<Grid Grid.Row="2" Margin="0,0,0,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
@@ -76,57 +159,75 @@
|
||||
<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}}"
|
||||
ToolTip="Add memes"/>
|
||||
</Grid>
|
||||
|
||||
<ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto">
|
||||
<Grid>
|
||||
<TextBlock Text="No memes yet. Click + or drag files in here."
|
||||
Foreground="#7B7D85" FontSize="13"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
TextWrapping="Wrap" TextAlignment="Center" Width="260">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Items.Count}" Value="0">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
<ScrollViewer Grid.Row="3" VerticalScrollBarVisibility="Auto" Padding="0,0,4,0">
|
||||
<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>
|
||||
<WrapPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
<Border Height="1" Background="#3A3B3E" Margin="4,10,4,10"/>
|
||||
</StackPanel>
|
||||
|
||||
<ItemsControl ItemsSource="{Binding Items}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type vm:MemeTileViewModel}">
|
||||
<Button Width="88" Height="88" Margin="4" Padding="0"
|
||||
Style="{StaticResource FlatButtonStyle}"
|
||||
Command="{Binding DataContext.SelectItemCommand, ElementName=RootWindow}"
|
||||
CommandParameter="{Binding}"
|
||||
Tag="{Binding DataContext, ElementName=RootWindow}"
|
||||
ToolTip="{Binding DisplayName}">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Remove"
|
||||
Command="{Binding PlacementTarget.Tag.RemoveItemCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Image Source="{Binding Thumbnail}" Stretch="Uniform" Width="80" Height="80"/>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextBlock Text="No memes yet. Click + or drag files in here."
|
||||
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>
|
||||
<WrapPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<TextBlock Grid.Row="3" Text="{Binding StatusMessage}" Foreground="#9A9CA3" FontSize="11" Margin="2,8,0,0"/>
|
||||
<Grid Grid.Row="4" Margin="2,8,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{Binding StatusMessage}" Foreground="#9A9CA3"
|
||||
FontSize="11" TextTrimming="CharacterEllipsis" VerticalAlignment="Center"/>
|
||||
<!-- Required by Giphy's API terms wherever their results are displayed. -->
|
||||
<TextBlock Grid.Column="1" Text="Powered by GIPHY" Foreground="#7B7D85"
|
||||
FontSize="10" FontWeight="SemiBold" VerticalAlignment="Center"
|
||||
Margin="8,0,0,0"
|
||||
Visibility="{Binding IsGiphySource, Converter={StaticResource BoolToVisibility}}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Window>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="Settings - Ebbe's Meme Clipboard"
|
||||
Width="380" Height="380"
|
||||
Width="400"
|
||||
Background="#F0202225"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
ResizeMode="NoResize"
|
||||
@@ -32,5 +32,18 @@
|
||||
IsChecked="{Binding IsPasteAndSend}"/>
|
||||
<TextBlock Text="Presses Enter right after pasting to submit it - use with care in chat apps."
|
||||
Foreground="#7B7D85" FontSize="10" TextWrapping="Wrap" Margin="20,4,0,0"/>
|
||||
|
||||
<TextBlock Text="Startup" Foreground="White" FontSize="14" FontWeight="Bold" Margin="0,24,0,8"/>
|
||||
<CheckBox Content="Start automatically when Windows starts" Foreground="White"
|
||||
IsChecked="{Binding AutostartEnabled}"/>
|
||||
|
||||
<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}"
|
||||
Background="Transparent" Foreground="White" BorderThickness="0"
|
||||
Padding="10,8" FontSize="13" CaretBrush="White"/>
|
||||
</Border>
|
||||
<TextBlock TextWrapping="Wrap" Foreground="#7B7D85" FontSize="11" Margin="0,4,0,0"
|
||||
Text="API key for the Giphy tab. Get a free one at developers.giphy.com (create an app, choose an API key). Leave empty to disable Giphy search."/>
|
||||
</StackPanel>
|
||||
</Window>
|
||||
|
||||
@@ -16,6 +16,14 @@ public partial class SettingsWindow : Window
|
||||
DataContext = _viewModel;
|
||||
}
|
||||
|
||||
/// <summary>Re-reads live state (e.g. the autostart registry entry) each time it's opened.</summary>
|
||||
public void ShowSettings()
|
||||
{
|
||||
_viewModel.Refresh();
|
||||
Show();
|
||||
Activate();
|
||||
}
|
||||
|
||||
private void HotkeyBox_OnPreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
Reference in New Issue
Block a user