[sdl] Add option to choose display screen (#16363)

This commit is contained in:
Clyde Stubbs
2026-06-04 04:18:16 +10:00
committed by GitHub
parent 3b0f669f47
commit 7b8cbe2de1
3 changed files with 57 additions and 7 deletions

View File

@@ -20,6 +20,7 @@ Sdl = sdl_ns.class_("Sdl", display.Display, cg.Component)
sdl_window_flags = cg.global_ns.enum("SDL_WindowFlags")
CONF_CENTERED_ON_DISPLAY = "centered_on_display"
CONF_SDL_OPTIONS = "sdl_options"
CONF_SDL_ID = "sdl_id"
CONF_WINDOW_OPTIONS = "window_options"
@@ -31,6 +32,8 @@ WINDOW_OPTIONS = (
"resizable",
)
SDL_WINDOWPOS_CENTERED_MASK = 0x2FFF0000
def get_sdl_options(value):
if value != "":
@@ -47,6 +50,20 @@ def get_window_options():
return {cv.Optional(option, default=False): cv.boolean for option in WINDOW_OPTIONS}
def _validate_position(config: dict) -> dict:
if CONF_CENTERED_ON_DISPLAY in config:
if CONF_X in config or CONF_Y in config:
raise cv.Invalid(
f"Cannot specify '{CONF_CENTERED_ON_DISPLAY}' with '{CONF_X}' and '{CONF_Y}' options"
)
return config
if CONF_X in config and CONF_Y in config:
return config
if CONF_X in config or CONF_Y in config:
raise cv.Invalid(f"Must specify both '{CONF_X}' and '{CONF_Y}' options")
raise cv.Invalid("Must specify either 'x' and 'y' or 'centered_on_display'")
CONFIG_SCHEMA = cv.All(
display.FULL_DISPLAY_SCHEMA.extend(
cv.Schema(
@@ -66,10 +83,13 @@ CONFIG_SCHEMA = cv.All(
{
cv.Optional(CONF_POSITION): cv.Schema(
{
cv.Required(CONF_X): cv.int_,
cv.Required(CONF_Y): cv.int_,
cv.Optional(CONF_X): cv.int_,
cv.Optional(CONF_Y): cv.int_,
cv.Optional(CONF_CENTERED_ON_DISPLAY): cv.int_range(
0, 128
),
}
),
).add_extra(_validate_position),
**get_window_options(),
}
),
@@ -105,7 +125,15 @@ async def to_code(config):
cg.add(var.set_window_options(create_flags))
if position := window_options.get(CONF_POSITION):
cg.add(var.set_position(position[CONF_X], position[CONF_Y]))
if (centered := position.get(CONF_CENTERED_ON_DISPLAY)) is not None:
cg.add(
var.set_position(
SDL_WINDOWPOS_CENTERED_MASK | centered,
SDL_WINDOWPOS_CENTERED_MASK | centered,
)
)
else:
cg.add(var.set_position(position[CONF_X], position[CONF_Y]))
if lamb := config.get(CONF_LAMBDA):
lambda_ = await cg.process_lambda(

View File

@@ -28,7 +28,7 @@ class Sdl : public display::Display {
this->height_ = height;
}
void set_window_options(uint32_t window_options) { this->window_options_ = window_options; }
void set_position(uint16_t pos_x, uint16_t pos_y) {
void set_position(int32_t pos_x, int32_t pos_y) {
this->pos_x_ = pos_x;
this->pos_y_ = pos_y;
}
@@ -54,8 +54,8 @@ class Sdl : public display::Display {
int width_{};
int height_{};
uint32_t window_options_{0};
int pos_x_{SDL_WINDOWPOS_UNDEFINED};
int pos_y_{SDL_WINDOWPOS_UNDEFINED};
int32_t pos_x_{SDL_WINDOWPOS_UNDEFINED};
int32_t pos_y_{SDL_WINDOWPOS_UNDEFINED};
SDL_Renderer *renderer_{};
SDL_Window *window_{};
SDL_Texture *texture_{};

View File

@@ -10,6 +10,28 @@ display:
dimensions:
width: 450
height: 600
window_options:
position:
x: 100
y: 100
- platform: sdl
id: second_display
dimensions:
width: 450
height: 600
window_options:
position:
centered_on_display: 1
- platform: sdl
id: third_display
dimensions:
width: 450
height: 600
window_options:
position:
centered_on_display: 0
binary_sensor:
- platform: sdl