Skip to content

A CircuitPython wrapper class to add list slice capability to a displayio.Palette object while preserving transparency.

License

Notifications You must be signed in to change notification settings

CedarGroveStudios/CircuitPython_PaletteSlice

Repository files navigation

Introduction

CedarGroveStudios/CircuitPython_PaletteSlice

Discord Build Status Code Style: Black

A CircuitPython wrapper class to add list slice and extended slice capability to a displayio.Palette object while preserving transparency.

The default functionality of a displayio.Palette object is similar to a Python list object, but very limited. For example, the integer value of color elements of the palette can be modified but only one element can be changed at a time. The PaletteSlice wrapper class provides the ability to use a slice object to specify a subset of a palette to change or to create a new palette from a source palette. Both slice and extended slice objects are supported.

In addition to a palette property (.palette), PaletteSlice contains a list representation (.reference_list) of the source palette with color and transparency values stored as a tuple.

The ability to create and manipulate palettes using slicing allows for the use of a standardized palette to be used to provide a color scheme for multiple objects within a project framework, regardless of an object's color depth. For example, a standard color palette of 1024 individual colors could be used for a 64-color bitmap object by slicing the standard palette using an extended slice object:

bitmap_image.pixel_shader = source_palette[::16]


Note that a PaletteSlice object behaves correctly only when a slice object is included in the syntax. For example,

bitmap_image.pixel_shader = source_palette

will cause a type error:

TypeError: pixel_shader must be displayio.Palette or displayio.ColorConverter

At a minimum, the PaletteSlice object must include the "all" slice object in order to return a displayio.Palette object:

bitmap_image.pixel_shader = source_palette[:]


Two Versions -- Minimal and Acme

Two versions of PaletteSlice are available. cedargrove_paletteslice.paletteslice is a minimal version that only supports palette slicing and the traditional palette functions:

  • .is_transparent(index)
  • .make_transparent(index)
  • .make_opaque(index)
  • len(palette)

The second version, cedargrove_paletteslice.paletteslice_acme currently extends the functionality of the minimal version with the additional functions:

  • __contains__(color) (usage: color in PaletteSlice.palette )
  • .append(color)
  • .count(color)
  • .index(color)
  • .insert(key)
  • .pop(key)

Under consideration for a future "acme" version are:

  • .entend(new_palette)
  • .remove(color)
  • .reverse()
  • .sort(key, reverse)

and perhaps the extended functions of:

  • min(palette)
  • max(palette)
  • enumerate(palette)

Dependencies

This driver depends on:

Please ensure all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading the Adafruit library and driver bundle or individual libraries can be installed using circup.

Installing to a Connected CircuitPython Device with Circup

Make sure that you have circup installed in your Python environment. Install it with the following command if necessary:

pip3 install circup

With circup installed and your CircuitPython device connected use the following command to install:

circup install cedargrove_paletteslice

Or the following command to update an existing version:

circup update

Usage Example

from cedargrove_paletteslice.paletteslice import PaletteSlice
sliceable_palette = PaletteSlice(source_palette)

# Create a new palette from the sliceable palette
new_sliced_palette = sliceable_palette[0:124:2]

Using slice with narray Pseudocolor Palettes:

Using slice with narray Pseudocolor Palettes

paletteslice_simpletest.py, paletteslice_acme_simpletest.py, and paletteslice_ulab_test.py are contained in the examples folder.

Documentation

PaletteSlice API Documentation

Brainstorm Diagram

Brainstorm Diagram

Brainstorm Diagram

PaletteSlice Design Considerations

CircuitPython classes such as PaletteSlice cannot inherit displayio.Palette or list attributes because of their specific core implementation. Therefore, PaletteSlice uses composition to appear to be a displayio.Palette object.

The PaletteSlice project began as a learning experience for the author but is also became a proof-of-concept for testing the usefulness of list slicing for displayio.Palette objects. It is hoped that this project will encourage list slice and extended slice capabilities be added to displayio.Palette in the CircuitPython core.

Brainstorm Diagram

For information on building library documentation, please check out this guide.

Contributing

Contributions are welcome! Please read our Code of Conduct before contributing to help this project stay welcoming.