コード例 #1
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            try
            {
                if (!hasProperlyGrabbedShadowElements)                  //if we have not yet succeeded in retoring states from shadows
                {
                    hasProperlyGrabbedShadowElements = shadowToState(); //try restoring states from shadows
                }
            }
            catch (Exception e)
            {
                //hopefully this never happens.
                AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, String.Format("It threw an {0} error when trying to restore shadow states", e.ToString()));
            }

            bool allElementsHaveParents = true;

            //hacky hack fix for weird deserialization problem. It occasionally happens that elements are deserialized before they belong to a window -
            //if this happens we have to get them from the shadow state a second time.
            if (savedStates != null)
            {
                foreach (State state in savedStates.states.Values)
                {
                    foreach (UIElement_Goo goo in state.stateDict.Keys)
                    {
                        if (FindTopmostParent <HumanUIBaseApp.MainWindow>(goo.element) == null)
                        {
                            allElementsHaveParents = false;
                        }
                    }
                }
            }

            if (!allElementsHaveParents)
            {
                shadowToState();
            }

            bool   saveState  = false;
            bool   clearState = false;
            string stateName  = "Unnamed State";

            List <object> elementObjects = new List <object>();
            List <KeyValuePair <string, UIElement_Goo> > allElements = new List <KeyValuePair <string, UIElement_Goo> >();
            List <string> elementFilters = new List <string>();

            if (!DA.GetDataList <object>("Elements", elementObjects))
            {
                return;
            }
            if (!DA.GetData <string>("State Name", ref stateName))
            {
                return;
            }
            DA.GetData <bool>("Save State", ref saveState);
            DA.GetData <bool>("Clear Saved States", ref clearState);

            bool hasFilters = DA.GetDataList <string>("Name Filter(s)", elementFilters);



            List <UIElement_Goo> filteredElements = new List <UIElement_Goo>();

            // This is necessary because sometimes elements will come in as UIElement_Goo,
            // and sometimes they will be wrapped Key-Value pairs from a dictionary. I think this
            // latter case is now fairly rare - I think only the "Filter UI Element" component was outputting a dictionary
            // but I'm leaving it in for backwards compatibility.
            foreach (object o in elementObjects)
            {
                switch (o.GetType().ToString())
                {
                case "HumanUI.UIElement_Goo":
                    UIElement_Goo goo = o as UIElement_Goo;
                    filteredElements.Add(goo);
                    break;

                case "Grasshopper.Kernel.Types.GH_ObjectWrapper":
                    GH_ObjectWrapper wrapper = o as GH_ObjectWrapper;
                    KeyValuePair <string, UIElement_Goo> kvp = (KeyValuePair <string, UIElement_Goo>)wrapper.Value;
                    allElements.Add(kvp);
                    break;

                default:
                    break;
                }
            }

            if (allElements.Count > 0) //if we've been getting keyvaluepairs and need to filter
            {
                //create a dictionary for filtering
                Dictionary <string, UIElement_Goo> elementDict = allElements.ToDictionary(pair => pair.Key, pair => pair.Value);



                //filter the dictionary
                foreach (string fil in elementFilters)
                {
                    filteredElements.Add(elementDict[fil]);
                }
                //if there are no filters, include all values.
                if (elementFilters.Count == 0)
                {
                    foreach (UIElement_Goo u in elementDict.Values)
                    {
                        filteredElements.Add(u);
                    }
                }
            }



            //clear the saved state info
            if (clearState)
            {
                savedStates.Clear();
                savedShadowStates.Clear();
            }



            //if the user has specified that the state should be saved
            if (saveState)
            {
                baseElems = new List <UIElement>();

                //setting up a 1:1 correspondence between base elements and parent elements (UI_ElementGoo).
                foreach (UIElement_Goo u in filteredElements)
                {
                    baseElems.Add(HUI_Util.extractBaseElement(u.element));
                }


                State namedState = new State();
                //for each element
                for (int i = 0; i < baseElems.Count; i++)
                {
                    UIElement     u      = baseElems[i];
                    UIElement_Goo parent = filteredElements[i];
                    //get its state
                    object state = HUI_Util.GetElementValue(u);
                    //add the element and its state to an element state dictionary


                    namedState.AddMember(parent, state);
                }
                savedStates.Add(stateName, namedState);
            }
            DA.SetData("Saved States", savedStates);
            DA.SetDataList("Saved State Names", savedStates.Names);
        }