add icons to dynamic cycle in description resource



  • On 09/05/2013 at 02:46, xxxxxxxx wrote:

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

    ---------
    Hi,

    i have a description resource with a cycle element, and i need to extend that cycle dynamically in my plugin code.

    It's working well with the code below, but now i also want to add icons to the cycle items.
    Does anybody know how to do this ?

    I already tried to do it similarly to the AsyncDialog SDK-Example, but that one has a Dialog instead of a Resource file, so it's a little defferent and the method does not work in my case..

    here's the code, the interesting part is in the for loop :

    // get cycle-container from description
    		BaseContainer*    bc =        description->GetParameterI(CLONE_LAYER, NULL);
    		if(bc==NULL) return;		
      
    		bc->SetParameter(DESC_NAME, GeData("Layer"));
    		BaseContainer layerCycle;
    		// add static cycle items
    		layerCycle.SetParameter(0L, GeData("none"));
    		layerCycle.SetParameter(1L, GeData("new parent layer"));
      
    		// add dynamic cycle items
    		LONG layerCounter = 2L;		
    		for(unsigned int i=0;i<layerList.size();i++){
    		    IconData layerIcon;
    		    layerList[i]->GetIcon(&layerIcon);
    		    layerCycle.SetParameter(i+2L,GeData(layerList[i]->GetName()+"&"+PtrToString(&layerIcon)+"&"));
    		    // how to add an icon to this item ?
      
    		}
      
    		// put cycle back into the description
    		bc->SetParameter(DESC_CYCLE, GeData(layerCycle));
    

    This is to be a layer picker that should always display all layers in the doc with their corresponding colors plus two additional options.

    thanks,
    Daniel



  • On 09/05/2013 at 03:32, xxxxxxxx wrote:

    What you need is the Cyclebutton CustomGui.

    Here are some convenience functions I used in one of my plugins for that. Maybe a bit out of context for your purpose, but I hope you can use it.

      
    static Bool IsSingleID(const DescID &id;, const DescID *singleid)   
    {   
         return !singleid || id.IsPartOf(*singleid,NULL);   
    }   
      
    static Bool AddCycleButton(Description *dc, LONG id, const String &name;, const DescID &groupid;, const BaseContainer &names;, const BaseContainer &icons;)   
    {   
         const DescID* singleid = dc->GetSingleDescID();   
      
         if (!singleid || IsSingleID(id, singleid))   
         {   
              BaseContainer bc=GetCustomDataTypeDefault(DTYPE_LONG);   
      
              // Set CycleButton properties   
              bc.SetString(DESC_NAME, name);   
              bc.SetLong(DESC_DEFAULT, 0);   
              bc.SetContainer(DESC_CYCLE, names);   
              bc.SetLong(DESC_SCALEH, FALSE);   
              bc.SetBool(DESC_ANIMATE, DESC_ANIMATE_OFF);   
              bc.SetContainer(DESC_CYCLEICONS, icons);   
              bc.SetLong(DESC_CUSTOMGUI, CUSTOMGUI_CYCLEBUTTON);   
      
              // Create CycleButton   
              return dc->SetParameter(DescLevel(id, DTYPE_LONG, 0), bc, groupid);   
         }   
         return TRUE;   
    }   
    

    Use them like this:

      
    Bool MyObject::GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags;)   
    {   
         // Load description (user interface)   
         if (!description->LoadDescription(node->GetType())) return FALSE;   
         flags |= DESCFLAGS_DESC_LOADED;   
      
         BaseContainer names;   
         BaseContainer icons;   
      
         names.SetString(0, "Item 1");   
         icons.SetLong(0, ID_OF_SOME_REGISTERED_ICON);   
      
         names.SetString(1, "Item 2");   
         icons.SetLong(1, ID_OF_SOME_OTHER_REGISTERED_ICON);   
      
         if (!AddCycleButton(description, MYOBJECT_CYCLEBUTTON_1, GeLoadString(IDS_MYOBJECT_CYCLEBUTTON_1), DescID(MYOBJECT_CYCLEBUTTONGROUP), names, icons)) return FALSE;   
      
         return TRUE;   
    }   
    


  • On 09/05/2013 at 05:08, xxxxxxxx wrote:

    Hi Frank,

    I just tried i using your method using registered icon id's like 'Osphere' and it works great indeed!

    So the next question would be if there is a way to get the id of the layer icons in the scene ?

    Or is there maybe another way to pass the IconData from layer->GetIcon() directly into
    the DESC_CYCLEICONS Container ?

    Registering an icon with a unique id from PluginCafe for every layer in the scene does seem a little inconvenient ;-)

    updated code:

    // get cycle-container from description
    		BaseContainer*    bc =        description->GetParameterI(CLONE_LAYER, NULL);
    		if(bc==NULL) return;		
      
    		bc->SetParameter(DESC_NAME, GeData("Layer"));
    		BaseContainer cycleNames;
    		BaseContainer cycleIcons;
    		// add static cycle items
    		cycleNames.SetParameter(0L, GeData("none"));
    		cycleIcons.SetParameter(0L, GeData(Ocube));		// test-icon-id
    		cycleNames.SetParameter(1L, GeData("new parent layer"));
    		cycleIcons.SetParameter(1L, GeData(Osphere));	// test-icon-id
      
    		// add dynamic cycle items
    		LONG layerCounter = 2L;		
    		for(unsigned int i=0;i<layerList.size();i++){			
      		    // set cycle item name
    		    cycleNames.SetParameter(i+2L,GeData(layerList[i]->GetName()));
      
    		    // cycle item icon
    		    IconData layerIcon;
    		    layerList[i]->GetIcon(&layerIcon);
    		    // which id to use for this layer icon ?						
    		    //cycleIcons.SetParameter(i+2L, );			
    		}
    		// put cycle names and icons back into the description
    		bc->SetParameter(DESC_CYCLE, GeData(cycleNames));
    		bc->SetParameter(DESC_CYCLEICONS, GeData(cycleIcons));
    


  • On 10/05/2013 at 02:21, xxxxxxxx wrote:

    I must admit, I don't know. But those icons have to come from somewhere, so I guess they are registered. Which icons do you mean, anyway? Layers don't have icons. Do you mean the icons for switching stuff on and off in the Layer Manager? If you can't find out about those icon IDs, a hacky but working solution might be to copy the icons you need (or create your own) and register them with unique IDs.

    By the way, I have written two articles about the CYCLE and icon topic on the c4dprogramming blog. One about the CYCLEBUTTON customgui, and one about the simple .res-based solution for normal LONG CYCLEs. The code I gave you for this has also been a bit optimized and compacted.
    http://c4dprogramming.wordpress.com/2013/05/10/the-cyclebutton-customgui/
    http://c4dprogramming.wordpress.com/2013/05/10/long-cycles-with-icons-and-separator/



  • On 12/05/2013 at 00:20, xxxxxxxx wrote:

    Hi,

    actually i mean the color icon that each layer has, i assume thats the IconData i can when i call 
    layer->GetIcon(&iconData) but these i cannot put into the DESC_CYCLEICONS Container it seems.

    Your Coding Blog is great btw, been checking it out a couple times!


Log in to reply