Skip to content

Commit

Permalink
Add editor suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
DominicSaladin committed Mar 4, 2024
1 parent a3801c3 commit f2f8b02
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 14 deletions.
75 changes: 65 additions & 10 deletions speed-time/Dialogs/TrackTimeEditor.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,50 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
xmlns:potato="https://dsaladin.dev/products/fancypotato/wpf/xaml"
xmlns:localBehaviors="clr-namespace:DSaladin.SpeedTime.Behavior"
xmlns:fa="https://dsaladin.dev/products/fontawesome/wpf/xaml"
xmlns:converter="clr-namespace:DSaladin.SpeedTime.Converter"
xmlns:language="clr-namespace:DSaladin.SpeedTime.Language"
xmlns:model="clr-namespace:DSaladin.SpeedTime.Model"
xmlns:local="clr-namespace:DSaladin.SpeedTime.Dialogs"
d:DataContext="{d:DesignInstance local:TrackTimeEditor}"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="450" MaxHeight="300" MaxWidth="400">
<potato:DSDialogControl.Resources>
<converter:DateTimeTimeConverter x:Key="DateTimeTimeConverter" />

<DataTemplate x:Key="ItemTemplate" DataType="{x:Type model:TrackTime}">
<Grid>
<TextBlock Text="{Binding Title}" VerticalAlignment="Center" Padding="5,0,5,0" TextTrimming="CharacterEllipsis" />
</Grid>
</DataTemplate>

<DataTemplate x:Key="SelectedTemplate" DataType="{x:Type model:TrackTime}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="45" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Title}" VerticalAlignment="Center" Padding="5,0,5,0" TextTrimming="CharacterEllipsis" />
<potato:DSButton Grid.Column="1" Content="" FontSize="16" Padding="0,0,0,0" Margin="0,0,2,0" />
</Grid>
</DataTemplate>

<Style TargetType="{x:Type ListViewItem}" x:Key="ContainerStyle" BasedOn="{StaticResource DefaultListViewItem}">
<Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
<Setter Property="Height" Value="30" />
<Setter Property="Margin" Value="0,2,0,2" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</potato:DSDialogControl.Resources>
<potato:DSDialogControl.InputBindings>
<KeyBinding Key="Esc" Command="{Binding SaveAndCloseCommand}" />
Expand All @@ -37,7 +71,7 @@
Click="Close_Click" />
<Label Grid.Column="1" Content="{x:Static language:SpeedTime.timeeditor_title}" FontSize="20" FontWeight="Bold" HorizontalAlignment="Center" />
<potato:DSTextBox Style="{DynamicResource TransparentTextBox}" Grid.Column="1" Grid.RowSpan="2" FontSize="11" FontWeight="Bold"
HorizontalAlignment="Center" VerticalAlignment="Bottom" SelectAllOnFocus="True">
HorizontalAlignment="Center" VerticalAlignment="Bottom" SelectAllOnFocus="True" TabIndex="-1">
<potato:DSTextBox.Text>
<Binding Path="SelectedDate">
<Binding.Converter>
Expand All @@ -47,20 +81,40 @@
</potato:DSTextBox.Text>
</potato:DSTextBox>
</Grid>
<Grid Grid.Row="1" Margin="15,0,15,15">
<Grid Grid.Row="1" Margin="15,0,15,0">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="Auto" MaxHeight="165" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="60" />
</Grid.RowDefinitions>
<potato:DSTextBox x:Name="tbx_title" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Margin="0,5,0,5" Text="{Binding TrackTimeTitle}" SelectAllOnFocus="True" />
<Grid Grid.Row="1" Margin="90,0,90,0">
<potato:DSTextBox x:Name="tbx_title" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Margin="0,5,0,5" TabIndex="0"
Text="{Binding TrackTimeTitle, UpdateSourceTrigger=PropertyChanged}" SelectAllOnFocus="True" LostFocus="Title_LostFocus">
<potato:DSTextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding EnterButtonCommand}" />
<KeyBinding Key="Tab" Command="{Binding TabButtonCommand}" />
<KeyBinding Key="Esc" Command="{Binding EscButtonCommand}" />
<KeyBinding Key="Up" Command="{Binding UpButtonCommand}" />
<KeyBinding Key="Down" Command="{Binding DownButtonCommand}" />
</potato:DSTextBox.InputBindings>
</potato:DSTextBox>

<ListView Grid.Row="1" ItemsSource="{Binding TrackedTimesViewSource.View, Mode=OneWay, NotifyOnTargetUpdated=True}" ScrollViewer.CanContentScroll="False"
Height="{Binding SuggestionsHeight}" IsSynchronizedWithCurrentItem="True" Margin="5,0,5,0" SelectedIndex="{Binding SuggestionSelectedIndex}"
ItemContainerStyle="{DynamicResource ContainerStyle}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<behaviors:Interaction.Behaviors>
<localBehaviors:SelectFirstItemOnTargetUpdated />
<localBehaviors:ScrollToSelectedIndex />
</behaviors:Interaction.Behaviors>
</ListView>

<Grid Grid.Row="2" Margin="90,0,90,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<potato:DSTextBox x:Name="tbx_startTime" Grid.Column="0" Margin="10,5,10,5" HorizontalContentAlignment="Center" SelectAllOnFocus="True">
<potato:DSTextBox x:Name="tbx_startTime" Grid.Column="0" Margin="10,5,10,5" HorizontalContentAlignment="Center" SelectAllOnFocus="True" TabIndex="1">
<potato:DSTextBox.Text>
<Binding Path="TrackingStarted" ConverterParameter="HH:mm">
<Binding.Converter>
Expand All @@ -69,7 +123,7 @@
</Binding>
</potato:DSTextBox.Text>
</potato:DSTextBox>
<potato:DSTextBox x:Name="tbx_endTime" Grid.Column="1" Margin="10,5,10,5" HorizontalContentAlignment="Center" SelectAllOnFocus="True">
<potato:DSTextBox x:Name="tbx_endTime" Grid.Column="1" Margin="10,5,10,5" HorizontalContentAlignment="Center" SelectAllOnFocus="True" TabIndex="2">
<potato:DSTextBox.Text>
<Binding Path="TrackingStopped" ConverterParameter="HH:mm">
<Binding.Converter>
Expand All @@ -79,9 +133,10 @@
</potato:DSTextBox.Text>
</potato:DSTextBox>
</Grid>
<CheckBox x:Name="ckb_break" Grid.Row="2" Content="{x:Static language:SpeedTime.timeeditor_break}" Margin="5,0,0,0" IsChecked="{Binding IsBreak}" HorizontalAlignment="Center" />
<potato:DSButton Grid.Row="3" Content="{x:Static language:SpeedTime.Cancel}" Style="{DynamicResource AccentErrorButton}" Width="100" Margin="0,10,0,0"
HorizontalAlignment="Left" Command="{Binding CancelAndCloseCommand}" />
<CheckBox x:Name="ckb_break" Grid.Row="3" Content="{x:Static language:SpeedTime.timeeditor_break}" Margin="5,0,0,0" IsChecked="{Binding IsBreak}" HorizontalAlignment="Center"
TabIndex="4" />
<potato:DSButton Grid.Row="4" Content="{x:Static language:SpeedTime.Cancel}" Style="{DynamicResource AccentErrorButton}" Width="100" Margin="0,20,0,0"
HorizontalAlignment="Left" Command="{Binding CancelAndCloseCommand}" TabIndex="5" />
</Grid>
</Grid>
</potato:DSDialogControl>
139 changes: 137 additions & 2 deletions speed-time/Dialogs/TrackTimeEditor.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using DSaladin.SpeedTime.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
Expand Down Expand Up @@ -40,12 +41,57 @@ public TrackTime TrackTime
}
}

public string TrackTimeTitle { get; set; } = "";
private string trackTimeTitle = "";
public string TrackTimeTitle
{
get { return trackTimeTitle; }
set
{
trackTimeTitle = value;
NotifyPropertyChanged();
RefreshSuggestions();
}
}

private bool IsSuggestionsOpen = false;

public DateTime SelectedDate { get; set; } = DateTime.Today;
public DateTime TrackingStarted { get; set; } = DateTime.Today;
public DateTime TrackingStopped { get; set; }
public bool IsBreak { get; set; }

public double SuggestionsHeight
{
get
{
if (!IsSuggestionsOpen)
return 0;

if (TrackedTimesViewSource.View is null || string.IsNullOrEmpty(TrackTimeTitle) || TrackedTimesViewSource.View.Cast<object>().Count() == 0)
return 0;

return 165;
}
}

public CollectionViewSource TrackedTimesViewSource { get; private set; } = new();

private int suggestionSelectedIndex = -1;
public int SuggestionSelectedIndex
{
get => suggestionSelectedIndex;
set
{
suggestionSelectedIndex = value;
NotifyPropertyChanged();
}
}

public RelayCommand EnterButtonCommand { get; set; }
public RelayCommand TabButtonCommand { get; set; }
public RelayCommand EscButtonCommand { get; set; }
public RelayCommand UpButtonCommand { get; set; }
public RelayCommand DownButtonCommand { get; set; }
public RelayCommand SaveAndCloseCommand { get; set; }
public RelayCommand CancelAndCloseCommand { get; set; }

Expand All @@ -62,16 +108,105 @@ public TrackTimeEditor(TrackTime? trackTime = null)

Loaded += (s, e) =>
{
TrackedTimesViewSource = new();
TrackedTimesViewSource.SetCurrentValue(CollectionViewSource.SourceProperty, App.dbContext.TrackedTimes.Local.DistinctBy(t => t.Title));
TrackedTimesViewSource.Filter += TrackedTimesViewSource_Filter;
TrackedTimesViewSource.SortDescriptions.Add(new("TrackingStarted", ListSortDirection.Descending));
TrackedTimesViewSource.SortDescriptions.Add(new("TrackingStopped", ListSortDirection.Descending));

tbx_title.Focus();
tbx_title.SelectAll();
};

EnterButtonCommand = new((_) =>
{
IsSuggestionsOpen = false;
NotifyPropertyChanged(nameof(SuggestionsHeight));

if (TrackedTimesViewSource.View.Cast<object>().Count() == 0)
{
TitleMoveNext();
return;
}

string newTitle = TrackedTimesViewSource.View.Cast<TrackTime>().ElementAt(SuggestionSelectedIndex).Title;

if (TrackTimeTitle == newTitle)
{
TitleMoveNext();
return;
}

TrackTimeTitle = newTitle;
IsSuggestionsOpen = false;
NotifyPropertyChanged(nameof(SuggestionsHeight));
});

TabButtonCommand = new((_) =>
{
IsSuggestionsOpen = false;
NotifyPropertyChanged(nameof(SuggestionsHeight));
TitleMoveNext();
});

EscButtonCommand = new((_) =>
{
TrackTimeTitle = TrackTime.Title;
SaveAndClose();
});

UpButtonCommand = new((_) =>
{
if (SuggestionSelectedIndex <= 0)
return;

SuggestionSelectedIndex--;
});

DownButtonCommand = new((_) =>
{
if (SuggestionSelectedIndex >= TrackedTimesViewSource.View.Cast<object>().Count() - 1)
return;

SuggestionSelectedIndex++;
});
}

public TrackTimeEditor(DateTime startDate): this()
public TrackTimeEditor(DateTime startDate) : this()
{
SelectedDate = startDate;
}

private void TitleMoveNext()
{
TraversalRequest request = new(FocusNavigationDirection.Next) { Wrapped = true };
tbx_title.MoveFocus(request);
}

private void Title_LostFocus(object sender, RoutedEventArgs e)
{
TrackTime.Title = TrackTimeTitle;
}

private void TrackedTimesViewSource_Filter(object sender, FilterEventArgs e)
{
CollectionViewSource viewSource = (CollectionViewSource)sender;
e.Accepted = (e.Item as TrackTime)!.Title.Contains(TrackTimeTitle, StringComparison.OrdinalIgnoreCase);
}

private void RefreshSuggestions()
{
if (TrackedTimesViewSource.View is null)
return;

TrackedTimesViewSource.View.Refresh();

IsSuggestionsOpen = true;
NotifyPropertyChanged(nameof(TrackedTimesViewSource));
NotifyPropertyChanged(nameof(SuggestionsHeight));
//NotifyPropertyChanged(nameof(WindowHeight));
}

private void SaveAndClose()
{
if (string.IsNullOrEmpty(TrackTimeTitle))
Expand Down
3 changes: 2 additions & 1 deletion speed-time/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
<ColumnDefinition Width="65" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding CurrentTime.Title, TargetNullValue=''}" Style="{DynamicResource DefaultTextBlock}"
d:Text="Searching bugs" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" />
d:Text="Searching bugs" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"
Padding="4,4,4,4" />
<Label Grid.Column="1" Content="{Binding CurrentTime.Hours, TargetNullValue=''}" ContentStringFormat=" {0:N2}h"
d:Content="1.25" Style="{DynamicResource Title4Label}" HorizontalAlignment="Right" />
</Grid>
Expand Down
3 changes: 3 additions & 0 deletions speed-time/ViewModel/QuickTimeTrackerViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ public QuickTimeTrackerViewModel(TrackTime? lastTrackTime)

TabButtonCommand = new((_) =>
{
if (TrackedTimesViewSource.View.Cast<object>().Count() == 0)
return;

WorkTitle = TrackedTimesViewSource.View.Cast<TrackTime>().ElementAt(SuggestionSelectedIndex).Title;
});

Expand Down
2 changes: 1 addition & 1 deletion speed-time/speed-time.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<PackageReadmeFile>README.md</PackageReadmeFile>
<ApplicationIcon>Icon.ico</ApplicationIcon>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<Version>0.15.1</Version>
<Version>0.16</Version>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile></AssemblyOriginatorKeyFile>
</PropertyGroup>
Expand Down

0 comments on commit f2f8b02

Please sign in to comment.