mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2025-10-13 23:10:23 +03:00
improvements
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using ImGuiNET;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NResUI.Abstractions;
|
||||
@@ -33,6 +34,8 @@ public class App
|
||||
|
||||
public void Init(IWindow window, GL openGl, ImFontPtr openSansFont)
|
||||
{
|
||||
// Call this once at program startup
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
ImGui.StyleColorsLight();
|
||||
|
||||
IServiceCollection serviceCollection = new ServiceCollection();
|
||||
|
@@ -34,22 +34,60 @@ public class CpDatSchemeExplorer : IImGuiPanel
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
if (ImGui.BeginTable("content", 7, ImGuiTableFlags.Borders | ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.NoHostExtendX))
|
||||
if (ImGui.BeginTable("content", 8, ImGuiTableFlags.Borders | ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.NoHostExtendX | ImGuiTableFlags.Sortable))
|
||||
{
|
||||
ImGui.TableSetupColumn("Индекс");
|
||||
ImGui.TableSetupColumn("Уровень вложенности");
|
||||
ImGui.TableSetupColumn("Архив");
|
||||
ImGui.TableSetupColumn("Элемент");
|
||||
ImGui.TableSetupColumn("Magic1");
|
||||
ImGui.TableSetupColumn("Magic2");
|
||||
ImGui.TableSetupColumn("Описание");
|
||||
ImGui.TableSetupColumn("Magic3");
|
||||
ImGui.TableSetupColumn("Тип");
|
||||
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
// Handle sorting
|
||||
ImGuiTableSortSpecsPtr sortSpecs = ImGui.TableGetSortSpecs();
|
||||
if (sortSpecs.SpecsDirty)
|
||||
{
|
||||
// Only handle the first sort spec for simplicity
|
||||
var sortSpec = sortSpecs.Specs;
|
||||
|
||||
if (sortSpec.ColumnIndex == 0)
|
||||
{
|
||||
_viewModel.RebuildFlatList();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
_viewModel.FlatList.Sort((a, b) =>
|
||||
{
|
||||
int result = 0;
|
||||
switch (sortSpec.ColumnIndex)
|
||||
{
|
||||
case 1: result = a.Level.CompareTo(b.Level); break;
|
||||
case 2: result = string.Compare(a.Entry.ArchiveFile, b.Entry.ArchiveFile, StringComparison.Ordinal); break;
|
||||
case 3: result = string.Compare(a.Entry.ArchiveEntryName, b.Entry.ArchiveEntryName, StringComparison.Ordinal); break;
|
||||
case 4: result = a.Entry.Magic1.CompareTo(b.Entry.Magic1); break;
|
||||
case 5: result = a.Entry.Magic2.CompareTo(b.Entry.Magic2); break;
|
||||
case 6: result = string.Compare(a.Entry.Description, b.Entry.Description, StringComparison.Ordinal); break;
|
||||
case 7: result = a.Entry.Type.CompareTo(b.Entry.Type); break;
|
||||
}
|
||||
|
||||
return sortSpec.SortDirection == ImGuiSortDirection.Descending ? -result : result;
|
||||
});
|
||||
}
|
||||
|
||||
sortSpecs.SpecsDirty = false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < _viewModel.FlatList.Count; i++)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(i.ToString());
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(_viewModel.FlatList[i].Level.ToString());
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(_viewModel.FlatList[i].Entry.ArchiveFile);
|
||||
@@ -62,7 +100,7 @@ public class CpDatSchemeExplorer : IImGuiPanel
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(_viewModel.FlatList[i].Entry.Description);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(_viewModel.FlatList[i].Entry.Magic3.ToString());
|
||||
ImGui.Text(_viewModel.FlatList[i].Entry.Type.ToString("G"));
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
@@ -80,9 +118,9 @@ public class CpDatSchemeExplorer : IImGuiPanel
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(entry.Magic2.ToString());
|
||||
|
||||
ImGui.Text("Magic3: ");
|
||||
ImGui.Text("Тип: ");
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(entry.Magic3.ToString());
|
||||
ImGui.Text(entry.Type.ToString());
|
||||
|
||||
ImGui.Text("Кол-во дочерних элементов: ");
|
||||
ImGui.SameLine();
|
||||
|
@@ -1,23 +1,43 @@
|
||||
using ImGuiNET;
|
||||
using CpDatLib;
|
||||
using ImGuiNET;
|
||||
using MissionTmaLib.Parsing;
|
||||
using NResLib;
|
||||
using NResUI.Abstractions;
|
||||
using NResUI.Models;
|
||||
using ScrLib;
|
||||
using TexmLib;
|
||||
using VarsetLib;
|
||||
|
||||
namespace NResUI.ImGuiUI;
|
||||
|
||||
public class NResExplorerPanel : IImGuiPanel
|
||||
{
|
||||
private readonly NResExplorerViewModel _viewModel;
|
||||
private readonly TexmExplorerViewModel _texmExplorerViewModel;
|
||||
private readonly VarsetViewModel _varsetViewModel;
|
||||
private readonly CpDatSchemeViewModel _cpDatSchemeViewModel;
|
||||
private readonly MissionTmaViewModel _missionTmaViewModel;
|
||||
private readonly ScrViewModel _scrViewModel;
|
||||
|
||||
public NResExplorerPanel(NResExplorerViewModel viewModel)
|
||||
public NResExplorerPanel(NResExplorerViewModel viewModel, TexmExplorerViewModel texmExplorerViewModel,
|
||||
VarsetViewModel varsetViewModel, CpDatSchemeViewModel cpDatSchemeViewModel, MissionTmaViewModel missionTmaViewModel, ScrViewModel scrViewModel)
|
||||
{
|
||||
_viewModel = viewModel;
|
||||
_texmExplorerViewModel = texmExplorerViewModel;
|
||||
_varsetViewModel = varsetViewModel;
|
||||
_cpDatSchemeViewModel = cpDatSchemeViewModel;
|
||||
_missionTmaViewModel = missionTmaViewModel;
|
||||
_scrViewModel = scrViewModel;
|
||||
}
|
||||
|
||||
int contextMenuRow = -1;
|
||||
|
||||
public void OnImGuiRender()
|
||||
{
|
||||
if (ImGui.Begin("NRes Explorer"))
|
||||
{
|
||||
ImGui.Text("NRes - это файл-архив. Они имеют разные расширения. Примеры - Textures.lib, weapon.rlb, object.dlb, behpsp.res");
|
||||
ImGui.Text(
|
||||
"NRes - это файл-архив. Они имеют разные расширения. Примеры - Textures.lib, weapon.rlb, object.dlb, behpsp.res");
|
||||
ImGui.Separator();
|
||||
|
||||
if (!_viewModel.HasFile)
|
||||
@@ -34,7 +54,7 @@ public class NResExplorerPanel : IImGuiPanel
|
||||
if (_viewModel.Archive is not null)
|
||||
{
|
||||
ImGui.Text(_viewModel.Path);
|
||||
|
||||
|
||||
ImGui.Text("Header: ");
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(_viewModel.Archive.Header.NRes);
|
||||
@@ -48,8 +68,8 @@ public class NResExplorerPanel : IImGuiPanel
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(_viewModel.Archive.Header.TotalFileLengthBytes.ToString());
|
||||
|
||||
|
||||
if (ImGui.BeginTable("content", 12, ImGuiTableFlags.Borders | ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.NoHostExtendX))
|
||||
if (ImGui.BeginTable("content", 12,
|
||||
ImGuiTableFlags.Borders | ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.NoHostExtendX))
|
||||
{
|
||||
ImGui.TableSetupColumn("Тип файла");
|
||||
ImGui.TableSetupColumn("Кол-во элементов");
|
||||
@@ -70,6 +90,17 @@ public class NResExplorerPanel : IImGuiPanel
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
ImGui.Selectable("##row_select" + i, false, ImGuiSelectableFlags.SpanAllColumns);
|
||||
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
Console.WriteLine("Context menu for row " + i);
|
||||
contextMenuRow = i;
|
||||
ImGui.OpenPopup("row_context_menu");
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGui.Text(_viewModel.Archive.Files[i].FileType);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(_viewModel.Archive.Files[i].ElementCount.ToString());
|
||||
@@ -122,6 +153,130 @@ public class NResExplorerPanel : IImGuiPanel
|
||||
);
|
||||
}
|
||||
|
||||
if (ImGui.BeginPopup("row_context_menu"))
|
||||
{
|
||||
if (contextMenuRow == -1 || contextMenuRow > _viewModel.Archive.Files.Count)
|
||||
{
|
||||
ImGui.Text("Broken context menu :(. Reopen");
|
||||
}
|
||||
else
|
||||
{
|
||||
var file = _viewModel.Archive.Files[contextMenuRow];
|
||||
ImGui.Text("Actions for file " + file.FileName);
|
||||
ImGui.TextDisabled("Program has no understading of file format(");
|
||||
ImGui.Separator();
|
||||
if (ImGui.MenuItem("Open as Texture TEXM"))
|
||||
{
|
||||
using var fs = new FileStream(_viewModel.Path!, FileMode.Open, FileAccess.Read,
|
||||
FileShare.Read);
|
||||
fs.Seek(file.OffsetInFile, SeekOrigin.Begin);
|
||||
|
||||
var buffer = new byte[file.FileLength];
|
||||
|
||||
fs.ReadExactly(buffer, 0, file.FileLength);
|
||||
|
||||
using var ms = new MemoryStream(buffer);
|
||||
|
||||
var parseResult = TexmParser.ReadFromStream(ms, file.FileName);
|
||||
|
||||
_texmExplorerViewModel.SetParseResult(parseResult, Path.Combine(_viewModel.Path!, file.FileName));
|
||||
Console.WriteLine("Read TEXM from context menu");
|
||||
}
|
||||
|
||||
if (ImGui.MenuItem("Open as Archive NRes"))
|
||||
{
|
||||
using var fs = new FileStream(_viewModel.Path!, FileMode.Open, FileAccess.Read,
|
||||
FileShare.Read);
|
||||
fs.Seek(file.OffsetInFile, SeekOrigin.Begin);
|
||||
|
||||
var buffer = new byte[file.FileLength];
|
||||
|
||||
fs.ReadExactly(buffer, 0, file.FileLength);
|
||||
|
||||
using var ms = new MemoryStream(buffer);
|
||||
|
||||
var parseResult = NResParser.ReadFile(ms);
|
||||
|
||||
_viewModel.SetParseResult(parseResult, Path.Combine(_viewModel.Path!, file.FileName));
|
||||
Console.WriteLine("Read NRes from context menu");
|
||||
}
|
||||
|
||||
if (ImGui.MenuItem("Open as Varset .var"))
|
||||
{
|
||||
using var fs = new FileStream(_viewModel.Path!, FileMode.Open, FileAccess.Read,
|
||||
FileShare.Read);
|
||||
fs.Seek(file.OffsetInFile, SeekOrigin.Begin);
|
||||
|
||||
var buffer = new byte[file.FileLength];
|
||||
|
||||
fs.ReadExactly(buffer, 0, file.FileLength);
|
||||
|
||||
using var ms = new MemoryStream(buffer);
|
||||
|
||||
var parseResult = VarsetParser.Parse(ms);
|
||||
|
||||
_varsetViewModel.Items = parseResult;
|
||||
Console.WriteLine("Read Varset from context menu");
|
||||
}
|
||||
|
||||
if (ImGui.MenuItem("Open as Scheme cp.dat"))
|
||||
{
|
||||
using var fs = new FileStream(_viewModel.Path!, FileMode.Open, FileAccess.Read,
|
||||
FileShare.Read);
|
||||
fs.Seek(file.OffsetInFile, SeekOrigin.Begin);
|
||||
|
||||
var buffer = new byte[file.FileLength];
|
||||
|
||||
fs.ReadExactly(buffer, 0, file.FileLength);
|
||||
|
||||
using var ms = new MemoryStream(buffer);
|
||||
|
||||
var parseResult = CpDatParser.Parse(ms);
|
||||
|
||||
_cpDatSchemeViewModel.SetParseResult(parseResult, file.FileName);
|
||||
Console.WriteLine("Read cp.dat from context menu");
|
||||
}
|
||||
|
||||
if (ImGui.MenuItem("Open as Mission .tma"))
|
||||
{
|
||||
using var fs = new FileStream(_viewModel.Path!, FileMode.Open, FileAccess.Read,
|
||||
FileShare.Read);
|
||||
fs.Seek(file.OffsetInFile, SeekOrigin.Begin);
|
||||
|
||||
var buffer = new byte[file.FileLength];
|
||||
|
||||
fs.ReadExactly(buffer, 0, file.FileLength);
|
||||
|
||||
using var ms = new MemoryStream(buffer);
|
||||
|
||||
var parseResult = MissionTmaParser.ReadFile(ms);
|
||||
|
||||
_missionTmaViewModel.SetParseResult(parseResult, Path.Combine(_viewModel.Path!, file.FileName));
|
||||
Console.WriteLine("Read .tma from context menu");
|
||||
}
|
||||
|
||||
if (ImGui.MenuItem("Open as Scripts .scr"))
|
||||
{
|
||||
using var fs = new FileStream(_viewModel.Path!, FileMode.Open, FileAccess.Read,
|
||||
FileShare.Read);
|
||||
fs.Seek(file.OffsetInFile, SeekOrigin.Begin);
|
||||
|
||||
var buffer = new byte[file.FileLength];
|
||||
|
||||
fs.ReadExactly(buffer, 0, file.FileLength);
|
||||
|
||||
using var ms = new MemoryStream(buffer);
|
||||
|
||||
var parseResult = ScrParser.ReadFile(ms);
|
||||
|
||||
_scrViewModel.SetParseResult(parseResult, Path.Combine(_viewModel.Path!, file.FileName));
|
||||
Console.WriteLine("Read .scr from context menu");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
}
|
||||
|
@@ -9,8 +9,8 @@ public class CpDatSchemeViewModel
|
||||
public string? Error { get; set; }
|
||||
|
||||
public CpDatScheme? CpDatScheme { get; set; }
|
||||
|
||||
public List<(int Level, CpDatEntry Entry)> FlatList { get; set; }
|
||||
|
||||
public List<(int Level, CpDatEntry Entry)> FlatList { get; set; } = [];
|
||||
|
||||
public string? Path { get; set; }
|
||||
|
||||
@@ -23,17 +23,27 @@ public class CpDatSchemeViewModel
|
||||
|
||||
if (CpDatScheme is not null)
|
||||
{
|
||||
FlatList = [];
|
||||
RebuildFlatList();
|
||||
}
|
||||
}
|
||||
|
||||
public void RebuildFlatList()
|
||||
{
|
||||
FlatList = [];
|
||||
|
||||
if (CpDatScheme is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CollectEntries(CpDatScheme.Root, 0);
|
||||
CollectEntries(CpDatScheme.Root, 0);
|
||||
|
||||
void CollectEntries(CpDatEntry entry, int level)
|
||||
void CollectEntries(CpDatEntry entry, int level)
|
||||
{
|
||||
FlatList.Add((level, entry));
|
||||
foreach (var child in entry.Children)
|
||||
{
|
||||
FlatList.Add((level, entry));
|
||||
foreach (var child in entry.Children)
|
||||
{
|
||||
CollectEntries(child, level + 1);
|
||||
}
|
||||
CollectEntries(child, level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<OutputType Condition="'$(OS)' == 'Windows_NT'">WinExe</OutputType>
|
||||
<OutputType Condition="'$(OS)' != 'Windows_NT'">Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
Reference in New Issue
Block a user