DeSignature Posted March 25, 2020 Share Posted March 25, 2020 How come, if I call my PIO a first time in a drawing that all PIO record fields - since all the respective text items that are created in that PIO are blanc - appear to be empty? If I delete that PIO en recall the same PIO, all the text items are displayed as I intended them to be displayed. When I insert the PIO in a new drawing, there is no PIO record in the new drawing, I guess when I reinsert the PIO, the PIO can get it's values from the record created by the first call. Is there a standard procedure to avoid this behavior? Quote Link to comment
JBenghiat Posted March 25, 2020 Share Posted March 25, 2020 I'm not completely sure I understand the question: are you placing a PIO via script and immediately trying to access its data? You can run https://developer.vectorworks.net/index.php/VS:DefineCustomObj to create the record first (you can get a handle to the PIO's record by its name and check for nil). Otherwise, the PIO doesn't actually create it's record until after the vs runs. Quote Link to comment
DeSignature Posted March 25, 2020 Author Share Posted March 25, 2020 (edited) The PIO is not being placed via a script, I just click a button in a tool palette and place the corresponding (custom) object somewhere on a sheet layer. For now, I'll check out the DefineCustomObj function. Thanks. Edited March 25, 2020 by DeSignature Quote Link to comment
JBenghiat Posted March 25, 2020 Share Posted March 25, 2020 What you are seeing is not expected behavior, then. You should see PIO defaults on the first insertion. Is your PIO event enabled? If so, you may have code allocated to the wrong events. Quote Link to comment
Pat Stanford Posted March 25, 2020 Share Posted March 25, 2020 The difference is that the first time you place a PIO in a specific document there Plug-in Parameter Record does not yet exist. When you place the PIO it is created. When you delete the PIO the Parameter Record is not deleted, so the next time you place the same PIO the Parameter Record with the default data is still there to be used. You should be able to set reasonable default values in the Plug-in Editor so that on first insertion you get something reasonable. And these should be editable if you click the Preferences setting of the insertion tool (Pencil/wrench icon) to be used as the defaults for future insertions. Quote Link to comment
DeSignature Posted March 26, 2020 Author Share Posted March 26, 2020 Is there a function or a procedure that can check whether or not a record already exists in a drawing? Apparently, if I replace the variable strings ( GetRField (PIO_H, PIO_R, StrVar) ) in the linked text items by constant strings ( 'Some Text' ), then the text items get displayed at the first insertion of the PIO. So, I guess I could write a code that checks if the record is already present in the current drawing, if not then the text items should use constant strings, if so then the text items should use variable strings. Quote Link to comment
DeSignature Posted March 28, 2020 Author Share Posted March 28, 2020 (edited) The function Count (R IN [PIO_N]) helped me out here, but I could not find a the criteria to see if a record already exists in a drawing. Since the function above checks if there exists an object with the referenced record attached to it in the drawing, it still doesn't check if a certain record exists in the drawing. If I insert the PIO in a drawing for the first time the Count will return 0, once I've inserted 1 PIO, the count will return 1, but if I delete the PIO the count would return 0 again - which would be correct, but the PIO did create a record and if I delete the PIO, the record would still exist in the drawing. EDIT: This function only helped me out to display the text objects at the insertion of the PIO, since the created texts were constant strings ('Some Text'), they couldn't be edited anymore, so ...: back to the drawing board. Edited March 28, 2020 by DeSignature Quote Link to comment
JBenghiat Posted March 28, 2020 Share Posted March 28, 2020 On 3/26/2020 at 6:17 AM, DeSignature said: Is there a function or a procedure that can check whether or not a record already exists in a drawing? I alluded to this in my first post. To get a handle to the plug-in’s record, use GetObject(plug-in_name). If the handle equals NIL, it doesn’t exist. But I would still revisit your issue in general. Plug-in objects shouldn’t need any special handling to display their default values on the first insertion. Something is either wrong with the structure of your code or the way you are retrieving parameters. Can you post some sample code? Quote Link to comment
DeSignature Posted March 28, 2020 Author Share Posted March 28, 2020 Well I'll definitely will have to give that a try, but something tells me that this function will look for inserted PIO's and not for (hidden) PIO records ... Anyway, I have simplified the actual code and tested the result, the result is the same, the variable strings are not being displayed at the moment of insertion, they get displayed when the 'Edit Subgeometry' dialog gets confirmed or when the PIO is being reinserted. Really looking forward to your findings, just hoping it won't be something too obvious ... Dimitri. PROCEDURE Simple; VAR PIO_N : STRING; PIO_H, PIO_R, PIO_W : HANDLE; EventId, EventResult : LONGINT; DialogId, DialogResult : LONGINT; Result : BOOLEAN; Txt : STRING; PROCEDURE Geometry; PROCEDURE Define_Size; BEGIN END; PROCEDURE Draw_Geometry; BEGIN; RectangleN (-30, -15, 1, 0, 60, 30); END; PROCEDURE Insert_Subgeometry; PROCEDURE Draw_Subgeometry; BEGIN MoveTo (-30, 10); LineTo (60, #0); MoveTo (0, -15); LineTo (30, #90); END; PROCEDURE Insert_Text_Items; PROCEDURE Insert_Text_Items_A (x, y: REAL; T: STRING); BEGIN TextSize (8); MoveTo (x, y); CreateText (T); END; PROCEDURE Insert_Text_Items_B (x, y, StrS: REAL; T: STRING); BEGIN TextSize (StrS); MoveTo (x, y); CreateText (T); END; BEGIN Insert_Text_Items_A (-15, 12.5, 'Text A:'); Insert_Text_Items_A (15, 12.5, 'Text B:'); { ... } Insert_Text_Items_B (-15, 0, 12, GetRField (PIO_H, PIO_N, 'RecordField A')); LinkText (LNewObj, PIO_N, GetRField (PIO_H, PIO_N, 'RecordField A')); Insert_Text_Items_B (15, 0, 12, GetRField (PIO_H, PIO_N, 'RecordField B')); LinkText (LNewObj, PIO_N, GetRField (PIO_H, PIO_N, 'RecordField B')); { ... } END; BEGIN Draw_Subgeometry; Insert_Text_Items; END; BEGIN Define_Size; Draw_Geometry; Insert_Subgeometry; END; PROCEDURE EditSubgeometry; PROCEDURE Records; BEGIN NewField (PIO_N, 'RecordField A', 'TEXT A', 4, 1); NewField (PIO_N, 'RecordField B', 'TEXT B', 4, 1); { ... } END; PROCEDURE Apply2All (ObjH: HANDLE); BEGIN GetItemText (DialogID, 161, Txt); SetRField (ObjH, PIO_N, 'RecordField A', Txt); { ... } ResetObject (ObjH); END; PROCEDURE DialogLayout; BEGIN DialogId := CreateLayout ('Dialog A', FALSE, 'OK', 'Cancel'); CreateGroupBox (DialogId, 100, 'Tab A', FALSE); CreateRightStaticText (DialogId, 110, 'Text A:', 20); CreateEditText (DialogId, 111, 'TEXT A', 41); { ... } CreateCheckBox (DialogId, 120, 'Apply To All'); SetFirstGroupItem (DialogId, 100, 110); SetRightItem (DialogId, 110, 111, 0, 0); SetBelowItem (DialogId, 110, 120, 0, 0); { ... } CreateGroupBox (DialogId, 200, 'Tab B', FALSE); CreateRightStaticText (DialogId, 210, 'Text B:', 20); CreateEditText (DialogId, 211, 'Text B', 41); { ... } SetFirstGroupItem (DialogId, 200, 210); SetRightItem (DialogId, 210, 211, 0, 0); { ... } CreateTabControl (DialogId, 10); SetFirstLayoutItem (DialogId, 10); CreateTabPane (DialogId, 10, 100); CreateTabPane (DialogId, 10, 200); END; PROCEDURE DialogEvents (VAR Item, Data: LONGINT); PROCEDURE DialogSettings; BEGIN SetItemText (DialogID, 111, GetRField (PIO_H, PIO_N, 'RecordField A')); { ... } SetItemText (DialogID, 211, GetRField (PIO_H, PIO_N, 'RecordField B')); { ... } END; PROCEDURE ConfirmDialog; BEGIN GetItemText (DialogId, 111, Txt); SetRField (PIO_H, PIO_N, 'RecordField A', Txt); { ... } GetItemText (DialogId, 211, Txt); SetRField (PIO_H, PIO_N, 'RecordField B', Txt); { ... } GetBooleanItem (DialogID, 120, Result); IF Result = TRUE THEN ForEachObject (Apply2All, PON = PIO_N); ResetObject (PIO_H); END; PROCEDURE CancelDialog; BEGIN END; BEGIN IF GetCustomObjectInfo (PIO_N, PIO_H, PIO_R, PIO_W) THEN CASE Item OF SetupDialogC : DialogSettings; 1 : ConfirmDialog; 2 : CancelDialog; END; END; BEGIN Records; DialogLayout; IF VerifyLayout (DialogID) THEN DialogResult := RunLayoutDialog (DialogID, DialogEvents); END; PROCEDURE Button_B; BEGIN END; PROCEDURE Button_C; BEGIN END; PROCEDURE Button_D; BEGIN END; PROCEDURE AutoEdit; VAR AutoTxt : STRING; BEGIN AutoTxt := GetFName; IF GetCustomObjectInfo (PIO_N, PIO_H, PIO_R, PIO_W) THEN BEGIN SetRField (PIO_H, PIO_N, 'RecordField A', AutoTxt); { ... } END; ResetObject (PIO_H); END; BEGIN vsoGetEventInfo (EventId, EventResult); CASE EventId OF 03: IF GetCustomObjectInfo (PIO_N, PIO_H, PIO_R, PIO_W) THEN BEGIN PushAttrs; Geometry; PopAttrs; END; 05: BEGIN Result := SetObjPropVS (08, TRUE); Result := vsoInsertAllParams; Result := vsoAppendWidget (12, 100, 'Edit Subgeometry', 0); Result := vsoAppendWidget (12, 200, 'Button B', 0); Result := vsoAppendWidget (12, 300, 'Button C', 0); Result := vsoAppendWidget (12, 400, 'Button D', 0); Result := vsoAppendWidget (12, 500, 'Auto Edit', 0); END; 35: IF GetCustomObjectInfo (PIO_N, PIO_H, PIO_R, PIO_W) THEN CASE EventResult OF 100: EditSubgeometry; 200: Button_B; 300: Button_C; 400: Button_D; 500: AutoEdit; END; END; END; RUN (Simple); Quote Link to comment
Pat Stanford Posted March 28, 2020 Share Posted March 28, 2020 DeSignature, 43 minutes ago, DeSignature said: Well I'll definitely will have to give that a try, but something tells me that this function will look for inserted PIO's and not for (hidden) PIO records ... Josh is one of the most knowledgeable (THE most knowledgeable in many areas) and most generous with sharing his knowledge. Your putting yourself at risk by putting out your opinion that something won't work with his statement that that is the way to do it. By the way, I agree with him, but I tested it with the following single line script: AlrtDialog(Concat(GetObject('Door'))); I ran it in a new document which did not have a door and I got a return of 0 meaning a nil handle. Placed a door and ran it. Got a 16 digit number which is the handle. Deleted the door and ran it again and got the same 16 digit number. That shows that it is the handle to the Record Definition, not the Door object in the drawing. And remember, in VW, only a single object in the drawing can have a name. If you draw a rectangle, go to the OIP and set the Name field to Door, you will not be able to add a door object to the drawing as the name has already been taken. Similarly, if a door has ever been placed in the drawing the Door Record now exists and you will never be able to name an object in the drawing Door. Quote Link to comment
DeSignature Posted March 28, 2020 Author Share Posted March 28, 2020 It's just that GetObject(plug-in_name) contained 'plug-in_name' and not 'plug-in_handle', but I really do agree it would have been much wiser to check the function reference before putting out my opinion and I will keep your advise in mind. Hoping I didn't offend anybody in any way, Dimitri. Quote Link to comment
JBenghiat Posted March 28, 2020 Share Posted March 28, 2020 I’m not nearly as generous with my time as @PatStanford, but I do know the ins and outs of vs fairly well. 🙂 GetObject() will return a handle to the object with the name you pass to it. Every PIO has a record format with the same name as the PIO. In terms of object type, it is exactly the same as a data record format. VW creates the format when you first insert the PIO or open its default settings in the mode bar. In your case, you have an issue with the code, though. You are calling LinkText() which is for creating symbols with text linked to record fields. You do not need this for PIOs, and in fact the use here is causing the text to always be one step behind. The PIO will completely redraw it’s contents any time you change a parameter, so simply creating the text is enough. If you are setting the parameter via another script, call ResetObj() to get the values to update. You also don’t need to use GetRField to get the parameter value, unless the text is more than 255 characters or you use SetRField elsewhere in the script. Usually you can just use PParameterName, which is essentially a constant at run time with a type matching the parameter type. Quote Link to comment
DeSignature Posted March 31, 2020 Author Share Posted March 31, 2020 Following your remarks, I have deleted the LinkText() calls, I tried to include the GetObject function in about every part of the script, I tried to include the DefineCustomObj function in about every part of the script - every part but the correct one, I guess - using the 3 possible preference settings, I did not delete or replace the GetRField function since I do use the SetRField function in the script. but still, in every case the texts do not get displayed at insertion of the PIO. As far as I can understand, I have to try to create the records before anything else happens in the script, so I guess I I'm creating the records at the wrong time in the script. As I have mentioned above, the DefineCustomObj function did not help out on this one, where should I call this function? Quote Link to comment
JBenghiat Posted March 31, 2020 Share Posted March 31, 2020 Just adding DefineCustomObj() everywhere may be doing more harm than good. You should not need this anywhere in the code — my suggestion was based on the assumption you were placing custom objects via scripts, which is when the call is needed. As far as I can tell, you are only using SetRField in a button event. You can view the scope of each event running separately. I also noticed EditSubGeometry calls NewField() on the plug-in record. You should never modify the plug-in record via VectorScript, so that could be causing issues. Only use the Plug-in Manager to edit the parameter format. I would recommend stripping the code down to only the reset event to troubleshoot, and getting rid of all your DefineCustomObj calls for now. One of my initial suspicions is that your code isn’t handling events correctly. You may also want to restructure your code a bit to make it easier to troubleshoot. In some cases, you seem to be using subprocedures in lieu of commented code blocks, which could be causing scope issues. In contrast, one place where I do recommend subprocedures is for each event type (currently they are all inline in the case statement), which lets you write a simple main function with an event handler and clarifies that each handler should have its own scope. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.