Custom ColorField?



  • Hi,
    I have a GeUserArea drawing different objects, and would like to allow the user to specify a name and color for each of the objects.

    To avoid many user actions, I would like to open a single dialog box, which would contain an edit field for the name, and some ColorField components to specify the color.
    I would prefer not to have the user enter name via separate text edit field in one dialog, and a ColorField, opening another dialog.

    Is there a way to obtain ColorField components and use them as gadgets in a dialog box? Or other ways to combine color-gadgets with edit fields, checkboxes, buttons, etc... ?
    Or is the only solution to provide my own RGB, HSV color sliders, and/or colorwheel?

    Thanks,
    Daniel



  • Hi @C4DS,

    thank you for reaching out us. Assuming I do understand your question correctly, you should use GeDialog::AddColorChooser()(Link) instead of ::AddColorField(). The prior will give you the whole "color chooser thing", while the latter will only give you a colored rectangle. When you want to define your dialog as a resource, you will simply have to use the COLOR element, it should also work in dialog resources (haven't tried it myself though).

    edit: It will look something like this:

    Cheers,
    Ferdinand



  • @zipit
    Thanks for the info.
    I went with using:

    	Int32 flags = DR_COLORFIELD_NO_MODE_BUTTONS | DR_COLORFIELD_NO_PICTURE | DR_COLORFIELD_NO_BRIGHTNESS | 
    		DR_COLORFIELD_NO_KELVIN | DR_COLORFIELD_NO_RGB | DR_COLORFIELD_NO_HSV |
    		DR_COLORFIELD_NO_MIXER | DR_COLORFIELD_NO_SWATCHES | DR_COLORFIELD_NO_SCREENPICKER |
    		DR_COLORFIELD_ENABLE_SPECTRUM | DR_COLORFIELD_RGB_HIDE_HEX;
    	AddColorChooser(IDC_COLOR_CHOOSER, BFH_LEFT, 10, 10, flags, BaseContainer());
    
    

    and ended up with:

    ColorChooser.jpg

    Almost what I am looking for.
    However, I noticed that when right-mouse clicking the color gradient box, a popup allows to choose between small, medium, large size. By default the medium size is shown. How to control this.
    Is this done with the settings BaseContainer in some way? I couldn't find detailed information what these settings are, and how to control them.

    Also, is it possible to hide/remove the top color rectangle?
    Thanks again.



  • Hi @C4DS,

    no, I do not think that there is anything to find for you in the settings container. Internally there is only some very low-level stuff written into it and also the information you pass as the layoutflags, so it should probably be marked as private. The non-public ColorChooserGui, i.e., what is effectively at work for ::AddColorChooser and the recipient of theBaseContainer in question, is also not a monolithic thing, but rather split into many interfaces for all the bits and bobs that go into a color gui gadget of Cinema 4D. The size of the ColorInterfaceSpectrum, i.e. the "thing" in your screenshot, is stored locally in the interface and initially derived from the world settings container: GetWorldContainerInstance()->GetInt32(WPREF_COLOR_MODE_SPECTRUM_SIZE).

    The values there can be COLORSYSTEM_SIZE_SMALL, COLORSYSTEM_SIZE_MEDIUM and COLORSYSTEM_SIZE_LARGE. So technically you could write to the world settings container before you open your dialog and after that restore the old value; something like the Python script attached at the end. But as stated in the script itself, this is very much a workaround with probably unintended side effects.

    I also do not see a way to remove the "top color rectangle", which makes sense to me, since it is what you expand the GUI out from and into when it is being render in a description resource. So removing it would break the GUI there. Sorry, I don't really have a better answer for you.

    Cheers,
    Ferdinand

    """How to open a color chooser spectrum GUI with specified size in a dialog.
    
    This is very much a workaround I would say, which most likely has unintended 
    consequences while the dialog is open. All newly created or refreshed spectrum 
    interfaces will then be large, and even beyond the life time of the dialog 
    when they are not being refreshed after the dialog has closed.
    
    As discussed in:
    
        https://plugincafe.maxon.net/topic/13101/
    """
    
    import c4d
    
    class MyDialog (c4d.gui.GeDialog):
        """A dialog that opens with a large color spectrum gadget.
        """
        def __init__(self):
            """Constructor.
            """
            # Get the world settings and store the old value and set the
            # color spectrum size globally to large.
            self._worldSettings = c4d.GetWorldContainerInstance()
            self._oldSize = self._worldSettings.GetInt32(
                c4d.WPREF_COLOR_MODE_SPECTRUM_SIZE)
            self._worldSettings.SetInt32(
                c4d.WPREF_COLOR_MODE_SPECTRUM_SIZE,
                c4d.COLORSYSTEM_SIZE_LARGE)
    
        def __del__(self):
            """Destructor.
            """
            # Write the old value back. 
            self._worldSettings.SetInt32(
                c4d.WPREF_COLOR_MODE_SPECTRUM_SIZE,
                self._oldSize)
    
        def CreateLayout(self):
            """Adds a color chooser gadget with a spectrum field.
            """
            self.AddColorChooser(id=1, 
                                 flags=c4d.BFH_SCALEFIT,
                                 layoutflags=c4d.DR_COLORFIELD_ENABLE_SPECTRUM)
            return True
    
    
    if __name__=='__main__':
        global dialog
        dialog = MyDialog()
        dialog.Open(c4d.DLG_TYPE_ASYNC, xpos=-2, ypos=-2)
    


  • @zipit
    Thanks for the detailed info.
    Much appreciated!