Spaces:
Running
Running
# 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""" | |
<div style=" | |
background: {bg_hex}; | |
padding: 20px; | |
border-radius: 8px; | |
margin: 10px 0; | |
"> | |
<div style=" | |
background: {box_hex}; | |
opacity: {theme['box_opacity']}; | |
padding: 15px; | |
border-radius: 12px; | |
margin-bottom: 10px; | |
{'box-shadow: 0 4px 8px rgba(0,0,0,0.1);' if theme['shadow'] else ''} | |
"> | |
<h4 style="color: {title_hex}; margin: 0 0 10px 0;">{theme['name']}</h4> | |
<p style="color: {text_hex}; margin: 0; font-size: 14px;"> | |
{theme['description']} | |
</p> | |
<div style=" | |
width: 40px; | |
height: 4px; | |
background: {accent_hex}; | |
margin-top: 10px; | |
border-radius: 2px; | |
"></div> | |
</div> | |
</div> | |
""" | |
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 | |
""" |