mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 16:57:53 -06:00
Rotating/panning the view, using mouse left/right + CTRL modifier, while any gizmo is active
This commit is contained in:
parent
0f8f412e90
commit
68a7e5ce41
3 changed files with 131 additions and 134 deletions
|
@ -3505,40 +3505,35 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
#endif /* SLIC3R_DEBUG_MOUSE_EVENTS */
|
||||
}
|
||||
|
||||
if (m_main_toolbar.on_mouse(evt, *this))
|
||||
{
|
||||
if (m_main_toolbar.on_mouse(evt, *this)) {
|
||||
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
|
||||
mouse_up_cleanup();
|
||||
m_mouse.set_start_position_3D_as_invalid();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_undoredo_toolbar.on_mouse(evt, *this))
|
||||
{
|
||||
if (m_undoredo_toolbar.on_mouse(evt, *this)) {
|
||||
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
|
||||
mouse_up_cleanup();
|
||||
m_mouse.set_start_position_3D_as_invalid();
|
||||
return;
|
||||
}
|
||||
|
||||
if (wxGetApp().plater()->get_collapse_toolbar().on_mouse(evt, *this))
|
||||
{
|
||||
if (wxGetApp().plater()->get_collapse_toolbar().on_mouse(evt, *this)) {
|
||||
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
|
||||
mouse_up_cleanup();
|
||||
m_mouse.set_start_position_3D_as_invalid();
|
||||
return;
|
||||
}
|
||||
|
||||
if (wxGetApp().plater()->get_view_toolbar().on_mouse(evt, *this))
|
||||
{
|
||||
if (wxGetApp().plater()->get_view_toolbar().on_mouse(evt, *this)) {
|
||||
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
|
||||
mouse_up_cleanup();
|
||||
m_mouse.set_start_position_3D_as_invalid();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_gizmos.on_mouse(evt))
|
||||
{
|
||||
if (m_gizmos.on_mouse(evt)) {
|
||||
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
|
||||
mouse_up_cleanup();
|
||||
|
||||
|
@ -3547,12 +3542,15 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
return;
|
||||
}
|
||||
|
||||
#if ENABLE_PAN_ROTATE_SCENE_IN_GIZMOS
|
||||
bool any_gizmo_active = m_gizmos.get_current() != nullptr;
|
||||
#endif // ENABLE_PAN_ROTATE_SCENE_IN_GIZMOS
|
||||
|
||||
int selected_object_idx = m_selection.get_object_idx();
|
||||
int layer_editing_object_idx = is_layers_editing_enabled() ? selected_object_idx : -1;
|
||||
m_layers_editing.select_object(*m_model, layer_editing_object_idx);
|
||||
|
||||
if (m_mouse.drag.move_requires_threshold && m_mouse.is_move_start_threshold_position_2D_defined() && m_mouse.is_move_threshold_met(pos))
|
||||
{
|
||||
if (m_mouse.drag.move_requires_threshold && m_mouse.is_move_start_threshold_position_2D_defined() && m_mouse.is_move_threshold_met(pos)) {
|
||||
m_mouse.drag.move_requires_threshold = false;
|
||||
m_mouse.set_move_start_threshold_position_2D_as_invalid();
|
||||
}
|
||||
|
@ -3561,8 +3559,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
// Grab keyboard focus on any mouse click event.
|
||||
m_canvas->SetFocus();
|
||||
|
||||
if (evt.Entering())
|
||||
{
|
||||
if (evt.Entering()) {
|
||||
//#if defined(__WXMSW__) || defined(__linux__)
|
||||
// // On Windows and Linux needs focus in order to catch key events
|
||||
// Set focus in order to remove it from sidebar fields
|
||||
|
@ -3587,49 +3584,49 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
m_mouse.set_start_position_2D_as_invalid();
|
||||
//#endif
|
||||
}
|
||||
else if (evt.Leaving())
|
||||
{
|
||||
else if (evt.Leaving()) {
|
||||
_deactivate_undo_redo_toolbar_items();
|
||||
|
||||
// to remove hover on objects when the mouse goes out of this canvas
|
||||
m_mouse.position = Vec2d(-1.0, -1.0);
|
||||
m_dirty = true;
|
||||
}
|
||||
else if (evt.LeftDown() || evt.RightDown() || evt.MiddleDown())
|
||||
{
|
||||
else if (evt.LeftDown() || evt.RightDown() || evt.MiddleDown()) {
|
||||
if (_deactivate_undo_redo_toolbar_items() || _deactivate_search_toolbar_item())
|
||||
return;
|
||||
|
||||
// If user pressed left or right button we first check whether this happened
|
||||
// on a volume or not.
|
||||
m_layers_editing.state = LayersEditing::Unknown;
|
||||
if ((layer_editing_object_idx != -1) && m_layers_editing.bar_rect_contains(*this, pos(0), pos(1)))
|
||||
{
|
||||
if (layer_editing_object_idx != -1 && m_layers_editing.bar_rect_contains(*this, pos(0), pos(1))) {
|
||||
// A volume is selected and the mouse is inside the layer thickness bar.
|
||||
// Start editing the layer height.
|
||||
m_layers_editing.state = LayersEditing::Editing;
|
||||
_perform_layer_editing_action(&evt);
|
||||
}
|
||||
else if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled)
|
||||
{
|
||||
else if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) {
|
||||
if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports
|
||||
&& m_gizmos.get_current_type() != GLGizmosManager::FdmSupports
|
||||
&& m_gizmos.get_current_type() != GLGizmosManager::Seam)
|
||||
{
|
||||
&& m_gizmos.get_current_type() != GLGizmosManager::Seam) {
|
||||
m_rectangle_selection.start_dragging(m_mouse.position, evt.ShiftDown() ? GLSelectionRectangle::Select : GLSelectionRectangle::Deselect);
|
||||
m_dirty = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
#if ENABLE_PAN_ROTATE_SCENE_IN_GIZMOS
|
||||
// Select volume in this 3D canvas.
|
||||
// Don't deselect a volume if layer editing is enabled or any gizmo is active. We want the object to stay selected
|
||||
// during the scene manipulation.
|
||||
|
||||
if (m_picking_enabled && !any_gizmo_active && (!m_hover_volume_idxs.empty() || !is_layers_editing_enabled())) {
|
||||
#else
|
||||
// Select volume in this 3D canvas.
|
||||
// Don't deselect a volume if layer editing is enabled. We want the object to stay selected
|
||||
// during the scene manipulation.
|
||||
|
||||
if (m_picking_enabled && (!m_hover_volume_idxs.empty() || !is_layers_editing_enabled()))
|
||||
{
|
||||
if (evt.LeftDown() && !m_hover_volume_idxs.empty())
|
||||
{
|
||||
if (m_picking_enabled && (!m_hover_volume_idxs.empty() || !is_layers_editing_enabled())) {
|
||||
#endif // ENABLE_PAN_ROTATE_SCENE_IN_GIZMOS
|
||||
if (evt.LeftDown() && !m_hover_volume_idxs.empty()) {
|
||||
int volume_idx = get_first_hover_volume_idx();
|
||||
bool already_selected = m_selection.contains_volume(volume_idx);
|
||||
bool ctrl_down = evt.CmdDown();
|
||||
|
@ -3638,8 +3635,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
|
||||
if (already_selected && ctrl_down)
|
||||
m_selection.remove(volume_idx);
|
||||
else
|
||||
{
|
||||
else {
|
||||
m_selection.add(volume_idx, !ctrl_down, true);
|
||||
m_mouse.drag.move_requires_threshold = !already_selected;
|
||||
if (already_selected)
|
||||
|
@ -3649,8 +3645,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
|
||||
// propagate event through callback
|
||||
if (curr_idxs != m_selection.get_volume_idxs())
|
||||
{
|
||||
if (curr_idxs != m_selection.get_volume_idxs()) {
|
||||
if (m_selection.is_empty())
|
||||
m_gizmos.reset_all_states();
|
||||
else
|
||||
|
@ -3663,16 +3658,17 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
}
|
||||
|
||||
if (!m_hover_volume_idxs.empty())
|
||||
{
|
||||
if (evt.LeftDown() && m_moving_enabled && (m_mouse.drag.move_volume_idx == -1))
|
||||
{
|
||||
if (!m_hover_volume_idxs.empty()) {
|
||||
if (evt.LeftDown() && m_moving_enabled && m_mouse.drag.move_volume_idx == -1) {
|
||||
// Only accept the initial position, if it is inside the volume bounding box.
|
||||
int volume_idx = get_first_hover_volume_idx();
|
||||
BoundingBoxf3 volume_bbox = m_volumes.volumes[volume_idx]->transformed_bounding_box();
|
||||
volume_bbox.offset(1.0);
|
||||
if (volume_bbox.contains(m_mouse.scene_position))
|
||||
{
|
||||
#if ENABLE_PAN_ROTATE_SCENE_IN_GIZMOS
|
||||
if (!any_gizmo_active && volume_bbox.contains(m_mouse.scene_position)) {
|
||||
#else
|
||||
if (volume_bbox.contains(m_mouse.scene_position)) {
|
||||
#endif // ENABLE_PAN_ROTATE_SCENE_IN_GIZMOS
|
||||
m_volumes.volumes[volume_idx]->hover = GLVolume::HS_None;
|
||||
// The dragging operation is initiated.
|
||||
m_mouse.drag.move_volume_idx = volume_idx;
|
||||
|
@ -3684,18 +3680,14 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (evt.Dragging() && evt.LeftIsDown() && (m_layers_editing.state == LayersEditing::Unknown) && (m_mouse.drag.move_volume_idx != -1))
|
||||
{
|
||||
if (!m_mouse.drag.move_requires_threshold)
|
||||
{
|
||||
else if (evt.Dragging() && evt.LeftIsDown() && m_layers_editing.state == LayersEditing::Unknown && m_mouse.drag.move_volume_idx != -1) {
|
||||
if (!m_mouse.drag.move_requires_threshold) {
|
||||
m_mouse.dragging = true;
|
||||
Vec3d cur_pos = m_mouse.drag.start_position_3D;
|
||||
// we do not want to translate objects if the user just clicked on an object while pressing shift to remove it from the selection and then drag
|
||||
if (m_selection.contains_volume(get_first_hover_volume_idx()))
|
||||
{
|
||||
if (m_selection.contains_volume(get_first_hover_volume_idx())) {
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
if (std::abs(camera.get_dir_forward()(2)) < EPSILON)
|
||||
{
|
||||
if (std::abs(camera.get_dir_forward()(2)) < EPSILON) {
|
||||
// side view -> move selected volumes orthogonally to camera view direction
|
||||
Linef3 ray = mouse_ray(pos);
|
||||
Vec3d dir = ray.unit_vector();
|
||||
|
@ -3717,8 +3709,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
// apply offset
|
||||
cur_pos = m_mouse.drag.start_position_3D + projection_x * camera_right + projection_z * camera_up;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// Generic view
|
||||
// Get new position at the same Z of the initial click point.
|
||||
float z0 = 0.0f;
|
||||
|
@ -3732,35 +3723,32 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
m_dirty = true;
|
||||
}
|
||||
}
|
||||
else if (evt.Dragging() && evt.LeftIsDown() && m_picking_enabled && m_rectangle_selection.is_dragging())
|
||||
{
|
||||
else if (evt.Dragging() && evt.LeftIsDown() && m_picking_enabled && m_rectangle_selection.is_dragging()) {
|
||||
m_rectangle_selection.dragging(pos.cast<double>());
|
||||
m_dirty = true;
|
||||
}
|
||||
else if (evt.Dragging())
|
||||
{
|
||||
else if (evt.Dragging()) {
|
||||
m_mouse.dragging = true;
|
||||
|
||||
if ((m_layers_editing.state != LayersEditing::Unknown) && (layer_editing_object_idx != -1))
|
||||
{
|
||||
if (m_layers_editing.state == LayersEditing::Editing)
|
||||
{
|
||||
if (m_layers_editing.state != LayersEditing::Unknown && layer_editing_object_idx != -1) {
|
||||
if (m_layers_editing.state == LayersEditing::Editing) {
|
||||
_perform_layer_editing_action(&evt);
|
||||
m_mouse.position = pos.cast<double>();
|
||||
}
|
||||
}
|
||||
// do not process the dragging if the left mouse was set down in another canvas
|
||||
else if (evt.LeftIsDown())
|
||||
{
|
||||
else if (evt.LeftIsDown()) {
|
||||
// if dragging over blank area with left button, rotate
|
||||
if (m_hover_volume_idxs.empty() && m_mouse.is_start_position_3D_defined())
|
||||
{
|
||||
#if ENABLE_PAN_ROTATE_SCENE_IN_GIZMOS
|
||||
if ((any_gizmo_active || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) {
|
||||
#else
|
||||
if (m_hover_volume_idxs.empty() && m_mouse.is_start_position_3D_defined()) {
|
||||
#endif // ENABLE_PAN_ROTATE_SCENE_IN_GIZMOS
|
||||
const Vec3d rot = (Vec3d(pos.x(), pos.y(), 0.) - m_mouse.drag.start_position_3D) * (PI * TRACKBALLSIZE / 180.);
|
||||
if (wxGetApp().app_config->get("use_free_camera") == "1")
|
||||
// Virtual track ball (similar to the 3DConnexion mouse).
|
||||
wxGetApp().plater()->get_camera().rotate_local_around_target(Vec3d(rot.y(), rot.x(), 0.));
|
||||
else
|
||||
{
|
||||
else {
|
||||
// Forces camera right vector to be parallel to XY plane in case it has been misaligned using the 3D mouse free rotation.
|
||||
// It is cheaper to call this function right away instead of testing wxGetApp().plater()->get_mouse3d_controller().connected(),
|
||||
// which checks an atomics (flushes CPU caches).
|
||||
|
@ -3774,11 +3762,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
m_mouse.drag.start_position_3D = Vec3d((double)pos(0), (double)pos(1), 0.0);
|
||||
}
|
||||
else if (evt.MiddleIsDown() || evt.RightIsDown())
|
||||
{
|
||||
else if (evt.MiddleIsDown() || evt.RightIsDown()) {
|
||||
// If dragging over blank area with right button, pan.
|
||||
if (m_mouse.is_start_position_2D_defined())
|
||||
{
|
||||
if (m_mouse.is_start_position_2D_defined()) {
|
||||
// get point in model space at Z = 0
|
||||
float z = 0.0f;
|
||||
const Vec3d& cur_pos = _mouse_to_3d(pos, &z);
|
||||
|
@ -3798,43 +3784,36 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
m_mouse.drag.start_position_2D = pos;
|
||||
}
|
||||
}
|
||||
else if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
|
||||
{
|
||||
if (m_layers_editing.state != LayersEditing::Unknown)
|
||||
{
|
||||
else if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) {
|
||||
if (m_layers_editing.state != LayersEditing::Unknown) {
|
||||
m_layers_editing.state = LayersEditing::Unknown;
|
||||
_stop_timer();
|
||||
m_layers_editing.accept_changes(*this);
|
||||
}
|
||||
else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging)
|
||||
{
|
||||
else if (m_mouse.drag.move_volume_idx != -1 && m_mouse.dragging) {
|
||||
do_move(L("Move Object"));
|
||||
wxGetApp().obj_manipul()->set_dirty();
|
||||
// Let the plater know that the dragging finished, so a delayed refresh
|
||||
// of the scene with the background processing data should be performed.
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
|
||||
}
|
||||
else if (evt.LeftUp() && m_picking_enabled && m_rectangle_selection.is_dragging())
|
||||
{
|
||||
else if (evt.LeftUp() && m_picking_enabled && m_rectangle_selection.is_dragging()) {
|
||||
if (evt.ShiftDown() || evt.AltDown())
|
||||
_update_selection_from_hover();
|
||||
|
||||
m_rectangle_selection.stop_dragging();
|
||||
}
|
||||
else if (evt.LeftUp() && !m_mouse.ignore_left_up && !m_mouse.dragging && m_hover_volume_idxs.empty() && !is_layers_editing_enabled())
|
||||
{
|
||||
else if (evt.LeftUp() && !m_mouse.ignore_left_up && !m_mouse.dragging && m_hover_volume_idxs.empty() && !is_layers_editing_enabled()) {
|
||||
// deselect and propagate event through callback
|
||||
if (!evt.ShiftDown() && m_picking_enabled)
|
||||
deselect_all();
|
||||
}
|
||||
else if (evt.RightUp())
|
||||
{
|
||||
else if (evt.RightUp()) {
|
||||
m_mouse.position = pos.cast<double>();
|
||||
// forces a frame render to ensure that m_hover_volume_idxs is updated even when the user right clicks while
|
||||
// the context menu is already shown
|
||||
render();
|
||||
if (!m_hover_volume_idxs.empty())
|
||||
{
|
||||
if (!m_hover_volume_idxs.empty()) {
|
||||
// if right clicking on volume, propagate event through callback (shows context menu)
|
||||
int volume_idx = get_first_hover_volume_idx();
|
||||
if (!m_volumes.volumes[volume_idx]->is_wipe_tower // no context menu for the wipe tower
|
||||
|
@ -3866,8 +3845,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
|
||||
mouse_up_cleanup();
|
||||
}
|
||||
else if (evt.Moving())
|
||||
{
|
||||
else if (evt.Moving()) {
|
||||
m_mouse.position = pos.cast<double>();
|
||||
|
||||
// updates gizmos overlay
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue