MaxStudio Posted February 12, 2013 Share Posted February 12, 2013 I would like to create a button in the object info pallette that allows me to flip an object exactly how it works with the vectoworks door object. Is this possible? I don't need to the code to make the object flip. I just need to know if there is a way to create the button. I don't think I overlooked it in the parameter list. Quote Link to comment
JBenghiat Posted February 12, 2013 Share Posted February 12, 2013 Yes, it's possible but it requires an event enabled PIO and hard-coding the button into the OIP. Perhaps start with this link, and search the forum archived for some of the terms. http://developer.vectorworks.net/index.php?title=VS:vsoAppendWidget If the PIO is for your own use, you can always have a checkbox that un-checks itself when clicked. Not elegant UI, but it will quickly give you the functionality you want. -Josh Quote Link to comment
MaxStudio Posted February 13, 2013 Author Share Posted February 13, 2013 Using the link you provided and example 3 I was able to get the button to be created. I started doing a few test to see if I could get the square object to change size when the button is clicked. I changed the second x coordinate in the rect (0, 0, 1, 1) to an 'x' variable. x:=1; rect(0,0,x,1) when the button is clicked: x:=x+12; Unfortunately, I'm not having any luck. I'm not sure if i'm putting my variables in the right places. Below is the original code. Any ideas where I should insert the x:=x=12;? PROCEDURE Example3; CONST kObjOnInitXProperties = 5; kResetEventID = 3; kObjXPropHasUIOverride = 8; kWidgetButton = 12; kObjOnObjectUIButtonHit = 35; buttonID_1 = 1234; {user-definable index} VAR theEvent, theButton :LONGINT; result :BOOLEAN; sourceFieldNumber :INTEGER; buttonEventID :INTEGER; displayString :STRING; thisDoesNothing :LONGINT; x:REAL BEGIN { This is where I placed x:=1; } vsoGetEventInfo(theEvent, theButton); CASE theEvent OF {User has single-clicked the objects icon.} kObjOnInitXProperties: BEGIN {This tells VW to let the object decide what goes onto the Object Info palette.} result := SetObjPropVS(kObjXPropHasUIOverride, TRUE); {Now we manually add the "normal" parameters...} {One way is to use this single call to add all of the existing parameters.} result := vsoInsertAllParams; {Finally, we add the button.} displayString := 'My Great Button'; result := vsoAppendWidget(kWidgetButton, buttonID_1, displayString, thisDoesNothing); END; {User has clicked a button in the Object Info palette.} kObjOnObjectUIButtonHit: BEGIN CASE theButton OF buttonID_1: BEGIN AlrtDialog('Custom Button Dialog'); { I thought I could place the x:=x+12; here, but it didn't seem to do anything} END; END; END; {Object reset has been called.} kResetEventID: BEGIN Rect(0, 0, 1, 1); END; END; END; Run(Example3); Any thoughts? Quote Link to comment
JBenghiat Posted February 13, 2013 Share Posted February 13, 2013 Each event gets run one at a time. In other words, when a button push event runs, the entire script runs, executing only the button case. When the object regens, only the regen case runs. You need to use the object's parameters to pass variables from one regen to the next. In your example, add a distance parameter, x. Add a GetCustomObjectInfo call to get a handle to the PIO and the name of the record (the same as the name of the PIO). Initialize x with x=Px. Use SetRField to store the x value. The field name would just be "x" not "Px". Because SetRfield accepts strings, use Num2StrF to coerce x into a dimension string. A button push will not automatically regen the object, so add ResetObject to the button event. In reset event code use Px instead of x. (or initialize x as part of the reset event as well) -Josh Quote Link to comment
MaxStudio Posted February 13, 2013 Author Share Posted February 13, 2013 (edited) Ok, so it draws the rectangle but when i click the button it changes the new width of the rectangle to 12 instead of adding the 12 to the original x. I know i'm doing something wrong just not sure what. PROCEDURE Example3; CONST kObjOnInitXProperties = 5; kResetEventID = 3; kObjXPropHasUIOverride = 8; kWidgetButton = 12; kObjOnObjectUIButtonHit = 35; buttonID_1 = 1234; {user-definable index} VAR theEvent, theButton :LONGINT; result :BOOLEAN; sourceFieldNumber :INTEGER; buttonEventID :INTEGER; displayString :STRING; thisDoesNothing :LONGINT; x,b,d:REAL; a,c:STRING; result2 :BOOLEAN; objname :STRING; oh,rh,wh :HANDLE; BEGIN { retrieve custom object information } result2:= GetCustomObjectInfo(objname,oh,rh,wh); { if object information was successfully retrieved } IF result2 THEN BEGIN { retrieve parameters } x := Px; b:=0; END; BEGIN vsoGetEventInfo(theEvent, theButton); CASE theEvent OF {User has single-clicked the objects icon.} kObjOnInitXProperties: BEGIN {This tells VW to let the object decide what goes onto the Object Info palette.} result := SetObjPropVS(kObjXPropHasUIOverride, TRUE); {Now we manually add the "normal" parameters...} {One way is to use this single call to add all of the existing parameters.} result := vsoInsertAllParams; {Finally, we add the button.} displayString := 'My Great Button'; result := vsoAppendWidget(kWidgetButton, buttonID_1, displayString, thisDoesNothing); END; {User has clicked a button in the Object Info palette.} kObjOnObjectUIButtonHit: BEGIN CASE theButton OF buttonID_1: BEGIN AlrtDialog('Custom Button Dialog'); b:=b+12; a:=Num2StrF(b); SetRField(oh,objname,'x',a); ResetObject(oh); END; END; END; {Object reset has been called.} kResetEventID: BEGIN x:=Px; c:=GetRField(oh,'x',a); b:=Str2Num(c); d:=b+x; Rect(0, 0, d, 1); END; END; END; END; Run(Example3); Edited February 13, 2013 by MaxStudio Quote Link to comment
JBenghiat Posted February 13, 2013 Share Posted February 13, 2013 You're over-complicating a bit. You're setting b to 0, so b:=b+12 will always be 12. You don't need b -- just use x. Px is the same as GetRField(oh, obname, 'x') (also note the corrected syntax). Just use x:=Px. c, a, b, and d are all unnecessary in your reset code. Think of the case statements this way -- cover up the case statements that aren't executed for each event. The variable values should still produce the desired effects. When you handle a button press, the entire script will run twice, resetting the variables to their defaults, once for the button handler, and once for the reset handler. Here is your code stripped down to the essentials. -Josh PROCEDURE Example3; CONST kObjOnInitXProperties = 5; kResetEventID = 3; kObjXPropHasUIOverride = 8; kWidgetButton = 12; kObjOnObjectUIButtonHit = 35; buttonID_1 = 1234; {user-definable index} VAR theEvent, theButton :LONGINT; result :BOOLEAN; buttonEventID :INTEGER; displayString :STRING; thisDoesNothing :LONGINT; x:REAL; objname :STRING; oh,rh,wh :HANDLE; BEGIN { retrieve custom object information } IF GetCustomObjectInfo(objname,oh,rh,wh) THEN BEGIN { retrieve parameters } x:=Px; vsoGetEventInfo(theEvent, theButton); CASE theEvent OF {User has single-clicked the objects icon.} kObjOnInitXProperties: BEGIN {This tells VW to let the object decide what goes onto the Object Info palette.} result := SetObjPropVS(kObjXPropHasUIOverride, TRUE); {Now we manually add the "normal" parameters...} {One way is to use this single call to add all of the existing parameters.} result := vsoInsertAllParams; {Finally, we add the button.} displayString := 'My Great Button'; result := vsoAppendWidget(kWidgetButton, buttonID_1, displayString, thisDoesNothing); END; {User has clicked a button in the Object Info palette.} kObjOnObjectUIButtonHit: BEGIN CASE theButton OF buttonID_1: BEGIN AlrtDialog('Custom Button Dialog'); x:=x+12; SetRField(oh,objname,'x',Num2StrF(x)); ResetObject(oh); END; END; END; {Object reset has been called.} kResetEventID: BEGIN Rect(0, 0, x, 1); END; END; {event Case} END; { if object information was successfully retrieved } END; Run(Example3); Quote Link to comment
Dieter @ DWorks Posted February 13, 2013 Share Posted February 13, 2013 In the part of code for the button event, you have b := b + 12; b will be 0 because you didn't set a value for it. You need to change this to b := Px + 12; to get the original value with an added 12 units. PS: Be aware that when you type +12 in your script, VW will add 12 units, so if the document is in mm it will add 12mm, if it is in cm it will add 12cm. If you do not want this, then add the symbol for the units like + 12cm for example to always add 12cm, no matter what the document units are. Quote Link to comment
MaxStudio Posted February 13, 2013 Author Share Posted February 13, 2013 perfect that worked! Thanks DWorks! Quote Link to comment
MaxStudio Posted February 13, 2013 Author Share Posted February 13, 2013 Ok, so in the last example i was able to get the rectangle to grow 12" everytime I clicked the button. In this next example I want the rectangle to rotate. Each time I click the button I want the rotation to be assigned a new value via the CASE OF. What I want to happen: 1. rectangle is created (click is set to 1, rotation set to 0) 2. button pressed (click does not = 4, becomes click + 1, click becomes 2, rotation set to 15) 3. button pressed again (click does not = 4, becomes click + 1, click becomes 3, rotation set to 30) 3. button pressed again (click does not = 4, becomes click + 1, click becomes 4, rotation set to 45) 4. button pressed again (click does = 4, click becomes 1, rotation set to 0) It draws the rectangle, but it's not rotating. I know I'm doing something wrong any ideas on this one? PROCEDURE Example3; CONST kObjOnInitXProperties = 5; kResetEventID = 3; kObjXPropHasUIOverride = 8; kWidgetButton = 12; kObjOnObjectUIButtonHit = 35; buttonID_1 = 1234; {user-definable index} VAR theEvent, theButton :LONGINT; result :BOOLEAN; sourceFieldNumber :INTEGER; buttonEventID :INTEGER; displayString :STRING; thisDoesNothing :LONGINT; x,y,w,h,rotate:REAL; click:LONGINT; f:STRING; H1:HANDLE; result2 :BOOLEAN; objname :STRING; oh,rh,wh :HANDLE; BEGIN { retrieve custom object information } result2:= GetCustomObjectInfo(objname,oh,rh,wh); { if object information was successfully retrieved } IF result2 THEN BEGIN { retrieve parameters } w := Pw; h := Ph; click:=1; f:=Num2Str(0,click); SetRField(oh,objname,'click',f); END; BEGIN vsoGetEventInfo(theEvent, theButton); CASE theEvent OF {User has single-clicked the objects icon.} kObjOnInitXProperties: BEGIN {This tells VW to let the object decide what goes onto the Object Info palette.} result := SetObjPropVS(kObjXPropHasUIOverride, TRUE); {Now we manually add the "normal" parameters...} {One way is to use this single call to add all of the existing parameters.} result := vsoInsertAllParams; {Finally, we add the button.} displayString := 'My Great Button'; result := vsoAppendWidget(kWidgetButton, buttonID_1, displayString, thisDoesNothing); END; {User has clicked a button in the Object Info palette.} kObjOnObjectUIButtonHit: BEGIN CASE theButton OF buttonID_1: BEGIN f:=GetRField(oh,'click',f); click:=Str2Num(f); IF (click=4) THEN BEGIN click:=1; f:=Num2Str(0,click); SetRField(oh,objname,'click',f); END ELSE BEGIN click:=click+1; f:=Num2Str(0,click); SetRField(oh,objname,'click',f); END; ResetObject(oh); SysBeep; END; END; END; {Object reset has been called.} kResetEventID: BEGIN CASE click OF 1: BEGIN rotate:=0; END; 2: BEGIN rotate:=15; END; 3: BEGIN rotate:=30; END; 4: BEGIN rotate:=45; END; END; Rect(x, y, x+w, y+h); H1:=LNewObj; HRotate(H1,x,y,rotate); END; END; END; END; Run(Example3); Quote Link to comment
Dieter @ DWorks Posted February 14, 2013 Share Posted February 14, 2013 You Always set the click to 1 in the retrieve parameters section. So click will be Always 1! Quote Link to comment
MaxStudio Posted February 14, 2013 Author Share Posted February 14, 2013 but even if I remove click:=1; from the retrieve parameter section nothing seems to change; the object still does not rotate. if I change click:=1; to click:=2; it draws the rectangle then rotates it 15 degrees, but the button does not do anything. This leads me to believe something is wrong with the way I'm setting or getting the field, or something is coded incorrectly in the CASE theButton OF buttonID_1: section ... Quote Link to comment
Dieter @ DWorks Posted February 14, 2013 Share Posted February 14, 2013 In your reset object part, you never get the click parameter, so that will be 0 and no case will be taken. Quote Link to comment
MaxStudio Posted February 14, 2013 Author Share Posted February 14, 2013 ok, but i don't want click to be an invisible parameter that does not show in the OIP. so here's a silly question... how do I retrieve this invisible parameter? Quote Link to comment
Dieter @ DWorks Posted February 14, 2013 Share Posted February 14, 2013 your pio is event enabled, so you choose which parameters are on the oip. It doesn't matter if a parameter is on the oip or not, you can always get it with Pparameter and set it with SetRField. Quote Link to comment
Miguel Barrera Posted February 17, 2013 Share Posted February 17, 2013 You can also hide a parameter by adding a double underline to the name such as __Parameter Name and can retrieve as P__PARAMETER_NAME and if it needs to be viewed in the PIO at any time, you can set it to visible with SetParameterVisibility(pioHandle,'__Parameter Name',TRUE); Quote Link to comment
twk Posted February 10, 2014 Share Posted February 10, 2014 Hi All, I'm trying to get this to work in VW2012, however the button doesnt show up in the OIP. Anyone know why? The script compiles fine. Cheers Quote Link to comment
Vectorworks, Inc Employee klinzey Posted February 10, 2014 Vectorworks, Inc Employee Share Posted February 10, 2014 With a quick read I think the step to check the "Event-Based" option in the plug-in editor was missed. Quote Link to comment
twk Posted February 25, 2014 Share Posted February 25, 2014 Ah yes kevin.. thanks that did the trick 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.