Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
328 changes: 302 additions & 26 deletions axis_ui.py

Large diffs are not rendered by default.

21 changes: 9 additions & 12 deletions encoderconf_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,23 @@ def setType(self,id):
found = False
elif(id == 4): # MT SPI
self.widget = (MtEncoderConf(self,self.main))
self.setTitle("SPI Settings")
self.setTitle("SPI Settings (port SPI3)")
elif(id == 5): # BISS-C
self.widget = (BissEncoderConf(self,self.main))
self.setTitle("BISS Settings")
self.setTitle("BISS Settings (port SPI3 - exclusif usage)")
elif(id == 6): # SSI
self.widget = (SsiEncoderConf(self,self.main))
self.setTitle("SSI Settings")
self.setTitle("SSI Settings (port SPI3 - exclusif usage)")
else:
layout.addWidget(QLabel("No settings"))


layout.setContentsMargins(0,0,0,0)
layout.setContentsMargins(5,0,5,0)
layout.setStretch(0,0)
if self.widget:
layout.addWidget(self.widget)
self.setLayout(layout)

if self.widget:
self.applyBtn = QPushButton("Apply")
self.applyBtn.clicked.connect(self.widget.apply)
footer = QHBoxLayout()
Expand All @@ -52,7 +55,6 @@ def setType(self,id):
footer.addStretch(5)
layout.addLayout(footer)

self.setLayout(layout)

class EncoderOption(QWidget):
def __init__(self,parent):
Expand Down Expand Up @@ -89,7 +91,7 @@ def initUI(self):

self.spinBox_cpr = QSpinBox()
self.spinBox_cpr.setRange(0,0xffff)
layout.addWidget(QLabel("CPR = 4x PPR"))
layout.addRow(QLabel("CPR = 4x PPR"))
layout.addRow(QLabel("CPR:"),self.spinBox_cpr)

self.checkBox_index = QCheckBox("Use index homing")
Expand Down Expand Up @@ -121,7 +123,6 @@ def initUI(self):

self.spinBox_cs = QSpinBox()
self.spinBox_cs.setRange(1,3)
layout.addWidget(QLabel("SPI3 extension port"))
layout.addRow(QLabel("CS pin"),self.spinBox_cs)

self.comboBox_mode = QComboBox()
Expand Down Expand Up @@ -169,10 +170,8 @@ def initUI(self):
self.checkBox_direction = QCheckBox("Reverse direction (default)")
self.spinBox_bits = QSpinBox()
self.spinBox_bits.setRange(1,32)
layout.addWidget(QLabel("SPI3 extension port"))
layout.addRow(QLabel("Bits"),self.spinBox_bits)
layout.addWidget(self.checkBox_direction)
layout.addWidget(QLabel("Port is used exclusively!"))
self.setLayout(layout)

def onshown(self):
Expand Down Expand Up @@ -202,11 +201,9 @@ def initUI(self):
self.comboBox_mode = QComboBox()
self.comboBox_speed = QComboBox()

layout.addWidget(QLabel("SPI3 extension port"))
layout.addRow(QLabel("Bits"),self.spinBox_bits)
layout.addRow(QLabel("Mode"),self.comboBox_mode)
layout.addRow(QLabel("SPI speed"),self.comboBox_speed)
layout.addWidget(QLabel("Port is used exclusively!"))
self.setLayout(layout)

def updateSpeeds(self,reply):
Expand Down
32 changes: 31 additions & 1 deletion ffb_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from PyQt6.QtWidgets import QWidget,QToolButton
from PyQt6.QtWidgets import QMessageBox,QVBoxLayout,QCheckBox,QButtonGroup,QGridLayout,QSpinBox
from PyQt6 import uic
from helper import res_path,classlistToIds,splitListReply,throttle
from helper import res_path,classlistToIds,splitListReply,throttle,qtBlockAndCall
from PyQt6.QtCore import QTimer,QEvent, pyqtSignal
import main
import buttonconf_ui
Expand Down Expand Up @@ -111,6 +111,13 @@ def __init__(self, main : 'main.MainUi'=None, title = "FFB main"):

self.register_callback("fx", "frictionPctSpeedToRampup", self.set_friction_pct_speed_rampup,0,int)

# --- Smoothing Controls ---
self.radioButton_reconfilter_0.toggled.connect(lambda checked: self.send_recon_filter(0) if checked else None)
self.radioButton_reconfilter_1.toggled.connect(lambda checked: self.send_recon_filter(1) if checked else None)
self.radioButton_reconfilter_2.toggled.connect(lambda checked: self.send_recon_filter(2) if checked else None)
self.radioButton_reconfilter_3.toggled.connect(lambda checked: self.send_recon_filter(3) if checked else None)
self.register_callback("fx", "reconFilterMode", self.update_recon_filter_ui, 0, int)

if(self.init_ui()):
tabId = self.main.add_tab(self,title)
self.main.select_tab(tabId)
Expand All @@ -131,6 +138,7 @@ def init_ui(self):
self.send_command("main","lsain",0,'?') # get analog types
self.send_command("main","aintypes",0,'?') # get active analog

self.send_commands("fx", ["reconFilterMode"])

self.updateSliders()
self.send_command("main","hidsendspd",0,'!') # get speed
Expand Down Expand Up @@ -337,6 +345,28 @@ def updateAnalogSources(self,types):

self.groupBox_analogaxes.setLayout(layout)

# Called when the reconstruction filter slider is moved
def send_recon_filter(self, value):
"""Sends the selected reconstruction filter mode to the firmware."""
self.send_value("fx", "reconFilterMode", value)

# Callback to update the reconstruction filter UI from firmware data
def update_recon_filter_ui(self, value):
"""Updates the reconstruction filter slider and label."""
button_radio = None
if (value < 0 or value >= 4):
self.main.log(f"Warning: Received unknown reconstruction filter mode value: {value}")
elif value == 0:
button_radio = self.radioButton_reconfilter_0
elif value == 1:
button_radio = self.radioButton_reconfilter_1
elif value == 2:
button_radio = self.radioButton_reconfilter_2
elif value == 3:
button_radio = self.radioButton_reconfilter_3
qtBlockAndCall(button_radio, button_radio.setChecked, True)
button_radio.setChecked(True)

@throttle(50)
def cffilter_changed(self,v,send=True):
self.tech_log.debug("Freq %s send %d", v, send)
Expand Down
31 changes: 27 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ def __init__(self):
self.timer = PyQt6.QtCore.QTimer(self)
self.timer.timeout.connect(self.update_timer) # pylint: disable=no-value-for-parameter
self.tabWidget_main.currentChanged.connect(self.tab_changed)
# Force the main window to resize to the content of the newly selected tab
self.tabWidget_main.currentChanged.connect(lambda: PyQt6.QtCore.QTimer.singleShot(0, self.adjustSize))
self.errors_dlg = errors.ErrorsDialog(self)
self.effects_monitor_dlg = effects_monitor.EffectsMonitorDialog(self)
self.maxaxischanged.connect(self.effects_monitor_dlg.set_max_axes)
Expand Down Expand Up @@ -287,6 +289,15 @@ def open_dfu_dialog(self):
dfu.deleteLater()


def changeEvent(self, event: PyQt6.QtCore.QEvent):
"""Minimize to systray when window is minimized."""
if event.type() == PyQt6.QtCore.QEvent.Type.WindowStateChange:
if self.windowState() & PyQt6.QtCore.Qt.WindowState.WindowMinimized:
self.hide()
event.ignore()
return
super().changeEvent(event)

def moveEvent(self, event: PyQt6.QtGui.QMoveEvent): #pylint: disable=invalid-name
"""Move all modal dialog when moving main ui."""
super().moveEvent(event)
Expand Down Expand Up @@ -758,7 +769,7 @@ def __init__(self, main: MainUi):
self._submenu_profiles: PyQt6.QtWidgets.QMenu = None

# Adding an icon
icon = PyQt6.QtGui.QIcon("app.png")
icon = PyQt6.QtGui.QIcon(helper.res_path('app.ico'))

# Adding item on the menu bar
tray = PyQt6.QtWidgets.QSystemTrayIcon(main)
Expand Down Expand Up @@ -928,6 +939,14 @@ def __init__(self, parent : MainUi = None ):
"""Display the about box with the release number updated."""
PyQt6.QtWidgets.QDialog.__init__(self, parent)
PyQt6.uic.loadUi(helper.res_path("about.ui"), self)
self.parent = parent
self.init_ui()

self.sig_dialog.signature_result.connect(parent.update_signature)
self.sig_dialog.signature_result.connect(lambda : self.init_ui())

def init_ui(self):
parent = self.parent
verstr = "Version: " + VERSION
self.hwuid = parent.hwuid
self.sig_dialog = SignatureInputDialog(self,parent.hwuid)
Expand All @@ -943,15 +962,13 @@ def __init__(self, parent : MainUi = None ):
self.pushButton_signature.setEnabled(False)

signaturestr = self.tr("Signature: ")
if not parent.hwsignature:
if not parent.hwsignature or parent.hwsignature == bytes([0xff])*64:
signaturestr += self.tr("Missing")
self.pushButton_signature.setEnabled(True)
else:
signaturestr += self.tr("Valid ✅" if parent.signature_valid else "Invalid ❌")
self.label_signature.setText(signaturestr)

self.sig_dialog.signature_result.connect(parent.update_signature)

def signature_dialog(self):
self.sig_dialog.open()

Expand Down Expand Up @@ -1045,6 +1062,12 @@ def process_events():

if __name__ == "__main__":
logging.config.fileConfig(helper.res_path('logger.conf'))
if sys.platform == "win32" or "Windows" in sys.platform:
import ctypes
try:
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("openffboard.configurator.app")
except Exception:
pass
restart = True
exit_code = -1
app = PyQt6.QtWidgets.QApplication(sys.argv)
Expand Down
Loading
Loading