Refactor XCUI editor module layout
This commit is contained in:
563
new_editor/src/Fields/UIEditorVector2FieldInteraction.cpp
Normal file
563
new_editor/src/Fields/UIEditorVector2FieldInteraction.cpp
Normal file
@@ -0,0 +1,563 @@
|
||||
#include <XCEditor/Fields/UIEditorVector2FieldInteraction.h>
|
||||
|
||||
#include <XCEngine/Input/InputTypes.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace XCEngine::UI::Editor {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::XCEngine::Input::KeyCode;
|
||||
using ::XCEngine::UI::UIInputEvent;
|
||||
using ::XCEngine::UI::UIInputEventType;
|
||||
using ::XCEngine::UI::UIPointerButton;
|
||||
using ::XCEngine::UI::Text::HandleKeyDown;
|
||||
using ::XCEngine::UI::Text::InsertCharacter;
|
||||
using ::XCEngine::UI::Editor::Widgets::BuildUIEditorVector2FieldLayout;
|
||||
using ::XCEngine::UI::Editor::Widgets::FormatUIEditorVector2FieldComponentValue;
|
||||
using ::XCEngine::UI::Editor::Widgets::HitTestUIEditorVector2Field;
|
||||
using ::XCEngine::UI::Editor::Widgets::IsUIEditorVector2FieldPointInside;
|
||||
using ::XCEngine::UI::Editor::Widgets::NormalizeUIEditorVector2FieldComponentValue;
|
||||
using ::XCEngine::UI::Editor::Widgets::TryParseUIEditorVector2FieldComponentValue;
|
||||
using ::XCEngine::UI::Editor::Widgets::UIEditorVector2FieldHitTarget;
|
||||
using ::XCEngine::UI::Editor::Widgets::UIEditorVector2FieldHitTargetKind;
|
||||
using ::XCEngine::UI::Editor::Widgets::UIEditorVector2FieldInvalidComponentIndex;
|
||||
using ::XCEngine::UI::Editor::Widgets::UIEditorVector2FieldLayout;
|
||||
using ::XCEngine::UI::Editor::Widgets::UIEditorVector2FieldMetrics;
|
||||
using ::XCEngine::UI::Editor::Widgets::UIEditorVector2FieldSpec;
|
||||
|
||||
bool ShouldUsePointerPosition(const UIInputEvent& event) {
|
||||
switch (event.type) {
|
||||
case UIInputEventType::PointerMove:
|
||||
case UIInputEventType::PointerEnter:
|
||||
case UIInputEventType::PointerButtonDown:
|
||||
case UIInputEventType::PointerButtonUp:
|
||||
case UIInputEventType::PointerWheel:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t ResolveFallbackSelectedComponentIndex(
|
||||
const UIEditorVector2FieldInteractionState& state) {
|
||||
return state.vector2FieldState.selectedComponentIndex ==
|
||||
UIEditorVector2FieldInvalidComponentIndex
|
||||
? 0u
|
||||
: state.vector2FieldState.selectedComponentIndex;
|
||||
}
|
||||
|
||||
std::string BuildComponentEditFieldId(
|
||||
const UIEditorVector2FieldSpec& spec,
|
||||
std::size_t componentIndex) {
|
||||
return spec.fieldId + "." + std::to_string(componentIndex);
|
||||
}
|
||||
|
||||
bool IsPermittedCharacter(
|
||||
const UIEditorVector2FieldSpec& spec,
|
||||
std::uint32_t character) {
|
||||
if (character >= static_cast<std::uint32_t>('0') &&
|
||||
character <= static_cast<std::uint32_t>('9')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (character == static_cast<std::uint32_t>('-') ||
|
||||
character == static_cast<std::uint32_t>('+')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !spec.integerMode && character == static_cast<std::uint32_t>('.');
|
||||
}
|
||||
|
||||
void SyncDisplayTexts(
|
||||
UIEditorVector2FieldInteractionState& state,
|
||||
const UIEditorVector2FieldSpec& spec) {
|
||||
for (std::size_t componentIndex = 0u;
|
||||
componentIndex < state.vector2FieldState.displayTexts.size();
|
||||
++componentIndex) {
|
||||
if (state.vector2FieldState.editing &&
|
||||
state.vector2FieldState.selectedComponentIndex == componentIndex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
state.vector2FieldState.displayTexts[componentIndex] =
|
||||
FormatUIEditorVector2FieldComponentValue(spec, componentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void SyncHoverTarget(
|
||||
UIEditorVector2FieldInteractionState& state,
|
||||
const UIEditorVector2FieldLayout& layout) {
|
||||
if (!state.hasPointerPosition) {
|
||||
state.vector2FieldState.hoveredTarget = UIEditorVector2FieldHitTargetKind::None;
|
||||
state.vector2FieldState.hoveredComponentIndex = UIEditorVector2FieldInvalidComponentIndex;
|
||||
return;
|
||||
}
|
||||
|
||||
const UIEditorVector2FieldHitTarget hitTarget =
|
||||
HitTestUIEditorVector2Field(layout, state.pointerPosition);
|
||||
state.vector2FieldState.hoveredTarget = hitTarget.kind;
|
||||
state.vector2FieldState.hoveredComponentIndex = hitTarget.componentIndex;
|
||||
}
|
||||
|
||||
bool MoveSelection(
|
||||
UIEditorVector2FieldInteractionState& state,
|
||||
int direction,
|
||||
UIEditorVector2FieldInteractionResult& result) {
|
||||
const std::size_t before = ResolveFallbackSelectedComponentIndex(state);
|
||||
const std::size_t after =
|
||||
direction < 0
|
||||
? (before == 0u ? 0u : before - 1u)
|
||||
: (before >= 1u ? 1u : before + 1u);
|
||||
state.vector2FieldState.selectedComponentIndex = after;
|
||||
result.selectionChanged = before != after;
|
||||
result.selectedComponentIndex = after;
|
||||
result.consumed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SelectComponent(
|
||||
UIEditorVector2FieldInteractionState& state,
|
||||
std::size_t componentIndex,
|
||||
UIEditorVector2FieldInteractionResult& result) {
|
||||
if (componentIndex >= 2u) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::size_t before = ResolveFallbackSelectedComponentIndex(state);
|
||||
state.vector2FieldState.selectedComponentIndex = componentIndex;
|
||||
result.selectionChanged = before != componentIndex;
|
||||
result.selectedComponentIndex = componentIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BeginEdit(
|
||||
UIEditorVector2FieldInteractionState& state,
|
||||
const UIEditorVector2FieldSpec& spec,
|
||||
std::size_t componentIndex,
|
||||
bool clearText) {
|
||||
if (spec.readOnly || componentIndex >= spec.values.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string baseline =
|
||||
FormatUIEditorVector2FieldComponentValue(spec, componentIndex);
|
||||
const std::string editFieldId =
|
||||
BuildComponentEditFieldId(spec, componentIndex);
|
||||
const bool changed = state.editModel.BeginEdit(editFieldId, baseline);
|
||||
if (!changed &&
|
||||
state.editModel.HasActiveEdit() &&
|
||||
state.editModel.GetActiveFieldId() != editFieldId) {
|
||||
return false;
|
||||
}
|
||||
if (!changed &&
|
||||
state.vector2FieldState.editing &&
|
||||
state.vector2FieldState.selectedComponentIndex == componentIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
state.vector2FieldState.selectedComponentIndex = componentIndex;
|
||||
state.vector2FieldState.editing = true;
|
||||
state.textInputState.value = clearText ? std::string() : baseline;
|
||||
state.textInputState.caret = state.textInputState.value.size();
|
||||
state.editModel.UpdateStagedValue(state.textInputState.value);
|
||||
state.vector2FieldState.displayTexts[componentIndex] = state.textInputState.value;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommitEdit(
|
||||
UIEditorVector2FieldInteractionState& state,
|
||||
UIEditorVector2FieldSpec& spec,
|
||||
UIEditorVector2FieldInteractionResult& result) {
|
||||
if (!state.vector2FieldState.editing ||
|
||||
!state.editModel.HasActiveEdit() ||
|
||||
state.vector2FieldState.selectedComponentIndex >= spec.values.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::size_t componentIndex = state.vector2FieldState.selectedComponentIndex;
|
||||
double parsedValue = spec.values[componentIndex];
|
||||
if (!TryParseUIEditorVector2FieldComponentValue(
|
||||
spec,
|
||||
state.textInputState.value,
|
||||
parsedValue)) {
|
||||
result.consumed = true;
|
||||
result.editCommitRejected = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
result.valuesBefore = spec.values;
|
||||
spec.values[componentIndex] = NormalizeUIEditorVector2FieldComponentValue(spec, parsedValue);
|
||||
result.valuesAfter = spec.values;
|
||||
result.valueChanged = result.valuesBefore != result.valuesAfter;
|
||||
result.editCommitted = true;
|
||||
result.consumed = true;
|
||||
result.changedComponentIndex = componentIndex;
|
||||
result.selectedComponentIndex = componentIndex;
|
||||
result.committedText =
|
||||
FormatUIEditorVector2FieldComponentValue(spec, componentIndex);
|
||||
|
||||
state.editModel.CommitEdit();
|
||||
state.textInputState = {};
|
||||
state.vector2FieldState.editing = false;
|
||||
state.vector2FieldState.displayTexts[componentIndex] = result.committedText;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CancelEdit(
|
||||
UIEditorVector2FieldInteractionState& state,
|
||||
const UIEditorVector2FieldSpec& spec,
|
||||
UIEditorVector2FieldInteractionResult& result) {
|
||||
if (!state.vector2FieldState.editing ||
|
||||
!state.editModel.HasActiveEdit() ||
|
||||
state.vector2FieldState.selectedComponentIndex >= spec.values.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::size_t componentIndex = state.vector2FieldState.selectedComponentIndex;
|
||||
state.editModel.CancelEdit();
|
||||
state.textInputState = {};
|
||||
state.vector2FieldState.editing = false;
|
||||
state.vector2FieldState.displayTexts[componentIndex] =
|
||||
FormatUIEditorVector2FieldComponentValue(spec, componentIndex);
|
||||
result.consumed = true;
|
||||
result.editCanceled = true;
|
||||
result.valuesBefore = spec.values;
|
||||
result.valuesAfter = spec.values;
|
||||
result.selectedComponentIndex = componentIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApplyStep(
|
||||
UIEditorVector2FieldInteractionState& state,
|
||||
UIEditorVector2FieldSpec& spec,
|
||||
double direction,
|
||||
bool snapToEdge,
|
||||
UIEditorVector2FieldInteractionResult& result) {
|
||||
if (spec.readOnly) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::size_t componentIndex = ResolveFallbackSelectedComponentIndex(state);
|
||||
state.vector2FieldState.selectedComponentIndex = componentIndex;
|
||||
|
||||
if (state.vector2FieldState.editing &&
|
||||
!CommitEdit(state, spec, result)) {
|
||||
return result.editCommitRejected;
|
||||
}
|
||||
|
||||
result.valuesBefore = spec.values;
|
||||
if (snapToEdge) {
|
||||
spec.values[componentIndex] =
|
||||
direction < 0.0
|
||||
? NormalizeUIEditorVector2FieldComponentValue(spec, spec.minValue)
|
||||
: NormalizeUIEditorVector2FieldComponentValue(spec, spec.maxValue);
|
||||
} else {
|
||||
const double step = spec.step == 0.0 ? 1.0 : spec.step;
|
||||
spec.values[componentIndex] = NormalizeUIEditorVector2FieldComponentValue(
|
||||
spec,
|
||||
spec.values[componentIndex] + step * direction);
|
||||
result.stepDelta = step * direction;
|
||||
}
|
||||
|
||||
result.valuesAfter = spec.values;
|
||||
result.stepApplied = true;
|
||||
result.valueChanged = result.valuesBefore != result.valuesAfter || result.valueChanged;
|
||||
result.changedComponentIndex = componentIndex;
|
||||
result.selectedComponentIndex = componentIndex;
|
||||
result.consumed = true;
|
||||
state.vector2FieldState.displayTexts[componentIndex] =
|
||||
FormatUIEditorVector2FieldComponentValue(spec, componentIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
UIEditorVector2FieldInteractionFrame UpdateUIEditorVector2FieldInteraction(
|
||||
UIEditorVector2FieldInteractionState& state,
|
||||
UIEditorVector2FieldSpec& spec,
|
||||
const ::XCEngine::UI::UIRect& bounds,
|
||||
const std::vector<UIInputEvent>& inputEvents,
|
||||
const UIEditorVector2FieldMetrics& metrics) {
|
||||
UIEditorVector2FieldLayout layout = BuildUIEditorVector2FieldLayout(bounds, spec, metrics);
|
||||
SyncDisplayTexts(state, spec);
|
||||
SyncHoverTarget(state, layout);
|
||||
|
||||
UIEditorVector2FieldInteractionResult interactionResult = {};
|
||||
interactionResult.selectedComponentIndex = state.vector2FieldState.selectedComponentIndex;
|
||||
for (const UIInputEvent& event : inputEvents) {
|
||||
if (ShouldUsePointerPosition(event)) {
|
||||
state.pointerPosition = event.position;
|
||||
state.hasPointerPosition = true;
|
||||
} else if (event.type == UIInputEventType::PointerLeave) {
|
||||
state.hasPointerPosition = false;
|
||||
}
|
||||
|
||||
UIEditorVector2FieldInteractionResult eventResult = {};
|
||||
eventResult.selectedComponentIndex = state.vector2FieldState.selectedComponentIndex;
|
||||
switch (event.type) {
|
||||
case UIInputEventType::FocusGained:
|
||||
eventResult.focusChanged = !state.vector2FieldState.focused;
|
||||
state.vector2FieldState.focused = true;
|
||||
if (state.vector2FieldState.selectedComponentIndex ==
|
||||
UIEditorVector2FieldInvalidComponentIndex) {
|
||||
state.vector2FieldState.selectedComponentIndex = 0u;
|
||||
}
|
||||
eventResult.selectedComponentIndex = state.vector2FieldState.selectedComponentIndex;
|
||||
break;
|
||||
|
||||
case UIInputEventType::FocusLost:
|
||||
eventResult.focusChanged = state.vector2FieldState.focused;
|
||||
state.vector2FieldState.focused = false;
|
||||
state.vector2FieldState.activeTarget = UIEditorVector2FieldHitTargetKind::None;
|
||||
state.vector2FieldState.activeComponentIndex = UIEditorVector2FieldInvalidComponentIndex;
|
||||
state.hasPointerPosition = false;
|
||||
if (state.vector2FieldState.editing) {
|
||||
CommitEdit(state, spec, eventResult);
|
||||
if (eventResult.editCommitRejected) {
|
||||
CancelEdit(state, spec, eventResult);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case UIInputEventType::PointerMove:
|
||||
case UIInputEventType::PointerEnter:
|
||||
case UIInputEventType::PointerLeave:
|
||||
break;
|
||||
|
||||
case UIInputEventType::PointerButtonDown: {
|
||||
const UIEditorVector2FieldHitTarget hitTarget =
|
||||
state.hasPointerPosition
|
||||
? HitTestUIEditorVector2Field(layout, state.pointerPosition)
|
||||
: UIEditorVector2FieldHitTarget {};
|
||||
eventResult.hitTarget = hitTarget;
|
||||
|
||||
if (event.pointerButton != UIPointerButton::Left) {
|
||||
break;
|
||||
}
|
||||
|
||||
const bool insideField =
|
||||
state.hasPointerPosition &&
|
||||
IsUIEditorVector2FieldPointInside(layout.bounds, state.pointerPosition);
|
||||
if (insideField) {
|
||||
eventResult.focusChanged = !state.vector2FieldState.focused;
|
||||
state.vector2FieldState.focused = true;
|
||||
state.vector2FieldState.activeTarget = hitTarget.kind == UIEditorVector2FieldHitTargetKind::None
|
||||
? UIEditorVector2FieldHitTargetKind::Row
|
||||
: hitTarget.kind;
|
||||
state.vector2FieldState.activeComponentIndex = hitTarget.componentIndex;
|
||||
if (hitTarget.kind == UIEditorVector2FieldHitTargetKind::Component) {
|
||||
SelectComponent(state, hitTarget.componentIndex, eventResult);
|
||||
} else if (state.vector2FieldState.selectedComponentIndex ==
|
||||
UIEditorVector2FieldInvalidComponentIndex) {
|
||||
state.vector2FieldState.selectedComponentIndex = 0u;
|
||||
eventResult.selectedComponentIndex = 0u;
|
||||
}
|
||||
eventResult.consumed = true;
|
||||
} else {
|
||||
if (state.vector2FieldState.editing) {
|
||||
CommitEdit(state, spec, eventResult);
|
||||
if (!eventResult.editCommitRejected) {
|
||||
eventResult.focusChanged = state.vector2FieldState.focused;
|
||||
state.vector2FieldState.focused = false;
|
||||
}
|
||||
} else if (state.vector2FieldState.focused) {
|
||||
eventResult.focusChanged = true;
|
||||
state.vector2FieldState.focused = false;
|
||||
}
|
||||
state.vector2FieldState.activeTarget = UIEditorVector2FieldHitTargetKind::None;
|
||||
state.vector2FieldState.activeComponentIndex = UIEditorVector2FieldInvalidComponentIndex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case UIInputEventType::PointerButtonUp: {
|
||||
const UIEditorVector2FieldHitTarget hitTarget =
|
||||
state.hasPointerPosition
|
||||
? HitTestUIEditorVector2Field(layout, state.pointerPosition)
|
||||
: UIEditorVector2FieldHitTarget {};
|
||||
eventResult.hitTarget = hitTarget;
|
||||
|
||||
if (event.pointerButton == UIPointerButton::Left) {
|
||||
const UIEditorVector2FieldHitTargetKind activeTarget = state.vector2FieldState.activeTarget;
|
||||
const std::size_t activeComponentIndex = state.vector2FieldState.activeComponentIndex;
|
||||
state.vector2FieldState.activeTarget = UIEditorVector2FieldHitTargetKind::None;
|
||||
state.vector2FieldState.activeComponentIndex = UIEditorVector2FieldInvalidComponentIndex;
|
||||
|
||||
if (activeTarget == UIEditorVector2FieldHitTargetKind::Component &&
|
||||
hitTarget.kind == UIEditorVector2FieldHitTargetKind::Component &&
|
||||
activeComponentIndex == hitTarget.componentIndex) {
|
||||
SelectComponent(state, hitTarget.componentIndex, eventResult);
|
||||
if (!state.vector2FieldState.editing) {
|
||||
eventResult.editStarted =
|
||||
BeginEdit(state, spec, hitTarget.componentIndex, false);
|
||||
}
|
||||
eventResult.consumed = true;
|
||||
} else if (hitTarget.kind == UIEditorVector2FieldHitTargetKind::Row) {
|
||||
eventResult.consumed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case UIInputEventType::KeyDown:
|
||||
if (!state.vector2FieldState.focused) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (state.vector2FieldState.editing) {
|
||||
if (event.keyCode == static_cast<std::int32_t>(KeyCode::Escape)) {
|
||||
CancelEdit(state, spec, eventResult);
|
||||
break;
|
||||
}
|
||||
|
||||
if (event.keyCode == static_cast<std::int32_t>(KeyCode::Tab)) {
|
||||
if (CommitEdit(state, spec, eventResult)) {
|
||||
MoveSelection(
|
||||
state,
|
||||
event.modifiers.shift ? -1 : 1,
|
||||
eventResult);
|
||||
}
|
||||
eventResult.consumed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const auto textResult =
|
||||
HandleKeyDown(state.textInputState, event.keyCode, event.modifiers);
|
||||
if (textResult.handled) {
|
||||
state.editModel.UpdateStagedValue(state.textInputState.value);
|
||||
state.vector2FieldState.displayTexts[state.vector2FieldState.selectedComponentIndex] =
|
||||
state.textInputState.value;
|
||||
eventResult.consumed = true;
|
||||
eventResult.selectedComponentIndex = state.vector2FieldState.selectedComponentIndex;
|
||||
if (textResult.submitRequested) {
|
||||
CommitEdit(state, spec, eventResult);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (static_cast<KeyCode>(event.keyCode)) {
|
||||
case KeyCode::Left:
|
||||
MoveSelection(state, -1, eventResult);
|
||||
break;
|
||||
|
||||
case KeyCode::Right:
|
||||
case KeyCode::Tab:
|
||||
MoveSelection(
|
||||
state,
|
||||
static_cast<KeyCode>(event.keyCode) == KeyCode::Tab && event.modifiers.shift ? -1 : 1,
|
||||
eventResult);
|
||||
break;
|
||||
|
||||
case KeyCode::Up:
|
||||
ApplyStep(state, spec, 1.0, false, eventResult);
|
||||
break;
|
||||
|
||||
case KeyCode::Down:
|
||||
ApplyStep(state, spec, -1.0, false, eventResult);
|
||||
break;
|
||||
|
||||
case KeyCode::Home:
|
||||
ApplyStep(state, spec, -1.0, true, eventResult);
|
||||
break;
|
||||
|
||||
case KeyCode::End:
|
||||
ApplyStep(state, spec, 1.0, true, eventResult);
|
||||
break;
|
||||
|
||||
case KeyCode::Enter:
|
||||
eventResult.selectedComponentIndex = ResolveFallbackSelectedComponentIndex(state);
|
||||
eventResult.editStarted = BeginEdit(
|
||||
state,
|
||||
spec,
|
||||
eventResult.selectedComponentIndex,
|
||||
false);
|
||||
eventResult.consumed = eventResult.editStarted;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case UIInputEventType::Character:
|
||||
if (!state.vector2FieldState.focused ||
|
||||
spec.readOnly ||
|
||||
event.modifiers.control ||
|
||||
event.modifiers.alt ||
|
||||
event.modifiers.super ||
|
||||
!IsPermittedCharacter(spec, event.character)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (state.vector2FieldState.selectedComponentIndex ==
|
||||
UIEditorVector2FieldInvalidComponentIndex) {
|
||||
state.vector2FieldState.selectedComponentIndex = 0u;
|
||||
}
|
||||
eventResult.selectedComponentIndex = state.vector2FieldState.selectedComponentIndex;
|
||||
|
||||
if (!state.vector2FieldState.editing) {
|
||||
eventResult.editStarted = BeginEdit(
|
||||
state,
|
||||
spec,
|
||||
state.vector2FieldState.selectedComponentIndex,
|
||||
true);
|
||||
}
|
||||
|
||||
if (InsertCharacter(state.textInputState, event.character)) {
|
||||
state.editModel.UpdateStagedValue(state.textInputState.value);
|
||||
state.vector2FieldState.displayTexts[state.vector2FieldState.selectedComponentIndex] =
|
||||
state.textInputState.value;
|
||||
eventResult.consumed = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
layout = BuildUIEditorVector2FieldLayout(bounds, spec, metrics);
|
||||
SyncDisplayTexts(state, spec);
|
||||
SyncHoverTarget(state, layout);
|
||||
if (eventResult.hitTarget.kind == UIEditorVector2FieldHitTargetKind::None &&
|
||||
state.hasPointerPosition) {
|
||||
eventResult.hitTarget = HitTestUIEditorVector2Field(layout, state.pointerPosition);
|
||||
}
|
||||
if (eventResult.selectedComponentIndex == UIEditorVector2FieldInvalidComponentIndex) {
|
||||
eventResult.selectedComponentIndex = state.vector2FieldState.selectedComponentIndex;
|
||||
}
|
||||
|
||||
if (eventResult.consumed ||
|
||||
eventResult.focusChanged ||
|
||||
eventResult.valueChanged ||
|
||||
eventResult.stepApplied ||
|
||||
eventResult.selectionChanged ||
|
||||
eventResult.editStarted ||
|
||||
eventResult.editCommitted ||
|
||||
eventResult.editCommitRejected ||
|
||||
eventResult.editCanceled ||
|
||||
eventResult.hitTarget.kind != UIEditorVector2FieldHitTargetKind::None) {
|
||||
interactionResult = std::move(eventResult);
|
||||
}
|
||||
}
|
||||
|
||||
layout = BuildUIEditorVector2FieldLayout(bounds, spec, metrics);
|
||||
SyncDisplayTexts(state, spec);
|
||||
SyncHoverTarget(state, layout);
|
||||
if (interactionResult.hitTarget.kind == UIEditorVector2FieldHitTargetKind::None &&
|
||||
state.hasPointerPosition) {
|
||||
interactionResult.hitTarget = HitTestUIEditorVector2Field(layout, state.pointerPosition);
|
||||
}
|
||||
if (interactionResult.selectedComponentIndex == UIEditorVector2FieldInvalidComponentIndex) {
|
||||
interactionResult.selectedComponentIndex = state.vector2FieldState.selectedComponentIndex;
|
||||
}
|
||||
|
||||
return {
|
||||
std::move(layout),
|
||||
std::move(interactionResult)
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor
|
||||
Reference in New Issue
Block a user