Skip to content

Commit 0f8eb05

Browse files
committed
Refactored EnginesStandaloneGui to use QTabWidget for engine selection
1 parent 0762a93 commit 0f8eb05

1 file changed

Lines changed: 194 additions & 75 deletions

File tree

  • Core/engines_loader/engines_only_mod

Core/engines_loader/engines_only_mod/gui.py

Lines changed: 194 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
QGridLayout,
5656
QFrame,
5757
QSplitter,
58+
QTabWidget,
5859
)
5960
from PySide6.QtGui import QIcon, QAction, QFont, QPixmap
6061

@@ -65,6 +66,7 @@
6566
)
6667
from Core.engines_loader.validator import check_engine_compatibility
6768
from Core.allversion import get_core_version, get_engine_sdk_version
69+
import Core.engines_loader as engines_loader
6870

6971

7072
class EnginesStandaloneGui(QMainWindow):
@@ -182,35 +184,25 @@ def _setup_ui(self):
182184
config_layout = QGridLayout(config_widget)
183185
config_layout.setSpacing(15)
184186

185-
# === Section Moteur ===
187+
# === Section Moteur (Tabs) ===
186188
engine_group = QGroupBox("Engine Configuration")
187-
engine_layout = QGridLayout()
189+
engine_layout = QVBoxLayout()
188190

189-
engine_label = QLabel("Engine:")
190-
engine_layout.addWidget(engine_label, 0, 0)
191+
# Ajout du QTabWidget pour les moteurs (comme dans l'application principale)
192+
self.compiler_tabs = QTabWidget()
193+
self.compiler_tabs.setDocumentMode(False)
194+
self.compiler_tabs.setTabsClosable(False)
195+
self.compiler_tabs.setMovable(False)
196+
engine_layout.addWidget(self.compiler_tabs)
191197

192-
self.engine_combo = QComboBox()
193-
self.engine_combo.setMinimumWidth(200)
194-
self.engine_combo.currentIndexChanged.connect(self._on_engine_changed)
195-
engine_layout.addWidget(self.engine_combo, 0, 1)
196-
197-
self.engine_version_label = QLabel("Version: -")
198-
self.engine_version_label.setStyleSheet("color: #888;")
199-
engine_layout.addWidget(self.engine_version_label, 0, 2)
200-
201-
engine_layout.addWidget(QLabel("Required Core:"), 1, 0)
202-
self.core_version_label = QLabel("-")
203-
self.core_version_label.setStyleSheet("color: #888;")
204-
engine_layout.addWidget(self.core_version_label, 1, 1, 1, 2)
205-
206-
# Bouton vérifier compatibilité
198+
# Bouton vérifier compatibilité (sélectionne l'onglet courant)
207199
compat_btn = QPushButton("Check Compatibility")
208200
compat_btn.clicked.connect(self._check_compatibility)
209-
engine_layout.addWidget(compat_btn, 2, 0)
201+
engine_layout.addWidget(compat_btn)
210202

211203
self.compat_status_label = QLabel("")
212204
self.compat_status_label.setStyleSheet("font-weight: bold;")
213-
engine_layout.addWidget(self.compat_status_label, 2, 1, 1, 2)
205+
engine_layout.addWidget(self.compat_status_label)
214206

215207
engine_group.setLayout(engine_layout)
216208
config_layout.addWidget(engine_group, 0, 0)
@@ -338,13 +330,6 @@ def _setup_ui(self):
338330
self.setStatusBar(self.statusBar)
339331
self.statusBar.showMessage("Ready")
340332

341-
# Initialiser les dimensions des groupes
342-
self._init_group_dimensions()
343-
344-
def _init_group_dimensions(self):
345-
"""Initialise les dimensions minimales des groupes."""
346-
self.engine_combo.setMinimumContentsLength(15)
347-
348333
def _center_window(self):
349334
"""Centre la fenêtre sur l'écran."""
350335
screen_geometry = QApplication.primaryScreen().geometry()
@@ -513,62 +498,145 @@ def _apply_language(self, lang_code: str):
513498
child.setTitle(tr["log"])
514499

515500
def _refresh_engines(self):
516-
"""Rafraîchit la liste des moteurs disponibles."""
517-
self.engine_combo.clear()
501+
"""Rafraîchit la liste des moteurs disponibles et crée leurs onglets."""
502+
# Nettoyer les onglets existants
503+
self.compiler_tabs.clear()
518504
self.engines_info = {}
519505

520506
engine_ids = available_engines()
521507

522-
for eid in engine_ids:
523-
try:
524-
engine_cls = get_engine(eid)
525-
if engine_cls:
526-
name = getattr(engine_cls, "name", eid)
527-
version = getattr(engine_cls, "version", "1.0.0")
528-
required_core = getattr(
529-
engine_cls, "required_core_version", "1.0.0"
530-
)
508+
if not engine_ids:
509+
# Pas de moteurs : afficher un message
510+
no_engine_widget = QWidget()
511+
no_engine_layout = QVBoxLayout()
512+
no_engine_label = QLabel("No engines available.\nPlease check ENGINES folder.")
513+
no_engine_label.setStyleSheet("color: #888; font-size: 14px;")
514+
no_engine_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
515+
no_engine_layout.addWidget(no_engine_label)
516+
no_engine_widget.setLayout(no_engine_layout)
517+
self.compiler_tabs.addTab(no_engine_label, "No Engines")
518+
self._log("No engines available. Please check ENGINES folder.")
519+
self.statusBar.showMessage("No engines available")
520+
return
531521

532-
self.engine_combo.addItem(f"{name} ({eid})", eid)
533-
self.engines_info[eid] = {
534-
"name": name,
535-
"version": version,
536-
"required_core": required_core,
537-
"class": engine_cls,
538-
}
539-
except Exception as e:
540-
self._log(f"Error loading engine {eid}: {e}")
541-
542-
if engine_ids:
522+
# Utiliser le mécanisme standard de bind_tabs comme dans l'application principale
523+
try:
524+
engines_loader.registry.bind_tabs(self)
543525
self._log(f"Loaded {len(engine_ids)} engine(s)")
544526
self.statusBar.showMessage(f"Ready - {len(engine_ids)} engines loaded")
545-
else:
546-
self._log("No engines available. Please check ENGINES folder.")
547-
self.statusBar.showMessage("No engines available")
527+
except Exception as e:
528+
self._log(f"Error binding engine tabs: {e}")
529+
# Fallback : créer les onglets manuellement
530+
for eid in engine_ids:
531+
try:
532+
engine_cls = get_engine(eid)
533+
if engine_cls:
534+
name = getattr(engine_cls, "name", eid)
535+
version = getattr(engine_cls, "version", "1.0.0")
536+
required_core = getattr(
537+
engine_cls, "required_core_version", "1.0.0"
538+
)
539+
540+
self.engines_info[eid] = {
541+
"name": name,
542+
"version": version,
543+
"required_core": required_core,
544+
"class": engine_cls,
545+
}
546+
547+
# Essayer de créer l'onglet via create_tab
548+
create_tab = getattr(engine_cls, "create_tab", None)
549+
if callable(create_tab):
550+
result = create_tab(self)
551+
if result:
552+
widget, label = result
553+
self.compiler_tabs.addTab(widget, label)
554+
else:
555+
# Pas de create_tab : créer un onglet par défaut
556+
default_widget = self._create_default_engine_widget(
557+
eid, name, version, required_core
558+
)
559+
self.compiler_tabs.addTab(default_widget, name)
560+
561+
except Exception as e:
562+
self._log(f"Error loading engine {eid}: {e}")
548563

549564
def _on_engine_changed(self, index):
550-
"""Appelé lorsque l'utilisateur sélectionne un moteur."""
565+
"""Appelé lorsque l'utilisateur sélectionne un moteur via l'onglet."""
551566
if index < 0:
552567
return
553568

554-
engine_id = self.engine_combo.currentData()
555-
self.selected_engine_id = engine_id
569+
# Récupérer l'ID du moteur depuis le registry
570+
try:
571+
engine_id = engines_loader.registry.get_engine_for_tab(index)
572+
self.selected_engine_id = engine_id
573+
if engine_id and engine_id in self.engines_info:
574+
info = self.engines_info[engine_id]
575+
self._log(f"Selected engine: {info['name']} v{info['version']}")
576+
except Exception as e:
577+
self._log(f"Error getting engine for tab {index}: {e}")
578+
579+
def _create_default_engine_widget(
580+
self, engine_id: str, name: str, version: str, required_core: str
581+
) -> QWidget:
582+
"""Crée un widget par défaut pour un moteur sans create_tab."""
583+
widget = QWidget()
584+
layout = QGridLayout()
585+
586+
layout.addWidget(QLabel(f"<b>Engine:</b> {name} ({engine_id})"), 0, 0, 1, 2)
587+
layout.addWidget(QLabel(f"<b>Version:</b> {version}"), 1, 0)
588+
layout.addWidget(QLabel(f"<b>Required Core:</b> {required_core}"), 1, 1)
589+
590+
# Info label
591+
info_label = QLabel(
592+
"This engine uses default configuration.\n"
593+
"Configure options in the main application for full functionality."
594+
)
595+
info_label.setStyleSheet("color: #888; font-style: italic;")
596+
info_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
597+
layout.addWidget(info_label, 2, 0, 1, 2)
556598

557-
if engine_id in self.engines_info:
558-
info = self.engines_info[engine_id]
559-
self.engine_version_label.setText(f"Version: {info['version']}")
560-
self.core_version_label.setText(info["required_core"])
561-
self._log(f"Selected engine: {info['name']} v{info['version']}")
599+
widget.setLayout(layout)
600+
return widget
562601

563602
def _check_compatibility(self):
564-
"""Vérifie la compatibilité du moteur sélectionné."""
565-
engine_id = self.engine_combo.currentData()
603+
"""Vérifie la compatibilité du moteur de l'onglet courant."""
604+
# Récupérer l'ID du moteur depuis l'onglet courant
605+
current_index = self.compiler_tabs.currentIndex()
606+
if current_index < 0:
607+
QMessageBox.warning(self, "Warning", "No engine tab selected")
608+
return
609+
610+
try:
611+
engine_id = engines_loader.registry.get_engine_for_tab(current_index)
612+
if not engine_id:
613+
# Essayer le fallback avec engines_info
614+
if self.engines_info:
615+
engine_id = list(self.engines_info.keys())[current_index]
616+
else:
617+
QMessageBox.warning(self, "Warning", "No engine available")
618+
return
619+
except Exception:
620+
engine_id = None
621+
566622
if not engine_id:
567-
QMessageBox.warning(self, "Warning", "Please select an engine first")
623+
QMessageBox.warning(self, "Warning", "No engine available")
568624
return
569625

570626
try:
571-
engine_cls = self.engines_info[engine_id]["class"]
627+
# Récupérer la classe du moteur
628+
engine_cls = None
629+
if engine_id in self.engines_info:
630+
engine_cls = self.engines_info[engine_id].get("class")
631+
if not engine_cls:
632+
engine_cls = get_engine(engine_id)
633+
634+
if not engine_cls:
635+
QMessageBox.warning(
636+
self, "Warning", f"Engine class not found: {engine_id}"
637+
)
638+
return
639+
572640
result = check_engine_compatibility(
573641
engine_cls,
574642
get_core_version(),
@@ -619,16 +687,49 @@ def _browse_workspace(self):
619687
self.workspace_dir = workspace_dir
620688

621689
def _run_compilation(self):
622-
"""Exécute la compilation."""
623-
engine_id = self.engine_combo.currentData()
690+
"""Exécute la compilation avec le moteur de l'onglet courant."""
691+
# Récupérer l'ID du moteur depuis l'onglet courant
692+
current_index = self.compiler_tabs.currentIndex()
693+
if current_index < 0:
694+
QMessageBox.warning(
695+
self,
696+
"Warning",
697+
(
698+
"Please select an engine tab first"
699+
if self.language == "en"
700+
else "Veuillez sélectionner un onglet de moteur d'abord"
701+
),
702+
)
703+
return
704+
705+
try:
706+
engine_id = engines_loader.registry.get_engine_for_tab(current_index)
707+
if not engine_id:
708+
# Fallback avec engines_info
709+
if self.engines_info:
710+
engine_id = list(self.engines_info.keys())[current_index]
711+
else:
712+
QMessageBox.warning(
713+
self,
714+
"Warning",
715+
(
716+
"No engine available"
717+
if self.language == "en"
718+
else "Aucun moteur disponible"
719+
),
720+
)
721+
return
722+
except Exception:
723+
engine_id = None
724+
624725
if not engine_id:
625726
QMessageBox.warning(
626727
self,
627728
"Warning",
628729
(
629-
"Please select an engine first"
730+
"No engine available"
630731
if self.language == "en"
631-
else "Veuillez sélectionner un moteur d'abord"
732+
else "Aucun moteur disponible"
632733
),
633734
)
634735
return
@@ -671,8 +772,8 @@ def _run_compilation(self):
671772
# Créer le moteur
672773
engine = create_engine(engine_id)
673774

674-
# Préparer les arguments
675-
result = engine.program_and_args(None, file_path)
775+
# Préparer les arguments avec le GUI pour accéder aux options
776+
result = engine.program_and_args(self, file_path)
676777

677778
if result:
678779
program, args = result
@@ -760,10 +861,27 @@ def _run_compilation(self):
760861
self.compile_btn.setEnabled(True)
761862

762863
def _dry_run(self):
763-
"""Affiche la commande sans l'exécuter."""
764-
engine_id = self.engine_combo.currentData()
864+
"""Affiche la commande sans l'exécuter en utilisant l'onglet courant."""
865+
# Récupérer l'ID du moteur depuis l'onglet courant
866+
current_index = self.compiler_tabs.currentIndex()
867+
if current_index < 0:
868+
QMessageBox.warning(self, "Warning", "Please select an engine tab first")
869+
return
870+
871+
try:
872+
engine_id = engines_loader.registry.get_engine_for_tab(current_index)
873+
if not engine_id:
874+
# Fallback avec engines_info
875+
if self.engines_info:
876+
engine_id = list(self.engines_info.keys())[current_index]
877+
else:
878+
QMessageBox.warning(self, "Warning", "No engine available")
879+
return
880+
except Exception:
881+
engine_id = None
882+
765883
if not engine_id:
766-
QMessageBox.warning(self, "Warning", "Please select an engine first")
884+
QMessageBox.warning(self, "Warning", "No engine available")
767885
return
768886

769887
file_path = self.file_path_edit.text()
@@ -773,7 +891,7 @@ def _dry_run(self):
773891

774892
try:
775893
engine = create_engine(engine_id)
776-
result = engine.program_and_args(None, file_path)
894+
result = engine.program_and_args(self, file_path)
777895

778896
if result:
779897
program, args = result
@@ -828,3 +946,4 @@ def launch_engines_gui(
828946

829947
if __name__ == "__main__":
830948
sys.exit(launch_engines_gui())
949+

0 commit comments

Comments
 (0)