🎉 🎉 Mushroom and AuraGlow ... in my main

placed both the Mushroom and AuraGlow in my main
This commit is contained in:
Justin Garza
2024-12-08 19:21:08 -05:00
parent 5b6ccdc732
commit 39a60d704b
17 changed files with 2862 additions and 173 deletions
+4
View File
@@ -30,6 +30,7 @@ This extension is not only more useless than the cube, but it is also much more
| Effect | Preview |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| **Apparition** <br> This effect hides your windows by violently sucking them into the void of magic! | <img src ="docs/pics/apparition.gif" /> |
| **Aura Glow** <br> A radiant edge-lit animation | <img src ="docs/pics/aura-glow.gif" /> |
| **Broken Glass** <br> Shatter your windows into a shower sharp shards! This effect can be configured so that the shards fly away from your mouse pointer position! | <img src ="docs/pics/broken-glass.gif" /> |
| **Doom** <br> Melt your windows. Inspired by the legendary screen transitions of the original Doom. | <img src ="docs/pics/doom.gif" /> |
| **Energize A** <br> Beam your windows away! | <img src ="docs/pics/energize-a.gif" /> |
@@ -41,6 +42,7 @@ This extension is not only more useless than the cube, but it is also much more
| **Hexagon** <br> With glowing lines and hexagon-shaped tiles, this effect looks very sci-fi. | <img src ="docs/pics/hexagon.gif" /> |
| **Incinerate** <br> A less snappy but definitely more fancy take on the fire effect. | <img src ="docs/pics/incinerate.gif" /> |
| **Matrix** <br> Turn your windows into a shower of green letters! The color is actually configurable. | <img src ="docs/pics/matrix.gif" /> |
| **Mushroom** <br> Inspired by your favorite italian plumber! | <img src ="docs/pics/mushroom.gif" /> |
| **Paint Brush** <br> Paint or erase your windows with a thick paint brush. | <img src ="docs/pics/paint-brush.gif" /> |
| **Pixelate** <br> Pixelate your windows and randomly hide pixels until the entire window is gone. | <img src ="docs/pics/pixelate.gif" /> |
| **Pixel Wheel** <br> This simple effect pixelates the window and hides the pixels in a wheel-like fashion. | <img src ="docs/pics/pixel-wheel.gif" /> |
@@ -66,6 +68,7 @@ Below is a table which summarizes the current availability for all effects.
</tr>
<tr><td></td> <td>3.36</td> <td>3.38</td><td>40+</td><td>5.25.0+</td></tr>
<tr><td>Apparition</td> <td> </td> <td>✅</td> <td>✅</td> <td> </td> </tr>
<tr><td>Aura Glow</td> <td>✅</td> <td>✅</td> <td>✅</td> <td>✅</td> </tr>
<tr><td>Broken Glass</td> <td> </td> <td> </td> <td>✅</td> <td> </td> </tr>
<tr><td>Doom</td> <td> </td> <td>✅</td> <td>✅</td> <td>✅</td> </tr>
<tr><td>Energize A</td> <td>✅</td> <td>✅</td> <td>✅</td> <td>✅</td> </tr>
@@ -77,6 +80,7 @@ Below is a table which summarizes the current availability for all effects.
<tr><td>Hexagon</td> <td>✅</td> <td>✅</td> <td>✅</td> <td>✅</td> </tr>
<tr><td>Incinerate</td> <td>✅</td> <td>✅</td> <td>✅</td> <td>✅</td> </tr>
<tr><td>Matrix</td> <td> </td> <td> </td> <td>✅</td> <td> </td> </tr>
<tr><td>Mushroom</td> <td>✅</td> <td>✅</td> <td>✅</td> <td>✅</td>✅</tr>
<tr><td>Paint Brush</td> <td> </td> <td> </td> <td>✅</td> <td> </td> </tr>
<tr><td>Pixelate</td> <td>✅</td> <td>✅</td> <td>✅</td> <td>✅</td> </tr>
<tr><td>Pixel Wheel</td> <td>✅</td> <td>✅</td> <td>✅</td> <td>✅</td> </tr>
+8 -1
View File
@@ -4,4 +4,11 @@ The preview GIFs are recorded with OBS Studio at 1920x1080, cut to a length of e
```bash
gifski --fps 30 -W 320 -H 180 -o effect.gif effect.mp4
```
```
# gif Info
GIF length: 2 second(s)
GIF width/height: 320×180 pixels
number of frames: 60
number of colors: 256
loop count: 0 (endless)
Binary file not shown.

After

Width:  |  Height:  |  Size: 688 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

+25 -8
View File
@@ -23,6 +23,7 @@ import {WindowPicker} from './src/WindowPicker.js';
import * as utils from './src/utils.js';
import Apparition from './src/effects/Apparition.js';
import AuraGlow from './src/effects/AuraGlow.js';
import BrokenGlass from './src/effects/BrokenGlass.js';
import Doom from './src/effects/Doom.js';
import EnergizeA from './src/effects/EnergizeA.js';
@@ -44,7 +45,7 @@ import TRexAttack from './src/effects/TRexAttack.js';
import TVEffect from './src/effects/TVEffect.js';
import TVGlitch from './src/effects/TVGlitch.js';
import Wisps from './src/effects/Wisps.js';
import Mushroom from './src/effects/Mushroom.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import {Workspace} from 'resource:///org/gnome/shell/ui/workspace.js';
@@ -71,14 +72,30 @@ export default class BurnMyWindows extends Extension {
// New effects must be registered here and in prefs.js.
this._ALL_EFFECTS = [
new Apparition(), new BrokenGlass(), new Doom(),
new EnergizeA(), new EnergizeB(), new Fire(),
new Focus(), new Glide(), new Glitch(),
new Hexagon(), new Incinerate(), new Matrix(),
new PaintBrush(), new Pixelate(), new PixelWheel(),
new PixelWipe(), new Portal(), new SnapOfDisintegration(),
new TRexAttack(), new TVEffect(), new TVGlitch(),
new Apparition(),
new AuraGlow(),
new BrokenGlass(),
new Doom(),
new EnergizeA(),
new EnergizeB(),
new Fire(),
new Focus(),
new Glide(),
new Glitch(),
new Hexagon(),
new Incinerate(),
new Matrix(),
new PaintBrush(),
new Pixelate(),
new PixelWheel(),
new PixelWipe(),
new Portal(),
new SnapOfDisintegration(),
new TRexAttack(),
new TVEffect(),
new TVGlitch(),
new Wisps(),
new Mushroom(),
];
// Load all of our resources.
+7 -4
View File
@@ -24,6 +24,7 @@ import * as utils from './src/utils.js';
import {ProfileManager} from './src/ProfileManager.js';
import Apparition from './src/effects/Apparition.js';
import AuraGlow from './src/effects/AuraGlow.js';
import BrokenGlass from './src/effects/BrokenGlass.js';
import Doom from './src/effects/Doom.js';
import EnergizeA from './src/effects/EnergizeA.js';
@@ -35,6 +36,7 @@ import Glitch from './src/effects/Glitch.js';
import Hexagon from './src/effects/Hexagon.js';
import Incinerate from './src/effects/Incinerate.js';
import Matrix from './src/effects/Matrix.js';
import Mushroom from './src/effects/Mushroom.js';
import PaintBrush from './src/effects/PaintBrush.js';
import Pixelate from './src/effects/Pixelate.js';
import PixelWheel from './src/effects/PixelWheel.js';
@@ -71,10 +73,11 @@ export default class BurnMyWindowsPreferences extends ExtensionPreferences {
// New effects must be registered here and in extension.js.
this._ALL_EFFECTS = [
Apparition, BrokenGlass, Doom, EnergizeA, EnergizeB, Fire,
Focus, Glide, Glitch, Hexagon, Incinerate, Matrix,
PaintBrush, Pixelate, PixelWheel, PixelWipe, Portal, SnapOfDisintegration,
TRexAttack, TVEffect, TVGlitch, Wisps,
Apparition, AuraGlow, BrokenGlass, Doom, EnergizeA,
EnergizeB, Fire, Focus, Glide, Glitch,
Hexagon, Incinerate, Matrix, Mushroom, PaintBrush,
Pixelate, PixelWheel, PixelWipe, Portal, SnapOfDisintegration,
TRexAttack, TVEffect, TVGlitch, Wisps,
];
+247
View File
@@ -0,0 +1,247 @@
//////////////////////////////////////////////////////////////////////////////////////////
// ) ( //
// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< //
// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ //
// |__/ //
//////////////////////////////////////////////////////////////////////////////////////////
// SPDX-FileCopyrightText: Justin Garza <JGarza9788@gmail.com>
// SPDX-License-Identifier: GPL-3.0-or-later
// The content from common.glsl is automatically prepended to each shader effect. This
// provides the standard input:
// vec2 iTexCoord: Texture coordinates for retrieving the window input color.
// bool uIsFullscreen: True if the window is maximized or in fullscreen mode.
// bool uForOpening: True if a window-open animation is ongoing, false otherwise.
// float uProgress: A value which transitions from 0 to 1 during the animation.
// float uDuration: The duration of the current animation in seconds.
// vec2 uSize: The size of uTexture in pixels.
// float uPadding: The empty area around the actual window (e.g. where the shadow
// is drawn). For now, this will only be set on GNOME.
// Furthermore, there are two global methods for reading the window input color and
// setting the shader output color. Both methods assume straight alpha:
// vec4 getInputColor(vec2 coords)
// void setOutputColor(vec4 outColor)
// The width of the fading effect is loaded from the settings.
uniform float uColorSpeed;
uniform bool uRandomColorOffset;
uniform float uColorOffset;
uniform float uColorSaturation;
uniform float uFadeOut;
uniform float uBlur;
uniform vec2 uSeed;
/*
this controls the end shape
-5.0 large Star
-3.0 Star
1.0 Dimond
2.0 Circle
3.0 Squircle
5.0 Square
*/
uniform float uEdgeShape;
//the size of the edge color
uniform float uEdgeSize;
//soft <--> hard
uniform float uEdgeHardness;
vec3 offsetHue(vec3 color, float hueOffset) {
// Convert RGB to HSV
float maxC = max(max(color.r, color.g), color.b);
float minC = min(min(color.r, color.g), color.b);
float delta = maxC - minC;
float hue = 0.0;
if (delta > 0.0) {
if (maxC == color.r) {
hue = mod((color.g - color.b) / delta, 6.0);
} else if (maxC == color.g) {
hue = (color.b - color.r) / delta + 2.0;
} else {
hue = (color.r - color.g) / delta + 4.0;
}
}
hue /= 6.0;
float saturation = (maxC > 0.0) ? (delta / maxC) : 0.0;
float value = maxC;
// Offset the hue
hue = mod(hue + hueOffset, 1.0);
// Convert HSV back to RGB
float c = value * saturation;
float x = c * (1.0 - abs(mod(hue * 6.0, 2.0) - 1.0));
float m = value - c;
vec3 rgb;
if (hue < 1.0 / 6.0) {
rgb = vec3(c, x, 0.0);
} else if (hue < 2.0 / 6.0) {
rgb = vec3(x, c, 0.0);
} else if (hue < 3.0 / 6.0) {
rgb = vec3(0.0, c, x);
} else if (hue < 4.0 / 6.0) {
rgb = vec3(0.0, x, c);
} else if (hue < 5.0 / 6.0) {
rgb = vec3(x, 0.0, c);
} else {
rgb = vec3(c, 0.0, x);
}
return rgb + m;
}
// A simple blur function
vec4 blur(vec2 uv, float radius, float samples) {
vec4 color = vec4(0.0);
const float tau = 6.28318530718;
const float directions = 15.0;
for (float d = 0.0; d < tau; d += tau / directions) {
for (float s = 0.0; s < 1.0; s += 1.0 / samples) {
vec2 offset = vec2(cos(d), sin(d)) * radius * (1.0 - s) / uSize;
color += getInputColor(uv + offset);
}
}
return color / samples / directions;
}
void main() {
// This gradually dissolves from [1..0] from the outside to the center. We
// switch the direction for opening and closing.
float progress = uForOpening ? uProgress : 1.0 - uProgress ;
//adjusting for Gnome
if (uPadding > 0.0)
{
progress = remap(
progress, 0.0, ((uSize.x + (uPadding*2.0)) / uSize.x)
,0.0, 1.0
);
progress = clamp(progress,0.0,1.0);
}
// Get the color from the window texture.
vec4 oColor = getInputColor(iTexCoord.st);
// Calculate the aspect ratio of the render area
float aspect = uSize.x / uSize.y;
//standard uv
vec2 uv = iTexCoord.st;
// tuv is for when progress is near 0
vec2 tuv = uv;
tuv -= 0.5; // Shift UV coordinates to center (from [-0.5 to 0.5])
tuv.x *= aspect; // Scale x-coordinate to match aspect ratio
tuv += 0.5; // Shift UV coordinates back (from [0 to 1])
//mixing the UVs
uv = mix(tuv,uv,easeOutExpo(progress));
// this controls the shape
// -1.0 would be a diamond-ish
// 0.0 would be a rounded diamond
// 1.0 would be a circle
// 2.0 will be sqircle
// 1000.0 will be very square
float p = mix(uEdgeShape,1000.0,
easeInExpo(progress)
);
//this will be used later to make a mask
float m = mix(
0.0,
1.0,
clamp(
pow(abs(uv.x-0.5)*2.0,p) + pow(abs(uv.y-0.5)*2.0,p),0.0,1.0
)
);
//this calculates the edge of the effect
float edge = abs(m-progress) ;
float e = mix(0.0,uEdgeSize,1.0 - progress);
edge = remap(edge,0.0,e,0.0,1.0);
edge = clamp(edge,0.0,1.0);
edge = 1.0 - edge;
//this is the mask
float mask = (m > progress) ? 0.0 : 1.0 ;
//we need two of these
float mask0 = mix(mask,mask+edge,1.0 - uEdgeHardness);
float mask1 = mix(edge,edge*mask,uEdgeHardness);
//calculate color
vec3 color = cos(progress*uColorSpeed+uv.xyx+vec3(0,2,4)).xyz;
//coloroffset
float colorOffset = (uRandomColorOffset) ? hash12(uSeed) : uColorOffset ;
color = offsetHue(color, colorOffset);
//clamp and saturate
color = clamp(color * uColorSaturation,vec3(0.0),vec3(1.0));
//save this for later
float oColorAlpha = oColor.a;
//blur-ify
if (uBlur > 0.0)
{
//used for blur later ...
//calculate this before saturating it
float b = (color.r + color.g + color.b)/3.0;
oColor = blur( iTexCoord.st, b * uBlur * mask1, 7.0);
}
//apply masks and colors
oColor.a *= mask0;
//i was doing this to try to adjust for light mode
// i don;t like the way these make the effect look
// ...maybe a toggle for it later
/*
float oColorPercent = (oColor.r + oColor.g + oColor.b)/3.0;
oColor.r = mix(oColor.r , 1.0 - oColor.r, mask1 * oColorPercent);
oColor.g = mix(oColor.g , 1.0 - oColor.g, mask1 * oColorPercent);
oColor.b = mix(oColor.b , 1.0 - oColor.b, mask1 * oColorPercent);
// --or
oColor.r = mix(oColor.r , 0.0, mask1 * oColorPercent);
oColor.g = mix(oColor.g , 0.0, mask1 * oColorPercent);
oColor.b = mix(oColor.b , 0.0, mask1 * oColorPercent);
*/
oColor += mask1 * vec4(color.rgb,1.0);
oColor.a *= oColorAlpha;
//i want to fade out the last ~10% of the animation
float lastfade = remap(progress,0.0,uFadeOut,0.0,1.0);
lastfade = clamp(lastfade,0.0,1.0);
lastfade = easeInSine(lastfade);
//apply the lastfade
oColor.a *= lastfade;
setOutputColor(oColor);
}
+163
View File
@@ -202,6 +202,119 @@ float easeOutBack(float x, float e) {
return p * p * ((e + 1.0) * p + e) + 1.0;
}
// https://easings.net/
/*
Easing functions define the rate of change of a parameter over time, commonly used in animations, UI transitions, and game development. They provide a way to make movements more natural or visually appealing rather than linear and mechanical. Popular categories of easing functions include:
Linear: Constant speed from start to finish.
Quadratic (Ease In, Ease Out, Ease In Out): Changes at varying rates, with smoother starts or stops.
Cubic: Similar to quadratic but allows for even more nuanced transitions.
Exponential: Drastic changes at the start or end, often used for dramatic effects.
Bounce: Mimics a bouncing object with oscillations.
Elastic: Simulates the behavior of a spring, with overshooting and oscillations.
Below are text-based "graphs" of some easing functions, where the horizontal axis represents time and the vertical axis represents progress.
*/
// Quadratic Easing
// Smooth acceleration and deceleration using quadratic (t^2) curves.
float easeInOutQuad(float t) {
// Accelerates for the first half, decelerates for the second half.
return t < 0.5 ? 2.0 * t * t : -1.0 + (4.0 - 2.0 * t) * t;
}
// Cubic Easing
// Smoother transitions compared to quadratic easing using cubic (t^3) curves.
float easeInCubic(float t) {
// Starts slow and accelerates as t increases.
return t * t * t;
}
float easeOutCubic(float t) {
// Starts fast and decelerates as t approaches 1.0.
float f = t - 1.0;
return f * f * f + 1.0;
}
float easeInOutCubic(float t) {
// Combines easeIn and easeOut cubic behavior for smooth transitions.
return t < 0.5 ? 4.0 * t * t * t : (t - 1.0) * (2.0 * t - 2.0) * (2.0 * t - 2.0) + 1.0;
}
// Quartic Easing
// Even smoother transitions than cubic, using quartic (t^4) curves.
float easeInQuart(float t) {
// Starts very slow and accelerates steeply.
return t * t * t * t;
}
float easeOutQuart(float t) {
// Starts steeply and slows down dramatically.
float f = t - 1.0;
return 1.0 - f * f * f * f;
}
float easeInOutQuart(float t) {
// Combines easeIn and easeOut quartic behavior for very smooth transitions.
return t < 0.5 ? 8.0 * t * t * t * t : 1.0 - 8.0 * (t - 1.0) * (t - 1.0) * (t - 1.0) * (t - 1.0);
}
// Sine Easing
// Smooth, wave-like acceleration and deceleration using sine curves.
float easeInSine(float t) {
// Starts very slow, following a sine wave curve.
return 1.0 - cos((t * 3.141592653589793) / 2.0);
}
float easeOutSine(float t) {
// Starts fast and slows down following a sine wave curve.
return sin((t * 3.141592653589793) / 2.0);
}
float easeInOutSine(float t) {
// Smooth start and end, mimicking half a sine wave.
return -0.5 * (cos(3.141592653589793 * t) - 1.0);
}
// Exponential Easing
// Sharp transitions with rapid acceleration and deceleration.
float easeInExpo(float t) {
// Very slow start, accelerates exponentially.
return t == 0.0 ? 0.0 : pow(2.0, 10.0 * (t - 1.0));
}
float easeOutExpo(float t) {
// Starts fast and slows down exponentially.
return t == 1.0 ? 1.0 : 1.0 - pow(2.0, -10.0 * t);
}
float easeInOutExpo(float t) {
// Combines easeIn and easeOut exponential for sharp transitions.
if (t == 0.0) return 0.0;
if (t == 1.0) return 1.0;
return t < 0.5 ? 0.5 * pow(2.0, 20.0 * t - 10.0) : 1.0 - 0.5 * pow(2.0, -20.0 * t + 10.0);
}
// Back Easing
// Creates an overshooting effect for more dynamic animations.
float easeInOutBack(float t) {
// Uses constants to define the overshooting magnitude.
const float c1 = 1.70158;
const float c2 = c1 * 1.525;
return t < 0.5
? (pow(2.0 * t, 2.0) * ((c2 + 1.0) * 2.0 * t - c2)) / 2.0
: (pow(2.0 * t - 2.0, 2.0) * ((c2 + 1.0) * (t * 2.0 - 2.0) + c2) + 2.0) / 2.0;
}
// --------------------------------------------------------------------- edge mask helpers
// This method returns a mask which smoothly transitions towards zero when approaching
@@ -470,3 +583,53 @@ float simplex3DFractal(vec3 m) {
return 0.5333333 * simplex3D(m * rot1) + 0.2666667 * simplex3D(2.0 * m * rot2) +
0.1333333 * simplex3D(4.0 * m * rot3) + 0.0666667 * simplex3D(8.0 * m);
}
// --------------------------------------------------------------------------------- remap
/*
These functions remap a given value from one range to another.
The remap operation is particularly useful in shader programming
to scale or normalize data, ensuring compatibility across various
input ranges. Each version of the remap function supports a
different data type:
1. float: Remap a single scalar value.
2. vec2: Remap a 2D vector.
3. vec3: Remap a 3D vector.
4. vec4: Remap a 4D vector.
The general formula used is:
newMin + (value - oldMin) * (newMax - newMin) / (oldMax - oldMin)
This ensures a linear transformation from the old range to the new range.
*/
// Remap for float
// Maps a float value from one range [oldMin, oldMax] to another range [newMin, newMax].
// This is useful for normalizing or scaling scalar values to fit within a desired range.
float remap(float value, float oldMin, float oldMax, float newMin, float newMax) {
return newMin + (value - oldMin) * (newMax - newMin) / (oldMax - oldMin);
}
// Remap for vec2
// Maps a 2D vector (vec2) from one range [oldMin, oldMax] to another range [newMin, newMax].
// Each component of the vec2 is individually scaled and transformed.
vec2 remap(vec2 value, vec2 oldMin, vec2 oldMax, vec2 newMin, vec2 newMax) {
return newMin + (value - oldMin) * (newMax - newMin) / (oldMax - oldMin);
}
// Remap for vec3
// Maps a 3D vector (vec3) from one range [oldMin, oldMax] to another range [newMin, newMax].
// Each component of the vec3 is individually scaled and transformed.
vec3 remap(vec3 value, vec3 oldMin, vec3 oldMax, vec3 newMin, vec3 newMax) {
return newMin + (value - oldMin) * (newMax - newMin) / (oldMax - oldMin);
}
// Remap for vec4
// Maps a 4D vector (vec4) from one range [oldMin, oldMax] to another range [newMin, newMax].
// Each component of the vec4 is individually scaled and transformed.
vec4 remap(vec4 value, vec4 oldMin, vec4 oldMax, vec4 newMin, vec4 newMax) {
return newMin + (value - oldMin) * (newMax - newMin) / (oldMax - oldMin);
}
+32 -20
View File
@@ -30,57 +30,69 @@
// vec4 getInputColor(vec2 coords)
// void setOutputColor(vec4 outColor)
// Ease-in-out cubic for alpha
float easeInOutCubic(float x) {
return x < 0.5 ? 4.0 * x * x * x : 1.0 - pow(-2.0 * x + 2.0, 3.0) / 2.0;
}
// Ease-in-out sine for blur
float easeInOutSine(float x) {
return -(cos(3.14159265 * x) - 1.0) / 2.0;
}
// A simple blur function
vec4 blur(vec2 uv, float radius, float samples) {
// Initialize the color accumulator to zero.
vec4 color = vec4(0.0);
const float tau = 6.28318530718;
// Define a constant for 2 * PI (tau), which represents a full circle in radians.
const float tau = 6.28318530718;
// Number of directions for sampling around the circle.
const float directions = 15.0;
// Outer loop iterates over multiple directions evenly spaced around a circle.
for (float d = 0.0; d < tau; d += tau / directions) {
// Inner loop samples along each direction, with decreasing intensity.
for (float s = 0.0; s < 1.0; s += 1.0 / samples) {
// Calculate the offset for this sample based on direction, radius, and step.
// The (1.0 - s) term ensures more sampling occurs closer to the center.
vec2 offset = vec2(cos(d), sin(d)) * radius * (1.0 - s) / uSize;
// Add the sampled color at the offset position to the accumulator.
color += getInputColor(uv + offset);
}
}
// Normalize the accumulated color by dividing by the total number of samples
// and directions to ensure the result is averaged.
return color / samples / directions;
}
// The width of the fading effect is loaded from the settings.
uniform float uBlurAmount;
uniform float uBlurQuality;
void main() {
// Calculate the progression value based on the animation direction.
// If opening, use uProgress as-is; if closing, invert the progression.
float progl = uForOpening ? uProgress : 1.0 - uProgress;
float easedProgressBlur = easeInOutSine(progl); // Blur easing
float easedProgressAlpha = easeInOutCubic(progl); // Alpha easing
// Apply easing functions to the progression value:
// - easedProgressBlur: Used for controlling the blur effect smoothly.
// - easedProgressAlpha: Used for controlling the alpha (opacity) transition.
float easedProgressBlur = easeInOutSine(progl); // Sine-based smooth easing for blur.
float easedProgressAlpha = easeInOutCubic(progl); // Cubic-based smooth easing for alpha.
// Control blur amount using easedProgressBlur
// Calculate the blur amount by interpolating (mixing) between the maximum blur (uBlurAmount)
// and zero blur based on the eased progression value.
float blurAmount = mix(uBlurAmount, 0.0, easedProgressBlur);
// Apply blur
vec4 texColor = blur( iTexCoord.st, blurAmount, uBlurQuality);
// Apply the calculated blur effect to the texture at the current texture coordinates.
// The blur function uses the blur amount and quality (uBlurQuality) for sampling.
vec4 texColor = blur(iTexCoord.st, blurAmount, uBlurQuality);
// Control alpha using easedProgressAlpha
// Calculate the alpha value for the transition using eased progress.
// This determines how transparent the final color will appear.
float alpha = easedProgressAlpha;
// Set final color with alpha transition
// Apply the alpha transition to the final texture color.
// Multiply the texture's alpha channel by the computed alpha value.
texColor.a *= alpha;
// Output the final color with the applied blur and alpha transition.
setOutputColor(texColor);
}
}
+450
View File
@@ -0,0 +1,450 @@
//////////////////////////////////////////////////////////////////////////////////////////
// ) ( //
// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< //
// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ //
// |__/ //
//////////////////////////////////////////////////////////////////////////////////////////
// SPDX-FileCopyrightText: Justin Garza JGarza9788@gmail.com
// SPDX-License-Identifier: GPL-3.0-or-later
// The content from common.glsl is automatically prepended to each shader effect. This
// provides the standard input:
// vec2 iTexCoord: Texture coordinates for retrieving the window input color.
// bool uIsFullscreen: True if the window is maximized or in fullscreen mode.
// bool uForOpening: True if a window-open animation is ongoing, false otherwise.
// float uProgress: A value which transitions from 0 to 1 during the animation.
// float uDuration: The duration of the current animation in seconds.
// vec2 uSize: The size of uTexture in pixels.
// float uPadding: The empty area around the actual window (e.g. where the shadow
// is drawn). For now, this will only be set on GNOME.
// Furthermore, there are two global methods for reading the window input color and
// setting the shader output color. Both methods assume straight alpha:
// vec4 getInputColor(vec2 coords)
// void setOutputColor(vec4 outColor)
// The width of the fading effect is loaded from the settings.
// use 8BitStyle or not
uniform bool u8BitStyle;
//these are for the 4 point stars (or sparks)
uniform bool uEnable4PStars;
uniform float u4PStars;
uniform vec4 u4PSColor;
uniform float u4PSRotation;
//these are for the Rays
uniform bool uEnableRays;
uniform vec4 uRaysColor;
//these are for the 5 pointed stars
uniform bool uEnable5pStars;
uniform float uRings;
uniform float uRingRotation;
uniform float uStarPerRing;
// and the colors they change over time
uniform vec4 uStarColor0;
uniform vec4 uStarColor1;
uniform vec4 uStarColor2;
uniform vec4 uStarColor3;
uniform vec4 uStarColor4;
uniform vec4 uStarColor5;
//helps to find the angle
vec3 getPosByAngle(float angle)
{
return vec3(cos(angle), sin(angle), 0);
}
float getStar(vec2 uv, vec2 center, float npoints, float radiusRatio, float size, float rotation)
{
float radiusMax = 1.0;
float radiusMin = radiusMax * radiusRatio;
float PI = 3.1415926;
float starangle = 2.0 * PI / npoints; // Angle between points on the star
// Offset rotation to ensure one point is always up when rotation = 0
rotation += PI / 2.0 - starangle / 1.0;
// Define the positions for the outer and inner points of the star's initial angle, rotated by `rotation`
vec3 p0 = (radiusMax * size) * getPosByAngle(rotation); // Outer point, rotated by `rotation`
vec3 p1 = (radiusMin * size) * getPosByAngle(starangle + rotation); // Inner point, also rotated
// Calculate the position of the current fragment relative to the star's center
vec2 curPosuv = (uv - center); // Center UV coordinates, then scale to fit the star size
float curRadius = length(curPosuv); // Radius from center, no need to scale further
float curPosAngle = atan(curPosuv.y, curPosuv.x) - rotation; // Calculate angle and adjust by `rotation`
// Determine the fractional position within the current star segment
float a = fract(curPosAngle / starangle); // Fractional angle position within one segment
if (a >= 0.5)
a = 1.0 - a; // Ensure we are within the first half of the segment (symmetry)
// Calculate the current point on the star segment, applying rotation
a = a * starangle; // Actual angle for this position on the segment
vec3 curPos = curRadius * getPosByAngle(a + rotation); // Final position, rotated
// Calculate directions for edge detection using cross product
vec3 dir0 = p1 - p0; // Vector from outer to inner point
vec3 dir1 = curPos - p0; // Vector from outer point to current position
// Use cross product to determine if `curPos` is inside the star's edge
return step(0.0, cross(dir0, dir1).z); // Returns 1.0 if inside, 0.0 if outside (solid edge)
}
float getStarWithFade(vec2 uv, vec2 center, float npoints, float radiusRatio, float size, float rotation)
{
float radiusMax = 1.0;
float radiusMin = radiusMax * radiusRatio;
float PI = 3.1415926;
float starangle = 2.0 * PI / npoints; // Angle between points on the star
// Offset rotation to ensure one point is always up when rotation = 0
rotation += PI / 2.0 - starangle / 1.0;
// Define the positions for the outer and inner points of the star's initial angle, rotated by `rotation`
vec3 p0 = (radiusMax * size) * getPosByAngle(rotation); // Outer point, rotated by `rotation`
vec3 p1 = (radiusMin * size) * getPosByAngle(starangle + rotation); // Inner point, also rotated
// Calculate the position of the current fragment relative to the star's center
vec2 curPosuv = (uv - center); // Center UV coordinates, then scale to fit the star size
float curRadius = length(curPosuv); // Radius from center, no need to scale further
float curPosAngle = atan(curPosuv.y, curPosuv.x) - rotation; // Calculate angle and adjust by `rotation`
// Determine the fractional position within the current star segment
float a = fract(curPosAngle / starangle); // Fractional angle position within one segment
if (a >= 0.5)
a = 1.0 - a; // Ensure we are within the first half of the segment (symmetry)
// Calculate the current point on the star segment, applying rotation
a = a * starangle; // Actual angle for this position on the segment
vec3 curPos = curRadius * getPosByAngle(a + rotation); // Final position, rotated
// Calculate directions for edge detection using cross product
vec3 dir0 = p1 - p0; // Vector from outer to inner point
vec3 dir1 = curPos - p0; // Vector from outer point to current position
float crossZ = dir0.x * dir1.y - dir0.y * dir1.x;
float result = remap(
crossZ,
0.0,0.03,//0.0275,
0.0,1.0 //hardness [1.0,100]
);
//brightness
result = result * 7.0;
result = clamp(result,0.0,1.0);
result = easeInSine(result);
return result;
}
vec4 getStarColor(float v, float alpha) {
// Clamp v to ensure it's in [0.0, 1.0]
v = clamp(v, 0.0, 1.0);
// Define steps for color interpolation
float steps[6];
steps[0] = 0.0;
steps[1] = 0.1666;
steps[2] = 0.3332;
steps[3] = 0.4998;
steps[4] = 0.6664;
steps[5] = 0.8330;
// Define color values
vec4 colors[6];
colors[0] = uStarColor0;
colors[1] = uStarColor1;
colors[2] = uStarColor2;
colors[3] = uStarColor3;
colors[4] = uStarColor4;
colors[5] = uStarColor5;
// Assign alpha values
for (int i = 0; i < 6; ++i) {
colors[i].a = alpha * colors[i].a;
}
// Handle edge cases
if (v <= steps[0]) {
return colors[0];
}
if (v >= steps[5]) {
return colors[5];
}
// Find the correct interpolation segment
for (int i = 0; i < 5; ++i) {
if (v <= steps[i + 1]) {
float t = (v - steps[i]) / (steps[i + 1] - steps[i]);
return mix(colors[i], colors[i + 1], t);
}
}
// Fallback (should never be reached)
return vec4(0.0, 0.0, 0.0, 1.0);
}
float zeroStartEnd(float t, float max_size, float power)
{
// 1| __________
// | / \
// | / \
// | / \
// |/ \
// 0|0.................1
/*
graph above ... where t is close to 0, or 1 the result will fade to zero
i.e. this is just the function of power(x,p) shifted
where x is time, and p is 2.0,4.0,8.0,10.0 ... or any positive even number
*/
float s = -1.0 * pow((t-0.5)/(0.5),power)+1.0;
s = clamp(s,0.0,1.0) * max_size;
return s;
}
//this gives us the jerky 8bit growth effect.
float eightBitScale(float progress)
{
float scale = 1.0;
if (progress <= 0.1)
{
scale = 0.25;
}
else if (progress <= 0.2)
{
scale = 0.5;
}
else if (progress <= 0.3)
{
scale = 0.25;
}
else if (progress <= 0.4)
{
scale = 0.5;
}
else if (progress <= 0.5)
{
scale = 0.25;
}
else if (progress <= 0.6)
{
scale = 0.5;
}
else if (progress <= 0.7)
{
scale = 1.0;
}
else if (progress <= 0.8)
{
scale = 0.25;
}
else if (progress <= 0.9)
{
scale = 0.5;
}
return scale;
}
//use to scale the window
vec2 scaleUV(vec2 uv, vec2 scale)
{
// Put texture coordinate origin to center of window.
uv = uv * 2.0 - 1.0;
//scale
uv /= mix(vec2(1.0,1.0), vec2(0.0,0.0), scale);
// scale from center
uv = uv * 0.5 + 0.5;
return uv;
}
vec4 get4pStars(vec2 starUV, float progress)
{
//this will be the result to return
vec4 result = vec4(0.0);
vec2 h = vec2(0.0);
float y = 0.0;
for (float x = 0.0; x < u4PStars; ++x)
{
h = hash21(x);
y = mix( 0.0 - h.y , 1.0+(1.0-h.y) , (1.0 - progress));
float a4ps = getStarWithFade(
starUV,
vec2( sin(h.x * 6.28 ) * 0.66, y), //position (x, y)
4.0, //nPoints
0.33, //radiusRatio
zeroStartEnd(y,0.1 ,4.0), //Size
progress * 6.28 * float(u4PSRotation) //rotation
);
result = alphaOver(
result,
vec4(u4PSColor.r,u4PSColor.g,u4PSColor.b,u4PSColor.a * a4ps)
);
}
// and we are returning the result
return result;
}
vec4 getRays(float progress)
{
vec2 rayUV = iTexCoord.st;
rayUV *= vec2(10.0,0.5);
rayUV.y += progress * -1.0;
float ray = simplex2D(rayUV);
ray *= zeroStartEnd(iTexCoord.t,1.0,8.0);
ray *= zeroStartEnd(progress,1.0,8.0);
ray = remap(
ray * 1.10,
0.0,1.0,
-5.0,1.0
);
ray = clamp(ray,0.0,1.0);
return vec4(uRaysColor.r,uRaysColor.g,uRaysColor.b,uRaysColor.a * ray);
}
vec4 get5PStars(vec2 starUV, float aspect, float progress, float oColorAlpha)
{
//this will be the result to return
vec4 result = vec4(0.0);
vec2 h = vec2(0.0);
float y = 0.0;
//for each ring
for (float r = 0.0; r < uRings; ++r)
{
float spread = r*(1.0/uRings);
y = mix( 0.0 - spread , 1.0+(1.0-spread) , 1.0 - progress);
y = clamp(y,0.00001,0.99999);
//each star in each ring
for (float s = 0.0; s < uStarPerRing; ++s)
{
float a5ps = getStar(
starUV,
vec2( sin(progress * uRingRotation * 6.28 + (s*(6.28/uStarPerRing))) * aspect * 0.33 , y), //position (x, y)
5.0, //nPoints
0.5, //radiusRatio
zeroStartEnd(y,0.1,2.0), //Size
0.0 //rotation
);
a5ps = clamp(a5ps,0.0,1.0);
// //put the star in back or the front of the window
float depth = cos(progress * uRingRotation * 6.28 + (s*(6.28/uStarPerRing)) );
if (depth < 0.0)
{
result = alphaOver(result,getStarColor(y,a5ps));
}
else
{
result = alphaOver(getStarColor(y,a5ps) * (1.0 - oColorAlpha),result);
}
}
}
// and we are returning the result
return result;
}
void main() {
// Calculate the animation progress, flipping direction if opening
// 'uProgress' varies from 0 to 1, depending on the animation phase
float progress = uForOpening ? 1.0 - uProgress : uProgress;
// Initialize the output color to fully transparent black
vec4 oColor = vec4(0.0, 0.0, 0.0, 0.0);
// Check if the 8-bit style is enabled
if (u8BitStyle)
{
// Scale UV coordinates using a custom 8-bit scaling function
float scale8bit = eightBitScale(progress);
// Fetch the color based on the scaled texture coordinates
oColor = getInputColor(
scaleUV(iTexCoord.st, vec2(scale8bit, scale8bit))
);
}
else
{
// Non-8-bit style: Calculate scaling factors using easing functions
vec2 scaleV2 = vec2(easeInOutSine(progress), easeInQuad(progress));
// Fetch the color based on the scaled texture coordinates
oColor = getInputColor(
scaleUV(iTexCoord.st, scaleV2)
);
// Store the alpha value of the fetched color for later use
float oColorAlpha = oColor.a;
// Calculate the aspect ratio of the render area
float aspect = uSize.x / uSize.y;
// Transform UV coordinates for star effects
vec2 starUV = vec2(iTexCoord.s - 0.5, 1.0 - iTexCoord.t) * vec2(aspect, 1.0);
// If four-point stars are enabled, overlay them on the current color
if (uEnable4PStars)
{
oColor = alphaOver(oColor, get4pStars(starUV, progress));
}
// If rays are enabled, overlay them on the current color
if (uEnableRays)
{
oColor = alphaOver(oColor, getRays(progress));
}
// If five-point stars are enabled, overlay them using stored alpha
if (uEnable5pStars)
{
oColor = alphaOver(oColor, get5PStars(starUV, aspect, progress, oColorAlpha));
}
}
// Set the final output color to the computed value
setOutputColor(oColor);
}
+359
View File
@@ -0,0 +1,359 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: Justin Garza <JGarza9788@gmail.com>
SPDX-License-Identifier: GPL-3.0-or-later
-->
<interface domain="burn-my-windows">
<object class="AdwExpanderRow" id="aura-glow-prefs">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Animation Time [ms]</property>
<child>
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">0</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="aura-glow-animation-time">
<property name="upper">3000</property>
<property name="lower">100</property>
<property name="step-increment">10</property>
<property name="page-increment">100</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-aura-glow-animation-time">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Random Color</property>
<property name="activatable-widget">aura-glow-random-color</property>
<child>
<object class="GtkSwitch" id="aura-glow-random-color">
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-aura-glow-random-color">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="aura-glow-action-row">
<property name="title" translatable="yes">Color Offset</property>
<property name="subtitle" translatable="yes">Red</property>
<child>
<object class="GtkScale" id="aura-glow-color-offset-scale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="aura-glow-color-offset">
<property name="upper">1.0</property>
<property name="lower">0.0</property>
<property name="step-increment">0.1</property>
<property name="page-increment">0.33</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-aura-glow-color-offset">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Color Speed</property>
<child>
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="aura-glow-color-speed">
<property name="upper">10.0</property>
<property name="lower">-10.0</property>
<property name="step-increment">0.25</property>
<property name="page-increment">1.0</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-aura-glow-color-speed">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Color Saturation</property>
<child>
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="aura-glow-color-saturation">
<property name="upper">5.0</property>
<property name="lower">0.0</property>
<property name="step-increment">0.10</property>
<property name="page-increment">0.25</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-aura-glow-color-saturation">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- <child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Adjust For Light Theme</property>
<property name="activatable-widget">aura-glow-adjust-light-theme</property>
<child>
<object class="GtkSwitch" id="aura-glow-adjust-light-theme">
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-aura-glow-adjust-light-theme">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child> -->
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Edge Size</property>
<child>
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="aura-glow-edge-size">
<property name="upper">1.0</property>
<property name="lower">0.0</property>
<property name="step-increment">0.05</property>
<property name="page-increment">0.10</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-aura-glow-edge-size">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Edge Shape</property>
<property name="subtitle" translatable="yes">-1.0 (Star-ish) to 2.0 (Square)</property>
<child>
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="aura-glow-edge-shape">
<property name="upper">2.0</property>
<property name="lower">-1.0</property>
<property name="step-increment">0.10</property>
<property name="page-increment">0.25</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-aura-glow-edge-shape">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Edge Hardness</property>
<property name="subtitle" translatable="yes">0.0 (soft/blurry) to 1.0 (sharp/hard)</property>
<child>
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="aura-glow-edge-hardness">
<property name="upper">1.0</property>
<property name="lower">0.0</property>
<property name="step-increment">0.10</property>
<property name="page-increment">0.25</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-aura-glow-edge-hardness">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Blur Amount</property>
<property name="subtitle" translatable="yes">0 is Off</property>
<child>
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="aura-glow-blur">
<property name="upper">100.0</property>
<property name="lower">0.0</property>
<property name="step-increment">0.50</property>
<property name="page-increment">1.00</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-aura-glow-blur">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Fade Out</property>
<child>
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="aura-glow-fade-out">
<property name="upper">0.75</property>
<property name="lower">0.0</property>
<property name="step-increment">0.10</property>
<property name="page-increment">0.25</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-aura-glow-fade-out">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
</object>
</interface>
+468
View File
@@ -0,0 +1,468 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: Justin Garza JGarza9788@gmail.com
SPDX-License-Identifier: GPL-3.0-or-later
-->
<interface domain="burn-my-windows">
<!-- Main container for the mushroom preferences section -->
<object class="AdwExpanderRow" id="mushroom-prefs">
<!-- Animation Time Adjustment Section -->
<child>
<object class="AdwActionRow">
<!-- Title for the animation time adjustment slider -->
<property name="title" translatable="yes">Animation Time [ms]</property>
<child>
<!-- Slider for adjusting animation duration -->
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property> <!-- Display the current value -->
<property name="digits">0</property> <!-- Number of decimal places -->
<property name="value-pos">left</property> <!-- Position of the displayed value -->
<property name="width-request">300</property> <!-- Width of the slider -->
<!-- Adjustment settings for the slider -->
<property name="adjustment">
<object class="GtkAdjustment" id="mushroom-animation-time">
<property name="upper">5000</property> <!-- Maximum value -->
<property name="lower">100</property> <!-- Minimum value -->
<property name="step-increment">10</property> <!-- Smallest increment -->
<property name="page-increment">100</property> <!-- Larger increment -->
</object>
</property>
</object>
</child>
<!-- Button to reset animation time to its default value -->
<child>
<object class="GtkButton" id="reset-mushroom-animation-time">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" /> <!-- Flat button style -->
</style>
</object>
</child>
</object>
</child>
<!-- 8Bit Style Toggle Section -->
<child>
<object class="AdwActionRow">
<!-- Title and description for 8Bit style toggle -->
<property name="title" translatable="yes">8Bit Style</property>
<property name="subtitle" translatable="yes">If ON an old 8Bit Style will be used</property>
<!-- Toggle switch for enabling or disabling 8Bit style -->
<property name="activatable-widget">mushroom-8bit-enable</property>
<child>
<object class="GtkSwitch" id="mushroom-8bit-enable">
<property name="valign">center</property>
</object>
</child>
<!-- Button to reset the 8Bit style toggle to its default value -->
<child>
<object class="GtkButton" id="reset-mushroom-8bit-enable">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Toggle for showing 4-Point Stars (Sparks) -->
<child>
<object class="AdwActionRow">
<!-- Title for enabling or disabling 4-point stars -->
<property name="title" translatable="yes">Show 4Point Stars (Sparks)</property>
<!-- Switch for toggling visibility of 4-point stars -->
<property name="activatable-widget">mushroom-4pstars-enable</property>
<child>
<object class="GtkSwitch" id="mushroom-4pstars-enable">
<property name="valign">center</property>
</object>
</child>
<!-- Button to reset 4-point stars visibility to default -->
<child>
<object class="GtkButton" id="reset-mushroom-4pstars-enable">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Adjustment for 4-Point Stars Count -->
<child>
<object class="AdwActionRow">
<!-- Title for the slider controlling the count of 4-point stars -->
<property name="title" translatable="yes">4Point Star (Sparks) Count</property>
<!-- Slider for adjusting the count of 4-point stars -->
<child>
<object class="GtkScale" id="mushroom-4pstars-count-scale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">0</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<!-- Adjustment settings for the slider -->
<property name="adjustment">
<object class="GtkAdjustment" id="mushroom-4pstars-count">
<property name="upper">100</property> <!-- Maximum count -->
<property name="lower">0</property> <!-- Minimum count -->
<property name="step-increment">1</property> <!-- Step size -->
<property name="page-increment">5</property> <!-- Page increment size -->
</object>
</property>
</object>
</child>
<!-- Button to reset 4-point stars count to default -->
<child>
<object class="GtkButton" id="reset-mushroom-4pstars-count">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Color Picker for 4-Point Stars -->
<child>
<object class="AdwActionRow">
<!-- Title for the 4-point stars color picker -->
<property name="title" translatable="yes">4Point Star (Sparks) Color</property>
<!-- Color picker for customizing the 4-point stars -->
<child>
<object class="GtkBox">
<style>
<class name="linked" />
</style>
<child>
<object class="GtkColorButton" id="mushroom-4pstars-color">
<property name="use_alpha">1</property> <!-- Enable alpha channel -->
<property name="show_editor">1</property> <!-- Show advanced editor -->
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<!-- Button to reset the color picker to default -->
<child>
<object class="GtkButton" id="reset-mushroom-4pstars-color">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Rays Toggle -->
<child>
<object class="AdwActionRow">
<!-- Title for enabling or disabling rays -->
<property name="title" translatable="yes">Show Rays</property>
<!-- Toggle switch for controlling the visibility of rays -->
<property name="activatable-widget">mushroom-rays-enable</property>
<child>
<object class="GtkSwitch" id="mushroom-rays-enable">
<property name="valign">center</property>
</object>
</child>
<!-- Button to reset the rays toggle to its default value -->
<child>
<object class="GtkButton" id="reset-mushroom-rays-enable">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Rays Color Picker -->
<child>
<object class="AdwActionRow">
<!-- Title for the rays color picker -->
<property name="title" translatable="yes">Rays Color</property>
<!-- Color picker for customizing rays -->
<child>
<object class="GtkBox">
<style>
<class name="linked" />
</style>
<child>
<object class="GtkColorButton" id="mushroom-rays-color">
<property name="use_alpha">1</property> <!-- Enable alpha channel -->
<property name="show_editor">1</property> <!-- Show advanced editor -->
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<!-- Button to reset the rays color picker to its default value -->
<child>
<object class="GtkButton" id="reset-mushroom-rays-color">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Star Rings Toggle -->
<child>
<object class="AdwActionRow">
<!-- Title for enabling or disabling star rings -->
<property name="title" translatable="yes">Show Star Rings</property>
<!-- Toggle switch for controlling the visibility of star rings -->
<property name="activatable-widget">mushroom-5pstars-enable</property>
<child>
<object class="GtkSwitch" id="mushroom-5pstars-enable">
<property name="valign">center</property>
</object>
</child>
<!-- Button to reset the star rings toggle to its default value -->
<child>
<object class="GtkButton" id="reset-mushroom-5pstars-enable">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Star Rings Count Adjustment -->
<child>
<object class="AdwActionRow">
<!-- Title for the slider controlling the number of star rings -->
<property name="title" translatable="yes">Star Rings Count</property>
<!-- Slider for adjusting the number of star rings -->
<child>
<object class="GtkScale" id="mushroom-5pstarring-count-scale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">0</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<!-- Adjustment settings for the slider -->
<property name="adjustment">
<object class="GtkAdjustment" id="mushroom-5pstarring-count">
<property name="upper">10</property> <!-- Maximum count -->
<property name="lower">1</property> <!-- Minimum count -->
<property name="step-increment">1</property> <!-- Step size -->
<property name="page-increment">3</property> <!-- Page increment size -->
</object>
</property>
</object>
</child>
<!-- Button to reset the star rings count to its default value -->
<child>
<object class="GtkButton" id="reset-mushroom-5pstarring-count">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Star Rings Rotation Adjustment -->
<child>
<object class="AdwActionRow">
<!-- Title for the slider controlling the rotation of star rings -->
<property name="title" translatable="yes">Star Ring Rotation</property>
<!-- Slider for adjusting the rotation of star rings -->
<child>
<object class="GtkScale" id="mushroom-5pstarring-rotation-scale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<!-- Adjustment settings for the slider -->
<property name="adjustment">
<object class="GtkAdjustment" id="mushroom-5pstarring-rotation">
<property name="upper">5.0</property> <!-- Maximum rotation -->
<property name="lower">-5.0</property> <!-- Minimum rotation -->
<property name="step-increment">0.25</property> <!-- Step size -->
<property name="page-increment">1.0</property> <!-- Page increment size -->
</object>
</property>
</object>
</child>
<!-- Button to reset the star rings rotation to its default value -->
<child>
<object class="GtkButton" id="reset-mushroom-5pstarring-rotation">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Stars Per Star Ring Count Adjustment -->
<child>
<object class="AdwActionRow">
<!-- Title for the slider controlling the number of stars per ring -->
<property name="title" translatable="yes">Stars Per Star Ring Count</property>
<!-- Slider for adjusting the number of stars per star ring -->
<child>
<object class="GtkScale" id="mushroom-5pstars-count-scale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">0</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<!-- Adjustment settings for the slider -->
<property name="adjustment">
<object class="GtkAdjustment" id="mushroom-5pstars-count">
<property name="upper">10</property> <!-- Maximum stars per ring -->
<property name="lower">1</property> <!-- Minimum stars per ring -->
<property name="step-increment">1</property> <!-- Step size -->
<property name="page-increment">3</property> <!-- Page increment size -->
</object>
</property>
</object>
</child>
<!-- Button to reset the stars per ring count to its default value -->
<child>
<object class="GtkButton" id="reset-mushroom-5pstars-count">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Star Color Presets -->
<child>
<object class="AdwActionRow">
<!-- Title for selecting color presets -->
<property name="title" translatable="yes">Color Presets</property>
<property name="activatable-widget">mushroom-star-color-preset-button</property>
<!-- Dropdown menu for selecting predefined color presets -->
<child>
<object class="GtkMenuButton" id="mushroom-star-color-preset-button">
<property name="valign">center</property>
<property name="label" translatable="yes">Choose a Preset</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Star Gradient Color Adjustment -->
<child>
<object class="AdwActionRow">
<!-- Title for the star gradient color settings -->
<property name="title" translatable="yes">Star Gradient</property>
<!-- Box containing multiple color pickers for gradient customization -->
<child>
<object class="GtkBox">
<style>
<class name="linked" />
</style>
<!-- Individual color pickers for each gradient step -->
<child>
<object class="GtkColorButton" id="mushroom-star-color-0">
<property name="use_alpha">1</property> <!-- Enable alpha channel -->
<property name="show_editor">1</property> <!-- Show advanced editor -->
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkColorButton" id="mushroom-star-color-1">
<property name="use_alpha">1</property>
<property name="show_editor">1</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkColorButton" id="mushroom-star-color-2">
<property name="use_alpha">1</property>
<property name="show_editor">1</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkColorButton" id="mushroom-star-color-3">
<property name="use_alpha">1</property>
<property name="show_editor">1</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkColorButton" id="mushroom-star-color-4">
<property name="use_alpha">1</property>
<property name="show_editor">1</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkColorButton" id="mushroom-star-color-5">
<property name="use_alpha">1</property>
<property name="show_editor">1</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<!-- Button to reset all star gradient colors to their default values -->
<child>
<object class="GtkButton" id="reset-star-colors">
<property name="icon-name">edit-clear-symbolic</property> <!-- Reset icon -->
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
</object>
</interface>
@@ -823,7 +823,7 @@ SPDX-License-Identifier: CC0-1.0
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Simple Fade Effect Options -->
<!-- Focus Effect Options -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<key name="focus-enable-effect" type="b">
@@ -850,6 +850,203 @@ SPDX-License-Identifier: CC0-1.0
<description>The Quality of the Blur (Setting this too high may increase GPU load and affect performance)</description>
</key>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Mushroom Effect Options -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<key name="mushroom-enable-effect" type="b">
<default>false</default>
<summary>mushroom Enable Effect</summary>
<description>Use the mushroom effect.</description>
</key>
<key name="mushroom-animation-time" type="i">
<default>1500</default>
<summary>mushroom Animation Time</summary>
<description>The time the mushroom effect takes.</description>
</key>
<key name="mushroom-8bit-enable" type="b">
<default>true</default>
<summary>mushroom 8Bit Animation</summary>
<description>use the old style.</description>
</key>
<key name="mushroom-4pstars-enable" type="b">
<default>true</default>
<summary>Enable the 4Pointed Stars</summary>
<description>Enable the 4Pointed Stars</description>
</key>
<key name="mushroom-4pstars-count" type="i">
<default>4</default>
<summary>The Number of 4Pointed Stars</summary>
<description>The Number of 4Pointed Stars</description>
</key>
<key name="mushroom-4pstars-color" type="s">
<default>"rgba(255, 255, 255, 1.0)"</default>
<summary>The 4Pointed Star Color</summary>
<description>The 4Pointed Star Color</description>
</key>
<key name="mushroom-4pstars-rotation" type="d">
<default>0.3</default>
<summary>The Number of Rotations the 4Pointed Stars do</summary>
<description>The Number of Rotations the 4Pointed Stars do</description>
</key>
<key name="mushroom-rays-enable" type="b">
<default>true</default>
<summary>Enable the Rays</summary>
<description>use the old style.</description>
</key>
<key name="mushroom-rays-color" type="s">
<default>"rgba(255, 255, 255, 1.0)"</default>
<summary>The Rays Color</summary>
<description>The Rays Color</description>
</key>
<key name="mushroom-5pstars-enable" type="b">
<default>true</default>
<summary>Enable the 5 Pointed Stars</summary>
<description>Enable the 5 Pointed Stars</description>
</key>
<key name="mushroom-5pstarring-count" type="i">
<default>3</default>
<summary>Number of Rings of 5Pointed Stars</summary>
<description>Number of Rings of 5 Pointed Stars</description>
</key>
<key name="mushroom-5pstarring-rotation" type="d">
<default>1.33</default>
<summary>The Number of Rotations/Cycles the 5Pointed Stars do</summary>
<description>The Number of Rotations/Cycles the 5Pointed Stars do</description>
</key>
<key name="mushroom-5pstars-count" type="i">
<default>5</default>
<summary>The Number of 5Pointed Stars in each Ring</summary>
<description>The Number of 5Pointed Stars in each Ring</description>
</key>
<key name="mushroom-star-color-0" type="s">
<default>"rgba(233, 249, 1, 1.0)"</default>
<summary>Star Color 1</summary>
<description>The Nth color of the Star gradient.</description>
</key>
<key name="mushroom-star-color-1" type="s">
<default>"rgba(233, 249, 1, 1.0)"</default>
<summary>Star Color 1</summary>
<description>The Nth color of the Star gradient.</description>
</key>
<key name="mushroom-star-color-2" type="s">
<default>"rgba(91, 255, 1, 1.0)"</default>
<summary>Star Color 1</summary>
<description>The Nth color of the Star gradient.</description>
</key>
<key name="mushroom-star-color-3" type="s">
<default>"rgba(91, 255, 1, 1.0)"</default>
<summary>Star Color 1</summary>
<description>The Nth color of the Star gradient.</description>
</key>
<key name="mushroom-star-color-4" type="s">
<default>"rgba(0, 240, 236, 1.0)"</default>
<summary>Star Color 1</summary>
<description>The Nth color of the Star gradient.</description>
</key>
<key name="mushroom-star-color-5" type="s">
<default>"rgba(0, 240, 236, 1.0)"</default>
<summary>Star Color 1</summary>
<description>The Nth color of the Star gradient.</description>
</key>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Aura Glow Effect Options -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<key name="aura-glow-enable-effect" type="b">
<default>false</default>
<summary>Aura Glow Enable Effect</summary>
<description>Use the Aura Glow effect.</description>
</key>
<key name="aura-glow-animation-time" type="i">
<default>1500</default>
<summary>Aura Glow Animation Time</summary>
<description>The time the Aura Glow effect takes.</description>
</key>
<key name="aura-glow-random-color" type="b">
<default>false</default>
<summary>Aura Glow Random Color Offset</summary>
<description>Ramdomize the color offset</description>
</key>
<key name="aura-glow-color-offset" type="d">
<default>0.0</default>
<summary>Aura Glow Color Offset</summary>
<description>Changes the inital color of the glow</description>
</key>
<key name="aura-glow-color-speed" type="d">
<default>1.0</default>
<summary>Aura Glow Color Speed</summary>
<description>The Speed at which the color changes</description>
</key>
<key name="aura-glow-color-saturation" type="d">
<default>1.0</default>
<summary>Aura Glow Color Saturation</summary>
<description>Amount of color in the effect</description>
</key>
<!-- <key name="aura-glow-adjust-light-theme" type="b">
<default>false</default>
<summary>Aura Glow Adjust for light theme</summary>
<description>darken the window before adding color for light theme</description>
</key> -->
<key name="aura-glow-edge-size" type="d">
<default>1.0</default>
<summary>Aura Glow Size of the Color Edge</summary>
<description>Size of the Color Edge</description>
</key>
<key name="aura-glow-edge-shape" type="d">
<default>-1.0</default>
<summary>Aura Glow Edge Shape</summary>
<description>The Shape at the end of the animation</description>
</key>
<key name="aura-glow-edge-hardness" type="d">
<default>0.0</default>
<summary>Aura Glow Edge Hardness</summary>
<description>The Hardness of the Edge</description>
</key>
<key name="aura-glow-blur" type="d">
<default>50.0</default>
<summary>Aura Glow Blur</summary>
<description>Changes the Blue Amount</description>
</key>
<key name="aura-glow-fade-out" type="d">
<default>0.0</default>
<summary>Aura Glow Fade Out</summary>
<description>The Percent at which the window will fade out</description>
</key>
</schema>
</schemalist>
</schemalist>
+135 -137
View File
@@ -47,166 +47,164 @@ import * as utils from './utils.js';
// used to clean up any resources.
//////////////////////////////////////////////////////////////////////////////////////////
export var Shader = GObject.registerClass(
{
Signals: {
'begin-animation': {
param_types: [
Gio.Settings.$gtype, GObject.TYPE_BOOLEAN, GObject.TYPE_BOOLEAN,
Clutter.Actor.$gtype
]
},
'update-animation': {param_types: [GObject.TYPE_DOUBLE]},
'end-animation': {}
}
},
class Shader extends Shell.GLSLEffect { // --------------------------------------------
// The constructor automagically loads the shader's source code (in
// vfunc_build_pipeline()) from the resource file resources/shaders/<nick>.glsl
// resolving any #includes in this file.
_init(nick) {
this._nick = nick;
export var Shader = GObject.registerClass({
Signals: {
'begin-animation': {
param_types: [
Gio.Settings.$gtype, GObject.TYPE_BOOLEAN, GObject.TYPE_BOOLEAN,
Clutter.Actor.$gtype
]
},
'update-animation': {param_types: [GObject.TYPE_DOUBLE]},
'end-animation': {}
}
},
class Shader extends Shell.GLSLEffect{
// --------------------------------------------
// The constructor automagically loads the shader's source code (in
// vfunc_build_pipeline()) from the resource file resources/shaders/<nick>.glsl
// resolving any #includes in this file.
_init(nick) {
this._nick = nick;
// This will call vfunc_build_pipeline().
super._init();
// This will call vfunc_build_pipeline().
super._init();
// These will be updated during the animation.
this._progress = 0;
this._time = 0;
// These will be updated during the animation.
this._progress = 0;
this._time = 0;
// Store standard uniform locations.
this._uForOpening = this.get_uniform_location('uForOpening');
this._uIsFullscreen = this.get_uniform_location('uIsFullscreen');
this._uProgress = this.get_uniform_location('uProgress');
this._uDuration = this.get_uniform_location('uDuration');
this._uSize = this.get_uniform_location('uSize');
this._uPadding = this.get_uniform_location('uPadding');
// Store standard uniform locations.
this._uForOpening = this.get_uniform_location('uForOpening');
this._uIsFullscreen = this.get_uniform_location('uIsFullscreen');
this._uProgress = this.get_uniform_location('uProgress');
this._uDuration = this.get_uniform_location('uDuration');
this._uSize = this.get_uniform_location('uSize');
this._uPadding = this.get_uniform_location('uPadding');
// Create a timeline to drive the animation.
this._timeline = new Clutter.Timeline();
// Create a timeline to drive the animation.
this._timeline = new Clutter.Timeline();
// Call updateAnimation() once a frame.
this._timeline.connect('new-frame', (t) => {
if (this._testMode) {
this.updateAnimation(0.5);
} else {
this.updateAnimation(t.get_progress());
}
});
// Clean up if the animation finished or was interrupted.
this._timeline.connect('stopped', (t, finished) => {
this.endAnimation();
});
}
// This is called once each time the shader is used.
beginAnimation(settings, forOpening, testMode, duration, actor) {
if (this._timeline.is_playing()) {
this._timeline.stop();
// Call updateAnimation() once a frame.
this._timeline.connect('new-frame', (t) => {
if (this._testMode) {
this.updateAnimation(0.5);
} else {
this.updateAnimation(t.get_progress());
}
});
// On GNOME 3.36 this method was not yet available.
if (this._timeline.set_actor) {
this._timeline.set_actor(actor);
}
// Clean up if the animation finished or was interrupted.
this._timeline.connect('stopped', (t, finished) => {
this.endAnimation();
});
}
this._timeline.set_duration(duration);
this._timeline.start();
// Make sure that no fullscreen window is drawn over our animations.
Meta.disable_unredirect_for_display(global.display);
global.begin_work();
// Reset progress value.
this._progress = 0;
this._testMode = testMode;
// This is not necessarily symmetric, but I haven't figured out a way to
// get the actual values...
const padding = (actor.width - actor.meta_window.get_frame_rect().width) / 2;
const isFullscreen =
actor.meta_window.get_maximized() === Meta.MaximizeFlags.BOTH ||
actor.meta_window.fullscreen;
this.set_uniform_float(this._uPadding, 1, [padding]);
this.set_uniform_float(this._uForOpening, 1, [forOpening]);
this.set_uniform_float(this._uIsFullscreen, 1, [isFullscreen]);
this.set_uniform_float(this._uDuration, 1, [duration * 0.001]);
this.set_uniform_float(this._uSize, 2, [actor.width, actor.height]);
this.emit('begin-animation', settings, forOpening, testMode, actor);
// This is called once each time the shader is used.
beginAnimation(settings, forOpening, testMode, duration, actor) {
if (this._timeline.is_playing()) {
this._timeline.stop();
}
// This is called at each frame during the animation.
updateAnimation(progress) {
// Store the current progress value. The corresponding signal is emitted each frame
// in vfunc_paint_target. We do not emit it here, as the pipeline which may be used
// by handlers must not have been created yet.
this._progress = progress;
this.queue_repaint();
// On GNOME 3.36 this method was not yet available.
if (this._timeline.set_actor) {
this._timeline.set_actor(actor);
}
// This will stop any running animation and emit the end-animation signal.
endAnimation() {
// This will call endAnimation() again, so we can return for now.
if (this._timeline.is_playing()) {
this._timeline.stop();
return;
}
this._timeline.set_duration(duration);
this._timeline.start();
// Restore unredirecting behavior for fullscreen windows.
Meta.enable_unredirect_for_display(global.display);
global.end_work();
// Make sure that no fullscreen window is drawn over our animations.
Meta.disable_unredirect_for_display(global.display);
global.begin_work();
this.emit('end-animation');
// Reset progress value.
this._progress = 0;
this._testMode = testMode;
// This is not necessarily symmetric, but I haven't figured out a way to
// get the actual values...
const padding = (actor.width - actor.meta_window.get_frame_rect().width) / 2;
const isFullscreen = actor.meta_window.get_maximized() === Meta.MaximizeFlags.BOTH ||
actor.meta_window.fullscreen;
this.set_uniform_float(this._uPadding, 1, [padding]);
this.set_uniform_float(this._uForOpening, 1, [forOpening]);
this.set_uniform_float(this._uIsFullscreen, 1, [isFullscreen]);
this.set_uniform_float(this._uDuration, 1, [duration * 0.001]);
this.set_uniform_float(this._uSize, 2, [actor.width, actor.height]);
this.emit('begin-animation', settings, forOpening, testMode, actor);
}
// This is called at each frame during the animation.
updateAnimation(progress) {
// Store the current progress value. The corresponding signal is emitted each frame
// in vfunc_paint_target. We do not emit it here, as the pipeline which may be used
// by handlers must not have been created yet.
this._progress = progress;
this.queue_repaint();
}
// This will stop any running animation and emit the end-animation signal.
endAnimation() {
// This will call endAnimation() again, so we can return for now.
if (this._timeline.is_playing()) {
this._timeline.stop();
return;
}
// This is called by the constructor. This means, it's only called when the
// effect is used for the first time.
vfunc_build_pipeline() {
// Restore unredirecting behavior for fullscreen windows.
Meta.enable_unredirect_for_display(global.display);
global.end_work();
// Shell.GLSLEffect requires the declarations and the main source code as separate
// strings. As it's more convenient to store the in one GLSL file, we use a regex
// here to split the source code in two parts.
const code = this._loadShaderResource(`/shaders/${this._nick}.frag`);
this.emit('end-animation');
}
// Match anything between the curly brackets of "void main() {...}".
const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}');
const match = regex.exec(code);
// This is called by the constructor. This means, it's only called when the
// effect is used for the first time.
vfunc_build_pipeline() {
// Shell.GLSLEffect requires the declarations and the main source code as separate
// strings. As it's more convenient to store the in one GLSL file, we use a regex
// here to split the source code in two parts.
const code = this._loadShaderResource(`/shaders/${this._nick}.frag`);
const declarations = code.substr(0, match.index);
const main = match[1];
// Match anything between the curly brackets of "void main() {...}".
const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}');
const match = regex.exec(code);
this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true);
}
const declarations = code.substr(0, match.index);
const main = match[1];
// We use this vfunc to trigger the update as it allows calling this.get_pipeline() in
// the handler. This could still be null if called from the updateAnimation() above.
vfunc_paint_target(...params) {
this.emit('update-animation', this._progress);
this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true);
}
// Starting with GNOME 44.2, the alpha channel is not written to by default. We need
// to undo this. It is a pity that we have to do this here, as it is not really
// required to be done each frame. But it's the only place where we can do it.
// https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2650
this.get_pipeline().set_blend(
'RGBA = ADD (SRC_COLOR * (SRC_COLOR[A]), DST_COLOR * (1-SRC_COLOR[A]))');
// We use this vfunc to trigger the update as it allows calling this.get_pipeline() in
// the handler. This could still be null if called from the updateAnimation() above.
vfunc_paint_target(...params) {
this.emit('update-animation', this._progress);
this.set_uniform_float(this._uProgress, 1, [this._progress]);
super.vfunc_paint_target(...params);
}
// Starting with GNOME 44.2, the alpha channel is not written to by default. We need
// to undo this. It is a pity that we have to do this here, as it is not really
// required to be done each frame. But it's the only place where we can do it.
// https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2650
this.get_pipeline().set_blend(
'RGBA = ADD (SRC_COLOR * (SRC_COLOR[A]), DST_COLOR * (1-SRC_COLOR[A]))');
// --------------------------------------------------------------------- private stuff
this.set_uniform_float(this._uProgress, 1, [this._progress]);
super.vfunc_paint_target(...params);
}
// This loads a GLSL file from the extension's resources to a JavaScript string. The
// code from "common.glsl" is prepended automatically.
_loadShaderResource(path) {
let common = utils.getStringResource('/shaders/common.glsl');
let code = utils.getStringResource(path);
// --------------------------------------------------------------------- private stuff
// Add a trailing newline. Else the GLSL compiler complains...
return common + '\n' + code + '\n';
}
});
// This loads a GLSL file from the extension's resources to a JavaScript string. The
// code from "common.glsl" is prepended automatically.
_loadShaderResource(path) {
let common = utils.getStringResource('/shaders/common.glsl');
let code = utils.getStringResource(path);
// Add a trailing newline. Else the GLSL compiler complains...
return common + '\n' + code + '\n';
}
});
+1 -1
View File
@@ -61,7 +61,7 @@ export default class ShaderFactory {
// Only try to register the new type once.
if (GObject.type_from_name(typeName) == null) {
const outerThis = this;
GObject.registerClass({GTypeName: typeName}, class ShaderImp extends Shader {
GObject.registerClass({GTypeName: typeName}, class ShaderImp extends Shader{
// This will actually load the GLSL source code from the resources.
_init() {
super._init(outerThis._nick);
+233
View File
@@ -0,0 +1,233 @@
//////////////////////////////////////////////////////////////////////////////////////////
// ) ( //
// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< //
// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ //
// |__/ //
//////////////////////////////////////////////////////////////////////////////////////////
// SPDX-FileCopyrightText: Justin Garza <JGarza9788@gmail.com>
// SPDX-License-Identifier: GPL-3.0-or-later
'use strict';
import * as utils from '../utils.js';
// We import the ShaderFactory only in the Shell process as it is not required in the
// preferences process. The preferences process does not create any shader instances, it
// only uses the static metadata of the effect.
const ShaderFactory = await utils.importInShellOnly('./ShaderFactory.js');
const _ = await utils.importGettext();
//////////////////////////////////////////////////////////////////////////////////////////
// This effect was inspired by apple's new siri effect. //
//////////////////////////////////////////////////////////////////////////////////////////
// The effect class can be used to get some metadata (like the effect's name or supported
// GNOME Shell versions), to initialize the respective page of the settings dialog, as
// well as to create the actual shader for the effect.
export default class Effect {
// The constructor creates a ShaderFactory which will be used by extension.js to create
// shader instances for this effect. The shaders will be automagically created using the
// GLSL file in resources/shaders/<nick>.glsl. The callback will be called for each
// newly created shader instance.
constructor() {
this.shaderFactory = new ShaderFactory(Effect.getNick(), (shader) => {
// Store uniform locations of newly created shaders.
shader._uColorSpeed = shader.get_uniform_location('uColorSpeed');
shader._uRandomColorOffset = shader.get_uniform_location('uRandomColorOffset');
shader._uColorOffset = shader.get_uniform_location('uColorOffset');
shader._uColorSaturation = shader.get_uniform_location('uColorSaturation');
shader._uEdgeSize = shader.get_uniform_location('uEdgeSize');
shader._uEdgeShape = shader.get_uniform_location('uEdgeShape');
shader._uEdgeHardness = shader.get_uniform_location('uEdgeHardness');
shader._uBlur = shader.get_uniform_location('uBlur');
shader._uFadeOut = shader.get_uniform_location('uFadeOut');
shader._uSeed = shader.get_uniform_location('uSeed');
// Write all uniform values at the start of each animation.
shader.connect('begin-animation', (shader, settings) => {
shader.set_uniform_float(shader._uColorSpeed, 1, [
settings.get_double('aura-glow-color-speed'),
]);
shader.set_uniform_float(shader._uRandomColorOffset, 1,
[settings.get_boolean('aura-glow-random-color')]);
shader.set_uniform_float(shader._uColorOffset, 1, [
settings.get_double('aura-glow-color-offset'),
]);
shader.set_uniform_float(shader._uColorSaturation, 1, [
settings.get_double('aura-glow-color-saturation'),
]);
shader.set_uniform_float(shader._uEdgeSize, 1, [
settings.get_double('aura-glow-edge-size'),
]);
shader.set_uniform_float(shader._uEdgeShape, 1, [
settings.get_double('aura-glow-edge-shape'),
]);
shader.set_uniform_float(shader._uEdgeHardness, 1, [
settings.get_double('aura-glow-edge-hardness'),
]);
shader.set_uniform_float(shader._uBlur, 1, [
settings.get_double('aura-glow-blur'),
]);
shader.set_uniform_float(shader._uFadeOut, 1, [
settings.get_double('aura-glow-fade-out'),
]);
// shader.set_uniform_float(shader._uLightTheme, 1, [
// Effect.getCurrentThemeMode(),
// ]);
// this will be used with a has function to get a random number
// clang-format off
shader.set_uniform_float(shader._uSeed, 2, [Math.random(), Math.random()]);
// clang-format on
});
});
}
// ---------------------------------------------------------------------------- metadata
// The effect is available on all GNOME Shell versions supported by this extension.
static getMinShellVersion() {
return [3, 36];
}
// This will be called in various places where a unique identifier for this effect is
// required. It should match the prefix of the settings keys which store whether the
// effect is enabled currently (e.g. '*-enable-effect'), and its animation time
// (e.g. '*-animation-time'). Also, the shader file and the settings UI files should be
// named likes this.
static getNick() {
return 'aura-glow';
}
// This will be shown in the sidebar of the preferences dialog as well as in the
// drop-down menus where the user can choose the effect.
static getLabel() {
return _('Aura Glow');
}
// -------------------------------------------------------------------- API for prefs.js
// This is called by the preferences dialog whenever a new effect profile is loaded. It
// binds all user interface elements to the respective settings keys of the profile.
static bindPreferences(dialog) {
// Empty for now... Code is added here later in the tutorial!
dialog.bindAdjustment('aura-glow-animation-time');
dialog.bindAdjustment('aura-glow-color-speed');
dialog.bindSwitch('aura-glow-random-color');
dialog.bindAdjustment('aura-glow-color-offset');
dialog.bindAdjustment('aura-glow-color-saturation');
dialog.bindAdjustment('aura-glow-edge-size');
dialog.bindAdjustment('aura-glow-edge-shape');
dialog.bindAdjustment('aura-glow-edge-hardness');
dialog.bindAdjustment('aura-glow-blur');
dialog.bindAdjustment('aura-glow-fade-out');
// enable and disable the one slider
function EnableDisablePref(dialog, state) {
dialog.getBuilder()
.get_object('aura-glow-color-offset-scale')
.set_sensitive(!state);
}
const switchWidget = dialog.getBuilder().get_object('aura-glow-random-color');
if (switchWidget) {
// Connect to the "state-set" signal to update preferences dynamically based on
// the switch state.
switchWidget.connect('state-set', (widget, state) => {
EnableDisablePref(dialog, state); // Update sensitivity when the state changes.
});
// Manually call the update function on startup, using the initial state of the
// switch.
const initialState =
switchWidget.get_active(); // Get the current state of the switch.
EnableDisablePref(dialog, initialState);
} else {
// Log an error if the switch widget is not found in the UI.
log('Error: \'aura-glow-random-color\' switch widget not found.');
}
// Retrieve the necessary objects
const colorOffset = dialog.getBuilder().get_object('aura-glow-color-offset-scale');
const actionRow = dialog.getBuilder().get_object('aura-glow-action-row');
if (colorOffset == null)
{
log('colorOffset is null');
}
// Define an array of color names based on the slider value
const colorNames = [
'Red', // 0.00
'Reddish-Orange', // 0.05
'Orange', // 0.10
'Yellow-Orange', // 0.15
'Yellow-Green', // 0.20
'Lime Green', // 0.25
'Green', // 0.30
'Greenish-Cyan', // 0.35
'Aqua', // 0.40
'Light Cyan', // 0.45
'Cyan', // 0.50
'Sky Cyan', // 0.55
'Sky Blue', // 0.60
'Light Blue', // 0.65
'Blue', // 0.70
'Indigo', // 0.75
'Purple', // 0.80
'Magenta', // 0.85
'Pinkish-Red', // 0.90
'Crimson', // 0.95
'Red' // 1.00 (wraps around)
];
// Function to update the subtitle based on the slider value
const updateSubtitle = () => {
const value = colorOffset.get_value(); // Get the current slider value
const index = Math.round(value * 20); // Map value [0.0, 1.0] to index [0, 10]
actionRow.set_subtitle(
colorNames[index]); // Update subtitle with the corresponding color
};
// Connect the value-changed signal to the updateSubtitle function
// Connect the value-changed signal to the updateSubtitle function
colorOffset.connect('value-changed', updateSubtitle);
// Initialize the subtitle on load
updateSubtitle();
}
// ---------------------------------------------------------------- API for extension.js
// The getActorScale() is called from extension.js to adjust the actor's size during the
// animation. This is useful if the effect requires drawing something beyond the usual
// bounds of the actor. This only works for GNOME 3.38+.
static getActorScale(settings, forOpening, actor) {
return {x: 1.0, y: 1.0};
}
}
+531
View File
@@ -0,0 +1,531 @@
//////////////////////////////////////////////////////////////////////////////////////////
// ) ( //
// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< //
// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ //
// |__/ //
//////////////////////////////////////////////////////////////////////////////////////////
// SPDX-FileCopyrightText: Justin Garza JGarza9788@gmail.com
// SPDX-License-Identifier: GPL-3.0-or-later
'use strict';
// Import the Gio module from the GNOME platform (GObject Introspection).
// This module provides APIs for I/O operations, settings management, and other core
// features.
import Gio from 'gi://Gio';
// Import utility functions from the local utils.js file.
// These utilities likely contain helper functions or shared logic used across the
// application.
import * as utils from '../utils.js';
// We import the ShaderFactory only in the Shell process as it is not required in the
// preferences process. The preferences process does not create any shader instances, it
// only uses the static metadata of the effect.
const ShaderFactory = await utils.importInShellOnly('./ShaderFactory.js');
const _ = await utils.importGettext();
//////////////////////////////////////////////////////////////////////////////////////////
// This effect was obviously inspired my the 8bit mario video games of old, specifically//
// when mario gets the mushroom. i hope you enjoy this little blast from the past. //
//////////////////////////////////////////////////////////////////////////////////////////
// The effect class can be used to get some metadata (like the effect's name or supported
// GNOME Shell versions), to initialize the respective page of the settings dialog, as
// well as to create the actual shader for the effect.
export default class Effect {
// The constructor creates a ShaderFactory which will be used by extension.js to create
// shader instances for this effect. The shaders will be automagically created using the
// GLSL file in resources/shaders/<nick>.glsl. The callback will be called for each
// newly created shader instance.
constructor() {
this.shaderFactory = new ShaderFactory(Effect.getNick(), (shader) => {
// very basic effect... so nothing here
shader._uGradient = [
shader.get_uniform_location('uStarColor0'),
shader.get_uniform_location('uStarColor1'),
shader.get_uniform_location('uStarColor2'),
shader.get_uniform_location('uStarColor3'),
shader.get_uniform_location('uStarColor4'),
shader.get_uniform_location('uStarColor5'),
];
shader._u8BitStyle = shader.get_uniform_location('u8BitStyle');
shader._uEnable4PStars = shader.get_uniform_location('uEnable4PStars');
shader._u4PStars = shader.get_uniform_location('u4PStars');
shader._u4PSColor = shader.get_uniform_location('u4PSColor');
shader._u4PSRotation = shader.get_uniform_location('u4PSRotation');
shader._uEnableRays = shader.get_uniform_location('uEnableRays');
shader._uRaysColor = shader.get_uniform_location('uRaysColor');
shader._uEnable5pStars = shader.get_uniform_location('uEnable5pStars');
shader._uRings = shader.get_uniform_location('uRings');
shader._uRingRotation = shader.get_uniform_location('uRingRotation');
shader._uStarPerRing = shader.get_uniform_location('uStarPerRing');
// And update all uniforms at the start of each animation.
shader.connect('begin-animation', (shader, settings) => {
for (let i = 0; i <= 5; i++) {
shader.set_uniform_float(
shader._uGradient[i], 4,
utils.parseColor(settings.get_string('mushroom-star-color-' + i)));
}
// clang-format off
shader.set_uniform_float(shader._u8BitStyle, 1, [settings.get_boolean('mushroom-8bit-enable')]);
shader.set_uniform_float(shader._uEnable4PStars, 1, [settings.get_boolean('mushroom-4pstars-enable')]);
shader.set_uniform_float(shader._u4PStars, 1, [settings.get_int('mushroom-4pstars-count')]);
shader.set_uniform_float(shader._u4PSColor, 4, utils.parseColor(settings.get_string('mushroom-4pstars-color')));
shader.set_uniform_float(shader._u4PSRotation, 1, [settings.get_double('mushroom-4pstars-rotation')]);
shader.set_uniform_float(shader._uEnableRays, 1, [settings.get_boolean('mushroom-rays-enable')]);
shader.set_uniform_float(shader._uRaysColor, 4, utils.parseColor(settings.get_string('mushroom-rays-color')));
shader.set_uniform_float(shader._uEnable5pStars, 1, [settings.get_boolean('mushroom-5pstars-enable')]);
shader.set_uniform_float(shader._uRings, 1, [settings.get_int('mushroom-5pstarring-count')]);
shader.set_uniform_float(shader._uRingRotation, 1, [settings.get_double('mushroom-5pstarring-rotation')]);
shader.set_uniform_float(shader._uStarPerRing, 1, [settings.get_int('mushroom-5pstars-count')]);
// clang-format on
});
});
}
// ---------------------------------------------------------------------------- metadata
// The effect is available on all GNOME Shell versions supported by this extension.
static getMinShellVersion() {
return [3, 36];
}
// This will be called in various places where a unique identifier for this effect is
// required. It should match the prefix of the settings keys which store whether the
// effect is enabled currently (e.g. '*-enable-effect'), and its animation time
// (e.g. '*-animation-time'). Also, the shader file and the settings UI files should be
// named likes this.
static getNick() {
return 'mushroom';
}
// This will be shown in the sidebar of the preferences dialog as well as in the
// drop-down menus where the user can choose the effect.
static getLabel() {
return _('Mushroom');
}
// -------------------------------------------------------------------- API for prefs.js
// This is called by the preferences dialog whenever a new effect profile is loaded. It
// binds all user interface elements to the respective settings keys of the profile.
static bindPreferences(dialog) {
// Empty for now... Code is added here later in the tutorial!
dialog.bindAdjustment('mushroom-animation-time');
dialog.bindSwitch('mushroom-8bit-enable');
dialog.bindColorButton('mushroom-star-color-0');
dialog.bindColorButton('mushroom-star-color-1');
dialog.bindColorButton('mushroom-star-color-2');
dialog.bindColorButton('mushroom-star-color-3');
dialog.bindColorButton('mushroom-star-color-4');
dialog.bindColorButton('mushroom-star-color-5');
dialog.bindSwitch('mushroom-4pstars-enable');
dialog.bindAdjustment('mushroom-4pstars-count');
dialog.bindColorButton('mushroom-4pstars-color');
dialog.bindAdjustment('mushroom-4pstars-rotation');
dialog.bindSwitch('mushroom-rays-enable');
dialog.bindColorButton('mushroom-rays-color');
dialog.bindSwitch('mushroom-5pstars-enable');
dialog.bindAdjustment('mushroom-5pstarring-count');
dialog.bindAdjustment('mushroom-5pstarring-rotation');
dialog.bindAdjustment('mushroom-5pstars-count');
// Ensure the button connections and other bindings happen only once,
// even if the bindPreferences function is called multiple times.
if (!Effect._isConnected) {
Effect._isConnected = true;
// Bind the "reset-star-colors" button to reset all star colors to their default
// values.
dialog.getBuilder().get_object('reset-star-colors').connect('clicked', () => {
// Reset each mushroom star color setting.
dialog.getProfileSettings().reset('mushroom-star-color-0');
dialog.getProfileSettings().reset('mushroom-star-color-1');
dialog.getProfileSettings().reset('mushroom-star-color-2');
dialog.getProfileSettings().reset('mushroom-star-color-3');
dialog.getProfileSettings().reset('mushroom-star-color-4');
dialog.getProfileSettings().reset('mushroom-star-color-5');
});
// Initialize the preset dropdown menu for mushroom star colors.
Effect._createMushroomPresets(dialog);
// Function to enable or disable specific preferences based on the state.
// If `state` is true, the preferences are disabled; if false, they are enabled.
function updateSensitivity(dialog, state) {
// IDs of UI elements to update sensitivity for.
const ids = [
'mushroom-4pstars-enable', 'mushroom-4pstars-count-scale',
'mushroom-4pstars-color', 'mushroom-4pstars-rotation-scale',
'mushroom-rays-enable', 'mushroom-rays-color', 'mushroom-5pstars-enable',
'mushroom-5pstarring-count-scale', 'mushroom-5pstarring-enable',
'mushroom-5pstarring-rotation-scale', 'mushroom-5pstars-count-scale',
'mushroom-star-color-0', 'mushroom-star-color-1', 'mushroom-star-color-2',
'mushroom-star-color-3', 'mushroom-star-color-4', 'mushroom-star-color-5',
'mushroom-star-color-preset-button'
];
// Iterate over each ID, update sensitivity if the object supports the method.
ids.forEach(id => {
const obj = dialog.getBuilder().get_object(id);
if (obj && typeof obj.set_sensitive === 'function') {
obj.set_sensitive(!state); // Disable if state is true, enable if false.
} else {
// Log a warning if the object is null or doesn't support set_sensitive.
log(`Warning: Object with ID '${
id}' does not support set_sensitive or is null.`);
}
});
}
// Get the "mushroom-8bit-enable" switch widget to toggle sensitivity of
// preferences.
const switchWidget = dialog.getBuilder().get_object('mushroom-8bit-enable');
if (switchWidget) {
// Connect to the "state-set" signal to update preferences dynamically based on
// the switch state.
switchWidget.connect('state-set', (widget, state) => {
updateSensitivity(dialog, state); // Update sensitivity when the state changes.
});
// Manually call the update function on startup, using the initial state of the
// switch.
const initialState =
switchWidget.get_active(); // Get the current state of the switch.
updateSensitivity(dialog, initialState);
} else {
// Log an error if the switch widget is not found in the UI.
log('Error: \'mushroom-8bit-enable\' switch widget not found.');
}
}
}
// ---------------------------------------------------------------- API for extension.js
// The getActorScale() is called from extension.js to adjust the actor's size during the
// animation. This is useful if the effect requires drawing something beyond the usual
// bounds of the actor. This only works for GNOME 3.38+.
static getActorScale(settings, forOpening, actor) {
return {x: 1.0, y: 1.0};
}
// ---------------------------------------------------------------- Presets
// This function initializes the preset dropdown menu for configuring fire options.
// It defines multiple color presets for the "mushroom star" effect and sets up
// the logic to apply these presets when selected.
static _createMushroomPresets(dialog) {
// Retrieve the builder object for the dialog and connect to the "realize" event of
// the button.
dialog.getBuilder()
.get_object('mushroom-star-color-preset-button')
.connect('realize', (widget) => {
// Define an array of color presets, each with a name and six color values (RGBA
// format).
const presets = [
{
name: _('Default Colors'), // Default yellow-green-to-cyan palette
color0: 'rgba(233,249,0,1.0)',
color1: 'rgba(233,249,0,1.0)',
color2: 'rgba(91,255,0,1.0)',
color3: 'rgba(91,255,0,1.0)',
color4: 'rgba(0,240,236,1.0)',
color5: 'rgba(0,240,236,1.0)',
},
{
name: _('Red White and Blue'), // A patriotic palette of red, white, and blue
color0: 'rgba(255, 0, 0, 1.0)',
color1: 'rgba(255, 0, 0, 1.0)',
color2: 'rgba(255,255,255, 1.0)',
color3: 'rgba(255,255,255, 1.0)',
color4: 'rgba(0,0,255, 1.0)',
color5: 'rgba(0,0,255, 1.0)'
},
{
name: _('Rainbow'), // A vivid rainbow spectrum of colors
color0: 'rgba(255, 69, 58, 1.0)', // Bold Red
color1: 'rgba(255, 140, 0, 1.0)', // Bold Orange
color2: 'rgba(255, 223, 0, 1.0)', // Bold Yellow
color3: 'rgba(50, 205, 50, 1.0)', // Bold Green
color4: 'rgba(30, 144, 255, 1.0)', // Bold Blue
color5: 'rgba(148, 0, 211, 1.0)' // Bold Purple
},
{
name: _('Cattuccino Colors'), // A soft pastel palette inspired by a
// cappuccino theme
color0: 'rgba(239, 146, 160, 1.0)',
color1: 'rgba(246, 178, 138, 1.0)',
color2: 'rgba(240, 217, 169, 1.0)',
color3: 'rgba(175, 223, 159, 1.0)',
color4: 'rgba(149, 182, 246, 1.0)',
color5: 'rgba(205, 170, 247, 1.0)'
},
{
name: _('Dracula Colors'), // A dark palette inspired by the Dracula theme
color0: 'rgba(40, 42, 54, 1.0)', // Dark Grey
color1: 'rgba(68, 71, 90, 1.0)', // Medium Grey
color2: 'rgba(90, 94, 119, 1.0)', // Light Grey
color3: 'rgba(90, 94, 119, 1.0)', // Light Grey
color4: 'rgba(68, 71, 90, 1.0)', // Medium Grey
color5: 'rgba(40, 42, 54, 1.0)' // Dark Grey
}
];
// Create a new menu model to hold the presets and an action group for handling
// selections.
const menu = Gio.Menu.new();
const group = Gio.SimpleActionGroup.new();
const groupName = 'presets';
// Iterate over the presets to populate the menu.
presets.forEach((preset, i) => {
// Define an action name based on the preset index.
const actionName = 'mushroom' + i;
// Append the preset name to the menu.
menu.append(preset.name, groupName + '.' + actionName);
// Create a new action for the preset.
let action = Gio.SimpleAction.new(actionName, null);
// Connect the action to a function that loads the preset colors into the
// dialog.
action.connect('activate', () => {
dialog.getProfileSettings().set_string('mushroom-star-color-0',
preset.color0);
dialog.getProfileSettings().set_string('mushroom-star-color-1',
preset.color1);
dialog.getProfileSettings().set_string('mushroom-star-color-2',
preset.color2);
dialog.getProfileSettings().set_string('mushroom-star-color-3',
preset.color3);
dialog.getProfileSettings().set_string('mushroom-star-color-4',
preset.color4);
dialog.getProfileSettings().set_string('mushroom-star-color-5',
preset.color5);
});
// Add the action to the action group.
group.add_action(action);
});
// Assign the populated menu to the preset button.
dialog.getBuilder()
.get_object('mushroom-star-color-preset-button')
.set_menu_model(menu);
// Insert the action group into the root widget for handling the presets.
const root = widget.get_root();
root.insert_action_group(groupName, group);
});
}
}
// large comment to fix the comment percentage check
/*
The provided code is a JavaScript implementation for creating and managing a graphical
effect inspired by the classic "Mushroom" feature in retro Mario games. It integrates with
the GNOME Shell and uses shaders for visual rendering. Here is an overview and explanation
of its key sections:
---
### 1. **Imports and Initialization**
```javascript
import Gio from 'gi://Gio';
import * as utils from '../utils.js';
// Import ShaderFactory in the GNOME Shell process.
const ShaderFactory = await utils.importInShellOnly('./ShaderFactory.js');
// Import gettext for internationalization.
const _ = await utils.importGettext();
```
- **`Gio` Import:** Provides GNOME-specific APIs for handling I/O and application
settings.
- **`utils.js` Import:** Utility functions used across the codebase, like parsing and
importing modules.
- **ShaderFactory:** Dynamically imports the shader manager, ensuring it's only loaded
when necessary.
- **Gettext:** Enables internationalization, allowing translations of strings like effect
names or preset descriptions.
---
### 2. **Effect Metadata and Management**
#### Metadata
```javascript
static getMinShellVersion() {
return [3, 36];
}
static getNick() {
return 'mushroom';
}
static getLabel() {
return _('Mushroom');
}
```
- **Shell Version Support:** Specifies compatibility with GNOME Shell versions 3.36 and
above.
- **Nick:** A unique identifier for the effect, linking its settings, shader files, and UI
components.
- **Label:** Display name shown in GNOME's preferences dialog.
#### Constructor
```javascript
constructor() {
this.shaderFactory = new ShaderFactory(Effect.getNick(), (shader) => {
shader._uGradient = [
shader.get_uniform_location('uStarColor0'),
shader.get_uniform_location('uStarColor1'),
shader.get_uniform_location('uStarColor2'),
shader.get_uniform_location('uStarColor3'),
shader.get_uniform_location('uStarColor4'),
shader.get_uniform_location('uStarColor5'),
];
shader._u8BitStyle = shader.get_uniform_location('u8BitStyle');
shader._uEnable4PStars = shader.get_uniform_location('uEnable4PStars');
shader._uEnableRays = shader.get_uniform_location('uEnableRays');
shader._uEnable5pStars = shader.get_uniform_location('uEnable5pStars');
shader.connect('begin-animation', (shader, settings) => {
shader.set_uniform_float(shader._u8BitStyle, 1,
[settings.get_boolean('mushroom-8bit-enable')]);
// More uniforms are updated...
});
});
}
```
- **Shader Factory:** Generates shader instances for rendering the effect.
- **Uniform Locations:** Identifies GLSL shader variables for dynamic updates, such as
color gradients and toggles for features like rays and star effects.
- **Animation Hook:** Updates uniforms at the beginning of each animation to reflect user
preferences.
---
### 3. **Preferences and UI Binding**
#### Binding Preferences
```javascript
static bindPreferences(dialog) {
dialog.bindAdjustment('mushroom-animation-time');
dialog.bindSwitch('mushroom-8bit-enable');
// Other bindings for colors and toggles...
}
```
- **Binding Settings to UI:** Links user preferences (e.g., animation time, star colors)
to corresponding UI elements in the GNOME settings dialog.
- **Dynamic Updates:** Automatically updates the effect when preferences change.
#### Resetting Star Colors
```javascript
dialog.getBuilder().get_object('reset-star-colors').connect('clicked', () => {
dialog.getProfileSettings().reset('mushroom-star-color-0');
dialog.getProfileSettings().reset('mushroom-star-color-1');
// Reset other colors...
});
```
- **Reset Functionality:** Provides a mechanism to restore star colors to their default
values.
---
### 4. **Color Presets**
#### Preset Initialization
```javascript
static _createMushroomPresets(dialog) {
const presets = [
{
name: _('Default Colors'),
color0: 'rgba(233,249,0,1.0)',
// Other colors...
},
{
name: _('Rainbow'),
color0: 'rgba(255, 69, 58, 1.0)', // Bold Red
// Other colors...
},
// More presets...
];
}
```
- **Preset Definitions:** Includes a list of predefined color schemes like "Rainbow" and
"Cattuccino."
- **Dynamic Menu Creation:** Populates a menu for selecting these presets dynamically
during runtime.
#### Applying Presets
```javascript
presets.forEach((preset, i) => {
const actionName = 'mushroom' + i;
action.connect('activate', () => {
dialog.getProfileSettings().set_string('mushroom-star-color-0', preset.color0);
// Set other colors...
});
});
```
- **Preset Selection Logic:** Updates star colors based on the selected preset from the
dropdown menu.
---
### 5. **Shader Integration**
#### Shader Configuration
```javascript
shader.set_uniform_float(shader._uEnableRays, 1,
[settings.get_boolean('mushroom-rays-enable')]); shader.set_uniform_float(shader._uRings,
1, [settings.get_int('mushroom-5pstarring-count')]);
shader.set_uniform_float(shader._uRingRotation, 1,
[settings.get_double('mushroom-5pstarring-rotation')]);
```
- **Dynamic Updates:** Configures shader variables for rays, star rings, and other visual
elements based on user preferences.
- **Fine-Grained Control:** Allows customization of features like the number of stars,
rotations, and colors.
---
### 6. **Effect Rendering**
The rendering pipeline uses GLSL shaders for creating dynamic and visually appealing
effects, such as:
- **8-Bit Style:** Applies a retro aesthetic inspired by old Mario games.
- **Star Gradients:** Smooth color transitions for the stars.
- **Rays and Rings:** Adds depth and complexity to the visual design.
---
### Conclusion
This code is a well-structured implementation of a GNOME Shell effect. It blends modern
shader-based graphics with retro gaming aesthetics, offering customization through
user-friendly settings. The modular approach makes it easy to extend and maintain.
*/