[Mirror] A small vanilla-styled Minecraft mod which lets you access your notes in a simple book in the pause menu.

Compare changes

Choose any two refs to compare.

+654 -121
+4 -2
.forgejo/workflows/build.yml
··· 1 + on: [pull_request, push] 2 + 1 3 jobs: 2 4 build: 3 5 runs-on: docker ··· 5 7 - name: Checkout Repository 6 8 uses: actions/checkout@v3 7 9 - name: Install Java 8 - run: apt-get update && apt-get install -y openjdk-21 10 + run: apt-get update && apt-get install -y openjdk-21-jdk 9 11 - name: Compile Project 10 12 run: ./gradlew build 11 13 - uses: actions/upload-artifact@v3 12 14 with: 13 - name: nightly-build-amd64 15 + name: nightly-build 14 16 path: build/libs
+6 -6
gradle.properties
··· 1 + # Mod Properties 2 + mod_version=5.0.0 3 + maven_group=xyz.sillyjune 4 + archives_base_name=notebook 5 + 1 6 # Done to increase the memory available to gradle. 2 7 org.gradle.jvmargs=-Xmx1G 3 8 org.gradle.parallel=true ··· 11 16 loader_version=0.18.2 12 17 loom_version=1.14-SNAPSHOT 13 18 14 - # Mod Properties 15 - mod_version=5.0.1 16 - maven_group=xyz.sillyjune 17 - archives_base_name=notebook 18 - 19 19 # Dependencies 20 - fabric_version=0.139.4+1.21.11 20 + fabric_version=0.139.4+1.21.11
+99
remappedSrc/xyz/sillyjune/notebook/Notebook.java
··· 1 + package xyz.sillyjune.notebook; 2 + 3 + import com.google.gson.Gson; 4 + import com.mojang.blaze3d.platform.InputConstants; 5 + import net.fabricmc.api.EnvType; 6 + import net.fabricmc.api.Environment; 7 + import net.fabricmc.api.ModInitializer; 8 + import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; 9 + import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; 10 + import net.minecraft.client.KeyMapping; 11 + import net.minecraft.client.gui.components.WidgetSprites; 12 + import net.minecraft.resources.ResourceLocation; 13 + import org.lwjgl.glfw.GLFW; 14 + import org.slf4j.Logger; 15 + import org.slf4j.LoggerFactory; 16 + 17 + import java.io.File; 18 + import java.io.FileWriter; 19 + import java.io.IOException; 20 + import java.nio.file.Files; 21 + import java.nio.file.Paths; 22 + import java.util.Calendar; 23 + import java.util.Date; 24 + 25 + @Environment(EnvType.CLIENT) 26 + public class Notebook implements ModInitializer { 27 + private static KeyMapping openBookKeybind; 28 + public static WidgetSprites b_id(String id) { 29 + return new WidgetSprites( // For whatever reason, you can't specify .png at the end of these. I have questions for mojang. 30 + ResourceLocation.fromNamespaceAndPath("notebook", id + "/unfocused"), 31 + ResourceLocation.fromNamespaceAndPath("notebook", id + "/focused") 32 + ); 33 + } 34 + 35 + @Override 36 + public void onInitialize() { 37 + String config = NotebookConfig.read_config(); // Read config 38 + NotebookConfig cfg = NotebookConfig.default_config(); 39 + if (config != null) { // If the config file exists, set it to whatever json was inside 40 + cfg = new Gson().fromJson(config, NotebookConfig.class); 41 + } else { // If the config file doesn't exist, get the string version of the defaults we set cfg to 42 + String json = new Gson().toJson(cfg); 43 + try { // Write the defaults to config/notebook.json 44 + FileWriter writer = new FileWriter("config/notebook.json"); 45 + writer.write(json); 46 + writer.close(); 47 + } catch (IOException e) { 48 + LOGGER.warn("Failed to create config file!"); 49 + } 50 + } 51 + CONFIG = cfg; // Set the config 52 + openBookKeybindRegister(); // Register keybind for opening the notebook, ";" by default 53 + if (!new File(BOOK_FOLDER).exists() || !new File(BOOK_FOLDER + "/default.json").exists()) { 54 + try { 55 + Files.createDirectories(Paths.get(BOOK_FOLDER)); 56 + NotebookData data = new NotebookData(new String[0], "default.json"); 57 + data.write(); 58 + } catch (IOException e) { 59 + LOGGER.error("failed to create " + BOOK_FOLDER); 60 + } 61 + } 62 + if (CONFIG.debug()) { LOGGER.error("Juniper is very silly. Continue with extreme caution."); } 63 + Calendar cal = Calendar.getInstance(); 64 + cal.setTime(new Date()); 65 + if (cal.get(Calendar.MONTH) != Calendar.JUNE) { GAY = false; } // Gay unless proven straight. 66 + } 67 + 68 + public static void openBookKeybindRegister() { // Register keybind 69 + openBookKeybind = KeyBindingHelper.registerKeyBinding(new KeyMapping("key.notebook.open", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_SEMICOLON, KeyMapping.Category.register(ResourceLocation.parse("category.notebook.keys")))); 70 + ClientTickEvents.END_CLIENT_TICK.register(client -> { 71 + if (openBookKeybind.wasPressed()) { // Open notebook on key press 72 + client.setScreen(new NotebookScreen()); 73 + } 74 + }); 75 + 76 + } 77 + public static WidgetSprites getBookIcon() { 78 + if (!GAY){ 79 + return MAIN_BUTTON_ICON; 80 + } else { 81 + return MAIN_BUTTON_ICON_GAY; 82 + } 83 + } 84 + public static final Logger LOGGER = LoggerFactory.getLogger("notebook"); 85 + public static final WidgetSprites MAIN_BUTTON_ICON_GAY = b_id("book_gay"); 86 + public static final WidgetSprites DEL_BOOK_ICON = b_id("delete_book"); 87 + public static final WidgetSprites MAIN_BUTTON_ICON = b_id("book"); 88 + public static final WidgetSprites NEW_PAGE_ICON = b_id("new_page"); 89 + public static final WidgetSprites DEL_PAGE_ICON = b_id("delete_page"); 90 + public static final WidgetSprites LAST_BOOK_ICON = b_id("last_book"); 91 + public static final WidgetSprites NEW_BOOK_ICON = b_id("new_book"); 92 + public static final WidgetSprites NEXT_BOOK_ICON = b_id("next_book"); 93 + public static final WidgetSprites RENAME_BOOK_ICON = b_id("rename_book"); 94 + public static NotebookConfig CONFIG; 95 + public static final ResourceLocation BOOK_TEXTURE = ResourceLocation.parse("textures/gui/book.png"); 96 + public static String BOOK_FOLDER = "Notebook"; 97 + public static final String VERSION = "5.0.0"; 98 + public static boolean GAY = true; // I might be straight but gay people are pretty cool 99 + }
+32
remappedSrc/xyz/sillyjune/notebook/NotebookConfig.java
··· 1 + package xyz.sillyjune.notebook; 2 + 3 + import java.io.File; 4 + import java.io.FileNotFoundException; 5 + import java.util.Scanner; 6 + 7 + public record NotebookConfig(boolean debug, int button_offset) { 8 + public boolean debug() { // Is debug mode enabled? 9 + return debug; 10 + } 11 + public int button_offset() { // Button offset config option for compatibility with mods with buttons in the same place (e.g. create) 12 + return button_offset; 13 + } 14 + static String read_config() { // Read config from file 15 + try { 16 + File config = new File("config/notebook.json"); 17 + Scanner reader = new Scanner(config); 18 + StringBuilder d = new StringBuilder(); 19 + while (reader.hasNextLine()) { 20 + String data = reader.nextLine(); 21 + d.append(data); 22 + } 23 + reader.close(); 24 + return d.toString(); 25 + } catch (FileNotFoundException e) { 26 + return null; 27 + } 28 + } 29 + static NotebookConfig default_config() { 30 + return new NotebookConfig(false, 0); 31 + } 32 + }
+51
remappedSrc/xyz/sillyjune/notebook/NotebookData.java
··· 1 + package xyz.sillyjune.notebook; 2 + 3 + import com.google.gson.Gson; 4 + 5 + import java.io.File; 6 + import java.io.FileNotFoundException; 7 + import java.io.FileWriter; 8 + import java.io.IOException; 9 + import java.util.Scanner; 10 + 11 + import static xyz.sillyjune.notebook.Notebook.BOOK_FOLDER; 12 + import static xyz.sillyjune.notebook.Notebook.LOGGER; 13 + 14 + public class NotebookData { 15 + String[] content; 16 + String location; 17 + NotebookData(String[] content, String location) { 18 + this.content = content; 19 + this.location = location; 20 + } 21 + 22 + public static NotebookData read(String location) { // Read the record from a file 23 + File jsondata = new File(BOOK_FOLDER + "/" + location); 24 + StringBuilder d = new StringBuilder(); 25 + try { 26 + Scanner reader = new Scanner(jsondata); 27 + while (reader.hasNextLine()) { 28 + String data = reader.nextLine(); 29 + d.append(data); 30 + } 31 + reader.close(); 32 + } catch (FileNotFoundException e) { // If it fails, create a new one 33 + LOGGER.error("Failed to read book!\n" + e); 34 + NotebookData data = new NotebookData(new String[0], location); 35 + data.write(); // Write to file 36 + } 37 + String json = d.toString(); 38 + return new Gson().fromJson(json, NotebookData.class); 39 + } 40 + 41 + public void write() { 42 + String json = new Gson().toJson(this); 43 + try { // Write the record to a file 44 + FileWriter writer = new FileWriter(BOOK_FOLDER + "/" + this.location); 45 + writer.write(json); 46 + writer.close(); 47 + } catch (IOException e) { 48 + Notebook.LOGGER.error("Failed to write book!\n" + e); 49 + } 50 + } 51 + }
+282
remappedSrc/xyz/sillyjune/notebook/NotebookScreen.java
··· 1 + package xyz.sillyjune.notebook; 2 + 3 + import net.minecraft.client.GameNarrator; 4 + import net.minecraft.client.gui.GuiGraphics; 5 + import net.minecraft.client.gui.components.Button; 6 + import net.minecraft.client.gui.components.EditBox; 7 + import net.minecraft.client.gui.components.ImageButton; 8 + import net.minecraft.client.gui.components.MultiLineEditBox; 9 + import net.minecraft.client.gui.screens.Screen; 10 + import net.minecraft.client.gui.screens.inventory.PageButton; 11 + import net.minecraft.client.gui.widget.*; 12 + import net.minecraft.client.renderer.RenderPipelines; 13 + import net.minecraft.network.chat.CommonComponents; 14 + import net.minecraft.network.chat.Component; 15 + import net.minecraft.text.*; 16 + import net.minecraft.util.CommonColors; 17 + import net.minecraft.util.FormattedCharSequence; 18 + import java.awt.*; 19 + import java.awt.datatransfer.Clipboard; 20 + import java.awt.datatransfer.DataFlavor; 21 + import java.awt.datatransfer.Transferable; 22 + import java.awt.datatransfer.UnsupportedFlavorException; 23 + import java.io.File; 24 + import java.io.IOException; 25 + import java.nio.file.Path; 26 + import java.util.Collections; 27 + import java.util.List; 28 + import java.util.Objects; 29 + 30 + import static java.nio.file.Files.*; 31 + import static xyz.sillyjune.notebook.Notebook.*; 32 + 33 + public class NotebookScreen extends Screen { 34 + private MultiLineEditBox editBox; 35 + public int bookOffset = 0; 36 + private static NotebookData DATA; 37 + public static Button buttonDelBook; 38 + public static Button closeButton; 39 + public static Button buttonRenameBook; 40 + public static Button buttonNewBook; 41 + public static Button buttonIncreaseOffset; 42 + public static Button buttonDecreaseOffset; 43 + public Button[] switchableBooks = { null, null, null, null, null }; 44 + private int pageIndex; 45 + private int cursorIndex; 46 + private List<FormattedCharSequence> cachedPage; 47 + private EditBox bookNameField; 48 + private Button newPageButton; 49 + private Button delPageButton; 50 + private PageButton nextPageButton; 51 + private PageButton previousPageButton; 52 + private final boolean pageTurnSound; 53 + public NotebookScreen() { 54 + this(false); 55 + } 56 + private NotebookScreen(boolean playPageTurnSound) { 57 + super(GameNarrator.NO_TITLE); 58 + this.cachedPage = Collections.emptyList(); 59 + this.pageTurnSound = playPageTurnSound; 60 + } 61 + /// Creates a new blank page 62 + protected void newPage() { 63 + String[] new_pages = new String[DATA.content.length+1]; 64 + int i = 0; 65 + for (String page : DATA.content) { 66 + new_pages[i] = page; i++; 67 + } 68 + new_pages[new_pages.length-1] = " "; 69 + DATA.content = new_pages; DATA.write(); 70 + this.goToNextPage(); 71 + } 72 + // Removes the last page 73 + protected void delPage() { 74 + String[] new_pages = new String[DATA.content.length-1]; 75 + for (int i = 0; i < new_pages.length; i++) { 76 + new_pages[i] = DATA.content[i]; i++; 77 + } 78 + DATA.content = new_pages; DATA.write(); 79 + this.goToPreviousPage(); 80 + } 81 + // Reads an existing page from storage 82 + protected String readPage(int pagei) { 83 + if (pagei >= DATA.content.length) { newPage(); } 84 + // Prevents a crash if pages become corrupted somehow 85 + return Objects.requireNonNullElse(DATA.content[pagei], ""); 86 + } 87 + void goto_book(String book) { 88 + int bIdx = 0; 89 + for (String iter : Objects.requireNonNull(new File(BOOK_FOLDER).list())) { 90 + if (Objects.equals(iter, book)) { 91 + break; 92 + } 93 + bIdx += 1; 94 + } 95 + DATA = NotebookData.read(Objects.requireNonNull(new File(BOOK_FOLDER).list())[bIdx]); 96 + this.bookNameField.setValue(DATA.location.replace(".json", "")); 97 + this.pageIndex = 0; 98 + this.updatePageButtons(); 99 + 100 + } 101 + protected void goToPreviousPage() { 102 + if (this.pageIndex > 0) { --this.pageIndex; } 103 + this.cursorIndex = readPage(pageIndex).length(); 104 + this.updatePageButtons(); 105 + } 106 + protected void goToNextPage() { 107 + if (this.pageIndex < DATA.content.length - 1) { ++this.pageIndex; } 108 + this.cursorIndex = readPage(pageIndex).length(); 109 + this.updatePageButtons(); 110 + } 111 + 112 + String getBookNameText() { 113 + return this.bookNameField.getValue().replace(" ", "-"); 114 + } 115 + 116 + void initBookSwitching() { 117 + String[] books = Objects.requireNonNull(new File(BOOK_FOLDER).list()); 118 + int replaced = 0; 119 + for (int it = 0; it != 5; it++) { 120 + if (it+bookOffset > books.length - 1) { 121 + break; 122 + } 123 + replaced = it; 124 + String book = books[it+bookOffset]; 125 + if (this.switchableBooks[it] != null) { 126 + this.switchableBooks[it].visible = false; 127 + } 128 + this.switchableBooks[it] = this.addRenderableWidget(Button.builder(Component.literal(book.replace(".json", "")), (button) -> goto_book(book)).bounds(5, 55 + (25 * (it)), 108, 20).build()); 129 + } 130 + for (int it = replaced+1; it != 5; it++) { 131 + if (this.switchableBooks[it] != null) { 132 + this.switchableBooks[it].visible = false; 133 + this.switchableBooks[it] = null; 134 + } 135 + } 136 + } 137 + 138 + // Innit mate 139 + protected void init() { 140 + DATA = NotebookData.read("default.json"); 141 + pageIndex = 0; 142 + this.editBox = MultiLineEditBox.builder().setShowDecorations(false).setTextColor(-16777216).setCursorColor(-16777216).setShowBackground(false).setTextShadow(false).setX((this.width - 114) / 2 - 8).setY(28).build(this.font, 122, 134, CommonComponents.EMPTY); 143 + this.editBox.setCharacterLimit(1024); 144 + // Add done/close button 145 + closeButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_DONE, (button) -> this.onClose()).bounds(this.width / 2 - 100, 196, 200, 20).build()); 146 + // Page buttons 147 + int i = (this.width - 192) / 2; 148 + this.nextPageButton = this.addRenderableWidget(new PageButton(i + 116, 159, true, (button) -> this.goToNextPage(), this.pageTurnSound)); 149 + this.previousPageButton = this.addRenderableWidget(new PageButton(i + 43, 159, false, (button) -> this.goToPreviousPage(), this.pageTurnSound)); 150 + this.newPageButton = this.addRenderableWidget(new ImageButton(i + 119, 155, 20, 20, NEW_PAGE_ICON, (button) -> newPage())); 151 + this.delPageButton = this.addRenderableWidget(new ImageButton(i + 99, 155, 20, 20, DEL_PAGE_ICON, (button) -> delPage())); 152 + // Top bar buttons 153 + this.bookNameField = this.addRenderableWidget(new EditBox(this.font, 5, 5, 108, 20, Component.translatable("notebook.text.field"))); 154 + this.bookNameField.setEditable(true); 155 + this.bookNameField.setValue("default"); 156 + Objects.requireNonNull(this.font); 157 + this.editBox.setLineLimit(126 / 9); 158 + this.addRenderableWidget(this.editBox); 159 + 160 + buttonIncreaseOffset = this.addRenderableWidget(new ImageButton(113, 155, 20, 20, LAST_BOOK_ICON, (button) -> { 161 + bookOffset += 1; 162 + initBookSwitching(); 163 + })); 164 + buttonDecreaseOffset = this.addRenderableWidget(new ImageButton(115, 130, 20, 20, NEXT_BOOK_ICON, (button) -> { 165 + if (bookOffset > 0) { 166 + bookOffset -= 1; 167 + initBookSwitching(); 168 + } 169 + })); 170 + buttonDelBook = this.addRenderableWidget(new ImageButton(55, 30, 20, 20, DEL_BOOK_ICON, (button) -> { 171 + String[] books = Objects.requireNonNull(new File(BOOK_FOLDER).list()); 172 + boolean found = false; 173 + for (String iter : books) { 174 + if (iter.equals(getBookNameText() + ".json")) { 175 + found = true; 176 + break; 177 + } 178 + } 179 + if (!this.bookNameField.getValue().isEmpty() && found) { 180 + try { 181 + delete(Path.of(BOOK_FOLDER + "/" + DATA.location)); 182 + } catch (IOException ignored) {} 183 + if (this.bookNameField.getValue().equals("default")) { 184 + DATA.content = new String[] {""}; 185 + this.pageIndex = 0; 186 + DATA.write(); 187 + } 188 + } 189 + initBookSwitching(); 190 + } 191 + )); 192 + buttonNewBook = this.addRenderableWidget(new ImageButton(5, 30, 20, 20, NEW_BOOK_ICON, (button) -> { 193 + String[] books = Objects.requireNonNull(new File(BOOK_FOLDER).list()); 194 + boolean found = false; 195 + for (String iter : books) { 196 + if (iter.equals(getBookNameText() + ".json")) { 197 + found = true; 198 + break; 199 + } 200 + } 201 + if (!this.bookNameField.getValue().isEmpty() && !found) { 202 + DATA = new NotebookData(new String[] {""}, getBookNameText() + ".json"); 203 + this.editBox.setValue(DATA.content[0]); 204 + this.pageIndex = 0; 205 + DATA.write(); 206 + } 207 + initBookSwitching(); 208 + } 209 + )); 210 + buttonRenameBook = this.addRenderableWidget(new ImageButton(30, 30, 20, 20, RENAME_BOOK_ICON, (button) -> { 211 + String[] books = Objects.requireNonNull(new File(BOOK_FOLDER).list()); 212 + boolean found = false; 213 + for (String iter : books) { 214 + if (iter.equals(getBookNameText() + ".json")) { 215 + found = true; 216 + break; 217 + } 218 + } 219 + if (!this.bookNameField.getValue().isEmpty() && !found) { 220 + String[] bookData = DATA.content; 221 + try { 222 + delete(Path.of(BOOK_FOLDER + "/" + DATA.location)); 223 + } catch (IOException ignored) { 224 + } 225 + DATA = new NotebookData(bookData, getBookNameText() + ".json"); 226 + DATA.write(); 227 + } 228 + initBookSwitching(); 229 + } 230 + )); 231 + initBookSwitching(); 232 + 233 + this.updatePageButtons(); 234 + this.cursorIndex = readPage(pageIndex).length(); 235 + } 236 + // Refresh page buttons 237 + private void updatePageButtons() { 238 + boolean onFinalPage = this.pageIndex == DATA.content.length - 1; 239 + this.nextPageButton.visible = !onFinalPage; 240 + this.newPageButton.visible = onFinalPage; 241 + this.delPageButton.visible = onFinalPage; 242 + this.previousPageButton.visible = this.pageIndex > 0; 243 + if (pageIndex > DATA.content.length) pageIndex = 0; 244 + if (DATA.content.length == 0) { 245 + DATA.content = new String[] {""}; 246 + this.editBox.setValue(DATA.content[0]); 247 + } 248 + if (DATA.content[pageIndex] != null) { 249 + this.editBox.setValue(DATA.content[pageIndex]); 250 + } else { 251 + if (DATA.content[0] == null) { 252 + DATA.content = new String[] {""}; 253 + } 254 + this.editBox.setValue(DATA.content[0]); 255 + } 256 + 257 + } 258 + // The code I am going to avoid like the plague 259 + public void render(GuiGraphics context, int mouseX, int mouseY, float deltaTicks) { 260 + 261 + if (DATA.content[pageIndex] == null) { 262 + DATA.content[pageIndex] = ""; 263 + DATA.write(); 264 + } 265 + if (!DATA.content[pageIndex].equals(editBox.getValue())) { 266 + DATA.content[pageIndex] = editBox.getValue(); 267 + DATA.write(); 268 + } 269 + // Render book background 270 + context.blit(RenderPipelines.GUI_TEXTURED, BOOK_TEXTURE, (this.width - 192) / 2, 2, 0.0F, 0.0F, 192, 192, 256, 256); 271 + super.render(context, mouseX, mouseY, deltaTicks); 272 + // long 273 + context.drawString(this.font, Component.translatable("book.pageIndicator", this.pageIndex + 1, Math.max(DATA.content.length, 1)), ((this.width - 192) / 2) - this.font.width(Component.translatable("book.pageIndicator", this.pageIndex + 1, Math.max(DATA.content.length, 1))) + 192 - 44, 18, CommonColors.BLACK, false); 274 + if (GAY) { context.drawString(this.font, Component.translatable("notebook.gay"), 5, this.height - 22, CommonColors.WHITE, true); } 275 + if (CONFIG.debug()) { 276 + context.drawString(this.font, Component.nullToEmpty("Notebook v" + VERSION + " " + Component.translatable("devwarning.info").getString()), 5, this.height - 10, CommonColors.WHITE, true); 277 + } else { 278 + context.drawString(this.font, Component.nullToEmpty("Notebook v" + VERSION), 5, this.height - 10, CommonColors.WHITE, true); 279 + } 280 + } 281 + 282 + }
+35
remappedSrc/xyz/sillyjune/notebook/mixin/GameMenuScreenButton.java
··· 1 + package xyz.sillyjune.notebook.mixin; 2 + 3 + 4 + import xyz.sillyjune.notebook.NotebookScreen; 5 + import org.spongepowered.asm.mixin.Mixin; 6 + import org.spongepowered.asm.mixin.injection.At; 7 + import org.spongepowered.asm.mixin.injection.Inject; 8 + import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 + 10 + import static xyz.sillyjune.notebook.Notebook.*; 11 + 12 + import net.minecraft.client.gui.components.ImageButton; 13 + import net.minecraft.client.gui.screens.PauseScreen; 14 + import net.minecraft.client.gui.screens.Screen; 15 + import net.minecraft.network.chat.Component; 16 + 17 + @Mixin(PauseScreen.class) 18 + public abstract class GameMenuScreenButton extends Screen { 19 + protected GameMenuScreenButton(Component title) { 20 + super(title); 21 + } 22 + @Inject(at = @At("RETURN"), method="initWidgets") 23 + private void addCustomButton(CallbackInfo ci) { 24 + ImageButton b = new ImageButton( 25 + this.width / 2 + 104, 26 + this.height / 4 + 96 + -16, 27 + 20, 28 + 20, 29 + getBookIcon(), 30 + (button) -> this.minecraft.setScreen(new NotebookScreen()) 31 + ); 32 + b.setMessage(Component.translatable("key.notebook.open")); 33 + this.addRenderableWidget(b); 34 + } 35 + }
+34
remappedSrc/xyz/sillyjune/notebook/mixin/TitleScreenButton.java
··· 1 + package xyz.sillyjune.notebook.mixin; 2 + 3 + import org.spongepowered.asm.mixin.Mixin; 4 + import org.spongepowered.asm.mixin.injection.At; 5 + import org.spongepowered.asm.mixin.injection.Inject; 6 + import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 + import xyz.sillyjune.notebook.NotebookScreen; 8 + 9 + import static xyz.sillyjune.notebook.Notebook.getBookIcon; 10 + 11 + import net.minecraft.client.gui.components.ImageButton; 12 + import net.minecraft.client.gui.screens.Screen; 13 + import net.minecraft.client.gui.screens.TitleScreen; 14 + import net.minecraft.network.chat.Component; 15 + 16 + @Mixin(TitleScreen.class) 17 + public abstract class TitleScreenButton extends Screen { 18 + protected TitleScreenButton(Component title) { 19 + super(title); 20 + } 21 + @Inject(at = @At("RETURN"), method="init") 22 + private void addCustomButton(CallbackInfo ci) { 23 + ImageButton b = new ImageButton( 24 + this.width / 2 + 104, 25 + this.height / 4 + 96, 26 + 20, 27 + 20, 28 + getBookIcon(), 29 + (button) -> this.minecraft.setScreen(new NotebookScreen()) 30 + ); 31 + b.setMessage(Component.translatable("key.notebook.open")); 32 + this.addRenderableWidget(b); 33 + } 34 + }
+23 -24
src/client/java/xyz/sillyjune/notebook/Notebook.java
··· 1 1 package xyz.sillyjune.notebook; 2 2 3 3 import com.google.gson.Gson; 4 - 4 + import com.mojang.blaze3d.platform.InputConstants; 5 5 import net.fabricmc.api.EnvType; 6 6 import net.fabricmc.api.Environment; 7 7 import net.fabricmc.api.ModInitializer; 8 8 import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; 9 9 import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; 10 - import net.minecraft.client.gui.screen.ButtonTextures; 11 - import net.minecraft.client.option.KeyBinding; 12 - import net.minecraft.client.util.InputUtil; 13 - import net.minecraft.util.Identifier; 10 + import net.minecraft.client.KeyMapping; 11 + import net.minecraft.client.gui.components.WidgetSprites; 12 + import net.minecraft.resources.Identifier; 14 13 import org.lwjgl.glfw.GLFW; 15 14 import org.slf4j.Logger; 16 15 import org.slf4j.LoggerFactory; ··· 25 24 26 25 @Environment(EnvType.CLIENT) 27 26 public class Notebook implements ModInitializer { 28 - private static KeyBinding openBookKeybind; 29 - public static ButtonTextures b_id(String id) { 30 - return new ButtonTextures( // For whatever reason, you can't specify .png at the end of these. I have questions for mojang. 31 - Identifier.of("notebook", id + "/unfocused"), 32 - Identifier.of("notebook", id + "/focused") 27 + private static KeyMapping openBookKeybind; 28 + public static WidgetSprites b_id(String id) { 29 + return new WidgetSprites( // For whatever reason, you can't specify .png at the end of these. I have questions for mojang. 30 + Identifier.fromNamespaceAndPath("notebook", id + "/unfocused"), 31 + Identifier.fromNamespaceAndPath("notebook", id + "/focused") 33 32 ); 34 33 } 35 34 ··· 67 66 } 68 67 69 68 public static void openBookKeybindRegister() { // Register keybind 70 - openBookKeybind = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.notebook.open", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_SEMICOLON, KeyBinding.Category.create(Identifier.of("category.notebook.keys")))); 69 + openBookKeybind = KeyBindingHelper.registerKeyBinding(new KeyMapping("key.notebook.open", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_SEMICOLON, KeyMapping.Category.register(Identifier.parse("category.notebook.keys")))); 71 70 ClientTickEvents.END_CLIENT_TICK.register(client -> { 72 - if (openBookKeybind.wasPressed()) { // Open notebook on key press 71 + if (openBookKeybind.isDown()) { // Open notebook on key press 73 72 client.setScreen(new NotebookScreen()); 74 73 } 75 74 }); 76 75 77 76 } 78 - public static ButtonTextures getBookIcon() { 77 + public static WidgetSprites getBookIcon() { 79 78 if (!GAY){ 80 79 return MAIN_BUTTON_ICON; 81 80 } else { ··· 83 82 } 84 83 } 85 84 public static final Logger LOGGER = LoggerFactory.getLogger("notebook"); 86 - public static final ButtonTextures MAIN_BUTTON_ICON_GAY = b_id("book_gay"); 87 - public static final ButtonTextures DEL_BOOK_ICON = b_id("delete_book"); 88 - public static final ButtonTextures MAIN_BUTTON_ICON = b_id("book"); 89 - public static final ButtonTextures NEW_PAGE_ICON = b_id("new_page"); 90 - public static final ButtonTextures DEL_PAGE_ICON = b_id("delete_page"); 91 - public static final ButtonTextures LAST_BOOK_ICON = b_id("last_book"); 92 - public static final ButtonTextures NEW_BOOK_ICON = b_id("new_book"); 93 - public static final ButtonTextures NEXT_BOOK_ICON = b_id("next_book"); 94 - public static final ButtonTextures RENAME_BOOK_ICON = b_id("rename_book"); 85 + public static final WidgetSprites MAIN_BUTTON_ICON_GAY = b_id("book_gay"); 86 + public static final WidgetSprites DEL_BOOK_ICON = b_id("delete_book"); 87 + public static final WidgetSprites MAIN_BUTTON_ICON = b_id("book"); 88 + public static final WidgetSprites NEW_PAGE_ICON = b_id("new_page"); 89 + public static final WidgetSprites DEL_PAGE_ICON = b_id("delete_page"); 90 + public static final WidgetSprites LAST_BOOK_ICON = b_id("last_book"); 91 + public static final WidgetSprites NEW_BOOK_ICON = b_id("new_book"); 92 + public static final WidgetSprites NEXT_BOOK_ICON = b_id("next_book"); 93 + public static final WidgetSprites RENAME_BOOK_ICON = b_id("rename_book"); 95 94 public static NotebookConfig CONFIG; 96 - public static final Identifier BOOK_TEXTURE = Identifier.of("textures/gui/book.png"); 95 + public static final Identifier BOOK_TEXTURE = Identifier.parse("textures/gui/book.png"); 97 96 public static String BOOK_FOLDER = "Notebook"; 98 - public static final String VERSION = "5.0.1"; 97 + public static final String VERSION = "5.0.0"; 99 98 public static boolean GAY = true; // I might be straight but gay people are pretty cool 100 99 }
+64 -66
src/client/java/xyz/sillyjune/notebook/NotebookScreen.java
··· 1 1 package xyz.sillyjune.notebook; 2 2 3 - import net.minecraft.client.gl.RenderPipelines; 4 - import net.minecraft.client.gui.DrawContext; 5 - import net.minecraft.client.gui.screen.Screen; 6 - import net.minecraft.client.gui.widget.*; 7 - import net.minecraft.client.input.KeyInput; 8 - import net.minecraft.client.render.RenderLayer; 9 - import net.minecraft.client.util.NarratorManager; 10 - import net.minecraft.screen.ScreenTexts; 11 - import net.minecraft.text.*; 12 - import net.minecraft.util.Colors; 13 - 3 + import net.minecraft.client.GameNarrator; 4 + import net.minecraft.client.gui.GuiGraphics; 5 + import net.minecraft.client.gui.components.Button; 6 + import net.minecraft.client.gui.components.EditBox; 7 + import net.minecraft.client.gui.components.ImageButton; 8 + import net.minecraft.client.gui.components.MultiLineEditBox; 9 + import net.minecraft.client.gui.screens.Screen; 10 + import net.minecraft.client.gui.screens.inventory.PageButton; 11 + import net.minecraft.client.renderer.RenderPipelines; 12 + import net.minecraft.network.chat.CommonComponents; 13 + import net.minecraft.network.chat.Component; 14 + import net.minecraft.util.CommonColors; 15 + import net.minecraft.util.FormattedCharSequence; 14 16 import java.awt.*; 15 - import java.awt.datatransfer.Clipboard; 16 - import java.awt.datatransfer.DataFlavor; 17 - import java.awt.datatransfer.Transferable; 18 - import java.awt.datatransfer.UnsupportedFlavorException; 19 17 import java.io.File; 20 18 import java.io.IOException; 21 19 import java.nio.file.Path; ··· 27 25 import static xyz.sillyjune.notebook.Notebook.*; 28 26 29 27 public class NotebookScreen extends Screen { 30 - private EditBoxWidget editBox; 28 + private MultiLineEditBox editBox; 31 29 public int bookOffset = 0; 32 30 private static NotebookData DATA; 33 - public static ButtonWidget buttonDelBook; 34 - public static ButtonWidget closeButton; 35 - public static ButtonWidget buttonRenameBook; 36 - public static ButtonWidget buttonNewBook; 37 - public static ButtonWidget buttonIncreaseOffset; 38 - public static ButtonWidget buttonDecreaseOffset; 39 - public ButtonWidget[] switchableBooks = { null, null, null, null, null }; 31 + public static Button buttonDelBook; 32 + public static Button closeButton; 33 + public static Button buttonRenameBook; 34 + public static Button buttonNewBook; 35 + public static Button buttonIncreaseOffset; 36 + public static Button buttonDecreaseOffset; 37 + public Button[] switchableBooks = { null, null, null, null, null }; 40 38 private int pageIndex; 41 39 private int cursorIndex; 42 - private List<OrderedText> cachedPage; 43 - private TextFieldWidget bookNameField; 44 - private ButtonWidget newPageButton; 45 - private ButtonWidget delPageButton; 46 - private PageTurnWidget nextPageButton; 47 - private PageTurnWidget previousPageButton; 40 + private List<FormattedCharSequence> cachedPage; 41 + private EditBox bookNameField; 42 + private Button newPageButton; 43 + private Button delPageButton; 44 + private PageButton nextPageButton; 45 + private PageButton previousPageButton; 48 46 private final boolean pageTurnSound; 49 47 public NotebookScreen() { 50 48 this(false); 51 49 } 52 50 private NotebookScreen(boolean playPageTurnSound) { 53 - super(NarratorManager.EMPTY); 51 + super(GameNarrator.NO_TITLE); 54 52 this.cachedPage = Collections.emptyList(); 55 53 this.pageTurnSound = playPageTurnSound; 56 54 } ··· 89 87 bIdx += 1; 90 88 } 91 89 DATA = NotebookData.read(Objects.requireNonNull(new File(BOOK_FOLDER).list())[bIdx]); 92 - this.bookNameField.setText(DATA.location.replace(".json", "")); 90 + this.bookNameField.setValue(DATA.location.replace(".json", "")); 93 91 this.pageIndex = 0; 94 92 this.updatePageButtons(); 95 93 ··· 106 104 } 107 105 108 106 String getBookNameText() { 109 - return this.bookNameField.getText().replace(" ", "-"); 107 + return this.bookNameField.getValue().replace(" ", "-"); 110 108 } 111 109 112 110 void initBookSwitching() { ··· 121 119 if (this.switchableBooks[it] != null) { 122 120 this.switchableBooks[it].visible = false; 123 121 } 124 - this.switchableBooks[it] = this.addDrawableChild(ButtonWidget.builder(Text.literal(book.replace(".json", "")), (button) -> goto_book(book)).dimensions(5, 55 + (25 * (it)), 108, 20).build()); 122 + this.switchableBooks[it] = this.addRenderableWidget(Button.builder(Component.literal(book.replace(".json", "")), (button) -> goto_book(book)).bounds(5, 55 + (25 * (it)), 108, 20).build()); 125 123 } 126 124 for (int it = replaced+1; it != 5; it++) { 127 125 if (this.switchableBooks[it] != null) { ··· 135 133 protected void init() { 136 134 DATA = NotebookData.read("default.json"); 137 135 pageIndex = 0; 138 - this.editBox = EditBoxWidget.builder().hasOverlay(false).textColor(-16777216).cursorColor(-16777216).hasBackground(false).textShadow(false).x((this.width - 114) / 2 - 8).y(28).build(this.textRenderer, 122, 134, ScreenTexts.EMPTY); 139 - this.editBox.setMaxLength(1024); 136 + this.editBox = MultiLineEditBox.builder().setShowDecorations(false).setTextColor(-16777216).setCursorColor(-16777216).setShowBackground(false).setTextShadow(false).setX((this.width - 114) / 2 - 8).setY(28).build(this.font, 122, 134, CommonComponents.EMPTY); 137 + this.editBox.setCharacterLimit(1024); 140 138 // Add done/close button 141 - closeButton = this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> this.close()).dimensions(this.width / 2 - 100, 196, 200, 20).build()); 139 + closeButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_DONE, (button) -> this.onClose()).bounds(this.width / 2 - 100, 196, 200, 20).build()); 142 140 // Page buttons 143 141 int i = (this.width - 192) / 2; 144 - this.nextPageButton = this.addDrawableChild(new PageTurnWidget(i + 116, 159, true, (button) -> this.goToNextPage(), this.pageTurnSound)); 145 - this.previousPageButton = this.addDrawableChild(new PageTurnWidget(i + 43, 159, false, (button) -> this.goToPreviousPage(), this.pageTurnSound)); 146 - this.newPageButton = this.addDrawableChild(new TexturedButtonWidget(i + 119, 155, 20, 20, NEW_PAGE_ICON, (button) -> newPage())); 147 - this.delPageButton = this.addDrawableChild(new TexturedButtonWidget(i + 99, 155, 20, 20, DEL_PAGE_ICON, (button) -> delPage())); 142 + this.nextPageButton = this.addRenderableWidget(new PageButton(i + 116, 159, true, (button) -> this.goToNextPage(), this.pageTurnSound)); 143 + this.previousPageButton = this.addRenderableWidget(new PageButton(i + 43, 159, false, (button) -> this.goToPreviousPage(), this.pageTurnSound)); 144 + this.newPageButton = this.addRenderableWidget(new ImageButton(i + 119, 155, 20, 20, NEW_PAGE_ICON, (button) -> newPage())); 145 + this.delPageButton = this.addRenderableWidget(new ImageButton(i + 99, 155, 20, 20, DEL_PAGE_ICON, (button) -> delPage())); 148 146 // Top bar buttons 149 - this.bookNameField = this.addDrawableChild(new TextFieldWidget(this.textRenderer, 5, 5, 108, 20, Text.translatable("notebook.text.field"))); 147 + this.bookNameField = this.addRenderableWidget(new EditBox(this.font, 5, 5, 108, 20, Component.translatable("notebook.text.field"))); 150 148 this.bookNameField.setEditable(true); 151 - this.bookNameField.setText("default"); 152 - Objects.requireNonNull(this.textRenderer); 153 - this.editBox.setMaxLines(126 / 9); 154 - this.addDrawableChild(this.editBox); 149 + this.bookNameField.setValue("default"); 150 + Objects.requireNonNull(this.font); 151 + this.editBox.setLineLimit(126 / 9); 152 + this.addRenderableWidget(this.editBox); 155 153 156 - buttonIncreaseOffset = this.addDrawableChild(new TexturedButtonWidget(113, 155, 20, 20, LAST_BOOK_ICON, (button) -> { 154 + buttonIncreaseOffset = this.addRenderableWidget(new ImageButton(113, 155, 20, 20, LAST_BOOK_ICON, (button) -> { 157 155 bookOffset += 1; 158 156 initBookSwitching(); 159 157 })); 160 - buttonDecreaseOffset = this.addDrawableChild(new TexturedButtonWidget(115, 130, 20, 20, NEXT_BOOK_ICON, (button) -> { 158 + buttonDecreaseOffset = this.addRenderableWidget(new ImageButton(115, 130, 20, 20, NEXT_BOOK_ICON, (button) -> { 161 159 if (bookOffset > 0) { 162 160 bookOffset -= 1; 163 161 initBookSwitching(); 164 162 } 165 163 })); 166 - buttonDelBook = this.addDrawableChild(new TexturedButtonWidget(55, 30, 20, 20, DEL_BOOK_ICON, (button) -> { 164 + buttonDelBook = this.addRenderableWidget(new ImageButton(55, 30, 20, 20, DEL_BOOK_ICON, (button) -> { 167 165 String[] books = Objects.requireNonNull(new File(BOOK_FOLDER).list()); 168 166 boolean found = false; 169 167 for (String iter : books) { ··· 172 170 break; 173 171 } 174 172 } 175 - if (!this.bookNameField.getText().isEmpty() && found) { 173 + if (!this.bookNameField.getValue().isEmpty() && found) { 176 174 try { 177 175 delete(Path.of(BOOK_FOLDER + "/" + DATA.location)); 178 176 } catch (IOException ignored) {} 179 - if (this.bookNameField.getText().equals("default")) { 177 + if (this.bookNameField.getValue().equals("default")) { 180 178 DATA.content = new String[] {""}; 181 179 this.pageIndex = 0; 182 180 DATA.write(); ··· 185 183 initBookSwitching(); 186 184 } 187 185 )); 188 - buttonNewBook = this.addDrawableChild(new TexturedButtonWidget(5, 30, 20, 20, NEW_BOOK_ICON, (button) -> { 186 + buttonNewBook = this.addRenderableWidget(new ImageButton(5, 30, 20, 20, NEW_BOOK_ICON, (button) -> { 189 187 String[] books = Objects.requireNonNull(new File(BOOK_FOLDER).list()); 190 188 boolean found = false; 191 189 for (String iter : books) { ··· 194 192 break; 195 193 } 196 194 } 197 - if (!this.bookNameField.getText().isEmpty() && !found) { 195 + if (!this.bookNameField.getValue().isEmpty() && !found) { 198 196 DATA = new NotebookData(new String[] {""}, getBookNameText() + ".json"); 199 - this.editBox.setText(DATA.content[0]); 197 + this.editBox.setValue(DATA.content[0]); 200 198 this.pageIndex = 0; 201 199 DATA.write(); 202 200 } 203 201 initBookSwitching(); 204 202 } 205 203 )); 206 - buttonRenameBook = this.addDrawableChild(new TexturedButtonWidget(30, 30, 20, 20, RENAME_BOOK_ICON, (button) -> { 204 + buttonRenameBook = this.addRenderableWidget(new ImageButton(30, 30, 20, 20, RENAME_BOOK_ICON, (button) -> { 207 205 String[] books = Objects.requireNonNull(new File(BOOK_FOLDER).list()); 208 206 boolean found = false; 209 207 for (String iter : books) { ··· 212 210 break; 213 211 } 214 212 } 215 - if (!this.bookNameField.getText().isEmpty() && !found) { 213 + if (!this.bookNameField.getValue().isEmpty() && !found) { 216 214 String[] bookData = DATA.content; 217 215 try { 218 216 delete(Path.of(BOOK_FOLDER + "/" + DATA.location)); ··· 239 237 if (pageIndex > DATA.content.length) pageIndex = 0; 240 238 if (DATA.content.length == 0) { 241 239 DATA.content = new String[] {""}; 242 - this.editBox.setText(DATA.content[0]); 240 + this.editBox.setValue(DATA.content[0]); 243 241 } 244 242 if (DATA.content[pageIndex] != null) { 245 - this.editBox.setText(DATA.content[pageIndex]); 243 + this.editBox.setValue(DATA.content[pageIndex]); 246 244 } else { 247 245 if (DATA.content[0] == null) { 248 246 DATA.content = new String[] {""}; 249 247 } 250 - this.editBox.setText(DATA.content[0]); 248 + this.editBox.setValue(DATA.content[0]); 251 249 } 252 250 253 251 } 254 252 // The code I am going to avoid like the plague 255 - public void render(DrawContext context, int mouseX, int mouseY, float deltaTicks) { 253 + public void render(GuiGraphics context, int mouseX, int mouseY, float deltaTicks) { 256 254 257 255 if (DATA.content[pageIndex] == null) { 258 256 DATA.content[pageIndex] = ""; 259 257 DATA.write(); 260 258 } 261 - if (!DATA.content[pageIndex].equals(editBox.getText())) { 262 - DATA.content[pageIndex] = editBox.getText(); 259 + if (!DATA.content[pageIndex].equals(editBox.getValue())) { 260 + DATA.content[pageIndex] = editBox.getValue(); 263 261 DATA.write(); 264 262 } 265 263 // Render book background 266 - context.drawTexture(RenderPipelines.GUI_TEXTURED, BOOK_TEXTURE, (this.width - 192) / 2, 2, 0.0F, 0.0F, 192, 192, 256, 256); 264 + context.blit(RenderPipelines.GUI_TEXTURED, BOOK_TEXTURE, (this.width - 192) / 2, 2, 0.0F, 0.0F, 192, 192, 256, 256); 267 265 super.render(context, mouseX, mouseY, deltaTicks); 268 266 // long 269 - context.drawText(this.textRenderer, Text.translatable("book.pageIndicator", this.pageIndex + 1, Math.max(DATA.content.length, 1)), ((this.width - 192) / 2) - this.textRenderer.getWidth(Text.translatable("book.pageIndicator", this.pageIndex + 1, Math.max(DATA.content.length, 1))) + 192 - 44, 18, Colors.BLACK, false); 270 - if (GAY) { context.drawText(this.textRenderer, Text.translatable("notebook.gay"), 5, this.height - 22, Colors.WHITE, true); } 267 + context.drawString(this.font, Component.translatable("book.pageIndicator", this.pageIndex + 1, Math.max(DATA.content.length, 1)), ((this.width - 192) / 2) - this.font.width(Component.translatable("book.pageIndicator", this.pageIndex + 1, Math.max(DATA.content.length, 1))) + 192 - 44, 18, CommonColors.BLACK, false); 268 + if (GAY) { context.drawString(this.font, Component.translatable("notebook.gay"), 5, this.height - 22, CommonColors.WHITE, true); } 271 269 if (CONFIG.debug()) { 272 - context.drawText(this.textRenderer, Text.of("Notebook v" + VERSION + " " + Text.translatable("devwarning.info").getString()), 5, this.height - 10, Colors.WHITE, true); 270 + context.drawString(this.font, Component.nullToEmpty("Notebook v" + VERSION + " " + Component.translatable("devwarning.info").getString()), 5, this.height - 10, CommonColors.WHITE, true); 273 271 } else { 274 - context.drawText(this.textRenderer, Text.of("Notebook v" + VERSION), 5, this.height - 10, Colors.WHITE, true); 272 + context.drawString(this.font, Component.nullToEmpty("Notebook v" + VERSION), 5, this.height - 10, CommonColors.WHITE, true); 275 273 } 276 274 } 277 275
+12 -11
src/client/java/xyz/sillyjune/notebook/mixin/GameMenuScreenButton.java
··· 1 1 package xyz.sillyjune.notebook.mixin; 2 2 3 3 4 - import net.minecraft.client.gui.screen.GameMenuScreen; 5 - import net.minecraft.client.gui.screen.Screen; 6 - import net.minecraft.client.gui.widget.TexturedButtonWidget; 7 4 import xyz.sillyjune.notebook.NotebookScreen; 8 - import net.minecraft.text.Text; 9 5 import org.spongepowered.asm.mixin.Mixin; 10 6 import org.spongepowered.asm.mixin.injection.At; 11 7 import org.spongepowered.asm.mixin.injection.Inject; ··· 13 9 14 10 import static xyz.sillyjune.notebook.Notebook.*; 15 11 16 - @Mixin(GameMenuScreen.class) 12 + import net.minecraft.client.gui.components.ImageButton; 13 + import net.minecraft.client.gui.screens.PauseScreen; 14 + import net.minecraft.client.gui.screens.Screen; 15 + import net.minecraft.network.chat.Component; 16 + 17 + @Mixin(PauseScreen.class) 17 18 public abstract class GameMenuScreenButton extends Screen { 18 - protected GameMenuScreenButton(Text title) { 19 + protected GameMenuScreenButton(Component title) { 19 20 super(title); 20 21 } 21 - @Inject(at = @At("RETURN"), method="initWidgets") 22 + @Inject(at = @At("RETURN"), method="init") 22 23 private void addCustomButton(CallbackInfo ci) { 23 - TexturedButtonWidget b = new TexturedButtonWidget( 24 + ImageButton b = new ImageButton( 24 25 this.width / 2 + 104, 25 26 this.height / 4 + 96 + -16, 26 27 20, 27 28 20, 28 29 getBookIcon(), 29 - (button) -> this.client.setScreen(new NotebookScreen()) 30 + (button) -> this.minecraft.setScreen(new NotebookScreen()) 30 31 ); 31 - b.setMessage(Text.translatable("key.notebook.open")); 32 - this.addDrawableChild(b); 32 + b.setMessage(Component.translatable("key.notebook.open")); 33 + this.addRenderableWidget(b); 33 34 } 34 35 }
+10 -10
src/client/java/xyz/sillyjune/notebook/mixin/TitleScreenButton.java
··· 1 1 package xyz.sillyjune.notebook.mixin; 2 2 3 - import net.minecraft.client.gui.screen.GameMenuScreen; 4 - import net.minecraft.client.gui.screen.Screen; 5 - import net.minecraft.client.gui.screen.TitleScreen; 6 - import net.minecraft.client.gui.widget.TexturedButtonWidget; 7 - import net.minecraft.text.Text; 8 3 import org.spongepowered.asm.mixin.Mixin; 9 4 import org.spongepowered.asm.mixin.injection.At; 10 5 import org.spongepowered.asm.mixin.injection.Inject; ··· 12 7 import xyz.sillyjune.notebook.NotebookScreen; 13 8 14 9 import static xyz.sillyjune.notebook.Notebook.getBookIcon; 10 + 11 + import net.minecraft.client.gui.components.ImageButton; 12 + import net.minecraft.client.gui.screens.Screen; 13 + import net.minecraft.client.gui.screens.TitleScreen; 14 + import net.minecraft.network.chat.Component; 15 15 16 16 @Mixin(TitleScreen.class) 17 17 public abstract class TitleScreenButton extends Screen { 18 - protected TitleScreenButton(Text title) { 18 + protected TitleScreenButton(Component title) { 19 19 super(title); 20 20 } 21 21 @Inject(at = @At("RETURN"), method="init") 22 22 private void addCustomButton(CallbackInfo ci) { 23 - TexturedButtonWidget b = new TexturedButtonWidget( 23 + ImageButton b = new ImageButton( 24 24 this.width / 2 + 104, 25 25 this.height / 4 + 96, 26 26 20, 27 27 20, 28 28 getBookIcon(), 29 - (button) -> this.client.setScreen(new NotebookScreen()) 29 + (button) -> this.minecraft.setScreen(new NotebookScreen()) 30 30 ); 31 - b.setMessage(Text.translatable("key.notebook.open")); 32 - this.addDrawableChild(b); 31 + b.setMessage(Component.translatable("key.notebook.open")); 32 + this.addRenderableWidget(b); 33 33 } 34 34 }
+2 -2
src/client/resources/fabric.mod.json
··· 17 17 "Dushniyy (Russian translations)" 18 18 ], 19 19 "contact": { 20 - "issues": "https://tangled.org/sillyjune.xyz/Minecraft-Vanilla-Notebook/issues", 21 - "sources": "https://forgejo.sillyjune.xyz/juniper/Minecraft-Vanilla-Notebook", 20 + "issues": "https://github.com/JunePrimavera/Minecraft-Vanilla-Notebook/issues", 21 + "sources": "https://github.com/JunePrimavera/Minecraft-Vanilla-Notebook", 22 22 "homepage": "https://modrinth.com/mod/notebook" 23 23 }, 24 24 "license": "MIT",