mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-19 15:03:05 +00:00
Design: left-drag sweeps a rubber band, and it takes the whole body
The pick cycle died two commits ago and left no viewport route to a whole body at all: one click resolves vertex, edge or face, double-click is already zoom-to-fit, and the only way to take a body was the Bodies list — a geometry-first violation for as long as it stood. The rubber band is that route. Left-drag is the gesture, as asked. That button was orbit, so this canvas now maps the mouse the way every CAD the user already knows does: left selects, middle orbits, right pans. The change is a single flag on GLCanvas3D set only by DesignCanvas, so Prepare and Preview keep the mouse their users learned. Sketch mode inherits the same mapping, which is the consistent reading — Design is one modality, not two. Past an 8 px budget a press becomes a sweep, anchored at the ORIGINAL press point rather than at the frame where the threshold was crossed, so the first few pixels are not lost. Below the budget it is still a click and the existing vertex/edge/face pick runs untouched. Sampling is the display mesh's triangle vertices plus centroids — the same points the ray pick tests, already in world coordinates — and the body with the most samples inside wins, because the selection callback downstream carries one body. Crossing semantics: touching selects. Enclosed-only for left-to-right and crossing for right-to-left is the fuller CAD convention and is deferred, not forgotten; with one selectable body it would have bought nothing. Two defects fixed on the way, both found by exercising this: Right-drag pans, and every pan ended by popping the offer over wherever the camera stopped — the context menu arriving as the reward for moving the view. The offer is now the release of a STATIONARY right-click, at the same 8 px budget the pick uses. The selection handler wrote m_status twice. Only the later write ever reached the screen, so the earlier block had been dead since it was written, and its labels drifted out of step with the live ones unnoticed — including a vertex fix I made this morning in the branch that never renders. Deleted, with a note saying why, rather than left as two writers for the next person to pick the wrong one. Verified on :11 against a fresh build: click takes face 5; left-drag across the body reports "selected (whole body)" with the whole solid tinted and the camera unmoved; left-drag over empty space clears; stationary right-click opens the offer; right-drag pans with no menu; middle-drag orbits. Precedence re-checked after the deletion — face at 25 px from the corner, vertex from 10 px in. Refs snaporca-9xw. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LyRwbuq6fjn3VV9U9UvhBM
This commit is contained in:
co-authored by
Claude Opus 5
parent
33f97d259b
commit
bb403b82cf
@@ -12,6 +12,8 @@
|
||||
#include "MeshUtils.hpp" // ClippingPlane (section view)
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <wx/glcanvas.h>
|
||||
#include <wx/sizer.h>
|
||||
@@ -43,6 +45,12 @@ DesignCanvas::DesignCanvas(wxWindow* parent)
|
||||
m_canvas->set_process(wxGetApp().plater()->get_background_process());
|
||||
m_canvas->set_type(GLCanvas3D::ECanvasType::CanvasView3D);
|
||||
|
||||
// CAD navigation, this canvas only: left-drag sweeps a selection rubber band, so orbit
|
||||
// moves to middle-drag and pan to right-drag. Design is a different modality from
|
||||
// Prepare/Preview and every CAD the user already knows maps the mouse this way; the other
|
||||
// tabs are untouched.
|
||||
m_canvas->set_cad_navigation(true);
|
||||
|
||||
m_canvas->enable_picking(false); // viewport face/edge picking is custom (TODO)
|
||||
m_canvas->enable_moving(false);
|
||||
m_canvas->enable_gizmos(false);
|
||||
@@ -798,8 +806,18 @@ void DesignCanvas::set_on_context_menu(std::function<void(const wxPoint&)> cb)
|
||||
// Bound AFTER GLCanvas3D's own handlers, so this runs first and can consume the event.
|
||||
// It only consumes when it actually opens the offer; every other right-click still falls
|
||||
// through to the polyline-chain end and the move gizmo, which were there first.
|
||||
// Right-drag pans. Without remembering where the press landed, every pan ended by popping
|
||||
// the offer over wherever the camera stopped — the menu appearing as the reward for moving
|
||||
// the view. The offer is the release of a STATIONARY right-click, at the same 8 px budget
|
||||
// the left-click pick uses.
|
||||
m_canvas_widget->Bind(wxEVT_RIGHT_DOWN, [this](wxMouseEvent& e) {
|
||||
m_ctx_press = e.GetPosition();
|
||||
e.Skip(); // the canvas still needs the press to seed the pan
|
||||
});
|
||||
m_canvas_widget->Bind(wxEVT_RIGHT_UP, [this](wxMouseEvent& e) {
|
||||
if (m_on_context_menu && !is_sketching() && !inline_busy()) {
|
||||
const wxPoint d = e.GetPosition() - m_ctx_press;
|
||||
if (m_on_context_menu && !is_sketching() && !inline_busy()
|
||||
&& std::max(std::abs(d.x), std::abs(d.y)) <= 8) {
|
||||
m_on_context_menu(m_canvas_widget->ClientToScreen(e.GetPosition()));
|
||||
return; // consumed
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user