39
39
#include "shared-bindings/displayio/Shape.h"
40
40
#include "supervisor/shared/translate.h"
41
41
42
- static void unpack_position (mp_obj_t position_obj , int16_t * x , int16_t * y ) {
43
- // TODO(tannewt): Support any value sequence such as bytearray or bytes.
44
- mp_obj_tuple_t * position = MP_OBJ_TO_PTR (position_obj );
45
- if (MP_OBJ_IS_TYPE (position_obj , & mp_type_tuple ) && position -> len == 2 ) {
46
- * x = mp_obj_get_int (position -> items [0 ]);
47
- * y = mp_obj_get_int (position -> items [1 ]);
48
- } else if (position != mp_const_none ) {
49
- mp_raise_TypeError (translate ("position must be 2-tuple" ));
50
- }
51
- }
52
-
53
42
//| .. currentmodule:: displayio
54
43
//|
55
44
//| :class:`TileGrid` -- A grid of tiles sourced out of one bitmap
@@ -60,7 +49,7 @@ static void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) {
60
49
//|
61
50
//| A single tile grid is also known as a Sprite.
62
51
//|
63
- //| .. class:: TileGrid(bitmap, *, pixel_shader, position, width=1, height=1, tile_width=None, tile_height=None, default_tile=0)
52
+ //| .. class:: TileGrid(bitmap, *, pixel_shader, width=1, height=1, tile_width=None, tile_height=None, default_tile=0, x=0, y =0)
64
53
//|
65
54
//| Create a TileGrid object. The bitmap is source for 2d pixels. The pixel_shader is used to
66
55
//| convert the value and its location to a display native pixel color. This may be a simple color
@@ -70,24 +59,26 @@ static void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) {
70
59
//|
71
60
//| :param displayio.Bitmap bitmap: The bitmap storing one or more tiles.
72
61
//| :param displayio.Palette pixel_shader: The pixel shader that produces colors from values
73
- //| :param tuple position: Upper left corner of the grid
74
62
//| :param int width: Width of the grid in tiles.
75
63
//| :param int height: Height of the grid in tiles.
76
64
//| :param int tile_width: Width of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions.
77
65
//| :param int tile_height: Height of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitm
F438
ap's dimensions.
78
66
//| :param in default_tile: Default tile index to show.
67
+ //| :param int x: Initial x position of the left edge within the parent.
68
+ //| :param int y: Initial y position of the top edge within the parent.
79
69
//|
80
70
STATIC mp_obj_t displayio_tilegrid_make_new (const mp_obj_type_t * type , size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
81
- enum { ARG_bitmap , ARG_pixel_shader , ARG_position , ARG_width , ARG_height , ARG_tile_width , ARG_tile_height , ARG_default_tile };
71
+ enum { ARG_bitmap , ARG_pixel_shader , ARG_width , ARG_height , ARG_tile_width , ARG_tile_height , ARG_default_tile , ARG_x , ARG_y };
82
72
static const mp_arg_t allowed_args [] = {
83
73
{ MP_QSTR_bitmap , MP_ARG_REQUIRED | MP_ARG_OBJ },
84
74
{ MP_QSTR_pixel_shader , MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
85
- { MP_QSTR_position , MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
86
75
{ MP_QSTR_width , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 1 } },
87
76
{ MP_QSTR_height , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 1 } },
88
77
{ MP_QSTR_tile_width , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0 } },
89
78
{ MP_QSTR_tile_height , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0 } },
90
79
{ MP_QSTR_default_tile , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0 } },
80
+ { MP_QSTR_x , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0 } },
81
+ { MP_QSTR_y , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0 } },
91
82
};
92
83
mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
93
84
mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
@@ -129,10 +120,8 @@ STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_
129
120
mp_raise_ValueError (translate ("Tile height must exactly divide bitmap height" ));
130
121
}
131
122
132
- int16_t x = 0 ;
133
- int16_t y = 0 ;
134
- mp_obj_t position_obj = args [ARG_position ].u_obj ;
135
- unpack_position (position_obj , & x , & y );
123
+ int16_t x = args [ARG_x ].u_int ;
124
+ int16_t y = args [ARG_y ].u_int ;
136
125
137
126
displayio_tilegrid_t * self = m_new_obj (displayio_tilegrid_t );
138
127
self -> base .type = & displayio_tilegrid_type ;
@@ -142,41 +131,61 @@ STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_
142
131
return MP_OBJ_FROM_PTR (self );
143
132
}
144
133
145
- //| .. attribute:: position
134
+ // Helper to ensure we have the native super class instead of a subclass.
135
+ static displayio_tilegrid_t * native_tilegrid (mp_obj_t tilegrid_obj ) {
136
+ mp_obj_t native_tilegrid = mp_instance_cast_to_native_base (tilegrid_obj , & displayio_tilegrid_type );
137
+ return MP_OBJ_TO_PTR (native_tilegrid );
138
+ }
139
+
140
+ //| .. attribute:: x
146
141
//|
147
- //| The position of the top- left corner of the tilegrid .
142
+ //| X position of the left edge in the parent .
148
143
//|
149
- STATIC mp_obj_t displayio_tilegrid_obj_get_position (mp_obj_t self_in ) {
150
- displayio_tilegrid_t * self = MP_OBJ_TO_PTR (self_in );
151
- int16_t x ;
152
- int16_t y ;
153
- common_hal_displayio_tilegrid_get_position ( self , & x , & y );
144
+ STATIC mp_obj_t displayio_tilegrid_obj_get_x (mp_obj_t self_in ) {
145
+ displayio_tilegrid_t * self = native_tilegrid (self_in );
146
+ return MP_OBJ_NEW_SMALL_INT ( common_hal_displayio_tilegrid_get_x ( self )) ;
147
+ }
148
+ MP_DEFINE_CONST_FUN_OBJ_1 ( displayio_tilegrid_get_x_obj , displayio_tilegrid_obj_get_x );
154
149
155
- mp_obj_t coords [2 ];
156
- coords [0 ] = mp_obj_new_int (x );
157
- coords [1 ] = mp_obj_new_int (y );
150
+ STATIC mp_obj_t displayio_tilegrid_obj_set_x (mp_obj_t self_in , mp_obj_t x_obj ) {
151
+ displayio_tilegrid_t * self = native_tilegrid (self_in );
158
152
159
- return mp_obj_new_tuple (2 , coords );
153
+ mp_int_t x = mp_obj_get_int (x_obj );
154
+ common_hal_displayio_tilegrid_set_x (self , x );
155
+ return mp_const_none ;
160
156
}
161
- MP_DEFINE_CONST_FUN_OBJ_1 ( displayio_tilegrid_get_position_obj , displayio_tilegrid_obj_get_position );
157
+ MP_DEFINE_CONST_FUN_OBJ_2 ( displayio_tilegrid_set_x_obj , displayio_tilegrid_obj_set_x );
162
158
163
- STATIC mp_obj_t displayio_tilegrid_obj_set_position (mp_obj_t self_in , mp_obj_t value ) {
164
- displayio_tilegrid_t * self = MP_OBJ_TO_PTR (self_in );
159
+ const mp_obj_property_t displayio_tilegrid_x_obj = {
160
+ .base .type = & mp_type_property ,
161
+ .proxy = {(mp_obj_t )& displayio_tilegrid_get_x_obj ,
162
+ (mp_obj_t )& displayio_tilegrid_set_x_obj ,
163
+ (mp_obj_t )& mp_const_none_obj },
164
+ };
165
165
166
- int16_t x = 0 ;
167
- int16_t y = 0 ;
168
- unpack_position (value , & x , & y );
166
+ //| .. attribute:: y
167
+ //|
168
+ //| Y position of the top edge in the parent.
169
+ //|
170
+ STATIC mp_obj_t displayio_tilegrid_obj_get_y (mp_obj_t self_in ) {
171
+ displayio_tilegrid_t * self = native_tilegrid (self_in );
172
+ return MP_OBJ_NEW_SMALL_INT (common_hal_displayio_tilegrid_get_y (self ));
173
+ }
174
+ MP_DEFINE_CONST_FUN_OBJ_1 (displayio_tilegrid_get_y_obj , displayio_tilegrid_obj_get_y );
169
175
170
- common_hal_displayio_tilegrid_set_position (self , x , y );
176
+ STATIC mp_obj_t displayio_tilegrid_obj_set_y (mp_obj_t self_in , mp_obj_t y_obj ) {
177
+ displayio_tilegrid_t * self = native_tilegrid (self_in );
171
178
179
+ mp_int_t y = mp_obj_get_int (y_obj );
180
+ common_hal_displayio_tilegrid_set_y (self , y );
172
181
return mp_const_none ;
173
182
}
174
- MP_DEFINE_CONST_FUN_OBJ_2 (displayio_tilegrid_set_position_obj , displayio_tilegrid_obj_set_position );
183
+ MP_DEFINE_CONST_FUN_OBJ_2 (displayio_tilegrid_set_y_obj , displayio_tilegrid_obj_set_y );
175
184
176
- const mp_obj_property_t displayio_tilegrid_position_obj = {
185
+ const mp_obj_property_t displayio_tilegrid_y_obj = {
177
186
.base .type = & mp_type_property ,
178
- .proxy = {(mp_obj_t )& displayio_tilegrid_get_position_obj ,
179
- (mp_obj_t )& displayio_tilegrid_set_position_obj ,
187
+ .proxy = {(mp_obj_t )& displayio_tilegrid_get_y_obj ,
188
+ (mp_obj_t )& displayio_tilegrid_set_y_obj ,
180
189
(mp_obj_t )& mp_const_none_obj },
181
190
};
182
191
@@ -185,13 +194,13 @@ const mp_obj_property_t displayio_tilegrid_position_obj = {
185
194
//| The pixel shader of the tilegrid.
186
195
//|
187
196
STATIC mp_obj_t displayio_tilegrid_obj_get_pixel_shader (mp_obj_t self_in ) {
188
- displayio_tilegrid_t * self = MP_OBJ_TO_PTR (self_in );
197
+ displayio_tilegrid_t * self = native_tilegrid (self_in );
189
198
return common_hal_displayio_tilegrid_get_pixel_shader (self );
190
199
}
191
200
MP_DEFINE_CONST_FUN_OBJ_1 (displayio_tilegrid_get_pixel_shader_obj , displayio_tilegrid_obj_get_pixel_shader );
192
201
193
202
STATIC mp_obj_t displayio_tilegrid_obj_set_pixel_shader (mp_obj_t self_in , mp_obj_t pixel_shader ) {
194
- displayio_tilegrid_t * self = MP_OBJ_TO_PTR (self_in );
203
+ displayio_tilegrid_t * self = native_tilegrid (self_in );
195
204
if (!MP_OBJ_IS_TYPE (pixel_shader , & displayio_palette_type ) && !MP_OBJ_IS_TYPE (pixel_shader , & displayio_colorconverter_type )) {
196
205
mp_raise_TypeError (translate ("pixel_shader must be displayio.Palette or displayio.ColorConverter" ));
197
206
}
@@ -209,9 +218,72 @@ const mp_obj_property_t displayio_tilegrid_pixel_shader_obj = {
209
218
(mp_obj_t )& mp_const_none_obj },
210
219
};
211
220
221
+ //| .. method:: __getitem__(index)
222
+ //|
223
+ //| Returns the tile index at the given index. The index can either be an x,y tuple or an int equal
224
+ //| to ``y * width + x``.
225
+ //|
226
+ //| This allows you to::
227
+ //|
228
+ //| print(grid[0])
229
+ //|
230
+ //| .. method:: __setitem__(index, tile_index)
231
+ //|
232
+ //| Sets the tile index at the given index. The index can either be an x,y tuple or an int equal
233
+ //| to ``y * width + x``.
234
+ //|
235
+ //| This allows you to::
236
+ //|
237
+ //| grid[0] = 10
238
+ //|
239
+ //| or::
240
+ //|
241
+ //| grid[0,0] = 10
242
+ //|
243
+ STATIC mp_obj_t tilegrid_subscr (mp_obj_t self_in , mp_obj_t index_obj , mp_obj_t value_obj ) {
244
+ displayio_tilegrid_t * self = native_tilegrid (self_in );
245
+
246
+
247
+ if (MP_OBJ_IS_TYPE (index_obj , & mp_type_slice )) {
248
+ mp_raise_NotImplementedError (translate ("Slices not supported" ));
249
+ } else {
250
+ uint16_t x = 0 ;
251
+ uint16_t y = 0 ;
252
+ if (MP_OBJ_IS_SMALL_INT (index_obj )) {
253
+ mp_int_t i = MP_OBJ_SMALL_INT_VALUE (index_obj );
254
+ uint16_t width = common_hal_displayio_tilegrid_get_width (self );
255
+ x = i % width ;
256
+ y = i / width ;
257
+ } else {
258
+ mp_obj_t * items ;
259
+ mp_obj_get_array_fixed_n (index_obj , 2 , & items );
260
+ x = mp_obj_get_int (items [0 ]);
261
+ y = mp_obj_get_int (items [1 ]);
262
+ if (x >= common_hal_displayio_tilegrid_get_width (self ) || y >= common_hal_displayio_tilegrid_get_height (self )) {
263
+ mp_raise_IndexError (translate ("tile index out of bounds" ));
264
+ }
265
+ }
266
+
267
+ if (value_obj == MP_OBJ_SENTINEL ) {
268
+ // load
269
+ return MP_OBJ_NEW_SMALL_INT (common_hal_displayio_tilegrid_get_tile (self , x , y ));
270
+ } else if (value_obj == mp_const_none ) {
271
+ return MP_OBJ_NULL ; // op not supported
272
+ } else {
273
+ mp_int_t value = mp_obj_get_int (value_obj );
274
+ if (value < 0 || value > 255 ) {
275
+ mp_raise_ValueError (translate ("Tile indices must be 0 - 255" ));
276
+ }
277
+ common_hal_displayio_tilegrid_set_tile (self , x , y , value );
278
+ }
279
+ }
280
+ return mp_const_none ;
281
+ }
282
+
212
283
STATIC const mp_rom_map_elem_t displayio_tilegrid_locals_dict_table [] = {
213
284
// Properties
214
- { MP_ROM_QSTR (MP_QSTR_position ), MP_ROM_PTR (& displayio_tilegrid_position_obj ) },
285
+ { MP_ROM_QSTR (MP_QSTR_x ), MP_ROM_PTR (& displayio_tilegrid_x_obj ) },
286
+ { MP_ROM_QSTR (MP_QSTR_y ), MP_ROM_PTR (& displayio_tilegrid_y_obj ) },
215
287
{ MP_ROM_QSTR (MP_QSTR_pixel_shader ), MP_ROM_PTR (& displayio_tilegrid_pixel_shader_obj ) },
216
288
};
217
289
STATIC MP_DEFINE_CONST_DICT (displayio_tilegrid_locals_dict , displayio_tilegrid_locals_dict_table );
@@ -220,5 +292,6 @@ const mp_obj_type_t displayio_tilegrid_type = {
220
292
{ & mp_type_type },
221
293
.name = MP_QSTR_TileGrid ,
222
294
.make_new = displayio_tilegrid_make_new ,
295
+ .subscr = tilegrid_subscr ,
223
296
.locals_dict = (mp_obj_dict_t * )& displayio_tilegrid_locals_dict ,
224
297
};
0 commit comments