Jump to content
Developer Wiki and Function Reference Links ×

It works - but why?


Recommended Posts

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...   

Link to comment

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.

 

 

Link to comment

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);

 

Link to comment

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

Link to comment

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

Link to comment

@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.

  • Like 3
Link to comment

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...