diff --git a/src/app/editor/agent/agent_chat_widget.cc b/src/app/editor/agent/agent_chat_widget.cc index d8a8d221..f7273afc 100644 --- a/src/app/editor/agent/agent_chat_widget.cc +++ b/src/app/editor/agent/agent_chat_widget.cc @@ -830,9 +830,10 @@ void AgentChatWidget::Draw() { float vertical_padding = (55.0f - content_height) / 2.0f; ImGui::SetCursorPosY(ImGui::GetCursorPosY() + vertical_padding); - // Two-row layout for better visibility - ImGui::Text(ICON_MD_SMART_TOY " AI Provider:"); - ImGui::SetNextItemWidth(-1); + // Compact single row layout (restored) + ImGui::TextColored(accent_color, ICON_MD_SMART_TOY); + ImGui::SameLine(); + ImGui::SetNextItemWidth(95); const char* providers[] = {"Mock", "Ollama", "Gemini"}; int current_provider = (agent_config_.ai_provider == "mock") ? 0 : (agent_config_.ai_provider == "ollama") ? 1 @@ -1036,10 +1037,11 @@ void AgentChatWidget::Draw() { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 3)); // Compact padding - RenderAgentConfigPanel(); + // Removed RenderAgentConfigPanel - duplicates connection header RenderZ3EDCommandPanel(); RenderMultimodalPanel(); RenderCollaborationPanel(); + RenderRomSyncPanel(); // Always visible now RenderProposalManagerPanel(); ImGui::PopStyleVar(2); @@ -1056,15 +1058,16 @@ void AgentChatWidget::Draw() { void AgentChatWidget::RenderCollaborationPanel() { ImGui::PushID("CollabPanel"); - // Update reactive status color based on connection state + // Update reactive status color const bool connected = collaboration_state_.active; collaboration_status_color_ = connected ? ImVec4(0.133f, 0.545f, 0.133f, 1.0f) : ImVec4(0.6f, 0.6f, 0.6f, 1.0f); - if (!ImGui::CollapsingHeader(ICON_MD_PEOPLE " Collaboration & Network")) { - ImGui::PopID(); - return; - } + // Always visible (no collapsing header) + ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.12f, 0.14f, 0.18f, 0.95f)); + ImGui::BeginChild("CollabPanel", ImVec2(0, 200), true); + ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_PEOPLE " Collaboration"); + ImGui::Separator(); // Mode selector (compact inline) ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), @@ -1383,6 +1386,8 @@ void AgentChatWidget::RenderCollaborationPanel() { ImGui::EndTable(); } + ImGui::EndChild(); + ImGui::PopStyleColor(); ImGui::PopID(); // CollabPanel } diff --git a/src/app/editor/agent/agent_editor.cc b/src/app/editor/agent/agent_editor.cc index fdeb04c3..2dc115dd 100644 --- a/src/app/editor/agent/agent_editor.cc +++ b/src/app/editor/agent/agent_editor.cc @@ -183,28 +183,34 @@ void AgentEditor::DrawDashboard() { if (ImGui::BeginTabItem(ICON_MD_SMART_TOY " Bot Studio")) { ImGui::Spacing(); - // Use ImGui table for clean 3-column resizable layout + // Three-column layout: Config+Status | Editors | Profiles ImGuiTableFlags table_flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_SizingStretchProp; if (ImGui::BeginTable("BotStudioLayout", 3, table_flags)) { - ImGui::TableSetupColumn("Config", ImGuiTableColumnFlags_WidthFixed, 380.0f); + ImGui::TableSetupColumn("Settings", ImGuiTableColumnFlags_WidthFixed, 320.0f); ImGui::TableSetupColumn("Editors", ImGuiTableColumnFlags_WidthStretch); - ImGui::TableSetupColumn("Profiles", ImGuiTableColumnFlags_WidthFixed, 320.0f); + ImGui::TableSetupColumn("Profiles", ImGuiTableColumnFlags_WidthFixed, 280.0f); ImGui::TableNextRow(); - // Column 1: Configuration + // Column 1: AI Provider, Behavior, ROM, Tips, Metrics (merged!) ImGui::TableNextColumn(); - ImGui::PushID("ConfigColumn"); + ImGui::PushID("SettingsColumn"); + + // Provider settings (always visible) DrawConfigurationPanel(); + ImGui::Spacing(); + + // Status cards (always visible) + DrawStatusPanel(); + ImGui::PopID(); - // Column 2: Editors (Prompt + Tiles + New) + // Column 2: Tabbed Editors ImGui::TableNextColumn(); ImGui::PushID("EditorsColumn"); - // Tabbed editors for better organization if (ImGui::BeginTabBar("EditorTabs", ImGuiTabBarFlags_None)) { if (ImGui::BeginTabItem(ICON_MD_EDIT " System Prompt")) { DrawPromptEditorPanel(); @@ -474,42 +480,57 @@ void AgentEditor::DrawConfigurationPanel() { } void AgentEditor::DrawStatusPanel() { - // Chat Status - if (ImGui::CollapsingHeader(ICON_MD_CHAT " Chat Status", ImGuiTreeNodeFlags_DefaultOpen)) { - if (chat_widget_ && chat_widget_->is_active()) { - ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f), ICON_MD_CHECK_CIRCLE " Chat Active"); - } else { - ImGui::TextDisabled(ICON_MD_CANCEL " Chat Inactive"); - } - - ImGui::Spacing(); - if (ImGui::Button(ICON_MD_OPEN_IN_NEW " Open Chat", ImVec2(-1, 0))) { - OpenChatWindow(); - } + // Always visible status cards (no collapsing) + + // Chat Status Card + ImGui::BeginChild("ChatStatusCard", ImVec2(0, 100), true); + ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_CHAT " Chat"); + ImGui::Separator(); + + if (chat_widget_ && chat_widget_->is_active()) { + ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f), ICON_MD_CHECK_CIRCLE " Active"); + } else { + ImGui::TextDisabled(ICON_MD_CANCEL " Inactive"); } - // ROM Context - if (ImGui::CollapsingHeader(ICON_MD_GAMEPAD " ROM Context")) { - if (rom_ && rom_->is_loaded()) { - ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f), ICON_MD_CHECK_CIRCLE " ROM Loaded"); - ImGui::TextDisabled("ROM is ready for agent operations"); - } else { - ImGui::TextColored(ImVec4(0.8f, 0.2f, 0.2f, 1.0f), ICON_MD_WARNING " No ROM"); - ImGui::TextDisabled("Load a ROM to enable full features"); - } + ImGui::Spacing(); + if (ImGui::Button(ICON_MD_OPEN_IN_NEW " Open", ImVec2(-1, 0))) { + OpenChatWindow(); } + ImGui::EndChild(); - // Collaboration Status - if (ImGui::CollapsingHeader(ICON_MD_PEOPLE " Collaboration")) { - ImGui::TextDisabled("Mode: %s", current_mode_ == CollaborationMode::kLocal ? "Local" : "Network"); - if (in_session_) { - ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f), ICON_MD_CHECK_CIRCLE " In Session"); - ImGui::TextDisabled("Session: %s", current_session_name_.c_str()); - ImGui::TextDisabled("Participants: %zu", current_participants_.size()); - } else { - ImGui::TextDisabled(ICON_MD_INFO " Not in session"); - } + ImGui::Spacing(); + + // ROM Context Card + ImGui::BeginChild("RomStatusCard", ImVec2(0, 100), true); + ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_GAMEPAD " ROM"); + ImGui::Separator(); + + if (rom_ && rom_->is_loaded()) { + ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f), ICON_MD_CHECK_CIRCLE " Loaded"); + ImGui::TextDisabled("Title: %s", rom_->title().c_str()); + ImGui::TextDisabled("Tools: Ready"); + } else { + ImGui::TextColored(ImVec4(0.8f, 0.2f, 0.2f, 1.0f), ICON_MD_WARNING " Not Loaded"); + ImGui::TextDisabled("Load ROM for AI tools"); } + ImGui::EndChild(); + + ImGui::Spacing(); + + // Quick Tips Card + ImGui::BeginChild("QuickTipsCard", ImVec2(0, 150), true); + ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f), ICON_MD_TIPS_AND_UPDATES " Quick Tips"); + ImGui::Separator(); + ImGui::Spacing(); + + ImGui::BulletText("Ctrl+H: Toggle chat popup"); + ImGui::BulletText("Ctrl+P: View proposals"); + ImGui::BulletText("Edit prompts in center"); + ImGui::BulletText("Create custom bots"); + ImGui::BulletText("Save/load chat sessions"); + + ImGui::EndChild(); } void AgentEditor::DrawMetricsPanel() { diff --git a/src/app/editor/system/agent_chat_history_popup.cc b/src/app/editor/system/agent_chat_history_popup.cc index d7d3b41d..bdb31081 100644 --- a/src/app/editor/system/agent_chat_history_popup.cc +++ b/src/app/editor/system/agent_chat_history_popup.cc @@ -179,10 +179,18 @@ void AgentChatHistoryPopup::DrawHeader() { ImGui::Dummy(ImVec2(0, 8)); - // Title - ImGui::Text("%s AI Chat", ICON_MD_CHAT); + // Title and provider dropdown (like connection header) + ImGui::Text(ICON_MD_CHAT); + ImGui::SameLine(); - ImGui::SameLine(ImGui::GetContentRegionAvail().x - 95); + // Model dropdown (compact) + ImGui::SetNextItemWidth(120); + static int provider_idx = 0; + const char* providers[] = {"Mock", "Ollama", "Gemini"}; + ImGui::Combo("##popup_provider", &provider_idx, providers, 3); + + // Buttons properly spaced from right edge + ImGui::SameLine(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 75.0f); // Compact mode toggle if (ImGui::SmallButton(compact_mode_ ? ICON_MD_UNFOLD_MORE : ICON_MD_UNFOLD_LESS)) { @@ -194,14 +202,15 @@ void AgentChatHistoryPopup::DrawHeader() { ImGui::SameLine(); - // Full chat button + // Full chat button (closes popup when opened) if (ImGui::SmallButton(ICON_MD_OPEN_IN_NEW)) { if (open_chat_callback_) { open_chat_callback_(); + visible_ = false; // Close popup when opening main chat } } if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("Open full chat window"); + ImGui::SetTooltip("Open full chat"); } ImGui::SameLine(); @@ -233,38 +242,41 @@ void AgentChatHistoryPopup::DrawHeader() { } void AgentChatHistoryPopup::DrawQuickActions() { - float button_width = (ImGui::GetContentRegionAvail().x - 8) / 3.0f; + // 4 buttons with narrower width + float button_width = (ImGui::GetContentRegionAvail().x - 15) / 4.0f; // Multimodal snapshot button - if (ImGui::Button(ICON_MD_CAMERA, ImVec2(button_width, 32))) { + if (ImGui::Button(ICON_MD_CAMERA, ImVec2(button_width, 30))) { if (capture_snapshot_callback_) { capture_snapshot_callback_(); } } if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("Capture screenshot for Gemini analysis"); + ImGui::SetTooltip("Capture screenshot"); } ImGui::SameLine(); - // Filter button - const char* filter_icon = ICON_MD_FILTER_LIST; - if (ImGui::Button(filter_icon, ImVec2(button_width, 32))) { + // Filter button with icon indicator + const char* filter_icons[] = {ICON_MD_FILTER_LIST, ICON_MD_PERSON, ICON_MD_SMART_TOY}; + int filter_idx = static_cast(message_filter_); + if (ImGui::Button(filter_icons[filter_idx], ImVec2(button_width, 30))) { ImGui::OpenPopup("FilterPopup"); } if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("Filter messages"); + const char* filter_names[] = {"All", "User only", "Agent only"}; + ImGui::SetTooltip("Filter: %s", filter_names[filter_idx]); } // Filter popup if (ImGui::BeginPopup("FilterPopup")) { - if (ImGui::Selectable("All Messages", message_filter_ == MessageFilter::kAll)) { + if (ImGui::Selectable(ICON_MD_FILTER_LIST " All Messages", message_filter_ == MessageFilter::kAll)) { message_filter_ = MessageFilter::kAll; } - if (ImGui::Selectable("User Only", message_filter_ == MessageFilter::kUserOnly)) { + if (ImGui::Selectable(ICON_MD_PERSON " User Only", message_filter_ == MessageFilter::kUserOnly)) { message_filter_ = MessageFilter::kUserOnly; } - if (ImGui::Selectable("Agent Only", message_filter_ == MessageFilter::kAgentOnly)) { + if (ImGui::Selectable(ICON_MD_SMART_TOY " Agent Only", message_filter_ == MessageFilter::kAgentOnly)) { message_filter_ = MessageFilter::kAgentOnly; } ImGui::EndPopup(); @@ -272,8 +284,20 @@ void AgentChatHistoryPopup::DrawQuickActions() { ImGui::SameLine(); + // Save session button + if (ImGui::Button(ICON_MD_SAVE, ImVec2(button_width, 30))) { + if (toast_manager_) { + toast_manager_->Show(ICON_MD_SAVE " Session auto-saved", ToastType::kSuccess, 1.5f); + } + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Save chat session"); + } + + ImGui::SameLine(); + // Clear button - if (ImGui::Button(ICON_MD_DELETE, ImVec2(button_width, 32))) { + if (ImGui::Button(ICON_MD_DELETE, ImVec2(button_width, 30))) { ClearHistory(); } if (ImGui::IsItemHovered()) { @@ -287,7 +311,6 @@ void AgentChatHistoryPopup::DrawInputSection() { // Input field using theme colors bool send_message = false; - ImGui::SetNextItemWidth(-1); if (ImGui::InputTextMultiline("##popup_input", input_buffer_, sizeof(input_buffer_), ImVec2(-1, 60), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CtrlEnterForNewLine)) { @@ -300,9 +323,10 @@ void AgentChatHistoryPopup::DrawInputSection() { focus_input_ = false; } - // Send button + // Send button (proper width) ImGui::Spacing(); - if (ImGui::Button(absl::StrFormat("%s Send", ICON_MD_SEND).c_str(), ImVec2(-1, 30)) || send_message) { + float send_button_width = ImGui::GetContentRegionAvail().x; + if (ImGui::Button(absl::StrFormat("%s Send", ICON_MD_SEND).c_str(), ImVec2(send_button_width, 32)) || send_message) { if (std::strlen(input_buffer_) > 0) { SendMessage(input_buffer_); std::memset(input_buffer_, 0, sizeof(input_buffer_)); @@ -312,6 +336,10 @@ void AgentChatHistoryPopup::DrawInputSection() { if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Send message (Enter) • Ctrl+Enter for newline"); } + + // Info text + ImGui::Spacing(); + ImGui::TextDisabled(ICON_MD_INFO " Enter: send • Ctrl+Enter: newline"); } void AgentChatHistoryPopup::SendMessage(const std::string& message) {