.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to indicate position of getstring ?

12 REPLIES 12
Reply
Message 1 of 13
rebarwin
759 Views, 12 Replies

How to indicate position of getstring ?

Hello,

By using GETSTRING I can show the user an input field for text entry.

 

The question is: How can I decide which position in the drawing this input field appears ? I would like to be able to pass a geometry.point3d as a parameter but I do not find where to pass this parameter.

 

I show an example of getstring code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;  

[CommandMethod("GetStringFromUser")]

public static void GetStringFromUser()

{  

Document acDoc = Application.DocumentManager.MdiActiveDocument;   

PromptStringOptions pStrOpts = new PromptStringOptions("\nEnter your name: ");  

pStrOpts.AllowSpaces = true;  

PromptResult pStrRes = acDoc.Editor.GetString(pStrOpts);    

Application.ShowAlertDialog("The name entered was: " + pStrRes.StringResult);

}

Thanks for your help.

 

12 REPLIES 12
Message 2 of 13
Alfred.NESWADBA
in reply to: rebarwin

Hi,

 

the method GetString asks for some characters/a textstring. And that has nothing to do with coordinates on the drawing!

Imagine also that the user does not have DynamicInput (<F12>) active so the text to be typed in has to be typed in within the command-line-area (and there is no geomtry at all, so also no coordinates).

 

The only thing you can do is to get the mouse ccords on screen and calculate them back to the coordiantes at your current space. That is possible as long as you are in any 2D-space, but if e.g. you are in modelspace and that shows a perspective view you won't get coordinates without any objectsnap (and while GetString is active you don't have an objectsnap active).

 

May be you can give us some details? If it's more clear to us why you need coordinates for a GetString function that may help to find an alternative!

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 3 of 13
rebarwin
in reply to: rebarwin

I would like to show an input field for each segment of a polyline, requesting the length of each segment of the polyline.

 

The input field should be placed at the middle point of each segment of the polyline, to make clear what length is being requested. As the input field should be placed at the middle point of each segment I need to know how to indicate this in the getstring function.

 

Obviously the polyline is not at scale. If it was at scale it would be enough to read the length for each segment.

 

The drawings will always be 2D, never 3D.

 

Thanks for your help

Message 4 of 13
Alfred.NESWADBA
in reply to: rebarwin

Hi,

 

in this case, if I understand that correct, you don't want "to get" coordinates from GetString, your want "to place the textinput" to a specific position (to the midpoint of a polyline-segment?

In that case you can't work with GetString as that asks for a textvalue either at the position where your cursor currently is positioned or within the command-line. Instead I would create a small form (without border, just one TextBox) and show that at the position of the midpoint of your polylinesegment.

 

Good luck, - alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 5 of 13
rebarwin
in reply to: Alfred.NESWADBA

Thanks for your help.

 

That's right, I want "to place the textinput" in a specific position .

 

I suppose the solution you propose is to create a very small form only containing an input field and call it like that:

 

myForm = new InputFieldForm1();

nAnswer = Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(myForm);

 

How could I choose the position at which this form will be shown, using autocad coordinates ?

 

Thanks

Jose Maria

Message 6 of 13
rebarwin
in reply to: rebarwin

Or another possibility, if you say the getstring is placed at the cursor position, would be to change the cursos position before calling getstring.

Is it possible to change the cursor position programmatically ?

Message 7 of 13
dgorsman
in reply to: rebarwin

You may also be able to "fake it" by placing a temporary text object on screen where you want it; have the user enter the information in the text object; get the contents of the string (and error check!); move the text object to the middle of the next segment; and delete the text object when finished.  You might also consider placing multiple text objects (with associated leader lines if there isn't room) then reading them all in a single go before deleting the lot of them.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


Message 8 of 13
rebarwin
in reply to: dgorsman

Yes I can place a text object, but how can make the content automatically editable ?


Thanks

Message 9 of 13
jeff
in reply to: rebarwin

Here is 2 little examples of using text objects and depends on what year you are using.

Might need at least 2011 or 2012.

 

Just basic and need a regular polyline with line segs and not arcs(you could have arcs but not for this simple example)

 

Both just itterate the polyline invoking the InplaceTextEditor at the MidPoint of the LineSegments

 

Using InPlaceTextEditor you could do something like this but you probably would want to jump to the next segment when Enter is pressed.

 

 [CommandMethod("EnterLengths")]
        public void EnterLengths()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nSelect PolyLine");
            peo.SetRejectMessage("\nNot a PolyLine Select a PolyLine");
            peo.AddAllowedClass(typeof(Polyline), true);

            PromptEntityResult per = ed.GetEntity(peo);

            if (per.Status != PromptStatus.OK)
            {
                return;
            }

            using (Transaction trx = db.TransactionManager.StartTransaction())
            {

                Polyline pl = per.ObjectId.GetObject(OpenMode.ForRead) as Polyline;

                for (int i = 0; i < pl.NumberOfVertices; i++)
                {
                    if (pl.GetSegmentType(i) == SegmentType.Line)
                    {
                        LineSegment3d lineSeg = pl.GetLineSegmentAt(i);
                        using (MText mtxt = new MText())
                        {
                            mtxt.Contents = "";
                            mtxt.Location = lineSeg.MidPoint;
                            InplaceTextEditorSettings ipts = new InplaceTextEditorSettings();
                            ipts.SimpleMText = true;
                            ipts.TabSupported = false;                      
                            InplaceTextEditor.Invoke(mtxt, ipts);
                        }
                    }
                }
               
                trx.Commit();
            }


        }

 

 

 

If you use text objects and you do not want them to have to press ctrl+enter to move to next  or if they left click outside the text editor to create another new text object then Mtext will not work unless you hack it even more by maybe watching for a new line.

 

You will still have the same problem using DBText unless it is database resident.

So you could hack your way through by creating a empty DbText object then opening it in the InPlaceTextEditor and erasing it or not if wanted it to stay.

 

        [CommandMethod("EnterLengthsDbtxt")]
        public void EnterLengthsDbtxt()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nSelect PolyLine");
            peo.SetRejectMessage("\nNot a PolyLine Select a PolyLine");
            peo.AddAllowedClass(typeof(Polyline), true);

            PromptEntityResult per = ed.GetEntity(peo);

            if (per.Status != PromptStatus.OK)
            {
                return;
            }
            
            using (Transaction trx = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = db.CurrentSpaceId.GetObject(OpenMode.ForWrite) as BlockTableRecord;
                Polyline pl = per.ObjectId.GetObject(OpenMode.ForRead) as Polyline;

                for (int i = 0; i < pl.NumberOfVertices; i++)
                {
                    if (pl.GetSegmentType(i) == SegmentType.Line)
                    {
                        LineSegment3d lineSeg = pl.GetLineSegmentAt(i);

                        DBText dbTxt = new DBText();
                        dbTxt.TextString = "";
                        dbTxt.Position = lineSeg.MidPoint;

                        btr.AppendEntity(dbTxt);
                        trx.AddNewlyCreatedDBObject(dbTxt, true);

                        InplaceTextEditorSettings ipts = new InplaceTextEditorSettings();
                        ipts.SimpleMText = true;
                        ipts.TabSupported = false;
                        ObjectId[] ids = new ObjectId[0];
                        InplaceTextEditor.Invoke(dbTxt, ref ids);

                        dbTxt.Erase();
                    }
                }

                trx.Commit();
            }


        }

 

You can also find your answers @ TheSwamp
Message 10 of 13
jeffHGCE
in reply to: jeff

Here is a little screencast showing the code here which is the same as above except it fills in text with existing length and selects all the text. Will post code at bottom.

http://screencast.com/t/K6xQ0txwUSZ

 

What I wonder is how you will handle changing the lengths because changing the length of one segment or really moving the vertex(LineSegment properties are mostly read-only) will change the length of the segment before and & after it or at least one of the other.

 

        [CommandMethod("EnterLengthsDbtxt")]
        public void EnterLengthsDbtxt()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nSelect PolyLine");
            peo.SetRejectMessage("\nNot a PolyLine Select a PolyLine");
            peo.AddAllowedClass(typeof(Polyline), true);

            PromptEntityResult per = ed.GetEntity(peo);

            if (per.Status != PromptStatus.OK)
            {
                return;
            }
            
            using (Transaction trx = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = db.CurrentSpaceId.GetObject(OpenMode.ForWrite) as BlockTableRecord;
                Polyline pl = per.ObjectId.GetObject(OpenMode.ForRead) as Polyline;

                for (int i = 0; i < pl.NumberOfVertices; i++)
                {
                    if (pl.GetSegmentType(i) == SegmentType.Line)
                    {
                        LineSegment3d lineSeg = pl.GetLineSegmentAt(i);

                        DBText dbTxt = new DBText();
                        dbTxt.TextString = lineSeg.Length.ToString();
                        dbTxt.Position = lineSeg.MidPoint;

                        btr.AppendEntity(dbTxt);
                        trx.AddNewlyCreatedDBObject(dbTxt, true);

                        InplaceTextEditorSettings ipts = new InplaceTextEditorSettings();                       
                        ipts.SimpleMText = true;
                        ipts.TabSupported = false;
                        ObjectId[] ids = new ObjectId[0];
                        InplaceTextEditor.Invoke(dbTxt, ref ids);
                        InplaceTextEditor.Current.SelectAll();

                        double length;
                        if ((!String.IsNullOrWhiteSpace(dbTxt.TextString)) && Double.TryParse(dbTxt.TextString, out length))
                        {
                            //////
                            
                        }

                        dbTxt.Erase();
                    }
                }

                trx.Commit();
            }


        }

 

Message 11 of 13
Alfred.NESWADBA
in reply to: jeffHGCE

Hi,

 

>> how you will handle changing the lengths

Just a short interrupt: have you looked into constraints?

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 12 of 13
rebarwin
in reply to: rebarwin

Thank you very much for your help to all who have answered. This was important for me and now I see solutions for my problem.

 

I am trying them and will go back to this thread to report on the results.

 

Of the solutions that have been proposed, what seems closer is inplacetexteditor using dbtext instead of mtext, as in [CommandMethod("EnterLengthsDbtxt")] . This is because with dbtext you end edition by pressing enter, so it is simpler. With mtext you have to press Ctrl-Enter.

 

REGARDING THE SOLUTION WITH INPLACETEXTEDITOR ( [CommandMethod("EnterLengthsDbtxt")])

I would like a possibility of controlling the navigation keys: for instance when the user presses the up arrow key, the editing focus should go back to the previous segment.

 

REGARDING THE SOLUTION WITH SMALL FORM

This solution was proposed earlier and it would be great since it would also work on older autocad versions. I have 2 difficulties in implementing it:

Problem 1) Manage the navigation keys: When the user presses enter, it should go to the form in the next segment (without needing to press ok button), when the user presses the up arrow key, the editing focus should go back to the form in previous segment.

Problem 2) How to convert from autocad coordinates to screen coordinates needed to position the small form

 

REGARDING THE SOLUTION WITH GETSTRING

It seems the getstring input field appears at the cursor location, it would be enough to be able to change cursor location, but don't know if this is possible or how to do it.

 

REGARDING THE PROPOSAL TO LOOK AT CONSTRAINTS:

>> how you will handle changing the lengths

>Just a short interrupt: have you looked into constraints?

Sorry I don't know what constraints are

 

THANKS FOR YOUR HELP, THIS IS IMPORTANT FOR ME.

JOSE MARIA ESPINOSA

Message 13 of 13
Alfred.NESWADBA
in reply to: rebarwin

Hi,

 

for getting coordiantes:

Within AutoCAD I think you know how to get the coords, for the screen you can use

System.Windows.Forms.Control.MousePosition

to know where you mouse is placed on your screen and so where you have to popup your form-object.

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost