| 820 | } |
| 821 | |
| 822 | void Scene3DConfigPanel::bindDock(Scene3DDockWidget* dock) { |
| 823 | if (bound_dock_.data() == dock) { |
| 824 | return; |
| 825 | } |
| 826 | disconnectFromDock(); |
| 827 | bound_dock_ = dock; |
| 828 | |
| 829 | layer_list_->clearRows(); |
| 830 | config_host_->clear(); |
| 831 | // Robot rows belong to the dock they were added to; a rebind starts from a |
| 832 | // clean slate (the previous dock keeps its layers). |
| 833 | for (const auto& [id, row] : robot_rows_) { |
| 834 | row->deleteLater(); |
| 835 | } |
| 836 | robot_rows_.clear(); |
| 837 | robot_rows_host_->hide(); // back to collapsed until this dock's rows are rebuilt |
| 838 | |
| 839 | if (dock == nullptr) { |
| 840 | populateFollowCombo(); // reset to "None" |
| 841 | updateSelectedLayerPane(); |
| 842 | return; |
| 843 | } |
| 844 | |
| 845 | rebuildLayerList(); |
| 846 | loadControlsFromDock(dock); // reflect THIS dock's look; controls are per-dock |
| 847 | populateFollowCombo(); // reflect THIS dock's follow target + frame set |
| 848 | |
| 849 | connect(dock, &SceneDockWidget::layerAdded, this, &Scene3DConfigPanel::onLayerAdded); |
| 850 | connect(dock, &SceneDockWidget::layerRemoved, this, &Scene3DConfigPanel::onLayerRemoved); |
| 851 | connect(dock, &SceneDockWidget::layerVisibilityChanged, this, &Scene3DConfigPanel::onLayerVisibilityChanged); |
| 852 | connect(dock, &SceneDockWidget::layerWarningChanged, this, &Scene3DConfigPanel::onLayerWarningChanged); |
| 853 | // Keep the follow combo in step with the dock's frame set and follow target. |
| 854 | connect(dock, &Scene3DDockWidget::availableFramesChanged, this, [this](const QList<pj::scene3d::FrameRow>&) { |
| 855 | populateFollowCombo(); |
| 856 | }); |
| 857 | connect(dock, &Scene3DDockWidget::followFrameChanged, this, [this](const QString&) { populateFollowCombo(); }); |
| 858 | } |
| 859 | |
| 860 | void Scene3DConfigPanel::disconnectFromDock() { |
| 861 | if (bound_dock_ != nullptr) { |