GeDialog.LoadDialogResource() Problem



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 29/06/2011 at 15:48, xxxxxxxx wrote:

    I'm trying to load a dialog created with the resedit plugin in a CommandData plugin.
    At this stage it's just an example plugin with a single checkbox dialog but I can't get it to work

    My Folder Structure is :

    Example
    --res
    ----dialogs
    ------IDD_EXAMPLE.res
    ----Example.tif
    --strings_us
    ----IDD_EXAMPLE.str
    --c4d_symbols.h
    --Example.pyp

    And the code for my plugin is :

    import os
    import c4d
    from c4d import plugins, bitmaps, gui

    PLUGIN_ID = 1000001 #be sure to use a unique ID obtained from www.plugincafe.com

    class MyDialog(gui.GeDialog) :
        def CreateLayout(self) :
            return self.LoadDialogResource(IDD_EXAMPLE)

    class Example(plugins.CommandData) :

    def Execute(self, doc) :
            dialog = MyDialog()
            dialog.Open(c4d.DLG_TYPE_MODAL)
            return True

    if __name__ == "__main__":
        path, fn = os.path.split(__file__)
        bmp = bitmaps.BaseBitmap()
        bmp.InitWith(os.path.join(path, "res", "Example.tif"))
        plugins.RegisterCommandPlugin(id = PLUGIN_ID,
            str = "Example", help = "Command Plugin Example",
            dat = Example(), info = 0, icon = bmp)

    A dialog is succesfully created but it's empty, and when I close it,
    I get the error :
    "NameError:global name 'IDD_EXAMPLE' is not defined".

    So it seems I need to do something more to initialise the resource or point to the 'res' folder but I don't know what.
    None of the plugin examples seem to load an external dialog file, so I'm a bit stuck.

    Any help would be gratefully recieved.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 29/06/2011 at 17:45, xxxxxxxx wrote:

    There are usually two files in your res->description folder when using Coffee or C++.
    - the .res file--- containing the layout of the GUI items
    - the .h file   --- containing the numerical ID numbers assigned to your GUI items

    Python apparently can't read from the .h file.
    So you have to put that information at the top of your main plugin code.

    For example:

    import os  
    import c4d  
    from c4d import plugins, bitmaps, gui  
      
    IDD_EXAMPLE = 1000  
    IDC_BUTTON1 = 1001  
    etc...  
      
    PLUGIN_ID = 1000001 #be sure to use a unique ID obtained from www.plugincafe.com  
      
    class MyDialog(gui.GeDialog) :   
      def CreateLayout(self) :   
          return self.LoadDialogResource(IDD_EXAMPLE)   
      
    Etc...
    

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 29/06/2011 at 21:50, xxxxxxxx wrote:

    Or checkout the HeaderFile Parser.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 30/06/2011 at 13:06, xxxxxxxx wrote:

    Thanks guys, that makes sense.
    Unfotunately, I am still getting an error :

    "Failed to initialize global resource for the plugin"

    Any ideas ?

    I am messing around with using :

    res = plugins.GeResource()
    res.Init("..\Example")
    return self.LoadDialogResource(IDD_EXAMPLE, res)

    to try and manually intialize the resource but a) I think it's not supposed to be necessary and b) I don't understand how to write relative paths.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 30/06/2011 at 13:20, xxxxxxxx wrote:

    Is your dialog in a seperate file, and not in the main *.pyp ?

    Relative paths are created like this:

    from os.path import join, dirname   
    myPath = join(dirname(__file__), 'myFolder', 'myFile.suf')
    

    Ps: "could not initialise global resource for plugin" does, afaik, nothing have to do with a dialog. Did you write an ObjectData plugin for instance ? This error is raised when you overload a description name that couldn't be found.
    A description must be placed in "res/description", for more, look into the C++ docs.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 30/06/2011 at 13:59, xxxxxxxx wrote:

    Thanks Nux, the MyDialog class itself is defined in the main PYP file with my Command Plugin class. But it (is supposed to) load an IDD_EXAMPLE.res file from the plugin's res/dialogs folder.
    This was created with resedit plugin, which also made corresponding c4d_symbols.h and IDD_EXAMPLE.str files.
    I have followed the directory structure recommended in the Python for Cinema 4d sdk (see post 1).

    Thanks for your explanation of relative paths, I will definately refer back to it in future.

    For now, I found it is much easier to just hand-write my dialogue in the pyp file, without extenrnal resources, it is working already. My plugin is not such a big deal that it really needs extenral resource files.
    I will check out both Header file Parser & Description editor in future.

    Thanks again for your help.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 30/06/2011 at 14:12, xxxxxxxx wrote:

    Nux.
    Do you have an example of a dialog plugin that uses external .res files to hold the gizmo data?

    Making the dialog for the plugin is simple.
    But loading the gizmo data from the .res file is giving me trouble.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 30/06/2011 at 15:41, xxxxxxxx wrote:

    ScottA,
    I had the same problem with global resource error.  The fix for me was to add my dialog ID's to the c4d_symbols.h file.  Then I was able to access the id's in my python code using c4d.ID_MY_CONTROL

    python code examples:
               descId = data.get('id')
                if(descId[0].id == c4d.ID_BUTTON_REFRESH ) :
                    if(self.Debug) : print('Refresh button was pressed')
                    self.UpdateTagObjects(node)

    elif(descId[0].id == c4d.ID_BUTTON_CREATE ) :
                    if(self.Debug) : print('Create button was pressed')
                    self.CreateObjects(node)
                    self.UpdateTagObjects(node)

    c4d_symbols.h file:
         enum
    { // Dialog definitions of IDD_CACHEDIALOG start here IDD_CACHEDIALOG, IDC_CUSTOM1, IDC_CHECK1, // Dialog definitions of IDD_CACHEDIALOG end here ID_CHECK_CHILDREN, ID_DIR_FOLDER, ID_CHECK_ACTIVE, ID_BUTTON_REFRESH , ID_STATIC_OBJ_COUNT, ID_STATIC_USE_COUNT, ID_BUTTON_CREATE , ID_CHECK_DEBUG, ID_FLOAT_SCALE, ID_INT_FRAME_OFFSET, ID_BUTTON_HELP, // End of symbol definition _DUMMY_ELEMENT_ };

    hope this helps



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 30/06/2011 at 16:22, xxxxxxxx wrote:

    Thanks.
    But I already had them in my symbols.h file.
    I think my problems are inside of  the main pyp file. I'm trying to convert one of my Coffee res based dialog plugins to Python. And I'm running into conversion problems.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 30/06/2011 at 16:50, xxxxxxxx wrote:

    I'm a C# coder and have been struggling with python and C4d for months now... so I'm still am a nubie, but a couple of things jumped out at me in your python code:

    1. the init function should be def __init__(self) :
    2. all methods with in a class definition should have the first parameter as self even if you don't intend to pass any parameters.  Python always passes self
    3. the call to a class method should have the self.  i.e.  self.SetTitle("ResBasedMenu"), I think SetTitle is an inherited method?

    again I'm new at this so please correct me if i'm wrong.

    currently I'm struggling with the description system for my tag plugin, I'm using this so that the properties can be manipulated through the attributes manager.  Apparently not all controls supported in dialogs are supported in descriptions.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 30/06/2011 at 17:58, xxxxxxxx wrote:

    I think I've got it figured out now.
    I'm going to work on it a little bit more. Then I'll post it when it's done in case anyone needs a simple example.

    The SDK's (and Maxon) always say that resource based plugins are the best way to go.
    So there really should be a simple dialog example included with the Python SDK.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 01/07/2011 at 03:46, xxxxxxxx wrote:

    Here's some snippet of the RootDialog class used in my Description Editor plugin.

    class RootDialog(GeDialog) :  
      resourceId      = None  
      
      TITLE_DEFAULT   = "Root Dialog"  
      
      def __init__(self, descElement, title = None) :  
            # Description Object  
          self.descElement            = descElement  
      
            # Dialog title  
          if not title:  
              self.title              = self.TITLE_DEFAULT  
          else:  
              self.title              = title  
      
          self.result                 = None  
      
      def Init(self) :  
          self.SetTitle(self.title)  
      
          return True  
      
      def InitResourceId(self, id) :  
          if not isinstance(id, int) :  
              raise TypeError, "InitResourceId: need an integer argument, not %s" % id.__class__.__name__  
      
          self.resourceId     = id  
      
      def CreateLayout(self) :  
            # Create dialog layout  
      
          if self.resourceId is None:  
              raise RuntimeError, "Dialog resource not initialised!"  
      
          self.LoadDialogResource(  
              id          = self.resourceId,  
              flags       = c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT,  
          )  
      
          self.Init()  
      
          return True  
      
      [...]
    


  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 01/07/2011 at 12:02, xxxxxxxx wrote:

    After much searching through my collection of code. And a lot of WTF is this crazy thing doing!😂
    I've created a fairly good (simple) asyncronous, dockable, resource based, Dialog example:https://sites.google.com/site/scottayersmedia/ResBasedDialogPlugin_Python.zip

    Here's some interesting things I found along the way:
    -The folder it seems to look for by default is "dialogs"....not "description" <--- That's really weird

    -Using an auto incrementation enum system in the symbols.h file caused strange problems with certain ID numbers in my pyp file. So I had to use the exact same list of ID's in the symbols.h file as the main .pyp code file. And not use an auto increment system at all.

    -Some of the description flags don't seem to be supported(CUSTOMGUI_INLINE, ANIM OFF, ANIM ON, etc...) 😢

    Hope this helps.
    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 01/07/2011 at 12:48, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    ]Here's some interesting things I found along the way:
    - The folder it seems to look for by default is "dialogs"....not "description" <--- That's really weird

    -Using an auto incrementation enum system in the symbols.h file caused strange problems with certain ID numbers in my pyp file.

    1. Of course ! You are creating a dialog and not a NodeData instance which needs a description.

    2. Don't know what you mean with it.

    Did my example help you ?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 01/07/2011 at 13:15, xxxxxxxx wrote:

    Many thanks guys for all your helpful pointers & code !
    These are exactly the examples & info that I was missing in the python for c4d documentation ! Hopefully this thread will help others who struggle with this too.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 01/07/2011 at 13:16, xxxxxxxx wrote:

    I have found that the description versus dialogs don't support the same features as well.  And for the widgets that are supported the options are different.
    for example to create a line separator:
    SEPARATOR { LINE; }  // for descriptions
    SEPARATOR { SCALE_H; } //for dialogs

    I searched the C++ and C.O.F.F.E.E docs and found great info for dialogs, but nothing for the description system.  Am I just missing it?

    The way I discovered the SEPARATOR options is by looking at the description res files defined for C4D.
    located here: C:\Program Files\MAXON\CINEMA 4D R12\resource\res\description

    These files have helped me greatly in building my own description screens.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 01/07/2011 at 13:46, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Did my example help you ?

    Not in this case. I was already deep into building my plugin before you replied.
    But your input is always helpful.👍

    The enum thing was a very sneaky problem.
    I set my first symbols.h item id to start at 100000. Then auto increment. And my GUI items in my .pyp file started at 10001.
    Everything worked fine. Until I reached the number 100010 in my .pyp file. That gizmo was being ignored, and wouldn't execute my code pointing to it.
    So auto incrementing enums do work. But only under very limited circumstances.
    It took me a while to find that sucker too.😠
    Once I found it. I decided to not use auto incrementing at all. To eliminate any further problems.

    -ScottA


Log in to reply