Jump to content
Developer Wiki and Function Reference Links ×

Can I create a clickable button in the object info pallette?


MaxStudio

Recommended Posts

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.

Link to comment

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

Link to comment

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?

Link to comment

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

Link to comment

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 by MaxStudio
Link to comment

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

Link to comment

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.

Link to comment

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

Link to comment

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

...

Link to comment
  • 11 months later...
  • 2 weeks later...

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