Skip to content

Commit 4bfdd78

Browse files
committedSep 21, 2024·
Refactoring and start on sequence animation
1 parent 01f07f5 commit 4bfdd78

File tree

13 files changed

+107
-63
lines changed

13 files changed

+107
-63
lines changed
 

‎examples/src/main/java/org/jsignal/examples/DrawerTest.java

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
11
package org.jsignal.examples;
22

33
import org.jsignal.rx.Signal;
4-
import org.jsignal.std.BasicPainter;
5-
import org.jsignal.std.Button;
6-
import org.jsignal.std.Drawer;
7-
import org.jsignal.std.EasingFunction;
8-
import org.jsignal.std.Para;
9-
import org.jsignal.std.Scroll;
4+
import org.jsignal.std.*;
105
import org.jsignal.std.ez.EzColors;
116
import org.jsignal.std.ez.EzLayout;
12-
import org.jsignal.ui.Component;
13-
import org.jsignal.ui.Element;
14-
import org.jsignal.ui.Node;
15-
import org.jsignal.ui.UiThread;
16-
import org.jsignal.ui.UiUtil;
17-
import org.jsignal.ui.UiWindow;
7+
import org.jsignal.ui.*;
188

199
import static org.jsignal.ui.Nodes.compose;
2010
import static org.jsignal.ui.layout.Insets.insets;
@@ -56,7 +46,7 @@ protected Element render() {
5646
.build(),
5747
Drawer.builder()
5848
.open(open)
59-
.openAnimFunc(EasingFunction::easeOutBounce)
49+
.openAnimFunc(TimingFunction::easeOutBounce)
6050
.animDurationSeconds(0.5f)
6151
.content(Node.builder()
6252
.layout(EzLayout.builder()

‎examples/src/main/java/org/jsignal/examples/todo/TodoApp.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ protected Element render() {
111111
))
112112
.build(),
113113
Nodes.forEach(todos, (content, idx) -> {
114-
var enterAnim = AnimationHelper.builder()
115-
.function(EasingFunction::easeOutQuad)
116-
.run(true)
114+
var enterAnim = IntervalAnimation.builder()
115+
.function(TimingFunction::easeOutQuad)
116+
.start(true)
117117
.build();
118118

119119
var anim = Signal.create(enterAnim);
@@ -156,12 +156,12 @@ protected Element render() {
156156
Node.builder().layoutBuilder(lb -> lb.grow(1f)).build(),
157157
Button.builder()
158158
.color(EzColors.RED_600)
159-
.action(() -> anim.accept(AnimationHelper.builder()
160-
.start(1f)
159+
.action(() -> anim.accept(IntervalAnimation.builder()
160+
.begin(1f)
161161
.end(0f)
162-
.function(EasingFunction::easeOutQuad)
162+
.function(TimingFunction::easeOutQuad)
163163
.onFinish(() -> todos.modify(list -> list.remove((int) idx.get())))
164-
.run(true)
164+
.start(true)
165165
.build()
166166
))
167167
.size(Button.Size.SM)
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
package org.jsignal.prop;
22

33
// TODO: the word transitive is used incorrectly, rename to BuildProps
4-
public @interface TransitiveProps {}
4+
public @interface BuildProps {}

‎prop/src/main/java/org/jsignal/prop/PropGenerator.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public static TypeElement transitivePropsElement(TypeElement element) {
108108
return (TypeElement) element.getEnclosedElements()
109109
.stream()
110110
.filter(enclosed -> enclosed.getKind() == ElementKind.CLASS)
111-
.filter(enclosed -> findAnnotation(enclosed, TransitiveProps.class).isPresent())
111+
.filter(enclosed -> findAnnotation(enclosed, BuildProps.class).isPresent())
112112
.findFirst()
113113
.orElse(null);
114114
}

‎std/src/main/java/org/jsignal/std/Drawer.java

+5-10
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@
44
import io.github.humbleui.skija.Paint;
55
import org.jsignal.prop.GeneratePropComponent;
66
import org.jsignal.prop.Prop;
7-
import org.jsignal.rx.Computed;
8-
import org.jsignal.rx.Constant;
9-
import org.jsignal.rx.Effect;
10-
import org.jsignal.rx.Ref;
11-
import org.jsignal.rx.Signal;
12-
import org.jsignal.rx.SkipMemo;
7+
import org.jsignal.rx.*;
138
import org.jsignal.std.ez.EzColors;
149
import org.jsignal.std.ez.EzLayout;
1510
import org.jsignal.ui.Element;
@@ -36,7 +31,7 @@ public non-sealed class Drawer extends DrawerPropComponent {
3631
@Prop
3732
Supplier<Float> animDurationSeconds = Constant.of(0.2f);
3833
@Prop
39-
Supplier<EasingFunction> openAnimFunc = Constant.of(EasingFunction::linear);
34+
Supplier<TimingFunction> openAnimFunc = Constant.of(TimingFunction::linear);
4035
@Prop
4136
Runnable backgroundClick;
4237

@@ -87,7 +82,7 @@ protected Element render() {
8782
}
8883

8984
private Supplier<Supplier<Float>> createTranslation(Supplier<Float> width) {
90-
Ref<AnimationHelper> prevAnimation = new Ref<>();
85+
Ref<IntervalAnimation> prevAnimation = new Ref<>();
9186
Ref<Boolean> first = new Ref<>(true);
9287
return Computed.create(() -> {
9388
var o = open.get();
@@ -112,8 +107,8 @@ private Supplier<Supplier<Float>> createTranslation(Supplier<Float> width) {
112107
start = Constant.of(ignore(prev));
113108
}
114109

115-
var helper = AnimationHelper.builder()
116-
.start(start)
110+
var helper = IntervalAnimation.builder()
111+
.begin(start)
117112
.end(end)
118113
.durationSeconds(animDurationSeconds)
119114
.function(openAnimFunc)

‎std/src/main/java/org/jsignal/std/AnimationHelper.java ‎std/src/main/java/org/jsignal/std/IntervalAnimation.java

+30-14
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package org.jsignal.std;
22

3+
import org.jsignal.prop.BuildProps;
34
import org.jsignal.prop.GeneratePropHelper;
45
import org.jsignal.prop.Prop;
5-
import org.jsignal.prop.TransitiveProps;
66
import org.jsignal.rx.Constant;
77
import org.jsignal.rx.Signal;
88

@@ -11,41 +11,57 @@
1111
import static org.jsignal.rx.RxUtil.ignore;
1212

1313
@GeneratePropHelper
14-
public non-sealed class AnimationHelper extends AnimationHelperPropHelper implements Supplier<Float> {
14+
public final class IntervalAnimation extends IntervalAnimationPropHelper implements Supplier<Float> {
1515
@Prop
16-
Supplier<Float> start = Constant.of(0f);
16+
Supplier<Float> begin = Constant.of(0f);
1717
@Prop
1818
Supplier<Float> end = Constant.of(1f);
1919
@Prop
2020
Supplier<Float> durationSeconds = Constant.of(0.2f);
2121
@Prop
22-
Supplier<EasingFunction> function = Constant.of(EasingFunction::linear);
22+
Supplier<TimingFunction> function = Constant.of(TimingFunction::linear);
23+
@Prop
24+
int repeat = 1;
2325
@Prop
2426
Runnable onFinish = () -> {};
2527

26-
@TransitiveProps
28+
@BuildProps
2729
static class Build {
2830
@Prop
29-
boolean run = false;
31+
boolean start = false;
32+
@Prop
33+
boolean infinite = false;
3034
}
3135

3236
private final Signal<Float> progress = Signal.create(0f);
3337
private final Signal<State> state = Signal.create(State.INITIAL);
3438
private final Animation animation = new Animation((deltaTime, stop) -> {
35-
float increment = (deltaTime * 1e-9f) / durationSeconds.get();
36-
progress.transform(cur -> cur + increment);
37-
if (progress.get() > 1) {
38-
stop.run();
39-
state.accept(State.FINISHED);
40-
onFinish.run();
39+
if (progress.get() == 1f) {
40+
if (repeat != 1) {
41+
progress.accept(0f);
42+
if (repeat > 0) {
43+
repeat--;
44+
}
45+
} else {
46+
stop.run();
47+
state.accept(State.FINISHED);
48+
onFinish.run();
49+
return;
50+
}
4151
}
52+
53+
float increment = (deltaTime * 1e-9f) / durationSeconds.get();
54+
progress.transform(cur -> Math.min(1f, cur + increment));
4255
});
4356

4457
@Override
4558
void onBuild(Build buildProps) {
46-
if (buildProps.run) {
59+
if (buildProps.start) {
4760
start();
4861
}
62+
if (buildProps.infinite) {
63+
repeat = -1;
64+
}
4965
}
5066

5167
public void start() {
@@ -63,7 +79,7 @@ public void stop() {
6379
}
6480

6581
public Float get() {
66-
return function.get().apply(Math.min(1f, progress.get()), start.get(), end.get());
82+
return function.get().apply(Math.min(1f, progress.get()), begin.get(), end.get());
6783
}
6884

6985
public enum State {

‎std/src/main/java/org/jsignal/std/Para.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
import io.github.humbleui.skija.paragraph.Paragraph;
77
import io.github.humbleui.skija.paragraph.ParagraphBuilder;
88
import io.github.humbleui.skija.paragraph.TypefaceFontProvider;
9+
import org.jsignal.prop.BuildProps;
910
import org.jsignal.prop.GeneratePropComponent;
1011
import org.jsignal.prop.Prop;
11-
import org.jsignal.prop.TransitiveProps;
1212
import org.jsignal.rx.Context;
1313
import org.jsignal.rx.Effect;
1414
import org.jsignal.rx.Ref;
@@ -45,7 +45,7 @@ public static void loadFontFromResource(String location) throws IOException {
4545
}
4646
}
4747

48-
@TransitiveProps
48+
@BuildProps
4949
public static class Transitive {
5050
@Prop(oneofKey = "content")
5151
Supplier<String> string;

‎std/src/main/java/org/jsignal/std/ParaStyle.java

+23-9
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import io.github.humbleui.skija.paragraph.*;
44
import jakarta.annotation.Nullable;
5+
import org.jsignal.prop.BuildProps;
56
import org.jsignal.prop.GeneratePropHelper;
67
import org.jsignal.prop.Prop;
7-
import org.jsignal.prop.TransitiveProps;
88
import org.jsignal.rx.ComputedContext;
99
import org.jsignal.rx.Constant;
1010
import org.jsignal.rx.Provider;
@@ -25,7 +25,7 @@ public Provider.Entry customize(Function<ParaStyle.Builder, ParaStyle.Builder> c
2525

2626
public static final Context context = new Context();
2727

28-
@TransitiveProps
28+
@BuildProps
2929
public static class Transitive {
3030
@Prop
3131
Function<ParaTextStyle.Builder, ParaTextStyle.Builder> textStyleBuilder;
@@ -72,13 +72,27 @@ public void onBuild(Transitive props) {
7272
public ParagraphStyle toSkia() {
7373
var para = new ParagraphStyle();
7474
para.setTextStyle(textStyle.toSkia());
75-
if (alignment != null) para.setAlignment(alignment);
76-
if (height != null) para.setHeight(height);
77-
if (direction != null) para.setDirection(direction);
78-
if (strutStyle != null) para.setStrutStyle(strutStyle);
79-
if (ellipsis != null) para.setEllipsis(ellipsis);
80-
if (heightMode != null) para.setHeightMode(heightMode);
81-
if (maxLinesCount != null) para.setMaxLinesCount(maxLinesCount);
75+
if (alignment != null) {
76+
para.setAlignment(alignment);
77+
}
78+
if (height != null) {
79+
para.setHeight(height);
80+
}
81+
if (direction != null) {
82+
para.setDirection(direction);
83+
}
84+
if (strutStyle != null) {
85+
para.setStrutStyle(strutStyle);
86+
}
87+
if (ellipsis != null) {
88+
para.setEllipsis(ellipsis);
89+
}
90+
if (heightMode != null) {
91+
para.setHeightMode(heightMode);
92+
}
93+
if (maxLinesCount != null) {
94+
para.setMaxLinesCount(maxLinesCount);
95+
}
8296
return para;
8397
}
8498
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.jsignal.std;
2+
3+
import java.util.List;
4+
5+
public class SequenceAnimation {
6+
private final List<IntervalAnimation> sequence;
7+
private int cur;
8+
9+
public SequenceAnimation(List<IntervalAnimation> sequence) {
10+
this.sequence = sequence;
11+
this.cur = 0;
12+
}
13+
14+
public SequenceAnimation(IntervalAnimation... sequence) {
15+
this(List.of(sequence));
16+
}
17+
18+
public void start() {
19+
20+
}
21+
22+
public void stop() {
23+
24+
}
25+
}

‎std/src/main/java/org/jsignal/std/TextInput.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import io.github.humbleui.skija.Paint;
99
import io.github.humbleui.skija.paragraph.RectHeightMode;
1010
import io.github.humbleui.skija.paragraph.RectWidthMode;
11+
import org.jsignal.prop.BuildProps;
1112
import org.jsignal.prop.GeneratePropComponent;
1213
import org.jsignal.prop.Prop;
13-
import org.jsignal.prop.TransitiveProps;
1414
import org.jsignal.rx.Constant;
1515
import org.jsignal.rx.Effect;
1616
import org.jsignal.rx.Ref;
@@ -48,7 +48,7 @@ public non-sealed class TextInput extends TextInputPropComponent {
4848
@Prop
4949
Function<Para, Element> children = (para) -> para;
5050

51-
@TransitiveProps
51+
@BuildProps
5252
public static class Transitive {
5353
Function<Supplier<String>, Para> toPara = Para::fromString;
5454
}

‎std/src/main/java/org/jsignal/std/EasingFunction.java ‎std/src/main/java/org/jsignal/std/TimingFunction.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/**
44
* Functions copied from <a href="https://easings.net/" >https://easings.net/</a>
55
*/
6-
public interface EasingFunction {
6+
public interface TimingFunction {
77
float calculate(float x);
88

99
default float apply(float x, float start, float end) {
@@ -160,7 +160,7 @@ static float easeInOutElastic(float x) {
160160
} else if (x < 0.5f) {
161161
return -((float) Math.pow(2, 20 * x - 10) * (float) Math.sin((20 * x - 11.125) * c5)) / 2;
162162
} else {
163-
return ((float)Math.pow(2, -20 * x + 10) * (float) Math.sin((20 * x - 11.125) * c5)) / 2 + 1;
163+
return ((float) Math.pow(2, -20 * x + 10) * (float) Math.sin((20 * x - 11.125) * c5)) / 2 + 1;
164164
}
165165
}
166166

‎ui/src/main/java/org/jsignal/ui/Node.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
import io.github.humbleui.types.Point;
66
import io.github.humbleui.types.Rect;
77
import jakarta.annotation.Nullable;
8+
import org.jsignal.prop.BuildProps;
89
import org.jsignal.prop.GeneratePropHelper;
910
import org.jsignal.prop.Prop;
10-
import org.jsignal.prop.TransitiveProps;
1111
import org.jsignal.rx.*;
1212
import org.jsignal.ui.event.Event;
1313
import org.jsignal.ui.event.EventListener;
@@ -34,7 +34,7 @@ public non-sealed class Node extends NodePropHelper implements Nodes {
3434
public static final Context<Supplier<PaintCacheStrategy>> defaultPaintCacheStrategy = Context.create(
3535
() -> new UpgradingPaintCacheStrategy(PicturePaintCacheStrategy::new));
3636

37-
@TransitiveProps
37+
@BuildProps
3838
public static class Transitive {
3939
@Prop
4040
Collection<Object> tags = Collections.emptyList();

‎ui/src/main/java/org/jsignal/ui/UiWindow.java

+4
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,14 @@ public void requestLayout() {
119119
}
120120

121121
public void requestFrame() {
122+
// TODO: underlying JWM issue where requestFrame consistently gets ignored causing window to freeze.
123+
// Issue still happens when this if statement is commented out
122124
if (shouldPaint || window == null) {
123125
return;
124126
}
125127

126128
shouldPaint = true;
129+
// logger.info("frame requested", new Throwable());
127130
window.requestFrame();
128131
}
129132

@@ -167,6 +170,7 @@ void handleEvent(io.github.humbleui.jwm.Event event) {
167170
root.setOffScreen(canvas);
168171
paintSurfaceContext.with(e.getSurface()).provide(() -> root.paint(canvas));
169172
shouldPaint = false;
173+
// logger.info("frame painted");
170174

171175
calculateDeltaFrame();
172176

0 commit comments

Comments
 (0)
Please sign in to comment.