mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-23 21:55:34 +08:00
usability tweaks.
implemented lookup of file names by typing its first letters. 'sort by' menu now works properly.
This commit is contained in:
parent
7492ea24ae
commit
931d76db04
@ -27,6 +27,8 @@
|
||||
<CollectionViewSource x:Key="ListViewSource" Source="{Binding}"/>
|
||||
<local:BooleanToCollapsedVisibilityConverter x:Key="booleanToCollapsedVisibilityConverter" />
|
||||
<local:EntryTypeConverter x:Key="entryTypeConverter"/>
|
||||
<local:SortModeToBooleanConverter x:Key="sortModeToBooleanConverter" />
|
||||
|
||||
<Style x:Key="HeaderLeftAlign" TargetType="{x:Type GridViewColumnHeader}">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Left"></Setter>
|
||||
</Style>
|
||||
@ -151,16 +153,16 @@
|
||||
<Separator/>
|
||||
<MenuItem Header="{x:Static s:guiStrings.CtxMenuSortBy}">
|
||||
<MenuItem Header="{x:Static s:guiStrings.CtxMenuSortByName}" IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=AppWindow, Path=IsSortByName, Mode=OneWay}"
|
||||
IsChecked="{Binding ElementName=AppWindow, Path=SortMode, Mode=OneWay, Converter={StaticResource sortModeToBooleanConverter}, ConverterParameter=Name}"
|
||||
Command="{x:Static local:Commands.SortBy}" CommandParameter="Name"/>
|
||||
<MenuItem Header="{x:Static s:guiStrings.CtxMenuSortByType}" IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=AppWindow, Path=IsSortByType, Mode=OneWay}"
|
||||
IsChecked="{Binding ElementName=AppWindow, Path=SortMode, Mode=OneWay, Converter={StaticResource sortModeToBooleanConverter}, ConverterParameter=Type}"
|
||||
Command="{x:Static local:Commands.SortBy}" CommandParameter="Type"/>
|
||||
<MenuItem Header="{x:Static s:guiStrings.CtxMenuSortBySize}" IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=AppWindow, Path=IsSortBySize, Mode=OneWay}"
|
||||
IsChecked="{Binding ElementName=AppWindow, Path=SortMode, Mode=OneWay, Converter={StaticResource sortModeToBooleanConverter}, ConverterParameter=Size}"
|
||||
Command="{x:Static local:Commands.SortBy}" CommandParameter="Size"/>
|
||||
<MenuItem Header="{x:Static s:guiStrings.CtxMenuUnsorted}" IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=AppWindow, Path=IsUnsorted, Mode=OneWay}"
|
||||
IsChecked="{Binding ElementName=AppWindow, Path=SortMode, Mode=OneWay, Converter={StaticResource sortModeToBooleanConverter}}"
|
||||
Command="{x:Static local:Commands.SortBy}"/>
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
|
@ -25,6 +25,7 @@ using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
@ -108,7 +109,7 @@ namespace GARbro.GUI
|
||||
{
|
||||
if (null != m_lvSortByColumn)
|
||||
{
|
||||
Settings.Default.lvSortColumn = m_lvSortByColumn.Tag.ToString();
|
||||
Settings.Default.lvSortColumn = SortMode;
|
||||
Settings.Default.lvSortDirection = m_lvSortDirection;
|
||||
}
|
||||
else
|
||||
@ -165,7 +166,7 @@ namespace GARbro.GUI
|
||||
return;
|
||||
if (null == node)
|
||||
{
|
||||
while (MaxRecentFiles < m_recent_files.Count)
|
||||
while (MaxRecentFiles <= m_recent_files.Count)
|
||||
m_recent_files.RemoveLast();
|
||||
m_recent_files.AddFirst (file);
|
||||
}
|
||||
@ -200,10 +201,7 @@ namespace GARbro.GUI
|
||||
if (value.IsArchive)
|
||||
PushRecentFile (value.Path);
|
||||
|
||||
if (m_lvSortByColumn != null)
|
||||
lv_Sort (m_lvSortByColumn.Tag.ToString(), m_lvSortDirection);
|
||||
else
|
||||
lv_Sort (null, m_lvSortDirection);
|
||||
lv_Sort (SortMode, m_lvSortDirection);
|
||||
if (!value.IsArchive && !string.IsNullOrEmpty (value.Path))
|
||||
{
|
||||
Directory.SetCurrentDirectory (value.Path);
|
||||
@ -395,16 +393,14 @@ namespace GARbro.GUI
|
||||
GridViewColumnHeader m_lvSortByColumn = null;
|
||||
ListSortDirection m_lvSortDirection = ListSortDirection.Ascending;
|
||||
|
||||
public bool IsSortByName {
|
||||
get { return m_lvSortByColumn != null && "Name".Equals (m_lvSortByColumn.Tag); }
|
||||
public string SortMode
|
||||
{
|
||||
get { return GetValue (SortModeProperty) as string; }
|
||||
private set { SetValue (SortModeProperty, value); }
|
||||
}
|
||||
public bool IsSortByType {
|
||||
get { return m_lvSortByColumn != null && "Type".Equals (m_lvSortByColumn.Tag); }
|
||||
}
|
||||
public bool IsSortBySize {
|
||||
get { return m_lvSortByColumn != null && "Size".Equals (m_lvSortByColumn.Tag); }
|
||||
}
|
||||
public bool IsUnsorted { get { return m_lvSortByColumn == null; } }
|
||||
|
||||
public static readonly DependencyProperty SortModeProperty =
|
||||
DependencyProperty.RegisterAttached ("SortMode", typeof(string), typeof(MainWindow), new UIPropertyMetadata());
|
||||
|
||||
void lv_SetSortMode (string sortBy, ListSortDirection direction)
|
||||
{
|
||||
@ -427,6 +423,7 @@ namespace GARbro.GUI
|
||||
column.HeaderTemplate = Resources["SortArrowNone"] as DataTemplate;
|
||||
}
|
||||
}
|
||||
SortMode = sortBy;
|
||||
}
|
||||
|
||||
private void lv_Sort (string sortBy, ListSortDirection direction)
|
||||
@ -457,6 +454,7 @@ namespace GARbro.GUI
|
||||
|
||||
string sortBy = headerClicked.Tag.ToString();
|
||||
lv_Sort (sortBy, direction);
|
||||
SortMode = sortBy;
|
||||
|
||||
// Remove arrow from previously sorted header
|
||||
if (m_lvSortByColumn != null && m_lvSortByColumn != headerClicked)
|
||||
@ -488,20 +486,31 @@ namespace GARbro.GUI
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for keys pressed in the right pane
|
||||
/// Event handler for keys pressed in the directory view pane
|
||||
/// </summary>
|
||||
|
||||
private void lv_TextInput (object sender, TextCompositionEventArgs e)
|
||||
{
|
||||
LookupItem (e.Text);
|
||||
LookupItem (e.Text, e.Timestamp);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
class InputData
|
||||
{
|
||||
public int LastTime = 0;
|
||||
public StringBuilder Phrase = new StringBuilder();
|
||||
public bool Mismatch = false;
|
||||
}
|
||||
|
||||
const int TextLookupTimeout = 1000; // milliseconds
|
||||
|
||||
InputData m_current_input = new InputData();
|
||||
|
||||
/// <summary>
|
||||
/// Lookup item in listview pane by first letter.
|
||||
/// Lookup item in listview pane by first letters of name.
|
||||
/// </summary>
|
||||
|
||||
private void LookupItem (string key)
|
||||
private void LookupItem (string key, int timestamp)
|
||||
{
|
||||
if (string.IsNullOrEmpty (key))
|
||||
return;
|
||||
@ -509,20 +518,39 @@ namespace GARbro.GUI
|
||||
if (source == null)
|
||||
return;
|
||||
|
||||
var current = CurrentDirectory.SelectedItem as EntryViewModel;
|
||||
int index = 0;
|
||||
if (current != null && current.Name.StartsWith (key, StringIgnoreCase))
|
||||
index = CurrentDirectory.SelectedIndex+1;
|
||||
|
||||
for (int i = index, count = source.Count; i < count; ++i)
|
||||
if (timestamp - m_current_input.LastTime > TextLookupTimeout)
|
||||
{
|
||||
var entry = source.GetItemAt (i) as EntryViewModel;
|
||||
if (entry != null && entry.Name.StartsWith (key, StringIgnoreCase))
|
||||
m_current_input.Phrase.Clear();
|
||||
m_current_input.Mismatch = false;
|
||||
}
|
||||
m_current_input.LastTime = timestamp;
|
||||
if (m_current_input.Mismatch)
|
||||
return;
|
||||
|
||||
if (1 == m_current_input.Phrase.Length && m_current_input.Phrase[0] == key[0])
|
||||
{
|
||||
// same key repeats, lookup by first letter only
|
||||
int current = CurrentDirectory.SelectedIndex;
|
||||
if (current != -1 && current+1 < source.Count)
|
||||
{
|
||||
lv_SelectItem (entry);
|
||||
break;
|
||||
var next_item = source.GetItemAt (current+1) as EntryViewModel;
|
||||
if (next_item != null && next_item.Name.StartsWith (key, StringIgnoreCase))
|
||||
{
|
||||
lv_SelectItem (next_item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_input.Phrase.Append (key);
|
||||
}
|
||||
string input = m_current_input.Phrase.ToString();
|
||||
var matched = source.Cast<EntryViewModel>().Where (e => e.Name.StartsWith (input, StringIgnoreCase)).FirstOrDefault();
|
||||
if (null != matched)
|
||||
lv_SelectItem (matched);
|
||||
else
|
||||
m_current_input.Mismatch = true;
|
||||
}
|
||||
|
||||
private void acb_OnKeyDown (object sender, KeyEventArgs e)
|
||||
@ -1087,6 +1115,23 @@ namespace GARbro.GUI
|
||||
}
|
||||
}
|
||||
|
||||
public class SortModeToBooleanConverter : IValueConverter
|
||||
{
|
||||
public object Convert (object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
string actual_mode = value as string;
|
||||
string check_mode = parameter as string;
|
||||
if (string.IsNullOrEmpty (check_mode))
|
||||
return string.IsNullOrEmpty (actual_mode);
|
||||
return check_mode.Equals (actual_mode);
|
||||
}
|
||||
|
||||
public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class BooleanToCollapsedVisibilityConverter : IValueConverter
|
||||
{
|
||||
#region IValueConverter Members
|
||||
|
Loading…
Reference in New Issue
Block a user