#include "iconproducer.h" #include #include #include #include #include #include IconProducer::IconProducer(Battery *battery, QObject *parent) : QObject(parent) { connect(battery, SIGNAL(chargeStateChange(float,Battery::State)), this, SLOT(update(float,Battery::State))); connect(&mSettings, SIGNAL(settingsChanged()), this, SLOT(update())); mChargeLevel = battery->chargeLevel; mState = battery->state; themeChanged(); } IconProducer::IconProducer(QObject *parent): QObject(parent) { themeChanged(); update(); } void IconProducer::update(float newChargeLevel, Battery::State newState) { mChargeLevel = newChargeLevel; mState = newState; update(); } void IconProducer::update() { QString newIconName; if (mSettings.isUseThemeIcons()) { QMap *levelNameMap = (mState == Battery::Discharging ? &mLevelNameMapDischarging : &mLevelNameMapCharging); foreach (float level, levelNameMap->keys()) { if (level >= mChargeLevel) { newIconName = levelNameMap->value(level); break; } } } if (mSettings.isUseThemeIcons() && newIconName == mIconName) { return; } mIconName = newIconName; if (mSettings.isUseThemeIcons()) { mIcon = QIcon::fromTheme(mIconName); } else { mIcon = circleIcon(); } emit iconChanged(); } void IconProducer::themeChanged() { /* * We maintain specific charge-level-to-icon-name mappings for Oxygen and Awoken and * asume all other themes adhere to the freedesktop standard. * This is certainly not true, and as bug reports come in stating that * this and that theme is not working we will probably have to add new * mappings beside Oxygen and Awoken */ mLevelNameMapDischarging.clear(); mLevelNameMapCharging.clear(); if (QIcon::themeName() == "oxygen") { // Means: mLevelNameMapDischarging[10] = "battery-low"; // Use 'battery-low' for levels up to 10 mLevelNameMapDischarging[20] = "battery-caution"; // - 'battery-caution' for levels between 10 and 20 mLevelNameMapDischarging[40] = "battery-040"; // - 'battery-040' for levels between 20 and 40, etc.. mLevelNameMapDischarging[60] = "battery-060"; mLevelNameMapDischarging[80] = "battery-080"; mLevelNameMapDischarging[101] = "battery-100"; mLevelNameMapCharging[10] = "battery-charging-low"; mLevelNameMapCharging[20] = "battery-charging-caution"; mLevelNameMapCharging[40] = "battery-charging-040"; mLevelNameMapCharging[60] = "battery-charging-060"; mLevelNameMapCharging[80] = "battery-charging-080"; mLevelNameMapCharging[101] = "battery-charging"; } else if (QIcon::themeName().startsWith("AwOken")) // AwOken, AwOkenWhite, AwOkenDark { mLevelNameMapDischarging[5] = "battery-000"; mLevelNameMapDischarging[30] = "battery-020"; mLevelNameMapDischarging[50] = "battery-040"; mLevelNameMapDischarging[70] = "battery-060"; mLevelNameMapDischarging[95] = "battery-080"; mLevelNameMapDischarging[101] = "battery-100"; mLevelNameMapCharging[5] = "battery-000-charging"; mLevelNameMapCharging[30] = "battery-020-charging"; mLevelNameMapCharging[50] = "battery-040-charging"; mLevelNameMapCharging[70] = "battery-060-charging"; mLevelNameMapCharging[95] = "battery-080-charging"; mLevelNameMapCharging[101] = "battery-100-charging"; } else // As default we fall back to the freedesktop scheme. { mLevelNameMapDischarging[3] = "battery-empty"; mLevelNameMapDischarging[10] = "battery-caution"; mLevelNameMapDischarging[50] = "battery-low"; mLevelNameMapDischarging[90] = "battery-good"; mLevelNameMapDischarging[101] = "battery-full"; mLevelNameMapCharging[3] = "battery-empty"; mLevelNameMapCharging[10] = "battery-caution-charging"; mLevelNameMapCharging[50] = "battery-low-charging"; mLevelNameMapCharging[90] = "battery-good-charging"; mLevelNameMapCharging[101] = "battery-full-charging"; } update(); } QIcon& IconProducer::circleIcon() { static QMap > cache; int chargeLevelAsInt = (int) (mChargeLevel + 0.49); if (! cache[mState].contains(chargeLevelAsInt)) { cache[mState][chargeLevelAsInt] = buildCircleIcon(mState, mChargeLevel); } return cache[mState][chargeLevelAsInt]; } QIcon IconProducer::buildCircleIcon(Battery::State state, double chargeLevel) { static QString svg_template = "\n" "\n" "\n" " \n" " \n" " \n" " \n" "\n" "\n" "\n" "\n" "\n" "\n" " STATE_MARKER\n" "\n" ""; static QString filledCircle = ""; static QString plus = ""; static QString minus = ""; static QString hollowCircle = ""; QString svg = svg_template; if (chargeLevel > 99.9) { chargeLevel = 99.9; } double angle = M_PI_2 + 2*M_PI*chargeLevel/100; double circle_endpoint_x = 80.0*cos(angle) + 100; double circle_endpoint_y = -80.0*sin(angle) + 100; QString largeArgFlag = chargeLevel > 50 ? "1" : "0"; QString sweepFlag = "0"; svg.replace(QString("END_X"), QString::number(circle_endpoint_x)); svg.replace(QString("END_Y"), QString::number(circle_endpoint_y)); svg.replace(QString("LARGE_ARC_FLAG"), largeArgFlag); svg.replace(QString("SWEEP_FLAG"), sweepFlag); switch (state) { case Battery::FullyCharged: svg.replace("STATE_MARKER", filledCircle); break; case Battery::Charging: svg.replace("STATE_MARKER", plus); break; case Battery::Discharging: svg.replace("STATE_MARKER", minus); break; default: svg.replace("STATE_MARKER", hollowCircle); } if (state != Battery::FullyCharged && state != Battery::Charging && chargeLevel < mSettings.getPowerLowLevel() + 30) { if (chargeLevel <= mSettings.getPowerLowLevel() + 10) { svg.replace("RED_OPACITY", "1"); } else { svg.replace("RED_OPACITY", QString::number((mSettings.getPowerLowLevel() + 30 - chargeLevel)/20)); } } else { svg.replace("RED_OPACITY", "0"); } qDebug() << svg; // Paint the svg on a pixmap and create an icon from that. QSvgRenderer render(svg.toLatin1()); QPixmap pixmap(render.defaultSize()); pixmap.fill(QColor(0,0,0,0)); QPainter painter(&pixmap); render.render(&painter); return QIcon(pixmap); }