
net.thevpc.echo.StarsField Maven / Gradle / Ivy
package net.thevpc.echo;
import net.thevpc.common.props.PropertyType;
import net.thevpc.common.props.Props;
import net.thevpc.common.props.WritableValue;
import net.thevpc.echo.api.AppContainerChildren;
import net.thevpc.echo.api.AppImage;
import net.thevpc.echo.api.components.AppComponent;
import net.thevpc.echo.api.components.AppEventType;
import net.thevpc.echo.api.components.AppNumberField;
import net.thevpc.echo.constraints.AllMargins;
import net.thevpc.echo.constraints.Layout;
import net.thevpc.echo.impl.Applications;
import net.thevpc.echo.impl.components.NumberBase;
import net.thevpc.echo.spi.peers.AppNumberFieldPeer;
import net.thevpc.echo.util.NumberHelper;
public class StarsField extends NumberBase implements AppNumberField, AppContentAdapter {
private static StarFieldRenderer DEFAULT = new StarFieldRenderer() {
@Override
public AppImage createImage(StarFieldRendererContext context) {
if (context.getFill() <= 0.5) {
return context.getApplication().iconSets().icon("star-disabled",
context.getStarsField());
}
return context.getApplication().iconSets().icon("star-enabled",
context.getStarsField());
}
};
private Panel container;
private WritableValue> renderer;
public StarsField(String id,
Class numberType,
Application app) {
super(id, numberType, app, (Class) AppNumberField.class, AppNumberFieldPeer.class);
this.min().set(NumberHelper.valueOf(0, numberType));
this.max().set(NumberHelper.valueOf(5, numberType));
renderer = Props.of("renderer").valueOf(PropertyType.of(StarFieldRenderer.class, numberType));
container = new Panel(id, Layout.HORIZONTAL, app);
propagateEvents(renderer);
container.parentConstraints().addAll(AllMargins.of(2, 4, 2, 4));
Applications.bindContent(this);
revalidateContainer();
revalidateValue();
max().onChange(() -> {
revalidateContainer();
revalidateValue();
});
value().onChange(this::revalidateValue);
}
public StarsField(Class numberType,
Application app) {
this(null, numberType, app);
}
public static StarsField create(int max, Application app) {
StarsField s = new StarsField<>(Integer.class, app);
s.max().set(max);
return s;
}
public WritableValue> renderer() {
return renderer;
}
@Override
public AppComponent content() {
return container;
}
private void revalidateContainer() {
for (AppComponent child : container.children()) {
ImageView im = (ImageView) child;
im.events().clear();
}
container.children().clear();
int x = ((Number) max().get()).intValue();
if (x > 0) {
for (int i = 0; i < x; i++) {
ImageView imv = new ImageView(app());
int finalI = i;
imv.events().add(e -> {
if (e.isSimpleClick() && e.isPrimaryMouseButton()) {
if (finalI == 0) {
double lastValue = NumberHelper.valueOf(value().get(), Double.class);
if (lastValue == 0) {
value().set(NumberHelper.valueOf(1, valueType()));
} else {
value().set(NumberHelper.valueOf(0, valueType()));
}
} else {
value().set(NumberHelper.valueOf(finalI + 1, valueType()));
}
}
}, AppEventType.MOUSE_CLICKED);
container.children().add(imv);
}
}
}
private void revalidateValue() {
AppContainerChildren children = container.children();
T n = value().get();
if (n == null) {
n = NumberHelper.valueOf(0.0, valueType());
}
double in = NumberHelper.valueOf(n, Double.class);
StarFieldRenderer starRenderer = renderer().get();
if (starRenderer == null) {
starRenderer = DEFAULT;
}
for (int i = 0; i < children.size(); i++) {
ImageView im = (ImageView) children.get(i);
double fill = in - i;
if (fill <= 0) {
fill = 0;
}
if (fill > 1) {
fill = 1;
}
StarsField sf = this;
NumberStarRendererContext ctx = new NumberStarRendererContext(sf, i, (float) fill);
AppImage image = starRenderer.createImage(ctx);
if (image == null) {
image = DEFAULT.createImage(ctx);
}
im.image().set(image);
}
}
private class NumberStarRendererContext implements StarFieldRendererContext {
private final StarsField sf;
private final int i;
private final float fill;
public NumberStarRendererContext(StarsField sf, int i, float fill) {
this.sf = sf;
this.i = i;
this.fill = fill;
}
@Override
public Application getApplication() {
return getStarsField().app();
}
@Override
public StarsField getStarsField() {
return sf;
}
@Override
public int getPosition() {
return i;
}
@Override
public float getFill() {
return fill;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy