Button slider (?)

Description

I am trying to figure out the best way to implement a button that you can slide up/down from to change a value. Something like a transparent slider that can only be “initiated” from the a button (?). The slide area could be across a whole screen

What MCU/Processor/Board and compiler are you using?

IMXRT1052

What do you want to achieve?

A button that can be slid up/down to change a value

What have you tried so far?

I tried a normal slider, but that is active across it’s entire range and can’t have other buttons “underneath” it.

Code to reproduce

N/A

Screenshot and/or video

So then why don’t you use roller object. I think it’s exactly what you need. If your value is on another label you can change it in the callback of roller by catching the appropriate event.

1 Like

Thanks, I will give it a try… I will need to see if it can be modified to not act like a list, without predefined options and animation.

It sounds like you are trying to replace the slider knob with a custom element, and disable the ability to touch the slider outside of the knob area?

Sort of. It would be like a slider where the bar is invisible and the bar moves instead of the knob.

This type of value slider is very common in UI for things like software synthesizers, where the user “grabs” a ui element like a knob or field and then moves across the whole screen to change the value. This saves space, instead of having a full slider where the knob moves over a bar.

can you show us an example in a clip or even picture? this can help to give a better answer. thanks.

Here is an example I could find, where the “button” is a knob, but the idea is the same:

Knob value slide

1 Like

Interesting. This should be doable by making the slider object invisible plus disabling the ability to touch it outside the knob.

Standard lvgl’s widget doen’t have it, but you maybe apply by the lvgl’s event to get position by manual and turn to your value as you want.

Like this one change lvgl’s signal / touch position to the value for some control.

1 Like

ok, I started to mess around with the roller object. Here is an example, just using styles to change the look.

I would like to eliminate the “roll” visual behaviour, but I couldn’t find the code where it actually draws this during the scroll (?) The number should just change, not move up/down.
Turning animation off didn’t get rid of the rolling.

It is also a bit wasteful to store numeric values as strings for the options, preferably I could just define a top and bottom value numerically.

Then you are probably looking for the spinbox widget. The roller is designed to be used with strings, not just numbers.

As far as I know, the roller is implemented with a tall label that is moved as you scroll. What we would need here is a way to snap it to certain points rather than having it follow the cursor.

I think starting with an invisible slider with a label drawn on top of it is simpler than any of the other solutions.

OK, the spinbox widget is close to what I need. Here is an attempt.

I’m still not sure which signal can be used to capture dragging outside of the object sized area, like the roller does. I am using the signal “LV_SIGNAL_PRESSING” Also the label area of the text area for the spinbox doesn’t throw the same signal. So if I click on the actual label, the event isn’t triggered.

Here is my code snippet for the spinbox event:

	else if (sign == LV_SIGNAL_PRESSING) {

		lv_point_t p;
		lv_coord_t h = lv_obj_get_height(spinbox);
		lv_indev_get_point(param, &p);

		int16_t tmp = 0;

		p.y -= spinbox->coords.y1; /*Modify the point to shift with half knob (important on the start and end)*/

		tmp = (int32_t) ((int32_t) p.y * (ext->range_max - ext->range_min + 1)) / (h);
		tmp = ext->range_max - tmp; /*Invert the value: smaller value means higher y*/

		if (tmp < ext->range_min)
			tmp = ext->range_min;
		else if (tmp > ext->range_max)
			tmp = ext->range_max;

		if (tmp > ext->drag_value) {
			ext->drag_value = tmp;
			lv_spinbox_increment(spinbox);
		} else if (tmp < ext->drag_value) {
			ext->drag_value = tmp;
			lv_spinbox_decrement(spinbox);
		}

	}

and a video of the behaviour:

OK, I got a bit further now. I had to modify the spinbox to propagate and handle the scroll signal.

Yesssss, i’d love this too!!!