In the last post we created a simple MText object containing sections of text with different colours. The object was located at a hard-coded location, so now we want to use a simple technique to allow placement of our MText (or any object, for that matter) in the current user coordinate system.
Rather than implementing a full jig class – whether a DrawJig or an EntityJig (the latter being most appropriate for this scenario) – we’re going to use the .NET equivalent of the old (draggen) or acedDragGen() functionality: the overload of Editor.Drag() which takes a selection set, prompt and callback delegate (we might also have used a PromptDragOptions object, to get further options).
Here’s the updated C# code, with changed/added lines in red (you can also get the source file without line numbers here):
1 using Autodesk.AutoCAD.ApplicationServices;
2 using Autodesk.AutoCAD.EditorInput;
3 using Autodesk.AutoCAD.DatabaseServices;
4 using Autodesk.AutoCAD.Runtime;
5 using Autodesk.AutoCAD.Geometry;
6
7 namespace MTextCreationAndJigging
8 {
9 public class Commands
10 {
11 [CommandMethod("COLTXT2")]
12 static public void CreateColouredMText()
13 {
14 Document doc =
15 Application.DocumentManager.MdiActiveDocument;
16 Database db = doc.Database;
17 Editor ed = doc.Editor;
18
19 // Variables for our MText entity's identity
20 // and location
21
22 ObjectId mtId;
23 Point3d mtLoc = Point3d.Origin;
24
25 Transaction tr =
26 db.TransactionManager.StartTransaction();
27 using (tr)
28 {
29 // Create our new MText and set its properties
30
31 MText mt = new MText();
32 mt.Location = mtLoc;
33 mt.Contents =
34 "Some text in the default colour...\\P" +
35 "{\\C1;Something red}\\P" +
36 "{\\C2;Something yellow}\\P" +
37 "{\\C3;And} {\\C4;something} " +
38 "{\\C5;multi-}{\\C6;coloured}\\P";
39
40 // Open the block table, the model space and
41 // add our MText
42
43 BlockTable bt =
44 (BlockTable)tr.GetObject(
45 db.BlockTableId,
46 OpenMode.ForRead
47 );
48
49 BlockTableRecord ms =
50 (BlockTableRecord)tr.GetObject(
51 bt[BlockTableRecord.ModelSpace],
52 OpenMode.ForWrite
53 );
54
55 mtId = ms.AppendEntity(mt);
56 tr.AddNewlyCreatedDBObject(mt, true);
57
58 // Select the last entity added (our MText)
59
60 PromptSelectionResult psr = ed.SelectLast();
61
62 // Assuming that worked, we'll drag it
63
64 if (psr.Status == PromptStatus.OK)
65 {
66 // Launch our drag jig
67
68 PromptPointResult ppr =
69 ed.Drag(
70 psr.Value,
71 "\nSelect text location: ",
72 delegate(Point3d pt, ref Matrix3d mat)
73 {
74 // If no change has been made, say so
75
76 if (mtLoc == pt)
77 return SamplerStatus.NoChange;
78 else
79 {
80 // Otherwise we return the displacement
81 // matrix for the current position
82
83 mat =
84 Matrix3d.Displacement(
85 mtLoc.GetVectorTo(pt)
86 );
87 }
88 return SamplerStatus.OK;
89 }
90 );
91
92 // Assuming it works, transform our MText
93 // appropriately
94
95 if (ppr.Status == PromptStatus.OK)
96 {
97 // Get the final translation matrix
98
99 Matrix3d mat =
100 Matrix3d.Displacement(
101 mtLoc.GetVectorTo(ppr.Value)
102 );
103
104 // Transform our MText
105
106 mt.TransformBy(mat);
107
108 // Finally we commit our transaction
109
110 tr.Commit();
111 }
112 }
113 }
114 }
115 }
116 }
When we use the new COLTXT2 command, we see the MText object now follows the cursor around until we select the eventual destination:
This technique could easily be adapted to using any set of objects, although more work may be needed to transform the results. We had the MText itself, making this easy, but otherwise it might be needed to open the objects to transform them or to P/Invoke the acedXformSS() function.
In the next post we’ll take this one step further and launch the In-Place Editor for MText, to allow final editing once placed.