Better way of doing this? - "ComponentWalker"


#1

Suppose one sets the same settings again and again for many components, I found I can do it more easily via calling MyStyler().walk (this) in my root component, where MyStyler is defined as such:

class MyStyler : public ComponentWalker
{
public:
    ~MyStyler() {};
    void walk (Component*) override;
};

void MyStyler::walk (Component* component)
{
    component->setWantsKeyboardFocus (false);
    if (Slider* const slider = dynamic_cast<Slider*> (component))
    {
        if (slider->isRotary())
            slider->setVelocityBasedMode (true);
    }
    else if (DrawableButton* const button = dynamic_cast<DrawableButton*> (component))
        button->setColour (DrawableButton::backgroundOnColourId, Colours::transparentBlack);
    ComponentWalker::walk (component);
}

It sets the common settings for me. Here for example it enables velocity-based-mode for rotary sliders among other things.

And ComponentWalker is defined like this:

class ComponentWalker
{
public:
    virtual ~ComponentWalker() {}

    // Walk recursively iterates over all of the component's child components and their child components.
    // Subclasses may override this, for example to setMouseDragSensitivity on all Sliders, etc.
    //
    // Overriders should call ComponentWalker::walk when they wish to resume walking child components.
    virtual void walk (juce::Component*);
};

void ComponentWalker::walk (juce::Component* component)
{
    for (int i = 0; i < component->getNumChildComponents(); ++i)
        walk (component->getChildComponent (i));
}

Is there a better way to do this?


#2

Would recommend a lambda rather than a class for this kind of thing.


#3

Well there’s lots of ways you could do this, it really depends on how much flexibility you need and how many Components you have.

If you want to do it how you have but can use C++11 though, I would do this as a free function and a lambda as it’s a bit more flexible and doesn’t require sub-classing.