Initial commit
Dieser Commit ist enthalten in:
272
views/widgets/forge_animation_widget.py
Normale Datei
272
views/widgets/forge_animation_widget.py
Normale Datei
@ -0,0 +1,272 @@
|
||||
"""
|
||||
Forge Animation Widget - Verbesserter Dialog für Account-Erstellung mit prominenter Warnung
|
||||
"""
|
||||
|
||||
from PyQt5.QtWidgets import QDialog, QWidget, QVBoxLayout, QLabel, QTextEdit, QPushButton, QHBoxLayout, QFrame
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, QTimer
|
||||
from PyQt5.QtGui import QFont, QMovie, QPixmap
|
||||
|
||||
class ForgeAnimationDialog(QDialog):
|
||||
"""Modal-Dialog für die Account-Erstellung mit verbessertem Design"""
|
||||
|
||||
# Signal wenn Abbrechen geklickt wird
|
||||
cancel_clicked = pyqtSignal()
|
||||
# Signal wenn Dialog geschlossen wird
|
||||
closed = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None, platform_name="", is_login=False):
|
||||
super().__init__(parent)
|
||||
self.platform_name = platform_name
|
||||
self.is_login = is_login
|
||||
self.init_ui()
|
||||
|
||||
# Timer für das regelmäßige Nach-vorne-Holen
|
||||
self.raise_timer = QTimer()
|
||||
self.raise_timer.timeout.connect(self._raise_to_front)
|
||||
self.raise_timer.setInterval(500) # Alle 500ms
|
||||
|
||||
def init_ui(self):
|
||||
"""Initialisiert die UI mit verbessertem Design"""
|
||||
# Nur Dialog im Vordergrund, nicht das ganze Hauptfenster
|
||||
self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
|
||||
self.setModal(False) # Nicht modal - blockiert nicht das Hauptfenster
|
||||
self.setFixedSize(650, 600) # Ursprüngliche Größe beibehalten
|
||||
|
||||
# Styling für Light Theme
|
||||
self.setStyleSheet("""
|
||||
ForgeAnimationDialog {
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #E2E8F0;
|
||||
border-radius: 8px;
|
||||
}
|
||||
""")
|
||||
|
||||
# Hauptlayout
|
||||
layout = QVBoxLayout()
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setSpacing(0)
|
||||
|
||||
# NEUE WARNUNG OBEN - Sehr auffällig!
|
||||
warning_banner = QFrame()
|
||||
warning_banner.setFixedHeight(120) # Angepasste Höhe
|
||||
warning_banner.setStyleSheet("""
|
||||
QFrame {
|
||||
background-color: #DC2626;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
""")
|
||||
|
||||
warning_layout = QVBoxLayout(warning_banner)
|
||||
warning_layout.setContentsMargins(10, 10, 10, 10) # Reduzierte Margins
|
||||
warning_layout.setSpacing(5) # Weniger Abstand zwischen den Elementen
|
||||
|
||||
# Großer Warning Text
|
||||
warning_text = QLabel("⚠️ BROWSER NICHT BERÜHREN!")
|
||||
warning_text.setAlignment(Qt.AlignCenter)
|
||||
warning_text.setFixedHeight(40) # Feste Höhe für das Label
|
||||
warning_text.setStyleSheet("""
|
||||
QLabel {
|
||||
color: #FFFFFF;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
""")
|
||||
|
||||
warning_subtext = QLabel("Jede Interaktion kann den Prozess unterbrechen")
|
||||
warning_subtext.setAlignment(Qt.AlignCenter)
|
||||
warning_subtext.setFixedHeight(25) # Feste Höhe
|
||||
warning_subtext.setStyleSheet("""
|
||||
QLabel {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
""")
|
||||
|
||||
warning_layout.addWidget(warning_text)
|
||||
warning_layout.addWidget(warning_subtext)
|
||||
|
||||
layout.addWidget(warning_banner)
|
||||
|
||||
# Content Container
|
||||
content_container = QWidget()
|
||||
content_layout = QVBoxLayout(content_container)
|
||||
content_layout.setContentsMargins(30, 25, 30, 30)
|
||||
content_layout.setSpacing(20)
|
||||
|
||||
# Titel mit Plattform-Name
|
||||
platform_display = self.platform_name if self.platform_name else "Account"
|
||||
if self.is_login:
|
||||
title_label = QLabel(f"{platform_display}-Login läuft")
|
||||
else:
|
||||
title_label = QLabel(f"{platform_display}-Account wird erstellt")
|
||||
title_label.setObjectName("titleLabel")
|
||||
title_label.setAlignment(Qt.AlignCenter)
|
||||
title_label.setStyleSheet("""
|
||||
QLabel#titleLabel {
|
||||
color: #1A365D;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
padding-bottom: 20px;
|
||||
border: none;
|
||||
}
|
||||
""")
|
||||
content_layout.addWidget(title_label)
|
||||
|
||||
# Verstecktes Status-Label für Kompatibilität
|
||||
self.status_label = QLabel()
|
||||
self.status_label.setVisible(False) # Nicht sichtbar
|
||||
content_layout.addWidget(self.status_label)
|
||||
|
||||
# Log-Ausgabe (größer da mehr Platz vorhanden)
|
||||
self.log_output = QTextEdit()
|
||||
self.log_output.setReadOnly(True)
|
||||
self.log_output.setMinimumHeight(200) # Mehr Platz für Logs
|
||||
self.log_output.setStyleSheet("""
|
||||
QTextEdit {
|
||||
background-color: #F8FAFC;
|
||||
color: #2D3748;
|
||||
font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', monospace;
|
||||
font-size: 12px;
|
||||
border: 1px solid #CBD5E0;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
}
|
||||
""")
|
||||
content_layout.addWidget(self.log_output)
|
||||
|
||||
# Button-Container
|
||||
button_layout = QHBoxLayout()
|
||||
button_layout.addStretch()
|
||||
|
||||
# Abbrechen-Button (weniger prominent)
|
||||
self.cancel_button = QPushButton("Abbrechen")
|
||||
self.cancel_button.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: #F0F4F8;
|
||||
color: #4A5568;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
padding: 8px 24px;
|
||||
border-radius: 24px;
|
||||
border: 1px solid #E2E8F0;
|
||||
min-height: 40px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #FEE2E2;
|
||||
color: #DC2626;
|
||||
border-color: #DC2626;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: #DC2626;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
""")
|
||||
self.cancel_button.clicked.connect(self.cancel_clicked.emit)
|
||||
button_layout.addWidget(self.cancel_button)
|
||||
|
||||
button_layout.addStretch()
|
||||
content_layout.addLayout(button_layout)
|
||||
|
||||
layout.addWidget(content_container)
|
||||
self.setLayout(layout)
|
||||
|
||||
# Volle Sichtbarkeit
|
||||
self.setWindowOpacity(1.0)
|
||||
|
||||
|
||||
def start_animation(self):
|
||||
"""Zeigt den Dialog an"""
|
||||
self.status_label.setText("Initialisiere...")
|
||||
self.raise_timer.start() # Starte Timer für Always-on-Top
|
||||
|
||||
def stop_animation(self):
|
||||
"""Stoppt die Animation und den Timer"""
|
||||
self.raise_timer.stop()
|
||||
|
||||
def set_status(self, status: str):
|
||||
"""Aktualisiert den Status-Text"""
|
||||
self.status_label.setText(status)
|
||||
|
||||
def add_log(self, message: str):
|
||||
"""Fügt eine Log-Nachricht hinzu"""
|
||||
self.log_output.append(message)
|
||||
# Auto-scroll zum Ende
|
||||
scrollbar = self.log_output.verticalScrollBar()
|
||||
scrollbar.setValue(scrollbar.maximum())
|
||||
|
||||
def clear_log(self):
|
||||
"""Löscht alle Log-Nachrichten"""
|
||||
self.log_output.clear()
|
||||
|
||||
def set_progress(self, value: int):
|
||||
"""Setzt den Fortschritt (0-100) - wird ignoriert da wir Spinner nutzen"""
|
||||
pass # Spinner braucht keinen Fortschritt
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""Wird aufgerufen wenn der Dialog geschlossen wird"""
|
||||
self.stop_animation()
|
||||
self.closed.emit()
|
||||
event.accept()
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
"""Verhindert das Schließen mit ESC"""
|
||||
if event.key() == Qt.Key_Escape:
|
||||
event.ignore()
|
||||
else:
|
||||
super().keyPressEvent(event)
|
||||
|
||||
def _raise_to_front(self):
|
||||
"""Holt den Dialog in den Vordergrund"""
|
||||
self.raise_()
|
||||
# Nicht activateWindow() aufrufen - das holt das Hauptfenster mit
|
||||
|
||||
def show(self):
|
||||
"""Überschreibt show() um den Dialog richtig zu positionieren"""
|
||||
super().show()
|
||||
self._raise_to_front() # Initial in den Vordergrund holen
|
||||
|
||||
|
||||
# Zusätzliche Widget-Klasse für den Progress Modal
|
||||
class ForgeAnimationWidget(QLabel):
|
||||
"""
|
||||
Einfaches Animation Widget für den Progress Modal
|
||||
Kann einen Spinner oder andere Animation anzeigen
|
||||
"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setText("⚙️") # Placeholder Icon
|
||||
self.setAlignment(Qt.AlignCenter)
|
||||
self.setStyleSheet("""
|
||||
QLabel {
|
||||
font-size: 48px;
|
||||
color: #3182CE;
|
||||
}
|
||||
""")
|
||||
|
||||
# Animation Timer
|
||||
self.animation_timer = QTimer()
|
||||
self.animation_timer.timeout.connect(self.rotate_icon)
|
||||
self.rotation_state = 0
|
||||
|
||||
def start_animation(self):
|
||||
"""Startet die Animation"""
|
||||
self.animation_timer.start(100)
|
||||
|
||||
def stop_animation(self):
|
||||
"""Stoppt die Animation"""
|
||||
self.animation_timer.stop()
|
||||
|
||||
def rotate_icon(self):
|
||||
"""Einfache Rotation Animation"""
|
||||
icons = ["⚙️", "🔧", "🔨", "⚒️"]
|
||||
self.setText(icons[self.rotation_state % len(icons)])
|
||||
self.rotation_state += 1
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren