Skip to content

Commit

Permalink
Merge pull request #433 from Natestah/master
Browse files Browse the repository at this point in the history
Change Theme to a DropDown with flyout
  • Loading branch information
danipen authored Jul 8, 2024
2 parents f92e552 + 352da94 commit 318277d
Show file tree
Hide file tree
Showing 13 changed files with 229 additions and 34 deletions.
24 changes: 18 additions & 6 deletions src/AvaloniaEdit.Demo/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Platform;
using Avalonia.Markup.Xaml;
using System;
using System.ComponentModel;
using Avalonia.Styling;
using AvaloniaEdit.Demo.ViewModels;

namespace AvaloniaEdit.Demo
{
Expand All @@ -17,13 +19,12 @@ public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime)
{

var window = new MainWindow();

desktopLifetime.MainWindow = window;
//PlatformManager.CreateEmbeddableWindow().Crea


if (window.DataContext is MainWindowViewModel mainWindowViewModel)
{
mainWindowViewModel.PropertyChanged +=MainWindowViewModelOnPropertyChanged;
}
}
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewLifetime)
{
Expand All @@ -40,5 +41,16 @@ public override void OnFrameworkInitializationCompleted()

base.OnFrameworkInitializationCompleted();
}

private void MainWindowViewModelOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (sender is not MainWindowViewModel mainWindowViewModel) return;
if (e.PropertyName == nameof(MainWindowViewModel.SelectedTheme))
{
RequestedThemeVariant = mainWindowViewModel.SelectedTheme.ThemeName.ToString().ToLower().Contains("light")
? ThemeVariant.Light
: ThemeVariant.Dark;
}
}
}
}
1 change: 1 addition & 0 deletions src/AvaloniaEdit.Demo/AvaloniaEdit.Demo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<PackageReference Include="Avalonia" Version="$(AvaloniaSampleVersion)" />
<PackageReference Include="Avalonia.Desktop" Version="$(AvaloniaSampleVersion)" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="$(AvaloniaSampleVersion)"/>
<PackageReference Include="ReactiveUI" Version="20.1.1" />
<ProjectReference Include="..\AvaloniaEdit\AvaloniaEdit.csproj" />
<ProjectReference Include="..\AvaloniaEdit.TextMate\AvaloniaEdit.TextMate.csproj" />
</ItemGroup>
Expand Down
19 changes: 18 additions & 1 deletion src/AvaloniaEdit.Demo/CustomMargin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ namespace AvaloniaEdit.Demo
/// </summary>
internal sealed class CustomMargin : AbstractMargin
{
private readonly IBrush _backgroundBrush = new ImmutableSolidColorBrush(new Color(255, 51, 51, 51));
private readonly IBrush _defaultbackgroundBrush = Brushes.Transparent;
private IBrush _backgroundBrush = new ImmutableSolidColorBrush(new Color(255, 51, 51, 51));
private readonly IBrush _pointerOverBrush = new ImmutableSolidColorBrush(new Color(192, 80, 80, 80));
private readonly IPen _pointerOverPen = new ImmutablePen(new ImmutableSolidColorBrush(new Color(192, 37, 37, 37)), 1);
private readonly IBrush _markerBrush = new ImmutableSolidColorBrush(new Color(255, 195, 81, 92));
Expand All @@ -26,6 +27,22 @@ internal sealed class CustomMargin : AbstractMargin
private readonly List<int> _markedDocumentLines = [];
private int _pointerOverLine = -1;

public IBrush BackGroundBrush
{
get => _backgroundBrush;
set
{
_backgroundBrush = value;
InvalidateVisual();
}
}

public void SetDefaultBackgroundBrush()
{
_backgroundBrush = _defaultbackgroundBrush;
InvalidateVisual();
}

public CustomMargin()
{
Cursor = new Cursor(StandardCursorType.Arrow);
Expand Down
20 changes: 18 additions & 2 deletions src/AvaloniaEdit.Demo/MainWindow.xaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:AvalonEdit="using:AvaloniaEdit"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:AvaloniaEdit.Demo.ViewModels"
MinWidth="0"
MinHeight="300"
Width="1000"
Title="AvaloniaEdit Demo"
x:DataType="vm:MainWindowViewModel"
x:Class="AvaloniaEdit.Demo.MainWindow">
<DockPanel>
<StackPanel Orientation="Horizontal"
Expand All @@ -23,11 +25,25 @@
<Button Name="addControlBtn" Content="Add Button" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>
<Button Name="clearControlBtn" Content="Clear Buttons" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>
<ComboBox Name="syntaxModeCombo" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>
<Button Name="changeThemeBtn" Content="Change theme" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>

<DropDownButton Content="Change theme" VerticalAlignment="Stretch" VerticalContentAlignment="Center">
<Button.Flyout>
<Flyout>
<ListBox ItemsSource="{Binding AllThemes }" SelectedItem="{Binding SelectedTheme}">
<ListBox.DataTemplates>
<DataTemplate x:DataType="vm:ThemeViewModel">
<TextBlock Text="{Binding DisplayName}"/>
</DataTemplate>
</ListBox.DataTemplates>
</ListBox>
</Flyout>
</Button.Flyout>
</DropDownButton>

<Button Name="insertSnippetBtn" Content="Insert Snippet" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>
</StackPanel>
<StackPanel Name="StatusBar" Background="Purple" Height="25" DockPanel.Dock="Bottom" Orientation="Horizontal">
<TextBlock Foreground="White" Name="StatusText" Text="Ready" Margin="5 0 0 0" VerticalAlignment="Center" FontSize="12"/>
<TextBlock Name="StatusText" Text="Ready" Margin="5 0 0 0" VerticalAlignment="Center" FontSize="12"/>
</StackPanel>
<AvalonEdit:TextEditor Name="Editor"
FontFamily="Cascadia Code,Consolas,Menlo,Monospace"
Expand Down
118 changes: 104 additions & 14 deletions src/AvaloniaEdit.Demo/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
Expand All @@ -20,7 +21,7 @@
using Avalonia.Diagnostics;
using AvaloniaEdit.Snippets;
using Snippet = AvaloniaEdit.Snippets.Snippet;

using AvaloniaEdit.Demo.ViewModels;
namespace AvaloniaEdit.Demo
{
using Pair = KeyValuePair<int, Control>;
Expand All @@ -34,13 +35,13 @@ public class MainWindow : Window
private OverloadInsightWindow _insightWindow;
private Button _addControlButton;
private Button _clearControlButton;
private Button _changeThemeButton;
private Button _insertSnippetButton;
private ComboBox _syntaxModeCombo;
private TextBlock _statusTextBlock;
private ElementGenerator _generator = new ElementGenerator();
private RegistryOptions _registryOptions;
private int _currentTheme = (int)ThemeName.DarkPlus;
private CustomMargin _customMargin;

public MainWindow()
{
Expand Down Expand Up @@ -68,16 +69,14 @@ public MainWindow()
_textEditor.TextArea.IndentationStrategy = new Indentation.CSharp.CSharpIndentationStrategy(_textEditor.Options);
_textEditor.TextArea.Caret.PositionChanged += Caret_PositionChanged;
_textEditor.TextArea.RightClickMovesCaret = true;
_textEditor.Options.HighlightCurrentLine = true;

_addControlButton = this.FindControl<Button>("addControlBtn");
_addControlButton.Click += AddControlButton_Click;

_clearControlButton = this.FindControl<Button>("clearControlBtn");
_clearControlButton.Click += ClearControlButton_Click;

_changeThemeButton = this.FindControl<Button>("changeThemeBtn");
_changeThemeButton.Click += ChangeThemeButton_Click;

_insertSnippetButton = this.FindControl<Button>("insertSnippetBtn");
_insertSnippetButton.Click += InsertSnippetButton_Click;

Expand All @@ -87,6 +86,8 @@ public MainWindow()
(ThemeName)_currentTheme);

_textMateInstallation = _textEditor.InstallTextMate(_registryOptions);

_textMateInstallation.AppliedTheme += TextMateInstallationOnAppliedTheme;

Language csharpLanguage = _registryOptions.GetLanguageByExtension(".cs");

Expand Down Expand Up @@ -114,7 +115,104 @@ public MainWindow()
}, RoutingStrategies.Bubble, true);

// Add a custom margin at the left of the text area, which can be clicked.
_textEditor.TextArea.LeftMargins.Insert(0, new CustomMargin());
_customMargin = new CustomMargin();
_textEditor.TextArea.LeftMargins.Insert(0, _customMargin);

var mainWindowVM = new MainWindowViewModel(_textMateInstallation, _registryOptions);
foreach (ThemeName themeName in Enum.GetValues<ThemeName>())
{
var themeViewModel = new ThemeViewModel(themeName);
mainWindowVM.AllThemes.Add(themeViewModel);
if (themeName == ThemeName.DarkPlus)
{
mainWindowVM.SelectedTheme = themeViewModel;
}
}
DataContext = mainWindowVM;


}

private void TextMateInstallationOnAppliedTheme(object sender, TextMate.TextMate.Installation e)
{
ApplyThemeColorsToEditor(e);
ApplyThemeColorsToWindow(e);
}

void ApplyThemeColorsToEditor(TextMate.TextMate.Installation e)
{
ApplyBrushAction(e, "editor.background",brush => _textEditor.Background = brush);
ApplyBrushAction(e, "editor.foreground",brush => _textEditor.Foreground = brush);

if (!ApplyBrushAction(e, "editor.selectionBackground",
brush => _textEditor.TextArea.SelectionBrush = brush))
{
if (Application.Current!.TryGetResource("TextAreaSelectionBrush", out var resourceObject))
{
if (resourceObject is IBrush brush)
{
_textEditor.TextArea.SelectionBrush = brush;
}
}
}

if (!ApplyBrushAction(e, "editor.lineHighlightBackground",
brush =>
{
_textEditor.TextArea.TextView.CurrentLineBackground = brush;
_textEditor.TextArea.TextView.CurrentLineBorder = new Pen(brush); // Todo: VS Code didn't seem to have a border but it might be nice to have that option. For now just make it the same..
}))
{
_textEditor.TextArea.TextView.SetDefaultHighlightLineColors();
}

//Todo: looks like the margin doesn't have a active line highlight, would be a nice addition
if (!ApplyBrushAction(e, "editorLineNumber.foreground",
brush => _textEditor.LineNumbersForeground = brush))
{
_textEditor.LineNumbersForeground = _textEditor.Foreground;
}
}

private void ApplyThemeColorsToWindow(TextMate.TextMate.Installation e)
{
var panel = this.Find<StackPanel>("StatusBar");
if (panel == null)
{
return;
}

if (!ApplyBrushAction(e, "statusBar.background", brush => panel.Background = brush))
{
panel.Background = Brushes.Purple;
}

if (!ApplyBrushAction(e, "statusBar.foreground", brush => _statusTextBlock.Foreground = brush))
{
_statusTextBlock.Foreground = Brushes.White;
}

if (!ApplyBrushAction(e, "sideBar.background", brush => _customMargin.BackGroundBrush = brush))
{
_customMargin.SetDefaultBackgroundBrush();
}

//Applying the Editor background to the whole window for demo sake.
ApplyBrushAction(e, "editor.background",brush => Background = brush);
ApplyBrushAction(e, "editor.foreground",brush => Foreground = brush);
}

bool ApplyBrushAction(TextMate.TextMate.Installation e, string colorKeyNameFromJson, Action<IBrush> applyColorAction)
{
if (!e.TryGetThemeColor(colorKeyNameFromJson, out var colorString))
return false;

if (!Color.TryParse(colorString, out Color color))
return false;

var colorBrush = new SolidColorBrush(color);
applyColorAction(colorBrush);
return true;
}

private void Caret_PositionChanged(object sender, EventArgs e)
Expand Down Expand Up @@ -170,14 +268,6 @@ private void RemoveUnderlineAndStrikethroughTransformer()
}
}

private void ChangeThemeButton_Click(object sender, RoutedEventArgs e)
{
_currentTheme = (_currentTheme + 1) % Enum.GetNames(typeof(ThemeName)).Length;

_textMateInstallation.SetTheme(_registryOptions.LoadTheme(
(ThemeName)_currentTheme));
}

private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
Expand Down
21 changes: 21 additions & 0 deletions src/AvaloniaEdit.Demo/ViewModels/MainWIndowViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Collections.ObjectModel;
using ReactiveUI;
using TextMateSharp.Grammars;

namespace AvaloniaEdit.Demo.ViewModels;

public class MainWindowViewModel(TextMate.TextMate.Installation _textMateInstallation, RegistryOptions _registryOptions) : ReactiveObject
{
public ObservableCollection<ThemeViewModel> AllThemes { get; set; } = [];
private ThemeViewModel _selectedTheme;

public ThemeViewModel SelectedTheme
{
get => _selectedTheme;
set
{
this.RaiseAndSetIfChanged(ref _selectedTheme, value);
_textMateInstallation.SetTheme(_registryOptions.LoadTheme(value.ThemeName));
}
}
}
16 changes: 16 additions & 0 deletions src/AvaloniaEdit.Demo/ViewModels/ThemeViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using TextMateSharp.Grammars;

namespace AvaloniaEdit.Demo.ViewModels;

public class ThemeViewModel
{
private ThemeName _themeName;

public ThemeName ThemeName => _themeName;

public string DisplayName => _themeName.ToString();
public ThemeViewModel(ThemeName themeName)
{
_themeName = themeName;
}
}
4 changes: 2 additions & 2 deletions src/AvaloniaEdit.TextMate/AvaloniaEdit.TextMate.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

<ItemGroup>
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)" />
<PackageReference Include="TextMateSharp" Version="$(TextMateSharpVersion)" />
<PackageReference Include="TextMateSharp.Grammars" Version="$(TextMateSharpVersion)" />
<PackageReference Include="TextMateSharp" Version="1.0.58" />
<PackageReference Include="TextMateSharp.Grammars" Version="1.0.58" />
</ItemGroup>

</Project>
Loading

0 comments on commit 318277d

Please sign in to comment.