Commit 2a372f5a authored by Fjen Undso's avatar Fjen Undso
Browse files

add docstrings

parent 9b5ba248
from abc import ABC, abstractmethod
from .focusable import Focusable
class Drawable(Focusable, ABC):
"""A curses drawable object.
Args:
window: The window to draw the object on.
row: The row position of the object.
col: The column position of the object.
"""
def __init__(self, *, window, row=0, col=0):
Focusable.__init__(self)
self.window = window
......@@ -11,8 +20,10 @@ class Drawable(Focusable, ABC):
@abstractmethod
def draw(self):
"""Redraws the object. Useful after changing a state."""
pass
def toggle_focus(self):
# Focus often changes appearance
Focusable.toggle_focus(self)
self.draw()
......@@ -2,13 +2,25 @@ from abc import ABC, abstractmethod
class Focusable(ABC):
"""An object that can be focused and accepts keys.
Attributes:
focus: The current focus state.
"""
def __init__(self):
self.focus = False
@abstractmethod
def toggle_focus(self):
"""Toggle the focus state of the object."""
self.focus = not self.focus
@abstractmethod
def send_key(self, key):
"""Send a key to this object.
Args:
key: The key to send.
"""
pass
......@@ -3,6 +3,14 @@ from .abstracts.drawable import Drawable
class CheckBox(Drawable):
"""A Checkbox that can be toggled on a key event with or without focus.
Args:
text: The text to show.
toggle_key: Key to toggle the state on focus.
toggle_key_unfocused: Key to toggle the state without focus.
"""
def __init__(self, *, window, row=0, col=0, text=None, toggle_key=None,
toggle_key_unfocused=None):
self.text = text
......
from ..abstracts.focusable import Focusable
class FocusSwitcher(Focusable):
"""Container for focusable objects. Switches focus on key events.
Args:
elements: The focusable objects.
prev_key: Key to switch focus to the previous element.
next_key: Key to switch focus to the next element.
Attributes:
elements: The focusable objects.
prev_key: Key to switch focus to the previous element.
next_key: Key to switch focus to the next element.
last_focused: Element which had the focus before we lost our focus.
"""
def __init__(self, *, elements=[], prev_key=None, next_key=None):
Focusable.__init__(self)
self.elements = elements
......@@ -24,10 +39,8 @@ class FocusSwitcher(Focusable):
self.elements[0].toggle_focus()
Focusable.toggle_focus(self)
def add(self, element):
self.elements.append(element)
def send_key(self, key):
"""Switch focus if known key or forward it to all our elements."""
if not self.focus:
return
......@@ -40,6 +53,7 @@ class FocusSwitcher(Focusable):
e.send_key(key)
def next(self):
"""Set focus to next element."""
for i in range(len(self.elements)):
if self.elements[i].focus:
self.elements[i].toggle_focus()
......@@ -47,6 +61,7 @@ class FocusSwitcher(Focusable):
break
def prev(self):
"""Set focus to previous element."""
for i in range(len(self.elements)):
if self.elements[i].focus:
self.elements[i].toggle_focus()
......
......@@ -5,6 +5,8 @@ from .focusswitcher import FocusSwitcher
class NumberBarContainer(FocusSwitcher):
"""Combine NumberRange and ProgressBar objects to unify their state."""
def __init__(self, *, elements=[], prev_key=None, next_key=None):
super().__init__(elements=elements, prev_key=None, next_key=None)
......@@ -20,6 +22,7 @@ class NumberBarContainer(FocusSwitcher):
e.set(val)
def toggle_focus(self):
"""All elements focus state will be toggled"""
Focusable.toggle_focus(self)
# all elements share our focus state
for e in self.elements:
......
......@@ -2,6 +2,8 @@ import logging
class CursesHandler(logging.Handler):
"""Logging handler to send output to a curses subwindow."""
def __init__(self, screen):
logging.Handler.__init__(self)
maxy, maxx = screen.getmaxyx()
......
......@@ -3,6 +3,18 @@ from .abstracts.drawable import Drawable
class NumberRange(Drawable):
"""Limited number that can be modified by digit keys or incr/decr keys.
Args:
value: Initial number value.
min_value: Minimal number value.
max_value: Maximum number value.
text: The text to show.
attr: The curses attribute to use on focus.
prev_key: Key to increase number value.
next_key: Key to decrease number value.
"""
def __init__(self, *, window, row=0, col=0, value=0, min_value=0,
max_value=255, text='', attr=curses.A_STANDOUT, prev_key=None,
next_key=None):
......@@ -43,12 +55,19 @@ class NumberRange(Drawable):
self.set(int(str(self.value) + key))
def set(self, value):
"""Sets number value and respects range.
Args:
value: the value to set.
"""
self.value = min(value, self.max)
self.value = max(self.value, self.min)
self.draw()
def incr(self):
"""Increases number value by one"""
self.set(self.value + 1)
def decr(self):
"""Decreases number value by one"""
self.set(self.value - 1)
......@@ -3,6 +3,17 @@ from .abstracts.drawable import Drawable
class ProgressBar(Drawable):
"""A vertical progressbar consisting of a frame and progress indicator.
Args:
width: The width including frame.
height: The height including frame.
value: Initial value.
max_value: Maximum value.
text: Text to show on top of the progressbar.
attr: Curses attribute of the progress indicator.
"""
def __init__(self, *, window, row=0, col=0, width=0, height=0, value=0,
max_value=100, text='', attr=curses.A_STANDOUT):
assert(width > 2)
......@@ -37,6 +48,11 @@ class ProgressBar(Drawable):
self.window.refresh()
def set(self, value):
"""Set progress to value.
Args:
value: the value to set.
"""
self.value = min(value, self.max)
self.value = max(self.value, 0)
self.draw()
......
......@@ -14,12 +14,22 @@ SOCKET.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
def send_broadcast(data):
"""Send data via broadcast"""
"""Send data via broadcast.
Args:
data (bytes): the data to send.
"""
send(data, UDP_IP)
def send(data, host, send_rate=SEND_RATE):
"""Send data to the ESP listening at host:UDP_PORT."""
"""Send data to the ESP listening at host:UDP_PORT.
Args:
data (bytes): the data to send.
host (string): the host name or IP to send the data to.
send_rate (float): the time in seconds to wait after sending.
"""
global SEQUENCES
header = bytes([VERSION, SEQUENCES[host], 0, 0])
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
......@@ -34,14 +44,23 @@ def send(data, host, send_rate=SEND_RATE):
def send_to_many(data, hosts):
"""Send data to a list of ESPs"""
"""Send data to a list of hosts.
Args:
data (bytes): the data to send.
hosts: the host names or IPs to send the data to.
"""
for h in hosts:
send(data, h, 0)
time.sleep(SEND_RATE)
def pixel2bytes(pixel):
"""Convert rgbw color values to bytes. Limit values to range(0,255)."""
"""Convert rgbw color values to bytes. Limit values to range(0,255)
Args:
pixel: list of color values.
"""
out = []
for color in pixel:
if color < 0:
......@@ -53,7 +72,12 @@ def pixel2bytes(pixel):
def make_stripe_data(pixellist):
"""Convert a list of rgbw color values to bytes and make sure it matches the led strip length"""
"""Convert a list of rgbw color values to bytes.
make sure it matches the led strip length.
Args:
pixellist: list of color values
"""
assert(len(pixellist) % 4 == 0)
if len(pixellist) > LED_NUM * 4:
pixellist = pixellist[:LED_NUM * 4]
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment