editor: apply pending updates
This commit is contained in:
@@ -287,6 +287,7 @@ void InspectorPanel::ResetPanelState() {
|
||||
m_subjectKey.clear();
|
||||
m_presentation = {};
|
||||
m_gridFrame = {};
|
||||
m_popupOverlay = {};
|
||||
m_knownSectionIds.clear();
|
||||
m_lastSceneSelectionStamp = 0u;
|
||||
m_lastProjectSelectionStamp = 0u;
|
||||
@@ -303,6 +304,8 @@ void InspectorPanel::ResetInteractionState() {
|
||||
m_scrollVerticalOffset = 0.0f;
|
||||
m_interactionState = {};
|
||||
m_gridFrame = {};
|
||||
m_popupOverlay = {};
|
||||
ResetUIEditorMenuPopupInteractionState(m_popupInteractionState);
|
||||
m_lastAppliedColorPickerRevision = 0u;
|
||||
ResetAddComponentButtonState();
|
||||
}
|
||||
@@ -855,14 +858,12 @@ void InspectorPanel::Update(
|
||||
RefreshPresentation(context, subjectChanged);
|
||||
ApplyColorPickerToolValue(context);
|
||||
RebuildScrollableLayout();
|
||||
|
||||
Widgets::UIEditorMenuPopupLayout popupLayout = {};
|
||||
Widgets::UIEditorMenuPopupState popupState = {};
|
||||
std::vector<Widgets::UIEditorMenuPopupItem> popupItems = {};
|
||||
const bool popupOpen =
|
||||
BuildPropertyGridPopupRuntime(popupLayout, popupState, popupItems);
|
||||
RebuildPropertyGridPopupOverlay();
|
||||
const bool popupOpen = m_popupOverlay.open;
|
||||
const std::vector<UIRect> popupBounds =
|
||||
popupOpen ? std::vector<UIRect>{ popupLayout.popupRect } : std::vector<UIRect>{};
|
||||
popupOpen
|
||||
? std::vector<UIRect>{ m_popupOverlay.layout.popupRect }
|
||||
: std::vector<UIRect>{};
|
||||
|
||||
const std::vector<UIInputEvent> filteredEvents =
|
||||
BuildUIEditorPanelInputEvents(
|
||||
@@ -887,7 +888,9 @@ void InspectorPanel::Update(
|
||||
popupBounds.empty() ? nullptr : &popupBounds);
|
||||
const std::vector<UIInputEvent> contentEvents =
|
||||
popupOpen
|
||||
? BuildContentInputEventsExcludingPopup(filteredEvents, popupLayout.popupRect)
|
||||
? BuildContentInputEventsExcludingPopup(
|
||||
filteredEvents,
|
||||
m_popupOverlay.layout.popupRect)
|
||||
: filteredEvents;
|
||||
TryClaimHostedPanelCommandFocus(
|
||||
m_commandFocusService,
|
||||
@@ -954,13 +957,34 @@ void InspectorPanel::Update(
|
||||
}
|
||||
}
|
||||
|
||||
if (popupOpen) {
|
||||
HandlePropertyGridPopupOverlayInteraction(
|
||||
context,
|
||||
BuildPopupInputEvents(filteredEvents, popupLayout.popupRect));
|
||||
RebuildScrollableLayout();
|
||||
RebuildPropertyGridPopupOverlay();
|
||||
|
||||
if (m_popupOverlay.open) {
|
||||
const UIEditorMenuPopupInteractionFrame popupFrame =
|
||||
UpdateUIEditorMenuPopupInteraction(
|
||||
m_popupInteractionState,
|
||||
UIEditorMenuPopupInteractionRequest{
|
||||
.layout = m_popupOverlay.layout,
|
||||
.items = m_popupOverlay.items,
|
||||
.preferredHighlightedItemId = {},
|
||||
.closeOnFocusLost = false,
|
||||
},
|
||||
BuildPopupInputEvents(
|
||||
filteredEvents,
|
||||
m_popupOverlay.layout.popupRect));
|
||||
m_popupOverlay.widgetState = popupFrame.popupState;
|
||||
m_interactionState.propertyGridState.popupHighlightedIndex =
|
||||
popupFrame.popupState.hoveredIndex;
|
||||
if (popupFrame.result.itemActivated) {
|
||||
ApplyPropertyGridPopupActivation(
|
||||
context,
|
||||
popupFrame.result.activatedIndex);
|
||||
RebuildScrollableLayout();
|
||||
RebuildPropertyGridPopupOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
RebuildScrollableLayout();
|
||||
UpdateAddComponentButton(context, contentEvents);
|
||||
}
|
||||
|
||||
@@ -1068,14 +1092,7 @@ void InspectorPanel::Append(UIDrawList& drawList) const {
|
||||
}
|
||||
|
||||
void InspectorPanel::AppendOverlay(UIDrawList& drawList) const {
|
||||
if (!m_visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
Widgets::UIEditorMenuPopupLayout popupLayout = {};
|
||||
Widgets::UIEditorMenuPopupState popupState = {};
|
||||
std::vector<Widgets::UIEditorMenuPopupItem> popupItems = {};
|
||||
if (!BuildPropertyGridPopupRuntime(popupLayout, popupState, popupItems)) {
|
||||
if (!m_visible || !m_popupOverlay.open) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1085,152 +1102,102 @@ void InspectorPanel::AppendOverlay(UIDrawList& drawList) const {
|
||||
ResolveUIEditorMenuPopupPalette();
|
||||
Widgets::AppendUIEditorMenuPopupBackground(
|
||||
drawList,
|
||||
popupLayout,
|
||||
popupItems,
|
||||
popupState,
|
||||
m_popupOverlay.layout,
|
||||
m_popupOverlay.items,
|
||||
m_popupOverlay.widgetState,
|
||||
popupPalette,
|
||||
popupMetrics);
|
||||
Widgets::AppendUIEditorMenuPopupForeground(
|
||||
drawList,
|
||||
popupLayout,
|
||||
popupItems,
|
||||
popupState,
|
||||
m_popupOverlay.layout,
|
||||
m_popupOverlay.items,
|
||||
m_popupOverlay.widgetState,
|
||||
popupPalette,
|
||||
popupMetrics);
|
||||
}
|
||||
|
||||
std::vector<UIRect> InspectorPanel::CollectInteractiveOverlayBounds() const {
|
||||
Widgets::UIEditorMenuPopupLayout popupLayout = {};
|
||||
Widgets::UIEditorMenuPopupState popupState = {};
|
||||
std::vector<Widgets::UIEditorMenuPopupItem> popupItems = {};
|
||||
if (!BuildPropertyGridPopupRuntime(popupLayout, popupState, popupItems) ||
|
||||
popupLayout.popupRect.width <= 0.0f ||
|
||||
popupLayout.popupRect.height <= 0.0f) {
|
||||
if (!m_popupOverlay.open ||
|
||||
m_popupOverlay.layout.popupRect.width <= 0.0f ||
|
||||
m_popupOverlay.layout.popupRect.height <= 0.0f) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return { popupLayout.popupRect };
|
||||
return { m_popupOverlay.layout.popupRect };
|
||||
}
|
||||
|
||||
bool InspectorPanel::BuildPropertyGridPopupRuntime(
|
||||
Widgets::UIEditorMenuPopupLayout& popupLayout,
|
||||
Widgets::UIEditorMenuPopupState& popupState,
|
||||
std::vector<Widgets::UIEditorMenuPopupItem>& popupItems) const {
|
||||
void InspectorPanel::RebuildPropertyGridPopupOverlay() {
|
||||
m_popupOverlay = {};
|
||||
if (!m_visible ||
|
||||
m_gridFrame.layout.bounds.width <= 0.0f ||
|
||||
m_gridFrame.layout.bounds.height <= 0.0f) {
|
||||
return false;
|
||||
ResetUIEditorMenuPopupInteractionState(m_popupInteractionState);
|
||||
return;
|
||||
}
|
||||
|
||||
return Widgets::BuildUIEditorPropertyGridPopupRuntime(
|
||||
Widgets::UIEditorMenuPopupLayout popupLayout = {};
|
||||
Widgets::UIEditorMenuPopupState popupState = {};
|
||||
std::vector<Widgets::UIEditorMenuPopupItem> popupItems = {};
|
||||
if (!Widgets::BuildUIEditorPropertyGridPopupRuntime(
|
||||
m_gridFrame.layout,
|
||||
m_presentation.sections,
|
||||
m_interactionState.propertyGridState,
|
||||
popupLayout,
|
||||
popupState,
|
||||
popupItems,
|
||||
ResolveUIEditorMenuPopupMetrics());
|
||||
ResolveUIEditorMenuPopupMetrics())) {
|
||||
ResetUIEditorMenuPopupInteractionState(m_popupInteractionState);
|
||||
return;
|
||||
}
|
||||
|
||||
m_popupInteractionState.focused = popupState.focused;
|
||||
const UIEditorMenuPopupInteractionFrame popupFrame =
|
||||
UpdateUIEditorMenuPopupInteraction(
|
||||
m_popupInteractionState,
|
||||
UIEditorMenuPopupInteractionRequest{
|
||||
.layout = popupLayout,
|
||||
.items = popupItems,
|
||||
.preferredHighlightedItemId = {},
|
||||
.closeOnFocusLost = false,
|
||||
},
|
||||
{});
|
||||
m_popupOverlay.open = true;
|
||||
m_popupOverlay.layout = popupFrame.layout;
|
||||
m_popupOverlay.widgetState = popupFrame.popupState;
|
||||
m_popupOverlay.items = std::move(popupItems);
|
||||
m_interactionState.propertyGridState.popupHighlightedIndex =
|
||||
popupFrame.popupState.hoveredIndex;
|
||||
}
|
||||
|
||||
bool InspectorPanel::HandlePropertyGridPopupOverlayInteraction(
|
||||
bool InspectorPanel::ApplyPropertyGridPopupActivation(
|
||||
InspectorPanelContext& context,
|
||||
const std::vector<UIInputEvent>& inputEvents) {
|
||||
if (inputEvents.empty()) {
|
||||
std::size_t activatedIndex) {
|
||||
const std::string popupFieldId = m_interactionState.propertyGridState.popupFieldId;
|
||||
if (popupFieldId.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Widgets::UIEditorMenuPopupLayout popupLayout = {};
|
||||
Widgets::UIEditorMenuPopupState popupState = {};
|
||||
std::vector<Widgets::UIEditorMenuPopupItem> popupItems = {};
|
||||
if (!BuildPropertyGridPopupRuntime(popupLayout, popupState, popupItems)) {
|
||||
m_interactionState.propertyGridState.popupFieldId.clear();
|
||||
m_interactionState.propertyGridState.popupHighlightedIndex =
|
||||
Widgets::UIEditorPropertyGridInvalidIndex;
|
||||
ResetUIEditorMenuPopupInteractionState(m_popupInteractionState);
|
||||
|
||||
Widgets::UIEditorPropertyGridField* field =
|
||||
FindMutableField(popupFieldId);
|
||||
if (field == nullptr ||
|
||||
field->kind != Widgets::UIEditorPropertyGridFieldKind::Enum ||
|
||||
activatedIndex >= field->enumValue.options.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
for (const UIInputEvent& event : inputEvents) {
|
||||
const Widgets::UIEditorMenuPopupHitTarget hitTarget =
|
||||
Widgets::HitTestUIEditorMenuPopup(
|
||||
popupLayout,
|
||||
popupItems,
|
||||
event.position);
|
||||
|
||||
switch (event.type) {
|
||||
case UIInputEventType::PointerMove:
|
||||
case UIInputEventType::PointerEnter:
|
||||
m_interactionState.propertyGridState.popupHighlightedIndex =
|
||||
hitTarget.kind == Widgets::UIEditorMenuPopupHitTargetKind::Item &&
|
||||
hitTarget.index < popupItems.size() &&
|
||||
popupItems[hitTarget.index].enabled
|
||||
? hitTarget.index
|
||||
: Widgets::UIEditorMenuPopupInvalidIndex;
|
||||
handled = true;
|
||||
break;
|
||||
|
||||
case UIInputEventType::PointerButtonDown:
|
||||
if (event.pointerButton != UIPointerButton::Left) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (hitTarget.kind == Widgets::UIEditorMenuPopupHitTargetKind::Item &&
|
||||
hitTarget.index < popupItems.size() &&
|
||||
popupItems[hitTarget.index].enabled) {
|
||||
m_interactionState.propertyGridState.focused = true;
|
||||
m_interactionState.pressedPopupIndex = hitTarget.index;
|
||||
handled = true;
|
||||
} else if (hitTarget.kind ==
|
||||
Widgets::UIEditorMenuPopupHitTargetKind::PopupSurface) {
|
||||
m_interactionState.propertyGridState.focused = true;
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case UIInputEventType::PointerButtonUp:
|
||||
if (event.pointerButton != UIPointerButton::Left) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_interactionState.pressedPopupIndex !=
|
||||
Widgets::UIEditorPropertyGridInvalidIndex &&
|
||||
hitTarget.kind == Widgets::UIEditorMenuPopupHitTargetKind::Item &&
|
||||
hitTarget.index == m_interactionState.pressedPopupIndex &&
|
||||
hitTarget.index < popupItems.size() &&
|
||||
popupItems[hitTarget.index].enabled) {
|
||||
const std::string popupFieldId =
|
||||
m_interactionState.propertyGridState.popupFieldId;
|
||||
m_interactionState.propertyGridState.popupHighlightedIndex = hitTarget.index;
|
||||
m_interactionState.propertyGridState.popupFieldId.clear();
|
||||
m_interactionState.pressedPopupIndex =
|
||||
Widgets::UIEditorPropertyGridInvalidIndex;
|
||||
|
||||
Widgets::UIEditorPropertyGridField* field =
|
||||
FindMutableField(popupFieldId);
|
||||
if (field != nullptr &&
|
||||
field->kind == Widgets::UIEditorPropertyGridFieldKind::Enum &&
|
||||
hitTarget.index < field->enumValue.options.size()) {
|
||||
field->enumValue.selectedIndex = hitTarget.index;
|
||||
if (ApplyChangedField(field->fieldId)) {
|
||||
RefreshPresentation(context, false);
|
||||
} else {
|
||||
ForceResyncPresentation(context);
|
||||
}
|
||||
}
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (hitTarget.kind != Widgets::UIEditorMenuPopupHitTargetKind::None) {
|
||||
m_interactionState.pressedPopupIndex =
|
||||
Widgets::UIEditorPropertyGridInvalidIndex;
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
field->enumValue.selectedIndex = activatedIndex;
|
||||
if (ApplyChangedField(field->fieldId)) {
|
||||
RefreshPresentation(context, false);
|
||||
} else {
|
||||
ForceResyncPresentation(context);
|
||||
}
|
||||
|
||||
return handled;
|
||||
return true;
|
||||
}
|
||||
|
||||
UIEditorHostCommandEvaluationResult InspectorPanel::EvaluateEditCommand(
|
||||
|
||||
Reference in New Issue
Block a user