Using ParameterAttachment to link toggles to UI Elements

Hey everyone! I’ve been trying to link a toggle button in my code to the Image strip I use for my sliders. I’ve had a look into Parameter Attachments but have absolutely no idea how to implement them, even afer looking throught the example projects.

The code for my RasterKnob and BypassButton classes are below, hopefully you can understand what i’m trying to achieve!

RasterKnob

class RasterKnob : public juce::Slider
{
public:
	RasterKnob() : juce::Slider(SliderStyle::RotaryHorizontalVerticalDrag, TextEntryBoxPosition::NoTextBox)
	{
		setMouseCursor(MouseCursor::PointingHandCursor);
		setLookAndFeel(&mainSliderLookAndFeel);
		
	}

	~RasterKnob()
	{
		setLookAndFeel(nullptr);
	}

private:

	class RasterKnobLookAndFeel : public juce::LookAndFeel_V4
	{
	public:
		RasterKnobLookAndFeel()
		{
			image = juce::ImageCache::getFromMemory(BinaryData::LittlePhatty_png, BinaryData::LittlePhatty_pngSize);
			byImage = juce::ImageCache::getFromMemory(BinaryData::LittlePhatty_OFF_png, BinaryData::LittlePhatty_OFF_pngSize);
		}

		void drawRotarySlider(
			juce::Graphics& g,
			int x,
			int y,
			int width,
			int height,
			float sliderPosProportional,
			float /*rotaryStartAngle*/,
			float /*rotaryEndAngle*/,
			juce::Slider& /*slider*/) override
		{
			const auto frames = 101;
			const auto frameId = static_cast<int>(ceil(sliderPosProportional * (static_cast<float>(frames) - 1.0f)));
#
			// image is vertical strip, each frame is 1/100th of the height

			// if apvts.getRawParameterValue("BYPASS")->load() == true then draw byImage
			// else draw image
			bp = true;
			
			if (!bp) {
				g.drawImage(image,
					x,
					y,
					width,
					height,
					0,
					frameId * image.getHeight() / frames,
					image.getWidth(),
					image.getHeight() / frames);
			}
			else {
				g.drawImage(byImage,
					x,
					y,
					width,
					height,
					0,
					frameId * byImage.getHeight() / frames,
					byImage.getWidth(),
					byImage.getHeight() / frames);
			}
		}


	private:
		juce::Image image;
		juce::Image byImage;
		bool bp;

		JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RasterKnobLookAndFeel)
	} mainSliderLookAndFeel;

	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RasterKnob)
};

BypassButton


class BypassButton : public juce::ToggleButton
{

public:
	BypassButton() : juce::ToggleButton("")
	{
		setLookAndFeel(&mainButtonLookAndFeel);
		setImage();
	}

	~BypassButton()
	{
		setLookAndFeel(nullptr);
	}

	void setImage()
	{
		offImage_ = ImageCache::getFromMemory(BinaryData::Toggle_png, BinaryData::Toggle_pngSize);
		onImage_ = ImageCache::getFromMemory(BinaryData::Toggle1_png, BinaryData::Toggle1_pngSize);
	}

	void paintButton(Graphics& g, bool isMouseOver, bool isButtonDown) override
	{
		const auto frameId = static_cast<int>(getToggleState());
		const auto image = frameId ? onImage_ : offImage_;
		g.drawImage(image, getLocalBounds().toFloat());


	}

private:
	juce::Image offImage_;
	juce::Image onImage_;



	class BypassButtonLookAndFeel : public juce::LookAndFeel_V4
	{
	public:
		BypassButtonLookAndFeel()
		{
		}

		void drawTickBox(Graphics& g, Component& component,
			float x,
			float y,
			float w,
			float h,
			bool ticked,
			bool isEnabled,
			bool isMouseOverButton,
			bool isButtonDown) override
		{
			// Do nothing, we're not drawing a tick box
		}

	private:
		JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(BypassButtonLookAndFeel)
	} mainButtonLookAndFeel;

	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(BypassButton)
};