mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-19 06:53:02 +00:00
Give the Design tab its own camera view
The Camera is Plater-owned and shared by every canvas, and Design sits outside the panel switch that saves and restores it for Prepare, Preview and Assemble — so orbiting in Design moved what the editor tabs showed, and Design lost its own view on every switch. Trade the live camera for a parked one on the way in and back on the way out, so Design keeps its view the way Assemble already does.
This commit is contained in:
@@ -189,6 +189,15 @@ DesignCanvas::DesignCanvas(wxWindow* parent)
|
||||
|
||||
refresh_bed();
|
||||
|
||||
// The view this canvas opens on. Built lazily, on the way into the Design tab, so this
|
||||
// is the view the user is looking at right now.
|
||||
m_parked_camera = wxGetApp().plater()->get_camera();
|
||||
|
||||
// Before any of this class's own Binds below: wx calls dynamically bound handlers in
|
||||
// reverse order of binding, and GLCanvas3D::on_mouse takes wxEVT_RIGHT_UP / ENTER_WINDOW
|
||||
// without skipping them — so whatever is bound last is the only handler that sees them.
|
||||
// The context menu, the focus-follows-mouse and the status-chip re-anchor all depend on
|
||||
// running first, which is only true while this call stays ahead of them.
|
||||
m_canvas->bind_event_handlers();
|
||||
|
||||
// The Design GL canvas only receives key events (Esc to exit/enter Select, Ctrl+Z undo)
|
||||
@@ -268,6 +277,24 @@ void DesignCanvas::request_repaint()
|
||||
}
|
||||
}
|
||||
|
||||
void DesignCanvas::enter_viewport()
|
||||
{
|
||||
if (!m_camera_swapped) swap_camera();
|
||||
}
|
||||
|
||||
void DesignCanvas::leave_viewport()
|
||||
{
|
||||
if (m_camera_swapped) swap_camera();
|
||||
}
|
||||
|
||||
void DesignCanvas::swap_camera()
|
||||
{
|
||||
Plater* plater = wxGetApp().plater();
|
||||
if (plater == nullptr) return;
|
||||
std::swap(plater->get_camera(), m_parked_camera);
|
||||
m_camera_swapped = !m_camera_swapped;
|
||||
}
|
||||
|
||||
void DesignCanvas::force_repaint()
|
||||
{
|
||||
if (m_canvas == nullptr || m_canvas_widget == nullptr)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "slic3r/GUI/3DBed.hpp"
|
||||
#include "slic3r/GUI/Camera.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/CAD/SketchEngine.hpp"
|
||||
#include "slic3r/GUI/CAD/DesignSketchTool.hpp"
|
||||
@@ -69,6 +70,13 @@ public:
|
||||
void finish_sketch();
|
||||
bool is_sketching() const;
|
||||
void refresh_bed(); // re-sync the bed to the current printer (call on tab activation)
|
||||
// The Camera is Plater-owned and shared with Prepare/Preview/Assemble; GLCanvas3D has no
|
||||
// per-canvas camera, so every orbit here would otherwise overwrite what the editor tabs
|
||||
// show. Exactly one of the two views is live at a time, so entering and leaving are the
|
||||
// same operation: trade the live camera for the parked one. That also keeps this canvas's
|
||||
// own view across a tab switch.
|
||||
void enter_viewport();
|
||||
void leave_viewport();
|
||||
void set_show_bed(bool b); // view option: draw the printer bed + plate grid, or not
|
||||
void cancel_sketch();
|
||||
void set_on_sketch_commit(std::function<void(const SketchProfile&, const SketchPlane&)> cb);
|
||||
@@ -324,6 +332,7 @@ public:
|
||||
|
||||
private:
|
||||
void reload(bool keep_view);
|
||||
void swap_camera(); // enter_viewport / leave_viewport, in the one direction they share
|
||||
|
||||
wxGLCanvas* m_canvas_widget{nullptr};
|
||||
GLCanvas3D* m_canvas{nullptr};
|
||||
@@ -334,6 +343,11 @@ private:
|
||||
wxPoint m_ctx_press{0, 0}; // right-press origin: a right-DRAG pans, it must not offer
|
||||
|
||||
Bed3D m_bed;
|
||||
// The half of the camera swap above that is NOT on screen: the editor tabs' view while
|
||||
// Design is up, this canvas's view while it is not. Seeded in the constructor so the first
|
||||
// entry inherits the view the user was already looking at.
|
||||
Camera m_parked_camera;
|
||||
bool m_camera_swapped{false}; // guards a leave without an enter, and the reverse
|
||||
Model m_model;
|
||||
bool m_first_frame{true};
|
||||
bool m_body_selected{false}; // tree selected a body feature → tint the solid
|
||||
|
||||
@@ -6937,12 +6937,18 @@ wxString DesignPanel::idle_hint() const
|
||||
// Nothing else in the panel needs to know: the popup keeps its text and comes straight back.
|
||||
void DesignPanel::on_tab_hidden()
|
||||
{
|
||||
if (m_viewport) m_viewport->show_status_hud(false);
|
||||
if (m_viewport) {
|
||||
m_viewport->show_status_hud(false);
|
||||
m_viewport->leave_viewport(); // hand the shared camera back to the editor tabs
|
||||
}
|
||||
}
|
||||
|
||||
void DesignPanel::on_tab_shown()
|
||||
{
|
||||
if (m_viewport) m_viewport->show_status_hud(true); // ...and back on the way in
|
||||
if (m_viewport) {
|
||||
m_viewport->show_status_hud(true); // ...and back on the way in
|
||||
m_viewport->enter_viewport(); // borrow the shared camera; on_tab_hidden gives it back
|
||||
}
|
||||
|
||||
if (m_active == Tool::None && m_doc.display_mesh.its.indices.empty())
|
||||
set_status(idle_hint()); // first paint: the tab has never been edited
|
||||
|
||||
Reference in New Issue
Block a user