Skip to content

Commit

Permalink
Various UI tweaks.
Browse files Browse the repository at this point in the history
  • Loading branch information
comintern committed Dec 15, 2018
1 parent aa01470 commit 421c213
Show file tree
Hide file tree
Showing 11 changed files with 304 additions and 55 deletions.
@@ -1,4 +1,5 @@
using System.Windows.Forms;
using System.Drawing;
using System.Windows.Forms;
using Rubberduck.UI.Refactorings;

namespace Rubberduck.UI.AddRemoveReferences
Expand All @@ -9,7 +10,14 @@ public partial class AddRemoveReferencesDialog : Form, IRefactoringDialog<AddRem

public AddRemoveReferencesDialog()
{
InitializeComponent();
InitializeComponent();
MinimumSize= new Size(600, 380);
}

public sealed override Size MinimumSize
{
get => base.MinimumSize;
set => base.MinimumSize = value;
}

public AddRemoveReferencesDialog(AddRemoveReferencesViewModel viewModel) : this()
Expand Down
Expand Up @@ -101,6 +101,7 @@ public AddRemoveReferencesViewModel(IAddRemoveReferencesModel model, IReferenceR

AddCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteAddCommand);
RemoveCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteRemoveCommand);
ClearSearchCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteClearSearchCommand);
BrowseCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteBrowseCommand);
MoveUpCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteMoveUpCommand);
MoveDownCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteMoveDownCommand);
Expand All @@ -112,6 +113,10 @@ public AddRemoveReferencesViewModel(IAddRemoveReferencesModel model, IReferenceR
ApplyCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteApplyCommand);
}

public string ProjectCaption => string.IsNullOrEmpty(Model?.Project?.IdentifierName)
? RubberduckUI.References_Caption
: string.Format(RubberduckUI.References_CaptionTemplate, Model.Project.IdentifierName);

/// <summary>
/// The IAddRemoveReferencesModel for the view.
/// </summary>
Expand All @@ -120,7 +125,7 @@ public AddRemoveReferencesViewModel(IAddRemoveReferencesModel model, IReferenceR
/// <summary>
/// Hides the projects filter if the host does not support them. Statically set.
/// </summary>
public bool ProjectsVisible => HostHasProjects;
public bool ProjectsHidden => !HostHasProjects;

/// <summary>
/// The number of built-in (locked) references of the project.
Expand All @@ -137,6 +142,11 @@ public AddRemoveReferencesViewModel(IAddRemoveReferencesModel model, IReferenceR
/// </summary>
public ICommand RemoveCommand { get; }

/// <summary>
/// Clears the search textbox.
/// </summary>
public ICommand ClearSearchCommand { get; }

/// <summary>
/// Prompts the user to browse for a reference.
/// </summary>
Expand Down Expand Up @@ -222,6 +232,18 @@ private void ExecuteRemoveCommand(object parameter)
AvailableReferences.Refresh();
}

/// <summary>
/// Delegate for ClearSearchCommand.
/// </summary>
/// <param name="parameter">Ignored</param>
private void ExecuteClearSearchCommand(object parameter)
{
if (!string.IsNullOrEmpty(Search))
{
Search = string.Empty;
}
}

/// <summary>
/// Delegate for BrowseCommand.
/// </summary>
Expand Down Expand Up @@ -445,6 +467,7 @@ public string Search
set
{
_search = value;
OnPropertyChanged();
AvailableReferences.Refresh();
}
}
Expand Down
Expand Up @@ -7,11 +7,11 @@
xmlns:local="clr-namespace:Rubberduck.UI.AddRemoveReferences"
xmlns:converters="clr-namespace:Rubberduck.UI.Converters"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:controls="clr-namespace:Rubberduck.UI.Controls"
mc:Ignorable="d"
d:DesignHeight="380" d:DesignWidth="600"
d:DataContext="{d:DesignInstance local:AddRemoveReferencesViewModel}">
<UserControl.Resources>
<BitmapImage x:Key="SearchIcon" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/magnifier-medium.png" />
<BitmapImage x:Key="BrowseIcon" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/folder-open.png" />
<BitmapImage x:Key="LibraryIcon" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/node-select-all.png" />
<BitmapImage x:Key="VbaProjectIcon" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Custom/PNG/ObjectClass.png" />
Expand All @@ -24,7 +24,8 @@

<local:ReferenceStatusImageSourceConverter x:Key="StatusToIcon" />
<local:PriorityButtonVisibilityConverter x:Key="PriorityButtonVisibility" />
<converters:RemainingWidthConverter x:Key="RemainingWidth" />
<local:SearchImageSourceConverter x:Key="SearchToIcon" />
<converters:BoolToHiddenVisibilityConverter x:Key="ProjectVisibilityConverter" />

<Style x:Key="DialogButtonStyle" TargetType="Button">
<Setter Property="Margin" Value="5,0" />
Expand Down Expand Up @@ -129,7 +130,7 @@
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Dock="Top" Background="{x:Static SystemColors.WindowBrush}">
<Label DockPanel.Dock="Top" Content="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=References_Caption}" FontWeight="Bold" />
<Label DockPanel.Dock="Top" Content="{Binding ProjectCaption}" FontWeight="Bold" />
<TextBlock DockPanel.Dock="Top" Text="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=References_SubCaption}" Margin="10,0,0,10" />
</DockPanel>
<Border Grid.Row="1" Background="{x:Static SystemColors.ControlLightBrush}">
Expand All @@ -149,7 +150,7 @@
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem Tag="Projects" Visibility="{Binding ProjectsVisible}">
<TabItem Tag="Projects" Visibility="{Binding ProjectsHidden, Converter={StaticResource ProjectVisibilityConverter}}">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="{StaticResource VbaProjectIcon}" />
Expand Down Expand Up @@ -203,7 +204,7 @@
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0">
<TextBox Name="SearchBox" Grid.Column="0">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource PlaceHolder}">
<Setter Property="Height" Value="20" />
Expand All @@ -213,13 +214,22 @@
</Style>
</TextBox.Style>
</TextBox>
<Border Grid.Column="1" Margin="2" Width="16" Height="16">
<Image Source="{StaticResource SearchIcon}" />
</Border>
<Button Name="SearchButton" Grid.Column="1" Command="{Binding ClearSearchCommand}"
BorderBrush="{x:Static SystemColors.ControlLightBrush}"
Background="Transparent"
Width="20" Height="20" Padding="0" Margin="0,1"
controls:EventFocusAttachment.ElementToFocus="{Binding ElementName=SearchBox}">
<Image Margin="2" Width="16" Height="16"
Source="{Binding Search, Converter={StaticResource SearchToIcon}, UpdateSourceTrigger=PropertyChanged}" />
</Button>
</Grid>
</Border>
<Border Grid.Row="1" Grid.Column="0">
<ListView Name="LibrarySelect" SelectedItem="{Binding SelectedLibrary, Mode=TwoWay}" ItemsSource="{Binding AvailableReferences}" HorizontalContentAlignment="Stretch">
<ListView Name="LibrarySelect" SelectedItem="{Binding SelectedLibrary, Mode=TwoWay}"
SelectionMode="Single"
ItemsSource="{Binding AvailableReferences}"
HorizontalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Hidden">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Height" Value="20" />
Expand All @@ -230,17 +240,23 @@
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}, Converter={StaticResource RemainingWidth}}" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Width="16" Height="16"
Background="Transparent"
BorderBrush="Transparent"
Command="{Binding DataContext.PinLibraryCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:AddRemoveReferencesWindow}}}">
<i:Interaction.Behaviors>
<controls:BindableListItemDrillThroughBehavior />
</i:Interaction.Behaviors>
<Image Source="{Binding Status, Converter={StaticResource StatusToIcon}}" />
</Button>
<TextBlock Grid.Column="1" Text="{Binding Description}" Margin="2,0">
<TextBlock Grid.Column="1" Text="{Binding Description}" Margin="2,0" TextTrimming="CharacterEllipsis">
<i:Interaction.Behaviors>
<controls:BindableListItemDrillThroughBehavior />
</i:Interaction.Behaviors>
<TextBlock.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick"
Command="{Binding DataContext.AddCommand, UpdateSourceTrigger=PropertyChanged, ElementName=LibrarySelect}" />
Expand All @@ -261,7 +277,12 @@
</Button>
</StackPanel>
<Border Grid.Row="1" Grid.Column="2">
<ListView Name="ProjectSelect" SelectedItem="{Binding SelectedReference, Mode=TwoWay}" ItemsSource="{Binding ProjectReferences}" HorizontalContentAlignment="Stretch">
<ListView Name="ProjectSelect"
SelectedItem="{Binding SelectedReference, Mode=TwoWay}"
SelectionMode="Single"
ItemsSource="{Binding ProjectReferences, NotifyOnTargetUpdated=True}"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
HorizontalContentAlignment="Stretch">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Height" Value="20" />
Expand All @@ -272,7 +293,7 @@
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}, Converter={StaticResource RemainingWidth}}" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="20" />
<ColumnDefinition Width="20" />
Expand All @@ -283,8 +304,14 @@
BorderBrush="Transparent"
Command="{Binding DataContext.PinReferenceCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:AddRemoveReferencesWindow}}}">
<Image Source="{Binding Status, Converter={StaticResource StatusToIcon}}" />
<i:Interaction.Behaviors>
<controls:BindableListItemDrillThroughBehavior />
</i:Interaction.Behaviors>
</Button>
<TextBlock Grid.Column="1" Text="{Binding Description}" Margin="2,0">
<TextBlock Grid.Column="1" Text="{Binding Description}" Margin="2,0" TextTrimming="CharacterEllipsis">
<i:Interaction.Behaviors>
<controls:BindableListItemDrillThroughBehavior />
</i:Interaction.Behaviors>
<TextBlock.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick"
Command="{Binding DataContext.RemoveCommand, UpdateSourceTrigger=PropertyChanged, ElementName=ProjectSelect}" />
Expand Down
@@ -0,0 +1,58 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
using GongSolutions.Wpf.DragDrop.Utilities;

namespace Rubberduck.UI.Controls
{
public class BindableListItemDrillThroughBehavior : Behavior<FrameworkElement>
{
protected override void OnAttached()
{
base.OnAttached();

var element = AssociatedObject;
if (element == null)
{
return;
}

AddHandler(element);
}

private void AddHandler(IInputElement element)
{
element.PreviewMouseLeftButtonDown += OnClickStarting;
}

private void RemoveHandler(IInputElement element)
{
element.PreviewMouseLeftButtonDown -= OnClickStarting;
}

private void OnClickStarting(object sender, MouseButtonEventArgs e)
{
var element = AssociatedObject;
var listItem = element?.GetVisualAncestor<ListViewItem>();

if (listItem == null)
{
return;
}

listItem.IsSelected = true;
}

protected override void OnDetaching()
{
var listView = AssociatedObject;
if (listView != null)
{
RemoveHandler(listView);
}

base.OnDetaching();
}
}
}
@@ -0,0 +1,75 @@
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using GongSolutions.Wpf.DragDrop.Utilities;

namespace Rubberduck.UI.AddRemoveReferences
{
public class BindableListViewResizeBehavior : Behavior<ListView>
{
protected override void OnAttached()
{
base.OnAttached();

var listView = AssociatedObject;
if (listView == null)
{
return;
}

AddHandler(listView);
}

private void AddHandler(FrameworkElement listView)
{
listView.SizeChanged += OnSizeChanged;
}

private void RemoveHandler(FrameworkElement listView)
{
listView.SizeChanged -= OnSizeChanged;
}

private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
if (!e.WidthChanged)
{
return;
}

var listView = AssociatedObject;

var textBlock = listView?.GetVisualDescendent<TextBlock>();
// ListView uses a grid internally, so we need to overshoot and come back. WPWTF.
var grid = textBlock?.GetVisualAncestor<Grid>();
var target = grid?.ColumnDefinitions.FirstOrDefault(column => column.Width.IsStar);

if (target == null)
{
return;
}

var scroll = listView.GetVisualDescendents<ScrollViewer>()
.FirstOrDefault(element => element.ComputedVerticalScrollBarVisibility == Visibility.Visible);

var scrollWidth = scroll != null && scroll.IsVisible ? scroll.ActualWidth - scroll.ViewportWidth : 0;
var calculated = listView.ActualWidth - grid.ColumnDefinitions
.Where(column => !ReferenceEquals(target, column))
.Sum(column => column.Width.Value) - scrollWidth;

target.Width = new GridLength(calculated);
}

protected override void OnDetaching()
{
var listView = AssociatedObject;
if (listView != null)
{
RemoveHandler(listView);
}

base.OnDetaching();
}
}
}
@@ -0,0 +1,18 @@
using System;
using System.Globalization;
using System.Windows.Media;
using ImageSourceConverter = Rubberduck.UI.Converters.ImageSourceConverter;

namespace Rubberduck.UI.AddRemoveReferences
{
public class SearchImageSourceConverter : ImageSourceConverter
{
private readonly ImageSource _search = ToImageSource(Resources.RubberduckUI.magnifier_medium);
private readonly ImageSource _clear = ToImageSource(Resources.RubberduckUI.cross_script);

public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.IsNullOrEmpty(value?.ToString()) ? _search : _clear;
}
}
}

0 comments on commit 421c213

Please sign in to comment.