src/Screens/ModelEditorScreen.cpp
// draw UI element that lets user change a model joint's type
draw UI element that lets user change a model joint's type
draw UI element that lets user change a model joint ' s type
void drawSelectionJointTypeSwitcher(UndoableUiModel& st) {
        OpenSim::Joint const* selection = st.getSelectedAs<OpenSim::Joint>();
        if (!selection) {
            return;
        }
        auto const* parentJointset =
            selection->hasOwner() ? dynamic_cast<OpenSim::JointSet const*>(&selection->getOwner()) : nullptr;
        if (!parentJointset) {
            return;
        }
        OpenSim::JointSet const& js = *parentJointset;
        int idx = -1;
        for (int i = 0; i < js.getSize(); ++i) {
            OpenSim::Joint const* j = &js[i];
            if (j == selection) {
                idx = i;
                break;
            }
        }
        if (idx == -1) {
            return;
        }
        ImGui::TextUnformatted("joint type");
        ImGui::NextColumn();
        std::optional<size_t> maybeTypeIndex = JointRegistry::indexOf(*selection);
        int typeIndex = maybeTypeIndex ? static_cast<int>(*maybeTypeIndex) : -1;
        auto jointNames = JointRegistry::nameCStrings();
        ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth());
        if (ImGui::Combo(
                "##newjointtypeselector",
                &typeIndex,
                jointNames.data(),
                static_cast<int>(jointNames.size())) &&
            typeIndex >= 0) {
            std::unique_ptr<OpenSim::Joint> newJoint{JointRegistry::prototypes()[static_cast<size_t>(typeIndex)]->clone()};
            copyCommonJointProperties(*selection, *newJoint);
             note: this will invalidate the `selection` joint, because the
             OpenSim::JointSet container will automatically kill it
            OpenSim::Joint* ptr = newJoint.get();
            st.setDirty(true);
            const_cast<OpenSim::JointSet&>(js).set(idx, newJoint.release());
            st.declareDeathOf(selection);
            st.setSelected(ptr);
        }
        ImGui::NextColumn();
    }
void drawSelectionJointTypeSwitcher ( UndoableUiModel & st ) { OpenSim :: Joint const * selection = st . getSelectedAs < OpenSim :: Joint > ( ) ; if ( ! selection ) { return ; } auto const * parentJointset = selection -> hasOwner ( ) ? dynamic_cast < OpenSim :: JointSet const * > ( & selection -> getOwner ( ) ) : nullptr ; if ( ! parentJointset ) { return ; } OpenSim :: JointSet const & js = * parentJointset ; int idx = -1 ; for ( int i = 0 ; i < js . getSize ( ) ; ++ i ) { OpenSim :: Joint const * j = & js [ i ] ; if ( j == selection ) { idx = i ; break ; } } if ( idx == -1 ) { return ; } ImGui :: TextUnformatted ( " " ) ; ImGui :: NextColumn ( ) ; std :: optional < size_t > maybeTypeIndex = JointRegistry :: indexOf ( * selection ) ; int typeIndex = maybeTypeIndex ? static_cast < int > ( * maybeTypeIndex ) : -1 ; auto jointNames = JointRegistry :: nameCStrings ( ) ; ImGui :: SetNextItemWidth ( ImGui :: GetContentRegionAvailWidth ( ) ) ; if ( ImGui :: Combo ( " " , & typeIndex , jointNames . data ( ) , static_cast < int > ( jointNames . size ( ) ) ) && typeIndex >= 0 ) { std :: unique_ptr < OpenSim :: Joint > newJoint { JointRegistry :: prototypes ( ) [ static_cast < size_t > ( typeIndex ) ] -> clone ( ) } ; copyCommonJointProperties ( * selection , * newJoint ) ; OpenSim :: Joint * ptr = newJoint . get ( ) ; st . setDirty ( true ) ; const_cast < OpenSim :: JointSet & > ( js ) . set ( idx , newJoint . release ( ) ) ; st . declareDeathOf ( selection ) ; st . setSelected ( ptr ) ; } ImGui :: NextColumn ( ) ; }
draw UI element that lets user change a model joint's type
draw UI element that lets user change a model joint ' s type
// it's a joint, but it's not owned by a JointSet, so the implementation cannot switch // the joint type // logically, this should never happen // look the Joint up in the type registry so we know where it should be in the ImGui::Combo // copy + fixup  a prototype of the user's selection // overwrite old joint in model // // note: this will invalidate the `selection` joint, because the // OpenSim::JointSet container will automatically kill it