diff --git a/hyprland-visual-editor/README.md b/hyprland-visual-editor/README.md new file mode 100755 index 00000000..d8ced365 --- /dev/null +++ b/hyprland-visual-editor/README.md @@ -0,0 +1,75 @@ +# Hyprland Visual Editor + +Visually edit Hyprland animations, borders and shaders from a Noctalia +panel, without ever touching your `hyprland.lua`. A Luau port of XimoCP's v4 +plugin for Noctalia v5. + +> **⚠️ Lua config required.** This plugin targets Hyprland's **Lua** configuration +> (`hyprland.lua`). It does **not** work with the legacy hyprlang `.conf` format — +> HVE generates Lua (`hl.animation`, `hl.config`) and loads it via `dofile`. + +## Plugin + +| Field | Value | +| --- | --- | +| ID | `linux-fertxo/hyprland-visual-editor` | +| Entries | Bar widget: `hve-trigger` · panel: `hve-panel` · service: `hve-scanner` | + +## Requirements + +- `hyprland` running a **Lua** config (`hyprland.lua`) — not the legacy hyprlang + `.conf` format (HVE emits `hl.animation` / `hl.config` and loads via `dofile`). +- `bash` and `python` on `PATH` (the preset converter and assembler are shell + scripts that call `python3`). + +## Usage + +1. Add the **Hyprland Visual Editor** widget to your bar. +2. Click the bar widget to open the panel. Pick a preset (Animations, Borders or + Effects) and press **Apply** — HVE applies it and reloads Hyprland instantly. + +On first enable, HVE appends the overlay loader to the end of your +`~/.config/hypr/hyprland.lua` (idempotent, marked with a +`HYPRLAND VISUAL EDITOR` comment). If you prefer to do it manually, the line is: + +```lua +pcall(function() dofile(os.getenv("HOME") .. "/.cache/noctalia/HVE/overlay.lua") end) +``` + +The panel can also be toggled directly: + +```sh +noctalia msg panel-toggle linux-fertxo/hyprland-visual-editor:hve-panel +``` + +## Settings + +| Setting | Type | Default | Description | +| --- | --- | --- | --- | +| `is_system_active` | `bool` | `false` | Master switch that enables effects. | +| `active_anim_file` | `string` | `""` | Currently active animation preset. | +| `active_border_file` | `string` | `""` | Currently active border preset. | +| `active_shader_file` | `string` | `""` | Currently active shader preset. | + +## IPC + +```sh +noctalia msg panel-toggle linux-fertxo/hyprland-visual-editor:hve-panel +``` + +## Notes + +- HVE writes its generated overlay to `~/.cache/noctalia/HVE/overlay.lua` and + reloads Hyprland with `hyprctl reload` after every apply. Your `hyprland.lua` + is never modified except for the one-time loader line above. +- Ships 18 animation presets, 13 border presets and 9 GLSL shaders. Add your own + by dropping a `.conf`/`.frag` into the matching `assets/` folder with the + `@Title` / `@Desc` / `@Icon` / `@Color` / `@Tag` metadata header. +- Shaders are applied as absolute-path `screen_shader` entries; re-apply the + shader after moving the plugin directory. +- UI is localized: English (`en`), Spanish (`es`) and Catalan (`ca`). + +## Credits + +- **Architecture & core:** XimoCP (Noctalia v4, QML) +- **Luau port (v5):** Hermy & [linux-fertxo](https://github.com/linux-fertxo) diff --git a/hyprland-visual-editor/assets/animations/01_relampago.conf b/hyprland-visual-editor/assets/animations/01_relampago.conf new file mode 100755 index 00000000..8c558037 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/01_relampago.conf @@ -0,0 +1,42 @@ +# @Title: Lightning +# @Icon: bolt +# @Color: #f87171 +# @Tag: FAST +# @Desc: Maximum visual response. + +# ----------------------------------------------------- +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# +animations { + enabled = true + + # --- BEZIERS (SPEED CURVES) --- + # "Lightning": Starts ultra-fast and brakes sharply at the end. + bezier = lightning, 0.05, 0.9, 0.1, 1.05 + # "Smooth": Linear yet soft for fades. + bezier = smooth, 0.25, 1, 0.5, 1 + # "Instant": Almost instantaneous for movement. + bezier = instant, 0, 1, 0, 1 + + # --- WINDOWS (Core changes) --- + # In: Very fast (Speed 2), appears at 80% (less visual travel). + animation = windowsIn, 1, 2, lightning, popin 80% + + # Out: Fleeting (Speed 1.5). Disappears faster than it arrived. + animation = windowsOut, 1, 1.5, lightning, popin 80% + + # Movement: Snapped to mouse. Speed 1.5 makes it feel electric. + animation = windowsMove, 1, 1.5, instant, slide + + # --- LAYERS AND FADES --- + animation = fade, 1, 2, smooth + animation = layers, 1, 2, lightning, fade + animation = layersIn, 1, 2, lightning, fade + animation = layersOut, 1, 1.5, lightning, fade + + # ---WORK SPACES --- + # Slidefade: Slides but fades 20%. It gives a sensation of warp speed. + animation = workspaces, 1, 2.5, lightning, slidefade 20% + animation = specialWorkspace, 1, 2.5, lightning, slide +} diff --git a/hyprland-visual-editor/assets/animations/02_inercia_elastica.conf b/hyprland-visual-editor/assets/animations/02_inercia_elastica.conf new file mode 100755 index 00000000..dd2c1638 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/02_inercia_elastica.conf @@ -0,0 +1,52 @@ +# @Title: Elastic Inertia +# @Icon: adjustments +# @Color: #60a5fa +# @Tag: PHYSICS +# @Desc: Organic movement. The windows gain momentum when leaving and bounce when entering. + +# ----------------------------------------------------- +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +animations { + enabled = true + + # --- BEZIERS DE FÍSICA --- + + # 1. ANTICIPATION (To close): + # The curve drops to -0.1 (gains momentum behind) and then shoots to 1. + bezier = anticipate, 0.1, -0.1, 0.1, 1.0 + + # 2. INERTIA (To open): + # It arrives quickly and goes a little overboard (1.05) to settle smoothly. + bezier = inertia, 0.05, 0.9, 0.1, 1.05 + + # 3. FRICTION (To move): + # Starts fast, finishes very smooth. + bezier = friction, 0.05, 0.9, 0.1, 1.0 + + # ---ANIMATIONS --- + + # INPUT: Pure inertia. + # We use 'slide' so that it enters from the bottom/side like a physical card. + animation = windowsIn, 1, 5, inertia, slide + + # OUTPUT: Anticipation. + # Look at the effect: the window moves back a millimeter before flying away. + # We lower the speed to 6 so that there is time to see that "impulse". + animation = windowsOut, 1, 6, anticipate, slide + + # MOVEMENT: Friction. + # No weird bounces, just smooth dragging. + animation = windowsMove, 1, 5, friction, slide + + # LAYERS AND FADES: Synchronized. + # We go down from 10 to 5. Now the opacity goes hand in hand with the movement. + animation = fade, 1, 5, friction + animation = layers, 1, 5, friction, fade + + # WORKSPACES: + # 'slidefade 20%' gives a very modern 3D depth sensation. + animation = workspaces, 1, 6, inertia, slidefade 20% +} diff --git a/hyprland-visual-editor/assets/animations/03_seda_minimalista.conf b/hyprland-visual-editor/assets/animations/03_seda_minimalista.conf new file mode 100755 index 00000000..6c0f5337 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/03_seda_minimalista.conf @@ -0,0 +1,42 @@ +# @Title: Minimalist Silk +# @Icon: circle-dot +# @Color: #818cf8 +# @Tag: SOFT +# @Desc: Absolute smoothness. No bouncing, just perfect macOS-style landings. + +# ----------------------------------------------------- +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +animations { + enabled = true + + # ---BEZIERS (PURE MATHEMATICS) --- + # Quartic Out: The curve of elegance. Brakes very smoothly. + bezier = quart, 0.25, 1, 0.5, 1 + + # Expo Out: For the desktops, we want the finish to be even smoother. + bezier = expo, 0.16, 1, 0.3, 1 + + # ---WINDOWS (The change to Popin) --- + # INPUT: 'popin 80%'. The window starts from the center (at 80% size) and grows. + # It's much more elegant than watching it fly from the side of the screen. + animation = windowsIn, 1, 6, quart, popin 80% + + # OUTPUT: A little faster (Speed 5) so that it doesn't get in the way. + animation = windowsOut, 1, 5, quart, popin 80% + + # MOVEMENT: We use 'quart' so that the window has weight when dragging it. + animation = windowsMove, 1, 6, quart, slide + + # ---LAYERS --- + # Menus fade out smoothly. + animation = fade, 1, 6, quart + + # ---WORK SPACES --- + # HERE IS THE TRICK: 'slidefade 20%' + # Instead of just swiping, the old desktop gets a little darker and zooms out. + # Gives a very subtle 3D depth sensation. + animation = workspaces, 1, 6, expo, slidefade 20% +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/04_minimalismo_snappy.conf b/hyprland-visual-editor/assets/animations/04_minimalismo_snappy.conf new file mode 100755 index 00000000..0df264b4 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/04_minimalismo_snappy.conf @@ -0,0 +1,36 @@ +# @Title: Snappy Minimalism +# @Icon:bolt +# @Color: #94a3b8 +# @Tag: SNAPPY +# @Desc: Optimized for maximum speed. Only window and workspace management. + + +# ----------------------------------------------------- +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +animations { + enabled = true + + # Beziers específicos de movimiento + bezier = winIn, 0.07, 0.88, 0.04, 0.99 + bezier = menu_decel, 0.05, 0.82, 0, 1 + bezier = menu_accel, 0.38, 0, 1, 1 # <---ADDED! The missing piece + bezier = md3_decel, 0.05, 0.8, 0.1, 0.97 + bezier = easeOutCirc, 0, 0.48, 0.38, 1 + + # Window Animations + animation = windowsIn, 1, 3.2, winIn, slide + animation = windowsOut, 1, 2.8, easeOutCirc, slide # Added 'slide' to prevent jumps + animation = windowsMove, 1, 3.0, md3_decel, slide + + # Fades and Layers + animation = fade, 1, 1.8, md3_decel + animation = layersIn, 1, 1.8, menu_decel, slide + animation = layersOut, 1, 1.5, menu_accel, slide # Ahora 'menu_accel' ya existe + + # Espacios de trabajo + animation = workspaces, 1, 4.0, menu_decel, slidefade 20% + animation = specialWorkspace, 1, 2.3, md3_decel, slidefade 15% +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/05_material_moderno.conf b/hyprland-visual-editor/assets/animations/05_material_moderno.conf new file mode 100755 index 00000000..7fce074c --- /dev/null +++ b/hyprland-visual-editor/assets/animations/05_material_moderno.conf @@ -0,0 +1,52 @@ +# @Title: Modern Material +# @Icon: layers-intersect +# @Color: #c084fc +# @Tag: MODERN +# @Desc: Google Pixel aesthetic. Organic animations, subtle scales and haptic feedback. + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +animations { + enabled = true + + # ---BEZIERS (Android Officials) --- + # Decel: For things that enter (stop when they arrive) + bezier = md3_decel, 0.05, 0.7, 0.1, 1 + # Accel: For things that come out (accelerate as they leave) + bezier = md3_accel, 0.3, 0, 0.8, 0.15 + # Standard: For movements within the screen + bezier = md3_standard, 0.2, 0, 0, 1 + + # ---WINDOWS (Subtle Scale) --- + # Entry: 'popin 80%'. Less travel, more elegance. + # Speed ​​4: A little softer than standard to appreciate the curve. + animation = windowsIn, 1, 4, md3_decel, popin 80% + + # Output: 'popin 80%'. Shrinks slightly as it disappears. + # Speed ​​3: Fast, we don't want to wait for it to close. + animation = windowsOut, 1, 3, md3_accel, popin 80% + + # Movement: [CRITICAL] Explicitly defined as 'slide'. + # We use 'md3_standard' to make it feel attached to the mouse but with weight. + animation = windowsMove, 1, 3, md3_standard, slide + + # ---LAYERS AND MENUS (Consistency) --- + animation = fade, 1, 3, md3_decel + + # Layers: If you enter by sliding, you exit by sliding. + animation = layersIn, 1, 3, md3_decel, slide + animation = layersOut, 1, 3, md3_accel, slide + animation = fadeLayersIn, 1, 2, md3_decel + animation = fadeLayersOut, 1, 2, md3_accel + + # ---WORK SPACES (Depth) --- + # We use 'slidefade 20%' to simulate Android gesture navigation. + # The previous desktop darkens slightly when leaving. + animation = workspaces, 1, 5, md3_decel, slidefade 20% + + # Special: Vertical slide (like app drawer). + animation = specialWorkspace, 1, 3, md3_decel, slide +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/06_impacto_clasico.conf b/hyprland-visual-editor/assets/animations/06_impacto_clasico.conf new file mode 100755 index 00000000..99633523 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/06_impacto_clasico.conf @@ -0,0 +1,48 @@ +# @Title: Classic Impact +# @Icon: flame +# @Color: #fb7185 +# @Tag: FX +# @Desc: Jelly effect. Elastic bounce on entry and anticipation on exit. + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +animations { + enabled = true + + # ---CHARACTER BEZIERS --- + + #1. ELASTIC (Entry): Go up fast and bounce at the end (Overshoot). + bezier = elastic, 0.05, 0.9, 0.1, 1.05 + # 2. RETRO (Exit): Take momentum backwards (BackIn) and accelerate. + # This makes the window appear to "shrink" before disappearing. + bezier = retro, 0.6, -0.28, 0.735, 0.045 + + # 3. SMOOTH (Movement): To drag windows without looking like jelly. + bezier = smooth, 0.1, 1, 0.1, 1 + + # ---WINDOWS --- + + # INPUT: Speed 6. The 'popin 80%' combined with 'elastic' creates the rebound effect. + animation = windowsIn, 1, 6, elastic, popin 80% + # OUTPUT: Speed ​​5 (A little faster). + # The 'retro' curve makes it suck in before leaving. + animation = windowsOut, 1, 5, retro, popin 80% + + # MOVEMENT: We use 'slide' and a smooth curve. + # If we used 'elastic' here, the window would vibrate when released, which is dizzy. + animation = windowsMove, 1, 5, smooth, slide + + # ---REST OF THE SYSTEM --- + + # Standard fades + animation = fade, 1, 5, smooth + # Workspaces: We give them the same 'elastic' bounce so that the entire system + # feels playful and coherent. + animation = workspaces, 1, 6, elastic, slide + + # Special: Vertical slide with rebound. + animation = specialWorkspace, 1, 6, elastic, slide +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/07_lineal.conf b/hyprland-visual-editor/assets/animations/07_lineal.conf new file mode 100755 index 00000000..ae341599 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/07_lineal.conf @@ -0,0 +1,42 @@ +# @Title: Linear +# @Icon: chart-line +# @Color: #2dd4bf +# @Tag: FLAT +# @Desc: Mathematical precision. Constant movement "Sci-Fi HUD" style. + + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# ------------------------------------------------------ +# Optimized by NVL: Increased speed to avoid lag sensation. +# ------------------------------------------------------ + +animations { + enabled = true + # ---STANDARD LINEAR BEZIER --- + # Correct mathematical definition of a line from 0 to 1. + bezier = linear, 0.0, 0.0, 1.0, 1.0 + + # ---WINDOWS (Machine Style) --- + # Speed 5: Fast enough so that the final "hit" doesn't bother you. + # We use pure 'slide'. Without scales or strange transparencies. + animation = windowsIn, 1, 5, linear, slide + animation = windowsOut, 1, 5, linear, slide + + # Movement: Here the linearity feels very "raw". + # The window follows the mouse exactly, without weight. + animation = windowsMove, 1, 5, linear, slide + + # ---FADES AND LAYERS --- + # Linear fades should be fast. + animation = fade, 1, 4, linear + animation = layers, 1, 4, linear, fade + + # ---WORK SPACES --- + # Simple Slide. It's like flipping slides on an old projector. + # Dry, fast and functional. + animation = workspaces, 1, 5, linear, slide +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/08_cristal.conf b/hyprland-visual-editor/assets/animations/08_cristal.conf new file mode 100755 index 00000000..56d284ec --- /dev/null +++ b/hyprland-visual-editor/assets/animations/08_cristal.conf @@ -0,0 +1,52 @@ +# @Title: Crystal +# @Icon: droplet +# @Color: #38bdf8 +# @Tag: VIBE +# @Desc: Ethereal glide. Feeling of glass floating without friction. + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# ------------------------------------------------------ +# Optimized by NVL: Elastic bounces removed. +# Focus on "Glass" softness and transparencies. +# ------------------------------------------------------ +animations { + enabled = yes + + # ---BEZIERS (CRYSTALLINE) --- + + # "Glass": A smooth exponential curve. + # Starts fast and brakes extremely smoothly at the end (without rebound). + bezier = glass, 0.16, 1, 0.3, 1 + + # "Fade": Linear but smoothed for opacities. + bezier = fade, 0.33, 1, 0.68, 1 + + # ---WINDOWS --- + + # INPUT: We use 'slide' but with the 'glass' curve. + # The window slides in as if it were on ice/glass. + # Speed ​​6: Slow and elegant. + animation = windowsIn, 1, 6, glass, slide + + # OUTPUT: Here we apply the "ethereal touch". + # We use 'popin 90%'. The window moves away a little as it disappears. + animation = windowsOut, 1, 6, glass, popin 90% + + # MOVEMENT: Absolutely fluid. + animation = windowsMove, 1, 6, glass, slide + + # ---FADES (Protagonists) --- + # For a "Crystal" effect, the fades must be noticeable. + #Speed ​​7: Things take a while to become solid. + animation = fade, 1, 7, fade + animation = layers, 1, 6, glass, fade + + # ---WORK SPACES --- + # 'slidefade 10%' is key here. + # The movement is subtle and transparent, not aggressive. + animation = workspaces, 1, 6, glass, slidefade 10% +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/09_seda_silk.conf b/hyprland-visual-editor/assets/animations/09_seda_silk.conf new file mode 100755 index 00000000..ff506564 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/09_seda_silk.conf @@ -0,0 +1,55 @@ +# @Title: Silk +# @Icon: feather +# @Color: #4ade80 +# @Tag: HYBRID +# @Desc: The refined JaKooLit style. Energetic entries, fleeting exits and stable workspaces. + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# ------------------------------------------------------ +# Optimized by NVL: The bounce in the +# workspaces to avoid motion sickness. +# ------------------------------------------------------ + +animations { + enabled = yes + + # ---BEZIERS (The JaKooLit Signature) --- + + # "Overshot": The perfect standard bounce. + # Goes up fast, goes 5% and comes back. It feels organic. + bezier = overshot, 0.05, 0.9, 0.1, 1.05 + + # "SmoothOut": A smooth curve for fast exits. + # Starts smooth, accelerates and ends smooth. No pulling. + bezier = smoothOut, 0.3, 0, 0.3, 1 + # "Crazy": (Optional) If you want to keep that aggressive entrance from the original. + # We will use it only for window input, NOT for workspaces. + bezier = crazy, 0.1, 1.1, 0.1, 1.1 + + # ---WINDOWS (Controlled Energy) --- + + # INPUT: We use 'overshot' (or 'crazy' if you want more bounce). + # 'popin 80%' + 'slide' creates that effect of the window launching towards you. + # Speed ​​6: The fluidity is noticeable. + animation = windowsIn, 1, 6, overshot, slide + # OUTPUT: Fast (Speed ​​4). + # The window leaves without disturbing using the smooth curve. + animation = windowsOut, 1, 4, smoothOut, slide + + # MOVEMENT: Fluid and connected to the mouse. + animation = windowsMove, 1, 5, overshot, slide + + # ---LAYERS AND FADES --- + animation = fade, 1, 5, smoothOut + animation = layers, 1, 5, overshot, slide + + # ---WORK SPACES (Here is the improvement) --- + # Instead of using crazy curves, we use standard 'overshot'. + # The desktop shift has a little "settlement" at the end, + # but it no longer looks like the screen is made of jelly. + animation = workspaces, 1, 6, overshot, slide +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/10_retro_arcade.conf b/hyprland-visual-editor/assets/animations/10_retro_arcade.conf new file mode 100755 index 00000000..0d551e5d --- /dev/null +++ b/hyprland-visual-editor/assets/animations/10_retro_arcade.conf @@ -0,0 +1,58 @@ +# @Title: Retro Arcade +# @Icon: device-gamepad-2 +# @Color: #f472b6 +# @Tag: 80s +# @Desc: "Toon/Arcade" effect. The windows jump and bounce exaggeratedly. + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# ------------------------------------------------------ +# Optimized by NVL: We have moved the "crazy" curve +# from the movement (where it was annoying) to the entrance (where it was fun). +# ------------------------------------------------------ + +animations { + enabled = true + + # ---BEZIERS ARCADE --- + + # "JUMP" (Your old smoothIn): The jewel in the crown. + # Backs up a lot and bounces a lot. Perfect for "pop" windows. + bezier = jump, 0.5, -0.3, 0.68, 1.4 + + # "SQUASH" (To close): + # Anticipation to gain momentum and disappear. + bezier = squash, 0.5, -0.5, 0.1, 1.0 + + # "RUBBER" (To move): + # A more controlled bounce so that dragging is not an ordeal. + bezier = rubber, 0.05, 0.9, 0.1, 1.05 + + # ---WINDOWS (The Show) --- + + # INPUT: 'popin 80%' + 'jump'. + # The window appears small, shrinks for a millisecond, and BOING! explodes on screen. + # Speed ​​5 so that the caricature can be appreciated. + animation = windowsIn, 1, 5, jump, popin 80% + + # OUTPUT: 'popin 80%' + 'squash'. + # The window shrinks drastically (as if being vacuumed) before leaving. + animation = windowsOut, 1, 4, squash, popin 80% + + # MOVEMENT: We use 'rubber' (standard overshot). + # We want it to be fun but controllable. + animation = windowsMove, 1, 4, rubber, slide + + # ---REST OF THE SYSTEM --- + + # Fades: Quick and simple so as not to distract from the main show. + animation = fade, 1, 3, default + + # Workspaces: BOING! + # Switching desktops causes the entire screen to bounce. + # It's a very strong effect, but it fits perfectly with the "Retro" theme. + animation = workspaces, 1, 5, jump, slide +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/11_futurista.conf b/hyprland-visual-editor/assets/animations/11_futurista.conf new file mode 100755 index 00000000..293e4f5e --- /dev/null +++ b/hyprland-visual-editor/assets/animations/11_futurista.conf @@ -0,0 +1,57 @@ +# @Title: Futuristic +# @Icon: cpu +# @Color: #22d3ee +# @Tag: TECH +# @Desc: Holographic interface. Digital precision, zero bounce and vertical data flow. + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# ------------------------------------------------------ +# Optimized by NVL: Elasticity removed. +# Now uses exponential curves for "Robotic" precision. +# ------------------------------------------------------ + +animations { + enabled = true + + # ---BEZIERS TECH --- + + # "Holo": Exponential Curve (Quint). + # It darts and stops dead at exactly the right pixel. + bezier = holo, 0.23, 1, 0.32, 1 + + # "Data": Linear-Smoothed. For continuous information flows. + bezier = data, 0.16, 1, 0.3, 1 + + # ---WINDOWS (Projection) --- + + # INPUT: 'slide' from below. + # The window appears to "pop up" from the console. + # Speed ​​5: Fast but visible. + animation = windowsIn, 1, 5, holo, slide + + # OUTPUT: 'popin 100%' + 'slide'. + # The window does not resize, it just slides on and off. + # Speed ​​4: Quick disconnect. + animation = windowsOut, 1, 4, holo, popin 100% + + # MOVEMENT: Surgical precision. + # The window follows the mouse without weight, like a laser cursor. + animation = windowsMove, 1, 5, holo, slide + + # ---FADES (Digital) --- + animation = fade, 1, 5, data + animation = layers, 1, 5, holo, fade + + # ---WORK SPACES (The Matrix Style) --- + # HERE IS THE KEY: 'slide' (Vertical Sliding). + # Switching desktops feels like scrolling in a giant terminal. + # Very "Cyberpunk". + animation = workspaces, 1, 6, holo, slide + + # Special: Same thing, total vertical coherence. + animation = specialWorkspace, 1, 6, holo, slide +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/12_rebote.conf b/hyprland-visual-editor/assets/animations/12_rebote.conf new file mode 100755 index 00000000..daa42970 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/12_rebote.conf @@ -0,0 +1,58 @@ +# @Title: Rebound +# @Icon: trending-up +# @Color: #fbbf24 +# @Tag: BOUNCY +# @Desc: Vertical spring physics. The windows fall and bounce when opened. + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# ------------------------------------------------------ +# Optimized by NVL: Converted from "Fast Lift" +# to "Royal Physical Dock". +# ------------------------------------------------------ + +animations { + enabled = true + + # ---PHYSICS BEZIERS --- + + # "Spring" (The Pier): + # It goes up quickly, goes up to 1.1 (10% extra) and returns to its place. + bezier = spring, 0.05, 0.9, 0.1, 1.1 + + # "Crouch": + # Before jumping (closing), it shrinks down a little (-0.1). + bezier = crouch, 0.1, -0.1, 0.1, 1.0 + + # ---WINDOWS (Gravity Effect) --- + + # INPUT: 'popin 80%' + 'spring'. + # The window falls from above (or grows) and BOING, it bounces upon arrival. + # Speed ​​5: We need time to see the rebound. + animation = windowsIn, 1, 5, spring, popin 80% + + # OUTPUT: 'popin 80%' + 'crouch'. + # The window makes a downward gesture and disappears. + animation = windowsOut, 1, 5, crouch, popin 80% + + # MOVEMENT: Fluid but with a touch of elasticity. + animation = windowsMove, 1, 5, spring, slide + + # ---FADES --- + animation = fade, 1, 3, default + animation = fadeLayersIn, 1, 3, default + animation = layers, 1, 4, spring, popin + + # ---WORK SPACES (The Pogo Stick) --- + # We maintain your original idea of verticality ('slide'). + # When changing desktops, the entire screen goes up/down and bounces when braking. + # It's a very fun effect. + animation = workspaces, 1, 5, spring, slide + + # Gestures (Annotated for security, best in hyprland.conf) + # gesture = 3, horizontal, unset + # gesture = 3, vertical, workspace +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/13_organico.conf b/hyprland-visual-editor/assets/animations/13_organico.conf new file mode 100755 index 00000000..f7c317a2 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/13_organico.conf @@ -0,0 +1,55 @@ +# ------------------------------------------------------ +# @Title: Organic +# @Icon: leaf +# @Color: #a3e635 +# @Tag: NATURE +# @Desc: "Sprout" movement. Smooth vertical growth and slow fades. +# ------------------------------------------------------ + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# >>> Optimized by NVL: Cleanup of redundancies and plant physics. <<< + +animations { + enabled = yes + + # ---NATURAL BEZIERS --- + + # "Sprout": + # Starts slow, rises and settles extremely smoothly. + # It does not have an aggressive bounce, it is like a leaf swayed by the wind. + bezier = sprout, 0.25, 0.8, 0.25, 1.0 + + # "Wind": + # A slight overshot (1.05) for when we move windows, + # so that they don't look like stones, but rather something light. + bezier = wind, 0.05, 0.9, 0.1, 1.05 + + # ---WINDOWS (Photosynthesis) --- + # INPUT: 'popin 85%'. + # The window "pops up" to almost full size. + #Speed ​​6: Slow and relaxing. + animation = windowsIn, 1, 6, sprout, popin 85% + + # OUTPUT: 'popin 95%'. + # Hardly shrinks. It simply evaporates like dew. + animation = windowsOut, 1, 5, sprout, popin 95% + + # MOVEMENT: We use 'wind' to make it feel light when dragging. + animation = windowsMove, 1, 5, wind, slide + + # ---FADES (Fog) --- + # Speed ​​7: Very slow and dreamlike transparencies. + animation = fade, 1, 7, sprout + + # Layers: They enter gently growing. + animation = layers, 1, 5, sprout, popin + + # ---WORK SPACES (Creeper) --- + # We maintain your 'slide'. + # Moving between desks feels like climbing a vine. + animation = workspaces, 1, 6, sprout, slide +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/14_elastico.conf b/hyprland-visual-editor/assets/animations/14_elastico.conf new file mode 100755 index 00000000..96b0d923 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/14_elastico.conf @@ -0,0 +1,56 @@ +# @Title: Elastic +# @Icon: arrows-diagonal +# @Color: #6366f1 +# @Tag: FLEX +# @Desc: Rubber band physics. The windows reach, stretch and bounce vertically. + + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# ------------------------------------------------------ +# Optimized by NVL: Real bounce physics has been injected +# (15% Overshoot) to justify the name "Elastic". +# ------------------------------------------------------ + +animations { + enabled = yes + + # ---ELASTIC BEZIERS --- + + # "Rubber" (La Rubber): + # It rises very quickly and goes a long way (1.15) to create visual vibration. + bezier = rubber, 0.05, 0.9, 0.1, 1.15 + + # "Snap": + # To close windows. A reverse curve that starts slow and accelerates a lot at the end. + # How to release a tight rubber band. + bezier = snap, 0.1, 1, 0, 1 + + # ---WINDOWS (Bungee Jumping) --- + # INPUT: 'slide' + 'rubber'. + # The window enters from below/above and bounces when it reaches its position. + # Speed ​​5: Perfect to see the effect. + animation = windowsIn, 1, 5, rubber, slide + + # OUTPUT: 'slide' + 'snap'. + # The window shoots towards the vertical edge. + # Speed ​​4: Fast and dry. + animation = windowsOut, 1, 4, snap, slide + + # MOVEMENT: Here we soften a little (minor overshot) so as not to get dizzy. + animation = windowsMove, 1, 5, rubber, slide + + # ---FADES (Fast) --- + # Elasticity implies kinetic energy, not slowness. + animation = fade, 1, 4, default + + # Layers: Menus also bounce vertically. + animation = layers, 1, 4, rubber, slide + + # ---WORK SPACES (Trampoline) --- + # Vertical displacement with a lot of bounce. + animation = workspaces, 1, 6, rubber, slide +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/15_desvanecido.conf b/hyprland-visual-editor/assets/animations/15_desvanecido.conf new file mode 100755 index 00000000..c1d79385 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/15_desvanecido.conf @@ -0,0 +1,56 @@ +# @Title: Faded +# @Icon: cloud +# @Color: #cbd5e1 +# @Tag: GHOST +# @Desc: Spectral materialization. The windows appear smoothly without barely moving. + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# ------------------------------------------------------ +# Optimized by NVL: Removed physical bounces. +# Full focus on opacity and subtle scaling (The Ghost Effect). +# ------------------------------------------------------ + +animations { + enabled = yes + + # ---SPECTRAL BEZIERS --- + + # "Phantom": A pure Sine curve. + # There are no sudden accelerations or braking. It's like breathing. + bezier = phantom, 0.4, 0, 0.6, 1 + + # "Mist": + # For movement. A little more friction so it doesn't slip. + bezier = mist, 0.2, 0.8, 0.2, 1 + + # ---WINDOWS (Appearances) --- + + # INPUT: 'popin 90%' + 'phantom'. + # The window appears almost at its final size, it only grows by 10% while it becomes opaque. + #Speed ​​7: Slow. We want to see the transition. + animation = windowsIn, 1, 7, phantom, popin 90% + + # OUTPUT: 'popin 95%' + 'phantom'. + # It barely moves when closed. It just stops being there. + animation = windowsOut, 1, 6, phantom, popin 95% + + # MOVEMENT: Smooth and silent. + animation = windowsMove, 1, 6, mist, slide + + # ---FADES (The Core) --- + # Speed ​​8: The transparencies are very noticeable. + animation = fade, 1, 8, phantom + + # Layers: Menus appear floating. + animation = layers, 1, 6, phantom, popin + + # ---WORK SPACES (Teleportation) --- + # Forget the 'slide'. A ghost walks through walls. + # We use pure 'fade' or 'slidefade' with very little movement. + # This causes the old desktop to dissolve into the new one. + animation = workspaces, 1, 8, phantom, fade +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/16_dinamico.conf b/hyprland-visual-editor/assets/animations/16_dinamico.conf new file mode 100755 index 00000000..7244d288 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/16_dinamico.conf @@ -0,0 +1,29 @@ +# @Title: Dynamic +# @Icon: adjustments +# @Color: #f97316 +# @Tag: LIVE +# @Desc: Organic rhythm. Combination of speed and smooth settling. + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# ------------------------------------------------------ +# Optimized by NVL: Differentiated from "Inertia". +# Focus on the variable rhythm and "breathing" of the windows. +# ------------------------------------------------------ + +animations { + enabled = true + + bezier = pulse, 0.1, 0.9, 0.1, 1.05 + bezier = quick, 0.2, 1, 0.2, 1 + + animation = windowsIn, 1, 6, pulse, slide + animation = windowsOut, 1, 4, quick, slide + animation = windowsMove, 1, 5, pulse, slide + animation = fade, 1, 5, pulse + animation = layers, 1, 5, pulse, popin + animation = workspaces, 1, 6, pulse, slidefade 40% +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/17_sutil.conf b/hyprland-visual-editor/assets/animations/17_sutil.conf new file mode 100755 index 00000000..77769fb5 --- /dev/null +++ b/hyprland-visual-editor/assets/animations/17_sutil.conf @@ -0,0 +1,60 @@ +# @Title: Subtle +# @Icon: sparkles +# @Color: #94a3b8 +# @Tag: PRO +# @Desc: Zero distractions. Absolute smoothness without bounces or sudden movements. + + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# ------------------------------------------------------ +# Optimized by NVL: Removed all bounce physics. +# Adjusted for maximum concentration and zero eye strain. +# ------------------------------------------------------ + +animations { + enabled = true + + # ---OFFICE BEZIERS --- + + # "Soft": A soft Quartic curve. + # Start with determination and stop with absolute elegance. + bezier = soft, 0.25, 1, 0.5, 1 + + # "Focus": Linear-Smoothed. + # For movements that need to be fast but not dry. + bezier = focus, 0.16, 1, 0.3, 1 + + # ---WINDOWS (Focus Mode) --- + + # INPUT: 'popin 95%' + 'soft'. + # The window appears almost in place. It does not travel across the screen. + #Speed ​​5: Fast enough not to wait, slow enough not to scare. + animation = windowsIn, 1, 5, soft, popin 95% + + # OUTPUT: 'popin 98%' + 'focus'. + # Almost a pure fade, with a micro-scaling. + #Speed ​​4: Quick disappearance. + animation = windowsOut, 1, 4, focus, popin 98% + + # MOVEMENT: Solid. + # The window feels heavy and stable, it doesn't float. + animation = windowsMove, 1, 5, soft, slide + + # ---LAYERS AND FADES --- + # Speed 4: Quick transitions. + animation = fade, 1, 4, soft + + # Layers: They enter by sliding very little. + animation = layers, 1, 4, soft, popin + + # ---WORK SPACES (Flow) --- + # 'slidefade 5%'. + # Look at the 5%. It's a tiny movement. + # The desktop changes almost without moving, it just slides a few pixels. + # It is the definition of "Subtle". + animation = workspaces, 1, 5, soft, slidefade 5% +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/animations/18_energico.conf b/hyprland-visual-editor/assets/animations/18_energico.conf new file mode 100755 index 00000000..83435e4a --- /dev/null +++ b/hyprland-visual-editor/assets/animations/18_energico.conf @@ -0,0 +1,59 @@ +# @Title: Energetic +# @Icon: flame +# @Color: #e11d48 +# @Tag: BOLD +# @Desc: Maximum visual impact. Exaggerated rebounds (56%) and backward exits. + +# ------------------------------------------------------ +# ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ +# + +# ------------------------------------------------------ +# Optimized by NVL: Remapped high impact curve +# to the input to avoid visual glitches when closing. +# ------------------------------------------------------ + +animations { + enabled = true + + # ---HIGH OCTANE BEZIERS --- + + # "Nitro" (Your original OutBack): + # Go up to 1.56. It is the most aggressive bounce of the entire collection. + # Perfect for triumphal entrances. + bezier = nitro, 0.34, 1.56, 0.64, 1 + + # "Recoil": + # Go down to -0.3. The window visibly shrinks before disappearing. + # It's like the recoil of a gun. + bezier = recoil, 0.36, 0, 0.66, -0.56 + + # "Crazy" (For movement): + # A strong but controlled bounce to make dragging windows feel powerful. + bezier = crazy, 0.05, 0.9, 0.1, 1.05 + + # ---WINDOWS (Explosions) --- + + # INPUT: 'popin 80%' + 'nitro'. + # The window appears, it grows larger than necessary (it takes up almost the entire screen for a moment) + # and settles into place. BOOM! + animation = windowsIn, 1, 6, nitro, popin 80% + + # OUTPUT: 'popin 80%' + 'recoil'. + # The window shrinks abruptly and disappears. + animation = windowsOut, 1, 5, recoil, popin 80% + + # MOVEMENT: Heavy and powerful. + animation = windowsMove, 1, 5, crazy, slide + + # ---FADES --- + # Quick, we don't want to distract from the main action. + animation = fade, 1, 3, default + animation = layers, 1, 4, nitro, popin + + # ---WORK SPACES (Earthquake) --- + # We use 'nitro' here too. + # Switching desktops shakes the screen hard. + animation = workspaces, 1, 5, nitro, slide +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/01_cascade.conf b/hyprland-visual-editor/assets/borders/01_cascade.conf new file mode 100755 index 00000000..6f11215d --- /dev/null +++ b/hyprland-visual-editor/assets/borders/01_cascade.conf @@ -0,0 +1,30 @@ +# @Title: Waterfall +# @Icon: arrow-down +# @Color: #cba6f7 +# @Tag: FLOW +# @Desc: Dynamic border with vertical gradient using the Noctalia palette. + +# _ _ ___ ____ _____ _ _ ___ _ +# | \ | |/_ \ /___|_ _|/\ | | |_ _| /\ +# | \| | | | | | | | /_ \ | | | | /_ \ +# | |\ | |_| | |___ | |/___ \| |___ | | /___ \ +# |_| \_|\___/\____| |_/_/\_\_____|___/_/\_ +# ____ ___ ____ ____ ____ ____ ____ +# | __ ) /_ \| _ \| _ \| __ | _ \/___| +# | _ \| | | | |_) | | | | _ | |_) \___ \ +# | |_) | |_| | _ <| |_| | |__| _ < ___) | +# |____/\___/|_| \_\____/|____|_| \_\____/ +# +# ------------------------------------------------------ +# PRESET: 01_CASCADE (DYNAMIC VERSION) +# ------------------------------------------------------ + +general { + #180deg = Vertical (Top to Bottom) + # Repeat $primary to force the solid color to the bottom + col.active_border = $primary $surface 90deg + col.inactive_border = $surface_lowest +} +# Angle animation MUST be disabled for the waterfall to +# don't start spinning like a washing machine. +animation = borderangle, 0 \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/02_diagonal.conf b/hyprland-visual-editor/assets/borders/02_diagonal.conf new file mode 100755 index 00000000..e470bdc2 --- /dev/null +++ b/hyprland-visual-editor/assets/borders/02_diagonal.conf @@ -0,0 +1,31 @@ +# @Title: Diagonal +# @Icon: slash +# @Color: #cba6f7 +# @Tag: FADE +# @Desc: Smooth gradient at a 45° angle using the Noctalia palette. + +# _ _ ___ ____ _____ _ _ ___ _ +# | \ | |/_ \ /___|_ _|/\ | | |_ _| /\ +# | \| | | | | | | | /_ \ | | | | /_ \ +# | |\ | |_| | |___ | |/___ \| |___ | | /___ \ +# |_| \_|\___/\____| |_/_/\_\_____|___/_/\_ +# ____ ___ ____ ____ ____ ____ ____ +# | __ ) /_ \| _ \| _ \| __ | _ \/___| +# | _ \| | | | |_) | | | | _ | |_) \___ \ +# | |_) | |_| | _ <| |_| | |__| _ < ___) | +# |____/\___/|_| \_\____/|____|_| \_\____/ +# +# ------------------------------------------------------ +# PRESET: 02_DIAGONAL_FADE (DYNAMIC VERSION) +# ------------------------------------------------------ + +general { + # We merge the Primary color with the Surface color + # This creates the fading effect towards the bottom of the window + col.active_border = $primary $surface 45deg + # Subtle idle so as not to distract + col.inactive_border = $surface_lowest +} + +# We keep the animation at 0 for a clean, static gradient +animation = borderangle, 0 \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/03_duo.conf b/hyprland-visual-editor/assets/borders/03_duo.conf new file mode 100755 index 00000000..c8c86c29 --- /dev/null +++ b/hyprland-visual-editor/assets/borders/03_duo.conf @@ -0,0 +1,31 @@ +# @Title: Dynamic Duo +# @Icon: circle-half +# @Color: #cba6f7 +# @Tag: 2-TONE +# @Desc: High contrast between Noctalia's Primary and Secondary color. + +# _ _ ___ ____ _____ _ _ ___ _ +# | \ | |/_ \ /___|_ _|/\ | | |_ _| /\ +# | \| | | | | | | | /_ \ | | | | /_ \ +# | |\ | |_| | |___ | |/___ \| |___ | | /___ \ +# |_| \_|\___/\____| |_/_/\_\_____|___/_/\_ +# ____ ___ ____ ____ ____ ____ ____ +# | __ ) /_ \| _ \| _ \| __ | _ \/___| +# | _ \| | | | |_) | | | | _ | |_) \___ \ +# | |_) | |_| | _ <| |_| | |__| _ < ___) | +# |____/\___/|_| \_\____/|____|_| \_\____/ +# +# ------------------------------------------------------ +# PRESET: 03_DUO_CONTRAST (DYNAMIC VERSION) +# ------------------------------------------------------ + +general { + # We combine Purple ($primary) with Peach ($secondary) + # 45 degree angle creates a perfect diagonal division + col.active_border = $primary $secondary 90deg + # Subtle idle + col.inactive_border = $surface_lowest +} + +# No rotation to keep color hierarchy fixed +animation = borderangle, 0 \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/04_tri.conf b/hyprland-visual-editor/assets/borders/04_tri.conf new file mode 100755 index 00000000..b4305615 --- /dev/null +++ b/hyprland-visual-editor/assets/borders/04_tri.conf @@ -0,0 +1,32 @@ +# @Title: Noctalia Trident +# @Icon: triangle +# @Color: #94e2d5 +# @Tag: 3-TONE +# @Desc: The perfect balance between Primary, Secondary and Tertiary. + +# _ _ ___ ____ _____ _ _ ___ _ +# | \ | |/_ \ /___|_ _|/\ | | |_ _| /\ +# | \| | | | | | | | /_ \ | | | | /_ \ +# | |\ | |_| | |___ | |/___ \| |___ | | /___ \ +# |_| \_|\___/\____| |_/_/\_\_____|___/_/\_ +# ____ ___ ____ ____ ____ ____ ____ +# | __ ) /_ \| _ \| _ \| __ | _ \/___| +# | _ \| | | | |_) | | | | _ | |_) \___ \ +# | |_) | |_| | _ <| |_| | |__| _ < ___) | +# |____/\___/|_| \_\____/|____|_| \_\____/ +# +# ------------------------------------------------------ +# PRESET: 04_TRI_PRIME (DYNAMIC VERSION) +# ------------------------------------------------------ + +general { + # The Noctalia triad: Purple ($primary), Orange ($secondary) and Aquamarine ($tertiary) + # At 45 degrees, the three colors share the attention of the window. +col.active_border = $primary $secondary $tertiary 90deg + + # Dark idle to highlight the working window + col.inactive_border = $surface_lowest +} + +# No movement to maintain the elegance of the three fixed tones +animation = borderangle, 0 \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/05_spectrum.conf b/hyprland-visual-editor/assets/borders/05_spectrum.conf new file mode 100755 index 00000000..7fb89698 --- /dev/null +++ b/hyprland-visual-editor/assets/borders/05_spectrum.conf @@ -0,0 +1,32 @@ +# @Title: Spectrum +# @Icon: aperture +# @Color: #fab387 +# @Tag: RAINBOW +# @Desc: The complete Noctalia color cycle (Static). + +# _ _ ___ ____ _____ _ _ ___ _ +# | \ | |/_ \ /___|_ _|/\ | | |_ _| /\ +# | \| | | | | | | | /_ \ | | | | /_ \ +# | |\ | |_| | |___ | |/___ \| |___ | | /___ \ +# |_| \_|\___/\____| |_/_/\_\_____|___/_/\_ +# ____ ___ ____ ____ ____ ____ ____ +# | __ ) /_ \| _ \| _ \| __ | _ \/___| +# | _ \| | | | |_) | | | | _ | |_) \___ \ +# | |_) | |_| | _ <| |_| | |__| _ < ___) | +# |____/\___/|_| \_\____/|____|_| \_\____/ +# +# ------------------------------------------------------ +# PRESET: 05_FULL_SPECTRUM (DYNAMIC VERSION) +# ------------------------------------------------------ + +general { + # The "Noctalia Gang": Purple, Orange, Aquamarine and Pink/Red. + # This combination covers the entire visual spectrum of your brand. +col.active_border = $primary $secondary $tertiary $error 45deg + + # Ultra dark background to make the spectrum shine brighter + col.inactive_border = $surface_lowest +} + +# We maintain the static angle to appreciate the complete palette +animation = borderangle, 0 \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/06_pulse.conf b/hyprland-visual-editor/assets/borders/06_pulse.conf new file mode 100755 index 00000000..f44521b3 --- /dev/null +++ b/hyprland-visual-editor/assets/borders/06_pulse.conf @@ -0,0 +1,46 @@ +# @Title: Heartbeat +# @Icon: activity +# @Color: #fab387 +# @Tag: EKG +# @Desc: Electrocardiogram effect. A pulse of color runs through the window when focused. + +# _ _ ___ ____ _____ _ _ ___ _ +# | \ | |/_ \ /___|_ _|/\ | | |_ _| /\ +# | \| | | | | | | | /_ \ | | | | /_ \ +# | |\ | |_| | |___ | |/___ \| |___ | | /___ \ +# |_| \_|\___/\____| |_/_/\_\_____|___/_/\_ +# ____ ___ ____ ____ ____ ____ ____ +# | __ ) /_ \| _ \| _ \| __ | _ \/___| +# | _ \| | | | |_) | | | | _ | |_) \___ \ +# | |_) | |_| | _ <| |_| | |__| _ < ___) | +# |____/\___/|_| \_\____/|____|_| \_\____/ +# +# ------------------------------------------------------ +# PRESET: 06_HEARTBEAT (EKG STYLE) +# ------------------------------------------------------ +general { + # We maintain the visual trick: A lot of empty space and little color. + # This creates the spinning "energy ball." +col.active_border = $primary $surface $surface $surface 45deg + col.inactive_border = $surface_lowest +} + +animations { + enabled = yes + + # ---THE MAGIC CURVE --- + # bezier = name, x1, y1, x2, y2 + # + #0.05, 0.9 -> In 5% of the time, you have already completed 90% of the turn. + #0.1, 1.0 -> In 10% of the time, the turn has finished (100%). + # Rest of time -> Stays flat at 1.0 (still) until you restart the loop. + bezier = heartbeat, 0.05, 0.9, 0.1, 1.0 + # Animation: + # Speed 40: We set a long time (approx. 4 seconds total). + # Thanks to the curve, the turn lasts 0.4s and the pause lasts 3.6s. + # loop: Repeats infinitely. + animation = borderangle, 1, 40, heartbeat, loop + + # The color comes in suddenly and stays + animation = border, 1, 10, default +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/07_infinity.conf b/hyprland-visual-editor/assets/borders/07_infinity.conf new file mode 100755 index 00000000..aa7506a1 --- /dev/null +++ b/hyprland-visual-editor/assets/borders/07_infinity.conf @@ -0,0 +1,39 @@ +# @Title: Infinity +# @Icon: infinity +# @Color: #cba6f7 +# @Tag: LOOP +# @Desc: Fluid loop of Noctalia colors. Constant and elegant rotation. + +# _ _ ___ ____ _____ _ _ ___ _ +# | \ | |/_ \ /___|_ _|/\ | | |_ _| /\ +# | \| | | | | | | | /_ \ | | | | /_ \ +# | |\ | |_| | |___ | |/___ \| |___ | | /___ \ +# |_| \_|\___/\____| |_/_/\_\_____|___/_/\_ +# ____ ___ ____ ____ ____ ____ ____ +# | __ ) /_ \| _ \| _ \| __ | _ \/___| +# | _ \| | | | |_) | | | | _ | |_) \___ \ +# | |_) | |_| | _ <| |_| | |__| _ < ___) | +# |____/\___/|_| \_\____/|____|_| \_\____/ +# +# ------------------------------------------------------ +# PRESET: 07_INFINITY_LOOP (DYNAMIC VERSION) +# ------------------------------------------------------ + +general { + # We use the full palette: Primary -> Secondary -> Tertiary -> Error -> Primary + # Repeating $primary at the end ensures that the gradient is circular and uncut. +col.active_border = $primary $secondary $tertiary $error $primary $secondary $tertiary $error 45deg + col.inactive_border = $surface_lowest +} + +animations { + enabled = yes + + # The 'linear' curve is mandatory so that the movement does not have jerks. + # Note: We already injected it in assemble.sh, but defining it here ensures that it works. + bezier = linear, 0.0, 0.0, 1.0, 1.0 + + # Speed: 50 (Balanced). Not too fast that it distracts, nor too slow that it cannot be seen. +# The 'loop' mode keeps it active as long as the window has focus. + animation = borderangle, 1, 50, linear, loop +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/08_neon.conf b/hyprland-visual-editor/assets/borders/08_neon.conf new file mode 100755 index 00000000..75e33be1 --- /dev/null +++ b/hyprland-visual-editor/assets/borders/08_neon.conf @@ -0,0 +1,47 @@ +# @Title: Neon +# @Icon: blur +# @Color: #cba6f7 +# @Tag: GLITCH +# @Desc: "Cyberpunk" effect. The edge light flickers, moving back and forth like unstable electricity. + +# _ _ ___ ____ _____ _ _ ___ _ +# | \ | |/_ \ /___|_ _|/\ | | |_ _| /\ +# | \| | | | | | | | /_ \ | | | | /_ \ +# | |\ | |_| | |___ | |/___ \| |___ | | /___ \ +# |_| \_|\___/\____| |_/_/\_\_____|___/_/\_ +# ____ ___ ____ ____ ____ ____ ____ +# | __ ) /_ \| _ \| _ \| __ | _ \/___| +# | _ \| | | | |_) | | | | _ | |_) \___ \ +# | |_) | |_| | _ <| |_| | |__| _ < ___) | +# |____/\___/|_| \_\____/|____|_| \_\____/ +# +# ------------------------------------------------------ +# PRESET: 08_NEON_GLITCH (CYBERPUNK VERSION) +# ------------------------------------------------------ + +general { + # HIGH CONTRAST: + # We alternate the primary color with the background repeatedly. + # This creates "streaks" of light instead of a smooth gradient. +# It looks like the filament of a light bulb or barcode. + col.active_border = $primary $surface $primary $surface $primary $surface 45deg + + col.inactive_border = $surface_lowest +} + +animations { + enabled = yes + + # ---THE "GLITCH" CURVE --- + # Note the negative (-0.5) and excessive (1.5) numbers. + # This means: + #1. Move quickly forward. + #2. Back off! (The -0.5 causes the turn to reverse for an instant). +#3. Lunge forward again (1.5). + bezier = glitch, 0.1, 1.5, 0.9, -0.5 + + # Speed 40: A 4 second loop. + # Being an infinite loop with that crazy curve, the edge will look like + # is suffering from constant electrical interference. + animation = borderangle, 1, 40, glitch, loop +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/09_glitch.conf b/hyprland-visual-editor/assets/borders/09_glitch.conf new file mode 100755 index 00000000..1f4e6b56 --- /dev/null +++ b/hyprland-visual-editor/assets/borders/09_glitch.conf @@ -0,0 +1,38 @@ +# @Title: Cyber Glitch +# @Icon: bug +# @Color: #f38ba8 +# @Tag: ERROR +# @Desc: Aggressive digital glitch effect. Alert colors with ultra-fast rotation. + +# _ _ ___ ____ _____ _ _ ___ _ +# | \ | |/_ \ /___|_ _|/\ | | |_ _| /\ +# | \| | | | | | | | /_ \ | | | | /_ \ +# | |\ | |_| | |___ | |/___ \| |___ | | /___ \ +# |_| \_|\___/\____| |_/_/\_\_____|___/_/\_ +# ____ ___ ____ ____ ____ ____ ____ +# | __ ) /_ \| _ \| _ \| __ | _ \/___| +# | _ \| | | | |_) | | | | _ | |_) \___ \ +# | |_) | |_| | _ <| |_| | |__| _ < ___) | +# |____/\___/|_| \_\____/|____|_| \_\____/ +# +# ------------------------------------------------------ +# PRESET: 09_CYBER_GLITCH (DYNAMIC VERSION) +# ------------------------------------------------------ + +general { + # The Glitch trick: We put the background color ($surface) between the bright colors. + # When rotating fast, the edge will appear to have "dead pixels" or flickering. +col.active_border = $error $surface $primary $surface 90deg + col.inactive_border = $surface_lowest +} + +animations { + enabled = yes + + # 'Rapid' curve: Jumps almost instantly, eliminating any softness. + bezier = rapid, 0, 1, 0, 1 + + # Speed: 15 (Frantic). + # On your RTX 5070ti this will look crisp and electric, with no blurry trails. + animation = borderangle, 1, 15, rapid, loop +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/10_golden.conf b/hyprland-visual-editor/assets/borders/10_golden.conf new file mode 100755 index 00000000..2c5507bf --- /dev/null +++ b/hyprland-visual-editor/assets/borders/10_golden.conf @@ -0,0 +1,43 @@ +# @Title: Golden Luxury +# @Icon: crown +# @Color: #FFD700 +# @Tag: PRO +# @Desc: 24k gold. An intense white reflection travels over a real gold surface. + +# _ _ ___ ____ _____ _ _ ___ _ +# | \ | |/_ \ /___|_ _|/\ | | |_ _| /\ +# | \| | | | | | | | /_ \ | | | | /_ \ +# | |\ | |_| | |___ | |/___ \| |___ | | /___ \ +# |_| \_|\___/\____| |_/_/\_\_____|___/_/\_ +# ____ ___ ____ ____ ____ ____ ____ +# | __ ) /_ \| _ \| _ \| __ | _ \/___| +# | _ \| | | | |_) | | | | _ | |_) \___ \ +# | |_) | |_| | _ <| |_| | |__| _ < ___) | +# |____/\___/|_| \_\____/|____|_| \_\____/ +# + +# ------------------------------------------------------ +# PRESET: 10_GOLDEN_LUXURY (HARDCODED GOLD) +# ------------------------------------------------------ + +general { + # REAL GOLD PALETTE: + #0xffC5A000 = Dark Gold (Base) + #0xffFFD700 = Pure Gold (Medium Luster) + #0xffFFFFFF = White (Specular Reflection) +# The sequence creates a very rich metallic gradient: + col.active_border = 0xffC5A000 0xffFFD700 0xffFFFFFF 0xffFFD700 0xffC5A000 45deg + + # Inactive: A very subtle dark gray so that the gold stands out more when activated + col.inactive_border = $surface_lowest +} + +animations { + enabled = yes + + # "Shimmer": Soft curve so that the shine moves elegantly. + bezier = shimmer, 0.45, 0, 0.55, 1 + + # Speed 60: Slow and heavy movement, like precious metal. +animation = borderangle, 1, 60, shimmer, loop +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/11_toxic.conf b/hyprland-visual-editor/assets/borders/11_toxic.conf new file mode 100755 index 00000000..87e2457c --- /dev/null +++ b/hyprland-visual-editor/assets/borders/11_toxic.conf @@ -0,0 +1,32 @@ +# @Title: Toxic +# @Icon: biohazard +# @Color: #39ff14 +# @Tag: ACID +# @Desc: Intense radioactive green with toxic flow effect. + +# ------------------------------------------------------ +# Optimized by NVL +# ------------------------------------------------------ + +general { + # Thickness so that the effect is well appreciated + border_size = 2 + + # ---Radioactive Flow Effect --- + # We use Neon Green (39ff14) + Deep Black (0c1017) + Neon Green (39ff14) +# This creates a "spot" of light that runs along the edge. + col.active_border = rgba(39ff14ff) rgba(0c1017ff) rgba(39ff14ff) 30deg + + # Idle border in a very subtle dark green + col.inactive_border = rgba(022c0b55) +} + +animations { + enabled = yes + + # Smooth curve for liquid movement + bezier = nv_toxic, 0.4, 0, 0.2, 1 + + # Speed 40: A middle ground between frenetic and elegant + animation = borderangle, 1, 40, nv_toxic, loop +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/12_neon_cyberpunk.conf b/hyprland-visual-editor/assets/borders/12_neon_cyberpunk.conf new file mode 100755 index 00000000..ff2b2709 --- /dev/null +++ b/hyprland-visual-editor/assets/borders/12_neon_cyberpunk.conf @@ -0,0 +1,36 @@ +# @Title: Neon Cyber-Glow (Dual) +# @Icon: bolt +# @Color: #00fff7 +# @Tag: GLOW +# @Desc: Two-color glow simulation using a white/violet light base. + +# ------------------------------------------------------ +# Optimized by HVE +# ------------------------------------------------------ + +general { + border_size = 2 + # The border is still two-color (Cyan and Magenta) + col.active_border = rgba(00fff7ff) rgba(1a0026ff) rgba(ff00ffff) 45deg + col.inactive_border = rgba(0f0f2655) +} +decoration { + shadow { + enabled = true + range = 20 # We increase the range so that the aura is greater + render_power = 4 # More power to make the glow dense + + # ---THE TRICK --- + # We use a "bridge" color. A very transparent bluish white (44) + # acts as a focus behind the border. Turning cyan and pink + # on this white, it seems that both emit their own light. + color = rgba(ffffff44) +offset = 0 0 + } +} + +animations { + enabled = yes + bezier = nv_neon_flow, 0.4, 0, 0.2, 1 + animation = borderangle, 1, 30, nv_neon_flow, loop +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/borders/13_the_joker.conf b/hyprland-visual-editor/assets/borders/13_the_joker.conf new file mode 100755 index 00000000..d1c5e7e9 --- /dev/null +++ b/hyprland-visual-editor/assets/borders/13_the_joker.conf @@ -0,0 +1,46 @@ +# @Title: the_joker +# @Icon: mood-sad +# @Color: #39ff14 +# @Tag: THEME +# @Desc: Joker Aesthetic: Acid green and deep purple with electric glow. + +# ------------------------------------------------------ +# Optimized by HVE +# ------------------------------------------------------ + +general { + border_size = 2 + + # ---The Joker's Chaos --- + # We combine Neon Green (39ff14) with an Electric Purple (9d00ff). +# The dark color in the middle (1a0026) is vital to make the lights appear separate. + col.active_border = rgba(39ff14ff) rgba(1a0026ff) rgba(9d00ffff) 45deg + + # Inactive: Very dark and subtle purple + col.inactive_border = rgba(1a002655) +} + +decoration { + # ---Gotham Glow --- + shadow { + enabled = true + range = 18 # A slightly wider aura for the Joker effect + render_power = 3 + + # We use deep purple for the shadow. + # By rotating the green on this purple background, a vibrant optical effect is created. + color = rgba(9d00ff55) + + offset = 0 0 + } +} + +animations { + enabled = yes + + # Constant flow curve + bezier = nv_joker_flow, 0.4, 0, 0.2, 1 + + # Speed 30: A constant turn that maintains dynamism + animation = borderangle, 1, 30, nv_joker_flow, loop +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/scripts/apply_animation.sh b/hyprland-visual-editor/assets/scripts/apply_animation.sh new file mode 100755 index 00000000..348785a3 --- /dev/null +++ b/hyprland-visual-editor/assets/scripts/apply_animation.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# apply_animation.sh — HVE v5 (Lua edition) + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +PLUGIN_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")" +PRESETS_DIR="$PLUGIN_DIR/assets/animations" +FRAGMENTS_DIR="$PLUGIN_DIR/assets/fragments" +SCRIPTS_DIR="$PLUGIN_DIR/assets/scripts" +CONVERTER="$SCRIPTS_DIR/conf2lua.py" + +mkdir -p "$FRAGMENTS_DIR" +PRESET_NAME=$1 + +if [ "$PRESET_NAME" == "none" ] || [ -z "$PRESET_NAME" ]; then + rm -f "$FRAGMENTS_DIR/animation.lua" + echo "Animations disabled." +else + TARGET_FILE="$PRESETS_DIR/$PRESET_NAME" + if [ -f "$TARGET_FILE" ]; then + python3 "$CONVERTER" "$TARGET_FILE" > "$FRAGMENTS_DIR/animation.lua" + echo "Animation applied: $PRESET_NAME" + else + rm -f "$FRAGMENTS_DIR/animation.lua" + echo "Error: Animation $PRESET_NAME not found." + fi +fi + +# Assemble (sin reload — el widget lo dispara) +bash "$SCRIPTS_DIR/assemble.sh" diff --git a/hyprland-visual-editor/assets/scripts/assemble.sh b/hyprland-visual-editor/assets/scripts/assemble.sh new file mode 100755 index 00000000..cf43a404 --- /dev/null +++ b/hyprland-visual-editor/assets/scripts/assemble.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# assemble.sh — HVE v5 (Lua edition) +# Genera ~/.cache/noctalia/HVE/overlay.lua + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +PLUGIN_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")" +FRAGMENTS_DIR="$PLUGIN_DIR/assets/fragments" +HVE_SAFE_DIR="$HOME/.cache/noctalia/HVE" +FINAL_FILE="$HVE_SAFE_DIR/overlay.lua" + +mkdir -p "$HVE_SAFE_DIR" + +# 1. Header + reset +cat > "$FINAL_FILE" << 'HEADER' +-- HVE Overlay — generado automáticamente +-- Cargar desde hyprland.lua: +-- pcall(function() dofile(os.getenv("HOME") .. "/.cache/noctalia/HVE/overlay.lua") end) + +-- Reset: desactivar todas las animaciones para evitar conflictos entre presets +hl.animation({ leaf = "windowsIn", enabled = false }) +hl.animation({ leaf = "windowsOut", enabled = false }) +hl.animation({ leaf = "windowsMove", enabled = false }) +hl.animation({ leaf = "fade", enabled = false }) +hl.animation({ leaf = "fadeIn", enabled = false }) +hl.animation({ leaf = "fadeOut", enabled = false }) +hl.animation({ leaf = "fadeLayersIn", enabled = false }) +hl.animation({ leaf = "fadeLayersOut", enabled = false }) +hl.animation({ leaf = "layers", enabled = false }) +hl.animation({ leaf = "layersIn", enabled = false }) +hl.animation({ leaf = "layersOut", enabled = false }) +hl.animation({ leaf = "workspaces", enabled = false }) +hl.animation({ leaf = "specialWorkspace", enabled = false }) +hl.animation({ leaf = "borderangle", enabled = false }) +hl.animation({ leaf = "border", enabled = false }) +hl.animation({ leaf = "global", enabled = false }) + +HEADER + +# 2. Animations +if [ -f "$FRAGMENTS_DIR/animation.lua" ]; then + echo "" >> "$FINAL_FILE" + echo "-- [MODULE: ANIMATIONS]" >> "$FINAL_FILE" + cat "$FRAGMENTS_DIR/animation.lua" >> "$FINAL_FILE" +fi + +# 3. Borders +if [ -f "$FRAGMENTS_DIR/border.lua" ]; then + echo "" >> "$FINAL_FILE" + echo "-- [MODULE: BORDERS]" >> "$FINAL_FILE" + cat "$FRAGMENTS_DIR/border.lua" >> "$FINAL_FILE" +fi + +# 4. Shaders +if [ -f "$FRAGMENTS_DIR/shader.lua" ]; then + echo "" >> "$FINAL_FILE" + echo "-- [MODULE: SHADERS]" >> "$FINAL_FILE" + cat "$FRAGMENTS_DIR/shader.lua" >> "$FINAL_FILE" +fi + +# 5. Geometry +if [ -f "$FRAGMENTS_DIR/geometry.lua" ]; then + echo "" >> "$FINAL_FILE" + echo "-- [MODULE: GEOMETRY]" >> "$FINAL_FILE" + cat "$FRAGMENTS_DIR/geometry.lua" >> "$FINAL_FILE" +fi diff --git a/hyprland-visual-editor/assets/scripts/border.sh b/hyprland-visual-editor/assets/scripts/border.sh new file mode 100755 index 00000000..88102e96 --- /dev/null +++ b/hyprland-visual-editor/assets/scripts/border.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# border.sh — HVE v5: aplica preset de borde +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +PLUGIN_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")" +PRESETS_DIR="$PLUGIN_DIR/assets/borders" +FRAGMENTS_DIR="$PLUGIN_DIR/assets/fragments" +SCRIPTS_DIR="$PLUGIN_DIR/assets/scripts" +CONVERTER="$SCRIPTS_DIR/conf2lua.py" +COLORS_FILE="$HOME/.config/hypr/noctalia/noctalia-colors.lua" + +mkdir -p "$FRAGMENTS_DIR" +PRESET_NAME=$1 + +if [ "$PRESET_NAME" == "none" ] || [ -z "$PRESET_NAME" ]; then + rm -f "$FRAGMENTS_DIR/border.lua" +else + TARGET_FILE="$PRESETS_DIR/$PRESET_NAME" + if [ -f "$TARGET_FILE" ]; then + # Extraer colores de noctalia-colors.lua para expandir $variables + COLOR_ARGS="" + if [ -f "$COLORS_FILE" ]; then + while IFS= read -r line; do + name=$(echo "$line" | grep -oP 'local\s+\K\w+') + val=$(echo "$line" | grep -oP '"\K[^"]*') + if [ -n "$name" ] && [ -n "$val" ]; then + COLOR_ARGS="$COLOR_ARGS --color $name=$val" + fi + done < <(grep -oP 'local\s+\w+\s*=\s*"[^"]*"' "$COLORS_FILE") + fi + + python3 "$CONVERTER" "$TARGET_FILE" $COLOR_ARGS > "$FRAGMENTS_DIR/border.lua" + else + rm -f "$FRAGMENTS_DIR/border.lua" + fi +fi +bash "$SCRIPTS_DIR/assemble.sh" diff --git a/hyprland-visual-editor/assets/scripts/conf2lua.py b/hyprland-visual-editor/assets/scripts/conf2lua.py new file mode 100755 index 00000000..d20e9083 --- /dev/null +++ b/hyprland-visual-editor/assets/scripts/conf2lua.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python3 +"""conf2lua.py — Convierte presets .conf/.frag a llamadas hl.* para Hyprland Lua + +Uso: conf2lua.py [--color KEY=VALUE ...] + +Las variables $color se expanden con los valores proporcionados. +Ej: conf2lua.py border.conf --color primary=rgb(67e4d4) --color surface=rgb(0d2f30) +""" + +import sys, re, os + + +def gradient_to_lua(value, colors): + """Convierte '$primary $surface 90deg' → string o tabla según nº colores""" + tokens = value.strip().split() + if not tokens: + return '""' + + angle = None + color_tokens = tokens[:] + if tokens[-1].endswith('deg'): + angle = tokens[-1].replace('deg', '') + color_tokens = tokens[:-1] + + if not color_tokens: + return '""' + + # Expandir $var → valor real + resolved = [] + for t in color_tokens: + if t.startswith('$'): + varname = t[1:] + resolved.append('"' + colors.get(varname, t) + '"') + else: + resolved.append('"' + t + '"') + + if len(resolved) == 1 and not angle: + # Color sólido → string simple + return resolved[0] + + # Gradiente → formato tabla + parts = ["{\n colors = { " + ", ".join(resolved) + " }"] + if angle: + parts.append("angle = " + angle) + parts.append(" }") + return ",\n ".join(parts) + + +def parse_animation(text, lines, colors): + for line in text.split('\n'): + stripped = line.strip() + if not stripped or stripped.startswith('# @') or stripped.startswith('// @'): + continue + + if stripped.startswith('animations') or stripped.startswith('general') or stripped.startswith('decoration'): + continue + if stripped == '}' or stripped == '};': + continue + + if stripped.startswith('#') or stripped.startswith('//'): + lines.append(f"-- {stripped.lstrip('#/ ')}") + continue + + m = re.match(r'bezier\s*=\s*(\S+),\s*(\S+),\s*(\S+),\s*(\S+),\s*(\S+)', stripped) + if m: + name, x1, y1, x2, y2 = m.groups() + lines.append(f'hl.curve("{name}", {{ type = "bezier", points = {{ {{{x1}, {y1}}}, {{{x2}, {y2}}} }} }})') + continue + + m = re.match(r'animation\s*=\s*(.+?),?\s*(\d+)\s*,?\s*([^,]+)\s*,?\s*([^,]+)\s*,?\s*(.*)', stripped) + if m: + leaf, en, speed, curve, style = m.groups() + leaf = leaf.strip() + curve = curve.strip().rstrip(',') + style = style.strip().rstrip(',') + if en == '0': + lines.append(f'hl.animation({{ leaf = "{leaf}", enabled = false }})') + else: + parts = [f'leaf = "{leaf}"', f'enabled = true', f'speed = {speed}', f'bezier = "{curve}"'] + if style: + parts.append(f'style = "{style}"') + lines.append(f'hl.animation({{ {", ".join(parts)} }})') + continue + + m = re.match(r'enabled\s*=\s*(.+)', stripped) + if m: + continue + + +def parse_border(text, lines, colors): + for line in text.split('\n'): + stripped = line.strip() + if not stripped or stripped.startswith('# @') or stripped.startswith('// @'): + continue + + if stripped == '}' or stripped == '};': + continue + + if stripped.startswith('#') or stripped.startswith('//'): + lines.append(f"-- {stripped.lstrip('#/ ')}") + continue + + if stripped.startswith('general') or stripped.startswith('animations') or stripped.startswith('decoration'): + continue + + m = re.match(r'col\.active_border\s*=\s*(.+)', stripped) + if m: + val = m.group(1).strip() + lines.append(f'hl.config({{ general = {{ col = {{ active_border = {gradient_to_lua(val, colors)} }} }} }})') + continue + + # col.inactive_border = VALUE + m = re.match(r'col\.inactive_border\s*=\s*(.+)', stripped) + if m: + val = m.group(1).strip() + lines.append(f'hl.config({{ general = {{ col = {{ inactive_border = {gradient_to_lua(val, colors)} }} }} }})') + continue + + # bezier = name, x1, y1, x2, y2 (BORDER) + m = re.match(r'bezier\s*=\s*(\S+),\s*(\S+),\s*(\S+),\s*(\S+),\s*(\S+)', stripped) + if m: + name, x1, y1, x2, y2 = m.groups() + lines.append(f'hl.curve("{name}", {{ type = "bezier", points = {{ {{{x1}, {y1}}}, {{{x2}, {y2}}} }} }})') + continue + + # animation = borderangle, enabled, speed, curve, style (BORDER) + m = re.match(r'animation\s*=\s*(.+?),?\s*(\d+)\s*,?\s*([^,]+)\s*,?\s*([^,]+)\s*,?\s*(.*)', stripped) + if m: + leaf, en, speed, curve, style = m.groups() + leaf = leaf.strip() + curve = curve.strip().rstrip(',') + style = style.strip().rstrip(',') + if en == '0': + lines.append(f'hl.animation({{ leaf = "{leaf}", enabled = false }})') + else: + parts = [f'leaf = "{leaf}"', f'enabled = true', f'speed = {speed}', f'bezier = "{curve}"'] + if style: + parts.append(f'style = "{style}"') + lines.append(f'hl.animation({{ {", ".join(parts)} }})') + continue + + m = re.match(r'enabled\s*=\s*(.+)', stripped) + if m: + continue + + +def parse_shader(filepath, lines): + expanded = os.path.expanduser(filepath) if filepath.startswith('~') else filepath + lines.append(f'hl.config({{ decoration = {{ screen_shader = "{expanded}" }} }})') + + +def detect_type(text, filepath): + if filepath.endswith('.frag'): + return 'shader' + if 'col.active_border' in text or 'col.inactive_border' in text: + return 'border' + return 'animation' + + +def parse_args(): + """Parsea argumentos: archivo + --color KEY=VALUE ...""" + args = sys.argv[1:] + filepath = None + colors = {} + + i = 0 + while i < len(args): + if args[i] == '--color' and i + 1 < len(args): + kv = args[i + 1] + if '=' in kv: + k, v = kv.split('=', 1) + colors[k] = v + i += 2 + elif not filepath and not args[i].startswith('--'): + filepath = args[i] + i += 1 + else: + i += 1 + + return filepath, colors + + +def parse(text, filepath='', colors=None): + if colors is None: + colors = {} + lines = [ + "-- HVE Overlay — generado automáticamente", + "-- Cargar desde hyprland.lua con: dofile(os.getenv('HOME') .. '/.cache/noctalia/HVE/overlay.lua')", + "", + ] + + preset_type = detect_type(text, filepath) + + if preset_type == 'animation': + lines.append(f"-- [ANIMATION: {os.path.basename(filepath)}]") + parse_animation(text, lines, colors) + elif preset_type == 'border': + lines.append(f"-- [BORDER: {os.path.basename(filepath)}]") + parse_border(text, lines, colors) + elif preset_type == 'shader': + lines.append(f"-- [SHADER: {os.path.basename(filepath)}]") + parse_shader(filepath, lines) + + return '\n'.join(lines) + + +if __name__ == '__main__': + filepath, colors = parse_args() + if not filepath: + print("Uso: conf2lua.py [--color KEY=VALUE ...]", file=sys.stderr) + sys.exit(1) + + with open(filepath) as f: + content = f.read() + + print(parse(content, filepath, colors)) diff --git a/hyprland-visual-editor/assets/scripts/scan.sh b/hyprland-visual-editor/assets/scripts/scan.sh new file mode 100755 index 00000000..d475e371 --- /dev/null +++ b/hyprland-visual-editor/assets/scripts/scan.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# --- PATHS --- +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +ASSETS_DIR="$SCRIPT_DIR/.." +TARGET_FOLDER="$1" +SEARCH_DIR="$ASSETS_DIR/$TARGET_FOLDER" + +if [ ! -d "$SEARCH_DIR" ]; then echo "[]"; exit 0; fi + +echo "[" +FIRST=true + +while read -r filepath; do + filename=$(basename "$filepath") + + # Skip system files + if [[ "$filename" == *"store"* || "$filename" == "geometry.conf" ]]; then continue; fi + + ID_NAME="${filename%.*}" + + # 1. Translation keys + KEY_T="${TARGET_FOLDER}.presets.${ID_NAME}.title" + KEY_D="${TARGET_FOLDER}.presets.${ID_NAME}.desc" + + # 2. ACTUAL FILE READING (Metadata extraction) + function get_meta() { + # 2>/dev/null prevents errors on weird files + grep -m1 -E "^[ \t]*(#|//) @$1:" "$filepath" 2>/dev/null | cut -d: -f2- | sed 's/^[ \t]*//;s/[ \t]*$//;s/"/\\"/g' | tr -d '\r' + } + + RAW_T=$(get_meta "Title") + RAW_D=$(get_meta "Desc") + ICON=$(get_meta "Icon") + COLOR=$(get_meta "Color") + TAG=$(get_meta "Tag") + + # Safe default values + [ -z "$RAW_T" ] && RAW_T="$ID_NAME" + [ -z "$ICON" ] && ICON="help" + [ -z "$COLOR" ] && COLOR="#888888" + [ -z "$TAG" ] && TAG="USER" + + if [ "$FIRST" = true ]; then FIRST=false; else echo ","; fi + + # 3. JSON Output with EVERYTHING (Keys + Raw Text) + cat < /dev/null && pwd )" +PLUGIN_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")" +PRESETS_DIR="$PLUGIN_DIR/assets/shaders" +FRAGMENTS_DIR="$PLUGIN_DIR/assets/fragments" +SCRIPTS_DIR="$PLUGIN_DIR/assets/scripts" +CONVERTER="$SCRIPTS_DIR/conf2lua.py" +mkdir -p "$FRAGMENTS_DIR" +PRESET_NAME=$1 +if [ "$PRESET_NAME" == "none" ] || [ -z "$PRESET_NAME" ]; then + rm -f "$FRAGMENTS_DIR/shader.lua" +else + TARGET_FILE="$PRESETS_DIR/$PRESET_NAME" + if [ -f "$TARGET_FILE" ]; then + python3 "$CONVERTER" "$TARGET_FILE" > "$FRAGMENTS_DIR/shader.lua" + else + rm -f "$FRAGMENTS_DIR/shader.lua" + fi +fi +bash "$SCRIPTS_DIR/assemble.sh" diff --git a/hyprland-visual-editor/assets/shaders/01_night.frag b/hyprland-visual-editor/assets/shaders/01_night.frag new file mode 100755 index 00000000..5e552e83 --- /dev/null +++ b/hyprland-visual-editor/assets/shaders/01_night.frag @@ -0,0 +1,80 @@ +//@Title: Night Light +//@Icon: moon +//@Color: #fcd34d +//@Tag: WARM +//@Desc: Reduces blue light to protect eyesight. + +// from https://github.com/hyprwm/Hyprland/issues/1140#issuecomment-1335128437 + + + +/* +To override this parameters create a file named './blue-light-filter.inc' +We only need to match the file name and use 'inc' to incdicate that + this is an "include" file + Example: + + ┌────────────────────────────────────────────────────────────────────────────┐ + │ // file: ./blue-light-filter.inc │ + │ // float in Kelvin (lower = warmer) │ + │ #define BLUE_LIGHT_FILTER_TEMPERATURE 3000.0 │ + │ // float (0.0 = no effect, 1.0 = full effect) │ + │ #define BLUE_LIGHT_FILTER_INTENSITY 0.9 │ + │ │ + └────────────────────────────────────────────────────────────────────────────┘ + + + */ +#version 300 es + +#ifndef BLUE_LIGHT_FILTER_TEMPERATURE + #define BLUE_LIGHT_FILTER_TEMPERATURE 3000.0 // Default fallback value +#endif +#ifndef BLUE_LIGHT_FILTER_INTENSITY + #define BLUE_LIGHT_FILTER_INTENSITY 0.9 // Default fallback value +#endif + + +precision highp float; +in vec2 v_texcoord; +out vec4 fragColor; +uniform sampler2D tex; + + +const float TEMPERATURE = BLUE_LIGHT_FILTER_TEMPERATURE; +const float INTENSITY = BLUE_LIGHT_FILTER_INTENSITY; + +#define WithQuickAndDirtyLuminancePreservation +const float LuminancePreservationFactor = 1.0; + +// function from https://www.shadertoy.com/view/4sc3D7 +// valid from 1000 to 40000 K (and additionally 0 for pure full white) +vec3 colorTemperatureToRGB(const in float TEMPERATURE) { + // values from: http://blenderartists.org/forum/showthread.php?270332-OSL-Goodness&p=2268693&viewfull=1#post2268693 + mat3 m = (TEMPERATURE <= 6500.0) ? mat3(vec3(0.0, -2902.1955373783176, -8257.7997278925690), + vec3(0.0, 1669.5803561666639, 2575.2827530017594), + vec3(1.0, 1.3302673723350029, 1.8993753891711275)) + : mat3(vec3(1745.0425298314172, 1216.6168361476490, -8257.7997278925690), + vec3(-2666.3474220535695, -2173.1012343082230, 2575.2827530017594), + vec3(0.55995389139931482, 0.70381203140554553, 1.8993753891711275)); + return mix(clamp(vec3(m[0] / (vec3(clamp(TEMPERATURE, 1000.0, 40000.0)) + m[1]) + m[2]), vec3(0.0), vec3(1.0)), + vec3(1.0), smoothstep(1000.0, 0.0, TEMPERATURE)); +} + +void main() { + vec4 pixColor = texture(tex, v_texcoord); + + // RGB + vec3 color = vec3(pixColor[0], pixColor[1], pixColor[2]); + +#ifdef WithQuickAndDirtyLuminancePreservation + color *= mix(1.0, dot(color, vec3(0.2126, 0.7152, 0.0722)) / max(dot(color, vec3(0.2126, 0.7152, 0.0722)), 1e-5), + LuminancePreservationFactor); +#endif + + color = mix(color, color * colorTemperatureToRGB(TEMPERATURE), INTENSITY); + + vec4 outCol = vec4(color, pixColor[3]); + + fragColor = outCol; +} diff --git a/hyprland-visual-editor/assets/shaders/02_mono.frag b/hyprland-visual-editor/assets/shaders/02_mono.frag new file mode 100755 index 00000000..ca3f782d --- /dev/null +++ b/hyprland-visual-editor/assets/shaders/02_mono.frag @@ -0,0 +1,24 @@ +// @Title: Monochrome +// @Icon: circle-half +// @Color: #94a3b8 +// @Tag: BW +// @Desc: Gray scale for maximum concentration. + +#version 300 es +precision highp float; + +in vec2 v_texcoord; +out vec4 fragColor; +uniform sampler2D tex; + +void main() { + vec4 c = texture(tex, v_texcoord); + + //Standard luminance formula (NTSC/PAL) + //The human eye perceives green as brighter than blue, + //that's why we use these weights: + float gray = dot(c.rgb, vec3(0.299, 0.587, 0.114)); + + //We create a new color using the gray value for R, G and B + fragColor = vec4(vec3(gray), c.a); +} diff --git a/hyprland-visual-editor/assets/shaders/03_vibrant.frag b/hyprland-visual-editor/assets/shaders/03_vibrant.frag new file mode 100755 index 00000000..b669ef70 --- /dev/null +++ b/hyprland-visual-editor/assets/shaders/03_vibrant.frag @@ -0,0 +1,39 @@ +// @Title: Vibrant +// @Icon: sun +// @Color: #facc15 +// @Tag: SAT +// @Desc: Increases saturation and contrast. + +#version 300 es +precision highp float; + +in vec2 v_texcoord; +out vec4 fragColor; +uniform sampler2D tex; + +void main() { + // 1. Modern color capture + vec4 col = texture(tex, v_texcoord); + + // 2. Current saturation calculation + //We look for the difference between the strongest and weakest channel + float max_val = max(col.r, max(col.g, col.b)); + float min_val = min(col.r, min(col.g, col.b)); + float sat = max_val - min_val; + + // 3. Standard luminance (Rec. 709) + //We use modern coefficients for greater accuracy on digital displays: + // $$L = 0.2126R + 0.7152G + 0.0722B$$ + float luma = dot(col.rgb, vec3(0.2126, 0.7152, 0.0722)); + + //4. Vibrance Logic + //Intensity: 0.8. The lower 'sat' is, the more 'amount' we will apply. + float vibrance = 0.8; + float amount = vibrance * (1.0 - sat); + + //We mix the luminance with the original color based on intelligent calculation + vec3 result = mix(vec3(luma), col.rgb, 1.0 + amount); + + // 5. Exit + fragColor = vec4(result, col.a); +} diff --git a/hyprland-visual-editor/assets/shaders/04_sharp.frag b/hyprland-visual-editor/assets/shaders/04_sharp.frag new file mode 100755 index 00000000..2df2f5ad --- /dev/null +++ b/hyprland-visual-editor/assets/shaders/04_sharp.frag @@ -0,0 +1,37 @@ +//@Title: Sharpness +//@Icon: aperture +//@Color: #22d3ee +//@Tag: SHARP +//@Desc: Enhances borders and texts (Sharpen). + +#version 300 es +precision highp float; + +in vec2 v_texcoord; +out vec4 fragColor; +uniform sampler2D tex; + +void main() { + //1. We take the central pixel (Modern Sampling) + vec4 center = texture(tex, v_texcoord); + + //2. We define the displacement + //Note: 0.0005 is ideal for 1080p. + //If you use 4K, you might need to raise it to 0.001. + float offset = 0.0005; + + //3. We sample adjacent (texture instead of texture2D) + vec3 up = texture(tex, v_texcoord + vec2(0.0, offset)).rgb; + vec3 down = texture(tex, v_texcoord - vec2(0.0, offset)).rgb; + vec3 left = texture(tex, v_texcoord - vec2(offset, 0.0)).rgb; + vec3 right = texture(tex, v_texcoord + vec2(offset, 0.0)).rgb; + + //4. Kernel de enfoque (Laplacian Sharpening) + //We multiply the center by 5 and subtract the cross of neighbors. + //This amplifies contrast differences at the edges. + vec3 result = center.rgb * 5.0 - (up + down + left + right); + + //5. Outlet with safety cutout (clamp) + //The clamp is vital here because subtraction can give negative values + fragColor = vec4(clamp(result, 0.0, 1.0), center.a); +} diff --git a/hyprland-visual-editor/assets/shaders/05_ink.frag b/hyprland-visual-editor/assets/shaders/05_ink.frag new file mode 100755 index 00000000..6d0ce2ae --- /dev/null +++ b/hyprland-visual-editor/assets/shaders/05_ink.frag @@ -0,0 +1,36 @@ +// @Title: Paper +// @Icon: file-text +// @Color: #fdba74 +// @Tag: READ +// @Desc: Soft sepia tone for prolonged reading. + +#version 300 es +precision highp float; + +in vec2 v_texcoord; +out vec4 fragColor; +uniform sampler2D tex; + +// Noise function (Still works the same at 300 es) +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main() { + // 1. Sampling (texture instead of texture2D) + vec4 color = texture(tex, v_texcoord); + + // 2. Grayscale (Standard luminance) + float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114)); + + // 3. Sepia/paper tint + // Multiply the gray by a vector that leans towards yellow/cream + vec3 sepia = vec3(gray) * vec3(1.0, 0.95, 0.82); + + // 4. Add noise (paper grain) + // The noise is added to the final color to give that textured feel + float noise = (rand(v_texcoord) - 0.5) * 0.05; + + // 5. Final output + fragColor = vec4(sepia + noise, color.a); +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/shaders/06_invert.frag b/hyprland-visual-editor/assets/shaders/06_invert.frag new file mode 100755 index 00000000..755ec563 --- /dev/null +++ b/hyprland-visual-editor/assets/shaders/06_invert.frag @@ -0,0 +1,22 @@ +// @Title: Inverted +// @Icon: repeat +// @Color: #ffffff +// @Tag: INV +// @Desc: Inverts the colors (High Contrast Mode). + +#version 300 es +precision highp float; + +in vec2 v_texcoord; // Before: varying +out vec4 fragColor; // Before: gl_FragColor (Now we define it ourselves!) +uniform sampler2D tex; + +void main() { + // Before: texture2D -> Now: texture + vec4 pixColor = texture(tex, v_texcoord); + + // The mathematical logic DOES NOT change, just the "plumbing" + vec3 inverted = 1.0 - pixColor.rgb; + + fragColor = vec4(inverted, pixColor.a); +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/shaders/07_oled.frag b/hyprland-visual-editor/assets/shaders/07_oled.frag new file mode 100755 index 00000000..1fa6ee3a --- /dev/null +++ b/hyprland-visual-editor/assets/shaders/07_oled.frag @@ -0,0 +1,27 @@ +// @Title: Pure OLED +// @Icon: square +// @Color: #000000 +// @Tag: DARK +// @Desc: Absolute blacks for OLED screens. + +#version 300 es +precision highp float; + +in vec2 v_texcoord; +out vec4 fragColor; +uniform sampler2D tex; + +void main() { + // 1. Modern sampling + vec4 col = texture(tex, v_texcoord); + + // 2. Threshold logic + // 'length(col.rgb)' measures the total color intensity. + // If the intensity is less than 0.1, we force it to absolute black. + if(length(col.rgb) < 0.1) { + col.rgb = vec3(0.0); + } + + // 3. Output + fragColor = col; +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/shaders/08_vision.frag b/hyprland-visual-editor/assets/shaders/08_vision.frag new file mode 100755 index 00000000..9fc410fb --- /dev/null +++ b/hyprland-visual-editor/assets/shaders/08_vision.frag @@ -0,0 +1,25 @@ +// @Title: Night Vision +// @Icon: eye +// @Color: #4ade80 +// @Tag: NIGHT +// @Desc: High contrast green phosphor filter. + +#version 300 es +precision highp float; + +in vec2 v_texcoord; +out vec4 fragColor; +uniform sampler2D tex; + +void main() { + // 1. Modern sampling + vec4 col = texture(tex, v_texcoord); + + // 2. Luminance calculation + // Multiply colors by human eye sensitivity + float lum = dot(col.rgb, vec3(0.299, 0.587, 0.114)); + + // 3. Color reconstruction + // R = 0.0, G = lum, B = 0.0, A = original + fragColor = vec4(0.0, lum, 0.0, col.a); +} \ No newline at end of file diff --git a/hyprland-visual-editor/assets/shaders/09_hybrid.frag b/hyprland-visual-editor/assets/shaders/09_hybrid.frag new file mode 100755 index 00000000..5cd3e10f --- /dev/null +++ b/hyprland-visual-editor/assets/shaders/09_hybrid.frag @@ -0,0 +1,29 @@ +// @Title: Cyberpunk +// @Icon: cpu +// @Color: #d946ef +// @Tag: CYBER +// @Desc: Mix of high contrast and neon tones. + +#version 300 es +precision highp float; + +in vec2 v_texcoord; +out vec4 fragColor; +uniform sampler2D tex; + +void main() { + // 1. Modern color capture + vec4 col = texture(tex, v_texcoord); + + // 2. Controlled desaturation (30%) + // Calculate the gray and mix it with the original to avoid losing all the color + float gray = dot(col.rgb, vec3(0.299, 0.587, 0.114)); + vec3 mixed = mix(col.rgb, vec3(gray), 0.3); + + // 3. Contrast boost (Mid-tone boost) + // We use 0.5 as a pivot point: lights get lighter, darks get darker + mixed = mix(vec3(0.5), mixed, 1.2); + + // 4. Final output + fragColor = vec4(mixed, col.a); +} \ No newline at end of file diff --git a/hyprland-visual-editor/panel.luau b/hyprland-visual-editor/panel.luau new file mode 100644 index 00000000..af75101b --- /dev/null +++ b/hyprland-visual-editor/panel.luau @@ -0,0 +1,215 @@ +--!nonstrict +-- HVE v5 — Panel Principal + +local home = noctalia.getenv("HOME") or "/home/fertxo" +local pdir = noctalia.pluginDir() or (home .. "/.config/noctalia/plugins/hyprland-visual-editor") +local cacheDir = (noctalia.getenv("XDG_CACHE_HOME") or (home .. "/.cache")) .. "/noctalia/HVE" +local stateFile = cacheDir .. "/hve_state.txt" + +local function parseItems(text) + if not text or text == "" then return {} end + local items = {} + for obj in text:gmatch("%{[^}]+%}") do + local file = obj:match('"file"%s*:%s*"([^"]*)') or "" + local title = obj:match('"rawTitle"%s*:%s*"([^"]*)') or file + if file ~= "" then + table.insert(items, { file = file, title = title, + desc = obj:match('"rawDesc"%s*:%s*"([^"]*)') or "", + icon = obj:match('"icon"%s*:%s*"([^"]*)') or "help", + color = obj:match('"color"%s*:%s*"([^"]*)') or "#888", + tag = obj:match('"tag"%s*:%s*"([^"]*)') or "USER", + }) + end + end + return items +end + +local function loadItems(category) + local content = noctalia.readFile(cacheDir .. "/" .. category .. ".json") + if content then return parseItems(content) end + return {} +end + +local function loadState() + local nativeActive = noctalia.getConfig("is_system_active") + local isActive = (nativeActive == "true" or nativeActive == true) + local anim = noctalia.getConfig("active_anim_file") or "" + local border = noctalia.getConfig("active_border_file") or "" + local shader = noctalia.getConfig("active_shader_file") or "" + + local content = noctalia.readFile(stateFile) + if content then + for line in content:gmatch("[^\n]+") do + local key, val = line:match("^(%w+)=(.*)$") + if key == "isActive" then isActive = (val == "true") or isActive + elseif key == "activeAnim" and anim == "" then anim = val + elseif key == "activeBorder" and border == "" then border = val + elseif key == "activeShader" and shader == "" then shader = val + end + end + end + return isActive, anim, border, shader +end + +local activeTab = 0 +local isActive, activeAnim, activeBorder, activeShader = loadState() +local selAnim, selBorder, selShader = 0, 0, 0 +local animItems = loadItems("animations") +local borderItems = loadItems("borders") +local shaderItems = loadItems("shaders") +local tabIcons = { "home", "movie", "border-all", "wand" } + +local function t(key) + return noctalia.tr(key) +end + +-- Resuelve el destino: "archivo" si hay preset seleccionado y HVE activo, "none" si no +local function resolveTarget(isOn, file) + if isOn and file ~= "" then return file end + return "none" +end + +local function requestSave() + local state = "isActive=" .. tostring(isActive) .. "\n" + .. "activeAnim=" .. activeAnim .. "\n" + .. "activeBorder=" .. activeBorder .. "\n" + .. "activeShader=" .. activeShader + noctalia.runAsync("mkdir -p " .. cacheDir .. " && printf '%s' '" .. state .. "' > " .. stateFile, nil, 5000) +end + +local function applyAnimation(file) + noctalia.runAsync("bash " .. pdir .. "/assets/scripts/apply_animation.sh " .. file .. " && hyprctl reload 2>/dev/null", nil, 10000) +end +local function applyBorder(file) + noctalia.runAsync("bash " .. pdir .. "/assets/scripts/border.sh " .. file .. " && hyprctl reload 2>/dev/null", nil, 10000) +end +local function applyShader(file) + noctalia.runAsync("bash " .. pdir .. "/assets/scripts/shader.sh " .. file .. " && hyprctl reload 2>/dev/null", nil, 10000) +end + +local function tabBar() + local names = { t("panel.home"), t("panel.animations"), t("panel.borders"), t("panel.effects") } + local btns = {} + for i = 1, 4 do + table.insert(btns, ui.button({ + text = names[i], glyph = tabIcons[i], + onClick = "onTab" .. (i - 1), flexGrow = 1, + })) + end + return ui.row({ gap = 4, align = "stretch" }, btns) +end + +local function buildCategory(items, activeFile, category) + if #items == 0 then + return ui.label({ text = t("panel.no_presets"), color = "on_surface_variant" }) + end + local opts = { t("panel.none") } + for i, item in ipairs(items) do + local mark = (item.file == activeFile) and " ★" or "" + table.insert(opts, item.title .. mark) + end + local selVal = 0 + if category == "Anim" then selVal = selAnim + elseif category == "Border" then selVal = selBorder + elseif category == "Shader" then selVal = selShader end + local applied = activeFile ~= "" and activeFile or t("panel.none") + return ui.scroll({ flexGrow = 1, gap = 8 }, { + ui.label({ text = #items .. " " .. t("panel.presets_available"), fontSize = 12, color = "on_surface_variant" }), + ui.select({ options = opts, selectedIndex = selVal, onChange = "onSel" .. category }), + ui.button({ text = t("panel.apply"), onClick = "onApply" .. category, flexGrow = 1 }), + ui.label({ text = t("panel.current_preset") .. ": " .. applied, fontSize = 11, color = "primary" }), + }) +end + +function render() + local content + if activeTab == 0 then + local summary = "✦ " .. #animItems .. " " .. t("panel.count_animations") + .. " | " .. #borderItems .. " " .. t("panel.count_borders") + .. " | " .. #shaderItems .. " " .. t("panel.count_shaders") + local homeChildren = { + ui.label({ text = "🏠 " .. string.upper(t("panel.home")), fontSize = 16, color = "primary" }), + ui.row({ gap = 8, align = "center" }, { + ui.toggle({ checked = isActive, onChange = "onToggleActive" }), + ui.label({ text = isActive and t("panel.enabled") or t("panel.disabled"), flexGrow = 1 }), + }), + ui.label({ text = summary, fontSize = 12, color = "on_surface_variant" }), + } + if not isActive then + table.insert(homeChildren, ui.label({ text = "⚠️ " .. t("panel.enable_warning"), fontSize = 11, color = "error" })) + end + table.insert(homeChildren, ui.label({ text = "ℹ️ " .. t("panel.apply_hint"), fontSize = 11, color = "on_surface_variant" })) + table.insert(homeChildren, ui.label({ text = t("panel.credits"), fontSize = 11, color = "on_surface_variant" })) + content = ui.scroll({ flexGrow = 1, gap = 12 }, homeChildren) + elseif activeTab == 1 then + content = ui.scroll({ flexGrow = 1, gap = 8 }, { + ui.label({ text = "🎬 " .. string.upper(t("panel.animations")), fontSize = 16, color = "primary" }), + buildCategory(animItems, activeAnim, "Anim"), + }) + elseif activeTab == 2 then + content = ui.scroll({ flexGrow = 1, gap = 8 }, { + ui.label({ text = "🔲 " .. string.upper(t("panel.borders")), fontSize = 16, color = "primary" }), + buildCategory(borderItems, activeBorder, "Border"), + }) + elseif activeTab == 3 then + content = ui.scroll({ flexGrow = 1, gap = 8 }, { + ui.label({ text = "✨ " .. string.upper(t("panel.effects")), fontSize = 16, color = "primary" }), + buildCategory(shaderItems, activeShader, "Shader"), + }) + end + + panel.render(ui.column({ flexGrow = 1, gap = 12 }, { + ui.row({ align = "center", justify = "space_between", gap = 8 }, { + ui.label({ text = "🦉 Hyprland Visual Editor", fontSize = 16, fontWeight = "bold", color = "primary" }), + ui.button({ glyph = "close", onClick = "onClose" }), + }), + tabBar(), + content, + })) +end + +function onToggleActive(value) + isActive = (value == "true") + requestSave() + render() +end +function onTab0() activeTab = 0; render() end +function onTab1() activeTab = 1; render() end +function onTab2() activeTab = 2; render() end +function onTab3() activeTab = 3; render() end +function onSelAnim(idx) selAnim = tonumber(idx) or 0; render() end +function onSelBorder(idx) selBorder = tonumber(idx) or 0; render() end +function onSelShader(idx) selShader = tonumber(idx) or 0; render() end + +function onApplyAnim() + if selAnim > 0 and selAnim <= #animItems then + activeAnim = animItems[selAnim].file + else + activeAnim = "" + end + applyAnimation(resolveTarget(isActive, activeAnim)) + requestSave() + render() +end +function onApplyBorder() + if selBorder > 0 and selBorder <= #borderItems then + activeBorder = borderItems[selBorder].file + else + activeBorder = "" + end + applyBorder(resolveTarget(isActive, activeBorder)) + requestSave() + render() +end +function onApplyShader() + if selShader > 0 and selShader <= #shaderItems then + activeShader = shaderItems[selShader].file + else + activeShader = "" + end + applyShader(resolveTarget(isActive, activeShader)) + requestSave() + render() +end +function onClose() panel.close() end +function onOpen(_context) render() end diff --git a/hyprland-visual-editor/plugin.toml b/hyprland-visual-editor/plugin.toml new file mode 100644 index 00000000..78608dd8 --- /dev/null +++ b/hyprland-visual-editor/plugin.toml @@ -0,0 +1,51 @@ +id = "linux-fertxo/hyprland-visual-editor" +name = "Hyprland Visual Editor" +version = "2.0.0" +plugin_api = 3 +author = "XimoCP (v4 original) + Hermy & linux-fertxo (v5 Luau port)" +license = "MIT" +dependencies = ["hyprland", "bash", "python"] +tags = ["hyprland", "animation", "theming", "panel", "bar"] +icon = "adjustments-horizontal" +description = "Visually edit Hyprland animations, borders and shaders from a Noctalia panel." + +[[setting]] +key = "is_system_active" +type = "bool" +label_key = "settings.is_system_active.label" +description_key = "settings.is_system_active.description" +default = false + +[[setting]] +key = "active_anim_file" +type = "string" +label_key = "settings.active_anim_file.label" +default = "" + +[[setting]] +key = "active_border_file" +type = "string" +label_key = "settings.active_border_file.label" +default = "" + +[[setting]] +key = "active_shader_file" +type = "string" +label_key = "settings.active_shader_file.label" +default = "" + +[[widget]] +id = "hve-trigger" +entry = "widget.luau" + +[[service]] +id = "hve-scanner" +entry = "service.luau" + +[[panel]] +id = "hve-panel" +entry = "panel.luau" +width = 700 +height = 360 +placement = "attached" +position = "auto" diff --git a/hyprland-visual-editor/service.luau b/hyprland-visual-editor/service.luau new file mode 100644 index 00000000..2afbc579 --- /dev/null +++ b/hyprland-visual-editor/service.luau @@ -0,0 +1,22 @@ +--!nonstrict +-- HVE v5 — Background Service (cachés JSON + dofile en hyprland.lua) + +local home = noctalia.getenv("HOME") or "/home/fertxo" +local pdir = noctalia.pluginDir() or (home .. "/.config/noctalia/plugins/hyprland-visual-editor") +local cachedir = (noctalia.getenv("XDG_CACHE_HOME") or (home .. "/.cache")) .. "/noctalia/HVE" + +-- 1. Generar cachés JSON (fire-and-forget) +noctalia.runAsync("mkdir -p " .. cachedir, nil, 5000) +for _, cat in ipairs({"animations", "borders", "shaders"}) do + noctalia.runAsync("bash " .. pdir .. "/assets/scripts/scan.sh " .. cat .. " > " .. cachedir .. "/" .. cat .. ".json", nil, 30000) +end + +-- 2. Asegurar el dofile en hyprland.lua (idempotente, por marcador) +local hyprlandLua = home .. "/.config/hypr/hyprland.lua" +local content = noctalia.readFile(hyprlandLua) +if content and not content:find("HVE/overlay.lua", 1, true) then + local block = "\n\n-- >>> HYPRLAND VISUAL EDITOR (HVE) <<<\n" + .. "pcall(function() dofile(os.getenv(\"HOME\") .. \"/.cache/noctalia/HVE/overlay.lua\") end)\n" + .. "-- <<< HYPRLAND VISUAL EDITOR (HVE) <<<\n" + noctalia.writeFile(hyprlandLua, content .. block) +end diff --git a/hyprland-visual-editor/thumbnail.webp b/hyprland-visual-editor/thumbnail.webp new file mode 100644 index 00000000..5a37e2bb Binary files /dev/null and b/hyprland-visual-editor/thumbnail.webp differ diff --git a/hyprland-visual-editor/translations/ca.json b/hyprland-visual-editor/translations/ca.json new file mode 100644 index 00000000..f0c60f87 --- /dev/null +++ b/hyprland-visual-editor/translations/ca.json @@ -0,0 +1,39 @@ +{ + "settings": { + "is_system_active": { + "label": "Sistema actiu", + "description": "Interruptor mestre que activa els efectes de Hyprland Visual Editor." + }, + "active_anim_file": { + "label": "Animació activa" + }, + "active_border_file": { + "label": "Vora activa" + }, + "active_shader_file": { + "label": "Shader actiu" + } + }, + "panel": { + "home": "Inici", + "animations": "Animacions", + "borders": "Vores", + "effects": "Efectes", + "enabled": "HVE activat", + "disabled": "HVE desactivat", + "no_presets": "No hi ha presets — executa scan.sh", + "none": "Cap", + "presets_available": "presets disponibles", + "apply": "Aplica", + "current_preset": "Preset aplicat actualment", + "enable_warning": "Activa l'interruptor per aplicar canvis", + "apply_hint": "Tria un preset i prem Aplica per aplicar-lo a l'instant", + "credits": "Basat en el widget original de XimoCP · portat a Luau per Hermy i Linux Fertxo", + "count_animations": "animacions", + "count_borders": "vores", + "count_shaders": "shaders" + }, + "widget": { + "tooltip": "Hyprland Visual Editor — obrir el panel" + } +} diff --git a/hyprland-visual-editor/translations/en.json b/hyprland-visual-editor/translations/en.json new file mode 100644 index 00000000..3b7814ad --- /dev/null +++ b/hyprland-visual-editor/translations/en.json @@ -0,0 +1,39 @@ +{ + "settings": { + "is_system_active": { + "label": "System active", + "description": "Master switch that enables Hyprland Visual Editor effects." + }, + "active_anim_file": { + "label": "Active animation" + }, + "active_border_file": { + "label": "Active border" + }, + "active_shader_file": { + "label": "Active shader" + } + }, + "panel": { + "home": "Home", + "animations": "Animations", + "borders": "Borders", + "effects": "Effects", + "enabled": "HVE enabled", + "disabled": "HVE disabled", + "no_presets": "No presets found — run scan.sh", + "none": "None", + "presets_available": "presets available", + "apply": "Apply", + "current_preset": "Current preset applied", + "enable_warning": "Enable the toggle to apply changes", + "apply_hint": "Pick a preset and press Apply to apply it instantly", + "credits": "Based on the original widget by XimoCP · ported to Luau by Hermy and Linux Fertxo", + "count_animations": "animations", + "count_borders": "borders", + "count_shaders": "shaders" + }, + "widget": { + "tooltip": "Hyprland Visual Editor — open the panel" + } +} diff --git a/hyprland-visual-editor/translations/es.json b/hyprland-visual-editor/translations/es.json new file mode 100644 index 00000000..86ba83a8 --- /dev/null +++ b/hyprland-visual-editor/translations/es.json @@ -0,0 +1,39 @@ +{ + "settings": { + "is_system_active": { + "label": "Sistema activo", + "description": "Interruptor maestro que activa los efectos de Hyprland Visual Editor." + }, + "active_anim_file": { + "label": "Animación activa" + }, + "active_border_file": { + "label": "Borde activo" + }, + "active_shader_file": { + "label": "Shader activo" + } + }, + "panel": { + "home": "Inicio", + "animations": "Animaciones", + "borders": "Bordes", + "effects": "Efectos", + "enabled": "HVE activado", + "disabled": "HVE desactivado", + "no_presets": "No hay presets — ejecuta scan.sh", + "none": "Ninguno", + "presets_available": "presets disponibles", + "apply": "Aplicar", + "current_preset": "Preset aplicado actualmente", + "enable_warning": "Activa el interruptor para aplicar cambios", + "apply_hint": "Elige un preset y pulsa Aplicar para aplicarlo al instante", + "credits": "Basado en el widget original de XimoCP · portado a Luau por Hermy y Linux Fertxo", + "count_animations": "animaciones", + "count_borders": "bordes", + "count_shaders": "shaders" + }, + "widget": { + "tooltip": "Hyprland Visual Editor — abrir el panel" + } +} diff --git a/hyprland-visual-editor/widget.luau b/hyprland-visual-editor/widget.luau new file mode 100644 index 00000000..780665b7 --- /dev/null +++ b/hyprland-visual-editor/widget.luau @@ -0,0 +1,9 @@ +--!nonstrict +-- HVE v5 — Bar Widget (abre el panel) + +barWidget.setGlyph("adjustments-horizontal") +barWidget.setTooltip(noctalia.tr("widget.tooltip")) + +function onClick() + noctalia.togglePanel("linux-fertxo/hyprland-visual-editor:hve-panel") +end