Skinning the Slider / Replacing knob and slider track with PNGs

I moved this line initializing cachedImage_faderknob_png to the constructor of the class:

cachedImage_faderknob_png = ImageCache::getFromMemory (faderknob_png, faderknob_pngSize);

Once I moved it there, I got a compile error saying these were undefined:  cachedImage_faderknob_png, faderknob_png, faderknob_pngSize.

Also, I moved the Image faderknob to inside the class.  I tried it both inside the constructor and after the destructor in an attempt to clear the compile errors mentioned above.

I did everything else suggested in the post, exactly as they are.  I tried applying it to all of the children instead of a particular slider, since that seems a little more straight-forward.

This is my entire [MiscUserDefs] section now:

//[MiscUserDefs] You can add your own user definitions and misc code here...
#ifndef __JUCE_LookAndFeelCustom_JUCEHEADER__
#define __JUCE_LookAndFeelCustom_JUCEHEADER__
class LookAndFeelCustom : public LookAndFeel_V3 // inherit from LookAndFeel_V3
        Image faderknob;
        cachedImage_faderknob_png = ImageCache::getFromMemory (faderknob_png, faderknob_pngSize);
    virtual ~LookAndFeelCustom();
    Image faderknob;
    /* Now we created an exact copy of the base class LookAndFeel_V3. It "inherited" all the functionality of LookAndFeel_V3, now we extend it with our own functionality by overwriting the original functionality. E.g: */
    // overwrite the original drawRotarySlider with out own
    virtual void drawLinearSliderThumb    (        Graphics &     g,
                                                int     x,
                                                int     y,
                                                int     width,
                                                int     height,
                                                float     sliderPos,
                                                float     minSliderPos,
                                                float     maxSliderPos,
                                                const Slider::SliderStyle,
                                                Slider & slider )
        g.drawImageWithin(cachedImage_faderknob_png, OriginOffset-tmpF/2.0f, OriginOffset-1.25f*tmpF/2, tmpF, tmpF, RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, false);
#endif   // __JUCE_LookAndFeelCustom_JUCEHEADER__

Checked in introjucer, even though there were the compile errors going on.  Still those sliders are looking the same.

All help has been and will be very appreciated, whether it is specific ideas or on how to approach this.  Right now I am reading books and watching videos on C++, trying out things for many hours, then when it seems hopeless, I do a forum post.  I've been working on trying to skin the sliders for about three weeks now.

1 Like

Check your private messages :)

yeah, I'm going to have to agree with Sean here, even though I'm not as much a minamalist as he is :)

I have a lot of experience working on UIs for audio products (one of the companies mentioned in the thread--which doesn't use Juce), and even though we've started to move away from skeumorphism, the fact of the matter is that the tools for working with raster graphics are just better and more flexible.

Jules, please don't assume that anyone who wants filmstrips wants hardware-looking knobs. I just want to design a nice looking (flat actually) set of widgets and I'm tearing my hair out trying to implement it with Juce because it's not built around the idea of using PNGs, which sometimes is just the right tool for the job from a designer's perspective.



I want to agree strongly with Sean’s point that JUCE “should not reflect a fixed set of aesthetics”. Skeuomorphic is a particular style of raster graphic manipulation and I’ve seen both excellent and Hideous examples of skeuomorphic design. I personally am designing a product intended to run on Mac and PC platforms that is targeted at singers, many of who from my experience are computer-phobic.
Giving them an interface which feels more like an “appliance” than a “computer program” goes a long way at overcoming their phobia. Going strictly for a “flat” aesthetic seems to totally overlook a huge dimension of the user experience, particularly for music related products where users are likely to have aesthetic sensibilities, perhaps more than the normal computer user.
I have some guitars that are made of rosewood. It is beautiful. When I pick it up and play it that rosewood is a significant part of my experience. A flat aesthetic to me would be analogous to spray painting that beautiful guitar silver because it was a “cleaner interface”.
I argue for getting away from the nasty taste the overuse and examples bad skeuomorphic has left in some peoples mouth and calling it “raster graphic manipulation” or something similar.

1 Like

Just because you’re using vector does not mean, that you design must be flat:

The Design was done in Adobe Illustrator, exported to svg and then re-constructed dynamically in my look and feel class. It’s quite involved - but well worth it in my opinion. Now I have realistic looking knobs that can be used at any size.

EDIT: And as an added bonus, it’s not to hard to export screenshots to PDF for inclusion in your user manuals - this way even your screenshots are searchable and look beautiful in all sizes :slight_smile:


PixelPacker : Super Thanks for your input, and your graphics look excellent! If your code is not proprietary, I’d very much like to see what you are doing and use any classes you may have developed, If it’s somewhere “in between” be happy to know the price.

1 Like

It’s not only proprietary, but also messy :slight_smile:

What I did was to auto.generate a c++ class from the SVG file that contains the definitions for all the paths and gradients and is able to draw the whole thing. Then I split the draw method up into different parts (draw_knob_scale(), draw_knob_lower(), draw_knob_handle()) and modified them so that rotation is applied correctly. For example the shape of the knob rotates, while the highlight-gradient stays fixed.

If I had to do it again (and I probably will at some point), I’d try to use Drawable::createFromSVG() and then modify the resulting hierarchy of Drawables before calling paint() on it.

The key to success here is a clean design in illustrator that does not use additive blending and is structurally simple.

If you’re interested I can ask the artist who did the design if he’s available.



Sure, if the artist is available, it would be nice to have

that option.

Thanks for the input!


PS: Seems to me like there might be room for a

“hybrid” where the fixed gradient was a raster graphics

with limited opacity… but, then you Loose the Beauty

of the Vector Graphics scalability….

Be nice to see an official JUCE version along the lines

of what you implemented……

I don’t understand what you mean by hybrid. What I meant is the following: if you rotate the knob, the gradient rotates with it. What I did is to rotate the gradient in the opposite direction so that it stays fixed. So it’s still all vector.

Despite that: graphics with not much detail, like highlight gradients and drop shadows might just look fine when scaled up, as they are quite smooth to start with.

1 Like

Did you ever find the solution to displaying a PNG thumb?

1 Like

both links are dead

Howdy. I like your thorough questions. It appears this is an old post but based on your questions I would recommend you getting a c++ book. You want to understand what object oriented programming is about. specificaly, look into inheritance and subclassing. These are ways to take some code and extend it.

Im sure youve learned much since your post :slight_smile:

life saver

It’s an 8 year old post and predates the new form :stuck_out_tongue:

Search is your friend:

1 Like

Hey Jules,

I have removed my previous comment as at the time I was burnt out from reading doco and endless posts trying to understand the philosophy of modern plug-in UI design.

For some reason I thought you were only supportive of flat UI design where in actual fact it’s vector based design which is your ethos.

Anyway I’m much the wiser now and ready to flex my design skills in JUCE.

Thank you very much for this frame work.


1 Like

Hey Pixel,

So are you saying after making the knob designs, you hand coded the drawing dimensions into the Slider look and feel member functions within the JUCE frame work?


I’m not prepared to answer most of your question, but these are both definitely using vector graphics. Mostly seems like just shapes and gradients to me! Some spots on that UAD plugin (and many other UAD plugins) have fake little scratches which I suspect to be a mostly transparent image overlay, but you really don’t need to use images to get this sort of look.

You might ask “but it will take me so long to design knobs this good looking” True, but if you can design them in indesign, you can also (probably) render them in JUCE using mostly standard JUCE classes. If you intend to create a filmstrip by taking photos of an actual knob, sure. Perfectly replicating a real knob is going to be much easier with a camera, some good editing skills, and a filmstrip. But that’s not really ever done in commercial plugins, and could only possibly look worse than spending some time designing good skeuomorphic knobs.

1 Like

My point is not that I want to do things the old way (filmsstrip is just what I first came across) and am happy to learn the modern methods of creating vector based UI elements. (I’ve been reading a lot this evening and much more up to date on modern UI graphics methodologies).

My point is if I was to create my own (or get a designer) to create industry standard vector assets. I don’t see anything in the documentation on how to implement my own ui content.
It seems I need to develop my own code and it feels as though I am hacking the framework which may break in future updates.

1 Like

Not at all, you need to write your own code because you’re customizing the framework! Most likely all you need to do is override one of the LookAndFeel classes, then provide an instance of that LAF to your sliders/buttons/etc. But to create custom behavior, you need to write custom code! If you do this right, you won’t write anything which would break in updates. Basically, most JUCE drawing code is done with a Graphics& instance that you draw onto with Graphics:: methods, or methods provided by other classes which take Graphics& as arguments. The API for Graphics is very unlikely to remove any functionality, as that would likely break most in-progress JUCE projects. It has been largely the same API for a very long time at this point (although implementations sometimes do change, which is good! That’s what an abstraction like Graphics is for).

You really don’t need to look far to find this: most widget classes have LookAndFeelMethods which describe what you can customize about them. In the JUCE codebase, there are 4 look and feels, which you can look at for examples.

You’re not hacking the framework by using it! You need to write code to use it. No reason to fear that.

There’s even a tutorial for this here

1 Like

Hey Zac,

Ok that’s fantastic information, thank you.
I think it’s my past IT experience (I’m an IT systems engineer and not a software engineer by background) that’s given me the mindset of not altering code that is not supported by the vender per say. I have been burnt before with patches.

Also sorry I had the impression that the philosophy of JUCE was flat UI only. I realize now this is not the case, and it’s actually Vector design only, which with clever design techniques like Pixel has done above, you can achieve very impressive UI assets that really pop.

Anyway that is great news.
As you can most likely tell, I’m a newbie to this field and am somewhat ignorant but I’m not here to be spoon fed.
I’ll brush up on my C++ and get my head heavily into the frame work and doco.

Stoked as I love this frame work.

Thanks again.

1 Like