110 lines
3.4 KiB
C++
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.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<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
|