From 44a9a8eee9683d9a8ac96f5c3e3d2e882cf17449 Mon Sep 17 00:00:00 2001 From: Tom Charnock Date: Fri, 3 Jan 2025 20:11:13 +0100 Subject: [PATCH] Working with test words (hello my name is Tom) and implemented shortcuts (but no shortcuts added) --- characters.py | 588 +++++++++++++++++++++++++++++++++++++++++++------- code.py | 241 +++++++++++++++------ flake.nix | 1 + 3 files changed, 684 insertions(+), 146 deletions(-) diff --git a/characters.py b/characters.py index 438bb01..9353495 100644 --- a/characters.py +++ b/characters.py @@ -1,5 +1,6 @@ try: from adafruit_hid.keycode import Keycode + keycodes = { "\ue31e": [Keycode.SPACEBAR], "\u002e": [Keycode.PERIOD], @@ -34,85 +35,85 @@ try: "\u0049": [Keycode.SHIFT, Keycode.I], "\u002a": [Keycode.SHIFT, Keycode.EIGHT], "\u0037": [Keycode.SEVEN], - "\u0063": [Keycode.C], + "\u0063": [Keycode.C], "\u0043": [Keycode.SHIFT, Keycode.C], - "\u005c": [Keycode.BACKSLASH], - "\u2229": [Keycode.LEFT_CONTROL, Keycode.A], - "\u0078": [Keycode.X], - "\u0058": [Keycode.SHIFT, Keycode.X], - "\u0022": [Keycode.SHIFT, Keycode.QUOTE], + "\u005c": [Keycode.BACKSLASH], + "\u2229": [Keycode.LEFT_CONTROL, Keycode.A], + "\u0078": [Keycode.X], + "\u0058": [Keycode.SHIFT, Keycode.X], + "\u0022": [Keycode.SHIFT, Keycode.QUOTE], "\u0039": [Keycode.NINE], - "\u006c": [Keycode.L], - "\u004c": [Keycode.SHIFT, Keycode.L], - "\u007e": [Keycode.SHIFT, Keycode.GRAVE_ACCENT], + "\u006c": [Keycode.L], + "\u004c": [Keycode.SHIFT, Keycode.L], + "\u007e": [Keycode.SHIFT, Keycode.GRAVE_ACCENT], "\u21da": [Keycode.APPLICATION, Keycode.LEFT_ARROW], - "\u007a": [Keycode.Z], - "\u005a": [Keycode.SHIFT, Keycode.Z], - "\u003e": [Keycode.SHIFT, Keycode.PERIOD], + "\u007a": [Keycode.Z], + "\u005a": [Keycode.SHIFT, Keycode.Z], + "\u003e": [Keycode.SHIFT, Keycode.PERIOD], "\u21db": [Keycode.APPLICATION, Keycode.RIGHT_ARROW], - "\u0064": [Keycode.D], - "\u0044": [Keycode.SHIFT, Keycode.D], - "\u0060": [Keycode.GRAVE_ACCENT], + "\u0064": [Keycode.D], + "\u0044": [Keycode.SHIFT, Keycode.D], + "\u0060": [Keycode.GRAVE_ACCENT], "\uebd2": [Keycode.LEFT_CONTROL, Keycode.V], - "\u0068": [Keycode.H], + "\u0068": [Keycode.H], "\u0048": [Keycode.SHIFT, Keycode.H], - "\u0040": [Keycode.SHIFT, Keycode.TWO], + "\u0040": [Keycode.SHIFT, Keycode.TWO], "\u0030": [Keycode.ZERO], - "\u21b5": [Keycode.RETURN], - "\u21ab": [Keycode.SHIFT, Keycode.RETURN], - "\u002d": [Keycode.MINUS], + "\u21b5": [Keycode.RETURN], + "\u21ab": [Keycode.SHIFT, Keycode.RETURN], + "\u002d": [Keycode.MINUS], "\u21ff": [Keycode.PRINT_SCREEN], - "\u006f": [Keycode.O], - "\u004f": [Keycode.SHIFT, Keycode.O], + "\u006f": [Keycode.O], + "\u004f": [Keycode.SHIFT, Keycode.O], "\u0029": [Keycode.SHIFT, Keycode.ZERO], "\u2193": [Keycode.DOWN_ARROW], - "\u006d": [Keycode.M], - "\u004d": [Keycode.SHIFT, Keycode.M], + "\u006d": [Keycode.M], + "\u004d": [Keycode.SHIFT, Keycode.M], "\u0028": [Keycode.SHIFT, Keycode.NINE], "\u2192": [Keycode.RIGHT_ARROW], - "\u0070": [Keycode.P], - "\u0050": [Keycode.SHIFT, Keycode.P], + "\u0070": [Keycode.P], + "\u0050": [Keycode.SHIFT, Keycode.P], "\u005f": [Keycode.SHIFT, Keycode.MINUS], - "\u0066": [Keycode.F], - "\u0046": [Keycode.SHIFT, Keycode.F], + "\u0066": [Keycode.F], + "\u0046": [Keycode.SHIFT, Keycode.F], "\u0023": [Keycode.SHIFT, Keycode.THREE], "\u2191": [Keycode.UP_ARROW], - "\u0077": [Keycode.W], - "\u0057": [Keycode.SHIFT, Keycode.W], + "\u0077": [Keycode.W], + "\u0057": [Keycode.SHIFT, Keycode.W], "\u007c": [Keycode.SHIFT, Keycode.BACKSLASH], - "\u006a": [Keycode.J], - "\u004a": [Keycode.SHIFT, Keycode.J], + "\u006a": [Keycode.J], + "\u004a": [Keycode.SHIFT, Keycode.J], "\u0025": [Keycode.SHIFT, Keycode.FIVE], - "\u0071": [Keycode.Q], - "\u0051": [Keycode.SHIFT, Keycode.Q], + "\u0071": [Keycode.Q], + "\u0051": [Keycode.SHIFT, Keycode.Q], "\u003f": [Keycode.SHIFT, Keycode.FORWARD_SLASH], - "\u0079": [Keycode.Y], - "\u0059": [Keycode.SHIFT, Keycode.Y], + "\u0079": [Keycode.Y], + "\u0059": [Keycode.SHIFT, Keycode.Y], "\u0024": [Keycode.SHIFT, Keycode.FOUR], "\u2190": [Keycode.LEFT_ARROW], - "\u0062": [Keycode.B], - "\u0042": [Keycode.SHIFT, Keycode.B], + "\u0062": [Keycode.B], + "\u0042": [Keycode.SHIFT, Keycode.B], "\u007d": [Keycode.SHIFT, Keycode.RIGHT_BRACKET], - "\u006b": [Keycode.K], - "\u004b": [Keycode.SHIFT, Keycode.K], + "\u006b": [Keycode.K], + "\u004b": [Keycode.SHIFT, Keycode.K], "\u007b": [Keycode.SHIFT, Keycode.LEFT_BRACKET], - "\u0067": [Keycode.G], - "\u0047": [Keycode.SHIFT, Keycode.G], + "\u0067": [Keycode.G], + "\u0047": [Keycode.SHIFT, Keycode.G], "\u0021": [Keycode.SHIFT, Keycode.ONE], - "\u0073": [Keycode.S], - "\u0053": [Keycode.SHIFT, Keycode.S], + "\u0073": [Keycode.S], + "\u0053": [Keycode.SHIFT, Keycode.S], "\u005e": [Keycode.SHIFT, Keycode.SIX], "\u21e4": [Keycode.HOME], - "\u0076": [Keycode.V], - "\u0056": [Keycode.SHIFT, Keycode.V], + "\u0076": [Keycode.V], + "\u0056": [Keycode.SHIFT, Keycode.V], "\u005d": [Keycode.RIGHT_BRACKET], "\u21e5": [Keycode.END], - "\u006e": [Keycode.N], - "\u004e": [Keycode.SHIFT, Keycode.N], + "\u006e": [Keycode.N], + "\u004e": [Keycode.SHIFT, Keycode.N], "\u005b": [Keycode.LEFT_BRACKET], "\uebcc": [Keycode.LEFT_CONTROL, Keycode.C], - "\u0074": [Keycode.T], - "\u0054": [Keycode.SHIFT, Keycode.T], + "\u0074": [Keycode.T], + "\u0054": [Keycode.SHIFT, Keycode.T], "\u0026": [Keycode.SHIFT, Keycode.SEVEN], "\uf31a": [Keycode.APPLICATION], } @@ -125,44 +126,99 @@ characters = [ [ [ [ - [None, None, None, None], #00000 - ["\ue31e", "\u002e", "\u003c", "\u0031"], #00001 [SPACE, FULLSTOP, LESS THAN, 1] + [None, None, None, None], # 00000 + [ + "\ue31e", + "\u002e", + "\u003c", + "\u0031", + ], # 00001 [SPACE, FULLSTOP, LESS THAN, 1] ], [ - ["\u21b9", "\u002c", None, "\u0032"], #00010 [TAB, COMMA, None, 2] - ["\u0065", "\u0045", "\u003d", "\u0035"], #00011 [e, E, EQUALS, 5] + ["\u21b9", "\u002c", None, "\u0032"], # 00010 [TAB, COMMA, None, 2] + ["\u0065", "\u0045", "\u003d", "\u0035"], # 00011 [e, E, EQUALS, 5] ], ], [ [ - ["\u21dc", "\u003a", None, "\u0033"], #00100 [BACKSPACE, COLON, None, 3] - ["\u0061", "\u0041", "\u002b", "\u0036"], #00101 [a, A, PLUS, 6] + [ + "\u21dc", + "\u003a", + None, + "\u0033", + ], # 00100 [BACKSPACE, COLON, None, 3] + ["\u0061", "\u0041", "\u002b", "\u0036"], # 00101 [a, A, PLUS, 6] ], [ - ["\u0072", "\u0052", "\u002f", "\uea6d"], #00110 [r, R, SLASH, CTRL+F] - ["\u0075", "\u0055", "\u0027", "\u0038"], #00111 [u, U, APOSTROPHE, 8] + [ + "\u0072", + "\u0052", + "\u002f", + "\uea6d", + ], # 00110 [r, R, SLASH, CTRL+F] + [ + "\u0075", + "\u0055", + "\u0027", + "\u0038", + ], # 00111 [u, U, APOSTROPHE, 8] ], ], ], [ [ [ - ["\u21af", "\u003b", None, "\u0034"], #01000 [ESCAPE, SEMICOLON, None, 4] - ["\u0069", "\u0049", "\u002a", "\u0037"], #01001 [i, I, ASTERISK, 7] + [ + "\u21af", + "\u003b", + None, + "\u0034", + ], # 01000 [ESCAPE, SEMICOLON, None, 4] + [ + "\u0069", + "\u0049", + "\u002a", + "\u0037", + ], # 01001 [i, I, ASTERISK, 7] ], [ - ["\u0063", "\u0043", "\u005c", "\u2229"], #01010 [c, C, BACKSLASH, CTRL+A] - ["\u0078", "\u0058", "\u0022", "\u0039"], #01011 [x, X, DOUBLE QUOTES, 9] + [ + "\u0063", + "\u0043", + "\u005c", + "\u2229", + ], # 01010 [c, C, BACKSLASH, CTRL+A] + [ + "\u0078", + "\u0058", + "\u0022", + "\u0039", + ], # 01011 [x, X, DOUBLE QUOTES, 9] ], ], [ [ - ["\u006c", "\u004c", "\u007e", "\u21da"], #01100 [l, L, TILDE, SUPER LEFT] - ["\u007a", "\u005a", "\u003e", "\u21db"], #01101 [z, Z, GREATER THAN, SUPER RIGHT] + [ + "\u006c", + "\u004c", + "\u007e", + "\u21da", + ], # 01100 [l, L, TILDE, SUPER LEFT] + [ + "\u007a", + "\u005a", + "\u003e", + "\u21db", + ], # 01101 [z, Z, GREATER THAN, SUPER RIGHT] ], [ - ["\u0064", "\u0044", "\u0060", "\uebd2"], #01110 [d, D, TICK, CTRL+V] - ["\u0068", "\u0048", "\u0040", "\u0030"], #01111 [h, H, AT, 0] + [ + "\u0064", + "\u0044", + "\u0060", + "\uebd2", + ], # 01110 [d, D, TICK, CTRL+V] + ["\u0068", "\u0048", "\u0040", "\u0030"], # 01111 [h, H, AT, 0] ], ], ], @@ -171,44 +227,109 @@ characters = [ [ [ [ - ["\u21b5", "\u21ab", "\u002d", "\u21ff"], #10000 [RETURN, SHIFT RETURN, MINUS, PRINT SCREEN] - ["\u006f", "\u004f", "\u0029", "\u2193"], #10001 [o, O, CLOSE BRACKET, DOWN] + [ + "\u21b5", + "\u21ab", + "\u002d", + "\u21ff", + ], # 10000 [RETURN, SHIFT RETURN, MINUS, PRINT SCREEN] + [ + "\u006f", + "\u004f", + "\u0029", + "\u2193", + ], # 10001 [o, O, CLOSE BRACKET, DOWN] ], [ - ["\u006d", "\u004d", "\u0028", "\u2192"], #10010 [m, M, OPEN BRACKET, RIGHT] - ["\u0070", "\u0050", "\u005f", None], #10011 [p, P, UNDERSCORE, None] + [ + "\u006d", + "\u004d", + "\u0028", + "\u2192", + ], # 10010 [m, M, OPEN BRACKET, RIGHT] + [ + "\u0070", + "\u0050", + "\u005f", + None, + ], # 10011 [p, P, UNDERSCORE, None] ], ], [ [ - ["\u0066", "\u0046", "\u0023", "\u2191"], #10100 [f, F, HASH, UP] - ["\u0077", "\u0057", "\u007c", None], #10101 [w, W, PIPE, None] + ["\u0066", "\u0046", "\u0023", "\u2191"], # 10100 [f, F, HASH, UP] + ["\u0077", "\u0057", "\u007c", None], # 10101 [w, W, PIPE, None] ], [ - ["\u006a", "\u004a", "\u0025", None], #10110 [j, J, PERCENT, None] - ["\u0071", "\u0051", "\u003f", None], #10111 [q, Q, QUESTION MARK, None] + ["\u006a", "\u004a", "\u0025", None], # 10110 [j, J, PERCENT, None] + [ + "\u0071", + "\u0051", + "\u003f", + None, + ], # 10111 [q, Q, QUESTION MARK, None] ], ], ], [ [ [ - ["\u0079", "\u0059", "\u0024", "\u2190"], #11000 [y, Y, DOLLAR, LEFT] - ["\u0062", "\u0042", "\u007d", None], #11001 [b, B, CLOSE CURLY BRACKET, None] + [ + "\u0079", + "\u0059", + "\u0024", + "\u2190", + ], # 11000 [y, Y, DOLLAR, LEFT] + [ + "\u0062", + "\u0042", + "\u007d", + None, + ], # 11001 [b, B, CLOSE CURLY BRACKET, None] ], [ - ["\u006b", "\u004b", "\u007b", None], #11010 [k, K, OPEN CURLY BRACKET, None] - ["\u0067", "\u0047", "\u0021", None], #11011 [g, G, EXCLAMATION MARK, None] + [ + "\u006b", + "\u004b", + "\u007b", + None, + ], # 11010 [k, K, OPEN CURLY BRACKET, None] + [ + "\u0067", + "\u0047", + "\u0021", + None, + ], # 11011 [g, G, EXCLAMATION MARK, None] ], ], [ [ - ["\u0073", "\u0053", "\u005e", "\u21e4"], #11100 [s, S, CIRCUMFLEX, HOME] - ["\u0076", "\u0056", "\u005d", "\u21e5"], #11101 [v, V, CLOSE SQUARE BRACKET, END] + [ + "\u0073", + "\u0053", + "\u005e", + "\u21e4", + ], # 11100 [s, S, CIRCUMFLEX, HOME] + [ + "\u0076", + "\u0056", + "\u005d", + "\u21e5", + ], # 11101 [v, V, CLOSE SQUARE BRACKET, END] ], [ - ["\u006e", "\u004e", "\u005b", "\uebcc"], #11110 [n, N, OPEN SQUARE BRACKET, CTRL+C] - ["\u0074", "\u0054", "\u0026", "\uf31a"], #11111 [t, T, AMPERSAND, SUPER] + [ + "\u006e", + "\u004e", + "\u005b", + "\uebcc", + ], # 11110 [n, N, OPEN SQUARE BRACKET, CTRL+C] + [ + "\u0074", + "\u0054", + "\u0026", + "\uf31a", + ], # 11111 [t, T, AMPERSAND, SUPER] ], ], ], @@ -217,5 +338,306 @@ characters = [ extra_characters = ["\u00e9", "\u00e7"] +shortcuts = [ + [ + [ + [ + [ + [None, None, None, None], # 00000 + [None, None, None, None], # 00001 [None, None, None, None] + ], + [ + [None, None, None, None], # 00010 [None, None, None, None] + [None, None, None, None], # 00011 [None, None, None, None] + ], + ], + [ + [ + [None, None, None, None], # 00100 [None, None, None, None] + [None, None, None, None], # 00101 [None, None, None, None] + ], + [ + [None, None, None, None], # 00110 [None, None, None, None] + [None, None, None, None], # 00111 [None, None, None, None] + ], + ], + ], + [ + [ + [ + [None, None, None, None], # 01000 [None, None, None, None] + [None, None, None, None], # 01001 [None, None, None, None] + ], + [ + [None, None, None, None], # 01010 [None, None, None, None] + [None, None, None, None], # 01011 [None, None, None, None] + ], + ], + [ + [ + [None, None, None, None], # 01100 [None, None, None, None] + [None, None, None, None], # 01101 [None, None, None, None] + ], + [ + [None, None, None, None], # 01110 [None, None, None, None] + [None, None, None, None], # 01111 [None, None, None, None] + ], + ], + ], + ], + [ + [ + [ + [ + [None, None, None, None], # 10000 [None, None, None, None] + [None, None, None, None], # 10001 [None, None, None, None] + ], + [ + [None, None, None, None], # 10010 [None, None, None, None] + [None, None, None, None], # 10011 [None, None, None, None] + ], + ], + [ + [ + [None, None, None, None], # 10100 [None, None, None, None] + [None, None, None, None], # 10101 [None, None, None, None] + ], + [ + [None, None, None, None], # 10110 [None, None, None, None] + [None, None, None, None], # 10111 [None, None, None, None] + ], + ], + ], + [ + [ + [ + [None, None, None, None], # 11000 [None, None, None, None] + [None, None, None, None], # 11001 [None, None, None, None] + ], + [ + [None, None, None, None], # 11010 [None, None, None, None] + [None, None, None, None], # 11011 [None, None, None, None] + ], + ], + [ + [ + [None, None, None, None], # 11100 [None, None, None, None] + [None, None, None, None], # 11101 [None, None, None, None] + ], + [ + [None, None, None, None], # 11110 [None, None, None, None] + [None, None, None, None], # 11111 [None, None, None, None] + ], + ], + ], + ], +] + +words = [ + [ + [ + [ + [ + [ + [None, None, None, None], # 00000 + ["Tom", None, None, None], # 00001 [Tom, None, None, None] + ], + [ + ["is", None, None, None], # 00010 [is, None, None, None] + [None, None, None, None], # 00011 [None, None, None, None] + ], + ], + [ + [ + ["name", None, None, None], # 00100 [name, None, None, None] + [None, None, None, None], # 00101 [None, None, None, None] + ], + [ + [None, None, None, None], # 00110 [None, None, None, None] + [None, None, None, None], # 00111 [None, None, None, None] + ], + ], + ], + [ + [ + [ + ["my", None, None, None], # 01000 [my, None, None, None] + [None, None, None, None], # 01001 [None, None, None, None] + ], + [ + [None, None, None, None], # 01010 [None, None, None, None] + [None, None, None, None], # 01011 [None, None, None, None] + ], + ], + [ + [ + [None, None, None, None], # 01100 [None, None, None, None] + [None, None, None, None], # 01101 [None, None, None, None] + ], + [ + [None, None, None, None], # 01110 [None, None, None, None] + [None, None, None, None], # 01111 [None, None, None, None] + ], + ], + ], + ], + [ + [ + [ + [ + ["hello", None, None, None], # 10000 [Hello, None, None, None] + [None, None, None, None], # 10001 [None, None, None, None] + ], + [ + [None, None, None, None], # 10010 [None, None, None, None] + [None, None, None, None], # 10011 [None, None, None, None] + ], + ], + [ + [ + [None, None, None, None], # 10100 [None, None, None, None] + [None, None, None, None], # 10101 [None, None, None, None] + ], + [ + [None, None, None, None], # 10110 [None, None, None, None] + [None, None, None, None], # 10111 [None, None, None, None] + ], + ], + ], + [ + [ + [ + [None, None, None, None], # 11000 [None, None, None, None] + [None, None, None, None], # 11001 [None, None, None, None] + ], + [ + [None, None, None, None], # 11010 [None, None, None, None] + [None, None, None, None], # 11011 [None, None, None, None] + ], + ], + [ + [ + [None, None, None, None], # 11100 [None, None, None, None] + [None, None, None, None], # 11101 [None, None, None, None] + ], + [ + [None, None, None, None], # 11110 [None, None, None, None] + [None, None, None, None], # 11111 [None, None, None, None] + ], + ], + ], + ], + ], + [ + [ + [ + [ + [ + [None, None, None, None], # 00000 + [None, None, None, None], # 00001 [None, None, None, None] + ], + [ + [None, None, None, None], # 00010 [None, None, None, None] + [None, None, None, None], # 00011 [None, None, None, None] + ], + ], + [ + [ + [None, None, None, None], # 00100 [None, None, None, None] + [None, None, None, None], # 00101 [None, None, None, None] + ], + [ + [None, None, None, None], # 00110 [None, None, None, None] + [None, None, None, None], # 00111 [None, None, None, None] + ], + ], + ], + [ + [ + [ + [None, None, None, None], # 01000 [None, None, None, None] + [None, None, None, None], # 01001 [None, None, None, None] + ], + [ + [None, None, None, None], # 01010 [None, None, None, None] + [None, None, None, None], # 01011 [None, None, None, None] + ], + ], + [ + [ + [None, None, None, None], # 01100 [None, None, None, None] + [None, None, None, None], # 01101 [None, None, None, None] + ], + [ + [None, None, None, None], # 01110 [None, None, None, None] + [None, None, None, None], # 01111 [None, None, None, None] + ], + ], + ], + ], + [ + [ + [ + [ + [None, None, None, None], # 10000 [None, None, None, None] + [None, None, None, None], # 10001 [None, None, None, None] + ], + [ + [None, None, None, None], # 10010 [None, None, None, None] + [None, None, None, None], # 10011 [None, None, None, None] + ], + ], + [ + [ + [None, None, None, None], # 10100 [None, None, None, None] + [None, None, None, None], # 10101 [None, None, None, None] + ], + [ + [None, None, None, None], # 10110 [None, None, None, None] + [None, None, None, None], # 10111 [None, None, None, None] + ], + ], + ], + [ + [ + [ + [None, None, None, None], # 11000 [None, None, None, None] + [None, None, None, None], # 11001 [None, None, None, None] + ], + [ + [None, None, None, None], # 11010 [None, None, None, None] + [None, None, None, None], # 11011 [None, None, None, None] + ], + ], + [ + [ + [None, None, None, None], # 11100 [None, None, None, None] + [None, None, None, None], # 11101 [None, None, None, None] + ], + [ + [None, None, None, None], # 11110 [None, None, None, None] + [None, None, None, None], # 11111 [None, None, None, None] + ], + ], + ], + ], + ], +] + + def get_character_set(): - return sorted(list(set(sum([list(a) for a in sum(sum(sum(sum(sum(characters, []), []), []), []), []) if a is not None], []) + extra_characters))) + return sorted( + list( + set( + sum( + [ + list(a) + for a in sum(sum(sum(sum(sum(characters, []), []), []), []), []) + if a is not None + ], + [], + ) + + extra_characters + ) + ) + ) diff --git a/code.py b/code.py index b4d6c1d..e74bace 100644 --- a/code.py +++ b/code.py @@ -3,36 +3,38 @@ import board import math import random import busio +import usb_hid from digitalio import DigitalInOut, Direction, Pull import displayio from vectorio import Rectangle, Circle, Polygon from adafruit_display_text import label from adafruit_bitmap_font import bitmap_font -import gc9a01 -import usb_hid -from characters import characters, keycodes from adafruit_hid.keyboard import Keyboard +from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS +import gc9a01 +from characters import characters, shortcuts, words, keycodes kbd = Keyboard(usb_hid.devices) +layout = KeyboardLayoutUS(kbd) font = bitmap_font.load_font("fonts/VictorMonoNerdFont-SemiBoldItalic-32.pcf") displayio.release_displays() mode_labels = [ - ["Letters", "Shortcuts", "Words", "Predictive"], - ["Lettres", "Raccourcis", "Mots", "Prédictif"] + ["Letters", "Shortcuts", "Words", "Predictive"], + ["Lettres", "Raccourcis", "Mots", "Prédictif"], ] language_labels = ["English", "Français"] backlight_labels = ["Backlight", "Rétroéclairage"] tft_clk = board.GP14 -tft_mosi= board.GP15 +tft_mosi = board.GP15 tft_rst = board.GP27 -tft_dc = board.GP28 -tft_cs = board.GP29 +tft_dc = board.GP28 +tft_cs = board.GP29 -tft_bl = DigitalInOut(board.GP26) +tft_bl = DigitalInOut(board.GP26) tft_bl.direction = Direction.OUTPUT tft_bl.value = True @@ -52,7 +54,7 @@ key6 = DigitalInOut(board.GP0) key6.pull = Pull.UP spi = busio.SPI(clock=tft_clk, MOSI=tft_mosi) - + display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=tft_rst) display = gc9a01.GC9A01(display_bus, width=240, height=240) @@ -62,13 +64,10 @@ display.root_group = main_display label_position_radius = 90 circle_radius = 16 + def create_settings_text(y): text = label.Label( - font, - text="", - color=0xffffff, - anchor_point=(0.5, 0.5), - anchored_position=(0, 0) + font, text="", color=0xFFFFFF, anchor_point=(0.5, 0.5), anchored_position=(0, 0) ) text_group = displayio.Group(scale=1) text_group.x = 120 @@ -77,63 +76,105 @@ def create_settings_text(y): main_display.append(text_group) return text + top_text = create_settings_text(50) middle_text = create_settings_text(110) bottom_text = create_settings_text(170) + def calculate_text_position(key_angle, label_position_radius=label_position_radius): x = int(120 + label_position_radius * math.sin(key_angle)) y = int(120 - label_position_radius * math.cos(key_angle)) return x, y - -def create_text_area_angle(key_angle, text_colour=0xffffff, label_position_radius=label_position_radius): - return create_text_area(*calculate_text_position(key_angle, text_colour=text_colour, label_position_radius=label_position_radius)) -def create_text_area(x, y, text_colour=0xffffff): + +def create_text_area_angle( + key_angle, text_colour=0xFFFFFF, label_position_radius=label_position_radius +): + return create_text_area( + *calculate_text_position( + key_angle, + text_colour=text_colour, + label_position_radius=label_position_radius, + ) + ) + + +def create_text_area(x, y, text_colour=0xFFFFFF): key_display = displayio.Group(scale=1) key_display.x = x key_display.y = y key_text = label.Label( font, - text = " ", + text=" ", color=text_colour, anchor_point=(0.5, 0.5), - anchored_position=(0, 0) + anchored_position=(0, 0), ) key_display.append(key_text) main_display.append(key_display) return key_text + def create_circle(x, y, key_colour, circle_radius=circle_radius): key_palette = displayio.Palette(1) key_circle = Circle(pixel_shader=key_palette, radius=circle_radius, x=x, y=y) main_display.append(key_circle) return key_palette, key_circle - -def create_key_display(key_angle, key_colour, text_colour=0xffffff, circle_radius=circle_radius, label_position_radius=label_position_radius): - x, y = calculate_text_position(key_angle, label_position_radius=label_position_radius) - key_palette, key_circle = create_circle(x, y, key_colour, circle_radius=circle_radius) + + +def create_key_display( + key_angle, + key_colour, + text_colour=0xFFFFFF, + circle_radius=circle_radius, + label_position_radius=label_position_radius, +): + x, y = calculate_text_position( + key_angle, label_position_radius=label_position_radius + ) + key_palette, key_circle = create_circle( + x, y, key_colour, circle_radius=circle_radius + ) key_text = create_text_area(x, y, text_colour=text_colour) return key_text, key_palette, key_colour, key_circle -key0_text, key0_palette, key0_colour, key0_circle = create_key_display(-2.*math.pi/3., (219, 97, 71)) -key1_text, key1_palette, key1_colour, key1_circle = create_key_display(-math.pi/3., (100, 150, 40)) -key2_text, key2_palette, key2_colour, key2_circle = create_key_display(0., (40, 150, 100)) -key3_text, key3_palette, key3_colour, key3_circle = create_key_display(math.pi/3., (100, 40, 150)) -key4_text, key4_palette, key4_colour, key4_circle = create_key_display(2.*math.pi/3., (40, 40, 150)) -selected_circle_radius=32 -selected_text, selected_palette, selected_colour, selected_circle = create_key_display(math.pi, (255, 255, 255), text_colour=0x000000, circle_radius=selected_circle_radius, label_position_radius=60) + +key0_text, key0_palette, key0_colour, key0_circle = create_key_display( + -2.0 * math.pi / 3.0, (219, 97, 71) +) +key1_text, key1_palette, key1_colour, key1_circle = create_key_display( + -math.pi / 3.0, (100, 150, 40) +) +key2_text, key2_palette, key2_colour, key2_circle = create_key_display( + 0.0, (40, 150, 100) +) +key3_text, key3_palette, key3_colour, key3_circle = create_key_display( + math.pi / 3.0, (100, 40, 150) +) +key4_text, key4_palette, key4_colour, key4_circle = create_key_display( + 2.0 * math.pi / 3.0, (40, 40, 150) +) +selected_circle_radius = 32 +selected_text, selected_palette, selected_colour, selected_circle = create_key_display( + math.pi, + (255, 255, 255), + text_colour=0x000000, + circle_radius=selected_circle_radius, + label_position_radius=70, +) key5_colour = (0, 100, 30) key5_palette = displayio.Palette(1) -key5_circle = Circle(pixel_shader=key5_palette, radius=circle_radius, x=120-32, y=120) +key5_circle = Circle(pixel_shader=key5_palette, radius=circle_radius, x=120 - 32, y=120) main_display.append(key5_circle) key6_colour = (15, 100, 200) key6_palette = displayio.Palette(1) -key6_circle = Circle(pixel_shader=key6_palette, radius=circle_radius, x=120+32, y=120) +key6_circle = Circle(pixel_shader=key6_palette, radius=circle_radius, x=120 + 32, y=120) main_display.append(key6_circle) + def swap_to_settings_display(): tft_bl.value = True key0_text.text = "" @@ -150,19 +191,27 @@ def swap_to_settings_display(): key5_circle.radius = 0 key6_circle.radius = 0 selected_circle.radius = 0 - + + def settings_display(mode, language, backlight, location): top_text.text = mode_labels[language][mode] - top_text.color = 0x1c4d2d if location == 0 else 0xffffff + top_text.color = 0x1C4D2D if location == 0 else 0xFFFFFF middle_text.text = language_labels[language] - middle_text.color = 0x1c4d2d if location == 1 else 0xffffff + middle_text.color = 0x1C4D2D if location == 1 else 0xFFFFFF bottom_text.text = backlight_labels[language] - bottom_text.color = (0x1c4d2d if backlight else 0xff0000) if location == 2 else 0xffffff + bottom_text.color = ( + (0x1C4D2D if backlight else 0xFF0000) if location == 2 else 0xFFFFFF + ) -def swap_to_character_display(): + +def swap_away_from_settings_display(): top_text.text = "" middle_text.text = "" bottom_text.text = "" + + +def swap_to_character_display(): + swap_away_from_settings_display() key0_circle.radius = circle_radius key1_circle.radius = circle_radius key2_circle.radius = circle_radius @@ -172,6 +221,7 @@ def swap_to_character_display(): key6_circle.radius = circle_radius selected_circle.radius = selected_circle_radius + def edit_character(pin, character, key_text, key_palette, colour): if not pin: key_palette[0] = (0, 0, 0) @@ -183,12 +233,43 @@ def edit_character(pin, character, key_text, key_palette, colour): key_text.text = "" key_palette[0] = colour + def character_display(pin0, pin1, pin2, pin3, pin4, selection): - edit_character(pin0, characters[1][pin1][pin2][pin3][pin4][selection], key0_text, key0_palette, key0_colour) - edit_character(pin1, characters[pin0][1][pin2][pin3][pin4][selection], key1_text, key1_palette, key1_colour) - edit_character(pin2, characters[pin0][pin1][1][pin3][pin4][selection], key2_text, key2_palette, key2_colour) - edit_character(pin3, characters[pin0][pin1][pin2][1][pin4][selection], key3_text, key3_palette, key3_colour) - edit_character(pin4, characters[pin0][pin1][pin2][pin3][1][selection], key4_text, key4_palette, key4_colour) + edit_character( + pin0, + characters[1][pin1][pin2][pin3][pin4][selection], + key0_text, + key0_palette, + key0_colour, + ) + edit_character( + pin1, + characters[pin0][1][pin2][pin3][pin4][selection], + key1_text, + key1_palette, + key1_colour, + ) + edit_character( + pin2, + characters[pin0][pin1][1][pin3][pin4][selection], + key2_text, + key2_palette, + key2_colour, + ) + edit_character( + pin3, + characters[pin0][pin1][pin2][1][pin4][selection], + key3_text, + key3_palette, + key3_colour, + ) + edit_character( + pin4, + characters[pin0][pin1][pin2][pin3][1][selection], + key4_text, + key4_palette, + key4_colour, + ) if any([pin0, pin1, pin2, pin3, pin4]): character = characters[pin0][pin1][pin2][pin3][pin4][selection] if character is None: @@ -200,7 +281,7 @@ def character_display(pin0, pin1, pin2, pin3, pin4, selection): else: selected_text.text = "" selected_palette[0] = (0, 0, 0) - + def mode_display(selection): if selection is 0: @@ -216,35 +297,65 @@ def mode_display(selection): key5_palette[0] = key5_colour key6_palette[0] = key6_colour + def pressed(key): return not key.value + def poll(): - return [pressed(key0), pressed(key1), pressed(key2), pressed(key3), pressed(key4)], [pressed(key5), pressed(key6)] + return [ + pressed(key0), + pressed(key1), + pressed(key2), + pressed(key3), + pressed(key4), + ], [pressed(key5), pressed(key6)] + def toggle(_p, p, t): updates = update(_p, p) toggles = [not _t if u and __p else _t for _t, u, __p in zip(t, updates, _p)] return any(updates), toggles + def update(_p, p): return [___p != __p for ___p, __p in zip(_p, p)] -def get_time(p, t): - return [_t+1 if _p else 0 for _p, _t in zip(p, t)] -def get_character(p, s): - return characters[p[0]][p[1]][p[2]][p[3]][p[4]][s] +def get_time(p, t): + return [_t + 1 if _p else 0 for _p, _t in zip(p, t)] + + +def send_keycode(v): + if v is not None: + kbd.send(*keycodes[v]) + + +def send_character(p, s): + send_keycode(characters[p[0]][p[1]][p[2]][p[3]][p[4]][s]) + + +def send_shortcut(p, s): + send_keycode(shortcuts[p[0]][p[1]][p[2]][p[3]][p[4]][s]) + + +def send_word(p, s, l): + w = words[l][p[0]][p[1]][p[2]][p[3]][p[4]][s] + if w is not None: + layout.write(w) + layout.write(" ") + def release_countdown(p, t, start=3): - return [max(_t-1, 0) if not _p else start for _p, _t in zip(p, t)] + return [max(_t - 1, 0) if not _p else start for _p, _t in zip(p, t)] + def main(rate=0.05, start=3): - p = [False]*5 - t = [0]*5 - m = [False]*2 - tm = [0]*2 - toggles = [False]*2 + p = [False] * 5 + t = [0] * 5 + m = [False] * 2 + tm = [0] * 2 + toggles = [False] * 2 selection = 0 settings = False mode = 0 @@ -261,7 +372,7 @@ def main(rate=0.05, start=3): toggles = [False] * 2 swap_to_settings_display() location = 0 - tm = [0]*2 + tm = [0] * 2 elif settings: u = update(_m, m) if u[0] and _m[0]: @@ -286,6 +397,7 @@ def main(rate=0.05, start=3): else: tft_bl.value = backlight swap_to_character_display() + elif not settings: u = any(update(_p, p)) um, toggles = toggle(_m, m, toggles) @@ -294,18 +406,21 @@ def main(rate=0.05, start=3): if backlight: mode_display(selection) - if u or um and backlight: + if (u or um) and backlight and mode == 0: character_display(*_p, selection) - + if u and not any(_p): pressed = [_t > 0 for _t in t] if mode == 0: - c = get_character(pressed, selection) - if c is not None: - kbd.send(*keycodes[c]) + send_character(pressed, selection) + elif mode == 1: + send_shortcut(pressed, selection) + elif mode == 2: + send_word(pressed, selection, language) p = _p m = _m time.sleep(rate) - + + main() diff --git a/flake.nix b/flake.nix index 400da0c..bdb667b 100644 --- a/flake.nix +++ b/flake.nix @@ -9,6 +9,7 @@ { devShell = pkgs.mkShell { buildInputs = with pkgs; [ + black circup tio ];