Skip to content

lv_encoder_emu

lv_encoder_emu

Soft rotary-encoder emulator for LVGL on non-MCU runtimes.

Stand-in for hardware machine.Encoder / rotaryio while developing on desktop (SDL/PG), PyScript, or Jupyter. Each :class:EncoderEmu owns:

  • a :class:SoftEncoder (position + pushbutton state)
  • an eventsys :class:~eventsys.EncoderDevice registered on runtime
  • an LVGL emulator UI (← / Enter / →) on a secondary displaysys surface, in a private focus group (not the app default)

Multiple emulators may coexist in one app (one window/canvas each)::

from board_config import runtime
import display_driver  # primary LVGL first
from lv_encoder_emu import EncoderEmu

emu_a = EncoderEmu(runtime, title="Enc A")
emu_b = EncoderEmu(runtime, title="Enc B")
# emu_a.device / emu_b.device are LVGL encoder indevs on the primary display

Classes

SoftEncoder

SoftEncoder(pos=0)

Position / button state for runtime.add_encoder read callbacks.

Same contract apps use with MCU machine.Encoder / rotaryio: a wrapping position integer and a boolean pushbutton.

Methods:
read_pos
read_pos()

Zero-arg callable for runtime.add_encoder(read=...).

read_button
read_button()

Zero-arg callable for runtime.add_encoder(button_read=...).

EncoderEmu

EncoderEmu(runtime, *, display=None, attach_devices=None, title='Encoder', width=240, height=80, scale=1, canvas_id=None, button=DEFAULT_ENCODER_BUTTON, target_lv_display=None, soft=None)

One emulated encoder: secondary surface + LVGL UI + eventsys device.

Call after import display_driver so the primary LVGL display exists. The encoder indev is attached to target_lv_display (default: primary).

Parameters:

Name Type Description Default
runtime

board_config.runtime (or any :class:eventsys.Runtime).

required
display

Existing secondary displaysys driver, or None to create one.

None
attach_devices

Host devices for display_driver.attach (PS/JN); ignored when display is created by :func:make_emu_display.

None
title, width, height, scale, canvas_id

Forwarded to :func:make_emu_display when creating a display.

required
button

Mouse button index for the encoder switch (default 3, matching display_driver._encoder_cb).

DEFAULT_ENCODER_BUTTON
target_lv_display

LVGL display that receives the encoder indev; default is the primary LVGL display.

None
soft

Optional existing :class:SoftEncoder; created when omitted.

None
Attributes
soft property
soft

:class:SoftEncoder state (position / button).

device property
device

Registered eventsys :class:~eventsys.EncoderDevice.

display property
display

Secondary displaysys driver for the emulator surface.

bridge property
bridge

display_driver.DisplayDriver for the emulator LVGL display.

group property
group

LVGL group owning the emulator buttons (not the app default).

root property
root

Root LVGL object of the emulator UI.

Functions:

make_emu_display

make_emu_display(primary=None, *, width=240, height=80, title='Encoder', scale=1, canvas_id=None)

Create a same-backend secondary display for an encoder emulator.

Parameters:

Name Type Description Default
primary

Primary displaysys driver (default: board_config.display_drv).

None
width, height

Emulator panel size in pixels.

required
title

Window title (SDL/PG).

'Encoder'
scale

PGDisplay scale (ignored by other backends).

1
canvas_id

PyScript canvas DOM id (default aux_canvas). Each emulator needs a distinct id when using more than one PS surface.

None

Returns:

Name Type Description
tuple

(display, attach_devices) where attach_devices is

None (desktop reuses runtime.host_dev) or a list of host

devices for PyScript/Jupyter.