I'm just getting started with blockjigs, and they're working OK, but the user needs to hit Esc to exit out of the while loop. I'd like to cancel out of the command when the user hits space(enter), similar to most autocad commands. Ideally it will react differently to a space/enter: if I'm in the rotating jig, it'll keep the block at the original rotation, if inserting a block, it'll cancel out of the command. Once I trap the space/enter, I can work that logic out though.
Basically I have a do/while loop executing a jig drag while the promptStatus is OK.
I'm not sure if I need to change the do/while loop where I call the jigs, or maybe it's in the UserInputControls in the SamplerStatus override? Also, if my execution is silly/inefficient I'm open to other comments, I'm still really new to this.
The call to the jigs with the do/while loop:
public static void InsertRotatorBlockTest(ObjectId blockId, Scale3d scale, string layerName = "0", ResultBuffer optionalXData = null)
{
Database db = Active.Database;
Transaction tr = Active.Document.TransactionManager.StartTransaction();
using (tr)
{
//Open block table to be sure it exists
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
PromptResult pr;
double rotation = 0;
do
{
// now the jig
// create the blockref
Point3d pt = new Point3d(0, 0, 0);
BlockReference br = new BlockReference(pt, blockId)
{
ScaleFactors = scale,
Layer = layerName,
Rotation = rotation
};
if (optionalXData != null)
{
br.XData = optionalXData;
}
InsertBlockJig insertJig = new InsertBlockJig(br);
// insert the blockref into modelspace
pr = Active.Editor.Drag(insertJig);
if (pr.Status==PromptStatus.OK)
{
// rotate it
RotatingBlockJig rotateJig = new RotatingBlockJig(br);
pr = Active.Editor.Drag(rotateJig);
BlockTableRecord curSpace = (BlockTableRecord)tr.GetObject(Active.Database.CurrentSpaceId,
OpenMode.ForWrite);
curSpace.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
// Call a function to make the graphics display (otherwise it only shows after commit)
Active.Document.TransactionManager.QueueForGraphicsFlush();
rotation = br.Rotation;
}
} while (pr.Status != PromptStatus.Cancel &&
pr.Status != PromptStatus.Error &&
pr.Status != PromptStatus.Keyword);
tr.Commit();
}
}
The two EntityJig classes:
class InsertBlockJig : EntityJig
{
Point3d _mCenterPt, _mActualPoint;
public InsertBlockJig(Entity ent)
: base(ent)
{
_mCenterPt = ((BlockReference) ent).Position;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
JigPromptPointOptions jigOpts =
new JigPromptPointOptions();
jigOpts.UserInputControls =
(UserInputControls.Accept3dCoordinates
| UserInputControls.NullResponseAccepted
| UserInputControls.NoNegativeResponseAccepted);
jigOpts.Message =
"\nEnter insert point: ";
PromptPointResult dres =
prompts.AcquirePoint(jigOpts);
if (_mActualPoint == dres.Value)
{
return SamplerStatus.NoChange;
}
else
{
_mActualPoint = dres.Value;
}
return SamplerStatus.OK;
}
protected override bool Update()
{
_mCenterPt = _mActualPoint;
try
{
((BlockReference)Entity).Position = _mCenterPt;
}
catch (Exception)
{
return false;
}
return true;
}
}
class RotatingBlockJig : EntityJig
{
// Fields
private double _mRotation;
private BlockReference _br;
// Constructor
public RotatingBlockJig(BlockReference br)
: base(br)
{
_mRotation = br.Rotation;
_br = br;
}
// Overrides
protected override bool Update()
{
(Entity as BlockReference).Rotation = _mRotation;
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
JigPromptAngleOptions prAngleOpts = new JigPromptAngleOptions("\n Rotation: ");
prAngleOpts.BasePoint = _br.Position;
prAngleOpts.UseBasePoint = true;
prAngleOpts.Cursor=CursorType.RubberBand;
PromptDoubleResult prRotResult = prompts.AcquireAngle(prAngleOpts);
if (prRotResult.Status == PromptStatus.Cancel) return SamplerStatus.Cancel;
// Return no change if no rotation, to prevent flashing
if (prRotResult.Value.Equals(_mRotation))
{
return SamplerStatus.NoChange;
}
else
{
_mRotation = prRotResult.Value;
return SamplerStatus.OK;
}
return SamplerStatus.OK;
}
}