|
|
|
|
@@ -5,6 +5,7 @@
|
|
|
|
|
|
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
|
|
#include <QAbstractButton>
|
|
|
|
|
#include <QCloseEvent>
|
|
|
|
|
#include <QGroupBox>
|
|
|
|
|
#include <QSlider>
|
|
|
|
|
@@ -18,7 +19,7 @@
|
|
|
|
|
#include "sensor_driver.hpp"
|
|
|
|
|
#include "utils.hpp"
|
|
|
|
|
|
|
|
|
|
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
|
|
|
|
|
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), m_mtx(QMutex::RecursionMode::Recursive)
|
|
|
|
|
{
|
|
|
|
|
qDebug(ltr("Creating main window"));
|
|
|
|
|
|
|
|
|
|
@@ -28,6 +29,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
|
|
|
|
|
enumMonitors();
|
|
|
|
|
|
|
|
|
|
setupMonitorsTab();
|
|
|
|
|
setupSensorsTab();
|
|
|
|
|
|
|
|
|
|
setupTrayIcon();
|
|
|
|
|
|
|
|
|
|
@@ -52,6 +54,8 @@ void MainWindow::closeEvent(QCloseEvent* event)
|
|
|
|
|
|
|
|
|
|
void MainWindow::enumSensors()
|
|
|
|
|
{
|
|
|
|
|
m_sensors.clear();
|
|
|
|
|
|
|
|
|
|
auto sensors = enumerateSensors();
|
|
|
|
|
|
|
|
|
|
for(auto& sensor: sensors) {
|
|
|
|
|
@@ -61,15 +65,20 @@ void MainWindow::enumSensors()
|
|
|
|
|
|
|
|
|
|
void MainWindow::enumMonitors()
|
|
|
|
|
{
|
|
|
|
|
m_mtx.lock();
|
|
|
|
|
|
|
|
|
|
m_ui.monitorDropdown->clear();
|
|
|
|
|
m_monitors.clear();
|
|
|
|
|
|
|
|
|
|
auto monitors = enumerateMonitors();
|
|
|
|
|
|
|
|
|
|
for(auto& monitor: monitors) {
|
|
|
|
|
const auto currentBrightness = monitor.getBrightness();
|
|
|
|
|
m_ui.monitorDropdown->addItem(monitor.getName());
|
|
|
|
|
m_monitors.push_back({std::move(monitor), 0.f, 1.f, currentBrightness, false});
|
|
|
|
|
m_ui.monitorDropdown->addItem(m_monitors.back().driver.getName());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_mtx.unlock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::loadIcons()
|
|
|
|
|
@@ -110,23 +119,111 @@ void MainWindow::loadIcons()
|
|
|
|
|
void MainWindow::setupMonitorsTab()
|
|
|
|
|
{
|
|
|
|
|
connect(m_ui.monitorDropdown, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MainWindow::updateCurrentMonitorGUI);
|
|
|
|
|
connect(m_ui.monitorEnumerateButton, &QAbstractButton::clicked, [this](bool) { enumMonitors(); });
|
|
|
|
|
connect(m_ui.monitorResetButton, &QAbstractButton::clicked, [this](bool) { resetAllMonitorSettings(); });
|
|
|
|
|
|
|
|
|
|
setupLimitsSlider();
|
|
|
|
|
setupOverallLimitsSlider();
|
|
|
|
|
|
|
|
|
|
setupBrightness();
|
|
|
|
|
setupOverallBrightness();
|
|
|
|
|
|
|
|
|
|
resetAllMonitorSettings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::setupLimitsSlider()
|
|
|
|
|
{
|
|
|
|
|
connect(m_ui.monitorMinBrightnessSlider, &QSlider::valueChanged, [this](int value) {
|
|
|
|
|
m_ui.monitorMinBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
|
|
|
|
|
if(value > m_ui.monitorMaxBrightnessSlider->value()) {
|
|
|
|
|
m_ui.monitorMaxBrightnessSlider->setValue(value);
|
|
|
|
|
}
|
|
|
|
|
const auto curIdx = m_ui.monitorDropdown->currentIndex();
|
|
|
|
|
m_monitors[curIdx].minBrightness = utils::map(value, 0, 100, 0.f, 1.f);
|
|
|
|
|
});
|
|
|
|
|
connect(m_ui.monitorMaxBrightnessSlider, &QSlider::valueChanged, [this](int value) {
|
|
|
|
|
m_ui.monitorMaxBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
|
|
|
|
|
if(value < m_ui.monitorMinBrightnessSlider->value()) {
|
|
|
|
|
m_ui.monitorMinBrightnessSlider->setValue(value);
|
|
|
|
|
}
|
|
|
|
|
const auto curIdx = m_ui.monitorDropdown->currentIndex();
|
|
|
|
|
m_monitors[curIdx].maxBrightness = utils::map(value, 0, 100, 0.f, 1.f);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::setupOverallLimitsSlider()
|
|
|
|
|
{
|
|
|
|
|
connect(m_ui.monitorOverallMinBrightnessSlider, &QSlider::valueChanged, [this](int value) {
|
|
|
|
|
m_ui.monitorOverallMinBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
|
|
|
|
|
if(value > m_ui.monitorOverallMaxBrightnessSlider->value()) {
|
|
|
|
|
m_ui.monitorOverallMaxBrightnessSlider->setValue(value);
|
|
|
|
|
}
|
|
|
|
|
for(auto& monitor: m_monitors) {
|
|
|
|
|
monitor.minBrightness = utils::map(value, 0, 100, 0.f, 1.f);
|
|
|
|
|
}
|
|
|
|
|
updateCurrentMonitorGUI(m_ui.monitorDropdown->currentIndex());
|
|
|
|
|
});
|
|
|
|
|
connect(m_ui.monitorOverallMaxBrightnessSlider, &QSlider::valueChanged, [this](int value) {
|
|
|
|
|
m_ui.monitorOverallMaxBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
|
|
|
|
|
if(value < m_ui.monitorOverallMinBrightnessSlider->value()) {
|
|
|
|
|
m_ui.monitorOverallMinBrightnessSlider->setValue(value);
|
|
|
|
|
}
|
|
|
|
|
for(auto& monitor: m_monitors) {
|
|
|
|
|
monitor.maxBrightness = utils::map(value, 0, 100, 0.f, 1.f);
|
|
|
|
|
}
|
|
|
|
|
updateCurrentMonitorGUI(m_ui.monitorDropdown->currentIndex());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::setupBrightness()
|
|
|
|
|
{
|
|
|
|
|
m_ui.monitorBrightnessSlider->setDisabled(true);
|
|
|
|
|
m_ui.monitorOverallBrightnessSlider->setDisabled(true);
|
|
|
|
|
|
|
|
|
|
m_ui.monitorOverrideCheck->setChecked(false);
|
|
|
|
|
connect(m_ui.monitorOverrideCheck, &QCheckBox::stateChanged,
|
|
|
|
|
[this](int state) { m_ui.monitorBrightnessSlider->setEnabled(state == Qt::CheckState::Checked); });
|
|
|
|
|
|
|
|
|
|
m_ui.monitorOverallOverrideCheck->setChecked(false);
|
|
|
|
|
connect(m_ui.monitorOverallOverrideCheck, &QCheckBox::stateChanged,
|
|
|
|
|
[this](int state) { m_ui.monitorOverallBrightnessSlider->setEnabled(state == Qt::CheckState::Checked); });
|
|
|
|
|
|
|
|
|
|
connect(m_ui.monitorBrightnessSlider, &QSlider::valueChanged, [this](int value) {
|
|
|
|
|
m_ui.monitorBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
|
|
|
|
|
const auto newBrightness = utils::map(value, 0, 100, 0.f, 1.f);
|
|
|
|
|
qDebug(ltr("Overriding brightness with %1").arg(newBrightness));
|
|
|
|
|
m_brightness = newBrightness;
|
|
|
|
|
const auto curIdx = m_ui.monitorDropdown->currentIndex();
|
|
|
|
|
m_monitors[curIdx].brightness = newBrightness;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
m_ui.monitorOverrideCheck->setChecked(false);
|
|
|
|
|
connect(m_ui.monitorOverrideCheck, &QCheckBox::stateChanged, [this](int state) {
|
|
|
|
|
m_ui.monitorBrightnessSlider->setEnabled(state == Qt::CheckState::Checked);
|
|
|
|
|
const auto curIdx = m_ui.monitorDropdown->currentIndex();
|
|
|
|
|
m_monitors[curIdx].manualOverride = state == Qt::CheckState::Checked;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::setupOverallBrightness()
|
|
|
|
|
{
|
|
|
|
|
m_ui.monitorOverallBrightnessSlider->setDisabled(true);
|
|
|
|
|
|
|
|
|
|
connect(m_ui.monitorOverallBrightnessSlider, &QSlider::valueChanged, [this](int value) {
|
|
|
|
|
m_ui.monitorOverallBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
|
|
|
|
|
const auto newBrightness = utils::map(value, 0, 100, 0.f, 1.f);
|
|
|
|
|
qDebug(ltr("Overriding overall brightness with %1").arg(newBrightness));
|
|
|
|
|
for(auto& monitor: m_monitors) {
|
|
|
|
|
if(monitor.manualOverride) {
|
|
|
|
|
monitor.brightness = newBrightness;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
updateCurrentMonitorGUI(m_ui.monitorDropdown->currentIndex());
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
m_ui.monitorOverallOverrideCheck->setChecked(false);
|
|
|
|
|
connect(m_ui.monitorOverallOverrideCheck, &QCheckBox::stateChanged, [this](int state) {
|
|
|
|
|
m_ui.monitorOverallBrightnessSlider->setEnabled(state == Qt::CheckState::Checked);
|
|
|
|
|
for(auto& monitor: m_monitors) {
|
|
|
|
|
monitor.manualOverride = state == Qt::CheckState::Checked;
|
|
|
|
|
}
|
|
|
|
|
updateCurrentMonitorGUI(m_ui.monitorDropdown->currentIndex());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::setupSensorsTab()
|
|
|
|
|
{
|
|
|
|
|
m_ui.tabs->removeTab(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::setupTrayIcon()
|
|
|
|
|
@@ -180,26 +277,29 @@ void MainWindow::setupCallbackTimer()
|
|
|
|
|
qDebug(ltr("Callback timer started"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::resetAllMonitorSettings()
|
|
|
|
|
{
|
|
|
|
|
m_ui.monitorOverallMinBrightnessSlider->setValue(0);
|
|
|
|
|
m_ui.monitorOverallMaxBrightnessSlider->setValue(100);
|
|
|
|
|
m_ui.monitorOverallOverrideCheck->setCheckState(Qt::CheckState::Unchecked);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::updateCurrentMonitorGUI(int index)
|
|
|
|
|
{
|
|
|
|
|
const auto brightness = utils::map(m_monitors[index].brightness, 0.f, 1.f, 0, 100);
|
|
|
|
|
const auto minimum = utils::map(m_monitors[index].minBrightness, 0.f, 1.f, 0, 100);
|
|
|
|
|
const auto maximum = utils::map(m_monitors[index].maxBrightness, 0.f, 1.f, 0, 100);
|
|
|
|
|
|
|
|
|
|
m_ui.monitorMinBrightnessSlider->setValue(minimum);
|
|
|
|
|
m_ui.monitorMinBrightnessValueLabel->setText(QString("%1%").arg(minimum, 3, 10));
|
|
|
|
|
|
|
|
|
|
m_ui.monitorMaxBrightnessSlider->setValue(maximum);
|
|
|
|
|
m_ui.monitorMaxBrightnessValueLabel->setText(QString("%1%").arg(maximum, 3, 10));
|
|
|
|
|
|
|
|
|
|
m_ui.monitorBrightnessSlider->setValue(brightness);
|
|
|
|
|
m_ui.monitorBrightnessValueLabel->setText(QString("%1%").arg(brightness, 3, 10));
|
|
|
|
|
if(index == -1) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_ui.monitorMinBrightnessSlider->setValue(utils::map(m_monitors[index].minBrightness, 0.f, 1.f, 0, 100));
|
|
|
|
|
m_ui.monitorMaxBrightnessSlider->setValue(utils::map(m_monitors[index].maxBrightness, 0.f, 1.f, 0, 100));
|
|
|
|
|
m_ui.monitorBrightnessSlider->setValue(utils::map(m_monitors[index].brightness, 0.f, 1.f, 0, 100));
|
|
|
|
|
m_ui.monitorOverrideCheck->setChecked(m_monitors[index].manualOverride);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::updateState()
|
|
|
|
|
{
|
|
|
|
|
m_mtx.lock();
|
|
|
|
|
|
|
|
|
|
qDebug(ltr("Updating state"));
|
|
|
|
|
|
|
|
|
|
bool sensorError = false;
|
|
|
|
|
@@ -224,34 +324,22 @@ void MainWindow::updateState()
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const auto setAllMonitorsBrightness = [this](float& brightness) {
|
|
|
|
|
if(m_monitors.empty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
auto brightness = NAN;
|
|
|
|
|
|
|
|
|
|
bool errorOccurred = false;
|
|
|
|
|
for(auto& monitor: m_monitors) {
|
|
|
|
|
if(!monitor.driver.setBrightness(brightness)) {
|
|
|
|
|
errorOccurred = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return !errorOccurred;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if(!getAverageSensorValue(m_brightness)) {
|
|
|
|
|
if(!getAverageSensorValue(brightness)) {
|
|
|
|
|
enumSensors();
|
|
|
|
|
qInfo(ltr("At least one sensor became invalid, re-enumerating sensors found %1 valid sensor(s)").arg(m_sensors.size()));
|
|
|
|
|
sensorError = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const auto iconBrightness = utils::map(m_brightness, 0.f, 1.f, size_t{0}, size_t{8});
|
|
|
|
|
|
|
|
|
|
if(!setAllMonitorsBrightness(m_brightness)) {
|
|
|
|
|
if(!setMonitorBrightness(brightness)) {
|
|
|
|
|
enumMonitors();
|
|
|
|
|
qInfo(ltr("At least one monitor became invalid, re-enumerating monitors found %1 valid monitor(s)").arg(m_monitors.size()));
|
|
|
|
|
monitorError = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const auto iconBrightness = utils::map(brightness, 0.f, 1.f, size_t{0}, size_t{8});
|
|
|
|
|
|
|
|
|
|
if(!sensorError && !monitorError && m_trayIcon) {
|
|
|
|
|
m_trayIcon->setIcon(*m_sensorStateIcons[iconBrightness]);
|
|
|
|
|
}
|
|
|
|
|
@@ -263,10 +351,80 @@ void MainWindow::updateState()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(m_trayIcon) {
|
|
|
|
|
m_trayIcon->setToolTip(tr("AdaptiveBrightness - %1%").arg(m_brightness * 100, 0, 'f', 0));
|
|
|
|
|
m_trayIcon->setToolTip(tr("AdaptiveBrightness - %1%").arg(brightness * 100, 0, 'f', 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_ui.monitorBrightnessSlider->setValue(utils::map(m_brightness, 0.f, 1.f, 0, 100));
|
|
|
|
|
m_mtx.unlock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool MainWindow::setMonitorBrightness(float& brightness)
|
|
|
|
|
{
|
|
|
|
|
constexpr auto hysteresis = [](const auto& lowThreshold, const auto& highThreshold, const auto& currentValue, const auto& newValue) {
|
|
|
|
|
if(newValue > highThreshold || newValue < lowThreshold)
|
|
|
|
|
return newValue;
|
|
|
|
|
return currentValue;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if(m_monitors.empty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool errorOccurred = false;
|
|
|
|
|
bool allMonitorsSameBrightness = true;
|
|
|
|
|
|
|
|
|
|
for(size_t i = 0; i < m_monitors.size(); ++i) {
|
|
|
|
|
const auto updateMonitorBrightness = [&] {
|
|
|
|
|
const auto brightnessRange = m_monitors[i].maxBrightness - m_monitors[i].minBrightness;
|
|
|
|
|
const auto hysteresisDelta = m_monitors[i].manualOverride ? 0.f : m_monitors[i].HYSTERESIS_THRESHOLD * brightnessRange;
|
|
|
|
|
const auto lowThreshold = std::clamp(m_monitors[i].prevBrightness - hysteresisDelta, m_monitors[i].minBrightness, m_monitors[i].maxBrightness);
|
|
|
|
|
const auto highThreshold = std::clamp(m_monitors[i].prevBrightness + hysteresisDelta, m_monitors[i].minBrightness, m_monitors[i].maxBrightness);
|
|
|
|
|
if(hysteresis(lowThreshold, highThreshold, m_monitors[i].prevBrightness, m_monitors[i].brightness) != m_monitors[i].prevBrightness) {
|
|
|
|
|
qDebug(ltr("Setting monitor %1 brightness from %2 to %3")
|
|
|
|
|
.arg(i)
|
|
|
|
|
.arg(m_monitors[i].prevBrightness, 0, 'f', 2)
|
|
|
|
|
.arg(m_monitors[i].brightness, 0, 'f', 2));
|
|
|
|
|
m_monitors[i].prevBrightness = m_monitors[i].brightness;
|
|
|
|
|
return m_monitors[i].driver.setBrightness(m_monitors[i].brightness);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
qDebug(ltr("Hysteresis prevented setting monitor %1 brightness from %2 to %3")
|
|
|
|
|
.arg(i)
|
|
|
|
|
.arg(m_monitors[i].prevBrightness, 0, 'f', 2)
|
|
|
|
|
.arg(m_monitors[i].brightness, 0, 'f', 2));
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if(!std::isnan(brightness) && !m_monitors[i].manualOverride) {
|
|
|
|
|
m_monitors[i].brightness = brightness;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_monitors[i].brightness = std::clamp(m_monitors[i].brightness, m_monitors[i].minBrightness, m_monitors[i].maxBrightness);
|
|
|
|
|
|
|
|
|
|
if(i > 0 && m_monitors[i - 1].brightness != m_monitors[i].brightness) {
|
|
|
|
|
allMonitorsSameBrightness = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!updateMonitorBrightness()) {
|
|
|
|
|
errorOccurred = true;
|
|
|
|
|
}
|
|
|
|
|
else if(m_ui.monitorDropdown->currentIndex() == static_cast<int>(i)) {
|
|
|
|
|
updateCurrentMonitorGUI(static_cast<int>(i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!errorOccurred) {
|
|
|
|
|
auto avgBrightness = 0.f;
|
|
|
|
|
std::for_each(m_monitors.begin(), m_monitors.end(), [&avgBrightness](const auto& mon) { avgBrightness += mon.brightness; });
|
|
|
|
|
avgBrightness /= m_monitors.size();
|
|
|
|
|
brightness = avgBrightness;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(allMonitorsSameBrightness) {
|
|
|
|
|
m_ui.monitorOverallBrightnessSlider->setValue(utils::map(brightness, 0.f, 1.f, 0, 100));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return !errorOccurred;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::trayIconClicked(QSystemTrayIcon::ActivationReason reason)
|
|
|
|
|
|