Below is an example that demonstrates how to display/edit the application settings supported by the Face Transfer (WIP) pane for overriding which assets to load (per supported figure generation/gender) when a figure is not selected, when applying a Material(s) Preset, and/or during a save operation, via script.
The example checks for the platform being executed on, and plugin registration/activation state, to control the creation, display, and enabled state of options - in accordance with operation of the pane. The options follow a common pattern, and so each option's unique data is defined in an Object and passed to functions that use the data to construct the widgets.
// DAZ Studio version 4.22.0.9 filetype DAZ Script // Define an anonymous function; // serves as our main loop, // limits the scope of variables (function(){ // Define 'static' variables // Create an application settings object var s_oAppSettings = new DzAppSettings(); // Get the Style var s_oStyle = App.getStyle(); // Get pixel metrics from the style var s_nMargin = s_oStyle.pixelMetric( "DZ_GeneralMargin" ); var s_nButtonHeight = s_oStyle.pixelMetric( "DZ_ButtonHeight" ); /*********************************************************************/ // 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; }; /*********************************************************************/ // String : A function that constructs a native formats filter for a file dialog function getNativeFileFilter() { // Get the content manager var oContentMgr = App.getContentMgr(); // If we do not have a content manager if( !oContentMgr ){ // We are done... return ""; } // Return the constructed file filter return text( "%1 Formats" ).arg( App.appName ) + " (*." + oContentMgr.getNativeFileExtensions().join( " *." ) + ")"; }; /*********************************************************************/ // String : A function that constructs a script formats filter for a file dialog function getScriptFileFilter() { // Create a script object var oScript = new DzScript(); // Return the constructed file filter return "Daz Script" + " (*." + oScript.getScriptExtensions().join( " *." ) + ")"; }; /*********************************************************************/ // String : A function for finding a relative path for an absolute path function findRelativeContentFilePath( sAbsFilePath ) { // If the relative path is empty if( sAbsFilePath.isEmpty() ){ // We are done... return ""; } // Get the content manager var oContentMgr = App.getContentMgr(); // If we do not have a content manager if( !oContentMgr ){ // We are done... return ""; } // Get the relative path of the file var sRelFilePath = oContentMgr.getRelativePath( DzContentMgr.AllDirsAndCloud, sAbsFilePath ); // If the path is not relative if( sRelFilePath == sAbsFilePath ){ // We are done... (not mapped) return ""; } // Return the relative path return sRelFilePath; }; /*********************************************************************/ // String : A function for finding an absolute path for a relative path function findAbsContentFilePath( sRelFilePath ) { // If the relative path is empty if( sRelFilePath.isEmpty() ){ // We are done... return ""; } // Get the content manager var oContentMgr = App.getContentMgr(); // If we do not have a content manager if( !oContentMgr ){ // We are done... return ""; } // Declare working variable var sFilePath; // Initialize var bHasAllEnums = (App.version64 >= 0x000400090000002e);//4.9.0.46 var nDirType = DzContentMgr.AllDirs; // Get the import manager var oImportMgr = App.getImportMgr(); // If the file type is imported if( oImportMgr.findImporter( sRelFilePath ) ){ // If the version does not provide all enumerated values if( !bHasAllEnums ){ // Update the directory type nDirType = DzContentMgr.PoserDirs | DzContentMgr.ImportDirs | 0x20; //DzContentMgr.CloudDB // Otherwise } else { // Update the directory type nDirType = DzContentMgr.PoserDirs | DzContentMgr.ImportDirs | DzContentMgr.CloudDB; } // If the file type is native } else { // If the version does not provide all enumerated values if( !bHasAllEnums ){ // Update the directory type nDirType = DzContentMgr.NativeDirs | 0x20; //DzContentMgr.CloudDB // Otherwise } else { // Update the directory type nDirType = DzContentMgr.NativeDirs | DzContentMgr.CloudDB; } } // Return the path return oContentMgr.findFile( sRelFilePath, nDirType ); }; /*********************************************************************/ // Boolean : A function for determining whether or not a feature provided // by a plugin is enabled; i.e., the plugin is registered or within trial function isFeatureEnabled( sPlugin, bTrialEnabled ) { // Get the plugin manager var oPluginMgr = App.getPluginMgr(); // Get the plugin var oPlugin = oPluginMgr.findPlugin( sPlugin ); // If the plugin was not found if( !oPlugin ){ // We are done... return false; } // If the feature is enabled during a trial if( bTrialEnabled ){ // Return whether or not the plugin is activated return oPlugin.isActivated(); } // Return whether or not the plugin is registered return oPlugin.isRegistered(); }; /*********************************************************************/ // void : A function for responding to an asset 'browse' button being clicked; // 'this' is expected to be a DzComboEdit associated with the button function handleAssetBrowseClicked() { // Get the absolute path of the current value var sAbsFilename = findAbsContentFilePath( this.text ); // Prompt the user to select a native format file sAbsFilename = FileDialog.doFileDialog( true, text( "Select an asset" ), sAbsFilename, getNativeFileFilter() ); // If the user cancelled if( sAbsFilename.isEmpty() ){ // We are done... return; } // Get the relative filename var sRelFilename = findRelativeContentFilePath( sAbsFilename ); // If we do not have a relative filename if( sRelFilename.isEmpty() ){ // If the absolute filename cannot be found in the list; // this call is case-insensetive, so we do not need to // discretely handle paths for Daz Connect installed // assets separately from those that are not if( this.findItem( sAbsFilename ) < 0 ){ // Add the absolute filename to the list of items this.addItem( sAbsFilename ); } // Set the field to the absolute filename this.text = sAbsFilename; // We are done... return; } // If the relative filename does not start with a slash if( sRelFilename.charAt( 0 ) != "/" ){ // Prepend a slash to the relative filename sRelFilename = "/" + sRelFilename; } // If the relative filename cannot be found in the list; // this call is case-insensetive, so we do not need to // discretely handle paths for Daz Connect installed // assets separately from those that are not if( this.findItem( sRelFilename ) < 0 ){ // Add the relative filename to the list of items this.addItem( sRelFilename ); } // Set the field to the relative filename this.text = sRelFilename; }; /*********************************************************************/ // void : A function for responding to a script 'browse' button being clicked; // 'this' is expected to be a DzComboEdit associated with the button function handleScriptBrowseClicked() { // Get the absolute path of the current value var sAbsFilename = findAbsContentFilePath( this.text ); // Prompt the user to select a native format file sAbsFilename = FileDialog.doFileDialog( true, text( "Select a script" ), sAbsFilename, getScriptFileFilter() ); // If the user cancelled if( sAbsFilename.isEmpty() ){ // We are done... return; } // Get the relative filename var sRelFilename = findRelativeContentFilePath( sAbsFilename ); // If we do not have a relative filename if( sRelFilename.isEmpty() ){ // If the absolute filename cannot be found in the list; // this call is case-insensetive, so we do not need to // discretely handle paths for Daz Connect installed // assets separately from those that are not if( this.findItem( sAbsFilename ) < 0 ){ // Add the absolute filename to the list of items this.addItem( sAbsFilename ); } // Set the field to the absolute filename this.text = sAbsFilename; // We are done... return; } // If the relative filename does not start with a slash if( sRelFilename.charAt( 0 ) != "/" ){ // Prepend a slash to the relative filename sRelFilename = "/" + sRelFilename; } // If the relative filename cannot be found in the list; // this call is case-insensetive, so we do not need to // discretely handle paths for Daz Connect installed // assets separately from those that are not if( this.findItem( sRelFilename ) < 0 ){ // Add the relative filename to the list of items this.addItem( sRelFilename ); } // Set the field to the relative filename this.text = sRelFilename; }; /*********************************************************************/ // Object : A function for creating a DzComboEdit with an adjacent // browse button for choosing the path of an asset function createAssetBrowseEdit( wParent, lytGrid, nRow, sValue, sDefault ) { // Create a container widget var wContainerWgt = new DzWidget( wParent ); lytGrid.addWidget( wContainerWgt, nRow, 1 ); // Create a layout for the container var lytContainer = new DzHBoxLayout( wContainerWgt ); lytContainer.margin = s_nMargin; lytContainer.spacing = 0; // Create a combo edit for the asset path var wComboEdit = new DzComboEdit( wParent ); wComboEdit.placeholderText = text( "Provide an asset path..." ); wComboEdit.readOnly = true; if( !sDefault.isEmpty() ){ wComboEdit.addItems( [ sDefault, "-" ] ); } lytContainer.addWidget( wComboEdit ); // Create a "browse" button var wBrowseBtn = new DzPushButton( wParent ); wBrowseBtn.text = "..."; wBrowseBtn.maxWidth = s_nButtonHeight; lytContainer.addWidget( wBrowseBtn ); // Connect the clicked signal on the browse button to the // handleBrowseClicked function, with the DzComboEdit as // the 'this' object connect( wBrowseBtn, "clicked()", wComboEdit, handleAssetBrowseClicked ); // If the value is not empty if( !sValue.isEmpty() ){ // Add the value to the list, along with a separator wComboEdit.addItems( [ sValue, "-" ] ); // Set the value of the combo edit to the setting wComboEdit.text = sValue; // If the value is empty } else { // Set the value of the combo edit to the default wComboEdit.text = sDefault; } // Return an object with the widgets return { "wContainerWgt": wContainerWgt, "wComboEdit": wComboEdit, "wBrowseBtn": wBrowseBtn }; } /*********************************************************************/ // Object : A function for creating a labeled DzComboEdit with an // adjacent browse button for choosing the path of an asset function createLabeledAssetBrowseEdit( wParent, lytGrid, nRow, sLabel, sValue, sDefault ) { // Create a label for the "browse edit" var wLabel = new DzLabel( wParent ); wLabel.text = sLabel + " :"; wLabel.alignment = DzWidget.AlignRight | DzWidget.AlignVCenter; lytGrid.addWidget( wLabel, nRow, 0 ); // Create a combo edit and browse button for the asset var oWidgets = createAssetBrowseEdit( wParent, lytGrid, nRow, sValue, sDefault ); // Add the label to the widgets object oWidgets.wLabel = wLabel; // Return the created widgets return oWidgets; }; /*********************************************************************/ // Object : A function for creating a DzComboEdit with an adjacent // browse button for choosing the path of a script function createScriptBrowseEdit( wParent, lytGrid, nRow, sValue, sDefault ) { // Create a container widget var wContainerWgt = new DzWidget( wParent ); lytGrid.addWidget( wContainerWgt, nRow, 1 ); // Create a layout for the container var lytContainer = new DzHBoxLayout( wContainerWgt ); lytContainer.margin = s_nMargin; lytContainer.spacing = 0; // Create a combo edit for the script path var wComboEdit = new DzComboEdit( wParent ); wComboEdit.placeholderText = text( "Provide a script path..." ); wComboEdit.readOnly = true; if( !sDefault.isEmpty() ){ wComboEdit.addItems( [ sDefault, "-" ] ); } lytContainer.addWidget( wComboEdit ); // Create a "browse" button var wBrowseBtn = new DzPushButton( wParent ); wBrowseBtn.text = "..."; wBrowseBtn.maxWidth = s_nButtonHeight; lytContainer.addWidget( wBrowseBtn ); // Connect the clicked signal on the browse button to the // handleBrowseClicked function, with the DzComboEdit as // the 'this' object connect( wBrowseBtn, "clicked()", wComboEdit, handleScriptBrowseClicked ); // If the value is not empty if( !sValue.isEmpty() ){ // Add the value to the list, along with a separator wComboEdit.addItems( [ sValue, "-" ] ); // Set the value of the combo edit to the setting wComboEdit.text = sValue; // If the value is empty } else { // Set the value of the combo edit to the default wComboEdit.text = sDefault; } // Return an object with the widgets return { "wContainerWgt": wContainerWgt, "wComboEdit": wComboEdit, "wBrowseBtn": wBrowseBtn }; } /*********************************************************************/ // Object : A function for creating a labeled DzComboEdit with an // adjacent browse button for choosing the path of a script function createLabeledScriptBrowseEdit( wParent, lytGrid, nRow, sLabel, sValue, sDefault ) { // Create a label for the "browse edit" var wLabel = new DzLabel( wParent ); wLabel.text = sLabel + " :"; wLabel.alignment = DzWidget.AlignRight | DzWidget.AlignVCenter; lytGrid.addWidget( wLabel, nRow, 0 ); // Create a combo edit and browse button for the script var oWidgets = createScriptBrowseEdit( wParent, lytGrid, nRow, sValue, sDefault ); // Add the label to the widgets object oWidgets.wLabel = wLabel; // Return the created widgets return oWidgets; }; /*********************************************************************/ // Object : A function for creating a labeled DzComboEdit with an // adjacent browse button for choosing the path of a file function createLabeledAssetGroup( oData ) { // Get the group title var sGroupTitle = oData.sGroupTitle; // If the title has a placeholder if ( sGroupTitle.indexOf( "%1" ) > -1 ){ // Replace the placeholder with the Genesis version sGroupTitle = sGroupTitle.arg( oData.nGenesisVer ); } // Get the group help var sGroupHelp = oData.sGroupHelp; // If the group help is empty if( sGroupHelp.isEmpty() ){ // Get the group tip sGroupHelp = oData.sGroupTip; } // Create a group box var wGroupBox = new DzGroupBox( oData.wGroupParent ); wGroupBox.title = oData.sGroupTitle + oData.sGroupRequired + " :"; wGroupBox.toolTip = oData.sGroupTip; wGroupBox.whatsThis = oData.sGroupWhatsThis .arg( sGroupTitle ) .arg( sGroupHelp ); wGroupBox.enabled = oData.bGroupEnabled; // Create a grid layout for the group var lytGroup = new DzGridLayout( wGroupBox ); lytGroup.margin = s_nMargin; lytGroup.spacing = s_nMargin; // Get the number of options var nOptions = oData.aOptions.length; // Pre-size lists of widgets var aLabels = new Array( nOptions ); var aWidgets = new Array( nOptions ); // Declare working variables var oOption; var oWidgets; // Iterate over the options to create for( var i = 0; i < nOptions; i += 1 ){ // Get the 'current' option oOption = oData.aOptions[i]; // Create a labled browse edit for the option oWidgets = createLabeledAssetBrowseEdit( wGroupBox, lytGroup, i, oOption.sLabel, s_oAppSettings.getStringValue( oOption.sKey ), oOption.sDefault ); // Setup tool tips oWidgets.wLabel.toolTip = oOption.sTip; oWidgets.wComboEdit.toolTip = oOption.sTip; oWidgets.wBrowseBtn.toolTip = oOption.sBrowse; // Setup What's This? oWidgets.wLabel.whatsThis = wGroupBox.whatsThis; oWidgets.wComboEdit.whatsThis = wGroupBox.whatsThis; oWidgets.wBrowseBtn.whatsThis = wGroupBox.whatsThis; // Capture the label aLabels[i] = oWidgets.wLabel; // Capture the DzComboEdit aWidgets[i] = { "wComboEdit": oWidgets.wComboEdit, "sKey": oOption.sKey, "sDefault": oOption.sDefault }; } // Return an object with the widgets return { "wGroupBox": wGroupBox, "aLabels": aLabels, "aWidgets": aWidgets }; }; /*********************************************************************/ // void : A function for responding to a "None" item in a DzComboEdit being selected; // 'this' is expected to be the combo edit associated with the item function handleComboEditNoneItemChanged() { // Convert the arguments object into an array var aArguments = [].slice.call( arguments ); // If the value passed in is not the "None" item if( aArguments[0] != text( "None" ) ){ // We are done... return; } // Clear the text this.clearText(); }; /*********************************************************************/ // void : A function for adding a DzComboEdit menu item that causes // something other than populating with the item text to occur function addComboEditFunctionItem( wComboEdit, nIndex, sItem, bSeparator, funcCallback ) { // Declare working variable var aItems; // Initialize var nIdx = nIndex; // If the index passed in is less than the 'default' position if( nIndex < -1 ){ // Get the list of current items aItems = wComboEdit.items(); // Update our index to the 'last' position nIdx = aItems.length; } // If a separator is desired if( bSeparator ){ // Add the item and a separator to the list wComboEdit.insertItems( nIdx, [ sItem, "-" ] ); // If a separator is not desired } else { // Insert the item wComboEdit.insertItem( nIdx, sItem ); } // Connect the itemChanged signal to the callback function, // with the DzComboEdit as the 'this' object connect( wComboEdit, "itemChanged(const QString&)", wComboEdit, funcCallback ); }; /*********************************************************************/ // void : A function for setting the minimum width on a set of labels function setLabelMinimumWidths( aLabels, nWidth ) { // Declare working variable var nCurWidth; // Initialize var nMinWidth = 0; // If a width is specified if( nWidth ){ // Use the specified width nMinWidth = nWidth; // If a width is not specified } else { // Iterate over the labels for( var i = 0, n = aLabels.length; i < n; i += 1 ){ // Get the width of the current label nCurWidth = aLabels[i].width; // If the current width is larger than the captured width if( nCurWidth > nMinWidth ){ // Update the captured width nMinWidth = nCurWidth; } } } // Iterate over the labels for( var i = 0, n = aLabels.length; i < n; i += 1 ){ // Set the minimum width aLabels[i].minWidth = nMinWidth; } }; /*********************************************************************/ // void : A function for setting or removing a DzAppSettings key depending // on whether a value matches (case-insensitive) a default value function setOrRemoveStringSetting( sKey, sValue, sDefault ) { // If the value is the same as the default if( sValue.toLowerCase() == sDefault.toLowerCase() ){ // Remove the setting s_oAppSettings.removeKey( sKey ); // If the value is not the same as the default } else { // Set the setting s_oAppSettings.setStringValue( sKey, sValue ); } }; /*********************************************************************/ // void : A function for constructing/displaying a dialog function doDialog() { // Define plugin/key names var sFaceTransfer = "Face Transfer"; var sFaceTransfer2 = "Face Transfer 2"; // Define Scene Subset/Character Preset key names var sDefMaleKey = "DefaultMale"; var sDefFemaleKey = "DefaultFemale"; // Define Post Process key name var sPostProcessKey = "PostProcess"; // Define common strings var sGenesisVer = "Genesis %1"; var sLoadTitle = text( "%1 Load" ).arg( sGenesisVer ); var sMaterialTitle = text( "%1 Material" ).arg( sGenesisVer ); var sPostProcessTitle = text( "Post Process" ); var sRegRequired = text( " (registration required)" ); var sTrialRequired = text( " (trial required)" ); var sMale = text( "Male" ); var sFemale = text( "Female" ); var sScript = text( "Script" ); var sLoadAsset = "Scene Subset or Charater Preset"; var sMatAsset = "Material(s) Preset"; var sPostProcessScript = "Post Process script"; var sLoadTip = text( "The %1 to load if no %2 figure is selected" ).arg( sLoadAsset ).arg( sGenesisVer ); var sMaterialTip = text( "The %1 to apply to a %2 figure" ).arg( sMatAsset ).arg( sGenesisVer ); var sPostProcessTip = text( "The script to execute when saving a %1 figure" ).arg( sGenesisVer ); var sBrowseTip = text( "Click to browse for a %1 %2" ); var sWhatsThis = "<b>%1</b><br/><br/>%2"; var sPostProcessHelp = text( "This script is executed during a save operation - " + "after materials are applied, but before transfer data is removed and the " + "(optional) Scene Subset is saved.<br/><br/>" + "A global transient variable named <i>Figure</i>, which refers to the figure that is loaded/selected, " + "is provided to the script in the global context at runtime." ); // Create a basic dialog var wDlg = new DzBasicDialog(); var sDialogTitle = text( "%1 Assets" ).arg( sFaceTransfer ); var sDialogHelp = text( "This dialog provides access to application " + "settings used by %1 and %2" ) .arg( sFaceTransfer ) .arg( sFaceTransfer2 ); wDlg.caption = sDialogTitle; wDlg.toolTip = sDialogHelp; wDlg.whatsThis = sWhatsThis.arg( sDialogTitle ).arg( sDialogHelp ); // Get the wrapped widget var oDlgWgt = wDlg.getWidget(); // 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 tab widget var wTabWidget = new DzTabWidget( wDlg ); wDlg.addWidget( wTabWidget ); // Initialize var aLabels = []; var aFtRegOptions = []; var aFtTrialOptions = []; var bFtOverrideEnabled = false; var oData; var oOption; // ----------------------------------- // ---------- Face Transfer ---------- // ----------------------------------- // Face Transfer (1) is not available for macOS; it does not make sense // to display options that will ultimately have no impact if( App.platform() == DzApp.Windows ){ // Get whether or not overrides are enabled bFtOverrideEnabled = isFeatureEnabled( sFaceTransfer, false ); // Define common strings var sFtRegRequired = !bFtOverrideEnabled ? sRegRequired : ""; var sG8or81 = 8 + " or " + 8.1; // Navigate down a level, to settings for "Face Transfer" s_oAppSettings.pushPath( sFaceTransfer ); // Create a widget for the "Face Transfer" page var wFaceTransferPage = new DzWidget( wTabWidget ); wFaceTransferPage.toolTip = text( "This page provides access to " + "application settings for %1" ).arg( sFaceTransfer ); // Create a layout for the "Face Transfer" page var lytFtPage = new DzVBoxLayout( wFaceTransferPage ); lytFtPage.margin = s_nMargin; // ----- Genesis 8 Load // Define the configuration data for creating the group oData = {}; oData.nGenesisVer = 8; oData.sGenesisVer = sGenesisVer.arg( oData.nGenesisVer ); oData.wGroupParent = wFaceTransferPage; oData.sGroupTitle = sLoadTitle.arg( oData.nGenesisVer ); oData.sGroupTip = sLoadTip.arg( sG8or81 ); oData.sGroupWhatsThis = sWhatsThis; oData.sGroupHelp = ""; oData.sGroupRequired = sFtRegRequired; oData.bGroupEnabled = bFtOverrideEnabled; oData.aOptions = [ { "sLabel": sFemale, "sKey": sDefFemaleKey, "sDefault": "/data/Daz 3D/Genesis 8 Female Starter Essentials/Utilities/Genesis 8 Female With Basic Wear.duf", "sTip": sLoadTip.arg( sG8or81 + " " + sFemale ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( sG8or81 ) + " " + sFemale ).arg( sLoadAsset ) }, { "sLabel": sMale, "sKey": sDefMaleKey, "sDefault": "/data/Daz 3D/Genesis 8 Male Starter Essentials/Utilities/Genesis 8 Male With Basic Wear.duf", "sTip": sLoadTip.arg( sG8or81 + " " + sMale ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( sG8or81 ) + " " + sMale ).arg( sLoadAsset ) } ]; // Create the group oOption = createLabeledAssetGroup( oData ); // Add the group to the page layout lytFtPage.addWidget( oOption.wGroupBox ); // Capture the labels aLabels = aLabels.concat( oOption.aLabels ); // Capture the options aFtRegOptions = aFtRegOptions.concat( oOption.aWidgets ); // ----- Genesis 8 Material // Define the configuration data for creating the group oData = {}; oData.nGenesisVer = 8; oData.sGenesisVer = sGenesisVer.arg( oData.nGenesisVer ); oData.wGroupParent = wFaceTransferPage; oData.sGroupTitle = sMaterialTitle.arg( oData.nGenesisVer ); oData.sGroupTip = sMaterialTip.arg( oData.nGenesisVer ); oData.sGroupWhatsThis = sWhatsThis; oData.sGroupHelp = ""; oData.sGroupRequired = sFtRegRequired; oData.bGroupEnabled = bFtOverrideEnabled; oData.aOptions = [ { "sLabel": sFemale, "sKey": "Genesis8FemaleMaterial", "sDefault": "/data/DAZ 3D/Genesis 8/Female/Tools/Presets/Genesis 8 Female Simple MAT.duf", "sTip": sMaterialTip.arg( oData.nGenesisVer + " " + sFemale ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( oData.nGenesisVer ) + " " + sFemale ).arg( sMatAsset ) }, { "sLabel": sMale, "sKey": "Genesis8MaleMaterial", "sDefault": "/data/DAZ 3D/Genesis 8/Male/Tools/Presets/Genesis 8 Male Simple MAT.duf", "sTip": sMaterialTip.arg( oData.nGenesisVer + " " + sMale ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( oData.nGenesisVer ) + " " + sMale ).arg( sMatAsset ) } ]; // Create the group oOption = createLabeledAssetGroup( oData ); // Add the group to the page layout lytFtPage.addWidget( oOption.wGroupBox ); // Capture the labels aLabels = aLabels.concat( oOption.aLabels ); // Capture the options aFtRegOptions = aFtRegOptions.concat( oOption.aWidgets ); // ----- Genesis 8.1 Material // Define the configuration data for creating the group oData = {}; oData.nGenesisVer = 8.1; oData.sGenesisVer = sGenesisVer.arg( oData.nGenesisVer ); oData.wGroupParent = wFaceTransferPage; oData.sGroupTitle = sMaterialTitle.arg( oData.nGenesisVer ); oData.sGroupTip = sMaterialTip.arg( oData.nGenesisVer ); oData.sGroupWhatsThis = sWhatsThis; oData.sGroupHelp = ""; oData.sGroupRequired = sFtRegRequired; oData.bGroupEnabled = bFtOverrideEnabled; oData.aOptions = [ { "sLabel": sFemale, "sKey": "Genesis8_1FemaleMaterial", "sDefault": "/data/DAZ 3D/Genesis 8/Female 8_1/Tools/Presets/Genesis 8.1 Female Simple MAT.duf", "sTip": sMaterialTip.arg( oData.nGenesisVer + " " + sFemale ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( oData.nGenesisVer ) + " " + sFemale ).arg( sMatAsset ) }, { "sLabel": sMale, "sKey": "Genesis8_1MaleMaterial", "sDefault": "/data/DAZ 3D/Genesis 8/Male 8_1/Tools/Presets/Genesis 8.1 Male Simple MAT.duf", "sTip": sMaterialTip.arg( oData.nGenesisVer + " " + sMale ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( oData.nGenesisVer ) + " " + sMale ).arg( sMatAsset ) } ]; // Create the group oOption = createLabeledAssetGroup( oData ); // Add the group to the page layout lytFtPage.addWidget( oOption.wGroupBox ); // Capture the labels aLabels = aLabels.concat( oOption.aLabels ); // Capture the options aFtRegOptions = aFtRegOptions.concat( oOption.aWidgets ); // ----- Post Process // Get whether or not overrides are enabled var bFtPostProcessEnabled = isFeatureEnabled( sFaceTransfer, true ); var sFtTrialRequired = !bFtPostProcessEnabled ? sTrialRequired : ""; // Define the configuration data for creating the group oData = {}; oData.nGenesisVer = 8; oData.sGenesisVer = sGenesisVer.arg( oData.nGenesisVer ); oData.wGroupParent = wFaceTransferPage; oData.sGroupTitle = sPostProcessTitle; oData.sGroupTip = sPostProcessTip.arg( oData.nGenesisVer ); oData.sGroupWhatsThis = sWhatsThis; oData.sGroupHelp = sPostProcessHelp; oData.sGroupRequired = sFtTrialRequired; oData.bGroupEnabled = bFtPostProcessEnabled; oData.aOptions = [ { "sLabel": sScript, "sKey": sPostProcessKey, "sDefault": "", "sTip": sPostProcessTip.arg( oData.nGenesisVer ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( oData.nGenesisVer ) ).arg( sPostProcessScript ) } ]; // Create the group oOption = createLabeledAssetGroup( oData ); // Add the group to the page layout lytFtPage.addWidget( oOption.wGroupBox ); // Capture the labels aLabels = aLabels.concat( oOption.aLabels ); // Capture the options aFtTrialOptions = aFtTrialOptions.concat( oOption.aWidgets ); // Iterate over the Face Transfer trial options for( var i = 0, n = aFtTrialOptions.length; i < n; i += 1 ){ // Get the 'current' option oOption = aFtTrialOptions[i]; // Add a "None" (clear) item to the menu addComboEditFunctionItem( oOption.wComboEdit, -1, text( "None" ), true, handleComboEditNoneItemChanged ); } // Add stretch to keep widget layouts tight lytFtPage.addStretch( 1 ); // Add the page to the tab widget wTabWidget.addTab( wFaceTransferPage, sFaceTransfer ); // Navigate up a level, to the root of the application settings s_oAppSettings.popPath(); } // ------------------------------------- // ---------- Face Transfer 2 ---------- // ------------------------------------- // Get whether or not overrides are enabled var bFt2OverrideEnabled = isFeatureEnabled( sFaceTransfer2, false ); var sFt2RegRequired = !bFt2OverrideEnabled ? sRegRequired : ""; // Initialize var aFt2RegOptions = []; var aFt2TrialOptions = []; // Navigate down a level, to settings for "Face Transfer 2" s_oAppSettings.pushPath( sFaceTransfer2 ); // Create a widget for the "Face Transfer 2" page var wFaceTransfer2Page = new DzWidget( wTabWidget ); wFaceTransfer2Page.toolTip = text( "This page provides access to " + "application settings for %1" ).arg( sFaceTransfer2 ); // Create a layout for the "Face Transfer 2" page var lytFt2Page = new DzVBoxLayout( wFaceTransfer2Page ); lytFt2Page.margin = s_nMargin; // ----- Genesis 9 Load // Define the configuration data for creating the group oData = {}; oData.nGenesisVer = 9; oData.sGenesisVer = sGenesisVer.arg( oData.nGenesisVer ); oData.wGroupParent = wFaceTransfer2Page; oData.sGroupTitle = sLoadTitle.arg( oData.nGenesisVer ); oData.sGroupTip = sLoadTip.arg( oData.nGenesisVer ); oData.sGroupWhatsThis = sWhatsThis; oData.sGroupHelp = ""; oData.sGroupRequired = sFt2RegRequired; oData.bGroupEnabled = bFt2OverrideEnabled; oData.aOptions = [ { "sLabel": sFemale, "sKey": sDefFemaleKey, "sDefault": "/data/Daz 3D/Genesis 9 Starter Essentials/Utilities/Genesis 9 Female With Basic Wear.duf", "sTip": sLoadTip.arg( oData.nGenesisVer + " " + sFemale ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( oData.nGenesisVer ) + " " + sFemale ).arg( sLoadAsset ) }, { "sLabel": sMale, "sKey": sDefMaleKey, "sDefault": "/data/Daz 3D/Genesis 9 Starter Essentials/Utilities/Genesis 9 Male With Basic Wear.duf", "sTip": sLoadTip.arg( oData.nGenesisVer + " " + sMale ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( oData.nGenesisVer ) + " " + sMale ).arg( sLoadAsset ) } ]; // Create the group oOption = createLabeledAssetGroup( oData ); // Add the group to the page layout lytFt2Page.addWidget( oOption.wGroupBox ); // Capture the labels aLabels = aLabels.concat( oOption.aLabels ); // Capture the options aFt2RegOptions = aFtRegOptions.concat( oOption.aWidgets ); // ----- Genesis 9 Material // Define the configuration data for creating the group oData = {}; oData.nGenesisVer = 9; oData.sGenesisVer = sGenesisVer.arg( oData.nGenesisVer ); oData.wGroupParent = wFaceTransfer2Page; oData.sGroupTitle = sMaterialTitle.arg( oData.nGenesisVer ); oData.sGroupTip = sMaterialTip.arg( oData.nGenesisVer ); oData.sGroupWhatsThis = sWhatsThis; oData.sGroupHelp = ""; oData.sGroupRequired = sFt2RegRequired; oData.bGroupEnabled = bFt2OverrideEnabled; oData.aOptions = [ { "sLabel": sFemale, "sKey": "Genesis9FemaleMaterial", "sDefault": "/data/DAZ 3D/Genesis 9/Base/Tools/Presets/Genesis 9 Female Simple MAT.duf", "sTip": sMaterialTip.arg( oData.nGenesisVer + " " + sFemale ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( oData.nGenesisVer ) + " " + sFemale ).arg( sMatAsset ) }, { "sLabel": sMale, "sKey": "Genesis9MaleMaterial", "sDefault": "/data/DAZ 3D/Genesis 9/Base/Tools/Presets/Genesis 9 Male Simple MAT.duf", "sTip": sMaterialTip.arg( oData.nGenesisVer + " " + sMale ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( oData.nGenesisVer ) + " " + sMale ).arg( sMatAsset ) } ]; // Create the group oOption = createLabeledAssetGroup( oData ); // Add the group to the page layout lytFt2Page.addWidget( oOption.wGroupBox ); // Capture the labels aLabels = aLabels.concat( oOption.aLabels ); // Capture the options aFt2RegOptions = aFt2RegOptions.concat( oOption.aWidgets ); // ----- Post Process // Get whether or not overrides are enabled var bFt2PostProcessEnabled = isFeatureEnabled( sFaceTransfer2, true ); var sFt2TrialRequired = !bFt2PostProcessEnabled ? sTrialRequired : ""; // Define the configuration data for creating the group oData = {}; oData.nGenesisVer = 9; oData.sGenesisVer = sGenesisVer.arg( oData.nGenesisVer ); oData.wGroupParent = wFaceTransfer2Page; oData.sGroupTitle = sPostProcessTitle; oData.sGroupTip = sPostProcessTip.arg( oData.nGenesisVer ); oData.sGroupWhatsThis = sWhatsThis; oData.sGroupHelp = sPostProcessHelp; oData.sGroupRequired = sFt2TrialRequired; oData.bGroupEnabled = bFt2PostProcessEnabled; oData.aOptions = [ { "sLabel": sScript, "sKey": sPostProcessKey, "sDefault": "", "sTip": sPostProcessTip.arg( oData.nGenesisVer ), "sBrowse": sBrowseTip.arg( sGenesisVer.arg( oData.nGenesisVer ) ).arg( sPostProcessScript ) } ]; // Create the group oOption = createLabeledAssetGroup( oData ); // Add the group to the page layout lytFt2Page.addWidget( oOption.wGroupBox ); // Capture the labels aLabels = aLabels.concat( oOption.aLabels ); // Capture the options aFt2TrialOptions = aFt2TrialOptions.concat( oOption.aWidgets ); // Iterate over the Face Transfer 2 trial options for( var i = 0, n = aFt2TrialOptions.length; i < n; i += 1 ){ // Get the 'current' option oOption = aFt2TrialOptions[i]; // Add a "None" (clear) item to the menu addComboEditFunctionItem( oOption.wComboEdit, -1, text( "None" ), true, handleComboEditNoneItemChanged ); } // Add stretch to keep widget layouts tight lytFt2Page.addStretch( 1 ); // Add the page to the tab widget wTabWidget.addTab( wFaceTransfer2Page, sFaceTransfer2 ); // Navigate up a level, to the root of the application settings s_oAppSettings.popPath(); //-------------------------------------------- // Align all of the labels setLabelMinimumWidths( aLabels, 40 ); // Get the minimum height of the dialog var sizeHint = oDlgWgt.minimumSizeHint; var nHeight = sizeHint.height; // Set the fixed height of the dialog to the minimum wDlg.setFixedHeight( nHeight ); // Display the dialog if( wDlg.exec() ){ // Navigate down a level, to settings for "Face Transfer" s_oAppSettings.pushPath( sFaceTransfer ); // If overrides are enabled for Genesis 8 if( bFtOverrideEnabled ){ // Iterate over the Face Transfer registered options for( var i = 0, n = aFtRegOptions.length; i < n; i += 1 ){ // Get the 'current' option oOption = aFtRegOptions[i]; // Set or remove the setting depending on whether the value is the default setOrRemoveStringSetting( oOption.sKey, oOption.wComboEdit.text, oOption.sDefault ); } } // If the post processing override is enabled for Genesis 8/8.1 if( bFtPostProcessEnabled ){ // Iterate over the Face Transfer trial options for( var i = 0, n = aFtTrialOptions.length; i < n; i += 1 ){ // Get the 'current' option oOption = aFtTrialOptions[i]; // Set or remove the setting depending on whether the value is the default setOrRemoveStringSetting( oOption.sKey, oOption.wComboEdit.text, oOption.sDefault ); } } // Navigate up a level, to the root of the application settings s_oAppSettings.popPath(); // Navigate down a level, to settings for "Face Transfer 2" s_oAppSettings.pushPath( sFaceTransfer2 ); // If overrides are enabled for Genesis 9 if( bFt2OverrideEnabled ){ // Iterate over the Face Transfer 2 registered options for( var i = 0, n = aFt2RegOptions.length; i < n; i += 1 ){ // Get the 'current' option oOption = aFt2RegOptions[i]; // Set or remove the setting depending on whether the value is the default setOrRemoveStringSetting( oOption.sKey, oOption.wComboEdit.text, oOption.sDefault ); } } // If the post processing override is enabled for Genesis 9 if( bFt2PostProcessEnabled ){ // Iterate over the Face Transfer 2 trial options for( var i = 0, n = aFt2TrialOptions.length; i < n; i += 1 ){ // Get the 'current' option oOption = aFt2TrialOptions[i]; // Set or remove the setting depending on whether the value is the default setOrRemoveStringSetting( oOption.sKey, oOption.wComboEdit.text, oOption.sDefault ); } } // Navigate up a level, to the root of the application settings s_oAppSettings.popPath(); } }; /*********************************************************************/ // Display the dialog doDialog(); // Finalize the function and invoke })();