Skip to content

Commit 421c213

Browse files
committed
Various UI tweaks.
1 parent aa01470 commit 421c213

11 files changed

+304
-55
lines changed

Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesDialog.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Windows.Forms;
1+
using System.Drawing;
2+
using System.Windows.Forms;
23
using Rubberduck.UI.Refactorings;
34

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

1011
public AddRemoveReferencesDialog()
1112
{
12-
InitializeComponent();
13+
InitializeComponent();
14+
MinimumSize= new Size(600, 380);
15+
}
16+
17+
public sealed override Size MinimumSize
18+
{
19+
get => base.MinimumSize;
20+
set => base.MinimumSize = value;
1321
}
1422

1523
public AddRemoveReferencesDialog(AddRemoveReferencesViewModel viewModel) : this()

Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesViewModel.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ public AddRemoveReferencesViewModel(IAddRemoveReferencesModel model, IReferenceR
101101

102102
AddCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteAddCommand);
103103
RemoveCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteRemoveCommand);
104+
ClearSearchCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteClearSearchCommand);
104105
BrowseCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteBrowseCommand);
105106
MoveUpCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteMoveUpCommand);
106107
MoveDownCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteMoveDownCommand);
@@ -112,6 +113,10 @@ public AddRemoveReferencesViewModel(IAddRemoveReferencesModel model, IReferenceR
112113
ApplyCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteApplyCommand);
113114
}
114115

116+
public string ProjectCaption => string.IsNullOrEmpty(Model?.Project?.IdentifierName)
117+
? RubberduckUI.References_Caption
118+
: string.Format(RubberduckUI.References_CaptionTemplate, Model.Project.IdentifierName);
119+
115120
/// <summary>
116121
/// The IAddRemoveReferencesModel for the view.
117122
/// </summary>
@@ -120,7 +125,7 @@ public AddRemoveReferencesViewModel(IAddRemoveReferencesModel model, IReferenceR
120125
/// <summary>
121126
/// Hides the projects filter if the host does not support them. Statically set.
122127
/// </summary>
123-
public bool ProjectsVisible => HostHasProjects;
128+
public bool ProjectsHidden => !HostHasProjects;
124129

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

145+
/// <summary>
146+
/// Clears the search textbox.
147+
/// </summary>
148+
public ICommand ClearSearchCommand { get; }
149+
140150
/// <summary>
141151
/// Prompts the user to browse for a reference.
142152
/// </summary>
@@ -222,6 +232,18 @@ private void ExecuteRemoveCommand(object parameter)
222232
AvailableReferences.Refresh();
223233
}
224234

235+
/// <summary>
236+
/// Delegate for ClearSearchCommand.
237+
/// </summary>
238+
/// <param name="parameter">Ignored</param>
239+
private void ExecuteClearSearchCommand(object parameter)
240+
{
241+
if (!string.IsNullOrEmpty(Search))
242+
{
243+
Search = string.Empty;
244+
}
245+
}
246+
225247
/// <summary>
226248
/// Delegate for BrowseCommand.
227249
/// </summary>
@@ -445,6 +467,7 @@ public string Search
445467
set
446468
{
447469
_search = value;
470+
OnPropertyChanged();
448471
AvailableReferences.Refresh();
449472
}
450473
}

Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesWindow.xaml

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
xmlns:local="clr-namespace:Rubberduck.UI.AddRemoveReferences"
88
xmlns:converters="clr-namespace:Rubberduck.UI.Converters"
99
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
10+
xmlns:controls="clr-namespace:Rubberduck.UI.Controls"
1011
mc:Ignorable="d"
1112
d:DesignHeight="380" d:DesignWidth="600"
1213
d:DataContext="{d:DesignInstance local:AddRemoveReferencesViewModel}">
1314
<UserControl.Resources>
14-
<BitmapImage x:Key="SearchIcon" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/magnifier-medium.png" />
1515
<BitmapImage x:Key="BrowseIcon" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/folder-open.png" />
1616
<BitmapImage x:Key="LibraryIcon" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/node-select-all.png" />
1717
<BitmapImage x:Key="VbaProjectIcon" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Custom/PNG/ObjectClass.png" />
@@ -24,7 +24,8 @@
2424

2525
<local:ReferenceStatusImageSourceConverter x:Key="StatusToIcon" />
2626
<local:PriorityButtonVisibilityConverter x:Key="PriorityButtonVisibility" />
27-
<converters:RemainingWidthConverter x:Key="RemainingWidth" />
27+
<local:SearchImageSourceConverter x:Key="SearchToIcon" />
28+
<converters:BoolToHiddenVisibilityConverter x:Key="ProjectVisibilityConverter" />
2829

2930
<Style x:Key="DialogButtonStyle" TargetType="Button">
3031
<Setter Property="Margin" Value="5,0" />
@@ -129,7 +130,7 @@
129130
<RowDefinition Height="40" />
130131
</Grid.RowDefinitions>
131132
<DockPanel Grid.Row="0" Dock="Top" Background="{x:Static SystemColors.WindowBrush}">
132-
<Label DockPanel.Dock="Top" Content="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=References_Caption}" FontWeight="Bold" />
133+
<Label DockPanel.Dock="Top" Content="{Binding ProjectCaption}" FontWeight="Bold" />
133134
<TextBlock DockPanel.Dock="Top" Text="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=References_SubCaption}" Margin="10,0,0,10" />
134135
</DockPanel>
135136
<Border Grid.Row="1" Background="{x:Static SystemColors.ControlLightBrush}">
@@ -149,7 +150,7 @@
149150
</StackPanel>
150151
</TabItem.Header>
151152
</TabItem>
152-
<TabItem Tag="Projects" Visibility="{Binding ProjectsVisible}">
153+
<TabItem Tag="Projects" Visibility="{Binding ProjectsHidden, Converter={StaticResource ProjectVisibilityConverter}}">
153154
<TabItem.Header>
154155
<StackPanel Orientation="Horizontal">
155156
<Image Source="{StaticResource VbaProjectIcon}" />
@@ -203,7 +204,7 @@
203204
<ColumnDefinition Width="*" />
204205
<ColumnDefinition Width="20" />
205206
</Grid.ColumnDefinitions>
206-
<TextBox Grid.Column="0">
207+
<TextBox Name="SearchBox" Grid.Column="0">
207208
<TextBox.Style>
208209
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource PlaceHolder}">
209210
<Setter Property="Height" Value="20" />
@@ -213,13 +214,22 @@
213214
</Style>
214215
</TextBox.Style>
215216
</TextBox>
216-
<Border Grid.Column="1" Margin="2" Width="16" Height="16">
217-
<Image Source="{StaticResource SearchIcon}" />
218-
</Border>
217+
<Button Name="SearchButton" Grid.Column="1" Command="{Binding ClearSearchCommand}"
218+
BorderBrush="{x:Static SystemColors.ControlLightBrush}"
219+
Background="Transparent"
220+
Width="20" Height="20" Padding="0" Margin="0,1"
221+
controls:EventFocusAttachment.ElementToFocus="{Binding ElementName=SearchBox}">
222+
<Image Margin="2" Width="16" Height="16"
223+
Source="{Binding Search, Converter={StaticResource SearchToIcon}, UpdateSourceTrigger=PropertyChanged}" />
224+
</Button>
219225
</Grid>
220226
</Border>
221227
<Border Grid.Row="1" Grid.Column="0">
222-
<ListView Name="LibrarySelect" SelectedItem="{Binding SelectedLibrary, Mode=TwoWay}" ItemsSource="{Binding AvailableReferences}" HorizontalContentAlignment="Stretch">
228+
<ListView Name="LibrarySelect" SelectedItem="{Binding SelectedLibrary, Mode=TwoWay}"
229+
SelectionMode="Single"
230+
ItemsSource="{Binding AvailableReferences}"
231+
HorizontalContentAlignment="Stretch"
232+
ScrollViewer.HorizontalScrollBarVisibility="Hidden">
223233
<ListView.ItemContainerStyle>
224234
<Style TargetType="ListViewItem">
225235
<Setter Property="Height" Value="20" />
@@ -230,17 +240,23 @@
230240
<Grid>
231241
<Grid.ColumnDefinitions>
232242
<ColumnDefinition Width="20" />
233-
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}, Converter={StaticResource RemainingWidth}}" />
243+
<ColumnDefinition Width="*" />
234244
<ColumnDefinition Width="50" />
235245
</Grid.ColumnDefinitions>
236246
<Button Grid.Column="0"
237247
Width="16" Height="16"
238248
Background="Transparent"
239249
BorderBrush="Transparent"
240250
Command="{Binding DataContext.PinLibraryCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:AddRemoveReferencesWindow}}}">
251+
<i:Interaction.Behaviors>
252+
<controls:BindableListItemDrillThroughBehavior />
253+
</i:Interaction.Behaviors>
241254
<Image Source="{Binding Status, Converter={StaticResource StatusToIcon}}" />
242255
</Button>
243-
<TextBlock Grid.Column="1" Text="{Binding Description}" Margin="2,0">
256+
<TextBlock Grid.Column="1" Text="{Binding Description}" Margin="2,0" TextTrimming="CharacterEllipsis">
257+
<i:Interaction.Behaviors>
258+
<controls:BindableListItemDrillThroughBehavior />
259+
</i:Interaction.Behaviors>
244260
<TextBlock.InputBindings>
245261
<MouseBinding MouseAction="LeftDoubleClick"
246262
Command="{Binding DataContext.AddCommand, UpdateSourceTrigger=PropertyChanged, ElementName=LibrarySelect}" />
@@ -261,7 +277,12 @@
261277
</Button>
262278
</StackPanel>
263279
<Border Grid.Row="1" Grid.Column="2">
264-
<ListView Name="ProjectSelect" SelectedItem="{Binding SelectedReference, Mode=TwoWay}" ItemsSource="{Binding ProjectReferences}" HorizontalContentAlignment="Stretch">
280+
<ListView Name="ProjectSelect"
281+
SelectedItem="{Binding SelectedReference, Mode=TwoWay}"
282+
SelectionMode="Single"
283+
ItemsSource="{Binding ProjectReferences, NotifyOnTargetUpdated=True}"
284+
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
285+
HorizontalContentAlignment="Stretch">
265286
<ListView.ItemContainerStyle>
266287
<Style TargetType="ListViewItem">
267288
<Setter Property="Height" Value="20" />
@@ -272,7 +293,7 @@
272293
<Grid>
273294
<Grid.ColumnDefinitions>
274295
<ColumnDefinition Width="20" />
275-
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}, Converter={StaticResource RemainingWidth}}" />
296+
<ColumnDefinition Width="*" />
276297
<ColumnDefinition Width="50" />
277298
<ColumnDefinition Width="20" />
278299
<ColumnDefinition Width="20" />
@@ -283,8 +304,14 @@
283304
BorderBrush="Transparent"
284305
Command="{Binding DataContext.PinReferenceCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:AddRemoveReferencesWindow}}}">
285306
<Image Source="{Binding Status, Converter={StaticResource StatusToIcon}}" />
307+
<i:Interaction.Behaviors>
308+
<controls:BindableListItemDrillThroughBehavior />
309+
</i:Interaction.Behaviors>
286310
</Button>
287-
<TextBlock Grid.Column="1" Text="{Binding Description}" Margin="2,0">
311+
<TextBlock Grid.Column="1" Text="{Binding Description}" Margin="2,0" TextTrimming="CharacterEllipsis">
312+
<i:Interaction.Behaviors>
313+
<controls:BindableListItemDrillThroughBehavior />
314+
</i:Interaction.Behaviors>
288315
<TextBlock.InputBindings>
289316
<MouseBinding MouseAction="LeftDoubleClick"
290317
Command="{Binding DataContext.RemoveCommand, UpdateSourceTrigger=PropertyChanged, ElementName=ProjectSelect}" />
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System.Windows;
2+
using System.Windows.Controls;
3+
using System.Windows.Input;
4+
using System.Windows.Interactivity;
5+
using GongSolutions.Wpf.DragDrop.Utilities;
6+
7+
namespace Rubberduck.UI.Controls
8+
{
9+
public class BindableListItemDrillThroughBehavior : Behavior<FrameworkElement>
10+
{
11+
protected override void OnAttached()
12+
{
13+
base.OnAttached();
14+
15+
var element = AssociatedObject;
16+
if (element == null)
17+
{
18+
return;
19+
}
20+
21+
AddHandler(element);
22+
}
23+
24+
private void AddHandler(IInputElement element)
25+
{
26+
element.PreviewMouseLeftButtonDown += OnClickStarting;
27+
}
28+
29+
private void RemoveHandler(IInputElement element)
30+
{
31+
element.PreviewMouseLeftButtonDown -= OnClickStarting;
32+
}
33+
34+
private void OnClickStarting(object sender, MouseButtonEventArgs e)
35+
{
36+
var element = AssociatedObject;
37+
var listItem = element?.GetVisualAncestor<ListViewItem>();
38+
39+
if (listItem == null)
40+
{
41+
return;
42+
}
43+
44+
listItem.IsSelected = true;
45+
}
46+
47+
protected override void OnDetaching()
48+
{
49+
var listView = AssociatedObject;
50+
if (listView != null)
51+
{
52+
RemoveHandler(listView);
53+
}
54+
55+
base.OnDetaching();
56+
}
57+
}
58+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System.Linq;
2+
using System.Windows;
3+
using System.Windows.Controls;
4+
using System.Windows.Interactivity;
5+
using GongSolutions.Wpf.DragDrop.Utilities;
6+
7+
namespace Rubberduck.UI.AddRemoveReferences
8+
{
9+
public class BindableListViewResizeBehavior : Behavior<ListView>
10+
{
11+
protected override void OnAttached()
12+
{
13+
base.OnAttached();
14+
15+
var listView = AssociatedObject;
16+
if (listView == null)
17+
{
18+
return;
19+
}
20+
21+
AddHandler(listView);
22+
}
23+
24+
private void AddHandler(FrameworkElement listView)
25+
{
26+
listView.SizeChanged += OnSizeChanged;
27+
}
28+
29+
private void RemoveHandler(FrameworkElement listView)
30+
{
31+
listView.SizeChanged -= OnSizeChanged;
32+
}
33+
34+
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
35+
{
36+
if (!e.WidthChanged)
37+
{
38+
return;
39+
}
40+
41+
var listView = AssociatedObject;
42+
43+
var textBlock = listView?.GetVisualDescendent<TextBlock>();
44+
// ListView uses a grid internally, so we need to overshoot and come back. WPWTF.
45+
var grid = textBlock?.GetVisualAncestor<Grid>();
46+
var target = grid?.ColumnDefinitions.FirstOrDefault(column => column.Width.IsStar);
47+
48+
if (target == null)
49+
{
50+
return;
51+
}
52+
53+
var scroll = listView.GetVisualDescendents<ScrollViewer>()
54+
.FirstOrDefault(element => element.ComputedVerticalScrollBarVisibility == Visibility.Visible);
55+
56+
var scrollWidth = scroll != null && scroll.IsVisible ? scroll.ActualWidth - scroll.ViewportWidth : 0;
57+
var calculated = listView.ActualWidth - grid.ColumnDefinitions
58+
.Where(column => !ReferenceEquals(target, column))
59+
.Sum(column => column.Width.Value) - scrollWidth;
60+
61+
target.Width = new GridLength(calculated);
62+
}
63+
64+
protected override void OnDetaching()
65+
{
66+
var listView = AssociatedObject;
67+
if (listView != null)
68+
{
69+
RemoveHandler(listView);
70+
}
71+
72+
base.OnDetaching();
73+
}
74+
}
75+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Windows.Media;
4+
using ImageSourceConverter = Rubberduck.UI.Converters.ImageSourceConverter;
5+
6+
namespace Rubberduck.UI.AddRemoveReferences
7+
{
8+
public class SearchImageSourceConverter : ImageSourceConverter
9+
{
10+
private readonly ImageSource _search = ToImageSource(Resources.RubberduckUI.magnifier_medium);
11+
private readonly ImageSource _clear = ToImageSource(Resources.RubberduckUI.cross_script);
12+
13+
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
14+
{
15+
return string.IsNullOrEmpty(value?.ToString()) ? _search : _clear;
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)