This is part 3 of a multi-part series. You can find the previous posts here: part1, part2.
Now that the Domain Model has been created, the next step is to edit the Designer.dsldd file. This file is used to describe how the graphical design surface will appear to your users. It is also used to describe how your domain model maps to shapes and connectors on the design surface. Unlike the DomainModel file, there is no visual designer associated with the Designer file. We therefore need to directly edit the XML in this file. The XML format is documented in Walkthrough 3, which is part of the DSL tools download. I will briefly describe the major sections in the file, and the changes which need to be made. You can find the completed XML file here.
Actually, before we get to the Designer file, we need to create some new string resources in the Diagram/Designer.Resource.resx file. Instead of hard coding text strings directly in the designer XML, the XML references string resources. You can find a list of string resources to add in the same file which contains the completed XML.
When working with the XML in the Designer file, I prefer to start from the bottom and work my way up.
The diagram section describes the design surface itself. It includes three main elements: toolbox, shapes and connectors.
The toolbox section contains one entry for each shape or connector which will appear in the designer's toolbox. Each item refers to a shape or connector which has been defined earlier in the XML file. The order attribute determines the order in which the items will appear in the toolbox. Every item needs a unique value for order.
For our example, we will create toolbox items for SetUp, Guess and Hint (shapes) as well as for FirstMove and NextMove (connectors). Note that we don't create an entry in the toolbox for GameMove, because this class does not represent an entity which is directly used on the design surface.
The shapes section contains information about how each shape will be displayed on the design surface. It includes things like geometry (rectangle, circle, etc.), size, color, etc. Each shape referenced in the toolbox section must have an entry in the shapes section.
For our example, we will describe SetUpShape, HintShape and GuessShape. I gave each shape a different fillcolor and set the geometry on all three shapes to "RoundedRectangle".
This sections contains information about how each connector will be displayed. It also lists which shapes are valid sources and targets for each connector. All shapes referenced in this section must also appear in the shapes section. All connectors listed in the toolbox section, must have a corresponding entry here.
For our example, we have two connectors. FirstMoveConnector allows connections from SetUpShape to GuessShape, HintShape. NextMoveConnector allows connections from GuessShape, HintShape to GuessShape, HintShape.
Once the diagram has been defined, the next step is to describe the mapping between the shapes and connectors in the diagram, and the classes and relations in the domain model. The two main sections in the diagram map are shape map and connector map. This section also contains a CLASS element. This element lists the root class in the domain model. In our example, this is the Game class.
This section contains the mapping between classes in the domain model and shapes in the diagram. Each shape map contains the class, the shape, and the name of the property on the parent (in our case Game) which will point to the class. These properties were created by using the embedded relationship in the domain model designer. In that designer, they are represented by the roles whose Accepts property we set to all.
In our example, we will say that the class SetUp uses the role Game/SetUp and is represented by the shape SetUpShape. We similarly create entries for (Hint, Game/GameMove, HintShape) and (Guess, Game/GameMove, GuessShape). Note that the property used to hold Guesses and Hints is GameMove. This is because Game actually embeds the class GameMove. The Guess and Hint classes inherit from GameMove.
- Connector Map
This section contains the mapping between relations in the domain model and connectors in the digram. Each connector map contains the relation (the element is actually called class), the connector, the name of the property in the source class which points to the destination class (target), and the name of the property in the destination class which points back to the source class (source). These properties are part of the reference relations that we created. They correspond to the roles whose IsPropertyGenerator values we set to true.
In our example, we will say that the relation SetUpHasGameMove is mapped to the connector FirstMoveConnector. The target property is SetUp\GameMove. The source property is GameMove\SetUp. We will also say that the relation GameMoveHasGameMove is mapped to the connector NextMoveConnector. The target property is GameMove\Target and the source property is GameMove\Source.
That's pretty much all there is to it. The only other thing we need to do is change the CLASS element in the element node section at the top of the file to also point to the Game class. You should now be able to transform templates, build your solution and run it. You should now have a working designer for our simple game. In the next installment, I will describe how to generate the code for the game based upon a diagram created with the designer.