Display web pannel if configured

This commit is contained in:
YTKAB0BP
2025-02-25 22:02:36 +03:00
parent 55610b408a
commit 17b6b6c8ec
2 changed files with 293 additions and 2 deletions
@@ -1,13 +1,16 @@
package ru.ytkab0bp.slicebeam.fragment;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Process;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@@ -33,6 +36,7 @@ import ru.ytkab0bp.slicebeam.components.bed_menu.FileMenu;
import ru.ytkab0bp.slicebeam.components.bed_menu.OrientationMenu;
import ru.ytkab0bp.slicebeam.components.bed_menu.SliceMenu;
import ru.ytkab0bp.slicebeam.components.bed_menu.TransformMenu;
import ru.ytkab0bp.slicebeam.config.ConfigObject;
import ru.ytkab0bp.slicebeam.events.NeedSnackbarEvent;
import ru.ytkab0bp.slicebeam.events.SlicingProgressEvent;
import ru.ytkab0bp.slicebeam.navigation.Fragment;
@@ -43,6 +47,7 @@ import ru.ytkab0bp.slicebeam.slic3r.Slic3rRuntimeError;
import ru.ytkab0bp.slicebeam.theme.ThemesRepo;
import ru.ytkab0bp.slicebeam.utils.Vec3d;
import ru.ytkab0bp.slicebeam.utils.ViewUtils;
import ru.ytkab0bp.slicebeam.view.BedSwipeDownLayout;
import ru.ytkab0bp.slicebeam.view.DividerView;
import ru.ytkab0bp.slicebeam.view.GLView;
import ru.ytkab0bp.slicebeam.view.ThemeBottomNavigationView;
@@ -97,6 +102,9 @@ public class BedFragment extends Fragment {
private GCodeProcessorResult gCodeResult;
private UnfoldMenu currentUnfoldMenu;
private BedSwipeDownLayout swipeDownLayout;
private WebView panelWebView;
private static String tempFileName;
private static File tempExportingFile;
@@ -158,6 +166,9 @@ public class BedFragment extends Fragment {
currentUnfoldMenu.dismiss();
return true;
}
if (swipeDownLayout.onBackPressed()) {
return true;
}
if (currentMenuSlot != 0) {
navigationView.setSelectedItemId(0);
return true;
@@ -191,6 +202,24 @@ public class BedFragment extends Fragment {
public void onResume() {
super.onResume();
glView.onResume();
ConfigObject cfg = SliceBeam.CONFIG.findPrinter(SliceBeam.CONFIG.presets.get("printer"));
boolean enable = cfg != null && cfg.get("host_type") != null && !TextUtils.isEmpty(cfg.get("print_host"));
swipeDownLayout.setEnableTop(enable);
if (enable) {
String host = cfg.get("print_host");
if (host.contains(":")) {
try {
int port = Integer.parseInt(host.split(":")[1]);
if (port >= 7125 && port <= 7200) {
host = host.split(":")[0];
}
} catch (Exception ignored) {}
}
if (!host.startsWith("http://")) {
host = "http://" + host;
}
panelWebView.loadUrl(host);
}
}
@Override
@@ -199,6 +228,7 @@ public class BedFragment extends Fragment {
glView.onPause();
}
@SuppressLint("SetJavaScriptEnabled")
@Override
public View onCreateView(Context ctx) {
glView = new GLView(ctx);
@@ -229,7 +259,23 @@ public class BedFragment extends Fragment {
ll.addView(menuView, new LinearLayout.LayoutParams(ViewUtils.dp(MENU_SIZE_DP), ViewGroup.LayoutParams.MATCH_PARENT));
}
ll.addView(glView, new LinearLayout.LayoutParams(portrait ? ViewGroup.LayoutParams.MATCH_PARENT : 0, portrait ? 0 : ViewGroup.LayoutParams.MATCH_PARENT, 1f));
swipeDownLayout = new BedSwipeDownLayout(ctx);
panelWebView = new WebView(ctx);
panelWebView.getSettings().setJavaScriptEnabled(true);
if (portrait) {
LinearLayout inner = new LinearLayout(ctx);
inner.setOrientation(LinearLayout.VERTICAL);
ll = inner;
inner.addView(glView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f));
swipeDownLayout.addView(inner);
swipeDownLayout.addView(panelWebView);
} else {
swipeDownLayout.addView(glView);
swipeDownLayout.addView(panelWebView);
ll.addView(swipeDownLayout, new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1f));
}
if (portrait) {
ll.addView(menuView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewUtils.dp(MENU_SIZE_DP)));
@@ -328,7 +374,11 @@ public class BedFragment extends Fragment {
return true;
});
overlayLayout.addView(contentView = ll);
if (portrait) {
overlayLayout.addView(contentView = swipeDownLayout);
} else {
overlayLayout.addView(contentView = ll);
}
overlayLayout.addView(snackbarsLayout = new CoordinatorLayout(ctx), new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) {{
if (portrait) {
bottomMargin = ViewUtils.dp(80 * 2);
@@ -0,0 +1,241 @@
package ru.ytkab0bp.slicebeam.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils;
import androidx.dynamicanimation.animation.FloatValueHolder;
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
import ru.ytkab0bp.slicebeam.theme.IThemeView;
import ru.ytkab0bp.slicebeam.theme.ThemesRepo;
import ru.ytkab0bp.slicebeam.utils.ViewUtils;
public class BedSwipeDownLayout extends FrameLayout implements IThemeView {
private final static int TOP_MARGIN_DP = 28;
private final static int ARROW_LENGTH_DP = 11;
private Path path = new Path();
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint dimmPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float progress = 0;
private boolean openEnabled = true;
private boolean processingSwipe;
private SpringAnimation springAnimation;
private float startProgress;
private GestureDetector gestureDetector;
public BedSwipeDownLayout(@NonNull Context context) {
super(context);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(ViewUtils.dp(3));
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setPathEffect(new CornerPathEffect(ViewUtils.dp(6)));
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(@NonNull MotionEvent e) {
if (springAnimation != null) return false;
processingSwipe = true;
startProgress = progress;
return true;
}
@Override
public boolean onSingleTapUp(@NonNull MotionEvent e) {
if (springAnimation != null) return false;
animateTo(1f);
return true;
}
@Override
public boolean onScroll(@Nullable MotionEvent e1, @NonNull MotionEvent e2, float distanceX, float distanceY) {
if (springAnimation != null) return false;
if (processingSwipe) {
progress = MathUtils.clamp(startProgress + (e2.getY() - e1.getY()) / getHeight(), 0, 1);
invalidateTranslation();
return true;
}
return false;
}
@Override
public boolean onFling(@Nullable MotionEvent e1, @NonNull MotionEvent e2, float velocityX, float velocityY) {
if (springAnimation != null) return false;
if (velocityY >= 1500) {
animateTo(1f);
return true;
}
return false;
}
});
setWillNotDraw(false);
onApplyTheme();
}
public boolean onBackPressed() {
if (springAnimation != null) {
return true;
}
if (progress == 1f) {
animateTo(0f);
return true;
}
return false;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (openEnabled) {
if (processingSwipe) {
boolean d = gestureDetector.onTouchEvent(ev);
if (ev.getActionMasked() == MotionEvent.ACTION_UP || ev.getActionMasked() == MotionEvent.ACTION_CANCEL) {
processingSwipe = false;
if (springAnimation == null && progress != 0 && progress != 1) {
animateTo(progress > 0.5f ? 1f : 0f);
}
}
return d;
}
if (progress != 1f && springAnimation == null) {
if (ev.getY() < ViewUtils.dp(TOP_MARGIN_DP) + getHeight() * progress) {
return gestureDetector.onTouchEvent(ev);
}
}
}
return super.dispatchTouchEvent(ev);
}
@Override
protected boolean drawChild(@NonNull Canvas canvas, View child, long drawingTime) {
int i = indexOfChild(child);
canvas.save();
float tY = -getHeight() * (1f - progress);
if (openEnabled && i != 0) {
int clr = ThemesRepo.getColor(android.R.attr.windowBackground);
dimmPaint.setColor(clr);
canvas.drawRect(0, child.getTop() + tY, child.getWidth(), child.getTop() + tY + child.getHeight(), dimmPaint);
canvas.clipRect(0, child.getTop() + tY, child.getWidth(), child.getTop() + tY + child.getHeight());
}
boolean ch = super.drawChild(canvas, child, drawingTime);
if (openEnabled) {
if (i == 0) {
dimmPaint.setColor(Color.argb((int) (0x66 * progress), 0, 0, 0));
canvas.drawPaint(dimmPaint);
}
}
canvas.restore();
return ch;
}
@Override
public void draw(@NonNull Canvas canvas) {
super.draw(canvas);
if (openEnabled) {
path.rewind();
float cx = getWidth() * 0.5f, cy = ViewUtils.dp(TOP_MARGIN_DP) * 0.5f + getHeight() * progress;
float angle = (float) Math.toRadians(25) * (1f - Math.min(progress, 0.5f) / 0.5f);
int len = ViewUtils.dp(ARROW_LENGTH_DP);
path.moveTo(cx, cy);
path.lineTo((float) (cx - Math.cos(angle) * len), (float) (cy - Math.sin(angle) * len));
path.moveTo(cx, cy);
path.lineTo((float) (cx + Math.cos(angle) * len), (float) (cy - Math.sin(angle) * len));
canvas.drawPath(path, paint);
}
}
private void animateTo(float to) {
springAnimation = new SpringAnimation(new FloatValueHolder(progress))
.setMinimumVisibleChange(1 / 500f)
.setSpring(new SpringForce(to)
.setStiffness(600f)
.setDampingRatio(1f))
.addUpdateListener((animation, value, velocity) -> {
progress = value;
invalidateTranslation();
})
.addEndListener((animation, canceled, value, velocity) -> {
springAnimation = null;
processingSwipe = false;
});
springAnimation.start();
}
private void invalidateTranslation() {
if (getChildCount() > 0) {
getChildAt(0).setTranslationY(getHeight() * progress * 0.25f);
for (int i = 1; i < getChildCount(); i++) {
View ch = getChildAt(i);
ch.setTranslationY(-getHeight() * (1f - progress) * 0.75f);
ch.setAlpha(progress);
}
}
invalidate();
}
public void setEnableTop(boolean enable) {
if (enable == openEnabled) {
return;
}
openEnabled = enable;
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
if (getChildCount() > 0) {
getChildAt(0).measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height - ViewUtils.dp(TOP_MARGIN_DP) * (openEnabled ? 1 : 0), MeasureSpec.EXACTLY));
for (int i = 1; i < getChildCount(); i++) {
getChildAt(i).measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (openEnabled && getChildCount() > 0) {
View first = getChildAt(0);
first.layout(0, ViewUtils.dp(TOP_MARGIN_DP), first.getMeasuredWidth(), ViewUtils.dp(TOP_MARGIN_DP) + first.getMeasuredHeight());
for (int i = 1; i < getChildCount(); i++) {
View ch = getChildAt(i);
ch.layout(0, 0, ch.getMeasuredWidth(), ch.getMeasuredHeight());
}
}
invalidateTranslation();
}
@Override
public void onApplyTheme() {
paint.setColor(ColorUtils.setAlphaComponent(ThemesRepo.getColor(android.R.attr.colorControlHighlight), 0x44));
}
}