using System; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.Geometry; using System.Collections.Generic; namespace BlockRefGrip { public class Commands { //Move Line and Text public static void MoveLineAndText(BlockReference bref, Point3d newPoint) { Database db = HostApplicationServices.WorkingDatabase; using (Transaction trans = db.TransactionManager.StartTransaction()) { BlockTableRecord btrec = (BlockTableRecord)trans.GetObject(bref.BlockTableRecord, OpenMode.ForRead); Line _line = null; DBText dbText = null; foreach (ObjectId objId in btrec) { Entity ent = (Entity)trans.GetObject(objId, OpenMode.ForWrite); if (ent is Line) { _line = (Line)ent; } else if (ent is DBText) { dbText = (DBText)ent; } } //Convert WCS point to BlockOS Matrix3d _matrix = bref.BlockTransform; newPoint = newPoint.TransformBy(_matrix.Inverse()); //Move Line double different = newPoint.Y - _line.StartPoint.Y; _line.StartPoint = newPoint; _line.EndPoint = new Point3d(_line.EndPoint.X, _line.StartPoint.Y, 0); //Move Text dbText.Position = new Point3d(dbText.Position.X, dbText.Position.Y + different, 0); trans.Commit(); } } //Get Line starting point public static Point3d GetLineStartPoint(BlockReference bref) { Database db = HostApplicationServices.WorkingDatabase; Point3d lineStartPoint = new Point3d(); using (Transaction trans = db.TransactionManager.StartTransaction()) { BlockTableRecord btrec = (BlockTableRecord)trans.GetObject(bref.BlockTableRecord, OpenMode.ForRead); foreach (ObjectId objId in btrec) { Entity ent = (Entity)trans.GetObject(objId, OpenMode.ForRead); if (ent is Line) { Line _line = (Line)ent; lineStartPoint = _line.StartPoint; //Convert BlockOS point to WCS Matrix3d _matrix = bref.BlockTransform; lineStartPoint = lineStartPoint.TransformBy(_matrix); } } } return lineStartPoint; } [CommandMethod("GOO")] public static void GripOverruleOnOff() { Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; if (GripVectorOverrule.overruling) { ObjectOverrule.RemoveOverrule(RXClass.GetClass(typeof(Autodesk.AutoCAD.DatabaseServices.BlockReference)), GripVectorOverrule.theOverrule); } else { ObjectOverrule.AddOverrule(RXClass.GetClass(typeof(Autodesk.AutoCAD.DatabaseServices.BlockReference)), GripVectorOverrule.theOverrule, true); } GripVectorOverrule.overruling = !GripVectorOverrule.overruling; GripOverrule.Overruling = GripVectorOverrule.overruling; ed.WriteMessage("\nEnable grips for MYTESTBLOCK {0}.", GripVectorOverrule.overruling ? "on" : "off"); } } public class myGripData : GripData { // Object id of the original entity public ObjectId m_key = ObjectId.Null; // Progressive grip number public int m_index = 0; // Original grip location public Point3d m_original_point = Point3d.Origin; public override void OnGripStatusChanged(ObjectId entityId, GripData.Status newStatus) { if (newStatus == Status.GripAbort) { // Revert grips to original location GripVectorOverrule.ResetGrips(entityId); } } } public class GripVectorOverrule : GripOverrule { // A static pointer to our overrule instance static public GripVectorOverrule theOverrule = new GripVectorOverrule(); // A flag to indicate whether we're overruling static public bool overruling = false; // gripdata for each selected Block Reference static Dictionary _ents_handled = new Dictionary(); public GripVectorOverrule() { // Set event handlers on documents to get access to // OnImpliedSelectionChanged DocumentCollection dm = Application.DocumentManager; dm.DocumentCreated += new DocumentCollectionEventHandler(dm_DocumentCreated); dm.DocumentToBeDestroyed += new DocumentCollectionEventHandler(dm_DocumentToBeDestroyed); // Attach handler to currently loaded documents foreach (Document doc in dm) { doc.ImpliedSelectionChanged += new EventHandler(doc_ImpliedSelectionChanged); } } void dm_DocumentCreated(object sender, DocumentCollectionEventArgs e) { e.Document.ImpliedSelectionChanged += new EventHandler(doc_ImpliedSelectionChanged); } void dm_DocumentToBeDestroyed(object sender, DocumentCollectionEventArgs e) { e.Document.ImpliedSelectionChanged -= new EventHandler(doc_ImpliedSelectionChanged); } void doc_ImpliedSelectionChanged(object sender, EventArgs e) { // Check for empty selection on current document Document doc = Application.DocumentManager.MdiActiveDocument; PromptSelectionResult res = doc.Editor.SelectImplied(); // If nothing selected, it's a good time to reset GripData // dictionary if (res != null) if (res.Value == null) GripVectorOverrule.ResetAllGrips(); } public override void GetGripPoints(Entity entity, GripDataCollection grips, double curViewUnitSize, int gripSize, Vector3d curViewDir, GetGripPointsFlags bitFlags) { // Get BlockRefrence object BlockReference bref = (BlockReference)entity; //Check if its our block if (bref.Name == "MYTESTBLOCK") { // Everything seems ok, add grip points // Use also a private GripDataCollection, don't mess // with AutoCAD's GripDataCollection myGrips = new GripDataCollection(); //Collect BlockRef base points myGripData gd = new myGripData(); gd.m_index = 0; gd.m_key = entity.ObjectId; gd.GripPoint = gd.m_original_point = Commands.GetLineStartPoint(bref); gd.GizmosEnabled = true; grips.Add(gd); myGrips.Add(gd); // Check for same entity already in list. If so, // remove it _ents_handled.Remove(entity.ObjectId); // Add to our managed list _ents_handled.Add(entity.ObjectId, myGrips); } else { base.GetGripPoints(entity, grips, curViewUnitSize, gripSize, curViewDir, bitFlags); } } public override void MoveGripPointsAt(Entity entity, GripDataCollection grips, Vector3d offset, MoveGripPointsFlags bitFlags) { // Retrieve from the streched grips the ObjectId/dictionary // key // shouldn't happen. Programmer's paranoia if (grips.Count == 0) return; myGripData gda = grips[0] as myGripData; if (gda != null) // It's one of our grips { if (_ents_handled.ContainsKey(gda.m_key)) { // Retrieve our original grip collection GripDataCollection original_grips = _ents_handled[gda.m_key]; // Correct grips with offset information for (int i = 0; i < grips.Count; i++) { // Retrieve original grip and set current // dragged location myGripData gdo = (myGripData)grips[i]; myGripData gd = original_grips[gdo.m_index] as myGripData; gd.GripPoint = gd.m_original_point + offset; gdo.GripPoint = gdo.m_original_point + offset; //Call method moving Line and Text inside of BlockTableRecord Commands.MoveLineAndText((BlockReference)entity, gdo.GripPoint); } // Done, don't fall into standard handling return; } } // Revert to standard handling base.MoveGripPointsAt(entity, grips, offset, bitFlags); } public static void ResetGrips(ObjectId entity_id) { // Reset grips to their original point if (_ents_handled.ContainsKey(entity_id)) { GripDataCollection grips = _ents_handled[entity_id]; for (int i = 0; i < grips.Count; i++) { myGripData gdo = (myGripData)grips[i]; gdo.GripPoint = gdo.m_original_point; } } } public static void ResetAllGrips() { // Clear handled list, to be called when selection is cleared _ents_handled.Clear(); } } }