Skip to content

Commit

Permalink
implement hiding of options (mostly)
Browse files Browse the repository at this point in the history
  • Loading branch information
nextdayy committed Nov 10, 2024
1 parent 95a0bcc commit 9c21dd8
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Predicate;

public abstract class Config {
Expand Down Expand Up @@ -73,7 +72,7 @@ protected void addDependency(String option, BooleanSupplier condition) {

protected void addDependency(String option, String name, BooleanSupplier condition) {
Property<?> opt = getProperty(option).addDisplayCondition(condition);
opt.getOrPutMetadata("dependencyNames", () -> new ArrayList<String>(3)).add(name);
if (name != null) opt.getOrPutMetadata("dependencyNames", () -> new ArrayList<String>(3)).add(name);
}

/**
Expand All @@ -82,10 +81,11 @@ protected void addDependency(String option, String name, BooleanSupplier conditi
* @param option the option to add the dependency to
* @param condition the <b>boolean option</b> which provides the dependency
*/
@SuppressWarnings("unchecked")
protected void addDependency(String option, String condition) {
Property<?> cond = getProperty(condition);
if (cond.type != boolean.class) throw new IllegalArgumentException("Condition property must be boolean");
Property<?> opt = getProperty(option).addDisplayCondition(cond::getAs);
Property<?> opt = getProperty(option).addDisplayCondition((Property<Boolean>) cond);
opt.getOrPutMetadata("dependencyNames", () -> new ArrayList<String>(3)).add(cond.getTitle());
}

Expand All @@ -100,17 +100,12 @@ protected <T> void addCallback(String option, Predicate<T> callback) {
((Property<T>) getProperty(option)).addCallback(callback);
}

/**
* Add a callback to the specified option path, which is dot-separated for sub-configs.
* <br>
* The name of the option should be the name of the field.
*/
@SuppressWarnings("unchecked")
@kotlin.OverloadResolutionByLambdaReturnType
protected <T> void addCallback(String option, Consumer<T> callback) {
((Property<T>) getProperty(option)).addCallback(callback);

protected void hideWhenShouldNotDisplay(String option) {
getProperty(option).addMetadata("hideOnDisplayFailure", true);
}


/**
* Add a callback to the specified option path, which is dot-separated for sub-configs.
* <br>
Expand All @@ -119,6 +114,7 @@ protected <T> void addCallback(String option, Consumer<T> callback) {
protected void addCallback(String option, Runnable callback) {
getProperty(option).addCallback(t -> {
callback.run();
return false;
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ package org.polyfrost.oneconfig.api.config.v1
import org.polyfrost.oneconfig.api.config.v1.internal.ConfigVisualizer.Companion.strv
import org.polyfrost.polyui.color.PolyColor
import org.polyfrost.polyui.color.mutable
import org.polyfrost.polyui.component.*
import org.polyfrost.polyui.component.Drawable
import org.polyfrost.polyui.component.extensions.*
import org.polyfrost.polyui.component.impl.*
import org.polyfrost.polyui.event.Event
Expand Down Expand Up @@ -63,7 +63,8 @@ fun interface Visualizer {
if (p !is PolyColor.Mutable) {
prop.setAsReferential(p.mutable())
}
return Block(color = prop.getAs(), size = Vec2(58f, 32f)).withBoarder(3f, color = { page.border20 }).onClick { ColorPicker(prop.getAs<PolyColor.Mutable>().ref(), null, null, polyUI); true }
return Block(color = prop.getAs(), size = Vec2(58f, 32f)).withBoarder(3f, color = { page.border20 })
.onClick { ColorPicker(prop.getAs<PolyColor.Mutable>().ref(), null, null, polyUI); true }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ open class ConfigVisualizer {
val list = options.getOrPut(category) { HashMap(4) }.getOrPut(subcategory) { ArrayList(8) }
if (node is Property<*>) {
val vis = node.getVisualizer() ?: return
list.add(Triple(node.title, node.description, wrap(vis.visualize(node), node.title ?: return, node.description, icon)))
list.add(Triple(node.title, node.description, wrap(vis.visualize(node), node.title ?: return, node.description, icon).addHideHandler(node)))
} else {
node as Tree
if (node.map.isEmpty()) {
Expand Down Expand Up @@ -192,7 +192,7 @@ open class ConfigVisualizer {
if (node !is Property<*>) return@map null
val vis = node.getVisualizer() ?: return@map null
index.add(node.title to node.description)
wrapForAccordion(vis.visualize(node), node.title ?: return@map null, node.description)
wrapForAccordion(vis.visualize(node), node.title ?: return@map null, node.description).addHideHandler(node)
}
var open = false
val out = Block(
Expand Down Expand Up @@ -275,6 +275,16 @@ open class ConfigVisualizer {
}
}

private fun Drawable.addHideHandler(prop: Property<*>): Drawable {
prop.onDisplayChange { s ->
this.isEnabled = s
if (prop.getMetadata<Boolean?>("hideOnDisplayFailure") == true) {
// todo
}
}
return this
}

companion object {
@JvmField
val INSTANCE = ConfigVisualizer()
Expand Down
7 changes: 2 additions & 5 deletions modules/config/api/config.api
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,14 @@ public final class org/polyfrost/oneconfig/api/config/v1/Properties {

public abstract class org/polyfrost/oneconfig/api/config/v1/Property : org/polyfrost/oneconfig/api/config/v1/Node, java/io/Serializable {
protected field callbacks Ljava/util/List;
protected field predicates Ljava/util/List;
public final field type Ljava/lang/Class;
protected fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
public final fun addCallback (Ljava/util/Collection;)Lorg/polyfrost/oneconfig/api/config/v1/Property;
public final fun addCallback (Ljava/util/function/Consumer;)Lorg/polyfrost/oneconfig/api/config/v1/Property;
public final fun addCallback (Ljava/util/function/Predicate;)Lorg/polyfrost/oneconfig/api/config/v1/Property;
public final fun addCallback ([Ljava/util/function/Consumer;)Lorg/polyfrost/oneconfig/api/config/v1/Property;
public final fun addCallback ([Ljava/util/function/Predicate;)Lorg/polyfrost/oneconfig/api/config/v1/Property;
public final fun addCancellableCallbacks (Ljava/util/Collection;)Lorg/polyfrost/oneconfig/api/config/v1/Property;
public final fun addDisplayCondition (Ljava/util/Collection;)Lorg/polyfrost/oneconfig/api/config/v1/Property;
public final fun addDisplayCondition (Ljava/util/function/BooleanSupplier;)Lorg/polyfrost/oneconfig/api/config/v1/Property;
public final fun addDisplayCondition (Lorg/polyfrost/oneconfig/api/config/v1/Property;)Lorg/polyfrost/oneconfig/api/config/v1/Property;
public final fun addDisplayCondition ([Ljava/util/function/BooleanSupplier;)Lorg/polyfrost/oneconfig/api/config/v1/Property;
public final fun canDisplay ()Z
protected final fun clearCallbacks ()V
Expand All @@ -72,9 +69,9 @@ public abstract class org/polyfrost/oneconfig/api/config/v1/Property : org/polyf
public final fun getAs ()Ljava/lang/Object;
public final fun isArray ()Z
public final fun isPrimitive ()Z
public fun onDisplayChange (Ljava/util/function/Consumer;)V
public fun overwrite (Lorg/polyfrost/oneconfig/api/config/v1/Node;)V
public static fun recast (Lorg/polyfrost/oneconfig/api/config/v1/Property;)Lorg/polyfrost/oneconfig/api/config/v1/Property;
public final fun removeCallback (Ljava/util/function/Consumer;)V
public final fun removeCallback (Ljava/util/function/Predicate;)V
public final fun removeDisplayCondition (Ljava/util/function/BooleanSupplier;)V
public fun revaluateDisplay ()V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.polyfrost.oneconfig.utils.v1.WrappingUtils;

import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
Expand All @@ -53,8 +54,8 @@ public abstract class Property<T> extends Node implements Serializable {
*/
@NotNull
public transient final Class<?> type;
protected transient List<@NotNull Consumer<@Nullable T>> callbacks = null;
protected transient List<@NotNull Predicate<@Nullable T>> predicates = null;
protected transient List<@NotNull Predicate<@Nullable T>> callbacks = null;
private transient Consumer<Boolean> displayCallback = null;
private transient boolean display = true;
private transient List<BooleanSupplier> conditions = null;

Expand All @@ -77,16 +78,34 @@ public final boolean canDisplay() {
return display;
}

public void onDisplayChange(Consumer<Boolean> callback) {
this.displayCallback = callback;
}

/**
* Add a display condition to this property.
*/
public final Property<T> addDisplayCondition(@NotNull BooleanSupplier condition) {
if (conditions == null) conditions = new ArrayList<>(5);
if (conditions == null) conditions = new ArrayList<>(3);
conditions.add(condition);
revaluateDisplay();
return this;
}

public final Property<T> addDisplayCondition(@NotNull Property<Boolean> condition) {
// asm: weak ref to avoid a potential memory leak if we are discarded for any reason
WeakReference<Property<T>> ref = new WeakReference<>(this);
condition.addCallback(t -> {
Property<T> self = ref.get();
if (self == null) return false;
else self.revaluateDisplay();
return false;
});
this.addDisplayCondition(condition::get);
return this;
}


public final Property<T> addDisplayCondition(@NotNull BooleanSupplier... conditions) {
return addDisplayCondition(Arrays.asList(conditions));
}
Expand All @@ -101,14 +120,17 @@ public final Property<T> addDisplayCondition(@NotNull Collection<BooleanSupplier
}

public void revaluateDisplay() {
display = true;
if (conditions == null) return;
for (BooleanSupplier s : conditions) {
if (!s.getAsBoolean()) {
display = false;
break;
if (conditions != null) {
for (BooleanSupplier s : conditions) {
if (!s.getAsBoolean()) {
if (display && displayCallback != null) displayCallback.accept(false);
display = false;
return;
}
}
}
if (displayCallback != null) displayCallback.accept(true);
display = true;
}

/**
Expand All @@ -132,23 +154,10 @@ protected final void clearDisplayConditions() {
* Add a callback to this property, which is called when the value changes.
*
* @param callback the callback to add. The new value is passed to the callback. Return true if you wish to cancel the setting of the property.
* @see #removeCallback(Consumer)
* @see #removeCallback(Predicate)
*/
@kotlin.OverloadResolutionByLambdaReturnType
public final Property<T> addCallback(@NotNull Predicate<@Nullable T> callback) {
if (predicates == null) predicates = new ArrayList<>(2);
predicates.add(callback);
return this;
}

/**
* Add a callback to this property, which is called when the value changes.
*
* @param callback the callback to add. The new value is passed to the callback.
* @see #removeCallback(Consumer)
*/
@kotlin.OverloadResolutionByLambdaReturnType
public final Property<T> addCallback(@NotNull Consumer<@Nullable T> callback) {
if (callbacks == null) callbacks = new ArrayList<>(2);
callbacks.add(callback);
return this;
Expand All @@ -157,24 +166,11 @@ public final Property<T> addCallback(@NotNull Consumer<@Nullable T> callback) {
@SafeVarargs
@kotlin.OverloadResolutionByLambdaReturnType
public final Property<T> addCallback(@NotNull Predicate<@Nullable T>... callbacks) {
return addCancellableCallbacks(Arrays.asList(callbacks));
}

@SafeVarargs
@kotlin.OverloadResolutionByLambdaReturnType
public final Property<T> addCallback(@NotNull Consumer<@Nullable T>... callbacks) {
return addCallback(Arrays.asList(callbacks));
}

@kotlin.OverloadResolutionByLambdaReturnType
public final Property<T> addCancellableCallbacks(@NotNull Collection<Predicate<@Nullable T>> callbacks) {
if (this.predicates == null) this.predicates = new ArrayList<>(callbacks);
else this.predicates.addAll(callbacks);
return this;
}

@kotlin.OverloadResolutionByLambdaReturnType
public final Property<T> addCallback(@NotNull Collection<Consumer<@Nullable T>> callbacks) {
public final Property<T> addCallback(@NotNull Collection<Predicate<@Nullable T>> callbacks) {
if (this.callbacks == null) this.callbacks = new ArrayList<>(callbacks);
else this.callbacks.addAll(callbacks);
return this;
Expand All @@ -195,19 +191,11 @@ public void overwrite(Node with) {
/**
* Remove a callback.
*/
public final void removeCallback(@NotNull Consumer<@Nullable T> callback) {
public final void removeCallback(@NotNull Predicate<@Nullable T> callback) {
if (callbacks == null) return;
callbacks.remove(callback);
}

/**
* Remove a callback.
*/
public final void removeCallback(@NotNull Predicate<@Nullable T> callback) {
if (predicates == null) return;
predicates.remove(callback);
}

/**
* Remove all callbacks.
*/
Expand All @@ -232,8 +220,8 @@ public final void set(@Nullable T value) {
* Use this method with caution.
*/
public void setReferential(@Nullable T value) {
if (predicates != null) {
for (Predicate<T> p : predicates) {
if (callbacks != null) {
for (Predicate<T> p : callbacks) {
try {
if (p.test(value)) {
LOGGER.info("property {} set cancelled by {}", this.getID(), p);
Expand All @@ -245,15 +233,6 @@ public void setReferential(@Nullable T value) {
}
}
set0(value);
if (callbacks != null) {
for (Consumer<T> c : callbacks) {
try {
c.accept(value);
} catch (Throwable t) {
LOGGER.error("failed to call callback {} on property {}", c, this.getID(), t);
}
}
}
}

protected abstract void set0(@Nullable T value);
Expand Down

0 comments on commit 9c21dd8

Please sign in to comment.