File indexing completed on 2024-04-28 05:36:15

0001 /*
0002  *   SPDX-FileCopyrightText: 2014 Nikita Skovoroda <chalkerx@gmail.com>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "powerdevilbrightnesslogic.h"
0008 
0009 #include <QDebug>
0010 
0011 namespace PowerDevil
0012 {
0013 BrightnessLogic::BrightnessLogic()
0014 {
0015 }
0016 
0017 void BrightnessLogic::setValue(int value)
0018 {
0019     m_value = value;
0020 }
0021 
0022 void BrightnessLogic::setValueMax(int valueMax)
0023 {
0024     if (valueMax != m_valueMax) {
0025         m_valueMax = valueMax;
0026         m_steps = calculateSteps(valueMax);
0027     }
0028 }
0029 
0030 void BrightnessLogic::setValueBeforeTogglingOff(int valueBeforeTogglingOff)
0031 {
0032     m_valueBeforeTogglingOff = valueBeforeTogglingOff;
0033 }
0034 
0035 int BrightnessLogic::action(BrightnessKeyType type) const
0036 {
0037     switch (type) {
0038     case Increase:
0039         return increased();
0040     case Decrease:
0041         return decreased();
0042     case Toggle:
0043         return toggled();
0044     case IncreaseSmall:
0045         return increasedSmall();
0046     case DecreaseSmall:
0047         return decreasedSmall();
0048     }
0049 
0050     return -1; // We shouldn't get here
0051 }
0052 
0053 int BrightnessLogic::increased() const
0054 {
0055     if (m_value == m_valueMax) {
0056         return m_valueMax; // we are at the maximum already
0057     }
0058 
0059     // Add 1 and round upwards to the nearest step
0060     int step = m_steps - (m_valueMax - m_value - 1) * m_steps / m_valueMax;
0061 
0062     if (m_valueMax > 100 && qRound(percentage(stepToValue(step))) <= qRound(percentage(m_value))) {
0063         // When no visible change was made, add 1 step.
0064         // This can happen only if valueMax > 100, else 1 >= 1%.
0065         step++;
0066     }
0067 
0068     return stepToValue(step);
0069 }
0070 
0071 int BrightnessLogic::increasedSmall() const
0072 {
0073     const double newPercent = (std::round(m_value * 100 / double(m_valueMax)) + 1) / 100.0;
0074     return std::min<int>(m_valueMax, std::round(m_valueMax * newPercent));
0075 }
0076 
0077 int BrightnessLogic::decreased() const
0078 {
0079     if (m_value == valueMin()) {
0080         return valueMin(); // we are at the minimum already
0081     }
0082 
0083     // Subtract 1 and round downwards to the nearest Step
0084     int step = (m_value - 1) * m_steps / m_valueMax;
0085 
0086     if (m_valueMax > 100 && qRound(percentage(stepToValue(step))) >= qRound(percentage(m_value))) {
0087         // When no visible change was made, subtract 1 step.
0088         // This can happen only if valueMax > 100, else 1 >= 1%.
0089         step--;
0090     }
0091 
0092     return stepToValue(step);
0093 }
0094 
0095 int BrightnessLogic::decreasedSmall() const
0096 {
0097     const double newPercent = (std::round(m_value * 100 / double(m_valueMax)) - 1) / 100.0;
0098     return std::max<int>(valueMin(), std::round(m_valueMax * newPercent));
0099 }
0100 
0101 int BrightnessLogic::toggled() const
0102 {
0103     if (m_value > 0) {
0104         return 0; // currently on: toggle off
0105     } else if (m_valueBeforeTogglingOff > 0) {
0106         return m_valueBeforeTogglingOff; // currently off and was on before toggling: restore
0107     } else {
0108         return m_valueMax; // currently off and would stay off if restoring: toggle to max
0109     }
0110 }
0111 
0112 int BrightnessLogic::steps() const
0113 {
0114     return m_steps;
0115 }
0116 
0117 float BrightnessLogic::percentage(int value) const
0118 {
0119     return value * 100.0 / m_valueMax;
0120 }
0121 
0122 const BrightnessLogic::BrightnessInfo BrightnessLogic::info() const
0123 {
0124     return BrightnessInfo{m_value, m_valueMax, m_valueBeforeTogglingOff, m_steps};
0125 }
0126 
0127 int BrightnessLogic::stepToValue(int step) const
0128 {
0129     return qBound(valueMin(), qRound(step * 1.0 * m_valueMax / m_steps), m_valueMax);
0130 }
0131 
0132 }