aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/client/modmenu/ConfigGui.java19
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java65
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java64
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WSlider.java16
-rw-r--r--src/main/resources/assets/libgui/textures/widget/slider.pngbin2597 -> 2978 bytes
5 files changed, 112 insertions, 52 deletions
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/modmenu/ConfigGui.java b/src/main/java/io/github/cottonmc/cotton/gui/client/modmenu/ConfigGui.java
index 97b3cfc..b8abd22 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/client/modmenu/ConfigGui.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/client/modmenu/ConfigGui.java
@@ -3,11 +3,8 @@ package io.github.cottonmc.cotton.gui.client.modmenu;
import io.github.cottonmc.cotton.gui.client.BackgroundPainter;
import io.github.cottonmc.cotton.gui.client.LibGuiClient;
import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription;
-import io.github.cottonmc.cotton.gui.widget.Axis;
import io.github.cottonmc.cotton.gui.widget.WButton;
import io.github.cottonmc.cotton.gui.widget.WGridPanel;
-import io.github.cottonmc.cotton.gui.widget.WLabeledSlider;
-import io.github.cottonmc.cotton.gui.widget.WSlider;
import io.github.cottonmc.cotton.gui.widget.WTextField;
import io.github.cottonmc.cotton.gui.widget.WToggleButton;
import net.minecraft.client.MinecraftClient;
@@ -33,8 +30,20 @@ public class ConfigGui extends LightweightGuiDescription {
WTextField testField = new WTextField();
testField.setSuggestion("test");
root.add(testField, 0, 3, 4, 1);
- root.add(new WSlider(-100, 100, Axis.VERTICAL).setValueChangeListener(System.out::println), 6, 0, 1, 3);
- root.add(new WLabeledSlider(1, 100).setValueChangeListener(System.out::println), 1, 4, 4, 1);
+
+ /*
+ WSlider verticalSlider = new WSlider(-100, 100, Axis.VERTICAL);
+ verticalSlider.setDraggingFinishedListener(() -> System.out.println("Mouse released"));
+ verticalSlider.setValueChangeListener(System.out::println);
+
+ WLabeledSlider horizontalSlider = new WLabeledSlider(0, 500);
+ horizontalSlider.setLabelUpdater(value -> new LiteralText(value + "!"));
+ horizontalSlider.setDraggingFinishedListener(() -> System.out.println("Mouse released"));
+ horizontalSlider.setValue(250);
+
+ root.add(verticalSlider, 6, 0, 1, 3);
+ root.add(horizontalSlider, 1, 4, 4, 1);
+ */
root.add(new WKirbSprite(), 5, 4);
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java
index bfa455e..074371f 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java
@@ -12,10 +12,11 @@ import java.util.function.IntConsumer;
* <p>You can set two listeners on a slider:
* <ul>
* <li>
- * A value change listener that gets all value changes (except direct setValue calls).
+ * A value change listener that gets all value changes (including direct setValue calls).
* </li>
* <li>
- * A focus release listener that gets called when the player stops dragging the slider.
+ * A dragging finished listener that gets called when the player stops dragging the slider
+ * or modifies the value with the keyboard.
* For example, this can be used for sending sync packets to the server
* when the player has selected a value.
* </li>
@@ -43,8 +44,13 @@ public abstract class WAbstractSlider extends WWidget {
*/
protected float coordToValueRatio;
+ /**
+ * True if there is a pending dragging finished event caused by the keyboard.
+ */
+ private boolean valueChangedWithKeys = false;
+
@Nullable private IntConsumer valueChangeListener = null;
- @Nullable private Runnable focusReleaseListener = null;
+ @Nullable private Runnable draggingFinishedListener = null;
protected WAbstractSlider(int min, int max, Axis axis) {
if (max <= min)
@@ -73,7 +79,7 @@ public abstract class WAbstractSlider extends WWidget {
@Override
public void setSize(int x, int y) {
super.setSize(x, y);
- int trackHeight = (axis == Axis.HORIZONTAL ? x : y) - getThumbWidth() + 1;
+ int trackHeight = (axis == Axis.HORIZONTAL ? x : y) - getThumbWidth();
valueToCoordRatio = (float) (max - min) / trackHeight;
coordToValueRatio = 1 / valueToCoordRatio;
}
@@ -108,6 +114,7 @@ public abstract class WAbstractSlider extends WWidget {
@Override
public void onClick(int x, int y, int button) {
moveSlider(x, y);
+ if (draggingFinishedListener != null) draggingFinishedListener.run();
}
private void moveSlider(int x, int y) {
@@ -115,36 +122,31 @@ public abstract class WAbstractSlider extends WWidget {
int rawValue = min + Math.round(valueToCoordRatio * pos);
int previousValue = value;
value = MathHelper.clamp(rawValue, min, max);
- if (value != previousValue && valueChangeListener != null) valueChangeListener.accept(value);
+ if (value != previousValue) onValueChanged(value);
}
@Override
public WWidget onMouseUp(int x, int y, int button) {
dragging = false;
+ if (draggingFinishedListener != null) draggingFinishedListener.run();
return super.onMouseUp(x, y, button);
}
- @Override
- public void onFocusLost() {
- if (focusReleaseListener != null) focusReleaseListener.run();
- }
-
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
+ onValueChanged(value);
}
- public WAbstractSlider setValueChangeListener(@Nullable IntConsumer valueChangeListener) {
+ public void setValueChangeListener(@Nullable IntConsumer valueChangeListener) {
this.valueChangeListener = valueChangeListener;
- return this;
}
- public WAbstractSlider setFocusReleaseListener(@Nullable Runnable focusReleaseListener) {
- this.focusReleaseListener = focusReleaseListener;
- return this;
+ public void setDraggingFinishedListener(@Nullable Runnable draggingFinishedListener) {
+ this.draggingFinishedListener = draggingFinishedListener;
}
public int getMinValue() {
@@ -159,27 +161,50 @@ public abstract class WAbstractSlider extends WWidget {
return axis;
}
+ protected void onValueChanged(int value) {
+ if (valueChangeListener != null) valueChangeListener.accept(value);
+ }
+
@Override
public void onKeyPressed(int ch, int key, int modifiers) {
boolean valueChanged = false;
if (modifiers == 0) {
- if ((ch == GLFW.GLFW_KEY_LEFT || ch == GLFW.GLFW_KEY_DOWN) && value > min) {
+ if (isDecreasingKey(ch) && value > min) {
value--;
valueChanged = true;
- } else if ((ch == GLFW.GLFW_KEY_RIGHT || ch == GLFW.GLFW_KEY_UP) && value < max) {
+ } else if (isIncreasingKey(ch) && value < max) {
value++;
valueChanged = true;
}
} else if (modifiers == GLFW.GLFW_MOD_CONTROL) {
- if ((ch == GLFW.GLFW_KEY_LEFT || ch == GLFW.GLFW_KEY_DOWN) && value != min) {
+ if (isDecreasingKey(ch) && value != min) {
value = min;
valueChanged = true;
- } else if ((ch == GLFW.GLFW_KEY_RIGHT || ch == GLFW.GLFW_KEY_UP) && value != max) {
+ } else if (isIncreasingKey(ch) && value != max) {
value = max;
valueChanged = true;
}
}
- if (valueChanged && valueChangeListener != null) valueChangeListener.accept(value);
+ if (valueChanged) {
+ onValueChanged(value);
+ valueChangedWithKeys = true;
+ }
+ }
+
+ @Override
+ public void onKeyReleased(int ch, int key, int modifiers) {
+ if (valueChangedWithKeys && (isDecreasingKey(ch) || isIncreasingKey(ch))) {
+ if (draggingFinishedListener != null) draggingFinishedListener.run();
+ valueChangedWithKeys = false;
+ }
+ }
+
+ private static boolean isDecreasingKey(int ch) {
+ return ch == GLFW.GLFW_KEY_LEFT || ch == GLFW.GLFW_KEY_DOWN;
+ }
+
+ private static boolean isIncreasingKey(int ch) {
+ return ch == GLFW.GLFW_KEY_RIGHT || ch == GLFW.GLFW_KEY_UP;
}
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java
index 77a3325..37fe464 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java
@@ -4,38 +4,62 @@ import io.github.cottonmc.cotton.gui.client.ScreenDrawing;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
-import net.minecraft.util.Identifier;
+import net.minecraft.text.Text;
+
+import javax.annotation.Nullable;
/**
* A vanilla-style labeled slider widget.
*
+ * <p>In addition to the standard slider listeners,
+ * labeled sliders also support "label updaters" that can update the label
+ * when the value is changed.
+ *
* @see WAbstractSlider for more information about listeners
*/
-/*
- TODO:
- - Add the labels
- - Better textures for thumbs when dragging
- - The thumb goes 1px outside the track on the right side
- */
public class WLabeledSlider extends WAbstractSlider {
- private static final Identifier TEXTURE = AbstractButtonWidget.WIDGETS_LOCATION;
+ @Nullable private Text label = null;
+ @Nullable private LabelUpdater labelUpdater = null;
public WLabeledSlider(int min, int max) {
super(min, max, Axis.HORIZONTAL);
}
- public WLabeledSlider(int max) {
- this(0, max);
+ public WLabeledSlider(int min, int max, Text label) {
+ this(min, max);
+ this.label = label;
}
+
@Override
public void setSize(int x, int y) {
super.setSize(x, 20);
}
+ @Nullable
+ public Text getLabel() {
+ return label;
+ }
+
+ public void setLabel(@Nullable Text label) {
+ this.label = label;
+ }
+
+ @Override
+ protected void onValueChanged(int value) {
+ super.onValueChanged(value);
+ if (labelUpdater != null) {
+ label = labelUpdater.updateLabel(value);
+ }
+ }
+
+ public void setLabelUpdater(@Nullable LabelUpdater labelUpdater) {
+ this.labelUpdater = labelUpdater;
+ }
+
@Override
protected int getThumbWidth() {
- return 6;
+ return 8;
}
@Override
@@ -49,16 +73,23 @@ public class WLabeledSlider extends WAbstractSlider {
drawButton(x, y, 0, width);
// 1: regular, 2: hovered, 0: disabled/dragging
- int thumbX = (int) (coordToValueRatio * (value - min));
+ int thumbX = Math.round(coordToValueRatio * (value - min));
int thumbY = 0;
int thumbWidth = getThumbWidth();
int thumbHeight = height;
- int thumbState = dragging ? 0 : (mouseX >= thumbX && mouseX <= thumbX + thumbWidth && mouseY >= thumbY && mouseY <= thumbY + thumbHeight ? 2 : 1);
+ boolean hovering = mouseX >= thumbX && mouseX <= thumbX + thumbWidth && mouseY >= thumbY && mouseY <= thumbY + thumbHeight;
+ int thumbState = dragging || hovering ? 2 : 1;
drawButton(x + thumbX, y + thumbY, thumbState, thumbWidth);
if (thumbState == 1 && isFocused()) {
- // TODO: draw the focus border
+ float px = 1 / 32f;
+ ScreenDrawing.rect(WSlider.TEXTURE, x + thumbX, y + thumbY, thumbWidth, thumbHeight, 24*px, 0*px, 32*px, 20*px, 0xFFFFFFFF);
+ }
+
+ if (label != null) {
+ int color = isMouseInsideBounds(mouseX, mouseY) ? 0xFFFFA0 : 0xE0E0E0;
+ ScreenDrawing.drawCenteredWithShadow(label.asFormattedString(), x + width / 2, y + height / 2 - 4, color);
}
}
@@ -77,4 +108,9 @@ public class WLabeledSlider extends WAbstractSlider {
ScreenDrawing.rect(AbstractButtonWidget.WIDGETS_LOCATION, x, y, halfWidth, 20, buttonLeft, buttonTop, buttonLeft + buttonWidth, buttonTop + buttonHeight, 0xFFFFFFFF);
ScreenDrawing.rect(AbstractButtonWidget.WIDGETS_LOCATION, x + halfWidth, y, halfWidth, 20, buttonEndLeft, buttonTop, 200 * px, buttonTop + buttonHeight, 0xFFFFFFFF);
}
+
+ @FunctionalInterface
+ public interface LabelUpdater {
+ Text updateLabel(int value);
+ }
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WSlider.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WSlider.java
index 14e9972..c57b705 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WSlider.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WSlider.java
@@ -9,19 +9,9 @@ import net.minecraft.util.Identifier;
import javax.annotation.Nullable;
/**
- * A slider widget that can be used to select int values.
+ * A simple slider widget that can be used to select int values.
*
- * <p>You can set two listeners on a slider:
- * <ul>
- * <li>
- * A value change listener that gets all value changes (except direct setValue calls).
- * </li>
- * <li>
- * A focus release listener that gets called when the player stops dragging the slider.
- * For example, this can be used for sending sync packets to the server
- * when the player has selected a value.
- * </li>
- * </ul>
+ * @see WAbstractSlider for supported listeners
*/
public class WSlider extends WAbstractSlider {
public static final int TRACK_WIDTH = 6;
@@ -78,7 +68,7 @@ public class WSlider extends WAbstractSlider {
ScreenDrawing.rect(TEXTURE, trackX, y + height, TRACK_WIDTH, 1, 16*px, 2*px, 22*px, 3*px, 0xFFFFFFFF);
} else {
int trackY = y + height / 2 - TRACK_WIDTH / 2;
- thumbX = (int) (coordToValueRatio * (value - min));
+ thumbX = Math.round(coordToValueRatio * (value - min));
thumbY = height / 2 - THUMB_SIZE / 2;
thumbXOffset = 8;
diff --git a/src/main/resources/assets/libgui/textures/widget/slider.png b/src/main/resources/assets/libgui/textures/widget/slider.png
index ce8f434..e41250e 100644
--- a/src/main/resources/assets/libgui/textures/widget/slider.png
+++ b/src/main/resources/assets/libgui/textures/widget/slider.png
Binary files differ