9#include "absl/strings/str_format.h"
28#include "imgui/imgui.h"
37std::string ResolveAgentChatHistoryPath() {
40 return (*agent_dir /
"agent_chat_history.json").string();
44 return (*temp_dir /
"agent_chat_history.json").string();
46 return (std::filesystem::current_path() /
"agent_chat_history.json").string();
56 context += absl::StrFormat(
"\nName: %s", selection.
display_name);
58 if (selection.
id >= 0) {
59 context += absl::StrFormat(
"\nID: 0x%X", selection.
id);
62 context += absl::StrFormat(
"\nSecondary: 0x%X", selection.
secondary_id);
65 context +=
"\nRead Only: true";
83 return static_cast<int>(i);
99 const int next = (index + direction + size) % size;
106 return "View: Toggle Project Panel";
108 return "View: Toggle AI Agent Panel";
110 return "View: Toggle Proposals Panel";
112 return "View: Toggle Settings Panel";
114 return "View: Toggle Help Panel";
116 return "View: Toggle Notifications Panel";
118 return "View: Toggle Properties Panel";
140 return "Notifications";
184 return "notifications";
245 if (direction == 0) {
255 const int step = direction > 0 ? 1 : -1;
256 OpenPanel(StepRightPanel(current_panel, step));
281 ImGuiContext* context = ImGui::GetCurrentContext();
286 const ImGuiViewport* viewport = ImGui::GetMainViewport();
291 const float vp_width = viewport->WorkSize.x;
302 float viewport_width = 0.0f;
303 if (
const ImGuiViewport* viewport = ImGui::GetMainViewport()) {
304 viewport_width = viewport->WorkSize.x;
306 if (viewport_width <= 0.0f && ImGui::GetCurrentContext()) {
307 viewport_width = ImGui::GetIO().DisplaySize.x;
310 float clamped = std::max(limits.min_width, width);
311 if (viewport_width > 0.0f) {
312 const float ratio = viewport_width < 768.0f
313 ? std::max(0.88f, limits.max_width_ratio)
314 : limits.max_width_ratio;
315 const float max_width = std::max(limits.min_width, viewport_width * ratio);
316 clamped = std::clamp(clamped, limits.min_width, max_width);
319 float* target =
nullptr;
348 if (std::abs(*target - clamped) < 0.5f) {
354 "SetPanelWidth type=%d requested=%.1f clamped=%.1f",
355 static_cast<int>(type), width, clamped);
488 float viewport_width)
const {
494 const float ratio = viewport_width < 768.0f
495 ? std::max(0.88f, limits.max_width_ratio)
496 : limits.max_width_ratio;
497 const float max_width = std::max(limits.min_width, viewport_width * ratio);
498 return std::clamp(width, limits.min_width, max_width);
521 const std::unordered_map<std::string, float>& widths) {
523 LOG_INFO(
"RightPanelManager",
"RestorePanelWidths: %zu entries from settings",
528 if (it != widths.end()) {
549 ImGui::IsKeyPressed(ImGuiKey_Escape)) {
570 float delta_time = std::clamp(ImGui::GetIO().DeltaTime, 0.0f, 1.0f / 20.0f);
607 const ImGuiViewport* viewport = ImGui::GetMainViewport();
608 const float viewport_width = viewport->WorkSize.x;
611 const float viewport_height =
612 std::max(0.0f, viewport->WorkSize.y - top_inset - bottom_safe);
615 const float full_width =
625 ImGuiWindowFlags panel_flags =
626 ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove |
627 ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDocking |
628 ImGuiWindowFlags_NoNavFocus;
632 float panel_x = viewport->WorkPos.x + viewport_width - animated_width;
633 ImGui::SetNextWindowPos(ImVec2(panel_x, viewport->WorkPos.y + top_inset));
634 ImGui::SetNextWindowSize(ImVec2(full_width, viewport_height));
638 .border = panel_border,
639 .padding = ImVec2(0.0f, 0.0f),
640 .border_size = 1.0f},
641 nullptr, panel_flags);
648 ImGuiStyleVar_WindowPadding,
653 false, ImGuiWindowFlags_AlwaysUseWindowPadding);
654 if (panel_content_open) {
655 switch (draw_panel) {
686 const ImVec2 win_pos = ImGui::GetWindowPos();
687 const float win_height = ImGui::GetWindowHeight();
688 ImGui::SetCursorScreenPos(
689 ImVec2(win_pos.x - handle_width * 0.5f, win_pos.y));
690 ImGui::InvisibleButton(
"##RightPanelResizeHandle",
691 ImVec2(handle_width, win_height));
692 const bool handle_hovered = ImGui::IsItemHovered();
693 const bool handle_active = ImGui::IsItemActive();
694 if (handle_hovered || handle_active) {
695 ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
697 if (handle_hovered &&
698 ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
704 ImGui::GetIO().MouseDelta.x;
706 ImGui::SetTooltip(
"Width: %.0f px",
711 handle_color.w = handle_active ? 0.95f : (handle_hovered ? 0.72f : 0.35f);
712 ImGui::GetWindowDrawList()->AddLine(
713 ImVec2(win_pos.x, win_pos.y),
714 ImVec2(win_pos.x, win_pos.y + win_height),
715 ImGui::GetColorU32(handle_color), handle_active ? 2.0f : 1.0f);
725 ImVec2 header_min = ImGui::GetCursorScreenPos();
726 ImVec2 header_max = ImVec2(header_min.x + ImGui::GetWindowWidth(),
727 header_min.y + header_height);
729 ImDrawList* draw_list = ImGui::GetWindowDrawList();
730 draw_list->AddRectFilled(
731 header_min, header_max,
735 draw_list->AddLine(ImVec2(header_min.x, header_max.y),
736 ImVec2(header_max.x, header_max.y),
740 ImGui::SetCursorPosX(padding);
741 ImGui::SetCursorPosY(ImGui::GetCursorPosY() +
742 (header_height - ImGui::GetTextLineHeight()) * 0.5f);
754 const std::string previous_shortcut =
756 const std::string next_shortcut =
758 const std::string previous_tooltip =
759 previous_shortcut.empty() ?
"Previous right panel"
760 : absl::StrFormat(
"Previous right panel (%s)",
761 previous_shortcut.c_str());
762 const std::string next_tooltip =
763 next_shortcut.empty()
765 : absl::StrFormat(
"Next right panel (%s)", next_shortcut.c_str());
769 previous_tooltip.c_str(),
false,
771 "switch_panel_prev")) {
779 ImGui::OpenPopup(
"##RightPanelSwitcher");
784 next_tooltip.c_str(),
false,
786 "switch_panel_next")) {
790 if (ImGui::BeginPopup(
"##RightPanelSwitcher")) {
791 for (
PanelType panel_type : kRightPanelSwitchOrder) {
794 const char* shortcut_action = GetPanelShortcutAction(panel_type);
795 std::string shortcut;
796 if (shortcut_action[0] !=
'\0') {
798 if (shortcut ==
"Unassigned") {
802 if (ImGui::MenuItem(label.c_str(),
803 shortcut.empty() ?
nullptr : shortcut.c_str(),
804 current_panel == panel_type)) {
813 const float button_size = chrome_button_size.x;
814 const float button_y =
815 header_min.y + (header_height - chrome_button_size.y) * 0.5f;
816 float current_x = ImGui::GetWindowWidth() - button_size - padding;
819 ImGui::SetCursorScreenPos(ImVec2(header_min.x + current_x, button_y));
821 "Close Panel (Esc)",
false, ImVec4(0, 0, 0, 0),
822 "right_sidebar",
"close_panel")) {
828 current_x -= (button_size + 4.0f);
829 ImGui::SetCursorScreenPos(ImVec2(header_min.x + current_x, button_y));
842 ImGui::SetCursorPosY(header_height + 8.0f);
857 {ImGuiStyleVar_FramePadding, ImVec2(8.0f, 6.0f)},
858 {ImGuiStyleVar_FrameRounding, 4.0f},
862 std::string header_text;
864 header_text = std::string(icon) +
" " + label;
869 ImGuiTreeNodeFlags flags =
870 ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanAvailWidth |
871 ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_FramePadding;
873 flags |= ImGuiTreeNodeFlags_DefaultOpen;
876 bool is_open = ImGui::TreeNodeEx(header_text.c_str(), flags);
887 ImGui::Unindent(4.0f);
908 ImGui::TextUnformatted(value);
913 ImGui::PushTextWrapPos(ImGui::GetContentRegionAvail().x);
914 ImGui::TextWrapped(
"%s", text);
915 ImGui::PopTextWrapPos();
919 const std::string& action,
const std::string& fallback)
const {
928 if (shortcut->
keys.empty()) {
936 const char* description,
937 const std::string& fallback) {
947#ifdef YAZE_BUILD_AGENT_UI
953 "The AI Agent is not initialized. "
954 "Open the AI Agent from View menu or use Ctrl+Shift+A.");
960 const float action_bar_height = ImGui::GetFrameHeightWithSpacing() + 8.0f;
961 const float content_height =
963 ImGui::GetContentRegionAvail().y - action_bar_height);
965 if (ImGui::BeginChild(
"AgentChatBody", ImVec2(0, content_height),
true)) {
972 const ImVec4 transparent_bg(0, 0, 0, 0);
976 "Open Proposals",
false, transparent_bg,
977 "agent_sidebar",
"open_proposals")) {
984 "Clear Chat History",
false, transparent_bg,
985 "agent_sidebar",
"clear_history")) {
991 "Save Chat History",
false, transparent_bg,
992 "agent_sidebar",
"save_history")) {
1001 "The AI Agent requires agent UI support. "
1002 "Build with YAZE_BUILD_AGENT_UI=ON to enable.");
1007#ifdef YAZE_BUILD_AGENT_UI
1014 std::string selection_context;
1020 struct QuickAction {
1025 std::vector<QuickAction> actions;
1026 if (!selection_context.empty()) {
1027 actions.push_back({
"Explain selection",
1028 "Explain this selection and how to edit it safely.\n\n" +
1029 selection_context});
1032 "Suggest improvements or checks for this selection.\n\n" +
1033 selection_context});
1038 actions.push_back({
"Summarize map",
1039 "Summarize the current overworld map and its key "
1040 "features. Use overworld tools if available."});
1041 actions.push_back({
"List sprites/items",
1042 "List notable sprites or items on the current "
1046 actions.push_back({
"Audit room",
1047 "Summarize the current dungeon room layout, doors, "
1048 "and object density."});
1049 actions.push_back({
"List sprites",
1050 "List sprites in the current dungeon room and any "
1051 "potential conflicts."});
1054 actions.push_back({
"Review tiles",
1055 "Review the current tileset usage and point out any "
1056 "obvious issues."});
1057 actions.push_back({
"Palette check",
1058 "Check palette usage for contrast/readability "
1062 actions.push_back({
"Palette audit",
1063 "Audit the active palette for hue/contrast balance "
1064 "and note risks."});
1065 actions.push_back({
"Theme ideas",
1066 "Suggest a palette variation that fits the current "
1070 actions.push_back({
"Sprite review",
1071 "Review the selected sprite properties and suggest "
1075 actions.push_back({
"Copy edit",
1076 "Review the current message text for clarity and "
1077 "style improvements."});
1080 actions.push_back({
"ASM review",
1081 "Review the current ASM changes for risks and style "
1085 actions.push_back({
"Hex context",
1086 "Explain what the current hex selection likely "
1090 actions.push_back({
"Test suggestion",
1091 "Propose a short emulator test to validate the "
1092 "current feature."});
1095 actions.push_back({
"Agent config review",
1096 "Review current agent configuration for practical "
1100 actions.push_back({
"Agent overview",
1101 "Suggest the next best agent-assisted action for the "
1102 "current editor context."});
1106 if (actions.empty()) {
1110 ImGui::TextColored(accent,
"%s Editor Actions",
ICON_MD_BOLT);
1114 int columns = ImGui::GetContentRegionAvail().x > 420.0f ? 2 : 1;
1115 if (ImGui::BeginTable(
"AgentQuickActionsTable", columns,
1116 ImGuiTableFlags_SizingStretchSame)) {
1117 for (
const auto& action : actions) {
1118 ImGui::TableNextColumn();
1119 if (ImGui::Button(action.label, ImVec2(-1, 0))) {
1144 "The proposal system is not initialized. "
1145 "Proposals will appear here when the AI Agent creates them.");
1159 "Settings will be available once initialized. "
1160 "This panel provides quick access to application settings.");
1195 const char* editor_name =
"No Editor Selected";
1200 editor_name =
"Overworld Editor";
1204 editor_name =
"Dungeon Editor";
1208 editor_name =
"Graphics Editor";
1212 editor_name =
"Palette Editor";
1216 editor_name =
"Music Editor";
1220 editor_name =
"Screen Editor";
1224 editor_name =
"Sprite Editor";
1228 editor_name =
"Message Editor";
1232 editor_name =
"Emulator";
1249 ImGui::Indent(8.0f);
1253 absl::StrFormat(
"%s+Shift+S", ctrl));
1257 absl::StrFormat(
"%s+Shift+P", ctrl));
1259 absl::StrFormat(
"%s+Shift+K", ctrl));
1261 absl::StrFormat(
"%s+B", ctrl));
1264 ImGui::Unindent(8.0f);
1273 ImGui::Indent(8.0f);
1283 ImGui::Unindent(8.0f);
1288 ImGui::Indent(8.0f);
1293 absl::StrFormat(
"%s+C", ctrl));
1295 absl::StrFormat(
"%s+V", ctrl));
1296 DrawShortcutRow(
"dungeon.object.delete",
"Delete selection",
"Delete");
1300 ImGui::Unindent(8.0f);
1305 ImGui::Indent(8.0f);
1313 absl::StrFormat(
"%s+G", ctrl));
1314 ImGui::Unindent(8.0f);
1319 ImGui::Indent(8.0f);
1323 ImGui::Unindent(8.0f);
1328 ImGui::Indent(8.0f);
1334 ImGui::Unindent(8.0f);
1339 ImGui::Indent(8.0f);
1341 "Insert Line Break");
1343 ImGui::Unindent(8.0f);
1348 ImGui::Indent(8.0f);
1352 ImGui::TextWrapped(
"Select an editor to see specific shortcuts.");
1354 ImGui::Unindent(8.0f);
1363 ImGui::GetStyleColorVec4(ImGuiCol_Text));
1365 ImGui::TextWrapped(
"Paint tiles by selecting from Tile16 Selector");
1368 "Switch between Light World, Dark World, and Special Areas");
1371 "Use Entity Mode to place entrances, exits, items, and sprites");
1373 ImGui::TextWrapped(
"Right-click on the map to pick a tile for painting");
1378 ImGui::GetStyleColorVec4(ImGuiCol_Text));
1380 ImGui::TextWrapped(
"Select rooms from the Room Selector or Room Matrix");
1382 ImGui::TextWrapped(
"Place objects using the Object Editor panel");
1385 "Edit room headers for palette, GFX, and floor settings");
1387 ImGui::TextWrapped(
"Multiple rooms can be opened in separate tabs");
1392 ImGui::GetStyleColorVec4(ImGuiCol_Text));
1394 ImGui::TextWrapped(
"Browse graphics sheets using the Sheet Browser");
1396 ImGui::TextWrapped(
"Edit pixels directly with the Pixel Editor");
1398 ImGui::TextWrapped(
"Choose palettes from Palette Controls");
1400 ImGui::TextWrapped(
"View 3D objects like rupees and crystals");
1405 ImGui::GetStyleColorVec4(ImGuiCol_Text));
1407 ImGui::TextWrapped(
"Edit overworld, dungeon, and sprite palettes");
1409 ImGui::TextWrapped(
"Use Quick Access for color harmony tools");
1411 ImGui::TextWrapped(
"Changes update in real-time across all editors");
1416 ImGui::GetStyleColorVec4(ImGuiCol_Text));
1418 ImGui::TextWrapped(
"Browse songs in the Song Browser");
1420 ImGui::TextWrapped(
"Use the tracker for playback control");
1422 ImGui::TextWrapped(
"Edit instruments and BRR samples");
1427 ImGui::GetStyleColorVec4(ImGuiCol_Text));
1429 ImGui::TextWrapped(
"Edit all in-game dialog messages");
1431 ImGui::TextWrapped(
"Preview text rendering with the font atlas");
1433 ImGui::TextWrapped(
"Manage the compression dictionary");
1438 ImGui::TextWrapped(
"Open a ROM file via File > Open ROM");
1440 ImGui::TextWrapped(
"Select an editor from the sidebar");
1442 ImGui::TextWrapped(
"Use panels to access tools and settings");
1444 ImGui::TextWrapped(
"Save your work via File > Save ROM");
1450 const float button_width = ImGui::GetContentRegionAvail().x;
1453 {ImGuiStyleVar_FramePadding, ImVec2(8.0f, 6.0f)},
1454 {ImGuiStyleVar_FrameRounding, 4.0f},
1464 ImVec2(button_width, 0))) {
1478 ImVec2(button_width, 0))) {
1479 gui::OpenUrl(
"https://github.com/scawful/yaze/issues/new");
1491 if (ImGui::Button(
ICON_MD_FORUM " Join Discord", ImVec2(button_width, 0))) {
1502 "A comprehensive editor for The Legend of Zelda: "
1503 "A Link to the Past ROM files.");
1509 ImGui::Text(
"Written by: scawful");
1510 ImGui::Text(
"Special Thanks: Zarby89, JaredBrian");
1528 float avail = ImGui::GetContentRegionAvail().x;
1538 ImVec2(avail * 0.5f - 4.0f, 0))) {
1543 ImVec2(avail * 0.5f - 4.0f, 0))) {
1553 if (history.empty()) {
1559 "Notifications will appear here when actions complete.");
1565 if (unread_count > 0) {
1576 false, ImGuiWindowFlags_AlwaysVerticalScrollbar);
1577 if (notification_list_open) {
1579 auto now = std::chrono::system_clock::now();
1582 bool shown_today =
false;
1583 bool shown_yesterday =
false;
1584 bool shown_older =
false;
1586 for (
const auto& entry : history) {
1588 std::chrono::duration_cast<std::chrono::hours>(now - entry.timestamp)
1592 if (diff < 24 && !shown_today) {
1595 }
else if (diff >= 24 && diff < 48 && !shown_yesterday) {
1598 shown_yesterday =
true;
1599 }
else if (diff >= 48 && !shown_older) {
1606 ImGui::PushID(&entry);
1611 switch (entry.type) {
1641 ImGui::TextWrapped(
"%s", entry.message.c_str());
1644 auto diff_sec = std::chrono::duration_cast<std::chrono::seconds>(
1645 now - entry.timestamp)
1647 std::string time_str;
1648 if (diff_sec < 60) {
1649 time_str =
"just now";
1650 }
else if (diff_sec < 3600) {
1651 time_str = absl::StrFormat(
"%dm ago", diff_sec / 60);
1652 }
else if (diff_sec < 86400) {
1653 time_str = absl::StrFormat(
"%dh ago", diff_sec / 3600);
1655 time_str = absl::StrFormat(
"%dd ago", diff_sec / 86400);
1677 "Select an item in the editor to view and edit its properties here.");
1715 "Open a .yaze project file to access project management features "
1716 "including ROM versioning, snapshots, and configuration.");
1723 ImGui::TextWrapped(
"Create a new project via File > New Project");
1725 ImGui::TextWrapped(
"Open existing .yaze project files");
1727 ImGui::TextWrapped(
"Projects track ROM versions and settings");
1733 ImGui::TextWrapped(
"Version snapshots with Git integration");
1735 ImGui::TextWrapped(
"ROM backup and restore");
1737 ImGui::TextWrapped(
"Project-specific settings");
1739 ImGui::TextWrapped(
"Assembly code folder integration");
1746 bool clicked =
false;
1750 auto DrawPanelButton = [&](
const char* icon,
const char* base_tooltip,
1751 const char* shortcut_action,
PanelType type) {
1754 {ImGuiCol_Button, ImVec4(0, 0, 0, 0)},
1761 if (ImGui::SmallButton(icon)) {
1766 if (ImGui::IsItemHovered()) {
1768 if (shortcut.empty() || shortcut ==
"Unassigned") {
1769 ImGui::SetTooltip(
"%s", base_tooltip);
1771 ImGui::SetTooltip(
"%s (%s)", base_tooltip, shortcut.c_str());
void SendMessage(const std::string &message)
void Draw(float available_height=0.0f)
void set_active(bool active)
absl::Status SaveHistory(const std::string &filepath)
std::string GetShortcutLabel(const std::string &action, const std::string &fallback) const
void Draw()
Draw the panel and its contents.
void DrawEditorSpecificShortcuts()
std::unordered_map< std::string, float > SerializePanelWidths() const
Persist/restore per-panel widths for user settings.
float notifications_width_
float GetClampedPanelWidth(PanelType type, float viewport_width) const
float GetPanelWidth() const
Get the width of the panel when expanded.
void DrawPropertiesPanel()
void ClosePanel()
Close the currently active panel.
void CyclePanel(int direction)
Cycle to the next/previous right panel in header order.
void DrawPanelValue(const char *label, const char *value)
void NotifyPanelWidthChanged(PanelType type, float width)
void SetPanelWidth(PanelType type, float width)
Set panel width for a specific panel type.
bool DrawAgentQuickActions()
void DrawEditorSpecificHelp()
ToastManager * toast_manager_
void OnHostVisibilityChanged(bool visible)
Snap transient animations when host visibility changes.
EditorType active_editor_type_
void TogglePanel(PanelType type)
Toggle a specific panel on/off.
bool BeginPanelSection(const char *label, const char *icon=nullptr, bool default_open=true)
ShortcutManager * shortcut_manager_
static std::string PanelTypeKey(PanelType type)
std::unordered_map< std::string, PanelSizeLimits > panel_size_limits_
float GetConfiguredPanelWidth(PanelType type) const
ProposalDrawer * proposal_drawer_
void DrawGlobalShortcuts()
static float GetDefaultPanelWidth(PanelType type, EditorType editor=EditorType::kUnknown)
Get the default width for a specific panel type.
void CycleToPreviousPanel()
void SetPanelSizeLimits(PanelType type, const PanelSizeLimits &limits)
Set sizing constraints for an individual right panel.
bool IsPanelExpanded() const
Check if any panel is currently expanded (or animating closed)
bool DrawPanelToggleButtons()
Draw toggle buttons for the status cluster.
bool IsPanelActive(PanelType type) const
Check if a specific panel is active.
void ResetPanelWidths()
Reset all panel widths to their defaults.
void DrawNotificationsPanel()
void OpenPanel(PanelType type)
Open a specific panel.
void DrawPanelLabel(const char *label)
void DrawProposalsPanel()
SelectionPropertiesPanel * properties_panel_
void DrawPanelDescription(const char *text)
void DrawEditorContextHeader()
PanelSizeLimits GetPanelSizeLimits(PanelType type) const
void DrawShortcutRow(const std::string &action, const char *description, const std::string &fallback)
std::function< void(PanelType, float)> on_panel_width_changed_
void DrawPanelHeader(const char *title, const char *icon)
void DrawAgentChatPanel()
ProjectManagementPanel * project_panel_
void DrawQuickActionButtons()
void RestorePanelWidths(const std::unordered_map< std::string, float > &widths)
SettingsPanel * settings_panel_
const SelectionContext & GetSelection() const
Get the current selection context.
bool HasSelection() const
Check if there's an active selection.
void Draw()
Draw the properties panel content.
const Shortcut * FindShortcut(const std::string &name) const
size_t GetUnreadCount() const
const std::deque< NotificationEntry > & GetHistory() const
static bool BeginContentChild(const char *id, const ImVec2 &min_size, bool border=false, ImGuiWindowFlags flags=0)
static void EndContentChild()
static SafeAreaInsets GetSafeAreaInsets()
static float GetTopInset()
RAII guard for ImGui style colors.
RAII guard for ImGui style vars.
RAII compound guard for window-level style setup.
const Theme & GetCurrentTheme() const
static ThemeManager & Get()
#define ICON_MD_ROCKET_LAUNCH
#define ICON_MD_NOTIFICATIONS
#define ICON_MD_LANDSCAPE
#define ICON_MD_LOCK_OPEN
#define ICON_MD_FOLDER_SPECIAL
#define ICON_MD_CHECKLIST
#define ICON_MD_FILE_DOWNLOAD
#define ICON_MD_SWAP_HORIZ
#define ICON_MD_VIDEOGAME_ASSET
#define ICON_MD_BUG_REPORT
#define ICON_MD_MUSIC_NOTE
#define ICON_MD_CHEVRON_LEFT
#define ICON_MD_CHECK_CIRCLE
#define ICON_MD_DESCRIPTION
#define ICON_MD_HELP_OUTLINE
#define ICON_MD_STRAIGHTEN
#define ICON_MD_NOTIFICATIONS_OFF
#define ICON_MD_SELECT_ALL
#define ICON_MD_DELETE_FOREVER
#define ICON_MD_CHEVRON_RIGHT
#define ICON_MD_FIBER_MANUAL_RECORD
#define ICON_MD_SMART_TOY
#define ICON_MD_DELETE_SWEEP
#define LOG_INFO(category, format,...)
std::string BuildSelectionContextSummary(const SelectionContext &selection)
const char * GetPanelShortcutAction(RightPanelManager::PanelType type)
RightPanelManager::PanelType StepRightPanel(RightPanelManager::PanelType current, int direction)
const std::array< RightPanelManager::PanelType, 7 > kRightPanelSwitchOrder
int FindRightPanelIndex(RightPanelManager::PanelType type)
const char * GetSelectionTypeName(SelectionType type)
Get a human-readable name for a selection type.
std::string PrintShortcut(const std::vector< ImGuiKey > &keys)
const char * GetPanelTypeName(RightPanelManager::PanelType type)
Get the name of a panel type.
const char * GetPanelTypeIcon(RightPanelManager::PanelType type)
Get the icon for a panel type.
bool TransparentIconButton(const char *icon, const ImVec2 &size, const char *tooltip, bool is_active, const ImVec4 &active_color, const char *panel_id, const char *anim_id)
Draw a transparent icon button (hover effect only).
const char * GetCtrlDisplayName()
Get the display name for the primary modifier key.
ImVec4 ConvertColorToImVec4(const Color &color)
void ColoredText(const char *text, const ImVec4 &color)
ImVec4 GetSurfaceContainerHighestVec4()
bool OpenUrl(const std::string &url)
ImVec4 GetTextDisabledVec4()
ImVec4 GetTextSecondaryVec4()
void ColoredTextF(const ImVec4 &color, const char *fmt,...)
ImVec4 GetSurfaceContainerHighVec4()
ImVec4 GetSurfaceContainerVec4()
Holds information about the current selection.
std::vector< ImGuiKey > keys
static constexpr float kPanelWidthSettings
static constexpr float kPanelWidthHelp
static constexpr float kPanelMinWidthProject
static constexpr float kHeaderButtonSpacing
static constexpr float kPanelMinWidthHelp
static constexpr float kPanelWidthNotifications
static constexpr float kPanelWidthMedium
static constexpr float kAnimationSnapThreshold
static constexpr float kPanelMinWidthNotifications
static constexpr float kPanelMinWidthAgentChat
static constexpr float kContentMinHeightChat
static constexpr float kPanelPaddingLarge
static constexpr float kHeaderButtonGap
static constexpr float kAnimationSpeed
static constexpr float kPanelMinWidthSettings
static constexpr float kPanelPaddingMedium
static constexpr float kPanelWidthProject
static constexpr float kSplitterWidth
static constexpr float kPanelMinWidthProposals
static constexpr float kPanelHeaderHeight
static constexpr float kPanelMinWidthAbsolute
static constexpr float kContentMinHeightList
static constexpr float kPanelMinWidthProperties
static constexpr float kPanelWidthProposals
static constexpr float kPanelWidthProperties
static constexpr float kPanelWidthAgentChat