/ PyPortal_Calculator / code.py
code.py
1 # SPDX-FileCopyrightText: 2019 Melissa LeBlanc-Williams for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 5 """ 6 PyPortal Calculator Demo 7 """ 8 import time 9 from collections import namedtuple 10 import board 11 import displayio 12 from adafruit_display_text.label import Label 13 from adafruit_bitmap_font import bitmap_font 14 from adafruit_display_shapes.rect import Rect 15 from adafruit_button import Button 16 from calculator import Calculator 17 import adafruit_touchscreen 18 Coords = namedtuple("Point", "x y") 19 20 ts = adafruit_touchscreen.Touchscreen(board.TOUCH_XL, board.TOUCH_XR, 21 board.TOUCH_YD, board.TOUCH_YU, 22 calibration=((5200, 59000), (5800, 57000)), 23 size=(320, 240)) 24 25 # Settings 26 BUTTON_WIDTH = 60 27 BUTTON_HEIGHT = 30 28 BUTTON_MARGIN = 8 29 MAX_DIGITS = 29 30 BLACK = 0x0 31 ORANGE = 0xFF8800 32 WHITE = 0xFFFFFF 33 GRAY = 0x888888 34 LABEL_OFFSET = 290 35 36 # Make the display context 37 calc_group = displayio.Group() 38 board.DISPLAY.show(calc_group) 39 40 # Make a background color fill 41 color_bitmap = displayio.Bitmap(320, 240, 1) 42 color_palette = displayio.Palette(1) 43 color_palette[0] = GRAY 44 bg_sprite = displayio.TileGrid(color_bitmap, 45 pixel_shader=color_palette, 46 x=0, y=0) 47 calc_group.append(bg_sprite) 48 49 # Load the font 50 font = bitmap_font.load_font("/fonts/Arial-12.bdf") 51 buttons = [] 52 53 # Some button functions 54 def button_grid(row, col): 55 return Coords(BUTTON_MARGIN * (row + 1) + BUTTON_WIDTH * row + 20, 56 BUTTON_MARGIN * (col + 1) + BUTTON_HEIGHT * col + 40) 57 58 def add_button(row, col, label, width=1, color=WHITE, text_color=BLACK): 59 pos = button_grid(row, col) 60 new_button = Button(x=pos.x, y=pos.y, 61 width=BUTTON_WIDTH * width + BUTTON_MARGIN * (width - 1), 62 height=BUTTON_HEIGHT, label=label, label_font=font, 63 label_color=text_color, fill_color=color, style=Button.ROUNDRECT) 64 buttons.append(new_button) 65 return new_button 66 67 def find_button(label): 68 result = None 69 for _, btn in enumerate(buttons): 70 if btn.label == label: 71 result = btn 72 return result 73 74 border = Rect(20, 8, 280, 35, fill=WHITE, outline=BLACK, stroke=2) 75 calc_display = Label(font, text="0", color=BLACK) 76 calc_display.y = 25 77 78 clear_button = add_button(0, 0, "AC") 79 add_button(1, 0, "+/-") 80 add_button(2, 0, "%") 81 add_button(3, 0, "/", 1, ORANGE, WHITE) 82 add_button(0, 1, "7") 83 add_button(1, 1, "8") 84 add_button(2, 1, "9") 85 add_button(3, 1, "x", 1, ORANGE, WHITE) 86 add_button(0, 2, "4") 87 add_button(1, 2, "5") 88 add_button(2, 2, "6") 89 add_button(3, 2, "-", 1, ORANGE, WHITE) 90 add_button(0, 3, "1") 91 add_button(1, 3, "2") 92 add_button(2, 3, "3") 93 add_button(3, 3, "+", 1, ORANGE, WHITE) 94 add_button(0, 4, "0", 2) 95 add_button(2, 4, ".") 96 add_button(3, 4, "=", 1, ORANGE, WHITE) 97 98 # Add the display and buttons to the main calc group 99 calc_group.append(border) 100 calc_group.append(calc_display) 101 for b in buttons: 102 calc_group.append(b) 103 104 calculator = Calculator(calc_display, clear_button, LABEL_OFFSET) 105 106 button = "" 107 while True: 108 point = ts.touch_point 109 if point is not None: 110 # Button Down Events 111 for _, b in enumerate(buttons): 112 if b.contains(point) and button == "": 113 b.selected = True 114 button = b.label 115 elif button != "": 116 # Button Up Events 117 last_op = calculator.get_current_operator() 118 op_button = find_button(last_op) 119 # Deselect the last operation when certain buttons are pressed 120 if op_button is not None: 121 if button in ('=', 'AC', 'CE'): 122 op_button.selected = False 123 elif button in ('+', '-', 'x', '/') and button != last_op: 124 op_button.selected = False 125 calculator.add_input(button) 126 b = find_button(button) 127 if b is not None: 128 if button not in ('+', '-', 'x', '/') or button != calculator.get_current_operator(): 129 b.selected = False 130 button = "" 131 time.sleep(0.05)