1 module unecht.core.components.editor.ui.menuSystem; 2 3 version(UEIncludeEditor): 4 5 import unecht.core.component; 6 import unecht.core.components.sceneNode; 7 import unecht.core.entity; 8 9 import derelict.imgui.imgui; 10 11 /// 12 final class UEEditorMenuItem : UEComponent 13 { 14 mixin(UERegisterObject!()); 15 16 import unecht.core.components.editor.menus; 17 18 EditorMenuItem menuItem; 19 20 void render() 21 { 22 import std..string:toStringz; 23 24 if(sceneNode.children.length>0) 25 { 26 auto open = igBeginMenu(this.entity.name.toStringz); 27 scope(exit){if(open)igEndMenu();} 28 29 if(open) 30 { 31 foreach(c; sceneNode.children) 32 { 33 auto subitem = c.entity.getComponent!UEEditorMenuItem; 34 if(subitem) 35 subitem.render(); 36 } 37 } 38 } 39 else 40 { 41 if(menuItem.func) 42 { 43 auto isValid = menuItem.validateFunc?menuItem.validateFunc():true; 44 45 if(igMenuItem(this.entity.name.toStringz,"",false,isValid)) 46 { 47 if(isValid) 48 { 49 menuItem.func(); 50 } 51 } 52 } 53 } 54 } 55 } 56 57 import unecht.core.assets.texture; 58 59 /// 60 final class UEEditorMenuBar : UEComponent 61 { 62 mixin(UERegisterObject!()); 63 64 static ImVec2 _size; 65 66 static @property float height() { return _size.y; } 67 68 private static ubyte[] texImg = cast(ubyte[])import("playbuttons.png"); 69 70 private UETexture2D tex; 71 72 override void onCreate() { 73 super.onCreate; 74 75 tex = new UETexture2D(); 76 tex.loadFromMemFile(texImg); 77 78 addMenuItem("main", sceneNode); 79 addMenuItem("edit", sceneNode); 80 addMenuItem("assets", sceneNode); 81 addMenuItem("entity", sceneNode); 82 83 import unecht.core.componentManager; 84 85 foreach(ref m; UEComponentsManager.menuItems) 86 { 87 import std..string:split; 88 auto pathElements = split(m.name, "/"); 89 90 attachItem(pathElements,m); 91 } 92 } 93 94 private UEEditorMenuItem addMenuItem(string name, UESceneNode node) 95 { 96 auto e = UEEntity.create(name, node); 97 return e.addComponent!UEEditorMenuItem; 98 } 99 100 private void attachItem(string[] path, EditorMenuItem menuItem) 101 { 102 assert(this.sceneNode); 103 104 UESceneNode node = sceneNode; 105 while(path.length > 1) 106 { 107 auto search = findMatchingMenu(path[0], node); 108 if(!search) 109 { 110 search = addMenuItem(path[0], node); 111 } 112 113 assert(search); 114 assert(search.sceneNode); 115 116 path = path[1..$]; 117 node = search.sceneNode; 118 } 119 120 auto item = addMenuItem(path[0], node); 121 item.menuItem = menuItem; 122 } 123 124 private UEEditorMenuItem findMatchingMenu(string name, UESceneNode node) 125 { 126 foreach(c; node.children) 127 { 128 auto item = c.entity.getComponent!UEEditorMenuItem; 129 if(item) 130 { 131 if(item.entity.name == name) 132 return item; 133 } 134 } 135 136 return null; 137 } 138 139 //TODO: #127 140 void render() 141 { 142 auto menuBar = igBeginMainMenuBar(); 143 igGetWindowSize(&_size); 144 scope(exit){if(menuBar)igEndMainMenuBar();} 145 146 if(menuBar) 147 { 148 foreach(c; sceneNode.children) 149 { 150 auto subitem = c.entity.getComponent!UEEditorMenuItem; 151 if(subitem) 152 subitem.render(); 153 } 154 155 renderControlButtons(); 156 } 157 } 158 159 private void renderControlButtons() 160 { 161 import unecht.ue:ue; 162 import unecht.core.components.internal.gui:UEGui; 163 164 static buttonSize = ImVec2(22,22); 165 static texSize = ImVec2(48,16); 166 static tileSize = ImVec2(16,16); 167 168 if(UEGui.ImageAtlasButton(tex.driverHandle, buttonSize, tileSize, texSize, ImVec2(0,0), !ue.scene.playing)) 169 ue.scene.playing = true; 170 171 igSameLine(); 172 173 if(UEGui.ImageAtlasButton(tex.driverHandle, buttonSize, tileSize, texSize, ImVec2(1,0), !ue.scene.playing)) 174 ue.scene.step(); 175 176 igSameLine(); 177 178 if(UEGui.ImageAtlasButton(tex.driverHandle, buttonSize, tileSize, texSize, ImVec2(2,0), ue.scene.playing)) 179 ue.scene.playing = false; 180 } 181 }