From ee2bac28f91f0c5b70e898b848da8b8e22e42069 Mon Sep 17 00:00:00 2001 From: Chewico Date: Thu, 10 Jul 2025 23:10:33 +0200 Subject: [PATCH] Working on child window --- DeerStudio/imgui.ini | 22 +- .../src/DeerStudio/EditorEngine/API/Layout.h | 47 +-- .../API_Implementation/Layout.cpp | 315 +++++++++--------- roe/Editor/Panels/AssetExplorer/IconRender.as | 13 + roe/Editor/Panels/AssetExplorer/RootAssets.as | 8 +- roe/Editor/icons/mesh.ase | Bin 0 -> 802 bytes roe/Editor/icons/mesh.png | Bin 0 -> 515 bytes roe/Editor/icons/script.png | Bin 0 -> 422 bytes roe/Editor/icons/shader.png | Bin 270 -> 569 bytes roe/Editor/icons/texture.png | Bin 0 -> 453 bytes 10 files changed, 210 insertions(+), 195 deletions(-) create mode 100644 roe/Editor/icons/mesh.ase create mode 100644 roe/Editor/icons/mesh.png create mode 100644 roe/Editor/icons/script.png create mode 100644 roe/Editor/icons/texture.png diff --git a/DeerStudio/imgui.ini b/DeerStudio/imgui.ini index 3bfee56..7d8a2c1 100644 --- a/DeerStudio/imgui.ini +++ b/DeerStudio/imgui.ini @@ -10,31 +10,31 @@ Collapsed=0 [Window][Terrain Editor] Pos=925,24 -Size=355,413 +Size=355,434 Collapsed=0 DockId=0x00000006,0 [Window][Viewport] Pos=309,24 -Size=614,413 +Size=614,434 Collapsed=0 DockId=0x00000005,0 [Window][ViewportPannel] Pos=309,24 -Size=614,413 +Size=614,434 Collapsed=0 DockId=0x00000005,1 [Window][ShaderExplorer] -Pos=0,439 -Size=1280,281 +Pos=0,460 +Size=1280,260 Collapsed=0 DockId=0x00000004,0 [Window][TreePannel] Pos=0,24 -Size=307,413 +Size=307,434 Collapsed=0 DockId=0x00000001,0 @@ -46,7 +46,7 @@ DockId=0x00000004,0 [Window][PropertiesPannel] Pos=925,24 -Size=355,413 +Size=355,434 Collapsed=0 DockId=0x00000006,1 @@ -73,17 +73,17 @@ Collapsed=0 DockId=0x00000005,2 [Window][AssetExplorer] -Pos=0,439 -Size=1280,281 +Pos=0,460 +Size=1280,260 Collapsed=0 DockId=0x00000004,1 [Docking][Data] DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y Selected=0x34A4C10F - DockNode ID=0x00000003 Parent=0xA1672E74 SizeRef=1280,413 Split=X + DockNode ID=0x00000003 Parent=0xA1672E74 SizeRef=1280,434 Split=X DockNode ID=0x00000001 Parent=0x00000003 SizeRef=307,696 Selected=0xE45B9F93 DockNode ID=0x00000002 Parent=0x00000003 SizeRef=971,696 Split=X Selected=0x34A4C10F DockNode ID=0x00000005 Parent=0x00000002 SizeRef=614,454 CentralNode=1 Selected=0x34A4C10F DockNode ID=0x00000006 Parent=0x00000002 SizeRef=355,454 Selected=0xA35A27E3 - DockNode ID=0x00000004 Parent=0xA1672E74 SizeRef=1280,281 Selected=0x21191D0B + DockNode ID=0x00000004 Parent=0xA1672E74 SizeRef=1280,260 Selected=0x21191D0B diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API/Layout.h b/DeerStudio/src/DeerStudio/EditorEngine/API/Layout.h index 01c7305..1db6454 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API/Layout.h +++ b/DeerStudio/src/DeerStudio/EditorEngine/API/Layout.h @@ -5,26 +5,31 @@ class asIScriptFunction; class CScriptAny; namespace Deer { - namespace EditorEngine { - // Set up the colums to fit the pixelSize elements - void setupAutomaticColumns(int pixelSize); - // Set up the colums to the number - void setupColumns(int); - // Iterates to the next column - void nextColumn(); - // Ends the columns made with setupColumns - void endColumns(); + namespace EditorEngine { + // Set up the colums to fit the pixelSize elements + void setupAutomaticColumns(int pixelSize); + // Set up the colums to the number + void setupColumns(int); + // Iterates to the next column + void nextColumn(); + // Ends the columns made with setupColumns + void endColumns(); - // Renders a component node - bool componentNode(std::string&, CScriptAny*, asIScriptFunction*); - // Renders a component node with option to menu - bool componentNode_contextMenu(std::string&, CScriptAny*, asIScriptFunction*, asIScriptFunction*); - // Renders a tree leaf - void treeNode(std::string&, bool); - // Renders a tree node with its sub nodes - bool treeNodeRecursive(std::string&, bool, CScriptAny*, asIScriptFunction&); + // Renders a component node + bool componentNode(std::string&, CScriptAny*, asIScriptFunction*); + // Renders a component node with option to menu + bool componentNode_contextMenu(std::string&, CScriptAny*, + asIScriptFunction*, asIScriptFunction*); + // Renders a tree leaf + void treeNode(std::string&, bool); + // Renders a tree node with its sub nodes + bool treeNodeRecursive(std::string&, bool, CScriptAny*, + asIScriptFunction&); - void space(); - void space_params(int, int); - } -} \ No newline at end of file + // Call, x, y, border + void childWindow(CScriptAny*, asIScriptFunction*, int, int, bool); + + void space(); + void space_params(int, int); + } // namespace EditorEngine +} // namespace Deer \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Layout.cpp b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Layout.cpp index 87a1849..bbb3957 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Layout.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Layout.cpp @@ -1,196 +1,193 @@ #include "DeerStudio/EditorEngine/API/Layout.h" -#include "DeerStudio/EditorEngine/ErrorHandle.h" #include "DeerStudio/EditorEngine.h" +#include "DeerStudio/EditorEngine/ErrorHandle.h" #include "angelscript.h" -#include "scriptany.h" #include "imgui.h" +#include "scriptany.h" namespace Deer { - namespace EditorEngine { - void treeNode(std::string& txt, bool active) { - ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf | + namespace EditorEngine { + void treeNode(std::string& txt, bool active) { + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth; - if (active) - flags |= ImGuiTreeNodeFlags_Selected; + if (active) + flags |= ImGuiTreeNodeFlags_Selected; - ImGui::TreeNodeEx(txt.c_str(), flags); - } + ImGui::TreeNodeEx(txt.c_str(), flags); + } - bool treeNodeRecursive(std::string& txt, bool active, CScriptAny *data, asIScriptFunction& func) { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); - ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnDoubleClick | - ImGuiTreeNodeFlags_OpenOnArrow | - ImGuiTreeNodeFlags_SpanFullWidth | - ImGuiTreeNodeFlags_DefaultOpen; + bool treeNodeRecursive(std::string& txt, bool active, CScriptAny* data, + asIScriptFunction& func) { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnDoubleClick | + ImGuiTreeNodeFlags_OpenOnArrow | + ImGuiTreeNodeFlags_SpanFullWidth | + ImGuiTreeNodeFlags_DefaultOpen; - if (active) - flags |= ImGuiTreeNodeFlags_Selected; + if (active) + flags |= ImGuiTreeNodeFlags_Selected; - if (ImGui::TreeNodeEx(txt.c_str(), flags)) { - ImGui::PushID(txt.c_str()); - if (executingScriptContext && executingScriptContext->PushState() == asSUCCESS) { - AS_CHECK_ADDITIONAL_INFO( - executingScriptContext->Prepare(&func), - func.GetDeclaration() - ); + if (ImGui::TreeNodeEx(txt.c_str(), flags)) { + ImGui::PushID(txt.c_str()); + if (executingScriptContext && + executingScriptContext->PushState() == asSUCCESS) { + AS_CHECK_ADDITIONAL_INFO( + executingScriptContext->Prepare(&func), + func.GetDeclaration()); - AS_CHECK_ADDITIONAL_INFO( - executingScriptContext->SetArgObject(0, data), - func.GetDeclaration() - ); - - AS_CHECK_ADDITIONAL_INFO( - executingScriptContext->Execute(), - func.GetDeclaration() - ); - - executingScriptContext->PopState(); - } else { - ImGui::Text("Something failed"); - } + AS_CHECK_ADDITIONAL_INFO( + executingScriptContext->SetArgObject(0, data), + func.GetDeclaration()); - ImGui::PopID(); - ImGui::TreePop(); + AS_CHECK_ADDITIONAL_INFO(executingScriptContext->Execute(), + func.GetDeclaration()); + executingScriptContext->PopState(); + } else { + ImGui::Text("Something failed"); + } - ImGui::PopStyleVar(); - return true; - } + ImGui::PopID(); + ImGui::TreePop(); - ImGui::PopStyleVar(); - return false; - } + ImGui::PopStyleVar(); + return true; + } - bool componentNode(std::string& txt, CScriptAny* data, asIScriptFunction* func) { - - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4)); - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + ImGui::PopStyleVar(); + return false; + } - ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth | - ImGuiTreeNodeFlags_Framed | - ImGuiTreeNodeFlags_AllowItemOverlap | - ImGuiTreeNodeFlags_FramePadding | - ImGuiTreeNodeFlags_DefaultOpen; + bool componentNode(std::string& txt, CScriptAny* data, + asIScriptFunction* func) { - if (ImGui::TreeNodeEx(txt.c_str(), flags)){ - ImGui::Dummy(ImVec2(0, 10)); - ImGui::PushID(txt.c_str()); - if (executingScriptContext && executingScriptContext->PushState() == asSUCCESS) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); - AS_CHECK( executingScriptContext->Prepare(func)); + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth | + ImGuiTreeNodeFlags_Framed | + ImGuiTreeNodeFlags_AllowItemOverlap | + ImGuiTreeNodeFlags_FramePadding | + ImGuiTreeNodeFlags_DefaultOpen; - AS_CHECK(executingScriptContext->SetArgObject(0, data)); - - AS_CHECK(executingScriptContext->Execute()); - - executingScriptContext->PopState(); - } else { - ImGui::Text("Something failed"); - } + if (ImGui::TreeNodeEx(txt.c_str(), flags)) { + ImGui::Dummy(ImVec2(0, 10)); + ImGui::PushID(txt.c_str()); + if (executingScriptContext && + executingScriptContext->PushState() == asSUCCESS) { - ImGui::Dummy(ImVec2(0, 10)); - ImGui::PopID(); - ImGui::TreePop(); + AS_CHECK(executingScriptContext->Prepare(func)); - ImGui::PopStyleVar(2); - return true; - } + AS_CHECK(executingScriptContext->SetArgObject(0, data)); - ImGui::PopStyleVar(2); - return false; - } - - bool componentNode_contextMenu(std::string& txt, CScriptAny* data, asIScriptFunction* func, asIScriptFunction* menu) { - - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4)); - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + AS_CHECK(executingScriptContext->Execute()); - ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth | - ImGuiTreeNodeFlags_Framed | - ImGuiTreeNodeFlags_AllowItemOverlap | - ImGuiTreeNodeFlags_FramePadding | - ImGuiTreeNodeFlags_DefaultOpen; + executingScriptContext->PopState(); + } else { + ImGui::Text("Something failed"); + } - if (ImGui::TreeNodeEx(txt.c_str(), flags)){ - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10)); - if (ImGui::BeginPopupContextItem(txt.c_str())) { - if (executingScriptContext && executingScriptContext->PushState() == asSUCCESS) { + ImGui::Dummy(ImVec2(0, 10)); + ImGui::PopID(); + ImGui::TreePop(); - AS_CHECK( executingScriptContext->Prepare(menu)); + ImGui::PopStyleVar(2); + return true; + } - AS_CHECK(executingScriptContext->SetArgObject(0, data)); - - AS_CHECK(executingScriptContext->Execute()); - - executingScriptContext->PopState(); - } else { - ImGui::Text("Something failed"); - } - ImGui::EndPopup(); - } - ImGui::PopStyleVar(); + ImGui::PopStyleVar(2); + return false; + } - ImGui::Dummy(ImVec2(0, 10)); - ImGui::PushID(txt.c_str()); - if (executingScriptContext && executingScriptContext->PushState() == asSUCCESS) { + bool componentNode_contextMenu(std::string& txt, CScriptAny* data, + asIScriptFunction* func, + asIScriptFunction* menu) { - AS_CHECK( executingScriptContext->Prepare(func)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); - AS_CHECK(executingScriptContext->SetArgObject(0, data)); - - AS_CHECK(executingScriptContext->Execute()); - - executingScriptContext->PopState(); - } else { - ImGui::Text("Something failed"); - } + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth | + ImGuiTreeNodeFlags_Framed | + ImGuiTreeNodeFlags_AllowItemOverlap | + ImGuiTreeNodeFlags_FramePadding | + ImGuiTreeNodeFlags_DefaultOpen; - ImGui::Dummy(ImVec2(0, 10)); - ImGui::PopID(); - ImGui::TreePop(); + if (ImGui::TreeNodeEx(txt.c_str(), flags)) { + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, + ImVec2(10, 10)); + if (ImGui::BeginPopupContextItem(txt.c_str())) { + if (executingScriptContext && + executingScriptContext->PushState() == asSUCCESS) { - ImGui::PopStyleVar(2); - return true; - } + AS_CHECK(executingScriptContext->Prepare(menu)); - ImGui::PopStyleVar(2); - return false; - } - - void setupColumns(int i) { - ImGui::Columns(i, nullptr, false); - } - - void setupAutomaticColumns(int pixelSize) { - float width = ImGui::GetWindowContentRegionWidth(); - - if (width < pixelSize) { - ImGui::Columns(); - return; - } - - int cols = (int)(width / (pixelSize)); - float componentWidth = width / (float)cols; - - ImGui::Columns(cols, 0, false); - } - - void endColumns() { - ImGui::Columns(); - } - - void nextColumn() { - ImGui::NextColumn(); - } - - void space() { - ImGui::Dummy(ImVec2(10, 10)); - } + AS_CHECK(executingScriptContext->SetArgObject(0, data)); - void space_params(int x, int y) { - ImGui::Dummy(ImVec2(x, y)); - } - } -} \ No newline at end of file + AS_CHECK(executingScriptContext->Execute()); + + executingScriptContext->PopState(); + } else { + ImGui::Text("Something failed"); + } + ImGui::EndPopup(); + } + ImGui::PopStyleVar(); + + ImGui::Dummy(ImVec2(0, 10)); + ImGui::PushID(txt.c_str()); + if (executingScriptContext && + executingScriptContext->PushState() == asSUCCESS) { + + AS_CHECK(executingScriptContext->Prepare(func)); + + AS_CHECK(executingScriptContext->SetArgObject(0, data)); + + AS_CHECK(executingScriptContext->Execute()); + + executingScriptContext->PopState(); + } else { + ImGui::Text("Something failed"); + } + + ImGui::Dummy(ImVec2(0, 10)); + ImGui::PopID(); + ImGui::TreePop(); + + ImGui::PopStyleVar(2); + return true; + } + + ImGui::PopStyleVar(2); + return false; + } + + void setupColumns(int i) { ImGui::Columns(i, nullptr, false); } + + void setupAutomaticColumns(int pixelSize) { + float width = ImGui::GetWindowContentRegionWidth(); + + if (width < pixelSize) { + ImGui::Columns(); + return; + } + + int cols = (int)(width / (pixelSize)); + float componentWidth = width / (float)cols; + + ImGui::Columns(cols, 0, false); + } + + void childWindow(CScriptAny* data, asIScriptFunction* func, int width, + int height, bool border) {} + + void endColumns() { ImGui::Columns(); } + + void nextColumn() { ImGui::NextColumn(); } + + void space() { ImGui::Dummy(ImVec2(10, 10)); } + + void space_params(int x, int y) { ImGui::Dummy(ImVec2(x, y)); } + } // namespace EditorEngine +} // namespace Deer \ No newline at end of file diff --git a/roe/Editor/Panels/AssetExplorer/IconRender.as b/roe/Editor/Panels/AssetExplorer/IconRender.as index ea87afd..918f3b4 100644 --- a/roe/Editor/Panels/AssetExplorer/IconRender.as +++ b/roe/Editor/Panels/AssetExplorer/IconRender.as @@ -11,6 +11,19 @@ bool drawFolder(string&in name) { return click; } +bool drawIcon(string&in name, string&in iconName) { + bool click = false; + UI::drawIconCentered(iconName, 64); + + if (UI::isItemClicked(0) and UI::isMouseDoubleClicked(0)) { + click = true; + } + + UI::textCenter(name); + UI::nextColumn(); + return click; +} + bool drawFile(string&in name) { bool click = false; UI::drawIconCentered("file", 64); diff --git a/roe/Editor/Panels/AssetExplorer/RootAssets.as b/roe/Editor/Panels/AssetExplorer/RootAssets.as index 0403e47..0fe25fb 100644 --- a/roe/Editor/Panels/AssetExplorer/RootAssets.as +++ b/roe/Editor/Panels/AssetExplorer/RootAssets.as @@ -2,10 +2,10 @@ AssetType renderRootAssets() { AssetType selectedAssetType = AssetType::None; - if (drawFolder("Scripts")) selectedAssetType = AssetType::None; - if (drawFolder("Meshes")) selectedAssetType = AssetType::Mesh; - if (drawFolder("Textures")) selectedAssetType = AssetType::None; - if (drawFolder("Shaders")) selectedAssetType = AssetType::Shader; + if (drawIcon("Scripts", "script")) selectedAssetType = AssetType::None; + if (drawIcon("Meshes", "mesh")) selectedAssetType = AssetType::Mesh; + if (drawIcon("Textures", "texture")) selectedAssetType = AssetType::None; + if (drawIcon("Shaders", "shader")) selectedAssetType = AssetType::Shader; return selectedAssetType; } diff --git a/roe/Editor/icons/mesh.ase b/roe/Editor/icons/mesh.ase new file mode 100644 index 0000000000000000000000000000000000000000..dd58515384eb50d551c336724ea5c1589220d100 GIT binary patch literal 802 zcmcJMZ%7ky9EX3FYf&IkgcOnI(4ho6hkuf8E~*u&gp-&`nuVopluNC(F(}B$*osw5 ztX+zw7J-h0p_#2{6{9w*;V5*{y3v+QHfiRY60gsQ6nfwHxQ8G2=6Sxq6RafUOJ4%n ziH9Nygpgx+mxo$D{+H9e6@>i!p15S4gk=-;*P8OLlOsex<$|&d8muqO0Zob>pub57 zPIT9U(U%tRS1cdA9V`P?&qQE>xe+W;W`pG=X`q-c1f|k5py0l1}ar5uu4%5YIYgGez6#wsHg)!>7Rh6j$+WD7I7-3p6G?O))x)Q?D{D~cg7xvvy>6e z8Cz1R`MWKv$4`w%c$v=+(yD2bL=?~|XC z>7Lf~bk0|fzRRESXvT)ZH#7snVAa|E=@GX2mTkAMH7hLHtkhc`(!s&l4}EWEyYubA zu9*1&ZRT^XX{FGnoN5m(c7H@wf fsSxrnTll(CvXDs0DfH&$`fW22=Wp{Y0 zCc#oldBQ57@$sYcqZaoT;*lz5KvSsoxj;`$?JN&J7tk2q zE#u_d6Z<00H$-*>u+AB}-VxFWfJ&CS-V$380G%avy(c&mfR!G1yD8fK)_c}_9|3JG z*RIpi_8Df3_W!fE;NQUrv{nfj3ov=T0Qsk>BuSDt^8%kk5 zGb#jha&23#UvygkSTRTUtAd)?wd}`g9u5a)?%)09&-IB1&KUgp%e{M{28Uvcz~(8J z7|vNP5A={ujqG~;`mEwkiOSD%CBj#v7Q|{8mCc>$CUBPNZhMu_l1m{{4N5M;A#D!9 zjI~GmLV1cTRMs-^2XP9pE=W?EV!+8-A>h@Z_25qpuU66a7?;m2PedLpKe+Ajh2RwZ zvq^%6x1|=$tk>Hq;TU}BYw{6k#Vw4nat38*ls(TetFazpc6x5Uo}q(1M(+Cld8f*@ za=znzCaTaRH-YiO_Xa)v4#R7^4c0RVere$0_+)5O5_>@SQ}n?-OfDCgjTAWfJ9gS7 z#4#$pV3b_&it+fWUsY1SZ@+#1bNSa_>uuV9$DTDlqwTXN326mh?Kx#_AN!Le47o=1~^@^_u)}I;xF1F;N-Dv595b6r`6vl|Fr~$ OKZB>MpUXO@geCyBqpMy3 literal 0 HcmV?d00001 diff --git a/roe/Editor/icons/shader.png b/roe/Editor/icons/shader.png index 80393c21771db11e9a27ec34c7ed24b6d3e231ec..97b68de1d34d21ebf783de4ada3f677078fe8d47 100755 GIT binary patch literal 569 zcmV-90>=G`P)E^o!`}3!|ZZb zG&;TG9DOD-7*N^)cdeC!1|Hp6#``@@RxQtl(FpX~Dsy&i<%1A1GYXxtT5Cm)2D1Qf z=T}q8s>AefROUT{@MAITjCz2UOF`BFbpXzc@Nj&UVOkS3s0>~y>_$ZfM5_-v1-b#Q z8`Pe+-W~QZkaVff$RgQK@pB4b%+E>BOJADrGb|w!8`)ahF+xORvG3Z*dyMZ zz9Q=uwgbSe`&V^mRPXp%GBO~`py#r;!kPe64H&z!TleY=@Lu3)ygmT%W$ zAj8{X?zl>7n8hxM9#IY05zGyJwDVjtqg}=fT^Ky3T z%gLtS?dYJmjQ~lHPEUEcqS^1EPo7l)kko?FA?{#hR}MEqv^B=<-QXW38&hF+|7@un zZsoH=DqMECUu3SEkqw+Fej?K*L3pxA7$0Z^-%GmH;=3 zt$~h2L<5~*4RodOzX=far0{qGpQ9mloAR<*005KIltASu%p<5W@fEE_Bsz{Y{vQKY z6Q@S*;zWT{;C(xAYqwpT%v(xi^6l2BMOokss&kAQ(e{e_*DO=qY`|kC`_?SS3(pqU UmC@?-fB*mh07*qoM6N<$f&w;m82|tP diff --git a/roe/Editor/icons/texture.png b/roe/Editor/icons/texture.png new file mode 100644 index 0000000000000000000000000000000000000000..7ccbe36366a2c26048eee0ef123bcf4a1b4b683d GIT binary patch literal 453 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEVC?a9aSW-L^LCcCH?yNiYx>do zOL{j3eYpA~L&S4?2b;+(g-K34T}QhnvcIXZcb-E$Fo~ez==b##X@zHkJn|Bx7#Py3AkRIf8IP}?~S)EelpQDe?#)WMCf%f zp1bDf^7i}R%~F3p{MoW%>%J|Fr?%nGk%L6 r0QnNE`W