public void AssignControl(object controlledObject, FieldPropertyListInfo fieldPropertyInfo, byte assignmentButton) { if (ControlStates.ContainsKey(assignmentButton)) { var controlState = ControlStates[assignmentButton]; controlState.ControlledObject = controlledObject; controlState.FieldPropertyInfo = fieldPropertyInfo; // See if it's a vector and assign subsequent controls if it is. byte vectorSize = 1; if (fieldPropertyInfo.FieldPropertyType == typeof(Vector2) || fieldPropertyInfo.FieldPropertyType == typeof(Xna.Vector2)) { vectorSize = 2; } else if (fieldPropertyInfo.FieldPropertyType == typeof(Vector3) || fieldPropertyInfo.FieldPropertyType == typeof(Xna.Vector3)) { vectorSize = 3; } else if (fieldPropertyInfo.FieldPropertyType == typeof(Vector4) || fieldPropertyInfo.FieldPropertyType == typeof(Xna.Vector4)) { vectorSize = 4; } if (vectorSize > 1) { controlState.IsVector = true; controlState.VectorIndex = 0; for (byte i = 1; i < vectorSize; i++) { byte vectorAssignmentButton = (byte)(assignmentButton + i); if (AssignToControlMapping.ContainsKey(vectorAssignmentButton) && AssignToControlMapping[vectorAssignmentButton].Type == AssignToControlMapping[assignmentButton].Type) // So long as this control is still the same control type { var vectorControlState = ControlStates[vectorAssignmentButton]; vectorControlState.ControlledObject = controlledObject; vectorControlState.FieldPropertyInfo = fieldPropertyInfo; vectorControlState.IsVector = true; vectorControlState.VectorIndex = i; ControlStates[vectorAssignmentButton] = vectorControlState; } else { break; } } } ControlStates[assignmentButton] = controlState; } Assigning = false; }
static void SubmitHelpMarker(FieldPropertyListInfo info) { if (info.MemberInfo != null) { var helpAttribute = CustomAttributeExtensions.GetCustomAttribute <EditorHelper.HelpAttribute>(info.MemberInfo, true); if (helpAttribute != null) { ImGui.SameLine(); HelpMarker(helpAttribute.HelpText); } } }
static void SubmitMidiAssignment(object entityComponent, FieldPropertyListInfo info, MidiState.MidiControlDescriptionType type) { if (Program.MidiState.Assigning && Program.MidiState.LastAssignmentType == type) { ImGui.PushID(GetIdString(info, entityComponent)); if (ImGui.Button("A")) { Program.MidiState.AssignControl(entityComponent, info); } ImGui.SameLine(); ImGui.PopID(); } }
static string GetIdString(FieldPropertyListInfo info, object entityComponent) { string objectID = entityComponent.ToString(); if (entityComponent as Component != null) { objectID = (entityComponent as Component).Guid.ToString(); } else if (entityComponent as Entity != null) { objectID = (entityComponent as Entity).Guid.ToString(); } return(objectID + info.Name); }
static void SubmitReadonlyFieldPropertyInspector(FieldPropertyListInfo info) { string valText; var value = info.GetValue(); if (value != null) { valText = value.ToString(); } else { valText = "null"; } ImGui.Text($"{info.Name}: {valText}"); }
static void SubmitObjectInspector(object selectedObject) { ImGuiTreeNodeFlags collapsingHeaderFlags = ImGuiTreeNodeFlags.CollapsingHeader; collapsingHeaderFlags |= ImGuiTreeNodeFlags.DefaultOpen; var selectedType = selectedObject.GetType(); if (ImGui.CollapsingHeader("Fields", collapsingHeaderFlags)) { var fields = selectedType.GetFields(); foreach (var info in fields.Where(field => !field.IsLiteral && !field.IsInitOnly)) { SubmitFieldPropertyInspector(new FieldPropertyListInfo(info, selectedObject), selectedObject); } } var properties = selectedType.GetProperties(); if (ImGui.CollapsingHeader("Properties", collapsingHeaderFlags)) { // When SetMethod is private, it will still be writable so long as it's class isn't inherited, so check to see if it's public too for the behaviour I want. foreach (var info in properties.Where(prop => prop.CanRead && prop.CanWrite && prop.SetMethod.IsPublic)) { SubmitFieldPropertyInspector(new FieldPropertyListInfo(info, selectedObject), selectedObject); } } if (ImGui.CollapsingHeader("Read-Only Properties", collapsingHeaderFlags)) { // When SetMethod is private, it will still be writable so long as it's class isn't inherited, so check to see if it's public too for the behaviour I want. foreach (var info in properties.Where(prop => prop.CanRead && (!prop.CanWrite || !prop.SetMethod.IsPublic))) { var fieldPropertyInfo = new FieldPropertyListInfo(info, selectedObject); SubmitReadonlyFieldPropertyInspector(fieldPropertyInfo); SubmitHelpMarker(fieldPropertyInfo); } } }
static unsafe void SubmitFieldPropertyInspector(FieldPropertyListInfo info, object entityComponent, bool showMidi = true) { ImGui.PushID(GetIdString(info, entityComponent)); EditorHelper.RangeAttribute rangeAttribute = null; if (info.MemberInfo != null) { rangeAttribute = CustomAttributeExtensions.GetCustomAttribute <EditorHelper.RangeAttribute>(info.MemberInfo, true); } var infoType = info.FieldPropertyType; if (infoType == typeof(string)) { string val = (string)info.GetValue(); if (val == null) { val = string.Empty; } if (ImGui.InputText(info.Name, ref val, 1000)) { info.SetValue(val); } } else if (infoType == typeof(bool)) { if (showMidi) { SubmitMidiAssignment(entityComponent, info, MidiState.MidiControlDescriptionType.Button); } bool val = (bool)info.GetValue(); if (ImGui.Checkbox(info.Name, ref val)) { info.SetValue(val); } } else if (infoType == typeof(float)) { if (showMidi) { SubmitMidiAssignment(entityComponent, info, MidiState.MidiControlDescriptionType.Knob); } float val = (float)info.GetValue(); bool result; if (rangeAttribute != null && (rangeAttribute.RangeType == EditorHelper.RangeAttribute.RangeTypeEnum.Float || rangeAttribute.RangeType == EditorHelper.RangeAttribute.RangeTypeEnum.Int)) { if (rangeAttribute.RangeType == EditorHelper.RangeAttribute.RangeTypeEnum.Float) { result = ImGui.SliderFloat(info.Name, ref val, rangeAttribute.MinFloat, rangeAttribute.MaxFloat); } else { result = ImGui.SliderFloat(info.Name, ref val, rangeAttribute.MinInt, rangeAttribute.MaxInt); } } else { result = ImGui.DragFloat(info.Name, ref val, 0.1f); } if (result) { info.SetValue(val); } } else if (infoType == typeof(Vector2)) { if (showMidi) { SubmitMidiAssignment(entityComponent, info, MidiState.MidiControlDescriptionType.Knob); } Vector2 val = (Vector2)info.GetValue(); if (ImGui.DragFloat2(info.Name, ref val)) { info.SetValue(val); } } else if (infoType == typeof(Vector3)) { if (showMidi) { SubmitMidiAssignment(entityComponent, info, MidiState.MidiControlDescriptionType.Knob); } Vector3 val = (Vector3)info.GetValue(); if (ImGui.DragFloat3(info.Name, ref val)) { info.SetValue(val); } } else if (infoType == typeof(Vector4)) { if (showMidi) { SubmitMidiAssignment(entityComponent, info, MidiState.MidiControlDescriptionType.Knob); } Vector4 val = (Vector4)info.GetValue(); if (ImGui.DragFloat4(info.Name, ref val)) { info.SetValue(val); } } else if (infoType == typeof(Xna.Vector2)) { if (showMidi) { SubmitMidiAssignment(entityComponent, info, MidiState.MidiControlDescriptionType.Knob); } Xna.Vector2 xnaVal = (Xna.Vector2)info.GetValue(); Vector2 val = new Vector2(xnaVal.X, xnaVal.Y); if (ImGui.DragFloat2(info.Name, ref val)) { xnaVal.X = val.X; xnaVal.Y = val.Y; info.SetValue(xnaVal); } } else if (infoType == typeof(Xna.Vector3)) { if (showMidi) { SubmitMidiAssignment(entityComponent, info, MidiState.MidiControlDescriptionType.Knob); } Xna.Vector3 xnaVal = (Xna.Vector3)info.GetValue(); Vector3 val = new Vector3(xnaVal.X, xnaVal.Y, xnaVal.Z); if (ImGui.DragFloat3(info.Name, ref val)) { xnaVal.X = val.X; xnaVal.Y = val.Y; xnaVal.Z = val.Z; info.SetValue(xnaVal); } } else if (infoType == typeof(Xna.Vector4)) { if (showMidi) { SubmitMidiAssignment(entityComponent, info, MidiState.MidiControlDescriptionType.Knob); } Xna.Vector4 xnaVal = (Xna.Vector4)info.GetValue(); Vector4 val = new Vector4(xnaVal.X, xnaVal.Y, xnaVal.Z, xnaVal.W); if (ImGui.DragFloat4(info.Name, ref val)) { xnaVal.X = val.X; xnaVal.Y = val.Y; xnaVal.Z = val.Z; xnaVal.W = val.W; info.SetValue(xnaVal); } } else if (infoType == typeof(int)) { if (showMidi) { SubmitMidiAssignment(entityComponent, info, MidiState.MidiControlDescriptionType.Knob); } int val = (int)info.GetValue(); bool result; if (rangeAttribute != null && rangeAttribute.RangeType == EditorHelper.RangeAttribute.RangeTypeEnum.Int) { result = ImGui.SliderInt(info.Name, ref val, rangeAttribute.MinInt, rangeAttribute.MaxInt); } else { result = ImGui.InputInt(info.Name, ref val); } if (result) { info.SetValue(val); } } else if (infoType == typeof(uint)) { if (showMidi) { SubmitMidiAssignment(entityComponent, info, MidiState.MidiControlDescriptionType.Knob); } int val = (int)((uint)info.GetValue()); bool result; if (rangeAttribute != null && rangeAttribute.RangeType == EditorHelper.RangeAttribute.RangeTypeEnum.Int) { result = ImGui.SliderInt(info.Name, ref val, rangeAttribute.MinInt, rangeAttribute.MaxInt); } else { result = ImGui.InputInt(info.Name, ref val); } if (result) { if (val < 0) { val = 0; } info.SetValue((uint)val); } } else if (infoType.IsEnum) { if (showMidi) { SubmitMidiAssignment(entityComponent, info, MidiState.MidiControlDescriptionType.Button); } var val = info.GetValue(); var enumNames = infoType.GetEnumNames(); int currentIndex = 0; for (int i = 0; i < enumNames.Length; i++) { if (enumNames[i] == val.ToString()) { currentIndex = i; } } if (ImGui.Combo(info.Name, ref currentIndex, enumNames, enumNames.Length)) { info.SetValue(infoType.GetEnumValues().GetValue(currentIndex)); } } else if (typeof(IList).IsAssignableFrom(infoType)) { var listthing = info.GetValue(); IList list = listthing as IList; ImGui.Text($"{info.Name} List ({list.Count} items)"); ImGui.SameLine(); if (ImGui.Button("-")) { if (list.Count > 0) { list.RemoveAt(list.Count - 1); } } ImGui.SameLine(); if (ImGui.Button("+")) { Type listItemType = list.GetType().GetGenericArguments().First(); if (listItemType.IsValueType) { list.Add(Activator.CreateInstance(listItemType)); } else { list.Add(null); } } ImGui.Indent(); for (int i = 0; i < list.Count; i++) { FieldPropertyListInfo itemInfo = new FieldPropertyListInfo(list, i); SubmitFieldPropertyInspector(itemInfo, list); } ImGui.Unindent(); } else if (!infoType.IsValueType) { string valText; var value = info.GetValue(); if (value != null) { valText = value.ToString(); } else { valText = "null"; } string label = $"{info.Name}: {valText}"; if (typeof(Component).IsAssignableFrom(infoType) || typeof(Entity).IsAssignableFrom(infoType)) { if (ImGui.Selectable(label, false)) { SelectedEntityComponent = value; scrollEntitiesView = true; scrollSceneGraphView = true; } } else { ImGui.Text(label); } if (draggedObject != null && infoType.IsAssignableFrom(draggedObject.GetType())) { if (ImGui.BeginDragDropTarget()) { var payload = ImGui.AcceptDragDropPayload(PAYLOAD_STRING); if (payload.NativePtr != null) // Only when this is non-null does it mean that we've released the drag { info.SetValue(draggedObject); draggedObject = null; } ImGui.EndDragDropTarget(); } } } else { SubmitReadonlyFieldPropertyInspector(info); } ImGui.PopID(); SubmitHelpMarker(info); }
public void AssignControl(object controlledObject, FieldPropertyListInfo fieldPropertyInfo) { AssignControl(controlledObject, fieldPropertyInfo, lastAssignmentButton); }