Below is an example demonstrating how to construct a simple dialog with a button, name it so its position is stored uniquely from other script constructed dialogs, and react to a user clicking the button by presenting a popup menu.
// DAZ Studio version 4.15.0.16 filetype DAZ Script // Define an anonymous function; // serves as our main loop, // limits the scope of variables (function(){ // Initialize 'static' variable var s_wMenuClicked = null; /*********************************************************************/ // String : A function for retrieving a translation if one exists function text( sText ) { // If the version of the application supports qsTr() if( typeof( qsTr ) != "undefined" ){ // Return the translated (if any) text return qsTr( sText ); } // Return the original text return sText; }; /*********************************************************************/ // Point : A function for getting the global cursor position function globalCursorPos() { // Return the global cursor position return (new Point).cursorPos(); }; /*********************************************************************/ // void : A function for creating a popup menu function addPopupMenu( wParent ) { // Return a popup menu return new DzPopupMenu( wParent ); }; /*********************************************************************/ // Number : A function for creating a popup menu item function addPopupMenuItem( wMenu, pixIcon, sText, nId, nIndex ) { // If a menu was not provided if( !wMenu ){ // Return invalid return -1; } // If text was not provided or is the wrong type if( typeof( sText ) != "string" ){ // Initialize sText = ""; } // If an id was not provided or is the wrong type if( typeof( nId ) != "number" ){ // Initialize nId = -1; } // If an index was not provided or is the wrong type if( typeof( nIndex ) != "number" ){ // Initialize nIndex = -1; } // Get whether or not we are using deprecated API - < 4.15.0.16 var bDeprecated = typeof( wMenu.insertTextItem ) != "function"; // If we have a pixmap, and we have text, and we are not using deprecated API if( pixIcon && !sText.isEmpty() && !bDeprecated ){ // Insert the item and return the id return wMenu.insertItem( pixIcon, sText, nId, nIndex ); // If we do not have a pixmap, but we have text } else if( !pixIcon && !sText.isEmpty() ){ // If we are not using deprecated API if( !bDeprecated ){ // Insert the item and return the id return wMenu.insertTextItem( sText, nId, nIndex ); // If we are using deprecated API } else { // Insert the item and return the id return wMenu.insertItem( sText, nId, nIndex ); } // If we have a pixmap, but we do not have text } else if( pixIcon && sText.isEmpty() ){ // If we are not using deprecated API if( !bDeprecated ){ // Insert the item and return the id return wMenu.insertPixmapItem( pixIcon, nId, nIndex ); // If we are using deprecated API } else { // Insert the item and return the id return wMenu.insertItem( pixIcon, nId, nIndex ); } } // Return an invalid id return -1; }; /*********************************************************************/ // Object<id,widget> : A function for creating a submenu on a popup menu function addPopupSubMenu( wMenu, pixIcon, sText, nId, nIndex ) { // If a menu was not provided if( !wMenu ){ // Return invalid return { "id": -1, "widget": null }; } // If text was not provided or is the wrong type if( typeof( sText ) != "string" ){ // Initialize sText = ""; } // If an id was not provided or is the wrong type if( typeof( nId ) != "number" ){ // Initialize nId = -1; } // If an index was not provided or is the wrong type if( typeof( nIndex ) != "number" ){ // Initialize nIndex = -1; } // Declare working variables var wSubMenu; var oSubMenu; // If executed in 4.22.1.149 or newer if( App.version64 >= 0x0004001600010095 ){ // Create a submenu wSubMenu = addPopupMenu( wMenu ); // Use the DzPopupMenu oSubMenu = wSubMenu; // If executed in 4.15.0.16 or newer } else if( typeof( wMenu.insertTextSubmenuItem ) == "function" ) { // Create a submenu wSubMenu = addPopupMenu( wMenu ); // Use the QMenu wrapped by DzPopupMenu oSubMenu = wSubMenu.getWidget(); } // Initialize var nMenuId = -1; // If we have a submenu if( wSubMenu && oSubMenu ){ // If we have a pixmap, and we have text if( pixIcon && !sText.isEmpty() ){ // Insert the submenu, capture the id nMenuId = wMenu.insertSubmenuItem( pixIcon, sText, oSubMenu, nId, nIndex ); // If we do not have a pixmap, but we have text } else if( !pixIcon && !sText.isEmpty() ){ // Insert the submenu, capture the id nMenuId = wMenu.insertTextSubmenuItem( sText, oSubMenu, nId, nIndex ); // If we have a pixmap, but we do not have text } else if( pixIcon && sText.isEmpty() ){ // Insert the submenu, capture the id nMenuId = wMenu.insertPixmapSubmenuItem( pixIcon, oSubMenu, nId, nIndex ); } } // Return an object with the submenu and id in the parent menu return { "id": nMenuId, "widget": wSubMenu }; }; /*********************************************************************/ // void : A function for handling a menu item being clicked; // the 'this' object is assumed to be a DzPopupMenu object function handlePopupMenuItemClicked() { // Capture the menu containing the item that was clicked s_wMenuClicked = this; }; /*********************************************************************/ // void : A function for handling the menu being requested; // the 'this' object is assumed to be a DzPushButton object function handleButtonClicked() { // Create a pixmap to use as an icon var pixNone = new Pixmap( App.getResourcesPath() + "/images/icons/whatsthissmallicon.png" ); // Create a menu var wMenu = addPopupMenu( this ); // If executed in 4.15.0.16 or newer var bCanCount = typeof( wMenu.numItems ) == "function"; // Initialize var nMenuId = -1; var nMenuIdx = bCanCount ? wMenu.numItems() : 0; // This first item demonstrates how to modify the // text and/or pixmap of an item, the creation of // other items demonstrate the typical statements // If executed in a build older than 4.15.0.16 if( typeof( wMenu.setText ) != "function" ){ // Create a pixmap item nMenuId = wMenu.insertItem( pixNone, nMenuIdx, nMenuIdx ); // Modify the text wMenu.changeItem( nMenuId, text( "<None>" ) ); // Clear the pixmap for the item wMenu.changeItem( nMenuId, null ); // If executed in 4.15.0.16 or newer } else { // Create a pixmap item nMenuId = wMenu.insertPixmapItem( pixNone, nMenuIdx, nMenuIdx ); // Modify the text wMenu.setText( nMenuId, text( "<None>" ) ); // If executed in a build older than 4.22.1.149 if( typeof( wMenu.clearPixmap ) != "function" ){ // Clear the pixmap for the item wMenu.setPixmap( nMenuId, Pixmap() ); // If executed in 4.22.1.149 or newer } else { // Clear the pixmap for the item wMenu.clearPixmap( nMenuId ); } } // If executed in 4.15.0.24 or newer var bCanConnect = typeof( wMenu.connectItem ) == "function"; // If connections are possible if( bCanConnect ){ // Connect the item to a function that handles it being activated wMenu.connectItem( nMenuId, wMenu, handlePopupMenuItemClicked ); } // Visually separate the first item from the rest nMenuId = wMenu.insertSeparator(); // Initialize var nSubMenuId = -1; var nSubMenuIdx = -1; var wSubMenu = null; // Update the menu index to the last position nMenuIdx = bCanCount ? wMenu.numItems() : nMenuIdx += 1; // Create a submenu var oSubMenu = addPopupSubMenu( wMenu, undefined, text( "Submenu 1" ), nMenuIdx, nMenuIdx ); // If a submenu was created if( oSubMenu["id"] > -1 && oSubMenu["widget"] ){ // Get the id of the menu item for the submenu nMenuId = oSubMenu["id"]; // Get the submenu widget wSubMenu = oSubMenu["widget"]; // Update the menu index to the last position nSubMenuIdx = bCanCount ? wSubMenu.numItems() : 0; // Create an item on the submenu nSubMenuId = addPopupMenuItem( wSubMenu, pixNone, text( "Sub One" ), nSubMenuIdx, nSubMenuIdx ); // If connections are possible if( bCanConnect ){ // Connect the item to a function that handles it being activated wSubMenu.connectItem( nSubMenuId, wSubMenu, handlePopupMenuItemClicked ); } // Update the menu index to the last position nSubMenuIdx = bCanCount ? wSubMenu.numItems() : nSubMenuIdx += 1; // Create an item on the submenu nSubMenuId = addPopupMenuItem( wSubMenu, pixNone, text( "Sub Two" ), nSubMenuIdx, nSubMenuIdx ); // If connections are possible if( bCanConnect ){ // Connect the item to a function that handles it being activated wSubMenu.connectItem( nSubMenuId, wSubMenu, handlePopupMenuItemClicked ); } // Update the menu index to the last position nSubMenuIdx = bCanCount ? wSubMenu.numItems() : nSubMenuIdx += 1; // Create an item on the submenu nSubMenuId = addPopupMenuItem( wSubMenu, pixNone, text( "Sub Three" ), nSubMenuIdx, nSubMenuIdx ); // If connections are possible if( bCanConnect ){ // Connect the item to a function that handles it being activated wSubMenu.connectItem( nSubMenuId, wSubMenu, handlePopupMenuItemClicked ); } // Visually separate the submenu items in the main menu from the rest nMenuId = wMenu.insertSeparator(); } // Update the menu index to the last position nMenuIdx = bCanCount ? wMenu.numItems() : nMenuIdx += 1; // Create an item on the menu nMenuId = addPopupMenuItem( wMenu, pixNone, text( "One" ), nMenuIdx, nMenuIdx ); // If connections are possible if( bCanConnect ){ // Connect the item to a function that handles it being activated wMenu.connectItem( nMenuId, wMenu, handlePopupMenuItemClicked ); } // Update the menu index to the last position nMenuIdx = bCanCount ? wMenu.numItems() : nMenuIdx += 1; // Create an item on the menu nMenuId = addPopupMenuItem( wMenu, pixNone, text( "Two" ), nMenuIdx, nMenuIdx ); // If connections are possible if( bCanConnect ){ // Connect the item to a function that handles it being activated wMenu.connectItem( nMenuId, wMenu, handlePopupMenuItemClicked ); } // Update the menu index to the last position nMenuIdx = bCanCount ? wMenu.numItems() : nMenuIdx += 1; // Create an item on the menu nMenuId = addPopupMenuItem( wMenu, pixNone, text( "Three" ), nMenuIdx, nMenuIdx ); // If connections are possible if( bCanConnect ){ // Connect the item to a function that handles it being activated wMenu.connectItem( nMenuId, wMenu, handlePopupMenuItemClicked ); } // Get the current global cursor position var pntPos = globalCursorPos(); // Define whether to use the width of the button // for the width of the main menu var bButtonWidth = false; // If we are using the width of the button if( bButtonWidth ){ // Set the width of the main menu wMenu.minWidth = this.width; } // Define whether the menu should be positioned // immediately below and adjacent to the button var bDropdown = false; // If we are positioning the menu like a dropdown if( bDropdown ){ // Set the position pntPos.y = this.globalY + this.height; pntPos.x = this.globalX; } // Declare working variable var nMenuWidth; // Define whether to use the right side of the menu // for justification/positioning var bRightJustify = false; // If we are using the right side of the menu if( bRightJustify ){ // Get the width of the main menu nMenuWidth = wMenu.getWidget().sizeHint.width; // If we are positioning the menu like a dropdown if( bDropdown ){ // Adjust the horizontal position pntPos.x += this.width - nMenuWidth; // If we are positioning the menu like a context menu } else { // Adjust the horizontal position pntPos.x -= nMenuWidth; } } // Cause the menu to display; // capture the id of the chosen item var nResultId = wMenu.exec( pntPos, 0 ); // If no menu item was chosen if( nResultId < 0 ){ // We are done... return; } // If we have a submenu, we cannot use the return value of exec() to look up // an item - the context of the value is all menus. If we do not have a // submenu, we have a simple scenario that allows us to use the return value // of exec() to look up an item - the context of the value is the menu. // If connections are possible, we have a submenu, and we know which menu has // the item that was clicked if( bCanConnect && wSubMenu && s_wMenuClicked ) { // Set the text of the button to the text of the clicked menu item this.text = s_wMenuClicked.text( nResultId ); // Set the pixmap of the button to the pixmap of the clicked menu item this.pixmap = s_wMenuClicked.pixmap( nResultId ); // If we do not have a submenu } else if( !wSubMenu ){ // Set the text of the button to the text of the clicked menu item this.text = wMenu.text( nResultId ); // Set the pixmap of the button to the pixmap of the clicked menu item this.pixmap = wMenu.pixmap( nResultId ); } }; /*********************************************************************/ // If the application version is less than 4.15.0.16 if( App.version64 < 0x0004000f00000010 ){ // We are done... return; } // Get the current style var oStyle = App.getStyle(); // Create a basic dialog var wDlg = new DzBasicDialog(); // Get the wrapped widget for the dialog var oDlgWgt = wDlg.getWidget(); // Set the title of the dialog wDlg.caption = "My Simple Test"; // Strip the space for a settings key var sKey = wDlg.caption.replace( / /g, "" ) + "Dlg"; // Set an [unique] object name on the wrapped dialog widget; // this is used for recording position and size separately // from all other [uniquely named] DzBasicDialog instances oDlgWgt.objectName = sKey; // Create a push button var wButton = new DzPushButton( wDlg ); wButton.buttonTextFormat = DzWidget.AlignLeft | DzWidget.AlignVCenter; wButton.displayDownArrow = true; wButton.text = text( "<None>" ); wButton.clicked.connect( wButton, handleButtonClicked ); // Add the widget to the dialog wDlg.addWidget( wButton ); // Get the minimum size of the dialog var sizeHint = oDlgWgt.minimumSizeHint; // Set the fixed size of the dialog wDlg.setFixedSize( sizeHint.width, sizeHint.height ); // If the user accepts the dialog if( wDlg.exec() ){ // Do... something print( "Use accepted:", wButton.text ); // If the user rejects the dialog } else { // Do... something else print( "User cancelled." ); } // Finalize the function and invoke })();