Skip to content

Commit 14eb5df

Browse files
Merge pull request #130 from moon-jam/tkinter-python-gui
Replace PySimpleGUI with Tkinter for Python GUI
2 parents 585d33b + b5b8739 commit 14eb5df

17 files changed

+1350
-278
lines changed

.github/workflows/firmware.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
name: Building
2525
runs-on: [ubuntu-latest]
2626
steps:
27-
- uses: actions/checkout@v3
27+
- uses: actions/checkout@v4
2828

2929
- name: Setup Rust toolchain
3030
run: rustup show
@@ -66,7 +66,7 @@ jobs:
6666
cargo make --cwd ledmatrix bin
6767
6868
- name: Upload ledmatrix files
69-
uses: actions/upload-artifact@v3
69+
uses: actions/upload-artifact@v4
7070
with:
7171
name: ledmatrix_fw_${{github.sha}}
7272
path: |
@@ -79,15 +79,15 @@ jobs:
7979
target/thumbv6m-none-eabi/release/ledmatrix_evt.uf2
8080
8181
- name: Upload b1display files
82-
uses: actions/upload-artifact@v3
82+
uses: actions/upload-artifact@v4
8383
with:
8484
name: b1display_fw_${{github.sha}}
8585
path: |
8686
target/thumbv6m-none-eabi/release/b1display.bin
8787
target/thumbv6m-none-eabi/release/b1display.uf2
8888
8989
- name: Upload c1minimal files
90-
uses: actions/upload-artifact@v3
90+
uses: actions/upload-artifact@v4
9191
with:
9292
name: c1minimal_fw_${{github.sha}}
9393
path: |
@@ -98,7 +98,7 @@ jobs:
9898
name: Linting
9999
runs-on: ubuntu-latest
100100
steps:
101-
- uses: actions/checkout@v3
101+
- uses: actions/checkout@v4
102102

103103
- name: Setup Rust toolchain
104104
run: rustup show
@@ -130,7 +130,7 @@ jobs:
130130
name: Formatting
131131
runs-on: ubuntu-latest
132132
steps:
133-
- uses: actions/checkout@v3
133+
- uses: actions/checkout@v4
134134

135135
- name: Setup Rust toolchain
136136
run: rustup show

.github/workflows/software.yml

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
# name: Cross-Build for FreeBSD
3030
# runs-on: 'ubuntu-22.04'
3131
# steps:
32-
# - uses: actions/checkout@v3
32+
# - uses: actions/checkout@v4
3333

3434
# - name: Setup Rust toolchain
3535
# run: rustup show
@@ -41,7 +41,7 @@ jobs:
4141
# run: cross build --target=x86_64-unknown-freebsd
4242

4343
# - name: Upload FreeBSD App
44-
# uses: actions/upload-artifact@v3
44+
# uses: actions/upload-artifact@v4
4545
# with:
4646
# name: qmk_hid_freebsd
4747
# path: target/x86_64-unknown-freebsd/debug/qmk_hid
@@ -50,7 +50,7 @@ jobs:
5050
name: Build Linux
5151
runs-on: ubuntu-22.04
5252
steps:
53-
- uses: actions/checkout@v3
53+
- uses: actions/checkout@v4
5454

5555
- name: Install dependencies
5656
run: |
@@ -69,7 +69,7 @@ jobs:
6969
run: cargo make --cwd inputmodule-control run -- --help | grep 'RAW HID and VIA commandline'
7070

7171
- name: Upload Linux tool
72-
uses: actions/upload-artifact@v3
72+
uses: actions/upload-artifact@v4
7373
with:
7474
name: inputmodule-control
7575
path: target/x86_64-unknown-linux-gnu/release/inputmodule-control
@@ -78,7 +78,7 @@ jobs:
7878
name: Build Windows
7979
runs-on: windows-2022
8080
steps:
81-
- uses: actions/checkout@v3
81+
- uses: actions/checkout@v4
8282

8383
- name: Setup Rust toolchain
8484
run: rustup show
@@ -92,7 +92,7 @@ jobs:
9292
run: cargo make --cwd inputmodule-control run -- --help | grep 'RAW HID and VIA commandline'
9393

9494
- name: Upload Windows App
95-
uses: actions/upload-artifact@v3
95+
uses: actions/upload-artifact@v4
9696
with:
9797
name: inputmodule-control.exe
9898
path: target/x86_64-pc-windows-msvc/release/inputmodule-control.exe
@@ -103,22 +103,30 @@ jobs:
103103
name: Build GUI
104104
runs-on: windows-latest
105105
steps:
106-
- uses: actions/checkout@v3
106+
- uses: actions/checkout@v4
107107

108+
- name: Download releases to bundle
109+
run: |
110+
mkdir releases
111+
mkdir releases\0.2.0
112+
Invoke-WebRequest -Uri https://github.com/FrameworkComputer/inputmodule-rs/releases/download/v0.2.0/ledmatrix.uf2 -OutFile releases\0.2.0\ledmatrix.uf2
113+
114+
# To run locally, need to make sure to include the pywin32 DLL
115+
# pyinstaller --onefile, --name "python/inputmodule/cli.py", --windowed, --add-data "releases;releases" --icon=res\framework_startmenuicon.ico --path C:\users\skype\appdata\local\packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\localcache\local-packages\Python312\site-packages\pywin32_system32 --add-data 'res;res' -p python/inputmodule python/inputmodule/cli.py
108116
- name: Create Executable
109-
uses: Martin005/pyinstaller-action@main
117+
uses: JohnAZoidberg/pyinstaller-action@dont-clean
110118
with:
111-
python_ver: '3.11'
119+
python_ver: '3.12'
112120
spec: python/inputmodule/cli.py #'src/build.spec'
113-
requirements: 'requirements.txt'
114-
upload_exe_with_name: 'ledmatrixgui'
115-
options: --onefile, --windowed, --add-data 'res;res'
121+
requirements: 'python/requirements.txt'
122+
upload_exe_with_name: 'ledmatrixgui.exe'
123+
options: --onefile, --name "ledmatrixgui", --windowed, --add-data "releases;releases" --icon=res/framework_startmenuicon.ico --add-data 'res;res' -p python/inputmodule
116124

117125
package-python:
118126
name: Package Python
119127
runs-on: ubuntu-22.04
120128
steps:
121-
- uses: actions/checkout@v3
129+
- uses: actions/checkout@v4
122130

123131
- run: |
124132
cd python
@@ -131,7 +139,7 @@ jobs:
131139
name: Lints
132140
runs-on: ubuntu-22.04
133141
steps:
134-
- uses: actions/checkout@v3
142+
- uses: actions/checkout@v4
135143

136144
- name: Install dependencies
137145
run: |

.github/workflows/traditional-cargo.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
name: Build firmware
2525
runs-on: [ubuntu-latest]
2626
steps:
27-
- uses: actions/checkout@v3
27+
- uses: actions/checkout@v4
2828

2929
- name: Setup Rust toolchain
3030
run: rustup show
@@ -41,7 +41,7 @@ jobs:
4141
name: Build Linux
4242
runs-on: ubuntu-22.04
4343
steps:
44-
- uses: actions/checkout@v3
44+
- uses: actions/checkout@v4
4545

4646
- name: Install dependencies
4747
run: |
@@ -61,7 +61,7 @@ jobs:
6161
name: Build Windows
6262
runs-on: windows-2022
6363
steps:
64-
- uses: actions/checkout@v3
64+
- uses: actions/checkout@v4
6565

6666
- name: Setup Rust toolchain
6767
run: rustup show
@@ -78,7 +78,7 @@ jobs:
7878
name: Lint and format
7979
runs-on: ubuntu-latest
8080
steps:
81-
- uses: actions/checkout@v3
81+
- uses: actions/checkout@v4
8282

8383
- name: Install dependencies
8484
run: |

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,14 @@ To build your own application see the: [API command documentation](commands.md)
3535
Or use our `inputmodule-control` app, which you can download from the latest
3636
[GH Actions](https://github.com/FrameworkComputer/inputmodule-rs/actions) run or
3737
the [release page](https://github.com/FrameworkComputer/inputmodule-rs/releases).
38-
Optionally there are is also a [Python script](python/README.md).
3938

4039
For device specific commands, see their individual documentation pages.
4140

41+
### GUI and Python
42+
There are also a python library and GUI tool. See their [README](python/README.md).
43+
44+
![](res/ledmatrixgui-home.png)
45+
4246
###### Permissions on Linux
4347
To ensure that the input module's port is accessible, install the `udev` rule and trigger a reload:
4448

python/inputmodule/cli.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
brightness,
1515
get_brightness,
1616
CommandVals,
17-
bootloader,
17+
bootloader_jump,
1818
GameOfLifeStartParam,
1919
GameControlVal,
2020
)
21-
from inputmodule.gui.games import (
21+
from inputmodule.games import (
2222
snake,
2323
snake_embedded,
2424
pong_embedded,
@@ -62,10 +62,6 @@
6262
RGB_COLORS,
6363
)
6464

65-
# Optional dependencies:
66-
# from PIL import Image
67-
# import PySimpleGUI as sg
68-
6965

7066
def main_cli():
7167
parser = argparse.ArgumentParser()
@@ -237,7 +233,7 @@ def main_cli():
237233

238234
if not ports:
239235
print("No device found")
240-
gui.popup(args.gui, "No device found")
236+
gui.popup("No device found", gui=args.gui)
241237
sys.exit(1)
242238
elif args.serial_dev is not None:
243239
filtered_devs = [
@@ -250,10 +246,10 @@ def main_cli():
250246
dev = ports[0]
251247
elif len(ports) >= 1 and not args.gui:
252248
gui.popup(
253-
args.gui,
254249
"More than 1 compatibles devices found. Please choose from the commandline with --serial-dev COMX.\nConnected ports:\n- {}".format(
255250
"\n- ".join([port.device for port in ports])
256251
),
252+
gui=args.gui,
257253
)
258254
print(
259255
"More than 1 compatible device found. Please choose with --serial-dev ..."
@@ -268,11 +264,11 @@ def main_cli():
268264

269265
if not args.gui and dev is None:
270266
print("No device selected")
271-
gui.popup(args.gui, "No device selected")
267+
gui.popup("No device selected", gui=args.gui)
272268
sys.exit(1)
273269

274270
if args.bootloader:
275-
bootloader(dev)
271+
bootloader_jump(dev)
276272
elif args.sleep is not None:
277273
send_command(dev, CommandVals.Sleep, [args.sleep])
278274
elif args.is_sleeping:
@@ -394,6 +390,7 @@ def find_devs():
394390
def print_devs(ports):
395391
for port in ports:
396392
print(f"{port.device}")
393+
print(f" {port.name}")
397394
print(f" VID: 0x{port.vid:04X}")
398395
print(f" PID: 0x{port.pid:04X}")
399396
print(f" SN: {port.serial_number}")
@@ -407,4 +404,4 @@ def main_gui():
407404

408405

409406
if __name__ == "__main__":
410-
main_cli()
407+
main_gui()

python/inputmodule/firmware_update.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import os
2+
import time
3+
4+
from inputmodule.inputmodule import bootloader_jump
5+
from inputmodule import uf2conv
6+
7+
def dev_to_str(dev):
8+
return dev.name
9+
10+
def flash_firmware(dev, fw_path):
11+
print(f"Flashing {fw_path} onto {dev_to_str(dev)}")
12+
13+
# First jump to bootloader
14+
drives = uf2conv.list_drives()
15+
if not drives:
16+
print("Jump to bootloader")
17+
bootloader_jump(dev)
18+
19+
timeout = 10 # 5s
20+
while not drives:
21+
if timeout == 0:
22+
print("Failed to find device in bootloader")
23+
# TODO: Handle return value
24+
return False
25+
# Wait for it to appear
26+
time.sleep(0.5)
27+
timeout -= 1
28+
drives = uf2conv.get_drives()
29+
30+
31+
if len(drives) == 0:
32+
print("No drive to deploy.")
33+
return False
34+
35+
# Firmware is pretty small, can just fit it all into memory
36+
with open(fw_path, 'rb') as f:
37+
fw_buf = f.read()
38+
39+
for d in drives:
40+
print("Flashing {} ({})".format(d, uf2conv.board_id(d)))
41+
uf2conv.write_file(d + "/NEW.UF2", fw_buf)
42+
43+
print("Flashing finished")
44+
45+
# Example return value
46+
# {
47+
# '0.1.7': {
48+
# 'ansi': 'framework_ansi_default_v0.1.7.uf2',
49+
# 'gridpad': 'framework_gridpad_default_v0.1.7.uf2'
50+
# },
51+
# '0.1.8': {
52+
# 'ansi': 'framework_ansi_default.uf2',
53+
# 'gridpad': 'framework_gridpad_default.uf2',
54+
# }
55+
# }
56+
def find_releases(res_path, filename_format):
57+
from os import listdir
58+
from os.path import isfile, join
59+
import re
60+
61+
releases = {}
62+
try:
63+
versions = listdir(os.path.join(res_path, "releases"))
64+
except FileNotFoundError:
65+
return releases
66+
67+
for version in versions:
68+
path = join(res_path, "releases", version)
69+
releases[version] = {}
70+
for filename in listdir(path):
71+
if not isfile(join(path, filename)):
72+
continue
73+
type_search = re.search(filename_format, filename)
74+
if not type_search:
75+
print(f"Filename '{filename}' not matching patten!")
76+
sys.exit(1)
77+
continue
78+
fw_type = type_search.group(1)
79+
releases[version][fw_type] = os.path.join(res_path, "releases", version, filename)
80+
return releases

python/inputmodule/gui/games.py renamed to python/inputmodule/games.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def opposite_direction(direction):
4343
return direction
4444

4545

46+
4647
def snake_keyscan():
4748
global direction
4849
global body

0 commit comments

Comments
 (0)