public void DoUI(IObjectUIControl control)
            {
                for (int i = 0; i < propertyDictKeys.Length; i++)
                {
                    string key = propertyDictKeys[i];

                    if (propertyInfos != null && propertyInfos.TryGetValue(key, out string desc))
                    {
                        control.SetTooltip(desc);
                    }
                    else
                    {
                        control.SetTooltip("No info for " + key);
                    }


                    if (propertyDict[key] is int)
                    {
                        propertyDict[key] = (int)control.NumberInput(propertyDict[key], key);
                    }
                    else if (propertyDict[key] is float)
                    {
                        propertyDict[key] = control.NumberInput(propertyDict[key], key);
                    }
                    else if (propertyDict[key] is string)
                    {
                        propertyDict[key] = control.TextInput(propertyDict[key], key);
                    }
                    else if (propertyDict[key] is bool)
                    {
                        propertyDict[key] = control.CheckBox(key, propertyDict[key]);
                    }
                }

                control.SetTooltip(null);


                if (control.Button("Edit"))
                {
                    ObjectParameterForm.TypeDef.Localize();
                    List <(ObjectParameterForm.TypeDef typeDef, string name)> parameterInfos = new List <(ObjectParameterForm.TypeDef typeDef, string name)>();

                    List <KeyValuePair <string, dynamic> > otherParameters = new List <KeyValuePair <string, dynamic> >();

                    //get parameterInfos from propertyDict
                    foreach (var item in propertyDict)
                    {
                        if (item.Value is int)
                        {
                            parameterInfos.Add((ObjectParameterForm.TypeDef.IntDef, item.Key));
                        }
                        else if (item.Value is float)
                        {
                            parameterInfos.Add((ObjectParameterForm.TypeDef.FloatDef, item.Key));
                        }
                        else if (item.Value is string)
                        {
                            parameterInfos.Add((ObjectParameterForm.TypeDef.StringDef, item.Key));
                        }
                        else if (item.Value is bool)
                        {
                            parameterInfos.Add((ObjectParameterForm.TypeDef.BoolDef, item.Key));
                        }
                        else
                        {
                            otherParameters.Add(item); //arrays and dictionaries are not supported
                        }
                    }

                    var parameterForm = new ObjectParameterForm(parameterInfos);

                    if (parameterForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        List <RevertableDictAddition.AddInfo>    addInfos    = new List <RevertableDictAddition.AddInfo>();
                        List <RevertableDictDeletion.DeleteInfo> deleteInfos = new List <RevertableDictDeletion.DeleteInfo>();
                        List <RevertableDictEntryChange>         changeInfos = new List <RevertableDictEntryChange>();

                        HashSet <string> newParamNames = new HashSet <string>();

                        List <KeyValuePair <string, dynamic> > newParameters = new List <KeyValuePair <string, dynamic> >();
                        foreach ((ObjectParameterForm.TypeDef typeDef, string parameterName) in parameterForm.EditedParameterInfos)
                        {
                            //check if name stayed the same
                            if (propertyDict.ContainsKey(parameterName))
                            {
                                if (propertyDict[parameterName].GetType() == typeDef.Type)
                                {
                                    //keep value if name and type stayed the same
                                    newParameters.Add(new KeyValuePair <string, dynamic>(parameterName, propertyDict[parameterName]));
                                }
                                else
                                {
                                    //set value to the default value of the new type
                                    newParameters.Add(new KeyValuePair <string, dynamic>(parameterName, typeDef.DefaultValue));
                                    //and add the value change to changeInfos
                                    changeInfos.Add(new RevertableDictEntryChange(parameterName, propertyDict, propertyDict[parameterName]));
                                }
                            }
                            else
                            {
                                //add added paramter to addInfos
                                newParameters.Add(new KeyValuePair <string, dynamic>(parameterName, typeDef.DefaultValue));
                                addInfos.Add(new RevertableDictAddition.AddInfo(typeDef.DefaultValue, parameterName));
                            }
                            newParamNames.Add(parameterName);
                        }

                        //add removed parameters to deleteInfos
                        foreach (var property in propertyDict)
                        {
                            if (!newParamNames.Contains(property.Key))
                            {
                                deleteInfos.Add(new RevertableDictDeletion.DeleteInfo(property.Value, property.Key));
                            }
                        }

                        //add everything to undo
                        scene.BeginUndoCollection();
                        scene.AddToUndo(new RevertableDictAddition(new RevertableDictAddition.AddInDictInfo[]
                        {
                            new RevertableDictAddition.AddInDictInfo(addInfos.ToArray(), propertyDict)
                        },
                                                                   Array.Empty <RevertableDictAddition.SingleAddInDictInfo>()));

                        scene.AddToUndo(new RevertableDictDeletion(new RevertableDictDeletion.DeleteInDictInfo[]
                        {
                            new RevertableDictDeletion.DeleteInDictInfo(deleteInfos.ToArray(), propertyDict)
                        },
                                                                   Array.Empty <RevertableDictDeletion.SingleDeleteInDictInfo>()));


                        foreach (var changeInfo in changeInfos)
                        {
                            scene.AddToUndo(changeInfo);
                        }
                        scene.EndUndoCollection();

                        //regenerate propertyDict by merging the newParameters and the oterParameters
                        propertyDict.Clear();

                        foreach (var parameter in newParameters)
                        {
                            propertyDict.Add(parameter.Key, parameter.Value);
                        }

                        foreach (var parameter in otherParameters)
                        {
                            propertyDict.Add(parameter.Key, parameter.Value);
                        }

                        //update keys
                        propertyDictKeys = propertyDict.Keys.ToArray();
                    }
                }
            }
            public void DoUI(IObjectUIControl control)
            {
#if ODYSSEY
                control.PlainText(Convert.ToString(obj.ScenarioBitField, 2));
#endif
                if (Spotlight.Properties.Settings.Default.AllowIDEdits)
                {
                    obj.ID = control.TextInput(obj.ID, "Object ID");
                }
                else
                {
                    control.TextInput(obj.ID, "Object ID");
                }

                if (obj.comment != null)
                {
                    control.TextInput(obj.comment, "Comment");
                }

                obj.Layer      = control.TextInput(obj.Layer, "Layer");
                obj.ObjectName = control.DropDownTextInput("Object Name", obj.ObjectName, DB_objectNames);

                if (showClassNameInfo)
                {
                    control.SetTooltip(classNameInfo);
                }
                obj.ClassName = control.DropDownTextInput("Class Name", obj.ClassName, DB_classNames);
                if (showClassNameAlias)
                {
                    control.PlainText(classNameAlias);
                }
                control.SetTooltip(null);

                obj.ModelName = control.DropDownTextInput("Model Name", obj.ModelName, DB_modelNames);

                control.VerticalSeperator();

                if (WinInput.Keyboard.IsKeyDown(WinInput.Key.LeftShift))
                {
                    obj.Position = control.Vector3Input(obj.Position, "Position", 1, 16);
                }
                else
                {
                    obj.Position = control.Vector3Input(obj.Position, "Position", 0.125f, 2);
                }

                if (WinInput.Keyboard.IsKeyDown(WinInput.Key.LeftShift))
                {
                    obj.Rotation = control.Vector3Input(obj.Rotation, "Rotation", 45, 18);
                }
                else
                {
                    obj.Rotation = control.Vector3Input(obj.Rotation, "Rotation", 5, 2);
                }

                if (WinInput.Keyboard.IsKeyDown(WinInput.Key.LeftShift))
                {
                    obj.Scale = control.Vector3Input(obj.Scale, "Scale", 1, 16);
                }
                else
                {
                    obj.Scale = control.Vector3Input(obj.Scale, "Scale", 0.125f, 2);
                }

                control.VerticalSeperator();

                if (WinInput.Keyboard.IsKeyDown(WinInput.Key.LeftShift))
                {
                    obj.DisplayTranslation = control.Vector3Input(obj.DisplayTranslation, "Display Position", 1, 16);
                }
                else
                {
                    obj.DisplayTranslation = control.Vector3Input(obj.DisplayTranslation, "Display Position", 0.125f, 2);
                }

                //TODO
            }