From 8b200e689cf955c0ff2a4649347f78b91824edaa Mon Sep 17 00:00:00 2001 From: utkabobr Date: Wed, 2 Apr 2025 03:43:49 +0300 Subject: [PATCH] Implement additional alternative camera control method --- .../java/ru/ytkab0bp/slicebeam/SliceBeam.java | 10 ------ .../components/bed_menu/CameraMenu.java | 17 +++++++++- .../ru/ytkab0bp/slicebeam/utils/Prefs.java | 8 ++--- .../ru/ytkab0bp/slicebeam/view/GLView.java | 34 +++++++++++-------- .../res/drawable/hand_point_up_outline_28.xml | 10 ++++++ app/src/main/res/values-ru/strings.xml | 5 ++- app/src/main/res/values/strings.xml | 5 ++- 7 files changed, 58 insertions(+), 31 deletions(-) create mode 100644 app/src/main/res/drawable/hand_point_up_outline_28.xml diff --git a/app/src/main/java/ru/ytkab0bp/slicebeam/SliceBeam.java b/app/src/main/java/ru/ytkab0bp/slicebeam/SliceBeam.java index 20f238d..cd271f0 100644 --- a/app/src/main/java/ru/ytkab0bp/slicebeam/SliceBeam.java +++ b/app/src/main/java/ru/ytkab0bp/slicebeam/SliceBeam.java @@ -4,12 +4,6 @@ import android.annotation.SuppressLint; import android.app.Application; import android.content.Intent; import android.util.Log; -import android.webkit.WebView; - -import com.instacart.library.truetime.TrueTime; - -import org.json.JSONException; -import org.json.JSONObject; import java.io.File; import java.io.FileOutputStream; @@ -32,15 +26,11 @@ import ru.ytkab0bp.slicebeam.boot.PrefsTask; import ru.ytkab0bp.slicebeam.boot.PrintConfigWarmupTask; import ru.ytkab0bp.slicebeam.boot.TrueTimeTask; import ru.ytkab0bp.slicebeam.boot.VibrationUtilsTask; -import ru.ytkab0bp.slicebeam.cloud.CloudController; import ru.ytkab0bp.slicebeam.config.ConfigObject; import ru.ytkab0bp.slicebeam.slic3r.ConfigOptionDef; import ru.ytkab0bp.slicebeam.slic3r.PrintConfigDef; import ru.ytkab0bp.slicebeam.slic3r.Slic3rConfigWrapper; -import ru.ytkab0bp.slicebeam.utils.IOUtils; import ru.ytkab0bp.slicebeam.utils.Prefs; -import ru.ytkab0bp.slicebeam.utils.VibrationUtils; -import ru.ytkab0bp.slicebeam.utils.ViewUtils; public class SliceBeam extends Application { public static SliceBeam INSTANCE; diff --git a/app/src/main/java/ru/ytkab0bp/slicebeam/components/bed_menu/CameraMenu.java b/app/src/main/java/ru/ytkab0bp/slicebeam/components/bed_menu/CameraMenu.java index 4e8c6f6..e14b431 100644 --- a/app/src/main/java/ru/ytkab0bp/slicebeam/components/bed_menu/CameraMenu.java +++ b/app/src/main/java/ru/ytkab0bp/slicebeam/components/bed_menu/CameraMenu.java @@ -1,5 +1,6 @@ package ru.ytkab0bp.slicebeam.components.bed_menu; +import android.content.Context; import android.widget.Toast; import androidx.dynamicanimation.animation.FloatValueHolder; @@ -10,6 +11,7 @@ import java.util.Arrays; import java.util.List; import ru.ytkab0bp.slicebeam.R; +import ru.ytkab0bp.slicebeam.components.BeamAlertDialogBuilder; import ru.ytkab0bp.slicebeam.recycler.SimpleRecyclerItem; import ru.ytkab0bp.slicebeam.recycler.SpaceItem; import ru.ytkab0bp.slicebeam.render.Camera; @@ -122,7 +124,20 @@ public class CameraMenu extends ListBedMenu { animateTo(toOrigin, toPosition); }), new SpaceItem(portrait ? ViewUtils.dp(8) : 0, portrait ? 0 : ViewUtils.dp(8)), - new BedMenuItem(R.string.MenuCameraEnableRotation, R.drawable.sync_outline_28).setCheckable((buttonView, isChecked) -> Prefs.setRotationEnabled(isChecked), Prefs.isRotationEnabled()), + new BedMenuItem(R.string.MenuCameraControlMode, R.drawable.hand_point_up_outline_28).onClick(v -> { + Context ctx = v.getContext(); + new BeamAlertDialogBuilder(v.getContext()) + .setTitle(R.string.MenuCameraControlMode) + .setSingleChoiceItems(new CharSequence[] { + ctx.getString(R.string.MenuCameraControlModeOne), + ctx.getString(R.string.MenuCameraControlModeTwo), + ctx.getString(R.string.MenuCameraControlModeThree) + }, Prefs.getCameraControlMode(), (dialog, which) -> { + Prefs.setCameraControlMode(which); + dialog.dismiss(); + }) + .show(); + }), new BedMenuItem(R.string.MenuCameraOrtho, R.drawable.image_format_32).setCheckable((buttonView, isChecked) -> { Prefs.setOrthoProjectionEnabled(isChecked); fragment.getGlView().getRenderer().updateProjection(); diff --git a/app/src/main/java/ru/ytkab0bp/slicebeam/utils/Prefs.java b/app/src/main/java/ru/ytkab0bp/slicebeam/utils/Prefs.java index 26afc55..64bb7d5 100644 --- a/app/src/main/java/ru/ytkab0bp/slicebeam/utils/Prefs.java +++ b/app/src/main/java/ru/ytkab0bp/slicebeam/utils/Prefs.java @@ -68,12 +68,12 @@ public class Prefs { return mPrefs.getString("beam_server_data", "{}"); } - public static boolean isRotationEnabled() { - return mPrefs.getBoolean("rotation_enabled", true); + public static int getCameraControlMode() { + return mPrefs.getInt("camera_control_mode", mPrefs.getBoolean("rotation_enabled", true) ? CAMERA_CONTROL_MODE_ROTATE_MOVE : CAMERA_CONTROL_MODE_MOVE_ONLY); } - public static void setRotationEnabled(boolean e) { - mPrefs.edit().putBoolean("rotation_enabled", e).apply(); + public static void setCameraControlMode(int mode) { + mPrefs.edit().putInt("camera_control_mode", mode).apply(); } public static boolean isOrthoProjectionEnabled() { diff --git a/app/src/main/java/ru/ytkab0bp/slicebeam/view/GLView.java b/app/src/main/java/ru/ytkab0bp/slicebeam/view/GLView.java index 2cee5bd..ae6fdc7 100644 --- a/app/src/main/java/ru/ytkab0bp/slicebeam/view/GLView.java +++ b/app/src/main/java/ru/ytkab0bp/slicebeam/view/GLView.java @@ -38,8 +38,8 @@ public class GLView extends GLSurfaceView implements IThemeView { private int touchSlop; private boolean fromTwoPointers; - private boolean isRotating; - private boolean isMoving; + private boolean onePointerGesture; + private boolean twoPointerGesture; private boolean isScaling; private long lastActionTime = System.currentTimeMillis(); @@ -268,14 +268,14 @@ public class GLView extends GLSurfaceView implements IThemeView { if (e.getPointerCount() == 1) { fromTwoPointers = false; isScaling = false; - isMoving = false; + twoPointerGesture = false; lastActionTime = 0; } return true; } if (e.getPointerCount() == 1) { - if (!isRotating && action != MotionEvent.ACTION_CANCEL) { + if (!onePointerGesture && action != MotionEvent.ACTION_CANCEL) { if (renderer.onClick(e.getX() * Prefs.getRenderScale(), e.getY() * Prefs.getRenderScale())) { requestRender(); } @@ -283,7 +283,7 @@ public class GLView extends GLSurfaceView implements IThemeView { lastX = e.getX(0); lastY = e.getY(0); - isRotating = false; + onePointerGesture = false; } // TODO: Rotate with inertia @@ -300,16 +300,16 @@ public class GLView extends GLSurfaceView implements IThemeView { if (deltaMs > 128) { isScaling = false; - isMoving = false; + twoPointerGesture = false; } boolean startingGesture = false; - if (!isScaling && !isMoving) { + if (!isScaling && !twoPointerGesture) { if (Math.abs(distanceX) < touchSlop && Math.abs(distanceY) < touchSlop && Math.abs(len - lastLength) > touchSlop * 1.5f) { isScaling = true; startingGesture = true; } else if (Math.sqrt(distanceX * distanceX + distanceY * distanceY) >= touchSlop) { - isMoving = true; + twoPointerGesture = true; startingGesture = true; } } @@ -325,9 +325,14 @@ public class GLView extends GLSurfaceView implements IThemeView { lastX = x; lastY = y; - } else if (isMoving) { + } else if (twoPointerGesture) { if (!startingGesture) { - renderer.getCamera().move(distanceX / touchSlop * Prefs.getCameraSensitivity(), distanceY / touchSlop * Prefs.getCameraSensitivity()); + int mode = Prefs.getCameraControlMode(); + if (mode == Prefs.CAMERA_CONTROL_MODE_ROTATE_MOVE || mode == Prefs.CAMERA_CONTROL_MODE_MOVE_ONLY) { + renderer.getCamera().move(distanceX / touchSlop * Prefs.getCameraSensitivity(), distanceY / touchSlop * Prefs.getCameraSensitivity()); + } else { + renderer.getCamera().rotateAround(distanceX / touchSlop * Prefs.getCameraSensitivity(), distanceY / touchSlop * Prefs.getCameraSensitivity()); + } requestRender(); } @@ -338,16 +343,17 @@ public class GLView extends GLSurfaceView implements IThemeView { float distanceX = lastX - e.getX(), distanceY = lastY - e.getY(); boolean startingGesture = false; - if (!isRotating) { + if (!onePointerGesture) { if (Math.sqrt(distanceX * distanceX + distanceY * distanceY) >= touchSlop) { - isRotating = true; + onePointerGesture = true; startingGesture = true; } } - if (isRotating) { + if (onePointerGesture) { if (!startingGesture) { - if (Prefs.isRotationEnabled()) { + int mode = Prefs.getCameraControlMode(); + if (mode == Prefs.CAMERA_CONTROL_MODE_ROTATE_MOVE) { renderer.getCamera().rotateAround(distanceX / touchSlop * Prefs.getCameraSensitivity(), distanceY / touchSlop * Prefs.getCameraSensitivity()); } else { renderer.getCamera().move(distanceX / touchSlop * Prefs.getCameraSensitivity(), distanceY / touchSlop * Prefs.getCameraSensitivity()); diff --git a/app/src/main/res/drawable/hand_point_up_outline_28.xml b/app/src/main/res/drawable/hand_point_up_outline_28.xml new file mode 100644 index 0000000..1375ce6 --- /dev/null +++ b/app/src/main/res/drawable/hand_point_up_outline_28.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 297d341..6f12a99 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -48,7 +48,10 @@ Вид\nслева Вид\nсправа Ортог. проекц. - Вкл. поворот + Режим управ. + Один палец - поворот, два пальца - перемещение + Один палец - перемещение, два пальца - поворот + Только перемещение Ориентация Расст. модели Модели расставлены. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ce2d443..67c78bd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -50,7 +50,10 @@ Left view Right view Orth. project. - Allow rotation + Control mode + One finger - rotation, two fingers - movement + One finger - movement, two fingers - rotation + Only movement Orientation Arrange models Models arranged.