Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 57 additions & 57 deletions CircuitPython_PyPaint/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@
All text above must be included in any redistribution.
"""

#pylint:disable=invalid-name, no-self-use

import gc
import time
import board
import displayio
import adafruit_logging as logging

try:
import adafruit_touchscreen
except ImportError:
Expand All @@ -29,8 +28,10 @@
except ImportError:
pass


class Color(object):
"""Standard colors"""

WHITE = 0xFFFFFF
BLACK = 0x000000
RED = 0xFF0000
Expand All @@ -46,32 +47,35 @@ class Color(object):
def __init__(self):
pass


################################################################################


class TouchscreenPoller(object):
"""Get 'pressed' and location updates from a touch screen device."""

def __init__(self, splash, cursor_bmp):
logging.getLogger('Paint').debug('Creating a TouchscreenPoller')
logging.getLogger("Paint").debug("Creating a TouchscreenPoller")
self._display_grp = splash
self._touchscreen = adafruit_touchscreen.Touchscreen(board.TOUCH_XL, board.TOUCH_XR,
board.TOUCH_YD, board.TOUCH_YU,
calibration=((9000, 59000),
(8000, 57000)),
size=(320, 240))
self._cursor_grp = displayio.Group(max_size=1)
self._touchscreen = adafruit_touchscreen.Touchscreen(
board.TOUCH_XL, board.TOUCH_XR,
board.TOUCH_YD, board.TOUCH_YU,
calibration=((9000, 59000), (8000, 57000)),
size=(320, 240),
)
self._cursor_grp = displayio.Group()
self._cur_palette = displayio.Palette(3)
self._cur_palette.make_transparent(0)
self._cur_palette[1] = 0xFFFFFF
self._cur_palette[2] = 0x0000
self._cur_sprite = displayio.TileGrid(cursor_bmp,
pixel_shader=self._cur_palette)
self._cur_sprite = displayio.TileGrid(
cursor_bmp, pixel_shader=self._cur_palette
)
self._cursor_grp.append(self._cur_sprite)
self._display_grp.append(self._cursor_grp)
self._x_offset = cursor_bmp.width // 2
self._y_offset = cursor_bmp.height // 2


def poll(self):
"""Check for input. Returns contact (a bool), False (no button B),
and it's location ((x,y) or None)"""
Expand All @@ -98,26 +102,26 @@ def set_cursor_bitmap(self, bmp):
:param bmp: the new cursor bitmap
"""
self._cursor_grp.remove(self._cur_sprite)
self._cur_sprite = displayio.TileGrid(bmp,
pixel_shader=self._cur_palette)
self._cur_sprite = displayio.TileGrid(bmp, pixel_shader=self._cur_palette)
self._cursor_grp.append(self._cur_sprite)
self.poke()


################################################################################


class CursorPoller(object):
"""Get 'pressed' and location updates from a D-Pad/joystick device."""

def __init__(self, splash, cursor_bmp):
logging.getLogger('Paint').debug('Creating a CursorPoller')
self._mouse_cursor = Cursor(board.DISPLAY,
display_group=splash,
bmp=cursor_bmp,
cursor_speed=2)
logging.getLogger("Paint").debug("Creating a CursorPoller")
self._mouse_cursor = Cursor(
board.DISPLAY, display_group=splash, bmp=cursor_bmp, cursor_speed=2
)
self._x_offset = cursor_bmp.width // 2
self._y_offset = cursor_bmp.height // 2
self._cursor = DebouncedCursorManager(self._mouse_cursor)
self._logger = logging.getLogger('Paint')
self._logger = logging.getLogger("Paint")

def poll(self):
"""Check for input. Returns press of A (a bool), B,
Expand All @@ -126,16 +130,16 @@ def poll(self):
self._cursor.update()
a_button = self._cursor.held
if a_button:
location = (self._mouse_cursor.x + self._x_offset,
self._mouse_cursor.y + self._y_offset)
location = (
self._mouse_cursor.x + self._x_offset,
self._mouse_cursor.y + self._y_offset,
)
return a_button, location

#pylint:disable=unused-argument
def poke(self, x=None, y=None):
"""Force a bitmap refresh."""
self._mouse_cursor.hide()
self._mouse_cursor.show()
#pylint:enable=unused-argument

def set_cursor_bitmap(self, bmp):
"""Update the cursor bitmap.
Expand All @@ -145,10 +149,11 @@ def set_cursor_bitmap(self, bmp):
self._mouse_cursor.cursor_bitmap = bmp
self.poke()


################################################################################
class Paint(object):

#pylint:disable=too-many-statements

class Paint(object):
def __init__(self, display=board.DISPLAY):
self._logger = logging.getLogger("Paint")
self._logger.setLevel(logging.DEBUG)
Expand All @@ -158,39 +163,39 @@ def __init__(self, display=board.DISPLAY):
self._x = self._w // 2
self._y = self._h // 2

self._splash = displayio.Group(max_size=5)
self._splash = displayio.Group()

self._bg_bitmap = displayio.Bitmap(self._w, self._h, 1)
self._bg_palette = displayio.Palette(1)
self._bg_palette[0] = Color.BLACK
self._bg_sprite = displayio.TileGrid(self._bg_bitmap,
pixel_shader=self._bg_palette,
x=0, y=0)
self._bg_sprite = displayio.TileGrid(
self._bg_bitmap, pixel_shader=self._bg_palette, x=0, y=0
)
self._splash.append(self._bg_sprite)

self._palette_bitmap = displayio.Bitmap(self._w, self._h, 5)
self._palette_palette = displayio.Palette(len(Color.colors))
for i, c in enumerate(Color.colors):
self._palette_palette[i] = c
self._palette_sprite = displayio.TileGrid(self._palette_bitmap,
pixel_shader=self._palette_palette,
x=0, y=0)
self._palette_sprite = displayio.TileGrid(
self._palette_bitmap, pixel_shader=self._palette_palette, x=0, y=0
)
self._splash.append(self._palette_sprite)

self._fg_bitmap = displayio.Bitmap(self._w, self._h, 5)
self._fg_palette = displayio.Palette(len(Color.colors))
for i, c in enumerate(Color.colors):
self._fg_palette[i] = c
self._fg_sprite = displayio.TileGrid(self._fg_bitmap,
pixel_shader=self._fg_palette,
x=0, y=0)
self._fg_sprite = displayio.TileGrid(
self._fg_bitmap, pixel_shader=self._fg_palette, x=0, y=0
)
self._splash.append(self._fg_sprite)

self._number_of_palette_options = len(Color.colors) + 2
self._swatch_height = self._h // self._number_of_palette_options
self._swatch_width = self._w // 10
self._logger.debug('Height: %d', self._h)
self._logger.debug('Swatch height: %d', self._swatch_height)
self._logger.debug("Height: %d", self._h)
self._logger.debug("Swatch height: %d", self._swatch_height)

self._palette = self._make_palette()
self._splash.append(self._palette)
Expand All @@ -206,20 +211,19 @@ def __init__(self, display=board.DISPLAY):

self._brush = 0
self._cursor_bitmaps = [self._cursor_bitmap_1(), self._cursor_bitmap_3()]
if hasattr(board, 'TOUCH_XL'):
if hasattr(board, "TOUCH_XL"):
self._poller = TouchscreenPoller(self._splash, self._cursor_bitmaps[0])
elif hasattr(board, 'BUTTON_CLOCK'):
elif hasattr(board, "BUTTON_CLOCK"):
self._poller = CursorPoller(self._splash, self._cursor_bitmaps[0])
else:
raise AttributeError('PyPaint requires a touchscreen or cursor.')
raise AttributeError("PyPaint requires a touchscreen or cursor.")

self._a_pressed = False
self._last_a_pressed = False
self._location = None
self._last_location = None

self._pencolor = 7
#pylint:enable=too-many-statements

def _make_palette(self):
self._palette_bitmap = displayio.Bitmap(self._w // 10, self._h, 5)
Expand Down Expand Up @@ -253,9 +257,9 @@ def _make_palette(self):
for i in range(self._h):
self._palette_bitmap[self._swatch_width - 1, i] = 7

return displayio.TileGrid(self._palette_bitmap,
pixel_shader=self._palette_palette,
x=0, y=0)
return displayio.TileGrid(
self._palette_bitmap, pixel_shader=self._palette_palette, x=0, y=0
)

def _cursor_bitmap_1(self):
bmp = displayio.Bitmap(9, 9, 3)
Expand Down Expand Up @@ -291,8 +295,6 @@ def _plot(self, x, y, c):
except IndexError:
pass

#pylint:disable=too-many-branches,too-many-statements

def _draw_line(self, start, end):
"""Draw a line from the previous position to the current one.

Expand Down Expand Up @@ -351,35 +353,33 @@ def _draw_line(self, start, end):
else:
x0 += 1

#pylint:enable=too-many-branches,too-many-statements

def _handle_palette_selection(self, location):
selected = location[1] // self._swatch_height
if selected >= self._number_of_palette_options:
return
self._logger.debug('Palette selection: %d', selected)
self._logger.debug("Palette selection: %d", selected)
if selected < len(Color.colors):
self._pencolor = selected
else:
self._brush = selected - len(Color.colors)
self._poller.set_cursor_bitmap(self._cursor_bitmaps[self._brush])

def _handle_motion(self, start, end):
self._logger.debug('Moved: (%d, %d) -> (%d, %d)', start[0], start[1], end[0], end[1])
self._logger.debug(
"Moved: (%d, %d) -> (%d, %d)", start[0], start[1], end[0], end[1]
)
self._draw_line(start, end)

def _handle_a_press(self, location):
self._logger.debug('A Pressed!')
if location[0] < self._w // 10: # in color picker
self._logger.debug("A Pressed!")
if location[0] < self._w // 10: # in color picker
self._handle_palette_selection(location)
else:
self._plot(location[0], location[1], self._pencolor)
self._poller.poke()

#pylint:disable=unused-argument
def _handle_a_release(self, location):
self._logger.debug('A Released!')
#pylint:enable=unused-argument
self._logger.debug("A Released!")

@property
def _was_a_just_pressed(self):
Expand All @@ -402,7 +402,6 @@ def _update(self):
self._last_a_pressed, self._last_location = self._a_pressed, self._location
self._a_pressed, self._location = self._poller.poll()


def run(self):
"""Run the painting program."""
while True:
Expand All @@ -415,5 +414,6 @@ def run(self):
self._handle_motion(self._last_location, self._location)
time.sleep(0.1)


painter = Paint()
painter.run()