Grasshopper

algorithmic modeling for Rhino

A method to determine the relative position of my canvas-drawn bitmap

Using the TextRender method, interestingly enough, I ran into a "feature" that renders text onto the actual canvas of Grasshopper! In a way I'm just going to call this a feature because one could get real creative with the use of this (instruction text, error messages, etc etc). 

The code snippet to do that: 

TextRenderer.DrawText(graphics, "Beware: Monsters out!", SystemFonts.DefaultFont, new Point(10, 10), SystemColors.ControlText);

I am interested in, however, having that text in the relative position of my bitmap render. This is what my component looks like:
Is there a method that determines the relative position of points with-in this image displayed?

Thank you.

Views: 966

Replies to This Discussion

The Canvas is a typical winforms control which is drawn using a System.Drawing.Graphics object, so you can draw whatever you want wherever you want. (Though not whenever you want, you're only allowed to use the Graphics object during paint events.)

The drawing logic of the Canvas is pretty complicated as there are a lot of layers/channels in which different things are drawn, and Grasshopper itself draws stuff in between channels as well. The (somewhat simplified) logic is thus:

  1. Graphics object and Painting flag are set for the duration of the upcoming drawing process.
  2. Canvas painting schedule is cleared.
  3. CanvasPaintBegin event is raised.
  4. ZUI alpha values are computed and cached based on the current zoom level.
  5. The pan+zoom transformation matrix is computed and applied to the current Graphics object.
  6. The background of the canvas is drawn. This includes the grid and the page and the page shadow.
  7. The CanvasPaintBackground event is raised in case anyone wants to draw something on top of the background but underneath everything else.
  8. If there is no Document loaded in the canvas, skip to step X
  9. The CanvasPrePaintGroups event is raised, in case someone wants to draw something underneath Group objects.
  10. All groups objects are drawn.
  11. All TagArtist objects registered with the canvas have their Paint method called with the Group flag.
  12. The CanvasPostPaintGroups event is raised.
  13. The CanvasPrePaintWires event is raised.
  14. All wires are drawn.
  15. All TagArtists registered with the canvas have their Paint method called with the Wire flag.
  16. The CanvasPostPaintWires event is raised.
  17. The CanvasPrePaintObjects event is raised.
  18. All objects are drawn.
  19. All TagArtists registered with the canvas have their Paint method called with the Objects flag.
  20. The CanvasPostPaintObjects event is raised.
  21. The CanvasPrePaintOverlay event is raised.
  22. All overlays are drawn (there typically aren't any).
  23. All TagArtists registered with the canvas.... enfin.
  24. The CanvasPostPaintOverlay event is raised.
  25. The CanvasPrePaintWidgets event is raised.
  26. All the Widgets (Compass, Marko, Align tools, Message Balloons) are drawn.
  27. If the solver is locked, the thick red border and the Locked icon are drawn.
  28. If the last solution was aborted, the Abort icon is drawn.
  29. If the current document is a cluster document, the Cluster icon is drawn.
  30. The CanvasPostPaintWidgets event is raised.
  31. If the canvas is currently locked (for example during Galapagos iterations), the fuzzy edges are drawn.
  32. The Drag+Drop curl is drawn if it exists.
  33. The MRU tiles are drawn.
  34. The CanvasPaintEnd event is raised.
  35. The graphics object is cleared, it is now no longer possible to draw anything to the canvas until the next paint event.
  36. The canvas redraw schedule is restarted if it exists.

Things like Window-Select rectangles, the Radial menu, the Moses tool etc. are called Interactions and they use the events to draw things as well, but they are not part of the intrinsic painting pipeline.

--

David Rutten

david@mcneel.com

During most of the painting process, the Graphics object which belongs to the Canvas has the zoom+pan transformation applied to it. So if you draw things in regular component coordinates they should appear in the right place.

I do not know if TextRenderer.DrawText ignores the display transform, it would be surprising if it did. When exactly are you calling that method?

--

David Rutten

david@mcneel.com

If you want to draw text to the canvas, I recommend using Graphics.DrawString with the Graphics object that you are given inside the Attribute Render method. DrawString has a fair number of overloads and you can specify wrapping, clipping, trimming and alignment options as well as font and fill properties.

You can use the GH_FontServer class to get access to standard fonts used in Grasshopper. DO NOT DISPOSE these fonts as they are used over and over again by different components.

--

David Rutten

david@mcneel.com

If the text doesn't fit in the rectangle, it may not be drawn at all. 10x10 pixels is pretty small. Also a rectangle starting at 10,10 means the text will be drawn close to the canvas 'page' corner, wherever that is. If your component is not visible when the page corner is, the Render method won't even be called.

--

David Rutten

david@mcneel.com

RSS

About

Translate

Search

Photos

  • Add Photos
  • View All

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service