save state of Color Chooser [SOLVED]



  • On 29/07/2016 at 10:57, xxxxxxxx wrote:

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

    ---------
    Hi! I'm implementing a CustomGuiData plugin and it works very good so far. It's a lot of work due to
    the many classes that are necessary, especially in combination with a new CustomDataType. Anyway,
    the custom GUI creates one of the new nifty Color Chooser widgets, the only problem is that everytime
    I change the value of my CustomDataType via the iCustomGui Dialog (in the Attributes Manager), the
    iCustomGui is re-allocated by Cinema 4D and thus CreateLayout() is called again, which ultimately
    causes the Color Chooser to reset to its initial state.

    Is there any way to save the state of the Color Chooser? Or maybe prevent Cinema from re-allocating
    the iCustomGui dialog when the value changed?

    Just in case I'm doing something wrong to notify C4D about the changed value, here's some code.
    The Command() function is the one inside my iCustomGui subclass.

      Bool Command(Int32 param, BaseContainer const& bc) override
      {
        ColorPaletteData* data = nullptr;
        switch (param) {
          case GADGET_USERAREA:
            nr::c4d::send_value_changed(this, bc);
            // TODO: this->Update(); ?
            break;
          case GADGET_NEWFOLDER:
            data = this->data.Get(true);
            if (data && data->AskNewFolder() != nullptr) {
              nr::c4d::send_value_changed(this, bc);
              this->Update();
            }
            return true;
          case GADGET_SHOWCOLORCHOOSER:
            data = this->data.Get(true);
            if (data) {
              data->show_chooser = !data->show_chooser;
              nr::c4d::send_value_changed(this, bc);
              this->Update();
            }
            return true;
        }
        return false;
      }
    

    And this is my send_value_changed() function (this notifies the holder of the iCustomGui about
    the changed value and will ultimately update the parameter that holds the CustomDataType in
    the BaseList2D node).

      /*!
       * This function takes over the process of informing the dialog that contains
       * the custom GUI that the value has been changed, ultimately updating the
       * parameter value via SetDParameter().
       *
       * Note that this function uses #iCustomGui::GetData() to read the new value.
       * This method is apparently unused in C4D SDK (as far as I can tell), but this
       * function makes use of it. :-)
       */
      inline Bool send_value_changed(iCustomGui* gui, BaseContainer msg = {})
      {
        msg.SetInt32(BFM_ACTION_ID, gui->GetId());
        msg.RemoveData(BFM_ACTION_VALUE);
        msg.SetData(BFM_ACTION_VALUE, gui->GetData().GetValue());
        return gui->SendParentMessage(msg);
      }
    

    Thanks in advance,
    Niklas



  • On 31/07/2016 at 04:50, xxxxxxxx wrote:

    Howdy,

    If you can you set the initial color of the chooser when it creates the layout, then couldn't you always save the current color into the plugin's world container and recall it when it creates the layout?

    Adios,
    Cactus Dan



  • On 31/07/2016 at 07:07, xxxxxxxx wrote:

    Hey Dan,

    sorry for not being clear enough. Saving the color in the world container
    is actually a very good idea. However, it's not only about the color but
    also about the layout information. The R17 Color Chooser has many
    features that you can toggle on and off. I want to save this state as well.

    Thanks,
    Niklas



  • On 01/08/2016 at 06:34, xxxxxxxx wrote:

    Hello,

    a custom GUI element can support switching the layout by defining the flag CUSTOMGUI_SUPPORT_LAYOUTDATA and reaction to the message BFM_GETCUSTOMGUILAYOUTDATA. The color chooser does support this so you could try to send this message to the GUI element to receive a BaseContainer with the current configuration.

    Best wishes,
    Sebastian



  • On 01/08/2016 at 08:37, xxxxxxxx wrote:

    Hello Sebastian,

    thanks that appears to be the right path! I do get a container returned

                GeData data= this->SendMessage(GADGET_COLORCHOOSER, BaseContainer(BFM_GETCUSTOMGUILAYOUTDATA));
                BaseContainer layout = *layout.GetContainer();
    

    Unfortunately I still have no idea how to restore the layout with the returned layout data.
    I've tried this, but it didn't work.

         layout.SetId(BFM_GETCUSTOMGUILAYOUTDATA);
          this->SendMessage(GADGET_COLORCHOOSER, layout);
    

    Thanks!
    Niklas



  • On 01/08/2016 at 09:01, xxxxxxxx wrote:

    Hello,

    it appears that the stored data has to be handed over to the GUI element during construction with AddCustomGui(). The stored data has to be saved in a sub-container with the ID CUSTOMGUI_SAVEDLAYOUTDATA.

    best wishes,
    Sebastian



  • On 01/08/2016 at 16:14, xxxxxxxx wrote:

    Thanks a lot Sebastian! It works perfect. :)

    Cheers,
    Niklas


Log in to reply