Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    How to change a real slider's max value

    SDK Help
    0
    11
    950
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 01/02/2014 at 17:58, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   13,14,15 
      Platform:   Windows  ;   
      Language(s) :     C++  ;

      ---------
      Hi, I try to change a real slider's max value when the user changes the status of a checkbox. But after I have changed the value, t he slider behaves strange. The normal real real editor box behaves normal.

      Bool MyTag::GetDDescription (GeListNode* node, Description* description, DESCFLAGS_DESC &flags)
      {
          DescID cid = DescLevel(MYTAG_REAL_VALUE, DTYPE_REAL, 0);
          BaseContainer bc = GetCustomDataTypeDefault(DTYPE_REAL);
          bc.SetLong(DESC_CUSTOMGUI, CUSTOMGUI_REALSLIDER);
          bc.SetLong(DESC_UNIT, DESC_UNIT_PERCENT);
          bc.SetLong(DESC_MAX, 100);
          bc.SetLong(DESC_MAXSLIDER, 100);
          bc.SetLong(DESC_MIN, 0);
          bc.SetLong(DESC_MINSLIDER, 100);
          bc.SetString(DESC_NAME, "Foo");
          description->SetParameter(cid, bc, DescLevel(0));
      }
      

      The code is somewhat simplified.
      I am sure I do something wrong here. Because I just want to change a specific parameter. But if I do not include the " bc.SetLong(DESC_CUSTOMGUI, CUSTOMGUI_REALSLIDER)", no slider appears.
      So I definitely do something wrong, since the slider already is defined in the RES file, I just want to alter the MAX values for both the Real and for the Slider.

      Anyone who knows how to do this correctly?

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 02/02/2014 at 13:20, xxxxxxxx wrote:

        Hi,
        I really think it would be a good idea if you delete the second thread you created about this. Because it will be confusing to have two threads running for the same question.

        Here's an example of how to dynamically change the max value of a dynamically created slider:

        Bool SimpleTag::GetDDescription(GeListNode *node, Description *description,DESCFLAGS_DESC &flags)  
        {      
          BaseContainer *data = ((BaseList2D* )node)->GetDataInstance();       //Get the container for the tag  
          if(!description->LoadDescription(node->GetType())) return FALSE;    //Loads the .res file stuff  
          
          //Get the state of the checkbox and assign it to a local variable  
          //NOTE: The checkbox is created in the .res file  
          Bool enabled = data->GetBool(MYBOX);  
          
          //Set up some logic that changes the max value depending if the checkbox is pressed  
          LONG dynamicMax;  
          if(enabled) dynamicMax = 10;  //If the checkbox is enabled the max value will be 1,000  
          else dynamicMax = 1;          //If the checkbox is not enabled the max value will be 100  
          
               
          //Create a dynamic slider gizmo here without using the .res file at all   
          //Mixing the .res file with this code will just make it more confusing than it needs to be!   
          DescID sliderId = DescLevel(MYSLIDER, DTYPE_REAL, 0);   //Assign the slider GUI item to this description variable  
          BaseContainer sliderBC = GetCustomDataTypeDefault(DTYPE_REAL);  
          sliderBC.SetLong(DESC_CUSTOMGUI, CUSTOMGUI_REALSLIDER);  
          sliderBC.SetReal(DESC_STEP, 0.01);  
          sliderBC.SetLong(DESC_UNIT, DESC_UNIT_PERCENT);  
          sliderBC.SetLong(DESC_MAX, dynamicMax);                 //<--- Use the dynamic value here  
          sliderBC.SetLong(DESC_MAXSLIDER, dynamicMax);           //<--- Use the dynamic value here  
          sliderBC.SetLong(DESC_MIN, 0);   
          sliderBC.SetLong(DESC_MINSLIDER, 0);  
          sliderBC.SetString(DESC_NAME, "Foo");  
          //sliderBC.SetBool(DESC_HIDE, enabled);   //<--- Use this to hide the slider if desired  
          description->SetParameter(sliderId, sliderBC, DescLevel(ID_OBJECTPROPERTIES));  
            
          
          flags |= DESCFLAGS_DESC_LOADED;  
          return TRUE;  
        }
        

        If you would like the entire plugin to play around with.
        Send me an e-mail at: [email protected].  And I'll zip it up and send it to the address you send me.

        -ScottA

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 02/02/2014 at 13:40, xxxxxxxx wrote:

          Originally posted by xxxxxxxx

          Hi,
          I really think it would be a good idea if you delete the second thread you created about this.

          Done.

          Thanks for the code!
          What you really do here, is creating a new control.
          I had thought it would be possible just to alter one parameter, and leave the rest as described in the RES file. 
          Like this:

              const DescID* singleDesciptionId = description->GetSingleDescID();
              DescID customDataTypeId = DescLevel(FOO_ID, DTYPE_GROUP, 0);
              if (!singleDesciptionId || customDataTypeId.IsPartOf(*singleDesciptionId, NULL)) 
              {
          		BaseContainer bc = GetCustomDataTypeDefault(DTYPE_GROUP);
          		bc.SetString(DESC_NAME, "Foobar");
          		description->SetParameter(customDataTypeId, bc, DescLevel(0));
              }
          

          But my impression that I am altering just one parameter may be wrong? Am I creating a new group? The controls inside the group remain though..
          This is what I wanted, use what is there as described in the RES file, and just alter what needs to be altered, nothing more, nothing less.

          Mail is on its way!

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 02/02/2014 at 13:52, xxxxxxxx wrote:

            You could probably mix them without a problem.
            Having some things set in the .res file and some things set in the .cpp file for the same gizmo.
            But trying to keep track of what's where like that could potentially make you crazy trying to find a bug in a more complicated setup.

            The main reason I try to do everything in one or the other as much as possible. Is just a personal preference. To keep things organized.

            -ScottA

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 02/02/2014 at 13:57, xxxxxxxx wrote:

              Originally posted by xxxxxxxx

              You could probably mix them without a problem.

              When I try to use just one of the values, like the DESC_MAXSLIDER or the DESC_MAX, the slider control disappears. Other misbehaves in other ways.

              Apart from that, I agree with what you say, it might complicate things, although I in this particular case do this only once in the complete plugin, and what I want to alter is only the DESC_MAXSLIDER and the DESC_MAX parameters.

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 03/02/2014 at 07:24, xxxxxxxx wrote:

                Hi Ingvarai,

                you can obtain the description container of a parameter via the Description::GetParameterI() method.
                The returned pointer to a BaseContainer can be altered and it will be reflected in the resulting description.
                Keep in mind that NodeData::GetDDescription() always creates a new Description and does never operate
                on a previous state of the node's description.

                Best,
                -Niklas

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 03/02/2014 at 10:28, xxxxxxxx wrote:

                  Hi Niklas, thanks for your reply!
                  I am, however, sorry to say that I am as far (short) as I was when I started this thread.
                  Please look at this code:

                  This works, I am able to show and hide the control
                  Example A

                  Bool ShowDescriptionElement(GeListNode* node, Description* descr, LONG MyDescID, Bool show)
                  {
                      AutoAlloc<AtomArray> ar;
                      if(!ar) return FALSE;
                      ar->Append(static_cast<C4DAtom*>(node));
                     BaseContainer* bc = descr->GetParameterI(DescLevel(MyDescID), ar);
                      if(bc)
                      bc->SetBool(DESC_HIDE, !show);
                   }
                  

                  This does not work , I am not able to set the name (change the caption) of the control
                  Example B

                  Bool SetDescriptionElementName(GeListNode* node, Description* descr, LONG MyDescID, String  name)
                  {
                      AutoAlloc<AtomArray> ar;
                      if(!ar) return FALSE;
                      ar->Append(static_cast<C4DAtom*>(node));
                     BaseContainer* bc = descr->GetParameterI(DescLevel(MyDescID), ar);
                      if(bc)
                      bc->SetString(DESC_NAME, name);
                   }
                  

                  It is obvious that I am doing it wrong here. But I am using GetParameterI as you suggested. I would be very interested in finding out what is wrong with Example B!

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 03/02/2014 at 12:08, xxxxxxxx wrote:

                    Because the AM displays the DESC_SHORT_NAME property, not DESC_NAME

                    Best,
                    -Niklas

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 03/02/2014 at 14:00, xxxxxxxx wrote:

                      Ok, as usual I feel a little silly and stupid, having worked with this on and off for 24 hours now.
                      And as usual, the solution is simple, when you know it.
                      Here is the answer to my original question in this thread:

                      Bool MyTag::GetDDescription (GeListNode* node, Description* description, DESCFLAGS_DESC &flags)
                      {
                              BaseContainer* bc = descr->GetParameterI(DescLevel(FOO_REAL_SLIDER), NULL);
                              if(bc)
                              {
                                        bc->SetLong(DESC_MAX, 2);
                                        bc->SetLong(DESC_MAXSLIDER, 2);
                              }  
                      }
                      

                      The code will set the MAX value to 200% and the Max Slider value to 200%, since the unit in this case is percent.
                      And this code can certainly be optimized for performance, since C4D will call it more than necessary. 
                      But it works!
                      I hope this will be of help to to others, who just need to change description element values at runtime. And I am not looking forward to the next time I run into an unsolved task which has a solution that is so hard to find [for me], and at the same time has a super simple solution ..

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 03/02/2014 at 15:45, xxxxxxxx wrote:

                        You could've known if you were more into the software. When creating User Data, you have the
                        option to set separate values for the short and long name of the property. The name is displayed in
                        the Attributes Manager while the long name is used in XPresso (for instance). The SDK doc page
                        about the Description class contains all the description property IDs, DESC_NAME and
                        DESC_SHORT_NAME listed as the first two.

                        Best,
                        -Niklas

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          On 03/02/2014 at 17:27, xxxxxxxx wrote:

                          Originally posted by xxxxxxxx

                          You could've known if you were more into the software.

                          If worked for Maxon, I would not need this forum 🙂
                          I really miss a C4D Plugin Writer's Wiki. Where I can look up how-to articles, code snippets for common tasks, etc. I think we all could benefit from such a thing. A Wiki.

                          I program a lot (it is my profession), and whenever a problem, a particular issue comes up in C#, I have the solution in minutes. Because the universe is full of code examples on how to carry out all imaginable tasks in C#. And a whole bunch of unimaginable tasks too, to boot.

                          In Cinema 4D on the other hand.. Even the simplest tasks, like in this case, alter a specific property of a control, takes hours, days, to find out about. Well, I do not know. Making it so difficult is perhaps one reason C4D is so rock solid and stable. Because only the most stubborn programmers have the patience to write a complex plugin. The others have fallen off the wagon long before something works..

                          What happens now - i build up my own skills, my own library of reusable code snippets and common methods. And while they come in handy for me, often, others seldom will benefit from my knowledge. Unless there is  post here in the forum I feel I have the solution to.

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post