Source code for simvx.editor.panels.status_bar

"""Status Bar — Bottom bar showing scene info, FPS, and selection."""


from __future__ import annotations

from simvx.core import Control, Vec2


[docs] class StatusBar(Control): """Bottom status bar displaying editor information. Shows: scene path, modification indicator, FPS, mouse position, selected node name. """ def __init__(self, editor_state=None, **kwargs): super().__init__(**kwargs) self.state = editor_state self.size = Vec2(800, 20) self.bg_colour = (0.12, 0.12, 0.12, 1.0) self.text_colour = (0.7, 0.7, 0.7, 1.0) self.font_size = 11.0 # FPS tracking self._frame_count = 0 self._fps_timer = 0.0 self._fps = 0.0 # Cached display strings self._scene_text = "No scene" self._selection_text = "" self._mouse_text = "0, 0"
[docs] def process(self, dt: float): self._frame_count += 1 self._fps_timer += dt if self._fps_timer >= 1.0: self._fps = self._frame_count / self._fps_timer self._frame_count = 0 self._fps_timer = 0.0 if self.state: self._scene_text = self.state.get_scene_title() sel = self.state.selection.primary self._selection_text = sel.name if sel else ""
# Play state indicator colours _PLAYING_COLOUR = (0.2, 0.9, 0.2, 1.0) _PAUSED_COLOUR = (1.0, 0.6, 0.0, 1.0) def _play_state_text(self) -> tuple[str, tuple] | None: """Return (text, colour) for the play state indicator, or None.""" if not self.state: return None if self.state.is_playing and self.state.is_paused: return ("PAUSED", self._PAUSED_COLOUR) if self.state.is_playing: return ("PLAYING", self._PLAYING_COLOUR) return None
[docs] def draw(self, renderer): x, y, w, h = self.get_global_rect() scale = self.font_size / 14.0 # Background renderer.draw_filled_rect(x, y, w, h, self.bg_colour) # Top border renderer.draw_line_coloured(x, y, x + w, y, (0.25, 0.25, 0.25, 1.0)) # Scene path (left) renderer.draw_text_coloured( self._scene_text, x + 8, y + 3, scale, self.text_colour) # Play state indicator (after scene name) play_info = self._play_state_text() play_offset = 0.0 if play_info: text, colour = play_info scene_w = renderer.text_width(self._scene_text, scale) px = x + 8 + scene_w + 16 renderer.draw_text_coloured(text, px, y + 3, scale, colour) play_offset = renderer.text_width(text, scale) + 16 # Selected node (center-left) if self._selection_text: scene_w = renderer.text_width(self._scene_text, scale) sel_x = x + 8 + scene_w + 16 + play_offset renderer.draw_text_coloured( f"Selected: {self._selection_text}", sel_x, y + 3, scale, (0.5, 0.8, 1.0, 1.0)) # FPS (right) fps_text = f"{self._fps:.0f} FPS" fps_w = renderer.text_width(fps_text, scale) renderer.draw_text_coloured( fps_text, x + w - fps_w - 8, y + 3, scale, self.text_colour) # Mouse position (center-right) mouse_w = renderer.text_width(self._mouse_text, scale) renderer.draw_text_coloured( self._mouse_text, x + w - fps_w - mouse_w - 30, y + 3, scale, self.text_colour)
[docs] def update_mouse_pos(self, mx: float, my: float): """Update displayed mouse position.""" self._mouse_text = f"{mx:.0f}, {my:.0f}"