diff --git a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/classes/Window.java b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/classes/Window.java
index f0ff7a0..0d39d52 100644
--- a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/classes/Window.java
+++ b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/classes/Window.java
@@ -19,98 +19,128 @@
package de.staropensource.sosengine.graphics.opengl.classes;
-import de.staropensource.sosengine.base.logging.LoggerInstance;
-import de.staropensource.sosengine.base.types.CodePart;
-import de.staropensource.sosengine.base.types.logging.LogIssuer;
+import de.staropensource.sosengine.base.exceptions.UnexpectedThrowableException;
import de.staropensource.sosengine.base.types.vectors.Vec2i;
+import de.staropensource.sosengine.base.utility.Miscellaneous;
import de.staropensource.sosengine.graphics.events.GraphicsApiErrorEvent;
-import lombok.Getter;
+import de.staropensource.sosengine.graphics.opengl.exceptions.NotOnMainThreadException;
+import de.staropensource.sosengine.graphics.opengl.exceptions.WindowCreationFailureException;
+import de.staropensource.sosengine.graphics.types.VsyncMode;
+import de.staropensource.sosengine.graphics.types.WindowMode;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.opengl.GL;
-
-import java.util.HashSet;
-import java.util.Set;
+import org.lwjgl.system.MemoryUtil;
import static org.lwjgl.glfw.GLFW.*;
-import static org.lwjgl.system.MemoryUtil.NULL;
/**
* A window on your screen.
*
* @since v1-alpha0
*/
-@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
-public class Window implements de.staropensource.sosengine.graphics.classes.Window {
- /**
- * A set of all active windows.
- *
- * @since v1-alpha0
- *
- * -- GETTER --
- * Returns a set of all active windows.
- *
- * @return set of all windows
- * @since v1-alpha0
- */
- @Getter
- public static Set<@NotNull Window> windows = new HashSet<>();
-
- /**
- * Logger instance.
- *
- * @see LoggerInstance
- * @since v1-alpha0
- */
- private final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass(), CodePart.ENGINE));
-
- /**
- * The window name.
- *
- * @since v1-alpha0
- *
- * -- GETTER --
- * Returns the window name.
- *
- * @return window name
- * @since v1-alpha0
- */
- @Getter
- private String windowName;
-
- /**
- * The window size.
- *
- * @since v1-alpha0
- * -- GETTER --
- * Returns the window size.
- *
- * @return window size
- * @since v1-alpha0
- */
- @Getter
- private Vec2i windowSize;
-
+@SuppressWarnings({ "unused" })
+public class Window extends de.staropensource.sosengine.graphics.classes.Window {
/**
* Creates a new window.
*
- * @param title window title
- * @param size window size
+ * @param title title
+ * @param size size
+ * @param position position
+ * @param windowMode window mode
+ * @param vsyncMode V-Sync mode
+ * @param resizable resizable flag
+ * @param borderless borderless flag
+ * @param focusable focusable flag
+ * @param onTop on top flag
+ * @param transparent transparency flag
+ * @param rendering rendering flag
+ * @throws UnexpectedThrowableException stuff thrown by the {@link #initializeWindow()} of the Graphics API
+ * @since v1-alpha2
*/
- public Window(String title, Vec2i size) {
- logger.diag("Creating new Window with title \"" + title + "\"");
+ public Window(@NotNull String title, @NotNull Vec2i size, @NotNull Vec2i position, @NotNull WindowMode windowMode, @NotNull VsyncMode vsyncMode, boolean resizable, boolean borderless, boolean focusable, boolean onTop, boolean transparent, boolean rendering) throws UnexpectedThrowableException {
+ super(title, size, position, windowMode, vsyncMode, resizable, borderless, focusable, onTop, transparent, rendering);
+ }
- windows.add(this);
- windowName = title;
- windowSize = size;
+ /** {@inheritDoc} */
+ @Override
+ public void initializeWindow() throws WindowCreationFailureException, NotOnMainThreadException {
+ // Ensure running on the main thread
+ if (!Miscellaneous.onMainThread())
+ throw new NotOnMainThreadException();
- long windowId = glfwCreateWindow(windowSize.getX(), windowSize.getY(), windowName, NULL, NULL);
- if (windowId == NULL)
- new GraphicsApiErrorEvent().callEvent("Unable to create window: ID is null");
+ long identifier = glfwCreateWindow(getSize().getX(), getSize().getY(), getTitle(), MemoryUtil.NULL, MemoryUtil.NULL);
+ if (identifier == MemoryUtil.NULL) {
+ new GraphicsApiErrorEvent().callEvent("Unable to create window: Identifier is null");
+ throw new de.staropensource.sosengine.graphics.opengl.exceptions.WindowCreationFailureException();
+ }
- glfwMakeContextCurrent(windowId);
- glfwShowWindow(windowId);
- GL.createCapabilities();
- glfwSwapBuffers(windowId);
+ setIdentifier(String.valueOf(identifier));
+
+ ownContext(identifier); // Own context
+ GL.createCapabilities(); // Create OpenGL capabilities
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void updateState() throws NotOnMainThreadException {
+ // Ensure running on the main thread
+ if (!Miscellaneous.onMainThread())
+ throw new NotOnMainThreadException();
+
+ long identifier = getIdentifierAsLong();
+ ownContext(identifier);
+
+ // Update window visibility
+ if (getWindowMode() == WindowMode.HIDDEN)
+ glfwHideWindow(identifier);
+ else
+ glfwShowWindow(identifier);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void render() throws NotOnMainThreadException {
+ // Ensure running on the main thread
+ if (!Miscellaneous.onMainThread())
+ throw new NotOnMainThreadException();
+
+ long identifier = getIdentifierAsLong();
+
+ glfwSwapBuffers(identifier);
glfwPollEvents();
}
+
+ /** {@inheritDoc} */
+ @NotNull
+ @Override
+ public Vec2i getSizeWithDecorations() {
+ return getSize();
+ }
+
+ /** {@inheritDoc} */
+ @NotNull
+ @Override
+ public Vec2i getPositionWithDecorations() {
+ return getPosition();
+ }
+
+ /**
+ * Returns the window identifier as a long.
+ *
+ * @return window identifier as a long
+ * @since v1-alpha2
+ */
+ public long getIdentifierAsLong() {
+ return Long.getLong(getIdentifier());
+ }
+
+ /**
+ * Updates the OpenGL context.
+ *
+ * @param identifier window to own the context of
+ * @since v1-alpha2
+ */
+ public void ownContext(long identifier) {
+ glfwMakeContextCurrent(identifier);
+ }
}
diff --git a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/NotOnMainThreadException.java b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/NotOnMainThreadException.java
new file mode 100644
index 0000000..938bd52
--- /dev/null
+++ b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/NotOnMainThreadException.java
@@ -0,0 +1,27 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * Note that many window properties may be overridden by any + * window manager or compositor. In almost all cases, that won't happen + * though (except for window size & position in tiling wms/compositors) + * except the user asks for that change directly. * * @since v1-alpha0 */ -@SuppressWarnings({ "unused" }) -public interface Window { +@Getter +@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" }) +public abstract class Window { /** * A set of all active windows. * * @since v1-alpha0 */ @NotNull - Set extends @NotNull Window> windows = new HashSet<>(); + private static final Set<@NotNull Window> windows = new HashSet<>(); + + /** + * The logger instance for this class. + * + * @see LoggerInstance + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the logger instance for this class. + * + * @return logger instance + * @see LoggerInstance + * @since v1-alpha2 + */ + @Getter(value = AccessLevel.PROTECTED) + private final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass(), CodePart.ENGINE)); /** * Contains the window identifier. * * @since v1-alpha1 + * + * -- GETTER -- + * Returns the window identifier. + * + * @return window identifier + * @since v1-alpha2 + * + * -- SETTER -- + * Sets the window identifier. + *
+ * Recommended to be called only once. + * + * @param identifier new window identifier + * @since v1-alpha2 */ - @NotNull - String identifier = ""; + @Setter(AccessLevel.PROTECTED) + private String identifier = null; /** * Determines the title of this window. * * @since v1-alpha1 + * + * -- GETTER -- + * Returns the window title. + * + * @return window title + * @since v1-alpha2 + * + * -- SETTER -- + * Sets the window title. + * + * @param title new window title + * @since v1-alpha2 */ @NotNull - String title = "sos!engine window (update this title)"; + @Setter + private String title; /** * Determines the size of this window. * * @since v1-alpha1 + * + * -- GETTER -- + * Returns the window size. + * + * @return window size + * @since v1-alpha2 + * + * -- SETTER -- + * Sets the window size. + * + * @param size new window size + * @since v1-alpha2 */ @NotNull - Vec2i size = new Vec2i(200, 200); + @Setter + private Vec2i size; + + /** + * Determines the position of this window. + * + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the window position. + * + * @return window position + * @since v1-alpha2 + * + * -- SETTER -- + * Sets the window position. + * + * @param position new window position + * @since v1-alpha2 + */ + @NotNull + @Setter + private Vec2i position; /** * Determines in which {@link WindowMode} this window is in. * * @since v1-alpha1 + * + * -- GETTER -- + * Returns the window mode. + * + * @return window mode + * @since v1-alpha2 + * + * -- SETTER -- + * Sets the window mode. + * + * @param windowMode new window mode + * @since v1-alpha2 */ - WindowMode mode = WindowMode.WINDOWED; + @NotNull + @Setter + private WindowMode windowMode; /** - * Determines if this window should have a border and decorations. + * Determines the V-Sync mode this window targets. * - * @since v1-alpha1 - */ - boolean borderless = false; - - /** - * Determines if this window should be displayed on top of all other windows. + * @since v1-alpha2 * - * @since v1-alpha1 + * -- GETTER -- + * Returns the V-Sync mode. + * + * @return V-Sync mode + * @since v1-alpha2 + * + * -- SETTER -- + * Sets the V-Sync mode. + * + * @param vsyncMode new vsync mode + * @since v1-alpha2 */ - boolean onTop = false; + @NotNull + @Setter + private VsyncMode vsyncMode; /** * Determines if this window can be resized by the user. * * @since v1-alpha1 + * + * -- GETTER -- + * Returns if the window is resizable. + * + * @return resizable flag state + * @since v1-alpha2 + * + * -- SETTER -- + * Sets if the window is resizable. + * + * @param resizable new resizable flag state + * @since v1-alpha2 */ - boolean resizable = false; + @Setter + private boolean resizable; + + /** + * Determines if this window should have a border and decorations. + * + * @since v1-alpha1 + * + * -- GETTER -- + * Returns if the window should be rendered without any decorations. + * + * @return borderless flag state + * @since v1-alpha2 + * + * -- SETTER -- + * Sets if the window should be rendered without any decorations. + * + * @param borderless new borderless flag state + * @since v1-alpha2 + */ + @Setter + private boolean borderless; + + /** + * Determines if the window can be focused. + * + * -- GETTER -- + * Returns if the window can be focused. + * + * @return focusable flag state + * @since v1-alpha2 + * + * -- SETTER -- + * Sets if the window can be focused. + * + * @param focusable new focusable flag state + * @since v1-alpha2 + */ + @Setter + private boolean focusable; + + /** + * Determines if this window should be displayed on top of all other windows. + * + * @since v1-alpha1 + * + * -- GETTER -- + * Returns if the window is displayed over regular windows. + * + * @return on top flag state + * @since v1-alpha2 + * + * -- SETTER -- + * Sets if the window is displayed over regular windows. + * + * @param onTop new on top flag state + * @since v1-alpha2 + */ + @Setter + private boolean onTop; + + /** + * Enables or disables transparency support for this window. + *
+ * Availability depends on the Graphics API, compositor or + * window manager and potentially system settings. + * + * @since v1-alpha2 + * + * -- GETTER -- + * Returns if the window can be transparent. + *
+ * Availability depends on the Graphics API, compositor or + * window manager and potentially system settings. + * + * @return transparency flag state + * @since v1-alpha2 + * + * -- SETTER -- + * Sets if the window can be transparent. + *
+ * Availability depends on the Graphics API, compositor or + * window manager and potentially system settings. + * + * @param transparent new transparency flag state + * @since v1-alpha2 + */ + @Setter + private boolean transparent; + + /** + * Determines if this window should be rendered. + * + * @since v1-alpha2 + * + * -- GETTER -- + * Returns if the window should be rendered. + * + * @return rendering flag state + * @since v1-alpha2 + * + * -- SETTER -- + * Sets if the window should be rendered. + * + * @param rendering new rendering flag state + * @since v1-alpha2 + */ + @Setter + private boolean rendering; + + /** + * Creates a new window. + * + * @param title title + * @param size size + * @param position position + * @param windowMode window mode + * @param vsyncMode V-Sync mode + * @param resizable resizable flag + * @param borderless borderless flag + * @param focusable focusable flag + * @param onTop on top flag + * @param transparent transparency flag + * @param rendering rendering flag + * @throws UnexpectedThrowableException stuff thrown by the {@link #initializeWindow()}, {@link #updateState()} and {@link #render()} methods of the implementing Graphics API + * @since v1-alpha2 + */ + public Window(@NotNull String title, @NotNull Vec2i size, @NotNull Vec2i position, @NotNull WindowMode windowMode, @NotNull VsyncMode vsyncMode, boolean resizable, boolean borderless, boolean focusable, boolean onTop, boolean transparent, boolean rendering) throws UnexpectedThrowableException { + logger.diag("Creating new window with properties: title=" + title + " size=" + size + " position=" + position + " windowMode=" + windowMode + " vsyncMode=" + vsyncMode + " resizable=" + resizable + " borderless=" + borderless + " focusable=" + focusable + " onTop=" + onTop + " transparent=" + transparent + " rendering=" + rendering); + + // Initialize variables + this.title = title; + this.size = size; + this.position = position; + this.windowMode = windowMode; + this.vsyncMode = vsyncMode; + this.resizable = resizable; + this.borderless = borderless; + this.focusable = focusable; + this.onTop = onTop; + this.transparent = transparent; + this.rendering = rendering; + + try { + // Allow Graphics API to initialize window + initializeWindow(); + + // Update state and render first image + updateState(); + render(); + } catch (Throwable throwable) { + throw new UnexpectedThrowableException(throwable); + } + + // Add to window set + windows.add(this); + } + + /** + * Returns a set of active windows. + * + * @return active windows + * @since v1-alpha2 + */ + @NotNull + public static ImmutableHashSet<@NotNull Window> getWindows() { + return new ImmutableHashSet<>(windows); + } + + /** + * Allows the Graphics API to initialize the window. + *
+ * NEVER place any code in the constructor. Instead, write + * API-specific window initialization code in here + * or stuff may break unexpectedly. + * + * @since v1-alpha2 + */ + protected abstract void initializeWindow() throws Throwable; + + /** + * Updates the state of this window. + *
+ * Do not call this method manually or you + * may cause unintended side effects. + */ + public abstract void updateState() throws Throwable; + + /** + * Renders this window. + *
+ * Do not call this method manually or you + * may cause unintended side effects. + */ + public abstract void render() throws Throwable; + + /** + * Returns the window size including decorations (e.g. title bar). + * + * @return window size including decorations + * @since v1-alpha2 + */ + @NotNull + public abstract Vec2i getSizeWithDecorations(); + + /** + * Returns the window position including decorations (e.g. title bar). + * + * @return window position including decorations + * @since v1-alpha2 + */ + @NotNull + public abstract Vec2i getPositionWithDecorations(); + + /** + * Provides an API for building {@link Window} classes more easily. + * + * @since v1-alpha2 + */ + @SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" }) + @Getter + public static class Builder { + /** + * Contains the window title. + * + * @see Window#title + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the window title. + * + * @return window title + * @see Window#title + * @since v1-alpha2 + */ + @Nullable + private String title = null; + + /** + * Contains the window size. + * + * @see Window#size + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the window size. + * + * @return window size + * @see Window#size + * @since v1-alpha2 + */ + @Nullable + private Vec2i size = null; + + /** + * Contains the window position. + * + * @see Window#position + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the window position. + * + * @return window position + * @see Window#position + * @since v1-alpha2 + */ + @Nullable + private Vec2i position = null; + + /** + * Contains the window mode. + * + * @see Window#windowMode + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the window mode. + * + * @return window mode + * @see Window#windowMode + * @since v1-alpha2 + */ + @Nullable + private WindowMode windowMode = null; + + /** + * Contains the V-Sync mode. + * + * @see Window#vsyncMode + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the V-Sync mode. + * + * @return V-Sync mode + * @see Window#vsyncMode + * @since v1-alpha2 + */ + @Nullable + private VsyncMode vsyncMode = null; + + /** + * Contains the resizable flag. + * + * @see Window#resizable + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the resizable flag state. + * + * @return resizable flag state + * @see Window#resizable + * @since v1-alpha2 + */ + @NotNull + private Tristate resizable = Tristate.UNSET; + + /** + * Contains the borderless flag. + * + * @see Window#borderless + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the borderless flag state. + * + * @return borderless flag state + * @see Window#borderless + * @since v1-alpha2 + */ + @NotNull + private Tristate borderless = Tristate.UNSET; + + /** + * Contains the focusable flag. + * + * @see Window#focusable + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the focusable flag state. + * + * @return focusable flag state + * @see Window#focusable + * @since v1-alpha2 + */ + @NotNull + private Tristate focusable = Tristate.UNSET; + + /** + * Contains the on top flag. + * + * @see Window#onTop + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the on top flag state. + * + * @return on top flag state + * @see Window#onTop + * @since v1-alpha2 + */ + @NotNull + private Tristate onTop = Tristate.UNSET; + + /** + * Contains the transparency flag. + * + * @see Window#transparent + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the transparency flag state. + * + * @return transparency flag state + * @see Window#transparent + * @since v1-alpha2 + */ + @NotNull + private Tristate transparent = Tristate.UNSET; + + /** + * Contains the rendering flag. + * + * @see Window#rendering + * @since v1-alpha2 + * + * -- GETTER -- + * Returns the rendering flag state. + * + * @return rendering flag state + * @see Window#rendering + * @since v1-alpha2 + */ + @NotNull + private Tristate rendering = Tristate.UNSET; + + /** + * Constructs this class. + * + * @since v1-alpha2 + */ + public Builder() {} + + /** + * Builds a new {@link Window} class. + * + * @throws IllegalStateException if the window title, size or position is unset + * @throws UnexpectedThrowableException thrown when creating a new {@link Window} instance fails + * @since v1-alpha2 + */ + public Window build() throws IllegalStateException, UnexpectedThrowableException { + // Booleanized tristates with default values + boolean resizableBoolean = true; + boolean borderlessBoolean = false; + boolean focusableBoolean = true; + boolean onTopBoolean = false; + boolean transparentBoolean = false; + boolean renderingBoolean = true; + + // Check for required fields + if (title == null) + throw new IllegalStateException("The window name is unset"); + if (size == null) + throw new IllegalStateException("The window size is unset"); + if (position == null) + throw new IllegalStateException("The window position is unset"); + + // Set default + if (windowMode == null) + windowMode = WindowMode.WINDOWED; + if (vsyncMode == null) + vsyncMode = VsyncMode.ON; + + // Override booleanized tristate defaults + if (resizable == Tristate.FALSE) + resizableBoolean = false; + if (borderless == Tristate.TRUE) + borderlessBoolean = true; + if (focusable == Tristate.FALSE) + focusableBoolean = false; + if (onTop == Tristate.TRUE) + onTopBoolean = true; + if (transparent == Tristate.TRUE) + transparentBoolean = true; + if (rendering == Tristate.FALSE) + renderingBoolean = false; + + // Create new Window instance + try { + return GraphicsSubsystem.getInstance().getApi().getInternalApi().getWindowClass() + .getDeclaredConstructor(String.class, Vec2i.class, Vec2i.class, WindowMode.class, VsyncMode.class, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE) + .newInstance(title, size, position, windowMode, vsyncMode, resizableBoolean, borderlessBoolean, focusableBoolean, onTopBoolean, transparentBoolean, renderingBoolean); + } catch (Throwable throwable) { + throw new UnexpectedThrowableException(throwable, "Window.Builder was unable to create new Window instance"); + } + } + + /** + * Sets the window title. + * + * @param title new window title + * @return builder instance + * @since v1-alpha2 + */ + @NotNull + public synchronized Builder setTitle(@Nullable String title) { + this.title = title; + return this; + } + + /** + * Sets the window size. + * + * @param size new window size + * @return builder instance + * @since v1-alpha2 + */ + @NotNull + public synchronized Builder setSize(@Nullable Vec2i size) { + this.size = size; + return this; + } + + /** + * Sets the window position. + * + * @param position new window position + * @return builder instance + * @since v1-alpha2 + */ + @NotNull + public synchronized Builder setPosition(@Nullable Vec2i position) { + this.position = position; + return this; + } + + /** + * Sets the window mode. + * + * @param windowMode new window mode + * @return builder instance + * @since v1-alpha2 + */ + @NotNull + public synchronized Builder setWindowMode(@Nullable WindowMode windowMode) { + this.windowMode = windowMode; + return this; + } + + /** + * Sets the V-Sync mode. + * + * @param vsyncMode new V-Sync mode + * @return builder instance + * @since v1-alpha2 + */ + @NotNull + public synchronized Builder setVsyncMode(@Nullable VsyncMode vsyncMode) { + this.vsyncMode = vsyncMode; + return this; + } + + /** + * Sets the resizable flag. + * + * @param resizable new resizable flag state + * @return builder instance + * @since v1-alpha2 + */ + @NotNull + public synchronized Builder setResizable(@NotNull Tristate resizable) { + this.resizable = resizable; + return this; + } + + /** + * Sets the borderless flag. + * + * @param borderless new borderless flag state + * @return builder instance + * @since v1-alpha2 + */ + @NotNull + public synchronized Builder setBorderless(@NotNull Tristate borderless) { + this.borderless = borderless; + return this; + } + + /** + * Sets the focusable flag. + * + * @param focusable new focusable flag state + * @return builder instance + * @since v1-alpha2 + */ + @NotNull + public synchronized Builder setFocusable(@NotNull Tristate focusable) { + this.focusable = focusable; + return this; + } + + /** + * Sets the on top flag. + * + * @param onTop new on top flag state + * @return builder instance + * @since v1-alpha2 + */ + @NotNull + public synchronized Builder setOnTop(@NotNull Tristate onTop) { + this.onTop = onTop; + return this; + } + + /** + * Sets the transparency flag. + * + * @param transparent new transparency flag state + * @return builder instance + * @since v1-alpha2 + */ + @NotNull + public synchronized Builder setTransparent(@NotNull Tristate transparent) { + this.transparent = transparent; + return this; + } + + /** + * Sets the rendering flag. + * + * @param rendering new rendering flag state + * @return builder instance + * @since v1-alpha2 + */ + @NotNull + public synchronized Builder setRendering(@NotNull Tristate rendering) { + this.rendering = rendering; + return this; + } + } } diff --git a/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java b/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java index 6f31bd1..bde2a5f 100644 --- a/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java +++ b/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java @@ -20,6 +20,7 @@ package de.staropensource.sosengine.testapp; import de.staropensource.sosengine.base.Engine; +import de.staropensource.sosengine.base.exceptions.UnexpectedThrowableException; import de.staropensource.sosengine.base.logging.LoggerInstance; import de.staropensource.sosengine.base.types.CodePart; import de.staropensource.sosengine.base.types.logging.LogIssuer; @@ -27,6 +28,7 @@ import de.staropensource.sosengine.base.types.vectors.Vec2i; import de.staropensource.sosengine.graphics.GraphicsSubsystem; import de.staropensource.sosengine.graphics.classes.ApiMainClass; import de.staropensource.sosengine.graphics.classes.ApiManagementClass; +import de.staropensource.sosengine.graphics.classes.Window; import lombok.Getter; import lombok.SneakyThrows; @@ -111,6 +113,15 @@ public class Main { ApiManagementClass management = api.getManagement(); // Create window + try { + Window window = new Window.Builder() + .setTitle("test application window") + .setSize(new Vec2i(960, 540)) + .setPosition(new Vec2i(10, 10)) + .build(); + } catch (UnexpectedThrowableException exception) { + logger.crash("build() throw an UnexpectedThrowableException", exception.getThrowable()); + } // Sleep for five seconds Thread.sleep(5000);