<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>http://ryanmccuaig.net/</id>
  <title>ryanmccuaig.net</title>
  <updated>2012-01-06T08:00:00Z</updated>
  <link rel="alternate" href="http://ryanmccuaig.net/"/>
  <link rel="self" href="http://ryanmccuaig.net/atom.xml"/>
  <author>
    <name>Ryan McCuaig</name>
    <uri>http://ryanmccuaig.net/about</uri>
  </author>
  <entry>
    <id>tag:ryanmccuaig.net,2012-01-06:/2012/01/06-vectorworks-tdd/</id>
    <title type="html">More Vectorworks TDD</title>
    <published>2012-01-06T08:00:00Z</published>
    <updated>2012-01-06T08:00:00Z</updated>
    <link rel="alternate" href="http://ryanmccuaig.net/2012/01/06-vectorworks-tdd/"/>
    <content type="html">&lt;article&gt;
&lt;h1&gt;More Vectorworks TDD&lt;/h1&gt;

&lt;p&gt;&lt;a href="http://twitter.com/hmkern99"&gt;Hans Martin Kern&lt;/a&gt; has added &lt;a href="http://www.spuriousthoughts.com/2011/10/03/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-4/"&gt;Part 4&lt;/a&gt; to his discussion of test-driven Tool plug-ins. Feeling inspired to finally finish my own Part 4.&lt;/p&gt;

&lt;h6&gt;Fri  6 Jan 2012&lt;/h6&gt;
&lt;/article&gt;</content>
  </entry>
  <entry>
    <id>tag:ryanmccuaig.net,2011-08-19:/2011/08/19-vectorworks-tdd/</id>
    <title type="html">Test-driven Vectorworks development</title>
    <published>2011-08-19T07:00:00Z</published>
    <updated>2011-08-19T07:00:00Z</updated>
    <link rel="alternate" href="http://ryanmccuaig.net/2011/08/19-vectorworks-tdd/"/>
    <content type="html">&lt;article&gt;
&lt;h1&gt;Test-driven Vectorworks development&lt;/h1&gt;

&lt;p&gt;I’m a born-again test-driven developer (where practical), so it thrills me to discover that
&lt;a href="http://twitter.com/hmkern99"&gt;Hans Martin Kern&lt;/a&gt; of &lt;a href="http://www.extragroup.de/en/"&gt;extragroup GmbH&lt;/a&gt; has written two
article series to guide us through the development of C++ plugins for
Vectorworks using TDD.&lt;/p&gt;

&lt;p&gt;Series one is about creating a Parametric Object:
&lt;a href="http://www.spuriousthoughts.com/2011/04/16/developing-a-vectorworks-2011-plug-in-tdd-style-episode-0/"&gt;Introduction&lt;/a&gt;,
&lt;a href="http://www.spuriousthoughts.com/2011/04/17/developing-a-vectorworks-2011-plug-in-tdd-style-episode-1/"&gt;Part 1&lt;/a&gt;,
&lt;a href="http://www.spuriousthoughts.com/2011/04/17/developing-a-vectorworks-2011-plug-in-tdd-style-episode-2/"&gt;Part 2&lt;/a&gt;,
&lt;a href="http://www.spuriousthoughts.com/2011/04/18/developing-a-vectorworks-2011-plug-in-tdd-style-episode-3/"&gt;Part 3&lt;/a&gt;,
&lt;a href="http://www.spuriousthoughts.com/2011/04/19/developing-a-vectorworks-2011-plug-in-tdd-style-episode-4/"&gt;Part 4&lt;/a&gt;,
&lt;a href="http://www.spuriousthoughts.com/2011/04/21/developing-a-vectorworks-2011-plug-in-tdd-style-episode-5/"&gt;Part 5&lt;/a&gt;,
&lt;a href="http://www.spuriousthoughts.com/2011/04/24/developing-a-vectorworks-2011-plug-in-tdd-style-episode-6/"&gt;Part 6&lt;/a&gt;,
&lt;a href="http://www.spuriousthoughts.com/2011/04/27/developing-a-vectorworks-2011-plug-in-tdd-style-episode-7/"&gt;Part 7&lt;/a&gt;,
&lt;a href="http://www.spuriousthoughts.com/2011/05/02/developing-a-vectorworks-2011-plug-in-tdd-style-epilogue/"&gt;Epilogue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Series two–still underway–is about creating a Tool:
&lt;a href="http://www.spuriousthoughts.com/2011/06/02/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-0/"&gt;Introduction&lt;/a&gt;,
&lt;a href="http://www.spuriousthoughts.com/2011/06/08/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-1/"&gt;Part 1&lt;/a&gt;,
&lt;a href="http://www.spuriousthoughts.com/2011/06/17/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-2/"&gt;Part 2&lt;/a&gt;,
&lt;a href="http://www.spuriousthoughts.com/2011/07/22/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-3/"&gt;Part 3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read and learn. Bonus points for the Muppet Show references.&lt;/p&gt;

&lt;h6&gt;Fri 19 Aug 2011&lt;/h6&gt;
&lt;/article&gt;</content>
  </entry>
  <entry>
    <id>tag:ryanmccuaig.net,2011-03-14:/2011/03/14-getting-started-part-3/</id>
    <title type="html">Getting started with the Vectorworks SDK, Part 3</title>
    <published>2011-03-14T07:00:00Z</published>
    <updated>2011-03-14T07:00:00Z</updated>
    <link rel="alternate" href="http://ryanmccuaig.net/2011/03/14-getting-started-part-3/"/>
    <content type="html">&lt;article&gt;
&lt;h1&gt;Getting started with the Vectorworks SDK, Part 3&lt;/h1&gt;

&lt;p&gt;We have &lt;a href="/2011/02/28-getting-started-part-2/"&gt;basic plug-in theory&lt;/a&gt; covered.&lt;/p&gt;

&lt;p&gt;What follows is what you will need to install to play along at home, so please get your tools ready while you breathlessly await Part 4. I shall assume you’re running an Intel Mac with Snow Leopard 10.6.6. (My own hardware is a 2006-era Mac Pro; if you have the juice to run Vectorworks 2011, you have the juice to build plug-ins).&lt;/p&gt;

&lt;h2&gt;Install Homebrew&lt;/h2&gt;

&lt;p&gt;This is a useful prerequisite, but not required. There are a few Unix command-line tools you will need. I’ve found &lt;a href="http://mxcl.github.com/homebrew/"&gt;Homebrew&lt;/a&gt; to be the simplest way to get these installed and keep them up-to-date, since they have to be built from source, many of them depend on other tools, which depend on other tools and libraries, &amp;amp;c.&lt;/p&gt;

&lt;h2&gt;Install &lt;code&gt;ack&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;You will want &lt;a href="http://betterthangrep.com/"&gt;&lt;code&gt;ack&lt;/code&gt;&lt;/a&gt;. Given the transitional state of the &lt;a href="http://developer.vectorworks.net/index.php?title=Main_Page"&gt;official documentation&lt;/a&gt;, I seem to spend a lot of time combing C++ header files for argument order, return values, examples of function usage, &amp;amp;c. Homebrew provides a command line version with &lt;code&gt;brew install ack&lt;/code&gt;, and I also have the &lt;a href="https://github.com/protocool/AckMate"&gt;AckMate&lt;/a&gt; plug-in installed in &lt;a href="http://macromates.com"&gt;TextMate&lt;/a&gt;. (Note that TextMate is in no way necessary for SDK development, but it’s useful for Vectorscript development).&lt;/p&gt;

&lt;h2&gt;Install &lt;code&gt;git&lt;/code&gt; and Gitx&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="http://git-scm.com"&gt;&lt;code&gt;git&lt;/code&gt;&lt;/a&gt; for version control. You will &lt;a href="http://cocoawithlove.com/2010/12/version-control-for-solo-mac-developers.html"&gt;want version control&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;(NB: It will start to greatly annoy you that Vectorworks uses pessimistic locking at a grain that makes no sense in architectural teamwork—ie. a file on disk—and offers no version control or design option tools of any kind. This is one of my longstanding hobbyhorses. Feel free to join the cause).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git&lt;/code&gt; has a brutal command-line user interface pasted on top of a shockingly elegant, simple conceptual underpinning. Expect pain, but know that it’s worth it in the end. Book some couch time with &lt;a href="http://gitcasts.com/"&gt;gitcasts&lt;/a&gt;. Installing &lt;code&gt;git&lt;/code&gt; is optional, but highly recommended: just &lt;code&gt;brew install git&lt;/code&gt;. At a bare minimum, use Subversion should you already know it. &lt;/p&gt;

&lt;p&gt;I rely on the open-source &lt;a href="http://gitx.frim.nl/"&gt;Gitx&lt;/a&gt; as a GUI. I use the &lt;a href="https://github.com/brotherbard/gitx"&gt;brotherbard fork&lt;/a&gt;, which has some nice features that may make their way back into the main line some day. &lt;a href="http://www.git-tower.com/"&gt;Tower&lt;/a&gt; looks promising, but I don’t have any real experience with it.&lt;/p&gt;

&lt;p&gt;Any &lt;code&gt;git&lt;/code&gt; GUI is unlikely to include every feature of the command-line version, so at least get comfortable with basic operations from the command line, however irritating it may be.&lt;/p&gt;

&lt;h2&gt;Install &lt;code&gt;rake&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="http://rake.rubyforge.org/"&gt;&lt;code&gt;rake&lt;/code&gt;&lt;/a&gt; to make sure the dozen or so tedious little steps required to build and deploy happen the same way every time. Many tools could work here – including plain old &lt;code&gt;make&lt;/code&gt;, or &lt;code&gt;ant&lt;/code&gt; if you happen to have a S&amp;amp;M thing for XML – but I’m simply most comfortable with &lt;code&gt;rake&lt;/code&gt;. Because Ruby comes stock on Mac OS X, you can install it with a simple &lt;code&gt;sudo gem install rake&lt;/code&gt;. Or, you can get fancy with the &lt;a href="https://rvm.beginrescueend.com/"&gt;Ruby Version Manager&lt;/a&gt;, as I do; I tend to have several versions of Ruby installed at any one time for my other development projects.&lt;/p&gt;

&lt;h2&gt;Install Xcode&lt;/h2&gt;

&lt;p&gt;You will most certainly want Xcode, available from Apple.&lt;/p&gt;

&lt;p&gt;(&lt;em&gt;Update:&lt;/em&gt; Xcode is now free through the Mac App Store. Ignore the next
three paragraphs).&lt;/p&gt;

&lt;p&gt;The easiest way to get this is through the &lt;a href="http://itunes.apple.com/ca/app/xcode/id422352214?mt=12"&gt;Mac App Store&lt;/a&gt;, where it’ll run you USD$5. The harder way is to get them as part of a Mac or iOS &lt;a href="http://developer.apple.com/programs/"&gt;developer membership&lt;/a&gt; (USD$99/year). Regrettably, it’s only as of last week that these developer tools are no longer free. Putting aside for the moment any judgment on the principle of charging at all, I would argue the dev tools are definitely worth more than five bucks.&lt;/p&gt;

&lt;p&gt;(It’s worth noting that (a) the sufficiently hardcore, cheap, or doctrinaire among us could build a Vectorworks plug-in using only &lt;code&gt;emacs&lt;/code&gt; or &lt;code&gt;vim&lt;/code&gt;, &lt;code&gt;gcc&lt;/code&gt; and &lt;a href="http://sourceforge.net/projects/rezilla/"&gt;Rezilla&lt;/a&gt;, all GPL open source; and (b) life’s pretty short. Go buy Xcode).&lt;/p&gt;

&lt;p&gt;Beware: the current version—Xcode 4—is a top-to-bottom rewrite, and is less than a week old as of this writing. For the near future googling whatever particular problem you’re having is likely to turn up stale hints for Xcode 3. &lt;/p&gt;

&lt;h2&gt;Install the SDK&lt;/h2&gt;

&lt;p&gt;Finally, the meat: Nemetschek makes the Vectorworks SDK available for &lt;a href="http://www.nemetschek.net/support/custom/sdk/"&gt;free download&lt;/a&gt;. Pick the first link. Accept the license agreement, nab the Mac version of SDK 2011 and unzip it. It consists of a giant pile of &lt;code&gt;.h&lt;/code&gt; and &lt;code&gt;.cpp&lt;/code&gt; files, some sparse documentation, a couple of non-beginner-level sample projects, and &lt;code&gt;.a&lt;/code&gt; static libraries that Nemetschek has compiled specifically for Mac OS X. We’ll talk about where to locate the SDK in the source tree in the next part.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;In Part 4, we’ll (finally) get down to some actual coding.&lt;/p&gt;

&lt;h6&gt;Mon 14 Mar 2011&lt;/h6&gt;
&lt;/article&gt;</content>
  </entry>
  <entry>
    <id>tag:ryanmccuaig.net,2011-02-28:/2011/02/28-getting-started-part-2/</id>
    <title type="html">Getting started with the Vectorworks SDK, Part 2</title>
    <published>2011-02-28T08:00:00Z</published>
    <updated>2011-02-28T08:00:00Z</updated>
    <link rel="alternate" href="http://ryanmccuaig.net/2011/02/28-getting-started-part-2/"/>
    <content type="html">&lt;article&gt;
&lt;h1&gt;Getting started with the Vectorworks SDK, Part 2&lt;/h1&gt;

&lt;p&gt;Following on &lt;a href="/2011/02/18-getting-started-with-the-vectorworks-sdk/" title="Part 1 of this article series"&gt;our last instalment&lt;/a&gt;, we’ll review the basic Vectorworks plug-in types, and
then break down the architecture of our custom text note plug-in.&lt;/p&gt;

&lt;h2&gt;Regarding plug-ins in general, which you can mostly skip if you know anything at all about Vectorscript development&lt;/h2&gt;

&lt;p&gt;At application startup, Vectorworks will scan a few directories looking
for custom code, namely &lt;code&gt;/Applications/Vectorworks 2011/Plug-ins&lt;/code&gt; and
&lt;code&gt;~/Applications/Library Support/Vectorworks/2011.noindex/Plug-ins&lt;/code&gt;. If
it’s in the right format, it’ll automatically load it and make it
available for use in drawings. Much of the core program function is
implemented using plug-ins. Most plug-ins will have to be added to a
workspace, so that it can be accessed through the UI.&lt;/p&gt;

&lt;p&gt;There are 4 generic types of plug-in. Think of them as
nouns and verbs. Parametric objects are the nouns. Menu commands,
tools, and VectorScript libraries are the verbs.&lt;/p&gt;

&lt;h3&gt;The nouns&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://developer.vectorworks.net/index.php?title=SDK:Parametric_General_Info" title="Parametric plug-in introduction page at developer.vectorworks.net"&gt;Parametric Objects&lt;/a&gt; are graphical objects that exist in
the 3D space of the drawing. They can control their own appearance based
on user-supplied parameters and some awareness of their context, eg. the
drawing scale. They can be relatively simple, like the Break Line, or
horrendously complicated, like the Nemetschek-supplied Door, Window,
Space and Stair objects.&lt;/p&gt;

&lt;p&gt;Unlike VectorScript, the SDK requires you to provide a corresponding
Menu or Tool to actually place the Parametric Object in a drawing. This
is usually an advantage.&lt;/p&gt;

&lt;p&gt;The Parametric Object is sub-typed by its characteristic geometry into
Point, Linear, Rectangular, 2D Path and 3D Path Objects. This will
mainly define how many draggable control points it has.&lt;/p&gt;

&lt;p&gt;The black art of good parametric object design starts in wedging your
particular concept into one of these subtypes, based on whether a given
parameter ought to be edited graphically or numerically. Much of this
guidance is going to come from industry experience. A door, for example,
is better defined as a Point object with its width set from a list of
valid widths, since door widths tend to come in a continuous range of
sizes. A window, on the other hand, is usually built to fit, so it’s
better that it be a Linear or 2D Path object that can be edited
graphically. It would be nice if there were hard-and-fast rules, but
then it wouldn’t be an art. So it goes.&lt;/p&gt;

&lt;h3&gt;The verbs&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://developer.vectorworks.net/index.php?title=SDK:Menu_Command_Plug-in" title="Menu command plug-in introduction page at developer.vectorworks.net"&gt;Menu commands&lt;/a&gt; and &lt;a href="http://developer.vectorworks.net/index.php?title=SDK:Tool_Plug-in" title="Tool plug-in introduction page at developer.vectorworks.net"&gt;Tools&lt;/a&gt; are used to provide a user interface to
your custom functionality. In general, the choice between them requires a judgment call based on their UI:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;use a Menu command if you don’t require any graphical input beyond
having drawing objects preselected for action;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;use a Tool if you do need graphical input, such as an insertion point,
a wall into which you want a Parametric object inserted, etc.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples of Menu-type plug-ins would be ones for generating reports or
grouping pre-selected objects. As you should expect from the names, Menu
commands will be accessed from the menu bar, and Tools will be accessed
from the tool palettes. There aren’t hard-and-fast rules here either;
many plug-ins could go either way. It sounds a bit dumb, but one of my
rules when I’m in doubt is: if I can’t come up with a good icon, it’s
probably a Menu.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://developer.vectorworks.net/index.php?title=SDK:Library_Plug-in" title="Vectorscript Library plug-in introduction page at developer.vectorworks.net"&gt;VectorScript libraries&lt;/a&gt; are used to provide new functions within
VectorScript. They aren’t expressed within the graphical UI; ie. you
can’t put them in a workspace. I find it comforting to know these exist:
I can use them to drop down to C++ within an existing VectorScript
plug-in to gain capabilities that aren’t present in VectorScript, but
without necessarily having to rewrite the entire plug-in using the SDK.
But, since that’s about all I know about them, I won’t touch on them
further in this tutorial.&lt;/p&gt;

&lt;h2&gt;Packaging&lt;/h2&gt;

&lt;p&gt;Plug-ins are packaged as &lt;a href="http://en.wikipedia.org/wiki/Application_bundle" title="Loadable bundles defined"&gt;bundles&lt;/a&gt; on Mac OS X, with the extension
&lt;code&gt;.vwlibrary&lt;/code&gt;. Our finished plug-in—and with rare exceptions all modern
plug-ins—will have a directory structure like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rmTextNote.vwlibrary
└── Contents
      ├── Info.plist
      ├── MacOS
      │   └── rmTextNote
      └── Resources
          └── rmTextNote.qtr
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This structure will be produced automatically as part of Xcode’s build
process.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code&gt;Info.plist&lt;/code&gt; is mostly OS X-related boilerplate, and will be generated
automatically by Xcode. You shouldn’t have to edit it.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code&gt;Contents/MacOS/rmTextNote&lt;/code&gt; is the binary resulting from compiling and
linking your C++ source code.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code&gt;Contents/Resources/rmTextNote.qtr&lt;/code&gt; is a resource file containing
graphics, user interface strings and the like. It’s split out to make
it easier to create versions of your plug-in in different languages.
It’s also where you can most see Vectorworks’ lingering 1980s
heritage: the file format is that of old ‘rsrc’ resource forks from
Mac OS 9 and earlier. You might spelunk them with a modern
&lt;a href="http://sourceforge.net/projects/rezilla/" title="Get the Rezilla resource editor"&gt;resource&lt;/a&gt; &lt;a href="http://resknife.sourceforge.net/" title="Get the Resknife resource editor"&gt;editor&lt;/a&gt;, but &lt;code&gt;.qtr&lt;/code&gt; resource files will
be best created by compiling &lt;code&gt;.r&lt;/code&gt; source files using &lt;code&gt;Rez&lt;/code&gt; (or
&lt;code&gt;Rez.exe&lt;/code&gt; on Windows). &lt;code&gt;Rez&lt;/code&gt; is installed as part of the OS X
developer tools.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(If you see a &lt;code&gt;.vwobject&lt;/code&gt; or &lt;code&gt;.vwplugin&lt;/code&gt; bundle, you’re probably looking
at an old-style plug-in that contains only a Parametric without its
corresponding Menu or Tool. My preference is to put all related
Parametrics, Menus and Tools in the same &lt;code&gt;.vwlibrary&lt;/code&gt;. As the VCOM
system takes hold, I expect you’ll start seeing only &lt;code&gt;.vwlibrary&lt;/code&gt;
bundles).&lt;/p&gt;

&lt;h2&gt;The anatomy of our text note plug-in&lt;/h2&gt;

&lt;p&gt;Our text note plug-in will provide both a Parametric object, and a Tool
to place it. We will break it down into 6 classes and 5 files.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/textnote-class-diagram.png" alt="Text Note class diagram" title="Text Note class diagram" /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    Somewhere in the plug-in object code there needs to be a
    &lt;code&gt;plugin_main()&lt;/code&gt; function defined. Vectorworks will look
    for this function at runtime to figure out how it should hook in
    your code, roughly in the same way as most Unices go hunting about
    for &lt;code&gt;int main(int argc, char *argv[])&lt;/code&gt; to kick off
    execution of any code. This is where you tell Vectorworks whether
    you're building a Menu, Tool, Parametric and/or a Library plug-in.
    You could stick this pretty much anywhere, but we'll plant this in a
    file called &lt;code&gt;ModuleMain.cpp&lt;/code&gt;. This file will be mostly
    boilerplate; the overall skeleton will vary little from plug-in to
    plug-in.
  &lt;/li&gt;
  &lt;li&gt;
    In &lt;code&gt;plugin_main()&lt;/code&gt;, we will make reference to two
    &lt;em&gt;definition classes&lt;/em&gt;: one for the Tool, and one for the
    Parametric. We'll namespace them, so that they can be referred to as
    &lt;code&gt;Tool::Definition&lt;/code&gt; and
    &lt;code&gt;Parametric::Definition&lt;/code&gt;. This is where we'll define the
    plug-in's name, type, icon, help strings, and Object Info Palette
    parameters.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Plug-ins will usually sit around waiting for events to be
    delivered to it by Vectorworks, and invoke various actions in
    response to those events. Examples would be:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;the user clicks on the Tool in the palette,&lt;/li&gt;
      &lt;li&gt;the user edits a Parametric control point or parameter in the
      Object Info Palette,&lt;/li&gt;
      &lt;li&gt;the user moves or rotates a Parametric,&lt;/li&gt;
      &lt;li&gt;&amp;amp;c.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Plug-ins used to have one big &lt;code&gt;switch&lt;/code&gt; statement at
    their core, and distinguished between different events by checking
    an integer constant delivered to it by Vectorworks. The modern way
    is to define a custom subclass of one of the stock &lt;em&gt;event sink
    classes&lt;/em&gt; supplied in the SDK. If you want to respond to an
    event, add a custom method for that event. If you don't provide a
    custom method, Vectorworks will use the one our event sink inherited
    from the superclass, which usually does nothing. This is usually
    referred to as the &lt;a href="http://c2.com/cgi/wiki?TemplateMethodPattern" title="Template
    Method Pattern defined"&gt;Template Method&lt;/a&gt; design pattern, aka.
    hook methods.&lt;/p&gt;
    
    &lt;p&gt;To that end, we will be defining the classes
    &lt;code&gt;Tool::EventSink&lt;/code&gt; and &lt;code&gt;Parametric::EventSink&lt;/code&gt;
    to catch these events. These classes tend to run about 75%
    boilerplate.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    I like to define a separate class that models the specific behaviour
    of a Parametric, and treat the event sinks mainly as dispatchers.
    This keeps the logic and parameters related to how a given entity
    behaves properly encapsulated, and lets us rely on the &lt;em&gt;model
    class&lt;/em&gt;&amp;mdash;called &lt;code&gt;RMTextNote&lt;/code&gt; in this
    case&amp;mdash;to provide consistent behaviour to either the Tool or
    Parametric event sink without duplicating code. The alternative is
    to keep logic in the event sinks. This is low-rent: it's convenient
    when there isn't much code, but managing the two concerns
    together&amp;mdash;managing incoming events and maintaining the
    parametric's graphical consistency&amp;mdash;gets cumbersome in a hurry.
  &lt;/li&gt;

  &lt;li&gt;
    For expediency, I keep a separate &lt;code&gt;RMUtilities&lt;/code&gt; class
    around. This packages up the snippets that don't yet fit elsewhere,
    but that I tend to use on many plug-ins. For example, I use it to
    abstract various office standards, like the name of the initial
    insertion class. I also keep a lot of the logic related to proper
    scaling here as class methods. As my stable of plug-ins expands, I
    may move some of this to an abstract superclass of either the model
    or the event sinks, but that seems like overkill right now.
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that instantiating and destroying objects from most of these
classes will be handled automatically by Vectorworks. The only one whose
life cycle we’ll have to manage is the &lt;code&gt;RMTextNote&lt;/code&gt;, which will exist on
the heap.&lt;/p&gt;

&lt;h2&gt;Plug-in parameters&lt;/h2&gt;

&lt;p&gt;We’ll define 8 parameters for our text note. (Note that Vectorworks will
automatically add Rotation to any Parametric). Some of these will be hidden or deactivated in relation to others.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/textnote-oip.png" alt="Text Note parameters and graphical examples" title="Text Note parameters and graphical examples" /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; is a string parameter that will hold the actual text.
Vectorworks internals limit this to 255 characters, but this should be
OK: we’re not writing novels here.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Marker&lt;/strong&gt; is a predefined list, letting us toggle between using a
dot and an arrow on the leader. Our office standard is to use a dot,
unless pointing at something tiny. This one is set up as radio buttons,
defaulting to Dot.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Show Bar In Margin?&lt;/strong&gt; is a boolean that turns on a vertical bar to
help set off the text when it gets to be several lines long.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Wrap Text?&lt;/strong&gt; is a boolean that specifies if the text should wrap.
Turning this on will turn on the display of the next two in the Object
Info Palette.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Text Width (page)&lt;/strong&gt; is a ‘dimension’ parameter, meaning it will
take on the units of the current drawing. It only shows when text
wrapping is turned on. It defines the width of the text block. We’ll
also allow this to be set by dragging a control point in the drawing.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Vertical Alignment&lt;/strong&gt; is a predefined list: one of (a) First Line,
(b) Middle, (c) Last Line. It only shows when wrapping is on, and lets
us tweak the wrapped text into a good spot. Usually First Line will
suffice. Note that this parameter is shown as a popup menu. It could
also have been radio buttons. I tend to use popups for long lists or
short but seldom-adjusted lists.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Use Layer Scale?&lt;/strong&gt; is a boolean that determines if the scale of the
containing layer or sheet layer viewport is to be used in figuring out
how big the note text and arrowhead should be, since these are measured
in paper units. Turning this off will activate the next parameter.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Show at Scale 1 to&lt;/strong&gt; is a real number parameter (not integer) that
can be used to manually set the ratio between world and paper scale.
Figuring out the correct scale is a particularly fraught issue in
Vectorworks; we’ll spend a good deal of time on it. This parameter isn’t
needed often, but it’s handy when the automatic scale determination
isn’t doing what you want.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We’ll set the font and size to 8pt Helvetica initially, then allow it to
be adjusted after placement from the Text menu like any piece of placed
text. This capability is available automatically to any Parametric,
provided it has been enabled, so we won’t need parameters for Font and
Size.&lt;/p&gt;

&lt;p&gt;(I also recommend adding a hidden integer &lt;strong&gt;Version&lt;/strong&gt; parameter at the
outset. We won’t use it in this tutorial, but it comes in handy as
production plug-ins evolve).&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;In &lt;a href="/2011/03/14-getting-started-part-3/"&gt;Part 3&lt;/a&gt;, we’ll get our development environment set up, and in Part 4 we’ll create a
skeleton plug-in from which we’ll gradually hang working code.&lt;/p&gt;

&lt;h6&gt;Mon 28 Feb 2011&lt;/h6&gt;
&lt;/article&gt;</content>
  </entry>
  <entry>
    <id>tag:ryanmccuaig.net,2011-02-18:/2011/02/18-getting-started-with-the-vectorworks-sdk/</id>
    <title type="html">Getting started with the Vectorworks SDK</title>
    <published>2011-02-18T08:00:00Z</published>
    <updated>2011-02-18T08:00:00Z</updated>
    <link rel="alternate" href="http://ryanmccuaig.net/2011/02/18-getting-started-with-the-vectorworks-sdk/"/>
    <content type="html">&lt;article&gt;
&lt;h1&gt;Getting started with the Vectorworks SDK&lt;/h1&gt;

&lt;p&gt;I’m not a fan of the stock text note tool in Vectorworks. The best I’ve yet used shipped with PowerCADD 2000. We’re going to make a PowerCADD-inspired Vectorworks text note tool to explore how to develop a simple &lt;a href="http://www.nemetschek.net/support/custom/sdk/" title="Download the Vectorworks SDK"&gt;Vectorworks C++ plug-in&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All source code is MIT-licensed and can be downloaded from &lt;a href="https://www.github.com/rgm/vectorworks/" title="Github repository for the source code"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;To follow along at home, you will need…&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;a Mac running Snow Leopard,&lt;/li&gt;
  &lt;li&gt;Vectorworks 2011,&lt;/li&gt;
  &lt;li&gt;Xcode, and&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://git-scm.com/" title="Git version control system"&gt;git&lt;/a&gt; for getting the source code, best installed through &lt;a href="https://github.com/mxcl/homebrew/" title="Homebrew package manager"&gt;homebrew&lt;/a&gt;;&lt;/li&gt;
  &lt;li&gt;a smattering of Ruby for build automation and miscellaneous
housekeeping; and&lt;/li&gt;
  &lt;li&gt;a knowledge of C++ that exceeds mine, which I’d describe as just-enough-to-be-dangerous.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Our project&lt;/h2&gt;

&lt;p&gt;The PowerCADD text note tool required three clicks to place: first (x,y) is the arrowhead, second gives the (x,y) of the shoulder, and the third gives the (x) of the text point. The (y) of the text point is always the same as the shoulder. Click-click-click-type-done.&lt;/p&gt;

&lt;video width="550" height="339" controls="controls"&gt;
  &lt;source src="/assets/powercadd-create.mp4" type="video/mp4; codecs=&amp;quot;avc1.42E01E&amp;quot;" /&gt;
&lt;/video&gt;

&lt;p&gt;Reshaping the note happens by clicking on those same points. Dragging the arrow does what you’d expect. Dragging the shoulder will drag the text along with it, keeping the same relative distance between shoulder and text. Dragging the text is constrained to stay on the same (y) as the shoulder.&lt;/p&gt;

&lt;video width="550" height="339" controls="controls"&gt;
  &lt;source src="/assets/powercadd-adjust.mp4" type="video/mp4; codecs=&amp;quot;avc1.42E01E&amp;quot;" /&gt;
&lt;/video&gt;

&lt;p&gt;As the CAD guy for a mid-sized firm, my preference is to hard-code our tools to work with our own drawing standards. I’d rather make it easy to do the right thing instead of being ‘that guy,’ beating on our drafters about arrowhead styles so that they start to roll their eyes at my approach. Thus, the code here reflects my personal taste in classes, arrowheads and type. While my taste is in fact correct, it also isn’t shared by everyone. Feel free to change these little details.&lt;/p&gt;

&lt;h2&gt;Why not just use Vectorscript?&lt;/h2&gt;

&lt;p&gt;You can cobble together something that kinda works for most things using Vectorworks’s other customisation system: Vectorscript. I’ve coded in it for years, and it can get most jobs done more safely.&lt;/p&gt;

&lt;p&gt;However, my tastes, skills and ambitions around what I want our CAD system to do have grown. There are a bunch of limitations to Vectorscript that now bug me:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I want to be able work with multiple files;&lt;/li&gt;
  &lt;li&gt;I want to experiment with pulling web-based information into drawings;&lt;/li&gt;
  &lt;li&gt;I don’t want to have to keep writing my own version of things that are in the standard library of every common scripting language, eg. strip for strings, push/pop/unshift for arrays, etc. etc;&lt;/li&gt;
  &lt;li&gt;I want better source code version control, without unmergeable binary containers;&lt;/li&gt;
  &lt;li&gt;I’m tired of there being one obvious function call in a related family of functions be missing or weirdly different;&lt;/li&gt;
  &lt;li&gt;I want to be able to do &lt;a href="http://c2.com/cgi/wiki?TestDrivenDevelopment" title="Test driven development explained"&gt;test-driven development&lt;/a&gt;; and, really,&lt;/li&gt;
  &lt;li&gt;I was pretty much done with Pascal after Computer Camp in the summer of 1985.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are some elements to the text note project that do benefit from the greater control over UI that the SDK offers. You could make something similar with Vectorscript, but it would have irritating little warts.&lt;/p&gt;

&lt;h2&gt;Modernity&lt;/h2&gt;

&lt;p&gt;Browsing through &lt;a href="http://developer.vectorworks.net/index.php?title=Main_Page" title="Nemetschek developer wiki"&gt;Nemetschek’s docs&lt;/a&gt; can be confusing. There’s a major conceptual transition going on in how one structures plugins, the deprecated way hasn’t been excised from the docs, and the new one isn’t yet explained clearly.&lt;/p&gt;

&lt;p&gt;Some history: the original incarnation of the SDK was procedural (notwithstanding that it’s all C++). Calls into the Vectorworks app were of the form &lt;code&gt;GS_GetOpacity(gCBP,...)&lt;/code&gt;: the first parameter was always a global callback pointer &lt;code&gt;gCBP&lt;/code&gt; providing a hook back into Vectorworks’ guts at runtime.&lt;/p&gt;

&lt;p&gt;The procedural form is deprecated as of Vectorworks 2010. Nemetschek is now pushing an object-oriented form. Calls to the SDK are now method calls of the form &lt;code&gt;gSDK-&amp;gt;GetOpacity()&lt;/code&gt; on a runtime-defined global C++ object. (Admittedly, it’s a bit tomayto-tomahto. &lt;code&gt;gSDK&lt;/code&gt;—an instance of &lt;code&gt;VectorWorks::ISDK&lt;/code&gt;—seems to be just a thin &lt;a href="http://c2.com/cgi/wiki?GodClass" title="God class antipattern explained"&gt;God Class&lt;/a&gt; wrapper around the old functions).&lt;/p&gt;

&lt;p&gt;The new form is an improvement once we start to get into using files, dialogs, and the like. More broadly, the plugin architecture is now being revised to something called Vectorworks Component Object Model (VCOM). I’m probably oversimplifying, but I understand VCOM as just meaning a switch to object-orientation. It replaces the old-style big spaghetti &lt;code&gt;switch&lt;/code&gt; statement at the heart of old plugins with &lt;a href="http://www.c2.com/cgi/wiki?HookMethod" title="Hook method explained"&gt;hook methods&lt;/a&gt; on a supplied object. This pattern is definitely more comfortable to me, since I’m used to seeing it in iOS and Mac OS X code, and encourages the other good things that come from object-orientation: maintainability, reusability, scalability.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;In &lt;a href="/2011/02/28-getting-started-part-2/" title="Part 2 of this article series"&gt;Part 2&lt;/a&gt;, we will go over the basic object architecture for our text note plugin, and get set up to start coding.&lt;/p&gt;

&lt;h6&gt;Fri 18 Feb 2011&lt;/h6&gt;
&lt;/article&gt;</content>
  </entry>
</feed>

