Implementing an encoder with a switch

I’ve implemented an encoder component with a switch. This means I need to intercept both the clicking of the knob, and dragging it. I register the press on encoder release (and only if I don’t register a drag), to distinguish between clicks and drags.

class EncoderSwitch : public app::SvgKnob
{
   void onButton(const event::Button &e) override
	{
        if (e.action == GLFW_RELEASE)
        {
            // If not dragging, it's a button press
            if (!m_is_dragging)
			{
                // button press
				m_pressed = true;
            }
        }

        SvgKnob::onButton(e);
    }

    void onDragStart(const event::DragStart &e) override
	{
        m_is_dragging = true;
        m_previous_value = getParamQuantity()->getValue();
        SvgKnob::onDragStart(e);
    }

    void onDragMove(const event::DragMove &e) override
	{
        // do drag
    }
}

The issue I have is that if I call SvgKnob::onButton(e); inside onButton() I get the GLFW_PRESS event but never get the GLFW_RELEASE event. If I remove the call to SvgKnob::onButton(e); I get both GLFW_PRESS and GLFW_RELEASE messages but dragging is not registered. Why is onButton() consuming the future GLFW_RELEASE and how can I prevent it?

how come?

It’s modelling an encoder with a switch (i.e. a component that can be rotated and pressed), so I want to detect dragging and treat that as turning the encoder, and detect releasing the button (when not dragging) and treat that as pressing the switch. They need to be separate actions, which is why I can’t treat the GLSW_PRESS event as a click of the switch (as it will also occur when dragging starts which should turn the encoder).

ah, got it. I guess I would tend to make something like that as a fully custom widget. But that’s just how I do it, not saying it’s the best way. For example:

1 Like

Befaco Noise Plethora has a knob with encoder, press and long press - maybe you can lift it.

pachde1 implements clicky knobs. Supports differentiated behaviors for Shift/Ctrl modifiers.

See the implementation here: src/components.hpp Line 132

I see their implementation handles everything within the onDragX() set of virtual functions, and doesn’t intercept the onButton() event. I’ll try that, thanks!

That approach worked, thanks!

1 Like