/// <summary> /// Extract data from the Grasshopper Data Access object, converting it into the specified type where necessary /// </summary> /// <param name="index"></param> /// <param name="type"></param> /// <param name="DA"></param> /// <returns></returns> protected object GetInputData(string name, Type type, IGH_DataAccess DA, ActionInputAttribute inputAtt) { object result = null; if (type != typeof(ActionTriggerInput)) { try { // TODO: equivalent for GetDataList Type equivalentType = GetEquivalentType(type); MemberInfo[] mInfos; var pAccess = ParamAccess(inputAtt); if (pAccess == GH_ParamAccess.item) { mInfos = typeof(IGH_DataAccess).GetMember("GetData"); } else { var listType = typeof(List <>); var constructedListType = listType.MakeGenericType(equivalentType); result = Activator.CreateInstance(constructedListType); mInfos = typeof(IGH_DataAccess).GetMember("GetDataList"); } //TODO: Trees? MethodInfo getDataMethod = null; foreach (MethodInfo mInfo in mInfos) { Type firstPT = mInfo.GetParameters()[0].ParameterType; if (firstPT == typeof(string)) { getDataMethod = mInfo; } } if (getDataMethod != null) { object[] args = new object[] { name, result }; MethodInfo getDataGeneric = getDataMethod.MakeGenericMethod(new Type[] { equivalentType }); bool success = (bool)getDataGeneric.Invoke(DA, args); if (success) { result = args[1]; if (result.GetType() != type) { result = Convert(result, type); } } else { result = null; } } } catch (Exception e) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message); } } return(result); }
/// <summary> /// Get the appropriate GH_ParamAccess value for a collection type with the given ActionInput attribute /// </summary> /// <param name="inputAtt"></param> /// <returns></returns> private GH_ParamAccess ParamAccess(ActionInputAttribute inputAtt) { if (inputAtt.OneByOne) { return(GH_ParamAccess.item); } else { return(GH_ParamAccess.list); } }
/// <summary> /// Automatically populate action inputs using data extracted from the Grasshopper Data Access object. /// </summary> /// <param name="action"></param> /// <param name="DA"></param> protected bool ExtractInputs(IAction action, IGH_DataAccess DA) { IList <PropertyInfo> inputs = ActionBase.ExtractInputParameters(ActionType); foreach (PropertyInfo pInfo in inputs) { ActionInputAttribute inputAtt = ActionInputAttribute.ExtractFrom(pInfo); if (inputAtt.Parametric) //Ignore non-parametric inputs { Type inputType = pInfo.PropertyType; object inputData = GetInputData(pInfo.Name, inputType, DA, inputAtt); if (!inputAtt.Required || inputData != null) { pInfo.SetValue(action, inputData, null); } else { return(false); } } } return(true); }
/// <summary> /// Registers all the input parameters for this component. /// </summary> protected override void RegisterInputParams(GH_InputParamManager pManager) { IAction action = (IAction)Activator.CreateInstance(ActionType, true); NicknameConverter nC = new NicknameConverter(); IList <PropertyInfo> inputs = ActionBase.ExtractInputParameters(ActionType); foreach (PropertyInfo pInfo in inputs) { Type pType = pInfo.PropertyType; ActionInputAttribute inputAtt = ActionInputAttribute.ExtractFrom(pInfo); if (inputAtt != null && inputAtt.Parametric) { string name = pInfo.Name; string nickname = string.IsNullOrEmpty(inputAtt.ShortName) ? nC.Convert(pInfo.Name) : inputAtt.ShortName; string description = inputAtt.CapitalisedDescription; if (pType == typeof(double)) { pManager.AddNumberParameter(name, nickname, description, GH_ParamAccess.item, (double)pInfo.GetValue(action, null)); } else if (pType == typeof(int)) { pManager.AddIntegerParameter(name, nickname, description, GH_ParamAccess.item, (int)pInfo.GetValue(action, null)); } else if (pType == typeof(string)) { pManager.AddTextParameter(name, nickname, description, GH_ParamAccess.item, (string)pInfo.GetValue(action, null)); } else if (pType == typeof(bool)) { //Special case when the input is a 'Write' toggle - default off! pManager.AddBooleanParameter(name, nickname, description, GH_ParamAccess.item, name == "Write" ? false : (bool)pInfo.GetValue(action, null)); } else if (pType == typeof(Vector)) { pManager.AddPointParameter(name, nickname, description, GH_ParamAccess.item); } else if (typeof(IList <Vector>).IsAssignableFrom(pType)) //Vector list { pManager.AddPointParameter(name, nickname, description, GH_ParamAccess.list); } else if (pType.IsAssignableFrom(typeof(Plane))) { pManager.AddPlaneParameter(name, nickname, description, GH_ParamAccess.item, ToRC.Convert((Plane)pInfo.GetValue(action, null))); } else if (pType == typeof(Line)) { pManager.AddLineParameter(name, nickname, description, GH_ParamAccess.item); } else if (pType == typeof(Angle)) { pManager.AddAngleParameter(name, nickname, description, GH_ParamAccess.item, (Angle)pInfo.GetValue(action, null)); } else if (typeof(Curve).IsAssignableFrom(pType)) { pManager.AddCurveParameter(name, nickname, description, GH_ParamAccess.item); } else if (typeof(CurveCollection).IsAssignableFrom(pType)) { pManager.AddCurveParameter(name, nickname, description, GH_ParamAccess.list); } else if (typeof(LinearElement).IsAssignableFrom(pType)) { IGH_Param param = new LinearElementParam(); pManager.AddParameter(param, name, nickname, description, GH_ParamAccess.item); } else if (typeof(PanelElement).IsAssignableFrom(pType)) { IGH_Param param = new PanelElementParam(); pManager.AddParameter(param, name, nickname, description, GH_ParamAccess.item); } else if (typeof(Element).IsAssignableFrom(pType)) { IGH_Param param = new ElementParam(); pManager.AddParameter(param, name, nickname, description, GH_ParamAccess.item); } else if (typeof(LinearElementCollection).IsAssignableFrom(pType)) { IGH_Param param = new LinearElementParam(); pManager.AddParameter(param, name, nickname, description, ParamAccess(inputAtt)); } else if (typeof(PanelElementCollection).IsAssignableFrom(pType)) { IGH_Param param = new PanelElementParam(); pManager.AddParameter(param, name, nickname, description, ParamAccess(inputAtt)); } else if (typeof(ElementCollection).IsAssignableFrom(pType)) { IGH_Param param = new ElementParam(); pManager.AddParameter(param, name, nickname, description, ParamAccess(inputAtt)); } else if (pType == typeof(Node)) { IGH_Param param = new NodeParam(); pManager.AddParameter(param, name, nickname, description, GH_ParamAccess.item); } else if (pType == typeof(NodeCollection)) { IGH_Param param = new NodeParam(); pManager.AddParameter(param, name, nickname, description, ParamAccess(inputAtt)); } else if (typeof(Nucleus.Model.Material).IsAssignableFrom(pType)) { IGH_Param param = new MaterialParam(); pManager.AddParameter(param, name, nickname, description, GH_ParamAccess.item); } else if (typeof(MaterialCollection).IsAssignableFrom(pType)) { IGH_Param param = new MaterialParam(); pManager.AddParameter(param, name, nickname, description, ParamAccess(inputAtt)); } else if (typeof(SectionFamily).IsAssignableFrom(pType)) { IGH_Param param = new SectionFamilyParam(); pManager.AddParameter(param, name, nickname, description, GH_ParamAccess.item); } else if (pType == typeof(Bool6D)) { IGH_Param param = new Bool6DParam(); pManager.AddParameter(param, name, nickname, description, GH_ParamAccess.item); } else if (pType == typeof(FilePath)) { pManager.AddTextParameter(name, nickname, description, GH_ParamAccess.item); } else if (pType == typeof(VertexGeometry)) { pManager.AddGeometryParameter(name, nickname, description, GH_ParamAccess.item); } else if (pType == typeof(VertexGeometryCollection)) { pManager.AddGeometryParameter(name, nickname, description, ParamAccess(inputAtt)); } else if (pType == typeof(ActionTriggerInput)) { pManager.AddGenericParameter(name, nickname, description, GH_ParamAccess.tree); } else if (pType == typeof(Direction)) { pManager.AddTextParameter(name, nickname, description, GH_ParamAccess.item, pInfo.GetValue(action, null)?.ToString()); } else if (pType == typeof(CoordinateSystemReference)) { pManager.AddTextParameter(name, nickname, description, GH_ParamAccess.item, pInfo.GetValue(action, null)?.ToString()); } else if (pType.IsEnum) { pManager.AddTextParameter(name, nickname, description, GH_ParamAccess.item, pInfo.GetValue(action, null)?.ToString()); } else { pManager.AddGenericParameter(pInfo.Name, nickname, description, GH_ParamAccess.item); } if (inputAtt.Required == false) { pManager[pManager.ParamCount - 1].Optional = true; } //TODO } } }
/// <summary> /// Prompt the user to enter data of the specified type. /// The appropriate 'Enter____' function will be automatically selected based on the type. /// Override this to enable actions to use application-specific data types as inputs. /// </summary> /// <param name="inputType">The type of data to be entered</param> /// <param name="value">Input: The default value. Output: The selected value./param> /// <param name="property">Optional. The property being populated.</param> /// <param name="action">Optional. The action the input parameters of which are currently /// being populated.</param> public virtual bool EnterInput(Type inputType, ref object value, PropertyInfo property = null, IAction action = null, bool chain = false) { string description = null; ActionInputAttribute inputAttributes = ActionInputAttribute.ExtractFrom(property); if (inputAttributes != null) { description = inputAttributes.Description; } if (description == null) { description = inputType.Name; } try { if (inputType == typeof(double)) //Double { value = EnterDouble("Enter " + description, (double)value); } else if (inputType == typeof(int)) //Integer { value = EnterInteger("Enter " + description, (int)value); } else if (inputType == typeof(string)) //String { if (inputAttributes?.SuggestionsPath != null) { IList <string> suggestions = null; if (action != null) { var pI = action.GetType().GetProperty(inputAttributes.SuggestionsPath); if (pI != null) { suggestions = pI.GetValue(action) as IList <string>; } } value = EnterString(suggestions, "Enter " + description, (string)value); } else { value = EnterString("Enter " + description, (string)value); } } else if (inputType == typeof(FilePath)) //FilePath { string filter = "All Files (*.*)|*.*"; bool open = false; if (inputAttributes != null && inputAttributes is ActionFilePathInputAttribute) { ActionFilePathInputAttribute filePathAttribute = (ActionFilePathInputAttribute)inputAttributes; filter = filePathAttribute.Filter; open = filePathAttribute.Open; } if (open) { value = EnterOpenFilePath("Select " + description, filter, (FilePath)value); } else { value = EnterSaveFilePath("Select " + description, filter, (FilePath)value); } } else if (inputType == typeof(Vector)) //Nucleus Vector { value = EnterPoint("Enter " + description); } else if (inputType.IsAssignableFrom(typeof(Vector[]))) { value = EnterPoints("Enter " + description); } else if (inputType.IsAssignableFrom(typeof(Plane))) // Nucleus Plane { value = EnterPlane("Enter " + description); } else if (inputType == typeof(Line)) //Nucleus Line { if (chain && value != null && value is Line) { Line line = (Line)value; value = EnterLine("", "Enter next end point of " + description, line.StartPoint); } else { value = EnterLine("Enter start point of " + description, "Enter end point of " + description); } } else if (inputType == typeof(Curve)) //Nucleus Curve { value = EnterCurve("Enter " + description); } else if (inputType == typeof(VertexGeometryCollection)) //Nucleus Shapes { value = EnterGeometry("Enter " + description); } else { return(false); //Input not recognised } } catch (OperationCanceledException) { return(false); } return(true); }