Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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

    'Nth' button press

    SDK Help
    0
    12
    1.6k
    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

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

      On 20/05/2012 at 21:17, xxxxxxxx wrote:

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

      ---------
      Hi folks,
       
      how do I get a button message happening for a button that's created in a dynamically added group?
       
      For instance, if a user has added two groups, how do I target the button press coming from the second group?

      //############################################################  
      //--                Dynamic Group Button  
      //############################################################  
      DescriptionCommand *dc_Group_Button = (DescriptionCommand* )data;  
      LONG Button_Group_Button = dc_Group_Button->id[0].id;  
      switch (Button_Group_Button)  
      {  
      case ID_TAB_GROUP_BUTTON:  // I can add +1 here, but this then only actions the ID_TAB_GROUP_BUTTON+1 ID button...  
        {  
        GePrint("nth button pressed...");  
        break;  
        }  
      }
      

      I'm just not sure how to implement the 'nth' button number into the Message() command... I tried experimenting with ID_TAB_GROUP_BUTTON+i (and manually set i=2 just for testing purposes) but it then wouldn't compile because it didn't like the +i being there. Any ideas?
       
      WP

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

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

        On 21/05/2012 at 07:16, xxxxxxxx wrote:

        When you create buttons dynamically, you usually increase their ID by one. If the Message's ID is within the range of

        (first_button_id - last_button_id) + 1 == n_buttons

        then the "Nth" button pressed is

        pressed_button_id = (message_id - first_button_id)

        Hope that helps. ^^
        Best,
        Niklas

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

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

          On 22/05/2012 at 05:59, xxxxxxxx wrote:

          Hi Niklas,
           
          thanks for you response. I can now get the "Nth" button press count, but I'm still having troubles getting this to work through the case ID.
           
          If I add the "Nth" button press long number to the ID_TAB_GROUP_BUTTON long then I get a compile error "case expression not constant". So the case isn't like having a variable long added to it.
           
          How do I deal with that part?
           
          EDIT: example of how I was using the nth count number:

          //############################################################  
          //-- Dynamic Group Button  
          //############################################################  
          DescriptionCommand *dc_Group_Button = (DescriptionCommand* )data;  
          LONG Button_Group_Button = dc_Group_Button->id[0].id;
          LONG Button_Number = Button_Group_Button - 4800; // 4800 is the starting ID for the dynamic button  
          switch (Button_Group_Button)  
          {  
          case ID_TAB_GROUP_BUTTON+Button_Number: // compile error here because the ID is not constant
          {  
          GePrint("Button pressed is number " + LongToString(Button_Number));  
          break;  
          }  
          }
          

          WP.

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

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

            On 22/05/2012 at 06:42, xxxxxxxx wrote:

            Hi WickedP,

            A case statement cannot be an expression in C++, because it is translated into a jump-table (with
            constant addresses => no expressions supported). Use if/else if/else instead. 🙂

            Best,

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

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

              On 22/05/2012 at 19:37, xxxxxxxx wrote:

              Aha!
               
              Thanks Niklas! I spent some time yesterday doing some general c++ research on the matter but I wasn't having a very good day yesterday medically so things probably weren't clicking. This morning it makes more sense - and is working!!
               
              For anyone else, working code:

              //############################################################  
              //--                Dynamic Group Button  
              //############################################################  
              DescriptionCommand *dc_Group_Button = (DescriptionCommand* )data;
              LONG Count = Data->GetLong(ID_TAB_GROUP_BUTTON);  // Data = basecontainer data...  
              LONG Button_Group_Button = dc_Group_Button->id[0].id;
              if((Button_Group_Button >= 4801) && (Button_Group_Button <= 4800 + Count))
              {
                  GePrint("Button ID press is " + LongToString(Button_Group_Button))
                  break;
              }
              else
              {
                  break;
              }
              

              EDIT: just something to note for others - be mindful with my code here that the break; in the else{} will prevent other commands from happening that are listed after this button call. So don't use break their if you intend on having other msg elements that come after this in your  code.
               
              Thanks again,
               
              WP.

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

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

                On 23/05/2012 at 07:24, xxxxxxxx wrote:

                Howdy,

                Just out of curiosity, why not keep count of how many buttons the user has added, and then cycle through them in a for() loop to see which one was clicked?

                Adios,
                Cactus Dan

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

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

                  On 23/05/2012 at 07:38, xxxxxxxx wrote:

                  @Cactus: That would be kind of too much, wouldn't it? Do you take a measuring tape and run 4 rounds 'round the career to measure the length of 4 rounds instead of just using simple mathematics?

                  Best,
                  Nik

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

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

                    On 23/05/2012 at 07:48, xxxxxxxx wrote:

                    Howdy,

                    Actually no. Cycling through the buttons is VERY fast, so there's no hit on performance.

                    For example:

                    switch (type)
                    {
                    	case MSG_DESCRIPTION_COMMAND:
                    	{
                    		DescriptionCommand *dc = (DescriptionCommand* ) data;
                    		LONG i, count = data->GetLong(ID_BUTTON_COUNT);
                    		for(i=0; i<count; i++)
                    		{
                    			if(dc->id[0].id == ID_BUTTON+i)
                    			{
                    				//process button click
                    			}
                    		}
                    	}
                    }
                      
                    
                    

                    ... works like a charm.

                    Adios,
                    Cactus Dan

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

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

                      On 23/05/2012 at 08:27, xxxxxxxx wrote:

                      There is a difference in performance, but not noticeable. You'd need to add a lot of thousands of
                      buttons to recognize it.
                      However, imho this is not an elegant solution. If you have 100 buttons and the User presses the
                      last one, you have 99 redundant loops with if-clauses in it.

                      Cheers,
                      Niklas

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

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

                        On 23/05/2012 at 08:48, xxxxxxxx wrote:

                        Howdy,

                        Yes that's true. And I would be concerned about that kind of if() statement in a loop if it were in an expression calculation that is called constantly on every refresh. But for a single button click that is a one time call, I wouldn't worry so much about the performance.

                        You could add a check to see if the DescriptionCommand is within the buttons' range of maximum allowed buttons:

                        switch (type)
                        {
                        	case MSG_DESCRIPTION_COMMAND:
                        	{
                        		DescriptionCommand *dc = (DescriptionCommand* ) data;
                        		if(dc->id[0].id >= ID_BUTTON && dc->id[0].id < ID_BUTTON+MAX_BUTTON_COUNT)
                        		{
                        			LONG i, count = data->GetLong(ID_BUTTON_COUNT);
                        			for(i=0; i<count; i++)
                        			{
                        				if(dc->id[0].id == ID_BUTTON+i)
                        				{
                        					//process button click
                        				}
                        			}
                        		}
                        	}
                        }
                        

                        ... so that it's not cycling through the buttons every time the Message() function receives a MSG_DESCRIPTION_COMMAND message. But other than that, I wouldn't be as concerned about it.

                        I remember reading an article about code optimization that suggested to optimize only where optimization is needed. So, after reading that article I stopped trying to optimize everything. 😉

                        Adios,
                        Cactus Dan

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

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

                          On 23/05/2012 at 09:33, xxxxxxxx wrote:

                          I really like it when people post their ideas. Even when/if they are not considered "optimal".
                          Because after you learn the basics of coding. You spend most of your time searching for approaches to solve a problem.
                          Seeing the way other people think helps me to think in ways that I otherwise would not even think about. And for me...seeing how other people approach a problem is where the real value is.
                          I often have more questions about how to approach a certain problem. Rather than how to write the actual code for it.
                          So please keep posting stuff like this Dan(and everyone). 🍺

                          Here's yet another way to do the same thing.
                          Not a "better" one. Just a different approach:

                          Bool SimpleTag::Message(GeListNode *node, LONG type, void *data)  
                          {  
                            
                            BaseTag *tag = (BaseTag* )node;                //Get the tag and assign it to a variable  
                            BaseContainer *bc = tag->GetDataInstance();   //Get the container for the tag  
                            
                            //BaseContainer *bc = ((BaseList2D* )node)->GetDataInstance(); //Another way of Getting the tag's container  
                            
                            switch (type)  
                              {          
                                case MSG_DESCRIPTION_COMMAND:                           //MSG_DESCRIPTION_COMMAND is send when button is clicked  
                                {              
                                    DescriptionCommand *dc = (DescriptionCommand* )data; //Data contains the description ID of the button             
                                    LONG button = dc->id[0].id;                         //Get the ID of the button that's pressed  
                                GePrint("Button id= " + LongToString(button));      //prints the button's ID number  
                                LONG nth = button - 1001;                           //Gets the nth button value in the list of buttons(assuming that the first button's ID value is 1002)  
                                GePrint("Nth Button " + LongToString(nth));  
                                                  
                                    switch (button) // check for different button IDs  
                                    {  
                                        case BUTTON1:  
                                            GePrint("Button1 was pushed");  
                                            bc->SetReal(MYNUMERIC, index+1);  //Adds a new slider to the tag  
                                            break;  
                            
                                        case BUTTON2:  
                                            GePrint("Button2 was pushed");  
                                            break;  
                                    }  
                                }  
                              }  
                             
                            tag->SetDirty(DIRTYFLAGS_DATA); //Used to update a Tag's AM GUI items  
                            return TRUE;  
                          }
                          

                          -ScottA

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

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

                            On 23/05/2012 at 09:41, xxxxxxxx wrote:

                            Howdy,

                            Just as the old saying goes, "There's more than one way to skin a cat." 😉

                            Adios,
                            Cactus Dan

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