📜 ⬆️ ⬇️

Intelligent user object handles in MultiCAD.NET



Easy editing of drawings is one of the key characteristics of computer-aided design systems. An important tool for working with drawing objects is grips — special markers at key points of an object that allow you to modify an object using the mouse, without using a menu or command line.

The handle control mechanism in MultiCAD.NET allows you to work with both simple and intelligent handles. We wrote about simple pens in one of the past articles , but here we look at intelligent pens, which, apart from the form (round, triangular, rhomboid, etc.), differ from simple ones in that they can change individual parameters of the object, causing pop-up menu or perform a set of actions defined in the handler. In addition, this API of intelligent pens also allows you to create simple pens, but using a new, unified approach.
')
Under the cut, the code for creating several types of intelligent object handles and animated images demonstrating their use.

McSmartGrip <T> class


To describe the intelligent pens in the MultiCAD.NET API, the McSmartGrip<T> class is used. This class contains several variants of the constructor with different lists of parameters, as well as event handlers that are generated depending on user actions:


For example, to create a simple handle that is responsible for moving an object’s point, the following constructor can be used:
 var simpleGrip = new McSmartGrip<ObjectRefEntity>(position, (obj, g, offset) => { obj.TryModify(); obj._pnt += offset; } 

This constructor provides for the implementation of the MoveGrip delegate, which we did with the help of lambda expressions ( http://msdn.microsoft.com/ru-ru/library/bb397687.aspx ), namely, shifted the position of the object by the value offset .

Register pens


Registration of the user object's handles is performed using the AppendGrip() method of the AppendGrip() class:
 public void AppendGrip(Multicad.CustomObjectBase.McBaseGrip grip); 

This class is used as an argument to the GetGripPoints() method, which is called to get pens each time an object is displayed:
 public virtual bool GetGripPoints(Multicad.CustomObjectBase.GripPointsInfo info); 

The following code snippet creates and adds all the same simple handle:

 public override bool GetGripPoints(GripPointsInfo info) { info.AppendGrip(new McSmartGrip<ObjectRefEntity>(_pnt, (obj, g, offset) => { obj.TryModify(); obj._pnt += offset; })); } 

As you can see, the whole procedure is very compact and takes up only one line of code. However, it concerned the most elementary case, namely, simple pens. Let's look at what other types of pens are supported in the MultiCAD.NET API, as well as the specifics of working with each of them.

Types of pens


Using MulitiCAD.NET, you can create pens of the following types:


Appearance pens


One object can contain several pens of different types; in order to visually distinguish them, you can assign the appearance of each of them, defining its shape and color. The variety of pen shapes is defined by the McBaseGrip.GripAppearance listing. Here are some of them:



You can also set the desired color of the handles from a set of colors defined in the GripColors class, or you can determine the color in the standard way using System.Drawing.Color .
Let's see how it works. As an example, take the TextInBox primitive we TextInBox , described in this article, and create for it several intelligent pens of various types.

Simple pen

We already mentioned this kind of pens in the article, and, as the name suggests, it is used for simple actions, for example, for moving points of an object. Add one simple handle to move the corner point of our primitive:
 info.AppendGrip(new McSmartGrip<ObjectRefEntity>(_pnt, (obj, g, offset) => { obj.TryModify(); obj._pnt += offset; })); 

The result of such a pen is in an animated illustration:



Pen button

Add a button handle that will control the display of the frame around the text by pressing. To create such a pen, a constructor is used with the type of the McBaseGrip.GripType.Button pen and the base color. The _show_frame button handler changes the value of the _show_frame frame drawing indicator to the opposite. For the created knob-button, we define the appearance of "on", which will change to "off" when pressed, and back.

 var OnOffGrip = new McSmartGrip<TextInBox>(McBaseGrip.GripType.Button, 1, _pnt + stepVector, McBaseGrip.GripAppearance.SwitchOn, 0, "Hide Frame", GripColors.Base); OnOffGrip.Tag = "OnOffGrip"; if (_show_frame == false) OnOffGrip.SetAppearanceAndText(McBaseGrip.GripAppearance.SwitchOff, "Show frame"); OnOffGrip.OnCommand = (obj, commandId, grip) => { obj.TryModify(); obj._show_frame = !obj._show_frame;}; info.AppendGrip(OnOffGrip); 


Result:



Also by pressing the knob button, the required registered command can be called:

 var cmdGrip = new McSmartGrip<TextInBox>( McBaseGrip.GripType.Button, 1, _pnt + 2 * stepVector, McBaseGrip.GripAppearance.Circle, 0, "button", GripColors.Base); cmdGrip.Tag="cmd"; cmdGrip.OnCommand = (obj, commandId, grip) => { McContext.ExecuteCommand(grip.Tag.ToString()); }; 


Pen menu

Another type of pens that can be created in MultiCAD.NET is the handle for calling the context menu. This type of pens is used when the user needs to select from the list the required value of an object parameter from the list.
This type of pens is created using a constructor with an indication of the type McBaseGrip.GripType.PopupMenu and the appearance defined by the value of McBaseGrip.GripAppearance.PopupMenu . To work with the context menu, you need to implement two delegates:
GetContextMenu - call the menu when you press the handle,
OnCommand - call actions when selecting items

 var ctxGrip = new McSmartGrip<TextInBox>(McBaseGrip.GripType.PopupMenu, 2, _pnt + 2 * stepVector, McBaseGrip.GripAppearance.PopupMenu, 0, "Select menu", System.Drawing.Color.Lime); ctxGrip.GetContextMenu = (obj, items) => { items.Add(new ContextMenuItem("Command 1", "none", 1)); }; ctxGrip.OnCommand = (obj, commandId, grip) => { if (grip.Id == 2) { switch (commandId) { case 1: { MessageBox.Show("Command 1 is selected"); break; } } } }; info.AppendGrip(ctxGrip); 


Result:



Interactive pen

And finally, the last type of pens, which we consider - interactive. The main difference between these pens is that they can use information about the anchor objects and, depending on this, determine their behavior.
As an example, add one of these pens, which will allow to change the text of our primitive to the name of the selected object (with the exception of the parent object). Depending on the binding object, the handle will change color: in the initial state, the handle will have the color of GripColors.Base , when you hover over the parent object, the color will change to Color.Red , to any other object that supports the binding to Color.Green .
An interactive pen is created by the constructor indicating the type McBaseGrip.GripType.Interactive , and the pen is implemented in the MouseMove delegate (as opposed to simple pens using MoveGrip ).

 var interactiveGrip = new McSmartGrip<TextInBox>(McBaseGrip.GripType.Interactive, 3, _pnt + 3 * stepVector, McBaseGrip.GripAppearance.Arrow, 0, "interactive", GripColors.Base); interactiveGrip.IsMovable = true; interactiveGrip.MouseMove = (obj, entInfo, grip, offset) => { grip.Color = GripColors.Base; if (!entInfo.SnapedObjectId.IsNull) { if (ID == entInfo.SnapedObjectId) { grip.Color = Color.Red; } else { grip.Color = Color.Green; obj.TryModify(); obj.Text = (entInfo.SnapedObjectId.GetObject().GetType().ToString()); } } }; info.AppendGrip(interactiveGrip); 

Result: the text “Text field” was replaced by “MultiCAD.Samples.TextInBox”.



We have listed the main types of intelligent handles that allow you to create an effective interface for working with custom objects created on MultiCAD.NET. The MultiCAD.NET documentation is included with the nanoCAD SDK, which can be accessed by registering with the nanoCAD Developer Club .

Discussion of the article is also available on our forum: forum.nanocad.ru/index.php?showtopic=6518 .
Translation of the article into English: Smart grips of custom object in MultiCAD.NET

Source: https://habr.com/ru/post/234181/


All Articles