Skip to content

Commit

Permalink
Avalonia partially working
Browse files Browse the repository at this point in the history
  • Loading branch information
aelij committed Mar 25, 2018
1 parent 67e34dd commit 7f63cb2
Show file tree
Hide file tree
Showing 21 changed files with 426 additions and 43 deletions.
4 changes: 3 additions & 1 deletion src/RoslynPad.Common.UI/Dialogs/IDialog.cs
@@ -1,8 +1,10 @@
using System.Threading.Tasks;

namespace RoslynPad.UI
{
public interface IDialog
{
void Show();
Task ShowAsync();
void Close();
}
}
4 changes: 1 addition & 3 deletions src/RoslynPad.Common.UI/Dialogs/IOpenFileDialog.cs
Expand Up @@ -16,9 +16,7 @@ public interface IOpenFileDialog

string FileName { get; set; }

IList<string> FileNames { get; }

Task<bool> ShowAsync();
Task<string[]> ShowAsync();
}

public class FileDialogFilter
Expand Down
8 changes: 5 additions & 3 deletions src/RoslynPad.Common.UI/Dialogs/ISaveFileDialog.cs
@@ -1,13 +1,15 @@
namespace RoslynPad.UI
using System.Threading.Tasks;

namespace RoslynPad.UI
{
public interface ISaveFileDialog
{
bool OverwritePrompt { get; set; }
bool AddExtension { get; set; }
string Filter { get; set; }
FileDialogFilter Filter { set; }
string DefaultExt { get; set; }
string FileName { get; set; }

bool? Show();
Task<string> ShowAsync();
}
}
8 changes: 6 additions & 2 deletions src/RoslynPad.Common.UI/ViewModels/MainViewModelBase.cs
Expand Up @@ -80,6 +80,7 @@ public MainViewModelBase(IServiceProvider serviceProvider, ITelemetryProvider te
NewDocumentCommand = commands.Create(CreateNewDocument);
OpenFileCommand = commands.CreateAsync(OpenFile);
CloseCurrentDocumentCommand = commands.CreateAsync(CloseCurrentDocument);
CloseDocumentCommand = commands.CreateAsync<OpenDocumentViewModel>(CloseDocument);
ClearErrorCommand = commands.Create(() => _telemetryProvider.ClearLastError());
ReportProblemCommand = commands.Create(ReportProblem);
EditUserDocumentPathCommand = commands.Create(EditUserDocumentPath);
Expand Down Expand Up @@ -316,6 +317,8 @@ private void ClearCurrentOpenDocument()

public IDelegateCommand CloseCurrentDocumentCommand { get; }

public IDelegateCommand<OpenDocumentViewModel> CloseDocumentCommand { get; }

public IDelegateCommand ToggleOptimizationCommand { get; }

public void OpenDocument(DocumentViewModel document)
Expand All @@ -337,13 +340,14 @@ public async Task OpenFile()

var dialog = _serviceProvider.GetService<IOpenFileDialog>();
dialog.Filter = new FileDialogFilter("C# Scripts", "csx");
if (!await dialog.ShowAsync().ConfigureAwait(true))
var fileNames = await dialog.ShowAsync().ConfigureAwait(true);
if (fileNames == null)
{
return;
}

// make sure we use the normalized path, in case the user used the wrong capitalization on Windows
var filePath = IOUtilities.NormalizeFilePath(dialog.FileName);
var filePath = IOUtilities.NormalizeFilePath(fileNames.First());
var document = DocumentViewModel.FromPath(filePath);
if (!document.IsAutoSave)
{
Expand Down
13 changes: 7 additions & 6 deletions src/RoslynPad.Common.UI/ViewModels/OpenDocumentViewModel.cs
Expand Up @@ -184,7 +184,7 @@ private async Task RenameSymbol()

var dialog = _serviceProvider.GetService<IRenameSymbolDialog>();
dialog.Initialize(symbol.Name);
dialog.Show();
await dialog.ShowAsync();
if (dialog.ShouldRename)
{
var newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, symbol, dialog.SymbolName, null).ConfigureAwait(true);
Expand Down Expand Up @@ -329,7 +329,7 @@ public async Task<SaveResult> Save(bool promptSave)
dialog.ShowDontSave = promptSave;
dialog.AllowNameEdit = true;
dialog.FilePathFactory = s => DocumentViewModel.GetDocumentPathFromName(WorkingDirectory, s);
dialog.Show();
await dialog.ShowAsync();
result = dialog.Result;
if (result == SaveResult.Save)
{
Expand All @@ -343,7 +343,7 @@ public async Task<SaveResult> Save(bool promptSave)
var dialog = _serviceProvider.GetService<ISaveDocumentDialog>();
dialog.ShowDontSave = true;
dialog.DocumentName = Document.Name;
dialog.Show();
await dialog.ShowAsync();
result = dialog.Result;
}

Expand Down Expand Up @@ -437,9 +437,10 @@ private async Task CompileAndSave()
var saveDialog = _serviceProvider.GetService<ISaveFileDialog>();
saveDialog.OverwritePrompt = true;
saveDialog.AddExtension = true;
saveDialog.Filter = "Libraries|*.dll|Executables|*.exe";
saveDialog.Filter = new FileDialogFilter("Libraries", "*.dll", "*.exe");
saveDialog.DefaultExt = "dll";
if (saveDialog.Show() != true) return;
var fileName = await saveDialog.ShowAsync().ConfigureAwait(true);
if (fileName == null) return;

var code = await GetCode(CancellationToken.None).ConfigureAwait(true);

Expand All @@ -450,7 +451,7 @@ private async Task CompileAndSave()

try
{
await Task.Run(() => _executionHost.CompileAndSave(code, saveDialog.FileName, OptimizationLevel)).ConfigureAwait(true);
await Task.Run(() => _executionHost.CompileAndSave(code, fileName, OptimizationLevel)).ConfigureAwait(true);
}
catch (CompilationErrorException ex)
{
Expand Down
11 changes: 9 additions & 2 deletions src/RoslynPad.Hosting/RpcClient.cs
Expand Up @@ -43,8 +43,15 @@ public async Task Connect(TimeSpan timeout)

public virtual void Dispose()
{
_stream?.Dispose();
_rpc?.Dispose();
try
{
_stream?.Dispose();
_rpc?.Dispose();
}
catch
{
// this shouldn't throw but it does in netcore
}
}
}
}
53 changes: 52 additions & 1 deletion src/RoslynPad.NetCore/App.xaml
@@ -1,15 +1,66 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cc="clr-namespace:AvaloniaEdit.CodeCompletion;assembly=AvaloniaEdit"
xmlns:local="clr-namespace:RoslynPad;assembly=RoslynPad.NetCore"
xmlns:formatting="clr-namespace:RoslynPad.Formatting;assembly=RoslynPad.NetCore"
xmlns:codeAnalysis="clr-namespace:Microsoft.CodeAnalysis;assembly=Microsoft.CodeAnalysis"
xmlns:codeActions="clr-namespace:Microsoft.CodeAnalysis.CodeActions;assembly=Microsoft.CodeAnalysis.Workspaces"
xmlns:codeFixes="clr-namespace:RoslynPad.Roslyn.CodeFixes;assembly=RoslynPad.Roslyn">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="resm:RoslynPad.Resources.Icons.xaml?assembly=RoslynPad.NetCore" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
<Application.Styles>
<StyleInclude Source="resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default" />
<StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default" />
<StyleInclude Source="resm:AvaloniaEdit.AvaloniaEdit.xaml?assembly=AvaloniaEdit" />

<Style Selector="Expander:left">
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}">
<DockPanel>
<ToggleButton Name="PART_toggle"
DockPanel.Dock="Right"
Content="{TemplateBinding Header}"
IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}">
<ToggleButton.RenderTransform>
<RotateTransform Angle="270" />
</ToggleButton.RenderTransform>
</ToggleButton>
<ContentPresenter Name="PART_ContentPresenter"
IsVisible="{TemplateBinding IsExpanded}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
</DockPanel>
</Border>
</ControlTemplate>
</Setter>
</Style>

<Style Selector="Expander /template/ ToggleButton#PART_toggle">
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter Name="PART_ContentPresenter"
Background="Transparent"
Content="{TemplateBinding Content}"
VerticalAlignment="Center" />
</ControlTemplate>
</Setter>
</Style>

<Style Selector="Expander:left:expanded /template/ ToggleButton#PART_toggle">
<Setter Property="RenderTransform"
Value="{x:Null}" />
<Setter Property="DockPanel.Dock"
Value="Top" />
</Style>

<Style Selector="TabControl">
<Setter Property="Template">
<ControlTemplate>
Expand All @@ -18,7 +69,7 @@
BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel>
<TabStrip Name="PART_TabStrip"
MemberSelector="{TemplateBinding MemberSelector}"
ItemTemplate="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=(Templates.HeaderTemplate)}"
Items="{TemplateBinding Items}"
SelectedIndex="{TemplateBinding Path=SelectedIndex, Mode=TwoWay}" />
<Carousel Name="PART_Content"
Expand Down
3 changes: 2 additions & 1 deletion src/RoslynPad.NetCore/DocumentTreeView.xaml
@@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui">
<TreeView Items="{Binding DocumentRoot.Children}">
<TreeView Items="{Binding DocumentRoot.Children}"
Name="Tree">
<TreeView.ItemTemplate>
<TreeDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}" />
Expand Down
63 changes: 62 additions & 1 deletion src/RoslynPad.NetCore/DocumentTreeView.xaml.cs
@@ -1,13 +1,74 @@
using Avalonia.Controls;
using System;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
using RoslynPad.UI;

namespace RoslynPad
{
class DocumentTreeView : UserControl
{
private MainViewModel _viewModel;

public DocumentTreeView()
{
AvaloniaXamlLoader.Load(this);
var treeView = this.Find<TreeView>("Tree");
treeView.ItemContainerGenerator.Materialized += ItemContainerGenerator_Materialized;
treeView.ItemContainerGenerator.Dematerialized += ItemContainerGenerator_Dematerialized;
}

private void ItemContainerGenerator_Materialized(object sender, Avalonia.Controls.Generators.ItemContainerEventArgs e)
{
foreach (var item in e.Containers)
{
if (item.ContainerControl is TreeViewItem treeViewItem)
{
treeViewItem.PointerPressed += OnDocumentClick;
treeViewItem.KeyDown += OnDocumentKeyDown;
}
}
}

private void ItemContainerGenerator_Dematerialized(object sender, Avalonia.Controls.Generators.ItemContainerEventArgs e)
{
foreach (var item in e.Containers)
{
if (item.ContainerControl is TreeViewItem treeViewItem)
{
treeViewItem.PointerPressed -= OnDocumentClick;
treeViewItem.KeyDown -= OnDocumentKeyDown;
}
}
}

protected override void OnDataContextChanged(EventArgs e)
{
_viewModel = DataContext as MainViewModel;
}


private void OnDocumentClick(object sender, PointerPressedEventArgs e)
{
if (e.MouseButton == MouseButton.Left && e.ClickCount >= 2)
{
OpenDocument(e.Source);
}
}

private void OnDocumentKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
OpenDocument(e.Source);
}
}

private void OpenDocument(object source)
{
var documentViewModel = (DocumentViewModel)((Control)source).DataContext;
_viewModel.OpenDocument(documentViewModel);
}
}
}
30 changes: 28 additions & 2 deletions src/RoslynPad.NetCore/DocumentView.xaml
@@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:RoslynPad;assembly=RoslynPad.NetCore"
xmlns:Editor="clr-namespace:RoslynPad.Editor;assembly=RoslynPad.Editor.Avalonia"
xmlns:ui="clr-namespace:RoslynPad.UI;assembly=RoslynPad.Common.UI">
<UserControl.KeyBindings>
Expand All @@ -20,8 +21,33 @@
</UserControl.KeyBindings>
<Grid RowDefinitions="Auto,*,5,*">
<StackPanel Grid.Row="0"
Background="White"
Orientation="Horizontal">
<StackPanel.Styles>
<Style Selector="Button">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="Padding"
Value="0" />
<Setter Property="Margin"
Value="0 0 3 0" />
<Setter Property="Width"
Value="18" />
<Setter Property="Height"
Value="18" />
</Style>
<Style Selector="Button:pointerover /template/ ContentPresenter">
<Setter Property="Background"
Value="#eeeeee" />
</Style>
<Style Selector="Button DrawingPresenter">
<Setter Property="Width"
Value="16" />
<Setter Property="Height"
Value="16" />
</Style>
</StackPanel.Styles>
<Button Command="{Binding RunCommand, Mode=OneTime}"
ToolTip.Tip="Run (F5)">
<Grid>
Expand Down Expand Up @@ -135,7 +161,7 @@
ToolTip.Tip="Rename Symbol (F2)"
Command="{Binding RenameSymbolCommand, Mode=OneTime}" />
</StackPanel>

<Editor:RoslynCodeEditor Name="Editor"
ContextActionsIcon="{DynamicResource Bulb}"
Grid.Row="1" />
Expand Down
5 changes: 5 additions & 0 deletions src/RoslynPad.NetCore/DocumentView.xaml.cs
Expand Up @@ -37,6 +37,11 @@ public DocumentView()
DataContextChanged += OnDataContextChanged;
}

private object Get(string s)
{
return App.Current.FindResource(s);
}

private async void OnDataContextChanged(object sender, EventArgs args)
{
_viewModel = DataContext as OpenDocumentViewModel;
Expand Down

0 comments on commit 7f63cb2

Please sign in to comment.