Jump to content

Best Practices for Custom Dialog Interactions


Recommended Posts

I'm working with my first custom dialog display, and all the new stuff is clicking into place just fine, but I'm struggling to figure out the best ways of processing the interaction and not having any luck finding examples or details. Here's the example I've been playing with (might be a few oddities in the code lingering from some of the different approached I've been experimenting with). Right now this is attached to a point insert custom tool, and I'm just experimenting to get an understanding of the flow here- All I'm currently doing is building a simple popup that will show the symbols from another resource file and insert the selected symbol into the custom object. I've got Alerts tied to the dialog handler so I can see all the events that get passed around while I'm figuring this out. 

 

Where I'm struggling, is on the symbol insertion step. I'm logging the selection event just fine and getting the resource index from the Thumbnail Popup, and off this event setting a variable to the selected index, under the assumption that then when I click 'OK' it will register the 'OK' press, check that the iSymbol variable has been set and then insert it. However getting this variable passed around is proving problematic. I've tried declaring the variable both inside and outside Dialog_Handler,  each have issues and I'm frequently being told iSymbol is getting referenced before assignment. The only way I'm able to make this 'work' is to build the symbol insertion in to the selection in the pulldown but that seems messy and can insert symbols without confirming anything. 

 

This also is causing me some looping issues that I'm not clear on the cause. After confirming the symbol, the SetupDialogC event is flagged again. Not sure what that's about...

 

Also, I'm getting an item passed into the data handler as -12613. I dug around and checked the usual places, searches and the MiniCadCallBacks.h file and I can't find anything about what this flag represents. Any ideas?

 

So clearly I'm still not quite getting the full process down, any easy fixes here or examples that can clear up some of the messiness I'm encountering?

import vs

debugMode = True

btnOK = 1
btnCancel = 2
kThumbnailPopup = 101
SetupDialogC = 12255

iSymbol = -1
#bSymbol = False

def Dialog_Handler(item, data):
	#global iSymbol
	
	if debugMode:
		text = 'Running Dialog Handler. Values Returned:\r\ritem: ' + str(item) + ' | data: ' + str(data)
		vs.AlertCritical('DIALOG HANDLER', text)

	resourceType = 16
	fullPath = "../Libraries/Objects - Building Equip_Appliances/_Office Equipment.vwx"
	(symList, numItems) = vs.BuildResourceListN(resourceType, fullPath)
	# (symList, numItems) = vs.BuildResourceList2(resourceType, 0, '', False)

	if item == SetupDialogC:
		for i in range(numItems):
			name = vs.GetNameFromResourceList(symList, i)
			#if name[:7] == 'zNested':
			#	continue
			vs.InsertImagePopupResource(dialog, kThumbnailPopup, symList, i)

	if item == kThumbnailPopup:  # Interaction with Pulldown Menu
		#bSymbol = True
		iSymbol = data
		hSymbol = vs.ImportResourceToCurrentFile(symList, iSymbol)
		vs.Symbol(vs.GetName(hSymbol), (0, 0), 0)
		
		if debugMode:
			vs.AlertCritical('Clicked something in popup, setting iSymbol to: ', str(iSymbol))
		
	#if item == btnOK and bSymbol:  # OK Button Pressed and symbol has been selected
		#hSymbol = vs.ImportResourceToCurrentFile(symList, iSymbol)
		#vs.Symbol(vs.GetName(hSymbol), (0, 0), 0)
		#if debugMode:
			#vs.AlertCritical('OK BUTTON!', 'iSymbol: ' + str(iSymbol))


def CreateSampleDialog():
	global dialog
	iSymbol = None
	
	dialog = vs.CreateLayout('Add Choice Sample', 1, 'OK', 'Cancel')

	vs.CreateThumbnailPopup(dialog, kThumbnailPopup)

	vs.SetFirstLayoutItem(dialog, kThumbnailPopup)

	vs.RunLayoutDialog(dialog, Dialog_Handler)


vs.SetPref(412, True)

CreateSampleDialog()

 

 

Link to comment

Hi @AlHanson ,

   Ok, easy question first. Your unknown constant is issued when you close the Popup window.

 

const Sint32 kThumbnailPopupClose = -12613;

 

You can find it documented in: "MiniCadCallbacks.X.h", which can be found in the same directory as "MiniCadCallBacks.h".

 

As to your other issues, I'll have to play with it more to understand. Perhaps someone may beat me to it. Gotta run now. More later, if needed.

 

Raymond

 

PS - Are you getting your popup loaded? I do not see any icons, even though the file you mention is in my application folder. Also, what version of VW are you using and on what platform. A Forum signature would help.

Link to comment

@AlHanson ,

   I would have thought someone would have responded before now, but since no one has, here is my follow up. If you've already solved your problem, please read no further. Otherwise, try the following code snippet.

 

   To make your example work I had to add "1" to the value returned in the "data" variable. I did not dig deeply into this and I quit messing with it when it finally worked. You may want to examine this further. Remove the "+ 1" to see what happens with your last symbol icon. Also, I added an IF clause in your "item == SetupDialogC" code to accept the first symbol after the popup is populated. If you don't click in the popup, "bSymbol" is never set to True, which makes it kind of hard to accept the first symbol without a lot of extra clicks to change the popup selection then change it back.

 

   Word of caution – The vs.BuildResourceList() command and the other three similar calls (vs.BuildResourceList2, vs.BuildResourceListN, and vs.BuildResourceListN2) are quite persnickety. You have to guess a lot to get what you want. Read the function descriptions carefully. This example works because there is only one file in the specified subfolder. Not sure what happens if there are multiple files in the subfolder and you only want to examine one file. I'll leave that to you if it ever becomes relevant.

 

   Lastly, take note of my use of GLOBAL variables. Because the Dialog_Handler() code gets executed repeatedly when the dialog is open, any change made on one pass that is needed for future passes has got to be GLOBAL to that routine, otherwise values will be lost before the dialog finishes executing.

import vs

debugMode = False

btnOK = 1
btnCancel = 2
kThumbnailPopup = 101
SetupDialogC = 12255
LibraryFolder = -13		# "Libraries" folder in VW app folder
resourceType = 16		# Symbol Definitions

symList = 0
iSymbol = -1
bSymbol = False

def Dialog_Handler(item, data):
	global symList, iSymbol, bSymbol
	
	if debugMode:
		text = 'Running Dialog Handler. Values Returned:\r\ritem: ' + str(item) + ' | data: ' + str(data)
		vs.AlertCritical('DIALOG HANDLER', text)

	if item == SetupDialogC:
		subPath = "Objects - Building Equip_Appliances"
		(symList, numItems) = vs.BuildResourceList(resourceType, LibraryFolder, subPath)
		if (numItems > 0):		# select the first symbol in the popup
			bSymbol = True
			iSymbol = 1

		for i in range(numItems+1):
			name = vs.GetNameFromResourceList(symList, i)
			#if name[:7] == 'zNested':
			#	continue
			vs.InsertImagePopupResource(dialog, kThumbnailPopup, symList, i)

	if item == kThumbnailPopup:  # Interaction with Pulldown Menu
		bSymbol = True
		iSymbol = data + 1
		if debugMode:
			vs.AlertCritical('Clicked something in popup, setting iSymbol to: ', str(iSymbol))
		
	if (item == btnOK) and bSymbol:  # OK Button Pressed and symbol has been selected
		hSymbol = vs.ImportResourceToCurrentFile(symList, iSymbol)
		vs.Symbol(vs.GetName(hSymbol), (0, 0), 0)
		if debugMode:
			vs.AlertCritical('OK BUTTON!', 'iSymbol: ' + str(iSymbol))
	# End of Dialog_Handler


def CreateSampleDialog():
	global dialog
	
	dialog = vs.CreateLayout('Add Choice Sample', 1, 'OK', 'Cancel')

	vs.CreateThumbnailPopup(dialog, kThumbnailPopup)

	vs.SetFirstLayoutItem(dialog, kThumbnailPopup)

	vs.RunLayoutDialog(dialog, Dialog_Handler)
	# End of CreateSampleDialog


vs.SetPref(412, True)		# PersistentPythonEngine Pref

CreateSampleDialog()

 

HTH,

Raymond

 

  • Like 4
Link to comment
  • 2 weeks later...

Sorry for the long delay but I haven't been able to dig into this for a while. This is  very helpful @MullinRJ, but I'm still struggling with some looping issues. 

 

I *think* I've finally narrowed down the problem to the plug in implementation I was using while playing around. I've been playing with as a Point Object Plug In, but with this option I can go through the process of displaying the pop up, selecting from the pulldown and ok'ing the selection and everything works as intended, however it will then retrigger event 12255 and start the process all over again, including when switching over to the modified code that you've provided. If I import the script into a simple menu command script, it all functions perfectly as intended and inserts the selected symbol without issue. So in part, the struggle here is likely my sequence of events if I am to build this as an insert point object... I'll have to dive into that more since this initial pass was really just experimentation to get used to the dialog building rather than creating something specific. Insights on the loop issue would be helpful if anybody has some better understanding of this or can suggest the better approach to using a dialog like this in a point insert object. 

Link to comment

@AlHanson ,

   As you've already discovered, plug-in objects execute quite differently from menu commands. To fully appreciate what is going on behind the scene you should trap each PIO event and display it in an Alert Dialog, just like you displayed the events being presented to your Modern Dialog. In your PIO Event loop, place an Alert Dialog at the top of your event loop just after the lines that return the Custom Object Info, the Event Info, and the New Object status as shown here:

CR = chr(13)		# define Carriage Return character
NIL = vs.Handle()	# define NIL
...

# Beginning of Event Loop
(gFlag, gPIOName, ghParm, ghParmRecord, ghWall) = vs.GetCustomObjectInfo()
(gTheEvent, gMessage) = vs.vsoGetEventInfo()
gNewObj = vs.IsNewCustomObject(gPIOName)

vs.AlrtDialog(vs.Concat('Event = ', gTheEvent, CR, 'Message = ', gMessage, CR, 'New Obj = ', gNewObj, CR, 'Object Handle = ', ghParm != NIL));	

if (gTheEvent == kObjOnInitXProperties):		# kObjOnInitXProperties = 5

elif (gTheEvent == kParametricRecalculate):		# kParametricRecalculate = 3

elif ():		# etc. - other events

# End of Event Loop

 

   Also, be aware that the events your PIO will receive are subject to the flags you set with the vs.SetObjPropVS() function, usually in event kObjOnInitXProperties (5). Setting all of the relevant flags is tricky, at best. The best way to get started is to copy existing examples. Trial and error is also your friend.

 

   A list of the Plug-in Object Extended Properties descriptions can be found in this SDK file:

.../SDK/SDKVW(<VW build number>)/SDKLib/Include/Kernel/MiniCadHookIntf.h

 

HTH,

Raymond

 

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