/* * Copyright (c) 2014, 2015 Christian Surlykke, Paulo Lieuthier * * This file is part of the LXQt project. * It is distributed under the LGPL 2.1 or later license. * Please refer to the LICENSE file for a copy of the license. */ #include "iconproducer.h" #include #include #include #include #include #include IconProducer::IconProducer(Solid::Battery *battery, QObject *parent) : QObject(parent) { connect(battery, &Solid::Battery::chargeStateChanged, this, &IconProducer::updateState); connect(battery, &Solid::Battery::chargePercentChanged, this, &IconProducer::updateChargePercent); connect(&mSettings, SIGNAL(settingsChanged()), this, SLOT(update())); mChargePercent = battery->chargePercent(); mState = battery->chargeState(); themeChanged(); } IconProducer::IconProducer(QObject *parent): QObject(parent) { themeChanged(); update(); } void IconProducer::updateChargePercent(int newChargePercent) { mChargePercent = newChargePercent; update(); } void IconProducer::updateState(int newState) { mState = (Solid::Battery::ChargeState) newState; update(); } void IconProducer::update() { QString newIconName; if (mSettings.isUseThemeIcons()) { QMap *levelNameMap = (mState == Solid::Battery::Discharging ? &mLevelNameMapDischarging : &mLevelNameMapCharging); foreach (float level, levelNameMap->keys()) { if (level >= mChargePercent) { newIconName = levelNameMap->value(level); break; } } } if (mSettings.isUseThemeIcons() && newIconName == mIconName) return; mIconName = newIconName; mIcon = mSettings.isUseThemeIcons() ? QIcon::fromTheme(mIconName) : 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: // Use 'battery-low' for levels up to 10 // - 'battery-caution' for levels between 10 and 20 // - 'battery-040' for levels between 20 and 40, etc.. mLevelNameMapDischarging[10] = "battery-low"; mLevelNameMapDischarging[20] = "battery-caution"; mLevelNameMapDischarging[40] = "battery-040"; 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) (mChargePercent + 0.49); if (!cache[mState].contains(chargeLevelAsInt)) cache[mState][chargeLevelAsInt] = buildCircleIcon(mState, mChargePercent); return cache[mState][chargeLevelAsInt]; } QIcon IconProducer::buildCircleIcon(Solid::Battery::ChargeState state, int 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) chargeLevel = 99; double angle; QString sweepFlag; if (state == Solid::Battery::Discharging) { angle = M_PI_2 + 2 * M_PI * chargeLevel/100; sweepFlag = "0"; } else { angle = M_PI_2 - 2 *M_PI * chargeLevel/100; sweepFlag = "1"; } double circle_endpoint_x = 80.0 * cos(angle) + 100; double circle_endpoint_y = -80.0 * sin(angle) + 100; QString largeArgFlag = chargeLevel > 50 ? "1" : "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 Solid::Battery::FullyCharged: svg.replace("STATE_MARKER", filledCircle); break; case Solid::Battery::Charging: svg.replace("STATE_MARKER", plus); break; case Solid::Battery::Discharging: svg.replace("STATE_MARKER", minus); break; default: svg.replace("STATE_MARKER", hollowCircle); } if (state != Solid::Battery::FullyCharged && state != Solid::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.0)); } 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); }