Search code examples
classcustomdialogdm-script

Class is not recognized by DM when it is used with a custom dialog


There

I am adapting a DM script to read hdf5 file. there is a user defined Class called "MetaStr2TagGroup". It works well within the script.

I am trying to build a custom dialog to allow more options for users in a straightforward way. The custom dialog works fine with my test without the actual script part.

The problem happens when I put the script with class “MetaStr2TagGroup” to the front of my custom dialog script. It still runs to give a dialog and allow all the actions. But once I ask it run the script then it give me an error message "Cannot find class named ‘metastr2taggroup’" But the class is still at the front of the entire script.

I don't understand that, Could any one explain me why it happens and how to avoid that?

My simplified code structure is like follows. The object Local_helper and local_Helper = Alloc( Helper ) are what I've added according to BmyGuest's comment. It is not working so far.

Class Helper{
    functions1(){}
    functions2(){}
    TagGroup functions3(){
        Call function 1 and function 2}
}
Function4()   {
    Call function3()
}
Function5(){}
Function6(){
    Call function4()
}

class Converter : UIframe   {
    **object Local_helper**
    Action1(){}
    Action2()   {
        **local_Helper = Alloc( Helper )**
        Call Function6()
    }
}

TagGroup MakeFields1{}
TagGroup MakeFields2{}

//Main start here
Call MakeField1()
Call MakeField2()
object dialog_frame = alloc(Converter).init()

Class error message when it is in a custom dialog script


Solution

  • The issue you are running against is, that the "UIframe" dialog is created on a different thread. When a dialog button is pressed, the original "script" is no longer in scope ( Just the dialog object is. )

    So the following code does not run properly:

    class CHelper
    {
        void DoStuff2( object self ) { OKDialog( "Action!" ); }
    }
    
    class CMyDialog : UIframe
    {
        void DoStuff( object self )
        {
            Result( "\n Running method from other class: " )
            Alloc( CHelper ).DoStuff2()
        }
    
        object Init( object self )
        {
            TagGroup dlg, dlgItems
            dlg = DLGCreateDialog( "Test", dlgItems )
            dlgItems.DLGAddElement( DLGCreatePushButton( "Do Action", "DoStuff" ) )
            return self.super.init( dlg )
        }
    }
    
    Alloc( CMyDialog ).Init().Display( "My DLG" )
    

    What you can do is to allocate an object of the second class right when you create the UI object. This can be done in the constructor method of the UIclass, or you can put the code into the Init() method as well. Now, this second object is in scope (because it´s part of the dialog object) and you can use it directly:

    This code does run properly:

    class CHelper
    {
        void DoStuff2( object self ) { OKDialog( "Action!" ); }
    }
    
    class CMyDialog : UIframe
    {
        object localHelper
        void DoStuff( object self )
        {
            Result( "\n Running method from other class: " )
            localHelper.DoStuff2()
        }
    
        object Init( object self )
        {
            localHelper = Alloc( CHelper )
            TagGroup dlg, dlgItems
            dlg = DLGCreateDialog( "Test", dlgItems )
            dlgItems.DLGAddElement( DLGCreatePushButton( "Do Action", "DoStuff" ))
            return self.super.init( dlg )
        }
    }
    
    Alloc( CMyDialog ).Init().Display( "My DLG" )
    

    The alternative option would be to have the "second" class installed as a library. That way, it is always available for allocation. However, I would not recommend that solution.