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

    Passing a String value to GeUserArea [SOLVED]

    SDK Help
    0
    11
    1.0k
    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 05/07/2017 at 06:12, xxxxxxxx wrote:

      Hi,

      we are a bit confused by your description. A GeUserArea doesn't have a type.
      Can you please explain in a bit more detail, what you want to achieve?

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

        On 05/07/2017 at 11:20, xxxxxxxx wrote:

        Hello and sorry for explaining it poorly.

        I have a iCustomGui which has a user area attached.

        Bool CreateLayout(void){
        	Bool res = GeDialog::CreateLayout();
        	my_gadget = AddUserArea(10000, BFH_SCALEFIT|BFV_SCALEFIT);
        	if (my_gadget )
        		AttachUserArea(my_user_area, my_gadget );
        	return res;
        }
        

        The variable my_user_area is defined in .res file as:
        LONG MY_PARAM { CUSTOMGUI MYPARAMCUSTOMGUI; }

        I have defined MYPARAMCUSTOMGUI as LONG, which is what I want.

        LONG custom_gui_type_table[] ={
        	DA_LONG
        };
          
        LONG GetResourceDataType(LONG*& table){
        	table = custom_gui_type_table;
        	return sizeof(custom_gui_type_table) / sizeof(Int32);
        }
        

        Now, the user area draws an image using DrawBitmap. I want to allow the user to change the image by loading a different one.
        To do that, I need to pass the new filename into the user area.
        So, inside the SetDParameter of a TagData plugin, I need to update the filename into my GeUserArea.

        Thank you very much for your time !

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

          On 07/07/2017 at 07:32, xxxxxxxx wrote:

          Hi,

          sorry, this took a bit longer. It was an interesting question, which then in the end turned out to be easier to achieve, than expected.

          So, I set up a CustomGUI for a string data type. In CreateLayout() of the iCustomGui implementation I added a BitmapButtonCustomGui to represent your image. The key is in the iCustomGui constructor, there you get a settings BaseContainer, which is actually a Description BaseContainer. Here I store the path to be found in the settings container in a member variable for later use in CreateLayout(), where I set the image of the BitmapButton after adding the actual button.

          In order to be able to set the image via resource file I added a property CUSTOMTYPE_STRING to the propertries table returned by CustomGuiData::GetProperties(). The ID of this property is also the ID to be used, when reading the filename from the settings BaseContainer.

          For testing purposes I used an ObjectData with a string parameter using the CustomGUI and an additional Filename parameter. In GetDDescription() you basically do the same as when adding or modifying a Description. Roughly like so:

          		const DescID* singleid = description->GetSingleDescID();
          		DescID	cid = DescID(DescLevel(OBJECTSTRINGWITHIMAGE_PARAM_STRINGWITHIMAGE, DTYPE_STRING, 0));
          		Filename fn = bc->GetFilename(OBJECTSTRINGWITHIMAGE_PARAM_FILENAME);
          		if (fn.Content()) // if filename parameter is empty, the default set for IMGFILENAME in resource file will be used
          		{
          			if (!singleid || cid.IsPartOf(*singleid, nullptr))
          			{
          				BaseContainer settings = GetCustomDataTypeDefault(DTYPE_STRING);
          				settings.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_STRINGWITHIMAGE);
          				settings.SetString(ID_STRINGWITHIMAGE_PROP_IMGFILENAME, fn.GetString()); // Read this in iCustomGui constructor
          				description->SetParameter(cid, settings, ID_OBJECTPROPERTIES);
          			}
          		}
          

          And that's about it. When the Filename parameter gets changed, the image of the String CustomGUI changes accordingly.

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

            On 17/07/2017 at 07:21, xxxxxxxx wrote:

            Hello and thank you for your answer.

            Right now I have defined this parameter in .res file as LONG:

            LONG MY_PARAM { CUSTOMGUI MYPARAMCUSTOMGUI; }
            

            To set and get its value using data instance I do the following:

            BaseContainer* data = baselist2d->GetDataInstance(); //checks are skipped for this example
            data->SetInt32(MY_PARAM, 32);//example
            

            How can I do that if MY_PARAM parameter is both LONG and STRING ?
            Does the following work ?

            //Can I use the same param ID for 2 types ?
            data->SetInt32(MY_PARAM, 32);
            data->SetString(MY_PARAM, "testing string");
            

            Your code uses GetDDescription to add the param dynamically. Can I do without using GetDDescription ?
            Also, I need to be able to modify the image path in SetDParameter.

            e.g.

            switch (id[0].id) {
            	case OTHER_STRING_PARAMETER: {
            		String new_path = t_data.GetString();
            		data->SetInt32(MY_PARAM, 32); 
            		data->SetString(MY_PARAM, new_path);
            		break;
            	}
            }
            

            Can I do the above ?

            Thank you for your time Andreas !

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

              On 18/07/2017 at 02:58, xxxxxxxx wrote:

              Hm, maybe I misunderstood your first posts, but I thought it was a CustomGUI for LONG type. And additionally you had the need to pass a string/filename to the CustomGUI so it shows some image.

              What I tried to demonstrate in my post, you can pass additional data via the description container to your CustomGUI. And my example also works with the parameter defined in a resource file. I just use GetDDescription to pass the extra data by "modifying" the description.

              As the values are stored in a BaseContainer under a certain ID, you can not store two values of different type under the same ID, but I tried to show with my post, that this is not actually needed.

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

                On 18/07/2017 at 05:41, xxxxxxxx wrote:

                Hello and thank you very much for your help.

                Here is what I did.

                Description:

                const DescID* single_id = description->GetSingleDescID();
                DescID cid = DescID( DescLevel( USER_AREA_PARAM, DTYPE_LONG, 0 ) );
                if ( !single_id || cid.IsPartOf(*single_id, NULL) ) {
                	BaseContainer settings = GetCustomDataTypeDefault(DTYPE_LONG);
                	settings.SetLong(DESC_CUSTOMGUI, USER_AREA_PLUGIN_ID);
                	settings.SetString(IMAGE_PATH_STRING, image_filename);
                	if (!description->SetParameter(cid, settings, DescLevel(GROUP_PARAM_ID))) {
                		return FALSE;
                	}
                }	
                

                Property table and type:

                static CustomProperty table_properties[] = {
                	{ CUSTOMTYPE_END, 0, 0 }
                };
                  
                LONG table_type[] = {
                	DA_LONG
                };
                

                In iCustomGui Constructor:
                image_path = settings.GetString(IMAGE_PATH_STRING);

                In iCustomGui CreateLayout:
                //AddUserArea
                //AttachUserArea(user_area, ....);
                user_area.setImagePath(image_path);

                As it is right now, it works exactly as I want.
                The problem is that since I have to load a new image based on the path, it happens constantly every time the layout is changed.

                Can I use SetDParameter to set a value in IMAGE_PATH_STRING of USER_AREA_PARAM ?
                It feels like I have to use a CustomDataType.

                Thank you for your time !

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

                  On 18/07/2017 at 05:44, xxxxxxxx wrote:

                  Can't you just compare against the last path used (maybe also file date)?

                  But yes, if you want to be able to use SetDParameter() in order to set the string and the integer, you will have to come up with your own datatype consisting of both components.

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

                    On 18/07/2017 at 06:22, xxxxxxxx wrote:

                    Originally posted by xxxxxxxx

                    Can't you just compare against the last path used (maybe also file date)?

                    I'll keep the path in a member in the ObjectData that has the user area parameter. Once this parameter is changed, I'll listen to MSG_DESCRIPTION_POSTSETPARAMETER to compare the previous value with the new one. I'll also copy the path member in CopyTo.

                    I cannot keep the member in the gadget since it is constantly created from scratch everytime the layout is changed.

                    Thank you.

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

                      On 19/07/2017 at 06:04, xxxxxxxx wrote:

                      I'm not quite sure, if there's still an issue left or if you have found a solution that suits you?

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

                        On 20/07/2017 at 00:03, xxxxxxxx wrote:

                        Hello.

                        I mark it as solved.

                        Thank you again Andreas !

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