Skew friendly FilmStrip Knob

Hi guys,

this is a modification to a FilmStripKnob class posted in another thread, but that works with skewed sliders.


class FilmStripKnob : public Slider
{
public:
    FilmStripKnob(Image image, const int numFrames, const bool stripIsHorizontal)
    : Slider(),
    numFrames_(numFrames),
    isHorizontal_(stripIsHorizontal),
    filmStrip(image)
    {
        setTextBoxStyle(NoTextBox, 0, 0, 0);
        
        if (isHorizontal_) {
            frameHeight = filmStrip.getHeight();
            frameWidth = filmStrip.getWidth() / numFrames_;
        }
        else {
            frameHeight = filmStrip.getHeight() / numFrames_;
            frameWidth = filmStrip.getWidth();
        }
    }
    
    void paint(Graphics& g)
    {
        const float sliderPos = (float) valueToProportionOfLength(getValue());

        int value = sliderPos * (numFrames_ - 1);
        if (isHorizontal_) {
            g.drawImage(filmStrip, 0, 0, getWidth(), getHeight(),
                        value * frameWidth, 0, frameWidth, frameHeight);
        }
        else {
            g.drawImage(filmStrip, 0, 0, getWidth(), getHeight(),
                        0, value * frameHeight, frameWidth, frameHeight);
        }
        
        if (isMouseOverOrDragging())
        {
        }
    }
    
    int getFrameWidth() const  { return frameWidth; }
    int getFrameHeight() const { return frameHeight; }
    
private:
    const int numFrames_;
    const bool isHorizontal_;
    Image filmStrip;
    int frameWidth, frameHeight;
};
1 Like

Thank you!

HI Team,

I’m not that skilled in C++ so I am quite stuck on where to add this code into my project.
My App is very simple and literally just one volume slider.

I’ve been doing the hard work and reading, reading, reading but I’m still quite stuck.

May I please have some assistance as to where in the project this code needs to be added.
Would really appreciate the help :slight_smile:

Cheers.

Hi r4z0r and welcome to the forum!

Create a new file FilmStripKnob.h and put the code above in there. Additionally, add these lines on top of the file

#pragma once
#include <JuceHeader.h>
using namespace juce;

Now go over to your PluginEditor.h and include the file:

#include FilmStripKnob.h

under the private tag, add your knob to the editor:

private:
    FilmStripKnob m_volume_knob;

Ok. Now since the code above does not provide a default constructor, we need to use the initializer list of your PluginEditor. Head over to to PluginEditor.cpp and locate the Constructor in the first few lines. Add code, such that it looks like this:

TestKnobJuceForumAudioProcessorEditor::TestKnobJuceForumAudioProcessorEditor (TestKnobJuceForumAudioProcessor& p)
    : AudioProcessorEditor (&p), m_volume_knob(ImageCache::getFromFile(File("/path/to/your/image.png")), 128, false), audioProcessor (p)
{

Make sure of course to provide the correct values for your case in m_volume_knob(...).

Lastly, we need to make the knob visible inside your editor. Inside the constructor of the PluginEditor, add these lines after the comment:

    // Make sure that before the constructor has finished, you've set the
    // editor's size to whatever you need it to be.
    addAndMakeVisible(m_volume_knob);
    m_volume_knob.setBounds(150,100, 100, 100);

The knob should now appear in your GUI :slight_smile:
Disclaimer: I have not tested the code above, it is quite old already.

Hey there, just wondering what the valueToProportionOfLength function would be. Seems the most important part of your example that was omitted! Perhaps an inverse function for the one provided to the original NormalisableRange?

Nevermind, the solution using this code works perfectly! I didn’t realize valueToProportionOfLength was a built in Slider method.

 const float sliderPos = (float) valueToProportionOfLength(getValue());

        int value = sliderPos * (numFrames_ - 1);