Last active
January 28, 2021 22:45
-
-
Save kmatch98/31fb5469b461d94012122fea78c5bf69 to your computer and use it in GitHub Desktop.
Widget: Round, horizontal switch for CircuitPython using displayio and adafruit_display_shapes. Includes a demo for the PyPortal.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is a trial of the switch_round_horizontal | |
# for use on the PyPortal | |
# | |
# To do: | |
# Allow color handling for both RGB tuples (255, 255, 255) or hex values (0xFFFFFF) | |
# | |
import time | |
#import random | |
import board | |
import displayio | |
from adafruit_display_shapes.circle import Circle | |
#from adafruit_display_shapes.roundrect import RoundRect | |
from adafruit_display_shapes.rect import Rect | |
from switch_round_horizontal import SwitchRoundHorizontal | |
import adafruit_touchscreen | |
from adafruit_pyportal import PyPortal | |
if "DISPLAY" not in dir(board): | |
# Setup the LCD display with driver | |
# You may need to change this to match the display driver for the chipset | |
# used on your display | |
from adafruit_ili9341 import ILI9341 | |
displayio.release_displays() | |
# setup the SPI bus | |
spi = board.SPI() | |
tft_cs = board.D9 # arbitrary, pin not used | |
tft_dc = board.D10 | |
tft_backlight = board.D12 | |
tft_reset = board.D11 | |
while not spi.try_lock(): | |
spi.configure(baudrate=32000000) | |
spi.unlock() | |
display_bus = displayio.FourWire( | |
spi, | |
command=tft_dc, | |
chip_select=tft_cs, | |
reset=tft_reset, | |
baudrate=32000000, | |
polarity=1, | |
phase=1, | |
) | |
print("spi.frequency: {}".format(spi.frequency)) | |
# Number of pixels in the display | |
DISPLAY_WIDTH = 320 | |
DISPLAY_HEIGHT = 240 | |
# create the display | |
display = ILI9341( | |
display_bus, | |
width=DISPLAY_WIDTH, | |
height=DISPLAY_HEIGHT, | |
rotation=180, # The rotation can be adjusted to match your configuration. | |
auto_refresh=True, | |
native_frames_per_second=90, | |
) | |
# reset the display to show nothing. | |
display.show(None) | |
else: | |
# built-in display | |
display = board.DISPLAY | |
screen_width = 320 | |
screen_height = 240 | |
ts = adafruit_touchscreen.Touchscreen(board.TOUCH_XL, board.TOUCH_XR, | |
board.TOUCH_YD, board.TOUCH_YU, | |
calibration=((5200, 59000), | |
(5800, 57000)), | |
size=(screen_width, screen_height)) | |
# Create an on-off switch | |
# structural variables | |
# -------------------- | |
# input parameters: | |
# x,y: position: upper left corner pixel position | |
# radius: (pixel diameter of button) ***** | |
# width: (default is calculate based on radius) | |
# switch_fill_color_off: RGB | |
# switch_fill_color_on: RGB | |
# switch_outline_color_off: RGB | |
# switch_outline_color_on: RGB | |
# background_color_off: RGB | |
# background_color_on: RGB | |
# background_outline_color_off: RGB | |
# background_outline_color_on: RGB | |
# | |
# display_text: Boolean | |
# animation_time: in seconds | |
# | |
# touch_padding: additional pixels outside of the bounding_box to accept touch input, affects touch_boundary | |
# | |
# | |
# other instance variables: | |
# bounding_box: [x, y, width, height] where x,y are the upper left corner | |
# touch_boundary: area that responds to touch | |
# value: Boolean (upon setter change, perform the animation) | |
# add getter/setter | |
# | |
# animation triggers | |
# selected(x,y): changes from current state to the other state | |
# setter only | |
# | |
# other functions: | |
# contains(x,y): check for touch input inside of touch_boundary | |
# | |
# Options to consider | |
# ------------------- | |
# rotation? | |
# text on switch: (0/1) | |
# | |
#test_circle=Circle(x0=0, y0=0, r=50) | |
#print("test_circle.x: {}, .y: {}".format(test_circle.x, test_circle.y)) | |
def color_fade(start_color, end_color, total_steps, step_number): | |
if step_number >= total_steps-1: | |
return end_color | |
if step_number <= 0: | |
return start_color | |
else: | |
faded_color = [0,0,0] | |
for i in range(3): | |
faded_color[i] = start_color[i] - int((step_number * (start_color[i]-end_color[i]))/total_steps) | |
return faded_color | |
my_group = displayio.Group(max_size=3) | |
# Group elements: | |
# 1. switch_roundrect: The switch background | |
# 2. switch_circle: The switch button | |
# 3. text_0 or text_1: The text on the switch button | |
switch_x = 30 | |
switch_y = 30 | |
switch_radius = 20 | |
switch_fill_color_off = (66, 44, 66) | |
switch_fill_color_on = (0, 100, 0) | |
switch_outline_color_off = (30, 30, 30) | |
switch_outline_color_on = (0, 60, 0) | |
background_color_off = (255, 255, 255) | |
background_color_on = (90, 255, 90) | |
background_outline_color_off = background_color_off | |
background_outline_color_on = background_color_on | |
switch_width=4*switch_radius # This is a good aspect ratio to start with | |
switch_stroke = 2 # Width of the outlines (in pixels) | |
text_stroke = switch_stroke # width of text lines | |
touch_padding = 0 # Additional boundary around widget that will accept touch input | |
animation_time = 0.2 # time for switch to display change (in seconds). 0.15 is a good starting point | |
display_text = True # show the text (0/1) | |
# initialize state variables | |
switch_value=False | |
switch_value=True | |
my_switch=SwitchRoundHorizontal(x=switch_x, y=switch_y, | |
height=switch_radius*2, | |
fill_color_off=switch_fill_color_off, | |
fill_color_on=switch_fill_color_on, | |
outline_color_off=switch_outline_color_off, | |
outline_color_on=switch_outline_color_on, | |
background_color_off=background_color_off, | |
background_color_on=background_color_on, | |
background_outline_color_off=background_outline_color_off, | |
background_outline_color_on=background_outline_color_on, | |
switch_stroke=switch_stroke, | |
display_button_text=display_text, | |
touch_padding=10, | |
animation_time=animation_time, | |
value=False) | |
my_switch2=SwitchRoundHorizontal(x=switch_x+100, y=switch_y, | |
height=switch_radius*2, | |
fill_color_off=switch_fill_color_off, | |
fill_color_on=switch_fill_color_on, | |
outline_color_off=switch_outline_color_off, | |
outline_color_on=switch_outline_color_on, | |
background_color_off=background_color_off, | |
background_color_on=background_color_on, | |
background_outline_color_off=background_outline_color_off, | |
background_outline_color_on=background_outline_color_on, | |
switch_stroke=switch_stroke, | |
display_button_text=False, | |
touch_padding=touch_padding, | |
animation_time=animation_time, | |
value=False) | |
my_switch3=SwitchRoundHorizontal(x=switch_x, y=switch_y+55, | |
height=switch_radius*2, | |
fill_color_off=(255, 0, 0), | |
fill_color_on=switch_fill_color_on, | |
outline_color_off=(80, 0, 0), | |
outline_color_on=switch_outline_color_on, | |
background_color_off=(150, 0, 0), | |
background_color_on=background_color_on, | |
background_outline_color_off=(30, 0, 0), | |
background_outline_color_on=background_outline_color_on, | |
switch_stroke=switch_stroke, | |
display_button_text=True, | |
touch_padding=touch_padding, | |
animation_time=animation_time, | |
value=False) | |
my_switch4=SwitchRoundHorizontal(x=switch_x+100, y=switch_y+55, | |
height=switch_radius*2, | |
fill_color_off=(255, 0, 0), | |
fill_color_on=switch_fill_color_on, | |
outline_color_off=(80, 0, 0), | |
outline_color_on=switch_outline_color_on, | |
background_color_off=(150, 0, 0), | |
background_color_on=background_color_on, | |
background_outline_color_off=(30, 0, 0), | |
background_outline_color_on=background_outline_color_on, | |
switch_stroke=switch_stroke, | |
display_button_text=False, | |
touch_padding=touch_padding, | |
animation_time=animation_time, | |
value=False) | |
my_switch5=SwitchRoundHorizontal(x=0, y=0, | |
height=switch_radius*4, | |
fill_color_off=switch_fill_color_off, | |
fill_color_on=switch_fill_color_on, | |
outline_color_off=switch_outline_color_off, | |
outline_color_on=switch_outline_color_on, | |
background_color_off=background_color_off, | |
background_color_on=background_color_on, | |
background_outline_color_off=background_outline_color_off, | |
background_outline_color_on=background_outline_color_on, | |
switch_stroke=switch_stroke, | |
display_button_text=True, | |
touch_padding=10, | |
animation_time=0.3, # for larger button, may want to extend the animation time | |
text_stroke=6, ## Add a wider text stroke | |
value=False) | |
# demonstrate relocation of a switch position using anchor_point, anchored_position | |
#my_switch.x=0 | |
#my_switch.y=0 | |
my_switch5.anchor_point=(1,1) | |
my_switch5.anchored_position=(305, 225) | |
# visually verify the bounding_box and touch_boundary | |
this_switch=my_switch5 | |
rect=Rect(x=this_switch.x, y=this_switch.y, | |
width=this_switch.bounding_box[2], | |
height=this_switch.bounding_box[3], | |
fill=0x777777, | |
outline=0x000000, | |
stroke=1) | |
rect2=Rect(x=this_switch.x+this_switch.touch_boundary[0], | |
y=this_switch.y+this_switch.touch_boundary[1], | |
width=this_switch.touch_boundary[2], | |
height=this_switch.touch_boundary[3], | |
fill=0xAAAAAA, | |
outline=0xFFFFFF, stroke=1) | |
my_group=displayio.Group(max_size=8) | |
#my_group.append(rect2) | |
#my_group.append(rect) | |
my_group.append(my_switch) | |
my_group.append(my_switch2) | |
my_group.append(my_switch3) | |
my_group.append(my_switch4) | |
my_group.append(my_switch5) | |
# Add my_group to the display | |
display.show(my_group) | |
display.refresh(target_frames_per_second=60, minimum_frames_per_second=30) | |
## Robotic switching demo | |
# sleep_time=0.5 | |
# fake_touch_point=[0,0,0] | |
# time.sleep(sleep_time) | |
# my_switch.selected(fake_touch_point) | |
# time.sleep(sleep_time) | |
# my_switch.selected(fake_touch_point) | |
# time.sleep(sleep_time) | |
# my_switch2.selected(fake_touch_point) | |
# time.sleep(sleep_time) | |
# my_switch2.selected(fake_touch_point) | |
# time.sleep(sleep_time) | |
# my_switch3.selected(fake_touch_point) | |
# time.sleep(sleep_time) | |
# my_switch4.selected(fake_touch_point) | |
# time.sleep(sleep_time) | |
# my_switch3.selected(fake_touch_point) | |
# time.sleep(sleep_time) | |
# my_switch4.selected(fake_touch_point) | |
# time.sleep(sleep_time) | |
# my_switch5.selected(fake_touch_point) | |
# time.sleep(sleep_time) | |
# my_switch5.selected(fake_touch_point) | |
# time.sleep(sleep_time) | |
# my_switch5.selected(fake_touch_point) | |
# time.sleep(sleep_time) | |
# my_switch5.selected(fake_touch_point) | |
# Start the main loop | |
while True: | |
p = ts.touch_point | |
#print("touch_point p: {}".format(p)) | |
if p: | |
#this_switch=my_switch5 | |
#print("this_switch x,y: {},{}, touch_boundary: {}".format(this_switch.x, this_switch.y, this_switch.touch_boundary)) | |
#print("bounding_box: {}".format(this_switch.bounding_box)) | |
if my_switch.contains(p): | |
my_switch.selected(p) | |
elif my_switch2.contains(p): | |
my_switch2.selected(p) | |
elif my_switch3.contains(p): | |
my_switch3.selected(p) | |
elif my_switch4.contains(p): | |
my_switch4.selected(p) | |
elif my_switch5.contains(p): | |
#print("switch5 touched") | |
my_switch5.selected(p) | |
time.sleep(0.05) # touch responce is more accurate with a small delayed added | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The MIT License (MIT) | |
# | |
# Copyright (c) 2021 Kevin Matocha (kmatch98) | |
# | |
# Permission is hereby granted, free of charge, to any person obtaining a copy | |
# of this software and associated documentation files (the "Software"), to deal | |
# in the Software without restriction, including without limitation the rights | |
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
# copies of the Software, and to permit persons to whom the Software is | |
# furnished to do so, subject to the following conditions: | |
# | |
# The above copyright notice and this permission notice shall be included in | |
# all copies or substantial portions of the Software. | |
# | |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
# THE SOFTWARE. | |
# | |
################################ | |
# A round switch widget for CircuitPython, using displayio and adafruit_display_shapes | |
# | |
# Features: | |
# - Color grading as the switch animates between the off and on states | |
# - Option to display 0 or 1 to confirm the switch state (display_button_text=True) | |
# - Provides setting for animation_time (approximate), and adapts redraw rate based on real time. | |
# | |
# | |
# Open items: ****** | |
# - Clarify x,y placement for widgets. Should this correspond to the upper-left corner or the center? | |
# - Update color handling for either RGB tuples or RGB hex codes | |
# - For `selected` function, make `touch_point` input as optional | |
# - Update documentation | |
# | |
# | |
# Structural parameters | |
# -------------------- | |
# - x,y: position: upper left corner pixel position | |
# - width: (default width is calculated based on radius) | |
# - height: (pixel height of button, may be rounded up by 1) | |
# - name: string | |
# - switch_fill_color_off: RGB | |
# - switch_fill_color_on: RGB | |
# - switch_outline_color_off: RGB | |
# - switch_outline_color_on: RGB | |
# - background_color_off: RGB | |
# - background_color_on: RGB | |
# - background_outline_color_off: RGB | |
# - background_outline_color_on: RGB | |
# | |
# - display_button_text: Boolean to select if the 0/1 is displayed on the switch | |
# - animation_time: in seconds, approximate duration of the animation | |
# | |
# - touch_padding: additional pixels outside of the bounding_box to accept touch input, affects `touch_boundary` | |
# | |
# | |
# other instance variables: | |
# ------------------------- | |
# - value: Boolean getter/setter (upon a state change, this will perform the switch animation) | |
# - bounding_box: [x, y, width, height] where x,y is the upper left corner offset from self.x, self.y | |
# - touch_boundary: [x, y, width, height] touch area, where x,y is the upper left corner offset from self.x, self.y | |
# Note that the `touch_boundary` can be different from the bounding_box | |
# | |
# animation trigger: | |
# ------------------ | |
# - selected(touch_point): flips the switch, setter only | |
# | |
# other functions: | |
# ---------------- | |
# - contains(touch_point): check for touch input inside of `touch_boundary` | |
# | |
# Future options to consider: | |
# --------------------------- | |
# rotation? | |
# | |
import displayio | |
import time | |
from adafruit_display_shapes.circle import Circle | |
from adafruit_display_shapes.roundrect import RoundRect | |
from adafruit_display_shapes.rect import Rect | |
def _color_fade(start_color, end_color, fraction): | |
if fraction >= 1: | |
return end_color | |
if fraction <= 0: | |
return start_color | |
else: | |
faded_color = [0,0,0] | |
for i in range(3): | |
faded_color[i] = start_color[i] - int((start_color[i]-end_color[i])* fraction) | |
return faded_color | |
class SwitchRoundHorizontal(displayio.Group): | |
def __init__( | |
self, | |
*, | |
x=0, # Placement of upper left corner pixel position on the display | |
y=0, | |
width=None, # defaults to the 4*radius | |
height=30, | |
name="", | |
value=False, | |
touch_padding=0, | |
anchor_point=None, | |
anchored_position=None, | |
fill_color_off=(66, 44, 66), | |
fill_color_on=(0,100,0), | |
outline_color_off=(30,30,30), | |
outline_color_on=(0,60,0), | |
background_color_off=(255,255,255), | |
background_color_on=(0,60,0), | |
background_outline_color_off=None, # default to background_color_off | |
background_outline_color_on=None, # default to background_color_on | |
switch_stroke=2, | |
text_stroke=None, # default to switch_stroke | |
display_button_text=True, | |
animation_time=0.2, # animation duration (in seconds) | |
): | |
super().__init__(x=x, y=y, max_size=3) | |
# Group elements: | |
# 1. switch_roundrect: The switch background | |
# 2. switch_circle: The switch button | |
# 3. text_0 or text_1: The text on the switch button | |
self.name = name | |
self._radius = height//2 | |
switch_x = self._radius | |
switch_y = self._radius | |
if width is None: | |
self._width = 4 * self._radius | |
else: | |
self._width = width | |
self._name = name # button name | |
if background_outline_color_off is None: | |
background_outline_color_off = background_color_off | |
if background_outline_color_on is None: | |
background_outline_color_on = background_color_on | |
self._fill_color_off = fill_color_off | |
self._fill_color_on = fill_color_on | |
self._outline_color_off = outline_color_off | |
self._outline_color_on = outline_color_on | |
self._background_color_off = background_color_off | |
self._background_color_on = background_color_on | |
self._background_outline_color_off = background_outline_color_off | |
self._background_outline_color_on = background_outline_color_on | |
self._switch_stroke=switch_stroke | |
if text_stroke is None: | |
text_stroke = switch_stroke # width of text lines | |
self._text_stroke = text_stroke | |
self._display_button_text = display_button_text # state variable whether text (0/1) is displayed | |
self._touch_padding = touch_padding | |
self._animation_time = animation_time | |
self._value = value | |
self._text_0_on = not value # controls which text value is displayed (0 or 1) | |
self._anchor_point = anchor_point | |
self._anchored_position = anchored_position | |
# initialize the display elements | |
self._switch_circle = Circle(x0=switch_x, y0=switch_y, | |
r=self._radius, | |
fill=self._fill_color_off, | |
outline=self._outline_color_off, | |
stroke=self._switch_stroke) | |
self._switch_roundrect = RoundRect(x=switch_x-self._radius, y=switch_y-self._radius, | |
r=self._radius, | |
width=self._width, height=2*self._radius+1, | |
fill=self._background_color_off, | |
outline=self._background_outline_color_off, stroke=self._switch_stroke) | |
self._bounding_box = [self._switch_circle.x, | |
self._switch_circle.y, | |
self._width, | |
2*self._radius+1] | |
# bounding_box defines the "local" x and y. | |
# Must be offset by self.x and self.y to get the raw display coordinates | |
self._touch_boundary = [self._bounding_box[0]-self._touch_padding, | |
self._bounding_box[1]-self._touch_padding, | |
self._bounding_box[2]+2*self._touch_padding, | |
self._bounding_box[3]+2*self._touch_padding] | |
# The 0 text circle | |
self._text_0 = Circle(x0=switch_x, y0=switch_y, | |
r=self._radius//2, | |
fill=self._fill_color_off, | |
outline=self._outline_color_off, | |
stroke=self._text_stroke) | |
# The 1 text rectangle | |
self._text_1 = Rect(x=switch_x-self._switch_stroke+1, y=switch_y-self._radius//2, | |
height=self._radius, | |
width=self._text_stroke, | |
fill=self._fill_color_off, | |
outline=self._outline_color_off, | |
stroke=self._text_stroke) | |
# Store initial positions of the moving parts | |
self._switch_initial_x=self._switch_circle.x | |
self._text_0_initial_x=self._text_0.x | |
self._text_1_initial_x=self._text_1.x | |
# Set the initial switch position based on the starting value | |
if value: | |
self._draw_position(1) | |
else: | |
self._draw_position(0) | |
# Add the display elements to the self group | |
self.append(self._switch_roundrect) | |
self.append(self._switch_circle) | |
# Add the correct text element, if display_button_text is True | |
if display_button_text: | |
if (self._text_0_on): | |
self.append(self._text_0) | |
else: | |
self.append(self._text_1) | |
# update the position, if required | |
self._update_position | |
def _update_position(self): | |
# reposition self group based on anchor_point and anchored_position | |
if (self._anchor_point is not None) and (self._anchored_position is not None): | |
self.x=self._anchored_position[0]-int(self._anchor_point[0]*self._bounding_box[2]) - self._bounding_box[0] | |
self.y=self._anchored_position[1]-int(self._anchor_point[1]*self._bounding_box[3]) - self._bounding_box[1] | |
def _draw_position(self, position): | |
# To deal with any integer rounding errors | |
if position <= 0: # left-end position | |
self._switch_circle.x = self._switch_initial_x | |
self._text_0.x=self._text_0_initial_x | |
self._text_1.x=self._text_1_initial_x | |
elif position >= 1: # right-end position | |
self._switch_circle.x = self._switch_initial_x + self._width-2*self._radius-1 | |
self._text_0.x = self._text_0_initial_x + self._width-2*self._radius-1 | |
self._text_1.x = self._text_1_initial_x + self._width-2*self._radius-1 | |
else: # somewhere in the middle | |
self._switch_circle.x = self._switch_initial_x + int((self._width - (2 * self._radius) - 1)*position) | |
self._text_0.x = self._text_0_initial_x + int((self._width - (2 * self._radius) - 1)*position) | |
self._text_1.x = self._text_1_initial_x + int((self._width - (2 * self._radius) - 1)*position) | |
# Set the color to the correct fade | |
self._switch_circle.fill = _color_fade(self._fill_color_off, self._fill_color_on, position) | |
self._switch_circle.outline = _color_fade(self._outline_color_off, self._outline_color_on, position) | |
self._switch_roundrect.fill = _color_fade(self._background_color_off, self._background_color_on, position) | |
self._switch_roundrect.outline = _color_fade(self._background_outline_color_off, self._background_outline_color_on, position) | |
self._text_0.fill = self._switch_circle.fill | |
self._text_1.fill = self._switch_circle.fill | |
self._text_0.outline = self._switch_circle.outline | |
self._text_1.outline = self._switch_circle.outline | |
if (self._display_button_text and position > 0.5 and self._text_0_on): | |
self.pop() | |
self.append(self._text_1) | |
self._text_0_on = False | |
elif (self._display_button_text and position < 0.5 and not self._text_0_on): | |
self.pop() | |
self.append(self._text_0) | |
self._text_0_on = True | |
def selected(self, touch_point): # requires passing display to allow auto_refresh off when redrawing | |
# touch_point is a tuple: (x, y, pressure) | |
start_time=time.monotonic() | |
while True: | |
if self._value: | |
position = 1 - (time.monotonic() - start_time)/self._animation_time # fraction from 0 to 1 | |
else: | |
position = (time.monotonic() - start_time)/self._animation_time # fraction from 0 to 1 | |
self._draw_position(position) # update the switch position | |
if ((position >= 1) and not self._value): # ensures that the final position is drawn | |
self._value=True | |
break | |
if ((position <= 0) and self._value): # ensures that the final position is drawn | |
self._value=False | |
break | |
def contains(self, touch_point): | |
"""Returns True if the touch_point is within the widget's touch_boundary.""" | |
touch_x = touch_point[0] - self.x # adjust touch position for the local position | |
touch_y = touch_point[1] - self.y | |
if ( (self._touch_boundary[0] <= touch_x <= (self._touch_boundary[0]+self._touch_boundary[2])) and | |
(self._touch_boundary[1] <= touch_y <= (self._touch_boundary[1]+self._touch_boundary[3])) ): | |
return True | |
return False | |
@property | |
def bounding_box(self): | |
"""The boundary of the widget. Defined as a [x, y, width, height] where x,y are | |
offset from self.x and self.y.""" | |
return self._bounding_box | |
@property | |
def touch_boundary(self): | |
"""The region that responds to touch using the `contain(touch_point)` function. | |
Defined as a [x, y, width, height] where x,y are offset from self.x and self.y.""" | |
return self._touch_boundary | |
@touch_boundary.setter | |
def touch_boundary(self, new_touch_boundary): | |
self._touch_boundary = new_touch_boundary | |
@property | |
def value(self): | |
"""The current Boolean switch value.""" | |
return self._value | |
@value.setter | |
def value(self, new_value): | |
if (new_value != self._value): | |
fake_touch_point=[0,0,0] | |
self.selected(fake_touch_point) | |
@property | |
def anchor_point(self): | |
"""The anchor point for positioning the switch, works in concert with `anchored_position`.""" | |
return self._anchor_point | |
@anchor_point.setter | |
def anchor_point(self, new_anchor_point): | |
self._anchor_point = new_anchor_point | |
self._update_position() | |
@property | |
def anchored_position(self): | |
"""The anchored position for positioning the switch, works in concert with `anchor_point`.""" | |
return self._anchored_position | |
@anchored_position.setter | |
def anchored_position(self, new_anchored_position): | |
self._anchored_position = new_anchored_position | |
self._update_position() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment