Skip to content
This repository was archived by the owner on Dec 27, 2019. It is now read-only.

Commit 70acb82

Browse files
committed
Merge branch 'release/0.2.0'
2 parents d8832e0 + aeeec4b commit 70acb82

7 files changed

Lines changed: 100 additions & 30 deletions

File tree

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[*]
2+
charset=utf-8
3+
end_of_line=lf
4+
insert_final_newline=true
5+
indent_style=space
6+
indent_size=4
7+
8+
[{.babelrc,.stylelintrc,.eslintrc,jest.config,*.json,*.jsb3,*.jsb2,*.bowerrc}]
9+
indent_size=2

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@ several devices.
88
The main goal of this project is to help retro console gamers using older
99
professional matrix audio/video switch, such as Extron's Crosspoint series, and
1010
professional monitors, such as Sony's PVM and BVM series, better select the
11-
channels to which they have connected their
11+
channels to which they have connected consoles.
12+
13+
## Installation
14+
15+
Though this is designed for Raspian out of the box, it still requires one
16+
additional library. You can install it by running
17+
`sudo apt install python3-pil.imagetk`
1218

1319
## Usage and Configuration
1420

15-
See our [Wiki on GitHub](http://www.github.com/) for information on setting up,
16-
configuring, and using PiAvSwitchController.
21+
See the [Wiki on GitHub](http://www.github.com/6XGate/PiAvSwitchController/wiki)
22+
for information on setting up, configuring, and using PiAvSwitchController.
1723

1824
## Plans
1925

@@ -23,4 +29,4 @@ configuring, and using PiAvSwitchController.
2329

2430
## Change Log
2531

26-
See our [Project on GitHub](http://www.github.com/).
32+
See the [Project on GitHub](http://www.github.com/6XGate/PiAvSwitchController).
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,5 @@
102102
}
103103
}
104104
}
105-
]
105+
],
106106
}

extras/piavswictrl.desktop

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[Desktop Entry]
2+
Type=Application
3+
Name=PiAvSwitchController
4+
Exec=/usr/bin/env python3 <PiAvSwitchController location>/piavswictrl.py

piavswictrl.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,33 @@
11
#!/usr/bin/env python3
22

33
import sys
4+
import signal
45

56
from support.Switch import load_switches
67
from support.Device import load_devices
78
from support.config import load_config
89
from ui.Main import Main
910

10-
__version__ = "0.1.0"
11+
__version__ = "0.2.0"
12+
13+
root = None # type: Main
14+
15+
# noinspection PyUnusedLocal
16+
def on_quit(signum: int, frame) -> None:
17+
root.destroy()
1118

1219
def main():
20+
global root
21+
1322
config = load_config()
1423
load_switches(config['switches'])
1524
load_devices(config['devices'])
1625

26+
signal.signal(signal.SIGTERM, on_quit)
27+
1728
root = Main()
1829
root.mainloop()
30+
return 0
1931

2032
if __name__ == "__main__":
21-
main()
22-
sys.exit()
33+
sys.exit(main())

support/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ def load_config() -> Dict[str, Any]:
2424
# Initialize the configuration paths or path resolution.
2525
program_path = os.path.abspath(str(main.__file__))
2626
program_dir = os.path.dirname(program_path)
27-
config_path = os.path.abspath(os.path.join(program_dir, './config/pigaswi.json'))
27+
# noinspection SpellCheckingInspection
28+
config_path = os.path.abspath(os.path.join(program_dir, './config/piavswictrl.json'))
2829
config_dir = os.path.dirname(config_path)
2930

3031
# Now load up the configuration data.

ui/Main.py

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,88 @@
11
import functools
22
import tkinter as tk
3-
from tkinter import ttk
4-
from PIL import Image, ImageTk
3+
4+
from typing import List, Dict, Union
5+
from PIL import Image, ImageEnhance, ImageTk
56
from support.Device import devices, Device
67

7-
def select_input(device: Device):
8-
device.select()
8+
class Colors:
9+
FRAME = "Black"
10+
BUTTON_NORMAL = "Dark Grey"
11+
BUTTON_SELECTED = "White"
912

1013
class Main(tk.Tk):
1114

1215
def __init__(self):
1316
super().__init__()
17+
self.after_idle(self.__idle_poll)
1418
self.title('Pi Game Switch')
1519
self.attributes('-fullscreen', True)
16-
17-
# Get the number of columns and rows we will have.
18-
columns = int(self.winfo_screenwidth() / 128) - 1
19-
rows = int(self.winfo_screenheight() / 128) - 1
20+
self.__normal_images = {} # type: Dict[tk.Button, tk.PhotoImage]
21+
self.__selected_images = {} # type: Dict[tk.Button, tk.PhotoImage]
22+
self.__buttons = [] # type: List[tk.Button]
23+
self.__frame = tk.Frame(self, cursor='none', background=Colors.FRAME)
24+
self.__selected = None # type: Union[None, tk.Button]
2025

2126
# Configure the layout
22-
self.__frame = ttk.Frame(self)
23-
self.__frame.grid(columns=columns, rows=rows, sticky=(tk.N, tk.W, tk.E, tk.S))
27+
self.__frame.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
2428
self.columnconfigure(0, weight=1)
2529
self.rowconfigure(0, weight=1)
2630

27-
self.__buttons = []
28-
self.__images = []
31+
# Get the number of columns we will have.
32+
columns = int(self.winfo_screenwidth() / 130)
2933

3034
column = 0
3135
row = 0
3236
for device in devices:
33-
command = functools.partial(select_input, device)
37+
# Create the button.
38+
# noinspection SpellCheckingInspection
39+
button_config = {
40+
'borderwidth': 0,
41+
'highlightthickness': 0,
42+
'activebackground': Colors.BUTTON_NORMAL,
43+
'background': Colors.BUTTON_NORMAL
44+
}
3445
if len(device.image) > 0:
35-
image = ImageTk.PhotoImage(Image.open(device.image))
36-
self.__images.append(image)
37-
button = ttk.Button(self.__frame, image=image, command=command)
38-
button.grid(column=column, row=row, sticky=(tk.N, tk.W))
39-
self.__buttons.append(button)
46+
# Get the selected image.
47+
selected = ImageTk.PhotoImage(Image.open(device.image))
48+
# Generate the normal image.
49+
enhancer = ImageEnhance.Brightness(Image.open(device.image))
50+
normal = ImageTk.PhotoImage(enhancer.enhance(0.66))
51+
52+
button = tk.Button(self.__frame, image=normal, **button_config)
53+
self.__selected_images[button] = selected
54+
self.__normal_images[button] = normal
4055
else:
4156
text = device.title
42-
button = ttk.Button(self.__frame, text=text, command=command)
43-
button.grid(column=column, row=row, sticky=(tk.N, tk.W))
44-
self.__buttons.append(button)
57+
button = tk.Button(self.__frame, text=text, **button_config)
58+
59+
# Generate a partial to bind the command to the device.
60+
command = functools.partial(self.__select_device, button, device)
4561

62+
# Add the new button.
63+
button.config(command=command)
64+
button.grid(column=column, row=row, sticky=(tk.N, tk.W))
65+
button.grid_configure(padx=1, pady=1)
66+
self.__buttons.append(button)
67+
68+
# Move the column and row positions as necessary.
4669
column = column + 1
4770
if column == columns:
4871
row = row + 1
4972
column = 0
73+
74+
def __select_device(self, button: tk.Button, device: Device):
75+
selected = self.__selected
76+
if selected:
77+
selected.config(activebackground=Colors.BUTTON_NORMAL, background=Colors.BUTTON_NORMAL)
78+
if selected in self.__normal_images:
79+
selected.config(image=self.__normal_images[selected])
80+
81+
device.select()
82+
self.__selected = button
83+
button.config(activebackground=Colors.BUTTON_SELECTED, background=Colors.BUTTON_SELECTED)
84+
if button in self.__selected_images:
85+
button.config(image=self.__selected_images[button])
86+
87+
def __idle_poll(self) -> None:
88+
self.after(500, self.__idle_poll)

0 commit comments

Comments
 (0)