Esempio n. 1
0
        public void DrawInstancePropertyTable(
            SortedList <string, PropertyInfo> property_list,
            string table_name = "StaticPropertyTable"
            )
        {
            if (property_list.Count == 0)
            {
                return;
            }

            if (ImGui.BeginTable(table_name, 5, TableFlags))
            {
                ImGuiEx.TableSetupHeaders(
                    "Type",
                    "Name",
                    "Value",
                    "Gettable",
                    "Settable");

                foreach (var propertyPair in property_list)
                {
                    ImGui.TableNextRow();
                    DrawInstanceTableRow(propertyPair);
                }
                ImGui.EndTable();
            }
        }
Esempio n. 2
0
        public void DrawPropertyTable(
            SortedList <string, PropertyInfo> property_list,
            string table_name = "PropertyTable"
            )
        {
            if (property_list.Count == 0)
            {
                return;
            }

            if (ImGui.BeginTable(table_name, 4, TableFlags))
            {
                ImGuiEx.TableSetupHeaders(
                    "Type",
                    "Name",
                    "Gettable",
                    "Settable");
                foreach (var property in property_list)
                {
                    ImGui.TableNextRow();
                    ImGui.TableSetColumnIndex(0);
                    propertyDrawer.DrawType(property.Value.PropertyType);

                    ImGuiEx.TableTextRow(1, property.Key, property.Value.CanRead.ToString(), property.Value.CanWrite.ToString());
                }
                ImGui.EndTable();
            }
        }
Esempio n. 3
0
        public void DrawInstanceTableRow(KeyValuePair <string, PropertyInfo> propertyPair)
        {
            ImGui.TableSetColumnIndex(0);
            propertyDrawer.DrawType(propertyPair.Value.PropertyType);

            Caller.Try(() =>
            {
                bool readable   = PropertyCanRead(propertyPair.Value);
                object instance = readable ? propertyPair.Value.GetValue(GetClassInstance(), null) : null;

                ImGui.TableSetColumnIndex(1);
                propertyDrawer.DrawName(
                    propertyPair.Key,
                    propertyPair.Value.PropertyType,
                    GetClass().type,
                    instance);
            });

            ImGui.TableSetColumnIndex(2);
            propertyDrawer.DrawPropertyValue(propertyPair.Value, GetClassInstance());

            ImGuiEx.TableTextRow(
                3,
                propertyPair.Value.CanRead.ToString(),
                propertyPair.Value.CanWrite.ToString());
        }
Esempio n. 4
0
        public void DrawFieldTable(
            SortedList <string, FieldInfo> field_list,
            string table_name = "FieldTable"
            )
        {
            if (field_list.Count == 0)
            {
                return;
            }

            if (ImGui.BeginTable(table_name, 2, TableFlags))
            {
                ImGuiEx.TableSetupHeaders("Type", "Name");

                foreach (var fieldPair in field_list)
                {
                    ImGui.TableNextRow();
                    ImGui.TableSetColumnIndex(0);
                    fieldDrawer.DrawType(fieldPair.Value.FieldType);

                    ImGuiEx.TableTextRow(1, fieldPair.Key);
                }
                ImGui.EndTable();
            }
        }
Esempio n. 5
0
 public void DrawTable(string tableName, Type type, string name, bool errored = false)
 {
     ImGuiEx.TableView(tableName, () =>
     {
         ImGui.TableNextRow();
         paramTable.DrawRow(type, name, ref inputText, errored);
     }, "Type", "Name", "Value", "Error");
 }
Esempio n. 6
0
        public static void ForEdit2(string name, Func <xna.Vector2> getter, Action <xna.Vector2> setter, float speed = 1f)
        {
            var actualValue = getter();

            ImGuiEx.ForEdit2(name,
                             () => new Vector2(actualValue.X, actualValue.Y),
                             x => setter(new xna.Vector2(x.X, x.Y)), speed);
        }
Esempio n. 7
0
        public virtual void DrawMenuView(T tObj, out bool onEvent)
        {
            bool menuClicked = false;

            ImGuiEx.PopupContextItemView(() =>
            {
                menuClicked = DrawMenu(tObj);
            });
            onEvent = menuClicked;
        }
        private void DrawUiActions()
        {
            var toolbarSize = NVector2.UnitY * (ImGui.GetTextLineHeightWithSpacing() + ImGui.GetStyle().ItemSpacing.Y * 2);

            ImGui.Text($"{ImGuiEx.IcoMoon.HammerIcon} Actions");
            ImGui.BeginChildFrame(1, toolbarSize);
            {
                if (ImGuiEx.DelegateButton("New project", $"{ImGuiEx.IcoMoon.HammerIcon}", "New project"))
                {
                    _state = new State();
                    ResetEditor(_state);
                }
                ImGui.SameLine();

                if (ImGuiEx.DelegateButton("Save project", $"{ImGuiEx.IcoMoon.FloppyDiskIcon}", "Save project"))
                {
                    _openFdDefinition = ImGuiEx.CreateFilePickerDefinition(Assembly.GetExecutingAssembly()
                                                                           .Location, "Save", ".json");
                    ImGui.OpenPopup("Save project");
                }
                DoPopup("Save project", ref _openFdDefinition, () =>
                {
                    var json = JsonSerializer.Serialize(_state, CreateJsonSerializerOptions(_state.PropertyDefinitions));
                    File.WriteAllText(_openFdDefinition.SelectedRelativePath, json);
                });

                ImGui.SameLine();
                if (ImGuiEx.DelegateButton("Open project", $"{ImGuiEx.IcoMoon.FolderOpenIcon}", "Open project"))
                {
                    _openFdDefinition = ImGuiEx.CreateFilePickerDefinition(Assembly.GetExecutingAssembly()
                                                                           .Location, "Open", ".json");
                    ImGui.OpenPopup("Open project");
                }
                DoPopup("Open project", ref _openFdDefinition, () =>
                {
                    // load json
                    var json = File.ReadAllText(_openFdDefinition.SelectedRelativePath);

                    using var jsonDocument = JsonDocument.Parse(json);
                    var propJson           = jsonDocument.RootElement.GetProperty(nameof(_state.PropertyDefinitions)).ToString();
                    var properties         = JsonSerializer.Deserialize <Dictionary <string, Property> >(propJson, CreateJsonSerializerOptions());
                    var newState           = JsonSerializer.Deserialize <State>(json, CreateJsonSerializerOptions(properties));

                    // clean animator and sprites/textures
                    ResetEditor(newState, false);
                    _state = newState;
                });


                ImGui.SameLine();
            }
            ImGui.EndChildFrame();
        }
Esempio n. 9
0
 /// <summary>
 /// Draw container type such as [Value, Array, Set ...]
 /// </summary>
 protected void DrawContainerType(Array containerTypeArray, diContainer.EContainer eContainer, string label)
 {
     ImGuiEx.ComboView(label, () =>
     {
         foreach (diContainer.EContainer type in containerTypeArray)
         {
             if (ImGui.Selectable(type.ToString()) &&
                 eContainer != type)
             {
                 NotifyContainerTypeChange(type);
             }
         }
     }, "", ImGuiComboFlags.NoPreview);
 }
Esempio n. 10
0
 public void Draw()
 {
     ImGuiEx.TableView(TableLable, () =>
     {
         for (int i = 0; i < m_KeyNameList.Count; ++i)
         {
             ImGui.TableNextRow();
             DrawItem(i, m_KeyNameList[i], out bool onEvent);
             if (onEvent)
             {
                 break;
             }
         }
     }, Titles);
 }
Esempio n. 11
0
 public void Draw()
 {
     ImGuiEx.TableView("##TableView" + typeof(T).Name, () =>
     {
         foreach (var objPair in m_ID2Obj)
         {
             ImGui.TableNextRow();
             DrawItem(objPair.Value, out bool onEvent);
             if (onEvent)
             {
                 break;
             }
         }
     }, Titles);
 }
        private void DoPopup(string id, ref ImGuiEx.FilePickerDefinition fpd, Action onDone)
        {
            bool popupOpen = true;

            ImGui.SetNextWindowContentSize(NVector2.One * 400);
            if (ImGui.BeginPopupModal(id, ref popupOpen, ImGuiWindowFlags.NoResize))
            {
                if (ImGuiEx.DoFilePicker(ref fpd))
                {
                    onDone?.Invoke();
                }

                ImGui.EndPopup();
            }
        }
Esempio n. 13
0
 /// <summary>
 /// Draw ditype such as [Bool, Int, Float ...]
 /// </summary>
 protected virtual void DrawdiType(List <diType> ditypeList, Type curType, string label)
 {
     ImGui.SetNextItemWidth(100);
     ImGuiEx.ComboView(label, () =>
     {
         foreach (diType type in ditypeList)
         {
             //Selected and type not equal
             if (ImGui.Selectable(type.ValueType.Name) &&
                 Equals(type.ValueType, curType) == false)
             {
                 NotifyObjectTypeChange(type);
             }
         }
     }, curType.Name);
 }
Esempio n. 14
0
 void DrawTable()
 {
     ImGuiEx.TableView("MethodInvokeTable", () =>
     {
         for (int i = 0; i < inputText.Length; ++i)
         {
             ImGui.TableNextRow();
             if (errorRow == i)
             {
                 paramTable.DrawRow(methodParameters[i].ParameterType, methodParameters[i].Name, ref inputText[i], true);
             }
             else
             {
                 paramTable.DrawRow(methodParameters[i].ParameterType, methodParameters[i].Name, ref inputText[i]);
             }
         }
     }, "Type", "Name", "Value", "Error");
 }
Esempio n. 15
0
        public void DrawLeft()
        {
            var color = new Vector4(0.6f, 0.6f, 0.6f, 0.65f);

            ImGui.BeginChild("InstanceTableChlid", new Vector2(ImGui.GetWindowContentRegionWidth() * 0.35f, ImGui.GetWindowHeight()));
            ImGui.Text("Instance List");

            InstanceInfo removeInfo = new InstanceInfo();

            ImGuiEx.TableView("InstanceTable", () =>
            {
                foreach (InstanceInfo instance in instanceList)
                {
                    ImGui.TableNextRow();

                    if (instance == curInstance)
                    {
                        ImGui.TableSetBgColor(ImGuiTableBgTarget.RowBg0 + 1, ImGui.GetColorU32(color));
                    }

                    ImGuiEx.TableTextRow(0, instance.parent, instance.type.Name);

                    ImGui.TableSetColumnIndex(2);
                    if (ImGui.Button(instance.name.ToString()))
                    {
                        UpdateView(instance);
                        break;  //prevent error
                    }

                    ImGui.TableSetColumnIndex(3);
                    if (ImGui.ArrowButton(instance.GetHashCode().ToString(), ImGuiDir.Down))
                    {
                        removeInfo = instance;
                    }
                }
            }, tableFlags, "Parent", "Type", "Name", "Close");

            if (removeInfo != null)
            {
                instanceList.Remove(removeInfo);
            }

            ImGui.EndChild();
        }
Esempio n. 16
0
        public bool Content()
        {
            var hasChanged = false;

            hasChanged |= ImGuiEx.EnumRadioButtonGroup(ref renderMode);
            NewLine();

            int curDepth = 0;

            for (int i = 0; i < Skeleton.Bones.Count; i++)
            {
                if (curDepth < boneDepths[i])
                {
                    continue;
                }
                while (curDepth > boneDepths[i])
                {
                    curDepth--;
                    TreePop();
                }

                var flags = (i == highlightedBoneI ? ImGuiTreeNodeFlags.Selected : 0) |
                            ImGuiTreeNodeFlags.OpenOnDoubleClick | ImGuiTreeNodeFlags.OpenOnArrow |
                            ImGuiTreeNodeFlags.DefaultOpen;
                if (TreeNodeEx($"Bone {i} \"{Skeleton.UserIds[i]}\"", flags))
                {
                    curDepth++;
                }
                if (IsItemClicked() && i != highlightedBoneI)
                {
                    HighlightBone(i);
                    hasChanged = true;
                }
            }
            while (curDepth > 0)
            {
                curDepth--;
                TreePop();
            }

            return(hasChanged);
        }
Esempio n. 17
0
        public override void DrawWindowContent()
        {
            if (instance == null)
            {
                return;
            }

            ImGui.Text(arrayInstance.GetType().ToString() + " " + arrayName);

            var array = (Array)arrayInstance;

            ImGui.Text("Length:" + array.Length);

            ImGuiEx.TableView("ArrayInfo", () => {
                int index = 0;
                foreach (var i in (Array)arrayInstance)
                {
                    if (i == null)
                    {
                        continue;
                    }

                    ImGui.TableNextRow();
                    ImGui.TableSetColumnIndex(0);
                    arrayDrawer.DrawType(i.GetType());

                    ImGui.TableSetColumnIndex(1);
                    arrayDrawer.DrawArrayIndex(index);

                    ImGui.TableSetColumnIndex(2);
                    arrayDrawer.DrawArrayValue((Array)arrayInstance, i, index);

                    ++index;

                    //Array too large
                    if (index > 100)
                    {
                        break;
                    }
                }
            }, "Type", "Index", "Value");
        }
Esempio n. 18
0
            public void Content()
            {
                bool hasChanged = false;

                if (ImGuiEx.Hyperlink("Model", SceneModel.filename))
                {
                    var fullPath = new FilePath("resources/models/models").Combine(SceneModel.filename + ".dff");
                    diContainer.GetTag <OpenDocumentSet>().OpenWith <ModelViewer>(fullPath);
                }
                var color = SceneModel.color.ToFColor();

                ColorEdit4("Color", ref color, ImGuiColorEditFlags.NoPicker);
                NewLine();

                var pos      = Location.LocalPosition;
                var rotEuler = Location.LocalRotation.ToEuler() * 180.0f / MathF.PI;

                hasChanged |= DragFloat3("Position", ref pos);
                hasChanged |= DragFloat3("Rotation", ref rotEuler);
                NewLine();

                SliderFloat("Ambient", ref SceneModel.surfaceProps.ambient, -1f, 1f);
                SliderFloat("Specular", ref SceneModel.surfaceProps.specular, -1f, 1f);
                SliderFloat("Diffuse", ref SceneModel.surfaceProps.diffuse, -1f, 1f);
                Checkbox("Use cached models", ref SceneModel.useCachedModels);
                SliderInt("Wiggle Speed", ref SceneModel.wiggleAmpl, 0, 4);
                Checkbox("Is only visual", ref SceneModel.isVisualOnly);

                NewLine();
                var behaviorType = SceneBehaviour?.type ?? BehaviourType.Unknown;

                ImGuiEx.EnumCombo("Behavior", ref behaviorType);

                if (hasChanged)
                {
                    rotEuler = (rotEuler * MathF.PI / 180.0f) - Location.LocalRotation.ToEuler();
                    Location.LocalPosition  = pos;
                    Location.LocalRotation *= Quaternion.CreateFromYawPitchRoll(rotEuler.Y, rotEuler.X, rotEuler.Z);
                    diContainer.GetTag <FramebufferArea>().IsDirty = true;
                }
            }
        private void DrawUi(GameTime gameTime)
        {
            _imguiRenderer.BeforeLayout(gameTime);

            // Draw viewport overlays
            if (!string.IsNullOrEmpty(hoveredentityId))
            {
                DrawSpriteBounds(hoveredentityId, Color.CornflowerBlue.PackedValue);
            }
            else if (!string.IsNullOrEmpty(selectedEntityId))
            {
                DrawSpriteBounds(selectedEntityId, Color.GreenYellow.PackedValue);
            }

            ImGui.Begin("timeline");
            ImGuiEx.DrawUiTimeline(_state.Animator);
            ImGui.End();

            var hierarchyWindowWidth = 256;

            ImGui.SetNextWindowPos(new NVector2(GraphicsDevice.Viewport.Width - hierarchyWindowWidth, 0), ImGuiCond.FirstUseEver);
            ImGui.SetNextWindowSize(NVector2.UnitX * hierarchyWindowWidth +
                                    NVector2.UnitY * GraphicsDevice.Viewport.Height, ImGuiCond.FirstUseEver);

            ImGui.Begin("Management");
            {
                DrawUiActions();
                DrawUiHierarchyFrame();
                DrawUiProperties();
            }
            ImGui.End();

            _imguiRenderer.AfterLayout();

            if (ImGui.IsWindowHovered(ImGuiHoveredFlags.AnyWindow))
            {
                ImGui.CaptureKeyboardFromApp();
                ImGui.CaptureMouseFromApp();
            }
        }
Esempio n. 20
0
        public void DrawInstanceFieldTable(
            SortedList <string, FieldInfo> field_list,
            string table_name = "InstanceFieldTable"
            )
        {
            if (field_list.Count == 0)
            {
                return;
            }

            if (ImGui.BeginTable(table_name, 3, TableFlags))
            {
                ImGuiEx.TableSetupHeaders("Type", "Name", "Value");

                foreach (var fieldPair in field_list)
                {
                    ImGui.TableNextRow();
                    DrawInstanceTableRow(fieldPair);
                }
                ImGui.EndTable();
            }
        }
Esempio n. 21
0
        public void DrawMethodTable(
            SortedList <string, MethodInfo> table,
            string TableName = "ClassMethodTable"
            )
        {
            if (table.Count == 0)
            {
                return;
            }

            if (ImGui.BeginTable(TableName, 3, TableFlags))
            {
                ImGuiEx.TableSetupHeaders("Return Type", "Name", "Param");

                foreach (var method in table)
                {
                    ImGui.TableNextRow();
                    DrawTableRow(method);
                }
                ImGui.EndTable();
            }
        }
Esempio n. 22
0
        private void HandleInfoContent()
        {
            void ModelLink(string label, string?modelName)
            {
                bool isEnabled = modelName != null && modelName.Length > 0;

                if (ImGuiEx.Hyperlink(label, isEnabled ? modelName ! : "<none>", true, isEnabled))
                {
                    diContainer.GetTag <OpenDocumentSet>().OpenWith <ModelViewer>("resources/models/actorsex/" + modelName);
                }
            }

            ModelLink("Body: ", description?.body.model);
            Text($"Body animations: {description?.body.animations.Length ?? 0}");
            Text($"Body bones: {body?.skeleton.Bones.Count ?? 0}");

            NewLine();
            ModelLink("Wings: ", description?.wings.model);
            Text($"Wings animations: {description?.wings.animations.Length ?? 0}");
            Text($"Wings bones: {wings?.skeleton.Bones.Count ?? 0}");

            NewLine();
            void BoneLink(string label, int?boneIdx)
            {
                if (ImGuiEx.Hyperlink(label, boneIdx?.ToString() ?? "<none>", false, boneIdx != null))
                {
                    body?.skeletonRenderer.HighlightBone(boneIdx !.Value);
                    fbArea.IsDirty = true;
                    if (body != null && body.skeletonRenderer.RenderMode == DebugSkeletonRenderMode.Invisible)
                    {
                        body.skeletonRenderer.RenderMode = DebugSkeletonRenderMode.Bones;
                    }
                }
            }

            BoneLink("Head bone: ", description?.headBoneID);
            BoneLink("Effect bone: ", description?.effectBoneID);
            BoneLink("Wing attach bone: ", description?.attachWingsToBone);
        }
Esempio n. 23
0
        public override void DrawWindowContent()
        {
            if (ImGui.BeginTable("EditorTable", 3, TableFlags))
            {
                ImGuiEx.TableSetupHeaders();

                //Left
                ImGui.TableSetColumnIndex(0);
                DrawLeft();
                DrawConsoleOutput();

                //Middle
                ImGui.TableSetColumnIndex(1);
                DrawEditorTop();
                m_TabBarView.Draw();
                m_NodeEditor.DrawWindowContent();

                //Right
                ImGui.TableSetColumnIndex(2);
                DrawRight();
                ImGui.EndTable();
            }
        }
Esempio n. 24
0
        private void HandleHeadIKContent()
        {
            if (description == null || body == null)
            {
                return;
            }
            if (description.headBoneID < 0)
            {
                Text("This actor has no head.");
                return;
            }

            ImGuiEx.EnumRadioButtonGroup(ref headIKMode);
            var newValue = (description.headBoneID, camera.Location.GlobalPosition);

            body.singleIK = headIKMode switch
            {
                HeadIKMode.Disabled => null,
                HeadIKMode.Enabled => newValue,
                HeadIKMode.Frozen => body.singleIK ?? newValue,
                _ => throw new NotImplementedException("Unimplemented head IK mode")
            };
        }
    }
Esempio n. 25
0
        private void HandleRaycast()
        {
            if (worldCollider == null)
            {
                Text("No world or collider loaded");
                return;
            }

            if (Button("Shoot ray"))
            {
                ShootRay();
            }

            Spacing();
            Text("Intersections");
            var shouldUpdate = ImGuiEx.EnumCombo("Primitive", ref intersectionPrimitive);

            shouldUpdate |= SliderFloat("Size", ref intersectionSize, 0.01f, 20f);
            shouldUpdate |= Checkbox("Update location", ref updateIntersectionPrimitive);
            if (shouldUpdate)
            {
                UpdateIntersectionPrimitive();
            }
        }
Esempio n. 26
0
        /// Draws a field from cache info.
        protected void DrawField(ReflectionCache.CachedPropertyInfo info, object target, bool withLabel)
        {
            if (filter_.IsActive && !filter_.PassFilter(info.DisplayName))
            {
                return;
            }

            Type pType = info.Type;

            if (pType != typeof(bool) && withLabel)
            {
                ImGuiCli.Text(info.DisplayName);
                if (!string.IsNullOrWhiteSpace(info.Tip))// && ImGuiCli.IsItemHovered())
                {
                    ImGuiCli.SameLine();
                    ImGuiCli.Text(ICON_FA.INFO_CIRCLE);
                    if (ImGuiCli.IsItemHovered())
                    {
                        ImGuiCli.SetTooltip(info.Tip);
                    }
                }
            }

            string labelLessName = "##" + info.DisplayName;

            if (pType == typeof(bool))
            {
                bool   value = (bool)info.GetValue(target);
                string lbl   = withLabel ? info.DisplayName : "##" + info.DisplayName;
                if (ImGuiCli.Checkbox(lbl, ref value))
                {
                    info.SetValue(target, value);
                }
                if (!string.IsNullOrWhiteSpace(info.Tip) && ImGuiCli.IsItemHovered())
                {
                    ImGuiCli.SetTooltip(info.Tip);
                }
            }
            else if (pType == typeof(int))
            {
                int value = (int)info.GetValue(target);
                if (ImGuiCli.DragInt(labelLessName, ref value))
                {
                    info.SetValue(target, value);
                }
            }
            else if (pType == typeof(uint))
            {
                int value = (int)info.GetValue(target);
                if (ImGuiCli.DragInt(labelLessName, ref value, 1, 0, int.MaxValue))
                {
                    info.SetValue(target, (int)value);
                }
            }
            else if (pType == typeof(float))
            {
                float value = (float)info.GetValue(target);
                if (ImGuiCli.DragFloat(labelLessName, ref value))
                {
                    info.SetValue(target, value);
                }
            }
            else if (pType == typeof(double))
            {
                float value = (float)info.GetValue(target);
                if (ImGuiCli.DragFloat(labelLessName, ref value))
                {
                    info.SetValue(target, (double)value);
                }
            }
            else if (pType == typeof(string))
            {
                string value = (string)info.GetValue(target);
                if (value == null)
                {
                    value = "";
                }
                if (ImGuiCli.InputText(labelLessName, ref value))
                {
                    info.SetValue(target, value);
                }
            }
            else if (pType == typeof(Color))
            {
                Color value = (Color)info.GetValue(target);
                if (ImGuiCli.InputColor(labelLessName, ref value))
                {
                    info.SetValue(target, value);
                }
            }
            else if (pType == typeof(Vector2))
            {
                Vector2 value = (Vector2)info.GetValue(target);
                if (ImGuiEx.DragFloatN_Colored(labelLessName, ref value))
                {
                    info.SetValue(target, value);
                }
            }
            else if (pType == typeof(Vector3))
            {
                Vector3 value = (Vector3)info.GetValue(target);
                if (ImGuiEx.DragFloatN_Colored(labelLessName, ref value))
                {
                    info.SetValue(target, value);
                }
            }
            else if (pType == typeof(Vector4))
            {
                if (info.EditType == PropertyData.EditorType.Color)
                {
                    Vector4 value = (Vector4)info.GetValue(target);
                    if (ImGuiCli.InputColor(labelLessName, ref value))
                    {
                        info.SetValue(target, value);
                    }
                }
                else
                {
                    Vector4 value = (Vector4)info.GetValue(target);
                    if (ImGuiCli.DragFloat4(labelLessName, ref value))
                    {
                        info.SetValue(target, value);
                    }
                }
            }
            else if (pType == typeof(Matrix))
            {
                if (info.EditType == PropertyData.EditorType.Transform)
                {
                    Matrix value = (Matrix)info.GetValue(target);
                    if (ImGuiEx.MatrixTransform(ref value, true))
                    {
                        info.SetValue(target, value);
                    }
                }
                else
                {
                    Matrix value = (Matrix)info.GetValue(target);
                    if (ImGuiEx.DragMatrix(ref value))
                    {
                        info.SetValue(target, value);
                    }
                }
            }
            else if (pType.IsEnum)
            {
                int value = (int)info.GetValue(target);
                if (ImGuiCli.Combo(labelLessName, ref value, info.enumNames))
                {
                    info.SetValue(target, Enum.GetValues(info.Type).GetValue(value));
                }
            }
            else
            {
                PropertyData.ImPropertyHandler foundHandler = null;
                if (reflectCache_.TypeHandlers.TryGetValue(pType, out foundHandler))
                {
                    foundHandler.EmitUI(info, target);
                }
            }
        }
        private void DrawUiHierarchyFrame()
        {
            var size        = ImGui.GetContentRegionAvail();
            var itemSpacing = ImGui.GetStyle().ItemSpacing + NVector2.UnitY * 4;

            ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, itemSpacing);

            ImGui.Text($"{ImGuiEx.IcoMoon.ListIcon} Hierarchy");
            ImGui.BeginChildFrame(2, size - NVector2.UnitY * 256);
            {
                // create sprite
                bool itemHovered = false;
                ImGui.Text($"{ImGuiEx.IcoMoon.ImagesIcon} Entities");
                ImGui.SameLine();

                if (_state.Textures.Count > 0)
                {
                    if (ImGui.SmallButton($"{ImGuiEx.IcoMoon.PlusIcon}##1"))
                    {
                        ImGui.OpenPopup("Create entity");
                        ImGuiEx.DoEntityCreatorReset();
                    }
                }
                else
                {
                    ImGuiEx.DisabledButton($"{ImGuiEx.IcoMoon.PlusIcon}");
                }

                ImGuiEx.DoEntityCreatorModal(_state.Textures.Keys.ToArray(), (name, selectedTexture) =>
                {
                    Entity entity = new Entity(name, selectedTexture);

                    var propDef = _state.PropertyDefinitions[POSITION_PROPERTY];
                    entity.SetCurrentPropertyValue(propDef, propDef.CreateInstance());
                    _state.Animator.CreateTrack(propDef.Type, name, POSITION_PROPERTY);

                    var fiPropDef = _state.PropertyDefinitions[FRAMEINDEX_PROPERTY];
                    entity.SetCurrentPropertyValue(fiPropDef, fiPropDef.CreateInstance());
                    _state.Animator.CreateTrack(fiPropDef.Type, name, FRAMEINDEX_PROPERTY);

                    _state.Entities[entity.Id] = entity;
                });

                // show all created entities
                ImGui.Indent();
                foreach (var entity in _state.Entities.Values)
                {
                    bool selected = selectedEntityId == entity.Id;
                    ImGui.Selectable(entity.Id, ref selected);

                    if (selected)
                    {
                        selectedTextureId = string.Empty;
                        selectedEntityId  = entity.Id;
                    }

                    if (ImGui.IsItemHovered())
                    {
                        itemHovered     = true;
                        hoveredentityId = entity.Id;
                    }
                }
                ImGui.Unindent();

                if (!itemHovered)
                {
                    hoveredentityId = string.Empty;
                }

                // Add textures
                ImGui.Text($"{ImGuiEx.IcoMoon.TextureIcon} Textures");
                ImGui.SameLine();

                if (ImGui.SmallButton($"{ImGuiEx.IcoMoon.PlusIcon}##2"))
                {
                    _openFdDefinition = ImGuiEx.CreateFilePickerDefinition(Assembly.GetExecutingAssembly()
                                                                           .Location, "Open", ".png");
                    ImGui.OpenPopup("Load texture");
                }

                DoPopup("Load texture", ref _openFdDefinition, () =>
                {
                    var key = Path.GetFileNameWithoutExtension(_openFdDefinition.SelectedFileName);
                    if (!_state.Textures.ContainsKey(key))
                    {
                        var path             = _openFdDefinition.SelectedRelativePath;
                        var texture          = Texture2D.FromFile(GraphicsDevice, path);
                        _state.Textures[key] = new TextureFrame(texture, path,
                                                                new NVector2(32, 32),
                                                                new NVector2(16, 16));
                    }
                });

                // show all loaded textures
                ImGui.Indent();
                foreach (var texture in _state.Textures.Keys)
                {
                    bool selected = selectedTextureId == texture;
                    ImGui.Selectable(texture, ref selected);

                    if (selected)
                    {
                        selectedEntityId  = string.Empty;
                        selectedTextureId = texture;
                    }
                }
                ImGui.Unindent();

                ImGui.TreePop();
            }
            ImGui.EndChildFrame();
            ImGui.PopStyleVar();
        }
        private void DrawUiProperties()
        {
            void InsertKeyframe(string entityId, string propertyId)
            {
                var entity  = _state.Entities[entityId];
                var propDef = _state.PropertyDefinitions[propertyId];
                var trackId = _state.Animator.GetTrackKey(entityId, propertyId);
                var value   = entity.GetCurrentPropertyValue <object>(propDef);

                _state.Animator.InsertKeyframe(trackId, value);
            }

            ImGui.Text($"{ImGuiEx.IcoMoon.EqualizerIcon} Properties");
            ImGui.BeginChildFrame(3, NVector2.UnitY * 208);
            if (!string.IsNullOrEmpty(selectedEntityId))
            {
                var selectedEntity = _state.Entities[selectedEntityId];

                var tempEntityName = ImGuiEx.SavedInput(String.Empty, selectedEntity.Id);
                ImGui.SameLine();
                if (ImGui.Button("Rename") && !_state.Entities.ContainsKey(tempEntityName))
                {
                    RenameEntity(selectedEntity, tempEntityName);
                    ImGuiEx.ResetSavedInput();
                }

                ImGui.Separator();

                ImGui.Columns(2);
                ImGui.SetColumnWidth(0, 28);
                if (ImGui.Button($"{ImGuiEx.IcoMoon.KeyIcon}##group"))
                {
                    foreach (var propertyId in selectedEntity)
                    {
                        InsertKeyframe(selectedEntityId, propertyId);
                    }
                }
                ImGui.NextColumn();
                ImGui.Text("All properties");
                ImGui.Separator();
                ImGui.NextColumn();

                var keyframeButtonId = 0;
                foreach (var propertyId in selectedEntity)
                {
                    ImGui.PushID(keyframeButtonId++);
                    if (ImGui.Button($"{ImGuiEx.IcoMoon.KeyIcon}"))
                    {
                        InsertKeyframe(selectedEntityId, propertyId);
                    }
                    ImGui.PopID();

                    ImGui.NextColumn();

                    var propDefinition = _state.PropertyDefinitions[propertyId];
                    switch (propertyId)
                    {
                    case POSITION_PROPERTY:
                        Vector2 value = selectedEntity.GetCurrentPropertyValue <Vector2>(propDefinition);

                        var pos = new NVector2(value.X, value.Y);
                        ImGui.DragFloat2(propertyId, ref pos);

                        value.X = pos.X;
                        value.Y = pos.Y;

                        selectedEntity.SetCurrentPropertyValue(propDefinition, value);

                        break;

                    case FRAMEINDEX_PROPERTY:
                        int frameIndex = selectedEntity.GetCurrentPropertyValue <int>(propDefinition);

                        var texture = _state.Textures[selectedEntity.TextureId];
                        int framesX = (int)(texture.Width / texture.FrameSize.X);
                        int framesY = (int)(texture.Height / texture.FrameSize.Y);

                        ImGui.SliderInt(propertyId, ref frameIndex, 0, framesX * framesY - 1);

                        selectedEntity.SetCurrentPropertyValue(propDefinition, frameIndex);
                        break;
                    }

                    ImGui.NextColumn();
                }
            }
            else if (!string.IsNullOrEmpty(selectedTextureId))
            {
                var scale            = 2f;
                var selectedTexture  = _state.Textures[selectedTextureId];
                var currentFrameSize = selectedTexture.FrameSize;
                var currentPivot     = selectedTexture.Pivot;

                ImGui.DragFloat2("Framesize", ref currentFrameSize);
                ImGui.DragFloat2("Pivot", ref currentPivot);

                selectedTexture.FrameSize = currentFrameSize;
                selectedTexture.Pivot     = currentPivot;

                var scaledFrameSize = currentFrameSize * scale;
                var scaledPivot     = currentPivot * scale;

                ImGui.BeginChildFrame(2, NVector2.UnitY * 154f);

                var contentSize = ImGui.GetContentRegionAvail();
                var center      = ImGui.GetCursorScreenPos() + contentSize * 0.5f;
                var frameStart  = center - scaledFrameSize * 0.5f;

                // draw frame size
                var drawList = ImGui.GetWindowDrawList();
                drawList.AddRect(frameStart, frameStart + scaledFrameSize, Color.GreenYellow.PackedValue);

                // horizontal line
                drawList.AddLine(center - NVector2.UnitX * scaledFrameSize * 0.5f,
                                 center + NVector2.UnitX * scaledFrameSize * 0.5f,
                                 Color.ForestGreen.PackedValue);

                // vertical line
                drawList.AddLine(center - NVector2.UnitY * scaledFrameSize * 0.5f,
                                 center + NVector2.UnitY * scaledFrameSize * 0.5f,
                                 Color.ForestGreen.PackedValue);

                // draw pivot
                drawList.AddCircleFilled(frameStart + scaledPivot, 4, Color.White.PackedValue);

                ImGui.EndChildFrame();
            }

            ImGui.EndChildFrame();
        }