# 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
"""