2023-11-09 08:37:59 +08:00
|
|
|
package com.xixun.xixunplayer;
|
|
|
|
|
2023-11-10 20:44:11 +08:00
|
|
|
import android.annotation.SuppressLint;
|
2023-11-09 08:37:59 +08:00
|
|
|
import android.content.Context;
|
|
|
|
import android.net.Uri;
|
2023-12-01 16:17:06 +08:00
|
|
|
import android.view.View;
|
2023-11-09 08:37:59 +08:00
|
|
|
import android.webkit.WebView;
|
|
|
|
import android.webkit.WebViewClient;
|
|
|
|
import android.widget.ImageView;
|
|
|
|
|
|
|
|
import java.io.File;
|
2024-01-24 20:17:59 +08:00
|
|
|
import java.text.ParseException;
|
|
|
|
import java.text.SimpleDateFormat;
|
2023-11-10 09:47:38 +08:00
|
|
|
import java.util.ArrayList;
|
2024-01-24 20:17:59 +08:00
|
|
|
import java.util.HashMap;
|
2023-11-09 08:37:59 +08:00
|
|
|
|
2023-12-01 16:17:06 +08:00
|
|
|
import gnph.util.Dates;
|
2023-11-09 08:37:59 +08:00
|
|
|
import gnph.util.JSList;
|
|
|
|
import gnph.util.JSMap;
|
|
|
|
import pl.droidsonroids.gif.GifImageView;
|
|
|
|
|
2023-11-10 20:44:11 +08:00
|
|
|
@SuppressLint("ViewConstructor")
|
2023-12-01 16:17:06 +08:00
|
|
|
public class Prog extends AbsLayout {
|
2023-11-09 08:37:59 +08:00
|
|
|
|
2023-11-10 09:47:38 +08:00
|
|
|
ArrayList<Page> pages = new ArrayList<>();
|
2023-12-01 16:17:06 +08:00
|
|
|
ArrayList<Integer> avas = new ArrayList<>();
|
2023-11-10 09:47:38 +08:00
|
|
|
|
2023-12-01 16:17:06 +08:00
|
|
|
public Prog(JSMap task, Context context) {
|
2023-11-09 08:37:59 +08:00
|
|
|
super(context);
|
2023-11-10 09:47:38 +08:00
|
|
|
JSList<JSMap> jpages = task.jslist("items");
|
2024-01-24 20:17:59 +08:00
|
|
|
JSList<Long> partLengths = task.jslist("partLengths");
|
|
|
|
var isVertical = task.bool("isVertical");
|
|
|
|
var partObj = task;
|
|
|
|
if(partLengths==null) {
|
|
|
|
try {
|
|
|
|
var _program = jpages.get(0).jsmap("_program");
|
|
|
|
partLengths = _program.jslist("splitWidths");
|
|
|
|
isVertical = _program.bool("isVer");
|
|
|
|
partObj = _program;
|
|
|
|
} catch (Throwable ignored){}
|
|
|
|
}
|
2024-01-26 18:31:10 +08:00
|
|
|
var width = partObj.intg("width");
|
|
|
|
var height = partObj.intg("height");
|
2024-01-24 20:17:59 +08:00
|
|
|
AbsLayout box = this;
|
|
|
|
if(partLengths!=null && partLengths.size() > 1) {
|
|
|
|
box = new AbsLayout(context);
|
|
|
|
addView(box, new AbsLayout.LayoutParams(0, 0, width, height));
|
|
|
|
var mask = new View(context);
|
|
|
|
mask.setBackgroundColor(0xff000000);
|
|
|
|
var len0 = partLengths.get(0).intValue();
|
|
|
|
addView(mask, isVertical ? new AbsLayout.LayoutParams(0, len0, width, height - len0) : new AbsLayout.LayoutParams(len0, 0, width - len0, height));
|
|
|
|
int x = 0, y = 0;
|
|
|
|
for(int i=1; i<partLengths.size(); i++) {
|
|
|
|
var part = new SrcCopy(context, box);
|
|
|
|
if(isVertical) {
|
|
|
|
y -= partLengths.get(i-1);
|
|
|
|
x += width;
|
|
|
|
addView(part, new AbsLayout.LayoutParams(x, y, width, partLengths.get(i).intValue() - y));
|
|
|
|
} else {
|
|
|
|
x -= partLengths.get(i-1);
|
|
|
|
y += height;
|
|
|
|
addView(part, new AbsLayout.LayoutParams(x, y, partLengths.get(i).intValue() - x, height));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-11-10 09:47:38 +08:00
|
|
|
for(var pageMap : jpages) {
|
2023-11-09 08:37:59 +08:00
|
|
|
var _program = pageMap.jsmap("_program");
|
|
|
|
JSList<JSMap> layers = _program.jslist("layers");
|
2024-01-24 20:17:59 +08:00
|
|
|
if(layers==null || layers.isEmpty()) continue;
|
2023-11-10 09:47:38 +08:00
|
|
|
var page = new Page();
|
2024-01-26 18:31:10 +08:00
|
|
|
page.repeatTimes = pageMap.intg("repeatTimes", 1);
|
2023-11-09 08:37:59 +08:00
|
|
|
page.parse(pageMap.jslist("schedules"));
|
2024-01-24 20:17:59 +08:00
|
|
|
HashMap<String, EleVideo> videoMap = new HashMap<>();
|
2023-11-09 08:37:59 +08:00
|
|
|
for(int ll=layers.size()-1; ll>=0; ll--) {
|
2023-12-01 16:17:06 +08:00
|
|
|
var layer = new Layer();
|
2023-11-10 09:47:38 +08:00
|
|
|
layer.isLoop = layers.get(ll).bool("repeat");
|
2023-11-09 08:37:59 +08:00
|
|
|
JSList<JSMap> sources = layers.get(ll).jslist("sources");
|
|
|
|
var border = layers.get(ll).jsmap("border");
|
|
|
|
EleBorder bdEle = null;
|
|
|
|
int bdWidth = 0, bdStart = 0xffff, bdEnd = 0;
|
|
|
|
if(border!=null) {
|
|
|
|
bdEle = new EleBorder(Util.programDir+"/"+border.stnn("img"), border.stnn("eff"), border.intg("speed"), context);
|
|
|
|
bdWidth = bdEle.img.getHeight();
|
|
|
|
}
|
2024-01-24 20:17:59 +08:00
|
|
|
var src = new Source();
|
2023-11-09 08:37:59 +08:00
|
|
|
for(var source : sources) {
|
2024-01-24 20:17:59 +08:00
|
|
|
src.type = source.stnn("_type");
|
|
|
|
if(src.type.isEmpty()) continue;
|
2023-11-09 08:37:59 +08:00
|
|
|
var timeSpan = source.intg("timeSpan")*1000;
|
|
|
|
if(timeSpan==0) continue;
|
2024-01-24 20:17:59 +08:00
|
|
|
var geo = new AbsLayout.LayoutParams(source.intg("left")+bdWidth, source.intg("top")+bdWidth, source.intg("width")-bdWidth-bdWidth, source.intg("height")-bdWidth-bdWidth);
|
|
|
|
boolean notAudio = ! src.type.equals("Audio");
|
2024-01-26 18:31:10 +08:00
|
|
|
if((geo.width<=0 || geo.height<=0 || (geo.y>=height && height>0) || (geo.x>=width && width>0)) && notAudio) continue;
|
2024-01-24 20:17:59 +08:00
|
|
|
src.startTime = source.intg("playTime")*1000;
|
|
|
|
if(bdStart > src.startTime) bdStart = src.startTime;
|
|
|
|
src.endTime = src.startTime + timeSpan;
|
|
|
|
if(bdEnd < src.endTime) bdEnd = src.endTime;
|
|
|
|
if(layer.dur < src.endTime) layer.dur = src.endTime;
|
|
|
|
if(notAudio) {
|
|
|
|
if(page.sDur < src.endTime) page.sDur = src.endTime;
|
|
|
|
} else if(page.audioDur < src.endTime) page.audioDur = src.endTime;
|
|
|
|
|
|
|
|
src.entryDur = source.intg("entryEffectTimeSpan")*60;
|
|
|
|
if(src.entryDur > 0) {
|
|
|
|
var effect = source.str("entryEffect");
|
|
|
|
if(effect == null || effect.equalsIgnoreCase("None")) src.entryDur = 0;
|
|
|
|
else if(effect.equalsIgnoreCase("Random")) src.isEntryRand = true;
|
|
|
|
else {
|
|
|
|
effect = effect.replace("MOVING", "MOVE");
|
|
|
|
effect = effect.replace("LEFT_TOP", "TL");
|
|
|
|
effect = effect.replace("RIGHT_TOP", "TR");
|
|
|
|
effect = effect.replace("RIGHT_BOTTOM", "BR");
|
|
|
|
effect = effect.replace("LEFT_BOTTOM", "BL");
|
|
|
|
effect = effect.replace("ALPHA", "FADE");
|
|
|
|
effect = effect.replace("_IN", "");
|
|
|
|
effect = effect.replace("_OUT", "");
|
|
|
|
try {
|
|
|
|
src.entryEff = Effect.valueOf(effect);
|
|
|
|
} catch (Throwable e) {
|
|
|
|
if(effect.equalsIgnoreCase("ROTATE_RIGHT")) src.entryEff = Effect.ROTATE;
|
|
|
|
else if(effect.equalsIgnoreCase("ROTATE_LEFT")) src.entryEff = Effect.ROTATE_R;
|
|
|
|
else src.entryDur = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
src.exitDur = source.intg("exitEffectTimeSpan")*60;
|
|
|
|
if(src.exitDur > 0) {
|
|
|
|
var effect = source.str("exitEffect");
|
|
|
|
if(effect == null || effect.equalsIgnoreCase("None")) src.exitDur = 0;
|
|
|
|
else if(effect.equalsIgnoreCase("Random")) src.isExitRand = true;
|
|
|
|
else {
|
|
|
|
effect = effect.replace("MOVING", "MOVE");
|
|
|
|
effect = effect.replace("LEFT_TOP", "TL");
|
|
|
|
effect = effect.replace("RIGHT_TOP", "TR");
|
|
|
|
effect = effect.replace("RIGHT_BOTTOM", "BR");
|
|
|
|
effect = effect.replace("LEFT_BOTTOM", "BL");
|
|
|
|
effect = effect.replace("ALPHA", "FADE");
|
|
|
|
effect = effect.replace("_IN", "");
|
|
|
|
effect = effect.replace("_OUT", "");
|
|
|
|
try {
|
|
|
|
src.exitEff = Effect.valueOf(effect);
|
|
|
|
} catch (Throwable e) {
|
|
|
|
if(effect.equalsIgnoreCase("ROTATE_RIGHT")) src.exitEff = Effect.ROTATE;
|
|
|
|
else if(effect.equalsIgnoreCase("ROTATE_LEFT")) src.exitEff = Effect.ROTATE_R;
|
|
|
|
else src.exitDur = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(src.exitDur!=0) src.exitStart = timeSpan*60/1000 - src.exitDur;
|
|
|
|
|
|
|
|
var id = source.stnn("id");
|
|
|
|
src.view = null;
|
|
|
|
if(src.type.equals("Image")) {
|
|
|
|
var isGif = source.stnn("fileExt").toLowerCase().endsWith("gif");
|
|
|
|
if(isGif) {
|
|
|
|
var imgView = new GifImageView(context);
|
|
|
|
imgView.setImageURI(src.uri = Uri.fromFile(new File(Util.programDir + "/" + id)));
|
|
|
|
imgView.setScaleType(ImageView.ScaleType.FIT_XY);
|
|
|
|
src.view = imgView;
|
|
|
|
} else {
|
|
|
|
var imgView = new ImageView(context);
|
|
|
|
imgView.setImageURI(Uri.fromFile(new File(Util.programDir + "/" + id)));
|
|
|
|
imgView.setScaleType(ImageView.ScaleType.FIT_XY);
|
|
|
|
src.view = imgView;
|
|
|
|
}
|
|
|
|
} else if(src.type.equals("MultiPng") || src.type.equals("SplitText")) {
|
2023-11-10 20:44:11 +08:00
|
|
|
JSList<JSMap> imgs = source.jslist("arrayPics");
|
|
|
|
if(imgs.isEmpty()) continue;
|
2024-01-24 20:17:59 +08:00
|
|
|
if(imgs.size()==1 && imgs.get(0).intg("picDuration")==0) src.view = new EleScroll(context, imgs.get(0));
|
|
|
|
else {
|
|
|
|
var start = src.startTime;
|
|
|
|
var ele0 = src;
|
|
|
|
for(var map : imgs) {
|
|
|
|
var picDur = map.intg("picDuration")*1000;
|
|
|
|
if(picDur==0) continue;
|
|
|
|
src.type = "Image";
|
|
|
|
src.startTime = start;
|
|
|
|
src.endTime = start = src.startTime + picDur;
|
|
|
|
if(src!=ele0) {
|
|
|
|
src.entryEff = ele0.entryEff;
|
|
|
|
src.exitEff = ele0.exitEff;
|
|
|
|
src.entryDur = ele0.entryDur;
|
|
|
|
src.exitDur = ele0.exitDur;
|
|
|
|
src.exitStart = ele0.exitStart;
|
|
|
|
src.isEntryRand = ele0.isEntryRand;
|
|
|
|
src.isExitRand = ele0.isExitRand;
|
|
|
|
}
|
|
|
|
var imgView = new ImageView(context);
|
|
|
|
imgView.setImageURI(Uri.fromFile(new File(Util.programDir + "/" + map.stnn("id"))));
|
|
|
|
imgView.setScaleType(ImageView.ScaleType.FIT_XY);
|
|
|
|
src.view = imgView;
|
|
|
|
src.view.setVisibility(GONE);
|
|
|
|
src.view.setLayoutParams(geo);
|
|
|
|
box.addView(src.view);
|
|
|
|
layer.srcs.add(src);
|
|
|
|
src = new Source();
|
2023-11-10 20:44:11 +08:00
|
|
|
}
|
2024-01-24 20:17:59 +08:00
|
|
|
}
|
2024-01-25 20:43:39 +08:00
|
|
|
} else if(src.type.equals("DigitalClock")) src.view = new SrcDigitalClock(context, source);
|
|
|
|
else if(src.type.startsWith("DigitalClock")) src.view = new SrcDigiClock(context, source);
|
2024-01-24 20:17:59 +08:00
|
|
|
else if(src.type.equals("AnalogClock")) src.view = new EleAnaClock(geo.width, geo.height, Util.programDir + "/" + id, source, context);
|
|
|
|
else if(src.type.equals("Audio")) src.view = new EleVideo(context, Util.programDir + "/" +id, source.intg("vol", 100) / 100.0f);
|
|
|
|
else if(src.type.equals("Video")) {
|
|
|
|
var key = id + src.startTime + src.endTime;
|
|
|
|
var videoView = videoMap.get(key);
|
|
|
|
if(videoView!=null) {
|
|
|
|
var geoOld = (AbsLayout.LayoutParams) videoView.getLayoutParams();
|
|
|
|
if(geo.width*geo.height > geoOld.width*geoOld.height) {
|
|
|
|
videoView.setLayoutParams(geo);
|
|
|
|
geo = geoOld;
|
2023-11-10 20:44:11 +08:00
|
|
|
}
|
2024-01-24 20:17:59 +08:00
|
|
|
src.view = new SrcCopy(context, videoView);
|
|
|
|
((SrcCopy) src.view).scaleX = 0;
|
|
|
|
} else {
|
|
|
|
src.view = new EleVideo(context, Util.programDir+"/"+id, source.intg("vol", 100) / 100.0f);
|
|
|
|
videoMap.put(key, (EleVideo) src.view);
|
2023-11-10 20:44:11 +08:00
|
|
|
}
|
2024-01-24 20:17:59 +08:00
|
|
|
} else if(src.type.equals("WebURL")) {
|
2023-11-09 08:37:59 +08:00
|
|
|
var webView = new WebView(context);
|
|
|
|
webView.setWebViewClient(new WebViewClient() {
|
|
|
|
@Override
|
|
|
|
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
webView.loadUrl(source.stnn("url"));
|
2024-01-24 20:17:59 +08:00
|
|
|
src.view = webView;
|
2023-11-09 08:37:59 +08:00
|
|
|
}
|
2024-01-24 20:17:59 +08:00
|
|
|
else if(src.type.equals("Timer")) src.view = new SrcTimer(context, source);
|
|
|
|
else if(src.type.equals("Countdown")) src.view = new SrcCountdown(context, source);
|
2024-01-26 18:31:10 +08:00
|
|
|
else if(src.type.startsWith("Environ")) src.view = new SrcEnviron(context, source);
|
|
|
|
else if(src.type.startsWith("MultiLineText")) src.view = new SrcSensor(context, source);
|
2023-11-09 08:37:59 +08:00
|
|
|
else continue;
|
2024-01-24 20:17:59 +08:00
|
|
|
if(src.view==null) continue;
|
|
|
|
src.view.setVisibility(GONE);
|
|
|
|
src.view.setLayoutParams(geo);
|
|
|
|
box.addView(src.view);
|
|
|
|
layer.srcs.add(src);
|
|
|
|
src = new Source();
|
2023-11-09 08:37:59 +08:00
|
|
|
}
|
|
|
|
if(bdEle!=null && ! sources.isEmpty()) {
|
|
|
|
JSList<Long> geometry = border.jslist("geometry");
|
2024-01-24 20:17:59 +08:00
|
|
|
src.startTime = bdStart;
|
|
|
|
src.endTime = bdEnd;
|
|
|
|
src.view = bdEle;
|
|
|
|
src.view.setVisibility(GONE);
|
|
|
|
box.addView(src.view, new AbsLayout.LayoutParams(geometry.get(0).intValue(), geometry.get(1).intValue(), geometry.get(2).intValue(), geometry.get(3).intValue()));
|
|
|
|
layer.srcs.add(src);
|
2023-11-09 08:37:59 +08:00
|
|
|
}
|
2024-01-24 20:17:59 +08:00
|
|
|
if(! layer.srcs.isEmpty()) page.layers.add(layer);
|
|
|
|
}
|
|
|
|
if(page.sDur==0) {
|
|
|
|
if(page.audioDur > 0) page.sDur = page.audioDur;
|
|
|
|
else continue;
|
2023-11-09 08:37:59 +08:00
|
|
|
}
|
2023-12-01 16:17:06 +08:00
|
|
|
page.tDur = page.sDur * page.repeatTimes;
|
2023-11-09 08:37:59 +08:00
|
|
|
for_layer: for(int ll=0; ll<page.layers.size(); ll++) {
|
|
|
|
var layer = page.layers.get(ll);
|
2024-01-24 20:17:59 +08:00
|
|
|
for(int ss=0; ss<layer.srcs.size(); ss++) {
|
|
|
|
var src = layer.srcs.get(ss);
|
|
|
|
if(src.startTime >= page.sDur) {
|
|
|
|
if(layer.srcs.size() > 1) layer.srcs.remove(ss--);
|
2023-11-10 20:44:11 +08:00
|
|
|
else {
|
2023-11-09 08:37:59 +08:00
|
|
|
page.layers.remove(ll--);
|
|
|
|
continue for_layer;
|
|
|
|
}
|
2024-01-24 20:17:59 +08:00
|
|
|
} else if(src.endTime > page.sDur) src.endTime = page.sDur;
|
2023-11-09 08:37:59 +08:00
|
|
|
}
|
2023-12-01 16:17:06 +08:00
|
|
|
if(layer.dur > page.sDur) layer.dur = page.sDur;
|
|
|
|
if(layer.dur == page.sDur) layer.isLoop = false;
|
2023-11-09 08:37:59 +08:00
|
|
|
}
|
2023-11-10 09:47:38 +08:00
|
|
|
pages.add(page);
|
2023-11-09 08:37:59 +08:00
|
|
|
}
|
|
|
|
}
|
2023-12-01 16:17:06 +08:00
|
|
|
|
|
|
|
void release() {
|
|
|
|
try {
|
|
|
|
setVisibility(GONE);
|
|
|
|
View view;
|
|
|
|
for(int cc=0; cc<getChildCount(); cc++) if((view = getChildAt(cc)) instanceof EleVideo) ((EleVideo) view).release();
|
|
|
|
} catch (Throwable e) {
|
2024-01-24 20:17:59 +08:00
|
|
|
Util.printStackTrace(e);
|
2023-12-01 16:17:06 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static class Source {
|
|
|
|
View view;
|
2024-01-24 20:17:59 +08:00
|
|
|
long startMilli, endMilli = Long.MAX_VALUE;
|
|
|
|
int startTime, entryDur, exitStart = Integer.MAX_VALUE, exitDur, endTime, ff;
|
|
|
|
Effect entryEff, exitEff;
|
2023-12-01 16:17:06 +08:00
|
|
|
String type;
|
|
|
|
Uri uri;
|
2024-01-24 20:17:59 +08:00
|
|
|
boolean isEntryRand, isExitRand;
|
2023-12-01 16:17:06 +08:00
|
|
|
|
|
|
|
void show() {
|
|
|
|
if(view.getVisibility()==VISIBLE) return;
|
|
|
|
view.setVisibility(VISIBLE);
|
2024-01-24 20:17:59 +08:00
|
|
|
ff = 0;
|
|
|
|
if(isEntryRand) entryEff = Effect.values()[Util.rand.nextInt(Effect.values().length)];
|
|
|
|
if(isExitRand) exitEff = Effect.values()[Util.rand.nextInt(Effect.values().length)];
|
|
|
|
resetEff();
|
|
|
|
doEff();
|
2023-12-01 16:17:06 +08:00
|
|
|
}
|
|
|
|
void hide() {
|
|
|
|
if(view.getVisibility()!=VISIBLE) return;
|
|
|
|
view.setVisibility(GONE);
|
|
|
|
if(uri!=null) ((GifImageView) view).setImageURI(uri);
|
|
|
|
}
|
2024-01-24 20:17:59 +08:00
|
|
|
void doEff() {
|
|
|
|
var w = view.getLayoutParams().width;
|
|
|
|
var h = view.getLayoutParams().height;
|
|
|
|
if(ff < entryDur) {
|
|
|
|
if(entryEff == Effect.EXPAND_HOR) view.setScaleX(ff / (float) entryDur);
|
|
|
|
else if(entryEff == Effect.EXPAND_VER) view.setScaleY(ff / (float) entryDur);
|
|
|
|
else if(entryEff == Effect.EXPAND_LEFT) {
|
|
|
|
view.setScaleX(ff / (float) entryDur);
|
|
|
|
view.setTranslationX((1 - view.getScaleX()) * w / 2);
|
|
|
|
} else if(entryEff == Effect.EXPAND_TOP) {
|
|
|
|
view.setScaleY(ff / (float) entryDur);
|
|
|
|
view.setTranslationY((1 - view.getScaleY()) * h / 2);
|
|
|
|
} else if(entryEff == Effect.EXPAND_RIGHT) {
|
|
|
|
view.setScaleX(ff / (float) entryDur);
|
|
|
|
view.setTranslationX((view.getScaleX() - 1) * w / 2);
|
|
|
|
} else if(entryEff == Effect.EXPAND_BOTTOM) {
|
|
|
|
view.setScaleY(ff / (float) entryDur);
|
|
|
|
view.setTranslationY((view.getScaleY() - 1) * h / 2);
|
|
|
|
}
|
|
|
|
else if(entryEff == Effect.MOVE_LEFT) view.setTranslationX(w - ff*w/(float) entryDur);
|
|
|
|
else if(entryEff == Effect.MOVE_TOP) view.setTranslationY(h - ff*h/(float) entryDur);
|
|
|
|
else if(entryEff == Effect.MOVE_RIGHT) view.setTranslationX(ff*w/(float) entryDur - w);
|
|
|
|
else if(entryEff == Effect.MOVE_BOTTOM) view.setTranslationY(ff*h/(float) entryDur - h);
|
|
|
|
else if(entryEff == Effect.FADE) view.setAlpha(ff / (float) entryDur);
|
|
|
|
else if(entryEff == Effect.ZOOM) {
|
|
|
|
view.setScaleX(ff / (float) entryDur);
|
|
|
|
view.setScaleY(view.getScaleX());
|
|
|
|
} else if(entryEff == Effect.ZOOM_TL) {
|
|
|
|
var rate = ff / (float) entryDur;
|
|
|
|
view.setTranslationX((rate - 1) * w / 2);
|
|
|
|
view.setTranslationY((rate - 1) * h / 2);
|
|
|
|
view.setScaleX(rate);
|
|
|
|
view.setScaleY(rate);
|
|
|
|
} else if(entryEff == Effect.ZOOM_BR) {
|
|
|
|
var rate = ff / (float) entryDur;
|
|
|
|
view.setTranslationX((1 - rate) * w / 2);
|
|
|
|
view.setTranslationY((1 - rate) * h / 2);
|
|
|
|
view.setScaleX(rate);
|
|
|
|
view.setScaleY(rate);
|
|
|
|
} else if(entryEff == Effect.ZOOM_TR) {
|
|
|
|
var rate = ff / (float) entryDur;
|
|
|
|
view.setTranslationX((1 - rate) * w / 2);
|
|
|
|
view.setTranslationY((rate - 1) * h / 2);
|
|
|
|
view.setScaleX(rate);
|
|
|
|
view.setScaleY(rate);
|
|
|
|
} else if(entryEff == Effect.ZOOM_BL) {
|
|
|
|
var rate = ff / (float) entryDur;
|
|
|
|
view.setTranslationX((rate - 1) * w / 2);
|
|
|
|
view.setTranslationY((1 - rate) * h / 2);
|
|
|
|
view.setScaleX(rate);
|
|
|
|
view.setScaleY(rate);
|
|
|
|
} else if(entryEff == Effect.ROTATE) {
|
|
|
|
view.setScaleX(ff / (float) entryDur);
|
|
|
|
view.setScaleY(view.getScaleX());
|
|
|
|
view.setRotation(view.getScaleX() * 360);
|
|
|
|
} else if(entryEff == Effect.ROTATE_R) {
|
|
|
|
view.setScaleX(ff / (float) entryDur);
|
|
|
|
view.setScaleY(view.getScaleX());
|
|
|
|
view.setRotation(- view.getScaleX() * 360);
|
|
|
|
}
|
|
|
|
} else if(ff>=exitStart) {
|
|
|
|
var fff = ff - exitStart;
|
|
|
|
if(fff > exitDur) fff = exitDur;
|
|
|
|
if(exitEff == Effect.EXPAND_HOR) view.setScaleX(1 - fff / (float) exitDur);
|
|
|
|
else if(exitEff == Effect.EXPAND_VER) view.setScaleY(1 - fff / (float) exitDur);
|
|
|
|
else if(exitEff == Effect.EXPAND_LEFT) {
|
|
|
|
var rate = fff / (float) exitDur;
|
|
|
|
view.setScaleX(1 - rate);
|
|
|
|
view.setTranslationX(rate * w / 2);
|
|
|
|
} else if(exitEff == Effect.EXPAND_TOP) {
|
|
|
|
var rate = fff / (float) exitDur;
|
|
|
|
view.setScaleY(1 - rate);
|
|
|
|
view.setTranslationY(rate * h / 2);
|
|
|
|
} else if(exitEff == Effect.EXPAND_RIGHT) {
|
|
|
|
var rate = fff / (float) exitDur;
|
|
|
|
view.setScaleX(1 - rate);
|
|
|
|
view.setTranslationX(- rate * w / 2);
|
|
|
|
} else if(exitEff == Effect.EXPAND_BOTTOM) {
|
|
|
|
var rate = fff / (float) exitDur;
|
|
|
|
view.setScaleY(1 - rate);
|
|
|
|
view.setTranslationY(- rate * h / 2);
|
|
|
|
}
|
|
|
|
else if(exitEff == Effect.MOVE_LEFT) view.setTranslationX(- fff*w / (float) exitDur);
|
|
|
|
else if(exitEff == Effect.MOVE_RIGHT) view.setTranslationX(fff*w / (float) exitDur);
|
|
|
|
else if(exitEff == Effect.MOVE_TOP) view.setTranslationY(- fff*h / (float) exitDur);
|
|
|
|
else if(exitEff == Effect.MOVE_BOTTOM) view.setTranslationY(fff*h / (float) exitDur);
|
|
|
|
else if(exitEff == Effect.FADE) view.setAlpha(1 - fff / (float) exitDur);
|
|
|
|
else if(exitEff == Effect.ZOOM) {
|
|
|
|
view.setScaleX(1 - fff / (float) exitDur);
|
|
|
|
view.setScaleY(view.getScaleX());
|
|
|
|
} else if(exitEff == Effect.ZOOM_TL) {
|
|
|
|
var rate = fff / (float) exitDur;
|
|
|
|
view.setTranslationX(- rate * w / 2);
|
|
|
|
view.setTranslationY(- rate * h / 2);
|
|
|
|
view.setScaleX(1 - rate);
|
|
|
|
view.setScaleY(1 - rate);
|
|
|
|
} else if(exitEff == Effect.ZOOM_BR) {
|
|
|
|
var rate = fff / (float) exitDur;
|
|
|
|
view.setTranslationX(rate * w / 2);
|
|
|
|
view.setTranslationY(rate * h / 2);
|
|
|
|
view.setScaleX(1 - rate);
|
|
|
|
view.setScaleY(1 - rate);
|
|
|
|
} else if(exitEff == Effect.ZOOM_TR) {
|
|
|
|
var rate = fff / (float) exitDur;
|
|
|
|
view.setTranslationX(rate * w / 2);
|
|
|
|
view.setTranslationY(- rate * h / 2);
|
|
|
|
view.setScaleX(1 - rate);
|
|
|
|
view.setScaleY(1 - rate);
|
|
|
|
} else if(exitEff == Effect.ZOOM_BL) {
|
|
|
|
var rate = fff / (float) exitDur;
|
|
|
|
view.setTranslationX(- rate * w / 2);
|
|
|
|
view.setTranslationY(rate * h / 2);
|
|
|
|
view.setScaleX(1 - rate);
|
|
|
|
view.setScaleY(1 - rate);
|
|
|
|
} else if(exitEff == Effect.ROTATE) {
|
|
|
|
var rate = fff / (float) exitDur;
|
|
|
|
view.setScaleX(1 - rate);
|
|
|
|
view.setScaleY(view.getScaleX());
|
|
|
|
view.setRotation(rate * 360);
|
|
|
|
} else if(exitEff == Effect.ROTATE_R) {
|
|
|
|
var rate = fff / (float) exitDur;
|
|
|
|
view.setScaleX(1 - rate);
|
|
|
|
view.setScaleY(view.getScaleX());
|
|
|
|
view.setRotation(- rate * 360);
|
|
|
|
}
|
|
|
|
} else resetEff();
|
|
|
|
ff++;
|
|
|
|
}
|
|
|
|
void resetEff() {
|
|
|
|
view.setTranslationX(0);
|
|
|
|
view.setTranslationY(0);
|
|
|
|
view.setAlpha(1);
|
|
|
|
view.setScaleX(1);
|
|
|
|
view.setScaleY(1);
|
|
|
|
view.setRotation(0);
|
|
|
|
}
|
2023-12-01 16:17:06 +08:00
|
|
|
}
|
|
|
|
public static class Layer {
|
2024-01-24 20:17:59 +08:00
|
|
|
ArrayList<Source> srcs = new ArrayList<>();
|
2023-12-01 16:17:06 +08:00
|
|
|
long endMilli = Long.MAX_VALUE;
|
|
|
|
int dur;
|
|
|
|
boolean isLoop;
|
|
|
|
}
|
2024-01-24 20:17:59 +08:00
|
|
|
public enum Effect {
|
|
|
|
EXPAND_HOR, EXPAND_VER, EXPAND_LEFT, EXPAND_TOP, EXPAND_RIGHT, EXPAND_BOTTOM,
|
|
|
|
ZOOM, ZOOM_TL, ZOOM_TR, ZOOM_BR, ZOOM_BL,
|
|
|
|
ROTATE, ROTATE_R,
|
|
|
|
FADE,
|
|
|
|
MOVE_LEFT, MOVE_TOP, MOVE_RIGHT, MOVE_BOTTOM,
|
|
|
|
}
|
2023-12-01 16:17:06 +08:00
|
|
|
public static class Sche {
|
|
|
|
long startDate = -1, endDate = -1;
|
|
|
|
int startTime = -1, endTime = -1;
|
2024-01-24 20:17:59 +08:00
|
|
|
JSList<Long> weeks;
|
2023-12-01 16:17:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public static class Page {
|
|
|
|
ArrayList<Layer> layers = new ArrayList<>();
|
|
|
|
ArrayList<Sche> sches;
|
|
|
|
long endMilli = Long.MAX_VALUE;
|
2024-01-24 20:17:59 +08:00
|
|
|
int sDur, tDur, repeatTimes, audioDur;
|
2023-12-01 16:17:06 +08:00
|
|
|
|
|
|
|
void hide() {
|
2024-01-24 20:17:59 +08:00
|
|
|
for(var layer : layers) for(var src : layer.srcs) src.hide();
|
2023-12-01 16:17:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setMillis(long milli) {
|
|
|
|
endMilli = milli + sDur;
|
|
|
|
for(var layer : layers) {
|
|
|
|
if(layer.isLoop) layer.endMilli = milli + layer.dur;
|
2024-01-24 20:17:59 +08:00
|
|
|
for(var src : layer.srcs) {
|
|
|
|
src.endMilli = milli + src.endTime;
|
|
|
|
src.startMilli = milli + src.startTime;
|
|
|
|
if(src.startTime == 0) src.show();
|
2023-12-01 16:17:06 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public boolean isSchedule(long milli) {
|
|
|
|
if(sches==null) return true;
|
|
|
|
var local = milli + Dates.zoneOff;
|
|
|
|
var time = local % 86400000L;
|
2024-01-24 20:17:59 +08:00
|
|
|
long week = -1;
|
2023-12-01 16:17:06 +08:00
|
|
|
for(var sche : sches) {
|
|
|
|
if(notInRange(sche.startDate, local, sche.endDate)) continue;
|
|
|
|
if(notInRange(sche.startTime, time, sche.endTime)) continue;
|
|
|
|
if(sche.weeks==null) return true;
|
2024-01-24 20:17:59 +08:00
|
|
|
if(week==-1) week = (local / 86400000L + 3) % 7 + 1;
|
2023-12-01 16:17:06 +08:00
|
|
|
if(sche.weeks.contains(week)) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
public boolean notInRange(long start, long val, long end) {
|
|
|
|
if(end==-1) return false;
|
|
|
|
return start <= end ? !(val >= start && val < end) : val >= end && val < start;
|
|
|
|
}
|
2024-01-24 20:17:59 +08:00
|
|
|
SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
|
SimpleDateFormat timeFmt = new SimpleDateFormat("HH:mm:ss");
|
2023-12-01 16:17:06 +08:00
|
|
|
public void parse(JSList<JSMap> schedules) {
|
|
|
|
if(schedules!=null) for(var schedule : schedules) {
|
|
|
|
var sche = new Sche();
|
|
|
|
var startTime = schedule.str("startTime");
|
2024-01-24 20:17:59 +08:00
|
|
|
if(startTime!=null) {
|
|
|
|
if(startTime.length()==5) startTime += ":00";
|
|
|
|
try {
|
|
|
|
sche.startTime = (int)timeFmt.parse(startTime).getTime()+Dates.zoneOff;
|
|
|
|
} catch (ParseException e) {
|
|
|
|
Util.printStackTrace(e);
|
|
|
|
}
|
|
|
|
}
|
2023-12-01 16:17:06 +08:00
|
|
|
var endTime = schedule.str("endTime");
|
2024-01-24 20:17:59 +08:00
|
|
|
if(endTime!=null) {
|
|
|
|
if(endTime.length()==5) endTime += ":00";
|
|
|
|
try {
|
|
|
|
sche.endTime = (int)timeFmt.parse(endTime).getTime()+Dates.zoneOff;
|
|
|
|
} catch (ParseException e) {
|
|
|
|
Util.printStackTrace(e);
|
|
|
|
}
|
|
|
|
}
|
2023-12-01 16:17:06 +08:00
|
|
|
if(sche.startTime==sche.endTime) sche.startTime = sche.endTime = -1;
|
|
|
|
var startDate = schedule.str("startDate");
|
2024-01-24 20:17:59 +08:00
|
|
|
if(startDate!=null) {
|
|
|
|
try {
|
|
|
|
sche.startDate = dateFmt.parse(startDate).getTime() + Dates.zoneOff;
|
|
|
|
} catch (ParseException e) {
|
|
|
|
Util.printStackTrace(e);
|
|
|
|
}
|
|
|
|
}
|
2023-12-01 16:17:06 +08:00
|
|
|
var endDate = schedule.str("endDate");
|
2024-01-24 20:17:59 +08:00
|
|
|
if(endDate!=null) {
|
|
|
|
try {
|
|
|
|
sche.endDate = dateFmt.parse(endDate).getTime() + Dates.zoneOff + 86400000L;
|
|
|
|
} catch (ParseException e) {
|
|
|
|
Util.printStackTrace(e);
|
|
|
|
}
|
|
|
|
}
|
2023-12-01 16:17:06 +08:00
|
|
|
if(sche.startDate==sche.endDate) sche.startDate = sche.endDate = -1;
|
2024-01-24 20:17:59 +08:00
|
|
|
JSList<Long> weekFilter = schedule.jslist("weekFilter");
|
2023-12-01 16:17:06 +08:00
|
|
|
if(weekFilter!=null && ! weekFilter.isEmpty() && weekFilter.size() < 7) sche.weeks = weekFilter;
|
|
|
|
if(sches==null) sches = new ArrayList<>();
|
|
|
|
sches.add(sche);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-11-09 08:37:59 +08:00
|
|
|
}
|