mirror of
https://github.com/Dark98/SliceBeam.git
synced 2026-07-02 16:49:02 +00:00
Long click to move; Boosty page on click before redirect
This commit is contained in:
@@ -8,11 +8,19 @@ import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ImageSpan;
|
||||
import android.text.style.ReplacementSpan;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
@@ -30,6 +38,7 @@ import androidx.activity.EdgeToEdge;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
@@ -94,9 +103,11 @@ import ru.ytkab0bp.slicebeam.view.BeamSwitch;
|
||||
import ru.ytkab0bp.slicebeam.view.BoostySubsView;
|
||||
import ru.ytkab0bp.slicebeam.view.FadeRecyclerView;
|
||||
import ru.ytkab0bp.slicebeam.view.MiniColorView;
|
||||
import ru.ytkab0bp.slicebeam.view.TextColorImageSpan;
|
||||
|
||||
public class SetupActivity extends AppCompatActivity {
|
||||
public final static String EXTRA_ABOUT = "about";
|
||||
public final static String EXTRA_BOOSTY_ONLY = "boosty_only";
|
||||
|
||||
private final static String TAG = "SetupActivity";
|
||||
|
||||
@@ -137,6 +148,7 @@ public class SetupActivity extends AppCompatActivity {
|
||||
private Map<ProfilesRepo, List<Slic3rConfigWrapper>> profilesMap = new HashMap<>();
|
||||
private boolean isProfilesLoaded;
|
||||
private boolean about;
|
||||
private boolean boostyOnly;
|
||||
|
||||
private List<ConfigObject> enabledPrinters = new ArrayList<>();
|
||||
|
||||
@@ -153,8 +165,9 @@ public class SetupActivity extends AppCompatActivity {
|
||||
SliceBeam.EVENT_BUS.registerListener(this);
|
||||
|
||||
about = getIntent().getBooleanExtra(EXTRA_ABOUT, false);
|
||||
boostyOnly = getIntent().getBooleanExtra(EXTRA_BOOSTY_ONLY, false);
|
||||
|
||||
if (!about) {
|
||||
if (!about && !boostyOnly) {
|
||||
new BeamAlertDialogBuilder(this)
|
||||
.setTitle(R.string.IntroEarlyAccess)
|
||||
.setMessage(R.string.IntroEarlyAccessMessage)
|
||||
@@ -166,7 +179,7 @@ public class SetupActivity extends AppCompatActivity {
|
||||
adapter = new SimpleRecyclerAdapter() {
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return about ? 1 : limitRepoFragmentCount ? REPOS_INDEX + 1 : limitProfileFragmentCount ? PROFILES_INDEX + 1 : super.getItemCount();
|
||||
return about || boostyOnly ? 1 : limitRepoFragmentCount ? REPOS_INDEX + 1 : limitProfileFragmentCount ? PROFILES_INDEX + 1 : super.getItemCount();
|
||||
}
|
||||
};
|
||||
setItems();
|
||||
@@ -197,13 +210,15 @@ public class SetupActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
if (position == 0) {
|
||||
if (position == 0 && !boostyOnly) {
|
||||
backgroundProgress = positionOffset;
|
||||
} else {
|
||||
backgroundProgress = 1f;
|
||||
}
|
||||
|
||||
if (position == BOOSTY_INDEX) {
|
||||
if (boostyOnly) {
|
||||
boostyProgress = 1f;
|
||||
} else if (position == BOOSTY_INDEX) {
|
||||
boostyProgress = 1f - positionOffset;
|
||||
} else if (position == BOOSTY_INDEX - 1) {
|
||||
boostyProgress = positionOffset;
|
||||
@@ -462,7 +477,9 @@ public class SetupActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void setItems() {
|
||||
if (about) {
|
||||
if (boostyOnly) {
|
||||
adapter.setItems(Collections.singletonList(new BoostyItem()));
|
||||
} else if (about) {
|
||||
adapter.setItems(Collections.singletonList(new AboutItem()));
|
||||
} else {
|
||||
List<SimpleRecyclerItem> items = new ArrayList<>(Arrays.asList(
|
||||
@@ -1008,25 +1025,42 @@ public class SetupActivity extends AppCompatActivity {
|
||||
}});
|
||||
|
||||
TextView subscribeButton = new TextView(ctx);
|
||||
subscribeButton.setText(R.string.IntroBoostySupport);
|
||||
SpannableStringBuilder sb = SpannableStringBuilder.valueOf(ctx.getString(R.string.IntroBoostySupport)).append(" ");
|
||||
Drawable dr = ContextCompat.getDrawable(ctx, R.drawable.external_link_outline_24);
|
||||
int size = ViewUtils.dp(16);
|
||||
dr.setBounds(0, 0, size, size);
|
||||
sb.append("d", new TextColorImageSpan(dr, ViewUtils.dp(2f)), SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
subscribeButton.setText(sb);
|
||||
subscribeButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
subscribeButton.setTextColor(ThemesRepo.getColor(R.attr.boostyColorTop));
|
||||
subscribeButton.setTextColor(Color.WHITE);
|
||||
subscribeButton.setTypeface(ViewUtils.getTypeface(ViewUtils.ROBOTO_MEDIUM));
|
||||
subscribeButton.setGravity(Gravity.CENTER);
|
||||
subscribeButton.setPadding(ViewUtils.dp(12), ViewUtils.dp(8), ViewUtils.dp(12), ViewUtils.dp(8));
|
||||
subscribeButton.setBackground(ViewUtils.createRipple(ThemesRepo.getColor(android.R.attr.colorControlHighlight), 16));
|
||||
subscribeButton.setOnClickListener(v -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://boosty.to/ytkab0bp"))));
|
||||
ll.addView(subscribeButton, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) {{
|
||||
bottomMargin = ViewUtils.dp(12);
|
||||
ll.addView(subscribeButton, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewUtils.dp(52)) {{
|
||||
leftMargin = rightMargin = ViewUtils.dp(16);
|
||||
bottomMargin = ViewUtils.dp(8);
|
||||
}});
|
||||
|
||||
TextView buttonView = new TextView(ctx);
|
||||
buttonView.setText(R.string.IntroNext);
|
||||
if (boostyOnly) {
|
||||
buttonView.setText(android.R.string.ok);
|
||||
} else {
|
||||
buttonView.setText(R.string.IntroNext);
|
||||
}
|
||||
buttonView.setTextColor(ThemesRepo.getColor(R.attr.textColorOnAccent));
|
||||
buttonView.setTypeface(ViewUtils.getTypeface(ViewUtils.ROBOTO_MEDIUM));
|
||||
buttonView.setGravity(Gravity.CENTER);
|
||||
buttonView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
buttonView.setBackground(ViewUtils.createRipple(ThemesRepo.getColor(android.R.attr.colorControlHighlight), ThemesRepo.getColor(R.attr.boostyColorTop), 16));
|
||||
buttonView.setOnClickListener(v-> scrollToNext());
|
||||
buttonView.setOnClickListener(v-> {
|
||||
if (boostyOnly) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
scrollToNext();
|
||||
});
|
||||
ll.addView(buttonView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewUtils.dp(52)) {{
|
||||
leftMargin = rightMargin = ViewUtils.dp(16);
|
||||
bottomMargin = ViewUtils.dp(16);
|
||||
|
||||
@@ -31,6 +31,7 @@ import ru.ytkab0bp.slicebeam.SliceBeam;
|
||||
import ru.ytkab0bp.slicebeam.components.BeamAlertDialogBuilder;
|
||||
import ru.ytkab0bp.slicebeam.components.UnfoldMenu;
|
||||
import ru.ytkab0bp.slicebeam.events.FlattenModeResetEvent;
|
||||
import ru.ytkab0bp.slicebeam.events.LongClickTranslationEvent;
|
||||
import ru.ytkab0bp.slicebeam.events.NeedSnackbarEvent;
|
||||
import ru.ytkab0bp.slicebeam.events.ObjectsListChangedEvent;
|
||||
import ru.ytkab0bp.slicebeam.events.SelectedObjectChangedEvent;
|
||||
@@ -139,7 +140,7 @@ public class OrientationMenu extends ListBedMenu {
|
||||
private Vec3d tempVec = new Vec3d();
|
||||
private int startedScrollObject;
|
||||
|
||||
private void translateVisual(Double x, Double y, Double z) {
|
||||
public void translateVisual(Double x, Double y, Double z) {
|
||||
int j = fragment.getGlView().getRenderer().getSelectedObject();
|
||||
if (j == -1) return;
|
||||
startedScrollObject = j;
|
||||
@@ -395,6 +396,24 @@ public class OrientationMenu extends ListBedMenu {
|
||||
startedScrollObject = -1;
|
||||
}
|
||||
|
||||
@EventHandler(runOnMainThread = true)
|
||||
public void onLongClickTranslation(LongClickTranslationEvent e) {
|
||||
if (e.visual) {
|
||||
int j = fragment.getGlView().getRenderer().getSelectedObject();
|
||||
if (j == -1) return;
|
||||
|
||||
Model model = fragment.getGlView().getRenderer().getModel();
|
||||
model.getTranslation(j, tempVec);
|
||||
|
||||
xTitle.setText(formatTrackTitle(R.string.MenuOrientationPositionXValue, tempVec.x + e.x));
|
||||
yTitle.setText(formatTrackTitle(R.string.MenuOrientationPositionYValue, tempVec.y + e.y));
|
||||
xTrack.setCurrentPosition((int) (tempVec.x + e.x));
|
||||
yTrack.setCurrentPosition((int) (tempVec.y + e.y));
|
||||
} else {
|
||||
setSelectionValues();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(runOnMainThread = true)
|
||||
public void onSelectedObjectChanged(SelectedObjectChangedEvent e) {
|
||||
stopScroll();
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package ru.ytkab0bp.slicebeam.events;
|
||||
|
||||
import ru.ytkab0bp.eventbus.Event;
|
||||
|
||||
@Event
|
||||
public class LongClickTranslationEvent {
|
||||
public final double x;
|
||||
public final double y;
|
||||
public final boolean visual;
|
||||
|
||||
public LongClickTranslationEvent(double x, double y, boolean visual) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.visual = visual;
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ public class SettingsFragment extends ProfileListFragment {
|
||||
}),
|
||||
BeamServerData.isBoostyAvailable() ? new OptionElement(R.drawable.boosty, getContext().getString(R.string.SettingsBoosty)).setColor(R.attr.boostyColorTop, true).setOnClick(() -> {
|
||||
Activity act = (Activity) getContext();
|
||||
act.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://boosty.to/ytkab0bp")));
|
||||
act.startActivity(new Intent(act, SetupActivity.class).putExtra(SetupActivity.EXTRA_BOOSTY_ONLY, true));
|
||||
}) : null,
|
||||
new OptionElement(R.drawable.k3d_logo_new_14, getContext().getString(R.string.SettingsK3D)).setColor(R.attr.k3dColor, true).setOnClick(() -> {
|
||||
Activity act = (Activity) getContext();
|
||||
|
||||
@@ -107,6 +107,18 @@ public class MobileNavigationDelegate extends DelegateSlotImpl {
|
||||
return root = fl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
if (super.onBackPressed()) {
|
||||
return true;
|
||||
}
|
||||
if (currentSlot != 0) {
|
||||
switchSlot(0, () -> navigationView.setSelectedItemId(0));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FrameLayout getOverlayView() {
|
||||
return root;
|
||||
|
||||
@@ -41,7 +41,7 @@ public class Camera {
|
||||
this.zoom = zoom;
|
||||
}
|
||||
|
||||
public void move(float x, float y) {
|
||||
public Vec3d calcScreenMovement(float x, float y) {
|
||||
x /= zoom;
|
||||
y /= zoom;
|
||||
|
||||
@@ -61,8 +61,10 @@ public class Camera {
|
||||
screenX.multiply(x);
|
||||
screenY.multiply(y);
|
||||
|
||||
Vec3d move = new Vec3d(screenX).add(screenY);
|
||||
|
||||
return new Vec3d(screenX).add(screenY);
|
||||
}
|
||||
public void move(float x, float y) {
|
||||
Vec3d move = calcScreenMovement(x, y);
|
||||
position.add(move);
|
||||
origin.add(move);
|
||||
}
|
||||
|
||||
@@ -374,9 +374,8 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onClick(float x, float y) {
|
||||
if (model == null || isViewerEnabled) return false;
|
||||
|
||||
public int raycastObjectIndex(float x, float y) {
|
||||
if (model == null) return -1;
|
||||
double minDistance = Double.MAX_VALUE;
|
||||
int j = -1;
|
||||
for (int i = 0, c = model.getObjectsCount(); i < c; i++) {
|
||||
@@ -394,6 +393,13 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
}
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
public boolean onClick(float x, float y) {
|
||||
if (model == null || isViewerEnabled) return false;
|
||||
|
||||
int j = raycastObjectIndex(x, y);
|
||||
|
||||
if (isInFlattenMode && (j == selectedObject || j == -1)) {
|
||||
int minPlane = -1;
|
||||
|
||||
@@ -45,6 +45,7 @@ public class Bed3D {
|
||||
|
||||
private void configure(String path) {
|
||||
Native.bed_configure(pointer, path);
|
||||
Native.bed_init_triangles_mesh(pointer, triangles.pointer);
|
||||
boundingVolume = Native.bed_get_bounding_volume(pointer);
|
||||
|
||||
min = max = null;
|
||||
@@ -78,6 +79,10 @@ public class Bed3D {
|
||||
return boundingVolume != null;
|
||||
}
|
||||
|
||||
public GLModel.MeshRaycaster getRaycaster() {
|
||||
return triangles.getRaycaster();
|
||||
}
|
||||
|
||||
public void render(boolean bottom, double[] viewModelMatrix, double[] projectionMatrix, float invZoom) {
|
||||
assertTrue(viewModelMatrix.length == 16);
|
||||
assertTrue(projectionMatrix.length == 16);
|
||||
|
||||
@@ -46,6 +46,7 @@ class Native {
|
||||
static native int bed_get_bounding_volume_max_size(long ptr);
|
||||
static native double[] bed_get_bounding_volume(long ptr);
|
||||
static native void bed_configure(long ptr, String configPath);
|
||||
static native void bed_init_triangles_mesh(long ptr, long triangles);
|
||||
static native boolean bed_arrange(long ptr, long modelPtr);
|
||||
static native void bed_release(long ptr);
|
||||
|
||||
|
||||
@@ -17,17 +17,23 @@ import android.opengl.GLSurfaceView;
|
||||
import android.text.Layout;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import ru.ytkab0bp.slicebeam.R;
|
||||
import ru.ytkab0bp.slicebeam.SliceBeam;
|
||||
import ru.ytkab0bp.slicebeam.events.LongClickTranslationEvent;
|
||||
import ru.ytkab0bp.slicebeam.render.GLRenderer;
|
||||
import ru.ytkab0bp.slicebeam.slic3r.GLModel;
|
||||
import ru.ytkab0bp.slicebeam.theme.IThemeView;
|
||||
import ru.ytkab0bp.slicebeam.theme.ThemesRepo;
|
||||
import ru.ytkab0bp.slicebeam.utils.Prefs;
|
||||
import ru.ytkab0bp.slicebeam.utils.Vec3d;
|
||||
import ru.ytkab0bp.slicebeam.utils.ViewUtils;
|
||||
|
||||
public class GLView extends GLSurfaceView implements IThemeView {
|
||||
@@ -40,9 +46,26 @@ public class GLView extends GLSurfaceView implements IThemeView {
|
||||
private boolean fromTwoPointers;
|
||||
private boolean onePointerGesture;
|
||||
private boolean twoPointerGesture;
|
||||
private boolean longClickGesture;
|
||||
private boolean isScaling;
|
||||
|
||||
private Vec3d tempVec = new Vec3d();
|
||||
private Vec3d longClickOffset = new Vec3d();
|
||||
private Vec3d longClickTranslation = new Vec3d();
|
||||
private ArrayList<GLModel.HitResult> longClickHitResults = new ArrayList<>();
|
||||
private long lastActionTime = System.currentTimeMillis();
|
||||
private Runnable longClick = () -> {
|
||||
getRenderer().getBed().getRaycaster().raycast(getRenderer(), longClickHitResults, lastX, lastY);
|
||||
if (!longClickHitResults.isEmpty()) {
|
||||
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
longClickGesture = true;
|
||||
|
||||
GLModel.HitResult result = longClickHitResults.get(0);
|
||||
getRenderer().getModel().getTranslation(getRenderer().getSelectedObject(), tempVec);
|
||||
longClickOffset.x = result.position.x - tempVec.x;
|
||||
longClickOffset.y = result.position.y - tempVec.y;
|
||||
}
|
||||
};
|
||||
|
||||
private Path path = new Path();
|
||||
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
@@ -249,21 +272,43 @@ public class GLView extends GLSurfaceView implements IThemeView {
|
||||
int action = e.getActionMasked();
|
||||
|
||||
if (e.getPointerCount() > 2) {
|
||||
removeCallbacks(longClick);
|
||||
longClickGesture = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN) {
|
||||
if (e.getPointerCount() == 2) {
|
||||
removeCallbacks(longClick);
|
||||
longClickGesture = false;
|
||||
calcStartFocus(e);
|
||||
fromTwoPointers = true;
|
||||
} else {
|
||||
lastX = e.getX();
|
||||
lastY = e.getY();
|
||||
|
||||
int j = renderer.raycastObjectIndex(lastX, lastY);
|
||||
if (j == renderer.getSelectedObject() && j != -1) {
|
||||
postDelayed(longClick, 300);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_CANCEL) {
|
||||
removeCallbacks(longClick);
|
||||
if (longClickGesture) {
|
||||
queueEvent(()->{
|
||||
int j = getRenderer().getSelectedObject();
|
||||
getRenderer().getModel().getTranslation(j, tempVec);
|
||||
getRenderer().setSelectionTranslation(0, 0, 0);
|
||||
getRenderer().getModel().translate(j, longClickTranslation.x, longClickTranslation.y, 0);
|
||||
getRenderer().invalidateGlModel(j);
|
||||
requestRender();
|
||||
SliceBeam.EVENT_BUS.fireEvent(new LongClickTranslationEvent(longClickTranslation.x, longClickTranslation.y, false));
|
||||
});
|
||||
}
|
||||
longClickGesture = false;
|
||||
if (fromTwoPointers) {
|
||||
if (e.getPointerCount() == 1) {
|
||||
fromTwoPointers = false;
|
||||
@@ -286,7 +331,7 @@ public class GLView extends GLSurfaceView implements IThemeView {
|
||||
onePointerGesture = false;
|
||||
}
|
||||
|
||||
// TODO: Rotate with inertia
|
||||
// TODO: Rotate with inertia?
|
||||
return true;
|
||||
}
|
||||
if (action == MotionEvent.ACTION_MOVE) {
|
||||
@@ -347,18 +392,35 @@ public class GLView extends GLSurfaceView implements IThemeView {
|
||||
if (Math.sqrt(distanceX * distanceX + distanceY * distanceY) >= touchSlop) {
|
||||
onePointerGesture = true;
|
||||
startingGesture = true;
|
||||
removeCallbacks(longClick);
|
||||
}
|
||||
}
|
||||
|
||||
if (onePointerGesture) {
|
||||
if (!startingGesture) {
|
||||
int mode = Prefs.getCameraControlMode();
|
||||
if (mode == Prefs.CAMERA_CONTROL_MODE_ROTATE_MOVE) {
|
||||
renderer.getCamera().rotateAround(distanceX / touchSlop * Prefs.getCameraSensitivity(), distanceY / touchSlop * Prefs.getCameraSensitivity());
|
||||
if (longClickGesture) {
|
||||
Vec3d move = getRenderer().getCamera().calcScreenMovement(distanceX / touchSlop * 4.5f, distanceY / touchSlop * 4.5f);
|
||||
|
||||
getRenderer().getModel().getTranslation(getRenderer().getSelectedObject(), tempVec);
|
||||
getRenderer().getBed().getRaycaster().raycast(getRenderer(), longClickHitResults, e.getX(), e.getY());
|
||||
if (!longClickHitResults.isEmpty()) {
|
||||
GLModel.HitResult result = longClickHitResults.get(0);
|
||||
longClickTranslation.x = result.position.x - tempVec.x - longClickOffset.x;
|
||||
longClickTranslation.y = result.position.y - tempVec.y - longClickOffset.y;
|
||||
getRenderer().setSelectionTranslation(longClickTranslation.x, longClickTranslation.y, 0);
|
||||
SliceBeam.EVENT_BUS.fireEvent(new LongClickTranslationEvent(longClickTranslation.x, longClickTranslation.y, true));
|
||||
}
|
||||
|
||||
requestRender();
|
||||
} else {
|
||||
renderer.getCamera().move(distanceX / touchSlop * Prefs.getCameraSensitivity(), distanceY / touchSlop * Prefs.getCameraSensitivity());
|
||||
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());
|
||||
}
|
||||
requestRender();
|
||||
}
|
||||
requestRender();
|
||||
}
|
||||
|
||||
lastX = e.getX();
|
||||
|
||||
@@ -37,6 +37,10 @@ public class SnackbarsLayout extends FrameLayout {
|
||||
}
|
||||
|
||||
public void show(Snackbar snackbar) {
|
||||
if (snackbar.tag != null) {
|
||||
dismiss(snackbar.tag);
|
||||
}
|
||||
|
||||
SnackbarView v = new SnackbarView(getContext()).bind(snackbar);
|
||||
addView(v);
|
||||
applyTransforms();
|
||||
|
||||
@@ -1401,6 +1401,19 @@ extern "C" {
|
||||
bed_util_init_contourlines(ref->contour, ref->contourlines);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_ru_ytkab0bp_slicebeam_slic3r_Native_bed_1init_1triangles_1mesh(JNIEnv* env, jclass, jlong ptr, jlong triangles_ptr) {
|
||||
auto ref = reinterpret_cast<BedRef*>(ptr);
|
||||
auto tRef = reinterpret_cast<GLModelRef*>(triangles_ptr);
|
||||
|
||||
auto contour = ref->contour;
|
||||
BoundingBox bb = get_extents(contour);
|
||||
Point center = bb.center();
|
||||
float scaleFactor = 4;
|
||||
contour.scale(scaleFactor);
|
||||
contour.translate(-center.x() * scaleFactor * 0.5f, -center.y() * scaleFactor * 0.5f);
|
||||
bed_util_init_triangles_its(contour, &tRef->mesh.its);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_ru_ytkab0bp_slicebeam_slic3r_Native_bed_1arrange(JNIEnv* env, jclass, jlong ptr, jlong model) {
|
||||
BedRef* ref = (BedRef*) (intptr_t) ptr;
|
||||
ModelRef* mRef = (ModelRef*) (intptr_t) model;
|
||||
|
||||
@@ -56,6 +56,22 @@ void bed_util_init_gridlines(ExPolygon& contour, GLModel* glGridlines) {
|
||||
glGridlines->init_from(std::move(init_data));
|
||||
}
|
||||
|
||||
void bed_util_init_triangles_its(ExPolygon& contour, indexed_triangle_set* its) {
|
||||
if (contour.empty())
|
||||
return;
|
||||
|
||||
auto triangles = triangulate_expolygon_3d(contour, 0);
|
||||
its->vertices.reserve(triangles.size());
|
||||
|
||||
for (size_t i = 0; i < triangles.size(); i += 3) {
|
||||
its->vertices.emplace_back(triangles[i].cast<float>());
|
||||
its->vertices.emplace_back(triangles[i + 1].cast<float>());
|
||||
its->vertices.emplace_back(triangles[i + 2].cast<float>());
|
||||
|
||||
its->indices.emplace_back(i, i + 1, i + 2);
|
||||
}
|
||||
}
|
||||
|
||||
void bed_util_init_triangles(ExPolygon& contour, GLModel* glTriangles) {
|
||||
if (glTriangles->is_initialized())
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user