diff --git a/src/main/java/be/seeseemelk/diceos/system/DiceOSAdapter.java b/src/main/java/be/seeseemelk/diceos/system/DiceOSAdapter.java index 7e7e771..7927548 100644 --- a/src/main/java/be/seeseemelk/diceos/system/DiceOSAdapter.java +++ b/src/main/java/be/seeseemelk/diceos/system/DiceOSAdapter.java @@ -34,8 +34,6 @@ public class DiceOSAdapter extends ApplicationAdapter { private int offsetY = 0; private GraphicsContext gc; - private BitmapFont font; - @Override public void create() { log.info("DiceOS starting..."); @@ -50,8 +48,6 @@ public class DiceOSAdapter extends ApplicationAdapter { task.onStartup(); } - font = resourceLoader.loadFont("system/font"); - log.info("DiceOS started!"); } @@ -67,7 +63,8 @@ public class DiceOSAdapter extends ApplicationAdapter { cursorService.setScale(scaling); - gc = new GraphicsContext(screenViewport.getCamera(), display.getBatch(), displayHeight, displayWidth, font); + gc = new GraphicsContext(screenViewport.getCamera(), display.getBatch(), displayHeight, displayWidth, + DiceOS.getResourceLoader().getDefaultFont().getBitmapFont()); } @Override diff --git a/src/main/java/be/seeseemelk/diceos/system/InputService.java b/src/main/java/be/seeseemelk/diceos/system/InputService.java index 586bb34..dfc20ef 100644 --- a/src/main/java/be/seeseemelk/diceos/system/InputService.java +++ b/src/main/java/be/seeseemelk/diceos/system/InputService.java @@ -1,5 +1,6 @@ package be.seeseemelk.diceos.system; +import be.seeseemelk.diceos.system.toolkit.events.MouseClickEvent; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.InputAdapter; @@ -7,6 +8,8 @@ import io.avaje.inject.Component; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import java.awt.event.KeyEvent; + @Slf4j @Component @RequiredArgsConstructor @@ -24,6 +27,19 @@ public class InputService implements OnStartup { } else if (keycode == Input.Keys.ESCAPE) { Gdx.app.exit(); } + //DiceOS.getWindowService().onEvent(new KeyEvent(keycode)); + return false; + } + + @Override + public boolean touchUp(int screenX, int screenY, int pointer, int button) { + DiceOS.getWindowService().onEvent(new MouseClickEvent(screenX, screenY, MouseClickEvent.Button.LEFT, MouseClickEvent.Action.RELEASED)); + return false; + } + + @Override + public boolean touchDown(int screenX, int screenY, int pointer, int button) { + DiceOS.getWindowService().onEvent(new MouseClickEvent(screenX, screenY, MouseClickEvent.Button.LEFT, MouseClickEvent.Action.PRESSED)); return false; } }); diff --git a/src/main/java/be/seeseemelk/diceos/system/ResourceLoader.java b/src/main/java/be/seeseemelk/diceos/system/ResourceLoader.java index 58143d4..addaafb 100644 --- a/src/main/java/be/seeseemelk/diceos/system/ResourceLoader.java +++ b/src/main/java/be/seeseemelk/diceos/system/ResourceLoader.java @@ -1,5 +1,6 @@ package be.seeseemelk.diceos.system; +import be.seeseemelk.diceos.system.font.Font; import be.seeseemelk.diceos.system.font.FontLoader; import be.seeseemelk.diceos.system.font.FontMetadata; import be.seeseemelk.diceos.system.gfx.NinePatchLoader; @@ -18,6 +19,14 @@ import tools.jackson.dataformat.toml.TomlFactory; import java.util.HashMap; import java.util.Map; +/** + * A utility class responsible for loading and caching graphical and textual assets used in the application. + * It manages various types of resources including pixmaps, textures, nine-patches, and fonts, ensuring that + * assets are loaded only once and subsequently reused to optimize performance. + * + * The class supports loading assets from specified file paths and caches them in memory. It implements a + * lazy-loading mechanism to defer loading until a resource is requested. + */ @Slf4j @RequiredArgsConstructor @Component @@ -25,7 +34,7 @@ public class ResourceLoader { private final Map pixmaps = new HashMap<>(); private final Map textures = new HashMap<>(); private final Map ninePatches = new HashMap<>(); - private final Map fonts = new HashMap<>(); + private final Map fonts = new HashMap<>(); private final ObjectMapper mapper = new ObjectMapper(new TomlFactory()); public Pixmap loadPixmap(String path) { @@ -36,6 +45,13 @@ public class ResourceLoader { return textures.computeIfAbsent(path, p -> new Texture(Gdx.files.internal(p))); } + /** + * Loads and retrieves a {@link NinePatch} object for the given image path. The method caches loaded + * {@link NinePatch} instances to avoid redundant processing of the same asset. + * + * @param path the file path of the image to load as a 9-patch + * @return the loaded {@link NinePatch} instance corresponding to the specified image path + */ public NinePatch loadNinePatch(String path) { return ninePatches.computeIfAbsent(path, p -> { var pixmap = loadPixmap(p); @@ -44,16 +60,28 @@ public class ResourceLoader { }); } - public BitmapFont loadFont(String path) { + /** + * Loads and retrieves a {@link Font} object for the given file path. + * The method caches loaded {@link Font} instances to avoid redundant + * processing of the same asset. + * + * @param path the file path of the font to load + * @return the loaded {@link Font} instance corresponding to the specified file path + */ + public Font loadFont(String path) { return fonts.computeIfAbsent(path, this::loadBitmapfont); } - private BitmapFont loadBitmapfont(String path) { + public Font getDefaultFont() { + return loadFont("system/font"); + } + + private Font loadBitmapfont(String path) { log.info("Loading bitmap font from {}", path); var metadataString = Gdx.files.internal(path + ".toml").readString(); var metadata = mapper.readValue(metadataString, FontMetadata.class); @Cleanup("dispose") var pixmap = loadPixmap(metadata.getGeneral().getSource()); - return FontLoader.loadBitmapfont(pixmap, metadata); + return new Font(FontLoader.loadBitmapfont(pixmap, metadata)); } } diff --git a/src/main/java/be/seeseemelk/diceos/system/WindowService.java b/src/main/java/be/seeseemelk/diceos/system/WindowService.java index 80bce39..93cb110 100644 --- a/src/main/java/be/seeseemelk/diceos/system/WindowService.java +++ b/src/main/java/be/seeseemelk/diceos/system/WindowService.java @@ -2,14 +2,18 @@ package be.seeseemelk.diceos.system; import be.seeseemelk.diceos.system.gfx.GraphicsContext; import be.seeseemelk.diceos.system.toolkit.Window; +import be.seeseemelk.diceos.system.toolkit.events.Event; +import be.seeseemelk.diceos.system.toolkit.events.MouseClickEvent; import be.seeseemelk.diceos.system.toolkit.menu.Menu; import com.badlogic.gdx.graphics.g2d.NinePatch; import io.avaje.inject.Component; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.List; +@Slf4j @RequiredArgsConstructor @Component public class WindowService implements OnStartup { @@ -65,11 +69,24 @@ public class WindowService implements OnStartup { // Render menubar items gc.save(); - gc.translate(5, 0); + gc.translate(10, 0); for (var submenu : menu.getItems()) { submenu.paint(gc); - gc.translate(submenu.getWidth(), 0); + gc.translate(submenu.getWidth() + 4, 0); } gc.restore(); } + + void onEvent(Event event) { + switch (event) { + case MouseClickEvent e -> onMouseClickEvent(e); + default -> {} + } + } + + private void onMouseClickEvent(MouseClickEvent event) { + if (event.getY() <= 14) { + log.info("Clicking on menubar"); + } + } } diff --git a/src/main/java/be/seeseemelk/diceos/system/font/Font.java b/src/main/java/be/seeseemelk/diceos/system/font/Font.java new file mode 100644 index 0000000..e2ba81a --- /dev/null +++ b/src/main/java/be/seeseemelk/diceos/system/font/Font.java @@ -0,0 +1,26 @@ +package be.seeseemelk.diceos.system.font; + +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * Represents a font used for rendering text, providing utilities + * for measuring text dimensions. + */ +@RequiredArgsConstructor +public class Font { + @Getter + private final BitmapFont bitmapFont; + + /** + * Calculates the width of the given text when rendered with the current font. + * @param text The text to measure. + * @return The width of the text in pixels. + */ + public int getTextWidth(String text) { + var layout = new com.badlogic.gdx.graphics.g2d.GlyphLayout(); + layout.setText(bitmapFont, text); + return (int) layout.width; + } +} diff --git a/src/main/java/be/seeseemelk/diceos/system/font/FontLoader.java b/src/main/java/be/seeseemelk/diceos/system/font/FontLoader.java index fdafb31..d76fcf9 100644 --- a/src/main/java/be/seeseemelk/diceos/system/font/FontLoader.java +++ b/src/main/java/be/seeseemelk/diceos/system/font/FontLoader.java @@ -195,7 +195,7 @@ public class FontLoader { if (!isBlack) { currentTiming.glyphEnd = x; state = State.WAITING_FOR_GLYPH_WIDTHS; - log.info("Found glyph width: {} (from {} to {})", currentTiming.getGlyphWidth(), currentTiming.glyphStart, currentTiming.glyphEnd); + //log.info("Found glyph width: {} (from {} to {})", currentTiming.getGlyphWidth(), currentTiming.glyphStart, currentTiming.glyphEnd); } } } diff --git a/src/main/java/be/seeseemelk/diceos/system/font/GeneralSection.java b/src/main/java/be/seeseemelk/diceos/system/font/GeneralSection.java index d046c95..aef8b1e 100644 --- a/src/main/java/be/seeseemelk/diceos/system/font/GeneralSection.java +++ b/src/main/java/be/seeseemelk/diceos/system/font/GeneralSection.java @@ -16,6 +16,13 @@ public class GeneralSection { */ private String order; - // @gemini implement private int lineHeight; + + public int getLineHeight() { + return lineHeight; + } + + public void setLineHeight(int lineHeight) { + this.lineHeight = lineHeight; + } } diff --git a/src/main/java/be/seeseemelk/diceos/system/toolkit/events/MouseClickEvent.java b/src/main/java/be/seeseemelk/diceos/system/toolkit/events/MouseClickEvent.java index 9afbf0e..c37e3a5 100644 --- a/src/main/java/be/seeseemelk/diceos/system/toolkit/events/MouseClickEvent.java +++ b/src/main/java/be/seeseemelk/diceos/system/toolkit/events/MouseClickEvent.java @@ -17,9 +17,17 @@ public class MouseClickEvent extends MouseEvent { */ private final Button button; + /** + * The action performed in the mouse click event, indicating whether the mouse button + * was pressed or released. + */ + private final Action action; + public enum Button { - LEFT, - RIGHT, - ; + LEFT, RIGHT, + } + + public enum Action { + PRESSED, RELEASED } } diff --git a/src/main/java/be/seeseemelk/diceos/system/toolkit/menu/Menu.java b/src/main/java/be/seeseemelk/diceos/system/toolkit/menu/Menu.java index e155ec3..cacbc80 100644 --- a/src/main/java/be/seeseemelk/diceos/system/toolkit/menu/Menu.java +++ b/src/main/java/be/seeseemelk/diceos/system/toolkit/menu/Menu.java @@ -1,6 +1,7 @@ package be.seeseemelk.diceos.system.toolkit.menu; import be.seeseemelk.diceos.system.DiceOS; +import be.seeseemelk.diceos.system.font.Font; import be.seeseemelk.diceos.system.gfx.GraphicsContext; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -13,6 +14,7 @@ import java.util.List; public class Menu implements MenuItem { private final String title; private final List items = new ArrayList<>(); + private final Font font = DiceOS.getResourceLoader().getDefaultFont(); public Menu add(MenuItem item) { items.add(item); @@ -26,7 +28,7 @@ public class Menu implements MenuItem { @Override public int getWidth() { - return items.stream().mapToInt(MenuItem::getWidth).max().orElse(0); + return font.getTextWidth(title); } @Override