Skip to content

Commit

Permalink
stylesheet: Allow to use CSS to fully set gradient colors
Browse files Browse the repository at this point in the history
  • Loading branch information
sergio-costas authored and 3v1n0 committed Mar 21, 2024
1 parent 9b4b858 commit 781e5c0
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 37 deletions.
57 changes: 49 additions & 8 deletions _stylesheet.scss
Original file line number Diff line number Diff line change
Expand Up @@ -354,14 +354,55 @@ $dock_style_modes: [null, shrink, extended, extended-shrink];
}

#dashtodockContainer.dashtodock .progress-bar {
/* Customization of the progress bar style, e.g.:
// track colors (the "background")
-progress-bar-track-filling: rgba(0.25, 0.25, 0.25, 0,75);
-progress-bar-track-border: rgba(0.75, 0.75, 0.75, 0,25);
// progress bar colors
-progress-bar-background: rgba(0.8, 0.8, 0.8, 1);
-progress-bar-border: rgba(0.9, 0.9, 0.9, 1);
*/
/* Customization of the progress bar style. The possible elements
* are:
*
* -XXXXXX-YYYYYY: plain color
* -XXXXXX-YYYYYY-color-start: start color for gradient
* -XXXXXX-YYYYYY-color-end: end color for gradient
* -XXXXXX-YYYYYY-offset-start: offset for start color in gradient (0-1)
* -XXXXXX-YYYYYY-offset-end: offset for end color in gradient (0-1)
* -XXXXXX-line-width: width value for the line used for the border
*
* XXXXXX can be either
*
* progress-bar-track: the "track" over which the progress bar is shown
* progress-bar: the progress bar itself
*
* YYYYYY can be either
*
* background: for the background color
* border: for the border color
*
* plain color entries have priority over gradients, so if both are set for
* an element, the plain color will be used.
*
* Examples:
*
* -progress-bar-track-background: rgba(128, 128, 0, 0.75);
* -progress-bar-track-border: rgba(0, 0, 255, 0.25);
*
* -progress-bar-background: rgba(0, 204, 204, 1);
* -progress-bar-border: rgba(230, 230, 230, 1);
*
* Default values when these entries aren't set are equivalent to:
* -progress-bar-track-background-color-start: 64, 64, 64, 1.0
* -progress-bar-track-background-color-end: 89, 89, 89, 1.0
* -progress-bar-track-background-start-offset: 0.4
* -progress-bar-track-background-end-offset: 0.9
* -progress-bar-track-border-color-start: 128, 128, 128, 0.1
* -progress-bar-track-border-color-end: 89, 89, 89, 0.4
* -progress-bar-track-border-start-offset: 0.5
* -progress-bar-track-border-end-offset: 0.9
* -progress-bar-track-line-width: 1
* -progress-bar-background: 204, 204, 204, 1.0
* -progress-bar-border: 230, 230, 230, 1.0
* -progress-bar-line-width: 1
*/
-progress-bar-track-background: rgba(0, 0, 0, 0.45);
-progress-bar-track-border: rgba(0, 0, 0, 0.7);
-progress-bar-background: rgba(255, 255, 255, 1.0);
-progress-bar-border: rgba(255, 255, 255, 1.0);
}

#dashtodockContainer.top #dash .placeholder,
Expand Down
143 changes: 114 additions & 29 deletions appIconIndicators.js
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,34 @@ class RunningIndicatorBinary extends RunningIndicatorDots {
* Unity like notification and progress indicators
*/
class UnityIndicator extends IndicatorBase {
static defaultProgressBar = {
// default values for the progress bar itself
background: {
colorStart: {red: 204, green: 204, blue: 204, alpha: 255},
colorEnd: null,
},
border: {
colorStart: {red: 230, green: 230, blue: 230, alpha: 255},
colorEnd: null,
},
};

static defaultProgressBarTrack = {
// default values for the progress bar track
background: {
colorStart: {red: 64, green: 64, blue: 64, alpha: 255},
colorEnd: {red: 89, green: 89, blue: 89, alpha: 255},
offsetStart: 0.4,
offsetEnd: 0.9,
},
border: {
colorStart: {red: 128, green: 128, blue: 128, alpha: 26},
colorEnd: {red: 204, green: 204, blue: 204, alpha: 102},
offsetStart: 0.5,
offsetEnd: 0.9,
},
};

constructor(source) {
super(source);

Expand Down Expand Up @@ -840,6 +868,72 @@ class UnityIndicator extends IndicatorBase {
this._progressOverlayArea?.queue_repaint();
}

_readGradientData(node, elementName, defaultValues) {
const output = {
colorStart: defaultValues.colorStart,
colorEnd: defaultValues.colorEnd,
offsetStart: defaultValues.offsetStart ?? 0.0,
offsetEnd: defaultValues.offsetEnd ?? 1.0,
};

const [hasElementName, elementNameValue] = node.lookup_color(elementName, false);
if (hasElementName) {
output.colorStart = elementNameValue;
output.colorEnd = null;
} else {
const [hasColorStart, colorStartValue] = node.lookup_color(`${elementName}-color-start`, false);
const [hasColorEnd, colorEndValue] = node.lookup_color(`${elementName}-color-end`, false);
if (hasColorStart && hasColorEnd) {
output.colorStart = colorStartValue;
output.colorEnd = colorEndValue;
}
}

const [hasOffsetStart, offsetStartvalue] = node.lookup_color(`${elementName}-offset-start`, false);
if (hasOffsetStart)
output.offsetStart = offsetStartvalue;

const [hasOffsetEnd, offsetEndValue] = node.lookup_color(`${elementName}-offset-end`, false);
if (hasOffsetEnd)
output.offsetEnd = offsetEndValue;

return output;
}

_readElementData(node, elementName, defaultValues) {
const defaultLineWidth = defaultValues.lineWidth ?? 1.0;
const [hasValue, lineWidth] = node.lookup_double(`${elementName}-line-width`, false);

return {
background: this._readGradientData(node, `${elementName}-background`, defaultValues.background),
border: this._readGradientData(node, `${elementName}-border`, defaultValues.border),
lineWidth: hasValue ? lineWidth : defaultLineWidth,
};
}

_createGradient(values, x0, y0, x1, y1) {
if (values.colorEnd) {
const gradient = new Cairo.LinearGradient(x0, y0, x1, y1);
gradient.addColorStopRGBA(values.offsetStart,
values.colorStart.red / 255,
values.colorStart.green / 255,
values.colorStart.blue / 255,
values.colorStart.alpha / 255);
gradient.addColorStopRGBA(values.offsetEnd,
values.colorEnd.red / 255,
values.colorEnd.green / 255,
values.colorEnd.blue / 255,
values.colorEnd.alpha / 255);
return gradient;
} else {
const gradient = Cairo.SolidPattern.createRGBA(values.colorStart.red / 255,
values.colorStart.green / 255,
values.colorStart.blue / 255,
values.colorStart.alpha / 255);
return gradient;
}
}

_drawProgressOverlay(area) {
const {scaleFactor} = St.ThemeContext.get_for_stage(global.stage);
const [surfaceWidth, surfaceHeight] = area.get_surface_size();
Expand All @@ -850,58 +944,49 @@ class UnityIndicator extends IndicatorBase {
let x = Math.floor((surfaceWidth - iconSize) / 2);
let y = Math.floor((surfaceHeight - iconSize) / 2);

const lineWidth = Math.floor(Number(scaleFactor));
const baseLineWidth = Math.floor(Number(scaleFactor));
const padding = Math.floor(iconSize * 0.05);
let width = iconSize - 2.0 * padding;
let height = Math.floor(Math.min(18.0 * scaleFactor, 0.20 * iconSize));
x += padding;
y += iconSize - height - padding;

const node = this._progressOverlayArea.get_theme_node();

const progressBarTrack = this._readElementData(node,
'-progress-bar-track',
UnityIndicator.defaultProgressBarTrack);

const progressBar = this._readElementData(node,
'-progress-bar',
UnityIndicator.defaultProgressBar);

// Draw the track
let lineWidth = baseLineWidth * progressBarTrack.lineWidth;
cr.setLineWidth(lineWidth);

// Draw the background
x += lineWidth;
y += lineWidth;
width -= 2.0 * lineWidth;
height -= 2.0 * lineWidth;

let hasColor, bg, bd, fg;
const node = this._progressOverlayArea.get_theme_node();

[hasColor, bg] = node.lookup_color('-progress-bar-track-filling', false);
if (!hasColor)
bg = new Clutter.Color({red: 64, green: 64, blue: 64, alpha: 192});

[hasColor, fg] = node.lookup_color('-progress-bar-track-border', false);
if (!hasColor)
fg = new Clutter.Color({red: 192, green: 192, blue: 192, alpha: 64});

let fill = Cairo.SolidPattern.createRGBA(bg.red / 255, bg.green / 255, bg.blue / 255, bg.alpha / 255);
let stroke = Cairo.SolidPattern.createRGBA(
fg.red / 255, fg.green / 255, fg.blue / 255, fg.alpha / 255);
let fill = this._createGradient(progressBarTrack.background, 0, y, 0, y + height);
let stroke = this._createGradient(progressBarTrack.border, 0, y, 0, y + height);
Utils.drawRoundedLine(cr, x + lineWidth / 2.0,
y + lineWidth / 2.0, width, height, true, true, stroke, fill);

// Draw the finished bar
lineWidth = baseLineWidth * progressBar.lineWidth;
cr.setLineWidth(lineWidth);

x += lineWidth;
y += lineWidth;
width -= 2.0 * lineWidth;
height -= 2.0 * lineWidth;

const finishedWidth = Math.ceil(this._progress * width);

[hasColor, bg] = node.lookup_color('-progress-bar-background', false);
if (!hasColor)
bg = new Clutter.Color({red: 204, green: 204, blue: 204, alpha: 255});

[hasColor, bd] = node.lookup_color('-progress-bar-border', false);
if (!hasColor)
bd = new Clutter.Color({red: 230, green: 230, blue: 230, alpha: 255});

stroke = Cairo.SolidPattern.createRGBA(
bd.red / 255, bd.green / 255, bd.blue / 255, bd.alpha / 255);
fill = Cairo.SolidPattern.createRGBA(
bg.red / 255, bg.green / 255, bg.blue / 255, bg.alpha / 255);
fill = this._createGradient(progressBar.background, 0, y, 0, y + height);
stroke = this._createGradient(progressBar.border, 0, y, 0, y + height);

if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL) {
Utils.drawRoundedLine(cr,
Expand Down

0 comments on commit 781e5c0

Please sign in to comment.