2626
2727#include "shared-bindings/displayio/TileGrid.h"
2828
29+ #include "py/runtime.h"
2930#include "shared-bindings/displayio/Bitmap.h"
3031#include "shared-bindings/displayio/ColorConverter.h"
3132#include "shared-bindings/displayio/OnDiskBitmap.h"
3233#include "shared-bindings/displayio/Palette.h"
3334#include "shared-bindings/displayio/Shape.h"
3435
3536void common_hal_displayio_tilegrid_construct (displayio_tilegrid_t * self , mp_obj_t bitmap ,
36- uint16_t bitmap_width_in_tiles ,
37+ uint16_t bitmap_width_in_tiles , uint16_t bitmap_height_in_tiles ,
3738 mp_obj_t pixel_shader , uint16_t width , uint16_t height ,
3839 uint16_t tile_width , uint16_t tile_height , uint16_t x , uint16_t y , uint8_t default_tile ) {
3940 uint32_t total_tiles = width * height ;
@@ -54,6 +55,7 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_
5455 self -> inline_tiles = false;
5556 }
5657 self -> bitmap_width_in_tiles = bitmap_width_in_tiles ;
58+ self -> tiles_in_bitmap = bitmap_width_in_tiles * bitmap_height_in_tiles ;
5759 self -> width_in_tiles = width ;
5860 self -> height_in_tiles = height ;
5961 self -> x = x ;
@@ -204,6 +206,9 @@ uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint1
204206}
205207
206208void common_hal_displayio_tilegrid_set_tile (displayio_tilegrid_t * self , uint16_t x , uint16_t y , uint8_t tile_index ) {
209+ if (tile_index >= self -> tiles_in_bitmap ) {
210+ mp_raise_ValueError (translate ("Tile value out of bounds" ));
211+ }
207212 uint8_t * tiles = self -> tiles ;
208213 if (self -> inline_tiles ) {
209214 tiles = (uint8_t * ) & self -> tiles ;
@@ -442,6 +447,14 @@ void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) {
442447 } else if (MP_OBJ_IS_TYPE (self -> pixel_shader , & displayio_colorconverter_type )) {
443448 displayio_colorconverter_finish_refresh (self -> pixel_shader );
444449 }
450+ if (MP_OBJ_IS_TYPE (self -> bitmap , & displayio_bitmap_type )) {
451+ displayio_bitmap_finish_refresh (self -> bitmap );
452+ } else if (MP_OBJ_IS_TYPE (self -> bitmap , & displayio_shape_type )) {
453+ // TODO: Support shape changes.
454+ } else if (MP_OBJ_IS_TYPE (self -> bitmap , & displayio_ondiskbitmap_type )) {
455+ // OnDiskBitmap changes will trigger a complete reload so no need to
456+ // track changes.
457+ }
445458 // TODO(tannewt): We could double buffer changes to position and move them over here.
446459 // That way they won't change during a refresh and tear.
447460}
@@ -458,8 +471,21 @@ displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *sel
458471 return & self -> current_area ;
459472 }
460473
461- // We must recheck if our sources require a refresh because needs_refresh may or may not have
462- // been called.
474+ // If we have an in-memory bitmap, then check it for modifications.
475+ if (MP_OBJ_IS_TYPE (self -> bitmap , & displayio_bitmap_type )) {
476+ displayio_area_t * refresh_area = displayio_bitmap_get_refresh_areas (self -> bitmap , tail );
477+ if (refresh_area != tail ) {
478+ // Special case a TileGrid that shows a full bitmap and use it's
479+ // dirty area. Copy it to ours so we can transform it.
480+ if (self -> tiles_in_bitmap == 1 ) {
481+ displayio_area_copy (refresh_area , & self -> dirty_area );
482+ self -> partial_change = true;
483+ } else {
484+ self -> full_change = true;
485+ }
486+ }
487+ }
488+
463489 self -> full_change = self -> full_change ||
464490 (MP_OBJ_IS_TYPE (self -> pixel_shader , & displayio_palette_type ) &&
465491 displayio_palette_needs_refresh (self -> pixel_shader )) ||
0 commit comments