How to correctly create sub-dialogs from within dialogs?

40 views Asked by At

What's the difference for the two methods of UI initiator?

I'd like to create sub-dialog. By using the first code below, I can correctly achieve my requirement. The sub dialogue will only appear when I click the button.

But if I use the second code, which using the constructor, the sub dialogue will appear when I run the script.

What's the difference for these two method?

Also: Running the 3rd example gives me an error. Why?

Class MySub:UIFrame
{
    Object Init(Object self)
    {
        TagGroup DLGitems = DLGCreateDialog("Sub")
        TagGroup RadioList=DLGCreateRadioList()
        RadioList.DLGAddRadioItem("option 1",1)
        RadioList.DLGAddRadioItem("option 2",2)
        RadioList.DLGAddRadioItem("option 3",3)
        DLGitems.DLGAddElement(RadioList)
        Return self.super.Init(DLGitems)
    }
}
Class MyMain:UIFrame
    {
    Object SubDialog
    Void CallSubDialog(Object self)
        {
        Result("\nOpen sub-dialog.")
        SubDialog.Pose()                                // call the local object
        self.LookUpElement("Label").DLGTitle("option chosen")
        }
    Object Init(Object self, Object SDpass) 
        {
        SubDialog = SDpass                              // Keep the object in a local variabl
        TagGroup DLGitems = DLGCreateDialog("Main")
        DLGitems.DLGAddElement(DLGCreateLabel("choose option").DLGIdentifier("Label"))
        DLGitems.DLGAddElement(DLGCreatePushButton("Options","CallSubDialog"))
        Return self.super.Init(DLGitems)
        }
    }
Object SubDialogOBJ = Alloc(MySub).Init()               // Initialize the sub-dialog object in the main script
Object DialogOBJ = Alloc(MyMain).Init(SubDialogOBJ)     // Pass on the object into the other
DialogOBJ.Display("Dialog")
Class MySub:UIFrame
{
    TagGroup gen_MySubUI_dlg(Object self)
    {
        TagGroup DLGitems = DLGCreateDialog("Sub")
        TagGroup RadioList=DLGCreateRadioList()
        RadioList.DLGAddRadioItem("option 1",1)
        RadioList.DLGAddRadioItem("option 2",2)
        RadioList.DLGAddRadioItem("option 3",3)
        DLGitems.DLGAddElement(RadioList)
        Return DLGitems
    }
    MySub(Object self)
    {
        self.init(self.gen_MySubUI_dlg())
        self.Display("MySubUI")
    }
    ~MySub(Object self)
    {
        Result("Quit" + "\n")
    }

}
Class MyMain:UIFrame
    {
    Object SubDialog
    Void CallSubDialog(Object self)
        {
        Result("\nOpen sub-dialog.")
        SubDialog.Pose()                                // call the local object
        self.LookUpElement("Label").DLGTitle("option chosen")
        }
    Object Init(Object self, Object SDpass) 
        {
        SubDialog = SDpass                              // Keep the object in a local variabl
        TagGroup DLGitems = DLGCreateDialog("Main")
        DLGitems.DLGAddElement(DLGCreateLabel("choose option").DLGIdentifier("Label"))
        DLGitems.DLGAddElement(DLGCreatePushButton("Options","CallSubDialog"))
        Return self.super.Init(DLGitems)
        }
    }
Object SubDialogOBJ = Alloc(MySub)              // Initialize the sub-dialog object in the main script
Object DialogOBJ = Alloc(MyMain).Init(SubDialogOBJ)     // Pass on the object into the other
DialogOBJ.Display("Dialog")

Class MySub:UIFrame
{
    TagGroup gen_MySubUI_dlg(Object self)
    {
        TagGroup DLGitems = DLGCreateDialog("Sub")
        TagGroup RadioList=DLGCreateRadioList()
        RadioList.DLGAddRadioItem("option 1",1)
        RadioList.DLGAddRadioItem("option 2",2)
        RadioList.DLGAddRadioItem("option 3",3)
        DLGitems.DLGAddElement(RadioList)
        Return DLGitems
    }
    MySub(Object self)
    {
        self.init(self.gen_MySubUI_dlg())
        self.Display("MySubUI")
    }
    ~MySub(Object self)
    {
        Result("Quit" + "\n")
    }

}
Class MyMain:UIFrame
    {
    Object SubDialog
    Void CallSubDialog(Object self)
        {
        Result("\nOpen sub-dialog.")
        Alloc(MySub)                                // call the local object
        }
    Object Init(Object self) 
        {                           // Keep the object in a local variabl
        TagGroup DLGitems = DLGCreateDialog("Main")
        DLGitems.DLGAddElement(DLGCreateLabel("choose option").DLGIdentifier("Label"))
        DLGitems.DLGAddElement(DLGCreatePushButton("Options","CallSubDialog"))
        Return self.super.Init(DLGitems)
        }
    }

Object DialogOBJ = Alloc(MyMain).Init()     // Pass on the object into the other
DialogOBJ.Display("Dialog")
1

There are 1 answers

3
BmyGuest On BEST ANSWER

I do not quite understand your question. In your 2nd code you call self.Display in the constructor, so naturally the dialog gets immediately displayed?

Maybe you need to understand the concept of a constructor method better? This method is called (i.e. the code is run) the moment the object is created in memory, i.e. when you call Alloc(mySub) you create the object of class 'mySub' in memory, which invokes its constructor method.


I'm adding an example of what you might want to do: Allocate the sub-dialog while the main script is still in scope, but do not display it. Instead, hold it as member variable of the the main dialog and display when the button is pressed (in the "OnButtonPressed" action method).

There are different ways that could be done:

  1. Allocated on the main thread and pass the object as parameter to the main-dialog (on the main script) as in:
// On the main script:
object sub = Alloc(sub)
object main = Alloc(main)
main.SetSubDlg(sub)   // SetSubDlg is a custom method that stores into a member variable
main.LaunchDisplay()  // LaunchDisplay is a custom method that shows the main dialog.
  1. Allocate the sub-dialog in the constructor of the main dialog object. As the main dialog is allocated by the call on the main script, its constructor is immediately called while the script code is still in scope. I prefer this way, as it is cleaner encapsulating everything.
class CSubDialog : UIframe
{
    number CreateAndPose(object self)
    {
        TagGroup dlg,dlgitems
        dlg = DLGCreateDialog("SubDialog",dlgitems)
        dlgItems.DLGAddElement(DLGCreateLabel("I'm the sub dialog."))
        return self.init(dlg).pose()
    }
}

class CMainDialog : UIframe
{
    object subDlg
    CMainDialog(object self)
    {
        // The constructor of CMainDialg is called as soon as the 
        // Alloc(CMainDialog) in the main program is called.
        // At this time, the whole script code is still in scope
        // so the subDLG can be allocated. Just hold it as member
        // of this dialog.
        subDlg = Alloc(CSubDialog)
    }
    
    void OnLaunchSub(object self)
    {
        // Safer coding: Check that the member variable is 
        // holding a valid object. 
        if ( !subDlg.ScriptObjectIsValid() ) throw( "No Sub dialog found." )
        // Further safety, check if is of the correct class (All lower case!)
        if ("csubdialog" != subDLG.ScriptObjectGetClassName()) throw( "Wrong object." )
        subDLG.CreateAndPose()      
    }
    
    object CreateAndDisplay(object self)
    {
        TagGroup dlg,dlgitems
        dlg = DLGCreateDialog("Main Dialog",dlgitems)
        dlgItems.DLGAddElement(DLGCreateLabel("I'm the main dialog."))
        dlgItems.DLGAddElement(DLGCreatePushButton("Launch","OnLaunchSub"))
        self.init(dlg).display("Main Dialog")
        return self
    }
    
}

Alloc(CMainDialog).CreateAndDisplay()