Compare commits
8 Commits
b13d27c0b8
...
fbacfccd13
Author | SHA1 | Date |
---|---|---|
Jarrod Doyle | fbacfccd13 | |
Jarrod Doyle | 56614d3b1d | |
Jarrod Doyle | 0a71be4731 | |
Jarrod Doyle | d434e2c13f | |
Jarrod Doyle | 80f121bfde | |
Jarrod Doyle | 7593828ca7 | |
Jarrod Doyle | 66a57d415a | |
Jarrod Doyle | e76bc13ef5 |
|
@ -1,9 +1,22 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace KeepersCompound.TMV.UI;
|
namespace KeepersCompound.TMV.UI;
|
||||||
|
|
||||||
public partial class TextureBrowser : Node
|
public partial class TextureBrowser : Node
|
||||||
{
|
{
|
||||||
|
enum SortMode
|
||||||
|
{
|
||||||
|
Name,
|
||||||
|
Family,
|
||||||
|
Index,
|
||||||
|
Count,
|
||||||
|
}
|
||||||
|
|
||||||
private Tree _folderTree;
|
private Tree _folderTree;
|
||||||
private LineEdit _searchBar;
|
private LineEdit _searchBar;
|
||||||
private MenuButton _sortMenu;
|
private MenuButton _sortMenu;
|
||||||
|
@ -12,6 +25,12 @@ public partial class TextureBrowser : Node
|
||||||
private HFlowContainer _textureList;
|
private HFlowContainer _textureList;
|
||||||
private TextureRect _previewTexture;
|
private TextureRect _previewTexture;
|
||||||
private LineEdit _texturePath;
|
private LineEdit _texturePath;
|
||||||
|
private OptionButton _filterOptions;
|
||||||
|
private LineEdit _fileType;
|
||||||
|
private LineEdit _resolutionBox;
|
||||||
|
private LineEdit _fileSizeBox;
|
||||||
|
|
||||||
|
private string _searchFilterPrefix = "";
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
|
@ -27,6 +46,15 @@ public partial class TextureBrowser : Node
|
||||||
_textureList = GetNode<HFlowContainer>("%TextureList");
|
_textureList = GetNode<HFlowContainer>("%TextureList");
|
||||||
_previewTexture = GetNode<TextureRect>("%PreviewTexture");
|
_previewTexture = GetNode<TextureRect>("%PreviewTexture");
|
||||||
_texturePath = GetNode<LineEdit>("%PathBox");
|
_texturePath = GetNode<LineEdit>("%PathBox");
|
||||||
|
_filterOptions = GetNode<OptionButton>("%FilterOptions");
|
||||||
|
_fileType = GetNode<LineEdit>("%FileTypeBox");
|
||||||
|
_resolutionBox = GetNode<LineEdit>("%ResolutionBox");
|
||||||
|
_fileSizeBox = GetNode<LineEdit>("%FileSizeBox");
|
||||||
|
|
||||||
|
_searchBar.TextChanged += ApplySearchFilter;
|
||||||
|
_sortMenu.GetPopup().IdPressed += ApplySortMode;
|
||||||
|
_folderTree.ItemSelected += SetActiveFolder;
|
||||||
|
_filterOptions.ItemSelected += SetPreviewTextureFilter;
|
||||||
|
|
||||||
BuildFolderTree();
|
BuildFolderTree();
|
||||||
BuildTextureList(); // TODO: This should be triggered on folder change
|
BuildTextureList(); // TODO: This should be triggered on folder change
|
||||||
|
@ -35,13 +63,28 @@ public partial class TextureBrowser : Node
|
||||||
private void BuildFolderTree()
|
private void BuildFolderTree()
|
||||||
{
|
{
|
||||||
_folderTree.Clear();
|
_folderTree.Clear();
|
||||||
_folderTree.SetColumnTitle(0, "Name");
|
|
||||||
_folderTree.SetColumnTitle(1, "Count");
|
|
||||||
|
|
||||||
// TODO: We need some way to get family names
|
var context = Context.Instance;
|
||||||
// Maybe PathManager and CampaignResource should be expanded so that we
|
var textureNames = context.PathManager.GetResourceNames(LGS.ResourceType.Texture, context.CampaignName);
|
||||||
// can get the resource itself and query things
|
|
||||||
var pathManager = Context.Instance.PathManager;
|
var treeItems = new Dictionary<string, TreeItem>();
|
||||||
|
treeItems.Add("", _folderTree.CreateItem());
|
||||||
|
foreach (var name in textureNames)
|
||||||
|
{
|
||||||
|
var tokens = name.Split('/');
|
||||||
|
var fams = new string[tokens.Length + 1];
|
||||||
|
fams[0] = "";
|
||||||
|
for (var i = 1; i < tokens.Length; i++)
|
||||||
|
{
|
||||||
|
fams[i] = tokens[..i].Join("/");
|
||||||
|
if (!treeItems.ContainsKey(fams[i]))
|
||||||
|
{
|
||||||
|
var item = _folderTree.CreateItem(treeItems[fams[i - 1]]);
|
||||||
|
item.SetText(0, tokens[i - 1]);
|
||||||
|
treeItems.Add(fams[i], item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BuildTextureList()
|
private void BuildTextureList()
|
||||||
|
@ -66,7 +109,10 @@ public partial class TextureBrowser : Node
|
||||||
textureRect.StretchMode = TextureRect.StretchModeEnum.KeepAspectCentered;
|
textureRect.StretchMode = TextureRect.StretchModeEnum.KeepAspectCentered;
|
||||||
textureRect.SetAnchorsPreset(Control.LayoutPreset.FullRect);
|
textureRect.SetAnchorsPreset(Control.LayoutPreset.FullRect);
|
||||||
|
|
||||||
|
// We use meta here rather than just Name because Name replaces / with _ so
|
||||||
|
// we can't reliably construct it (the path can have natural _)
|
||||||
var slot = new Panel();
|
var slot = new Panel();
|
||||||
|
slot.SetMeta("TexPath", name);
|
||||||
slot.CustomMinimumSize = new Vector2(128, 128);
|
slot.CustomMinimumSize = new Vector2(128, 128);
|
||||||
slot.AddChild(textureRect);
|
slot.AddChild(textureRect);
|
||||||
slot.GuiInput += (input) =>
|
slot.GuiInput += (input) =>
|
||||||
|
@ -75,7 +121,7 @@ public partial class TextureBrowser : Node
|
||||||
mouseEvent.Pressed &&
|
mouseEvent.Pressed &&
|
||||||
mouseEvent.ButtonIndex == MouseButton.Left)
|
mouseEvent.ButtonIndex == MouseButton.Left)
|
||||||
{
|
{
|
||||||
SetPreviewTexture(name, texture);
|
SetPreviewTexture(name, texture, path);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,9 +129,70 @@ public partial class TextureBrowser : Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetPreviewTexture(string name, Texture2D texture)
|
private void SetPreviewTexture(string name, Texture2D texture, string path)
|
||||||
{
|
{
|
||||||
_previewTexture.Texture = texture;
|
_previewTexture.Texture = texture;
|
||||||
_texturePath.Text = name;
|
_texturePath.Text = name;
|
||||||
|
_fileType.Text = Path.GetExtension(path).ToUpper();
|
||||||
|
|
||||||
|
var resolution = texture.GetSize();
|
||||||
|
_resolutionBox.Text = $"{resolution.X}x{resolution.Y}";
|
||||||
|
|
||||||
|
var fileInfo = new FileInfo(path);
|
||||||
|
_fileSizeBox.Text = $"{(fileInfo.Length / 1000.0f).ToString("0.0")} kb";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplySearchFilter(string filter)
|
||||||
|
{
|
||||||
|
var regex = $"^{_searchFilterPrefix}.*{Regex.Escape(filter).Replace("\\*", ".*")}.*$";
|
||||||
|
foreach (var node in _textureList.GetChildren())
|
||||||
|
{
|
||||||
|
var panel = (Panel)node;
|
||||||
|
var name = panel.GetMeta("TexPath").ToString();
|
||||||
|
panel.Visible = Regex.IsMatch(name, regex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplySortMode(long id)
|
||||||
|
{
|
||||||
|
var popup = _sortMenu.GetPopup();
|
||||||
|
for (var i = 0; i < popup.ItemCount; i++)
|
||||||
|
{
|
||||||
|
popup.SetItemChecked(i, popup.GetItemId(i) == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Actualy sort
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetActiveFolder()
|
||||||
|
{
|
||||||
|
var selected = _folderTree.GetSelected();
|
||||||
|
var selectedFolder = selected.GetText(0) + "/";
|
||||||
|
var parent = selected.GetParent();
|
||||||
|
while (parent != null)
|
||||||
|
{
|
||||||
|
var text = parent.GetText(0);
|
||||||
|
if (text != "")
|
||||||
|
{
|
||||||
|
selectedFolder = text + "/" + selectedFolder;
|
||||||
|
}
|
||||||
|
parent = parent.GetParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This prefix is used in a regex, so we escape it here. The additional
|
||||||
|
// replace is because C# Regex doesn't escape /
|
||||||
|
_searchFilterPrefix = Regex.Escape(selectedFolder).Replace("/", "\\/");
|
||||||
|
ApplySearchFilter(_searchBar.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetPreviewTextureFilter(long idx)
|
||||||
|
{
|
||||||
|
var filterMode = idx switch
|
||||||
|
{
|
||||||
|
0 => CanvasItem.TextureFilterEnum.LinearWithMipmaps,
|
||||||
|
1 => CanvasItem.TextureFilterEnum.NearestWithMipmaps,
|
||||||
|
_ => throw new InvalidOperationException(),
|
||||||
|
};
|
||||||
|
_previewTexture.TextureFilter = filterMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,7 @@ size_flags_vertical = 3
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(256, 0)
|
custom_minimum_size = Vector2(256, 0)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
columns = 2
|
hide_root = true
|
||||||
column_titles_visible = true
|
|
||||||
|
|
||||||
[node name="HSplitContainer" type="HSplitContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer"]
|
[node name="HSplitContainer" type="HSplitContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
@ -76,14 +75,15 @@ tooltip_text = "Sort Mode"
|
||||||
icon = ExtResource("3_0k1fm")
|
icon = ExtResource("3_0k1fm")
|
||||||
icon_alignment = 1
|
icon_alignment = 1
|
||||||
item_count = 4
|
item_count = 4
|
||||||
popup/item_0/text = "Family"
|
popup/item_0/text = "Name"
|
||||||
popup/item_0/checkable = 2
|
popup/item_0/checkable = 2
|
||||||
popup/item_0/id = 1
|
popup/item_0/checked = true
|
||||||
popup/item_1/text = "Name"
|
popup/item_1/text = "Family"
|
||||||
popup/item_1/checkable = 2
|
popup/item_1/checkable = 2
|
||||||
popup/item_1/id = 2
|
popup/item_1/id = 1
|
||||||
popup/item_2/text = "Index"
|
popup/item_2/text = "Index"
|
||||||
popup/item_2/checkable = 2
|
popup/item_2/checkable = 2
|
||||||
|
popup/item_2/id = 2
|
||||||
popup/item_2/disabled = true
|
popup/item_2/disabled = true
|
||||||
popup/item_3/text = "Count"
|
popup/item_3/text = "Count"
|
||||||
popup/item_3/checkable = 2
|
popup/item_3/checkable = 2
|
||||||
|
@ -110,6 +110,7 @@ popup/item_0/id = 1
|
||||||
popup/item_1/text = "Show Custom"
|
popup/item_1/text = "Show Custom"
|
||||||
popup/item_1/checkable = 1
|
popup/item_1/checkable = 1
|
||||||
popup/item_1/checked = true
|
popup/item_1/checked = true
|
||||||
|
popup/item_1/id = 1
|
||||||
popup/item_2/text = "Show Family Name"
|
popup/item_2/text = "Show Family Name"
|
||||||
popup/item_2/checkable = 1
|
popup/item_2/checkable = 1
|
||||||
popup/item_2/id = 2
|
popup/item_2/id = 2
|
||||||
|
@ -217,6 +218,7 @@ layout_mode = 2
|
||||||
text = "Texture Filter"
|
text = "Texture Filter"
|
||||||
|
|
||||||
[node name="FilterOptions" type="OptionButton" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
|
[node name="FilterOptions" type="OptionButton" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
|
||||||
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
selected = 0
|
selected = 0
|
||||||
|
@ -275,6 +277,7 @@ layout_mode = 2
|
||||||
text = "File Type"
|
text = "File Type"
|
||||||
|
|
||||||
[node name="FileTypeBox" type="LineEdit" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
|
[node name="FileTypeBox" type="LineEdit" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
|
||||||
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
editable = false
|
editable = false
|
||||||
|
@ -284,6 +287,7 @@ layout_mode = 2
|
||||||
text = "Resolution"
|
text = "Resolution"
|
||||||
|
|
||||||
[node name="ResolutionBox" type="LineEdit" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
|
[node name="ResolutionBox" type="LineEdit" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
|
||||||
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
editable = false
|
editable = false
|
||||||
|
@ -293,6 +297,7 @@ layout_mode = 2
|
||||||
text = "File Size"
|
text = "File Size"
|
||||||
|
|
||||||
[node name="FileSizeBox" type="LineEdit" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
|
[node name="FileSizeBox" type="LineEdit" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
|
||||||
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
editable = false
|
editable = false
|
||||||
|
|
Loading…
Reference in New Issue