barLevel: Cache custom style properties

Custom properties are not cached by the theme node itself, so
looking them up repeatedly at every repaint is relatively
expensive.

Avoid this by caching the values ourselves at style changes.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2994>
This commit is contained in:
Florian Müllner 2023-10-26 19:37:36 +02:00 committed by Marge Bot
parent 77a72cec1e
commit a639fb0fc4

View File

@ -26,6 +26,17 @@ export const BarLevel = GObject.registerClass({
this._value = 0; this._value = 0;
this._overdriveStart = 1; this._overdriveStart = 1;
this._barLevelWidth = 0; this._barLevelWidth = 0;
this._barLevelHeight = 0;
this._barLevelBorderWidth = 0;
this._overdriveSeparatorWidth = 0;
this._barLevelColor = null;
this._barLevelActiveColor = null;
this._barLevelOverdriveColor = null;
this._barLevelBorderColor = null;
this._barLevelActiveBorderColor = null;
this._barLevelOverdriveBorderColor = null;
let defaultParams = { let defaultParams = {
style_class: 'barlevel', style_class: 'barlevel',
@ -96,34 +107,45 @@ export const BarLevel = GObject.registerClass({
this.queue_repaint(); this.queue_repaint();
} }
vfunc_style_changed() {
super.vfunc_style_changed();
const themeNode = this.get_theme_node();
this._barLevelHeight = themeNode.get_length('-barlevel-height');
this._barLevelBorderWidth =
Math.min(themeNode.get_length('-barlevel-border-width'), this._barLevelHeight);
this._overdriveSeparatorWidth =
themeNode.get_length('-barlevel-overdrive-separator-width');
this._barLevelColor = themeNode.get_color('-barlevel-background-color');
this._barLevelActiveColor = themeNode.get_color('-barlevel-active-background-color');
this._barLevelOverdriveColor = themeNode.get_color('-barlevel-overdrive-color');
const [hasBorderColor, barLevelBorderColor] =
themeNode.lookup_color('-barlevel-border-color', false);
this._barLevelBorderColor = hasBorderColor
? barLevelBorderColor : this._barLevelColor;
const [hasActiveBorderColor, barLevelActiveBorderColor] =
themeNode.lookup_color('-barlevel-active-border-color', false);
this._barLevelActiveBorderColor = hasActiveBorderColor
? barLevelActiveBorderColor : this._barLevelActiveColor;
const [hasOverdriveBorderColor, barLevelOverdriveBorderColor] =
themeNode.lookup_color('-barlevel-overdrive-border-color', false);
this._barLevelOverdriveBorderColor = hasOverdriveBorderColor
? barLevelOverdriveBorderColor : this._barLevelOverdriveColor;
}
vfunc_repaint() { vfunc_repaint() {
let cr = this.get_context(); let cr = this.get_context();
let themeNode = this.get_theme_node(); let themeNode = this.get_theme_node();
let [width, height] = this.get_surface_size(); let [width, height] = this.get_surface_size();
const rtl = this.get_text_direction() === Clutter.TextDirection.RTL; const rtl = this.get_text_direction() === Clutter.TextDirection.RTL;
let barLevelHeight = themeNode.get_length('-barlevel-height'); const barLevelBorderRadius = Math.min(width, this._barLevelHeight) / 2;
let barLevelBorderRadius = Math.min(width, barLevelHeight) / 2;
let fgColor = themeNode.get_foreground_color(); let fgColor = themeNode.get_foreground_color();
let barLevelColor = themeNode.get_color('-barlevel-background-color');
let barLevelActiveColor = themeNode.get_color('-barlevel-active-background-color');
let barLevelOverdriveColor = themeNode.get_color('-barlevel-overdrive-color');
let barLevelBorderWidth = Math.min(themeNode.get_length('-barlevel-border-width'), barLevelHeight);
let [hasBorderColor, barLevelBorderColor] =
themeNode.lookup_color('-barlevel-border-color', false);
if (!hasBorderColor)
barLevelBorderColor = barLevelColor;
let [hasActiveBorderColor, barLevelActiveBorderColor] =
themeNode.lookup_color('-barlevel-active-border-color', false);
if (!hasActiveBorderColor)
barLevelActiveBorderColor = barLevelActiveColor;
let [hasOverdriveBorderColor, barLevelOverdriveBorderColor] =
themeNode.lookup_color('-barlevel-overdrive-border-color', false);
if (!hasOverdriveBorderColor)
barLevelOverdriveBorderColor = barLevelOverdriveColor;
const TAU = Math.PI * 2; const TAU = Math.PI * 2;
let endX = 0; let endX = 0;
@ -140,11 +162,10 @@ export const BarLevel = GObject.registerClass({
let overdriveSeparatorX = barLevelBorderRadius + (width - 2 * barLevelBorderRadius) * overdriveRatio; let overdriveSeparatorX = barLevelBorderRadius + (width - 2 * barLevelBorderRadius) * overdriveRatio;
let overdriveActive = this._overdriveStart !== this._maxValue; let overdriveActive = this._overdriveStart !== this._maxValue;
let overdriveSeparatorWidth = 0; const overdriveSeparatorWidth = overdriveActive
if (overdriveActive) ? this._overdriveSeparatorWidth : 0;
overdriveSeparatorWidth = themeNode.get_length('-barlevel-overdrive-separator-width');
let xcArcStart = barLevelBorderRadius + barLevelBorderWidth; let xcArcStart = barLevelBorderRadius + this._barLevelBorderWidth;
let xcArcEnd = width - xcArcStart; let xcArcEnd = width - xcArcStart;
if (rtl) if (rtl)
[xcArcStart, xcArcEnd] = [xcArcEnd, xcArcStart]; [xcArcStart, xcArcEnd] = [xcArcEnd, xcArcStart];
@ -154,13 +175,13 @@ export const BarLevel = GObject.registerClass({
cr.arc(xcArcEnd, height / 2, barLevelBorderRadius, TAU * (3 / 4), TAU * (1 / 4)); cr.arc(xcArcEnd, height / 2, barLevelBorderRadius, TAU * (3 / 4), TAU * (1 / 4));
else else
cr.arcNegative(xcArcEnd, height / 2, barLevelBorderRadius, TAU * (3 / 4), TAU * (1 / 4)); cr.arcNegative(xcArcEnd, height / 2, barLevelBorderRadius, TAU * (3 / 4), TAU * (1 / 4));
cr.lineTo(endX, (height + barLevelHeight) / 2); cr.lineTo(endX, (height + this._barLevelHeight) / 2);
cr.lineTo(endX, (height - barLevelHeight) / 2); cr.lineTo(endX, (height - this._barLevelHeight) / 2);
cr.lineTo(xcArcEnd, (height - barLevelHeight) / 2); cr.lineTo(xcArcEnd, (height - this._barLevelHeight) / 2);
cr.setSourceColor(barLevelColor); cr.setSourceColor(this._barLevelColor);
cr.fillPreserve(); cr.fillPreserve();
cr.setSourceColor(barLevelBorderColor); cr.setSourceColor(this._barLevelBorderColor);
cr.setLineWidth(barLevelBorderWidth); cr.setLineWidth(this._barLevelBorderWidth);
cr.stroke(); cr.stroke();
/* normal progress bar */ /* normal progress bar */
@ -172,14 +193,14 @@ export const BarLevel = GObject.registerClass({
x = Math.max(endX, overdriveSeparatorX + overdriveSeparatorWidth / 2); x = Math.max(endX, overdriveSeparatorX + overdriveSeparatorWidth / 2);
cr.arcNegative(xcArcStart, height / 2, barLevelBorderRadius, TAU * (1 / 4), TAU * (3 / 4)); cr.arcNegative(xcArcStart, height / 2, barLevelBorderRadius, TAU * (1 / 4), TAU * (3 / 4));
} }
cr.lineTo(x, (height - barLevelHeight) / 2); cr.lineTo(x, (height - this._barLevelHeight) / 2);
cr.lineTo(x, (height + barLevelHeight) / 2); cr.lineTo(x, (height + this._barLevelHeight) / 2);
cr.lineTo(xcArcStart, (height + barLevelHeight) / 2); cr.lineTo(xcArcStart, (height + this._barLevelHeight) / 2);
if (this._value > 0) if (this._value > 0)
cr.setSourceColor(barLevelActiveColor); cr.setSourceColor(this._barLevelActiveColor);
cr.fillPreserve(); cr.fillPreserve();
cr.setSourceColor(barLevelActiveBorderColor); cr.setSourceColor(this._barLevelActiveBorderColor);
cr.setLineWidth(barLevelBorderWidth); cr.setLineWidth(this._barLevelBorderWidth);
cr.stroke(); cr.stroke();
/* overdrive progress barLevel */ /* overdrive progress barLevel */
@ -188,50 +209,50 @@ export const BarLevel = GObject.registerClass({
else else
x = Math.max(endX, overdriveSeparatorX) - overdriveSeparatorWidth / 2; x = Math.max(endX, overdriveSeparatorX) - overdriveSeparatorWidth / 2;
if (this._value > this._overdriveStart) { if (this._value > this._overdriveStart) {
cr.moveTo(x, (height - barLevelHeight) / 2); cr.moveTo(x, (height - this._barLevelHeight) / 2);
cr.lineTo(endX, (height - barLevelHeight) / 2); cr.lineTo(endX, (height - this._barLevelHeight) / 2);
cr.lineTo(endX, (height + barLevelHeight) / 2); cr.lineTo(endX, (height + this._barLevelHeight) / 2);
cr.lineTo(x, (height + barLevelHeight) / 2); cr.lineTo(x, (height + this._barLevelHeight) / 2);
cr.lineTo(x, (height - barLevelHeight) / 2); cr.lineTo(x, (height - this._barLevelHeight) / 2);
cr.setSourceColor(barLevelOverdriveColor); cr.setSourceColor(this._barLevelOverdriveColor);
cr.fillPreserve(); cr.fillPreserve();
cr.setSourceColor(barLevelOverdriveBorderColor); cr.setSourceColor(this._barLevelOverdriveBorderColor);
cr.setLineWidth(barLevelBorderWidth); cr.setLineWidth(this._barLevelBorderWidth);
cr.stroke(); cr.stroke();
} }
/* end progress bar arc */ /* end progress bar arc */
if (this._value > 0) { if (this._value > 0) {
if (this._value <= this._overdriveStart) if (this._value <= this._overdriveStart)
cr.setSourceColor(barLevelActiveColor); cr.setSourceColor(this._barLevelActiveColor);
else else
cr.setSourceColor(barLevelOverdriveColor); cr.setSourceColor(this._barLevelOverdriveColor);
if (!rtl) { if (!rtl) {
cr.arc(endX, height / 2, barLevelBorderRadius, TAU * (3 / 4), TAU * (1 / 4)); cr.arc(endX, height / 2, barLevelBorderRadius, TAU * (3 / 4), TAU * (1 / 4));
cr.lineTo(Math.floor(endX), (height + barLevelHeight) / 2); cr.lineTo(Math.floor(endX), (height + this._barLevelHeight) / 2);
cr.lineTo(Math.floor(endX), (height - barLevelHeight) / 2); cr.lineTo(Math.floor(endX), (height - this._barLevelHeight) / 2);
} else { } else {
cr.arcNegative(endX, height / 2, barLevelBorderRadius, TAU * (3 / 4), TAU * (1 / 4)); cr.arcNegative(endX, height / 2, barLevelBorderRadius, TAU * (3 / 4), TAU * (1 / 4));
cr.lineTo(Math.ceil(endX), (height + barLevelHeight) / 2); cr.lineTo(Math.ceil(endX), (height + this._barLevelHeight) / 2);
cr.lineTo(Math.ceil(endX), (height - barLevelHeight) / 2); cr.lineTo(Math.ceil(endX), (height - this._barLevelHeight) / 2);
} }
cr.lineTo(endX, (height - barLevelHeight) / 2); cr.lineTo(endX, (height - this._barLevelHeight) / 2);
cr.fillPreserve(); cr.fillPreserve();
cr.setLineWidth(barLevelBorderWidth); cr.setLineWidth(this._barLevelBorderWidth);
cr.stroke(); cr.stroke();
} }
/* draw overdrive separator */ /* draw overdrive separator */
if (overdriveActive) { if (overdriveActive) {
cr.moveTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2); cr.moveTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height - this._barLevelHeight) / 2);
cr.lineTo(overdriveSeparatorX + overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2); cr.lineTo(overdriveSeparatorX + overdriveSeparatorWidth / 2, (height - this._barLevelHeight) / 2);
cr.lineTo(overdriveSeparatorX + overdriveSeparatorWidth / 2, (height + barLevelHeight) / 2); cr.lineTo(overdriveSeparatorX + overdriveSeparatorWidth / 2, (height + this._barLevelHeight) / 2);
cr.lineTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height + barLevelHeight) / 2); cr.lineTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height + this._barLevelHeight) / 2);
cr.lineTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2); cr.lineTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height - this._barLevelHeight) / 2);
if (this._value <= this._overdriveStart) if (this._value <= this._overdriveStart)
cr.setSourceColor(fgColor); cr.setSourceColor(fgColor);
else else
cr.setSourceColor(barLevelColor); cr.setSourceColor(this._barLevelColor);
cr.fill(); cr.fill();
} }