Skip to content

Commit

Permalink
Touchpad-friently 3d navigation (#4598)
Browse files Browse the repository at this point in the history
* gui: camera navigation style option

Add camera navigation style config option as a preparation for
introduction of touchpad style navigation

* gui: touchpa-friently 3d navigation

Implement FreeCAD-inspired touchpad-friendly camera operation mode:
- Shift+move: panning
- Alt+move: rotation

Set "Camera mode" to "Touchpad" in settings menu to activate this mode.

* cache current navigation style in class member variable

Cache current navigation style on canvas focus, do not
request settings value each mouse event.

* force focuse 3d preview on preferences window close

Explicitly force focus 3D preview pane on closing preferences window.
This allows preferences be updated only once without checking current
value each input event.
Another benefit is to have 3D view in focus is that user could
immediatelly use 3d-view shortcuts like Ctrl+<1..7> without clicking to
the 3D view first.
  • Loading branch information
buzzhuzz authored Apr 4, 2024
1 parent 1dc9caf commit 9d81245
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/libslic3r/AppConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ void AppConfig::set_defaults()
if (get("use_free_camera").empty())
set_bool("use_free_camera", false);

if (get("camera_navigation_style").empty())
set("camera_navigation_style", "0");

#ifdef SUPPORT_REVERSE_MOUSE_ZOOM
if (get("reverse_mouse_wheel_zoom").empty())
set_bool("reverse_mouse_wheel_zoom", false);
Expand Down
34 changes: 29 additions & 5 deletions src/slic3r/GUI/GLCanvas3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed)
, m_multisample_allowed(false)
, m_moving(false)
, m_tab_down(false)
, m_camera_movement(false)
, m_cursor_type(Standard)
, m_color_by("volume")
, m_reload_delayed(false)
Expand Down Expand Up @@ -3853,7 +3854,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_mouse.ignore_left_up = true;
m_tooltip.set_in_imgui(false);
if (imgui->update_mouse_data(evt)) {
if (evt.LeftDown() && m_canvas != nullptr)
if ((evt.LeftDown() || (evt.Moving() && (evt.AltDown() || evt.ShiftDown()))) && m_canvas != nullptr)
m_canvas->SetFocus();
m_mouse.position = evt.Leaving() ? Vec2d(-1.0, -1.0) : pos.cast<double>();
m_tooltip.set_in_imgui(true);
Expand Down Expand Up @@ -4172,7 +4173,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_dirty = true;
}
}
else if (evt.Dragging()) {
else if (evt.Dragging() || is_camera_rotate(evt) || is_camera_pan(evt)) {
m_mouse.dragging = true;

if (m_layers_editing.state != LayersEditing::Unknown && layer_editing_object_idx != -1) {
Expand All @@ -4182,7 +4183,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
}
// do not process the dragging if the left mouse was set down in another canvas
else if (evt.LeftIsDown()) {
else if (is_camera_rotate(evt)) {
// Orca: Sphere rotation for painting view
// if dragging over blank area with left button, rotate
if ((any_gizmo_active || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) {
Expand Down Expand Up @@ -4244,9 +4245,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)

m_dirty = true;
}
m_camera_movement = true;
m_mouse.drag.start_position_3D = Vec3d((double)pos(0), (double)pos(1), 0.0);
}
else if (evt.MiddleIsDown() || evt.RightIsDown()) {
else if (is_camera_pan(evt)) {
// If dragging over blank area with right button, pan.
if (m_mouse.is_start_position_2D_defined()) {
// get point in model space at Z = 0
Expand All @@ -4268,10 +4270,12 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_mouse.ignore_right_up = true;
}

m_camera_movement = true;
m_mouse.drag.start_position_2D = pos;
}
}
else if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) {
else if ((evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) ||
(m_camera_movement && !is_camera_rotate(evt) && !is_camera_pan(evt))) {
m_mouse.position = pos.cast<double>();

if (evt.LeftUp()) {
Expand Down Expand Up @@ -4450,6 +4454,25 @@ void GLCanvas3D::on_set_focus(wxFocusEvent& evt)
}
_refresh_if_shown_on_screen();
m_tooltip_enabled = true;
m_is_touchpad_navigation = wxGetApp().app_config->get_bool("camera_navigation_style");
}

bool GLCanvas3D::is_camera_rotate(const wxMouseEvent& evt) const
{
if (m_is_touchpad_navigation) {
return evt.Moving() && evt.AltDown() && !evt.ShiftDown();
} else {
return evt.Dragging() && evt.LeftIsDown();
}
}

bool GLCanvas3D::is_camera_pan(const wxMouseEvent& evt) const
{
if (m_is_touchpad_navigation) {
return evt.Moving() && evt.ShiftDown() && !evt.AltDown();
} else {
return evt.Dragging() && (evt.MiddleIsDown() || evt.RightIsDown());
}
}

Size GLCanvas3D::get_canvas_size() const
Expand Down Expand Up @@ -5052,6 +5075,7 @@ void GLCanvas3D::export_toolpaths_to_obj(const char* filename) const
void GLCanvas3D::mouse_up_cleanup()
{
m_moving = false;
m_camera_movement = false;
m_mouse.drag.move_volume_idx = -1;
m_mouse.set_start_position_3D_as_invalid();
m_mouse.set_start_position_2D_as_invalid();
Expand Down
6 changes: 6 additions & 0 deletions src/slic3r/GUI/GLCanvas3D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,8 @@ class GLCanvas3D

std::array<unsigned int, 2> m_old_size{ 0, 0 };

bool m_is_touchpad_navigation{ false };

// Screen is only refreshed from the OnIdle handler if it is dirty.
bool m_dirty;
bool m_initialized;
Expand All @@ -564,6 +566,7 @@ class GLCanvas3D
bool m_multisample_allowed;
bool m_moving;
bool m_tab_down;
bool m_camera_movement;
//BBS: add toolpath outside
bool m_toolpath_outside{ false };
ECursorType m_cursor_type;
Expand Down Expand Up @@ -963,6 +966,9 @@ class GLCanvas3D
void on_set_focus(wxFocusEvent& evt);
void force_set_focus();

bool is_camera_rotate(const wxMouseEvent& evt) const;
bool is_camera_pan(const wxMouseEvent& evt) const;

Size get_canvas_size() const;
Vec2d get_local_mouse_position() const;

Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/GUI_App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5275,6 +5275,7 @@ void GUI_App::open_preferences(size_t open_on_tab, const std::string& highlight_
// so we put it into an inner scope
PreferencesDialog dlg(mainframe, open_on_tab, highlight_option);
dlg.ShowModal();
this->plater_->get_current_canvas3D()->force_set_focus();
// BBS
//app_layout_changed = dlg.settings_layout_changed();
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
Expand Down
3 changes: 3 additions & 0 deletions src/slic3r/GUI/MainFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
{
PreferencesDialog dlg(this);
dlg.ShowModal();
plater()->get_current_canvas3D()->force_set_focus();
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
#else
Expand Down Expand Up @@ -2703,6 +2704,7 @@ void MainFrame::init_menubar_as_editor()
[this](wxCommandEvent &) {
PreferencesDialog dlg(this);
dlg.ShowModal();
plater()->get_current_canvas3D()->force_set_focus();
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
#else
Expand All @@ -2729,6 +2731,7 @@ void MainFrame::init_menubar_as_editor()
[this](wxCommandEvent &) {
PreferencesDialog dlg(this);
dlg.ShowModal();
plater()->get_current_canvas3D()->force_set_focus();
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
#else
Expand Down
4 changes: 4 additions & 0 deletions src/slic3r/GUI/Preferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,9 @@ wxWindow* PreferencesDialog::create_general_page()
std::vector<wxString> DefaultPage = {_L("Home"), _L("Prepare")};
auto item_default_page = create_item_combobox(_L("Default Page"), page, _L("Set the page opened on startup."), "default_page", DefaultPage);

std::vector<wxString> CameraNavStyle = {_L("Default"), _L("Touchpad")};
auto item_camera_navigation_style = create_item_combobox(_L("Camera style"), page, _L("Select camera navigation style.\nDefault: LMB+move for rotation, RMB/MMB+move for panning.\nTouchpad: Alt+move for rotation, Shift+move for panning."), "camera_navigation_style", CameraNavStyle);

auto item_mouse_zoom_settings = create_item_checkbox(_L("Zoom to mouse position"), page, _L("Zoom in towards the mouse pointer's position in the 3D view, rather than the 2D window center."), 50, "zoom_to_mouse");
auto item_use_free_camera_settings = create_item_checkbox(_L("Use free camera"), page, _L("If enabled, use free camera. If not enabled, use constrained camera."), 50, "use_free_camera");

Expand Down Expand Up @@ -1083,6 +1086,7 @@ wxWindow* PreferencesDialog::create_general_page()
sizer_page->Add(item_region, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_currency, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_default_page, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_camera_navigation_style, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_mouse_zoom_settings, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_use_free_camera_settings, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_show_splash_screen, 0, wxTOP, FromDIP(3));
Expand Down

0 comments on commit 9d81245

Please sign in to comment.