#!/usr/bin/env python3 """Stat Bar Widget Demo - Progress bars for health, mana, XP, etc. Interactive controls: 1-4: Decrease stat bars Shift+1-4: Increase stat bars F: Flash the health bar R: Reset all bars ESC: Exit demo """ import mcrfpy import sys # Add parent to path for imports sys.path.insert(0, str(__file__).rsplit('/', 2)[0]) from lib.stat_bar import StatBar, create_stat_bar_group class StatBarDemo: def __init__(self): self.scene = mcrfpy.Scene("stat_bar_demo") self.ui = self.scene.children self.bars = {} self.setup() def setup(self): """Build the demo scene.""" # Background bg = mcrfpy.Frame( pos=(0, 0), size=(1024, 768), fill_color=mcrfpy.Color(20, 20, 25) ) self.ui.append(bg) # Title title = mcrfpy.Caption( text="Stat Bar Widget Demo", pos=(512, 30), font_size=28, fill_color=mcrfpy.Color(255, 255, 255) ) title.outline = 2 title.outline_color = mcrfpy.Color(0, 0, 0) self.ui.append(title) # Section 1: Basic stat bars with labels section1_label = mcrfpy.Caption( text="Character Stats (press 1-4 to decrease, Shift+1-4 to increase)", pos=(50, 90), font_size=16, fill_color=mcrfpy.Color(150, 150, 150) ) self.ui.append(section1_label) # Health bar self.bars['hp'] = StatBar( pos=(50, 120), size=(250, 25), current=75, maximum=100, fill_color=StatBar.HEALTH_COLOR, label="HP" ) self.ui.append(self.bars['hp'].frame) # Mana bar self.bars['mp'] = StatBar( pos=(50, 155), size=(250, 25), current=50, maximum=80, fill_color=StatBar.MANA_COLOR, label="MP" ) self.ui.append(self.bars['mp'].frame) # Stamina bar self.bars['stamina'] = StatBar( pos=(50, 190), size=(250, 25), current=90, maximum=100, fill_color=StatBar.STAMINA_COLOR, label="Stamina" ) self.ui.append(self.bars['stamina'].frame) # XP bar self.bars['xp'] = StatBar( pos=(50, 225), size=(250, 25), current=250, maximum=1000, fill_color=StatBar.XP_COLOR, label="XP" ) self.ui.append(self.bars['xp'].frame) # Section 2: Different sizes section2_label = mcrfpy.Caption( text="Different Sizes", pos=(50, 290), font_size=16, fill_color=mcrfpy.Color(150, 150, 150) ) self.ui.append(section2_label) # Thin bar thin_bar = StatBar( pos=(50, 320), size=(200, 10), current=60, maximum=100, fill_color=mcrfpy.Color(100, 150, 200), show_text=False ) self.ui.append(thin_bar.frame) thin_label = mcrfpy.Caption( text="Thin (no text)", pos=(260, 315), font_size=12, fill_color=mcrfpy.Color(120, 120, 120) ) self.ui.append(thin_label) # Wide bar wide_bar = StatBar( pos=(50, 345), size=(400, 35), current=450, maximum=500, fill_color=StatBar.SHIELD_COLOR, label="Shield", font_size=16 ) self.ui.append(wide_bar.frame) # Section 3: Stat bar group section3_label = mcrfpy.Caption( text="Stat Bar Group (auto-layout)", pos=(500, 90), font_size=16, fill_color=mcrfpy.Color(150, 150, 150) ) self.ui.append(section3_label) group = create_stat_bar_group([ {"name": "Strength", "current": 15, "max": 20, "color": mcrfpy.Color(200, 80, 80)}, {"name": "Dexterity", "current": 18, "max": 20, "color": mcrfpy.Color(80, 200, 80)}, {"name": "Intelligence", "current": 12, "max": 20, "color": mcrfpy.Color(80, 80, 200)}, {"name": "Wisdom", "current": 14, "max": 20, "color": mcrfpy.Color(200, 200, 80)}, {"name": "Charisma", "current": 10, "max": 20, "color": mcrfpy.Color(200, 80, 200)}, ], start_pos=(500, 120), spacing=10, size=(220, 22)) for bar in group.values(): self.ui.append(bar.frame) # Section 4: Edge cases section4_label = mcrfpy.Caption( text="Edge Cases", pos=(50, 420), font_size=16, fill_color=mcrfpy.Color(150, 150, 150) ) self.ui.append(section4_label) # Empty bar empty_bar = StatBar( pos=(50, 450), size=(200, 20), current=0, maximum=100, fill_color=StatBar.HEALTH_COLOR, label="Empty" ) self.ui.append(empty_bar.frame) # Full bar full_bar = StatBar( pos=(50, 480), size=(200, 20), current=100, maximum=100, fill_color=StatBar.STAMINA_COLOR, label="Full" ) self.ui.append(full_bar.frame) # Overfill attempt (should clamp) overfill_bar = StatBar( pos=(50, 510), size=(200, 20), current=150, # Will be clamped to 100 maximum=100, fill_color=StatBar.XP_COLOR, label="Overfill" ) self.ui.append(overfill_bar.frame) # Section 5: Animation demo section5_label = mcrfpy.Caption( text="Animation Demo (watch the bars change)", pos=(500, 290), font_size=16, fill_color=mcrfpy.Color(150, 150, 150) ) self.ui.append(section5_label) self.anim_bar = StatBar( pos=(500, 320), size=(250, 30), current=50, maximum=100, fill_color=mcrfpy.Color(150, 100, 200), label="Animated" ) self.ui.append(self.anim_bar.frame) # Start animation loop self._anim_direction = 1 mcrfpy.Timer("anim_bar", self._animate_bar, 2000) # Section 6: Flash effect section6_label = mcrfpy.Caption( text="Flash Effect (press F)", pos=(500, 400), font_size=16, fill_color=mcrfpy.Color(150, 150, 150) ) self.ui.append(section6_label) self.flash_bar = StatBar( pos=(500, 430), size=(250, 30), current=80, maximum=100, fill_color=StatBar.HEALTH_COLOR, label="Flash Me" ) self.ui.append(self.flash_bar.frame) # Instructions instr = mcrfpy.Caption( text="1-4: Decrease bars | Shift+1-4: Increase bars | F: Flash | R: Reset | ESC: Exit", pos=(50, 730), font_size=14, fill_color=mcrfpy.Color(120, 120, 120) ) self.ui.append(instr) # Status display self.status = mcrfpy.Caption( text="Status: Ready", pos=(50, 600), font_size=16, fill_color=mcrfpy.Color(100, 200, 100) ) self.ui.append(self.status) def _animate_bar(self, runtime): """Animate the demo bar back and forth.""" current = self.anim_bar.current if self._anim_direction > 0: new_val = min(100, current + 30) if new_val >= 100: self._anim_direction = -1 else: new_val = max(10, current - 30) if new_val <= 10: self._anim_direction = 1 self.anim_bar.set_value(new_val, animate=True) def on_key(self, key, state): """Handle keyboard input.""" if state != "start": return if key == "Escape": sys.exit(0) # Number keys to modify bars bar_keys = ['hp', 'mp', 'stamina', 'xp'] key_map = {"Num1": 0, "Num2": 1, "Num3": 2, "Num4": 3} if key in key_map: idx = key_map[key] if idx < len(bar_keys): bar = self.bars[bar_keys[idx]] # Decrease by 10 bar.set_value(bar.current - 10, animate=True) self.status.text = f"Status: Decreased {bar_keys[idx].upper()}" elif key == "F": self.flash_bar.flash() self.status.text = "Status: Flash effect triggered!" elif key == "R": # Reset all bars self.bars['hp'].set_value(75, 100, animate=True) self.bars['mp'].set_value(50, 80, animate=True) self.bars['stamina'].set_value(90, 100, animate=True) self.bars['xp'].set_value(250, 1000, animate=True) self.status.text = "Status: All bars reset" def activate(self): """Activate the demo scene.""" self.scene.on_key = self.on_key mcrfpy.current_scene = self.scene def main(): """Run the stat bar demo.""" demo = StatBarDemo() demo.activate() # Headless mode: capture screenshot and exit try: if mcrfpy.headless_mode(): from mcrfpy import automation mcrfpy.Timer("screenshot", lambda rt: ( automation.screenshot("screenshots/primitives/stat_bar_demo.png"), sys.exit(0) ), 100) except AttributeError: pass if __name__ == "__main__": main()