Need Simple Menu to Enter 3 Values to be used in Existing Script

3dward3dward Posts: 32
edited September 2021 in Daz Studio Discussion

There's a script I want to add a menu to so I can enter 3 values for xyz so I don't have to edit the script every time I want to enter a new value. How would I do this? I'm not sure how to do menus. The menu needs a description string, xyz entry fields, and an ok and cancel button. If cancel is selected it quits and Daz resumes normally. If ok is selected then it needs to first run the script below, feeding the 3 values entered in the menu into xPos, yPos, and zPos. It looks like it may need to feed NAN in if 0 is written in a field based on the script code. Is the best solution to have this be one script stuck together with the menu script or separate? Below is the script that the menu should come before.

//by Room Creator
// DAZ Studio version 4.15.0.30 filetype DAZ Script

var xPos = 100;
var yPos = NAN;
var zPos = NAN;
function moveObject( object )
{
    if( object == undefined )
        return;
    if( !isNaN( xPos ) )
        object.getXPosControl().setValue( object.getXPosControl().getValue() + xPos );
    if( !isNaN( yPos ) )
        object.getYPosControl().setValue( object.getYPosControl().getValue() + yPos );
    if( !isNaN( zPos ) )
        object.getZPosControl().setValue( object.getZPosControl().getValue() + zPos );
}
beginUndo();
for( var i = 0; i < Scene.getNumSelectedNodes(); i++ )
moveObject( Scene.getSelectedNode( i ) );
acceptUndo( "Move selected object(s)" );

Post edited by 3dward on

Comments

  • Richard Haseltine said:

    Do you mean dialogue box, rather than menu? http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/general_ui/simple_dialog/start shows how to create and execute a dialogue, for numbers you would presumably want to use three http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/floatslider_dz as the active widgets

     Yeah I meant a dialog box. The DzColorWgt probably won't work for negative coordinates, or numbers beyond 255 right? The DzIntSlider does not have the number limit problems, but it appears I can't enter numbers by keyboard like I could by right clicking in the DzColorWgt. Is there anything that allows: right clicking a field to enter a number by keyboard, negative numbers, and setting the allowed range in code as well?

  • TaozTaoz Posts: 9,940
    edited September 2021

    Maybe this (or just the free QT editor that comes with DS) may help:

    https://www.daz3d.com/dialog-design

    Post edited by Taoz on
  • 3dward said:

    Richard Haseltine said:

    Do you mean dialogue box, rather than menu? http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/general_ui/simple_dialog/start shows how to create and execute a dialogue, for numbers you would presumably want to use three http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/floatslider_dz as the active widgets

     Yeah I meant a dialog box. The DzColorWgt probably won't work for negative coordinates, or numbers beyond 255 right? The DzIntSlider does not have the number limit problems, but it appears I can't enter numbers by keyboard like I could by right clicking in the DzColorWgt. Is there anything that allows: right clicking a field to enter a number by keyboard, negative numbers, and setting the allowed range in code as well?

    Replace the colour widget with three numeric sliders, one for each value - you should be able to entre values just by clicking on the current value.

  • OmnifluxOmniflux Posts: 377
    edited September 2021

    For DzFloatSlider, you need to set textEditable = true to edit the current value directly.

    Here is an example that works on a single node (Your original sample works on all selected nodes).

    (function(){	function buildSliderWidget (wDialog, oProperty)	{		var wSlider = new DzFloatSlider (wDialog);		wSlider.labelVisible = true;		wSlider.textEditable = true;		wSlider.label = oProperty.getLabel();		wSlider.sensitivity = oProperty.getSensitivity();		wSlider.clamped = oProperty.isClamped();		wSlider.max = oProperty.getMax() - oProperty.getValue();		wSlider.min = oProperty.getMin() - oProperty.getValue();				return wSlider;	}	var oNode = Scene.getPrimarySelection();	if (!oNode)		return;	var wDialog = new DzBasicDialog();	wDialog.caption = "Translate Node";	var oWidget = wDialog.getWidget();	oWidget.objectName = "%1%2".arg (wDialog.caption.replace (/ /g, '')).arg ("Dlg"); 	var aFunctions = [oNode.getXPosControl, oNode.getYPosControl, oNode.getZPosControl];	var aoSliderWidgets = aFunctions.map (function (f) { return buildSliderWidget (wDialog, f()); });	aoSliderWidgets.forEach (function (oSliderWidget) { wDialog.addWidget (oSliderWidget); });		var sizeHint = oWidget.minimumSizeHint;	wDialog.setFixedSize (sizeHint.width, sizeHint.height); 	if (wDialog.exec())	{		beginUndo();		aoSliderWidgets.forEach (function (oSliderWidget, i) { aFunctions[i]().setValue (aFunctions[i]().getValue() + oSliderWidget.value); });		acceptUndo ("Translate");	}})();

     

    Post edited by Omniflux on
  • Omniflux said:

    For DzFloatSlider, you need to set textEditable = true to edit the current value directly.

    Here is an example that works on a single node (Your original sample works on all selected nodes).

    So you can have keyboard entry with other sliders. I'm not sure exactly how I'd connect the code of the script I included (got errors trying to). The point is to relatively move all selected nodes, not just one. How would I call the first script from this one to feed the answers in, or should I stick them together as one script? 

  • OmnifluxOmniflux Posts: 377
    edited September 2021

    Here is one way of doing it that uses your existing code.

    (function(){	function moveObject( object )	{	    if( object == undefined )	        return;	    if( !isNaN( xPos ) )	        object.getXPosControl().setValue( object.getXPosControl().getValue() + xPos );	    if( !isNaN( yPos ) )	        object.getYPosControl().setValue( object.getYPosControl().getValue() + yPos );	    if( !isNaN( zPos ) )	        object.getZPosControl().setValue( object.getZPosControl().getValue() + zPos );	}	if (Scene.getPrimarySelection())	{		var wDialog = new DzBasicDialog();		wDialog.caption = "Translate Node(s)";		var oWidget = wDialog.getWidget();		oWidget.objectName = "%1%2".arg (wDialog.caption.replace (/ /g, '')).arg ("Dlg");		var wXSlider = new DzFloatSlider (wDialog);		wXSlider.labelVisible = true;		wXSlider.textEditable = true;		wXSlider.label = "X Translate";		wDialog.addWidget (wXSlider);		var wYSlider = new DzFloatSlider (wDialog);		wYSlider.labelVisible = true;		wYSlider.textEditable = true;		wYSlider.label = "Y Translate";		wDialog.addWidget (wYSlider);		var wZSlider = new DzFloatSlider (wDialog);		wZSlider.labelVisible = true;		wZSlider.textEditable = true;		wZSlider.label = "Z Translate";		wDialog.addWidget (wZSlider);		var sizeHint = oWidget.minimumSizeHint;		wDialog.setFixedSize (sizeHint.width, sizeHint.height);		if (wDialog.exec())		{			xPos = wXSlider.value;			yPos = wYSlider.value;			zPos = wZSlider.value;			beginUndo();			for( var i = 0; i &lt; Scene.getNumSelectedNodes(); i++ )				moveObject( Scene.getSelectedNode( i ) );			acceptUndo( "Move selected object(s)" );		}	}})();

    Note that all the if checks in the moveObject function are unneccessary in this case, as object is guaranteed to be defined and xPos, yPos, and zPos are guaranteed to be valid numbers.

    Post edited by Omniflux on
  • And finally, here is how I would write this starting from nothing - it is functionally equivalent to the above but without the code duplication.

    // DAZ Studio version 4.15.0.30 filetype DAZ Script(function(){	if (Scene.getNumSelectedNodes() &gt; 0)	{		var wDialog = new DzBasicDialog();		wDialog.caption = qsTr ("Translate Node(s)");		var oWidget = wDialog.getWidget();		oWidget.objectName = "%1%2".arg (wDialog.caption.replace (/ /g, '')).arg ("Dlg");		var asSliderLabels = [qsTr ("X Translate"), qsTr ("Y Translate"), qsTr ("Z Translate")];		var awSliders = asSliderLabels.map (function (sLabel) {			var wSlider = new DzFloatSlider (wDialog);			wSlider.labelVisible = true;			wSlider.textEditable = true;			wSlider.label = sLabel;			wDialog.addWidget (wSlider);			return wSlider;		});		var sizeHint = oWidget.minimumSizeHint;		wDialog.setFixedSize (sizeHint.width, sizeHint.height);		if (wDialog.exec())		{			beginUndo();			Scene.getSelectedNodeList().forEach (function (oNode) {				aoProperties = [oNode.getXPosControl, oNode.getYPosControl, oNode.getZPosControl];				aoProperties.forEach (function (oProperty, i) { oProperty().setValue (oProperty().getValue() + awSliders[i].value) });			});			acceptUndo (wDialog.caption);		}	}})();

     

  • Omniflux said:

    And finally, here is how I would write this starting from nothing - it is functionally equivalent to the above but without the code duplication.

    Thanks for your help!

Sign In or Register to comment.