Skip to content

Commit 10e7cc1

Browse files
committed
Changed version to 0.4
1 parent 4b8df08 commit 10e7cc1

9 files changed

+393
-1
lines changed

server/.build.bat.un~

1003 Bytes
Binary file not shown.

server/.build.bat~.un~

5.92 KB
Binary file not shown.

server/.gui.py.un~

625 Bytes
Binary file not shown.

server/.server.py.un~

14 KB
Binary file not shown.

server/build.bat~

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@echo off
2+
3+
4+
REM Create virtual environment and install requirements
5+
python -m venv patstrap-server-env
6+
source patstrap-server-env\bin\activate
7+
pip install -r requirements.txt
8+
9+
REM Use pyinstaller to create a standalone WINDOWS executable at .\dist\patstrap-server\patstrap-server.exe
10+
pyinstaller gui.py -n patstrap-server --noconsole --noconfirm --onefile --add-data "global.css;." --path=.\patstrap-server-env\lib\python3.11\site-packages --hidden-import zeroconf._utils.ipaddress --hidden-import zeroconf._handlers.answers
11+
pyinstaller gui.py -n patstrap-server-debug --noconfirm --onefile --add-data "global.css;." --path=.\patstrap-server-env\lib\python3.11\site-packages --hidden-import zeroconf._utils.ipaddress --hidden-import zeroconf._handlers.answers

server/build.bat~~

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@echo off
2+
3+
4+
REM Create virtual environment and install requirements
5+
python -m venv patstrap-server-env
6+
source patstrap-server-env\bin\activate
7+
pip install -r requirements.txt
8+
9+
REM Use pyinstaller to create a standalone WINDOWS executable at .\dist\patstrap-server\patstrap-server.exe
10+
pyinstaller gui.py -n patstrap-server --noconsole --noconfirm --onefile --add-data "global.css;." --path=.\patstrap-server-env\lib\python3.11\site-packages --hidden-import zeroconf._utils.ipaddress --hidden-import zeroconf._handlers.answers

server/gui.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def __init__(self, app: QApplication, args):
2727
self.prev_patstrap_status = False
2828
self.prev_vrchat_status = False
2929

30-
self.setWindowTitle("Patstrap Server v0.3")
30+
self.setWindowTitle("Patstrap Server v0.4")
3131
with open(resource_path("global.css"), "r") as file:
3232
self.setStyleSheet(file.read())
3333

server/gui.py~

+223
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QSlider
2+
from PyQt6.QtCore import Qt
3+
from server import Server
4+
5+
import argparse
6+
import time
7+
import sys
8+
import os
9+
10+
# Taken from https://stackoverflow.com/questions/7674790/bundling-data-files-with-pyinstaller-onefile
11+
def resource_path(relative_path):
12+
""" Get absolute path to resource, works for dev and for PyInstaller """
13+
try:
14+
# PyInstaller creates a temp folder and stores path in _MEIPASS
15+
base_path = sys._MEIPASS
16+
except Exception:
17+
base_path = os.path.abspath(".")
18+
19+
return os.path.join(base_path, relative_path)
20+
21+
class MainWindow(QWidget):
22+
def __init__(self, app: QApplication, args):
23+
super().__init__()
24+
25+
self.app = app
26+
self.slider_strength = None
27+
self.prev_patstrap_status = False
28+
self.prev_vrchat_status = False
29+
30+
self.setWindowTitle("Patstrap Server v0.3")
31+
with open(resource_path("global.css"), "r") as file:
32+
self.setStyleSheet(file.read())
33+
34+
layoutMain = QVBoxLayout()
35+
layoutMain.setContentsMargins(0, 0, 0, 0)
36+
37+
box = QWidget()
38+
box.setObjectName("mainbackground")
39+
40+
layout = QVBoxLayout()
41+
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
42+
layout.addWidget(self.create_patstrap_status())
43+
layout.addWidget(self.create_vrchat_status())
44+
layout.addWidget(self.create_settings())
45+
layout.addWidget(self.create_patstrap_battery_status())
46+
layout.addWidget(self.create_test())
47+
48+
self.server = Server(self, args)
49+
50+
box.setLayout(layout)
51+
layoutMain.addWidget(box)
52+
53+
self.setLayout(layoutMain)
54+
55+
def create_patstrap_status(self):
56+
box = QWidget()
57+
box.setObjectName("section")
58+
59+
layout = QHBoxLayout()
60+
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
61+
layout.setContentsMargins(20, 20, 20, 20)
62+
63+
title_label = QLabel("Patstrap connection")
64+
title_label.setAlignment(Qt.AlignmentFlag.AlignVCenter)
65+
layout.addWidget(title_label)
66+
67+
self.status_hardware_connection = QLabel(" ⬤")
68+
self.status_hardware_connection.setAlignment(Qt.AlignmentFlag.AlignRight)
69+
self.status_hardware_connection.setStyleSheet("color: #ba3f41;")
70+
layout.addWidget(self.status_hardware_connection)
71+
72+
box.setLayout(layout)
73+
return box
74+
75+
def create_patstrap_battery_status(self):
76+
box = QWidget()
77+
box.setObjectName("section")
78+
79+
layout = QHBoxLayout()
80+
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
81+
layout.setContentsMargins(20, 20, 20, 20)
82+
83+
title_label = QLabel("Battery")
84+
title_label.setAlignment(Qt.AlignmentFlag.AlignVCenter)
85+
layout.addWidget(title_label)
86+
87+
88+
self.status_hardware_battery = QLabel("unknown")
89+
self.status_hardware_battery.setAlignment(Qt.AlignmentFlag.AlignRight)
90+
self.status_hardware_battery.setStyleSheet("color: #999999;")
91+
layout.addWidget(self.status_hardware_battery)
92+
93+
box.setLayout(layout)
94+
return box
95+
96+
def set_battery(self, percent):
97+
color = "#ffffff"
98+
99+
if percent < 20:
100+
color = "#ba3f41"
101+
elif percent < 60:
102+
color = "#fcba03"
103+
elif percent <= 100:
104+
color = "#76abae"
105+
106+
self.status_hardware_battery.setText(f"{percent}%")
107+
self.status_hardware_battery.setStyleSheet(f"color: {color};")
108+
#self.status_hardware_battery.repaint()
109+
#self.app.processEvents()
110+
111+
def create_vrchat_status(self):
112+
box = QWidget()
113+
box.setObjectName("section")
114+
115+
layout = QHBoxLayout()
116+
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
117+
layout.setContentsMargins(20, 20, 20, 20)
118+
119+
title_label = QLabel("VRChat connection")
120+
title_label.setAlignment(Qt.AlignmentFlag.AlignVCenter)
121+
layout.addWidget(title_label)
122+
123+
self.status_vrchat_connection = QLabel(" ⬤")
124+
self.status_vrchat_connection.setAlignment(Qt.AlignmentFlag.AlignRight)
125+
self.status_vrchat_connection.setStyleSheet("color: #ba3f41;")
126+
layout.addWidget(self.status_vrchat_connection)
127+
128+
box.setLayout(layout)
129+
return box
130+
131+
def create_settings(self):
132+
box = QWidget()
133+
box.setObjectName("section")
134+
135+
layout = QHBoxLayout()
136+
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
137+
layout.setContentsMargins(20, 20, 20, 20)
138+
139+
title_label = QLabel("Intensity")
140+
title_label.setAlignment(Qt.AlignmentFlag.AlignLeft)
141+
layout.addWidget(title_label)
142+
143+
self.slider_strength = QSlider(Qt.Orientation.Horizontal)
144+
self.slider_strength.setMaximumWidth(200)
145+
self.slider_strength.setMinimum(0)
146+
self.slider_strength.setMaximum(100)
147+
self.slider_strength.setValue(50)
148+
layout.addWidget(self.slider_strength)
149+
150+
box.setLayout(layout)
151+
return box
152+
153+
def get_intensity(self) -> float:
154+
if self.slider_strength is None:
155+
return 0
156+
return self.slider_strength.value() / 100.0
157+
158+
def create_test(self):
159+
box = QWidget()
160+
box.setObjectName("section")
161+
box.setFixedHeight(140)
162+
163+
layoutH = QHBoxLayout()
164+
layoutV = QVBoxLayout()
165+
layoutV.setContentsMargins(20, 20, 20, 20)
166+
167+
self.test_left_button = QPushButton("Pat left")
168+
self.test_left_button.clicked.connect(self.pat_left)
169+
self.test_left_button.setDisabled(True)
170+
layoutH.addWidget(self.test_left_button)
171+
172+
self.test_right_button = QPushButton("Pat right")
173+
self.test_right_button.clicked.connect(self.pat_right)
174+
self.test_right_button.setDisabled(True)
175+
layoutH.addWidget(self.test_right_button)
176+
177+
info_label = QLabel("Test hardware")
178+
info_label.setAlignment(Qt.AlignmentFlag.AlignLeft)
179+
info_label.setFixedHeight(40)
180+
layoutV.addWidget(info_label)
181+
layoutV.addItem(layoutH)
182+
183+
box.setLayout(layoutV)
184+
return box
185+
186+
def pat_left(self):
187+
print("Pat left")
188+
self.server.strength_left = 2
189+
190+
def pat_right(self):
191+
print("Patt right")
192+
self.server.strength_right = 2
193+
194+
def set_patstrap_status(self, status: bool):
195+
if self.prev_patstrap_status != status:
196+
self.prev_patstrap_status = status
197+
self.status_hardware_connection.setStyleSheet("color: #76abae;" if status else "color: #ba3f41;")
198+
199+
self.test_right_button.setDisabled(not status)
200+
self.test_left_button.setDisabled(not status)
201+
202+
def set_vrchat_status(self, status: bool):
203+
if self.prev_vrchat_status != status:
204+
self.prev_vrchat_status = status
205+
self.status_vrchat_connection.setStyleSheet("color: #76abae;" if status else "color: #ba3f41;")
206+
207+
def closeEvent(self, _):
208+
print("Exiting server...")
209+
self.server.shutdown()
210+
211+
if __name__ == "__main__":
212+
213+
parser = argparse.ArgumentParser()
214+
parser.add_argument("-ep", "--esp-port", type=int, default=8888, help="Port to the esp hardware. If you change this, you will also need to change the firmware to be the same number! default: 8888")
215+
parser.add_argument("-op", "--osc-port", type=int, default=9001, help="VRChat's OSC input port. default: 9001")
216+
args = parser.parse_args()
217+
218+
app = QApplication(sys.argv)
219+
220+
window = MainWindow(app, args)
221+
window.setFixedSize(400, 485)
222+
window.show()
223+
sys.exit(app.exec())

0 commit comments

Comments
 (0)