Skip to content

Commit

Permalink
UWP visualizer app improvements (#565)
Browse files Browse the repository at this point in the history
* UWP visualizer app improvements

Tabbed UI, error reporting and warnings, instant preview as you type, remembers the files you had open, automatically launches with the samples files open, can save changes on a file

Had to set project min version to 14393 as build server complained about NuGet issues when using 10586.
  • Loading branch information
Andrew Bares authored Sep 11, 2017
1 parent e60b142 commit a6eb721
Show file tree
Hide file tree
Showing 17 changed files with 1,364 additions and 164 deletions.
13 changes: 12 additions & 1 deletion source/uwp/Visualizer/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlCardVisualizer"
RequestedTheme="Light">
RequestedTheme="Light"
xmlns:converters="using:XamlCardVisualizer.Converters">

<Application.Resources>
<converters:NotNullToVisibilityConverter x:Key="NotNullToVisibilityConverter"/>

<Style x:Key="HorizontalListViewItemContainerStyle" TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="0"/>
</Style>

</Application.Resources>

</Application>
100 changes: 100 additions & 0 deletions source/uwp/Visualizer/Converters/ErrorViewModelConverters.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
using XamlCardVisualizer.ViewModel;

namespace XamlCardVisualizer.Converters
{
public class ErrorViewModelTypeToIconBackgroundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is ErrorViewModelType)
{
switch ((ErrorViewModelType)value)
{
case ErrorViewModelType.Error:
case ErrorViewModelType.ErrorButRenderAllowed:
return new SolidColorBrush(Colors.Red);

case ErrorViewModelType.Warning:
return new SolidColorBrush(Colors.Orange);

default:
throw new NotImplementedException();
}
}

return value;
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}

public sealed class ErrorViewModelTypeToIconForegroundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is ErrorViewModelType)
{
switch ((ErrorViewModelType)value)
{
case ErrorViewModelType.Error:
case ErrorViewModelType.ErrorButRenderAllowed:
return new SolidColorBrush(Colors.White);

case ErrorViewModelType.Warning:
return new SolidColorBrush(Colors.Black);

default:
throw new NotImplementedException();
}
}

return value;
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}

public sealed class ErrorViewModelTypeToSymbolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is ErrorViewModelType)
{
switch ((ErrorViewModelType)value)
{
case ErrorViewModelType.Error:
case ErrorViewModelType.ErrorButRenderAllowed:
return Symbol.Cancel;

case ErrorViewModelType.Warning:
return Symbol.Important;

default:
throw new NotImplementedException();
}
}

return value;
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}
23 changes: 23 additions & 0 deletions source/uwp/Visualizer/Converters/NotNullToVisibilityConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;

namespace XamlCardVisualizer.Converters
{
public class NotNullToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return value != null ? Visibility.Visible : Visibility.Collapsed;
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}
118 changes: 118 additions & 0 deletions source/uwp/Visualizer/DocumentView.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<UserControl
x:Class="XamlCardVisualizer.DocumentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlCardVisualizer"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
xmlns:toolkitControls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:converters="using:XamlCardVisualizer.Converters">

<UserControl.Resources>

<converters:ErrorViewModelTypeToIconBackgroundConverter x:Key="ErrorViewModelTypeToIconBackgroundConverter"/>
<converters:ErrorViewModelTypeToIconForegroundConverter x:Key="ErrorViewModelTypeToIconForegroundConverter"/>
<converters:ErrorViewModelTypeToSymbolConverter x:Key="ErrorViewModelTypeToSymbolConverter"/>

</UserControl.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="350"/>
</Grid.ColumnDefinitions>

<!--Editor and errors-->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<TextBox
Text="{Binding Payload, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
AcceptsReturn="True"
VerticalAlignment="Stretch"
TextWrapping="Wrap"
FontSize="14"
FontFamily="Consolas"
BorderThickness="0"
Margin="0,0,12,0"
IsSpellCheckEnabled="False"/>
</ScrollViewer>

<!--Error info-->
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" MaxHeight="200">
<ItemsControl ItemsSource="{Binding Errors}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Padding="12" Background="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>

<Grid Margin="0,0,12,0" VerticalAlignment="Top">
<Ellipse
Fill="{Binding Type, Converter={StaticResource ErrorViewModelTypeToIconBackgroundConverter}}"
Width="30"
Height="30"/>
<SymbolIcon
Symbol="{Binding Type, Converter={StaticResource ErrorViewModelTypeToSymbolConverter}}"
Foreground="{Binding Type, Converter={StaticResource ErrorViewModelTypeToIconForegroundConverter}}"/>
</Grid>

<TextBlock
Text="{Binding Message}"
TextWrapping="Wrap"
Grid.Column="1"
IsTextSelectionEnabled="True"/>

<StackPanel
Grid.Column="2" Margin="3,0,0,0">

<TextBlock
Text="Line"
Style="{StaticResource CaptionTextBlockStyle}"
TextAlignment="Right"
HorizontalAlignment="Right"/>

<TextBlock
Text="{Binding Position.LineNumber}"
TextAlignment="Right"
HorizontalAlignment="Right"
Style="{StaticResource CaptionTextBlockStyle}"/>

</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>

<!--Preview-->
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto" Margin="11,0,0,0" Background="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}">
<Border
x:Name="AdaptiveCardHostContainer"
Child="{Binding RenderedCard}"
Padding="12"/>
</ScrollViewer>

<!--Vertical draggable column splitter-->
<toolkitControls:GridSplitter
Width="11"
Background="{ThemeResource SystemControlBackgroundAccentBrush}"
GripperCursor="Default"
HorizontalAlignment="Left"
Grid.Column="1"
ResizeDirection="Auto"
ResizeBehavior="BasedOnAlignment"
CursorBehavior="ChangeOnSplitterHover"
GripperForeground="White"/>
</Grid>
</UserControl>
35 changes: 35 additions & 0 deletions source/uwp/Visualizer/DocumentView.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using XamlCardVisualizer.Helpers;
using XamlCardVisualizer.ViewModel;

// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236

namespace XamlCardVisualizer
{
public sealed partial class DocumentView : UserControl
{
public DocumentViewModel ViewModel
{
get { return DataContext as DocumentViewModel; }
}

public DocumentView()
{
this.InitializeComponent();
}
}
}
31 changes: 31 additions & 0 deletions source/uwp/Visualizer/Helpers/BindableBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace XamlCardVisualizer.Helpers
{
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

protected void SetProperty<T>(ref T property, T value, [CallerMemberName]string propertyName = null)
{
if (object.Equals(property, value))
{
return;
}

property = value;
NotifyPropertyChanged(propertyName);
}

protected void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
46 changes: 46 additions & 0 deletions source/uwp/Visualizer/Helpers/IListExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XamlCardVisualizer.Helpers
{
public static class IListExtensions
{
public static bool MakeListLike<T>(this IList<T> list, IList<T> desired)
{
// If already equal, do nothing
if (desired.SequenceEqual(list))
return false;

// Remove any of the items that aren't there anymore
for (int i = 0; i < list.Count; i++)
if (!desired.Contains(list[i]))
{
list.RemoveAt(i);
i--;
}

for (int i = 0; i < desired.Count; i++)
{
if (i >= list.Count)
list.Add(desired[i]);

// There's a wrong item in its place
else if (!object.Equals(list[i], desired[i]))
{
// If it's already in the list somewhere, we remove it
list.Remove(desired[i]);

// No matter what we insert it into its desired spot
list.Insert(i, desired[i]);
}

// Otherwise it's already in the right place!
}

return true;
}
}
}
Loading

0 comments on commit a6eb721

Please sign in to comment.