#include "ProductConsolePanel.h" #include #include #include namespace XCEngine::UI::Editor::App { namespace { using ::XCEngine::UI::UIColor; using ::XCEngine::UI::UIDrawList; using ::XCEngine::UI::UIPoint; using ::XCEngine::UI::UIRect; constexpr std::string_view kConsolePanelId = "console"; constexpr float kPadding = 8.0f; constexpr float kLineHeight = 18.0f; constexpr float kFontSize = 11.0f; constexpr UIColor kSurfaceColor(0.205f, 0.205f, 0.205f, 1.0f); constexpr UIColor kTextColor(0.840f, 0.840f, 0.840f, 1.0f); constexpr UIColor kChannelColor(0.640f, 0.640f, 0.640f, 1.0f); constexpr UIColor kEmptyColor(0.580f, 0.580f, 0.580f, 1.0f); float ResolveTextTop(float rectY, float rectHeight, float fontSize) { const float lineHeight = fontSize * 1.6f; return rectY + std::floor((rectHeight - lineHeight) * 0.5f); } } // namespace const UIEditorPanelContentHostPanelState* ProductConsolePanel::FindMountedConsolePanel( const UIEditorPanelContentHostFrame& contentHostFrame) const { for (const UIEditorPanelContentHostPanelState& panelState : contentHostFrame.panelStates) { if (panelState.panelId == kConsolePanelId && panelState.mounted) { return &panelState; } } return nullptr; } void ProductConsolePanel::Update( const ProductEditorSession& session, const UIEditorPanelContentHostFrame& contentHostFrame) { const UIEditorPanelContentHostPanelState* panelState = FindMountedConsolePanel(contentHostFrame); if (panelState == nullptr) { m_visible = false; m_bounds = {}; m_entries = nullptr; return; } m_visible = true; m_bounds = panelState->bounds; m_entries = &session.consoleEntries; } void ProductConsolePanel::Append(UIDrawList& drawList) const { if (!m_visible || m_bounds.width <= 0.0f || m_bounds.height <= 0.0f) { return; } drawList.AddFilledRect(m_bounds, kSurfaceColor); const UIRect contentRect( m_bounds.x + kPadding, m_bounds.y + kPadding, (std::max)(m_bounds.width - kPadding * 2.0f, 0.0f), (std::max)(m_bounds.height - kPadding * 2.0f, 0.0f)); if (m_entries == nullptr || m_entries->empty()) { drawList.AddText( UIPoint(contentRect.x, ResolveTextTop(contentRect.y, kLineHeight, kFontSize)), "Console is empty.", kEmptyColor, kFontSize); return; } const std::size_t maxVisibleLines = (std::max)( static_cast(1), static_cast(contentRect.height / kLineHeight)); const std::size_t entryCount = m_entries->size(); const std::size_t firstVisible = entryCount > maxVisibleLines ? entryCount - maxVisibleLines : 0u; drawList.PushClipRect(contentRect); float nextY = contentRect.y; for (std::size_t index = firstVisible; index < entryCount; ++index) { const ProductEditorConsoleEntry& entry = (*m_entries)[index]; const std::string line = entry.channel.empty() ? entry.message : "[" + entry.channel + "] " + entry.message; drawList.AddText( UIPoint(contentRect.x, ResolveTextTop(nextY, kLineHeight, kFontSize)), line, entry.channel.empty() ? kTextColor : kChannelColor, kFontSize); nextY += kLineHeight; } drawList.PopClipRect(); } } // namespace XCEngine::UI::Editor::App