diff --git a/app/src/main/assets/models/3dbenchy.stl b/app/src/main/assets/models/3dbenchy.stl new file mode 100644 index 0000000..1f268d5 Binary files /dev/null and b/app/src/main/assets/models/3dbenchy.stl differ diff --git a/app/src/main/assets/models/box.stl b/app/src/main/assets/models/box.stl new file mode 100644 index 0000000..311e550 Binary files /dev/null and b/app/src/main/assets/models/box.stl differ diff --git a/app/src/main/assets/models/bunny.stl b/app/src/main/assets/models/bunny.stl new file mode 100644 index 0000000..94a9566 Binary files /dev/null and b/app/src/main/assets/models/bunny.stl differ diff --git a/app/src/main/assets/models/cone.stl b/app/src/main/assets/models/cone.stl new file mode 100644 index 0000000..f75c6d7 Binary files /dev/null and b/app/src/main/assets/models/cone.stl differ diff --git a/app/src/main/assets/models/cylinder.stl b/app/src/main/assets/models/cylinder.stl new file mode 100644 index 0000000..b4e1591 Binary files /dev/null and b/app/src/main/assets/models/cylinder.stl differ diff --git a/app/src/main/assets/models/fox.stl b/app/src/main/assets/models/fox.stl new file mode 100644 index 0000000..ad58f15 Binary files /dev/null and b/app/src/main/assets/models/fox.stl differ diff --git a/app/src/main/assets/models/pyramid.stl b/app/src/main/assets/models/pyramid.stl new file mode 100644 index 0000000..83269cd Binary files /dev/null and b/app/src/main/assets/models/pyramid.stl differ diff --git a/app/src/main/assets/models/sphere.stl b/app/src/main/assets/models/sphere.stl new file mode 100644 index 0000000..80d6ac5 Binary files /dev/null and b/app/src/main/assets/models/sphere.stl differ diff --git a/app/src/main/assets/models/xyz_cube.stl b/app/src/main/assets/models/xyz_cube.stl new file mode 100644 index 0000000..31e9f1a Binary files /dev/null and b/app/src/main/assets/models/xyz_cube.stl differ diff --git a/app/src/main/java/ru/ytkab0bp/slicebeam/components/UnfoldMenu.java b/app/src/main/java/ru/ytkab0bp/slicebeam/components/UnfoldMenu.java index bc583cc..123526a 100644 --- a/app/src/main/java/ru/ytkab0bp/slicebeam/components/UnfoldMenu.java +++ b/app/src/main/java/ru/ytkab0bp/slicebeam/components/UnfoldMenu.java @@ -74,7 +74,9 @@ public abstract class UnfoldMenu { private void show(View from, BedFragment fragment, FrameLayout into) { if (isVisible) return; - this.fragment = fragment; + if (fragment != null) { + this.fragment = fragment; + } this.isVisible = true; this.containerLayout = into; @@ -96,7 +98,7 @@ public abstract class UnfoldMenu { fromTranslationX = pos[0] - intoPos[0]; fromTranslationY = pos[1] - intoPos[1]; toTranslationX = 0; - toTranslationY = portrait ? into.getHeight() - side : 0; + toTranslationY = portrait ? into.getHeight() - side - into.getPaddingTop() - into.getPaddingBottom() : 0; rootView = new FrameLayout(ctx) { { setWillNotDraw(false); diff --git a/app/src/main/java/ru/ytkab0bp/slicebeam/components/WebViewMenu.java b/app/src/main/java/ru/ytkab0bp/slicebeam/components/WebViewMenu.java index 3071c33..415d71a 100644 --- a/app/src/main/java/ru/ytkab0bp/slicebeam/components/WebViewMenu.java +++ b/app/src/main/java/ru/ytkab0bp/slicebeam/components/WebViewMenu.java @@ -124,7 +124,7 @@ public class WebViewMenu extends UnfoldMenu { @Override public int getRequestedSize(FrameLayout into, boolean portrait) { - return portrait ? into.getHeight() : into.getWidth(); + return portrait ? into.getHeight() - into.getPaddingTop() - into.getPaddingBottom() : into.getWidth(); } private final class Bridge { diff --git a/app/src/main/java/ru/ytkab0bp/slicebeam/components/bed_menu/FileMenu.java b/app/src/main/java/ru/ytkab0bp/slicebeam/components/bed_menu/FileMenu.java index abb53ee..d4e902f 100644 --- a/app/src/main/java/ru/ytkab0bp/slicebeam/components/bed_menu/FileMenu.java +++ b/app/src/main/java/ru/ytkab0bp/slicebeam/components/bed_menu/FileMenu.java @@ -18,6 +18,8 @@ import androidx.core.graphics.ColorUtils; import androidx.recyclerview.widget.RecyclerView; import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -36,13 +38,16 @@ import ru.ytkab0bp.slicebeam.components.UnfoldMenu; import ru.ytkab0bp.slicebeam.components.WebViewMenu; import ru.ytkab0bp.slicebeam.config.ConfigObject; import ru.ytkab0bp.slicebeam.events.NeedDismissCalibrationsMenu; +import ru.ytkab0bp.slicebeam.events.NeedSnackbarEvent; import ru.ytkab0bp.slicebeam.events.ObjectsListChangedEvent; import ru.ytkab0bp.slicebeam.events.SelectedObjectChangedEvent; +import ru.ytkab0bp.slicebeam.fragment.BedFragment; import ru.ytkab0bp.slicebeam.recycler.PreferenceItem; import ru.ytkab0bp.slicebeam.recycler.SimpleRecyclerAdapter; import ru.ytkab0bp.slicebeam.recycler.SimpleRecyclerItem; import ru.ytkab0bp.slicebeam.recycler.SpaceItem; import ru.ytkab0bp.slicebeam.slic3r.Bed3D; +import ru.ytkab0bp.slicebeam.slic3r.Slic3rRuntimeError; import ru.ytkab0bp.slicebeam.theme.BeamTheme; import ru.ytkab0bp.slicebeam.theme.ThemesRepo; import ru.ytkab0bp.slicebeam.utils.ViewUtils; @@ -214,7 +219,7 @@ public class FileMenu extends ListBedMenu { public final class CalibrationsMenu extends UnfoldMenu { public int getRequestedSize(FrameLayout into, boolean portrait) { - return (int) (portrait ? into.getHeight() * 0.3f : into.getWidth() * 0.6f); + return (int) (portrait ? into.getHeight() * 0.35f : into.getWidth() * 0.6f); } private String loadJSLoader(String key) { @@ -309,6 +314,11 @@ public class FileMenu extends ListBedMenu { if (ctx instanceof MainActivity) { ((MainActivity) ctx).showUnfoldMenu(new WebViewMenu(Uri.parse("https://k3d.tech/calibrations/retractions/calibrator/").buildUpon().appendQueryParameter("lang", getK3DLanguage()).build(), loadJSLoader("k3d_rct")).setFragment(fragment), v); } + }), + new PreferenceItem().setIcon(R.drawable.deployed_code_24).setTitle(ctx.getString(R.string.MenuFileCalibrationsModels)).setSubtitle(ctx.getString(R.string.MenuFileCalibrationsModelsDescription)).setOnClickListener(v -> { + if (ctx instanceof MainActivity) { + ((MainActivity) ctx).showUnfoldMenu(new CalibrationModelsMenu().setFragment(fragment), v); + } }) )); rv.setAdapter(adapter); @@ -359,4 +369,111 @@ public class FileMenu extends ListBedMenu { SliceBeam.EVENT_BUS.unregisterListener(this); } } + + public final static class CalibrationModelsMenu extends UnfoldMenu { + private void loadModel(String key) { + BedFragment fragment = this.fragment; + ViewUtils.postOnMainThread(() -> { + File f = new File(SliceBeam.getModelCacheDir(), "calibration_" + key + ".stl"); + new Thread(()->{ + try { + InputStream in = SliceBeam.INSTANCE.getAssets().open("models/" + key + ".stl"); + FileOutputStream fos = new FileOutputStream(f); + byte[] buffer = new byte[10240]; int c; + while ((c = in.read(buffer)) != -1) { + fos.write(buffer, 0, c); + } + fos.close(); + in.close(); + + ViewUtils.postOnMainThread(() -> { + try { + if (f.getName().endsWith(".gcode")) { + fragment.loadGCode(f); + } else { + fragment.loadModel(f); + SliceBeam.EVENT_BUS.fireEvent(new ObjectsListChangedEvent()); + } + SliceBeam.EVENT_BUS.fireEvent(new NeedSnackbarEvent(R.string.MenuFileOpenFileLoaded)); + } catch (Slic3rRuntimeError e) { + f.delete(); + + ViewUtils.postOnMainThread(() -> new BeamAlertDialogBuilder(fragment.getContext()) + .setTitle(R.string.MenuFileOpenFileFailed) + .setMessage(e.toString()) + .setPositiveButton(android.R.string.ok, null) + .show()); + } + }); + } catch (Exception e) { + f.delete(); + ViewUtils.postOnMainThread(() -> new BeamAlertDialogBuilder(fragment.getContext()) + .setTitle(R.string.MenuFileOpenFileFailed) + .setMessage(e.toString()) + .setPositiveButton(android.R.string.ok, null) + .show()); + } + }).start(); + }, 200); + SliceBeam.EVENT_BUS.fireEvent(new NeedDismissCalibrationsMenu()); + dismiss(true); + } + + @Override + protected View onCreateView(Context ctx, boolean portrait) { + LinearLayout ll = new LinearLayout(ctx); + ll.setOrientation(LinearLayout.VERTICAL); + + LinearLayout toolbar = new LinearLayout(ctx); + toolbar.setPadding(ViewUtils.dp(12), 0, ViewUtils.dp(12), 0); + toolbar.setOrientation(LinearLayout.HORIZONTAL); + toolbar.setGravity(Gravity.CENTER_VERTICAL); + toolbar.setBackground(ViewUtils.createRipple(ThemesRepo.getColor(android.R.attr.colorControlHighlight), 0)); + toolbar.setOnClickListener(v -> dismiss()); + + ImageView icon = new ImageView(ctx); + icon.setImageResource(R.drawable.arrow_left_outline_28); + icon.setColorFilter(ThemesRepo.getColor(android.R.attr.textColorSecondary)); + toolbar.addView(icon, new LinearLayout.LayoutParams(ViewUtils.dp(28), ViewUtils.dp(28))); + + TextView title = new TextView(ctx); + title.setText(R.string.MenuOrientationPositionBack); + title.setTypeface(ViewUtils.getTypeface(ViewUtils.ROBOTO_MEDIUM)); + title.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + title.setTextColor(ThemesRepo.getColor(android.R.attr.textColorPrimary)); + toolbar.addView(title, new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f) {{ + leftMargin = ViewUtils.dp(12); + }}); + ll.addView(toolbar, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewUtils.dp(52))); + + ll.addView(new DividerView(ctx), new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewUtils.dp(1f))); + + RecyclerView rv = new FadeRecyclerView(ctx); + SimpleRecyclerAdapter adapter = new SimpleRecyclerAdapter(); + adapter.setItems(Arrays.asList( + new PreferenceItem().setIcon(R.drawable.model_3dbenchy).setNoTint(true).setRoundRadius(ViewUtils.dp(8)).setTitle(ctx.getString(R.string.MenuFileCalibrationsModels3DBenchy)).setOnClickListener(v -> loadModel("3dbenchy")), + new PreferenceItem().setIcon(R.drawable.model_xyz_cube).setNoTint(true).setRoundRadius(ViewUtils.dp(8)).setTitle(ctx.getString(R.string.MenuFileCalibrationsModelsXYZCube)).setOnClickListener(v -> loadModel("xyz_cube")), + new PreferenceItem().setIcon(R.drawable.model_bunny).setNoTint(true).setRoundRadius(ViewUtils.dp(8)).setTitle(ctx.getString(R.string.MenuFileCalibrationsModelsBunny)).setOnClickListener(v -> loadModel("bunny")), + new PreferenceItem().setIcon(R.drawable.model_fox).setNoTint(true).setRoundRadius(ViewUtils.dp(8)).setTitle(ctx.getString(R.string.MenuFileCalibrationsModelsFox)).setOnClickListener(v -> loadModel("fox")), + new PreferenceItem().setIcon(R.drawable.model_box).setNoTint(true).setRoundRadius(ViewUtils.dp(8)).setTitle(ctx.getString(R.string.MenuFileCalibrationsModelsBox)).setOnClickListener(v -> loadModel("box")), + new PreferenceItem().setIcon(R.drawable.model_cone).setNoTint(true).setRoundRadius(ViewUtils.dp(8)).setTitle(ctx.getString(R.string.MenuFileCalibrationsModelsCone)).setOnClickListener(v -> loadModel("cone")), + new PreferenceItem().setIcon(R.drawable.model_cylinder).setNoTint(true).setRoundRadius(ViewUtils.dp(8)).setTitle(ctx.getString(R.string.MenuFileCalibrationsModelsCylinder)).setOnClickListener(v -> loadModel("cylinder")), + new PreferenceItem().setIcon(R.drawable.model_pyramid).setNoTint(true).setRoundRadius(ViewUtils.dp(8)).setTitle(ctx.getString(R.string.MenuFileCalibrationsModelsPyramid)).setOnClickListener(v -> loadModel("pyramid")), + new PreferenceItem().setIcon(R.drawable.model_sphere).setNoTint(true).setRoundRadius(ViewUtils.dp(8)).setTitle(ctx.getString(R.string.MenuFileCalibrationsModelsSphere)).setOnClickListener(v -> loadModel("sphere")) + )); + rv.setAdapter(adapter); + ll.addView(rv, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f)); + return ll; + } + + @Override + public int getRequestedSize(FrameLayout into, boolean portrait) { + return portrait ? into.getHeight() - into.getPaddingTop() - into.getPaddingBottom() : into.getWidth(); + } + + public CalibrationModelsMenu setFragment(BedFragment fragment) { + this.fragment = fragment; + return this; + } + } } diff --git a/app/src/main/java/ru/ytkab0bp/slicebeam/recycler/PreferenceItem.java b/app/src/main/java/ru/ytkab0bp/slicebeam/recycler/PreferenceItem.java index 7c07806..db19466 100644 --- a/app/src/main/java/ru/ytkab0bp/slicebeam/recycler/PreferenceItem.java +++ b/app/src/main/java/ru/ytkab0bp/slicebeam/recycler/PreferenceItem.java @@ -2,6 +2,8 @@ package ru.ytkab0bp.slicebeam.recycler; import android.content.Context; import android.content.res.ColorStateList; +import android.graphics.Canvas; +import android.graphics.Path; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.text.TextUtils; @@ -13,6 +15,8 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.widget.AppCompatImageView; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; @@ -29,6 +33,7 @@ public class PreferenceItem extends SimpleRecyclerItem + + diff --git a/app/src/main/res/drawable/model_3dbenchy.png b/app/src/main/res/drawable/model_3dbenchy.png new file mode 100644 index 0000000..35e7cd1 Binary files /dev/null and b/app/src/main/res/drawable/model_3dbenchy.png differ diff --git a/app/src/main/res/drawable/model_box.png b/app/src/main/res/drawable/model_box.png new file mode 100644 index 0000000..58913be Binary files /dev/null and b/app/src/main/res/drawable/model_box.png differ diff --git a/app/src/main/res/drawable/model_bunny.png b/app/src/main/res/drawable/model_bunny.png new file mode 100644 index 0000000..f9524b6 Binary files /dev/null and b/app/src/main/res/drawable/model_bunny.png differ diff --git a/app/src/main/res/drawable/model_cone.png b/app/src/main/res/drawable/model_cone.png new file mode 100644 index 0000000..a51df2d Binary files /dev/null and b/app/src/main/res/drawable/model_cone.png differ diff --git a/app/src/main/res/drawable/model_cylinder.png b/app/src/main/res/drawable/model_cylinder.png new file mode 100644 index 0000000..dd416b4 Binary files /dev/null and b/app/src/main/res/drawable/model_cylinder.png differ diff --git a/app/src/main/res/drawable/model_fox.png b/app/src/main/res/drawable/model_fox.png new file mode 100644 index 0000000..1a34bdd Binary files /dev/null and b/app/src/main/res/drawable/model_fox.png differ diff --git a/app/src/main/res/drawable/model_pyramid.png b/app/src/main/res/drawable/model_pyramid.png new file mode 100644 index 0000000..3e912eb Binary files /dev/null and b/app/src/main/res/drawable/model_pyramid.png differ diff --git a/app/src/main/res/drawable/model_sphere.png b/app/src/main/res/drawable/model_sphere.png new file mode 100644 index 0000000..5d86b5a Binary files /dev/null and b/app/src/main/res/drawable/model_sphere.png differ diff --git a/app/src/main/res/drawable/model_xyz_cube.png b/app/src/main/res/drawable/model_xyz_cube.png new file mode 100644 index 0000000..0a25b13 Binary files /dev/null and b/app/src/main/res/drawable/model_xyz_cube.png differ diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index f5049db..8f6104c 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -18,6 +18,16 @@ Калибровка Linear/Pressure Advance K3D Откаты Калибровка расстояния и скорости откатов + Калибровочные модели + Библиотека калибровочных моделей + Калибровочный куб + Заяц + Лис + Куб + Конус + Цилиндр + Пирамида + Сфера Файл загружен. Импорт. профилей Не удалось импортировать diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5e28a7e..8a38d72 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -20,6 +20,17 @@ Linear/Pressure Advance Calibration K3D Retractions Retraction distance and speed calibration + Calibration models + Calibration models library + 3D Benchy + Calibration cube + Bunny + Fox + Box + Cone + Cylinder + Pyramid + Sphere Import profiles Import failed Not an .ini file