File indexing completed on 2022-10-04 13:46:48

0001 /*
0002     SPDX-FileCopyrightText: 2010 Etienne Rebetez <etienne.rebetez@oberwallis.ch>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "kalziumelementproperty.h"
0008 
0009 #include "kalziumdataobject.h"
0010 #include "search.h"
0011 
0012 #include <KLocalizedString>
0013 
0014 #include <prefs.h>
0015 
0016 KalziumElementProperty *KalziumElementProperty::instance()
0017 {
0018     static KalziumElementProperty elementProperty;
0019     return &elementProperty;
0020 }
0021 
0022 KalziumElementProperty::KalziumElementProperty()
0023     : m_mode(0)
0024 {
0025     m_currentScheme = Prefs::colorschemebox();
0026 
0027     if (schemeList().count() <= m_currentScheme)
0028         m_currentScheme = 0;
0029 
0030     m_currentGradient = Prefs::colorgradientbox();
0031 
0032     if (isGradient())
0033         m_mode = GRADIENTVALUE;
0034 }
0035 
0036 KalziumElementProperty::~KalziumElementProperty() = default;
0037 
0038 bool KalziumElementProperty::isGradient()
0039 {
0040     return m_currentGradient > 1;
0041 }
0042 
0043 void KalziumElementProperty::setScheme(int newScheme)
0044 {
0045     m_currentScheme = newScheme;
0046     Prefs::setColorschemebox(newScheme);
0047     Prefs::self()->save();
0048     propertyChanged();
0049 }
0050 
0051 void KalziumElementProperty::setGradient(int newGradient)
0052 {
0053     m_currentGradient = newGradient;
0054     Prefs::setColorgradientbox(newGradient);
0055     Prefs::self()->save();
0056 
0057     if (isGradient()) {
0058         m_mode = GRADIENTVALUE;
0059     } else {
0060         m_mode = NORMAL;
0061     }
0062 
0063     propertyChanged();
0064 }
0065 
0066 QStringList KalziumElementProperty::schemeList() const
0067 {
0068     return KalziumSchemeTypeFactory::instance()->schemes();
0069 }
0070 
0071 QStringList KalziumElementProperty::gradientList() const
0072 {
0073     QStringList customList;
0074     customList << i18nc("No Gradient", "None");
0075     customList << KalziumGradientTypeFactory::instance()->gradients();
0076     return customList;
0077 }
0078 
0079 KalziumSchemeType *KalziumElementProperty::scheme() const
0080 {
0081     return KalziumSchemeTypeFactory::instance()->build(m_currentScheme);
0082 }
0083 
0084 KalziumGradientType *KalziumElementProperty::gradient() const
0085 {
0086     if (m_currentGradient == NOGRADIENT) {
0087         return KalziumGradientTypeFactory::instance()->build(NOGRADIENT);
0088     }
0089     return KalziumGradientTypeFactory::instance()->build(m_currentGradient - 1);
0090 }
0091 
0092 int KalziumElementProperty::gradientId() const
0093 {
0094     return m_currentGradient;
0095 }
0096 
0097 int KalziumElementProperty::schemeId() const
0098 {
0099     return m_currentScheme;
0100 }
0101 
0102 void KalziumElementProperty::setSliderValue(double slide)
0103 {
0104     m_slider = slide;
0105     propertyChanged();
0106 }
0107 
0108 double KalziumElementProperty::getValue(int el) const
0109 {
0110     if (m_currentGradient != NOGRADIENT)
0111         return gradient()->value(el);
0112 
0113     return 0;
0114 }
0115 
0116 QColor KalziumElementProperty::getElementColor(int el)
0117 {
0118     if (m_currentGradient == NOGRADIENT)
0119         return scheme()->elementBrush(el).color();
0120 
0121     return gradientBrushLogic(el);
0122 }
0123 
0124 QBrush KalziumElementProperty::getElementBrush(int el)
0125 {
0126     QBrush elementBrush;
0127     elementBrush.setStyle(Qt::SolidPattern);
0128     elementBrush.setColor(Qt::transparent);
0129 
0130     // Hide filtered elements from search
0131     if (!KalziumDataObject::instance()->search()->matches(el) && KalziumDataObject::instance()->search()->isActive()) {
0132         return {Qt::darkGray, Qt::Dense7Pattern};
0133     }
0134 
0135     // The iconic view is the 3rd view (0,1,2,...). Pixmaps don't make nice gradients.
0136     if (m_currentScheme == 2) {
0137         elementBrush = scheme()->elementBrush(el);
0138     } else {
0139         // add a nice gradient
0140         QColor color = getElementColor(el);
0141         QLinearGradient grad(QPointF(0, 0), QPointF(0, 40));
0142         grad.setColorAt(0, color);
0143 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0144         qreal h, s, v, a;
0145 #else
0146         float h, s, v, a;
0147 #endif
0148         color.getHsvF(&h, &s, &v, &a);
0149         color.setHsvF(h, s, v * 0.7, a);
0150         grad.setColorAt(1, color);
0151 
0152         elementBrush = QBrush(grad);
0153     }
0154 
0155     return elementBrush;
0156 }
0157 
0158 QColor KalziumElementProperty::getTextColor(int el) const
0159 {
0160     return scheme()->textColor(el);
0161 }
0162 
0163 QColor KalziumElementProperty::getBorderColor(int el) const
0164 {
0165     // Show scheme color as border when gradients are selected.
0166     if (m_currentGradient != NOGRADIENT) {
0167         return scheme()->elementBrush(el).color();
0168     }
0169 
0170     // Transparent Borders don't make sens.
0171     if (getTextColor(el) == QColor(Qt::transparent)) {
0172         return {Qt::black};
0173     }
0174 
0175     return getTextColor(el);
0176 }
0177 
0178 int KalziumElementProperty::getMode() const
0179 {
0180     return m_mode;
0181 }
0182 
0183 QColor KalziumElementProperty::gradientBrushLogic(int el) const
0184 {
0185     QColor gradientColor;
0186     bool isActiv = true;
0187     const double gradientValue = gradient()->value(el);
0188     const double melting = KalziumDataObject::instance()->element(el)->dataAsVariant(ChemicalDataObject::meltingpoint).toDouble();
0189     const double boiling = KalziumDataObject::instance()->element(el)->dataAsVariant(ChemicalDataObject::boilingpoint).toDouble();
0190 
0191     switch (m_currentGradient) {
0192     case SOMGradientType:
0193         if (m_slider < melting) {
0194             // the element is solid
0195             gradientColor = Prefs::color_solid();
0196         } else if ((m_slider > melting) && (m_slider < boiling)) {
0197             // the element is liquid
0198             gradientColor = Prefs::color_liquid();
0199         } else if ((m_slider >= boiling) && (boiling > 0.0)) {
0200             // the element is vaporous
0201             gradientColor = Prefs::color_vapor();
0202         } else {
0203             gradientColor = Qt::lightGray;
0204         }
0205         return gradientColor;
0206 
0207     case DISCOVERYDATE:
0208         if (gradientValue > m_slider) {
0209             isActiv = false;
0210         }
0211         break;
0212 
0213     default: // All other gradients
0214         if (gradientValue < m_slider) {
0215             isActiv = false;
0216         }
0217         break;
0218     }
0219 
0220     if (!isActiv && gradientValue != -1) { // FIXME No magic number... Defined in KalziumGradientFactory
0221         gradientColor = Qt::transparent;
0222     } else {
0223         const double coeff = gradient()->elementCoeff(el);
0224         gradientColor = gradient()->calculateColor(coeff);
0225     }
0226     return gradientColor;
0227 }