From 5018464a410fc2ea4c8c90d2c0a02d603b3736ef Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 10 Jun 2020 14:13:01 +0200 Subject: [PATCH] Demo GUI fixes and improvements plus some shortcuts -added option to override components (by remove them before adding) -added shortcuts for tools -fixed mouse scroll on WASM -addding entity filtering option (WIP) -added some tooltips -remove Components duplicates in ComponentManipulator menu -fixed ImGUI controls IDs -added possibility to change values of component to add --- demos/source/app.d | 124 +++++++++++++++++++------ demos/source/demos/particles.d | 44 ++++----- demos/source/demos/snake.d | 10 ++- demos/source/gui/manager.d | 159 ++++++++++++++++++++++----------- 4 files changed, 237 insertions(+), 100 deletions(-) diff --git a/demos/source/app.d b/demos/source/app.d index 808426f..d526f97 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -71,6 +71,7 @@ struct Launcher float tool_repeat = 0; float repeat_time = 0; bool tool_show = true; + bool override_ = true; bool tool_mode = true; ToolCircle* tool_circle; @@ -154,6 +155,20 @@ struct Launcher } } + void overrideComponent(IteratorSystem.EntitiesData data) + { + foreach(i;0..data.length) + { + vec2 rel_vec = data.location[i] - position; + float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; + if(length < size2) + { + gEM.removeComponents(data.entity[i].id, rem_comps); + gEM.addComponents(data.entity[i].id, add_comps); + } + } + } + void removeComponent(IteratorSystem.EntitiesData data) { foreach(i;0..data.length) @@ -200,7 +215,13 @@ struct Launcher { ComponentRef[1] comps = [gui_manager.getSelectedComponent()]; iterator.add_comps = comps; - manager.callEntitiesFunction!IteratorSystem(&iterator.addComponent); + if(launcher.override_) + { + ushort[1] rcomps = [gui_manager.getSelectedComponent().component_id]; + iterator.rem_comps = rcomps; + manager.callEntitiesFunction!IteratorSystem(&iterator.overrideComponent); + } + else manager.callEntitiesFunction!IteratorSystem(&iterator.addComponent); } else { @@ -330,6 +351,33 @@ void mainLoop(void* arg) *cast(bool*)arg = false; return; } + else if(event.type == SDL_KEYDOWN) + { + if(event.key.state) + { + if(SDL_GetModState() & KMOD_CTRL) + { + switch(event.key.keysym.scancode) + { + case SDL_SCANCODE_1:launcher.used_tool=Tool.entity_spawner;break; + case SDL_SCANCODE_2:launcher.used_tool=Tool.component_manipulator;break; + case SDL_SCANCODE_3:launcher.used_tool=Tool.selector;break; + default:break; + } + } + else + { + switch(event.key.keysym.scancode) + { + case SDL_SCANCODE_1:break; + case SDL_SCANCODE_2:break; + case SDL_SCANCODE_3:break; + case SDL_SCANCODE_4:break; + default:break; + } + } + } + } else if(event.type == SDL_WINDOWEVENT) { switch(event.window.event) @@ -383,17 +431,32 @@ void mainLoop(void* arg) { float sign = 1; if(event.wheel.y < 0)sign = -1; - float val = sign * event.wheel.y * launcher.tool_repeat * 0.25; + float val = /*sign * event.wheel.y */ launcher.tool_repeat * 0.25; if(val < 0.1)val = 0.1; launcher.tool_repeat -= sign * val; if(launcher.tool_repeat < 0)launcher.tool_repeat = 0; else if(launcher.tool_repeat > 1000)launcher.tool_repeat = 1000; } + else if(SDL_GetModState() & KMOD_SHIFT) + { + int sign = 1; + if(event.wheel.y < 0)sign = -1; + switch(launcher.used_tool) + { + case Tool.entity_spawner: + launcher.gui_manager.selectTemplate(launcher.gui_manager.selected_template-sign); + break; + case Tool.component_manipulator: + launcher.gui_manager.selectComponent(launcher.gui_manager.selected_component-sign); + break; + default:break; + } + } else { int sign = 1; if(event.wheel.y < 0)sign = -1; - int val = sign * event.wheel.y * launcher.tool_size / 4; + int val = /*sign * event.wheel.y */ launcher.tool_size / 4; if(val < 1)val = 1; launcher.tool_size -= sign * val; if(launcher.tool_size < 1)launcher.tool_size = 1; @@ -503,22 +566,11 @@ void mainLoop(void* arg) } if(igBeginMenu("Show",true)) { - if(igMenuItemBool("Statistics",null,launcher.show_stat_wnd,true)) - { - launcher.show_stat_wnd = !launcher.show_stat_wnd; - } - else if(igMenuItemBool("Demo",null,launcher.show_demo_wnd,true)) - { - launcher.show_demo_wnd = !launcher.show_demo_wnd; - } - else if(igMenuItemBool("Tips",null,launcher.show_tips,true)) - { - launcher.show_tips = !launcher.show_tips; - } - else if(igMenuItemBool("Virual keys",null,launcher.show_virtual_keys_wnd,true)) - { - launcher.show_virtual_keys_wnd = !launcher.show_virtual_keys_wnd; - } + igMenuItemBoolPtr("Statistics",null,&launcher.show_stat_wnd,true); + igMenuItemBoolPtr("Demo",null,&launcher.show_demo_wnd,true); + igMenuItemBoolPtr("Tips",null,&launcher.show_tips,true); + igMenuItemBoolPtr("Virual keys",null,&launcher.show_virtual_keys_wnd,true); + igMenuItemBoolPtr("Profile",null,&launcher.show_profile_wnd,true); igEndMenu(); } if(igBeginMenu("Style",true)) @@ -655,12 +707,25 @@ void mainLoop(void* arg) } igEndCombo(); } + if(igIsItemHovered(0))igSetTooltip("Select tool (CTRL + 1,2,3)"); igCheckbox("Show Tool", &launcher.tool_show); + if(igIsItemHovered(0))igSetTooltip("Show/hide graphical tool representation"); + if(launcher.used_tool == Tool.component_manipulator) + { + igSameLine(0,4); + igCheckbox("Override", &launcher.override_); + } //igSelectable("Selectabe",false,ImGuiSelectableFlags_None,ImVec2(0,0)); - if(igRadioButtonBool("Add", launcher.tool_mode))launcher.tool_mode = true; - igSameLine(0,0); - if(igRadioButtonBool("Remove", !launcher.tool_mode))launcher.tool_mode = false; + if(launcher.used_tool != Tool.selector) + { + if(igRadioButtonBool("Add", launcher.tool_mode))launcher.tool_mode = true; + if(igIsItemHovered(0))igSetTooltip("Tool should adding (Entities or components)"); + igSameLine(0,4); + if(igRadioButtonBool("Remove", !launcher.tool_mode))launcher.tool_mode = false; + if(igIsItemHovered(0))igSetTooltip("Tool should removing (Entities or components)"); + } + igSliderInt("Tool size", &launcher.tool_size, 0, 256, null); igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4); launcher.gui_manager.toolGui(); @@ -668,7 +733,16 @@ void mainLoop(void* arg) } igEndGroup(); ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 2, ImDrawCornerFlags_All, 1); - + + //igBeginGroup(); + if(igCollapsingHeader("Filter", ImGuiTreeNodeFlags_SpanAvailWidth)) + { + igIndent(8); + launcher.gui_manager.filterGUI(); + igUnindent(8); + } + //igEndGroup(); + //ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 2, ImDrawCornerFlags_All, 1); //igEndChild(); //igEndChildFrame(); @@ -975,8 +1049,8 @@ int app_main(int argc, char** argv) import demos.space_invaders; import demos.particles; // launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); - // launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); - launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); + launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); + // launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); } int key_num; diff --git a/demos/source/demos/particles.d b/demos/source/demos/particles.d index 6ed8ea7..b58b775 100644 --- a/demos/source/demos/particles.d +++ b/demos/source/demos/particles.d @@ -473,12 +473,13 @@ void particlesStart() launcher.gui_manager.addSystem(DampingSystem.system_id,"Damping System"); launcher.gui_manager.addSystem(ParticleLifeSystem.system_id,"Particle Life System"); - launcher.gui_manager.addComponent(CColor(),"Color (white)"); - launcher.gui_manager.addComponent(CColor(0xFF101540),"Color (red)"); - launcher.gui_manager.addComponent(CColor(0xFF251010),"Color (blue)"); - launcher.gui_manager.addComponent(CColor(0xFF102010),"Color (green)"); - launcher.gui_manager.addComponent(CAttractor(0.1),"Attractor (str 0.1)"); - launcher.gui_manager.addComponent(CForceRange(vec2(5,40)),"ForceRange (5,40)"); + // launcher.gui_manager.addComponent(CColor(),"Color (white)"); + // launcher.gui_manager.addComponent(CColor(0xFF101540),"Color (red)"); + // launcher.gui_manager.addComponent(CColor(0xFF251010),"Color (blue)"); + // launcher.gui_manager.addComponent(CColor(0xFF102010),"Color (green)"); + launcher.gui_manager.addComponent(CColor(0xFF101540),"Color"); + launcher.gui_manager.addComponent(CAttractor(0.1),"Attractor"); + launcher.gui_manager.addComponent(CForceRange(vec2(5,40)),"ForceRange"); launcher.gui_manager.addComponent(CVelocity(),"Velocity"); launcher.gui_manager.addComponent(CDamping(),"Damping"); launcher.gui_manager.addComponent(CVortex(),"Vortex"); @@ -487,28 +488,29 @@ void particlesStart() EntityTemplate* tmpl; EntityTemplate* base_tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CColor.component_id, CVelocity.component_id, CDamping.component_id].staticArray); + base_tmpl.getComponent!CColor().value = 0xFF251010; launcher.gui_manager.addTemplate(base_tmpl,"Particle"); - tmpl = launcher.manager.allocateTemplate(base_tmpl); - tmpl.getComponent!CColor().value = 0xFF251010; - launcher.gui_manager.addTemplate(tmpl,"Particle (blue)"); - tmpl = launcher.manager.allocateTemplate(base_tmpl); - tmpl.getComponent!CColor().value = 0xFF102010; - launcher.gui_manager.addTemplate(tmpl,"Particle (green)"); - tmpl = launcher.manager.allocateTemplate(base_tmpl); - tmpl.getComponent!CColor().value = 0xFF101540; - launcher.gui_manager.addTemplate(tmpl,"Particle (red)"); + // tmpl = launcher.manager.allocateTemplate(base_tmpl); + // tmpl.getComponent!CColor().value = 0xFF251010; + // launcher.gui_manager.addTemplate(tmpl,"Particle (blue)"); + // tmpl = launcher.manager.allocateTemplate(base_tmpl); + // tmpl.getComponent!CColor().value = 0xFF102010; + // launcher.gui_manager.addTemplate(tmpl,"Particle (green)"); + // tmpl = launcher.manager.allocateTemplate(base_tmpl); + // tmpl.getComponent!CColor().value = 0xFF101540; + // launcher.gui_manager.addTemplate(tmpl,"Particle (red)"); // tmpl = launcher.manager.allocateTemplate(tmpl, [CDamping.component_id].staticArray); // launcher.gui_manager.addTemplate(tmpl,"Particle (damping)"); - tmpl = launcher.manager.allocateTemplate(tmpl); - tmpl.getComponent!CDamping().power = 4; - launcher.gui_manager.addTemplate(tmpl,"Particle (damping!)"); + // tmpl = launcher.manager.allocateTemplate(tmpl); + // tmpl.getComponent!CDamping().power = 4; + // launcher.gui_manager.addTemplate(tmpl,"Particle (damping!)"); tmpl = launcher.manager.allocateTemplate([CAttractor.component_id, CLocation.component_id, CForceRange.component_id].staticArray); launcher.gui_manager.addTemplate(tmpl,"Attractor"); tmpl = launcher.manager.allocateTemplate(tmpl, [CVortex.component_id].staticArray); launcher.gui_manager.addTemplate(tmpl,"Vortex"); - tmpl = launcher.manager.allocateTemplate(tmpl); - tmpl.getComponent!CVortex().strength = -0.6; - launcher.gui_manager.addTemplate(tmpl,"Vortex (reversed)"); + // tmpl = launcher.manager.allocateTemplate(tmpl); + // tmpl.getComponent!CVortex().strength = -0.6; + // launcher.gui_manager.addTemplate(tmpl,"Vortex (reversed)"); } diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index f46009c..579bc54 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -852,10 +852,12 @@ void snakeStart() launcher.gui_manager.addComponent(CApple(),"Apple"); launcher.gui_manager.addComponent(CSnake(),"Snake"); - launcher.gui_manager.addComponent(CParticle(1000),"Particle (1s)"); - launcher.gui_manager.addComponent(CParticleVector(vec2(0,1)),"Particle Vector (UP)"); + launcher.gui_manager.addComponent(CParticle(1000),"Particle"); + launcher.gui_manager.addComponent(CParticleVector(vec2(0,1)),"Particle Vector"); launcher.gui_manager.addComponent(CInput(),"Input"); - launcher.gui_manager.addComponent(CMovement(CMovement.Direction.up),"Movement (UP)"); + launcher.gui_manager.addComponent(CMovement(CMovement.Direction.up),"Movement"); + //launcher.gui_manager.addComponent(CAnimation(),"Movement"); + launcher.gui_manager.addComponent(CILocation(),"Int Location"); launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System"); launcher.gui_manager.addSystem(InputSystem.system_id,"Input System"); @@ -864,6 +866,8 @@ void snakeStart() launcher.gui_manager.addSystem(AnimationSystem.system_id,"Animation System"); launcher.gui_manager.addSystem(ParticleSystem.system_id,"Particle Life System"); launcher.gui_manager.addSystem(ParticleMovementSystem.system_id,"Particle Movement System"); + launcher.gui_manager.addSystem(DrawAppleSystem.system_id,"Draw Apple System"); + launcher.gui_manager.addSystem(DrawSnakeSystem.system_id,"Draw Snake System"); snake.snake_destroy_particle_frames = Mallocator.makeArray([vec4(64,144,16,16)*px,vec4(80,144,16,16)*px,vec4(96,144,16,16)*px,vec4(112,144,16,16)*px].staticArray); diff --git a/demos/source/gui/manager.d b/demos/source/gui/manager.d index b7c8678..4ae9688 100644 --- a/demos/source/gui/manager.d +++ b/demos/source/gui/manager.d @@ -28,8 +28,24 @@ struct GUIManager Vector!TemplateGUI templates; Vector!ComponentEditGUI edit_components; - uint selected_tempalte = 0; - uint selected_component = 0; + int selected_template = 0; + int selected_component = 0; + + void selectTemplate(int id) + { + if(templates.length == 0)return; + selected_template = id; + while(selected_template < 0)selected_template += cast(int)templates.length; + while(selected_template >= templates.length)selected_template -= cast(int)templates.length; + } + + void selectComponent(int id) + { + if(components.length == 0)return; + selected_component = id; + while(selected_component < 0)selected_component += cast(int)components.length; + while(selected_component >= components.length)selected_component -= cast(int)components.length; + } void clear() { @@ -51,13 +67,13 @@ struct GUIManager systems.clear(); templates.clear(); components.clear(); - selected_tempalte = 0; + selected_template = 0; selected_component = 0; } EntityTemplate* getSelectedTemplate() { - if(templates.length > selected_tempalte)return templates[selected_tempalte].tmpl; + if(templates.length > selected_template)return templates[selected_template].tmpl; else return null; } @@ -271,57 +287,65 @@ struct GUIManager } } + void componentGUI(ushort comp_id, void* data_ptr) + { + vec4 color; + if(comp_id >= edit_components.length)return; + if(edit_components[comp_id].used) + { + if(igCollapsingHeader(edit_components[comp_id].name, ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen)) + { + igIndent(8); + foreach(ref VariableGUI var;edit_components[comp_id].variables[0 .. edit_components[comp_id].used]) + { + igPushIDPtr(&var); + switch(var.type) + { + case VariableGUI.Type.byte_: + igDragScalarClamp(var.name, ImGuiDataType_S8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.ubyte_: + igDragScalarClamp(var.name, ImGuiDataType_U8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.short_: + igDragScalarClamp(var.name, ImGuiDataType_S16, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.ushort_: + igDragScalarClamp(var.name, ImGuiDataType_U16, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.int_: + igDragScalarClamp(var.name, ImGuiDataType_S32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.uint_: + igDragScalarClamp(var.name, ImGuiDataType_U32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.float_: + igDragScalarClamp(var.name, ImGuiDataType_Float, data_ptr+var.offset, 0.1, cast(void*)&var.float_.min, cast(void*)&var.float_.max, "%2.2f", 1); + break; + case VariableGUI.Type.color: + color = colorUintToVec4(*cast(uint*)(data_ptr+var.offset)); + if(igColorEdit4(var.name, color.data, ImGuiColorEditFlags_None)) + *cast(uint*)(data_ptr+var.offset) = colorVec4ToUint(color); + break; + default:break; + } + igPopID(); + } + //igPopID(); + igUnindent(8); + } + } + } + void entityComponentsGUI() { - EntityTemplate* tmpl = templates[selected_tempalte].tmpl; + EntityTemplate* tmpl = templates[selected_template].tmpl; EntityManager.EntityInfo* info = tmpl.info; - void* data_ptr = tmpl.entity_data.ptr; - vec4 color; foreach(comp_id; info.components) { - if(comp_id >= edit_components.length)break; + void* data_ptr = tmpl.entity_data.ptr; void* comp_ptr = data_ptr + info.tmpl_deltas[comp_id]; - if(edit_components[comp_id].used) - { - if(igCollapsingHeader(edit_components[comp_id].name, ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen)) - { - igIndent(8); - foreach(ref VariableGUI var;edit_components[comp_id].variables[0 .. edit_components[comp_id].used]) - { - switch(var.type) - { - case VariableGUI.Type.byte_: - igDragScalarClamp(var.name, ImGuiDataType_S8, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.ubyte_: - igDragScalarClamp(var.name, ImGuiDataType_U8, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.short_: - igDragScalarClamp(var.name, ImGuiDataType_S16, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.ushort_: - igDragScalarClamp(var.name, ImGuiDataType_U16, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.int_: - igDragScalarClamp(var.name, ImGuiDataType_S32, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.uint_: - igDragScalarClamp(var.name, ImGuiDataType_U32, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.float_: - igDragScalarClamp(var.name, ImGuiDataType_Float, comp_ptr+var.offset, 1, cast(void*)&var.float_.min, cast(void*)&var.float_.max, null, 1); - break; - case VariableGUI.Type.color: - color = colorUintToVec4(*cast(uint*)(comp_ptr+var.offset)); - if(igColorEdit4(var.name, color.data, ImGuiColorEditFlags_None)) - *cast(uint*)(comp_ptr+var.offset) = colorVec4ToUint(color); - break; - default:break; - } - } - igUnindent(8); - } - } + componentGUI(comp_id, comp_ptr); } } @@ -342,14 +366,15 @@ struct GUIManager { foreach(i, tmpl; templates) { - if(igSelectable(tmpl.name,selected_tempalte == i,ImGuiSelectableFlags_AllowDoubleClick,ImVec2(0,0))) + if(igSelectable(tmpl.name,selected_template == i,ImGuiSelectableFlags_AllowDoubleClick,ImVec2(0,0))) { - selected_tempalte = cast(uint)i; + selected_template = cast(uint)i; } } igListBoxFooter(); } } + if(igIsItemHovered(0))igSetTooltip("Select entity to spawn (SHIFT + Scroll)"); } style.Colors[ImGuiCol_Header] = col; entityComponentsGUI(); @@ -370,7 +395,10 @@ struct GUIManager igListBoxFooter(); } } + if(igIsItemHovered(0))igSetTooltip("Select component to add/remove (SHIFT + Scroll)"); } + style.Colors[ImGuiCol_Header] = col; + componentGUI(components[selected_component].component_id, components[selected_component].data); break; case Tool.selector: break; @@ -378,4 +406,33 @@ struct GUIManager style.Colors[ImGuiCol_Header] = col; } + + void filterGUI() + { + ImGuiStyle * style = igGetStyle(); + ImVec4 col = style.Colors[ImGuiCol_Header]; + style.Colors[ImGuiCol_Header] = style.Colors[ImGuiCol_TextSelectedBg]; + + int length = 0; + foreach(comp; edit_components) + { + if(comp.name !is null)length++; + } + + if(length && igListBoxHeaderInt("Components",cast(int)length,cast(int)length)) + { + foreach(i, comp; edit_components) + { + if(comp.name is null)return; + if(igSelectable(comp.name,false,0,ImVec2(0,0))) + { + + } + } + igListBoxFooter(); + } + if(igIsItemHovered(0))igSetTooltip("Select components to filter while tool work.\nComponents are only changed for filtered entities."); + + style.Colors[ImGuiCol_Header] = col; + } } \ No newline at end of file