Files
XCEngine/new_editor/app/Panels/ProductConsolePanel.cpp

110 lines
3.4 KiB
C++

#include "ProductConsolePanel.h"
#include <XCEditor/Foundation/UIEditorTheme.h>
#include <algorithm>
#include <cmath>
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.10f, 0.10f, 0.10f, 1.0f);
constexpr UIColor kTextColor(0.860f, 0.860f, 0.860f, 1.0f);
constexpr UIColor kChannelColor(0.660f, 0.660f, 0.660f, 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<std::size_t>(1),
static_cast<std::size_t>(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