code folding

This commit is contained in:
iAmAsval 2021-06-24 16:04:17 +02:00
parent e32136d5b2
commit 37503ec012
5 changed files with 153 additions and 4 deletions

@ -1 +1 @@
Subproject commit 682f45f762d049814a39e8fdfd8d1ee6bf1b1973
Subproject commit 62a11913e10409e540b34e0286a734f98d6af3c7

View File

@ -240,7 +240,7 @@ namespace FModel
private void OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (sender is not ListBox listBox) return;
if (!_applicationView.IsReady || sender is not ListBox listBox) return;
UserSettings.Default.LoadingMode = ELoadingMode.Multiple;
_applicationView.LoadingModes.LoadCommand.Execute(listBox.SelectedItems);
}

View File

@ -0,0 +1,139 @@
using System.Collections.Generic;
using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Folding;
namespace FModel.Views.Resources.Controls
{
/// <summary>
/// https://github.com/JTranOrg/JTranEdit/blob/master/JTranEdit/Classes/BraceFoldingStrategy.cs
/// </summary>
public interface IFoldingStrategy
{
IEnumerable<NewFolding> UpdateFoldings(TextDocument document);
void CollapseAll();
void ExpandAll();
}
public class JsonFoldingStrategies : IFoldingStrategy
{
private readonly List<IFoldingStrategy> _strategies = new();
private readonly FoldingManager _foldingManager;
private readonly IComparer<NewFolding> _comparer = new FoldingComparer();
public JsonFoldingStrategies(TextEditor avalonEditor)
{
_foldingManager = FoldingManager.Install(avalonEditor.TextArea);
_strategies.Add(new BraceFoldingStrategy(avalonEditor, '{', '}'));
_strategies.Add(new BraceFoldingStrategy(avalonEditor, '[', ']'));
}
public IEnumerable<NewFolding> UpdateFoldings(TextDocument document)
{
var foldings = new List<NewFolding>();
foreach (var strategy in _strategies)
{
foldings.AddRange(strategy.UpdateFoldings(document));
}
foldings.Sort(_comparer);
_foldingManager.UpdateFoldings(foldings, -1);
return foldings;
}
public void CollapseAll()
{
if (_foldingManager.AllFoldings == null)
return;
foreach (var folding in _foldingManager.AllFoldings)
{
folding.IsFolded = true;
}
// Unfold the first fold (if any) to give a useful overview on content
var foldSection = _foldingManager.GetNextFolding(0);
if (foldSection != null)
foldSection.IsFolded = false;
}
public void ExpandAll()
{
if (_foldingManager.AllFoldings == null)
return;
foreach (var folding in _foldingManager.AllFoldings)
{
folding.IsFolded = false;
}
}
private class FoldingComparer : IComparer<NewFolding>
{
public int Compare(NewFolding x, NewFolding y)
{
return x.StartOffset.CompareTo(y.StartOffset);
}
}
}
public class BraceFoldingStrategy : IFoldingStrategy
{
private readonly char _opening;
private readonly char _closing;
public BraceFoldingStrategy(TextEditor editor, char o, char c)
{
_opening = o;
_closing = c;
UpdateFoldings(editor.Document);
}
public IEnumerable<NewFolding> UpdateFoldings(TextDocument document)
{
return CreateNewFoldings(document);
}
public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
{
var newFoldings = new List<NewFolding>();
var startOffsets = new Stack<int>();
var lastNewLineOffset = 0;
for (var i = 0; i < document.TextLength; i++)
{
var c = document.GetCharAt(i);
if (c == _opening)
{
startOffsets.Push(i);
}
else if (c == _closing && startOffsets.Count > 0)
{
var startOffset = startOffsets.Pop();
if (startOffset < lastNewLineOffset)
{
newFoldings.Add(new NewFolding(startOffset, i + 1));
}
}
else if (c is '\n' or '\r')
{
lastNewLineOffset = i + 1;
}
}
newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
return newFoldings;
}
public void CollapseAll()
{
throw new System.NotImplementedException();
}
public void ExpandAll()
{
throw new System.NotImplementedException();
}
}
}

View File

@ -20,15 +20,15 @@ namespace FModel.Views.Resources.Controls
private readonly Regex _hexColorRegex = new("\"Hex\": \"(?'target'[0-9A-Fa-f]{3,8})\"$",
RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
private readonly System.Windows.Controls.ToolTip _toolTip = new();
private JsonFoldingStrategies _manager;
public AvalonEditor()
{
CommandBindings.Add(new CommandBinding(NavigationCommands.Search, (_, e) => FindNext(e.Parameter != null)));
InitializeComponent();
YesWeEditor = MyAvalonEditor;
YesWeSearch = WpfSuckMyDick;
MyAvalonEditor.TextArea.TextView.ElementGenerators.Add(new GamePathElementGenerator());
MyAvalonEditor.TextArea.TextView.ElementGenerators.Add(new HexColorElementGenerator());
}
@ -83,6 +83,8 @@ namespace FModel.Views.Resources.Controls
avalonEditor.Document == null || string.IsNullOrEmpty(avalonEditor.Document.Text))
return;
_manager ??= new JsonFoldingStrategies(avalonEditor);
_manager.UpdateFoldings(tabItem.Document);
avalonEditor.Document.FileName = tabItem.Directory + '/' + tabItem.Header.SubstringBeforeLast('.');
if (!tabItem.ShouldScroll) return;

View File

@ -7,6 +7,7 @@
xmlns:audioControls="clr-namespace:FModel.Views.Resources.Controls.Aup"
xmlns:converters="clr-namespace:FModel.Views.Resources.Converters"
xmlns:avalonedit="http://icsharpcode.net/sharpdevelop/avalonedit"
xmlns:folding="clr-namespace:ICSharpCode.AvalonEdit.Folding;assembly=ICSharpCode.AvalonEdit"
xmlns:adonisUi="clr-namespace:AdonisUI;assembly=AdonisUI"
xmlns:adonisConverters="clr-namespace:AdonisUI.Converters;assembly=AdonisUI"
xmlns:adonisExtensions="clr-namespace:AdonisUI.Extensions;assembly=AdonisUI"
@ -1635,4 +1636,11 @@
</Setter>
</Style>
<Style TargetType="{x:Type folding:FoldingMargin}">
<Setter Property="FoldingMarkerBrush" Value="#262630" />
<Setter Property="FoldingMarkerBackgroundBrush" Value="#262630" />
<Setter Property="SelectedFoldingMarkerBrush" Value="#808080" />
<Setter Property="SelectedFoldingMarkerBackgroundBrush" Value="#2A2B34" />
</Style>
</ResourceDictionary>