internal static Bitmap GetIcon(GH_ActiveObject comp) { string nickName = comp.NickName; Bitmap bitmap = new Bitmap(24, 24); using (Graphics graphic = Graphics.FromImage(bitmap)) { graphic.TextRenderingHint = TextRenderingHint.AntiAlias; graphic.DrawString(nickName, new System.Drawing.Font(FontFamily.GenericSansSerif, 6f), Brushes.Black, new RectangleF(-1f, -1f, 26f, 26f)); } return(bitmap); }
public override void AppendAdditionalMenuItems(ToolStripDropDown menu) { base.Menu_AppendWireDisplay(menu); GH_ActiveObject.Menu_AppendSeparator(menu); base.Menu_AppendReverseParameter(menu); base.Menu_AppendFlattenParameter(menu); base.Menu_AppendGraftParameter(menu); base.Menu_AppendSimplifyParameter(menu); GH_ActiveObject.Menu_AppendSeparator(menu); base.Menu_AppendPromptOne(menu); GH_ActiveObject.Menu_AppendSeparator(menu); base.Menu_AppendExtractParameter(menu); }
/*************************************/ /**** Public Methods ****/ /*************************************/ public static void ShowEvents(GH_ActiveObject component, List <Event> events, bool clearShownEvents = true) { if (events.Count > 0) { List <string> errors = events.Where(x => x.Type == EventType.Error).Select(x => x.Message).ToList(); List <string> warnings = events.Where(x => x.Type == EventType.Warning).Select(x => x.Message).ToList(); List <string> notes = events.Where(x => x.Type == EventType.Note).Select(x => x.Message).ToList(); // Re-process preexisting messages errors.AddRange(component.RuntimeMessages(GH_RuntimeMessageLevel.Error)); warnings.AddRange(component.RuntimeMessages(GH_RuntimeMessageLevel.Warning)); notes.AddRange(component.RuntimeMessages(GH_RuntimeMessageLevel.Remark)); notes.AddRange(component.RuntimeMessages(GH_RuntimeMessageLevel.Blank)); component.ClearRuntimeMessages(); foreach (string message in errors) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, message); } foreach (string message in warnings) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, message); } //If any warnings or errors have been added, then add the message as a blank. //This is to ensure the colour of the component gets the appropriate colour. //(A bug in GH ranks remarks higher than warning and errors, keeping the component grey when it should be orange/red) //Solution to use 'Blank' warning level, which generally does not do anything on the component. if (errors.Count() > 0 || warnings.Count() > 0) { foreach (string message in notes) { component.AddBlankNoteMessage(message); } } else { foreach (string message in notes) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, message); } } if (clearShownEvents) { Engine.Base.Compute.ClearCurrentEvents(); } } }
/*************************************/ /**** Private Methods ****/ /*************************************/ private static void AddBlankNoteMessage(this GH_ActiveObject component, string text) { //Method added to be able to force in 'Blank' messages to the component. //Method added because 'Blank' messages are not added when `AddRuntimeMessage` is called. //We are adding 'Blank' messages because 'Remark' is treated with higher priority than any of the others (bug in core Grasshopper), //which is causing issues with component colouring. //This is, the component stays standard grey, even if an error or warning has been raised. //If this bug is fixed, this method can be removed and we can return to only adding remarks to the components instead. var messages = component.RuntimeMessages(GH_RuntimeMessageLevel.Blank); foreach (string message in messages) { if (message == text) { return; } } try { //Force add blank messages via reflection //The code below is executing: 'm_messages.Add(new Message(text, GH_RuntimeMessageLevel.Blank));' Type t = typeof(GH_ActiveObject); FieldInfo messageField = t.GetField("m_messages", BindingFlags.NonPublic | BindingFlags.Instance); Type messageType = messageField.FieldType.GenericTypeArguments[0]; ConstructorInfo constructor = messageType.GetConstructors().First(); var mess = constructor.Invoke(new object[] { text, GH_RuntimeMessageLevel.Blank }); var messageList = messageField.GetValue(component); MethodInfo addMethod = messageField.FieldType.GetMethod("Add"); addMethod.Invoke(messageList, new object[] { mess }); } catch (Exception) { //As we are already in the message handling, no real place to add messages here } }
public void SetComponentOutputs(Schema schema, IGH_DataAccess DA, List <IGH_Param> outputParams, GH_ActiveObject component) { foreach (var datatree in schema.Values) { string outputParamName = datatree.ParamName; if (outputParamName.StartsWith("RH_OUT:")) { var chunks = outputParamName.Split(new char[] { ':' }); outputParamName = chunks[chunks.Length - 1]; } int paramIndex = 0; for (int i = 0; i < outputParams.Count; i++) { if (outputParams[i].Name.Equals(outputParamName)) { paramIndex = i; break; } } var structure = new Grasshopper.Kernel.Data.GH_Structure <Grasshopper.Kernel.Types.IGH_Goo>(); Grasshopper.Kernel.Types.IGH_Goo singleGoo = null; foreach (var kv in datatree.InnerTree) { var tokens = kv.Key.Trim(new char[] { '{', '}' }).Split(';'); List <int> elements = new List <int>(); foreach (var token in tokens) { if (!string.IsNullOrWhiteSpace(token)) { elements.Add(int.Parse(token)); } } var path = new Grasshopper.Kernel.Data.GH_Path(elements.ToArray()); for (int gooIndex = 0; gooIndex < kv.Value.Count; gooIndex++) { var goo = GooFromReshopperObject(kv.Value[gooIndex]); singleGoo = goo; structure.Insert(goo, path, gooIndex); } } if (structure.DataCount == 1) { DA.SetData(paramIndex, singleGoo); } else { DA.SetDataTree(paramIndex, structure); } } foreach (var error in schema.Errors) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, error); } foreach (var warning in schema.Warnings) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, warning); } }
// this method creates the spreadsheet, deletes the old one if overwrite is on and there's already on with the same name, // and adds the worksheets if they've been specified. Wrapped in a static method so other components (like WriteToSpreadsheet) // can make use of it and create new spreadsheets. public static SpreadsheetEntry createNewSpreadsheet(GH_ActiveObject activeObj, AuthToken authToken, string sheetName, List<string> worksheets, bool overwrite) { SpreadsheetEntry matchingEntry = null; //setup OAuth Parameters OAuth2Parameters parameters = GDriveUtil.GetParameters(authToken); // It seems clunky to need both a SpreadsheetService and a DocumentService - but // DocumentService is necessary to add/delete spreadsheets, and SpreadsheetService // is needed to manipulate the worksheets. //setup auth and factory for documentsService GOAuth2RequestFactory requestFactory = new GOAuth2RequestFactory(null, "MyDocumentsListIntegration-v1", parameters); DocumentsService docService = new DocumentsService("MyDocumentsListIntegration-v1"); docService.RequestFactory = requestFactory; //setup SpreadsheetsService SpreadsheetsService service = GDriveUtil.GetSpreadsheetsService(parameters); //make spreadsheet documentquery Google.GData.Documents.SpreadsheetQuery dQuery = new Google.GData.Documents.SpreadsheetQuery(); DocumentsFeed dFeed = docService.Query(dQuery); //if user has opted to overwrite, find first matching spreadsheet and delete. If no matching spreadsheet found, nothing happens. if (overwrite) { foreach (DocumentEntry entry in dFeed.Entries) { if (entry.Title.Text.Equals(sheetName)) { docService.Delete(entry); break; } } } //create new spreadsheet object DocumentEntry dEntry = new DocumentEntry(); dEntry.Title.Text = sheetName; dEntry.Categories.Add(DocumentEntry.SPREADSHEET_CATEGORY); docService.Insert(DocumentsListQuery.documentsBaseUri, dEntry); //find the spreadsheet we just created as a SpreadsheetEntry matchingEntry = GDriveUtil.findSpreadsheetByName(sheetName, service); //if worksheets specified, add worksheets if (worksheets.Count > 0) { if (matchingEntry == null) //this shouldn't ever happen, since we just created a new spreadsheet called sheetName. { activeObj.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Something went wrong with spreadsheet creation."); return null; } WorksheetFeed wsFeed = matchingEntry.Worksheets; //first, we find the existing worksheets, store them, add new ones, and then delete the old. List<WorksheetEntry> entriesToDelete = new List<WorksheetEntry>(); foreach (WorksheetEntry entry in wsFeed.Entries) { entriesToDelete.Add(entry); } // find the dimensions of the first worksheet, to use for other worksheet creation uint rows = ((WorksheetEntry)wsFeed.Entries[0]).Rows; uint cols = ((WorksheetEntry)wsFeed.Entries[0]).Cols; for (int i = 0; i < worksheets.Count; i++) { { string wsName = worksheets[i]; WorksheetEntry entry = new WorksheetEntry(rows, cols, wsName); service.Insert(wsFeed, entry); } } foreach (WorksheetEntry entryToDelete in entriesToDelete) { entryToDelete.Delete(); } } //end if worksheets... return matchingEntry; }