twk Posted July 29, 2015 Share Posted July 29, 2015 Greetings all, Anyone know how, if possible, to script in a way to get a handle to an external object via a button on the Object Info Pallette(OIP)?? So far my experimenting has utilised - Event Enabled PIO - Placing in the Button Event loop, the GetPt(px,py) and h:=PickObject(px, py) - and then SetRField the Area of picked object onto Parameter Field Im trying to have a static txt parameter display area for certain type of objects on layer (via a critera, same pen/fill/class/etc). the result from the PickObj method semi works, but it doesnt store the value in the parameter field. and sometimes it causes VW to go haywire. (Menu Items greyed out etc). Does anyone know if Im way off track or a bit close? Thanks in advance Tui W K Quote Link to comment
JBenghiat Posted July 29, 2015 Share Posted July 29, 2015 Sounds like you are on the right track. SetRField should only be in the button event. What does your SetRField look like? Does your call work from the main reset part of the script if you use a test string? A button event won't reset the object to display the new data. Add a ResetObject() call to cause the PIO to regenerate. -Josh Quote Link to comment
twk Posted July 29, 2015 Author Share Posted July 29, 2015 (edited) Hi Josh, Yes, setrfield works from main reset procedure test. Below is full testing code. Procedure EventStamp; CONST kObjOnInitXProp = 5; kResetEventID = 3; kObjXPropHasUIOverride = 8; kWidgetButton = 12; ButtonID_1 = 1331; ButtonID_2 = 1332; kButtonOIPHit = 35; VAR theEvent, theButton : LONGINT; result, bCustomObjInfo, bPIOisNEW : BOOLEAN; PIONameh :STRING; hParm, hParmRecord, hWall : HANDLE; iNothing : LONGINT; hPick : HANDLE; px, py : REAL; p1x, p1y, vAREA : REAL; bPick : BOOLEAN; PROCEDURE ResetEvent; {$INCLUDE \Vectorscript Scripts\PIO Codes\trigFunctions.vss} {$INCLUDE \Vectorscript Scripts\PIO Codes\CustRect01.vss} BEGIN IF bCustomObjInfo THEN BEGIN CustomRect(5mm, 5mm, -5mm/2,-5mm/2); Locus(0,0); {ResetObject(hParm);} END; END; BEGIN bCustomObjInfo := GetCustomObjectInfo(PIONameh, hParm, hParmRecord, hWall) & (hParm <> Nil); bPIOisNEW := IsNewCustomObject(PIONameh); vsoGetEventInfo(theEvent, theButton); CASE theEvent OF kObjOnInitXProp : BEGIN result := SetObjPropVS(kObjXPropHasUIOverride, TRUE); result := vsoInsertAllParams; result := vsoAppendWidget(kWidgetButton, ButtonID_1, 'Pick Object', iNothing); result := vsoAppendWidget(kWidgetButton, ButtonID_2, 'Pick Object v2', iNothing); END; kButtonOIPHit : BEGIN CASE theButton OF ButtonID_1 : BEGIN GetPt(p1x, p1y); hPick := PickObject(p1x, p1y); END; {ButtonID_2 : AlrtDialog('You Hit Button 02');} END; IF (bCustomObjInfo) & (hPick<>NIL) THEN BEGIN vAREA := ObjAreaN(hpick); SetRField(hParm,PioNameH,'Area',Concat(vAREA)); ResetObject(hParm); END; END; kResetEventID : ResetEvent; END; END; Run(EventStamp); Edited July 29, 2015 by TuiWalker Quote Link to comment
twk Posted July 29, 2015 Author Share Posted July 29, 2015 Furthermore, all works well - button works - able to pick object - able to pass Area to Parameter and store it except - the initial PickObject UI cursor comes up - im able to select an object and store its area - however if i click on an empty space on the page it resets to the previous value in the Parameter - to keep the value store I have to click on the button again and select the same object (making it work by selecting same object two times) Quote Link to comment
JBenghiat Posted July 30, 2015 Share Posted July 30, 2015 Your script works for me. The only think I can think of is that the main name of your parameter should be "area" and not your alternate name. I would also recommend placing your set field section in the button 1 case. Delete the ResetObject call in your main code. If uncommented, this could cause an endless loop. Quote Link to comment
twk Posted July 31, 2015 Author Share Posted July 31, 2015 Hmm, I've relocated the SetRFiled call, but still no luck..and removed the ResetObject call as well. What do you mean by main name of parameter? I havent set any alternate names yet.. Unless I'm misreading something. Thanks for the help though.. Here's a screencap video of whats happening.. https://vimeo.com/135019482 Quote Link to comment
Hippocode Posted July 31, 2015 Share Posted July 31, 2015 (edited) I think I know what is wrong. Your event is running twice because you don't clear your state info on resetting. You can test this easily to assign an alertbox in your event and see how much times it pops up. Add this as an theEvent case: 3: BEGIN result:= GetCustomObjectInfo(objName,objHd,objrecHd,wHd); vsoStateClear(objHd); END; Edited July 31, 2015 by hippothamus Quote Link to comment
twk Posted July 31, 2015 Author Share Posted July 31, 2015 Hi Josh, tried adding that to the end of the ResetID, still no luck. I think it's got somehting to do with the Picking Object procedure.. still testing Below is code so far Procedure EventStamp; CONST kObjOnInitXProp = 5; kResetEventID = 3; kObjXPropHasUIOverride = 8; kWidgetButton = 12; ButtonID_1 = 1331; kButtonOIPHit = 35; VAR theEvent, theButton : LONGINT; result, bCustomObjInfo, bPIOisNEW : BOOLEAN; PIONameh :STRING; hParm, hParmRecord, hWall : HANDLE; iNothing : LONGINT; hPick : HANDLE; px, py : REAL; p1x, p1y, vAREA : REAL; bPick : BOOLEAN; PROCEDURE ResetEvent; {$INCLUDE \Vectorscript Scripts\PIO Codes\trigFunctions.vss} {$INCLUDE \Vectorscript Scripts\PIO Codes\CustRect01.vss} BEGIN IF bCustomObjInfo THEN BEGIN CustomRect(5mm, 5mm, -5mm/2,-5mm/2); Locus(0,0); {ResetObject(hParm);} END; END; BEGIN bCustomObjInfo := GetCustomObjectInfo(PIONameh, hParm, hParmRecord, hWall) & (hParm <> Nil); vsoGetEventInfo(theEvent, theButton); CASE theEvent OF kObjOnInitXProp : BEGIN result := SetObjPropVS(kObjXPropHasUIOverride, TRUE); result := vsoInsertAllParams; result := vsoAppendWidget(kWidgetButton, ButtonID_1, 'Pick Object', iNothing); END; kButtonOIPHit : BEGIN CASE theButton OF ButtonID_1 : BEGIN GetPt(p1x, p1y); hPick := PickObject(p1x, p1y); IF (bCustomObjInfo) & (hPick<>NIL) THEN BEGIN vAREA := ObjAreaN(hpick); SetRField(hParm,PioNameH,'Area',Concat(vAREA)); ResetObject(hParm); END; END; END; END; kResetEventID : BEGIN ResetEvent; IF bCustomObjInfo THEN vsoStateClear(hParm); END; END; END; Run(EventStamp); Quote Link to comment
Hippocode Posted August 1, 2015 Share Posted August 1, 2015 (edited) Try rewriting it in a while loop so until the user succeeds selecting a point it will keep requesting one. Maybe that "ends" the function in a better way. This will also make sure it will only copy the area if it has a valid object. Clicking in white space would not reset the values even if the GetPt was triggered again for some reason. Edited August 1, 2015 by hippothamus Quote Link to comment
twk Posted August 2, 2015 Author Share Posted August 2, 2015 A while loop.. sorry, could you elaborate, I've managed to crash my VW multiple times trying to add a while loop (while px/py <> NIL)?? is that how? Quote Link to comment
Hippocode Posted August 2, 2015 Share Posted August 2, 2015 While your object handle is NILL. This will allow you to keep clicking until you click on a valid object. Quote Link to comment
twk Posted August 2, 2015 Author Share Posted August 2, 2015 Thanks hippothamus, It's 3am here and Im still trying to kill this bug, appreciate the help. Quote Link to comment
twk Posted August 2, 2015 Author Share Posted August 2, 2015 (edited) Hmm, ok so changing the Button_ID1 Call to this kButtonOIPHit : BEGIN CASE theButton OF ButtonID_1 : BEGIN GetPt(p1x, p1y); hPick := PickObject(p1x, p1y); WHILE hPick = NIL DO BEGIN GetPt(p1x, p1y); END; IF (bCustomObjInfo) & (hPick<>NIL) THEN BEGIN vAREA := ObjAreaN(hpick); SetRField(hParm,PioNameH,'Area',Concat(vAREA)); ResetObject(hParm); END; END; END; END; Still no luck.. on a side note, my lack of understanding of getting While loops to work in my favor may be a cause as well. Thanks in advance .. again Edited August 2, 2015 by TuiWalker Quote Link to comment
Hippocode Posted August 2, 2015 Share Posted August 2, 2015 hPick := NIL; WHILE hPick = NIL DO BEGIN GetPt(p1x, p1y); hPick := PickObject(p1x, p1y); END; Quote Link to comment
twk Posted August 2, 2015 Author Share Posted August 2, 2015 (edited) Thanks Hippothamus, I'm at a loss, its still getting reset if I select in an empty space. Here is the full code, and atached is the VSO file if that helps. Parameters are: nObjFound : STATIC TEXT sArea : STATIC TEXT sCriteria : STATIC TEXT PROCEDURE Take2; CONST kObjOnInitXProp = 5; kResetEventID = 3; kObjXPropHasUIOverride = 8; kWidgetButton = 12; ButtonID_1 = 1331; kButtonOIPHit = 35; VAR theEvent, evResult : LONGINT; result, bCustomObjInfo, bPIOisNEW : BOOLEAN; PIONameh :STRING; hParm, hParmRecord, hWall : HANDLE; iNothing : LONGINT; hPick : HANDLE; p1x, p1y : REAL; PickCriteria : DYNARRAY[] OF CHAR; PROCEDURE ResetEvent; VAR vsqrDim : REAL; bAttr : BOOLEAN; BEGIN IF bCustomObjInfo THEN BEGIN TextJust(1); CreateText(Concat(PsArea, GetPrefString(178))); Locus(0,0); SetObjectVariableBoolean (hParm,800,TRUE); {ResetObject(hParm);} END; END; BEGIN bCustomObjInfo := GetCustomObjectInfo(PIONameh, hParm, hParmRecord, hWall) & (hParm <> Nil); vsoGetEventInfo(theEvent, evResult); CASE theEvent OF kObjOnInitXProp : BEGIN result := SetObjPropVS(kObjXPropHasUIOverride, TRUE); result := vsoInsertAllParams; result := vsoAppendWidget(kWidgetButton, ButtonID_1, 'Pick Object', iNothing); END; kButtonOIPHit : BEGIN CASE evResult OF ButtonID_1 : BEGIN IF bCustomObjInfo THEN BEGIN hPick := NIL; WHILE hPick = NIL DO BEGIN GetPT(p1x, p1y); hPick := PickObject(p1x, p1y); Message(GetTypeN(hPick)); PickCriteria := Concat('T=',GetTypeN(hPick)); SetRField(hParm, PIONameh, 'sCriteria', PickCriteria); SetRField(hParm,PioNameH,'sArea',Concat(AreaN(PickCriteria))); END; ResetObject(hParm); END; END; END; END; kResetEventID : BEGIN ResetEvent; IF bCustomObjInfo THEN vsoStateClear(hParm); END; END; END; Run(Take2); The Stored parameter fields get reset if I select an empty space directly after selecting an object to query. Maybe its a bug of the PickObj function?? If someone can replicate this and let me know if it's just my machine or if they're getting the same results as I am, it would be much appreciated. Also, the VWDeveloper Wiki explains the Gtpt function like this: Procedure GetPt switches the cursor to selection mode and allows the user to select a point in a VectorWorks document. This cannot be used if there is a function anywhere in the calling chain. What does the last part mean? Have I got a function somewhere in the ?calling chain?.. Thanks in Advance Tui Edited August 2, 2015 by TuiWalker Quote Link to comment
Hippocode Posted August 3, 2015 Share Posted August 3, 2015 I've tried your plug-in and it works here. The tool ends correctly and clicking a second time will do the usal select of another object instead of running your tool another time. I tested it in VW2015 on OsX. Quote Link to comment
twk Posted August 3, 2015 Author Share Posted August 3, 2015 ..and I present to you the culprit.. Vectorworks Preferences>> Session Tab>> 'Run scripts in Developer Mode' Turning that checkbox off made it work! After all that and it was a simple check box!! Thanks sooo much hippothamus and Josh for putting up with this roundabout exercise. Tui Quote Link to comment
Hippocode Posted August 3, 2015 Share Posted August 3, 2015 Well that's a surprise Have fun with it ! You might also store the UID of each object into your stamp object. If your stamp object auto resets on printing it will be updated in case one of your linked objects changed size. Quote Link to comment
JBenghiat Posted August 3, 2015 Share Posted August 3, 2015 There is no reason that turning off developer mode should cause your issue, unless your case statement isn't set up right. I tried your vso, and it worked fine for me even in developer mode, except that the object would occasionally crash VW. A few suggestions: You shouldn't need vsoState clear, as you haven't set up your object to accept states. Before CreateText, check that Len( text ) > 0 I recommend against testing for HParm = NIL. There are some cases where you want the NIL case to be handled, like inserting the object. My guess is your issue lies with the PickObject call -- it's fairly old and may be causing a memory leak. Try the FindObjAtPt commands, which might be more stable. -Josh Quote Link to comment
twk Posted August 5, 2015 Author Share Posted August 5, 2015 Thanks for the tips Josh.. Unfortunately I am very new to implementing events. FYI, im using this method for picking object attributes (hatch/fill/etc) and getting areas based on these. It's been working for the past couple of days with no crashes, all with Developer mode off. That being said, I'd really like to set this up correctly so I don't hit any problems down the road. You mentioned I don't need vsoState clear as I haven't set up my object to accept states. So do I need to remove vsoState clear? or Make my object accept states? With regards to the hParm<>NIL, I've used that with all my PIO's, is this incorrect? I can't recall where I picked up this step, must've been during my early days of learning VS, and I've never checked or thought it was incorrect. Thanks for the info. Will be trying the FindObjAtPt command and see how that fares. Thanks again Tui Quote Link to comment
JBenghiat Posted August 5, 2015 Share Posted August 5, 2015 Thanks for the tips Josh.. Unfortunately I am very new to implementing events. FYI, im using this method for picking object attributes (hatch/fill/etc) and getting areas based on these. It's been working for the past couple of days with no crashes, all with Developer mode off. Don't spend too much time on perfection, then. I do, however, find small imperfections can suddenly make a script crash in future versions. That being said, I'd really like to set this up correctly so I don't hit any problems down the road. You mentioned I don't need vsoState clear as I haven't set up my object to accept states. So do I need to remove vsoState clear? or Make my object accept states? States will tell you why a plugin is regenerating -- move, parameter change, layer change, etc. I don't think you need any special handling in your resource event, so it's not necessary. If you were to want the object to be state aware, you would set some options in the init event and add the addState event to you event cases. With regards to the hParm<>NIL, I've used that with all my PIO's, is this incorrect? I can't recall where I picked up this step, must've been during my early days of learning VS, and I've never checked or thought it was incorrect. Thanks for the info. There are a few instances where the handle will be nil. Off the top of my head, clicking on the preferences icon in the mode bar is one of them. -Josh 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.