Enable / disable / hide User Controls



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

    On 01/07/2012 at 15:17, xxxxxxxx wrote:

    Hi, I cannot find any way to enable, disable (grey out) or even hide user controls for my plugin.
    For example, I have a checkbox named "Automatic". When this is checked, I want a spline control to be either hidden, or greyed out.
    I have come that far that I programmatically, without reloading the plugin and without restarting C4D, can change the value of a checkbox, in the Execute event:
     
     def Execute(self, tag, doc, op, bt, priority, flags) :
           tag[1005] = True

    This is all.
    Considering how simple this is to do, to change the Controls default value, I wish there was possible to do this:
    tag[1005].Enabled = False
    or
    tag[1005].Visible = False
     
    But (of course) it has to be way more complicated than this. And I also might want to hide / grey out the group the control in question belongs to, but I have not found a way to access the group itself, at all. Any help is much appreciated!
     
    There is a thread here, but I have not succeeded in making anything here work in my own plugin.
    http://forums.cgsociety.org/archive/index.php/t-1000070.html
     
    -Ingvar



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

    On 01/07/2012 at 15:36, xxxxxxxx wrote:

    You need to look at the function GetDEnabling. Cinema calls this to determine if a control should be enabled or disabled (greyed out). Return true if enabled, false if not. So in your case you would test if the passed ID is for your spline object, if it is you check the status of the checkbox and return the correct value.

    You can also show or hide controls but it's more tricky and in C++ you need the function GetDDescription. I don't think it's in the Python API yet, unless they've added an easier way to do it (sorely needed).



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

    On 02/07/2012 at 04:17, xxxxxxxx wrote:

    Thanks spedler! This is the right solution.
    But still not that easy to find out about.
    Here is my code:
     
    def GetDEnabling(self, node, id, t_data, flags, itemdesc) :
          if (id[0].id == MY_SUPER_SPLINE) :
              return node[SOME_CHECKBOX] == 1
          return True

    Firstly, it is not obvious to me how to get the id out of the id - lol :))
    The id that comes as an argument actually consists of 3 numbers. And to get the one I want, I had to search the Internet, yes. id[0].id is what I need. Not obvious at all, and no example in the doc showing it to me.
     
    Then, the C4D docs about this event handler is strange. Fisrt it says the method should return true to set the control enabled, and false to set it disabled (grayed out). And in fact, that works. But in the same document I am told to  "Then make sure to include a call to the parent at the end:" and also this:  "_ Note: It is recommended that you include a call to the base class method as your last return."_
    With this example:
    return NodeData.GetDEnabling(node, id, t_data, flags, itemdesc)
     
    I wish the documenation could make up its mind. Am I supposed to return True of False, or am I supposed to return the call to this function?
    Anyhow, I was not able to implement this call at all, have no idea how to do it and the dcs give me no example. "NodeData" is unknown is the message I get.
     
    Without the help from you guys, I would have been stuck. This is a good example of tghe lack of examples in the docs. I wish they had shown sample code,  like the one I posted in the beginning of this message. Would have saved me lots of time!
     
    -Ingvar



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

    On 02/07/2012 at 06:48, xxxxxxxx wrote:

    Yes, the documentation should be improved because it's currently confusing.

    The note:
    "It is recommended that you include include a call to the base class method as your last return."
    Should be:
    "If the passed id element is not processed, you should include a call to the base class method as your last return:"

    And here's an example:

    def GetDEnabling(self, node, id, t_data, flags, itemdesc) :
        if (id[0].id == MY_SPLINE_ID) :
            return node[MY_CHECKBOX_ID] == 1
        else:
            return NodeData.GetDEnabling(node, id, t_data, flags, itemdesc)
    


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

    On 02/07/2012 at 06:53, xxxxxxxx wrote:

    The other thing which could be improved are the examples. Some have clearly been ported from the C++ original, but not completely. For example, Ingvar wants a GetDEnabling example, and you can find one in the C++ SDK DoubleCircle plugin, but the Python port is missing that bit. Presumably the call wasn't in the API when it was ported, so they really need bringing up to date.



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

    On 02/07/2012 at 08:32, xxxxxxxx wrote:

    In:

    return NodeData.GetDEnabling(node, id, t_data, flags, itemdesc)
    

    what is "NodeData" supposed to be?
    I've tried "self", "node" and the Object Class but no luck.

    Cheers
    Lennart



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

    On 02/07/2012 at 08:53, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    And here's an example:

    def GetDEnabling(self, node, id, t_data, flags, itemdesc) :
        if (id[0].id == MY_SPLINE_ID) :
            return node[MY_CHECKBOX_ID] == 1
        else:
            return NodeData.GetDEnabling(node, id, t_data, flags, itemdesc)
    

    Good. As I wrote in my post further up, and as Lennart points out, what is NodeData supposed to be? Have you tried this yourself? The problem is - the example you gave won't run here.
    While I am on the air - is there a way to diable (grey out) a whole group? Group IDs do not appear in this GetDEnabling handler, unfortunately. Only the controls themselves.
     
    -Ingvar



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

    On 02/07/2012 at 10:20, xxxxxxxx wrote:

    @ingvarai:

    NodeData is supoosed to be the NodeData class from the c4d.plugins module. Also, Yannick forgot to pass self as the first argument.

    else:
          return c4d.plugins.NodeData.GetDEnabling(self, node, id, t_data, flags, itemdesc)

    This might be confusing when you've been working with other languages before, but this is how Python works.

    Personally, I prefer using the super() method. As all classes in the c4d module inherit from object, you won't get problems with it.

    else:
          super(MySubclass, self).GetDEnabling(node, id, t_data, flags, itemdesc)

    Here's some code that should help you understand.

    class Superclass(object) :

    def bar(self) :
          print "Superclass.bar()"

    class Subclass(Superclass) :

    def bar(self) :
          print "Subclass.bar()"
          Superclass.bar(self)
          super(Subclass, self).bar()

    o = Subclass()
    o.bar()

    print

    Superclass.bar(o)
    Subclass.bar(o)

    print

    super(Subclass, o).bar()


    Subclass.bar()
    Superclass.bar()
    Superclass.bar()

    Superclass.bar()
    Subclass.bar()
    Superclass.bar()
    Superclass.bar()

    Superclass.bar()


    -Nik



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

    On 02/07/2012 at 10:56, xxxxxxxx wrote:

    Thanks Niklas, one step closer, but I still get a "TypeError: argument 5".

    Looking in the SDK, it says "flags" is not used, so I removed but then
    got . "TypeError: GetEnabling() takes exactly 5 arguments (6 given)"
    It's only five given.....

    Maxon for heavens sake, give a -working- example.
    Not only is the SDK a nightmare, but this is the official plugin support.

    Ingvar you will soon learn that coding for Cinema is not a walk in the park.

    Cheers
    Lennart



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

    On 02/07/2012 at 11:37, xxxxxxxx wrote:

    @tca:

    Hm, I actually didn't execute the version I did correct from Yannicks post, but I can't spot the error now
    by just looking at it. I'll dig in right away.

    Yes, indeed. I hope to have enough influence on MAXON, being a beta tester now, to make them
    enhancing the SDK.

    Cya in a minute,
    -Nik

    PS: Not used doesn't mean it does not require the argument. :)



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

    On 02/07/2012 at 12:29, xxxxxxxx wrote:

    @tca, ingvar, Yannick:

    I can't get the parent-call to work. (I've never needed it, so I didn't know it doesn't work until now) I guess it's just a bug in the Py4D API. Yannick or Sebastian should be able to give us more information.
    If the official support does not have a solution for the parent-call, I'd suggest just to ignore the advice in the SDK and return False instead of the return-value of the parent-call.

        def GetDEnabling(self, node, id, t_data, flags, itemdesc) :  
          rid = id[0].id  
          if rid == c4d.MYTAG_VALUE:  
              # ...  
              return False  
          elif rid == ...:  
              # ...  
              return True  
          return False
    

    -Nik



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

    On 02/07/2012 at 12:29, xxxxxxxx wrote:

    @Lennart
    _> Ingvar you will soon learn that coding for Cinema is not a walk in the park.
    _ Which is illustrated by this:
    "Maxon for heavens sake, give a -working- example."

    When Maxon cannot do it right themselves, I somehow accept that I myself have problems.. I am asking myself to what extent it is my way of thinking, to what extent the documentation is written in an unusal way and so forth. But I am starting to realize that the way the docs are laid out is unusal to me, and that this is part of the source of my problems. I spend waaaaaaaaay too much time carrying out even the simplest tasks.  So it is partly bad or even wrong documentation, and partly me that is not familiar with the way it is documented.
     
    And I have written plugins before. I wrote several for Sony Vegas, the video NLE. What a breeze! The SDK has a full list of Classes, their properties, their methods and mostly everything works on the first or second attempt. Ok, sleeves up, I must get used to the docs. But I often feel like blind folded, tapping around in the dakrness..
     
    And if you want C4D to crash - I mean really crash, you can do this:
    def GetDEnabling(self, node, id, t_data, flags, itemdesc) :
       if(id == 1003) :
          Return False
    :)))
     -Ingvar



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

    On 02/07/2012 at 12:38, xxxxxxxx wrote:

    Nik,
     
    how do you do this:
    c4d.MYTAG_VALUE:

    I have never gotten this to work.
    I must redefine MYTAG_VALUE in the pyp file.
    I often see the c4d.XXXX. What does it mean, and how do you do it?
     
    Another question:
    Is it possible to disable a whole group using Python? (With several user controls)
    I see that C4D can do it, with the built in controls.
     
    -Ingvar



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

    On 02/07/2012 at 12:38, xxxxxxxx wrote:

    @ingvar:
    I totally agree with you. Once I started with Py4D, I had experience with COFFEE so it wasn't that hard, because I did already understand the principles of c4d. I've never written any code before COFFEE, but I think it is even harder for people that are already used to something else, especially something better else. ;)

    To your "crashy" code: Why should this crash Cinema 4D? ^^ IMHO the easiest way to crash it, is this:

    op.InsertUnder(op)
    

    or even

    import types  
    types.FunctionType(types.CodeType(0, 0, 0, 0, "KABOOM", (), (), (), "", "", 0, ""), {})()
    

    That even works for every Python Interpreter 😂

    edit :

    This only works for descriptions, not for dialogs. When C4D detects a new plugin, it recomputes the "symbolcache". But if you later add new symbols to your description, it might happen that C4D does not add them to the "symbolcache". [citation needed, information out of experience]
    You can delete the file under %appdata%/MAXON/Cinema 4D RXX/prefs/symbolcachce to fix this. Note that it's called coffeesymbolcache under R12.

    Hm, I don't know actually. Only when Cinema 4D asks you about the group in GetDEnabling. Otherwise, you'd have to figure out what ID's are in the group you'd like to disable.
    The whole GetDEnabling thingy is a little overcomplicate, imho. Why not just make something like SetDEnabling(id, status)?! Just like Enable() of the GeDialog class..

    -Nik



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

    On 02/07/2012 at 13:07, xxxxxxxx wrote:

    Nik,
    _> You can delete the file under _
    Worked! Thank you!
     
    > Only when Cinema 4D asks you about the group in GetDEnabling
    Unfortunately it does not. Groups are not iterated, only user controls.
     
    > The whole GetDEnabling thingy is a little overcomplicate
    Probably prepared for a more complicate future.. :)
    Lots of things seem overcomplicated to me..
     
    -Ingvar



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

    On 02/07/2012 at 13:37, xxxxxxxx wrote:

    Thanks Niklas for checking.

    Cheers
    Lennart



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

    On 03/07/2012 at 01:29, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    The whole GetDEnabling thingy is a little overcomplicate, imho. Why not just make something like SetDEnabling(id, status)?! Just like Enable() of the GeDialog class..-Nik

    My guess is that a lot of the SDK is ancient and comes from early versions of Cinema. To rewrite it now would be a gigantic task because this goes right to the core of Cinema's GUI.

    If you think GetDEnabling is bad, wait until you have to use GetDDescription (C++ only ATM). This one requires you to use undocumented function calls that aren't even in the C++ docs.



  • On 04/09/2017 at 00:45, xxxxxxxx wrote:

    ahhm... this thread and others about GetDEnabling() are a bit confusing!
    ie. the sdk example does not use the (above discussed) return c4d.plugins.NodeData.GetDEnabling() call
    https://github.com/PluginCafe/cinema4d_py_sdk/blob/master/plugins/Py-DoubleCircle/Py-DoubleCircle.pyp

    so, is there a way to ghost an userdata entry (in python tag space)?

    for example i have a simple op[c4d.USERDATA_ID,5] = "whatever"
    now i want to ghost (or unghost) this field... (maybe just to disallow user interactions)

    i guess you need to hook GetDEnabling() in like message() ? but then, if i add
    def GetDEnabling(self, node, id, t_data, flags, itemdesc) : print "hi there!"
    to my pyhton tag, it doesnt get called at all. i do not get any console output....

    is GetDEnabling even possible in python tags?



  • On 06/09/2017 at 05:40, xxxxxxxx wrote:

    Hi,

    neither GetDEnabling() nor GetDDescription() can be overridden in a Python Tag (talking about the scripting tag here, not a TagData plugin implemented in Python). So, no, it's unfortunately not possible to disable parameters in a Python tag. But it should be fairly easy to translate a Python tag into a TagData plugin written in Python (script code goes into Execute()).



  • On 06/09/2017 at 23:12, xxxxxxxx wrote:

    ok, thanks for clarifying this, andreas!


Log in to reply