Unlink XCNewEditor default shell from ImGui compat slice
This commit is contained in:
@@ -44,6 +44,7 @@ endif()
|
||||
set(NEW_EDITOR_SOURCES
|
||||
src/main.cpp
|
||||
src/Application.cpp
|
||||
src/ApplicationDefaultShell.cpp
|
||||
src/panels/Panel.cpp
|
||||
src/Rendering/MainWindowBackdropPass.cpp
|
||||
src/Rendering/MainWindowNativeBackdropRenderer.cpp
|
||||
@@ -156,7 +157,6 @@ target_link_libraries(XCNewEditorImGuiCompat PRIVATE
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
XCEngine
|
||||
XCNewEditorImGuiCompat
|
||||
d3d12.lib
|
||||
dxgi.lib
|
||||
user32
|
||||
|
||||
138
new_editor/src/ApplicationDefaultShell.cpp
Normal file
138
new_editor/src/ApplicationDefaultShell.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
#include "Application.h"
|
||||
|
||||
#include "XCUIBackend/NativeWindowUICompositor.h"
|
||||
#include "panels/XCUIDemoPanel.h"
|
||||
#include "panels/XCUILayoutLabPanel.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace NewEditor {
|
||||
|
||||
Application::Application() = default;
|
||||
Application::~Application() = default;
|
||||
|
||||
std::unique_ptr<::XCEngine::Editor::XCUIBackend::IXCUIHostedPreviewPresenter>
|
||||
Application::CreateHostedPreviewPresenter(bool nativePreview) {
|
||||
if (nativePreview) {
|
||||
return ::XCEngine::Editor::XCUIBackend::CreateQueuedNativeXCUIHostedPreviewPresenter(
|
||||
m_hostedPreviewQueue,
|
||||
m_hostedPreviewSurfaceRegistry);
|
||||
}
|
||||
|
||||
return ::XCEngine::Editor::XCUIBackend::CreateNullXCUIHostedPreviewPresenter();
|
||||
}
|
||||
|
||||
void Application::InitializePanelsForActiveWindowHost() {
|
||||
InitializeNativeShell();
|
||||
}
|
||||
|
||||
void Application::InitializeLegacyImGuiPanels() {
|
||||
}
|
||||
|
||||
void Application::ConfigureHostedPreviewPresenters() {
|
||||
}
|
||||
|
||||
void Application::ResetLegacyPanels() {
|
||||
m_demoPanel.reset();
|
||||
m_layoutLabPanel.reset();
|
||||
}
|
||||
|
||||
void Application::SyncShellChromePanelStateFromPanels() {
|
||||
}
|
||||
|
||||
void Application::ConfigureShellCommandRouter() {
|
||||
m_shellCommandRouter.Clear();
|
||||
|
||||
ShellCommandBindings bindings = {};
|
||||
bindings.getXCUIDemoPanelVisible = [this]() {
|
||||
return m_shellChromeState.IsPanelVisible(ShellPanelId::XCUIDemo);
|
||||
};
|
||||
bindings.setXCUIDemoPanelVisible = [this](bool visible) {
|
||||
m_shellChromeState.SetPanelVisible(ShellPanelId::XCUIDemo, visible);
|
||||
};
|
||||
bindings.getXCUILayoutLabPanelVisible = [this]() {
|
||||
return m_shellChromeState.IsPanelVisible(ShellPanelId::XCUILayoutLab);
|
||||
};
|
||||
bindings.setXCUILayoutLabPanelVisible = [this](bool visible) {
|
||||
m_shellChromeState.SetPanelVisible(ShellPanelId::XCUILayoutLab, visible);
|
||||
};
|
||||
bindings.getNativeBackdropVisible = [this]() {
|
||||
return IsShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop);
|
||||
};
|
||||
bindings.setNativeBackdropVisible = [this](bool visible) {
|
||||
SetShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop, visible);
|
||||
};
|
||||
bindings.getPulseAccentEnabled = [this]() {
|
||||
return IsShellViewToggleEnabled(ShellViewToggleId::PulseAccent);
|
||||
};
|
||||
bindings.setPulseAccentEnabled = [this](bool enabled) {
|
||||
SetShellViewToggleEnabled(ShellViewToggleId::PulseAccent, enabled);
|
||||
};
|
||||
bindings.getNativeXCUIOverlayVisible = [this]() {
|
||||
return IsShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay);
|
||||
};
|
||||
bindings.setNativeXCUIOverlayVisible = [this](bool visible) {
|
||||
SetShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay, visible);
|
||||
};
|
||||
bindings.getHostedPreviewHudVisible = [this]() {
|
||||
return IsShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud);
|
||||
};
|
||||
bindings.setHostedPreviewHudVisible = [this](bool visible) {
|
||||
SetShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud, visible);
|
||||
};
|
||||
bindings.getNativeDemoPanelPreviewEnabled = [this]() {
|
||||
return IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo);
|
||||
};
|
||||
bindings.setNativeDemoPanelPreviewEnabled = [this](bool enabled) {
|
||||
m_shellChromeState.SetHostedPreviewMode(
|
||||
ShellPanelId::XCUIDemo,
|
||||
enabled ? ShellHostedPreviewMode::NativeOffscreen : ShellHostedPreviewMode::HostedPresenter);
|
||||
};
|
||||
bindings.getNativeLayoutLabPreviewEnabled = [this]() {
|
||||
return IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab);
|
||||
};
|
||||
bindings.setNativeLayoutLabPreviewEnabled = [this](bool enabled) {
|
||||
m_shellChromeState.SetHostedPreviewMode(
|
||||
ShellPanelId::XCUILayoutLab,
|
||||
enabled ? ShellHostedPreviewMode::NativeOffscreen : ShellHostedPreviewMode::HostedPresenter);
|
||||
};
|
||||
|
||||
Application::RegisterShellViewCommands(m_shellCommandRouter, bindings);
|
||||
}
|
||||
|
||||
::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta
|
||||
Application::DispatchShellShortcuts(
|
||||
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot& snapshot) {
|
||||
if (!m_shellInputBridge.HasBaseline()) {
|
||||
m_shellInputBridge.Prime(snapshot);
|
||||
}
|
||||
|
||||
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta frameDelta =
|
||||
m_shellInputBridge.Translate(snapshot);
|
||||
const ::XCEngine::Editor::XCUIBackend::XCUIEditorCommandInputSnapshot commandSnapshot =
|
||||
Application::BuildShellShortcutSnapshot(frameDelta);
|
||||
m_shellCommandRouter.InvokeMatchingShortcut({ &commandSnapshot });
|
||||
return frameDelta;
|
||||
}
|
||||
|
||||
void Application::InitializeWindowCompositor() {
|
||||
m_windowCompositor = ::XCEngine::Editor::XCUIBackend::CreateNativeWindowUICompositor();
|
||||
if (m_windowCompositor != nullptr) {
|
||||
m_windowCompositor->Initialize(m_hwnd, m_windowRenderer, {});
|
||||
}
|
||||
}
|
||||
|
||||
void Application::FrameLegacyImGuiHost() {
|
||||
m_xcuiInputSource.ClearFrameTransients();
|
||||
}
|
||||
|
||||
void Application::RenderLegacyImGuiUiFrame() {
|
||||
}
|
||||
|
||||
void Application::RenderShellChrome() {
|
||||
}
|
||||
|
||||
void Application::RenderHostedPreviewHud() {
|
||||
}
|
||||
|
||||
} // namespace NewEditor
|
||||
} // namespace XCEngine
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <XCEngine/UI/Types.h>
|
||||
#include <XCEngine/UI/Widgets/UIEditorCollectionPrimitives.h>
|
||||
#include <XCEngine/UI/Widgets/UIExpansionModel.h>
|
||||
#include <XCEngine/UI/Widgets/UIFlatHierarchyHelpers.h>
|
||||
#include <XCEngine/UI/Widgets/UIKeyboardNavigationModel.h>
|
||||
#include <XCEngine/UI/Widgets/UISelectionModel.h>
|
||||
|
||||
@@ -556,23 +557,17 @@ bool HasTreeItemChildren(const RuntimeBuildContext& state, std::size_t nodeIndex
|
||||
return false;
|
||||
}
|
||||
|
||||
const float indentLevel = ResolveTreeIndentLevel(node);
|
||||
const auto siblingIt = std::find(parent.children.begin(), parent.children.end(), nodeIndex);
|
||||
if (siblingIt == parent.children.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto it = siblingIt + 1; it != parent.children.end(); ++it) {
|
||||
const LayoutNode& sibling = state.nodes[*it];
|
||||
const float siblingIndentLevel = ResolveTreeIndentLevel(sibling);
|
||||
if (siblingIndentLevel <= indentLevel) {
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return UIWidgets::UIFlatHierarchyHasChildren(
|
||||
std::span<const std::size_t>(parent.children),
|
||||
static_cast<std::size_t>(siblingIt - parent.children.begin()),
|
||||
[&state](std::size_t siblingIndex) {
|
||||
return ResolveTreeIndentLevel(state.nodes[siblingIndex]);
|
||||
});
|
||||
}
|
||||
|
||||
bool IsNodeCollapsible(const RuntimeBuildContext& state, std::size_t nodeIndex) {
|
||||
@@ -626,32 +621,20 @@ bool IsNodeVisible(const RuntimeBuildContext& state, std::size_t nodeIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
float requiredAncestorIndent = ResolveTreeIndentLevel(node);
|
||||
if (requiredAncestorIndent <= 0.0f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto siblingIt = std::find(parent.children.begin(), parent.children.end(), nodeIndex);
|
||||
if (siblingIt == parent.children.end()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::size_t siblingOffset =
|
||||
static_cast<std::size_t>(siblingIt - parent.children.begin());
|
||||
for (std::size_t offset = siblingOffset; offset > 0u && requiredAncestorIndent > 0.0f; --offset) {
|
||||
const std::size_t siblingIndex = parent.children[offset - 1u];
|
||||
const LayoutNode& sibling = state.nodes[siblingIndex];
|
||||
const float siblingIndent = ResolveTreeIndentLevel(sibling);
|
||||
if (siblingIndent < requiredAncestorIndent) {
|
||||
if (!IsNodeExpanded(state, siblingIndex)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
requiredAncestorIndent = siblingIndent;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return UIWidgets::UIFlatHierarchyIsVisible(
|
||||
std::span<const std::size_t>(parent.children),
|
||||
static_cast<std::size_t>(siblingIt - parent.children.begin()),
|
||||
[&state](std::size_t siblingIndex) {
|
||||
return ResolveTreeIndentLevel(state.nodes[siblingIndex]);
|
||||
},
|
||||
[&state](std::size_t siblingIndex) {
|
||||
return IsNodeExpanded(state, siblingIndex);
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::size_t> CollectVisibleChildren(
|
||||
@@ -961,14 +944,17 @@ std::size_t FindTreeParentItemIndex(
|
||||
return kInvalidIndex;
|
||||
}
|
||||
|
||||
for (auto it = siblingIt; it != treeView.children.begin();) {
|
||||
--it;
|
||||
if (ResolveTreeIndentLevel(state.nodes[*it]) < indentLevel) {
|
||||
return *it;
|
||||
}
|
||||
const std::size_t parentOffset = UIWidgets::UIFlatHierarchyFindParentOffset(
|
||||
std::span<const std::size_t>(treeView.children),
|
||||
static_cast<std::size_t>(siblingIt - treeView.children.begin()),
|
||||
[&state](std::size_t siblingIndex) {
|
||||
return ResolveTreeIndentLevel(state.nodes[siblingIndex]);
|
||||
});
|
||||
if (parentOffset == UIWidgets::kInvalidUIFlatHierarchyItemOffset) {
|
||||
return kInvalidIndex;
|
||||
}
|
||||
|
||||
return kInvalidIndex;
|
||||
return treeView.children[parentOffset];
|
||||
}
|
||||
|
||||
std::size_t FindFirstTreeChildItemIndex(
|
||||
@@ -981,25 +967,25 @@ std::size_t FindFirstTreeChildItemIndex(
|
||||
|
||||
const LayoutNode& node = state.nodes[nodeIndex];
|
||||
const LayoutNode& treeView = state.nodes[node.parentIndex];
|
||||
const float indentLevel = ResolveTreeIndentLevel(node);
|
||||
const auto siblingIt = std::find(treeView.children.begin(), treeView.children.end(), nodeIndex);
|
||||
if (siblingIt == treeView.children.end()) {
|
||||
return kInvalidIndex;
|
||||
}
|
||||
|
||||
for (auto it = siblingIt + 1; it != treeView.children.end(); ++it) {
|
||||
const std::size_t candidateIndex = *it;
|
||||
const float candidateIndent = ResolveTreeIndentLevel(state.nodes[candidateIndex]);
|
||||
if (candidateIndent <= indentLevel) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsNodeVisible(state, candidateIndex)) {
|
||||
return candidateIndex;
|
||||
}
|
||||
const std::size_t childOffset = UIWidgets::UIFlatHierarchyFindFirstVisibleChildOffset(
|
||||
std::span<const std::size_t>(treeView.children),
|
||||
static_cast<std::size_t>(siblingIt - treeView.children.begin()),
|
||||
[&state](std::size_t siblingIndex) {
|
||||
return ResolveTreeIndentLevel(state.nodes[siblingIndex]);
|
||||
},
|
||||
[&state](std::size_t siblingIndex) {
|
||||
return IsNodeVisible(state, siblingIndex);
|
||||
});
|
||||
if (childOffset == UIWidgets::kInvalidUIFlatHierarchyItemOffset) {
|
||||
return kInvalidIndex;
|
||||
}
|
||||
|
||||
return kInvalidIndex;
|
||||
return treeView.children[childOffset];
|
||||
}
|
||||
|
||||
bool HandleKeyboardExpand(RuntimeBuildContext& state) {
|
||||
|
||||
227
new_editor/src/XCUIBackend/XCUINativeShellLayout.h
Normal file
227
new_editor/src/XCUIBackend/XCUINativeShellLayout.h
Normal file
@@ -0,0 +1,227 @@
|
||||
#pragma once
|
||||
|
||||
#include "XCUIShellChromeState.h"
|
||||
|
||||
#include <XCEngine/UI/Types.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <initializer_list>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
namespace XCUIBackend {
|
||||
|
||||
struct XCUINativeShellMetrics {
|
||||
float outerMargin = 22.0f;
|
||||
float innerGap = 18.0f;
|
||||
float headerHeight = 58.0f;
|
||||
float footerHeight = 34.0f;
|
||||
float panelHeaderHeight = 42.0f;
|
||||
float panelPadding = 14.0f;
|
||||
float panelMinWidth = 260.0f;
|
||||
float panelMinHeight = 180.0f;
|
||||
float primaryPanelWidthRatio = 0.60f;
|
||||
};
|
||||
|
||||
struct XCUINativeShellPanelSpec {
|
||||
XCUIShellPanelId panelId = XCUIShellPanelId::XCUIDemo;
|
||||
std::string_view title = {};
|
||||
bool visible = true;
|
||||
};
|
||||
|
||||
struct XCUINativeShellPanelLayout {
|
||||
XCUIShellPanelId panelId = XCUIShellPanelId::XCUIDemo;
|
||||
std::string title = {};
|
||||
UI::UIRect panelRect = {};
|
||||
UI::UIRect canvasRect = {};
|
||||
bool visible = false;
|
||||
bool hovered = false;
|
||||
bool active = false;
|
||||
};
|
||||
|
||||
struct XCUINativeShellLayoutResult {
|
||||
UI::UIRect shellRect = {};
|
||||
UI::UIRect topBarRect = {};
|
||||
UI::UIRect footerRect = {};
|
||||
UI::UIRect workspaceRect = {};
|
||||
std::vector<XCUINativeShellPanelLayout> panelLayouts = {};
|
||||
XCUIShellPanelId activePanel = XCUIShellPanelId::XCUIDemo;
|
||||
};
|
||||
|
||||
inline bool XCUINativeShellContainsPoint(
|
||||
const UI::UIRect& rect,
|
||||
const UI::UIPoint& point) {
|
||||
return point.x >= rect.x &&
|
||||
point.y >= rect.y &&
|
||||
point.x <= rect.x + rect.width &&
|
||||
point.y <= rect.y + rect.height;
|
||||
}
|
||||
|
||||
inline UI::UIRect BuildXCUINativeShellCanvasRect(
|
||||
const UI::UIRect& panelRect,
|
||||
const XCUINativeShellMetrics& metrics = {}) {
|
||||
return UI::UIRect(
|
||||
panelRect.x + metrics.panelPadding,
|
||||
panelRect.y + metrics.panelHeaderHeight,
|
||||
(std::max)(0.0f, panelRect.width - metrics.panelPadding * 2.0f),
|
||||
(std::max)(0.0f, panelRect.height - metrics.panelHeaderHeight - metrics.panelPadding));
|
||||
}
|
||||
|
||||
inline XCUINativeShellPanelLayout BuildXCUINativeShellPanelLayout(
|
||||
const XCUINativeShellPanelSpec& spec,
|
||||
const UI::UIRect& panelRect,
|
||||
const UI::UIPoint& pointerPosition,
|
||||
bool windowFocused,
|
||||
bool active,
|
||||
const XCUINativeShellMetrics& metrics = {}) {
|
||||
XCUINativeShellPanelLayout layout = {};
|
||||
layout.panelId = spec.panelId;
|
||||
layout.title = std::string(spec.title);
|
||||
layout.panelRect = panelRect;
|
||||
layout.canvasRect = BuildXCUINativeShellCanvasRect(panelRect, metrics);
|
||||
layout.visible =
|
||||
spec.visible &&
|
||||
panelRect.width >= metrics.panelMinWidth &&
|
||||
panelRect.height >= metrics.panelMinHeight;
|
||||
layout.hovered = windowFocused && XCUINativeShellContainsPoint(layout.canvasRect, pointerPosition);
|
||||
layout.active = active;
|
||||
return layout;
|
||||
}
|
||||
|
||||
inline XCUIShellPanelId ResolveXCUINativeShellActivePanel(
|
||||
XCUIShellPanelId currentActivePanel,
|
||||
const std::vector<XCUINativeShellPanelLayout>& panelLayouts,
|
||||
bool pointerPressed) {
|
||||
if (panelLayouts.empty()) {
|
||||
return currentActivePanel;
|
||||
}
|
||||
|
||||
bool activePanelStillPresent = false;
|
||||
for (const XCUINativeShellPanelLayout& panelLayout : panelLayouts) {
|
||||
if (panelLayout.panelId == currentActivePanel) {
|
||||
activePanelStillPresent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XCUIShellPanelId resolvedActivePanel = activePanelStillPresent
|
||||
? currentActivePanel
|
||||
: panelLayouts.front().panelId;
|
||||
if (!pointerPressed) {
|
||||
return resolvedActivePanel;
|
||||
}
|
||||
|
||||
for (const XCUINativeShellPanelLayout& panelLayout : panelLayouts) {
|
||||
if (panelLayout.hovered) {
|
||||
return panelLayout.panelId;
|
||||
}
|
||||
}
|
||||
|
||||
return resolvedActivePanel;
|
||||
}
|
||||
|
||||
inline XCUINativeShellLayoutResult BuildXCUINativeShellLayout(
|
||||
const UI::UIRect& shellRect,
|
||||
std::initializer_list<XCUINativeShellPanelSpec> panelSpecs,
|
||||
XCUIShellPanelId currentActivePanel,
|
||||
const UI::UIPoint& pointerPosition,
|
||||
bool windowFocused,
|
||||
bool pointerPressed,
|
||||
const XCUINativeShellMetrics& metrics = {}) {
|
||||
XCUINativeShellLayoutResult result = {};
|
||||
result.shellRect = shellRect;
|
||||
result.activePanel = currentActivePanel;
|
||||
|
||||
result.topBarRect = UI::UIRect(
|
||||
shellRect.x + metrics.outerMargin,
|
||||
shellRect.y + metrics.outerMargin,
|
||||
(std::max)(0.0f, shellRect.width - metrics.outerMargin * 2.0f),
|
||||
metrics.headerHeight);
|
||||
|
||||
result.footerRect = UI::UIRect(
|
||||
shellRect.x + metrics.outerMargin,
|
||||
(std::max)(
|
||||
result.topBarRect.y + result.topBarRect.height + metrics.innerGap,
|
||||
shellRect.y + shellRect.height - metrics.outerMargin - metrics.footerHeight),
|
||||
(std::max)(0.0f, shellRect.width - metrics.outerMargin * 2.0f),
|
||||
metrics.footerHeight);
|
||||
|
||||
const float workspaceTop = result.topBarRect.y + result.topBarRect.height + metrics.innerGap;
|
||||
const float workspaceBottom = result.footerRect.y - metrics.innerGap;
|
||||
result.workspaceRect = UI::UIRect(
|
||||
shellRect.x + metrics.outerMargin,
|
||||
workspaceTop,
|
||||
(std::max)(0.0f, shellRect.width - metrics.outerMargin * 2.0f),
|
||||
(std::max)(0.0f, workspaceBottom - workspaceTop));
|
||||
|
||||
std::vector<XCUINativeShellPanelSpec> visiblePanels = {};
|
||||
visiblePanels.reserve(panelSpecs.size());
|
||||
for (const XCUINativeShellPanelSpec& panelSpec : panelSpecs) {
|
||||
if (panelSpec.visible) {
|
||||
visiblePanels.push_back(panelSpec);
|
||||
}
|
||||
}
|
||||
|
||||
if (visiblePanels.empty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.panelLayouts.reserve((std::min)(std::size_t(2), visiblePanels.size()));
|
||||
if (visiblePanels.size() >= 2u) {
|
||||
const float leftWidth = (std::max)(
|
||||
metrics.panelMinWidth,
|
||||
(std::min)(
|
||||
result.workspaceRect.width * metrics.primaryPanelWidthRatio,
|
||||
result.workspaceRect.width - metrics.panelMinWidth - metrics.innerGap));
|
||||
const float rightWidth = (std::max)(0.0f, result.workspaceRect.width - leftWidth - metrics.innerGap);
|
||||
|
||||
result.panelLayouts.push_back(BuildXCUINativeShellPanelLayout(
|
||||
visiblePanels[0],
|
||||
UI::UIRect(
|
||||
result.workspaceRect.x,
|
||||
result.workspaceRect.y,
|
||||
leftWidth,
|
||||
result.workspaceRect.height),
|
||||
pointerPosition,
|
||||
windowFocused,
|
||||
false,
|
||||
metrics));
|
||||
result.panelLayouts.push_back(BuildXCUINativeShellPanelLayout(
|
||||
visiblePanels[1],
|
||||
UI::UIRect(
|
||||
result.workspaceRect.x + leftWidth + metrics.innerGap,
|
||||
result.workspaceRect.y,
|
||||
rightWidth,
|
||||
result.workspaceRect.height),
|
||||
pointerPosition,
|
||||
windowFocused,
|
||||
false,
|
||||
metrics));
|
||||
} else {
|
||||
result.panelLayouts.push_back(BuildXCUINativeShellPanelLayout(
|
||||
visiblePanels.front(),
|
||||
result.workspaceRect,
|
||||
pointerPosition,
|
||||
windowFocused,
|
||||
false,
|
||||
metrics));
|
||||
}
|
||||
|
||||
result.activePanel = ResolveXCUINativeShellActivePanel(
|
||||
currentActivePanel,
|
||||
result.panelLayouts,
|
||||
pointerPressed);
|
||||
for (XCUINativeShellPanelLayout& panelLayout : result.panelLayouts) {
|
||||
panelLayout.active = panelLayout.panelId == result.activePanel;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace XCUIBackend
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace XCEngine {
|
||||
@@ -14,13 +15,15 @@ namespace XCUIBackend {
|
||||
|
||||
enum class XCUIPanelCanvasHostBackend : std::uint8_t {
|
||||
Null = 0,
|
||||
ImGui
|
||||
ImGui,
|
||||
Native
|
||||
};
|
||||
|
||||
struct XCUIPanelCanvasHostCapabilities {
|
||||
bool supportsPointerHitTesting = false;
|
||||
bool supportsHostedSurfaceImages = false;
|
||||
bool supportsPrimitiveOverlays = false;
|
||||
bool supportsExternallyDrivenSession = false;
|
||||
};
|
||||
|
||||
struct XCUIPanelCanvasRequest {
|
||||
@@ -46,6 +49,20 @@ struct XCUIPanelCanvasSession {
|
||||
bool windowFocused = false;
|
||||
};
|
||||
|
||||
struct XCUIPanelCanvasFrameSnapshot {
|
||||
std::string childId = {};
|
||||
XCUIPanelCanvasSession session = {};
|
||||
bool bordered = true;
|
||||
bool showingSurfaceImage = false;
|
||||
bool drawPreviewFrame = true;
|
||||
std::string placeholderTitle = {};
|
||||
std::string placeholderSubtitle = {};
|
||||
std::string badgeTitle = {};
|
||||
std::string badgeSubtitle = {};
|
||||
XCUIHostedPreviewSurfaceImage surfaceImage = {};
|
||||
::XCEngine::UI::UIDrawData overlayDrawData = {};
|
||||
};
|
||||
|
||||
inline const char* ResolveXCUIPanelCanvasChildId(
|
||||
const XCUIPanelCanvasRequest& request,
|
||||
const char* fallback = "XCUIPanelCanvasHost") {
|
||||
@@ -99,6 +116,10 @@ public:
|
||||
const ::XCEngine::UI::UIColor& color,
|
||||
float fontSize = 0.0f) = 0;
|
||||
virtual void EndCanvas() = 0;
|
||||
virtual bool TryGetLatestFrameSnapshot(XCUIPanelCanvasFrameSnapshot& outSnapshot) const {
|
||||
outSnapshot = {};
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<IXCUIPanelCanvasHost> CreateNullXCUIPanelCanvasHost();
|
||||
|
||||
Reference in New Issue
Block a user