Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev/v0.6.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Z4urce committed Nov 13, 2024
2 parents c4e13c7 + b91dfdf commit c745b1f
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 34 deletions.
113 changes: 83 additions & 30 deletions BridgeApp/app_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from app_config import AppConfig, PatternConfig
from app_pattern import VibrationPattern

WINDOW_NAME = "Haptic Pancake Bridge v0.5.3a"
WINDOW_NAME = "Haptic Pancake Bridge v0.6.0a"

LIST_SERVER_TYPE = ["OSC (VRChat)", "WebSocket (Resonite)"]

Expand All @@ -20,6 +20,7 @@
KEY_VIB_STR_OVERRIDE = '-VIB-STR-'
KEY_BTN_TEST = '-BTN-TEST-'
KEY_BTN_CALIBRATE = '-BTN-CALIBRATE-'
KEY_BTN_ADD_EXTERNAL = '-BTN-ADD-EXTERNAL-'
KEY_BATTERY_THRESHOLD = '-BATTERY-'

# Pattern Config
Expand All @@ -33,11 +34,14 @@


class GUIRenderer:
def __init__(self, app_config: AppConfig, tracker_test_event, restart_osc_event, refresh_trackers_event):
sg.theme('DarkAmber') # Add a touch of color
def __init__(self, app_config: AppConfig, tracker_test_event,
restart_osc_event, refresh_trackers_event, add_external_event):
sg.theme('DarkAmber')
self.tracker_test_event = tracker_test_event
self.restart_osc_event = restart_osc_event
self.refresh_trackers_event = refresh_trackers_event
self.add_external_event = add_external_event

self.config = app_config
self.shutting_down = False
self.window = None
Expand Down Expand Up @@ -100,8 +104,11 @@ def build_pattern_setting_layout(key: str, pattern_list: [str], pattern_config:
def small_vertical_space():
return sg.Text('', font=('AnyFont', 1), auto_size_text=True)

def tracker_row(self, tracker_id, tracker_serial, tracker_model):
string = f"⚫ {tracker_serial} {tracker_model}"
def device_row(self, tracker_serial, tracker_model, additional_layout, icon=None):
if icon is None:
icon = "⚫"

string = f"{icon} {tracker_serial} {tracker_model}"

dev_config = self.config.get_tracker_config(tracker_serial)
address = dev_config.address
Expand All @@ -111,34 +118,77 @@ def tracker_row(self, tracker_id, tracker_serial, tracker_model):
multiplier_tooltip = "Additional strength multiplier\nCompensates for different trackers\n1.0 for default (Vive/Tundra Tracker)\n200 for Vive Wand\n400 for Index c."

print(f"[GUI] Adding tracker: {string}")
layout = [[sg.Text(string, pad=(0, 0))],
[sg.Text(" "), sg.Text("Address:"),
sg.InputText(address, k=(KEY_OSC_ADDRESS, tracker_serial), enable_events=True, size=35,
tooltip="OSC Address or Resonite Address"),
sg.Button("Identify", k=(KEY_BTN_TEST, tracker_serial), tooltip="Send a 500ms pulse to the tracker")],
[sg.Text(" "),
sg.Text("Battery threshold:", tooltip="Disables vibration bellow this battery level"),
sg.Spin([num for num in range(0, 91)], battery_threshold, pad=0,
key=(KEY_BATTERY_THRESHOLD, tracker_serial), enable_events=True),
sg.Text("%", pad=0),
sg.VSeparator(),
sg.Text("Pulse multiplier:", tooltip=multiplier_tooltip, pad=0),
sg.InputText(vib_multiplier, k=(KEY_VIB_STR_OVERRIDE, tracker_serial), enable_events=True,
size=4,
tooltip="The haptic intensity for this tracker will be multiplied by this number"),
sg.Button("Calibrate", button_color='grey', disabled=True, key=(KEY_BTN_CALIBRATE, tracker_serial),
tooltip="Coming soon...")
]]

row = [sg.pin(sg.Col(layout, key=('-ROW-', tracker_id)))]
layout = [
[sg.Text(string, pad=(0, 0))],
[sg.Text(" "), sg.Text("Address:"),
sg.InputText(address, k=(KEY_OSC_ADDRESS, tracker_serial),
enable_events=True, size=35,
tooltip="OSC Address or Resonite Address"),
sg.Button("Identify", k=(KEY_BTN_TEST, tracker_serial),
tooltip="Send a 500ms pulse to the tracker")],
additional_layout]

row = [sg.pin(sg.Col(layout, key=('-ROW-', tracker_serial)))]
return row

def add_tracker(self, tracker_id, tracker_serial, tracker_model):
def tracker_row(self, tracker_serial, tracker_model):
dev_config = self.config.get_tracker_config(tracker_serial)
vib_multiplier = dev_config.multiplier_override
battery_threshold = dev_config.battery_threshold
multiplier_tooltip = "The haptic intensity for this tracker will be multiplied by this number"

tr = [sg.Text(" "),
sg.Text("Battery threshold:", tooltip="Disables vibration bellow this battery level"),
sg.Spin([num for num in range(0, 90)], battery_threshold, pad=0,
key=(KEY_BATTERY_THRESHOLD, tracker_serial), enable_events=True),
sg.Text("%", pad=0),
sg.VSeparator(),
sg.Text("Pulse multiplier:", tooltip=multiplier_tooltip, pad=0),
sg.InputText(vib_multiplier, k=(KEY_VIB_STR_OVERRIDE, tracker_serial), enable_events=True,
size=4, tooltip=multiplier_tooltip),
sg.Button("Calibrate", button_color='grey', disabled=True, key=(KEY_BTN_CALIBRATE, tracker_serial),
tooltip="Coming soon...")]
return self.device_row(tracker_serial, tracker_model, tr)

def add_tracker(self, tracker_serial, tracker_model):
row = [self.tracker_row(tracker_serial, tracker_model)]
self.add_target(tracker_serial, tracker_model, row)

def add_external_device(self, device_serial, device_model):
layout = []
icon = None

if device_serial.startswith("EMUSND"):
layout.append(sg.Text(" "))
layout.append(sg.Text("Sound:", size=6))
layout.append(sg.InputText("Default", size=35))
layout.append(sg.FileBrowse("Browse", key=(KEY_BTN_TEST, device_serial)))
icon = "🔊"
if device_serial.startswith("EMUTXT"):
layout.append(sg.Text(" "))
layout.append(sg.Button("Open Output Window"))
icon = "📝"
if device_serial.startswith("SERIALCOM"):
layout.append(sg.Text(" "))
layout.append(sg.Text("COM Port:", size=8))
layout.append(sg.InputText("COM6", size=33))
layout.append(sg.FileBrowse("Browse", key=(KEY_BTN_TEST, device_serial)))
icon = "〰"
if device_serial.startswith("NETWORK"):
layout.append(sg.Text(" "))
layout.append(sg.Text("Server IP:", size=8))
layout.append(sg.InputText("192.168.1.67", size=33))
icon = "📡"

row = [self.device_row(device_serial, device_model, layout, icon=icon)]
self.add_target(device_serial, device_model, row)

def add_target(self, tracker_serial, tracker_model, layout):
if tracker_serial in self.trackers:
print(f"[GUI] Tracker {tracker_serial} is already on the list. Skipping...")
return

row = [self.tracker_row(tracker_id, tracker_serial, tracker_model)]
row = [self.tracker_row(tracker_serial, tracker_model)]
if self.window is not None:
self.window.extend_layout(self.window[KEY_LAYOUT_TRACKERS], row)
else:
Expand All @@ -151,11 +201,12 @@ def add_message(self, message):
self.layout.append([sg.Text(message, text_color='red')])

def add_footer(self):
cs_tooltip = "Coming soon..."
external_devices = ['Add', ['Emulated (Sound)::EMUSND', 'Emulated (Text)::EMUTXT',
'Serial (COM port)::SERIALCOM', 'Network (Server)::NETWORK']]
self.layout.append([self.small_vertical_space()])
self.layout.append([sg.Button("Refresh Tracker List", size=18, key=KEY_BTN_REFRESH),
sg.Button("Add Serial device", disabled=True, button_color='grey', tooltip=cs_tooltip),
sg.Button("Add Network device", disabled=True, button_color='grey', tooltip=cs_tooltip)])
sg.ButtonMenu("Add External device", external_devices, key=KEY_BTN_ADD_EXTERNAL, disabled=True,
tooltip="Add an external feedback device"), ])
self.layout.append([sg.HSep()])
self.layout.append(
[sg.Text("Made by Z4urce", enable_events=True, font='Default 8 underline', key=KEY_OPEN_URL)])
Expand Down Expand Up @@ -188,6 +239,8 @@ def run(self):
return False
if event[0] == KEY_BTN_TEST:
self.tracker_test_event(event[1])
if event == KEY_BTN_ADD_EXTERNAL:
self.add_external_event(values[KEY_BTN_ADD_EXTERNAL])
if event == KEY_BTN_APPLY:
self.restart_osc_event()
if event == KEY_BTN_REFRESH:
Expand Down
23 changes: 21 additions & 2 deletions BridgeApp/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def main():

# Init GUI
global gui
gui = GUIRenderer(config, pulse_test, restart_bridge_server, refresh_tracker_list)
gui = GUIRenderer(config, pulse_test, restart_bridge_server, refresh_tracker_list, add_external_target)
print("[Main] GUI initialized")

# Start the Server
Expand Down Expand Up @@ -75,13 +75,31 @@ def refresh_tracker_list():
return

for device in vr.query_devices():
gui.add_tracker(device.index, device.serial, device.model)
gui.add_tracker(device.serial, device.model)

# Debug tracker (Uncomment this for debug purposes)
# gui.add_tracker(99, "T35T-53R1AL", "Test Model 1.0")
print("[Main] Tracker list refreshed")


def add_external_target(external_type):
print(external_type)

sound_emu = "EMUSND"
text_emu = "EMUTXT"
serial_com = "SERIALCOM"
network = "NETWORK"

if external_type.endswith(sound_emu):
gui.add_external_device(sound_emu+"-1", "Sound Target")
if external_type.endswith(text_emu):
gui.add_external_device(text_emu+"-1", "Text Target")
if external_type.endswith(serial_com):
gui.add_external_device(serial_com+"-1", "Serial Target")
if external_type.endswith(network):
gui.add_external_device(network+"-1", "Network Target")


def param_received(address, value):
# value is the floating value (0..1) that determines how intense the feedback should be
for serial, tracker_config in config.tracker_config_dict.items():
Expand All @@ -98,6 +116,7 @@ def param_received(address, value):
print(f"[Main][ERROR] {e}\n{traceback.format_exc()}")
with open('hpb_crashlog.txt', "w+") as crash_log:
import json

json.dump(traceback.format_exc(), fp=crash_log)
finally:
# Shut down the processes
Expand Down
Empty file added BridgeApp/target_emulated.py
Empty file.
4 changes: 2 additions & 2 deletions hapticpancake.spec
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]


a = Analysis(
['BridgeApp/main.py'],
['BridgeApp\\main.py'],
pathex=[],
binaries=binaries,
datas=datas,
Expand Down Expand Up @@ -41,5 +41,5 @@ exe = EXE(
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['Images/icon.ico'],
icon=['Images\\icon.ico'],
)

0 comments on commit c745b1f

Please sign in to comment.