Regarding the GUI, many components should offer direct methods for UI customization, without necessarily relying on the LookAndFeel class.
You can create a class that inherits from one of the components, and then override the paint() function. This is probably the most direct method currently available.
It could be nice to have something where you pass a lambda as the paint function, but that would also be easy enough to create yourself if you needed it.
It is something requested from years…
I’m not sure — maybe it could be extended rather than replaced? I mean, keeping the existing LookAndFeel, but implementing the new methods behind the scenes
Any approach to improve LnF would have be welcomed ; Now we have WebView UI! ![]()
With the following wrapper/mixin, you can easily obtain a derived class from any existing Component subclass, with a onPaint member added that you can assign a lambda to (and onPaintOverChildren with the same semantic).
/** Adds to a Component a std::function member that is called when its paint()
method is invoked.
Usage example:
```
auto label = WithLambdaPaint <juce::Label> ("my label", "Some text");
label.onPaint = [this] (Graphics& g)
{
g.setColour (Colours::green);
g.fillRect (label.getLocalBounds ().reduced (10));
paintBaseClass (g);
};
```
*/
template <typename BaseComponent>
class WithLambdaPaint : public BaseComponent
{
public:
using BaseComponent::BaseComponent; // import the same constructors of the base class
public:
/** When this member has a value, the `paint()` callback of this class
invokes it and returns. In that case, it's up to the assigned functional to
call the paint behaviour of `BaseComponent`, if desired.
Because `paint()` is a protected function of JUCE Components, the public
`paintBaseClass()` function is provided, which can be called in place of
`BaseComponent::paint()` where needed.
When this member has no value, the `paint()` callback of this class invokes
`BaseComponent::paint()` directly, preserving the existing behaviour of
`BaseComponent` when it is not customized via `onPaint`. */
std::function <void (juce::Graphics&)> onPaint;
void paintBaseClass (juce::Graphics& g)
{
BaseComponent::paint (g);
}
std::function <void (juce::Graphics&)> onPaintOverChildren;
void paintOverChildrenBaseClass (juce::Graphics& g)
{
BaseComponent::paintOverChildren (g);
}
public: // overridden methods
void paint (juce::Graphics& g) override
{
if (onPaint)
onPaint (g);
else
BaseComponent::paint (g);
}
void paintOverChildren (juce::Graphics& g) override
{
if (onPaintOverChildren)
onPaintOverChildren (g);
else
BaseComponent::paintOverChildren (g);
}
};
