168 lines
6.2 KiB
Python
168 lines
6.2 KiB
Python
import gi
|
|
import matplotlib
|
|
matplotlib.use('GTK3Agg')
|
|
from matplotlib.figure import Figure
|
|
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
|
|
|
|
from gi.repository import Gtk, Gdk, GLib
|
|
import pyperclip
|
|
import time
|
|
|
|
class AnimationConfigurator(Gtk.Window):
|
|
def __init__(self):
|
|
super().__init__(title="Hyprland Animation Configurator")
|
|
self.set_default_size(600, 600)
|
|
|
|
self.curves = {
|
|
"default": (0.25, 0.25, 0.75, 0.75),
|
|
"soft": (0.25, 0.8, 0.25, 1),
|
|
"jellyFast": (0.25, 1.1, 0.4, 1.2),
|
|
"bounce": (0.34, 1.56, 0.64, 1.0),
|
|
"snappy": (0.45, 1.8, 0.4, 1),
|
|
"smoothOut": (0.3, 1, 0.6, 1),
|
|
}
|
|
|
|
self.styles = ["slide", "popin", "gnomed", "fade", "slidefade", "slidevert", "slidefadevert"]
|
|
|
|
main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
|
|
main_box.set_margin_top(10)
|
|
main_box.set_margin_bottom(10)
|
|
main_box.set_margin_start(10)
|
|
main_box.set_margin_end(10)
|
|
|
|
# Dropdown de curvas
|
|
self.curve_combo = Gtk.ComboBoxText()
|
|
for name in self.curves:
|
|
self.curve_combo.append_text(name)
|
|
self.curve_combo.set_active(0)
|
|
self.curve_combo.connect("changed", self.update_curve)
|
|
main_box.pack_start(Gtk.Label(label="Curva Bézier"), False, False, 0)
|
|
main_box.pack_start(self.curve_combo, False, False, 0)
|
|
|
|
# Slider de velocidad
|
|
self.speed_adjustment = Gtk.Adjustment(5, 1, 20, 1, 0, 0)
|
|
self.speed_slider = Gtk.Scale(orientation=Gtk.Orientation.HORIZONTAL, adjustment=self.speed_adjustment)
|
|
self.speed_slider.set_digits(0)
|
|
main_box.pack_start(Gtk.Label(label="Velocidad (ds: 1ds = 100ms)"), False, False, 0)
|
|
main_box.pack_start(self.speed_slider, False, False, 0)
|
|
|
|
# Dropdown de estilo
|
|
self.style_combo = Gtk.ComboBoxText()
|
|
for s in self.styles:
|
|
self.style_combo.append_text(s)
|
|
self.style_combo.set_active(3) # 'fade'
|
|
main_box.pack_start(Gtk.Label(label="Estilo"), False, False, 0)
|
|
main_box.pack_start(self.style_combo, False, False, 0)
|
|
|
|
# Preview Bézier con matplotlib
|
|
self.figure = Figure(figsize=(4, 2))
|
|
self.ax = self.figure.add_subplot(111)
|
|
self.canvas = FigureCanvas(self.figure)
|
|
self.update_curve() # inicializa la curva
|
|
main_box.pack_start(self.canvas, True, True, 0)
|
|
|
|
# Botón para generar línea
|
|
self.output_label = Gtk.Label(label="")
|
|
gen_button = Gtk.Button(label="Copiar línea de configuración")
|
|
gen_button.connect("clicked", self.copy_line)
|
|
main_box.pack_start(gen_button, False, False, 5)
|
|
main_box.pack_start(self.output_label, False, False, 5)
|
|
|
|
# Botones para previews
|
|
preview_buttons = Gtk.Box(spacing=10)
|
|
fade_button = Gtk.Button(label="Previsualizar fade")
|
|
fade_button.connect("clicked", self.run_fade_preview)
|
|
slide_button = Gtk.Button(label="Previsualizar slide")
|
|
slide_button.connect("clicked", self.run_slide_preview)
|
|
preview_buttons.pack_start(fade_button, True, True, 0)
|
|
preview_buttons.pack_start(slide_button, True, True, 0)
|
|
main_box.pack_start(preview_buttons, False, False, 10)
|
|
|
|
# Área de previsualización
|
|
self.preview_area = Gtk.Fixed()
|
|
self.preview_box = Gtk.EventBox()
|
|
self.preview_box.set_size_request(100, 50)
|
|
self.preview_box.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0.2, 0.6, 1.0, 1.0))
|
|
self.preview_area.put(self.preview_box, -110, 0)
|
|
main_box.pack_start(self.preview_area, True, True, 0)
|
|
|
|
self.add(main_box)
|
|
self.show_all()
|
|
|
|
def bezier_point(self, t, p0, p1, p2, p3):
|
|
return (
|
|
(1 - t)**3 * p0 + 3 * (1 - t)**2 * t * p1 + 3 * (1 - t) * t**2 * p2 + t**3 * p3
|
|
)
|
|
|
|
def update_curve(self, *_):
|
|
name = self.curve_combo.get_active_text()
|
|
if not name:
|
|
return
|
|
x1, y1, x2, y2 = self.curves[name]
|
|
ts = [t / 100 for t in range(101)]
|
|
xs = [self.bezier_point(t, 0, x1, x2, 1) for t in ts]
|
|
ys = [self.bezier_point(t, 0, y1, y2, 1) for t in ts]
|
|
self.ax.clear()
|
|
self.ax.plot(xs, ys)
|
|
self.ax.set_title(f"Curva: {name}")
|
|
self.canvas.draw()
|
|
|
|
def copy_line(self, *_):
|
|
curve = self.curve_combo.get_active_text()
|
|
speed = int(self.speed_slider.get_value())
|
|
style = self.style_combo.get_active_text()
|
|
line = f"animation = windows, 1, {speed}, {curve}, {style}"
|
|
pyperclip.copy(line)
|
|
self.output_label.set_text(f"Copiado: {line}")
|
|
|
|
def run_fade_preview(self, *_):
|
|
name = self.curve_combo.get_active_text()
|
|
_, y1, y2, _ = 0, *self.curves[name][1:3], 1
|
|
duration = int(self.speed_slider.get_value()) * 100
|
|
steps = 60
|
|
interval = duration / steps
|
|
|
|
t = 0
|
|
def update():
|
|
nonlocal t
|
|
t += 1 / steps
|
|
if t > 1:
|
|
t = 1
|
|
alpha = self.bezier_point(t, 0, y1, y2, 1)
|
|
self.preview_box.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0.2, 0.6, 1.0, alpha))
|
|
return t < 1
|
|
|
|
self.preview_box.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0.2, 0.6, 1.0, 0))
|
|
GLib.timeout_add(int(interval), update)
|
|
|
|
def run_slide_preview(self, *_):
|
|
name = self.curve_combo.get_active_text()
|
|
x1, _, x2, _ = self.curves[name]
|
|
duration = int(self.speed_slider.get_value()) * 100
|
|
steps = 60
|
|
interval = duration / steps
|
|
width = self.preview_area.get_allocated_width()
|
|
end_x = (width - 100) // 2
|
|
|
|
t = 0
|
|
def update():
|
|
nonlocal t
|
|
t += 1 / steps
|
|
if t > 1:
|
|
t = 1
|
|
x = self.bezier_point(t, -110, x1 * end_x, x2 * end_x, end_x)
|
|
self.preview_area.move(self.preview_box, int(x), 0)
|
|
return t < 1
|
|
|
|
self.preview_area.move(self.preview_box, -110, 0)
|
|
GLib.timeout_add(int(interval), update)
|
|
|
|
|
|
def main():
|
|
win = AnimationConfigurator()
|
|
Gtk.main()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|