# Aura Glow
Looks really cool! I think the defaults could be a bit more "spectacular". More color speed (5?) and less saturation (0.5?) looks much better in my opinion.
There is a significant delay when closing a window before the animation starts. Can this be removed?
Is a saturation > 1 useful?

✅ Color Speed = 5
✅ Saturation at 0.5
❓ the delay ...
i think this was caused by the padding
i tried to get rid of it in the shader (see "//adjust for gnome" in the shader).
maybe you know a better way .
✅ Is a saturation > 1 useful?
... i guess not 😀

# Mushroom
Aweome!
Only complaint: The preset dropdown says "8Bit Plumber (default)" but the default is actually "New Bros 2".

✅ fixed, i'll just take the word "default" out

# RGB Warp
The defaults look great!
I would rename it to "RGB Warp" instead of "RGB Warp Effect" to be consistent with the other effects.
All the settings in the UI could use some spaces.
Is the Wave Size parameter useful? Any other values than 1 look pretty weird.

✅
✅
✅ wavesize ... it was more useful in shadertoy, when it was there, removed.

# TeamRocket
The best one in my opinion!
I would call it "Team Rocket" instead of "TeamRocket" to be consistent with the other effects.
I would enable window rotation per default and set the Y value to a value other than 0, maybe 0.5. This makes it a bit more organic!

✅
✅

# UnicornFart
Here I have severe performance issues. On my machine, the effect is not usable. Even with only 10 stars and sparks, I only get a few FPS. What shall we do about this? I think we either need to optimize this or think about a different effect. I liked your initial idea with the wobbly rgb noise as well...
Anyways, great work! I am really looking forward to this! Let me know what you think about these points, and then I'll soon have a look at the individual effect implementations.

ok, i'll take this out and try something else.
...maybe i shouldn't have used the blur on it.
👍👍👍
This commit is contained in:
Justin Garza
2025-01-24 18:50:15 -05:00
parent dd49880638
commit 4b8124c5bb
13 changed files with 17 additions and 1758 deletions
+1
View File
@@ -12,3 +12,4 @@
/resources/burn-my-windows.gresource.xml
kwin/_build
kwin/*.tar.gz
notes.md
+1 -8
View File
@@ -47,13 +47,7 @@ import TeamRocket from './src/effects/TeamRocket.js';
import TRexAttack from './src/effects/TRexAttack.js';
import TVEffect from './src/effects/TVEffect.js';
import TVGlitch from './src/effects/TVGlitch.js';
import UnicornFart from './src/effects/UnicornFart.js';
import Wisps from './src/effects/Wisps.js';
import Mushroom from './src/effects/Mushroom.js';
import UnicornFart from './src/effects/UnicornFart.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import {Workspace} from 'resource:///org/gnome/shell/ui/workspace.js';
@@ -86,8 +80,7 @@ export default class BurnMyWindows extends Extension {
new Matrix(), new PaintBrush(), new Pixelate(), new PixelWheel(),
new PixelWipe(), new Portal(), new RGBWarp(), new SnapOfDisintegration(),
new TeamRocket(), new TRexAttack(), new TVEffect(), new TVGlitch(),
new Wisps(), new Mushroom(), new UnicornFart(),
new Wisps(), new Mushroom()
];
// Load all of our resources.
+1 -2
View File
@@ -50,7 +50,6 @@ import TVEffect from './src/effects/TVEffect.js';
import TVGlitch from './src/effects/TVGlitch.js';
import Wisps from './src/effects/Wisps.js';
import UnicornFart from './src/effects/UnicornFart.js';
import {ExtensionPreferences, gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
@@ -84,7 +83,7 @@ export default class BurnMyWindowsPreferences extends ExtensionPreferences {
Pixelate, PixelWheel, PixelWipe,
Portal, RGBWarp, SnapOfDisintegration,
TeamRocket, TRexAttack, TVEffect,
TVGlitch, Wisps, UnicornFart,
TVGlitch, Wisps,
];
+2 -3
View File
@@ -30,7 +30,6 @@
// vec4 getInputColor(vec2 coords)
// void setOutputColor(vec4 outColor)
uniform float uWavesize;
uniform float uBrightness;
uniform float uStretchR;
uniform float uStretchG;
@@ -65,10 +64,10 @@ void main() {
//w will be used to calculate the the size of the wave
float p = mix(0.0, 1.0 + uWavesize, progress);
float p = mix(0.0, 1.0 + 1.0, progress);
w = 1.0 - abs(p - f.y);
w = clamp(w,0.0,1.0);
w = pow(w, mix(100.0,1.0,uWavesize) );
w = pow(w, mix(100.0,1.0,1.0) );
//starting output color
vec4 oColor = vec4(0.0);
-526
View File
@@ -1,526 +0,0 @@
//////////////////////////////////////////////////////////////////////////////////////////
// ) ( //
// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
// | '_ \ || | '_| ' \)) | ' \()| || | \ 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.
//variables
uniform float uSparkCount; //number of sparkles
uniform vec2 uSparkStartEnd; // the start and end of the sparkles
uniform float uSparkOffset; //how much the sparkles can be offset
uniform float uStarCount; //number of Stars
uniform float uStarRot; // how much the stars rotate
uniform float uStarSize; // the size of the stars
uniform vec2 uStarStartEnd; //start and end of the star's movement
uniform float uBlurQuality; // blurquality for the window
uniform float uSeed; // a random number
//particle colors
uniform vec4 uSparkColor0;
uniform vec4 uSparkColor1;
uniform vec4 uSparkColor2;
uniform vec4 uSparkColor3;
uniform vec4 uSparkColor4;
uniform vec4 uSparkColor5;
//star colors
uniform vec4 uStarColor0;
uniform vec4 uStarColor1;
uniform vec4 uStarColor2;
uniform vec4 uStarColor3;
uniform vec4 uStarColor4;
uniform vec4 uStarColor5;
// Define a constant for 2 * PI (tau), which represents a full circle in radians.
const float PI = 3.14159265359;
const float tau = 6.28318530718;
//helps to find the angle
vec3 getPosByAngle(float angle)
{
return vec3(cos(angle), sin(angle), 0);
}
//this returns the Spark
float getSpark(vec2 uv,vec2 center, float brightness, float size, float rotation)
{
//the size
size = clamp(size,0.001,1.0);
uv = (uv + vec2(0.5)) ; //set center
uv = (uv - center) ;//Center UV coordinates, then scale to fit the star size
//scale
uv = uv * 2.0 -1.0;
uv /= mix(vec2(1.0,1.0), vec2(0.0,0.0), vec2(1.0 - size));
uv = uv * 0.5 + 0.5;
uv = rotate(uv, rotation, vec2(0.5));
//the brightness of the spark
brightness = clamp(brightness,0.001,1.0);
float bn = mix(0.0,0.07,brightness); //recalculate size
//this is basically the brightness
float p = mix(-1.0,1000.0,easeInExpo(bn));
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
)
);
//calcuate and return this mask
float mask = easeInSine(1.0 - (m - bn)) - 0.004 ;
mask = clamp(mask,0.0,1.0);
return mask;
}
//this was lifted from aura-glow
float getMask(float t)
{
// 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,t);
// 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(1.0,1000.0,
easeInExpo(t)
);
//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 is the mask
//float mask = (m > t) ? 0.0 : 1.0 ;
float mask = (m > t) ? (1.0 - (m - t)) : 1.0 ;
mask = clamp(mask,0.0,1.0);
return mask;
}
// A simple blur function
vec4 blur(vec2 uv, float radius, float samples) {
// Initialize the color accumulator to zero.
vec4 color = vec4(0.0);
// 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;
}
//fades out at 0 and 1 ...based on the 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 FadeInOut(float t, float power)
{
float s = -1.0 * pow((t-0.5)/(0.5),power)+1.0;
s = clamp(s,0.0,1.0);
return s;
}
//returns the Spark's color
vec4 getSparkColors(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] = uSparkColor0 ;
colors[1] = uSparkColor1 ;
colors[2] = uSparkColor2 ;
colors[3] = uSparkColor3 ;
colors[4] = uSparkColor4 ;
colors[5] = uSparkColor5 ;
// 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);
}
vec4 getSparks(float t)
{
//the UV for this function
float aspect = uSize.x / uSize.y;
vec2 uv = iTexCoord.st * vec2(aspect,1.0);
vec4 result = vec4(0.0);
//for each spark
for (float i = 0.0; i < uSparkCount ; ++i)
{
//random values
vec4 v4 = hash41( i * uSeed);
//the X and Y position ... at the end
vec3 pos = getPosByAngle( (i/uSparkCount) * tau + (v4.x * 0.3) );
//the distance the spark will travel
float d = mix(0.33,0.34,v4.z) ;
d = mix(
uSparkStartEnd.x + (v4.z * uSparkOffset),
uSparkStartEnd.y - (v4.y * uSparkOffset),
(1.0 - t)
);
float s = getSpark(
uv,
vec2(0.5 * aspect,0.5) + ( pos.xy * d ), //position (x, y)
FadeInOut(t,8.0) * 0.9 ,//Brightness
FadeInOut(t,8.0) * (v4.w * 0.5) ,//Size
0.0 //rotation
);
//set the color
vec4 c = getSparkColors( hash11(v4.w) ,1.0);
s = clamp(s*2.0,0.0,1.0);
c.rgb *= s;
c.a *= s;
result += c ;
}
//make it bright
result.a = pow(result.a,2.0);
//fade at endges
result.a *= FadeInOut(iTexCoord.s,4.0);
result.a *= FadeInOut(iTexCoord.t,4.0);
return clamp(result,vec4(0.0),vec4(1.0));
// return result;
}
vec4 getStarColors(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);
}
//gets the mask of a Star
float getStar(vec2 uv, vec2 center, float npoints, float radiusRatio, float size, float rotation)
{
float radiusMax = 1.0;
float radiusMin = radiusMax * radiusRatio;
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)
}
//convert the XY to angle
float XYtoAngle(vec2 XY)
{
return atan(XY.y, XY.x);
}
vec4 getStars(float t)
{
//the UV for this function
float aspect = uSize.x / uSize.y;
vec2 uv = iTexCoord.st * vec2(aspect,1.0);
// float result = 0.0;
vec4 result = vec4(0.0);
//loop for each star
for (float i = 0.0; i < uStarCount ; ++i)
{
//random values for this star
vec4 v4 = hash41( i * uSeed);
//the X and Y position ... at the end
vec3 pos = getPosByAngle( (i/uStarCount) * tau + (uStarRot * tau * t) );
//the distance the spark will travel
float d = mix(0.33,0.34,v4.z) ;
d = mix(
uStarStartEnd.x ,
uStarStartEnd.y ,
(1.0 - t)
);
float s = getStar(
uv,
vec2(0.5 * aspect,0.5) + ( pos.xy * d ), //position (x, y)
5.0, //npoints
0.5, //Ratio
FadeInOut(t,4.0) * uStarSize,//Size
PI //rotation
);
s *= FadeInOut(iTexCoord.s,4.0);
s *= FadeInOut(iTexCoord.t,4.0);
s = clamp(s,0.0,1.0);
//the color is based on it's starting location
vec4 color = getStarColors( i/uStarCount ,1.0);
result += vec4(color.rgb * s,s * color.a);
}
return result;
}
void main() {
// Calculate the progression value based on the animation direction.
// If opening, use uProgress as-is; if closing, invert the progression.
float progress = uForOpening ? 1.0 - uProgress : uProgress ;
//zero to one... mostly one
float ztomo = remap(
progress,
0.0,0.1,
0.0,1.0
);
ztomo = easeInOutSine(ztomo);
//progress variants
// float oExpo = easeOutExpo(progress);
// float iExpo = easeInExpo(progress);
// float oQuad = easeOutQuad(progress);
float ioCubic = easeInOutCubic(progress);
float ioSine = easeInOutSine(progress);
vec2 uv = iTexCoord.st;
//center
uv = uv * 2.0 - 1.0;
//scale
uv /= mix(vec2(0.5,0.5), vec2(0.0,0.0), ioCubic);
// scale from center
uv = uv * 0.5 + 0.5;
//get blured version of the window
vec4 oColor = blur(uv, ioCubic * 200.0,uBlurQuality);
oColor.a *= (1.0 - ioSine);
//get and apply sparks
if (uSparkCount > 0)
{
vec4 sparks = getSparks(ioSine);
oColor = alphaOver(oColor, sparks);
}
//get and apply stars
if (uStarCount > 0 )
{
oColor = alphaOver(oColor, getStars(mix(0.0001,0.999,ioSine)));
}
//output
setOutputColor(oColor);
}
+1 -1
View File
@@ -150,7 +150,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<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="upper">1.0</property>
<property name="lower">0.0</property>
<property name="step-increment">0.10</property>
<property name="page-increment">0.25</property>
+3 -40
View File
@@ -49,43 +49,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">WaveSize</property>
<!-- <property name="subtitle" translatable="yes"></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="rgbwarp-wavesize">
<property name="upper">1.0</property>
<property name="lower">0.0</property>
<property name="step-increment">0.01</property>
<property name="page-increment">0.1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-rgbwarp-wavesize">
<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">
@@ -128,7 +91,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">OffsetRed</property>
<property name="title" translatable="yes">Offset Red</property>
<!-- <property name="subtitle" translatable="yes"></property> -->
<child>
@@ -166,7 +129,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">OffsetGreen</property>
<property name="title" translatable="yes">Offset Green</property>
<!-- <property name="subtitle" translatable="yes"></property> -->
<child>
@@ -204,7 +167,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">OffsetBlue</property>
<property name="title" translatable="yes">Offset Blue</property>
<!-- <property name="subtitle" translatable="yes"></property> -->
<child>
-535
View File
@@ -1,535 +0,0 @@
<?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 unicorn-fart preferences section -->
<object class="AdwExpanderRow" id="unicorn-fart-prefs">
<!-- Animation Time Adjustment Section -->
<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="unicorn-fart-animation-time">
<property name="upper">5000</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-unicorn-fart-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">Effect Presets</property>
<property name="activatable-widget">unicorn-fart-preset-button</property>
<child>
<object class="GtkMenuButton" id="unicorn-fart-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>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Spark Count</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="unicorn-fart-spark-count">
<property name="upper">100</property>
<property name="lower">0</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-spark-count">
<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">Spark Start</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="unicorn-fart-spark-start">
<property name="upper">0.5</property>
<property name="lower">0.0</property>
<property name="step-increment">0.01</property>
<property name="page-increment">0.1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-spark-start">
<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">Spark End</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="unicorn-fart-spark-end">
<property name="upper">1.0</property>
<property name="lower">0.5</property>
<property name="step-increment">0.01</property>
<property name="page-increment">0.1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-spark-end">
<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">Spark offset</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="unicorn-fart-spark-offset">
<property name="upper">0.5</property>
<property name="lower">0.0</property>
<property name="step-increment">0.1</property>
<property name="page-increment">0.25</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-spark-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">Star Count</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="unicorn-fart-star-count">
<property name="upper">25</property>
<property name="lower">0</property>
<property name="step-increment">1</property>
<property name="page-increment">5</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-star-count">
<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">Star Rotation</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="unicorn-fart-star-rotation">
<property name="upper">3.0</property>
<property name="lower">-3.0</property>
<property name="step-increment">0.1</property>
<property name="page-increment">0.5</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-star-rotation">
<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">Star 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="unicorn-fart-star-size">
<property name="upper">0.1</property>
<property name="lower">0.0</property>
<property name="step-increment">0.1</property>
<property name="page-increment">0.5</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-star-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">Star Start</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="unicorn-fart-star-start">
<property name="upper">0.5</property>
<property name="lower">0.0</property>
<property name="step-increment">0.01</property>
<property name="page-increment">0.1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-star-start">
<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">Star End</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="unicorn-fart-star-end">
<property name="upper">1.0</property>
<property name="lower">0.5</property>
<property name="step-increment">0.01</property>
<property name="page-increment">0.1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-star-end">
<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 Quality</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="unicorn-fart-blur-quality">
<property name="upper">10.0</property>
<property name="lower">0.0</property>
<property name="step-increment">0.01</property>
<property name="page-increment">0.1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-blur-quality">
<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>
<!-- Particle Colors -->
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Particle Colors</property>
<child>
<object class="GtkBox">
<style>
<class name="linked" />
</style>
<child>
<object class="GtkColorButton" id="unicorn-fart-spark-color-0">
<property name="use_alpha">1</property>
<property name="show_editor">1</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkColorButton" id="unicorn-fart-spark-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="unicorn-fart-spark-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="unicorn-fart-spark-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="unicorn-fart-spark-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="unicorn-fart-spark-color-5">
<property name="use_alpha">1</property>
<property name="show_editor">1</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-spark-colors">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Values</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<!-- Star Gradient Colors -->
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Star Colors</property>
<child>
<object class="GtkBox">
<style>
<class name="linked" />
</style>
<child>
<object class="GtkColorButton" id="unicorn-fart-star-color-0">
<property name="use_alpha">1</property>
<property name="show_editor">1</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkColorButton" id="unicorn-fart-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="unicorn-fart-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="unicorn-fart-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="unicorn-fart-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="unicorn-fart-star-color-5">
<property name="use_alpha">1</property>
<property name="show_editor">1</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="reset-unicorn-fart-star-colors">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Values</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
</object>
</interface>
@@ -987,13 +987,13 @@ SPDX-License-Identifier: CC0-1.0
</key>
<key name="aura-glow-color-speed" type="d">
<default>1.0</default>
<default>5.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>
<default>0.5</default>
<summary>Aura Glow Color Saturation</summary>
<description>Amount of color in the effect</description>
</key>
@@ -1109,13 +1109,13 @@ SPDX-License-Identifier: CC0-1.0
</key>
<key name="team-rocket-y" type="d">
<default>0.0</default>
<default>0.5</default>
<summary>Team Rocket Y</summary>
<description>Y position</description>
</key>
<key name="team-rocket-win-rot" type="b">
<default>false</default>
<default>true</default>
<summary>Rotate the Window</summary>
<description>Rotate the Window</description>
</key>
@@ -1133,165 +1133,6 @@ SPDX-License-Identifier: CC0-1.0
</key>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Unicorn Fart Options -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<key name="unicorn-fart-enable-effect" type="b">
<default>false</default>
<summary>Unicorn Fart Enable Effect</summary>
<description>Use the Unicorn Fart effect.</description>
</key>
<key name="unicorn-fart-animation-time" type="i">
<default>1500</default>
<summary>Unicorn Fart Animation Time</summary>
<description>The time the Unicorn Fart effect takes.</description>
</key>
<!-- sparks -->
<key name="unicorn-fart-spark-count" type="i">
<default>25</default>
<summary>Number of Sparks</summary>
<description>Set the total number of sparks generated.</description>
</key>
<key name="unicorn-fart-spark-start" type="d">
<default>0.0</default>
<summary>Spark Start Point</summary>
<description>Define the starting position for sparks.</description>
</key>
<key name="unicorn-fart-spark-end" type="d">
<default>1.0</default>
<summary>Spark End Point</summary>
<description>Define the ending position for sparks.</description>
</key>
<key name="unicorn-fart-spark-offset" type="d">
<default>0.5</default>
<summary>Spark Offset</summary>
<description>Set the positional offset for sparks.</description>
</key>
<!-- stars -->
<key name="unicorn-fart-star-count" type="i">
<default>6</default>
<summary>Number of Stars</summary>
<description>Set the total number of stars displayed.</description>
</key>
<key name="unicorn-fart-star-rotation" type="d">
<default>0.33</default>
<summary>Star Rotation</summary>
<description>Control the rotational angle of stars.</description>
</key>
<key name="unicorn-fart-star-size" type="d">
<default>0.1</default>
<summary>Star Size</summary>
<description>Set the size of the stars.</description>
</key>
<key name="unicorn-fart-star-start" type="d">
<default>0.0</default>
<summary>Star Start Point</summary>
<description>Define the starting position for stars.</description>
</key>
<key name="unicorn-fart-star-end" type="d">
<default>1.0</default>
<summary>Star End Point</summary>
<description>Define the ending position for stars.</description>
</key>
<!-- blur -->
<key name="unicorn-fart-blur-quality" type="d">
<default>5.0</default>
<summary>Blur Quality</summary>
<description>Set the quality level for the blur effect.</description>
</key>
<key name="unicorn-fart-seed" type="d">
<default>1.0</default>
<summary>Random Seed</summary>
<description>Define the seed value for random effects.</description>
</key>
<!-- particle colors -->
<key name="unicorn-fart-spark-color-0" type="s">
<default>"rgba(255, 255, 255, 1.0)"</default>
<summary>Primary Particle Color</summary>
<description>Set the first color used for particles.</description>
</key>
<key name="unicorn-fart-spark-color-1" type="s">
<default>"rgba(255, 255, 255, 1.0)"</default>
<summary>Secondary Particle Color</summary>
<description>Set the second color used for particles.</description>
</key>
<key name="unicorn-fart-spark-color-2" type="s">
<default>"rgba(255, 255, 255, 1.0)"</default>
<summary>Tertiary Particle Color</summary>
<description>Set the third color used for particles.</description>
</key>
<key name="unicorn-fart-spark-color-3" type="s">
<default>"rgba(255, 255, 255, 1.0)"</default>
<summary>Quaternary Particle Color</summary>
<description>Set the fourth color used for particles.</description>
</key>
<key name="unicorn-fart-spark-color-4" type="s">
<default>"rgba(255, 255, 255, 1.0)"</default>
<summary>Quinary Particle Color</summary>
<description>Set the fifth color used for particles.</description>
</key>
<key name="unicorn-fart-spark-color-5" type="s">
<default>"rgba(255, 255, 255, 1.0)"</default>
<summary>Senary Particle Color</summary>
<description>Set the sixth color used for particles.</description>
</key>
<!-- star colors -->
<key name="unicorn-fart-star-color-0" type="s">
<default>"rgba(255, 0, 0, 1.0)"</default>
<summary>Primary Star Color</summary>
<description>Set the first color used for stars.</description>
</key>
<key name="unicorn-fart-star-color-1" type="s">
<default>"rgba(255, 255, 0, 1.0)"</default>
<summary>Secondary Star Color</summary>
<description>Set the second color used for stars.</description>
</key>
<key name="unicorn-fart-star-color-2" type="s">
<default>"rgba(0, 255, 0, 1.0)"</default>
<summary>Tertiary Star Color</summary>
<description>Set the third color used for stars.</description>
</key>
<key name="unicorn-fart-star-color-3" type="s">
<default>"rgba(0, 255, 255, 1.0)"</default>
<summary>Quaternary Star Color</summary>
<description>Set the fourth color used for stars.</description>
</key>
<key name="unicorn-fart-star-color-4" type="s">
<default>"rgba(0, 0, 255, 1.0)"</default>
<summary>Quinary Star Color</summary>
<description>Set the fifth color used for stars.</description>
</key>
<key name="unicorn-fart-star-color-5" type="s">
<default>"rgba(255, 0, 255, 1.0)"</default>
<summary>Senary Star Color</summary>
<description>Set the sixth color used for stars.</description>
</key>
</schema>
+1 -1
View File
@@ -201,7 +201,7 @@ export default class Effect {
// format).
const presets = [
{
name: _('8Bit Plumber (Default)'),
name: _('8Bit Plumber'),
ScaleStyle: 0.0,
SparkCount: 0,
SparkColor: 'rgba(255,255,255,0.0)',
+1 -6
View File
@@ -38,7 +38,6 @@ export default class Effect {
constructor() {
this.shaderFactory = new ShaderFactory(Effect.getNick(), (shader) => {
// Store uniform locations of newly created shaders.
shader._uWavesize = shader.get_uniform_location('uWavesize');
shader._uBrightness = shader.get_uniform_location('uBrightness');
shader._uStretchR = shader.get_uniform_location('uStretchR');
shader._uStretchG = shader.get_uniform_location('uStretchG');
@@ -46,9 +45,6 @@ export default class Effect {
// Write all uniform values at the start of each animation.
shader.connect('begin-animation', (shader, settings) => {
shader.set_uniform_float(shader._uWavesize, 1, [
settings.get_double('rgbwarp-wavesize'),
]);
shader.set_uniform_float(shader._uBrightness, 1, [
settings.get_double('rgbwarp-brightness'),
@@ -88,7 +84,7 @@ export default class Effect {
// 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 _('RGB Warp Effect');
return _('RGB Warp');
}
// -------------------------------------------------------------------- API for prefs.js
@@ -99,7 +95,6 @@ export default class Effect {
// Empty for now... Code is added here later in the tutorial!
dialog.bindAdjustment('rgbwarp-animation-time');
dialog.bindAdjustment('rgbwarp-wavesize');
dialog.bindAdjustment('rgbwarp-brightness');
dialog.bindAdjustment('rgbwarp-offset-r');
dialog.bindAdjustment('rgbwarp-offset-g');
+1 -1
View File
@@ -99,7 +99,7 @@ export default class Effect {
// 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 _('TeamRocket');
return _('Team Rocket');
}
// -------------------------------------------------------------------- API for prefs.js
-471
View File
@@ -1,471 +0,0 @@
//////////////////////////////////////////////////////////////////////////////////////////
// ) ( //
// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
// | '_ \ || | '_| ' \)) | ' \()| || | \ 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();
//////////////////////////////////////////////////////////////////////////////////////////
// I thought to myself, i said "self what would a unicorn fart look like" and then i came
// up with this, and i don't care that i'm out of the box, i think outside of the box,
// yeah f*ck that box!
//////////////////////////////////////////////////////////////////////////////////////////
// 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._uParticles = shader.get_uniform_location('uParticles');
// shader._uParticleSize = shader.get_uniform_location('uParticleSize');
// shader._uParticleSpeed = shader.get_uniform_location('uParticleSpeed');
// shader._uParticleColorRandom =
// shader.get_uniform_location('uParticleColorRandom'); shader._uParticleColorSpeed
// = shader.get_uniform_location('uParticleColorSpeed');
shader._uSparkCount = shader.get_uniform_location('uSparkCount');
shader._uSparkStartEnd = shader.get_uniform_location('uSparkStartEnd');
shader._uSparkOffset = shader.get_uniform_location('uSparkOffset');
shader._uSparkCount = shader.get_uniform_location('uSparkCount');
shader._uStarCount = shader.get_uniform_location('uStarCount');
shader._uStarRot = shader.get_uniform_location('uStarRot');
shader._uStarSize = shader.get_uniform_location('uStarSize');
shader._uStarStartEnd = shader.get_uniform_location('uStarStartEnd');
shader._uBlurQuality = shader.get_uniform_location('uBlurQuality');
shader._uSeed = shader.get_uniform_location('uSeed');
shader._uStarColors = [
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._uParticleColors = [
shader.get_uniform_location('uSparkColor0'),
shader.get_uniform_location('uSparkColor1'),
shader.get_uniform_location('uSparkColor2'),
shader.get_uniform_location('uSparkColor3'),
shader.get_uniform_location('uSparkColor4'),
shader.get_uniform_location('uSparkColor5'),
];
// Write all uniform values at the start of each animation.
shader.connect('begin-animation', (shader, settings) => {
for (let i = 0; i <= 5; i++) {
shader.set_uniform_float(
shader._uStarColors[i], 4,
utils.parseColor(settings.get_string('unicorn-fart-star-color-' + i)));
}
for (let i = 0; i <= 5; i++) {
shader.set_uniform_float(
shader._uParticleColors[i], 4,
utils.parseColor(settings.get_string('unicorn-fart-spark-color-' + i)));
}
shader.set_uniform_float(shader._uSparkCount, 1,
[settings.get_int('unicorn-fart-spark-count')]);
shader.set_uniform_float(shader._uSparkStartEnd, 2, [
settings.get_double('unicorn-fart-spark-start'),
settings.get_double('unicorn-fart-spark-end')
]);
shader.set_uniform_float(shader._uSparkOffset, 1,
[settings.get_double('unicorn-fart-spark-offset')]);
shader.set_uniform_float(shader._uStarCount, 1,
[settings.get_int('unicorn-fart-star-count')]);
shader.set_uniform_float(shader._uStarRot, 1,
[settings.get_double('unicorn-fart-star-rotation')]);
shader.set_uniform_float(shader._uStarSize, 1,
[settings.get_double('unicorn-fart-star-size')]);
shader.set_uniform_float(shader._uStarStartEnd, 2, [
settings.get_double('unicorn-fart-star-start'),
settings.get_double('unicorn-fart-star-end')
]);
shader.set_uniform_float(shader._uBlurQuality, 1,
[settings.get_double('unicorn-fart-blur-quality')]);
shader.set_uniform_float(shader._uSeed, 1, [Math.random()]);
});
});
}
// ---------------------------------------------------------------------------- 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 'unicorn-fart';
}
// 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 _('UnicornFart');
}
// -------------------------------------------------------------------- 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('unicorn-fart-animation-time');
dialog.bindAdjustment('unicorn-fart-spark-count');
dialog.bindAdjustment('unicorn-fart-spark-start');
dialog.bindAdjustment('unicorn-fart-spark-end');
dialog.bindAdjustment('unicorn-fart-spark-offset');
dialog.bindAdjustment('unicorn-fart-star-count');
dialog.bindAdjustment('unicorn-fart-star-rotation');
dialog.bindAdjustment('unicorn-fart-star-size');
dialog.bindAdjustment('unicorn-fart-star-start');
dialog.bindAdjustment('unicorn-fart-star-end');
dialog.bindAdjustment('unicorn-fart-blur-quality');
// switches
dialog.bindSwitch('unicorn-fart-particles-enable');
// star-color
dialog.bindColorButton('unicorn-fart-star-color-0');
dialog.bindColorButton('unicorn-fart-star-color-1');
dialog.bindColorButton('unicorn-fart-star-color-2');
dialog.bindColorButton('unicorn-fart-star-color-3');
dialog.bindColorButton('unicorn-fart-star-color-4');
dialog.bindColorButton('unicorn-fart-star-color-5');
// particle-colors
dialog.bindColorButton('unicorn-fart-spark-color-0');
dialog.bindColorButton('unicorn-fart-spark-color-1');
dialog.bindColorButton('unicorn-fart-spark-color-2');
dialog.bindColorButton('unicorn-fart-spark-color-3');
dialog.bindColorButton('unicorn-fart-spark-color-4');
dialog.bindColorButton('unicorn-fart-spark-color-5');
// 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-unicorn-fart-spark-colors" button to reset all star colors to
// their default values.
dialog.getBuilder()
.get_object('reset-unicorn-fart-spark-colors')
.connect('clicked', () => {
// Reset each mushroom star color setting.
dialog.getProfileSettings().reset('unicorn-fart-spark-color-0');
dialog.getProfileSettings().reset('unicorn-fart-spark-color-1');
dialog.getProfileSettings().reset('unicorn-fart-spark-color-2');
dialog.getProfileSettings().reset('unicorn-fart-spark-color-3');
dialog.getProfileSettings().reset('unicorn-fart-spark-color-4');
dialog.getProfileSettings().reset('unicorn-fart-spark-color-5');
});
dialog.getBuilder()
.get_object('reset-unicorn-fart-star-colors')
.connect('clicked', () => {
// Reset each mushroom star color setting.
dialog.getProfileSettings().reset('unicorn-fart-star-color-0');
dialog.getProfileSettings().reset('unicorn-fart-star-color-1');
dialog.getProfileSettings().reset('unicorn-fart-star-color-2');
dialog.getProfileSettings().reset('unicorn-fart-star-color-3');
dialog.getProfileSettings().reset('unicorn-fart-star-color-4');
dialog.getProfileSettings().reset('unicorn-fart-star-color-5');
});
// Initialize the preset dropdown menu for mushroom star colors.
Effect._createUnicornFartPresets(dialog);
}
}
// ---------------------------------------------------------------- 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: 2.0, y: 2.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 _createUnicornFartPresets(dialog) {
// Retrieve the builder object for the dialog and connect to the "realize" event of
// the button.
dialog.getBuilder()
.get_object('unicorn-fart-preset-button')
.connect('realize', (widget) => {
// Define an array of color presets, each with a name and six color values (RGBA
// format).
const presets = [
{
name: _('Unicorn Fart (Default)'),
SparkCount: 25,
SparkStart: 0.0,
SparkEnd: 1.0,
SparkOffset: 1.0,
StarCount: 6,
StarRot: 0.33,
StarSize: 0.10,
StarStart: 0.0,
StarEnd: 1.0,
BlurQuality: 5.0,
Sparkcolor0: 'rgba(255,255,255,1.0)',
Sparkcolor1: 'rgba(255,255,255,1.0)',
Sparkcolor2: 'rgba(255,255,255,1.0)',
Sparkcolor3: 'rgba(255,255,255,1.0)',
Sparkcolor4: 'rgba(255,255,255,1.0)',
Sparkcolor5: 'rgba(255,255,255,1.0)',
Starcolor0: 'rgba(255,0,0,1.0)',
Starcolor1: 'rgba(255,255,0,1.0)',
Starcolor2: 'rgba(0,255,0,1.0)',
Starcolor3: 'rgba(0,255,255,1.0)',
Starcolor4: 'rgba(0,0,255,1.0)',
Starcolor5: 'rgba(255,0,255,1.0)',
},
{
name: _('Fairy🧚'),
SparkCount: 100,
SparkStart: 0.0,
SparkEnd: 1.0,
SparkOffset: 1.0,
StarCount: 0,
StarRot: 0.33,
StarSize: 0.10,
StarStart: 0.0,
StarEnd: 1.0,
BlurQuality: 5.0,
Sparkcolor0: 'rgba(255,255,255,1.0)',
Sparkcolor1: 'rgba(255,255,255,1.0)',
Sparkcolor2: 'rgba(255,255,255,1.0)',
Sparkcolor3: 'rgba(255,255,255,1.0)',
Sparkcolor4: 'rgba(255,255,255,1.0)',
Sparkcolor5: 'rgba(255,255,255,1.0)',
Starcolor0: 'rgba(255,0,0,1.0)',
Starcolor1: 'rgba(255,255,0,1.0)',
Starcolor2: 'rgba(0,255,0,1.0)',
Starcolor3: 'rgba(0,255,255,1.0)',
Starcolor4: 'rgba(0,0,255,1.0)',
Starcolor5: 'rgba(255,0,255,1.0)',
},
{
name: _('Ring of Fire ❤️‍🔥'),
SparkCount: 100,
SparkStart: 0.0,
SparkEnd: 1.0,
SparkOffset: 1.0,
StarCount: 25,
StarRot: 3.0,
StarSize: 0.10,
StarStart: 0.0,
StarEnd: 1.0,
BlurQuality: 5.0,
Sparkcolor0: 'rgba(255,0,0,1.0)', // Deep red
Sparkcolor1: 'rgba(255,69,0,1.0)', // Fiery orange-red
Sparkcolor2: 'rgba(255,140,0,1.0)', // Orange
Sparkcolor3: 'rgba(255,215,0,1.0)', // Bright yellow
Sparkcolor4: 'rgba(255,255,102,1.0)', // Light yellow
Sparkcolor5: 'rgba(255,255,255,1.0)', // White (hottest point)
Starcolor0: 'rgba(255,0,0,1.0)', // Deep red
Starcolor1: 'rgba(255,69,0,1.0)', // Fiery orange-red
Starcolor2: 'rgba(255,140,0,1.0)', // Orange
Starcolor3: 'rgba(255,215,0,1.0)', // Bright yellow
Starcolor4: 'rgba(255,255,102,1.0)', // Light yellow
Starcolor5: 'rgba(255,255,255,1.0)', // White (hottest point)
},
{
name: _('Mystic 🪄'),
SparkCount: 100,
SparkStart: 0.0,
SparkEnd: 1.0,
SparkOffset: 1.0,
StarCount: 25,
StarRot: 3.0,
StarSize: 0.10,
StarStart: 0.0,
StarEnd: 1.0,
BlurQuality: 5.0,
Sparkcolor0: 'rgba(75,0,130,1.0)', // Indigo
Sparkcolor1: 'rgba(138,43,226,1.0)', // Blue-violet
Sparkcolor2: 'rgba(0,191,255,1.0)', // Deep sky blue
Sparkcolor3: 'rgba(0,255,127,1.0)', // Spring green
Sparkcolor4: 'rgba(173,255,47,1.0)', // Green-yellow
Sparkcolor5: 'rgba(255,20,147,1.0)', // Deep pink
Starcolor0: 'rgba(75,0,130,1.0)', // Indigo
Starcolor1: 'rgba(138,43,226,1.0)', // Blue-violet
Starcolor2: 'rgba(0,191,255,1.0)', // Deep sky blue
Starcolor3: 'rgba(0,255,127,1.0)', // Spring green
Starcolor4: 'rgba(173,255,47,1.0)', // Green-yellow
Starcolor5: 'rgba(255,20,147,1.0)', // Deep pink
},
];
// 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 = 'unicorn-fart' + 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_int('unicorn-fart-spark-count',
preset.SparkCount);
dialog.getProfileSettings().set_double('unicorn-fart-spark-start',
preset.SparkStart);
dialog.getProfileSettings().set_double('unicorn-fart-spark-end',
preset.SparkEnd);
dialog.getProfileSettings().set_double('unicorn-fart-spark-offset',
preset.SparkOffset);
dialog.getProfileSettings().set_int('unicorn-fart-star-count',
preset.StarCount);
dialog.getProfileSettings().set_double('unicorn-fart-star-rotation',
preset.StarRot);
dialog.getProfileSettings().set_double('unicorn-fart-star-size',
preset.StarSize);
dialog.getProfileSettings().set_double('unicorn-fart-star-start',
preset.StarStart);
dialog.getProfileSettings().set_double('unicorn-fart-star-end',
preset.StarEnd);
dialog.getProfileSettings().set_double('unicorn-fart-blur-quality',
preset.BlurQuality);
dialog.getProfileSettings().set_string('unicorn-fart-spark-color-0',
preset.Sparkcolor0);
dialog.getProfileSettings().set_string('unicorn-fart-spark-color-1',
preset.Sparkcolor1);
dialog.getProfileSettings().set_string('unicorn-fart-spark-color-2',
preset.Sparkcolor2);
dialog.getProfileSettings().set_string('unicorn-fart-spark-color-3',
preset.Sparkcolor3);
dialog.getProfileSettings().set_string('unicorn-fart-spark-color-4',
preset.Sparkcolor4);
dialog.getProfileSettings().set_string('unicorn-fart-spark-color-5',
preset.Sparkcolor5);
dialog.getProfileSettings().set_string('unicorn-fart-star-color-0',
preset.Starcolor0);
dialog.getProfileSettings().set_string('unicorn-fart-star-color-1',
preset.Starcolor1);
dialog.getProfileSettings().set_string('unicorn-fart-star-color-2',
preset.Starcolor2);
dialog.getProfileSettings().set_string('unicorn-fart-star-color-3',
preset.Starcolor3);
dialog.getProfileSettings().set_string('unicorn-fart-star-color-4',
preset.Starcolor4);
dialog.getProfileSettings().set_string('unicorn-fart-star-color-5',
preset.Starcolor5);
});
// Add the action to the action group.
group.add_action(action);
});
// Assign the populated menu to the preset button.
dialog.getBuilder().get_object('unicorn-fart-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);
});
}
}