# ui_components.py """UI components and helper functions for PPT Generator""" import gradio as gr from typing import List, Dict, Tuple from constants import STYLE_TEMPLATES, PPT_TEMPLATES, DESIGN_THEMES, EXAMPLE_TOPICS, AUDIENCE_TYPES from content_utils import generate_dynamic_slides def create_custom_slides_ui(initial_count=5): """Custom slides configuration UI (3-20 slides)""" slides = [] for i in range(20): # Max 20 slides row = gr.Row(visible=(i < initial_count)) with row: with gr.Column(scale=2): title = gr.Textbox( label=f"Slide {i+1} Title", placeholder="e.g., Current Analysis, Solution, Roadmap...", ) with gr.Column(scale=3): style = gr.Dropdown( choices=list(STYLE_TEMPLATES.keys()), label=f"Style Selection", value="Colorful Mind Map" ) with gr.Column(scale=3): hint = gr.Textbox( label=f"Prompt Hint", placeholder="Content to express in this slide" ) slides.append({"title": title, "style": style, "hint": hint, "row": row}) return slides def load_example(template_name, language): """Load example topic for template""" lang_key = "Korean" if language == "Korean" else "English" example_topic = EXAMPLE_TOPICS[lang_key].get(template_name, "") return example_topic def update_audience_info(audience_type): """Display audience information""" info = AUDIENCE_TYPES.get(audience_type, {}) return f"""**{info.get('description', '')}** - Tone: {info.get('tone', '')} - Focus: {info.get('focus', '')}""" def update_theme_preview(theme_name): """Generate theme preview HTML""" theme = DESIGN_THEMES.get(theme_name, DESIGN_THEMES["Minimal Light"]) # Convert RGB to hex def rgb_to_hex(rgb_color): return f"#{rgb_color[0]:02x}{rgb_color[1]:02x}{rgb_color[2]:02x}" bg_hex = rgb_to_hex(theme["background"]) box_hex = rgb_to_hex(theme["box_fill"]) title_hex = rgb_to_hex(theme["title_color"]) text_hex = rgb_to_hex(theme["text_color"]) accent_hex = rgb_to_hex(theme["accent_color"]) preview_html = f"""

{theme['name']}

{theme['description']}

""" return preview_html def update_template_info(template_name, slide_count): is_custom = template_name == "Custom" info = "" if not is_custom and template_name in PPT_TEMPLATES: template = PPT_TEMPLATES[template_name] info = f"**{template['description']}**\n\n" # Show dynamically generated slide composition slides = generate_dynamic_slides("", template, slide_count) info += f"Slides to be generated ({len(slides)} total):\n" for i, slide in enumerate(slides): style_info = STYLE_TEMPLATES.get(slide['style'], {}) info += f"{i+1}. {slide['title']} - {style_info.get('use_case', '')}" if style_info.get('is_process_flow'): info += " πŸ”§" info += "\n" elif is_custom: info = "**Custom Template**\n\nConfigure your slides directly in the 'Custom Slide Configuration' section below." # Hide slide count selection for custom template slide_count_visible = not is_custom custom_accordion_open = is_custom return info, gr.update(visible=slide_count_visible), gr.update(open=custom_accordion_open) def update_custom_slides_visibility(count): """Update UI visibility based on custom slide count""" updates = [] for i in range(20): updates.append(gr.update(visible=(i < count))) # row return updates def clear_all(): """λͺ¨λ“  λ‚΄μš© μ΄ˆκΈ°ν™”""" return "", "", "", None, "πŸ”„ μ΄ˆκΈ°ν™”λ˜μ—ˆμŠ΅λ‹ˆλ‹€." def get_css(): """Get custom CSS for the interface""" return """ .preview-container { max-width: 1400px; margin: 0 auto; } .slide-container { transition: all 0.3s ease; } .slide-container:hover { transform: translateY(-2px); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15) !important; } #custom_accordion .form { max-height: 600px; overflow-y: auto; padding-right: 10px; } #custom_accordion .form::-webkit-scrollbar { width: 6px; } #custom_accordion .form::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 3px; } #custom_accordion .form::-webkit-scrollbar-thumb { background: #888; border-radius: 3px; } #custom_accordion .form::-webkit-scrollbar-thumb:hover { background: #555; } .supervisor-box textarea { border-left: 4px solid #667eea !important; padding-left: 10px !important; } .researcher-box textarea { border-left: 4px solid #10b981 !important; padding-left: 10px !important; } .executor-box textarea { border-left: 4px solid #764ba2 !important; padding-left: 10px !important; } """ def get_usage_instructions(): """Get usage instructions markdown""" return """ ### πŸ”„ Workflow: 1. **Select Language**: Choose English or Korean for your presentation content 2. **Load Example** or enter your own topic 3. **Select Audience**: Content will be automatically optimized for your target audience 4. **Choose Template and Theme**, then click generate 5. **Download**: Download the PPTX file when generation is complete ### πŸ€– 3-AI Collaboration System: - **Supervisor AI**: Designs PPT structure and provides guidance - **Researcher AI**: Searches and organizes content information - **Executor AI**: Creates actual PPT slides ### 🌐 Language Support: - **English**: Default interface language with English content generation - **Korean**: Select for Korean content generation (full Korean PPT support) ### 🎭 Audience Features: - **Executives/C-Level**: Strategic value, ROI, business impact focus - **Investors**: Market opportunity, growth potential, profitability emphasis - **Technical Team**: Technical details, implementation methods, performance metrics - **General Staff**: Practical content, collaboration methods, execution plans - **Customers/Partners**: Customer value, benefits, success stories - **General Public**: Easy explanations, usability, practical benefits ### πŸ’‘ Text Style Features: - **Concise noun-ending style**: Ends with nouns or short phrases - **Emoji usage**: Relevant emojis automatically added before each point - **8-12 words**: Each bullet point is very concise ### πŸ“ Custom Slides: - **Build your own**: Activated when selecting "Custom" template - **3-20 slides freely**: Choose number of slides with slider - **Style per slide**: Choose from 16 styles for each slide - **Provide hints**: Guide content direction with prompt hints ### πŸ”§ Process Flow Diagrams: - **Automatic generation** for Business Workflow or Flowchart styles - Full support for both English and Korean text - Process, decision, input/output node types supported """