added tab extra title

This commit is contained in:
Asval
2025-02-09 00:40:11 +01:00
parent dbf618e417
commit 93fa0b2bb6
8 changed files with 75 additions and 60 deletions

View File

@@ -6,14 +6,14 @@ using ICSharpCode.AvalonEdit.Document;
namespace FModel.Extensions; namespace FModel.Extensions;
public static class StringExtensions public static partial class StringExtensions
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string GetReadableSize(double size) public static string GetReadableSize(double size)
{ {
if (size == 0) return "0 B"; if (size == 0) return "0 B";
string[] sizes = { "B", "KB", "MB", "GB", "TB" }; string[] sizes = ["B", "KB", "MB", "GB", "TB"];
var order = 0; var order = 0;
while (size >= 1024 && order < sizes.Length - 1) while (size >= 1024 && order < sizes.Length - 1)
{ {
@@ -27,21 +27,22 @@ public static class StringExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetNameLineNumber(this string s, string lineToFind) public static int GetNameLineNumber(this string s, string lineToFind)
{ {
if (KismetRegex().IsMatch(lineToFind))
return s.GetKismetLineNumber(lineToFind);
if (int.TryParse(lineToFind, out var index)) if (int.TryParse(lineToFind, out var index))
return s.GetLineNumber(index); return s.GetLineNumber(index);
lineToFind = $" \"Name\": \"{lineToFind}\","; lineToFind = $" \"Name\": \"{lineToFind}\",";
using var reader = new StringReader(s); using var reader = new StringReader(s);
var lineNum = 0; var lineNum = 0;
string line; while (reader.ReadLine() is { } line)
while ((line = reader.ReadLine()) != null)
{ {
lineNum++; lineNum++;
if (line.Equals(lineToFind, StringComparison.OrdinalIgnoreCase)) if (line.Equals(lineToFind, StringComparison.OrdinalIgnoreCase))
return lineNum; return lineNum;
} }
return 1; return -1;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -64,18 +65,17 @@ public static class StringExtensions
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetKismetLineNumber(this string s, string input) private static int GetKismetLineNumber(this string s, string input)
{ {
var match = Regex.Match(input, @"^(.+)\[(\d+)\]$"); var match = KismetRegex().Match(input);
var name = match.Groups[1].Value; var name = match.Groups[1].Value;
int index = int.Parse(match.Groups[2].Value); int index = int.Parse(match.Groups[2].Value);
var lineToFind = $" \"Name\": \"{name}\","; var lineToFind = $" \"Name\": \"{name}\",";
var offset = $"\"StatementIndex\": {index}"; var offset = $"\"StatementIndex\": {index}";
using var reader = new StringReader(s); using var reader = new StringReader(s);
var lineNum = 0; var lineNum = 0;
string line;
while ((line = reader.ReadLine()) != null) while (reader.ReadLine() is { } line)
{ {
lineNum++; lineNum++;
if (line.Equals(lineToFind, StringComparison.OrdinalIgnoreCase)) if (line.Equals(lineToFind, StringComparison.OrdinalIgnoreCase))
@@ -91,7 +91,7 @@ public static class StringExtensions
} }
} }
return 1; return -1;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -99,8 +99,7 @@ public static class StringExtensions
{ {
using var reader = new StringReader(s); using var reader = new StringReader(s);
var lineNum = 0; var lineNum = 0;
string line; while (reader.ReadLine() is { } line)
while ((line = reader.ReadLine()) != null)
{ {
lineNum++; lineNum++;
if (line.Equals(" {")) if (line.Equals(" {"))
@@ -110,6 +109,9 @@ public static class StringExtensions
return lineNum + 1; return lineNum + 1;
} }
return 1; return -1;
} }
[GeneratedRegex(@"^(.+)\[(\d+)\]$", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
private static partial Regex KismetRegex();
} }

View File

@@ -907,7 +907,10 @@ public class CUE4ParseViewModel : ViewModel
{ {
var package = Provider.LoadPackage(entry); var package = Provider.LoadPackage(entry);
TabControl.AddTab($"{entry.Name} (Metadata)"); if (TabControl.CanAddTabs) TabControl.AddTab(entry);
else TabControl.SelectedTab.SoftReset(entry);
TabControl.SelectedTab.TitleExtra = "Metadata";
TabControl.SelectedTab.Highlighter = AvalonExtensions.HighlighterSelector(""); TabControl.SelectedTab.Highlighter = AvalonExtensions.HighlighterSelector("");
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(package, Formatting.Indented), false, false); TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(package, Formatting.Indented), false, false);

View File

@@ -14,34 +14,34 @@ public class ImageCommand : ViewModelCommand<TabItem>
{ {
} }
public override void Execute(TabItem contextViewModel, object parameter) public override void Execute(TabItem tabViewModel, object parameter)
{ {
if (parameter == null || !contextViewModel.HasImage) return; if (parameter == null || !tabViewModel.HasImage) return;
switch (parameter) switch (parameter)
{ {
case "Open": case "Open":
{ {
Helper.OpenWindow<AdonisWindow>(contextViewModel.SelectedImage.ExportName + " (Image)", () => Helper.OpenWindow<AdonisWindow>(tabViewModel.SelectedImage.ExportName + " (Image)", () =>
{ {
var popout = new ImagePopout var popout = new ImagePopout
{ {
Title = contextViewModel.SelectedImage.ExportName + " (Image)", Title = tabViewModel.SelectedImage.ExportName + " (Image)",
Width = contextViewModel.SelectedImage.Image.Width, Width = tabViewModel.SelectedImage.Image.Width,
Height = contextViewModel.SelectedImage.Image.Height, Height = tabViewModel.SelectedImage.Image.Height,
WindowState = contextViewModel.SelectedImage.Image.Height > 1000 ? WindowState.Maximized : WindowState.Normal, WindowState = tabViewModel.SelectedImage.Image.Height > 1000 ? WindowState.Maximized : WindowState.Normal,
ImageCtrl = { Source = contextViewModel.SelectedImage.Image } ImageCtrl = { Source = tabViewModel.SelectedImage.Image }
}; };
RenderOptions.SetBitmapScalingMode(popout.ImageCtrl, BoolToRenderModeConverter.Instance.Convert(contextViewModel.SelectedImage.RenderNearestNeighbor)); RenderOptions.SetBitmapScalingMode(popout.ImageCtrl, BoolToRenderModeConverter.Instance.Convert(tabViewModel.SelectedImage.RenderNearestNeighbor));
popout.Show(); popout.Show();
}); });
break; break;
} }
case "Copy": case "Copy":
ClipboardExtensions.SetImage(contextViewModel.SelectedImage.ImageBuffer, $"{contextViewModel.SelectedImage.ExportName}.png"); ClipboardExtensions.SetImage(tabViewModel.SelectedImage.ImageBuffer, $"{tabViewModel.SelectedImage.ExportName}.png");
break; break;
case "Save": case "Save":
contextViewModel.SaveImage(); tabViewModel.SaveImage();
break; break;
} }
} }

View File

@@ -15,7 +15,7 @@ public class TabCommand : ViewModelCommand<TabItem>
{ {
} }
public override async void Execute(TabItem contextViewModel, object parameter) public override async void Execute(TabItem tabViewModel, object parameter)
{ {
switch (parameter) switch (parameter)
{ {
@@ -23,53 +23,53 @@ public class TabCommand : ViewModelCommand<TabItem>
_applicationView.CUE4Parse.TabControl.RemoveTab(mdlClick); _applicationView.CUE4Parse.TabControl.RemoveTab(mdlClick);
break; break;
case "Close_Tab": case "Close_Tab":
_applicationView.CUE4Parse.TabControl.RemoveTab(contextViewModel); _applicationView.CUE4Parse.TabControl.RemoveTab(tabViewModel);
break; break;
case "Close_All_Tabs": case "Close_All_Tabs":
_applicationView.CUE4Parse.TabControl.RemoveAllTabs(); _applicationView.CUE4Parse.TabControl.RemoveAllTabs();
break; break;
case "Close_Other_Tabs": case "Close_Other_Tabs":
_applicationView.CUE4Parse.TabControl.RemoveOtherTabs(contextViewModel); _applicationView.CUE4Parse.TabControl.RemoveOtherTabs(tabViewModel);
break; break;
case "Asset_Export_Data": case "Asset_Export_Data":
await _threadWorkerView.Begin(_ => _applicationView.CUE4Parse.ExportData(contextViewModel.Entry)); await _threadWorkerView.Begin(_ => _applicationView.CUE4Parse.ExportData(tabViewModel.Entry));
break; break;
case "Asset_Save_Properties": case "Asset_Save_Properties":
await _threadWorkerView.Begin(cancellationToken => await _threadWorkerView.Begin(cancellationToken =>
{ {
_applicationView.CUE4Parse.Extract(cancellationToken, contextViewModel.Entry, false, EBulkType.Properties); _applicationView.CUE4Parse.Extract(cancellationToken, tabViewModel.Entry, false, EBulkType.Properties);
}); });
break; break;
case "Asset_Save_Textures": case "Asset_Save_Textures":
await _threadWorkerView.Begin(cancellationToken => await _threadWorkerView.Begin(cancellationToken =>
{ {
_applicationView.CUE4Parse.Extract(cancellationToken, contextViewModel.Entry, false, EBulkType.Textures); _applicationView.CUE4Parse.Extract(cancellationToken, tabViewModel.Entry, false, EBulkType.Textures);
}); });
break; break;
case "Asset_Save_Models": case "Asset_Save_Models":
await _threadWorkerView.Begin(cancellationToken => await _threadWorkerView.Begin(cancellationToken =>
{ {
_applicationView.CUE4Parse.Extract(cancellationToken, contextViewModel.Entry, false, EBulkType.Meshes); _applicationView.CUE4Parse.Extract(cancellationToken, tabViewModel.Entry, false, EBulkType.Meshes);
}); });
break; break;
case "Asset_Save_Animations": case "Asset_Save_Animations":
await _threadWorkerView.Begin(cancellationToken => await _threadWorkerView.Begin(cancellationToken =>
{ {
_applicationView.CUE4Parse.Extract(cancellationToken, contextViewModel.Entry, false, EBulkType.Animations); _applicationView.CUE4Parse.Extract(cancellationToken, tabViewModel.Entry, false, EBulkType.Animations);
}); });
break; break;
case "Open_Properties": case "Open_Properties":
if (contextViewModel.Entry.Name == "New Tab" || contextViewModel.Document == null) return; if (tabViewModel.Header == "New Tab" || tabViewModel.Document == null) return;
Helper.OpenWindow<AdonisWindow>(contextViewModel.Entry.Name + " (Properties)", () => Helper.OpenWindow<AdonisWindow>(tabViewModel.Header + " (Properties)", () =>
{ {
new PropertiesPopout(contextViewModel) new PropertiesPopout(tabViewModel)
{ {
Title = contextViewModel.Entry.Name + " (Properties)" Title = tabViewModel.Header + " (Properties)"
}.Show(); }.Show();
}); });
break; break;
case "Copy_Asset_Path": case "Copy_Asset_Path":
Clipboard.SetText(contextViewModel.Entry.Path); Clipboard.SetText(tabViewModel.Entry.Path);
break; break;
} }
} }

View File

@@ -97,7 +97,22 @@ public class TabItem : ViewModel
public GameFile Entry public GameFile Entry
{ {
get => _entry; get => _entry;
set => SetProperty(ref _entry, value); set
{
SetProperty(ref _entry, value);
RaisePropertyChanged(nameof(Header));
}
}
private string _titleExtra;
public string TitleExtra
{
get => _titleExtra;
set
{
SetProperty(ref _titleExtra, value);
RaisePropertyChanged(nameof(Header));
}
} }
private bool _hasSearchOpen; private bool _hasSearchOpen;
@@ -194,6 +209,8 @@ public class TabItem : ViewModel
} }
} }
public string Header => $"{Entry.Name}{(string.IsNullOrEmpty(TitleExtra) ? "" : $" ({TitleExtra})")}";
public bool HasImage => SelectedImage != null; public bool HasImage => SelectedImage != null;
public bool HasMultipleImages => _images.Count > 1; public bool HasMultipleImages => _images.Count > 1;
public string Page => $"{_images.IndexOf(_selectedImage) + 1} / {_images.Count}"; public string Page => $"{_images.IndexOf(_selectedImage) + 1} / {_images.Count}";
@@ -219,6 +236,7 @@ public class TabItem : ViewModel
public void SoftReset(GameFile entry) public void SoftReset(GameFile entry)
{ {
Entry = entry; Entry = entry;
TitleExtra = string.Empty;
ParentExportType = string.Empty; ParentExportType = string.Empty;
ScrollTrigger = null; ScrollTrigger = null;
Application.Current.Dispatcher.Invoke(() => Application.Current.Dispatcher.Invoke(() =>
@@ -389,7 +407,7 @@ public class TabControlViewModel : ViewModel
public void AddTab(string title) => AddTab(new FakeGameFile(title)); public void AddTab(string title) => AddTab(new FakeGameFile(title));
public void AddTab(GameFile entry, string parentExportType = null) public void AddTab(GameFile entry, string parentExportType = null)
{ {
if (SelectedTab?.Entry.Name == "New Tab") if (SelectedTab?.Header == "New Tab")
{ {
SelectedTab.Entry = entry; SelectedTab.Entry = entry;
return; return;

View File

@@ -76,28 +76,18 @@ public class GamePathVisualLineText : VisualLineText
if (a.ParentVisualLine.Document.FileName.Equals(fullPath.SubstringBeforeLast('.'), StringComparison.OrdinalIgnoreCase) && if (a.ParentVisualLine.Document.FileName.Equals(fullPath.SubstringBeforeLast('.'), StringComparison.OrdinalIgnoreCase) &&
!a.ParentVisualLine.Document.GetText(firstLine.Offset, firstLine.Length).Equals(" \"Summary\": {")) // Show Metadata case !a.ParentVisualLine.Document.GetText(firstLine.Offset, firstLine.Length).Equals(" \"Summary\": {")) // Show Metadata case
{ {
int lineNumber; var lineNumber = a.ParentVisualLine.Document.Text.GetNameLineNumber(obj);
DocumentLine line; if (lineNumber > -1)
if (Regex.IsMatch(obj, @"^(.+)\[(\d+)\]$"))
{ {
lineNumber = a.ParentVisualLine.Document.Text.GetKismetLineNumber(obj); var line = a.ParentVisualLine.Document.GetLineByNumber(lineNumber);
line = a.ParentVisualLine.Document.GetLineByNumber(lineNumber); AvalonEditor.YesWeEditor.Select(line.Offset, line.Length);
} AvalonEditor.YesWeEditor.ScrollToLine(lineNumber);
else return;
{
lineNumber = a.ParentVisualLine.Document.Text.GetNameLineNumber(obj);
line = a.ParentVisualLine.Document.GetLineByNumber(lineNumber);
} }
}
AvalonEditor.YesWeEditor.Select(line.Offset, line.Length); await _threadWorkerView.Begin(cancellationToken =>
AvalonEditor.YesWeEditor.ScrollToLine(lineNumber); _applicationView.CUE4Parse.ExtractAndScroll(cancellationToken, fullPath, obj, parentExportType));
}
else
{
await _threadWorkerView.Begin(cancellationToken =>
_applicationView.CUE4Parse.ExtractAndScroll(cancellationToken, fullPath, obj, parentExportType));
}
}; };
return a; return a;
} }

View File

@@ -127,6 +127,8 @@ public partial class AvalonEditor
if (!tabItem.ShouldScroll) return; if (!tabItem.ShouldScroll) return;
var lineNumber = avalonEditor.Document.Text.GetNameLineNumber(tabItem.ScrollTrigger); var lineNumber = avalonEditor.Document.Text.GetNameLineNumber(tabItem.ScrollTrigger);
if (lineNumber == -1) lineNumber = 1;
var line = avalonEditor.Document.GetLineByNumber(lineNumber); var line = avalonEditor.Document.GetLineByNumber(lineNumber);
avalonEditor.Select(line.Offset, line.Length); avalonEditor.Select(line.Offset, line.Length);
avalonEditor.ScrollToLine(lineNumber); avalonEditor.ScrollToLine(lineNumber);

View File

@@ -651,7 +651,7 @@
<MouseBinding MouseAction="MiddleClick" Command="{Binding SelectedItem.TabCommand, ElementName=TabControlName}" CommandParameter="{Binding}" /> <MouseBinding MouseAction="MiddleClick" Command="{Binding SelectedItem.TabCommand, ElementName=TabControlName}" CommandParameter="{Binding}" />
</DockPanel.InputBindings> </DockPanel.InputBindings>
<TextBlock DockPanel.Dock="Left" Text="{Binding Entry.Name}" TextTrimming="CharacterEllipsis" ToolTip="{Binding Entry.Name}"> <TextBlock DockPanel.Dock="Left" Text="{Binding Header}" TextTrimming="CharacterEllipsis" ToolTip="{Binding Text, RelativeSource={RelativeSource Self}}">
<TextBlock.Width> <TextBlock.Width>
<MultiBinding Converter="{x:Static converters:TabSizeConverter.Instance}" ConverterParameter="6"> <MultiBinding Converter="{x:Static converters:TabSizeConverter.Instance}" ConverterParameter="6">
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" /> <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" />