mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-29 13:52:07 +00:00
Compare commits
1 Commits
nightly-bu
...
feature/in
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b09c512d7 |
@@ -233,6 +233,9 @@ void AppConfig::set_defaults()
|
||||
if (get("reverse_mouse_wheel_zoom").empty())
|
||||
set_bool("reverse_mouse_wheel_zoom", false);
|
||||
|
||||
if (get("infinite_camera_drag").empty())
|
||||
set_bool("infinite_camera_drag", false);
|
||||
|
||||
if (get("enable_append_color_by_sync_ams").empty())
|
||||
set_bool("enable_append_color_by_sync_ams", true);
|
||||
if (get("enable_merge_color_by_sync_ams").empty())
|
||||
|
||||
@@ -4535,6 +4535,16 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
else if (evt.Dragging() || is_camera_rotate(evt, button_mappings) || is_camera_pan(evt, button_mappings)) {
|
||||
m_mouse.dragging = true;
|
||||
|
||||
// Orca: this event reports the position the pointer was teleported to by the infinite
|
||||
// camera drag. Restart the drag from there, so the jump is not turned into a camera
|
||||
// movement. Dropping the origin also keeps the drag consistent on platforms which
|
||||
// silently ignore the warp request (Wayland), where the pointer never actually moved.
|
||||
if (m_mouse.drag.pointer_wrapped) {
|
||||
m_mouse.drag.pointer_wrapped = false;
|
||||
m_mouse.set_start_position_2D_as_invalid();
|
||||
m_mouse.set_start_position_3D_as_invalid();
|
||||
}
|
||||
|
||||
if (m_layers_editing.state != LayersEditing::Unknown && layer_editing_object_idx != -1) {
|
||||
if (m_layers_editing.state == LayersEditing::Editing) {
|
||||
_perform_layer_editing_action(&evt);
|
||||
@@ -4616,6 +4626,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
camera.auto_type(Camera::EType::Perspective);
|
||||
m_dirty = true;
|
||||
m_mouse.ignore_right_up = true; // will be reset on button up event even if not right button is pressed
|
||||
_wrap_mouse_pointer_on_canvas_border(pos);
|
||||
}
|
||||
|
||||
m_camera_movement = true;
|
||||
@@ -4642,6 +4653,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
camera.set_target(camera.get_target() + orig - cur_pos);
|
||||
m_dirty = true;
|
||||
m_mouse.ignore_right_up = true; // will be reset on button up event even if not right button is pressed
|
||||
_wrap_mouse_pointer_on_canvas_border(pos);
|
||||
}
|
||||
|
||||
m_camera_movement = true;
|
||||
@@ -5529,6 +5541,7 @@ void GLCanvas3D::mouse_up_cleanup()
|
||||
m_moving = false;
|
||||
m_camera_movement = false;
|
||||
m_mouse.drag.move_volume_idx = -1;
|
||||
m_mouse.drag.pointer_wrapped = false;
|
||||
m_mouse.set_start_position_3D_as_invalid();
|
||||
m_mouse.set_start_position_2D_as_invalid();
|
||||
m_mouse.dragging = false;
|
||||
@@ -10226,6 +10239,47 @@ Vec3d GLCanvas3D::_mouse_to_bed_3d(const Point& mouse_pos)
|
||||
return mouse_ray(mouse_pos).intersect_plane(0.0);
|
||||
}
|
||||
|
||||
// Orca: Blender-like infinite camera drag. Once a pan/orbit drag reaches a canvas border the
|
||||
// pointer is teleported to the opposite one, so that the movement is only limited by how long
|
||||
// the user keeps dragging and not by the window (or screen) bounds.
|
||||
// The drag is flagged instead of being offset by the jump, because the warp request is not
|
||||
// honoured everywhere - Wayland compositors ignore it, in which case the pointer stays at the
|
||||
// border and the drag simply stops there, exactly as it does with this feature disabled.
|
||||
void GLCanvas3D::_wrap_mouse_pointer_on_canvas_border(const Point& mouse_pos)
|
||||
{
|
||||
if (m_canvas == nullptr || !wxGetApp().app_config->get_bool("infinite_camera_drag"))
|
||||
return;
|
||||
|
||||
const Size cnv_size = get_canvas_size();
|
||||
|
||||
auto wrapped_coord = [](int coord, int size) {
|
||||
// The pointer is teleported once it comes this close to a border and lands the same
|
||||
// distance away from the opposite one, so that it never wraps back on the next event.
|
||||
// The margin is proportional to the canvas because the pointer can travel a lot between
|
||||
// two motion events of a fast drag, and the border would be missed if it were too thin.
|
||||
const int border = std::clamp(size / 32, 12, 48);
|
||||
const int span = size - 2 * border;
|
||||
// Nothing to wrap into if the canvas is smaller than the two margins.
|
||||
if (span <= 0 || (coord >= border && coord <= size - border))
|
||||
return coord;
|
||||
// Clamping matters when the pointer is reported far outside of the canvas.
|
||||
return std::clamp(coord + (coord < border ? span : -span), border, size - border);
|
||||
};
|
||||
|
||||
const Point wrapped(wrapped_coord(static_cast<int>(mouse_pos.x()), cnv_size.get_width()),
|
||||
wrapped_coord(static_cast<int>(mouse_pos.y()), cnv_size.get_height()));
|
||||
if (wrapped == mouse_pos)
|
||||
return;
|
||||
|
||||
Vec2d logical_pos = wrapped.cast<double>();
|
||||
#if ENABLE_RETINA_GL
|
||||
const double factor = m_retina_helper->get_scale_factor();
|
||||
logical_pos /= factor;
|
||||
#endif // ENABLE_RETINA_GL
|
||||
m_canvas->WarpPointer(static_cast<int>(std::lround(logical_pos.x())), static_cast<int>(std::lround(logical_pos.y())));
|
||||
m_mouse.drag.pointer_wrapped = true;
|
||||
}
|
||||
|
||||
// While it looks like we can call
|
||||
// this->reload_scene(true, true)
|
||||
// the two functions are quite different:
|
||||
|
||||
@@ -333,6 +333,9 @@ class GLCanvas3D
|
||||
int move_volume_idx{ -1 };
|
||||
bool move_requires_threshold{ false };
|
||||
Point move_start_threshold_position_2D{ Invalid_2D_Point };
|
||||
// Orca: set when the pointer has been teleported to the opposite canvas border
|
||||
// by the infinite camera drag, see GLCanvas3D::_wrap_mouse_pointer_on_canvas_border()
|
||||
bool pointer_wrapped{ false };
|
||||
};
|
||||
|
||||
bool dragging{ false };
|
||||
@@ -1221,6 +1224,10 @@ public:
|
||||
private:
|
||||
bool _is_shown_on_screen() const;
|
||||
|
||||
// Orca: teleports the pointer to the opposite canvas border when a camera drag reaches
|
||||
// one, so that panning/orbiting is not limited by the window bounds.
|
||||
void _wrap_mouse_pointer_on_canvas_border(const Point& mouse_pos);
|
||||
|
||||
void _update_slice_error_status();
|
||||
|
||||
void _switch_toolbars_icon_filename();
|
||||
|
||||
@@ -1785,6 +1785,9 @@ void PreferencesDialog::create_items()
|
||||
auto reverse_mouse_zoom = create_item_checkbox(_L("Reverse mouse zoom"), _L("If enabled, reverses the direction of zoom with mouse wheel."), "reverse_mouse_wheel_zoom");
|
||||
g_sizer->Add(reverse_mouse_zoom);
|
||||
|
||||
auto item_infinite_camera_drag = create_item_checkbox(_L("Infinite camera drag"), _L("If enabled, the mouse pointer is teleported to the opposite side of the 3D view when it reaches a border while panning or orbiting, so camera movement is not limited by the window bounds."), "infinite_camera_drag");
|
||||
g_sizer->Add(item_infinite_camera_drag);
|
||||
|
||||
std::vector<wxString> ButtonDragActions = {_L("None"), _L("Pan"), _L("Rotate")};
|
||||
auto item_left_mouse_drag = create_item_combobox(_L("Left Mouse Drag"), _L("Set the action that dragging the left mouse button should perform."), "left_mouse_drag_action", ButtonDragActions);
|
||||
g_sizer->Add(item_left_mouse_drag);
|
||||
|
||||
Reference in New Issue
Block a user