Advance new editor hosted panels and state flow
This commit is contained in:
109
new_editor/app/Panels/ProductConsolePanel.cpp
Normal file
109
new_editor/app/Panels/ProductConsolePanel.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user