feat: Refactor UI Layouts and Enhance Visibility in AgentChatWidget and AgentEditor

- Restored a compact single-row layout for the AI provider selection in AgentChatWidget, improving visibility and accessibility.
- Removed redundant RenderAgentConfigPanel to streamline the UI, ensuring the connection header is always visible.
- Updated the collaboration panel to be always visible, enhancing user interaction without the need for collapsing headers.
- Modified the AgentEditor layout to feature a three-column design with always-visible settings and status cards, improving organization and user experience.
- Enhanced the chat history popup with a more compact title and provider dropdown, ensuring buttons are properly spaced and functional.
This commit is contained in:
scawful
2025-10-05 12:46:00 -04:00
parent 8e7c179d47
commit 02a72051f6
3 changed files with 120 additions and 66 deletions

View File

@@ -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
}

View File

@@ -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() {

View File

@@ -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<int>(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) {