leviathan-ui 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jesus Quijada
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.4
2
+ Name: leviathan-ui
3
+ Version: 1.0.0
4
+ Summary: Premium UI framework for PyQt5 with Windows 11 aesthetics, blur effects, and modern splash screens
5
+ Author-email: Jesus Quijada <jesusquijada.gh34@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/JesusQuijada34/leviathan-ui
8
+ Project-URL: Documentation, https://github.com/JesusQuijada34/leviathan-ui#readme
9
+ Project-URL: Repository, https://github.com/JesusQuijada34/leviathan-ui
10
+ Project-URL: Issues, https://github.com/JesusQuijada/leviathan-ui/issues
11
+ Keywords: pyqt5,ui,windows11,blur,splash,frameless,modern-ui
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Operating System :: Microsoft :: Windows
22
+ Classifier: Topic :: Software Development :: User Interfaces
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: PyQt5>=5.15.0
28
+ Requires-Dist: Pillow>=9.0.0
29
+ Dynamic: license-file
30
+
31
+ # Leviathan UI
32
+
33
+ **Premium UI Framework for PyQt5 with Windows 11 Aesthetics**
34
+
35
+ A modern, feature-rich UI framework that brings Windows 11's beautiful design language to your PyQt5 applications.
36
+
37
+ ## ✨ Features
38
+
39
+ - **🪟 WipeWindow**: Three stunning window modes
40
+ - `polished`: Solid background with shadows and rounded corners
41
+ - `ghost`: Fully transparent overlay mode
42
+ - `ghostBlur`: Acrylic/frosted glass blur effect (Windows 10/11)
43
+
44
+ - **🌊 InmersiveSplash**: Professional splash screen system
45
+ - Adaptive mode (respects taskbar) and fullscreen mode
46
+ - Custom phrases for startup and exit
47
+ - Smooth fade animations
48
+ - Automatic lifecycle management
49
+
50
+ - **🎨 CustomTitleBar**: Windows 11 style title bar
51
+ - Native SVG-drawn window controls
52
+ - System accent color integration
53
+ - Smooth drag and maximize/minimize
54
+
55
+ - **🎭 InmojiTrx**: High-quality icon generation
56
+ - Convert emojis to multi-resolution ICO files
57
+ - Support for PNG/ICO images
58
+ - Perfect taskbar rendering
59
+
60
+ ## 📦 Installation
61
+
62
+ ```bash
63
+ pip install leviathan-ui
64
+ ```
65
+
66
+ Or install from wheel:
67
+ ```bash
68
+ pip install leviathan_ui-1.0.0-py3-none-any.whl
69
+ ```
70
+
71
+ ## 🚀 Quick Start
72
+
73
+ ```python
74
+ from PyQt5.QtWidgets import QApplication, QWidget
75
+ from leviathan_ui import WipeWindow, InmersiveSplash, CustomTitleBar, InmojiTrx
76
+
77
+ app = QApplication([])
78
+
79
+ # Create your main window
80
+ window = QWidget()
81
+ window.resize(800, 600)
82
+
83
+ # Apply blur effect
84
+ WipeWindow.create()\
85
+ .set_mode("ghostBlur")\
86
+ .set_radius(15)\
87
+ .apply(window)
88
+
89
+ # Add custom title bar
90
+ title_bar = CustomTitleBar(window, title="My App")
91
+
92
+ # Set app icon
93
+ InmojiTrx("🚀").apply(app)
94
+
95
+ # Create splash screen
96
+ splash = InmersiveSplash.create()\
97
+ .set_mode("adaptive")\
98
+ .set_phrases(["Loading modules...", "Ready!"])\
99
+ .on_finish(window.show)\
100
+ .start()
101
+
102
+ app.exec_()
103
+ ```
104
+
105
+ ## 📖 Documentation
106
+
107
+ ### WipeWindow
108
+
109
+ ```python
110
+ WipeWindow.create()\
111
+ .set_mode("polished") # "polished", "ghost", or "ghostBlur"
112
+ .set_background("auto") # "auto" or hex color "#RRGGBB"
113
+ .set_radius(20) # Corner radius in pixels
114
+ .set_blur(30) # Blur intensity (ghostBlur mode only)
115
+ .apply(widget)
116
+ ```
117
+
118
+ ### InmersiveSplash
119
+
120
+ ```python
121
+ InmersiveSplash.create()\
122
+ .set_mode("adaptive") # "adaptive" or "full"
123
+ .set_color("auto") # "auto" or hex color
124
+ .set_phrases([...]) # List of status messages
125
+ .on_finish(callback) # Function to call when done
126
+ .attach_to_window(win, exit_phrases=[...]) # Auto exit splash
127
+ .start()
128
+ ```
129
+
130
+ ### CustomTitleBar
131
+
132
+ ```python
133
+ title_bar = CustomTitleBar(
134
+ parent=window,
135
+ title="My Application",
136
+ icon="🎨"
137
+ )
138
+ ```
139
+
140
+ ### InmojiTrx
141
+
142
+ ```python
143
+ # From emoji
144
+ InmojiTrx("🐉").apply(app)
145
+
146
+ # From image file
147
+ InmojiTrx("icon.png").apply(app)
148
+ ```
149
+
150
+ ## 🎯 Requirements
151
+
152
+ - Python 3.8+
153
+ - PyQt5 >= 5.15.0
154
+ - Pillow >= 9.0.0
155
+ - Windows 10/11 (for blur effects)
156
+
157
+ ## 📄 License
158
+
159
+ MIT License - feel free to use in your projects!
160
+
161
+ ## 🤝 Contributing
162
+
163
+ Contributions are welcome! Please feel free to submit a Pull Request.
164
+
165
+ ## ⭐ Credits
166
+
167
+ Created by Jesus Quijada
@@ -0,0 +1,137 @@
1
+ # Leviathan UI
2
+
3
+ **Premium UI Framework for PyQt5 with Windows 11 Aesthetics**
4
+
5
+ A modern, feature-rich UI framework that brings Windows 11's beautiful design language to your PyQt5 applications.
6
+
7
+ ## ✨ Features
8
+
9
+ - **🪟 WipeWindow**: Three stunning window modes
10
+ - `polished`: Solid background with shadows and rounded corners
11
+ - `ghost`: Fully transparent overlay mode
12
+ - `ghostBlur`: Acrylic/frosted glass blur effect (Windows 10/11)
13
+
14
+ - **🌊 InmersiveSplash**: Professional splash screen system
15
+ - Adaptive mode (respects taskbar) and fullscreen mode
16
+ - Custom phrases for startup and exit
17
+ - Smooth fade animations
18
+ - Automatic lifecycle management
19
+
20
+ - **🎨 CustomTitleBar**: Windows 11 style title bar
21
+ - Native SVG-drawn window controls
22
+ - System accent color integration
23
+ - Smooth drag and maximize/minimize
24
+
25
+ - **🎭 InmojiTrx**: High-quality icon generation
26
+ - Convert emojis to multi-resolution ICO files
27
+ - Support for PNG/ICO images
28
+ - Perfect taskbar rendering
29
+
30
+ ## 📦 Installation
31
+
32
+ ```bash
33
+ pip install leviathan-ui
34
+ ```
35
+
36
+ Or install from wheel:
37
+ ```bash
38
+ pip install leviathan_ui-1.0.0-py3-none-any.whl
39
+ ```
40
+
41
+ ## 🚀 Quick Start
42
+
43
+ ```python
44
+ from PyQt5.QtWidgets import QApplication, QWidget
45
+ from leviathan_ui import WipeWindow, InmersiveSplash, CustomTitleBar, InmojiTrx
46
+
47
+ app = QApplication([])
48
+
49
+ # Create your main window
50
+ window = QWidget()
51
+ window.resize(800, 600)
52
+
53
+ # Apply blur effect
54
+ WipeWindow.create()\
55
+ .set_mode("ghostBlur")\
56
+ .set_radius(15)\
57
+ .apply(window)
58
+
59
+ # Add custom title bar
60
+ title_bar = CustomTitleBar(window, title="My App")
61
+
62
+ # Set app icon
63
+ InmojiTrx("🚀").apply(app)
64
+
65
+ # Create splash screen
66
+ splash = InmersiveSplash.create()\
67
+ .set_mode("adaptive")\
68
+ .set_phrases(["Loading modules...", "Ready!"])\
69
+ .on_finish(window.show)\
70
+ .start()
71
+
72
+ app.exec_()
73
+ ```
74
+
75
+ ## 📖 Documentation
76
+
77
+ ### WipeWindow
78
+
79
+ ```python
80
+ WipeWindow.create()\
81
+ .set_mode("polished") # "polished", "ghost", or "ghostBlur"
82
+ .set_background("auto") # "auto" or hex color "#RRGGBB"
83
+ .set_radius(20) # Corner radius in pixels
84
+ .set_blur(30) # Blur intensity (ghostBlur mode only)
85
+ .apply(widget)
86
+ ```
87
+
88
+ ### InmersiveSplash
89
+
90
+ ```python
91
+ InmersiveSplash.create()\
92
+ .set_mode("adaptive") # "adaptive" or "full"
93
+ .set_color("auto") # "auto" or hex color
94
+ .set_phrases([...]) # List of status messages
95
+ .on_finish(callback) # Function to call when done
96
+ .attach_to_window(win, exit_phrases=[...]) # Auto exit splash
97
+ .start()
98
+ ```
99
+
100
+ ### CustomTitleBar
101
+
102
+ ```python
103
+ title_bar = CustomTitleBar(
104
+ parent=window,
105
+ title="My Application",
106
+ icon="🎨"
107
+ )
108
+ ```
109
+
110
+ ### InmojiTrx
111
+
112
+ ```python
113
+ # From emoji
114
+ InmojiTrx("🐉").apply(app)
115
+
116
+ # From image file
117
+ InmojiTrx("icon.png").apply(app)
118
+ ```
119
+
120
+ ## 🎯 Requirements
121
+
122
+ - Python 3.8+
123
+ - PyQt5 >= 5.15.0
124
+ - Pillow >= 9.0.0
125
+ - Windows 10/11 (for blur effects)
126
+
127
+ ## 📄 License
128
+
129
+ MIT License - feel free to use in your projects!
130
+
131
+ ## 🤝 Contributing
132
+
133
+ Contributions are welcome! Please feel free to submit a Pull Request.
134
+
135
+ ## ⭐ Credits
136
+
137
+ Created by Jesus Quijada
@@ -0,0 +1,6 @@
1
+ from .splash import InmersiveSplash
2
+ from .title_bar import CustomTitleBar, get_accent_color
3
+ from .inmojiTrx import InmojiTrx
4
+ from .wipeWindow import WipeWindow
5
+ from .lightsOff import LightsOff
6
+ from .dialogs import LeviathanDialog
@@ -0,0 +1,52 @@
1
+ import logging
2
+ import traceback
3
+ import sys
4
+ import os
5
+ from datetime import datetime
6
+
7
+ class LeviathanDebugger:
8
+ """
9
+ Herramienta de depuración robusta para Leviathan.
10
+ Captura errores inesperados y los muestra de forma legible.
11
+ """
12
+ @staticmethod
13
+ def setup_logging(log_file="debug.log"):
14
+ try:
15
+ logging.basicConfig(
16
+ level=logging.DEBUG,
17
+ format='%(asctime)s [%(levelname)s] %(name)s: %(message)s',
18
+ handlers=[
19
+ logging.FileHandler(log_file, encoding='utf-8'),
20
+ logging.StreamHandler(sys.stdout)
21
+ ]
22
+ )
23
+ except Exception as e:
24
+ print(f"⚠️ No se pudo iniciar el logging: {e}")
25
+
26
+ @staticmethod
27
+ def parse_error(e):
28
+ """Devuelve un resumen formateado del error para la terminal."""
29
+ ts = datetime.now().strftime("%H:%M:%S")
30
+ error_type = type(e).__name__
31
+ msg = str(e)
32
+ tb = traceback.format_exc()
33
+ return f"\n{'='*50}\n[{ts}] ❌ ERROR ({error_type}): {msg}\n--- TRACEBACK ---\n{tb}{'='*50}\n"
34
+
35
+ def _handle_exception(exc_type, exc_value, exc_traceback):
36
+ """Manejador global de excepciones no capturadas."""
37
+ if issubclass(exc_type, KeyboardInterrupt):
38
+ sys.__excepthook__(exc_type, exc_value, exc_traceback)
39
+ return
40
+
41
+ error_msg = LeviathanDebugger.parse_error(exc_value)
42
+ logging.critical("Excepción no capturada:", exc_info=(exc_type, exc_value, exc_traceback))
43
+ print(error_msg, file=sys.stderr)
44
+
45
+ def install_debugger(log_file="debug.log"):
46
+ """
47
+ Instala el sistema de depuración global.
48
+ Llama a esto al principio de tu archivo principal.
49
+ """
50
+ sys.excepthook = _handle_exception
51
+ LeviathanDebugger.setup_logging(log_file)
52
+ print("🚀 Depurador Leviathan Activado")
@@ -0,0 +1,174 @@
1
+ import sys
2
+ from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
3
+ QPushButton, QApplication, QFrame)
4
+ from PyQt5.QtCore import Qt, QPropertyAnimation, QEasingCurve, QRect, QPoint, QEvent
5
+ from PyQt5.QtGui import QFont, QColor
6
+
7
+ from .title_bar import CustomTitleBar, get_accent_color
8
+ from .wipeWindow import WipeWindow
9
+ from .lightsOff import LightsOff
10
+
11
+ class LeviathanDialog(QWidget):
12
+ """
13
+ 💠 LeviathanDialog: Reemplazo moderno para QMessageBox.
14
+ Integra Blur Overlay, TitleBar personalizada y efecto LightsOff.
15
+ """
16
+
17
+ TYPES = {
18
+ "info": {"icon": "ℹ️", "color": "auto"},
19
+ "success": {"icon": "✅", "color": "#28a745"},
20
+ "warning": {"icon": "⚠️", "color": "#ffc107"},
21
+ "error": {"icon": "❌", "color": "#dc3545"}
22
+ }
23
+
24
+ def __init__(self, parent, title, message, mode="info", buttons=None):
25
+ super().__init__(None) # Dialog flotante
26
+ self._parent_win = parent
27
+ self._mode_cfg = self.TYPES.get(mode, self.TYPES["info"])
28
+ self._accent = get_accent_color() if self._mode_cfg["color"] == "auto" else self._mode_cfg["color"]
29
+ self._buttons = buttons or ["ENTENDIDO"]
30
+ self._result = None
31
+ self._callback = None
32
+
33
+ self.setWindowTitle(title)
34
+ self.setFixedSize(450, 240)
35
+ self.setWindowModality(Qt.WindowModal if parent else Qt.NonModal)
36
+ self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
37
+
38
+ # 1. Overlay Blur (Cubre la ventana principal)
39
+ if self._parent_win:
40
+ self.overlay = QWidget(self._parent_win)
41
+ self.overlay.setGeometry(self._parent_win.rect())
42
+ # Nos aseguramos que el overlay redimensione con el padre
43
+ self._parent_win.installEventFilter(self)
44
+ WipeWindow.create().set_mode("ghostBlur").set_blur(40).apply(self.overlay)
45
+ self.overlay.show()
46
+ else:
47
+ self.overlay = None
48
+
49
+ # 2. Configuración de Ventana (WipeWindow)
50
+ WipeWindow.create()\
51
+ .set_mode("polished")\
52
+ .set_background("#181818")\
53
+ .set_radius(20)\
54
+ .apply(self)
55
+
56
+ # 3. Layout Principal
57
+ self.main_layout = QVBoxLayout(self)
58
+ self.main_layout.setContentsMargins(0, 0, 0, 0)
59
+ self.main_layout.setSpacing(0)
60
+
61
+ # Barra de Título
62
+ self.title_bar = CustomTitleBar(self, title=title, icon=self._mode_cfg["icon"])
63
+ self.main_layout.addWidget(self.title_bar)
64
+
65
+ # Contenido
66
+ content_frame = QFrame()
67
+ content_lay = QVBoxLayout(content_frame)
68
+ content_lay.setContentsMargins(30, 20, 30, 25)
69
+ content_lay.setSpacing(20)
70
+
71
+ msg_lay = QHBoxLayout()
72
+ icon_lbl = QLabel(self._mode_cfg["icon"])
73
+ icon_lbl.setFont(QFont("Segoe UI Emoji", 32))
74
+ icon_lbl.setStyleSheet("background: transparent;")
75
+
76
+ self.msg_lbl = QLabel(message)
77
+ self.msg_lbl.setWordWrap(True)
78
+ self.msg_lbl.setStyleSheet("color: #eeeeee; font-size: 14px; font-family: 'Segoe UI'; background: transparent;")
79
+
80
+ msg_lay.addWidget(icon_lbl)
81
+ msg_lay.addSpacing(15)
82
+ msg_lay.addWidget(self.msg_lbl, 1)
83
+ content_lay.addLayout(msg_lay)
84
+
85
+ # Botones Dinámicos
86
+ btn_container = QHBoxLayout()
87
+ btn_container.addStretch()
88
+
89
+ for btn_text in self._buttons:
90
+ btn = QPushButton(btn_text)
91
+ btn.setFixedSize(110, 36)
92
+
93
+ # Estilo basado en acento
94
+ is_main = btn_text == self._buttons[-1]
95
+ bg = self._accent if is_main else "transparent"
96
+ fg = "black" if is_main else "white"
97
+ border = f"2px solid {self._accent}"
98
+
99
+ btn.setStyleSheet(f"""
100
+ QPushButton {{
101
+ background-color: {bg};
102
+ color: {fg};
103
+ border: {border};
104
+ border-radius: 8px;
105
+ font-weight: bold;
106
+ font-family: 'Segoe UI';
107
+ }}
108
+ QPushButton:hover {{
109
+ background-color: white;
110
+ color: black;
111
+ border: 2px solid white;
112
+ }}
113
+ """)
114
+
115
+ # Efecto Glow
116
+ LightsOff.light_up(btn, color=self._accent if not is_main else "#ffffff", intensity=15)
117
+
118
+ btn.clicked.connect(lambda checked, t=btn_text: self._on_btn_clicked(t))
119
+ btn_container.addWidget(btn)
120
+
121
+ content_lay.addLayout(btn_container)
122
+ self.main_layout.addWidget(content_frame)
123
+
124
+ # Centrar respecto al padre
125
+ self._update_position()
126
+
127
+ # 5. Animaciones combinadas (Opacidad + Escala/Posición)
128
+ self.setWindowOpacity(0)
129
+ self.fade_anim = QPropertyAnimation(self, b"windowOpacity")
130
+ self.fade_anim.setDuration(350)
131
+ self.fade_anim.setStartValue(0)
132
+ self.fade_anim.setEndValue(1)
133
+ self.fade_anim.setEasingCurve(QEasingCurve.OutCubic)
134
+
135
+ def _update_position(self):
136
+ if self._parent_win:
137
+ center = self._parent_win.geometry().center()
138
+ self.move(center.x() - self.width() // 2, center.y() - self.height() // 2)
139
+
140
+ def eventFilter(self, obj, event):
141
+ # Sincronizar overlay con el padre si este cambia de tamaño
142
+ try:
143
+ if obj == self._parent_win and event.type() == QEvent.Resize:
144
+ if self.overlay:
145
+ self.overlay.setGeometry(self._parent_win.rect())
146
+ except: pass
147
+ return super().eventFilter(obj, event)
148
+
149
+ def _on_btn_clicked(self, text):
150
+ self._result = text
151
+ self.close()
152
+ # El callback se ejecuta DESPUÉS del close para que la UI esté limpia
153
+ if self._callback: self._callback(text)
154
+
155
+ def showEvent(self, event):
156
+ self.fade_anim.start()
157
+ super().showEvent(event)
158
+
159
+ def closeEvent(self, event):
160
+ # MUY IMPORTANTE: Remover el filtro antes de cerrar para evitar punteros rotos
161
+ if self._parent_win:
162
+ self._parent_win.removeEventFilter(self)
163
+ if self.overlay:
164
+ self.overlay.close()
165
+ self.overlay.deleteLater()
166
+ event.accept()
167
+ self.deleteLater() # Asegura que Python libere el objeto
168
+
169
+ @staticmethod
170
+ def launch(parent, title, message, mode="info", buttons=None, callback=None):
171
+ dlg = LeviathanDialog(parent, title, message, mode, buttons)
172
+ dlg._callback = callback
173
+ dlg.show()
174
+ return dlg
@@ -0,0 +1,21 @@
1
+ class FixLights:
2
+ """
3
+ 🛠️ fixLights: Debugger especializado para el sistema de iluminación.
4
+ Verifica si los widgets tienen efectos aplicados y si las animaciones están listas.
5
+ """
6
+ @staticmethod
7
+ def audit(widget):
8
+ """Revisa la salud visual de un widget."""
9
+ has_effect = widget.graphicsEffect() is not None
10
+ status = "✅ OK" if has_effect else "❌ NO LIGHTS"
11
+ print(f"Audit [{widget.objectName() or 'Widget'}]: {status}")
12
+ return has_effect
13
+
14
+ @staticmethod
15
+ def fix_all(app):
16
+ """Intenta reaplicar efectos a todos los hijos de la app si fallan."""
17
+ from .lightsOff import light_up
18
+ for widget in app.allWidgets():
19
+ if not widget.graphicsEffect():
20
+ light_up(widget)
21
+ print("🛠️ fixLights: Iluminación restaurada en todos los controles.")