388 auto rotation = data.get_rotation();
389 auto scale = data.get_scale();
390 auto skew = data.get_skew();
393 auto type = entt::resolve<math::transform>();
395 static math::vec3 euler_angles(0.0f, 0.0f, 0.0f);
397 math::quat old_quat(math::radians(euler_angles));
399 float dot_product = math::dot(old_quat, rotation);
400 bool equal = (dot_product > (1.0f - math::epsilon<float>()));
401 if(!equal && (!ImGui::IsMouseDragging(ImGuiMouseButton_Left) || ImGuizmo::IsUsing()))
403 euler_angles = data.get_rotation_euler_degrees();
408 ImGui::PushID(
"Position");
410 auto prop =
type.data(
"position"_hs);
418 layout.
set_data(prop_pretty_name,
"");
425 ImGui::GetContentRegionAvail().
x,
426 ImGui::GetFrameHeight(),
431 data.reset_position();
432 result.changed =
true;
433 result.edit_finished =
true;
438 result.edit_finished |= ImGui::IsItemDeactivatedAfterEdit();
439 ImGui::SetItemTooltipEx(
"Reset %s", prop_pretty_name.c_str());
443 ImGui::PushItemWidth(ImGui::GetContentRegionAvail().
x);
445 static const auto reset = math::zero<math::vec3>();
446 if(DragVec3(position, info, &reset))
448 data.set_position(position);
449 result.changed |=
true;
454 result.edit_finished |= ImGui::IsItemDeactivatedAfterEdit();
456 ImGui::PopItemWidth();
458 override_ctx.pop_segment();
462 ImGui::PushID(
"Rotation");
464 auto prop =
type.data(
"rotation"_hs);
472 layout.
set_data(prop_pretty_name,
"");
479 ImGui::GetContentRegionAvail().
x,
480 ImGui::GetFrameHeight(),
485 data.reset_rotation();
486 result.changed =
true;
487 result.edit_finished =
true;
490 add_property_action(ctx, override_ctx, result, prop_proxy, rotation, data.get_rotation(), prop.custom());
492 result.edit_finished |= ImGui::IsItemDeactivatedAfterEdit();
494 ImGui::SetItemTooltipEx(
"Reset %s", prop_pretty_name.c_str());
498 ImGui::PushItemWidth(ImGui::GetContentRegionAvail().
x);
500 auto old_euler = euler_angles;
501 static const auto reset = math::zero<math::vec3>();
502 if(DragVec3(euler_angles, info, &reset,
"%.2f°"))
504 data.rotate_local(math::radians(euler_angles - old_euler));
505 result.changed |=
true;
508 add_property_action(ctx, override_ctx, result, prop_proxy, rotation, data.get_rotation(), prop.custom());
510 result.edit_finished |= ImGui::IsItemDeactivatedAfterEdit();
513 ImGui::PopItemWidth();
515 override_ctx.pop_segment();
519 ImGui::PushID(
"Scale");
521 auto prop =
type.data(
"scale"_hs);
529 layout.
set_data(prop_pretty_name,
"");
533 static bool locked_scale =
false;
537 ImGui::GetContentRegionAvail().
x,
538 ImGui::CalcItemSize(label).
x + ImGui::GetFrameHeight() + ImGui::GetStyle().ItemSpacing.x,
541 if(ImGui::Button(label))
543 locked_scale = !locked_scale;
546 ImGui::SetItemTooltipEx(
"Enable/Disable Constrained Proportions");
553 result.changed =
true;
554 result.edit_finished =
true;
559 result.edit_finished |= ImGui::IsItemDeactivatedAfterEdit();
561 ImGui::SetItemTooltipEx(
"Reset %s", prop_pretty_name.c_str());
564 layout.prepare_for_item();
566 ImGui::PushItemWidth(ImGui::GetContentRegionAvail().
x);
568 static const auto reset = math::one<math::vec3>();
569 auto before_scale =
scale;
570 if(DragVec3(
scale, info, &reset))
572 auto delta =
scale - before_scale;
576 before_scale += math::vec3(delta.x);
577 before_scale += math::vec3(delta.y);
578 before_scale += math::vec3(delta.z);
579 scale = before_scale;
582 data.set_scale(
scale);
583 result.changed |=
true;
589 result.edit_finished |= ImGui::IsItemDeactivatedAfterEdit();
591 ImGui::PopItemWidth();
593 override_ctx.pop_segment();
597 ImGui::PushID(
"Skew");
599 auto prop =
type.data(
"skew"_hs);
607 layout.
set_data(prop_pretty_name,
"");
614 ImGui::GetContentRegionAvail().
x,
615 ImGui::GetFrameHeight(),
621 result.changed =
true;
622 result.edit_finished =
true;
625 add_property_action(ctx, override_ctx, result, prop_proxy, skew, data.get_skew(), prop.custom());
627 result.edit_finished |= ImGui::IsItemDeactivatedAfterEdit();
628 ImGui::SetItemTooltipEx(
"Reset %s", prop_pretty_name.c_str());
632 ImGui::PushItemWidth(ImGui::GetContentRegionAvail().
x);
634 static const auto reset = math::zero<math::vec3>();
635 if(DragVec3(skew, info, &reset))
638 result.changed |=
true;
640 add_property_action(ctx, override_ctx, result, prop_proxy, skew, data.get_skew(), prop.custom());
643 result.edit_finished |= ImGui::IsItemDeactivatedAfterEdit();
645 ImGui::PopItemWidth();
647 override_ctx.pop_segment();
void push_segment(const std::string &segment, const std::string &pretty_segment)
Pushes a new path segment onto both contexts and applies override styling.