From 777ad3721aa28ae95e96b8b0f641d0a7bb4a0d24 Mon Sep 17 00:00:00 2001 From: Adam Kewley Date: Tue, 25 Jun 2024 14:19:28 +0200 Subject: [PATCH] Refactor MeshWarpingTabSharedState to use getters etc. (#892) --- .../UI/MeshWarper/MeshWarpingTab.cpp | 21 +- .../MeshWarpingTabDecorationGenerators.h | 8 +- .../MeshWarper/MeshWarpingTabInputMeshPanel.h | 49 ++--- .../MeshWarper/MeshWarpingTabNavigatorPanel.h | 16 +- .../MeshWarpingTabResultMeshPanel.h | 27 +-- .../UI/MeshWarper/MeshWarpingTabSharedState.h | 185 +++++++++++++----- .../UI/MeshWarper/MeshWarpingTabStatusBar.h | 8 +- .../UI/MeshWarper/MeshWarpingTabToolbar.cpp | 22 ++- .../UI/MeshWarper/MeshWarpingTabToolbar.h | 2 +- 9 files changed, 199 insertions(+), 139 deletions(-) diff --git a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTab.cpp b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTab.cpp index dcf24155c..0570649e2 100644 --- a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTab.cpp +++ b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTab.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -57,7 +58,7 @@ class osc::MeshWarpingTab::Impl final { "History", [state = m_Shared](std::string_view panelName) { - return std::make_shared(panelName, state->editedDocument); + return std::make_shared(panelName, state->getUndoableSharedPtr()); }, ToggleablePanelFlags::Default - ToggleablePanelFlags::IsEnabledByDefault ); @@ -104,23 +105,21 @@ class osc::MeshWarpingTab::Impl final { { App::upd().make_main_loop_waiting(); m_PanelManager->on_mount(); - m_Shared->popupManager.on_mount(); + m_Shared->on_mount(); } void on_unmount() { + m_Shared->on_unmount(); m_PanelManager->on_unmount(); App::upd().make_main_loop_polling(); } bool onEvent(const SDL_Event& e) { - if (e.type == SDL_KEYDOWN) - { + if (e.type == SDL_KEYDOWN) { return onKeydownEvent(e.key); - } - else - { + } else { return false; } } @@ -128,7 +127,7 @@ class osc::MeshWarpingTab::Impl final { void on_tick() { // re-perform hover test each frame - m_Shared->currentHover.reset(); + m_Shared->setHover(std::nullopt); // garbage collect panel data m_PanelManager->on_tick(); @@ -146,9 +145,7 @@ class osc::MeshWarpingTab::Impl final { m_TopToolbar.onDraw(); m_PanelManager->on_draw(); m_StatusBar.onDraw(); - - // draw active popups over the UI - m_Shared->popupManager.on_draw(); + m_Shared->on_draw(); } private: @@ -202,7 +199,7 @@ class osc::MeshWarpingTab::Impl final { ParentPtr m_Parent; // top-level state that all panels can potentially access - std::shared_ptr m_Shared = std::make_shared(m_TabID, m_Parent); + std::shared_ptr m_Shared = std::make_shared(m_TabID, m_Parent, App::singleton(App::resource_loader())); // available/active panels that the user can toggle via the `window` menu std::shared_ptr m_PanelManager = std::make_shared(); diff --git a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabDecorationGenerators.h b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabDecorationGenerators.h index 20ca0615d..e5e4a9b12 100644 --- a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabDecorationGenerators.h +++ b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabDecorationGenerators.h @@ -13,7 +13,7 @@ namespace osc { // append decorations that are common to all panels to the given output vector void AppendCommonDecorations( - const MeshWarpingTabSharedState& sharedState, + MeshWarpingTabSharedState& sharedState, const Mesh& tpsSourceOrDestinationMesh, bool wireframeMode, const std::function& out, @@ -30,13 +30,13 @@ namespace osc { out({ .mesh = tpsSourceOrDestinationMesh, - .material = sharedState.wireframe_material, + .material = sharedState.wireframe_material(), }); } // add grid decorations - draw_xz_grid(*sharedState.meshCache, out); - draw_xz_floor_lines(*sharedState.meshCache, out, 100.0f); + draw_xz_grid(sharedState.updSceneCache(), out); + draw_xz_floor_lines(sharedState.updSceneCache(), out, 100.0f); } // returns the amount by which non-participating landmarks should be scaled w.r.t. pariticpating ones diff --git a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabInputMeshPanel.h b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabInputMeshPanel.h index c2683722f..fd4836a18 100644 --- a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabInputMeshPanel.h +++ b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabInputMeshPanel.h @@ -88,11 +88,11 @@ namespace osc // state update: tell central state if something's being hovered in this panel if (landmarkCollision) { - m_State->currentHover = landmarkCollision; + m_State->setHover(landmarkCollision); } else if (meshCollision) { - m_State->currentHover.emplace(m_DocumentIdentifier, meshCollision->position); + m_State->setHover(m_DocumentIdentifier, meshCollision->position); } // update camera: NOTE: make sure it's updated *before* rendering; otherwise, it'll be one frame late @@ -114,26 +114,13 @@ namespace osc void updateCamera() { // if the cameras are linked together, ensure this camera is updated from the linked camera - if (m_State->linkCameras && m_Camera != m_State->linkedCameraBase) - { - if (m_State->onlyLinkRotation) - { - m_Camera.phi = m_State->linkedCameraBase.phi; - m_Camera.theta = m_State->linkedCameraBase.theta; - } - else - { - m_Camera = m_State->linkedCameraBase; - } - } + m_State->updateOneCameraFromLinkedBase(m_Camera); // if the user interacts with the render, update the camera as necessary - if (m_LastTextureHittestResult.is_hovered) - { - if (ui::update_polar_camera_from_mouse_inputs(m_Camera, dimensions_of(m_LastTextureHittestResult.item_screen_rect))) - { - m_State->linkedCameraBase = m_Camera; // reflects latest modification - } + if (m_LastTextureHittestResult.is_hovered and + ui::update_polar_camera_from_mouse_inputs(m_Camera, dimensions_of(m_LastTextureHittestResult.item_screen_rect))) { + + m_State->setLinkedBaseCamera(m_Camera); } } @@ -287,9 +274,9 @@ namespace osc SceneDecoration decoration { - .mesh = m_State->landmarkSphere, + .mesh = m_State->getLandmarkSphereMesh(), .transform = {.scale = Vec3{m_LandmarkRadius}, .position = *maybeLocation}, - .color = IsFullyPaired(landmarkPair) ? m_State->pairedLandmarkColor : m_State->unpairedLandmarkColor, + .color = IsFullyPaired(landmarkPair) ? m_State->getPairedLandmarkColor() : m_State->getUnpairedLandmarkColor(), }; const TPSDocumentElementID landmarkID{landmarkPair.uid, TPSDocumentElementType::Landmark, m_DocumentIdentifier}; @@ -324,13 +311,13 @@ namespace osc { SceneDecoration decoration { - .mesh = m_State->landmarkSphere, + .mesh = m_State->getLandmarkSphereMesh(), .transform = { .scale = Vec3{GetNonParticipatingLandmarkScaleFactor()*m_LandmarkRadius}, .position = npl.location, }, - .color = m_State->nonParticipatingLandmarkColor, + .color = m_State->getNonParticipatingLandmarkColor(), }; const TPSDocumentElementID id{npl.uid, TPSDocumentElementType::NonParticipatingLandmark, m_DocumentIdentifier}; if (m_State->isSelected(id)) @@ -353,15 +340,15 @@ namespace osc const bool nonParticipating = isUserPlacingNonParticipatingLandmark(); const Color color = nonParticipating ? - m_State->nonParticipatingLandmarkColor : - m_State->unpairedLandmarkColor; + m_State->getNonParticipatingLandmarkColor() : + m_State->getUnpairedLandmarkColor(); const float radius = nonParticipating ? GetNonParticipatingLandmarkScaleFactor()*m_LandmarkRadius : m_LandmarkRadius; decorationConsumer({ - .mesh = m_State->landmarkSphere, + .mesh = m_State->getLandmarkSphereMesh(), .transform = {.scale = Vec3{radius}, .position = meshCollisionPosition}, .color = color.with_alpha(0.8f), // faded }); @@ -417,7 +404,7 @@ namespace osc { ActionDeleteSceneElementsByID( m_State->updUndoable(), - m_State->userSelection.getUnderlyingSet() + m_State->getUnderlyingSelectionSet() ); m_State->clearSelection(); } @@ -428,7 +415,7 @@ namespace osc // draws 2D ImGui overlays over the scene render void draw2DOverlayUI(const Rect& renderRect) { - ui::set_cursor_screen_pos(renderRect.p1 + m_State->overlayPadding); + ui::set_cursor_screen_pos(renderRect.p1 + m_State->getOverlayPadding()); drawInformationIcon(); ui::same_line(); @@ -574,7 +561,7 @@ namespace osc if (ui::draw_button(ICON_FA_EXPAND_ARROWS_ALT)) { auto_focus(m_Camera, m_State->getScratchMesh(m_DocumentIdentifier).bounds(), aspect_ratio_of(m_LastTextureHittestResult.item_screen_rect)); - m_State->linkedCameraBase = m_Camera; + m_State->setLinkedBaseCamera(m_Camera); } ui::draw_tooltip_if_item_hovered("Autoscale Scene", "Zooms camera to try and fit everything in the scene into the viewer"); } @@ -587,7 +574,7 @@ namespace osc const ImGuiSliderFlags flags = ImGuiSliderFlags_Logarithmic; const CStringView label = "landmark radius"; - ui::set_next_item_width(ui::get_content_region_avail().x - ui::calc_text_size(label).x - ui::get_style_item_inner_spacing().x - m_State->overlayPadding.x); + ui::set_next_item_width(ui::get_content_region_avail().x - ui::calc_text_size(label).x - ui::get_style_item_inner_spacing().x - m_State->getOverlayPadding().x); ui::draw_float_slider(label, &m_LandmarkRadius, 0.0001f, 100.0f, "%.4f", flags); } diff --git a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabNavigatorPanel.h b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabNavigatorPanel.h index 89a7dd303..27311f5da 100644 --- a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabNavigatorPanel.h +++ b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabNavigatorPanel.h @@ -221,7 +221,7 @@ namespace osc ui::get_panel_draw_list()->AddCircleFilled( circle.origin, circle.radius, - ui::to_ImU32(m_State->nonParticipatingLandmarkColor) + ui::to_ImU32(m_State->getNonParticipatingLandmarkColor()) ); tryDrawCircleHighlight(circle, isSelected, isHovered); @@ -229,15 +229,11 @@ namespace osc Color landmarkDotColor(bool hasLocation, bool isPaired) const { - if (hasLocation) - { - if (isPaired) - { - return m_State->pairedLandmarkColor; - } - else - { - return m_State->unpairedLandmarkColor; + if (hasLocation) { + if (isPaired) { + return m_State->getPairedLandmarkColor(); + } else { + return m_State->getUnpairedLandmarkColor(); } } return Color::half_grey(); diff --git a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabResultMeshPanel.h b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabResultMeshPanel.h index 617d738f4..b69596ca6 100644 --- a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabResultMeshPanel.h +++ b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabResultMeshPanel.h @@ -61,25 +61,14 @@ namespace osc void updateCamera() { // if cameras are linked together, ensure all cameras match the "base" camera - if (m_State->linkCameras && m_Camera != m_State->linkedCameraBase) - { - if (m_State->onlyLinkRotation) - { - m_Camera.phi = m_State->linkedCameraBase.phi; - m_Camera.theta = m_State->linkedCameraBase.theta; - } - else - { - m_Camera = m_State->linkedCameraBase; - } - } + m_State->updateOneCameraFromLinkedBase(m_Camera); // update camera if user drags it around etc. if (m_LastTextureHittestResult.is_hovered) { if (ui::update_polar_camera_from_mouse_inputs(m_Camera, dimensions_of(m_LastTextureHittestResult.item_screen_rect))) { - m_State->linkedCameraBase = m_Camera; // reflects latest modification + m_State->setLinkedBaseCamera(m_Camera); // reflects latest modification } } } @@ -162,11 +151,11 @@ namespace osc } if (ui::draw_menu_item("Warped Non-Participating Landmarks to CSV")) { - ActionSaveWarpedNonParticipatingLandmarksToCSV(m_State->getScratch(), m_State->meshResultCache); + ActionSaveWarpedNonParticipatingLandmarksToCSV(m_State->getScratch(), m_State->updResultCache()); } if (ui::draw_menu_item("Warped Non-Participating Landmark Positions to CSV")) { - ActionSaveWarpedNonParticipatingLandmarksToCSV(m_State->getScratch(), m_State->meshResultCache, LandmarkCSVFlags::NoHeader | LandmarkCSVFlags::NoNames); + ActionSaveWarpedNonParticipatingLandmarksToCSV(m_State->getScratch(), m_State->updResultCache(), LandmarkCSVFlags::NoHeader | LandmarkCSVFlags::NoNames); } if (ui::draw_menu_item("Landmark Pairs to CSV")) { @@ -190,7 +179,7 @@ namespace osc m_State->getResultMesh().bounds(), aspect_ratio_of(m_LastTextureHittestResult.item_screen_rect) ); - m_State->linkedCameraBase = m_Camera; + m_State->setLinkedBaseCamera(m_Camera); } ui::draw_tooltip_if_item_hovered( "Autoscale Scene", @@ -206,7 +195,7 @@ namespace osc const ImGuiSliderFlags flags = ImGuiSliderFlags_Logarithmic; const CStringView label = "landmark radius"; - ui::set_next_item_width(ui::get_content_region_avail().x - ui::calc_text_size(label).x - ui::get_style_item_inner_spacing().x - m_State->overlayPadding.x); + ui::set_next_item_width(ui::get_content_region_avail().x - ui::calc_text_size(label).x - ui::get_style_item_inner_spacing().x - m_State->getOverlayPadding().x); ui::draw_float_slider(label, &m_LandmarkRadius, 0.0001f, 100.0f, "%.4f", flags); } @@ -254,12 +243,12 @@ namespace osc for (const Vec3& nonParticipatingLandmarkPos : m_State->getResultNonParticipatingLandmarkLocations()) { decorationConsumer({ - .mesh = m_State->landmarkSphere, + .mesh = m_State->getLandmarkSphereMesh(), .transform = { .scale = Vec3{GetNonParticipatingLandmarkScaleFactor()*m_LandmarkRadius}, .position = nonParticipatingLandmarkPos, }, - .color = m_State->nonParticipatingLandmarkColor, + .color = m_State->getNonParticipatingLandmarkColor(), }); } diff --git a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabSharedState.h b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabSharedState.h index bc9cf6840..518eac6d1 100644 --- a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabSharedState.h +++ b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabSharedState.h @@ -17,9 +17,9 @@ #include #include #include -#include #include #include +#include #include #include @@ -32,30 +32,52 @@ namespace osc { // top-level UI state that is shared by all UI panels - struct MeshWarpingTabSharedState final { - + class MeshWarpingTabSharedState final { + public: MeshWarpingTabSharedState( UID tabID_, - ParentPtr parent_) : + ParentPtr parent_, + std::shared_ptr sceneCache_) : + + m_TabID{tabID_}, + m_TabHost{std::move(parent_)}, + m_SceneCache{std::move(sceneCache_)} + { + OSC_ASSERT(m_SceneCache != nullptr); + } - tabID{tabID_}, - tabHost{std::move(parent_)} + void on_mount() { + m_PopupManager.on_mount(); + } + + void on_unmount() + {} + + void on_draw() + { + // draw active popups over the UI + m_PopupManager.on_draw(); } const TPSDocument& getScratch() const { - return editedDocument->scratch(); + return m_UndoableTPSDocument->scratch(); } const UndoableTPSDocument& getUndoable() const { - return *editedDocument; + return *m_UndoableTPSDocument; } UndoableTPSDocument& updUndoable() { - return *editedDocument; + return *m_UndoableTPSDocument; + } + + std::shared_ptr getUndoableSharedPtr() + { + return m_UndoableTPSDocument; } const Mesh& getScratchMesh(TPSDocumentInputIdentifier which) const @@ -66,32 +88,60 @@ namespace osc const BVH& getScratchMeshBVH(TPSDocumentInputIdentifier which) { const Mesh& mesh = getScratchMesh(which); - return meshCache->get_bvh(mesh); + return updSceneCache().get_bvh(mesh); + } + + TPSResultCache& updResultCache() + { + return m_WarpingCache; } // returns a (potentially cached) post-TPS-warp mesh const Mesh& getResultMesh() { - return meshResultCache.getWarpedMesh(editedDocument->scratch()); + return m_WarpingCache.getWarpedMesh(m_UndoableTPSDocument->scratch()); } std::span getResultNonParticipatingLandmarkLocations() { - return meshResultCache.getWarpedNonParticipatingLandmarkLocations(editedDocument->scratch()); + return m_WarpingCache.getWarpedNonParticipatingLandmarkLocations(m_UndoableTPSDocument->scratch()); + } + + bool isHoveringSomething() const + { + return m_CurrentHover.has_value(); + } + + const MeshWarpingTabHover& getCurrentHover() const + { + return *m_CurrentHover; } bool isHovered(const TPSDocumentElementID& id) const { - return currentHover && currentHover->isHovering(id); + return m_CurrentHover && m_CurrentHover->isHovering(id); + } + + void setHover(const std::optional& newHover) + { + m_CurrentHover = newHover; + } + + void setHover(TPSDocumentInputIdentifier id, const Vec3& position) + { + m_CurrentHover.emplace(id, position); + } + + void setHover(std::nullopt_t) + { + m_CurrentHover.reset(); } bool hasSelection() const { // TODO: should probably gc the selection - for (const auto& el : userSelection.getUnderlyingSet()) - { - if (FindElement(getScratch(), el)) - { + for (const auto& el : m_UserSelection.getUnderlyingSet()) { + if (FindElement(getScratch(), el)) { return true; } } @@ -100,50 +150,54 @@ namespace osc bool isSelected(const TPSDocumentElementID& id) const { - return userSelection.contains(id); + return m_UserSelection.contains(id); } void select(const TPSDocumentElementID& id) { - userSelection.select(id); + m_UserSelection.select(id); } void clearSelection() { - userSelection.clear(); + m_UserSelection.clear(); } void selectAll() { - for (const auto& el : GetAllElementIDs(editedDocument->scratch())) - { - userSelection.select(el); + for (const auto& el : GetAllElementIDs(m_UndoableTPSDocument->scratch())) { + m_UserSelection.select(el); } } + const std::unordered_set& getUnderlyingSelectionSet() const + { + return m_UserSelection.getUnderlyingSet(); + } + void closeTab() { - tabHost->close_tab(tabID); + m_TabHost->close_tab(m_TabID); } bool canUndo() const { - return editedDocument->can_undo(); + return m_UndoableTPSDocument->can_undo(); } void undo() { - editedDocument->undo(); + m_UndoableTPSDocument->undo(); } bool canRedo() const { - return editedDocument->can_redo(); + return m_UndoableTPSDocument->can_redo(); } void redo() { - editedDocument->redo(); + m_UndoableTPSDocument->redo(); } template TPopup, class... Args> @@ -152,51 +206,80 @@ namespace osc { auto p = std::make_shared(std::forward(args)...); p->open(); - popupManager.push_back(std::move(p)); + m_PopupManager.push_back(std::move(p)); } + const Material& wireframe_material() const { return m_WireframeMaterial; } + const Mesh& getLandmarkSphereMesh() const { return m_LandmarkSphere; } + SceneCache& updSceneCache() { return *m_SceneCache; } + + Vec2 getOverlayPadding() const { return {10.0f, 10.0f}; } + Color getPairedLandmarkColor() const { return Color::green(); } + Color getUnpairedLandmarkColor() const { return Color::red(); } + Color getNonParticipatingLandmarkColor() const { return Color::purple(); } + + const PolarPerspectiveCamera& getLinkedBaseCamera() const { return m_LinkedCameraBase; } + bool isCamerasLinked() const { return m_LinkCameras; } + void setCamerasLinked(bool v) { m_LinkCameras = v; } + bool isOnlyCameraRotationLinked() const { return m_OnlyLinkRotation; } + void setOnlyCameraRotationLinked(bool v) { m_OnlyLinkRotation = v; } + bool updateOneCameraFromLinkedBase(PolarPerspectiveCamera& camera) + { + // if the cameras are linked together, ensure this camera is updated from the linked camera + if (isCamerasLinked() and camera != getLinkedBaseCamera()) { + if (isOnlyCameraRotationLinked()) { + camera.phi = m_LinkedCameraBase.phi; + camera.theta = m_LinkedCameraBase.theta; + } else { + camera = m_LinkedCameraBase; + } + return true; + } + return false; + } + void setLinkedBaseCamera(const PolarPerspectiveCamera& newCamera) + { + m_LinkedCameraBase = newCamera; + } + + private: // ID of the top-level TPS3D tab - UID tabID; + UID m_TabID; // handle to the screen that owns the TPS3D tab - ParentPtr tabHost; + ParentPtr m_TabHost; - // cached TPS3D algorithm result (to prevent recomputing it each frame) - TPSResultCache meshResultCache; + // cached TPS3D algorithm result (to prevent recomputing it over and over) + TPSResultCache m_WarpingCache; // the document that the user is editing - std::shared_ptr editedDocument = std::make_shared(); + std::shared_ptr m_UndoableTPSDocument = std::make_shared(); // `true` if the user wants the cameras to be linked - bool linkCameras = true; + bool m_LinkCameras = true; // `true` if `LinkCameras` should only link the rotational parts of the cameras - bool onlyLinkRotation = false; + bool m_OnlyLinkRotation = false; // shared linked camera - PolarPerspectiveCamera linkedCameraBase = create_camera_focused_on(editedDocument->scratch().sourceMesh.bounds()); + PolarPerspectiveCamera m_LinkedCameraBase = create_camera_focused_on(m_UndoableTPSDocument->scratch().sourceMesh.bounds()); + + // shared scene cache, to minimize rendering effort when redrawing + std::shared_ptr m_SceneCache; // wireframe material, used to draw scene elements in a wireframe style - MeshBasicMaterial wireframe_material = App::singleton(App::resource_loader())->wireframe_material(); + MeshBasicMaterial m_WireframeMaterial = m_SceneCache->wireframe_material(); - // shared sphere mesh (used by rendering code) - Mesh landmarkSphere = App::singleton(App::resource_loader())->sphere_mesh(); + // cached sphere mesh (to prevent re-generating a sphere over and over) + Mesh m_LandmarkSphere = m_SceneCache->sphere_mesh(); // current user selection - MeshWaringTabUserSelection userSelection; + MeshWaringTabUserSelection m_UserSelection; // current user hover: reset per-frame - std::optional currentHover; + std::optional m_CurrentHover; // currently active tab-wide popups - PopupManager popupManager; - - // shared mesh cache - std::shared_ptr meshCache = App::singleton(App::resource_loader()); - - Vec2 overlayPadding = {10.0f, 10.0f}; - Color pairedLandmarkColor = Color::green(); - Color unpairedLandmarkColor = Color::red(); - Color nonParticipatingLandmarkColor = Color::purple(); + PopupManager m_PopupManager; }; } diff --git a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabStatusBar.h b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabStatusBar.h index 41a4820bd..129392496 100644 --- a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabStatusBar.h +++ b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabStatusBar.h @@ -38,12 +38,10 @@ namespace osc private: void drawContent() { - if (m_State->currentHover) - { - drawCurrentHoverInfo(*m_State->currentHover); + if (m_State->isHoveringSomething()) { + drawCurrentHoverInfo(m_State->getCurrentHover()); } - else - { + else { ui::draw_text_disabled("(nothing hovered)"); } } diff --git a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabToolbar.cpp b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabToolbar.cpp index f5138f2cc..965e5acbf 100644 --- a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabToolbar.cpp +++ b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabToolbar.cpp @@ -107,21 +107,31 @@ class osc::MeshWarpingTabToolbar::Impl final { void drawCameraLockCheckbox() { - ui::draw_checkbox("link cameras", &m_State->linkCameras); + { + bool linked = m_State->isCamerasLinked(); + if (ui::draw_checkbox("link cameras", &linked)) { + m_State->setCamerasLinked(linked); + } + } ui::same_line(); - if (not m_State->linkCameras) { + if (not m_State->isCamerasLinked()) { ui::begin_disabled(); } - ui::draw_checkbox("only link rotation", &m_State->onlyLinkRotation); - if (not m_State->linkCameras) { + { + bool linkRotation = m_State->isOnlyCameraRotationLinked(); + if (ui::draw_checkbox("only link rotation", &linkRotation)) { + m_State->setOnlyCameraRotationLinked(linkRotation); + } + } + if (not m_State->isCamerasLinked()) { ui::end_disabled(); } } std::string m_Label; std::shared_ptr m_State; - UndoButton m_UndoButton{m_State->editedDocument}; - RedoButton m_RedoButton{m_State->editedDocument}; + UndoButton m_UndoButton{m_State->getUndoableSharedPtr()}; + RedoButton m_RedoButton{m_State->getUndoableSharedPtr()}; }; osc::MeshWarpingTabToolbar::MeshWarpingTabToolbar( diff --git a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabToolbar.h b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabToolbar.h index 1dbf90eb9..f7151ad16 100644 --- a/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabToolbar.h +++ b/src/OpenSimCreator/UI/MeshWarper/MeshWarpingTabToolbar.h @@ -3,7 +3,7 @@ #include #include -namespace osc { struct MeshWarpingTabSharedState; } +namespace osc { class MeshWarpingTabSharedState; } namespace osc {