diff --git a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/ManagerScreen.java b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/ManagerScreen.java index 596fe0cf3..1d17d70fd 100644 --- a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/ManagerScreen.java +++ b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/ManagerScreen.java @@ -4,6 +4,7 @@ import ca.teamdman.sfm.client.registry.SFMKeyMappings; import ca.teamdman.sfm.client.screen.tick_graph.TickTimeGraphRenderState; import ca.teamdman.sfm.client.screen.widget.SFMButtonBuilder; +import ca.teamdman.sfm.client.screen.widget.SFMPreferredEditorDropdown; import ca.teamdman.sfm.client.text_editor.SFMTextEditScreenDiskOpenContext; import ca.teamdman.sfm.common.command.ConfigCommandBehaviourInput; import ca.teamdman.sfm.common.containermenu.ManagerContainerMenu; @@ -375,6 +376,13 @@ protected void init() { ) .build() ); + this.addRenderableWidget(SFMPreferredEditorDropdown.create( + (this.width - this.imageWidth) / 2 - buttonWidth, + (this.height - this.imageHeight) / 2 + 16 + 50 - buttonHeight - 2, + buttonWidth, + buttonHeight, + false + )); editButton = this.addRenderableWidget( new SFMButtonBuilder() .setPosition( diff --git a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMDrawCanvasScreen.java b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMDrawCanvasScreen.java index 770db51d3..bbf804df0 100644 --- a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMDrawCanvasScreen.java +++ b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMDrawCanvasScreen.java @@ -2,6 +2,7 @@ import ca.teamdman.sfm.SFM; import ca.teamdman.sfm.client.screen.widget.SFMButtonBuilder; +import ca.teamdman.sfm.client.screen.widget.SFMPreferredEditorDropdown; import ca.teamdman.sfm.client.screen.text_editor.ISFMTextEditScreen; import ca.teamdman.sfm.client.text_editor.ISFMTextEditScreenOpenContext; import ca.teamdman.sfm.common.config.SFMConfig; @@ -215,6 +216,14 @@ protected void init() { () -> { } ))) .build()); + this.addRenderableWidget(SFMPreferredEditorDropdown.createForEditor( + 22, + this.height - 24, + 110, + 20, + this, + this::getCurrentText + )); } sfmlButton = new SFMButtonBuilder() .setPosition(this.width - 140, this.height - 24) diff --git a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMScreenChangeHelpers.java b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMScreenChangeHelpers.java index a834e87a7..dbf4d0670 100644 --- a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMScreenChangeHelpers.java +++ b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMScreenChangeHelpers.java @@ -117,15 +117,17 @@ public static void showExampleListScreen( ) { setOrPushScreen(new ExamplesScreen((chosenExample, templates) -> { - SFMTextEditScreenV1 screen = new SFMTextEditScreenV1(new SFMTextEditScreenExampleProgramOpenContext( + ISFMTextEditScreen screen = createProgramEditScreen(new SFMTextEditScreenExampleProgramOpenContext( chosenExample, diskProgramString, templates, labelPositionHolder, saveCallback )); - setOrPushScreen(screen); - screen.scrollToTop(); + showTextEditScreen(screen); + if (screen instanceof SFMTextEditScreenV1 v1) { + v1.scrollToTop(); + } })); } @@ -169,7 +171,7 @@ public static void showItemInspectorScreen(ItemStack stack) { public static void showChangelog() { SFMExampleProgram changelogExampleProgram = SFMExampleProgram.getChangelog(); - SFMTextEditScreenV1 screen = new SFMTextEditScreenV1(new SFMTextEditScreenExampleProgramOpenContext( + ISFMTextEditScreen screen = createProgramEditScreen(new SFMTextEditScreenExampleProgramOpenContext( changelogExampleProgram.programString(), changelogExampleProgram.programString(), List.of(changelogExampleProgram), @@ -177,8 +179,10 @@ public static void showChangelog() { newContent -> { } )); - setOrPushScreen(screen); - screen.scrollToTop(); + showTextEditScreen(screen); + if (screen instanceof SFMTextEditScreenV1 v1) { + v1.scrollToTop(); + } } public static @Nullable Screen getCurrentScreen() { diff --git a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMTextEditorConfigScreen.java b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMTextEditorConfigScreen.java index 02d4b745c..b0e7d35a7 100644 --- a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMTextEditorConfigScreen.java +++ b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/SFMTextEditorConfigScreen.java @@ -1,13 +1,11 @@ package ca.teamdman.sfm.client.screen; -import ca.teamdman.sfm.client.registry.SFMTextEditors; import ca.teamdman.sfm.client.screen.text_editor.ISFMTextEditScreen; import ca.teamdman.sfm.client.screen.widget.SFMButtonBuilder; import ca.teamdman.sfm.client.text_editor.SFMTextEditorIntellisenseLevel; import ca.teamdman.sfm.common.config.SFMClientTextEditorConfig; import ca.teamdman.sfm.common.localization.LocalizationEntry; import ca.teamdman.sfm.common.localization.SFMLocalizationDatagen; -import ca.teamdman.sfm.common.util.SFMEnvironmentUtils; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.Screen; @@ -15,24 +13,6 @@ @SuppressWarnings("NotNullFieldNotInitialized") public class SFMTextEditorConfigScreen extends Screen { - @SFMLocalizationDatagen - public static final LocalizationEntry PROGRAM_EDITOR_CONFIG_PREFERRED_EDITOR = new LocalizationEntry( - "gui.sfm.program_editor_config.preferred_editor", - "Preferred Editor" - ); - - @SFMLocalizationDatagen - public static final LocalizationEntry PROGRAM_EDITOR_CONFIG_PREFERRED_EDITOR_V1 = new LocalizationEntry( - "gui.sfm.program_editor_config.preferred_editor.v1", - "V1 (Default)" - ); - - @SFMLocalizationDatagen - public static final LocalizationEntry PROGRAM_EDITOR_CONFIG_PREFERRED_EDITOR_V2 = new LocalizationEntry( - "gui.sfm.program_editor_config.preferred_editor.v2", - "V2" - ); - @SFMLocalizationDatagen public static final LocalizationEntry PROGRAM_EDITOR_CONFIG_SCREEN_TITLE = new LocalizationEntry( "gui.sfm.program_editor_config.title", @@ -78,8 +58,6 @@ public class SFMTextEditorConfigScreen extends Screen { private final Runnable closeCallback; - private final boolean editorSelectorFeatureFlag = SFMEnvironmentUtils.isInIDE(); - private Button lineNumbersOnButton; private Button lineNumbersOffButton; @@ -90,10 +68,6 @@ public class SFMTextEditorConfigScreen extends Screen { private Button intellisenseAdvancedButton; - private Button preferredEditorV1Button; - - private Button preferredEditorV2Button; - public SFMTextEditorConfigScreen( ISFMTextEditScreen parent, SFMClientTextEditorConfig config, @@ -140,15 +114,6 @@ public void extractRenderState( y + 50, 0xFFFFFFFF ); - if (editorSelectorFeatureFlag) { - graphics.text( - font, - PROGRAM_EDITOR_CONFIG_PREFERRED_EDITOR.getComponent(), - x, - y + 100, - 0xFFFFFFFF - ); - } graphics.centeredText( font, this.title, @@ -179,6 +144,7 @@ protected void init() { .setText(CommonComponents.OPTION_ON) .setOnPress(button -> { config.showLineNumbers.set(true); + config.showLineNumbers.save(); updateButtonStates(); }) .build(); @@ -189,6 +155,7 @@ protected void init() { .setText(CommonComponents.OPTION_OFF) .setOnPress(button -> { config.showLineNumbers.set(false); + config.showLineNumbers.save(); updateButtonStates(); }) .build(); @@ -204,6 +171,7 @@ protected void init() { .setText(PROGRAM_EDITOR_CONFIG_INTELLISENSE_OFF) .setOnPress(button -> { config.intellisenseLevel.set(SFMTextEditorIntellisenseLevel.OFF); + config.intellisenseLevel.save(); updateButtonStates(); parent.onPreferenceChanged(); }) @@ -215,6 +183,7 @@ protected void init() { .setText(PROGRAM_EDITOR_CONFIG_INTELLISENSE_BASIC) .setOnPress(button -> { config.intellisenseLevel.set(SFMTextEditorIntellisenseLevel.BASIC); + config.intellisenseLevel.save(); updateButtonStates(); parent.onPreferenceChanged(); }) @@ -228,6 +197,7 @@ protected void init() { .setText(PROGRAM_EDITOR_CONFIG_INTELLISENSE_ADVANCED) .setOnPress(button -> { config.intellisenseLevel.set(SFMTextEditorIntellisenseLevel.ADVANCED); + config.intellisenseLevel.save(); updateButtonStates(); parent.onPreferenceChanged(); }) @@ -237,36 +207,6 @@ protected void init() { this.addRenderableWidget(intellisenseBasicButton); this.addRenderableWidget(intellisenseAdvancedButton); - // Preferred Editor Buttons - preferredEditorV1Button = - new SFMButtonBuilder() - .setPosition(x, y + 2 * spacing) - .setSize(buttonWidth, buttonHeight) - .setText(PROGRAM_EDITOR_CONFIG_PREFERRED_EDITOR_V1) - .setOnPress(button -> { - //noinspection OptionalGetWithoutIsPresent - config.preferredEditor.set(SFMTextEditors.V1.getId().get().identifier().toString()); - updateButtonStates(); - }) - .build(); - preferredEditorV2Button = - new SFMButtonBuilder() - .setPosition(x + buttonWidth + buttonSpacing, y + 2 * spacing) - .setSize(buttonWidth, buttonHeight) - .setText(PROGRAM_EDITOR_CONFIG_PREFERRED_EDITOR_V2) - .setOnPress(button -> { - //noinspection OptionalGetWithoutIsPresent - config.preferredEditor.set(SFMTextEditors.V2.getId().get().identifier().toString()); - updateButtonStates(); - }) - .build(); - if (editorSelectorFeatureFlag) { - // This behaviour is not ready for release. - this.addRenderableWidget(preferredEditorV1Button); - this.addRenderableWidget(preferredEditorV2Button); - } - - // Done Button this.addRenderableWidget( new SFMButtonBuilder() @@ -290,12 +230,6 @@ private void updateButtonStates() { config.intellisenseLevel.get() != SFMTextEditorIntellisenseLevel.BASIC; intellisenseAdvancedButton.active = config.intellisenseLevel.get() != SFMTextEditorIntellisenseLevel.ADVANCED; - - String currentEditor = config.preferredEditor.get(); - //noinspection OptionalGetWithoutIsPresent - preferredEditorV1Button.active = !currentEditor.equals(SFMTextEditors.V1.getId().get().identifier().toString()); - //noinspection OptionalGetWithoutIsPresent - preferredEditorV2Button.active = !currentEditor.equals(SFMTextEditors.V2.getId().get().identifier().toString()); } } diff --git a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/text_editor/SFMTextEditScreenV1.java b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/text_editor/SFMTextEditScreenV1.java index bfa158391..97a55f03c 100644 --- a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/text_editor/SFMTextEditScreenV1.java +++ b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/text_editor/SFMTextEditScreenV1.java @@ -7,6 +7,7 @@ import ca.teamdman.sfm.client.screen.widget.PickList; import ca.teamdman.sfm.client.screen.widget.PickListItem; import ca.teamdman.sfm.client.screen.widget.SFMButtonBuilder; +import ca.teamdman.sfm.client.screen.widget.SFMPreferredEditorDropdown; import ca.teamdman.sfm.client.text_editor.ISFMTextEditScreenOpenContext; import ca.teamdman.sfm.client.text_styling.ProgramSyntaxHighlightingHelper; import ca.teamdman.sfm.common.config.SFMConfig; @@ -370,13 +371,21 @@ protected void init() { .setTooltip(this, font, PROGRAM_EDIT_SCREEN_CONFIG_BUTTON_TOOLTIP) .build() ); + this.addRenderableWidget(SFMPreferredEditorDropdown.createForEditor( + this.width / 2 - 180, + this.height / 2 - 100 + 195, + 110, + 20, + this, + () -> textarea.getValue() + )); this.addRenderableWidget( new SFMButtonBuilder() .setPosition( - this.width / 2 - 2 - 150, + this.width / 2 - 66, this.height / 2 - 100 + 195 ) - .setSize(200, 20) + .setSize(130, 20) .setText(CommonComponents.GUI_DONE) .setOnPress((button) -> this.saveAndClose()) .setTooltip(this, font, PROGRAM_EDIT_SCREEN_DONE_BUTTON_TOOLTIP) @@ -385,10 +394,10 @@ protected void init() { this.addRenderableWidget( new SFMButtonBuilder() .setPosition( - this.width / 2 - 2 + 100, + this.width / 2 + 68, this.height / 2 - 100 + 195 ) - .setSize(100, 20) + .setSize(130, 20) .setText(CommonComponents.GUI_CANCEL) .setOnPress((button) -> this.onClose()) .build() diff --git a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/text_editor/SFMTextEditScreenV2.java b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/text_editor/SFMTextEditScreenV2.java index 55ff57d6d..01698551b 100644 --- a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/text_editor/SFMTextEditScreenV2.java +++ b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/text_editor/SFMTextEditScreenV2.java @@ -7,6 +7,7 @@ import ca.teamdman.sfm.client.screen.SFMScreenRenderUtils; import ca.teamdman.sfm.client.screen.SFMTextEditorConfigScreen; import ca.teamdman.sfm.client.screen.widget.SFMButtonBuilder; +import ca.teamdman.sfm.client.screen.widget.SFMPreferredEditorDropdown; import ca.teamdman.sfm.client.text_editor.Caret; import ca.teamdman.sfm.client.text_editor.Cursor; import ca.teamdman.sfm.client.text_editor.ISFMTextEditScreenOpenContext; @@ -248,6 +249,14 @@ protected void init() { .setTooltip(this, font, SFMTextEditScreenV1.PROGRAM_EDIT_SCREEN_CONFIG_BUTTON_TOOLTIP) .build() ); + this.addRenderableWidget(SFMPreferredEditorDropdown.createForEditor( + 22, + this.height - 24, + 110, + 20, + this, + () -> textEditContext.getContent() + )); } protected void renderTooltip( diff --git a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/widget/SFMPreferredEditorDropdown.java b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/widget/SFMPreferredEditorDropdown.java new file mode 100644 index 000000000..df78ff18b --- /dev/null +++ b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/screen/widget/SFMPreferredEditorDropdown.java @@ -0,0 +1,373 @@ +package ca.teamdman.sfm.client.screen.widget; + +import ca.teamdman.sfm.client.registry.SFMTextEditors; +import ca.teamdman.sfm.client.screen.SFMFontUtils; +import ca.teamdman.sfm.client.screen.SFMScreenChangeHelpers; +import ca.teamdman.sfm.client.screen.text_editor.ISFMTextEditScreen; +import ca.teamdman.sfm.client.text_editor.ISFMTextEditScreenOpenContext; +import ca.teamdman.sfm.client.text_editor.ISFMTextEditorRegistration; +import ca.teamdman.sfm.client.text_editor.SFMPreferredEditorChangedEvent; +import ca.teamdman.sfm.common.config.SFMConfig; +import ca.teamdman.sfm.common.label.LabelPositionHolder; +import ca.teamdman.sfm.common.localization.LocalizationEntry; +import ca.teamdman.sfm.common.localization.SFMLocalizationDatagen; +import ca.teamdman.sfm.common.util.SFMResourceLocation; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.Identifier; +import net.neoforged.neoforge.common.NeoForge; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class SFMPreferredEditorDropdown { + @SFMLocalizationDatagen + public static final LocalizationEntry PREFERRED_EDITOR = new LocalizationEntry( + "gui.sfm.preferred_editor", + "Editor" + ); + + @SFMLocalizationDatagen + public static final LocalizationEntry PREFERRED_EDITOR_V1 = new LocalizationEntry( + "gui.sfm.preferred_editor.sfm.v1", + "V1 (Default)" + ); + + @SFMLocalizationDatagen + public static final LocalizationEntry PREFERRED_EDITOR_V2 = new LocalizationEntry( + "gui.sfm.preferred_editor.sfm.v2", + "V2" + ); + + @SFMLocalizationDatagen + public static final LocalizationEntry PREFERRED_EDITOR_DRAW = new LocalizationEntry( + "gui.sfm.preferred_editor.sfm.draw", + "Draw" + ); + + public static Button create( + int x, + int y, + int width, + int height, + boolean compact + ) { + + return new SFMButtonBuilder() + .setPosition(x, y) + .setSize(width, height) + .setText(buttonMessage(getCurrentEditorId(), compact)) + .setOnPress(button -> SFMScreenChangeHelpers.setOrPushScreen(new PickerScreen( + x, + y, + width, + height, + id -> button.setMessage(buttonMessage(id, compact)) + ))) + .build(); + } + + public static Button createForEditor( + int x, + int y, + int width, + int height, + ISFMTextEditScreen editorScreen, + Supplier latestContent + ) { + + return new SFMButtonBuilder() + .setPosition(x, y) + .setSize(width, height) + .setText(buttonMessage(getCurrentEditorId(), true)) + .setOnPress(button -> SFMScreenChangeHelpers.setOrPushScreen(new PickerScreen( + x, + y, + width, + height, + id -> switchEditor(editorScreen, latestContent.get()) + ))) + .build(); + } + + private static void switchEditor( + ISFMTextEditScreen editorScreen, + String latestContent + ) { + + ISFMTextEditScreenOpenContext oldContext = editorScreen.openContext(); + ISFMTextEditScreenOpenContext newContext = new ISFMTextEditScreenOpenContext() { + @Override + public String initialValue() { + + return latestContent; + } + + @Override + public void onTryClose( + String newLatestContent, + Runnable finalizeClose + ) { + + oldContext.onTryClose(newLatestContent, finalizeClose); + } + + @Override + public void onSaveAndClose(String newLatestContent) { + + oldContext.onSaveAndClose(newLatestContent); + } + + @Override + public Consumer saveWriter() { + + return oldContext.saveWriter(); + } + + @Override + public LabelPositionHolder labelPositionHolder() { + + return oldContext.labelPositionHolder(); + } + }; + ISFMTextEditScreen newScreen = SFMScreenChangeHelpers.createProgramEditScreen(newContext); + switch (editorScreen.openBehaviour()) { + case Push -> { + SFMScreenChangeHelpers.popScreen(); + SFMScreenChangeHelpers.showTextEditScreen(newScreen); + } + case Replace -> SFMScreenChangeHelpers.setScreen(newScreen.asScreen()); + } + } + + public static Component getDisplayName(Identifier id) { + + return Component.translatableWithFallback( + PREFERRED_EDITOR.key().get() + "." + id.getNamespace() + "." + id.getPath(), + id.toString() + ); + } + + public static List getEditorIds() { + + List editorIds = new ArrayList<>(); + for (ISFMTextEditorRegistration registration : SFMTextEditors.registry()) { + Identifier id = SFMTextEditors.registry().getId(registration); + if (id != null) { + editorIds.add(id); + } + } + return editorIds; + } + + public static Identifier getCurrentEditorId() { + + List editorIds = getEditorIds(); + @Nullable Identifier current = SFMResourceLocation.tryParse( + SFMConfig.CLIENT_TEXT_EDITOR_CONFIG.preferredEditor.get() + ); + if (current == null || !editorIds.contains(current)) { + current = editorIds.getFirst(); + } + return current; + } + + private static Component buttonMessage( + Identifier id, + boolean compact + ) { + + MutableComponent message = compact + ? getDisplayName(id).copy() + : PREFERRED_EDITOR.getComponent().append(": ").append(getDisplayName(id)); + return message.append(" ▼"); + } + + private static class PickerScreen extends Screen { + private static final int PANEL_PADDING = 3; + + private static final int PANEL_BACKGROUND = 0xF0141414; + + private static final int PANEL_BORDER = 0xFF8B8B8B; + + private static final int ROW_HOVER_BACKGROUND = 0x40FFFFFF; + + private static final int TEXT_COLOR = 0xFFE0E0E0; + + private static final int TEXT_COLOR_HOVERED = 0xFFFFFFFF; + + private static final int TEXT_COLOR_CURRENT = 0xFFFFD83D; + + private final int anchorX; + + private final int anchorY; + + private final int anchorWidth; + + private final int anchorHeight; + + private final Consumer onSelect; + + private List editorIds = List.of(); + + private Identifier currentEditorId; + + private int popupX; + + private int popupY; + + private int popupWidth; + + private int popupHeight; + + private int rowHeight; + + private PickerScreen( + int anchorX, + int anchorY, + int anchorWidth, + int anchorHeight, + Consumer onSelect + ) { + + super(PREFERRED_EDITOR.getComponent()); + this.anchorX = anchorX; + this.anchorY = anchorY; + this.anchorWidth = anchorWidth; + this.anchorHeight = anchorHeight; + this.onSelect = onSelect; + } + + @Override + public boolean isInGameUi() { + + return true; + } + + @Override + protected void init() { + + super.init(); + editorIds = getEditorIds(); + currentEditorId = getCurrentEditorId(); + rowHeight = this.font.lineHeight + 4; + popupWidth = anchorWidth; + for (Identifier id : editorIds) { + popupWidth = Math.max(popupWidth, this.font.width(getDisplayName(id)) + 2 * PANEL_PADDING + 8); + } + popupHeight = editorIds.size() * rowHeight + 2 * PANEL_PADDING; + boolean dropUp = anchorY + anchorHeight + popupHeight + 2 > this.height; + popupX = Math.max(0, Math.min(anchorX, this.width - popupWidth)); + popupY = dropUp ? anchorY - popupHeight - 2 : anchorY + anchorHeight + 2; + } + + @Override + public void extractRenderState( + GuiGraphicsExtractor graphics, + int mouseX, + int mouseY, + float partialTick + ) { + + super.extractRenderState(graphics, mouseX, mouseY, partialTick); + graphics.fill( + popupX - 1, + popupY - 1, + popupX + popupWidth + 1, + popupY + popupHeight + 1, + PANEL_BORDER + ); + graphics.fill( + popupX, + popupY, + popupX + popupWidth, + popupY + popupHeight, + PANEL_BACKGROUND + ); + int hoveredIndex = rowIndexAt(mouseX, mouseY); + for (int i = 0; i < editorIds.size(); i++) { + Identifier id = editorIds.get(i); + int rowY = popupY + PANEL_PADDING + i * rowHeight; + if (i == hoveredIndex) { + graphics.fill( + popupX + 1, + rowY, + popupX + popupWidth - 1, + rowY + rowHeight, + ROW_HOVER_BACKGROUND + ); + } + int color = id.equals(currentEditorId) + ? TEXT_COLOR_CURRENT + : i == hoveredIndex ? TEXT_COLOR_HOVERED : TEXT_COLOR; + SFMFontUtils.draw( + graphics, + this.font, + getDisplayName(id), + popupX + PANEL_PADDING + 4, + rowY + 2, + color, + true + ); + } + } + + @Override + public void extractBackground( + GuiGraphicsExtractor graphics, + int mouseX, + int mouseY, + float partialTick + ) { + + } + + private int rowIndexAt( + double mouseX, + double mouseY + ) { + + if (mouseX < popupX || mouseX >= popupX + popupWidth) { + return -1; + } + if (mouseY < popupY + PANEL_PADDING) { + return -1; + } + int index = (int) ((mouseY - popupY - PANEL_PADDING) / rowHeight); + return index >= 0 && index < editorIds.size() ? index : -1; + } + + @Override + public boolean mouseClicked( + MouseButtonEvent event, + boolean doubleClick + ) { + + int index = rowIndexAt(event.x(), event.y()); + this.onClose(); + if (index >= 0) { + Identifier id = editorIds.get(index); + if (!id.equals(currentEditorId)) { + SFMConfig.CLIENT_TEXT_EDITOR_CONFIG.preferredEditor.set(id.toString()); + SFMConfig.CLIENT_TEXT_EDITOR_CONFIG.preferredEditor.save(); + NeoForge.EVENT_BUS.post(new SFMPreferredEditorChangedEvent(currentEditorId, id)); + onSelect.accept(id); + } + } + return true; + } + + @Override + public void onClose() { + + SFMScreenChangeHelpers.popScreen(); + } + } +} diff --git a/platform/minecraft/src/main/java/ca/teamdman/sfm/client/text_editor/SFMPreferredEditorChangedEvent.java b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/text_editor/SFMPreferredEditorChangedEvent.java new file mode 100644 index 000000000..eed3569ad --- /dev/null +++ b/platform/minecraft/src/main/java/ca/teamdman/sfm/client/text_editor/SFMPreferredEditorChangedEvent.java @@ -0,0 +1,29 @@ +package ca.teamdman.sfm.client.text_editor; + +import net.minecraft.resources.Identifier; +import net.neoforged.bus.api.Event; + +public class SFMPreferredEditorChangedEvent extends Event { + private final Identifier previousEditorId; + + private final Identifier newEditorId; + + public SFMPreferredEditorChangedEvent( + Identifier previousEditorId, + Identifier newEditorId + ) { + + this.previousEditorId = previousEditorId; + this.newEditorId = newEditorId; + } + + public Identifier getPreviousEditorId() { + + return previousEditorId; + } + + public Identifier getNewEditorId() { + + return newEditorId; + } +}