diff --git a/lib/pbio/include/pbsys/light.h b/lib/pbio/include/pbsys/light.h index 44c491568..3ef0be1f6 100644 --- a/lib/pbio/include/pbsys/light.h +++ b/lib/pbio/include/pbsys/light.h @@ -17,8 +17,18 @@ extern pbio_color_light_t *pbsys_status_light_main; #endif #if PBSYS_CONFIG_HUB_LIGHT_MATRIX + #include + extern pbio_light_matrix_t *pbsys_hub_light_matrix; + +void pbsys_hub_light_matrix_free_display(void); + +#else // PBSYS_CONFIG_HUB_LIGHT_MATRIX + +static inline void pbsys_hub_light_matrix_free_display(void) { +} + #endif #endif // _PBSYS_LIGHT_H_ diff --git a/lib/pbio/sys/light_matrix.c b/lib/pbio/sys/light_matrix.c index 43f96c691..bc02b218a 100644 --- a/lib/pbio/sys/light_matrix.c +++ b/lib/pbio/sys/light_matrix.c @@ -54,6 +54,14 @@ static pbio_error_t pbsys_hub_light_matrix_set_pixel(pbio_light_matrix_t *light_ return PBIO_ERROR_NOT_SUPPORTED; } +static void pbsys_hub_light_matrix_clear_display(void) { + #if PBSYS_CONFIG_HUB_LIGHT_MATRIX_DISPLAY + pbio_image_t *display = pbdrv_display_get_image(); + pbio_image_fill(display, 0); + pbdrv_display_update(); + #endif +} + static const pbio_light_matrix_funcs_t pbsys_hub_light_matrix_funcs = { .set_pixel = pbsys_hub_light_matrix_set_pixel, }; @@ -166,8 +174,22 @@ void pbsys_hub_light_matrix_handle_user_program_start(bool start) { pbio_light_animation_start(&pbsys_hub_light_matrix->animation); } else { // If the user program has ended, show stop sign and selected slot. + // Clear display if the user program drawn to it. + if (!pbio_light_animation_is_started(&pbsys_hub_light_matrix->animation)) { + pbsys_hub_light_matrix_clear_display(); + } pbsys_hub_light_matrix_show_idle_ui(100); } } +/** + * Free display for user program, stop running animation. + */ +void pbsys_hub_light_matrix_free_display(void) { + if (pbio_light_animation_is_started(&pbsys_hub_light_matrix->animation)) { + pbio_light_animation_stop(&pbsys_hub_light_matrix->animation); + pbsys_hub_light_matrix_clear_display(); + } +} + #endif // PBSYS_CONFIG_HUB_LIGHT_MATRIX diff --git a/pybricks/parameters/pb_type_image.c b/pybricks/parameters/pb_type_image.c index 77f31e327..35e924b1b 100644 --- a/pybricks/parameters/pb_type_image.c +++ b/pybricks/parameters/pb_type_image.c @@ -21,6 +21,8 @@ #include #include +#include + #include extern const mp_obj_type_t pb_type_Image; @@ -48,6 +50,18 @@ static int get_color(mp_obj_t obj) { return max - v * max / 100; } +static void display_stop_running_animation(const pb_type_Image_obj_t *img) { + if (img->is_display) { + pbsys_hub_light_matrix_free_display(); + } +} + +static void display_update(const pb_type_Image_obj_t *img) { + if (img->is_display) { + pbdrv_display_update(); + } +} + mp_obj_t pb_type_Image_display_obj_new(void) { pb_type_Image_obj_t *self = mp_obj_malloc(pb_type_Image_obj_t, &pb_type_Image); self->owner = MP_OBJ_NULL; @@ -175,11 +189,11 @@ static void pb_type_Image_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { static mp_obj_t pb_type_Image_clear(mp_obj_t self_in) { pb_type_Image_obj_t *self = MP_OBJ_TO_PTR(self_in); + display_stop_running_animation(self); + pbio_image_fill(&self->image, 0); - if (self->is_display) { - pbdrv_display_update(); - } + display_update(self); return mp_const_none; } @@ -196,12 +210,12 @@ static mp_obj_t pb_type_Image_load_image(size_t n_args, const mp_obj_t *pos_args int x = (self->image.width - source->image.width) / 2; int y = (self->image.height - source->image.height) / 2; + display_stop_running_animation(self); + pbio_image_fill(&self->image, 0); pbio_image_draw_image(&self->image, &source->image, x, y); - if (self->is_display) { - pbdrv_display_update(); - } + display_update(self); return mp_const_none; } @@ -220,6 +234,8 @@ static mp_obj_t pb_type_Image_draw_image(size_t n_args, const mp_obj_t *pos_args pb_assert_type(source_in, &pb_type_Image); pb_type_Image_obj_t *source = MP_OBJ_TO_PTR(source_in); + display_stop_running_animation(self); + if (transparent_in == mp_const_none) { pbio_image_draw_image(&self->image, &source->image, x, y); } else { @@ -228,9 +244,7 @@ static mp_obj_t pb_type_Image_draw_image(size_t n_args, const mp_obj_t *pos_args pbio_image_draw_image_transparent(&self->image, &source->image, x, y, transparent_value); } - if (self->is_display) { - pbdrv_display_update(); - } + display_update(self); return mp_const_none; } @@ -247,11 +261,11 @@ static mp_obj_t pb_type_Image_draw_pixel(size_t n_args, const mp_obj_t *pos_args mp_int_t y = pb_obj_get_int(y_in); int color = get_color(color_in); + display_stop_running_animation(self); + pbio_image_draw_pixel(&self->image, x, y, color); - if (self->is_display) { - pbdrv_display_update(); - } + display_update(self); return mp_const_none; } @@ -274,11 +288,11 @@ static mp_obj_t pb_type_Image_draw_line(size_t n_args, const mp_obj_t *pos_args, mp_int_t width = pb_obj_get_int(width_in); int color = get_color(color_in); + display_stop_running_animation(self); + pbio_image_draw_thick_line(&self->image, x1, y1, x2, y2, width, color); - if (self->is_display) { - pbdrv_display_update(); - } + display_update(self); return mp_const_none; } @@ -303,6 +317,8 @@ static mp_obj_t pb_type_Image_draw_box(size_t n_args, const mp_obj_t *pos_args, bool fill = mp_obj_is_true(fill_in); int color = get_color(color_in); + display_stop_running_animation(self); + int width = x2 - x1 + 1; int height = y2 - y1 + 1; if (fill) { @@ -311,9 +327,7 @@ static mp_obj_t pb_type_Image_draw_box(size_t n_args, const mp_obj_t *pos_args, pbio_image_draw_rounded_rect(&self->image, x1, y1, width, height, r, color); } - if (self->is_display) { - pbdrv_display_update(); - } + display_update(self); return mp_const_none; } @@ -334,15 +348,15 @@ static mp_obj_t pb_type_Image_draw_circle(size_t n_args, const mp_obj_t *pos_arg bool fill = mp_obj_is_true(fill_in); int color = get_color(color_in); + display_stop_running_animation(self); + if (fill) { pbio_image_fill_circle(&self->image, x, y, r, color); } else { pbio_image_draw_circle(&self->image, x, y, r, color); } - if (self->is_display) { - pbdrv_display_update(); - } + display_update(self); return mp_const_none; }