Compare commits

..

4 Commits

Author SHA1 Message Date
Jarrod Doyle b13d27c0b8
Basic functionality for the texture browser 2024-09-08 14:45:52 +01:00
Jarrod Doyle 63591c228b
Add CampaignName to Context 2024-09-08 13:24:10 +01:00
Jarrod Doyle 3d9556b1e9
Mockup texture browser 2024-09-08 13:14:13 +01:00
Jarrod Doyle fc7bb33520
Remove unused code 2024-09-08 07:17:10 +01:00
17 changed files with 593 additions and 36 deletions

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M2 1a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h1V3h9V2a1 1 0 0 0-1-1zm3 3a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1zm1 2h7v7H6z"/></svg>

After

Width:  |  Height:  |  Size: 231 B

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bfswg75r148mr"
path="res://.godot/imported/ActionCopy.svg-fe32bd9a658250ff5e4542f0ef742cc6.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://project/assets/icons/ActionCopy.svg"
dest_files=["res://.godot/imported/ActionCopy.svg-fe32bd9a658250ff5e4542f0ef742cc6.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M2 2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-4a1 1 0 0 1-1-1V3a1 1 0 0 0-1-1z"/></svg>

After

Width:  |  Height:  |  Size: 198 B

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dqefy830o4foj"
path="res://.godot/imported/Folder.svg-c5366e065eac9f3b42512c5da39f138e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://project/assets/icons/Folder.svg"
dest_files=["res://.godot/imported/Folder.svg-c5366e065eac9f3b42512c5da39f138e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M8 0a2 2 0 0 0 0 4 2 2 0 0 0 0-4zm0 6a2 2 0 0 0 0 4 2 2 0 0 0 0-4zm0 6a2 2 0 0 0 0 4 2 2 0 0 0 0-4z"/></svg>

After

Width:  |  Height:  |  Size: 195 B

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dm2jiwrvkjnaa"
path="res://.godot/imported/GuiTabMenuHl.svg-7d46ea78c1798f92cb9529645b049264.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://project/assets/icons/GuiTabMenuHl.svg"
dest_files=["res://.godot/imported/GuiTabMenuHl.svg-7d46ea78c1798f92cb9529645b049264.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M10.168 8.754a5 5 0 1 0-1.414 1.414l4.316 4.316 1.414-1.414zM6 3a3 3 0 0 1 0 6 3 3 0 0 1 0-6z"/></svg>

After

Width:  |  Height:  |  Size: 189 B

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://beb4tj06ivjae"
path="res://.godot/imported/Search.svg-000822acacc83acc029332775ac6bf48.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://project/assets/icons/Search.svg"
dest_files=["res://.godot/imported/Search.svg-000822acacc83acc029332775ac6bf48.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M9 1v2h6V1zM4 1a1 1 0 0 0-.691.291l-2 2a1 1 0 0 0 1.414 1.414l.293-.293v7.172l-.293-.293a1 1 0 0 0-1.414 1.414l2 2a1 1 0 0 0 1.414 0l2-2a1 1 0 0 0-1.414-1.414l-.293.293V4.412l.293.293a1 1 0 0 0 1.414-1.414l-2-2A1 1 0 0 0 4 1zm5 6v2h4V7zm0 6v2h2v-2z"/></svg>

After

Width:  |  Height:  |  Size: 344 B

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dx8paqeom7dtb"
path="res://.godot/imported/Sort.svg-25c42cee888ae0bd8bbed8b3683eb96a.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://project/assets/icons/Sort.svg"
dest_files=["res://.godot/imported/Sort.svg-25c42cee888ae0bd8bbed8b3683eb96a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -49,32 +49,6 @@ public class GifDecoder
} }
} }
private record GraphicsControl
{
public int TransparencyIndex;
public GraphicsControl(BinaryReader reader)
{
var blockSize = reader.ReadByte();
if (blockSize != 4)
{
throw new InvalidDataException($"Graphics Control block size should be 4. Found: {blockSize}");
}
// The only flag we care about is transparency
var flags = reader.ReadByte();
var transparency = (flags & 0x1) != 0;
var delayTime = reader.ReadUInt16(); // I don't think thief uses any animated gifs so we'll ignore this :)
var rawTransparencyIndex = reader.ReadByte();
TransparencyIndex = transparency ? rawTransparencyIndex : -1;
var terminator = reader.ReadByte();
if (terminator != 0)
{
throw new InvalidDataException($"Graphics Control terminator should be 0. Found: {terminator}");
}
}
}
public record ImageData public record ImageData
{ {
public int Width; public int Width;

View File

@ -9,12 +9,14 @@ public partial class Context : Node
public ResourcePathManager PathManager { get; private set; } public ResourcePathManager PathManager { get; private set; }
public ModelLoader ModelLoader { get; private set; } public ModelLoader ModelLoader { get; private set; }
public string CampaignName { get; set; }
public override void _Ready() public override void _Ready()
{ {
var extractPath = ProjectSettings.GlobalizePath($"user://extracted/tmp"); var extractPath = ProjectSettings.GlobalizePath($"user://extracted/tmp");
PathManager = new ResourcePathManager(extractPath); PathManager = new ResourcePathManager(extractPath);
ModelLoader = new ModelLoader(); ModelLoader = new ModelLoader();
CampaignName = "";
Instance = this; Instance = this;
} }

View File

@ -41,7 +41,6 @@ public partial class Mission : Node3D
public bool Dump = false; public bool Dump = false;
public int LightmapLayers = 33; public int LightmapLayers = 33;
string _campaignName;
string _missionName; string _missionName;
DbFile _file; DbFile _file;
TextureLoader _textureLoader; TextureLoader _textureLoader;
@ -59,10 +58,10 @@ public partial class Mission : Node3D
var resourceSelector = GetNode<Control>("%ResourceSelector") as ResourceSelector; var resourceSelector = GetNode<Control>("%ResourceSelector") as ResourceSelector;
resourceSelector.ResourceSelected += (string campaign, string mission) => resourceSelector.ResourceSelected += (string campaign, string mission) =>
{ {
_campaignName = campaign; var context = Context.Instance;
context.CampaignName = campaign;
_missionName = mission; _missionName = mission;
var pathManager = Context.Instance.PathManager; var (newCampaign, missionPath) = context.PathManager.GetResourcePath(ResourceType.Mission, campaign, mission);
var (newCampaign, missionPath) = pathManager.GetResourcePath(ResourceType.Mission, campaign, mission);
if (newCampaign != campaign) if (newCampaign != campaign)
{ {
GD.Print($"Didn't find campaign mission: ({campaign}, {mission})"); GD.Print($"Didn't find campaign mission: ({campaign}, {mission})");
@ -121,7 +120,7 @@ public partial class Mission : Node3D
{ {
ClearMap(); ClearMap();
_textureLoader = new TextureLoader(_campaignName); _textureLoader = new TextureLoader(Context.Instance.CampaignName);
Timing.TimeStage("DbFile Parse", () => _file = new(FileName)); Timing.TimeStage("DbFile Parse", () => _file = new(FileName));
Timing.TimeStage("Register Textures", () => UseChunk<TxList>("TXLIST", RegisterTextures)); Timing.TimeStage("Register Textures", () => UseChunk<TxList>("TXLIST", RegisterTextures));
Timing.TimeStage("Build WR", () => UseChunk<WorldRep>("WREXT", BuildWrMeshes)); Timing.TimeStage("Build WR", () => UseChunk<WorldRep>("WREXT", BuildWrMeshes));
@ -268,7 +267,7 @@ public partial class Mission : Node3D
var scale = scaleProp == null ? Vector3.One : scaleProp.value.ToGodotVec3(false); var scale = scaleProp == null ? Vector3.One : scaleProp.value.ToGodotVec3(false);
var model = Timing.TimeStage("Get Models", () => var model = Timing.TimeStage("Get Models", () =>
{ {
return Context.Instance.ModelLoader.Load(_campaignName, modelName); return Context.Instance.ModelLoader.Load(modelName);
}); });
if (model != null) if (model != null)
{ {
@ -287,17 +286,18 @@ public partial class Mission : Node3D
path = prop.value; path = prop.value;
var pathManager = Context.Instance.PathManager; var pathManager = Context.Instance.PathManager;
var campaign = Context.Instance.CampaignName;
if (path.StartsWith("fam", StringComparison.OrdinalIgnoreCase)) if (path.StartsWith("fam", StringComparison.OrdinalIgnoreCase))
{ {
var resType = ResourceType.Texture; var resType = ResourceType.Texture;
path = pathManager.GetResourcePath(resType, _campaignName, prop.value).Item2; path = pathManager.GetResourcePath(resType, campaign, prop.value).Item2;
} }
else else
{ {
var resType = ResourceType.ObjectTexture; var resType = ResourceType.ObjectTexture;
var convertedValue = ResourcePathManager.ConvertSeparator(prop.value); var convertedValue = ResourcePathManager.ConvertSeparator(prop.value);
var resName = Path.GetFileNameWithoutExtension(convertedValue); var resName = Path.GetFileNameWithoutExtension(convertedValue);
path = pathManager.GetResourcePath(resType, _campaignName, resName).Item2; path = pathManager.GetResourcePath(resType, campaign, resName).Item2;
} }
return path != null; return path != null;

View File

@ -18,7 +18,8 @@ public partial class Model : Node3D
node.QueueFree(); node.QueueFree();
} }
var model = Context.Instance.ModelLoader.Load(campaignName, modelPath); Context.Instance.CampaignName = campaignName;
var model = Context.Instance.ModelLoader.Load(modelPath);
AddChild(model); AddChild(model);
} }
} }

View File

@ -9,8 +9,9 @@ public class ModelLoader
{ {
private readonly Dictionary<(string, string), MeshInstance3D> _cache = new(); private readonly Dictionary<(string, string), MeshInstance3D> _cache = new();
public MeshInstance3D Load(string campaignName, string modelName, bool forceLoad = false) public MeshInstance3D Load(string modelName, bool forceLoad = false)
{ {
var campaignName = Context.Instance.CampaignName;
campaignName ??= ""; campaignName ??= "";
if (!forceLoad) if (!forceLoad)

View File

@ -0,0 +1,91 @@
using Godot;
namespace KeepersCompound.TMV.UI;
public partial class TextureBrowser : Node
{
private Tree _folderTree;
private LineEdit _searchBar;
private MenuButton _sortMenu;
private Button _openFolderButton;
private MenuButton _browserMenu;
private HFlowContainer _textureList;
private TextureRect _previewTexture;
private LineEdit _texturePath;
public override void _Ready()
{
// !HACK TEMP
Context.Instance.PathManager.Init("/stuff/Games/thief/drive_c/GOG Games/TG ND 1.27 (MAPPING)/");
Context.Instance.CampaignName = "TheBlackParade_1_0";
_folderTree = GetNode<Tree>("%FolderTree");
_searchBar = GetNode<LineEdit>("%SearchBar");
_sortMenu = GetNode<MenuButton>("%SortMenu");
_openFolderButton = GetNode<Button>("%OpenTextureFolderButton");
_browserMenu = GetNode<MenuButton>("%BrowserOverflowMenu");
_textureList = GetNode<HFlowContainer>("%TextureList");
_previewTexture = GetNode<TextureRect>("%PreviewTexture");
_texturePath = GetNode<LineEdit>("%PathBox");
BuildFolderTree();
BuildTextureList(); // TODO: This should be triggered on folder change
}
private void BuildFolderTree()
{
_folderTree.Clear();
_folderTree.SetColumnTitle(0, "Name");
_folderTree.SetColumnTitle(1, "Count");
// TODO: We need some way to get family names
// Maybe PathManager and CampaignResource should be expanded so that we
// can get the resource itself and query things
var pathManager = Context.Instance.PathManager;
}
private void BuildTextureList()
{
foreach (var child in _textureList.GetChildren())
{
child.QueueFree();
}
var pathManager = Context.Instance.PathManager;
var campaign = Context.Instance.CampaignName;
var resType = LGS.ResourceType.Texture;
var textureNames = pathManager.GetResourceNames(resType, campaign);
foreach (var name in textureNames)
{
var (_, path) = pathManager.GetResourcePath(resType, campaign, name);
var texture = TextureLoader.LoadTexture(path);
var textureRect = new TextureRect();
textureRect.Texture = texture;
textureRect.ExpandMode = TextureRect.ExpandModeEnum.IgnoreSize;
textureRect.StretchMode = TextureRect.StretchModeEnum.KeepAspectCentered;
textureRect.SetAnchorsPreset(Control.LayoutPreset.FullRect);
var slot = new Panel();
slot.CustomMinimumSize = new Vector2(128, 128);
slot.AddChild(textureRect);
slot.GuiInput += (input) =>
{
if (input is InputEventMouseButton mouseEvent &&
mouseEvent.Pressed &&
mouseEvent.ButtonIndex == MouseButton.Left)
{
SetPreviewTexture(name, texture);
}
};
_textureList.AddChild(slot);
}
}
private void SetPreviewTexture(string name, Texture2D texture)
{
_previewTexture.Texture = texture;
_texturePath.Text = name;
}
}

View File

@ -0,0 +1,298 @@
[gd_scene load_steps=8 format=3 uid="uid://byknmqac1a5vn"]
[ext_resource type="Texture2D" uid="uid://b208ufsau5jhb" path="res://project/jorge.png" id="1_1vlw2"]
[ext_resource type="Script" path="res://project/code/TMV/UI/TextureBrowser.cs" id="1_72xft"]
[ext_resource type="Texture2D" uid="uid://beb4tj06ivjae" path="res://project/assets/icons/Search.svg" id="1_ityvd"]
[ext_resource type="Texture2D" uid="uid://dx8paqeom7dtb" path="res://project/assets/icons/Sort.svg" id="3_0k1fm"]
[ext_resource type="Texture2D" uid="uid://dqefy830o4foj" path="res://project/assets/icons/Folder.svg" id="3_xdjfn"]
[ext_resource type="Texture2D" uid="uid://dm2jiwrvkjnaa" path="res://project/assets/icons/GuiTabMenuHl.svg" id="4_s4jwc"]
[ext_resource type="Texture2D" uid="uid://bfswg75r148mr" path="res://project/assets/icons/ActionCopy.svg" id="7_2pq2g"]
[node name="AssetBrowser" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="TabContainer" type="TabContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
current_tab = 0
[node name="Textures" type="MarginContainer" parent="TabContainer"]
layout_mode = 2
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
script = ExtResource("1_72xft")
metadata/_tab_index = 0
[node name="VBoxContainer" type="VBoxContainer" parent="TabContainer/Textures"]
layout_mode = 2
[node name="HSplitContainer" type="HSplitContainer" parent="TabContainer/Textures/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="FolderTree" type="Tree" parent="TabContainer/Textures/VBoxContainer/HSplitContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(256, 0)
layout_mode = 2
columns = 2
column_titles_visible = true
[node name="HSplitContainer" type="HSplitContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Browser" type="VBoxContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Options" type="HBoxContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Browser"]
layout_mode = 2
[node name="SearchBar" type="LineEdit" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Browser/Options"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
placeholder_text = "Search..."
clear_button_enabled = true
right_icon = ExtResource("1_ityvd")
[node name="SortMenu" type="MenuButton" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Browser/Options"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Sort Mode"
icon = ExtResource("3_0k1fm")
icon_alignment = 1
item_count = 4
popup/item_0/text = "Family"
popup/item_0/checkable = 2
popup/item_0/id = 1
popup/item_1/text = "Name"
popup/item_1/checkable = 2
popup/item_1/id = 2
popup/item_2/text = "Index"
popup/item_2/checkable = 2
popup/item_2/disabled = true
popup/item_3/text = "Count"
popup/item_3/checkable = 2
popup/item_3/id = 3
popup/item_3/disabled = true
[node name="OpenTextureFolderButton" type="Button" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Browser/Options"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Open folder in File Explorer"
icon = ExtResource("3_xdjfn")
flat = true
icon_alignment = 1
[node name="BrowserOverflowMenu" type="MenuButton" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Browser/Options"]
unique_name_in_owner = true
layout_mode = 2
icon = ExtResource("4_s4jwc")
item_count = 9
popup/item_0/text = "Keep Aspect Ratio"
popup/item_0/checkable = 1
popup/item_0/checked = true
popup/item_0/id = 1
popup/item_1/text = "Show Custom"
popup/item_1/checkable = 1
popup/item_1/checked = true
popup/item_2/text = "Show Family Name"
popup/item_2/checkable = 1
popup/item_2/id = 2
popup/item_3/text = "Show File Name"
popup/item_3/checkable = 1
popup/item_3/checked = true
popup/item_3/id = 3
popup/item_4/text = "Show File Type"
popup/item_4/checkable = 1
popup/item_4/checked = true
popup/item_4/id = 4
popup/item_5/text = "Show Resolution"
popup/item_5/checkable = 1
popup/item_5/id = 5
popup/item_6/id = 8
popup/item_6/separator = true
popup/item_7/text = "Show Usage Count"
popup/item_7/checkable = 1
popup/item_7/id = 6
popup/item_7/disabled = true
popup/item_8/text = "Show Texture Index"
popup/item_8/checkable = 1
popup/item_8/id = 7
popup/item_8/disabled = true
[node name="PanelContainer" type="PanelContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Browser"]
layout_mode = 2
size_flags_vertical = 3
[node name="MarginContainer" type="MarginContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Browser/PanelContainer"]
layout_mode = 2
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
[node name="Scroll" type="ScrollContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Browser/PanelContainer/MarginContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="TextureList" type="HFlowContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Browser/PanelContainer/MarginContainer/Scroll"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Panel" type="Panel" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Browser/PanelContainer/MarginContainer/Scroll/TextureList"]
custom_minimum_size = Vector2(128, 128)
layout_mode = 2
[node name="TextureRect2" type="TextureRect" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Browser/PanelContainer/MarginContainer/Scroll/TextureList/Panel"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("1_1vlw2")
expand_mode = 1
stretch_mode = 5
[node name="Preview" type="VBoxContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer"]
custom_minimum_size = Vector2(384, 0)
layout_mode = 2
[node name="VBoxContainer" type="VBoxContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview"]
layout_mode = 2
size_flags_vertical = 3
[node name="Panel" type="Panel" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer"]
custom_minimum_size = Vector2(384, 0)
layout_mode = 2
size_flags_vertical = 3
[node name="PreviewTexture" type="TextureRect" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/Panel"]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("1_1vlw2")
expand_mode = 1
stretch_mode = 5
[node name="PanelContainer" type="PanelContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer"]
layout_mode = 2
[node name="MarginContainer" type="MarginContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer"]
layout_mode = 2
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
[node name="Details" type="GridContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/h_separation = 16
columns = 2
[node name="FilterLabel" type="Label" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
text = "Texture Filter"
[node name="FilterOptions" type="OptionButton" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
size_flags_horizontal = 3
selected = 0
item_count = 2
popup/item_0/text = "Linear"
popup/item_1/text = "Nearest"
popup/item_1/id = 1
[node name="Position" type="Label" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
text = "Position"
[node name="PositionOptions" type="OptionButton" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
size_flags_horizontal = 3
selected = 0
item_count = 2
popup/item_0/text = "Scaled"
popup/item_1/text = "Tiled"
popup/item_1/id = 1
[node name="ZoomLabel" type="Label" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
visible = false
layout_mode = 2
text = "Zoom"
[node name="ZoomSlider" type="HSlider" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
visible = false
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
min_value = 0.5
max_value = 8.0
value = 0.5
[node name="PathLabel" type="Label" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
text = "Path"
[node name="HBoxContainer" type="HBoxContainer" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
[node name="PathBox" type="LineEdit" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
editable = false
[node name="PathCopyButton" type="Button" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details/HBoxContainer"]
layout_mode = 2
icon = ExtResource("7_2pq2g")
flat = true
[node name="FileTypeLabel" type="Label" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
text = "File Type"
[node name="FileTypeBox" type="LineEdit" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
size_flags_horizontal = 3
editable = false
[node name="ResolutionLabel" type="Label" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
text = "Resolution"
[node name="ResolutionBox" type="LineEdit" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
size_flags_horizontal = 3
editable = false
[node name="FileSizeLabel" type="Label" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
text = "File Size"
[node name="FileSizeBox" type="LineEdit" parent="TabContainer/Textures/VBoxContainer/HSplitContainer/HSplitContainer/Preview/VBoxContainer/PanelContainer/MarginContainer/Details"]
layout_mode = 2
size_flags_horizontal = 3
editable = false