RhinScript HTML box question

Hi @Dale, @Clement,

Do you know any way to close the modeless html dialog from the running script and NOT manually from the dialog buttons? (for example the maybe somehow the script in HTML box to monitor for some global variable change ?)

Thanks!

–jarek

@Jarek,

it is not easy to answer without an example. If your html dialog runs with blnModal set to False, what is it’s return value while the dialog is still open ?

c.

Hi @clement,

Consider a simple example that uses html box do display non-interactive html box page, like help file text/images etc; no buttons or window returning any value. What I would like to do is while the script continues running after showing non-modal html box is to have script tell the html box modeless window to close:

Dim f : f = Rhino.OpenFileName()
Dim r : r = Rhino.HtmlBox(f,, "dialogwidth:1620px;dialogHeight:750px", False) 

Possible ?

Thanks!

–jarek

Hi @Jarek,

not sure, but you might try to put the reference to the window itself in the dialog arguments. I mean inside the OnInitDialog() function of the html page. If this works, the variable r may contain the window which you can close from the script using r.close. Note that this requires that r contains something if the dialog is modeless.

I have never tried that, but can do tonight when i have some free time.

c.

Hi Clement - I still did not wrap my head around using the html box and variables exchange. I can follow the sample from the help file but not much more… I remember a while back you shared with me much more advanced texture unwrapper script that was using html box as UI, so I am sure you have lots of experience with it.
I don’t quite follow your suggestion - whenever you have time, a sample code would be very helpful. Thanks for looking into it!

–jarek

I’ve just tried something and it looks like that a html window only has a returnValue property if it is a modal window. On a modeless dialog like the one you’re asking about, the returnValue always seems to be True or False, no matter what it is set to from within the html script code.

To prove that it will only work with a modal dialog, but fails if blnModal=False i’ve used the html code below which assigns some text to a paragraph in the html. This text can be set as a dialog argument from within the script which opens the dialog using Rhino.HtmlBox method:

<HTML id=TestDialog style="width: 200px; height: 100px">
<HEAD>
<TITLE>Title</TITLE>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub OnInitDialog()
    document.getElementById("MyTxt").innerHTML = CStr(window.dialogArguments)
    window.returnValue = "Hello, sending back"
End Sub
-->
</SCRIPT>
</HEAD>
<BODY ONLOAD="OnInitDialog()" STYLE="font-family: Arial, sans-serif">
<P ID="MyTxt">Example Text to replace</P>
</BODY>
</HTML>

Save above, eg. as TestDialog.html on your desktop, then use this script to open it:

Option Explicit

Call Main()
Sub Main()
    Dim f, txt, r

    f = "C:\Users\UserName\Desktop\TestDialog.html"
    txt = "Some example text"
    
    r = Rhino.HtmlBox(f, txt, "dialogwidth:200px;dialogHeight:50px", True)
    If IsNull(r) Then
        Rhino.Print "r is Null"
    Else
        Rhino.Print(r)
    End If
End Sub

Note that you have to change the path in the variable f so it matches you system.

Some explanation what happens: The script “communicates” with the dialog while it is opened, the text in the variable

txt = "Some example text"

is sent into the paragraph of the opened dialog once it is initialized. This happens in the OnInitDialog() function of the script section in the html file. In the same function, i assigned a window.returnValue which is essentially what the variable r in the main script receives, if a modal dialog is closed. So once you close the modal dialog, it will return the “Hello, sending back” text string.

I did this example to show how to send something from the script to the dialog and how to send somthing from the dialog back to the script once the dialog is closed.

Now, if you change blnModal to False in the main script like so:

r = Rhino.HtmlBox(f, txt, "dialogwidth:200px;dialogHeight:50px", False)

the content of the variable r is True and immediately returned while die modeless dialog is still open. This is conformal with the RhinoScript helpfile which mentions that blnModal has to be set to True to retrieve something back from the html implementation.

Well, pretty sad :frowning: in javascript for example the showModelessDialog does return the window object back, which you can easily close from the calling script or dialog.

c.

Hey Clement, thanks for the extensive test and explanation - really appreciate it. It comes to a sad end though ; )
Do you think there is a way for the script in the HTML file to run constantly and monitor some variable or ini file that can be changed from the RhinoScript that keeps running after opening the modeless dialog? If the global variables were accessible from both RhinoScript and the script in the HTML page… Just a thought but I don’t know how to execute - strange but I cannot easily find good tutorials on VBSscript usage in HTML pages…

best,

–jarek

Yes, above example only shows how send a single variable (a text string) from the main script to the dialog. But you can send arrays or even the whole RhinoScript object to the html script scope. I’ve used this extensively in my HtmlBox scripts.

Below is an example @dale gave me 10 years ago:

Option Explicit
' copyright by dale fugier
Sub Main()
  Dim obj
  On Error Resume Next
  Set obj = Rhino.GetPluginObject("RhinoScript")
  If Err Then
    MsgBox Err.Description
    Exit Sub
  End If
  Call Rhino.HtmlBox("File.html", obj, "dialogWidth:200; dialogHeight:100;", False)
End Sub
Call Main()

The only problem is see here is that while the modeless dialog is opened and is doing eg. a loop for the polling, Rhino might not really be too responsive. Best way to handle these kind of jobs is by using event listeners which partially work using Python…

c.

Hi Clement,

I finally got somewhere looking at your examples and some other stuff. Not the most elegant way but would do for now.
The key part is using window.setinterval(["routine"],[miliseconds]) inside the OnInitDialog() - it would execute the given function every specified interval, until stopped with other method or until window is closed.
So in my test example I am creating an *.ini file, passing its path to the window, and the interval-called function is checking for the file existence. Once the file is gone, the HTML window will close.

I was hoping it can be done with a global variable or some other way without a need to create the actual flag file, but it seems like the global scope of script in RhinoScript is not visible to the global scope of the HTML box script. At least I could not get it to work. Also could not get passing the RhinoScript object to work - if I could, I could just read some values from the ini file instead of creating/deleting it.

If you are interested, I am attaching the RhinoScript test file and the HTML file which is modified version of the RS Help file.
HTML_box_test.zip (1.7 KB)

EDIT: adding the code below to the html will cause the window to delete the ini file when closed, so the RhinoScript can also keep track of the window being still open or not:

Sub Window_onUnload()
		Dim filesys : Set filesys = CreateObject("Scripting.FileSystemObject") 
		if filesys.FileExists(window.dialogArguments) then filesys.DeleteFile(window.dialogArguments)
	End Sub

thanks for all your help!

–jarek

@Jarek, i now understand much better what you’re doing after looking at the example code. To get the RhinoScript object running from within the html script code, you could do this in your OnInitDialog() function:

Dim args
    Set args = window.dialogArguments
    If IsObject(args) Then
        Set Rhino = args
        Rhino.Print "RhinoScript loaded as object OK !"
    End If

Then access all Rhino methods as normal using the Rhino and dot keyword in front of the methods. I guess this works then without an ini file. Since this does not copy the script scope, you might try to set variables via document user data or user text from within your main script, when calling the dialog, send the RhinoScript objects as args, then access this from within the html script scope.

c.

@Clement,

This is pretty slick (for RhinoScript + HTML. Yes, I did see 'Python" and “10 years ago” is your previous replies :wink: )

With that workflow we can have Rhino and HTML window more aware of each other and interacting (including closing the window from Rhino or interacting with Rhino prompts from the window). Take a look at the updated version. This is exactly what I needed. Thanks!

–jarek

TestHTMLBox_v2.zip (1.7 KB)

1 Like

@Jarek,

very nice :slight_smile:

I forgot to mention that you can also pass RuntimeData to the html box. The RhinoScript helpfile has an interesting section about RuntimeData. In one of my larger projects using Rhino.HtmlBox i am passing an array containing the RhinoScript object, RuntimeData and a few other static variables.

It’s a bit painful to serialize the ordered dialog arguments in the html script section first but quite powerful…especially combined with javascript :scream:

c.

@clement,

The RuntimeData is even better/cleaner way to go in this case. Thanks for another good suggestion.
Interesting that you were able to pass RhinoScript object and other stuff to HTML window (as array?).
Anytime I tried putting RhinoScript object into array for HTML I could not get it to work in HTML.

So far I need this for rather simple thing but in future I may try more complex html dialog (and tap into your experience :wink: )

–jarek

I use this to pass an array with RhinoScript object and some settings:

Rhino.HtmlBox(strUIPath, Array(objRhinoScript, arrSettings), ... )

Then in html script section, i use this to serialize it:

Sub OnInitDialog()
    window.returnValue = Null
    Dim args, arrSettings
    args = window.dialogArguments
    If IsArray(args) Then
        If IsObject(args(0)) Then
            Set Rhino = args(0)
            arrSettings = args(1)
    Else
        MsgBox "Error obtaining RhinoScript object", 0, "Title"
        window.close
        Exit Sub
    End If
End Sub    

But i have to say that the TxTemplate plugin dialog is only a modal html window. I want to redo this using Winforms and Python for RH6 if i have some time…

c.

1 Like

Works well with the RhinoScript object passed in array in modeless window too… not sure what I did wrong before. Also, passing values via RuntimeData works and makes it even simpler… I am all set. Many thanks.

–jarek