feat(new_editor): add project panel and polish dock chrome
This commit is contained in:
@@ -41,6 +41,45 @@ constexpr const wchar_t* kWindowTitle = L"Main Scene * - Main.xx - XCEngine Edit
|
||||
constexpr UINT kDefaultDpi = 96u;
|
||||
constexpr float kBaseDpiScale = 96.0f;
|
||||
|
||||
UIEditorShellComposeModel BuildShellComposeModelFromFrame(
|
||||
const UIEditorShellInteractionFrame& frame) {
|
||||
UIEditorShellComposeModel model = {};
|
||||
model.menuBarItems = frame.request.menuBarItems;
|
||||
model.toolbarButtons = frame.model.toolbarButtons;
|
||||
model.statusSegments = frame.model.statusSegments;
|
||||
model.workspacePresentations = frame.model.workspacePresentations;
|
||||
return model;
|
||||
}
|
||||
|
||||
void AppendShellPopups(
|
||||
UIDrawList& drawList,
|
||||
const UIEditorShellInteractionFrame& frame,
|
||||
const UIEditorShellInteractionPalette& palette,
|
||||
const UIEditorShellInteractionMetrics& metrics) {
|
||||
const std::size_t popupCount =
|
||||
(std::min)(frame.request.popupRequests.size(), frame.popupFrames.size());
|
||||
for (std::size_t index = 0; index < popupCount; ++index) {
|
||||
const UIEditorShellInteractionPopupRequest& popupRequest =
|
||||
frame.request.popupRequests[index];
|
||||
const UIEditorShellInteractionPopupFrame& popupFrame =
|
||||
frame.popupFrames[index];
|
||||
Widgets::AppendUIEditorMenuPopupBackground(
|
||||
drawList,
|
||||
popupRequest.layout,
|
||||
popupRequest.widgetItems,
|
||||
popupFrame.popupState,
|
||||
palette.popupPalette,
|
||||
metrics.popupMetrics);
|
||||
Widgets::AppendUIEditorMenuPopupForeground(
|
||||
drawList,
|
||||
popupRequest.layout,
|
||||
popupRequest.widgetItems,
|
||||
popupFrame.popupState,
|
||||
palette.popupPalette,
|
||||
metrics.popupMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
Application* GetApplicationFromWindow(HWND hwnd) {
|
||||
return reinterpret_cast<Application*>(GetWindowLongPtrW(hwnd, GWLP_USERDATA));
|
||||
}
|
||||
@@ -289,6 +328,27 @@ std::string DescribeInputEventType(const UIInputEvent& event) {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<UIInputEvent> FilterShellInputEventsForHostedContentCapture(
|
||||
const std::vector<UIInputEvent>& inputEvents) {
|
||||
std::vector<UIInputEvent> filteredEvents = {};
|
||||
filteredEvents.reserve(inputEvents.size());
|
||||
for (const UIInputEvent& event : inputEvents) {
|
||||
switch (event.type) {
|
||||
case UIInputEventType::PointerMove:
|
||||
case UIInputEventType::PointerEnter:
|
||||
case UIInputEventType::PointerLeave:
|
||||
case UIInputEventType::PointerButtonDown:
|
||||
case UIInputEventType::PointerButtonUp:
|
||||
case UIInputEventType::PointerWheel:
|
||||
break;
|
||||
default:
|
||||
filteredEvents.push_back(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return filteredEvents;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int Application::Run(HINSTANCE hInstance, int nCmdShow) {
|
||||
@@ -339,6 +399,7 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) {
|
||||
m_shellServices.commandDispatcher = &m_shortcutManager.GetCommandDispatcher();
|
||||
m_shellServices.shortcutManager = &m_shortcutManager;
|
||||
m_shellServices.textMeasurer = &m_renderer;
|
||||
m_projectPanel.Initialize(ResolveRepoRootPath());
|
||||
m_lastStatus = "Ready";
|
||||
m_lastMessage = "Old editor shell baseline loaded.";
|
||||
LogRuntimeTrace("app", "workspace initialized: " + DescribeWorkspaceState());
|
||||
@@ -385,6 +446,7 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) {
|
||||
LogRuntimeTrace("app", "renderer initialization failed");
|
||||
return false;
|
||||
}
|
||||
m_projectPanel.SetTextMeasurer(&m_renderer);
|
||||
|
||||
ShowWindow(m_hwnd, nCmdShow);
|
||||
UpdateWindow(m_hwnd);
|
||||
@@ -448,6 +510,11 @@ void Application::RenderFrame() {
|
||||
const UIEditorShellInteractionDefinition definition = BuildShellDefinition();
|
||||
std::vector<UIInputEvent> frameEvents = std::move(m_pendingInputEvents);
|
||||
m_pendingInputEvents.clear();
|
||||
const std::vector<UIInputEvent> hostedContentEvents = frameEvents;
|
||||
const std::vector<UIInputEvent> shellEvents =
|
||||
m_projectPanel.HasActivePointerCapture()
|
||||
? FilterShellInputEventsForHostedContentCapture(frameEvents)
|
||||
: frameEvents;
|
||||
if (!frameEvents.empty()) {
|
||||
LogRuntimeTrace(
|
||||
"input",
|
||||
@@ -459,10 +526,10 @@ void Application::RenderFrame() {
|
||||
m_workspaceController,
|
||||
UIRect(0.0f, 0.0f, width, height),
|
||||
definition,
|
||||
frameEvents,
|
||||
shellEvents,
|
||||
m_shellServices,
|
||||
metrics);
|
||||
if (!frameEvents.empty() ||
|
||||
if (!shellEvents.empty() ||
|
||||
m_shellFrame.result.workspaceResult.dockHostResult.layoutChanged ||
|
||||
m_shellFrame.result.workspaceResult.dockHostResult.commandExecuted) {
|
||||
std::ostringstream frameTrace = {};
|
||||
@@ -482,13 +549,24 @@ void Application::RenderFrame() {
|
||||
}
|
||||
ApplyHostCaptureRequests(m_shellFrame.result);
|
||||
UpdateLastStatus(m_shellFrame.result);
|
||||
m_projectPanel.Update(
|
||||
m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame,
|
||||
hostedContentEvents,
|
||||
!m_shellFrame.result.workspaceInputSuppressed,
|
||||
m_workspaceController.GetWorkspace().activePanelId == "project");
|
||||
ApplyHostedContentCaptureRequests();
|
||||
ApplyCurrentCursor();
|
||||
AppendUIEditorShellInteraction(
|
||||
const UIEditorShellComposeModel shellComposeModel =
|
||||
BuildShellComposeModelFromFrame(m_shellFrame);
|
||||
AppendUIEditorShellCompose(
|
||||
drawList,
|
||||
m_shellFrame,
|
||||
m_shellInteractionState,
|
||||
palette,
|
||||
metrics);
|
||||
m_shellFrame.shellFrame,
|
||||
shellComposeModel,
|
||||
m_shellInteractionState.composeState,
|
||||
palette.shellPalette,
|
||||
metrics.shellMetrics);
|
||||
m_projectPanel.Append(drawList);
|
||||
AppendShellPopups(drawList, m_shellFrame, palette, metrics);
|
||||
} else {
|
||||
drawList.AddText(
|
||||
UIPoint(28.0f, 28.0f),
|
||||
@@ -522,6 +600,14 @@ float Application::PixelsToDips(float pixels) const {
|
||||
}
|
||||
|
||||
LPCWSTR Application::ResolveCurrentCursorResource() const {
|
||||
switch (m_projectPanel.GetCursorKind()) {
|
||||
case App::ProductProjectPanel::CursorKind::ResizeEW:
|
||||
return IDC_SIZEWE;
|
||||
case App::ProductProjectPanel::CursorKind::Arrow:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Widgets::ResolveUIEditorDockHostCursorKind(
|
||||
m_shellFrame.workspaceInteractionFrame.dockHostFrame.layout)) {
|
||||
case Widgets::UIEditorDockHostCursorKind::ResizeEW:
|
||||
@@ -639,7 +725,19 @@ void Application::ApplyHostCaptureRequests(const UIEditorShellInteractionResult&
|
||||
}
|
||||
}
|
||||
|
||||
bool Application::HasInteractiveCaptureState() const {
|
||||
void Application::ApplyHostedContentCaptureRequests() {
|
||||
if (m_projectPanel.WantsHostPointerCapture() && GetCapture() != m_hwnd) {
|
||||
SetCapture(m_hwnd);
|
||||
}
|
||||
|
||||
if (m_projectPanel.WantsHostPointerRelease() &&
|
||||
GetCapture() == m_hwnd &&
|
||||
!HasShellInteractiveCaptureState()) {
|
||||
ReleaseCapture();
|
||||
}
|
||||
}
|
||||
|
||||
bool Application::HasShellInteractiveCaptureState() const {
|
||||
if (m_shellInteractionState.workspaceInteractionState.dockHostInteractionState.splitterDragState.active) {
|
||||
return true;
|
||||
}
|
||||
@@ -657,6 +755,10 @@ bool Application::HasInteractiveCaptureState() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Application::HasInteractiveCaptureState() const {
|
||||
return HasShellInteractiveCaptureState() || m_projectPanel.HasActivePointerCapture();
|
||||
}
|
||||
|
||||
UIEditorShellInteractionDefinition Application::BuildShellDefinition() const {
|
||||
std::string statusText = m_lastStatus;
|
||||
if (!m_lastMessage.empty()) {
|
||||
|
||||
Reference in New Issue
Block a user