Add Iced panel adapter and AI chat/script panels
- Implemented a theme system in `iced-panel-adapter` for consistent styling across panels. - Created `iced-panel-ai-chat` for an AI assistant interface, including message handling and UI components. - Developed `iced-panel-script` for a DSL editor with execution capabilities, allowing procedural drawing commands. - Introduced message types for interaction in both chat and script panels. - Added color and theme management for improved visual consistency.
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
//! AI Chat panel — AI assistant for image editing.
|
||||
//! Uses ThemeColors for consistent styling.
|
||||
|
||||
use crate::app::Message;
|
||||
use crate::panels::styles;
|
||||
use crate::theme::ThemeColors;
|
||||
use iced::widget::{button, column, container, horizontal_rule, row, scrollable, text, text_input};
|
||||
use iced::{Element, Length};
|
||||
|
||||
/// Build the AI chat panel.
|
||||
pub fn view(input: &str, messages: &[(String, String)], colors: ThemeColors) -> Element<'static, Message> {
|
||||
let provider_row = row![
|
||||
text("Provider:").size(10),
|
||||
button(text("Ollama").size(10)).on_press(Message::NoOp).padding([4, 8]),
|
||||
button(text("Claude").size(10)).on_press(Message::NoOp).padding([4, 8]),
|
||||
button(text("OpenAI").size(10)).on_press(Message::NoOp).padding([4, 8]),
|
||||
]
|
||||
.spacing(4);
|
||||
|
||||
let mut msg_list = column![].spacing(4);
|
||||
|
||||
if messages.is_empty() {
|
||||
let welcome = container(
|
||||
column![
|
||||
text("AI Assistant").size(12).font(iced::Font::MONOSPACE),
|
||||
text("Ask me anything about image editing!").size(11),
|
||||
text("").size(8),
|
||||
text("I can help with:").size(10),
|
||||
text(" - Creating and editing layers").size(10),
|
||||
text(" - Applying filters and effects").size(10),
|
||||
text(" - Drawing shapes and text").size(10),
|
||||
text(" - Color adjustments").size(10),
|
||||
]
|
||||
.spacing(2)
|
||||
)
|
||||
.padding(12)
|
||||
.style(move |_theme| iced::widget::container::Style {
|
||||
background: Some(iced::Background::Color(colors.bg_hover)),
|
||||
border: iced::Border::default().rounded(8),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
msg_list = msg_list.push(welcome);
|
||||
} else {
|
||||
for (role, content) in messages {
|
||||
let (label, color) = if role == "user" {
|
||||
("You", colors.accent)
|
||||
} else {
|
||||
("AI", iced::Color::from_rgb(0.4, 0.9, 0.4))
|
||||
};
|
||||
|
||||
let content_owned = content.clone();
|
||||
let msg_text = text(content_owned).size(11);
|
||||
let msg_text = msg_text.style(move |_theme: &iced::Theme| iced::widget::text::Style {
|
||||
color: Some(color),
|
||||
});
|
||||
|
||||
let bubble = container(
|
||||
column![text(label).size(10).font(iced::Font::MONOSPACE), msg_text].spacing(2)
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.padding(8)
|
||||
.style(move |_theme| iced::widget::container::Style {
|
||||
background: Some(iced::Background::Color(colors.bg_hover)),
|
||||
border: iced::Border::default().rounded(6),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
msg_list = msg_list.push(bubble);
|
||||
}
|
||||
}
|
||||
|
||||
let input_owned = input.to_string();
|
||||
let input_field = text_input("Ask the AI assistant...", &input_owned)
|
||||
.on_input(|s| Message::AiChatInput(s))
|
||||
.width(Length::Fill);
|
||||
|
||||
let send_btn = button(text("Send").size(11)).on_press(Message::AiChatSend).padding([6, 12]);
|
||||
let clear_btn = button(text("Clear").size(11)).on_press(Message::AiChatClear).padding([6, 12]);
|
||||
let input_row = row![input_field, send_btn, clear_btn].spacing(4);
|
||||
|
||||
let panel = column![
|
||||
text("AI Assistant").size(13).font(iced::Font::MONOSPACE),
|
||||
provider_row,
|
||||
horizontal_rule(1),
|
||||
scrollable(msg_list).height(Length::Fill),
|
||||
horizontal_rule(1),
|
||||
input_row,
|
||||
]
|
||||
.spacing(4)
|
||||
.padding(8);
|
||||
|
||||
container(panel)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.style(move |_theme| styles::panel_background(colors))
|
||||
.into()
|
||||
}
|
||||
Reference in New Issue
Block a user