diff --git a/extension.js b/extension.js index 733b0d0..df9bdad 100644 --- a/extension.js +++ b/extension.js @@ -40,6 +40,7 @@ import Pixelate from './src/effects/Pixelate.js'; import PixelWheel from './src/effects/PixelWheel.js'; import PixelWipe from './src/effects/PixelWipe.js'; import Portal from './src/effects/Portal.js'; +import RGBWarp from './src/effects/RGBWarp.js'; import SnapOfDisintegration from './src/effects/SnapOfDisintegration.js'; import TRexAttack from './src/effects/TRexAttack.js'; import TVEffect from './src/effects/TVEffect.js'; @@ -47,6 +48,8 @@ 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'; import {WindowPreview} from 'resource:///org/gnome/shell/ui/windowPreview.js'; @@ -72,30 +75,14 @@ export default class BurnMyWindows extends Extension { // New effects must be registered here and in prefs.js. this._ALL_EFFECTS = [ - 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 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 RGBWarp(), new SnapOfDisintegration(), + new TRexAttack(), new TVEffect(), new TVGlitch(), new Wisps(), new Mushroom(), + ]; // Load all of our resources. diff --git a/prefs.js b/prefs.js index 4196b3c..15d00b4 100644 --- a/prefs.js +++ b/prefs.js @@ -42,6 +42,7 @@ import Pixelate from './src/effects/Pixelate.js'; import PixelWheel from './src/effects/PixelWheel.js'; import PixelWipe from './src/effects/PixelWipe.js'; import Portal from './src/effects/Portal.js'; +import RGBWarp from './src/effects/RGBWarp.js'; import SnapOfDisintegration from './src/effects/SnapOfDisintegration.js'; import TRexAttack from './src/effects/TRexAttack.js'; import TVEffect from './src/effects/TVEffect.js'; @@ -49,6 +50,7 @@ import TVGlitch from './src/effects/TVGlitch.js'; import Wisps from './src/effects/Wisps.js'; + import {ExtensionPreferences, gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; // Currently, the extension supports only one set of UI files. In the past, there were @@ -73,11 +75,15 @@ export default class BurnMyWindowsPreferences extends ExtensionPreferences { // New effects must be registered here and in extension.js. this._ALL_EFFECTS = [ - Apparition, AuraGlow, BrokenGlass, Doom, EnergizeA, - EnergizeB, Fire, Focus, Glide, Glitch, - Hexagon, Incinerate, Matrix, Mushroom, 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, RGBWarp, SnapOfDisintegration, + TRexAttack, TVEffect, TVGlitch, + Wisps, ]; diff --git a/resources/shaders/rgbwarp.frag b/resources/shaders/rgbwarp.frag new file mode 100644 index 0000000..e362799 --- /dev/null +++ b/resources/shaders/rgbwarp.frag @@ -0,0 +1,116 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ 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) + + +uniform float uWavesize; +uniform float uBrightness; +uniform float uStretchR; +uniform float uStretchG; +uniform float uStretchB; + +// float wavesize = 1.0; +// float brightness = 1.0; +// float stretchR = 0.25; +// float stretchG = 0.20; +// float stretchB = 0.15; + + +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; +} + + +// The width of the fading effect is loaded from the settings. +uniform float uFadeWidth; + +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 ? uProgress : 1.0 - uProgress; + + //progress will now go from 0.5 to 1.0 + progress = mix(0.5,1.0,progress); + + // the UV + vec2 uv = iTexCoord.st; + vec2 f = vec2(uv.x,1.0 - uv.y); + + float w = 0.0; + + float p = mix(0.0, 1.0 + uWavesize, progress); + w = 1.0 - abs(p - f.y); + w = clamp(w,0.0,1.0); + + + w = pow(w, mix(100.0,1.0,uWavesize) ); + + float mask = 1.0; + if (p - f.y < 0.0) + { + mask = 0.0; + w = 0.0; + } + + vec4 oColor = vec4(0.0); + + oColor.r = getInputColor(uv + vec2(0.0,w * uStretchR ) ).r * mix(1.0, uBrightness, FadeInOut(progress,4)); + oColor.g = getInputColor(uv + vec2(0.0,w * uStretchG ) ).g * mix(1.0, uBrightness, FadeInOut(progress,4)); + oColor.b = getInputColor(uv + vec2(0.0,w * uStretchB ) ).b * mix(1.0, uBrightness, FadeInOut(progress,4)); + + // float stretchA = min(min(uStretchR,uStretchG),uStretchB); + // oColor.a = getInputColor(uv).a * mask * (1.0 - w); + + // float mask = (oColor.r + oColor.g + oColor.b)/3.0; + // float mask = max(max(oColor.r,oColor.g),oColor.b); + // oColor.a = getInputColor(uv).a * progress; + + //this will not work well on very dark themes + // float mask = (oColor.r + oColor.g + oColor.b)/3.0; + // if (mask > 0.0) + // { + // oColor.a = getInputColor(uv).a; + // } + + + oColor.a = getInputColor(uv).a * easeInOutSine(progress) * mask; + + // float a = getInputColor(uv).a * easeOutExpo(progress); + // oColor.a = clamp(a,0.0,1.0); + // oColor.a = getInputColor(uv).a ; + // oColor.a = mask * getInputColor(uv).a * cmax ; + + setOutputColor(oColor); +} \ No newline at end of file diff --git a/resources/ui/adw/rgbwarp.ui b/resources/ui/adw/rgbwarp.ui new file mode 100644 index 0000000..07fb495 --- /dev/null +++ b/resources/ui/adw/rgbwarp.ui @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + Animation Time [ms] + + + + center + 1 + 0 + left + 300 + + + + 5000 + 100 + 10 + 100 + + + + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + + + WaveSize + + + + + center + 1 + 2 + left + 300 + + + + 1.0 + 0.0 + 0.01 + 0.1 + + + + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + + Brightness + + + + + center + 1 + 2 + left + 300 + + + + 1.0 + 0.0 + 0.1 + 0.25 + + + + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + + OffsetRed + + + + + center + 1 + 2 + left + 300 + + + + 1.0 + 0.0 + 0.01 + 0.1 + + + + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + + OffsetGreen + + + + + center + 1 + 2 + left + 300 + + + + 1.0 + 0.0 + 0.01 + 0.1 + + + + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + + OffsetBlue + + + + + center + 1 + 2 + left + 300 + + + + 1.0 + 0.0 + 0.01 + 0.1 + + + + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + + diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml index f5e266a..c337b4b 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml @@ -1034,6 +1034,53 @@ SPDX-License-Identifier: CC0-1.0 The Percent at which the window will fade out + + + + + + false + RGBWarp Enable Effect + Use the RGBWarp. + + + + 1500 + RGBWarp Animation Time + The time the RGBWarp effect takes. + + + + 1.0 + RGBWarp Width + Width of the effect. + + + + 1.0 + RGBWarp Brightness + brightness of the effect. + + + + 1.0 + RGBWarp Red Offset + Red offset of the effect. + + + + 0.80 + RGBWarp Green Offset + Green offset of the effect. + + + + 0.60 + RGBWarp Blue Offset + Blue offset of the effect. + + + diff --git a/src/effects/AuraGlow.js b/src/effects/AuraGlow.js index 192811e..11983a4 100644 --- a/src/effects/AuraGlow.js +++ b/src/effects/AuraGlow.js @@ -155,19 +155,21 @@ export default class Effect { if (randColor) { // Connect to the "toggled" signal to update preferences dynamically randColor.connect('toggled', (widget) => { - const state = widget.get_active(); // Retrieve the state directly - EnableDisablePref(dialog, state); // Update sensitivity when the state changes + const state = widget.get_active(); // Retrieve the state directly + 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 = randColor.get_active(); // Get the initial state of the check button + + // Manually call the update function on startup, using the initial state of the + // switch + const initialState = + randColor.get_active(); // Get the initial state of the check button 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.'); } - //if we use a switch instead of a checkbox + // if we use a switch instead of a checkbox /* const switchWidget = dialog.getBuilder().get_object('aura-glow-random-color'); if (switchWidget) { diff --git a/src/effects/Mushroom.js b/src/effects/Mushroom.js index 8c1f4b8..8a2f027 100644 --- a/src/effects/Mushroom.js +++ b/src/effects/Mushroom.js @@ -235,7 +235,8 @@ export default class Effect { color5: 'rgba(0,240,236,1.0)', }, { - name: _('Red White and Blue 🇺🇸'), // A patriotic palette of red, white, and blue + name: + _('Red White and Blue 🇺🇸'), // A patriotic palette of red, white, and blue ScaleStyle: 1.0, SparkCount: 4, SparkColor: 'rgba(255,255,255,1.0)', @@ -270,7 +271,7 @@ export default class Effect { }, { name: _('Cattuccino 😺'), // A soft pastel palette inspired by a - // cappuccino theme + // cappuccino theme ScaleStyle: 1.0, SparkCount: 4, SparkColor: 'rgba(255,255,255,1.0)', @@ -313,12 +314,12 @@ export default class Effect { RingCount: 0, RingRotation: 1.33, StarCount: 7, - color0: 'rgba(255,255,255,0.0)', - color1: 'rgba(255,255,255,0.0)', - color2: 'rgba(255,255,255,0.0)', - color3: 'rgba(255,255,255,0.0)', - color4: 'rgba(255,255,255,0.0)', - color5: 'rgba(255,255,255,0.0)', + color0: 'rgba(255,255,255,0.0)', + color1: 'rgba(255,255,255,0.0)', + color2: 'rgba(255,255,255,0.0)', + color3: 'rgba(255,255,255,0.0)', + color4: 'rgba(255,255,255,0.0)', + color5: 'rgba(255,255,255,0.0)', } ]; diff --git a/src/effects/RGBWarp.js b/src/effects/RGBWarp.js new file mode 100644 index 0000000..762f858 --- /dev/null +++ b/src/effects/RGBWarp.js @@ -0,0 +1,118 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< // +// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ // +// |__/ // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Your Name +// 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 ... // +// <- Please add a description of your effect here -> // +////////////////////////////////////////////////////////////////////////////////////////// + +// 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/.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._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'); + shader._uStretchB = shader.get_uniform_location('uStretchB'); + + // 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'), + ]); + + shader.set_uniform_float(shader._uStretchR, 1, [ + settings.get_double('rgbwarp-offset-r'), + ]); + + shader.set_uniform_float(shader._uStretchG, 1, [ + settings.get_double('rgbwarp-offset-g'), + ]); + + shader.set_uniform_float(shader._uStretchB, 1, [ + settings.get_double('rgbwarp-offset-b'), + ]); + }); + }); + } + + // ---------------------------------------------------------------------------- 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 'rgbwarp'; + } + + // 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'); + } + + // -------------------------------------------------------------------- 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('rgbwarp-animation-time'); + dialog.bindAdjustment('rgbwarp-wavesize'); + dialog.bindAdjustment('rgbwarp-brightness'); + dialog.bindAdjustment('rgbwarp-offset-r'); + dialog.bindAdjustment('rgbwarp-offset-g'); + dialog.bindAdjustment('rgbwarp-offset-b'); + } + + // ---------------------------------------------------------------- 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}; + } +} \ No newline at end of file