from PySide2.QtCore import QRect, Signal, Qt
from PySide2.QtGui import QFont, QLinearGradient, QColor, QKeySequence
from PySide2.QtWidgets import QFormLayout, QGridLayout, QKeySequenceEdit, QWidget, QPushButton, QTableWidget, QTableWidgetItem, QAbstractScrollArea, QAbstractItemView, \
QTabWidget, QGraphicsScene, QGraphicsView, QFrame, QSlider, QLabel, QLineEdit, QCheckBox, QStatusBar, QScrollArea, QTextEdit, \
QComboBox
import math # for gradient generation
import platform # for selecting specific fonts for specific systems
mainFont = QFont()
mainFont.setBold(True)
mainFont.setWeight(75)
def combinePySide2Values(theValues):
# ADDED THIS TO FIX PySide2 VERSIONS < 5.15
# AND THE "can not interpret as integer"
# ERROR WHEN COMBINING ALIGNMENT FLAGS
returnValue = int(theValues[0])
for a in range(1, len(theValues)):
returnValue = returnValue + int(theValues[a])
return returnValue
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
# ============ FONTS, GRADIENTS AND OTHER WINDOW SPECIFICS ============
MainWindow.setFixedSize(590, 670) # the main window should be this size at launch, and no bigger
MainWindow.setWindowTitle("NeewerLite-Python [2024-04-20-BETA] by Zach Glenwright")
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
# ============ THE TOP-MOST BUTTONS ============
self.turnOffButton = QPushButton(self.centralwidget)
self.turnOffButton.setGeometry(QRect(10, 4, 150, 22))
self.turnOffButton.setText("Turn Light(s) Off")
self.turnOnButton = QPushButton(self.centralwidget)
self.turnOnButton.setGeometry(QRect(165, 4, 150, 22))
self.turnOnButton.setText("Turn Light(s) On")
self.scanCommandButton = QPushButton(self.centralwidget)
self.scanCommandButton.setGeometry(QRect(416, 4, 81, 22))
self.scanCommandButton.setText("Scan")
self.tryConnectButton = QPushButton(self.centralwidget)
self.tryConnectButton.setGeometry(QRect(500, 4, 81, 22))
self.tryConnectButton.setText("Connect")
self.turnOffButton.setEnabled(False)
self.turnOnButton.setEnabled(False)
self.tryConnectButton.setEnabled(False)
# ============ THE LIGHT TABLE ============
self.lightTable = QTableWidget(self.centralwidget)
self.lightTable.setColumnCount(4)
self.lightTable.setColumnWidth(0, 120)
self.lightTable.setColumnWidth(1, 150)
self.lightTable.setColumnWidth(2, 94)
self.lightTable.setColumnWidth(3, 190)
__QT0 = QTableWidgetItem()
__QT0.setText("Light Name")
self.lightTable.setHorizontalHeaderItem(0, __QT0)
__QT1 = QTableWidgetItem()
__QT1.setText("MAC Address")
self.lightTable.setHorizontalHeaderItem(1, __QT1)
__QT2 = QTableWidgetItem()
__QT2.setText("Linked")
self.lightTable.setHorizontalHeaderItem(2, __QT2)
__QT3 = QTableWidgetItem()
__QT3.setText("Status")
self.lightTable.setHorizontalHeaderItem(3, __QT3)
self.lightTable.setGeometry(QRect(10, 32, 571, 261))
self.lightTable.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
self.lightTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.lightTable.setAlternatingRowColors(True)
self.lightTable.setSelectionBehavior(QAbstractItemView.SelectRows)
self.lightTable.verticalHeader().setStretchLastSection(False)
# ============ THE CUSTOM PRESET BUTTONS ============
self.customPresetButtonsCW = QWidget(self.centralwidget)
self.customPresetButtonsCW.setGeometry(QRect(10, 300, 571, 68))
self.customPresetButtonsLay = QGridLayout(self.customPresetButtonsCW)
self.customPresetButtonsLay.setContentsMargins(0, 0, 0, 0) # ensure this widget spans from the left to the right edge of the light table
self.customPreset_0_Button = customPresetButton(self.centralwidget, text="1
PRESET
GLOBAL")
self.customPresetButtonsLay.addWidget(self.customPreset_0_Button, 1, 1)
self.customPreset_1_Button = customPresetButton(self.centralwidget, text="2
PRESET
GLOBAL")
self.customPresetButtonsLay.addWidget(self.customPreset_1_Button, 1, 2)
self.customPreset_2_Button = customPresetButton(self.centralwidget, text="3
PRESET
GLOBAL")
self.customPresetButtonsLay.addWidget(self.customPreset_2_Button, 1, 3)
self.customPreset_3_Button = customPresetButton(self.centralwidget, text="4
PRESET
GLOBAL")
self.customPresetButtonsLay.addWidget(self.customPreset_3_Button, 1, 4)
self.customPreset_4_Button = customPresetButton(self.centralwidget, text="5
PRESET
GLOBAL")
self.customPresetButtonsLay.addWidget(self.customPreset_4_Button, 1, 5)
self.customPreset_5_Button = customPresetButton(self.centralwidget, text="6
PRESET
GLOBAL")
self.customPresetButtonsLay.addWidget(self.customPreset_5_Button, 1, 6)
self.customPreset_6_Button = customPresetButton(self.centralwidget, text="7
PRESET
GLOBAL")
self.customPresetButtonsLay.addWidget(self.customPreset_6_Button, 1, 7)
self.customPreset_7_Button = customPresetButton(self.centralwidget, text="8
PRESET
GLOBAL")
self.customPresetButtonsLay.addWidget(self.customPreset_7_Button, 1, 8)
# ============ THE MODE TABS ============
self.ColorModeTabWidget = QTabWidget(self.centralwidget)
self.ColorModeTabWidget.setGeometry(QRect(10, 385, 571, 254))
# === >> MAIN TAB WIDGETS << ===
self.CCT = QWidget()
self.HSI = QWidget()
self.ANM = QWidget()
# ============ SINGLE SLIDER WIDGET DEFINITIONS ============
self.colorTempSlider = parameterWidget(title="Color Temperature", gradient="TEMP",
sliderMin=32, sliderMax=72, sliderVal=56, prefix="00K")
self.brightSlider = parameterWidget(title="Brightness", gradient="BRI")
self.GMSlider = parameterWidget(title="GM Compensation", gradient="GM", sliderOffset=-50, sliderVal=50, prefix="")
self.RGBSlider = parameterWidget(title="Hue", gradient="RGB", sliderMin=0, sliderMax=360, sliderVal=180, prefix="º")
self.colorSatSlider = parameterWidget(title="Saturation", gradient="SAT", sliderVal=100)
# change the saturation gradient when the RGB slider changes
self.RGBSlider.valueChanged.connect(self.colorSatSlider.adjustSatGradient)
self.speedSlider = parameterWidget(title="Speed", gradient="SPEED", sliderMin=0, sliderMax=10, sliderVal=5, prefix="")
self.sparksSlider = parameterWidget(title="Sparks", gradient="SPARKS", sliderMin=0, sliderMax=10, sliderVal=5, prefix="")
# ============ DOUBLE SLIDER WIDGET DEFINITIONS ============
self.brightDoubleSlider = doubleSlider(sliderType="BRI")
self.RGBDoubleSlider = doubleSlider(sliderType="RGB")
self.colorTempDoubleSlider = doubleSlider(sliderType="TEMP")
# ============ FX CHOOSER DEFINITIONS ============
self.effectChooser_Title = QLabel(self.ANM, text="Choose an effect:")
self.effectChooser_Title.setGeometry(QRect(8, 6, 120, 20))
self.effectChooser_Title.setFont(mainFont)
self.effectChooser = QComboBox(self.ANM)
self.effectChooser.setGeometry(QRect(125, 6, 430, 22))
# ============ FX CHOOSER DEFINITIONS ============
self.specialOptionsSection = QWidget(self.ANM)
self.specialOptions_Title = QLabel(self.specialOptionsSection, text="Choose a color option:")
self.specialOptions_Title.setFont(mainFont)
self.specialOptions_Title.setGeometry(0, 0, 250, 20)
self.specialOptionsChooser = QComboBox(self.specialOptionsSection)
self.specialOptionsChooser.setGeometry(QRect(0, 20, self.ColorModeTabWidget.width() - 16, 22))
self.specialOptionsSection.hide()
# self.specialOptionsChooser.addItems(["Red", "Blue", "Red and Blue", "White and Blue", "Red, Blue and White"])
# self.specialOptionsChooser.setCurrentIndex(2)
# self.specialOptionsSetion.setParent(self.CCT)
# self.specialOptionsSetion.move(8, 20)
# =============================================================================
# === >> THE LIGHT PREFS TAB << ===
self.lightPrefs = QWidget()
# CUSTOM NAME FIELD FOR THIS LIGHT
self.customName = QCheckBox(self.lightPrefs)
self.customName.setGeometry(QRect(10, 14, 541, 16))
self.customName.setText("Custom Name for this light:")
self.customName.setFont(mainFont)
self.customNameTF = QLineEdit(self.lightPrefs)
self.customNameTF.setGeometry(QRect(10, 34, 541, 20))
self.customNameTF.setMaxLength(80)
# CUSTOM HSI COLOR TEMPERATURE RANGES FOR THIS LIGHT
self.colorTempRange = QCheckBox(self.lightPrefs)
self.colorTempRange.setGeometry(QRect(10, 82, 541, 16))
self.colorTempRange.setText("Use Custom Color Temperature Range for CCT mode:")
self.colorTempRange.setFont(mainFont)
self.colorTempRange_Min_TF = QLineEdit(self.lightPrefs)
self.colorTempRange_Min_TF.setGeometry(QRect(10, 102, 120, 20))
self.colorTempRange_Min_TF.setMaxLength(80)
self.colorTempRange_Max_TF = QLineEdit(self.lightPrefs)
self.colorTempRange_Max_TF.setGeometry(QRect(160, 102, 120, 20))
self.colorTempRange_Max_TF.setMaxLength(80)
self.colorTempRange_Min_Description = QLabel(self.lightPrefs)
self.colorTempRange_Min_Description.setGeometry(QRect(10, 124, 120, 16))
self.colorTempRange_Min_Description.setAlignment(Qt.AlignCenter)
self.colorTempRange_Min_Description.setText("Minimum")
self.colorTempRange_Min_Description.setFont(mainFont)
self.colorTempRange_Max_Description = QLabel(self.lightPrefs)
self.colorTempRange_Max_Description.setGeometry(QRect(160, 124, 120, 16))
self.colorTempRange_Max_Description.setAlignment(Qt.AlignCenter)
self.colorTempRange_Max_Description.setText("Maximum")
self.colorTempRange_Max_Description.setFont(mainFont)
# WHETHER OR NOT TO ONLY ALLOW CCT MODE FOR THIS LIGHT
self.onlyCCTModeCheck = QCheckBox(self.lightPrefs)
self.onlyCCTModeCheck.setGeometry(QRect(10, 160, 401, 31))
self.onlyCCTModeCheck.setText("This light can only use CCT mode\n(for Neewer lights without HSI mode)")
self.onlyCCTModeCheck.setFont(mainFont)
# SAVE IIITTTTTT!
self.saveLightPrefsButton = QPushButton(self.lightPrefs)
self.saveLightPrefsButton.setGeometry(QRect(416, 170, 141, 23))
self.saveLightPrefsButton.setText("Save Preferences")
# === >> THE GLOBAL PREFS TAB << ===
self.globalPrefs = QScrollArea()
self.globalPrefsCW = QWidget()
self.globalPrefsCW.setMaximumWidth(550) # make sure to resize all contents to fit in the horizontal space of the scrollbar widget
self.globalPrefsLay = QFormLayout(self.globalPrefsCW)
self.globalPrefsLay.setLabelAlignment(Qt.AlignLeft)
self.globalPrefs.setWidget(self.globalPrefsCW)
self.globalPrefs.setWidgetResizable(True)
# MAIN PROGRAM PREFERENCES
self.findLightsOnStartup_check = QCheckBox("Scan for Neewer lights on program launch")
self.autoConnectToLights_check = QCheckBox("Automatically try to link to newly found lights")
self.printDebug_check = QCheckBox("Print debug information to the console")
self.rememberLightsOnExit_check = QCheckBox("Remember the last mode parameters set for lights on exit")
self.rememberPresetsOnExit_check = QCheckBox("Save configuration of custom presets on exit")
self.maxNumOfAttempts_field = QLineEdit()
self.maxNumOfAttempts_field.setFixedWidth(35)
self.acceptable_HTTP_IPs_field = QTextEdit()
self.acceptable_HTTP_IPs_field.setFixedHeight(70)
self.whiteListedMACs_field = QTextEdit()
self.whiteListedMACs_field.setFixedHeight(70)
self.resetGlobalPrefsButton = QPushButton("Reset Preferences to Defaults")
self.saveGlobalPrefsButton = QPushButton("Save Global Preferences")
# THE FIRST SECTION OF KEYBOARD MAPPING SECTION
self.windowButtonsCW = QWidget()
self.windowButtonsLay = QGridLayout(self.windowButtonsCW)
self.SC_turnOffButton_field = singleKeySequenceEditCancel("Ctrl+PgDown")
self.windowButtonsLay.addWidget(QLabel("Window Top
Turn Light(s) Off", alignment=Qt.AlignCenter), 1, 1)
self.windowButtonsLay.addWidget(self.SC_turnOffButton_field, 2, 1)
self.SC_turnOnButton_field = singleKeySequenceEditCancel("Ctrl+PgUp")
self.windowButtonsLay.addWidget(QLabel("Window Top
Turn Light(s) On", alignment=Qt.AlignCenter), 1, 2)
self.windowButtonsLay.addWidget(self.SC_turnOnButton_field, 2, 2)
self.SC_scanCommandButton_field = singleKeySequenceEditCancel("Ctrl+Shift+S")
self.windowButtonsLay.addWidget(QLabel("Window Top
Scan/Re-Scan", alignment=Qt.AlignCenter), 1, 3)
self.windowButtonsLay.addWidget(self.SC_scanCommandButton_field, 2, 3)
self.SC_tryConnectButton_field = singleKeySequenceEditCancel("Ctrl+Shift+C")
self.windowButtonsLay.addWidget(QLabel("Window Top
Connect", alignment=Qt.AlignCenter), 1, 4)
self.windowButtonsLay.addWidget(self.SC_tryConnectButton_field, 2, 4)
# SWITCHING BETWEEN TABS KEYBOARD MAPPING SECTION
self.tabSwitchCW = QWidget()
self.tabSwitchLay = QGridLayout(self.tabSwitchCW)
self.SC_Tab_CCT_field = singleKeySequenceEditCancel("Alt+1")
self.tabSwitchLay.addWidget(QLabel("Switching Tabs
To CCT", alignment=Qt.AlignCenter), 1, 1)
self.tabSwitchLay.addWidget(self.SC_Tab_CCT_field, 2, 1)
self.SC_Tab_HSI_field = singleKeySequenceEditCancel("Alt+2")
self.tabSwitchLay.addWidget(QLabel("Switching Tabs
To HSI", alignment=Qt.AlignCenter), 1, 2)
self.tabSwitchLay.addWidget(self.SC_Tab_HSI_field, 2, 2)
self.SC_Tab_SCENE_field = singleKeySequenceEditCancel("Alt+3")
self.tabSwitchLay.addWidget(QLabel("Switching Tabs
To SCENE", alignment=Qt.AlignCenter), 1, 3)
self.tabSwitchLay.addWidget(self.SC_Tab_SCENE_field, 2, 3)
self.SC_Tab_PREFS_field = singleKeySequenceEditCancel("Alt+4")
self.tabSwitchLay.addWidget(QLabel("Switching Tabs
To Light Prefs", alignment=Qt.AlignCenter), 1, 4)
self.tabSwitchLay.addWidget(self.SC_Tab_PREFS_field, 2, 4)
# BRIGHTNESS ADJUSTMENT KEYBOARD MAPPING SECTION
self.brightnessCW = QWidget()
self.brightnessLay = QGridLayout(self.brightnessCW)
self.SC_Dec_Bri_Small_field = singleKeySequenceEditCancel("/")
self.brightnessLay.addWidget(QLabel("Brightness
Small Decrease", alignment=Qt.AlignCenter), 1, 1)
self.brightnessLay.addWidget(self.SC_Dec_Bri_Small_field, 2, 1)
self.SC_Dec_Bri_Large_field = singleKeySequenceEditCancel("Ctrl+/")
self.brightnessLay.addWidget(QLabel("Brightness
Large Decrease", alignment=Qt.AlignCenter), 1, 2)
self.brightnessLay.addWidget(self.SC_Dec_Bri_Large_field, 2, 2)
self.SC_Inc_Bri_Small_field = singleKeySequenceEditCancel("*")
self.brightnessLay.addWidget(QLabel("Brightness
Small Increase", alignment=Qt.AlignCenter), 1, 3)
self.brightnessLay.addWidget(self.SC_Inc_Bri_Small_field, 2, 3)
self.SC_Inc_Bri_Large_field = singleKeySequenceEditCancel("Ctrl+*")
self.brightnessLay.addWidget(QLabel("Brightness
Large Increase", alignment=Qt.AlignCenter), 1, 4)
self.brightnessLay.addWidget(self.SC_Inc_Bri_Large_field, 2, 4)
# SLIDER ADJUSTMENT KEYBOARD MAPPING SECTIONS
self.sliderAdjustmentCW = QWidget()
self.sliderAdjustmentLay = QGridLayout(self.sliderAdjustmentCW)
self.SC_Dec_1_Small_field = singleKeySequenceEditCancel("7")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 1
Small Decrease", alignment=Qt.AlignCenter), 1, 1)
self.sliderAdjustmentLay.addWidget(self.SC_Dec_1_Small_field, 2, 1)
self.SC_Dec_1_Large_field = singleKeySequenceEditCancel("Ctrl+7")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 1
Large Decrease", alignment=Qt.AlignCenter), 1, 2)
self.sliderAdjustmentLay.addWidget(self.SC_Dec_1_Large_field, 2, 2)
self.SC_Inc_1_Small_field = singleKeySequenceEditCancel("9")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 1
Small Increase", alignment=Qt.AlignCenter), 1, 3)
self.sliderAdjustmentLay.addWidget(self.SC_Inc_1_Small_field, 2, 3)
self.SC_Inc_1_Large_field = singleKeySequenceEditCancel("Ctrl+9")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 1
Large Increase", alignment=Qt.AlignCenter), 1, 4)
self.sliderAdjustmentLay.addWidget(self.SC_Inc_1_Large_field, 2, 4)
self.SC_Dec_2_Small_field = singleKeySequenceEditCancel("4")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 2
Small Decrease", alignment=Qt.AlignCenter), 3, 1)
self.sliderAdjustmentLay.addWidget(self.SC_Dec_2_Small_field, 4, 1)
self.SC_Dec_2_Large_field = singleKeySequenceEditCancel("Ctrl+4")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 2
Large Decrease", alignment=Qt.AlignCenter), 3, 2)
self.sliderAdjustmentLay.addWidget(self.SC_Dec_2_Large_field, 4, 2)
self.SC_Inc_2_Small_field = singleKeySequenceEditCancel("6")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 2
Small Increase", alignment=Qt.AlignCenter), 3, 3)
self.sliderAdjustmentLay.addWidget(self.SC_Inc_2_Small_field, 4, 3)
self.SC_Inc_2_Large_field = singleKeySequenceEditCancel("Ctrl+6")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 2
Large Increase", alignment=Qt.AlignCenter), 3, 4)
self.sliderAdjustmentLay.addWidget(self.SC_Inc_2_Large_field, 4, 4)
self.SC_Dec_3_Small_field = singleKeySequenceEditCancel("1")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 3
Small Decrease", alignment=Qt.AlignCenter), 5, 1)
self.sliderAdjustmentLay.addWidget(self.SC_Dec_3_Small_field, 6, 1)
self.SC_Dec_3_Large_field = singleKeySequenceEditCancel("Ctrl+1")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 3
Large Decrease", alignment=Qt.AlignCenter), 5, 2)
self.sliderAdjustmentLay.addWidget(self.SC_Dec_3_Large_field, 6, 2)
self.SC_Inc_3_Small_field = singleKeySequenceEditCancel("3")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 3
Small Increase", alignment=Qt.AlignCenter), 5, 3)
self.sliderAdjustmentLay.addWidget(self.SC_Inc_3_Small_field, 6, 3)
self.SC_Inc_3_Large_field = singleKeySequenceEditCancel("Ctrl+3")
self.sliderAdjustmentLay.addWidget(QLabel("Slider 3
Large Increase", alignment=Qt.AlignCenter), 5, 4)
self.sliderAdjustmentLay.addWidget(self.SC_Inc_3_Large_field, 6, 4)
# BOTTOM BUTTONS
self.bottomButtonsCW = QWidget()
self.bottomButtonsLay = QGridLayout(self.bottomButtonsCW)
self.bottomButtonsLay.addWidget(self.resetGlobalPrefsButton, 1, 1)
self.bottomButtonsLay.addWidget(self.saveGlobalPrefsButton, 1, 2)
# FINALLY, IT'S TIME TO BUILD THE PREFERENCES PANE ITSELF
self.globalPrefsLay.addRow(QLabel("Main Program Options", alignment=Qt.AlignCenter))
self.globalPrefsLay.addRow(self.findLightsOnStartup_check)
self.globalPrefsLay.addRow(self.autoConnectToLights_check)
self.globalPrefsLay.addRow(self.printDebug_check)
self.globalPrefsLay.addRow(self.rememberLightsOnExit_check)
self.globalPrefsLay.addRow(self.rememberPresetsOnExit_check)
self.globalPrefsLay.addRow("Maximum Number of retries:", self.maxNumOfAttempts_field)
self.globalPrefsLay.addRow(QLabel("