Skip to content

Commit

Permalink
Merge pull request #130 from moon-jam/tkinter-python-gui
Browse files Browse the repository at this point in the history
Replace PySimpleGUI with Tkinter for Python GUI
  • Loading branch information
JohnAZoidberg authored Nov 25, 2024
2 parents 585d33b + b5b8739 commit 14eb5df
Show file tree
Hide file tree
Showing 17 changed files with 1,350 additions and 278 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/firmware.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
name: Building
runs-on: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Rust toolchain
run: rustup show
Expand Down Expand Up @@ -66,7 +66,7 @@ jobs:
cargo make --cwd ledmatrix bin
- name: Upload ledmatrix files
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ledmatrix_fw_${{github.sha}}
path: |
Expand All @@ -79,15 +79,15 @@ jobs:
target/thumbv6m-none-eabi/release/ledmatrix_evt.uf2
- name: Upload b1display files
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: b1display_fw_${{github.sha}}
path: |
target/thumbv6m-none-eabi/release/b1display.bin
target/thumbv6m-none-eabi/release/b1display.uf2
- name: Upload c1minimal files
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: c1minimal_fw_${{github.sha}}
path: |
Expand All @@ -98,7 +98,7 @@ jobs:
name: Linting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Rust toolchain
run: rustup show
Expand Down Expand Up @@ -130,7 +130,7 @@ jobs:
name: Formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Rust toolchain
run: rustup show
Expand Down
36 changes: 22 additions & 14 deletions .github/workflows/software.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
# name: Cross-Build for FreeBSD
# runs-on: 'ubuntu-22.04'
# steps:
# - uses: actions/checkout@v3
# - uses: actions/checkout@v4

# - name: Setup Rust toolchain
# run: rustup show
Expand All @@ -41,7 +41,7 @@ jobs:
# run: cross build --target=x86_64-unknown-freebsd

# - name: Upload FreeBSD App
# uses: actions/upload-artifact@v3
# uses: actions/upload-artifact@v4
# with:
# name: qmk_hid_freebsd
# path: target/x86_64-unknown-freebsd/debug/qmk_hid
Expand All @@ -50,7 +50,7 @@ jobs:
name: Build Linux
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

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

- name: Upload Linux tool
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: inputmodule-control
path: target/x86_64-unknown-linux-gnu/release/inputmodule-control
Expand All @@ -78,7 +78,7 @@ jobs:
name: Build Windows
runs-on: windows-2022
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

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

- name: Upload Windows App
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: inputmodule-control.exe
path: target/x86_64-pc-windows-msvc/release/inputmodule-control.exe
Expand All @@ -103,22 +103,30 @@ jobs:
name: Build GUI
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Download releases to bundle
run: |
mkdir releases
mkdir releases\0.2.0
Invoke-WebRequest -Uri https://github.com/FrameworkComputer/inputmodule-rs/releases/download/v0.2.0/ledmatrix.uf2 -OutFile releases\0.2.0\ledmatrix.uf2
# To run locally, need to make sure to include the pywin32 DLL
# 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
- name: Create Executable
uses: Martin005/pyinstaller-action@main
uses: JohnAZoidberg/pyinstaller-action@dont-clean
with:
python_ver: '3.11'
python_ver: '3.12'
spec: python/inputmodule/cli.py #'src/build.spec'
requirements: 'requirements.txt'
upload_exe_with_name: 'ledmatrixgui'
options: --onefile, --windowed, --add-data 'res;res'
requirements: 'python/requirements.txt'
upload_exe_with_name: 'ledmatrixgui.exe'
options: --onefile, --name "ledmatrixgui", --windowed, --add-data "releases;releases" --icon=res/framework_startmenuicon.ico --add-data 'res;res' -p python/inputmodule

package-python:
name: Package Python
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- run: |
cd python
Expand All @@ -131,7 +139,7 @@ jobs:
name: Lints
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install dependencies
run: |
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/traditional-cargo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
name: Build firmware
runs-on: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Rust toolchain
run: rustup show
Expand All @@ -41,7 +41,7 @@ jobs:
name: Build Linux
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install dependencies
run: |
Expand All @@ -61,7 +61,7 @@ jobs:
name: Build Windows
runs-on: windows-2022
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Rust toolchain
run: rustup show
Expand All @@ -78,7 +78,7 @@ jobs:
name: Lint and format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install dependencies
run: |
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,14 @@ To build your own application see the: [API command documentation](commands.md)
Or use our `inputmodule-control` app, which you can download from the latest
[GH Actions](https://github.com/FrameworkComputer/inputmodule-rs/actions) run or
the [release page](https://github.com/FrameworkComputer/inputmodule-rs/releases).
Optionally there are is also a [Python script](python/README.md).

For device specific commands, see their individual documentation pages.

### GUI and Python
There are also a python library and GUI tool. See their [README](python/README.md).

![](res/ledmatrixgui-home.png)

###### Permissions on Linux
To ensure that the input module's port is accessible, install the `udev` rule and trigger a reload:

Expand Down
19 changes: 8 additions & 11 deletions python/inputmodule/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
brightness,
get_brightness,
CommandVals,
bootloader,
bootloader_jump,
GameOfLifeStartParam,
GameControlVal,
)
from inputmodule.gui.games import (
from inputmodule.games import (
snake,
snake_embedded,
pong_embedded,
Expand Down Expand Up @@ -62,10 +62,6 @@
RGB_COLORS,
)

# Optional dependencies:
# from PIL import Image
# import PySimpleGUI as sg


def main_cli():
parser = argparse.ArgumentParser()
Expand Down Expand Up @@ -237,7 +233,7 @@ def main_cli():

if not ports:
print("No device found")
gui.popup(args.gui, "No device found")
gui.popup("No device found", gui=args.gui)
sys.exit(1)
elif args.serial_dev is not None:
filtered_devs = [
Expand All @@ -250,10 +246,10 @@ def main_cli():
dev = ports[0]
elif len(ports) >= 1 and not args.gui:
gui.popup(
args.gui,
"More than 1 compatibles devices found. Please choose from the commandline with --serial-dev COMX.\nConnected ports:\n- {}".format(
"\n- ".join([port.device for port in ports])
),
gui=args.gui,
)
print(
"More than 1 compatible device found. Please choose with --serial-dev ..."
Expand All @@ -268,11 +264,11 @@ def main_cli():

if not args.gui and dev is None:
print("No device selected")
gui.popup(args.gui, "No device selected")
gui.popup("No device selected", gui=args.gui)
sys.exit(1)

if args.bootloader:
bootloader(dev)
bootloader_jump(dev)
elif args.sleep is not None:
send_command(dev, CommandVals.Sleep, [args.sleep])
elif args.is_sleeping:
Expand Down Expand Up @@ -394,6 +390,7 @@ def find_devs():
def print_devs(ports):
for port in ports:
print(f"{port.device}")
print(f" {port.name}")
print(f" VID: 0x{port.vid:04X}")
print(f" PID: 0x{port.pid:04X}")
print(f" SN: {port.serial_number}")
Expand All @@ -407,4 +404,4 @@ def main_gui():


if __name__ == "__main__":
main_cli()
main_gui()
80 changes: 80 additions & 0 deletions python/inputmodule/firmware_update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import os
import time

from inputmodule.inputmodule import bootloader_jump
from inputmodule import uf2conv

def dev_to_str(dev):
return dev.name

def flash_firmware(dev, fw_path):
print(f"Flashing {fw_path} onto {dev_to_str(dev)}")

# First jump to bootloader
drives = uf2conv.list_drives()
if not drives:
print("Jump to bootloader")
bootloader_jump(dev)

timeout = 10 # 5s
while not drives:
if timeout == 0:
print("Failed to find device in bootloader")
# TODO: Handle return value
return False
# Wait for it to appear
time.sleep(0.5)
timeout -= 1
drives = uf2conv.get_drives()


if len(drives) == 0:
print("No drive to deploy.")
return False

# Firmware is pretty small, can just fit it all into memory
with open(fw_path, 'rb') as f:
fw_buf = f.read()

for d in drives:
print("Flashing {} ({})".format(d, uf2conv.board_id(d)))
uf2conv.write_file(d + "/NEW.UF2", fw_buf)

print("Flashing finished")

# Example return value
# {
# '0.1.7': {
# 'ansi': 'framework_ansi_default_v0.1.7.uf2',
# 'gridpad': 'framework_gridpad_default_v0.1.7.uf2'
# },
# '0.1.8': {
# 'ansi': 'framework_ansi_default.uf2',
# 'gridpad': 'framework_gridpad_default.uf2',
# }
# }
def find_releases(res_path, filename_format):
from os import listdir
from os.path import isfile, join
import re

releases = {}
try:
versions = listdir(os.path.join(res_path, "releases"))
except FileNotFoundError:
return releases

for version in versions:
path = join(res_path, "releases", version)
releases[version] = {}
for filename in listdir(path):
if not isfile(join(path, filename)):
continue
type_search = re.search(filename_format, filename)
if not type_search:
print(f"Filename '{filename}' not matching patten!")
sys.exit(1)
continue
fw_type = type_search.group(1)
releases[version][fw_type] = os.path.join(res_path, "releases", version, filename)
return releases
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def opposite_direction(direction):
return direction



def snake_keyscan():
global direction
global body
Expand Down
Loading

0 comments on commit 14eb5df

Please sign in to comment.