How to use the customgui files?



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

    On 22/08/2011 at 14:31, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   12 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Hi,
    I'd like to learn more about the custom gui items in the SDK. But I don't know how to use them in my plugins.

    There are two locked files for each custom gui example( .cpp &  .h )
    Am I supposed to leave these files as is. And link to them somehow from inside my own plugins?
    Or
    Am I supposed to cut and paste what I need from them into my plugins?

    If I could maybe see a very simple working example on using one of them. Perhaps the bitmapbutton if possible. Then maybe I would be able to figure out how to use the other ones on my own.

    -ScottA



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

    On 22/08/2011 at 16:45, xxxxxxxx wrote:

    Well....Duh!
    I figured out that to use those files I just need to include the .h files. The same way I've always used them in the past.  God my memory is terrible.

    Now I just need to know how to implement the bitmapbutton code.
    Here's a simple dialog example that displays the DateTimeGUI:

      
    #define PLUGIN_ID 1000006   // TESTING ID!!!!  be sure to use a unique ID obtained from www.plugincafe.com  
      
    #include "c4d.h"  
    #include "gui.h"  
    #include "c4d_symbols.h"  
    #include "lib_browser.h"  
    #include "customgui_datetime.h"  
    #include "customgui_bitmapbutton.h"  
    #include "../../resource/_api/c4d_customgui/customgui_bitmapbutton.h"  
      
      
    class myDialog : public GeDialog  
    {  
      private:  
          DateTimeControl *dt;          
          BitmapButtonCustomGui *myButton;  
      
      public:  
          myDialog(void);  
          virtual Bool CreateLayout(void);  
          virtual Bool InitValues(void);  
          virtual Bool Command(LONG id,const BaseContainer &msg);  
          virtual LONG Message(const BaseContainer &msg,BaseContainer &result);  
    };  
      
      
    myDialog::myDialog(void)  // The Constructor  
    {  
      //Not used in this example  
    }  
      
    Bool myDialog::CreateLayout(void)  
    {  
      SetTitle("DateTime Test");  
      
      GroupBegin(0,BFH_SCALEFIT|BFV_SCALEFIT,0,1,String(),0);  
        
      BaseContainer customgui; // fill the container with the custom GUI's values (DATETIME_TIME_CONTROL, DATETIME_DATE_CONTROL, etc.)      
      dt = (DateTimeControl* )AddCustomGui(10000,DATETIME_GUI,String(),BFH_SCALEFIT|BFV_SCALEFIT,0,0,customgui); // Adds the DateTime GUI to the dialog  
      myButton = (BitmapButtonCustomGui* )AddCustomGui(10001,CUSTOMGUI_BITMAPBUTTON,String(), BFH_SCALEFIT|BFV_SCALEFIT,0,0,customgui);///Not finished!!!!!!  
      
      GroupEnd();      
        
      return TRUE;  
    }  
      
      
    Bool myDialog::InitValues(void){  
        
      if (!GeDialog::InitValues()) return FALSE;  
      
      //Nothing to initialize in this example   
            
      return TRUE;  
    }  
      
    Bool myDialog::Command(LONG id,const BaseContainer &msg)  
    {  
            
      //Empty for now  
      
      return TRUE;  
    }  
      
      
    LONG myDialog::Message(const BaseContainer &msg,BaseContainer &result)  
    {  
      
      return GeDialog::Message(msg,result);  
    }  
      
    class MyDateTime : public CommandData // MyDateTime is the class name that needs to be listed in the main.cpp to register it properly   
    {  
      private:  
          myDialog dlg;  
      
      public:  
          virtual Bool Execute(BaseDocument *doc);          
          virtual Bool RestoreLayout(void *secret);          
    };  
      
    Bool MyDateTime::Execute(BaseDocument *doc)  
    {  
      //return dlg.Open(DLG_TYPE_ASYNC_FULLSCREEN_MONITOR,ID_PLUGIN,0,0); // use for full screen if desired  
      return dlg.Open(DLG_TYPE_ASYNC,PLUGIN_ID, -1, -1, 300,150);      
    }  
      
    Bool MyDateTime::RestoreLayout(void *secret)  
    {  
      return dlg.RestoreLayout(PLUGIN_ID,0,secret);  
    }  
      
    Bool RegisterMyDateTime(void)  
    {  
      return RegisterCommandPlugin(PLUGIN_ID,GeLoadString(IDS_DateTime),0,AutoBitmap("icon.tif"),String("Date/Time Example"),gNew MyDateTime);      
    }
    

    The Date&Time GUI works.
    But I need help getting the bitmap button code to work.

    -ScottA



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

    On 23/08/2011 at 00:40, xxxxxxxx wrote:

    What doesn't work in your code? If AddCustomGui() returns a non-null pointer then it's added the bitmap button and you can use it to access the BitmapButtonCustomGui functions, e.g. myButton->SetImage().

    Then just check for button clicks in the dialog's Command function in the usual way.



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

    On 23/08/2011 at 07:41, xxxxxxxx wrote:

    I don't know how to set up the functions like SetImage(), SetToggleState, SetDragArray..etc.
    Do I use them in the CreateLayout method?
    Do I use them in my InitValues method?
    Do I use them in my Message method?

    I don't even know if I'm supposed to use CUSTOMGUI_BITMAPBUTTON like I did. Or use CUSTOMDATATYPE_BITMAPBUTTON.
    I just used CUSTOMGUI_BITMAPBUTTON because it works with the DataTime GUI.

    I'm just generally confused about how I'm supposed to use everything.
    If I saw an example. It would probably answer a lot of these little questions I have about how, and where, everything needs to be.

    -ScottA



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

    On 23/08/2011 at 09:24, xxxxxxxx wrote:

    Okay, here's what I do in my smart IBL (sIBL) loader plugin. In that plugin I need a variable number of bitmap buttons in the dialog so the user can pick one sIBL set from the list by clicking the button. Here's the code which adds as many buttons as I need:

      
    void SIBLDialog::ShowThumbs(LONG counter, String stat)   
    {   
         BaseContainer lvbc, bitbc, msg;   
         BitmapButtonCustomGui *browser;   
         Filename thumb;   
         LONG i;   
      
         // set up the bitmap button container   
         bitbc.SetLong(BITMAPBUTTON_BORDER, BORDER_OUT);   
         bitbc.SetBool(BITMAPBUTTON_BUTTON, TRUE);   
         // the variable 'counter' is the number of buttons I need; the constant SIBL_GUI_BITBUTTON is just a placeholder ID value   
         for(i = 0L; i < counter; i++)   
         {   
              // add the thumbnails   
              browser = AddCustomGui(SIBL_GUI_BITBUTTON + i, CUSTOMGUI_BITMAPBUTTON, "", 0L, 128, 96, bitbc);   
              if(browser)   
              {   
                   thumb = presets[i].path + Filename(presets[i].icoFile);   
                   if(GeFExist(thumb))   
                        browser->SetImage(thumb, FALSE);   
              }   
         }   
    }   
    

    I've removed a lot of extraneous code to make it clearer. This code is called from multiple places. You can set up your bitmap buttons from CreateLayout() if they aren't going to change, or from wherever you like if they are.

    Can't help with SetToggleState() et., but SetImage() is very easy - it's overloaded and the one used here is the one which just takes a Filename class.

    With luck this will get you working so you can test the other functions.



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

    On 23/08/2011 at 11:59, xxxxxxxx wrote:

    Thanks Steve.

    I have SetImage() working now. So the next thing I need to know is how to change the image on the button when the button is clicked.
    Matthias once told me that Buttons should be used in the Message method. So I tried to do that. But it's not working.

    define PLUGIN_ID 1000006   // TESTING ID!!!!  be sure to use a unique ID obtained from www.plugincafe.com  
      
    #include "c4d.h"  
    #include "gui.h"  
    #include "c4d_symbols.h"  
    #include "lib_browser.h"  
    #include "customgui_datetime.h"  
    #include "customgui_bitmapbutton.h"  
    #include "../../resource/_api/c4d_customgui/customgui_bitmapbutton.h"  
      
      
    class myDialog : public GeDialog  
    {  
      private:  
          DateTimeControl *dt;          
          BitmapButtonCustomGui *myButton;  
      
      public:  
          myDialog(void);  
          virtual Bool CreateLayout(void);  
          virtual Bool InitValues(void);  
          virtual Bool Command(LONG id,const BaseContainer &msg);  
          virtual LONG Message(const BaseContainer &msg, BaseContainer &result);  
    };  
      
      
    myDialog::myDialog(void)  // The Constructor  
    {  
      //Not used in this example  
    }  
      
    Bool myDialog::CreateLayout(void)  
    {  
      SetTitle("Custom GUI Example");  
      
      GroupBegin(0,BFH_SCALEFIT|BFV_SCALEFIT,0,1,String(),0);      
      BaseContainer dtc, bbc; // Create the containers for the dateTime & BitmapButton GUI's     
      dt = (DateTimeControl* )AddCustomGui(10000,DATETIME_GUI,String(),BFH_SCALEFIT|BFV_SCALEFIT,0,0,dtc); // Adds the DateTime GUI to the dialog  
      GroupEnd();  
      
      GroupBegin(0,BFH_SCALEFIT|BFV_SCALEFIT,0,1,String(),0);  
      bbc.SetLong(BITMAPBUTTON_BORDER, BORDER_OUT);  
      bbc.SetBool(BITMAPBUTTON_BUTTON, TRUE);      
      myButton = (BitmapButtonCustomGui* )AddCustomGui(10001,CUSTOMGUI_BITMAPBUTTON,"MY BUTTON", 0L,120,120,bbc); //Adds the BitmapButton GUI to the dialog  
      Filename file1 = Filename("C:\\Users\\user\\Desktop\\image1.jpg");    //The file path to the initial button image  
      myButton->SetImage(file1, FALSE);  
      GroupEnd();  
        
      return TRUE;  
    }  
      
      
    Bool myDialog::InitValues(void){  
        
      if (!GeDialog::InitValues()) return FALSE;  
      //Not used  
        
      return TRUE;  
    }  
      
    Bool myDialog::Command(LONG id,const BaseContainer &msg)  
    {  
      //Not used  
      return TRUE;  
    }  
      
      
    LONG myDialog::Message(const BaseContainer &msg,BaseContainer &result)  
    {  
      ///////////////This is not working!!!//////////  
      
      switch (msg.GetId())  
      {     
         case 10001:  
                  GePrint("Button was Pushed");  
                  Filename file1 = Filename("C:\\Users\\user\\Desktop\\image2.jpg"); //swap the button's image with this one  
                  break;  
          
      }  
        
      return GeDialog::Message(msg,result);  
    }  
      
    class MyDateTime : public CommandData // MyDateTime is the class name that needs to be listed in the main.cpp to register it properly   
    {  
      private:  
          myDialog dlg;  
      
      public:  
          virtual Bool Execute(BaseDocument *doc);          
          virtual Bool RestoreLayout(void *secret);          
    };  
      
    Bool MyDateTime::Execute(BaseDocument *doc)  
    {  
      //return dlg.Open(DLG_TYPE_ASYNC_FULLSCREEN_MONITOR,ID_PLUGIN,0,0); // use for full screen if desired  
      return dlg.Open(DLG_TYPE_ASYNC,PLUGIN_ID, -1, -1, 300,150);      
    }  
      
    Bool MyDateTime::RestoreLayout(void *secret)  
    {  
      return dlg.RestoreLayout(PLUGIN_ID,0,secret);  
    }  
      
    Bool RegisterMyDateTime(void)  
    {  
      return RegisterCommandPlugin(PLUGIN_ID,GeLoadString(IDS_DateTime),0,AutoBitmap("icon.tif"),String("Date/Time Example"),gNew MyDateTime);      
    }
    

    Any idea what I'm doing wrong in my message method?

    -ScottA



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

    On 23/08/2011 at 14:08, xxxxxxxx wrote:

    I must admit I use GeDialog::Command, not GeDialog::Message, to respond to the button click, as per the SDK. Try that and see if it works.

    In any case, after you set File1 to the new image, you'll need to call SetImage again to set the new image.



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

    On 23/08/2011 at 14:58, xxxxxxxx wrote:

    Yes. It works and swaps the image if put the button call code in the Command method.

    This is why I get confused about using the Message method and the Command method.
    When I use the built in buttons to communicate a click event. Matthias told me to use the Message method so C4D updates when they are clicked. And it works.
    Yet in this case (as well as some other cases) . The click event has to happen in the Command method.
    I wish I had a better understanding of what's going on in those two methods. And why this is the case.

    I think I understand the basics of SetToggleState(). But I'm having trouble assigning it to a variable and using it as a way to check if the button has been clicked.

    And I also need to know how to handle the SetCallback() function.
    What it does and what it's used for....etc. That kind of thing.

    -ScottA



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

    On 24/08/2011 at 01:50, xxxxxxxx wrote:

    Perhaps Matthias, if he's reading this thread, could explain about the Command vs. Message functions in GeDialog?

    For me though the SDK is clear: Command is used when the user clicks on a gadget, Message for handling messages not covered by the other functions. In fact, the SDK specifically says that normally you don't need to override Message in a GeDialog.

    You've hit on a significant problem with the SDK with things like SetCallback. It isn't so much how to use it (though there's that too) but why you'd want to use it at all. Unless you're lucky enough to find an example in the SDK or here then you're working in the dark.



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

    On 24/08/2011 at 11:34, xxxxxxxx wrote:

    I've got the process of adding CustomGui's down now.
    It's a pretty simple process with a few steps of importing things from the customgui_ source files.
    But now I'm running into all kinds of things that don't seem to work as documented.
    Or at least as I'm interpreting them by following the docs in a literal manner.

    For example.
    The _BaseCustomGui example which is used for layout stuff does not work for me when I used what the docs say to use:

    Bool myDialog::CreateLayout(void)  
    {  
      BaseContainer bcBase; // Create the containers for Custom GUI's    
      SetTitle("Custom GUI Example");  
      
      GroupBegin(0,BFH_SCALEFIT|BFV_SCALEFIT,0,1,String(),0);      
      myBase = (_BaseCustomGui* )AddCustomGui(10006,CUSTOMGUI_LAYOUTMODE,String(),BFH_SCALEFIT|BFV_SCALEFIT,0,0,bcBase); // Adds the Base GUI to the dialog  
      GroupEnd();  
      
      return TRUE;  
    }  
      
    Bool myDialog::Command(LONG id,const BaseContainer &msg)  
    {  
      
      LONG width = myBase->GetWidth(PLUGIN_ID);       //Gets the width in pixels of the GUI  
      LONG mode = myBase->GetLayoutMode(PLUGIN_ID);   //Get the GUI's layout mode  
      GePrint(LongToString(width));                  // Results in zero!!??  
      GePrint(LongToString(mode));                   // Results in zero!!??  
      
      int layoutswitch = myBase->SupportLayoutSwitch(PLUGIN_ID); //Checks to see if layout switching is supported  
      GePrint(RealToString(layoutswitch));  
      
      
      switch (id)  
      {     
         case 10001:  
                  GePrint("Bitmap Button was Pushed");                  
          myButton->SetToggleState(TRUE);                                  
          Filename file1 = Filename("C:\\Users\\user\\Desktop\\image2.jpg"); //swap the button's image with this one  
          myButton->SetImage(file1, FALSE);                                  //This works as expected   
          LONG layoutmode = myBase->GetLayoutMode(PLUGIN_ID);  
              if (layoutmode==LAYOUTMODE_MAXIMIZED)    GePrint("Maximized");     // Does not work!!  
          myBase->SetLayoutMode(PLUGIN_ID, LAYOUTMODE_MINIMIZED);            //Does not work!!  
                  break;  
      }  
      
      
      switch (id)  
      {     
         case 10002:  
                  GePrint("Reset Button was Pushed");                              
          Filename file1 = Filename("C:\\Users\\user\\Desktop\\image1.jpg"); //swap the button's image with this one  
          myButton->SetImage(file1, FALSE);  
          myButton->SetToggleState(FALSE);      
                  break;        
      }  
        
      return TRUE;  
    }
    

    None of the layout stuff works.
    Everything returns a zero value as if it's not properly pointing to my dialog window.

    -ScottA



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

    On 30/08/2011 at 08:19, xxxxxxxx wrote:

    Sorry for the delay.

    This line makes no sense to me. What kind of cosuom GUI element do you want to add to your layout?

    myBase = (_BaseCustomGui* )AddCustomGui(10006,CUSTOMGUI_LAYOUTMODE,String(),BFH_SCALEFIT|BFV_SCALEFIT,0,0,bcBase);
    

    Also in response to Steve's question about buttons and Message vs. Command - it's important to keep in mind if you are using descriptions or dialogs. Buttons in descriptions are checked in Message, in dialogs you use Command instead.

    cheers,
    Matthias



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

    On 30/08/2011 at 09:02, xxxxxxxx wrote:

    Thanks Matthias. I think the initial question was whether to use GeDialog::Command or GeDialog::Message to respond to button clicks (I'd always used Command). But if Message can also be used to detect button clicks in a dialog, as Scott said worked for him, the question then, and I suppose it's a bit academic, is whether there is any difference to using these methods *within GeDialog*.

    Steve



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

    On 30/08/2011 at 14:59, xxxxxxxx wrote:

    I'm exploring all of the custom GUI stuff Matthias.
    Just generally trying to go through them all and create simple working examples of them so I can just copy and paste the code into my plugins when needed. Instead of having to spend the time to figure them out One-by-one. When I'm in the middle of writing an actual plugin.
    This would be sooooo much easier to learn if there were customGUI examples to learn from.

    In the example I posted. I wanted to click on my bitmap button and have the SetLayoutMode() function minimize my dialog window. I assume that's one of the things that SetLayoutMode()  does?
    But I keep getting zero return values from it when I click my button.

    Thanks for the Message() vs. Command() button info.

    -ScottA



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

    On 30/08/2011 at 21:37, xxxxxxxx wrote:

    You assume incorrectly.  SetLayoutMode() minimizes/maximizes "layout" groups within the dialog - in this case, the group belonging to the customgui.  Never assume...



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

    On 31/08/2011 at 03:37, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Thanks Matthias. I think the initial question was whether to use GeDialog::Command or GeDialog::Message to respond to button clicks (I'd always used Command). But if Message can also be used to detect button clicks in a dialog, as Scott said worked for him, the question then, and I suppose it's a bit academic, is whether there is any difference to using these methods *within GeDialog*.

    As mentioned checking button clicks in Message is only done for descriptions (NodeData::Message) not dialogs.

    cheers,
    Matthias



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

    On 31/08/2011 at 03:47, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    This would be sooooo much easier to learn if there were customGUI examples to learn from.

    I will try to get hold of some examples. Meanwhile there is a bit info on the forum. Also take a look at the datatype.cpp SDK example which is kinda related and shows how to write an own data type with an own GUI, although not really a custom GUI.

    cheers,
    Matthias



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

    On 31/08/2011 at 09:07, xxxxxxxx wrote:

    OK Thanks.
    And thanks for adding more examples in the C++ SDK docs. I've noticed that you've been adding some new ones in the recent updates.

    I can't just do a Google search for tutorials on this C4D API stuff like I can with raw C++. Or MS based API's. So SDK examples are very, very helpful.

    -ScottA


Log in to reply