Calibration models library

This commit is contained in:
YTKAB0BP
2024-11-18 19:42:18 +03:00
parent 4246b6ff8c
commit 1451fe274c
25 changed files with 187 additions and 5 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -74,7 +74,9 @@ public abstract class UnfoldMenu {
private void show(View from, BedFragment fragment, FrameLayout into) {
if (isVisible) return;
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);
@@ -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 {
@@ -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;
}
}
}
@@ -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<PreferenceItem.Preference
private int textColorRes;
private boolean noTint;
private ValueProvider valueProvider;
private float roundRadius;
public PreferenceItem setTitle(CharSequence title) {
mTitle = title;
@@ -70,6 +75,11 @@ public class PreferenceItem extends SimpleRecyclerItem<PreferenceItem.Preference
return this;
}
public PreferenceItem setRoundRadius(float roundRadius) {
this.roundRadius = roundRadius;
return this;
}
public PreferenceItem setTextColorRes(int textColorRes) {
this.textColorRes = textColorRes;
return this;
@@ -94,6 +104,7 @@ public class PreferenceItem extends SimpleRecyclerItem<PreferenceItem.Preference
private TextView title, subtitle;
private ImageView icon;
private TextView value;
private float radius;
public PreferenceHolderView(Context context) {
super(context);
@@ -101,7 +112,23 @@ public class PreferenceItem extends SimpleRecyclerItem<PreferenceItem.Preference
setOrientation(HORIZONTAL);
setGravity(Gravity.CENTER_VERTICAL);
icon = new ImageView(context);
icon = new AppCompatImageView(context) {
private Path path = new Path();
@Override
public void draw(@NonNull Canvas canvas) {
if (radius != 0) {
canvas.save();
path.rewind();
path.addRoundRect(0, 0, getWidth(), getHeight(), radius, radius, Path.Direction.CW);
canvas.clipPath(path);
}
super.draw(canvas);
if (radius != 0) {
canvas.restore();
}
}
};
icon.setLayoutParams(new LayoutParams(ViewUtils.dp(28), ViewUtils.dp(28)) {{
setMarginStart(ViewUtils.dp(4));
setMarginEnd(ViewUtils.dp(8));
@@ -178,6 +205,11 @@ public class PreferenceItem extends SimpleRecyclerItem<PreferenceItem.Preference
} else {
icon.setImageTintList(ColorStateList.valueOf(ThemesRepo.getColor(item.textColorRes != 0 ? item.textColorRes : android.R.attr.textColorSecondary)));
}
radius = item.roundRadius;
icon.invalidate();
ViewGroup.LayoutParams params = icon.getLayoutParams();
params.width = params.height = radius != 0 ? ViewUtils.dp(42) : ViewUtils.dp(28);
}
@Override
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="#000">
<path
android:fillColor="@android:color/white"
android:pathData="M440,777L440,503L200,364L200,638Q200,638 200,638Q200,638 200,638L440,777ZM520,777L760,638Q760,638 760,638Q760,638 760,638L760,364L520,503L520,777ZM480,434L717,297L480,160Q480,160 480,160Q480,160 480,160L243,297L480,434ZM160,708Q141,697 130.5,679Q120,661 120,639L120,321Q120,299 130.5,281Q141,263 160,252L440,91Q459,80 480,80Q501,80 520,91L800,252Q819,263 829.5,281Q840,299 840,321L840,639Q840,661 829.5,679Q819,697 800,708L520,869Q501,880 480,880Q459,880 440,869L160,708ZM480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Z"/>
</vector>
Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

+10
View File
@@ -18,6 +18,16 @@
<string name="MenuFileCalibrationsLADescription">Калибровка Linear/Pressure Advance</string>
<string name="MenuFileCalibrationsRetract">K3D Откаты</string>
<string name="MenuFileCalibrationsRetractDescription">Калибровка расстояния и скорости откатов</string>
<string name="MenuFileCalibrationsModels">Калибровочные модели</string>
<string name="MenuFileCalibrationsModelsDescription">Библиотека калибровочных моделей</string>
<string name="MenuFileCalibrationsModelsXYZCube">Калибровочный куб</string>
<string name="MenuFileCalibrationsModelsBunny">Заяц</string>
<string name="MenuFileCalibrationsModelsFox">Лис</string>
<string name="MenuFileCalibrationsModelsBox">Куб</string>
<string name="MenuFileCalibrationsModelsCone">Конус</string>
<string name="MenuFileCalibrationsModelsCylinder">Цилиндр</string>
<string name="MenuFileCalibrationsModelsPyramid">Пирамида</string>
<string name="MenuFileCalibrationsModelsSphere">Сфера</string>
<string name="MenuFileOpenFileLoaded">Файл загружен.</string>
<string name="MenuFileImportProfiles">Импорт. профилей</string>
<string name="MenuFileImportProfilesFailed">Не удалось импортировать</string>
+11
View File
@@ -20,6 +20,17 @@
<string name="MenuFileCalibrationsLADescription">Linear/Pressure Advance Calibration</string>
<string name="MenuFileCalibrationsRetract">K3D Retractions</string>
<string name="MenuFileCalibrationsRetractDescription">Retraction distance and speed calibration</string>
<string name="MenuFileCalibrationsModels">Calibration models</string>
<string name="MenuFileCalibrationsModelsDescription">Calibration models library</string>
<string name="MenuFileCalibrationsModels3DBenchy" translatable="false">3D Benchy</string>
<string name="MenuFileCalibrationsModelsXYZCube">Calibration cube</string>
<string name="MenuFileCalibrationsModelsBunny">Bunny</string>
<string name="MenuFileCalibrationsModelsFox">Fox</string>
<string name="MenuFileCalibrationsModelsBox">Box</string>
<string name="MenuFileCalibrationsModelsCone">Cone</string>
<string name="MenuFileCalibrationsModelsCylinder">Cylinder</string>
<string name="MenuFileCalibrationsModelsPyramid">Pyramid</string>
<string name="MenuFileCalibrationsModelsSphere">Sphere</string>
<string name="MenuFileImportProfiles">Import profiles</string>
<string name="MenuFileImportProfilesFailed">Import failed</string>
<string name="MenuFileImportProfilesFailedNotIni">Not an .ini file</string>