Add .hidden to TileGrid and Group

This allows for one to preserve ordering within a Group while
hiding something temporarily.

Fixes #1688
This commit is contained in:
Scott Shawcroft 2019-08-27 16:03:05 -07:00
parent e92b5f7e3e
commit 949f8761b8
No known key found for this signature in database
GPG Key ID: 9349BC7E64B1921E
13 changed files with 158 additions and 18 deletions

View File

@ -90,6 +90,32 @@ displayio_group_t* native_group(mp_obj_t group_obj) {
return MP_OBJ_TO_PTR(native_group);
}
//| .. attribute:: hidden
//|
//| True when the Group and all of it's layers are not visible. When False, the Group's layers
//| are visible if they haven't been hidden.
//|
STATIC mp_obj_t displayio_group_obj_get_hidden(mp_obj_t self_in) {
displayio_group_t *self = native_group(self_in);
return mp_obj_new_bool(common_hal_displayio_group_get_hidden(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_group_get_hidden_obj, displayio_group_obj_get_hidden);
STATIC mp_obj_t displayio_group_obj_set_hidden(mp_obj_t self_in, mp_obj_t hidden_obj) {
displayio_group_t *self = native_group(self_in);
common_hal_displayio_group_set_hidden(self, mp_obj_is_true(hidden_obj));
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_set_hidden_obj, displayio_group_obj_set_hidden);
const mp_obj_property_t displayio_group_hidden_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&displayio_group_get_hidden_obj,
(mp_obj_t)&displayio_group_set_hidden_obj,
(mp_obj_t)&mp_const_none_obj},
};
//| .. attribute:: scale
//|
//| Scales each pixel within the Group in both directions. For example, when scale=2 each pixel
@ -305,6 +331,7 @@ STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t valu
}
STATIC const mp_rom_map_elem_t displayio_group_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_hidden), MP_ROM_PTR(&displayio_group_hidden_obj) },
{ MP_ROM_QSTR(MP_QSTR_scale), MP_ROM_PTR(&displayio_group_scale_obj) },
{ MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&displayio_group_x_obj) },
{ MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&displayio_group_y_obj) },

View File

@ -36,6 +36,8 @@ displayio_group_t* native_group(mp_obj_t group_obj);
void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y);
uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self);
void common_hal_displayio_group_set_scale(displayio_group_t* self, uint32_t scale);
bool common_hal_displayio_group_get_hidden(displayio_group_t* self);
void common_hal_displayio_group_set_hidden(displayio_group_t* self, bool hidden);
mp_int_t common_hal_displayio_group_get_x(displayio_group_t* self);
void common_hal_displayio_group_set_x(displayio_group_t* self, mp_int_t x);
mp_int_t common_hal_displayio_group_get_y(displayio_group_t* self);

View File

@ -144,6 +144,30 @@ static displayio_tilegrid_t* native_tilegrid(mp_obj_t tilegrid_obj) {
mp_obj_assert_native_inited(native_tilegrid);
return MP_OBJ_TO_PTR(native_tilegrid);
}
//| .. attribute:: hidden
//|
//| True when the TileGrid is hidden. This may be False even when a part of a hidden Group.
//|
STATIC mp_obj_t displayio_tilegrid_obj_get_hidden(mp_obj_t self_in) {
displayio_tilegrid_t *self = native_tilegrid(self_in);
return mp_obj_new_bool(common_hal_displayio_tilegrid_get_hidden(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_hidden_obj, displayio_tilegrid_obj_get_hidden);
STATIC mp_obj_t displayio_tilegrid_obj_set_hidden(mp_obj_t self_in, mp_obj_t hidden_obj) {
displayio_tilegrid_t *self = native_tilegrid(self_in);
common_hal_displayio_tilegrid_set_hidden(self, mp_obj_is_true(hidden_obj));
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_hidden_obj, displayio_tilegrid_obj_set_hidden);
const mp_obj_property_t displayio_tilegrid_hidden_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&displayio_tilegrid_get_hidden_obj,
(mp_obj_t)&displayio_tilegrid_set_hidden_obj,
(mp_obj_t)&mp_const_none_obj},
};
//| .. attribute:: x
//|
@ -368,6 +392,7 @@ STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t v
STATIC const mp_rom_map_elem_t displayio_tilegrid_locals_dict_table[] = {
// Properties
{ MP_ROM_QSTR(MP_QSTR_hidden), MP_ROM_PTR(&displayio_tilegrid_hidden_obj) },
{ MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&displayio_tilegrid_x_obj) },
{ MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&displayio_tilegrid_y_obj) },
{ MP_ROM_QSTR(MP_QSTR_flip_x), MP_ROM_PTR(&displayio_tilegrid_flip_x_obj) },

View File

@ -36,6 +36,8 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_
mp_obj_t pixel_shader, uint16_t width, uint16_t height,
uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile);
bool common_hal_displayio_tilegrid_get_hidden(displayio_tilegrid_t* self);
void common_hal_displayio_tilegrid_set_hidden(displayio_tilegrid_t* self, bool hidden);
mp_int_t common_hal_displayio_tilegrid_get_x(displayio_tilegrid_t *self);
void common_hal_displayio_tilegrid_set_x(displayio_tilegrid_t *self, mp_int_t x);
mp_int_t common_hal_displayio_tilegrid_get_y(displayio_tilegrid_t *self);

View File

@ -34,7 +34,6 @@ typedef enum {
DISPLAY_DATA
} display_byte_type_t;
typedef enum {
CHIP_SELECT_UNTOUCHED,
CHIP_SELECT_TOGGLE_EVERY_BYTE

View File

@ -50,6 +50,8 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin,
uint16_t brightness_command, mp_float_t brightness, bool auto_brightness,
bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second) {
// Turn off auto-refresh as we init.
self->auto_refresh = false;
uint16_t ram_width = 0x100;
uint16_t ram_height = 0x100;
if (single_byte_bounds) {
@ -64,7 +66,6 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
self->write_ram_command = write_ram_command;
self->brightness_command = brightness_command;
self->auto_brightness = auto_brightness;
self->auto_refresh = auto_refresh;
self->first_manual_refresh = !auto_refresh;
self->data_as_commands = data_as_commands;
@ -128,6 +129,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
// Set the group after initialization otherwise we may send pixels while we delay in
// initialization.
common_hal_displayio_display_show(self, &circuitpython_splash);
self->auto_refresh = auto_refresh;
}
bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) {

View File

@ -34,6 +34,47 @@ void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_
displayio_group_construct(self, children, max_size, scale, x, y);
}
bool common_hal_displayio_group_get_hidden(displayio_group_t* self) {
return self->hidden;
}
void common_hal_displayio_group_set_hidden(displayio_group_t* self, bool hidden) {
if (self->hidden == hidden) {
return;
}
self->hidden = hidden;
if (self->hidden_by_parent) {
return;
}
for (size_t i = 0; i < self->size; i++) {
mp_obj_t layer = self->children[i].native;
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
displayio_tilegrid_set_hidden_by_parent(layer, hidden);
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
displayio_group_set_hidden_by_parent(layer, hidden);
}
}
}
void displayio_group_set_hidden_by_parent(displayio_group_t *self, bool hidden) {
if (self->hidden_by_parent == hidden) {
return;
}
self->hidden_by_parent = hidden;
// If we're already hidden, then we're done.
if (self->hidden) {
return;
}
for (size_t i = 0; i < self->size; i++) {
mp_obj_t layer = self->children[i].native;
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
displayio_tilegrid_set_hidden_by_parent(layer, hidden);
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
displayio_group_set_hidden_by_parent(layer, hidden);
}
}
}
uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self) {
return self->scale;
}

View File

@ -49,11 +49,14 @@ typedef struct {
uint16_t max_size;
bool item_removed;
bool in_group;
bool hidden;
bool hidden_by_parent;
displayio_buffer_transform_t absolute_transform;
displayio_area_t dirty_area; // Catch all for changed area
} displayio_group_t;
void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* child_array, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y);
void displayio_group_set_hidden_by_parent(displayio_group_t *self, bool hidden);
bool displayio_group_get_previous_area(displayio_group_t *group, displayio_area_t* area);
bool displayio_group_fill_area(displayio_group_t *group, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer);
void displayio_group_update_transform(displayio_group_t *group, const displayio_buffer_transform_t* parent_transform);

View File

@ -97,7 +97,7 @@ bool common_hal_displayio_i2cdisplay_bus_free(mp_obj_t obj) {
bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t obj) {
displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj);
return !common_hal_busio_i2c_try_lock(self->bus);
return common_hal_busio_i2c_try_lock(self->bus);
}
void common_hal_displayio_i2cdisplay_send(mp_obj_t obj, display_byte_type_t data_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length) {

View File

@ -67,14 +67,30 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_
self->bitmap = bitmap;
self->pixel_shader = pixel_shader;
self->in_group = false;
self->first_draw = true;
self->hidden = false;
self->hidden_by_parent = false;
self->previous_area.x1 = 0xffff;
self->previous_area.x2 = self->previous_area.x1;
self->flip_x = false;
self->flip_y = false;
self->transpose_xy = false;
}
bool common_hal_displayio_tilegrid_get_hidden(displayio_tilegrid_t* self) {
return self->hidden;
}
void common_hal_displayio_tilegrid_set_hidden(displayio_tilegrid_t* self, bool hidden) {
self->hidden = hidden;
}
void displayio_tilegrid_set_hidden_by_parent(displayio_tilegrid_t *self, bool hidden) {
self->hidden_by_parent = hidden;
}
bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_area_t* area) {
if (self->first_draw) {
if (self->previous_area.x1 == self->previous_area.x2) {
return false;
}
displayio_area_copy(&self->previous_area, area);
@ -138,12 +154,10 @@ void displayio_tilegrid_update_transform(displayio_tilegrid_t *self,
self->in_group = absolute_transform != NULL;
self->absolute_transform = absolute_transform;
if (absolute_transform != NULL) {
self->moved = !self->first_draw;
self->moved = true;
_update_current_x(self);
_update_current_y(self);
} else {
self->first_draw = true;
}
}
@ -155,7 +169,7 @@ void common_hal_displayio_tilegrid_set_x(displayio_tilegrid_t *self, mp_int_t x)
return;
}
self->moved = !self->first_draw;
self->moved = true;
self->x = x;
if (self->absolute_transform != NULL) {
@ -170,7 +184,7 @@ void common_hal_displayio_tilegrid_set_y(displayio_tilegrid_t *self, mp_int_t y)
if (self->y == y) {
return;
}
self->moved = !self->first_draw;
self->moved = true;
self->y = y;
if (self->absolute_transform != NULL) {
_update_current_y(self);
@ -306,6 +320,11 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_c
return false;
}
bool hidden = self->hidden || self->hidden_by_parent;
if (hidden) {
return false;
}
displayio_area_t overlap;
if (!displayio_area_compute_overlap(area, &self->current_area, &overlap)) {
return false;
@ -455,14 +474,17 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_c
}
void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) {
if (self->moved || self->first_draw) {
bool first_draw = self->previous_area.x1 == self->previous_area.x2;
bool hidden = self->hidden || self->hidden_by_parent;
if (!first_draw && hidden) {
self->previous_area.x2 = self->previous_area.x1;
} else if (self->moved || first_draw) {
displayio_area_copy(&self->current_area, &self->previous_area);
}
self->moved = false;
self->full_change = false;
self->partial_change = false;
self->first_draw = false;
if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) {
displayio_palette_finish_refresh(self->pixel_shader);
} else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) {
@ -481,7 +503,17 @@ void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) {
}
displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *self, displayio_area_t* tail) {
if (self->moved && !self->first_draw) {
bool first_draw = self->previous_area.x1 == self->previous_area.x2;
bool hidden = self->hidden || self->hidden_by_parent;
// Check hidden first because it trumps all other changes.
if (hidden) {
if (!first_draw) {
self->previous_area.next = tail;
return &self->previous_area;
} else {
return tail;
}
} else if (self->moved && !first_draw) {
displayio_area_union(&self->previous_area, &self->current_area, &self->dirty_area);
if (displayio_area_size(&self->dirty_area) <= 2U * self->pixel_width * self->pixel_height) {
self->dirty_area.next = tail;
@ -512,7 +544,7 @@ displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *sel
displayio_palette_needs_refresh(self->pixel_shader)) ||
(MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type) &&
displayio_colorconverter_needs_refresh(self->pixel_shader));
if (self->full_change || self->first_draw) {
if (self->full_change || first_draw) {
self->current_area.next = tail;
return &self->current_area;
}

View File

@ -57,15 +57,18 @@ typedef struct {
displayio_area_t current_area; // Stored as an absolute area so it applies across frames.
bool partial_change;
bool full_change;
bool first_draw;
bool moved;
bool inline_tiles;
bool in_group;
bool flip_x;
bool flip_y;
bool transpose_xy;
bool hidden;
bool hidden_by_parent;
} displayio_tilegrid_t;
void displayio_tilegrid_set_hidden_by_parent(displayio_tilegrid_t *self, bool hidden);
// Updating the screen is a three stage process.
// The first stage is used to determine i

View File

@ -222,7 +222,8 @@ displayio_tilegrid_t blinka_sprite = {
.tiles = 0,
.partial_change = false,
.full_change = false,
.first_draw = true,
.hidden = false,
.hidden_by_parent = false,
.moved = false,
.inline_tiles = true,
.in_group = true
@ -242,5 +243,7 @@ displayio_group_t circuitpython_splash = {
.max_size = 2,
.children = splash_children,
.item_removed = false,
.in_group = false
.in_group = false,
.hidden = false,
.hidden_by_parent = false
};

View File

@ -139,7 +139,8 @@ displayio_tilegrid_t supervisor_terminal_text_grid = {{
.tiles = NULL,
.partial_change = false,
.full_change = false,
.first_draw = true,
.hidden = false,
.hidden_by_parent = false,
.moved = false,
.inline_tiles = false,
.in_group = true