Dialogs, a beginner's problems



  • On 29/06/2013 at 08:35, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R13-R14 
    Platform:      
    Language(s) :     C++  ;

    ---------
    I am a completely beginner regarding dialogs.
    As usual I have studied the SDK, the forums, and various (albeit very few) tutorials on the Internet. And as usual, I spend MANY hours carrying out tasks I had expected were almost self-explanatory. It takes time, because  writing for C4D is everything except straight forward. And it seems I have to live with it.

    I want to make a modal dialog, which opens when the user clicks a button in my tag user interface.
    I looked at one dialog, a ListView Dialog, but it failed in the LoadDialogResource function. Then I found this: http://www.andrewnoske.com/wiki/index.php?title=Cinema_4D\_-\_C%2B%2B_plugins#Tutorial_2:\_Simple_Custom_Dialog
    which brought me a bit further.

    Now I have these (beginner's) questions:

    1. What is the preferred / correct way to do the CreateLayout(void)?
      I tried LoadDialogResource(), but no matter what I did, it always returned false.
      So I went for the aforementioned tutorial.

    Here I came this far:

    Looks OK at first sight, but it is far from that.
    2) Nothing works, the controls seem to be painted on the surface, they do not respond at all.
    as soon as the windows is resized / repainted, all controls disappear:

    What have I done wrong here?

    Additional questions:
    3) How do I make the dialog modal?
    4) How do I remove the minimize and maximize buttons?
    Any help is much appreciated!



  • On 29/06/2013 at 14:35, xxxxxxxx wrote:

    Ok, as I said - it is a beginner's question.
    The dialog functions all right, when registered as a dialog plugin and invoked from the C4D Plugins menu. But I want the dialog to be part of my Tag Plugin. There lies the challenge at the moment, I want a dialog to come up when pressing a button in the Tag Plugin. And so far, it won't work..

    Edited:
    I have used the wrong dialog.
    Changing the base class GeDialog -> GeModalDialog seems to solve most (if not all) of the questions I had in the initial post in this thread.



  • On 29/06/2013 at 15:07, xxxxxxxx wrote:

    1. Each dialog has an associate integer ID in the context of the local resource, defined in c4d_symbols.h.
      The resource loader can resolve this ID back into its symbol-name and load the dialog resource.

    - LoadDialogResource(DLG_MAIN, NULL, BFH_SCALEFIT | BFV_SCALEFIT);
    - Resource-loader recieves ID 100024, resolves it into "DLG_MAIN"
    - Loads dialog resource "res/dialogs/DLG_MAIN.res"

    1. Since you do not show code, I can only guess why this happens: You probably do something like this:

    > MyDialog dlg;
    >
    > dlg.Open(DLG_TYPE_ASYNC);

    As soon as the dialog goes out of scope, it is deallocated from the stack causing all gadgets to
    disappear from the window. If you do not understand why, learn about threading and memory lifetime.

    1. This information is right there in the documentation of the Open() method.

    1. Modal dialogs do not have such.


  • On 29/06/2013 at 15:28, xxxxxxxx wrote:

    about 2.) the most common reason for a blank dialog would be a syntax error in the corresponding res file. should be obvious, as it will be indicated by a dialog box. unresponsive or 'funny' behaviour of dialog or description gui elements can usually be tracked down to incorrect initialization of one or more elements. for dialogs this are the SetXYZ methods or the wrapping CustomDataType classes. also overriding the Message() method for dialogs an not properly invoke a call to the parent class will lead to empty dialog windows and/or crashes.

    about 4.) i'm not 100% sure right now, but aren't the min/max buttons hidden for the non resizable dialog type flags ? if not - you could use the popup_blah_something dialog type id. it will hide the titlebar of the dialog completely (so that you have to implement a title bar, a close button and if unavoidable some sort of window dragging).

    happy,
    rendering



  • On 30/06/2013 at 13:26, xxxxxxxx wrote:

    Thanks for the help, as I said in the previous post, everything got better when I when I changed it from GeDialog to GeModalDialog, the pieces fell into place.
    Regarding my question about whether to use a RES file or not, I now create the controls dynamically, no use of a RES file at all. And it functions very good. As it always is, when finally finding out how to do things.
    So to what extent one should use a RES file or not, is is of pure academic interest now, since the dynamic creation of the controls work so well.



  • On 01/07/2013 at 07:49, xxxxxxxx wrote:

    . res file advantage #1:
    The .res file (and it's friends .h & .str ) can be changed without having to recompile the plugin.
    . res file advantage #2:
    The .res file system is typically used to write plugins that display their text in multiple languages.
    . res file advantage #3:
    Using the .res file to lay out your gizmos makes your plugin's .cpp file smaller(OOP)
    Which requires less scrolling when working in your .cpp files.

    Disadvantage #1:
    The .res file method is static. No changing things on the fly.
    Disadvantage #2:
    For GeDialog plugins. The .res files do not support many of the options for dialogs.
    So it's most commonly used in Node based plugins(tags, objects, etc..).
    Disadvantage #3:
    Your plugin might be fairly small. And using three more separate files(.res, .h, &.str) might over complicate your simple plugin more than it needs to be.
    A small plugin does not really need all of that OOP stuff. With all the separated files.
    But that's my own personal opinion. Others may not agree.

    -ScottA



  • On 01/07/2013 at 07:56, xxxxxxxx wrote:

    Disadvantage #4:
    Changes to the .res file in most cases (besides asthetic) require code in your GeDialog class to support them.  If you change the type of an element or add elements, they are not automatically supported by your code.  I do all of my dialogs dynamically in CreateLayout().



  • On 01/07/2013 at 09:21, xxxxxxxx wrote:

    For me, disadvantage #1 is of most importance. Because I generate UI controls for the dialog, depending on various variable criteria.



  • On 01/07/2013 at 09:57, xxxxxxxx wrote:

    disadvantage 1 is simply not true, you can of course change the resource dynamically. disadvantage 2 sound at least a bit surprising. could you name an example (flag/element). i thought i do know c4ds resource syntax pretty well and i have not heard of a single flag that is supported from code but not from the ressource (well except for the initialization of custom datatypes, but you have to init them for cpp based definitions too).



  • On 01/07/2013 at 10:31, xxxxxxxx wrote:

    disadvantage 1 is simply not true
    Looks like that to me, but if you can show / hide controls dynamically using RES files, then there's no disadvantage.



  • On 01/07/2013 at 11:11, xxxxxxxx wrote:

    The .res file holding your descriptions is a text file. It's a static resource.
    You can of course change things by overriding methods like GetDEnabling() and GetDDescription().
    But this does not change the fact that the .res file is static resource.
    And in Python. We don't even have GetDEnabling() available to override.
    I consider this to be disadvantage of the .res system.

    There's been several posts on the forums where someone (including me) has tried to use a .res file to set a description in a GeDialog. And couldn't. Because it's a Node based only description that is not supported by the GeDialog class.
    This happens quite regularly to people. And we've discussed it several times.
    This is also what I consider to be a disadvantage of the .res system.

    If you guys don't think these are disadvantages. That's fine.
    A lot of this stuff is subjective to personal preferences.

    -ScottA



  • On 01/07/2013 at 11:13, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    disadvantage 1 is simply not true
    Looks like that to me, but if you can show / hide controls dynamically using RES files, then there's no disadvantage.

    depends on the type of the ressource.

    1. for dialogs:

    there are several ways to do that here. you are not bound to the createlayout method to define a dialog content. you cannot delete an an element specifically (at least i am not aware of a way), but you can flush groups and then rebuild its content with the new values. technically should be hiding possible for elements with the gedialog.sendmessage method, but i have never tried it, as i did never need it. c4d also offers subdialog elements which allow you to dynamically attach other dialogs to a dialog. in the cpp sdk is an example for that (i think its called dialogtest or something like that). last but not least there the loadressource method itself. it does not replace the dialogs resource but appends the passed ressource to the dialogs ressource. so you can load two ressources into a dialog , which will effectively append one resource to the other. very useful if you have common elements for multiple plugins.

    2. for descriptions:

    for descriptions the mentioned methods obviously won't work. modifying the description is here only possible on a much lower level. there is GetDEnabling on the one hand which allows you to grey out elements and the there is GetDDescription which allows you to do more stuff, but things can get quite complicated. steve (a form member here and the author of xparticles) wrote an excellent tutorial on that topic.

    steves blog : http://www.microbion.co.uk/graphics/c4d/cookbook-2.htm



  • On 01/07/2013 at 11:27, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    The .res file holding your descriptions is a text file. It's a static resource.
    You can of course change things by overriding methods like GetDEnabling() and GetDDescription().
    But this does not change the fact that the .res file is static resource.
    And in Python. We don't even have GetDEnabling() available to override.
    I consider this to be disadvantage of the .res system.

    There's been several posts on the forums where someone (including me) has tried to use a .res file to set a description in a GeDialog. And couldn't. Because it's a Node based only description that is not supported by the GeDialog class.
    This happens quite regularly to people. And we've discussed it several times.
    This is also what I consider to be a disadvantage of the .res system.

    If you guys don't think these are disadvantages. That's fine.
    A lot of this stuff is subjective to personal preferences.

    -ScottA

    of course there is GetDEnabling in python , i think you meant GetDDescription which is not wrapped for python. i am also not sure how these methods are disadvantage of file based resources, as they do refer to descriptions where you do not have the option of code based definitions. and about loading ressources : i (almost) never used the code based definitions and had neither problems in python nor recently in cpp. would be a bit surprising in cpp as its the preferred modus operandi by maxon. there is also nothing magical about it, simply use LoadResource().

    but i do agree, in the end its is a question of taste and efficiency and you might be better of with code based definitions if you do not want to learn the (fairly simple) res syntax or just have to define two elements.



  • On 01/07/2013 at 12:18, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    and the there is GetDDescription which allows you to do more stuff, but things can get quite complicated.

    I have already used that one to show / hide elements, I had forgotten it when I wrote my post.
    On the other hand, when dynamically creating a layout, things get much simpler. And a modal dialog is active just a short while, to get some user input, so here I find the dynamic approach perfect. 
    Among the benefits: I can use the same ID for a Static text, as well as for an Edit box, depending on the user wanting to load or save something. And the function for setting the text can be the same, as long as the ID is the same.

    if(modeReadOnly)
    {
       AddStaticText(DLG_TEXT_SELECTED_FILE, BFH_LEFT, 400, 0, "", BORDER_THIN_IN);
    }
    else
    {
        AddEditText(DLG_TEXT_SELECTED_FILE, BFH_SCALEFIT, 0, 0);
    }
      
    // And then I can use the same method, regardless of mode
      
    void FooDialog::SetSelectedFile(Filename filename)
    {
        filename.ClearSuffixComplete();
        this->SetString(DLG_TEXT_SELECTED_FILE, filename.GetFileString());
    }
    


  • On 01/07/2013 at 12:35, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Among the benefits: I can use the same ID for a Static text, as well as for an Edit box, depending on the user wanting to load or save something. And the function for setting the text can be the same, as long as the ID is the same.

    you can do that in res files to. you can reuse the same id as often as you want. some elements like groups also accept no ids at all. also IDC_STATIC is always defined and has not to be redefined in the c4d_symbols file again (and should be only used for elements where you do not care about their id).



  • On 01/07/2013 at 13:32, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    but i do agree, in the end its is a question of taste and efficiency and you might be better of with code based definitions if you do not want to learn the (fairly simple) res syntax or just have to define two elements.

    It has nothing to do with learning the "fairly simple" res syntax.

    There's several occasions when you cannot use the .res file on a gizmo in your GeDialog plugin.
    I don't remember what they are off the top of my head. But If I remember correctly. I think the custom guis are like that.
    So what happens is you end up with having to declare some things the CreateLayout() method that are not using the .res file at all. Even if you wanted to use the .res file. And not .cpp file.
    So you end up with a sort of scatter brained code using the .res file for some things. And the .cpp file  for others.

    Maybe you haven't run into this before. But I have.

    -ScottA



  • On 01/07/2013 at 13:38, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    you can do that in res files to. you can reuse the same id as often as you want.

    Have you tested it? If you have one static text, and one edit text, both with the same ID, and then

    1. use GetDDescription to hide one of them
    2. use this->SetString(SOME_ID, someText);  to set the text

    Will that work? I have not tested, but of it works, then both elements should get the text.



  • On 01/07/2013 at 14:14, xxxxxxxx wrote:

    well, it depends on what you do define as 'working'. elements pointing to the the same ID will act as one, just like as you would have defined them with one id in code. so you won't be able to distinguish them for command ids or message ids. getddescription is a bit confusing for me that context, as it does refer to descriptions and is different resource syntax/logic.

    for using the setter methods, it will always target the first match. so if you have multiple elements you will always need multiple ids. i would be surprised if that is different for code defined dialogs.



  • On 01/07/2013 at 14:44, xxxxxxxx wrote:

    Yes, but then I will definitely use the dynamic creation of elements. Because then I create (Add) either A or B, and as long as they use the same ID, the SetString will guaranteed work.



  • On 01/07/2013 at 15:32, xxxxxxxx wrote:

    setters will also work for two different resource files targeting the same ids. its the whole point of file based resources.the idea is to load the dialog definition you need / and or construct it with the above described methods (instead of putting the same element twice into one file and (un)hide one). there are of course scenarios were your dialog content has to be so dynamic that is does almost make no sense to use any file based definitions at all. but i guess these are pretty rare.


Log in to reply