Skip to content

Commit 252a113

Browse files
committed
feat(gui-ide): ajouter status bar et ajuster layout
- Ajoute un status bar fixe avec infos dynamiques (workspace, files, engine, progress).\n- Force la creation de la status bar quand le UI est charge via QUiLoader.\n- Reduit la largeur du panneau workspace et la hauteur du panel log pour une UI plus stable.\n- Active l'auto-resize ecran pour le mode IDE.
1 parent 1544852 commit 252a113

2 files changed

Lines changed: 194 additions & 3 deletions

File tree

Core/IdeLikeGui/connections.py

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
QTabWidget,
2727
QTextEdit,
2828
QToolButton,
29+
QStatusBar,
2930
QWidget,
3031
)
3132

@@ -180,12 +181,19 @@ def _find(cls, name: str):
180181
self.toolButton_more = _find(QToolButton, "toolButton_more")
181182
self.log = _find(QTextEdit, "log")
182183
self.progress = _find(QProgressBar, "progress")
184+
self.statusbar = self.findChild(QStatusBar, "statusbar")
185+
self.status_hint = None
186+
try:
187+
self.status_hint = self.statusbar.findChild(QLabel, "status_hint") if self.statusbar else None
188+
except Exception:
189+
self.status_hint = None
183190
try:
184191
if self.log is not None:
185192
self.log.setReadOnly(True)
186193
self.log.setAcceptRichText(False)
187194
except Exception:
188195
pass
196+
_setup_status_bar(self)
189197

190198

191199
def _setup_ide_like_compiler_tabs(self) -> None:
@@ -207,6 +215,7 @@ def _apply_classic_policies(self) -> None:
207215
from ..UiConnection import (
208216
_apply_button_icons,
209217
_apply_initial_theme,
218+
_auto_resize_for_screen,
210219
_connect_dialogs_to_app,
211220
_refresh_log_palette,
212221
)
@@ -215,6 +224,10 @@ def _apply_classic_policies(self) -> None:
215224
_apply_initial_theme(self)
216225
_refresh_log_palette(self)
217226
_apply_button_icons(self)
227+
try:
228+
QTimer.singleShot(0, lambda: _auto_resize_for_screen(self))
229+
except Exception:
230+
_auto_resize_for_screen(self)
218231
except Exception:
219232
pass
220233

@@ -406,6 +419,7 @@ def _apply_activity_buttons_theme(self) -> None:
406419
btn.setStyleSheet(style)
407420
except Exception:
408421
pass
422+
_apply_status_bar_theme(self, dark, fg, border)
409423

410424

411425
def _connect_ide_like_signals(self) -> None:
@@ -458,6 +472,7 @@ def _connect_text(widget, handler) -> None:
458472
self.btn_bc_loader.clicked.connect(lambda: open_bc_loader_dialog(self))
459473
except Exception:
460474
pass
475+
_bind_status_updates(self)
461476

462477
def init_ide_like_ui(self) -> None:
463478
"""Initialize the ide-like UI and wire it to existing Core methods."""
@@ -469,6 +484,166 @@ def init_ide_like_ui(self) -> None:
469484
_schedule_ide_like_async_init(self)
470485

471486

487+
def _setup_status_bar(self) -> None:
488+
if self.statusbar is None:
489+
try:
490+
self.statusbar = QStatusBar(self)
491+
self.statusbar.setObjectName("statusbar")
492+
self.setStatusBar(self.statusbar)
493+
except Exception:
494+
return
495+
try:
496+
self.status_hint = QLabel("Ready")
497+
self.status_hint.setObjectName("status_hint")
498+
self.statusbar.addPermanentWidget(self.status_hint, 1)
499+
except Exception:
500+
pass
501+
502+
503+
def _apply_status_bar_theme(self, dark: bool, fg: str, border: str) -> None:
504+
if not getattr(self, "statusbar", None):
505+
return
506+
if dark:
507+
bg = "#151A20"
508+
else:
509+
bg = "#F7F7F9"
510+
style = (
511+
"QStatusBar {"
512+
f"background: {bg};"
513+
f"color: {fg};"
514+
f"border-top: 1px solid {border};"
515+
"}"
516+
"QStatusBar::item { border: none; }"
517+
"QLabel#status_hint { padding: 2px 8px; }"
518+
)
519+
try:
520+
self.statusbar.setStyleSheet(style)
521+
except Exception:
522+
pass
523+
524+
525+
def _bind_status_updates(self) -> None:
526+
"""Keep a lightweight status line without touching core logic."""
527+
statusbar = getattr(self, "statusbar", None)
528+
if statusbar is None:
529+
return
530+
531+
def _queue_update() -> None:
532+
try:
533+
QTimer.singleShot(0, lambda: _update_status_line(self))
534+
except Exception:
535+
_update_status_line(self)
536+
537+
_queue_update()
538+
539+
for attr in (
540+
"btn_select_folder",
541+
"btn_select_files",
542+
"btn_remove_file",
543+
"btn_clear_workspace",
544+
"venv_button",
545+
"compile_btn",
546+
"cancel_btn",
547+
):
548+
btn = getattr(self, attr, None)
549+
if btn is None:
550+
continue
551+
try:
552+
btn.clicked.connect(_queue_update)
553+
except Exception:
554+
pass
555+
556+
file_list = getattr(self, "file_list", None)
557+
if file_list is not None:
558+
try:
559+
file_list.itemSelectionChanged.connect(_queue_update)
560+
except Exception:
561+
pass
562+
try:
563+
model = file_list.model()
564+
if model is not None:
565+
model.rowsInserted.connect(lambda *_: _queue_update())
566+
model.rowsRemoved.connect(lambda *_: _queue_update())
567+
model.modelReset.connect(lambda *_: _queue_update())
568+
except Exception:
569+
pass
570+
571+
compiler_tabs = getattr(self, "compiler_tabs", None)
572+
if compiler_tabs is not None:
573+
try:
574+
compiler_tabs.currentChanged.connect(lambda *_: _queue_update())
575+
except Exception:
576+
pass
577+
578+
progress = getattr(self, "progress", None)
579+
if progress is not None:
580+
try:
581+
progress.valueChanged.connect(lambda *_: _queue_update())
582+
except Exception:
583+
pass
584+
585+
586+
def _update_status_line(self) -> None:
587+
statusbar = getattr(self, "statusbar", None)
588+
if statusbar is None:
589+
return
590+
591+
def _short_path(path: str | None, max_len: int = 28) -> str:
592+
if not path:
593+
return "None"
594+
try:
595+
p = os.path.normpath(path)
596+
except Exception:
597+
p = path
598+
if len(p) <= max_len:
599+
return p
600+
return f"...{p[-max_len:]}"
601+
602+
ws = _short_path(getattr(self, "workspace_dir", None))
603+
files_total = 0
604+
files_sel = 0
605+
try:
606+
fl = getattr(self, "file_list", None)
607+
if fl is not None:
608+
files_total = fl.count()
609+
files_sel = len(fl.selectedItems())
610+
except Exception:
611+
pass
612+
613+
engine_name = "None"
614+
try:
615+
tabs = getattr(self, "compiler_tabs", None)
616+
if tabs is not None and tabs.currentIndex() >= 0:
617+
engine_name = tabs.tabText(tabs.currentIndex())
618+
except Exception:
619+
pass
620+
621+
prog = ""
622+
try:
623+
pb = getattr(self, "progress", None)
624+
if pb is not None:
625+
prog = f"{pb.value()}%"
626+
except Exception:
627+
pass
628+
629+
parts = [
630+
f"Workspace: {ws}",
631+
f"Files: {files_total}",
632+
f"Selected: {files_sel}",
633+
f"Engine: {engine_name}",
634+
]
635+
if prog:
636+
parts.append(f"Progress: {prog}")
637+
638+
msg = " | ".join(parts)
639+
try:
640+
if getattr(self, "status_hint", None):
641+
self.status_hint.setText(msg)
642+
statusbar.showMessage(msg)
643+
except Exception:
644+
pass
645+
646+
472647
def _schedule_ide_like_async_init(self) -> None:
473648
"""Defer heavier IDE setup steps to keep first paint responsive."""
474649
try:

ui/ui_ide_design2.ui

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,13 @@ QProgressBar::chunk { background: #0e639c; }</string>
264264
<widget class="QFrame" name="workspace_panel">
265265
<property name="minimumSize">
266266
<size>
267-
<width>340</width>
267+
<width>260</width>
268268
<height>0</height>
269269
</size>
270270
</property>
271271
<property name="maximumSize">
272272
<size>
273-
<width>560</width>
273+
<width>420</width>
274274
<height>16777215</height>
275275
</size>
276276
</property>
@@ -534,6 +534,18 @@ QProgressBar::chunk { background: #0e639c; }</string>
534534
</widget>
535535
</widget>
536536
<widget class="QFrame" name="logs_panel">
537+
<property name="minimumSize">
538+
<size>
539+
<width>0</width>
540+
<height>160</height>
541+
</size>
542+
</property>
543+
<property name="maximumSize">
544+
<size>
545+
<width>16777215</width>
546+
<height>240</height>
547+
</size>
548+
</property>
537549
<property name="frameShape">
538550
<enum>QFrame::Shape::StyledPanel</enum>
539551
</property>
@@ -591,7 +603,11 @@ QProgressBar::chunk { background: #0e639c; }</string>
591603
</item>
592604
</layout>
593605
</widget>
594-
<widget class="QStatusBar" name="statusbar"/>
606+
<widget class="QStatusBar" name="statusbar">
607+
<property name="sizeGripEnabled">
608+
<bool>true</bool>
609+
</property>
610+
</widget>
595611
</widget>
596612
<resources/>
597613
<connections/>

0 commit comments

Comments
 (0)