From 3dc72d62527c76c01bb38b49d5450461792fdd67 Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Mon, 29 Jan 2024 16:15:00 +1000 Subject: [PATCH] Use opaque colors Alpha blending is expensive. Reducing alpha blending by using opaque colors reduces GPU work, and thus `swap` time. --- components/AsymmetricRoundedRectangle.qml | 57 ++++++++++++----------- components/BarGaugeBase.qml | 4 +- components/CircularMultiGauge.qml | 8 ++-- components/CircularSingleGauge.qml | 4 +- components/SegmentedButtonRow.qml | 6 ++- components/SideGauge.qml | 4 +- components/SideMultiGauge.qml | 4 +- components/TankGauge.qml | 6 ++- components/ThreePhaseBarGauge.qml | 4 +- components/ThreePhaseDisplay.qml | 2 + components/widgets/BatteryWidget.qml | 7 ++- themes/color/ColorDesign.json | 13 +----- themes/color/Dark.json | 12 +++++ themes/color/Light.json | 18 +++++-- tools/themeparser.py | 39 ++++++++-------- 15 files changed, 109 insertions(+), 79 deletions(-) diff --git a/components/AsymmetricRoundedRectangle.qml b/components/AsymmetricRoundedRectangle.qml index 3a6af1b3e..3306015f8 100644 --- a/components/AsymmetricRoundedRectangle.qml +++ b/components/AsymmetricRoundedRectangle.qml @@ -18,34 +18,7 @@ Item { property alias border: roundedRect.border // we have to draw each element separately as any of the colors may have transparency... - - Rectangle { - id: topBorderRect - anchors { - fill: parent - bottomMargin: root.height - root.border.width - leftMargin: root.roundedSide === VenusOS.AsymmetricRoundedRectangle_RoundedSide_Left ? root.radius : 0 - rightMargin: root.roundedSide === VenusOS.AsymmetricRoundedRectangle_RoundedSide_Right ? root.radius : 0 - } - - visible: root.roundedSide !== VenusOS.AsymmetricRoundedRectangle_RoundedSide_All - - color: roundedRect.border.color - } - - Rectangle { - id: bottomBorderRect - anchors { - fill: parent - topMargin: root.height - root.border.width - leftMargin: root.roundedSide === VenusOS.AsymmetricRoundedRectangle_RoundedSide_Left ? root.radius : 0 - rightMargin: root.roundedSide === VenusOS.AsymmetricRoundedRectangle_RoundedSide_Right ? root.radius : 0 - } - - visible: root.roundedSide !== VenusOS.AsymmetricRoundedRectangle_RoundedSide_All - - color: roundedRect.border.color - } + // the order matters, because any of the colors may be fully opaque... Rectangle { id: backgroundRect @@ -90,4 +63,32 @@ Item { border.color: Theme.color_ok } } + + Rectangle { + id: topBorderRect + anchors { + fill: parent + bottomMargin: root.height - root.border.width + leftMargin: root.roundedSide === VenusOS.AsymmetricRoundedRectangle_RoundedSide_Left ? root.radius : 0 + rightMargin: root.roundedSide === VenusOS.AsymmetricRoundedRectangle_RoundedSide_Right ? root.radius : 0 + } + + visible: root.roundedSide !== VenusOS.AsymmetricRoundedRectangle_RoundedSide_All + + color: roundedRect.border.color + } + + Rectangle { + id: bottomBorderRect + anchors { + fill: parent + topMargin: root.height - root.border.width + leftMargin: root.roundedSide === VenusOS.AsymmetricRoundedRectangle_RoundedSide_Left ? root.radius : 0 + rightMargin: root.roundedSide === VenusOS.AsymmetricRoundedRectangle_RoundedSide_Right ? root.radius : 0 + } + + visible: root.roundedSide !== VenusOS.AsymmetricRoundedRectangle_RoundedSide_All + + color: roundedRect.border.color + } } diff --git a/components/BarGaugeBase.qml b/components/BarGaugeBase.qml index 744eed6b4..2b60f3bf0 100644 --- a/components/BarGaugeBase.qml +++ b/components/BarGaugeBase.qml @@ -13,8 +13,8 @@ Rectangle { property int valueType: VenusOS.Gauges_ValueType_NeutralPercentage readonly property int valueStatus: Gauges.getValueStatus(_value * 100, valueType) property alias foregroundParent: fgRect.parent - property color foregroundColor: Theme.statusColorValue(valueStatus) - property color backgroundColor: Theme.statusColorValue(valueStatus, true) + property color foregroundColor: Theme.color_darkOk,Theme.statusColorValue(valueStatus) + property color backgroundColor: Theme.color_darkOk,Theme.statusColorValue(valueStatus, true) property color surfaceColor: Theme.color_levelsPage_gauge_separatorBarColor property real value: 0.0 property int orientation: Qt.Vertical diff --git a/components/CircularMultiGauge.qml b/components/CircularMultiGauge.qml index 44da851d5..3ae1f19e0 100644 --- a/components/CircularMultiGauge.qml +++ b/components/CircularMultiGauge.qml @@ -52,8 +52,8 @@ Item { startAngle: 0 endAngle: 270 value: loader.value - progressColor: Theme.statusColorValue(loader.gaugeStatus) - remainderColor: Theme.statusColorValue(loader.gaugeStatus, true) + progressColor: Theme.color_darkOk,Theme.statusColorValue(loader.gaugeStatus) + remainderColor: Theme.color_darkOk,Theme.statusColorValue(loader.gaugeStatus, true) strokeWidth: gauges.strokeWidth animationEnabled: gauges.animationEnabled shineAnimationEnabled: Global.batteries.system.mode === VenusOS.Battery_Mode_Charging @@ -67,8 +67,8 @@ Item { startAngle: 0 endAngle: 270 value: loader.value - progressColor: Theme.statusColorValue(loader.gaugeStatus) - remainderColor: Theme.statusColorValue(loader.gaugeStatus, true) + progressColor: Theme.color_darkOk,Theme.statusColorValue(loader.gaugeStatus) + remainderColor: Theme.color_darkOk,Theme.statusColorValue(loader.gaugeStatus, true) strokeWidth: gauges.strokeWidth animationEnabled: gauges.animationEnabled } diff --git a/components/CircularSingleGauge.qml b/components/CircularSingleGauge.qml index f91869214..5f006f3d1 100644 --- a/components/CircularSingleGauge.qml +++ b/components/CircularSingleGauge.qml @@ -41,8 +41,8 @@ Item { radius: width/2 startAngle: 0 endAngle: 359 // "Note that a single PathArc cannot be used to specify a circle." - progressColor: Theme.statusColorValue(gauges.status) - remainderColor: Theme.statusColorValue(gauges.status, true) + progressColor: Theme.color_darkOk,Theme.statusColorValue(gauges.status) + remainderColor: Theme.color_darkOk,Theme.statusColorValue(gauges.status, true) strokeWidth: Theme.geometry_circularSingularGauge_strokeWidth } } diff --git a/components/SegmentedButtonRow.qml b/components/SegmentedButtonRow.qml index 63121afc3..5915d2471 100644 --- a/components/SegmentedButtonRow.qml +++ b/components/SegmentedButtonRow.qml @@ -14,6 +14,7 @@ Item { property int fontPixelSize: Theme.font_size_body3 property alias model: buttonRepeater.model property int currentIndex + property bool flat signal buttonClicked(buttonIndex: int) @@ -38,15 +39,16 @@ Item { delegate: AsymmetricRoundedRectangle { id: buttonDelegate + flat: root.flat width: root.width / buttonRepeater.count height: parent ? parent.height : 0 color: modelData.enabled === false && model.index !== root.currentIndex ? Theme.color_background_disabled - : (mouseArea.pressed || model.index === root.currentIndex + : ((mouseArea.pressed || model.index === root.currentIndex) ? Theme.color_ok : Theme.color_darkOk) border.width: Theme.geometry_button_border_width - border.color: modelData.enabled === false && model.index !== root.currentIndex ? color : Theme.color_ok + border.color: (modelData.enabled === false && model.index !== root.currentIndex) ? buttonDelegate.color : Theme.color_ok radius: Theme.geometry_button_radius roundedSide: model.index === 0 ? VenusOS.AsymmetricRoundedRectangle_RoundedSide_Left diff --git a/components/SideGauge.qml b/components/SideGauge.qml index 4dc84079f..5cfeb5c28 100644 --- a/components/SideGauge.qml +++ b/components/SideGauge.qml @@ -19,8 +19,8 @@ ArcGauge { radius: Theme.geometry_briefPage_edgeGauge_radius useLargeArc: false strokeWidth: Theme.geometry_arc_strokeWidth - progressColor: Theme.statusColorValue(valueStatus) - remainderColor: Theme.statusColorValue(valueStatus, true) + progressColor: Theme.color_darkOk,Theme.statusColorValue(valueStatus) + remainderColor: Theme.color_darkOk,Theme.statusColorValue(valueStatus, true) arcHorizontalCenterOffset: (horizontalAlignment & Qt.AlignLeft) ? -(width - (2 * radius)) / 2 : (horizontalAlignment & Qt.AlignRight) ? (width - (2 * radius)) / 2 : 0 diff --git a/components/SideMultiGauge.qml b/components/SideMultiGauge.qml index fb528e5da..86d7d6211 100644 --- a/components/SideMultiGauge.qml +++ b/components/SideMultiGauge.qml @@ -63,8 +63,8 @@ Item { // If showing multiple gauges on the right edge, shift them towards the left - (gaugeRepeater.count === 1 || root.horizontalAlignment === Qt.AlignLeft ? 0 : (strokeWidth * gaugeRepeater.count)) valueType: root.valueType - progressColor: feedingToGrid ? Theme.color_green : Theme.statusColorValue(valueStatus) - remainderColor: feedingToGrid ? Theme.color_darkGreen : Theme.statusColorValue(valueStatus, true) + progressColor: Theme.color_darkOk,feedingToGrid ? Theme.color_green : Theme.statusColorValue(valueStatus) + remainderColor: Theme.color_darkOk,feedingToGrid ? Theme.color_darkGreen : Theme.statusColorValue(valueStatus, true) direction: root.direction startAngle: root.startAngle endAngle: root.endAngle diff --git a/components/TankGauge.qml b/components/TankGauge.qml index ff891b884..74c88a1f9 100644 --- a/components/TankGauge.qml +++ b/components/TankGauge.qml @@ -13,8 +13,12 @@ ClippingBarGauge { property bool isGrouped: false property bool expanded - radius: Theme.geometry_levelsPage_tankGauge_radius + readonly property int _gaugeStatus: Gauges.getValueStatus(value * 100, gaugeValueType) + + backgroundColor: Theme.color_darkOk,Theme.statusColorValue(root._gaugeStatus, true) + foregroundColor: Theme.color_darkOk,Theme.statusColorValue(root._gaugeStatus) surfaceColor: Theme.color_levelsPage_gauge_separatorBarColor + radius: Theme.geometry_levelsPage_tankGauge_radius Rectangle { width: parent.width diff --git a/components/ThreePhaseBarGauge.qml b/components/ThreePhaseBarGauge.qml index ac043cdde..af294f74c 100644 --- a/components/ThreePhaseBarGauge.qml +++ b/components/ThreePhaseBarGauge.qml @@ -55,8 +55,8 @@ Flow { anchors.right: parent.right width: parent.width - (phaseLabel.visible ? phaseLabel.width : 0) height: parent.height - foregroundColor: feedingToGrid ? Theme.color_green : Theme.statusColorValue(valueStatus) - backgroundColor: feedingToGrid ? Theme.color_darkGreen : Theme.statusColorValue(valueStatus, true) + foregroundColor: Theme.color_darkOk,feedingToGrid ? Theme.color_green : Theme.statusColorValue(valueStatus) + backgroundColor: Theme.color_darkOk,feedingToGrid ? Theme.color_darkGreen : Theme.statusColorValue(valueStatus, true) valueType: root.valueType value: valueRange.valueAsRatio orientation: root.orientation diff --git a/components/ThreePhaseDisplay.qml b/components/ThreePhaseDisplay.qml index 8c41d4f68..69353c027 100644 --- a/components/ThreePhaseDisplay.qml +++ b/components/ThreePhaseDisplay.qml @@ -45,6 +45,8 @@ Flow { const valueStatus = root.phaseModelProperty ? Gauges.getValueStatus(valueRange.valueAsRatio * 100, root.valueType) : Theme.Ok + + Theme.color_darkOk // force capture since Theme.statusColorValue() doesn't. return (valueStatus === Theme.Critical || valueStatus === Theme.Warning) ? Theme.statusColorValue(valueStatus) : Theme.color_font_primary diff --git a/components/widgets/BatteryWidget.qml b/components/widgets/BatteryWidget.qml index 1a3cac561..2eb4d6a3e 100644 --- a/components/widgets/BatteryWidget.qml +++ b/components/widgets/BatteryWidget.qml @@ -53,6 +53,7 @@ OverviewWidget { quantityLabel.value: batteryData.stateOfCharge quantityLabel.unit: VenusOS.Units_Percentage + quantityLabel.unitColor: Theme.color_overviewPage_widget_battery_units_color color: "transparent" @@ -132,6 +133,7 @@ OverviewWidget { value: Global.systemSettings.convertFromCelsius(batteryData.temperature) unit: Global.systemSettings.temperatureUnit + unitColor: Theme.color_overviewPage_widget_battery_units_color font.pixelSize: Theme.font_size_body2 alignment: Qt.AlignRight } @@ -150,7 +152,7 @@ OverviewWidget { font.pixelSize: Theme.font_size_body1 width: parent.width elide: Text.ElideRight - color: Theme.color_font_secondary + color: Theme.color_overviewPage_widget_battery_units_color } Label { text: Global.batteries.timeToGoText(Global.batteries.system, VenusOS.Battery_TimeToGo_ShortFormat) @@ -174,6 +176,7 @@ OverviewWidget { value: batteryData.voltage unit: VenusOS.Units_Volt_DC font.pixelSize: root._useSmallFont ? Theme.font_size_body1 : Theme.font_size_body2 + unitColor: Theme.color_overviewPage_widget_battery_units_color alignment: Qt.AlignLeft }, @@ -188,6 +191,7 @@ OverviewWidget { value: batteryData.current unit: VenusOS.Units_Amp font.pixelSize: root._useSmallFont ? Theme.font_size_body1 : Theme.font_size_body2 + unitColor: Theme.color_overviewPage_widget_battery_units_color }, QuantityLabel { @@ -202,6 +206,7 @@ OverviewWidget { value: batteryData.power unit: VenusOS.Units_Watt font.pixelSize: root._useSmallFont ? Theme.font_size_body1 : Theme.font_size_body2 + unitColor: Theme.color_overviewPage_widget_battery_units_color alignment: Qt.AlignRight } ] diff --git a/themes/color/ColorDesign.json b/themes/color/ColorDesign.json index abe627986..682c00217 100644 --- a/themes/color/ColorDesign.json +++ b/themes/color/ColorDesign.json @@ -1,20 +1,11 @@ { "color_blue": "#387DC5", - "color_dimBlue": "#B3387DC5", - "color_darkBlue": "#4D387DC5", "color_orange": "#F0962E", - "color_darkOrange": "#4DF0962E", "color_green": "#72B84C", - "color_dimGreen": "#B372B84C", - "color_darkGreen": "#4D72B84C", "color_red": "#F35C58", - "color_dimRed": "#B3F35C58", - "color_darkRed": "#4DF35C58", "color_black": "#000000", "color_gray1": "#141414", "color_gray2": "#272622", - "color_dimGray2": "#99272622", - "color_darkGray2": "#4D272622", "color_gray3": "#504F4B", "color_gray4": "#64635F", "color_gray5": "#969591", @@ -23,8 +14,8 @@ "color_gray8": "#F0EFEB", "color_gray9": "#FAF9F5", "color_white": "#FFFFFF", - "color_dimWhite": "#99FFFFFF", - "color_darkWhite": "#4DFFFFFF", + "color_dimWhite": "#969591", + "color_darkWhite": "#64635F", "color_fuel": "#B0C62B", "color_oil": "#A3755C", "color_gasoline": "#DFBC3E", diff --git a/themes/color/Dark.json b/themes/color/Dark.json index dcb38fa1a..bded36d89 100644 --- a/themes/color/Dark.json +++ b/themes/color/Dark.json @@ -6,6 +6,17 @@ "color_humidity2": "#405A25", "color_humidity3": "#784B17", + "color_dimBlue": "#15304A", + "color_dimOrange": "#593912", + "color_dimRed": "#592220", + "color_dimGreen": "#508135", + "color_dimGray": "#7B7A76", + "color_darkBlue": "#11263B", + "color_darkOrange": "#482D0E", + "color_darkRed": "#491C1B", + "color_darkGreen": "#223817", + "color_darkGray": "#504F4B", + "color_ok": "color_blue", "color_darkOk": "color_darkBlue", "color_warning": "color_orange", @@ -91,6 +102,7 @@ "color_overviewPage_widget_battery_background": "color_blue", "color_overviewPage_widget_battery_bubble_background": "#7394bd", "color_overviewPage_widget_battery_bubble_border": "#FFFFFF", + "color_overviewPage_widget_battery_units_color": "color_dimWhite", "color_briefPage_background": "color_black", "color_briefPage_battery_value_text_color": "color_gray5", diff --git a/themes/color/Light.json b/themes/color/Light.json index 1f0f09877..a2c1194b4 100644 --- a/themes/color/Light.json +++ b/themes/color/Light.json @@ -6,6 +6,17 @@ "color_humidity2": "#97B974", "color_humidity3": "#DBB78E", + "color_dimBlue": "#BBCEE0", + "color_dimOrange": "#F0D5B4", + "color_dimRed": "#F0C3BF", + "color_dimGreen": "#9BCB7E", + "color_dimGray": "#7B7A76", + "color_darkBlue": "#C0D4E6", + "color_darkOrange": "#F7DBB9", + "color_darkRed": "#F8CAC6", + "color_darkGreen": "#D1E6C2", + "color_darkGray": "#504F4B", + "color_ok": "color_blue", "color_darkOk": "color_darkBlue", "color_warning": "color_orange", @@ -15,7 +26,7 @@ "color_critical_background": "#F58B87", "color_font_primary": "color_gray2", - "color_font_secondary": "color_dimGray2", + "color_font_secondary": "color_dimGray", "color_font_disabled": "color_gray4", "color_background_primary": "color_white", @@ -91,12 +102,13 @@ "color_overviewPage_widget_battery_background": "color_blue", "color_overviewPage_widget_battery_bubble_background": "#7394bd", "color_overviewPage_widget_battery_bubble_border": "#FFFFFF", + "color_overviewPage_widget_battery_units_color": "#636359", "color_briefPage_background": "color_gray9", "color_briefPage_battery_value_text_color": "color_gray2", "color_briefPage_battery_unit_text_color": "color_gray3", "color_briefPage_circularGauge_shine": "#BBFFFFFF", - "color_briefPage_sidePanel_forecast_separator": "color_darkGray2", + "color_briefPage_sidePanel_forecast_separator": "color_darkWhite", "color_briefPage_sidePanel_loadGraph_dotColor": "color_gray3", "color_levelsPage_tankIcon": "color_gray2", @@ -119,6 +131,6 @@ "color_notificationsPage_text_color": "color_gray4", - "color_settings_gsmModem_signalStrength_inactive": "color_darkGray2", + "color_settings_gsmModem_signalStrength_inactive": "color_darkWhite", "color_settings_gsmModem_signalStrength_active": "color_gray2" } diff --git a/tools/themeparser.py b/tools/themeparser.py index 8347996a8..4b7fb00f8 100644 --- a/tools/themeparser.py +++ b/tools/themeparser.py @@ -32,32 +32,33 @@ class ThemeSingleton : public Theme { - Q_OBJECT - QML_NAMED_ELEMENT(Theme) - QML_SINGLETON + Q_OBJECT + QML_NAMED_ELEMENT(Theme) + QML_SINGLETON - // property declarations + // property declarations %s public: - ThemeSingleton(QObject *parent = nullptr) - : Theme(parent) - { - } + ThemeSingleton(QObject *parent = nullptr) + : Theme(parent) + { + } - // property accessors + // property accessors %s - Q_INVOKABLE QColor statusColorValue(StatusLevel level, bool darkColor = false) const - { - const QVariant c = (level == Ok && darkColor) ? color_darkOk() - : (level == Ok) ? color_ok() - : (level == Warning && darkColor) ? color_darkWarning() - : (level == Warning) ? color_warning() - : (level == Critical && darkColor) ? color_darkCritical() - : color_critical(); - return c.typeId() == QMetaType::QColor ? c.value() : QColor(c.value()); - } + // NOTE: won't capture, so client needs to manually capture the color change signal. + Q_INVOKABLE QColor statusColorValue(StatusLevel level, bool darkColor = false) const + { + const QVariant c = (level == Ok && darkColor) ? color_darkOk() + : (level == Ok) ? color_ok() + : (level == Warning && darkColor) ? color_darkWarning() + : (level == Warning) ? color_warning() + : (level == Critical && darkColor) ? color_darkCritical() + : color_critical(); + return c.typeId() == QMetaType::QColor ? c.value() : QColor(c.value()); + } };