Spaces:
Paused
Paused
Revert "Cleanup: Remove unused files, Svelte frontend, old UI, and update docs for Streamlit-only architecture"
8fa76f7
| import gradio as gr | |
| from typing import Callable, Any, Optional | |
| import numpy as np | |
| def create_voice_interface(pipeline: Any, game_mechanics: Any) -> gr.Column: | |
| """Create voice-controlled interface for monster generation""" | |
| with gr.Column() as voice_interface: | |
| gr.Markdown(""" | |
| ### ποΈ Voice Control Interface | |
| Speak your monster description or use the microphone to create your digital companion! | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| # Voice input | |
| voice_input = gr.Audio( | |
| label="π€ Voice Description", | |
| sources=["microphone", "upload"], | |
| type="filepath", | |
| elem_classes=["cyber-input"], | |
| info="Describe your monster using voice" | |
| ) | |
| # Voice control buttons | |
| with gr.Row(): | |
| start_recording = gr.Button( | |
| "π΄ Start Recording", | |
| elem_classes=["cyber-button"], | |
| size="sm" | |
| ) | |
| stop_recording = gr.Button( | |
| "βΉοΈ Stop Recording", | |
| elem_classes=["cyber-button"], | |
| size="sm" | |
| ) | |
| # Real-time transcription display | |
| transcription_display = gr.Textbox( | |
| label="π Transcription", | |
| placeholder="Your voice will be transcribed here...", | |
| interactive=False, | |
| lines=3, | |
| elem_classes=["cyber-output"] | |
| ) | |
| # Voice commands | |
| gr.Markdown(""" | |
| **Voice Commands:** | |
| - "Create a [type] monster" - Generate specific type | |
| - "Make it [color/trait]" - Add characteristics | |
| - "Give it [ability]" - Add special abilities | |
| """) | |
| with gr.Column(scale=1): | |
| # Preview and generation status | |
| generation_status = gr.Markdown( | |
| value="π’ Ready for voice input", | |
| elem_classes=["cyber-message"] | |
| ) | |
| # Audio visualization | |
| audio_viz = gr.HTML( | |
| value=""" | |
| <div class="audio-visualizer"> | |
| <div class="bar"></div> | |
| <div class="bar"></div> | |
| <div class="bar"></div> | |
| <div class="bar"></div> | |
| <div class="bar"></div> | |
| </div> | |
| """, | |
| elem_classes=["cyber-container"] | |
| ) | |
| # Quick voice templates | |
| gr.Markdown("**Quick Templates:**") | |
| template_buttons = [] | |
| templates = [ | |
| ("π₯ Fire Type", "Create a fierce fire-breathing dragon monster"), | |
| ("π§ Water Type", "Create a graceful aquatic monster"), | |
| ("β‘ Electric Type", "Create a sparking electric monster"), | |
| ("πΏ Nature Type", "Create a peaceful nature guardian monster") | |
| ] | |
| for label, prompt in templates: | |
| btn = gr.Button(label, size="sm", elem_classes=["cyber-button"]) | |
| template_buttons.append((btn, prompt)) | |
| # Voice interface specific styling | |
| gr.HTML(""" | |
| <style> | |
| .audio-visualizer { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| height: 100px; | |
| gap: 5px; | |
| } | |
| .audio-visualizer .bar { | |
| width: 10px; | |
| height: 30px; | |
| background: linear-gradient(to top, #00ff41, #8A2BE2); | |
| animation: audio-wave 1s ease-in-out infinite; | |
| border-radius: 5px; | |
| } | |
| .audio-visualizer .bar:nth-child(1) { animation-delay: 0s; } | |
| .audio-visualizer .bar:nth-child(2) { animation-delay: 0.1s; } | |
| .audio-visualizer .bar:nth-child(3) { animation-delay: 0.2s; } | |
| .audio-visualizer .bar:nth-child(4) { animation-delay: 0.3s; } | |
| .audio-visualizer .bar:nth-child(5) { animation-delay: 0.4s; } | |
| @keyframes audio-wave { | |
| 0%, 100% { height: 30px; } | |
| 50% { height: 60px; } | |
| } | |
| </style> | |
| """) | |
| return voice_interface | |
| def create_visual_interface(pipeline: Any, game_mechanics: Any) -> gr.Column: | |
| """Create visual/camera-based interface for monster generation""" | |
| with gr.Column() as visual_interface: | |
| gr.Markdown(""" | |
| ### ποΈ Visual Control Interface | |
| Use images, drawings, or camera input to inspire your monster creation! | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| # Image input options | |
| with gr.Tabs(): | |
| with gr.TabItem("π· Camera"): | |
| camera_input = gr.Image( | |
| label="Camera Capture", | |
| sources=["webcam"], | |
| type="pil", | |
| elem_classes=["cyber-input", "camera-feed"] | |
| ) | |
| with gr.TabItem("πΌοΈ Upload"): | |
| image_upload = gr.File( | |
| label="Upload Reference Images", | |
| file_count="multiple", | |
| file_types=["image"], | |
| elem_classes=["cyber-input"] | |
| ) | |
| uploaded_gallery = gr.Gallery( | |
| label="Uploaded References", | |
| columns=3, | |
| rows=1, | |
| height="150px", | |
| elem_classes=["cyber-container"] | |
| ) | |
| with gr.TabItem("βοΈ Draw"): | |
| sketch_pad = gr.Sketchpad( | |
| label="Draw Your Monster", | |
| type="pil", | |
| elem_classes=["cyber-input", "sketch-pad"] | |
| ) | |
| # Visual style options | |
| gr.Markdown("**Visual Style Options:**") | |
| style_modifier = gr.CheckboxGroup( | |
| choices=[ | |
| "π¨ Artistic", | |
| "π€ Mechanical", | |
| "β¨ Magical", | |
| "π Organic", | |
| "π Crystalline" | |
| ], | |
| label="Style Modifiers", | |
| elem_classes=["cyber-checkbox"] | |
| ) | |
| color_palette = gr.Radio( | |
| choices=[ | |
| "π Vibrant", | |
| "π Dark", | |
| "βοΈ Cool", | |
| "π₯ Warm", | |
| "π¨ Custom" | |
| ], | |
| label="Color Palette", | |
| value="π Vibrant", | |
| elem_classes=["cyber-radio"] | |
| ) | |
| with gr.Column(scale=1): | |
| # Image analysis display | |
| image_analysis = gr.Markdown( | |
| value="π Image Analysis Results", | |
| elem_classes=["cyber-message"] | |
| ) | |
| # Detected features | |
| detected_features = gr.JSON( | |
| label="π Detected Features", | |
| elem_classes=["cyber-stats"] | |
| ) | |
| # Generation preview | |
| preview_placeholder = gr.HTML( | |
| value=""" | |
| <div class="preview-container"> | |
| <div class="scanning-overlay"> | |
| <div class="scan-line"></div> | |
| </div> | |
| <p>Preview will appear here...</p> | |
| </div> | |
| """, | |
| elem_classes=["cyber-container"] | |
| ) | |
| # Confidence meter | |
| confidence_display = gr.HTML( | |
| value=""" | |
| <div class="confidence-meter"> | |
| <label>Generation Confidence:</label> | |
| <div class="meter-bar"> | |
| <div class="meter-fill" style="width: 0%"></div> | |
| </div> | |
| <span class="meter-value">0%</span> | |
| </div> | |
| """, | |
| elem_classes=["cyber-container"] | |
| ) | |
| # Visual interface specific styling | |
| gr.HTML(""" | |
| <style> | |
| .camera-feed { | |
| border: 3px solid #00ff41; | |
| border-radius: 10px; | |
| overflow: hidden; | |
| position: relative; | |
| } | |
| .camera-feed::after { | |
| content: 'LIVE'; | |
| position: absolute; | |
| top: 10px; | |
| right: 10px; | |
| background: red; | |
| color: white; | |
| padding: 5px 10px; | |
| border-radius: 5px; | |
| font-size: 12px; | |
| animation: blink 1s infinite; | |
| } | |
| @keyframes blink { | |
| 0%, 100% { opacity: 1; } | |
| 50% { opacity: 0.5; } | |
| } | |
| .sketch-pad { | |
| background: rgba(0, 0, 0, 0.9); | |
| border: 2px solid #8A2BE2; | |
| } | |
| .preview-container { | |
| position: relative; | |
| height: 200px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| overflow: hidden; | |
| } | |
| .scanning-overlay { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| pointer-events: none; | |
| } | |
| .scan-line { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| height: 2px; | |
| background: linear-gradient(90deg, transparent, #00ff41, transparent); | |
| animation: scan-vertical 2s linear infinite; | |
| } | |
| @keyframes scan-vertical { | |
| 0% { top: 0; } | |
| 100% { top: 100%; } | |
| } | |
| .confidence-meter { | |
| padding: 15px; | |
| } | |
| .confidence-meter label { | |
| color: #8A2BE2; | |
| font-size: 14px; | |
| margin-bottom: 5px; | |
| display: block; | |
| } | |
| .meter-bar { | |
| background: rgba(0, 0, 0, 0.5); | |
| border: 1px solid #00ff41; | |
| height: 20px; | |
| border-radius: 10px; | |
| overflow: hidden; | |
| margin: 10px 0; | |
| } | |
| .meter-fill { | |
| height: 100%; | |
| background: linear-gradient(90deg, #00ff41, #8A2BE2); | |
| transition: width 0.5s ease; | |
| } | |
| .meter-value { | |
| color: #00ff41; | |
| font-weight: bold; | |
| font-size: 18px; | |
| } | |
| </style> | |
| """) | |
| return visual_interface | |
| def create_monster_status_display() -> gr.Column: | |
| """Create monster status display component""" | |
| with gr.Column() as status_display: | |
| # 3D Model viewer | |
| model_viewer = gr.Model3D( | |
| label="Your Digital Monster", | |
| height=400, | |
| elem_classes=["monster-display"] | |
| ) | |
| # Status indicators | |
| with gr.Row(): | |
| hp_bar = gr.HTML( | |
| value=create_status_bar("HP", 100, 100, "#ff4444"), | |
| elem_classes=["status-bar"] | |
| ) | |
| hunger_bar = gr.HTML( | |
| value=create_status_bar("Hunger", 80, 100, "#ffaa44"), | |
| elem_classes=["status-bar"] | |
| ) | |
| happiness_bar = gr.HTML( | |
| value=create_status_bar("Happiness", 90, 100, "#44ff44"), | |
| elem_classes=["status-bar"] | |
| ) | |
| # Communication display | |
| communication = gr.Textbox( | |
| label="Monster Says", | |
| value="π€π9οΈβ£0οΈβ£", | |
| interactive=False, | |
| elem_classes=["cyber-dialogue"] | |
| ) | |
| # Evolution progress | |
| evolution_display = gr.HTML( | |
| value=""" | |
| <div class="evolution-progress"> | |
| <h4>Evolution Progress</h4> | |
| <div class="progress-ring"> | |
| <svg width="120" height="120"> | |
| <circle cx="60" cy="60" r="50" stroke="#333" stroke-width="10" fill="none"/> | |
| <circle cx="60" cy="60" r="50" stroke="#8A2BE2" stroke-width="10" fill="none" | |
| stroke-dasharray="314" stroke-dashoffset="157" | |
| transform="rotate(-90 60 60)"/> | |
| </svg> | |
| <div class="progress-text">50%</div> | |
| </div> | |
| </div> | |
| """, | |
| elem_classes=["evolution-display"] | |
| ) | |
| return status_display | |
| def create_status_bar(label: str, current: int, max_val: int, color: str) -> str: | |
| """Create HTML status bar""" | |
| percentage = (current / max_val) * 100 | |
| return f""" | |
| <div class="status-bar-container"> | |
| <label>{label}</label> | |
| <div class="status-bar-bg"> | |
| <div class="status-bar-fill" style="width: {percentage}%; background: {color};"></div> | |
| </div> | |
| <span class="status-value">{current}/{max_val}</span> | |
| </div> | |
| """ | |
| def create_training_interface() -> gr.Column: | |
| """Create training interface component""" | |
| with gr.Column() as training_interface: | |
| gr.Markdown(""" | |
| ### πͺ Training Center | |
| Train your monster to improve its stats and prepare for evolution! | |
| """) | |
| # Training schedule | |
| with gr.Row(): | |
| with gr.Column(): | |
| training_schedule = gr.DataFrame( | |
| headers=["Time", "Activity", "Stat Focus", "Intensity"], | |
| datatype=["str", "str", "str", "number"], | |
| value=[ | |
| ["Morning", "Strength Training", "Attack", 7], | |
| ["Afternoon", "Agility Course", "Speed", 5], | |
| ["Evening", "Meditation", "Special", 3] | |
| ], | |
| elem_classes=["cyber-table"] | |
| ) | |
| with gr.Column(): | |
| # Training mini-game | |
| training_game = gr.HTML( | |
| value=""" | |
| <div class="training-game"> | |
| <h4>Quick Training</h4> | |
| <div class="game-area"> | |
| <div class="target" id="training-target"></div> | |
| </div> | |
| <p>Click the targets to train!</p> | |
| </div> | |
| """, | |
| elem_classes=["cyber-container"] | |
| ) | |
| # Training rewards | |
| rewards_display = gr.Markdown( | |
| """ | |
| **Today's Rewards:** | |
| - π +15 Attack | |
| - π‘οΈ +10 Defense | |
| - β‘ +5 Speed | |
| """, | |
| elem_classes=["cyber-message"] | |
| ) | |
| return training_interface |