Mike Rock Posted January 21 Share Posted January 21 I've got a bit of code that is making me scratch my head. I combined a couple examples to create a button in the Object Info Palette for a rectangle. The button triggers a color select dialog. color := ColorPopUp; {pops up a color select dialog} h := FSActLayer; {selects the rectangle created else where in the script} setclass(h,(GetClass(h))); {If this line is commented out the script doesn't work as intended} ColorIndexToRGB(color, r, g, b); {converts the value from the colorpopup function to RGB} SetFillBack(h, r, g, b); {sets the color of the rectangle} RedrawSelection; {refreshes the rectangle to show new color} As this was a mash up of a few different experiments the code was a little sloppy. Once I got the script to run and do what I wanted I went back to clean the code up. When I remove or comment out the setclass line the script stops working as I want it to. With the line commented out the color in the attribute palette changes to match the selection but the rectangle does note change. If I click on the Attribute Palette and select solid for the fill it ' pushes' the color to the rectangle. Changing the line type also 'pushes' the color. Any idea what is going on here and why setclass seems to the the fix? Surely there is a cleaner way... Quote Link to comment
Pat Stanford Posted January 21 Share Posted January 21 Guesses here. I have not tried the code. And it is always hard to debug a code snippet as often the problem is not where you think it is. Is the SetClass call setting the attributes of the object to be ByClass so you are actually not getting the color you picked, but rather the Class Color? Also, I can never remember if you need to use FillFore or FillBack without trying them both. Quote Link to comment
Mike Rock Posted January 22 Author Share Posted January 22 Here is the rest of code, for the 'real' script I do want to set to object to a specific class so I can use the code as is. I was just trying to understand what effect the setclass call was having on the code to make it work... 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,dialog1 :INTEGER; buttonEventID, color :INTEGER; displayString :STRING; thisDoesNothing, r, g, b :LONGINT; H :Handle; FUNCTION ColorPopUp :Integer; VAR dialog1, result :INTEGER; PROCEDURE Dialog_Handler(VAR item :LONGINT; data :LONGINT); BEGIN CASE item OF SetupDialogC: BEGIN SetColorChoice(dialog1, 4, 1242); END; 1: BEGIN GetColorChoice(dialog1, 4, result); ColorPopUp := result; END; END; END; BEGIN dialog1 := CreateLayout('Example Dialog', FALSE, 'OK', 'Cancel'); CreateColorPopup(dialog1, 4, 24); SetFirstLayoutItem(dialog1, 4); result := RunLayoutDialog(dialog1, Dialog_Handler); END; BEGIN vsoGetEventInfo(theEvent, theButton); CASE theEvent OF {User has single-clicked the object's 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; {Alternatively, you can use this to tack individual parameters onto the end of the list one at a time. This way, you don't have to use SetParameterVisibility in the reset event to hide parameters that you never want to see.} sourceFieldNumber := 1; displayString := 'My Great Field Name'; result := vsoAppendParamWidget(sourceFieldNumber, displayString, thisDoesNothing); {Finally, we add the button.} displayString := 'Color Select'; 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 color := ColorPopUp; {pops up a color select dialog} h := FSActLayer; {selects the rectangle created else where in the script} setclass(h, 'None'); {If this line is commented out the script doesn't work as intended} ColorIndexToRGB(color, r, g, b); {converts the value from the colorpopup function to RGB} SetFillback(h, r, g, b); {sets the color of the rectangle} RedrawSelection; {refreshes the rectangle to show new color} END; END; END; {Object reset has been called.} kResetEventID: BEGIN Rect(0, 0, 1, 1); END; END; END; RUN(Example3); Quote Link to comment
MullinRJ Posted January 22 Share Posted January 22 Hello, @Mike Rock. Try the following and see how far it gets you. I made some changes, all noted with "***", in your code, but I did not test it in a plug-in. One significant change involves your line H := FSActLayer;. I replaced FSActLayer, which only works on Drawing Layers, and replaced it with "PIOHand", a handle to the object you're trying to build. "PIOHand" is returned from a call to GetCustomObjectInfo(). See notes in your script where I made edits. Good luck, and write back with your next question. Oh, I also changed some indentation, and added comments to help read the code. I find is very helpful to comment the END statements to reference what they are ending. This can save LOTS of time when making future edits. PROCEDURE Example3; CONST kObjOnInitXProperties = 5; kResetEventID = 3; kObjXPropHasUIOverride = 8; kWidgetButton = 12; kObjOnObjectUIButtonHit = 35; buttonID_1 = 1234; {user-definable index} VAR PIOName :STRING; {*** ADD THIS LINE ***} PIOHand, recHand, wallHand :HANDLE; {*** ADD THIS LINE ***} theEvent, theButton :LONGINT; result :BOOLEAN; sourceFieldNumber,dialog1 :INTEGER; buttonEventID, color :INTEGER; displayString :STRING; thisDoesNothing, r, g, b :LONGINT; H :Handle; FUNCTION ColorPopUp :Integer; VAR dialog1, result :INTEGER; PROCEDURE Dialog_Handler(VAR item :LONGINT; data :LONGINT); BEGIN CASE item OF SetupDialogC: BEGIN SetColorChoice(dialog1, 4, 1242); END; { SetupDialogC } 1: BEGIN GetColorChoice(dialog1, 4, result); ColorPopUp := result; END; { 1 } END; { CASE item } END; { Dialog_Handler } BEGIN { ColorPopUp } dialog1 := CreateLayout('Example Dialog', FALSE, 'OK', 'Cancel'); CreateColorPopup(dialog1, 4, 24); SetFirstLayoutItem(dialog1, 4); result := RunLayoutDialog(dialog1, Dialog_Handler); END; { ColorPopUp } BEGIN { MAIN } result := GetCustomObjectInfo(PIOName, PIOHand, recHand, wallHand); {*** ADD THIS LINE ***} vsoGetEventInfo(theEvent, theButton); CASE theEvent OF {User has single-clicked the object's 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; {Alternatively, you can use this to tack individual parameters onto the end of the list one at a time. This way, you don't have to use SetParameterVisibility in the reset event to hide parameters that you never want to see.} sourceFieldNumber := 1; displayString := 'My Great Field Name'; result := vsoAppendParamWidget(sourceFieldNumber, displayString, thisDoesNothing); {Finally, we add the button.} displayString := 'Color Select'; result := vsoAppendWidget(kWidgetButton, buttonID_1, displayString, thisDoesNothing); END; { kObjOnInitXProperties } {User has clicked a button in the Object Info palette.} kObjOnObjectUIButtonHit: BEGIN CASE theButton OF buttonID_1: BEGIN color := ColorPopUp; {pops up a color select dialog} {*** remove following line. FSActLayer does not work inside PIOs as expected. ***} { h := FSActLayer; } {selects the rectangle created else where in the script} {*** change H to PIOHand ***} SetClass(PIOHand, 'None'); {If this line is commented out the script doesn't work as intended} ColorIndexToRGB(color, r, g, b); {converts the value from the colorpopup function to RGB} SetFillback(h, r, g, b); {sets the color of the rectangle} RedrawSelection; {refreshes the rectangle to show new color} END; { buttonID_1 } END; { CASE theButton } END; { kObjOnObjectUIButtonHit } {Object reset has been called.} kResetEventID: BEGIN Rect(0, 0, 1, 1); END; { kResetEventID } END; { CASE theEvent } END; { MAIN } RUN(Example3); HTH, Raymond Quote Link to comment
Mike Rock Posted January 22 Author Share Posted January 22 Hi @MullinRJ Thanks for cleaning up the code. I had to change the line SetFillback(h, r, g, b); to SetFillback(PIOHand, r, g, b); to reflect the new handle name used in your update. After that the code ran correctly. However it still requires the setclass line to work as intended. I can move to after the setfill line and it still works. If I comment it out completely I'm back the earlier issue of the color changing in the attribute palette for the rectangle but the rectangle color doesn't update until some action (clicking on solid fill, changing the line weight, manually assigning it to a new class) (What doesn't work - -changing views, moving or rotating the object) 'pushes' the new color to it. For now I'm happy to keep the setclass line in there as a work around if the proper solution isn't apparent. If the issue is tied to something bigger I'll cross that bridge when I come to it. Thanks again. Mike Quote Link to comment
Jesse Cogswell Posted January 22 Share Posted January 22 @Mike Rock Taking a quick glance at your code and based on what you just posted above, the thing you are missing is a ResetObject function after your SetFillBack functions. You have RedrawSelection, but the object hasn't been properly reset, so the change doesn't update. The reason it works with SetClass, is that you are telling VW to change the class of the object (even though it's to the same class), which forces a reset. 3 Quote Link to comment
Mike Rock Posted January 22 Author Share Posted January 22 Thanks @Jesse Cogswell - that was the solution and explanation I was hoping for. 1 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.