Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
0b6c834
Feat: Color Picker rewrite & alpha slider/presets
Superkat32 Jul 17, 2026
f4d7170
Feat: Re-add Color Picker confirm/cancel buttons, allow color picker …
Superkat32 Jul 17, 2026
9899ead
Feat: Improve color picker button scaling & precise preview alpha bac…
Superkat32 Jul 17, 2026
00bf779
Feat: Better Color Picker cursor shenanigans
Superkat32 Jul 17, 2026
c037cf7
Feat: Add color pickers to Sprite, Outline, Popup, and Text Block Pro…
Superkat32 Jul 17, 2026
0643f17
Chore: Sweep sweep
Superkat32 Jul 17, 2026
2f48750
Chore: Extra cleanup
Superkat32 Jul 17, 2026
3327dfb
Feat: Add background color into main screen for Text Block
Superkat32 Jul 17, 2026
e61b0c8
Chore: Optimize imports for various classes updated in the Color Pick…
Superkat32 Jul 17, 2026
bb1e544
Feat: Begin GlowcaseMultilineEditBox
Superkat32 Jul 28, 2026
e8cf50b
Feat: Begin GlowcaseMultilineEditBox (but also include these in case …
Superkat32 Jul 28, 2026
1fb1bf8
Feat: To-done: Multi-character selection (in Text Block screen) at th…
Superkat32 Jul 28, 2026
e69f2e5
Feat: Some cleanup and comments, before I work on the note edit screen
Superkat32 Jul 28, 2026
d394529
Feat: Beginning of overflow editing within GlowcaseMultilineEditBox
Superkat32 Jul 30, 2026
fb3fc7d
Feat: Better text overflow handling, break word selection/moving at tags
Superkat32 Aug 1, 2026
a15d17d
Chore: Comment cleanup
Superkat32 Aug 1, 2026
58a6d0e
Fix: Fix horizontal scrolling not being capped properly, inserting a …
Superkat32 Aug 1, 2026
b5eccdb
Chore: Little bit of cleanup & docs
Superkat32 Aug 1, 2026
b077971
Feat: Use new GlowcaseMultilineEditBox in NoteEditScreen
Superkat32 Aug 2, 2026
cb7a2b2
Chore: The great NoteEditScreen comment cleanup
Superkat32 Aug 2, 2026
d0e2834
Feat: Make PopupBlockEditScreen use new GlowcaseMultilineEditBox
Superkat32 Aug 2, 2026
2330682
Chore: Popup block edit screen comment cleanup
Superkat32 Aug 2, 2026
c8f3518
Feat: Show Popup Block's Title on PopupBlockViewScreen, and vertical …
Superkat32 Aug 3, 2026
30e4136
Chore: Optimize imports I think I did this like 5 hours ago
Superkat32 Aug 3, 2026
9b584a4
Feat: Begin Text Block ribbon tabs
Superkat32 Aug 5, 2026
858217c
Chore: Comment cleanup & some JavaDocs
Superkat32 Aug 5, 2026
d56811b
Feat: Continue work on Text Block tabs
Superkat32 Aug 6, 2026
243538b
Refactor: TextWidgets List isn't needed anymore
Superkat32 Aug 6, 2026
08e252e
Feat: Continue work on View Tab widgets
Superkat32 Aug 8, 2026
08394b7
Feat: Update Vec3FieldsWidget with builder & options, add DegreeRotat…
Superkat32 Aug 9, 2026
5961a48
Chore: Cleanup comments
Superkat32 Aug 9, 2026
a456a15
Feat: Insert Font tag button
Superkat32 Aug 9, 2026
eac6cdb
Feat: Fix some issues with SuggestionListWidget for the Text Screen, …
Superkat32 Aug 9, 2026
3a2e500
Feat: EditableSliderWidget (A slider which can be right-clicked to be…
Superkat32 Aug 10, 2026
fc71e08
Feat: Add text block offsets & rotations, allow InputFilter prefix to…
Superkat32 Aug 10, 2026
e575031
Feat: Creature of Whimsy
Superkat32 Aug 11, 2026
923d758
TODO (Anchor Controls) - Leave comments for future TODOs on the ancho…
Superkat32 Aug 11, 2026
db3a057
Fix: Ensure the edit box becomes focused after inserting a tag
Superkat32 Aug 11, 2026
9ce8174
Chore: Remove TextBlockOptionsScreen.java and cleanup other stuff lik…
Superkat32 Aug 11, 2026
1db6e9d
Feat: NumberEditBox(es), with ability to scroll to increment/decremen…
Superkat32 Aug 14, 2026
e3cf694
Chore: Some cleanup and fix integer box stack overflowing
Superkat32 Aug 14, 2026
beb3b6e
Feat: Add sounds to the number edit box for action feedback
Superkat32 Aug 14, 2026
ada7af0
Float point errors ruining my day!
Superkat32 Aug 15, 2026
26fa16b
Chore: Some extra cleanup & notes
Superkat32 Aug 17, 2026
8322584
Fix: Ensure the note item always has 10 lines, even if they are empty
Superkat32 Sep 7, 2026
79d15dc
Feat: Allow minimum alpha on Color Picker's alpha slider
Superkat32 Sep 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
import net.minecraft.world.level.storage.ValueOutput;

public class PopupBlockEntity extends GlowcaseBlockEntity {
public static final NodeParser PARSER = TagParser.DEFAULT;
public String title = "";
public List<Component> lines = new ArrayList<>();
public TextBlockEntity.TextAlignment textAlignment = TextBlockEntity.TextAlignment.CENTER;
public int color = 0xFFFFFFFF;
public boolean renderDirty = true;
public boolean viewScreenTitle = true;

public PopupBlockEntity(BlockPos pos, BlockState state) {
super(Glowcase.POPUP_BLOCK_ENTITY.get(), pos, state);
Expand All @@ -32,6 +32,7 @@ protected void saveAdditional(ValueOutput view) {
super.saveAdditional(view);

view.putString("title", this.title);
view.putBoolean("view_screen_title", this.viewScreenTitle);
view.putInt("color", this.color);

view.store("text_alignment", TextBlockEntity.TextAlignment.CODEC, this.textAlignment);
Expand All @@ -44,6 +45,7 @@ protected void loadAdditional(ValueInput view) {
super.loadAdditional(view);

this.title = view.getStringOr("title", "");
this.viewScreenTitle = view.getBooleanOr("view_screen_title", true);
this.color = view.getIntOr("color", 0xFFFFFF);

this.textAlignment = view.read("text_alignment", TextBlockEntity.TextAlignment.CODEC).orElse(TextBlockEntity.TextAlignment.CENTER);
Expand All @@ -52,39 +54,4 @@ protected void loadAdditional(ValueInput view) {

this.renderDirty = true;
}

public String getRawLine(int i) {
var line = this.lines.get(i);

if (line.getStyle() == null) {
return line.getString();
}

var insert = line.getStyle().getInsertion();

if (insert == null) {
return line.getString();
}
return insert;
}

public void addRawLine(int i, String string) {
var parsed = PARSER.parseComponent(string, ParserContext.of());

if (parsed.getString().equals(string)) {
this.lines.add(i, Component.literal(string));
} else {
this.lines.add(i, Component.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string)));
}
}

public void setRawLine(int i, String string) {
var parsed = PARSER.parseComponent(string, ParserContext.of());

if (parsed.getString().equals(string)) {
this.lines.set(i, Component.literal(string));
} else {
this.lines.set(i, Component.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string)));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,25 @@
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput;
import net.minecraft.world.phys.Vec3;

import java.util.ArrayList;
import java.util.List;

public class TextBlockEntity extends GlowcaseBlockEntity {
public static final NodeParser PARSER = TagParser.DEFAULT;

public static final int PLATE_BACKGROUND = 0x44000000;

public List<Component> lines = new ArrayList<>();
// TODO (AC) - Anchor related field changes/additions (don't forget to save & load them!)
public TextAlignment textAlignment = TextAlignment.CENTER;
public HorizontalAlignment horizontalAlignment = HorizontalAlignment.CENTER;
public ZOffset zOffset = ZOffset.CENTER;
public boolean shadow = true;
public float scale = 1F;
public int color = ColorUtil.WHITE;
public int backgroundColor = 0;
public Vec3 offset = Vec3.ZERO;
public Vec3 rotation = Vec3.ZERO; // Yaw, pitch, roll

public TextBlockEntity(BlockPos pos, BlockState state) {
super(Glowcase.TEXT_BLOCK_ENTITY.get(), pos, state);
Expand All @@ -54,7 +56,10 @@ protected void saveAdditional(ValueOutput view) {
view.store("z_offset", ZOffset.CODEC, this.zOffset);
view.putBoolean("shadow", this.shadow);

view.store("lines", ComponentSerialization.CODEC.listOf(), lines);
view.store("lines", ComponentSerialization.CODEC.listOf(), this.lines);

view.store("offset", Vec3.CODEC, this.offset);
view.store("rotation", Vec3.CODEC, this.rotation);
}

@Override
Expand All @@ -69,53 +74,24 @@ protected void loadAdditional(ValueInput view) {

this.backgroundColor = view.getIntOr("background_color", 0);
this.shadow = view.getBooleanOr("shadow", true);
// TODO (AC) - Handle loading old data alignment and converting it into new justify/anchor/whatever data
this.textAlignment = view.read("text_alignment", TextAlignment.CODEC).orElse(TextAlignment.CENTER);
this.horizontalAlignment = view.read("horizontal_alignment", HorizontalAlignment.CODEC).orElse(HorizontalAlignment.CENTER);
this.zOffset = view.read("z_offset", ZOffset.CODEC).orElse(ZOffset.CENTER);
this.lines = new ArrayList<>(view.read("lines", ComponentSerialization.CODEC.listOf()).orElseGet(List::of));
this.rebake(false);
}

public String getRawLine(int i) {
var line = this.lines.get(i);

if (line.getStyle() == null) {
return line.getString();
}

var insert = line.getStyle().getInsertion();

if (insert == null) {
return line.getString();
}
return insert;
}

public void addRawLine(int i, String string) {
var parsed = PARSER.parseComponent(string, ParserContext.of());

if (parsed.getString().equals(string)) {
this.lines.add(i, Component.literal(string));
} else {
this.lines.add(i, Component.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string)));
}
}
this.offset = view.read("offset", Vec3.CODEC).orElse(Vec3.ZERO);
this.rotation = view.read("rotation", Vec3.CODEC).orElse(Vec3.ZERO);

public void setRawLine(int i, String string) {
var parsed = PARSER.parseComponent(string, ParserContext.of());

if (parsed.getString().equals(string)) {
this.lines.set(i, Component.literal(string));
} else {
this.lines.set(i, Component.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string)));
}
this.rebake(false);
}

public void rebake(boolean immediate) {
if (!this.hasLevel() || !this.getLevel().isClientSide()) return;
this.getLevel().sendBlockUpdated(this.getBlockPos(), this.getBlockState(), this.getBlockState(), immediate ? Block.UPDATE_IMMEDIATE : 0);
}

// TODO (AC) - Rename into TextJustify?
public enum TextAlignment implements StringRepresentable {
LEFT,
CENTER,
Expand All @@ -133,6 +109,8 @@ public String getSerializedName() {
}
}

// TODO (AC Idea) - Rename to "ZAnchor" to provide a clear distinction between xyz offset and this?
// If done, fields/variables and translations for the edit screen should be updated
public enum ZOffset implements StringRepresentable {
FRONT, CENTER, BACK;

Expand All @@ -144,6 +122,7 @@ public String getSerializedName() {
}
}

@Deprecated
public enum HorizontalAlignment implements StringRepresentable {
LEFT, CENTER, RIGHT;

Expand All @@ -155,4 +134,41 @@ public String getSerializedName() {
return name().toLowerCase();
}
}

public enum Anchor implements StringRepresentable {
TOP_LEFT(-1, 1), TOP(0, 1), TOP_RIGHT(1, 1),
MIDDLE_LEFT(-1, 0), MIDDLE(0, 0), MIDDLE_RIGHT(1, 0),
BOTTOM_LEFT(-1, -1), BOTTOM(0, -1), BOTTOM_RIGHT(1, -1);

public static final Codec<Anchor> CODEC = StringRepresentable.fromEnum(Anchor::values);
public static final StreamCodec<ByteBuf, Anchor> STREAM_CODEC = ByteBufCodecs.BYTE.map(index -> Anchor.values()[index], anchor -> (byte) anchor.ordinal());

public static Anchor fromHorizontalAlignment(HorizontalAlignment horizontalAlignment) {
return switch (horizontalAlignment) {
case LEFT -> MIDDLE_LEFT;
case RIGHT -> MIDDLE_RIGHT;
default -> MIDDLE;
};
}

private final int x;
private final int y;
Anchor(int x, int y) {
this.x = x;
this.y = y;
}

public int getX() {
return this.x;
}

public int getY() {
return this.y;
}

@Override
public String getSerializedName() {
return this.name().toLowerCase();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,81 @@
package dev.hephaestus.glowcase.client.gui.screen.ingame;

import dev.hephaestus.glowcase.client.gui.widget.ingame.ColorPickerWidget;
import net.minecraft.ChatFormatting;
import dev.hephaestus.glowcase.client.gui.widget.ingame.color.picker.ColorPickerWidget;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.input.KeyEvent;
import net.minecraft.client.input.MouseButtonEvent;
import org.lwjgl.glfw.GLFW;

/**
* Main interface for any Screen wishing to implement a {@link ColorPickerWidget}.<br><br>
* Each ColorPickerIncludedScreen has *one* Color Picker widget which gets shared among all things using it.<br>
* Steps for adding a Color Picker to a screen:
* <ol type="0">
* <li>Implement this interface, and return a private ColorPickerWidget in {@link ColorPickerIncludedScreen#getColorPickerWidget()}.</li>
* <li>Initialize your ColorPickerWidget in {@link Screen#init()} via {@link ColorPickerWidget#builder(ColorPickerIncludedScreen)}. You do *not* need to add it as a renderableWidget.</li>
* <li>Include {@link ColorPickerIncludedScreen#extractColorPicker(GuiGraphicsExtractor, int, int, float)} at the very bottom of {@link Screen#extractRenderState(GuiGraphicsExtractor, int, int, float)} to ensure it renders atop of everything else.</li>
* <li>Include {@link ColorPickerIncludedScreen#mouseClickedColorPicker(MouseButtonEvent, boolean)} at the very top of {@link Screen#mouseClicked(MouseButtonEvent, boolean)}, return true if color picker was clicked, otherwise continue with method.</li>
* <li>Include {@link ColorPickerIncludedScreen#keyPressedColorPicker(KeyEvent)} at the very top of {@link Screen#keyPressed(KeyEvent)}, return true if color picker key pressed, otherwise continue with method.</li>
* <li>Booyah!</li>
* </ol>
* @author Superkat32
*/
public interface ColorPickerIncludedScreen {
ColorPickerWidget colorPickerWidget();
void toggleColorPicker(boolean active);
void insertHexTag(String hex);
void insertFormattingTag(ChatFormatting formatting);
ColorPickerWidget getColorPickerWidget();

default ColorPickerWidget createColorPickerWidget() {
return ColorPickerWidget.builder(this).build();
}

default void extractColorPicker(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float delta) {
this.getColorPickerWidget().extractRenderState(graphics, mouseX, mouseY, delta);
}

default boolean mouseClickedColorPicker(MouseButtonEvent event, boolean doubleClick) {
double mouseX = event.x();
double mouseY = event.y();
ColorPickerWidget colorPickerWidget = this.getColorPickerWidget();

if (colorPickerWidget.isActive() && colorPickerWidget.visible) {
if (colorPickerWidget.isMouseOver(mouseX, mouseY)) {
colorPickerWidget.mouseClicked(event, doubleClick);
Screen self = (Screen) this;
self.setFocused(colorPickerWidget);
self.setDragging(true);
return true;
} else if (colorPickerWidget.targetElement == null || !colorPickerWidget.targetElement.isMouseOver(mouseX, mouseY)) {
this.hideColorPickerWidget();
}
}
return false;
}

default boolean keyPressedColorPicker(KeyEvent event) {
int keyCode = event.key();
ColorPickerWidget colorPickerWidget = this.getColorPickerWidget();
if (colorPickerWidget.isActive()) {
Screen self = (Screen) this;
switch (keyCode) {
case GLFW.GLFW_KEY_ENTER, GLFW.GLFW_KEY_KP_ENTER -> colorPickerWidget.confirm();
case GLFW.GLFW_KEY_ESCAPE -> colorPickerWidget.cancel();
default -> {
GuiEventListener pickerTarget = colorPickerWidget.targetElement;
if (pickerTarget != null) {
self.setFocused(pickerTarget);
pickerTarget.keyPressed(event);
return true;
}
}
}
self.setFocused(null);
return true;
}
return false;
}

default void hideColorPickerWidget() {
this.getColorPickerWidget().hide();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public void init() {
this.itemWidget.setValue((this.blockEntity.isItemTag ? "#" : "") + item);
}
this.itemWidget.setHint(TextUtils.placeholder("gui.glowcase.item_or_tag"));
this.itemWidget.setFilter((currentValue, newChar, cursorPos) -> {
if (!InputFilters.assertOptionalPrefix('#', currentValue, newChar, cursorPos)) return false;
this.itemWidget.setFilter((currentValue, newChar, cursorPos, highlightPos) -> {
if (!InputFilters.assertOptionalPrefix('#', currentValue, newChar, cursorPos, highlightPos)) return false;
if (newChar == '#' && cursorPos == 0) return true;

return this.isValidCharacterForName(currentValue, newChar, cursorPos);
Expand Down
Loading
Loading