Menu's Slider Quantity snappy?

Hi,

is it possible to have the Menu’s Slider Quantity snap to integer intead of keep in float?

Here’s my code, which only display the “integer” part:

struct DelaySlider : rack::Quantity {
	MyModule *pModule;

	DelaySlider(MyModule *module) : pModule(module) {
	}

	void setValue(float value) override {
		value = clamp(value, getMinValue(), getMaxValue());
		if (pModule) {
			pModule->setDelay(value);
		}
	}
	float getValue() override {
		if (pModule) {
			return pModule->getDelay();
		}

		return getDefaultValue();
	}

	float getMinValue() override { return pModule->kDelayMsMin; }
	float getMaxValue() override { return pModule->kDelayMsMax; }
	float getDefaultValue() override { return pModule->kDelayMsDefault; }
	float getDisplayValue() override { return std::round(getValue()); }
	void setDisplayValue(float displayValue) override { setValue(displayValue); }
	std::string getLabel() override { return "Milliseconds"; }
	std::string getUnit() override { return ""; }
};

But I clearly see the slider move “floating” instead of “snappy” (for 10 values, for example). i.e. the value changing is continuous.

Can’t do round(), since it become “freeze” (probably because I should move the mouse higher, in a way I can snap to the next integer zone).

What’s the correct way to do this?

No one about this? Thanks :slight_smile:

Have you tried doing your quantization in the SetValue? Simply changing the display value isn’t changing the underlying value. I’m guessing that the display value is used just for the numeric display, and the value of the slider/knob position is the underlying value (which is why it isn’t “steppy”). Caveat: This is sheer speculation and I haven’t looked at the Rack code to see what it’s doing. Loking at the Rack could be heklpful to to figure out how to get knobs and sliders with steps and also provide the steppy feedback.

I suspect it may be difficult to make the slider jump in discrete steps, but its value can certainly be snapped to integer values. There are modules that use knobs to snap to integer values (like the octave setting in Vult Basal. Although its knob moves smoothly, it breaks its range into integer steps. I’m sure something like this would work with sliders also.

1 Like

Not really. I can use/see knob that “snap” also visually, and doesn’t move smoothly. Not on slider thought, maybe some limits?

Are you saying that you have seen existing modules that do this with knobs? Can you give an example of one that is open source? If so, we should be able to study its source code to figure out what it is doing. I know that is easier said than done because it often takes digging through the VCV Rack source code also, in order to understand how it works.

I would be willing to help if you can point me to an existing module’s source code that does what you want.

Just set snap = true on the Knob, and it will act visually this way. But its at Knob Level, way deeper rather than rack::Quantity.

Yes, exactly. Here’s one of mine:

struct Blue30SnapKnob : RoganSLBlue30
{
    Blue30SnapKnob()
    {
        snap = true;
        smooth = false;
    }
};

But I don’t know if I’ve ever seen a snapping slider…

1 Like

@DerozerDSP and @Yeager, that is cool, and I’m learning new stuff here too. I can see that Count Modula has created his own type RotarySwitch:

// Rotary switch base - values are limted to whole numbers
template <typename TBase>
struct RotarySwitch : TBase {
	RotarySwitch() {
		this->snap = true;
		this->smooth = false;
	}
	
	// handle the manually entered values
	void onChange(const event::Change &e) override {
		
		SvgKnob::onChange(e);
		
		this->getParamQuantity()->setValue(roundf(this->getParamQuantity()->getValue()));
	}
};

And he passes in a type that derives from Knob for the template parameter TBase.

When I look up the code for Knob, I find the following inside it:

	/** Enables value snapping to the nearest integer.
	Alternatively, use ParamQuantity::snapEnabled.
	*/
	bool snap = false;

And it turns out slider widgets are based on SliderKnob, which in turn derives from Knob.

So you do have an inherited Knob::snap member inside your slider widget. What happens when you set it to true?

I don’t have a Slider Widget, I’m dealing with a Right Click->Menu Sliders widget, which is basically a rack::Quantity.

Taken from this: how to implement context menu slider? - #10 by rsmus7

Check the LLFO module, on Right Click panel :slight_smile: , so you’d get what I’m looking for…

OK, I missed that you were talking about sliders in a right-click menu. Sorry about that! Yes, I don’t see any built-in support for snapping there, as you mention. It should be possible, however it will require some work. My best guess is you should derive a custom class from Slider, then look at how Knob implements snap and do something similar.